From 980aea8c363b73162e6b04014d3b1bc22ec7851a Mon Sep 17 00:00:00 2001 From: ozkl Date: Sun, 23 Apr 2023 19:48:54 +0300 Subject: [PATCH] emscripten port --- doomgeneric/Makefile.emscripten | 50 ++++++ doomgeneric/doomgeneric_emscripten.c | 220 +++++++++++++++++++++++++++ 2 files changed, 270 insertions(+) create mode 100644 doomgeneric/Makefile.emscripten create mode 100644 doomgeneric/doomgeneric_emscripten.c diff --git a/doomgeneric/Makefile.emscripten b/doomgeneric/Makefile.emscripten new file mode 100644 index 0000000..786a85a --- /dev/null +++ b/doomgeneric/Makefile.emscripten @@ -0,0 +1,50 @@ + +ifeq ($(V),1) + VB='' +else + VB=@ +endif + + +SDL_CFLAGS = `sdl2-config --cflags` +SDL_LIBS = `sdl2-config --cflags --libs` -lSDL2_mixer + + +CC=emcc +CFLAGS+=-DFEATURE_SOUND -s SDL2_MIXER_FORMATS='["mid"]' $(SDL_CFLAGS) +LDFLAGS+=--preload-file doom1.wad #--preload-file timidity.cfg --preload-file dgguspat +LIBS+=-lm -lc $(SDL_LIBS) + +# subdirectory for objects +OBJDIR=build +OUTPUT=doomgeneric + +SRC_DOOM = dummy.o am_map.o doomdef.o doomstat.o dstrings.o d_event.o d_items.o d_iwad.o d_loop.o d_main.o d_mode.o d_net.o f_finale.o f_wipe.o g_game.o hu_lib.o hu_stuff.o info.o i_cdmus.o i_endoom.o i_joystick.o i_scale.o i_sound.o i_system.o i_timer.o memio.o m_argv.o m_bbox.o m_cheat.o m_config.o m_controls.o m_fixed.o m_menu.o m_misc.o m_random.o p_ceilng.o p_doors.o p_enemy.o p_floor.o p_inter.o p_lights.o p_map.o p_maputl.o p_mobj.o p_plats.o p_pspr.o p_saveg.o p_setup.o p_sight.o p_spec.o p_switch.o p_telept.o p_tick.o p_user.o r_bsp.o r_data.o r_draw.o r_main.o r_plane.o r_segs.o r_sky.o r_things.o sha1.o sounds.o statdump.o st_lib.o st_stuff.o s_sound.o tables.o v_video.o wi_stuff.o w_checksum.o w_file.o w_main.o w_wad.o z_zone.o w_file_stdc.o i_input.o i_video.o doomgeneric.o doomgeneric_emscripten.o mus2mid.o i_sdlmusic.o i_sdlsound.o +OBJS += $(addprefix $(OBJDIR)/, $(SRC_DOOM)) + +all: $(OUTPUT) + +clean: + rm -rf $(OBJDIR) + rm -f $(OUTPUT).html + rm -f $(OUTPUT).js + rm -f $(OUTPUT).data + rm -f $(OUTPUT).wasm + +$(OUTPUT): $(OBJS) + @echo [Linking $@] + $(VB)$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) \ + -o $(OUTPUT).html $(LIBS) + +$(OBJS): | $(OBJDIR) + +$(OBJDIR): + mkdir -p $(OBJDIR) + +$(OBJDIR)/%.o: %.c + @echo [Compiling $<] + $(VB)$(CC) $(CFLAGS) -c $< -o $@ + +print: + @echo OBJS: $(OBJS) + diff --git a/doomgeneric/doomgeneric_emscripten.c b/doomgeneric/doomgeneric_emscripten.c new file mode 100644 index 0000000..7076dd2 --- /dev/null +++ b/doomgeneric/doomgeneric_emscripten.c @@ -0,0 +1,220 @@ +//doomgeneric emscripten port + +#include "doomkeys.h" +#include "m_argv.h" +#include "doomgeneric.h" + +#include +#include + +#include +#include + +#include + +SDL_Window* window = NULL; +SDL_Renderer* renderer = NULL; +SDL_Texture* texture; + +#define KEYQUEUE_SIZE 16 + +static unsigned short s_KeyQueue[KEYQUEUE_SIZE]; +static unsigned int s_KeyQueueWriteIndex = 0; +static unsigned int s_KeyQueueReadIndex = 0; + +static unsigned char convertToDoomKey(unsigned int key) +{ + switch (key) + { + case SDLK_RETURN: + key = KEY_ENTER; + break; + case SDLK_ESCAPE: + key = KEY_ESCAPE; + break; + case SDLK_LEFT: + key = KEY_LEFTARROW; + break; + case SDLK_RIGHT: + key = KEY_RIGHTARROW; + break; + case SDLK_UP: + key = KEY_UPARROW; + break; + case SDLK_DOWN: + key = KEY_DOWNARROW; + break; + case SDLK_LCTRL: + case SDLK_RCTRL: + key = KEY_FIRE; + break; + case SDLK_SPACE: + key = KEY_USE; + break; + case SDLK_LSHIFT: + case SDLK_RSHIFT: + key = KEY_RSHIFT; + break; + case SDLK_LALT: + case SDLK_RALT: + key = KEY_LALT; + break; + case SDLK_F2: + key = KEY_F2; + break; + case SDLK_F3: + key = KEY_F3; + break; + case SDLK_F4: + key = KEY_F4; + break; + case SDLK_F5: + key = KEY_F5; + break; + case SDLK_F6: + key = KEY_F6; + break; + case SDLK_F7: + key = KEY_F7; + break; + case SDLK_F8: + key = KEY_F8; + break; + case SDLK_F9: + key = KEY_F9; + break; + case SDLK_F10: + key = KEY_F10; + break; + case SDLK_F11: + key = KEY_F11; + break; + case SDLK_EQUALS: + case SDLK_PLUS: + key = KEY_EQUALS; + break; + case SDLK_MINUS: + key = KEY_MINUS; + break; + default: + key = tolower(key); + break; + } + + return key; +} + +static void addKeyToQueue(int pressed, unsigned int keyCode) +{ + unsigned char key = convertToDoomKey(keyCode); + + unsigned short keyData = (pressed << 8) | key; + + s_KeyQueue[s_KeyQueueWriteIndex] = keyData; + s_KeyQueueWriteIndex++; + s_KeyQueueWriteIndex %= KEYQUEUE_SIZE; +} + +static void handleKeyInput() +{ + SDL_Event e; + while (SDL_PollEvent(&e)) + { + if (e.type == SDL_QUIT) + { + puts("Quit requested"); + atexit(SDL_Quit); + exit(1); + } + + if (e.type == SDL_KEYDOWN) + { + addKeyToQueue(1, e.key.keysym.sym); + } + else if (e.type == SDL_KEYUP) + { + addKeyToQueue(0, e.key.keysym.sym); + } + } +} + + +void DG_Init() +{ + window = SDL_CreateWindow("DOOM", + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + DOOMGENERIC_RESX, + DOOMGENERIC_RESY, + SDL_WINDOW_SHOWN + ); + + // Setup renderer + renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); + // Clear winow + SDL_RenderClear( renderer ); + // Render the rect to the screen + SDL_RenderPresent(renderer); + + texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_TARGET, DOOMGENERIC_RESX, DOOMGENERIC_RESY); +} + +void DG_DrawFrame() +{ + SDL_UpdateTexture(texture, NULL, DG_ScreenBuffer, DOOMGENERIC_RESX*sizeof(uint32_t)); + + SDL_RenderClear(renderer); + SDL_RenderCopy(renderer, texture, NULL, NULL); + SDL_RenderPresent(renderer); + + handleKeyInput(); +} + +void DG_SleepMs(uint32_t ms) +{ + SDL_Delay(ms); +} + +uint32_t DG_GetTicksMs() +{ + return SDL_GetTicks(); +} + +int DG_GetKey(int* pressed, unsigned char* doomKey) +{ + if (s_KeyQueueReadIndex == s_KeyQueueWriteIndex) + { + //key queue is empty + return 0; + } + else + { + unsigned short keyData = s_KeyQueue[s_KeyQueueReadIndex]; + s_KeyQueueReadIndex++; + s_KeyQueueReadIndex %= KEYQUEUE_SIZE; + + *pressed = keyData >> 8; + *doomKey = keyData & 0xFF; + + return 1; + } + + return 0; +} + +void DG_SetWindowTitle(const char * title) +{ + if (window != NULL) + { + SDL_SetWindowTitle(window, title); + } +} + +int main(int argc, char **argv) +{ + doomgeneric_Create(argc, argv); + + emscripten_set_main_loop(doomgeneric_Tick, 0, 1); + + return 0; +} \ No newline at end of file