/* * sdl12shim.c - see sdl12shim.h. * * Written for fredygames.com to build Berusky for the browser with Emscripten's SDL2 port. * Copyright (C) 2026 FredyGames. Same license as Berusky: GNU GPL version 2 or later. */ #include "sdl12shim.h" #ifdef __EMSCRIPTEN__ #include #endif static SDL_Window *window = NULL; static Uint32 window_id = 0; static SDL_Renderer *renderer = NULL; static SDL_Texture *texture = NULL; static SDL_Surface *screen = NULL; static int key_repeat = 0; /* SDL 1.2 only repeats keys when the game asks for it. */ static int SDLCALL filter_events(void *userdata, SDL_Event *ev) { (void)userdata; if(ev->type == SDL_KEYDOWN && ev->key.repeat && !key_repeat) return 0; return 1; } SDL_Surface *SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags) { (void)bpp; (void)flags; /* The game quits and restarts the video subsystem before each mode change, which takes the * window and everything on it along. */ if(window && SDL_GetWindowFromID(window_id) != window) { window = NULL; renderer = NULL; texture = NULL; } if(texture) SDL_DestroyTexture(texture); texture = NULL; /* The game frees the old screen surface itself (it owns the pointer it was given). */ screen = NULL; if(!window) { window = SDL_CreateWindow("Berusky", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, 0); if(!window) return NULL; window_id = SDL_GetWindowID(window); renderer = SDL_CreateRenderer(window, -1, 0); if(!renderer) return NULL; SDL_SetEventFilter(filter_events, NULL); } else SDL_SetWindowSize(window, width, height); SDL_RenderSetLogicalSize(renderer, width, height); texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_STREAMING, width, height); screen = SDL_CreateRGBSurfaceWithFormat(0, width, height, 32, SDL_PIXELFORMAT_RGB888); if(!texture || !screen) return NULL; return screen; } static void present(void) { if(!screen || !texture) return; SDL_UpdateTexture(texture, NULL, screen->pixels, screen->pitch); SDL_RenderClear(renderer); SDL_RenderCopy(renderer, texture, NULL, NULL); SDL_RenderPresent(renderer); } void SDL_UpdateRects(SDL_Surface *s, int numrects, SDL_Rect *rects) { (void)s; (void)numrects; (void)rects; present(); } void SDL_UpdateRect(SDL_Surface *s, Sint32 x, Sint32 y, Uint32 w, Uint32 h) { (void)s; (void)x; (void)y; (void)w; (void)h; present(); } /* Full screen is the player's button on the page; the game's menu option does nothing here. */ int SDL_WM_ToggleFullScreen(SDL_Surface *surface) { (void)surface; return 0; } /* The page keeps its own title. */ void SDL_WM_SetCaption(const char *title, const char *icon) { (void)title; (void)icon; } int SDL_EnableKeyRepeat(int delay, int interval) { (void)interval; key_repeat = delay > 0; return 0; } int SDL_SetAlpha(SDL_Surface *surface, Uint32 flags, Uint8 alpha) { if(flags & SDL_SRCALPHA) { SDL_SetSurfaceAlphaMod(surface, alpha); return SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_BLEND); } SDL_SetSurfaceAlphaMod(surface, 255); return SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_NONE); } /* SDL 1.2's DisplayFormat converted to the screen format and dropped any alpha channel. */ SDL_Surface *SDL_DisplayFormat(SDL_Surface *surface) { SDL_Surface *s = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_RGB888, 0); if(s) SDL_SetSurfaceBlendMode(s, SDL_BLENDMODE_NONE); return s; }