diff --git a/CGDoom.g3a b/CGDoom.g3a index 2bb0f34..fe6c29e 100644 Binary files a/CGDoom.g3a and b/CGDoom.g3a differ diff --git a/Makefile b/Makefile index 693a882..d8a7a88 100644 --- a/Makefile +++ b/Makefile @@ -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 $@ diff --git a/cgdoom/cgdoom.c b/cgdoom/cgdoom.c index 8b76a7c..bef6e47 100644 --- a/cgdoom/cgdoom.c +++ b/cgdoom/cgdoom.c @@ -1,6 +1,7 @@ #include "platform.h" #include "os.h" #include "cgdoom.h" +#include #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; } diff --git a/cgdoom/cgdoom.h b/cgdoom/cgdoom.h index c9f92ba..c0f267a 100644 --- a/cgdoom/cgdoom.h +++ b/cgdoom/cgdoom.h @@ -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 */ diff --git a/cgdoom/d_main.c b/cgdoom/d_main.c index 6fa725e..37348a0 100644 --- a/cgdoom/d_main.c +++ b/cgdoom/d_main.c @@ -31,6 +31,7 @@ #include "os.h" #include "cgdoom-alloc.h" +#include #include "doomdef.h" #include "doomstat.h" diff --git a/cgdoom/g_game.c b/cgdoom/g_game.c index ac229fb..b1b854b 100644 --- a/cgdoom/g_game.c +++ b/cgdoom/g_game.c @@ -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<buttons = (byte)(BT_SPECIAL | BTS_SAVEGAME | (savegameslot< #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); } diff --git a/cgdoom/i_system.h b/cgdoom/i_system.h index 234471f..37d539d 100644 --- a/cgdoom/i_system.h +++ b/cgdoom/i_system.h @@ -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 */ diff --git a/cgdoom/i_video.c b/cgdoom/i_video.c index c36b377..3e621b7 100644 --- a/cgdoom/i_video.c +++ b/cgdoom/i_video.c @@ -93,32 +93,7 @@ void I_SetPalette(int gamma_correction) } } -#if defined(CG_EMULATOR) - -void I_Flip (void) -{ - int x,y; - for(y=0;yheight); + x = (short)(160 - M_StringWidth(string)/2); + M_WriteText(x,y,string); + y = y + SHORT(hu_font[0]->height); } return; } diff --git a/src-cg/keyboard.c b/src-cg/keyboard.c new file mode 100644 index 0000000..740a032 --- /dev/null +++ b/src-cg/keyboard.c @@ -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); +} diff --git a/src-sdl2/emul.c b/src-sdl2/emul.c index a4bd879..3b995ec 100644 --- a/src-sdl2/emul.c +++ b/src-sdl2/emul.c @@ -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 +#include "cgdoom.h" #include "platform.h" -#include -#include +#include #include -#include +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> 11) & 31)<<3; - bc[1] = ((p >> 5) & 63)<<2; - bc[2] = ((p >> 0) & 31)<<3; - for(a=0;a> 11) & 31)<<3; - bc[1] = ((p >> 5) & 63)<<2; - bc[2] = ((p >> 0) & 31)<<3; - for(a=0;a 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); -} diff --git a/src-sdl2/keyboard.c b/src-sdl2/keyboard.c new file mode 100644 index 0000000..e2f2a8b --- /dev/null +++ b/src-sdl2/keyboard.c @@ -0,0 +1,77 @@ +#include +#include + +#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); +} diff --git a/src-sdl2/platform.h b/src-sdl2/platform.h index 60125aa..d6f2810 100644 --- a/src-sdl2/platform.h +++ b/src-sdl2/platform.h @@ -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); //~