More progress in emulator build

I'd say this is about 70% complete to initial tests, then comes the
debugging. But that's for another day.
This commit is contained in:
Lephenixnoir 2021-08-14 15:10:56 +02:00
parent 2675d6d3aa
commit d075ba2174
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
14 changed files with 446 additions and 610 deletions

Binary file not shown.

View File

@ -10,7 +10,7 @@ CFLAGS := -I cgdoom
# Extra optimization passes just in case
CFLAGS += -O3 -fgcse-sm -fgcse-las -fgcse-after-reload -fmerge-all-constants
# We remove some warnings that come up a lot in Doom
CFLAGS += -Wall -Wextra -Wno-sign-compare -Wno-unused-but-set-variable -Wno-unused-but-set-parameter
CFLAGS += -Wall -Wextra -Wno-sign-compare -Wno-unused-but-set-variable -Wno-unused-but-set-parameter -Wno-implicit-fallthrough -Wno-misleading-indentation
LDFLAGS :=
@ -36,8 +36,8 @@ CG_LDFLAGS += -nostartfiles -T $(LIBFXCG_ROOT)/toolchain/prizm.x
# Generate a map of every function and global variable for debugging
CG_LDFLAGS += -Wl,-Map=build-cg/$(NAME).map
CG_SRC := $(SRC) $(wildcard src-cg/*.c src-cg/*.s)
CG_OBJ := $(CG_SRC:cgdoom/%=build-cg/%.o)
CG_SRC := $(wildcard src-cg/*.c src-cg/*.s)
CG_OBJ := $(SRC:cgdoom/%=build-cg/%.o) $(CG_SRC:src-cg/%=build-cg/%.o)
### Native SDL2 build.
@ -46,16 +46,16 @@ CC ?= gcc
SDL2_CFLAGS := $(CFLAGS) -I src-sdl2 -DCG_EMULATOR $(pkg-config sdl2 --cflags)
SDL2_LDFLAGS := $(LDFLAGS) $(pkg-config sdl2 --libs)
SDL2_SRC := $(SRC) $(wildcard src-sdl2/*.c)
SDL2_OBJ := $(SDL2_SRC:cgdoom/%=build-sdl2/%.o)
SDL2_SRC := $(wildcard src-sdl2/*.c)
SDL2_OBJ := $(SRC:cgdoom/%=build-sdl2/%.o) $(SDL2_SRC:src-sdl2/%=build-sdl2/%.o)
### Build rules.
all: all-cg50
all: all-cg
#~
all-cg50: $(NAME).g3a
all-cg: $(NAME).g3a
$(NAME).g3a: build-cg/$(NAME).bin
mkg3a -n : -i uns:CGDOOM_UNSELECTED.png -i sel:CGDOOM_SELECTED.png $< $@
@ -69,6 +69,9 @@ build-cg/%.c.o: cgdoom/%.c | build-cg/
build-cg/%.c.o: src-cg/%.c | build-cg/
$(CG_CC) $(CG_CFLAGS) -c $< -o $@
build-cg/%.s.o: src-cg/%.s | build-cg/
$(CG_CC) $(CG_CFLAGS) -c $< -o $@
build-cg/$(NAME).elf: $(CG_OBJ)
$(CG_CC) $(CG_CFLAGS) $(CG_LDFLAGS) $^ -o $@

View File

@ -1,6 +1,7 @@
#include "platform.h"
#include "os.h"
#include "cgdoom.h"
#include <stdlib.h>
#ifndef CG_EMULATOR
# include "cgdoom-alloc.h"
@ -616,9 +617,6 @@ int main(void)
VRAM = (unsigned short*)GetVRAMAddress();
#ifdef CG_EMULATOR
InitFlashSimu("doom.wad");
#else
int time, ms_index=0, ms_mmap=0;
EnableColor(1);
@ -630,8 +628,6 @@ int main(void)
int wad_count = FindWADs(wads, 16);
int dev_info = 0;
int choice = UI_Main(wads, wad_count, &dev_info, &gWADmethod,
&startmap, &startepisode);
if(choice < 0)
@ -643,13 +639,16 @@ int main(void)
SystemStack = (void *)0xac0f0000;
/* Setup access to WAD file */
#ifdef CG_EMULATOR
gWADmethod = CGDOOM_WAD_BFILE;
#endif
if(gWADmethod == CGDOOM_WAD_BFILE)
{
gWADfd = Bfile_OpenFile_OS(wads[choice].path, 0, 0);
}
else
{
#ifdef FLASH_INDEX
#ifdef FLASH_INDEX
/* Index most likely flash sectors into a sorted array, so that
sectors can be hit quickly. The index contains every sector
on a 4-kiB boundary (where fragments are most likely to
@ -663,7 +662,8 @@ int main(void)
}
qsort(gIndex, FLASH_INDEX_SIZE, sizeof *gIndex, IndexCompareSectors);
ms_index = (RTC_GetTicks() - time) * 8;
#endif
#endif /* FLASH_INDEX */
time = RTC_GetTicks();
gWADMap.mTable = (void *)0xfe200000; /* PRAM0 */
int fd = Bfile_OpenFile_OS(wads[choice].path, 0, 0);
@ -710,15 +710,11 @@ int main(void)
CGD_PRAM_Init(PRAM0_start, PRAM0_end);
}
#endif /* !CG_EMULATOR */
memset(VRAM, 0, WIDTH*HEIGHT*2);
D_DoomMain();
#ifndef CG_EMULATOR
if(gWADfd >= 0)
Bfile_CloseFile_OS(gWADfd);
#endif
return 1;
}

View File

@ -25,4 +25,23 @@ typedef struct
/* Map and episode to start at when loading the game. */
extern int startmap, startepisode;
/* Keyboard interface. */
// Special key names for cheats, debugs, etc (completes doomdef.h).
#define SKEY_CHEAT 0x10001
#define SKEY_DECVP 0x10002
#define SKEY_INCVP 0x10003
#define SKEY_NOCLIP 0x10004
#define SKEY_GAMMA 0x10005
#define SKEY_FREEMEM 0x10006
#define SKEY_FPSCOUNTER 0x10007
#define SKEY_FRAMESKIP 0x10008
// Scan keyboard (the previous state is also retained).
void UpdateKeyboardState(void);
// Check if a Doom key has just been pressed, or released.
int KeyWasJustPressed(int key);
int KeyWasJustReleased(int key);
#endif /* CGDOOM_H */

View File

@ -31,6 +31,7 @@
#include "os.h"
#include "cgdoom-alloc.h"
#include <stdlib.h>
#include "doomdef.h"
#include "doomstat.h"

View File

@ -258,39 +258,39 @@ void G_BuildTiccmd (ticcmd_t* cmd)
break;
}
if (forward > MAXPLMOVE)
{
forward = MAXPLMOVE;
}
else if (forward < -MAXPLMOVE)
{
forward = -MAXPLMOVE;
}
if (forward > MAXPLMOVE)
{
forward = MAXPLMOVE;
}
else if (forward < -MAXPLMOVE)
{
forward = -MAXPLMOVE;
}
if (side > MAXPLMOVE)
{
side = MAXPLMOVE;
}
else if (side < -MAXPLMOVE)
{
side = -MAXPLMOVE;
}
if (side > MAXPLMOVE)
{
side = MAXPLMOVE;
}
else if (side < -MAXPLMOVE)
{
side = -MAXPLMOVE;
}
cmd->forwardmove= forward;
cmd->sidemove= side;
cmd->forwardmove= forward;
cmd->sidemove= side;
// special buttons
if (sendpause)
{
sendpause = false;
cmd->buttons = BT_SPECIAL | BTS_PAUSE;
}
// special buttons
if (sendpause)
{
sendpause = false;
cmd->buttons = BT_SPECIAL | BTS_PAUSE;
}
if (sendsave)
{
sendsave = false;
cmd->buttons = (byte)(BT_SPECIAL | BTS_SAVEGAME | (savegameslot<<BTS_SAVESHIFT));
}
if (sendsave)
{
sendsave = false;
cmd->buttons = (byte)(BT_SPECIAL | BTS_SAVEGAME | (savegameslot<<BTS_SAVESHIFT));
}
}
@ -921,6 +921,8 @@ void G_DoLoadGame (void)
//
void G_SaveGame( int slot, char* description )
{
(void)slot;
(void)description;
}
void G_DoSaveGame (void)

View File

@ -23,6 +23,7 @@
#include "platform.h"
#include "cgdoom.h"
#include <stdlib.h>
#include "doomdef.h"
@ -256,129 +257,8 @@ static void R_SetViewSizeChange(int iDiff)
}
}
///////////////////////////////////////////////////////////////////////////////
// Keyboard input
//
// Instead of using libfxcg functions which only provide single-key analysis
// (GetKey, GetKeyWait, and PRGM_GetKey mainly), the following code uses a
// simple KEYSC driver. This is indirectly taken from gint code.
///////////////////////////////////////////////////////////////////////////////
/* Keyboard matrix codes */
#define KEYCODE_F1 0x91
#define KEYCODE_F2 0x92
#define KEYCODE_F3 0x93
#define KEYCODE_F4 0x94
#define KEYCODE_F5 0x95
#define KEYCODE_F6 0x96
#define KEYCODE_SHIFT 0x81
#define KEYCODE_OPTN 0x82
#define KEYCODE_VARS 0x83
#define KEYCODE_MENU 0x84
#define KEYCODE_LEFT 0x85
#define KEYCODE_UP 0x86
#define KEYCODE_ALPHA 0x71
#define KEYCODE_SQUARE 0x72
#define KEYCODE_POWER 0x73
#define KEYCODE_EXIT 0x74
#define KEYCODE_DOWN 0x75
#define KEYCODE_RIGHT 0x76
#define KEYCODE_XOT 0x61
#define KEYCODE_LOG 0x62
#define KEYCODE_LN 0x63
#define KEYCODE_SIN 0x64
#define KEYCODE_COS 0x65
#define KEYCODE_TAN 0x66
#define KEYCODE_FRAC 0x51
#define KEYCODE_FD 0x52
#define KEYCODE_LEFTP 0x53
#define KEYCODE_RIGHTP 0x54
#define KEYCODE_COMMA 0x55
#define KEYCODE_ARROW 0x56
#define KEYCODE_7 0x41
#define KEYCODE_8 0x42
#define KEYCODE_9 0x43
#define KEYCODE_DEL 0x44
#define KEYCODE_4 0x31
#define KEYCODE_5 0x32
#define KEYCODE_6 0x33
#define KEYCODE_MUL 0x34
#define KEYCODE_DIV 0x35
#define KEYCODE_1 0x21
#define KEYCODE_2 0x22
#define KEYCODE_3 0x23
#define KEYCODE_PLUS 0x24
#define KEYCODE_MINUS 0x25
#define KEYCODE_0 0x11
#define KEYCODE_DOT 0x12
#define KEYCODE_EXP 0x13
#define KEYCODE_NEG 0x14
#define KEYCODE_EXE 0x15
#define KEYCODE_ACON 0x07
/* Copy of the keyboard state, one byte per row */
typedef uint8_t KeyboardState[12] __attribute__((aligned(2)));
void ScanKeyboard(KeyboardState state)
{
volatile uint16_t *KEYSC = (void *)0xa44b0000;
uint16_t *array = (void *)state;
for(int i = 0; i < 6; i++) array[i] = KEYSC[i];
}
int KeycodeDown(KeyboardState state, int code)
{
int row = (code >> 4) ^ 1;
int col = 0x80 >> (code & 0x7);
return (state[row] & col) != 0;
}
int KeycodePressed(KeyboardState old_state, KeyboardState new_state, int code)
{
return !KeycodeDown(old_state, code) && KeycodeDown(new_state, code);
}
int KeycodeToDoomKey(int code)
{
switch(code)
{
case KEYCODE_LEFT: return KEY_LEFTARROW;
case KEYCODE_RIGHT: return KEY_RIGHTARROW;
case KEYCODE_UP: return KEY_UPARROW;
case KEYCODE_DOWN: return KEY_DOWNARROW;
case KEYCODE_SQUARE: return ' ';
case KEYCODE_ALPHA: return KEY_RCTRL;
case KEYCODE_F1: return '1';
case KEYCODE_F2: return '2';
case KEYCODE_F3: return '3';
case KEYCODE_F4: return '4';
case KEYCODE_F5: return '5';
case KEYCODE_F6: return '6';
case KEYCODE_SHIFT: return '7';
case KEYCODE_EXIT: return KEY_TAB;
case KEYCODE_OPTN: return KEY_PAUSE;
case KEYCODE_0: return KEY_SLEFTARROW;
case KEYCODE_DOT: return KEY_SRIGHTARROW;
case KEYCODE_MENU: return KEY_ESCAPE;
case KEYCODE_EXE: return KEY_ENTER;
default: return -1;
}
}
void I_StartTic (void)
{
static KeyboardState st = { 0 };
extern boolean fpscounteractive;
extern int fpscounter_data;
extern int giRefreshMask;
@ -403,50 +283,45 @@ void I_StartTic (void)
fps_frames = 0;
}
KeyboardState next_st;
ScanKeyboard(next_st);
UpdateKeyboardState();
/* Capture events for special keys */
if (KeycodePressed(st, next_st, KEYCODE_POWER))
if (KeyWasJustPressed(SKEY_CHEAT))
CGCheat();
if (KeycodePressed(st, next_st, KEYCODE_MINUS))
if (KeyWasJustPressed(SKEY_DECVP))
R_SetViewSizeChange(-1);
if (KeycodePressed(st, next_st, KEYCODE_PLUS))
if (KeyWasJustPressed(SKEY_INCVP))
R_SetViewSizeChange(1);
if (KeycodePressed(st, next_st, KEYCODE_ARROW))
if (KeyWasJustPressed(SKEY_NOCLIP))
CGSwitchClip();
if (KeycodePressed(st, next_st, KEYCODE_FRAC))
if (KeyWasJustPressed(SKEY_GAMMA))
CGCycleGamma();
if (KeycodePressed(st, next_st, KEYCODE_FD))
if (KeyWasJustPressed(SKEY_FREEMEM))
CGFreeMem();
if (KeycodePressed(st, next_st, KEYCODE_LEFTP))
if (KeyWasJustPressed(SKEY_FPSCOUNTER))
fpscounteractive = !fpscounteractive;
if (KeycodePressed(st, next_st, KEYCODE_VARS))
if (KeyWasJustPressed(SKEY_FRAMESKIP))
CGRefreshSwitch();
/* Emit events for all changes between st and next_st */
for (int row = 0; row < 12; row++)
static int keys[] = {
KEY_LEFTARROW, KEY_RIGHTARROW, KEY_UPARROW, KEY_DOWNARROW,
KEY_RCTRL, KEY_TAB, KEY_PAUSE, KEY_SLEFTARROW, KEY_SRIGHTARROW,
KEY_ESCAPE, KEY_ENTER,
' ', '1', '2', '3', '4', '5', '6', '7',
0
};
/* Emit events for all changes */
for(int i = 0; keys[i]; i++)
{
int changed = next_st[row] ^ st[row];
if (!changed)
continue;
event_t e;
if(KeyWasJustPressed(keys[i]))
e.type = ev_keydown;
else if(KeyWasJustReleased(keys[i]))
e.type = ev_keyup;
else continue;
for(int code = ((row ^ 1) << 4) | 0x7; code & 0x7; code--)
{
if(changed & 1)
{
int key = KeycodeToDoomKey(code);
if (key < 0)
continue;
event_t e;
e.type = KeycodeDown(next_st, code) ? ev_keydown : ev_keyup;
e.data1 = key;
D_PostEvent(&e);
}
changed >>= 1;
}
e.data1 = keys[i];
D_PostEvent(&e);
}
memcpy(st, next_st, sizeof st);
}

View File

@ -30,9 +30,6 @@
#pragma interface
#endif
// A check to determine which control system to compile for
//#define EMULATOR_CONTROLS 1
/* CGDOOM: I_ZoneBase() is extended with a second argument to support multiple
allocation zones, for more memory */

View File

@ -93,32 +93,7 @@ void I_SetPalette(int gamma_correction)
}
}
#if defined(CG_EMULATOR)
void I_Flip (void)
{
int x,y;
for(y=0;y<SCREENHEIGHT;y++)
{
for(x=0;x<SCREENWIDTH;x++)
{
VRAM[(x+(WIDTH-SCREENWIDTH)/2)+(y+(HEIGHT-SCREENHEIGHT)/2)*WIDTH] = gPalette[screens[0][x+y*SCREENWIDTH]];
}
}
EmuUpdateWindow();
}
void I_InitGraphics(void)
{
EmuInitGraphics();
}
void I_ShutdownGraphics(void)
{
EmuShutdownGraphics();
}
#elif defined(CGDOOM_DIRECT_R61524)
#if !defined(CG_EMULATOR) && defined(CGDOOM_DIRECT_R61524)
#define SYNCO() __asm__ volatile("synco":::"memory");
#define PRDR *(volatile uint8_t *)0xA405013C

View File

@ -452,7 +452,7 @@ menu_t SaveDef =
80,54,
0
};
*/
//
// M_ReadSaveStrings
@ -506,11 +506,13 @@ void M_DrawLoad(void)
void M_LoadGame(int choice)
{
(void)choice;
M_StartMessage(NOTIMP, NULL, true);
}
void M_SaveGame(int choice)
{
(void)choice;
M_StartMessage(NOTIMP, NULL, true);
}
@ -1169,15 +1171,15 @@ void M_Drawer (void)
break;
}
if (i == CGDstrlen(messageString+start))
{
CGDstrcpy(string,messageString+start);
start += i;
}
if (i == CGDstrlen(messageString+start))
{
CGDstrcpy(string,messageString+start);
start += i;
}
x = (short)(160 - M_StringWidth(string)/2);
M_WriteText(x,y,string);
y = y + SHORT(hu_font[0]->height);
x = (short)(160 - M_StringWidth(string)/2);
M_WriteText(x,y,string);
y = y + SHORT(hu_font[0]->height);
}
return;
}

149
src-cg/keyboard.c Normal file
View File

@ -0,0 +1,149 @@
///////////////////////////////////////////////////////////////////////////////
// Keyboard input
//
// Instead of using libfxcg functions which only provide single-key analysis
// (GetKey, GetKeyWait, and PRGM_GetKey mainly), the following code uses a
// simple KEYSC driver. This is indirectly taken from gint code.
///////////////////////////////////////////////////////////////////////////////
#include "cgdoom.h"
#include "doomdef.h"
/* Keyboard matrix codes */
#define KEYCODE_F1 0x91
#define KEYCODE_F2 0x92
#define KEYCODE_F3 0x93
#define KEYCODE_F4 0x94
#define KEYCODE_F5 0x95
#define KEYCODE_F6 0x96
#define KEYCODE_SHIFT 0x81
#define KEYCODE_OPTN 0x82
#define KEYCODE_VARS 0x83
#define KEYCODE_MENU 0x84
#define KEYCODE_LEFT 0x85
#define KEYCODE_UP 0x86
#define KEYCODE_ALPHA 0x71
#define KEYCODE_SQUARE 0x72
#define KEYCODE_POWER 0x73
#define KEYCODE_EXIT 0x74
#define KEYCODE_DOWN 0x75
#define KEYCODE_RIGHT 0x76
#define KEYCODE_XOT 0x61
#define KEYCODE_LOG 0x62
#define KEYCODE_LN 0x63
#define KEYCODE_SIN 0x64
#define KEYCODE_COS 0x65
#define KEYCODE_TAN 0x66
#define KEYCODE_FRAC 0x51
#define KEYCODE_FD 0x52
#define KEYCODE_LEFTP 0x53
#define KEYCODE_RIGHTP 0x54
#define KEYCODE_COMMA 0x55
#define KEYCODE_ARROW 0x56
#define KEYCODE_7 0x41
#define KEYCODE_8 0x42
#define KEYCODE_9 0x43
#define KEYCODE_DEL 0x44
#define KEYCODE_4 0x31
#define KEYCODE_5 0x32
#define KEYCODE_6 0x33
#define KEYCODE_MUL 0x34
#define KEYCODE_DIV 0x35
#define KEYCODE_1 0x21
#define KEYCODE_2 0x22
#define KEYCODE_3 0x23
#define KEYCODE_PLUS 0x24
#define KEYCODE_MINUS 0x25
#define KEYCODE_0 0x11
#define KEYCODE_DOT 0x12
#define KEYCODE_EXP 0x13
#define KEYCODE_NEG 0x14
#define KEYCODE_EXE 0x15
#define KEYCODE_ACON 0x07
/* Copy of the keyboard state, one byte per row */
typedef uint8_t KeyboardState[12] __attribute__((aligned(2)));
/* Current keyboard state. */
static KeyboardState st_prev={0}, st_now={0};
static void ScanKeyboard(KeyboardState state)
{
volatile uint16_t *KEYSC = (void *)0xa44b0000;
uint16_t *array = (void *)state;
for(int i = 0; i < 6; i++) array[i] = KEYSC[i];
}
static int DoomKeyToKeycode(int key)
{
switch(key)
{
/* Normal Doom keys */
case KEY_LEFTARROW: return KEYCODE_LEFT;
case KEY_RIGHTARROW: return KEYCODE_RIGHT;
case KEY_UPARROW: return KEYCODE_UP;
case KEY_DOWNARROW: return KEYCODE_DOWN;
case ' ': return KEYCODE_SQUARE;
case KEY_RCTRL: return KEYCODE_ALPHA;
case '1': return KEYCODE_F1;
case '2': return KEYCODE_F2;
case '3': return KEYCODE_F3;
case '4': return KEYCODE_F4;
case '5': return KEYCODE_F5;
case '6': return KEYCODE_F6;
case '7': return KEYCODE_SHIFT;
case KEY_TAB: return KEYCODE_EXIT;
case KEY_PAUSE: return KEYCODE_OPTN;
case KEY_SLEFTARROW: return KEYCODE_0;
case KEY_SRIGHTARROW: return KEYCODE_DOT;
case KEY_ESCAPE: return KEYCODE_MENU;
case KEY_ENTER: return KEYCODE_EXE;
/* Special CGDoom keys */
case SKEY_CHEAT: return KEYCODE_POWER;
case SKEY_DECVP: return KEYCODE_MINUS;
case SKEY_INCVP: return KEYCODE_PLUS;
case SKEY_NOCLIP: return KEYCODE_ARROW;
case SKEY_GAMMA: return KEYCODE_FRAC;
case SKEY_FREEMEM: return KEYCODE_FD;
case SKEY_FPSCOUNTER: return KEYCODE_LEFTP;
case SKEY_FRAMESKIP: return KEYCODE_VARS;
default: return -1;
}
}
static int KeyDown(KeyboardState state, int key)
{
int code = DoomKeyToKeycode(key);
if(code < 0) return 0;
int row = (code >> 4) ^ 1;
int col = 0x80 >> (code & 0x7);
return (state[row] & col) != 0;
}
void UpdateKeyboardState(void)
{
memcpy(st_prev, st_now, sizeof st_now);
ScanKeyboard(st_now);
}
int KeyWasJustPressed(int key)
{
return !KeyDown(st_prev, key) && KeyDown(st_now, key);
}
int KeyWasJustReleased(int key)
{
return KeyDown(st_prev, key) && !KeyDown(st_now, key);
}

View File

@ -1,328 +1,122 @@
// nonstandard extension used : nameless struct/union
#pragma warning (disable : 4201)
// unreferenced inline function has been removed
#pragma warning (disable : 4514)
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <windows.h>
#include "cgdoom.h"
#include "platform.h"
#include <tchar.h>
#include <stdarg.h>
#include <SDL2/SDL.h>
#include <stdio.h>
#include <windef.h>
SDL_Window *window = NULL;
SDL_Surface *VRAM_RGB888 = NULL;
// Global Variables:
static TCHAR *szWindowClass = _T("ConsoleW");
static HWND hWnd = NULL;
static HANDLE hThread = NULL;
static HANDLE hThreadKB = NULL;
static HANDLE hKeyLock = NULL;
static int iMainRetVal = -1;
static int ZOOM = 1;
/* Rendering system emulation. */
#define KEY_BUFFER_LENGTH 16
uint16_t _VRAM[WIDTH * HEIGHT];
typedef struct
static void QuitSDL(void)
{
int miKeyBuffer[KEY_BUFFER_LENGTH];
int miKeyUsed;
HANDLE mhEvent;
}GETCH_CONTEXT;
static GETCH_CONTEXT gGetchContext = {0};
static LRESULT CALLBACK MsgHandler(HWND,UINT,WPARAM,LPARAM);
static LRESULT CALLBACK EditBoxMsgHandler(HWND,UINT,WPARAM,LPARAM);
static DWORD __stdcall ThreadProc(void *pContext);
static void ConsoleWrite(IN const char *pszText);
void KeyHandler(int iKey)
{
/*if(iKey == VK_RETURN)
{
iKey = '\n';
}*/
WaitForSingleObject(hKeyLock,INFINITE);
if(gGetchContext.miKeyUsed < KEY_BUFFER_LENGTH)
{
gGetchContext.miKeyBuffer[gGetchContext.miKeyUsed] = iKey;
gGetchContext.miKeyUsed++;
}
SetEvent(gGetchContext.mhEvent);
ReleaseMutex(hKeyLock);
if(window)
SDL_DestroyWindow(window);
if(VRAM_RGB888)
SDL_FreeSurface(VRAM_RGB888);
SDL_Quit();
}
static void InitSDL(void)
{
if(SDL_Init(SDL_INIT_VIDEO) < 0) {
I_Error("InitSDL: %s", SDL_GetError());
return;
}
window = SDL_CreateWindow("CGDoom",
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
WIDTH, HEIGHT, 0);
VRAM_RGB888 = SDL_CreateRGBSurface(0, WIDTH, HEIGHT, 24, 0, 0, 0, 0);
if(!VRAM_RGB888) {
I_Error("InitSDL: Cannot create intermediate surface: %s",
SDL_GetError());
QuitSDL();
return;
}
atexit(QuitSDL);
}
uint16_t *GetVRAMAddress(void)
{
return _VRAM;
}
void Bdisp_PutDisp_DD(void)
{
if(!window)
InitSDL();
if(!window || !VRAM_RGB888)
return;
/* Copy from VRAM to RGB888 and let SDL handle the conversion to the
window's native format */
for(int y = 0; y < HEIGHT; y++)
for(int x = 0; x < WIDTH; x++)
{
int rgb565 = VRAM[WIDTH * y + x];
int r = (rgb565 >> 8) & 0xf8;
int g = (rgb565 >> 3) & 0xfc;
int b = (rgb565 << 3) & 0xf8;
Uint8 *rgb888 = VRAM_RGB888->pixels + y * VRAM_RGB888->pitch + 3 * x;
rgb888[0] = r;
rgb888[1] = g;
rgb888[2] = b;
}
SDL_BlitSurface(VRAM_RGB888, NULL, SDL_GetWindowSurface(window), NULL);
SDL_UpdateWindowSurface(window);
}
int Bdisp_FrameAndColor(int p1, int p2)
{
(void)p1;
(void)p2;
return 0;
}
void Bdisp_AllClr_VRAM(void)
{
memset(_VRAM, 0, WIDTH * HEIGHT * 2);
}
/* Keyboard system emulation. */
void GetKey(int *key)
{
SDL_Event e;
int valid=0, sym;
while(!valid)
{
SDL_WaitEvent(&e);
if(e.type != SDL_KEYDOWN) continue;
valid = 1;
switch((sym = e.key.keysym.sym))
{
case SDL_SCANCODE_UP: *key = KEY_CTRL_UP;
case SDL_SCANCODE_RIGHT: *key = KEY_CTRL_RIGHT;
case SDL_SCANCODE_DOWN: *key = KEY_CTRL_DOWN;
case SDL_SCANCODE_LEFT: *key = KEY_CTRL_LEFT;
case SDL_SCANCODE_RETURN: *key = KEY_CTRL_EXE;
default:
if(sym >= '0' && sym <= '9') *key = sym;
else valid = 0;
}
}
}
/* Main function */
int main(int argc,char *argv[])
{
MSG msg;
{
WNDCLASS wcex = {0};
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = MsgHandler;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = NULL;
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
RegisterClass(&wcex);
}
hKeyLock = CreateMutex(NULL,0,NULL);
gGetchContext.mhEvent = CreateEvent(NULL,1,0,NULL);
hWnd = CreateWindow(szWindowClass, "Display", WS_OVERLAPPED,CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, 0, NULL);
if (!hWnd)
{
return 0;
}
ShowWindow(hWnd, SW_SHOW);
SetWindowPos(hWnd,NULL,0,0,WIDTH*ZOOM+8,HEIGHT*ZOOM+23+4,SWP_NOMOVE|SWP_NOZORDER);
UpdateWindow(hWnd);
while (GetMessage(&msg, hWnd, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
CloseHandle(hKeyLock);
CloseHandle(gGetchContext.mhEvent);
CloseHandle(hThread);
CloseHandle(hThreadKB);
DestroyWindow(hWnd);
return iMainRetVal;
}
unsigned short VRAM1[WIDTH * HEIGHT] = {0};
unsigned short VRAM2[WIDTH * HEIGHT] = {0};
/*#if ((sizeof(void *)) != 4)
#error "only 32 bit platform is supported"
#endif
*/
unsigned int GetVRAMAddress( void )
{
return (int) ((void*)VRAM1);
}
static void Redraw(HWND hWnd)
{
PAINTSTRUCT ps;
HDC hDC;
int a,b,x,y,i=0;
hDC = BeginPaint(hWnd, &ps);
for(y=0;y<HEIGHT;y++)
for(x=0;x<WIDTH;x++)
{
COLORREF c = 0;
BYTE *bc = (BYTE*)&c;
WORD p = VRAM1[i];
bc[0] = ((p >> 11) & 31)<<3;
bc[1] = ((p >> 5) & 63)<<2;
bc[2] = ((p >> 0) & 31)<<3;
for(a=0;a<ZOOM;a++)
{
for(b=0;b<ZOOM;b++)
{
SetPixel(hDC,x*ZOOM+b,y*ZOOM+a,c);
}
}
i++;
}
EndPaint(hWnd, &ps);
}
static void Redraw2(HWND hWnd)
{
PAINTSTRUCT ps;
HDC hDC;
int a,b,x,y,i=0;
hDC = BeginPaint(hWnd, &ps);
for(y=0;y<HEIGHT;y++)
for(x=0;x<WIDTH;x++)
{
COLORREF c = 0;
BYTE *bc = (BYTE*)&c;
WORD p = VRAM1[i];
if(p != VRAM2[i])
{
bc[0] = ((p >> 11) & 31)<<3;
bc[1] = ((p >> 5) & 63)<<2;
bc[2] = ((p >> 0) & 31)<<3;
for(a=0;a<ZOOM;a++)
{
for(b=0;b<ZOOM;b++)
{
SetPixel(hDC,x*ZOOM+b,y*ZOOM+a,c);
}
}
VRAM2[i] = p;
}
i++;
}
EndPaint(hWnd, &ps);
}
DWORD __stdcall KeyboardFunc(void *p);
static int giOptimize = 0;
static int giIsRedraw = 0;
static LRESULT CALLBACK MsgHandler(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_CREATE:
hThread = CreateThread(NULL,0,&ThreadProc,NULL,0,NULL);
hThreadKB = CreateThread(NULL,0,&KeyboardFunc,NULL,0,NULL);
break;
case WM_SIZE:
break;
case WM_CHAR:
//KeyHandler((int)wParam);
break;
case WM_CLOSE:
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_PAINT:
//if(giOptimize)
Redraw2(hWnd);
giIsRedraw = 1;
//else
// Redraw(hWnd);
//giOptimize = 0;
break;
case WM_RBUTTONUP://switch zoom 1x <-> 2x
ZOOM = 3 - ZOOM;
SetWindowPos(hWnd,NULL,0,0,WIDTH*ZOOM+8,HEIGHT*ZOOM+23+4,SWP_NOMOVE|SWP_NOZORDER);
memset(VRAM2,0,sizeof(VRAM2));
InvalidateRect(hWnd,NULL,FALSE);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
//////////////////////////////////////////////////////////////////////////
int Consolekbhit()
{
return WaitForSingleObject(gGetchContext.mhEvent,0) == WAIT_OBJECT_0;
}
int Consolegetch()
{
int iResult;
WaitForSingleObject(gGetchContext.mhEvent,INFINITE);
WaitForSingleObject(hKeyLock,INFINITE);
gGetchContext.miKeyUsed--;
iResult = gGetchContext.miKeyBuffer[gGetchContext.miKeyUsed];
if(gGetchContext.miKeyUsed == 0)
{
ResetEvent(gGetchContext.mhEvent);
}
ReleaseMutex(hKeyLock);
return iResult;
}
static DWORD __stdcall ThreadProc(void *pContext)
{
G3A_main();
PostMessage(hWnd, WM_CLOSE, 0, 0);
return 0;
}
void Bdisp_PutDisp_DD()
{
//Redraw2(hWnd);
giOptimize = 1;
giIsRedraw = 0;
InvalidateRect(hWnd,NULL,FALSE);
while(!giIsRedraw)Sleep(1);
}
extern int iKeyDown;
int PRGM_GetKey()
{
/*if(Consolekbhit())
{
return Consolegetch();
}*/
return iKeyDown;
}
void Bdisp_AllClr_VRAM( void )
{
memset(VRAM1,0,sizeof(VRAM1));
}
HANDLE ghPort = 0;
int Serial_Open( unsigned char *mode )
{
DWORD dwMode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_NOWAIT;
ghPort = CreateFileA(
"\\\\.\\pipe\\seriak", // pipe name \\.\pipe\seriak
GENERIC_READ | // read and write access
GENERIC_WRITE,
0, // no sharing
NULL, // default security attributes
OPEN_EXISTING, // opens existing pipe
FILE_FLAG_WRITE_THROUGH, // default attributes
NULL); // no template file
SetNamedPipeHandleState(
ghPort, // pipe handle
&dwMode, // new pipe mode
NULL, // don't set maximum bytes
NULL); // don't set maximum time
return 0;
}
int Serial_Close( int mode )
{
CloseHandle(ghPort);
return 0;
}
int Serial_DirectTransmitOneByte( unsigned char byte_to_transmit )
{
DWORD dwSent;
WriteFile(ghPort,&byte_to_transmit,sizeof(byte_to_transmit),&dwSent,NULL);
return 0;
}
int Serial_CheckRX()
{
DWORD dwData = 0;
PeekNamedPipe(ghPort,NULL,0,0,&dwData,NULL);
//if(!dwData)Sleep(1);
return (int)dwData;
}
unsigned char Serial_Read()
{
DWORD dwData = 0;
BYTE byData;
ReadFile(ghPort,&byData,1,&dwData,NULL);
return byData;
}
@ -391,55 +185,3 @@ int Bfile_CloseFile_OS( int HANDLE )
fclose((FILE*)HANDLE);
return 0;
}
static unsigned char gcFlashBuffer[FLASH_PAGE_SIZE * FLASH_PAGE_COUNT] = {0};
const unsigned char *gpcFlashBuffer = gcFlashBuffer;
static const char *gpszFlashFileName = "flash.bin";
static void CreateFlash( const unsigned short*filename)
{
int f = Bfile_OpenFile_OS(filename,0);
int iRet;
int iIndex = 0;
for(;;)
{
// iIndex++;
iRet = Bfile_ReadFile_OS(f,gcFlashBuffer + (iIndex * FLASH_PAGE_SIZE), FLASH_PAGE_SIZE,-1);
iIndex++;
if(iRet < FLASH_PAGE_SIZE)
{
break;
}
}
Bfile_CloseFile_OS(f);
{
FILE *f = fopen(gpszFlashFileName,"wb");
fwrite(gcFlashBuffer,1,sizeof(gcFlashBuffer),f);
fclose(f);
}
}
void InitFlashSimu( const unsigned short*filename)
{
DWORD dwFileSize;
HANDLE hMap;
HANDLE hFile=CreateFileA(gpszFlashFileName,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
if(hFile==INVALID_HANDLE_VALUE)
{
CreateFlash( filename);
hFile=CreateFileA(gpszFlashFileName,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
};
ASSERT(hFile!=INVALID_HANDLE_VALUE);
// create anonymous file mapping
hMap=CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,0,NULL);
ASSERT(hMap!=NULL);
dwFileSize=GetFileSize(hFile,NULL); // get file size
// map buffer to local process space
gpcFlashBuffer =(unsigned char *)MapViewOfFile(hMap,FILE_MAP_READ,0,0,dwFileSize);
ASSERT(gpcFlashBuffer!=NULL);
}

77
src-sdl2/keyboard.c Normal file
View File

@ -0,0 +1,77 @@
#include <SDL2/SDL.h>
#include <stdlib.h>
#include "cgdoom.h"
#include "doomdef.h"
/* Copy of the keyboard state. */
static Uint8 *st_prev=NULL, *st_now=NULL;
static Uint8 *ScanKeyboard(void)
{
int length;
const Uint8 *state = SDL_GetKeyboardState(&length);
return memcpy(malloc(length), state, length);
}
static int DoomKeyToKeycode(int key)
{
switch(key)
{
/* Normal Doom keys */
case KEY_LEFTARROW: return SDL_SCANCODE_LEFT;
case KEY_RIGHTARROW: return SDL_SCANCODE_RIGHT;
case KEY_UPARROW: return SDL_SCANCODE_UP;
case KEY_DOWNARROW: return SDL_SCANCODE_DOWN;
/* case ' ': return KEYCODE_SQUARE;
case KEY_RCTRL: return KEYCODE_ALPHA;
case '1': return KEYCODE_F1;
case '2': return KEYCODE_F2;
case '3': return KEYCODE_F3;
case '4': return KEYCODE_F4;
case '5': return KEYCODE_F5;
case '6': return KEYCODE_F6;
case '7': return KEYCODE_SHIFT;
case KEY_TAB: return KEYCODE_EXIT;
case KEY_PAUSE: return KEYCODE_OPTN;
case KEY_SLEFTARROW: return KEYCODE_0;
case KEY_SRIGHTARROW: return KEYCODE_DOT;
case KEY_ESCAPE: return KEYCODE_MENU;
case KEY_ENTER: return KEYCODE_EXE; */
/* Special CGDoom keys */
/* case SKEY_CHEAT: return KEYCODE_POWER;
case SKEY_DECVP: return KEYCODE_MINUS;
case SKEY_INCVP: return KEYCODE_PLUS;
case SKEY_NOCLIP: return KEYCODE_ARROW;
case SKEY_GAMMA: return KEYCODE_FRAC;
case SKEY_FREEMEM: return KEYCODE_FD;
case SKEY_FPSCOUNTER: return KEYCODE_LEFTP;
case SKEY_FRAMESKIP: return KEYCODE_VARS; */
default: return -1;
}
}
static int KeyDown(Uint8 *state, int key)
{
int code = DoomKeyToKeycode(key);
return (code < 0 || state == NULL) ? 0 : state[code];
}
void UpdateKeyboardState(void)
{
free(st_prev);
st_prev = st_now;
st_now = ScanKeyboard();
}
int KeyWasJustPressed(int key)
{
return !KeyDown(st_prev, key) && KeyDown(st_now, key);
}
int KeyWasJustReleased(int key)
{
return KeyDown(st_prev, key) && !KeyDown(st_now, key);
}

View File

@ -10,19 +10,17 @@
/* Rendering system emulation. */
// Emulated fx-CG function
void Bdisp_PutDisp_DD(void);
void Bdisp_AllClr_VRAM(void);
uint16_t *GetVRAMAddress(void);
// Additional SDL-related calls
void EmuInitGraphics(void);
void EmuShutdownGraphics(void);
void EmuUpdateWindow(void);
int Bdisp_FrameAndColor(int, int);
#define EnableColor(...)
#define EnableStatusArea(...)
/* Input system emulation. */
// TODO
void GetKey(int *key);
//~