From 5c603e0069a09b80bf58b5269cf2bbc6be152222 Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Sat, 6 Nov 2021 13:19:22 +0300 Subject: [PATCH] system: add stub system driver --- src/CMakeLists.txt | 10 +- src/stubsys/files.c | 202 +++++++++++++++++++++++++++++ src/stubsys/main.c | 308 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 519 insertions(+), 1 deletion(-) create mode 100644 src/stubsys/files.c create mode 100644 src/stubsys/main.c diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 096663a..aa05b29 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -13,6 +13,7 @@ string(TOUPPER "${SYSTEM_DRIVER}" SYSTEM_DRIVER) string(COMPARE EQUAL "${SYSTEM_DRIVER}" "SDL" WITH_SDL) string(COMPARE EQUAL "${SYSTEM_DRIVER}" "SDL2" WITH_SDL2) string(COMPARE EQUAL "${SYSTEM_DRIVER}" "KOS32" WITH_KOS32) +string(COMPARE EQUAL "${SYSTEM_DRIVER}" "STUB" WITH_STUBSYS) string(TOUPPER "${RENDER_DRIVER}" RENDER_DRIVER) string(COMPARE EQUAL "${RENDER_DRIVER}" "OPENGL" WITH_OPENGL) string(COMPARE EQUAL "${RENDER_DRIVER}" "SOFTWARE" WITH_SOFTWARE) @@ -26,6 +27,7 @@ set(D2D_GAME_ROOT .) set(D2D_SDL_ROOT ${D2D_GAME_ROOT}/sdl) set(D2D_SDL2_ROOT ${D2D_GAME_ROOT}/sdl2) set(D2D_KOS32_ROOT ${D2D_GAME_ROOT}/kos32) +set(D2D_STUBSYS_ROOT ${D2D_GAME_ROOT}/stubsys) set(D2D_OPENGL_ROOT ${D2D_GAME_ROOT}/gl) set(D2D_SOFTWARE_ROOT ${D2D_GAME_ROOT}/soft) set(D2D_STUBRENDER_ROOT ${D2D_GAME_ROOT}/stubren) @@ -39,6 +41,7 @@ aux_source_directory(${D2D_GAME_ROOT} D2D_GAME_SRC) aux_source_directory(${D2D_SDL_ROOT} D2D_SDL_SRC) aux_source_directory(${D2D_SDL2_ROOT} D2D_SDL2_SRC) aux_source_directory(${D2D_KOS32_ROOT} D2D_KOS32_SRC) +aux_source_directory(${D2D_STUBSYS_ROOT} D2D_STUBSYS_SRC) aux_source_directory(${D2D_OPENGL_ROOT} D2D_OPENGL_SRC) aux_source_directory(${D2D_SOFTWARE_ROOT} D2D_SOFTWARE_SRC) aux_source_directory(${D2D_STUBRENDER_ROOT} D2D_STUBRENDER_SRC) @@ -86,8 +89,13 @@ elseif(WITH_KOS32) set(D2D_SYSTEM_INCLUDE_DIR "") set(D2D_SYSTEM_LIBRARY "-lck") set(D2D_SYSTEM_LINKFLAGS "") +elseif(WITH_STUBSYS) + set(D2D_SYSTEM_SRC "${D2D_STUBSYS_SRC}") + set(D2D_SYSTEM_INCLUDE_DIR "") + set(D2D_SYSTEM_LIBRARY "") + set(D2D_SYSTEM_LINKFLAGS "") else() - message(FATAL_ERROR "Select SYSTEM_DRIVER as 'SDL' or 'SDL2' or 'KOS32'") + message(FATAL_ERROR "Select SYSTEM_DRIVER as 'SDL' or 'SDL2' or 'KOS32' or 'STUB'") endif() if(WITH_STUBRENDER) diff --git a/src/stubsys/files.c b/src/stubsys/files.c new file mode 100644 index 0000000..7ccfe4e --- /dev/null +++ b/src/stubsys/files.c @@ -0,0 +1,202 @@ +/* Copyright (C) 1996-1997 Aleksey Volynskov + * Copyright (C) 2011 Rambo + * Copyright (C) 2020 SovietPony + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3 of the License ONLY. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "glob.h" +#include +#include +#include +#include +#include "files.h" +#include "error.h" + +#include "map.h" // MAP_load +#include "save.h" // SAVE_getname + +#ifdef UNIX +# include +#endif + +#include "common/streams.h" +#include "common/files.h" +#include "common/wadres.h" +#include "common/cp866.h" + +int d_start, d_end; + +char savname[SAVE_MAX][SAVE_MAXLEN]; +char savok[SAVE_MAX]; + +static int m_start, m_end; +static int s_start, s_end; + +void F_addwad (const char *fn) { + static int i = 0; + static FILE_Stream wadh[MAX_WADS]; + if (i < MAX_WADS) { + if (FILE_Open(&wadh[i], fn, "rb")) { + if (WADRES_addwad(&wadh[i].base)) { + i += 1; + } else { + ERR_failinit("Invalid WAD %s", fn); + } + } else { + ERR_failinit("Unable to add WAD %s", fn); + } + } else { + ERR_failinit("Too many wads"); + } +} + +void F_initwads (void) { + if (!WADRES_rehash()) { + ERR_failinit("F_initwads: failed rehash"); + } + d_start = F_getresid("D_START"); + d_end = F_getresid("D_END"); + m_start = F_getresid("M_START"); + m_end = F_getresid("M_END"); + s_start = F_getresid("S_START"); + s_end = F_getresid("S_END"); +} + +int F_findres (const char n[8]) { + return WADRES_find(n); +} + +int F_getresid (const char n[8]) { + int i = F_findres(n); + if (i == -1) { + ERR_fatal("F_getresid: resource %.8s not found", n); + } + return i; +} + +void F_getresname (char n[8], int r) { + WADRES_getname(r, n); +} + +int F_getsprid (const char n[4], int s, int d, char *dir) { + int i = WADRES_findsprite(n, s, d, dir); + if (i == -1) { + ERR_fatal("F_getsprid: image %.4s%c%c not found", n, s, d); + } + return i; +} + +int F_getreslen (int r) { + return WADRES_getsize(r); +} + +/* +void F_nextmus (char *s) { + int i = F_findres(s); + if (i <= m_start || i >= m_end) { + i = m_start; + } + for (++i; ; ++i) { + if (i >= m_end) { + i = m_start + 1; + } + WADRES_getname(i, s); + if (cp866_strcasecmp(s, "MENU") == 0 || + cp866_strcasecmp(s, "INTERMUS") == 0 || + cp866_strcasecmp(s, "\x8a\x8e\x8d\x85\x96\x0") == 0) { + continue; + } + if (cp866_strncasecmp(s, "DMI", 3) != 0) { + break; + } + } +} + +void F_randmus (char *s) { + int i; + int n = myrand(10); + for (i = 0; i < n; i++) { + F_nextmus(s); + } +} +*/ + +void F_loadmap (char n[8]) { + int id = F_getresid(n); + if (id != -1) { + Stream *r = WADRES_getbasereader(id); + long offset = WADRES_getoffset(id); + stream_setpos(r, offset); + if (!MAP_load(r)) { + ERR_fatal("Failed to load map"); + } + } else { + ERR_fatal("Failed to load map: resource %.8s not found", n); + } +} + +static char *getsavfpname (int n, int ro) { + static char fn[] = "savgame0.dat"; + static char p[100]; + fn[7] = n + '0'; +#ifdef UNIX + char *e = getenv("HOME"); + strncpy(p, e, 60); + strcat(p, "/.flatwaifu"); + if (!ro) { + mkdir(p, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); + } + strcat(p, "/"); + strcat(p, fn); +#else + strcpy(p, fn); +#endif + return p; +} + +void F_getsavnames (void) { + int i; + FILE_Stream rd; + for (i = 0; i < SAVE_MAX; ++i) { + savok[i] = 0; + char *p = getsavfpname(i, 1); + if (FILE_Open(&rd, p, "rb")) { + savok[i] = SAVE_getname(&rd.base, savname[i]); + FILE_Close(&rd); + } + if (!savok[i]) { + memset(savname[i], 0, 24); + } else { + savname[i][23] = 0; + } + } +} + +void F_loadgame (int n) { + FILE_Stream rd; + char *p = getsavfpname(n, 1); + if (FILE_Open(&rd, p, "rb")) { + SAVE_load(&rd.base); + FILE_Close(&rd); + } +} + +void F_savegame (int n, char *s) { + FILE_Stream wr; + char *p = getsavfpname(n, 0); + if (FILE_Open(&wr, p, "wb")) { + SAVE_save(&wr.base, s); + FILE_Close(&wr); + } +} diff --git a/src/stubsys/main.c b/src/stubsys/main.c new file mode 100644 index 0000000..75ddd86 --- /dev/null +++ b/src/stubsys/main.c @@ -0,0 +1,308 @@ +/* Copyright (C) 2020 SovietPony + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3 of the License ONLY. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifdef __EMSCRIPTEN__ +# include +#endif + +#include +#include +#include // srand exit +#include +#include +#include "system.h" +#include "input.h" + +#include "player.h" // pl1 pl2 +#include "menu.h" // G_keyf +#include "error.h" // logo +#include "monster.h" // nomon + +#include "files.h" // F_startup F_addwad F_initwads F_allocres +#include "config.h" // CFG_args CFG_load CFG_save +#include "args.h" // ARG_parse +#include "memory.h" // M_startup +#include "game.h" // G_init G_act +#include "sound.h" // S_init S_done +#include "music.h" // S_initmusic S_updatemusic S_donemusic +#include "render.h" // R_init R_draw R_done + +#define MODE_NONE 0 +#define MODE_OPENGL 1 +#define MODE_SOFTWARE 2 + +static clock_t ticks; +static int quit = 0; +static int mode = MODE_NONE; +static int text_input = 0; +static int width = 0; +static int height = 0; +static int fullscreen = 0; +static void *softbuffer = NULL; +static videomode_size_t vsize = { 320, 200, 0 }; +static videomode_t vlist = { 1, &vsize }; + +static const cfg_t arg[] = { + {"file", NULL, Y_FILES}, + {"cheat", &cheat, Y_SW_ON}, +// {"vga", &shot_vga, Y_SW_ON}, +// {"musvol", &mus_vol, Y_WORD}, + {"mon", &nomon, Y_SW_OFF}, + {"warp", &_warp, Y_BYTE}, +// {"config", NULL, cfg_file, Y_STRING}, + {NULL, NULL, 0} // end +}; + +static const cfg_t cfg[] = { +// {"screenshot", &shot_vga, Y_SW_ON}, +// {"music_volume", &mus_vol, Y_WORD}, +// {"music_random", &music_random, Y_SW_ON}, +// {"music_time", &music_time, Y_DWORD}, +// {"music_fade", &music_fade, Y_DWORD}, + {"pl1_left", &pl1.kl, Y_KEY}, + {"pl1_right",&pl1.kr, Y_KEY}, + {"pl1_up", &pl1.ku, Y_KEY}, + {"pl1_down", &pl1.kd, Y_KEY}, + {"pl1_jump", &pl1.kj, Y_KEY}, + {"pl1_fire", &pl1.kf, Y_KEY}, + {"pl1_next", &pl1.kwr, Y_KEY}, + {"pl1_prev", &pl1.kwl, Y_KEY}, + {"pl1_use", &pl1.kp, Y_KEY}, + {"pl2_left", &pl2.kl, Y_KEY}, + {"pl2_right", &pl2.kr, Y_KEY}, + {"pl2_up", &pl2.ku, Y_KEY}, + {"pl2_down", &pl2.kd, Y_KEY}, + {"pl2_jump", &pl2.kj, Y_KEY}, + {"pl2_fire", &pl2.kf, Y_KEY}, + {"pl2_next", &pl2.kwr, Y_KEY}, + {"pl2_prev", &pl2.kwl, Y_KEY}, + {"pl2_use", &pl2.kp, Y_KEY}, + {NULL, NULL, 0} // end +}; + +static void CFG_args (int argc, char **argv) { + const cfg_t *list[] = { arg, R_args(), S_args(), MUS_args() }; + ARG_parse(argc, argv, 4, list); +} + +static void CFG_load (void) { + const cfg_t *list[] = { cfg, R_conf(), S_conf(), MUS_conf() }; + CFG_read_config("default.cfg", 4, list); + CFG_read_config("doom2d.cfg", 4, list); +} + +static void CFG_save (void) { + const cfg_t *list[] = { cfg, R_conf(), S_conf(), MUS_conf() }; + CFG_update_config("doom2d.cfg", "doom2d.cfg", 4, list, "generated by doom2d, do not modify"); +} + +/* --- error.h --- */ + +void logo (const char *s, ...) { + va_list ap; + va_start(ap, s); + vprintf(s, ap); + va_end(ap); + fflush(stdout); +} + +void logo_gas (int cur, int all) { + // stub +} + +void ERR_failinit (char *s, ...) { + va_list ap; + va_start(ap, s); + vprintf(s, ap); + va_end(ap); + puts(""); + abort(); +} + +void ERR_fatal (char *s, ...) { + va_list ap; + R_done(); + MUS_done(); + S_done(); + puts("\nCRITICAL ERROR:"); + va_start(ap, s); + vprintf(s, ap); + va_end(ap); + puts(""); + abort(); +} + +void ERR_quit (void) { + quit = 1; +} + +/* --- system.h --- */ + +int Y_set_videomode_opengl (int w, int h, int fullscreen) { + assert(w > 0); + assert(h > 0); + mode = MODE_OPENGL; + width = w; + height = h; + return 1; +} + +int Y_set_videomode_software (int w, int h, int fullscreen) { + assert(w > 0); + assert(h > 0); + void *buf = softbuffer ? realloc(softbuffer, w * h) : malloc(w * h); + if (buf) { + mode = MODE_SOFTWARE; + softbuffer = buf; + width = w; + height = h; + } + return buf != NULL; +} + +const videomode_t *Y_get_videomode_list_opengl (int fullscreen) { + return &vlist; +} + +const videomode_t *Y_get_videomode_list_software (int fullscreen) { + return &vlist; +} + +void Y_get_videomode (int *w, int *h) { + if (mode != MODE_NONE) { + *w = width; + *h = height; + } else { + *w = 0; + *h = 0; + } +} + +int Y_videomode_setted (void) { + return mode != MODE_NONE; +} + +void Y_unset_videomode (void) { + mode = MODE_NONE; + free(softbuffer); + softbuffer = NULL; +} + +void Y_set_fullscreen (int yes) { + fullscreen = yes; +} + +int Y_get_fullscreen (void) { + return (mode != MODE_NONE) && fullscreen; +} + +void Y_swap_buffers (void) { + assert(mode == MODE_OPENGL); +} + +void Y_get_buffer (byte **buf, int *w, int *h, int *pitch) { + assert(mode == MODE_SOFTWARE); + // *buf = surf->pixels; + *buf = NULL; // fix this + *w = width; + *h = height; + *pitch = width; +} + +void Y_set_vga_palette (byte *vgapal) { + int i; + byte *p = vgapal; + assert(vgapal != NULL); + assert(mode == MODE_SOFTWARE); +} + +void Y_repaint_rect (int x, int y, int w, int h) { + assert(mode == MODE_SOFTWARE); +} + +void Y_repaint (void) { + assert(mode == MODE_SOFTWARE); +} + +void Y_enable_text_input (void) { + text_input = 1; +} + +void Y_disable_text_input (void) { + text_input = 0; +} + +/* --- main --- */ + +static void poll_events (void) { + // stub +} + +static void step (void) { + poll_events(); + MUS_update(); + clock_t t = clock(); + if ((t - ticks) * 1000 / CLOCKS_PER_SEC > DELAY) { + ticks = t; + G_act(); + } + R_draw(); +} + +int main (int argc, char *argv[]) { + logo("main: initialize\n"); + // Player 1 defaults + pl1.ku = KEY_KP_8; + pl1.kd = KEY_KP_5; + pl1.kl = KEY_KP_4; + pl1.kr = KEY_KP_6; + pl1.kf = KEY_PAGEDOWN; + pl1.kj = KEY_DELETE; + pl1.kwl = KEY_HOME; + pl1.kwr = KEY_END; + pl1.kp = KEY_KP_8; + // Player 2 defaults + pl2.ku = KEY_E; + pl2.kd = KEY_D; + pl2.kl = KEY_S; + pl2.kr = KEY_F; + pl2.kf = KEY_A; + pl2.kj = KEY_Q; + pl2.kwl = KEY_1; + pl2.kwr = KEY_2; + pl2.kp = KEY_E; + //srand(SDL_GetTicks()); + F_addwad("doom2d.wad"); + CFG_args(argc, argv); + CFG_load(); + F_initwads(); + S_init(); + MUS_init(); + R_init(); + G_init(); + ticks = clock(); +#ifdef __EMSCRIPTEN__ + emscripten_set_main_loop(step, 0, 1); +#else + while (!quit) { + step(); + } +#endif + CFG_save(); + R_done(); + MUS_done(); + S_done(); + return 0; +} -- 2.29.2