diff --git a/src/compat/SDL/SDL_endian.h b/src/compat/SDL/SDL_endian.h new file mode 100644 index 0000000..931b7f0 --- /dev/null +++ b/src/compat/SDL/SDL_endian.h @@ -0,0 +1,3 @@ +/* SDL/SDL_endian.h for the fredygames.com browser build of Hex-a-hop: the SDL 2 header, same API. + * Copyright (C) 2026 FredyGames. GNU GPL version 2 or later, like Hex-a-hop. */ +#include diff --git a/src/gfx.cpp b/src/gfx.cpp index 811a0e9..ef31fae 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -404,21 +404,6 @@ int main(int /*argc*/, char * /*argv*/[]) }*/ #endif - case SDL_ACTIVEEVENT: - { - int gain = e.active.gain ? e.active.state : 0; - int loss = e.active.gain ? 0 : e.active.state; - SDL_focus = (SDL_focus | gain) & ~loss; - if (gain & SDL_APPACTIVE) - StateMakerBase::current->ScreenModeChanged(); - if (loss & SDL_APPMOUSEFOCUS) - noMouse = 1; - else if (gain & SDL_APPMOUSEFOCUS) - noMouse = 0; - - break; - } - case SDL_MOUSEMOTION: noMouse = false; StateMakerBase::current->Mouse(e.motion.x, e.motion.y, e.motion.x-mousex, e.motion.y-mousey, 0, 0, mouse_buttons); diff --git a/src/hhsdl12.c b/src/hhsdl12.c new file mode 100644 index 0000000..75c9e37 --- /dev/null +++ b/src/hhsdl12.c @@ -0,0 +1,136 @@ +/* + * hhsdl12.c: see hhsdl12.h. The game draws on a surface of its own and copies it to the surface of + * SDL_SetVideoMode (here a 32-bit surface in memory); each SDL_Flip uploads that one to a streaming texture + * and shows it. + * Copyright (C) 2026 FredyGames. Distributed under the GNU GPL version 2 or later, like the game. + */ + + +#undef SDL_SetColorKey +#undef SDL_PollEvent +#undef SDL_Delay + +static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; +static SDL_Texture *texture = NULL; +static SDL_Surface *screen = NULL; + +SDL_Surface *hh_SetVideoMode(int width, int height, int bpp, Uint32 flags) +{ + (void)bpp; (void)flags; + if (window == NULL) { + window = SDL_CreateWindow("Hex-a-hop", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, 0); + if (window == NULL) + return NULL; + renderer = SDL_CreateRenderer(window, -1, 0); + if (renderer == NULL) + return NULL; + texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_STREAMING, width, height); + screen = SDL_CreateRGBSurfaceWithFormat(0, width, height, 32, SDL_PIXELFORMAT_RGB888); + } + /* Calls after the first (the game asks again when the full screen mode is toggled) return the same surface. */ + return screen; +} + +int hh_Flip(SDL_Surface *surface) +{ + if (surface != screen || texture == NULL) + return -1; + SDL_UpdateTexture(texture, NULL, screen->pixels, screen->pitch); + SDL_RenderClear(renderer); + SDL_RenderCopy(renderer, texture, NULL, NULL); + SDL_RenderPresent(renderer); + return 0; +} + +/* Converts to the format of the screen; the color key (if any) goes along. */ +SDL_Surface *hh_DisplayFormat(SDL_Surface *surface) +{ + return SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_RGB888, 0); +} + +int hh_SetColorKey(SDL_Surface *surface, Uint32 flags, Uint32 key) +{ + return SDL_SetColorKey(surface, (flags & SDL_SRCCOLORKEY) ? SDL_TRUE : SDL_FALSE, key); +} + +/* SDL 2 key code -> SDL 1.2 key symbol (0 when there is none). The SDL 2 codes of keys that are not + characters are the scancode with bit 30 set. */ +static int key12(Sint32 k) +{ + if (k >= 0 && k < 128) + return k; + if (k & 0x40000000) { + int sc = k & 0xFFFF; + if (sc >= 58 && sc <= 69) /* F1-F12 */ + return 282 + (sc - 58); + if (sc >= 104 && sc <= 106) /* F13-F15 */ + return 294 + (sc - 104); + if (sc >= 89 && sc <= 97) /* keypad 1-9 */ + return 257 + (sc - 89); + switch (sc) { + case 98: return 256; /* keypad 0 */ + case 99: return 266; /* keypad period */ + case 84: return 267; /* keypad divide */ + case 85: return 268; /* keypad multiply */ + case 86: return 269; /* keypad minus */ + case 87: return 270; /* keypad plus */ + case 88: return 271; /* keypad enter */ + case 103: return 272; /* keypad equals */ + case 82: return 273; /* up */ + case 81: return 274; /* down */ + case 79: return 275; /* right */ + case 80: return 276; /* left */ + case 73: return 277; /* insert */ + case 74: return 278; /* home */ + case 77: return 279; /* end */ + case 75: return 280; /* page up */ + case 78: return 281; /* page down */ + case 83: return 300; /* num lock */ + case 57: return 301; /* caps lock */ + case 71: return 302; /* scroll lock */ + case 229: return 303; /* right shift */ + case 225: return 304; /* left shift */ + case 228: return 305; /* right ctrl */ + case 224: return 306; /* left ctrl */ + case 230: return 307; /* right alt */ + case 226: return 308; /* left alt */ + case 231: return 312; /* right super */ + case 227: return 311; /* left super */ + case 72: return 19; /* pause */ + } + } + return 0; +} + +/* SDL 1.2 had no key repeat unless asked for; SDL 2 always has it. Repeats are dropped here, and the key + symbols of the events are the SDL 1.2 ones. */ +int hh_PollEvent(SDL_Event *event) +{ + while (SDL_PollEvent(event)) { + if (event->type == SDL_KEYDOWN || event->type == SDL_KEYUP) { + if (event->type == SDL_KEYDOWN && event->key.repeat) + continue; + event->key.keysym.sym = key12(event->key.keysym.sym); + } + return 1; + } + return 0; +} + +void hh_WM_SetCaption(const char *title, const char *icon) +{ + (void)icon; + if (window != NULL && title != NULL) + SDL_SetWindowTitle(window, title); +} + +void hh_WM_SetIcon(SDL_Surface *icon, Uint8 *mask) +{ + (void)icon; (void)mask; +} + +void hh_WarpMouse(Uint16 x, Uint16 y) +{ + (void)x; (void)y; +} diff --git a/src/hhsdl12.h b/src/hhsdl12.h new file mode 100644 index 0000000..c0f1725 --- /dev/null +++ b/src/hhsdl12.h @@ -0,0 +1,100 @@ +/* + * hhsdl12.h: the part of the SDL 1.2 API that Hex-a-hop uses, on top of SDL 2, for the fredygames.com + * browser build (Emscripten). Included before every source file (-include). Written for that build. + * Copyright (C) 2026 FredyGames. Distributed under the GNU GPL version 2 or later, like the game. + */ +#ifndef HHSDL12_H +#define HHSDL12_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int SDLKey; + +#define SDL_SWSURFACE 0x00000000 +#define SDL_DOUBLEBUF 0x40000000 +#define SDL_FULLSCREEN 0x80000000 +#define SDL_SRCCOLORKEY 0x00001000 +/* The game keeps its own focus flags (SDL 1.2 sent them in an activity event that SDL 2 does not have). */ +#define SDL_APPMOUSEFOCUS 0x01 +#define SDL_APPINPUTFOCUS 0x02 +#define SDL_APPACTIVE 0x04 +#define SDL_VIDEOEXPOSE 0x7ffd +#define SDLK_LAST 323 + +SDL_Surface *hh_SetVideoMode(int width, int height, int bpp, Uint32 flags); +int hh_Flip(SDL_Surface *screen); +SDL_Surface *hh_DisplayFormat(SDL_Surface *surface); +int hh_SetColorKey(SDL_Surface *surface, Uint32 flags, Uint32 key); +int hh_PollEvent(SDL_Event *event); +void hh_WM_SetCaption(const char *title, const char *icon); +void hh_WM_SetIcon(SDL_Surface *icon, Uint8 *mask); +void hh_WarpMouse(Uint16 x, Uint16 y); + +#ifdef __cplusplus +} +#endif + +#define SDL_SetVideoMode hh_SetVideoMode +#define SDL_Flip hh_Flip +#define SDL_DisplayFormat hh_DisplayFormat +#define SDL_SetColorKey hh_SetColorKey +#define SDL_PollEvent hh_PollEvent +#define SDL_WM_SetCaption hh_WM_SetCaption +#define SDL_WM_SetIcon hh_WM_SetIcon +#define SDL_WarpMouse hh_WarpMouse +/* The loops wait for the next frame with SDL_Delay: here that hands the page back to the browser (Asyncify). */ +#undef SDL_Delay +#define SDL_Delay(ms) emscripten_sleep(ms) + +/* The game indexes an array with SDL 1.2 key symbols: the key names have the SDL 1.2 values, and + hh_PollEvent converts the SDL 2 key codes of each event to them. */ +#undef SDLK_BACKSPACE +#define SDLK_BACKSPACE 8 +#undef SDLK_PAUSE +#define SDLK_PAUSE 19 +#undef SDLK_ESCAPE +#define SDLK_ESCAPE 27 +#undef SDLK_DELETE +#define SDLK_DELETE 127 +#undef SDLK_UP +#define SDLK_UP 273 +#undef SDLK_DOWN +#define SDLK_DOWN 274 +#undef SDLK_RIGHT +#define SDLK_RIGHT 275 +#undef SDLK_LEFT +#define SDLK_LEFT 276 +#undef SDLK_F1 +#define SDLK_F1 282 +#undef SDLK_F2 +#define SDLK_F2 283 +#undef SDLK_F4 +#define SDLK_F4 285 +#undef SDLK_F12 +#define SDLK_F12 293 +#define SDLK_KP1 257 +#define SDLK_KP2 258 +#define SDLK_KP3 259 +#define SDLK_KP4 260 +#define SDLK_KP5 261 +#define SDLK_KP6 262 +#define SDLK_KP7 263 +#define SDLK_KP8 264 +#define SDLK_KP9 265 +#undef SDLK_KP_PERIOD +#define SDLK_KP_PERIOD 266 +#undef SDLK_KP_ENTER +#define SDLK_KP_ENTER 271 +#undef SDLK_LSHIFT +#define SDLK_LSHIFT 304 +#undef SDLK_LCTRL +#define SDLK_LCTRL 306 +#undef SDLK_LALT +#define SDLK_LALT 308 + +#endif