ref: c68d3e221d9b372e250fcec40e01c6e5176abe8b
parent: 2bf42bfc7ce8fae05401547e03cda1a181f89a95
author: Jacob Moody <moody@posixcafe.org>
date: Mon Aug 4 06:43:28 EDT 2025
make nanobsp work with npe
--- a/include/npe/SDL2/SDL.h
+++ b/include/npe/SDL2/SDL.h
@@ -31,14 +31,48 @@
typedef int SDL_RendererFlip;
typedef struct SDL_DisplayMode SDL_DisplayMode;
typedef int SDL_SystemCursor;
-typedef union SDL_Color SDL_Color;
+typedef struct SDL_Color SDL_Color;
typedef struct SDL_Palette SDL_Palette;
typedef struct SDL_RendererInfo SDL_RendererInfo;
typedef struct SDL_mutex SDL_mutex;
+struct SDL_Rect {+ int x, y, w, h;
+};
+
+struct SDL_Color {+ Uint8 r;
+ Uint8 g;
+ Uint8 b;
+ Uint8 a;
+};
+
+struct SDL_Palette {+ int ncolors;
+ SDL_Color *colors;
+};
+
+struct SDL_PixelFormat {+ SDL_Palette *palette;
+ int format;
+ int BytesPerPixel;
+};
+
+struct SDL_Surface {+ SDL_PixelFormat *format;
+ SDL_Rect clip_rect;
+ Uint32 flags;
+ Uint32 key;
+ int keyset;
+ int w, h;
+ int pitch;
+ int n;
+ void *i;
+ uchar *pixels;
+};
+
#pragma incomplete SDL_Cursor
#pragma incomplete SDL_Renderer
-#pragma incomplete SDL_Surface
#pragma incomplete SDL_Texture
#pragma incomplete SDL_Window
@@ -116,6 +150,9 @@
void SDL_RenderGetScale(SDL_Renderer *renderer, float *scaleX, float *scaleY);
void SDL_GetWindowSize(SDL_Window *window, int *w, int *h);
void SDL_GetWindowPosition(SDL_Window *window, int *x, int *y);
+void SDL_SetWindowMinimumSize(SDL_Window *window, int min_w, int min_h);
+Uint32 SDL_GetWindowPixelFormat(SDL_Window *window);
+SDL_bool SDL_PixelFormatEnumToMasks(Uint32 format, int *bpp, Uint32 *Rmask, Uint32 *Gmask, Uint32 *Bmask, Uint32 *Amask);
Uint32 SDL_GetMouseState(int *x, int *y);
SDL_bool SDL_IsTextInputActive(void);
void SDL_StartTextInput(void);
@@ -135,6 +172,7 @@
void SDL_DestroyRenderer(SDL_Renderer *renderer);
void SDL_DestroyWindow(SDL_Window *window);
int SDL_GetDisplayUsableBounds(int displayIndex, SDL_Rect *rect);
+int SDL_GetDisplayBounds(int displayIndex, SDL_Rect *rect);
int SDL_GetDesktopDisplayMode(int displayIndex, SDL_DisplayMode *mode);
void SDL_SetWindowTitle(SDL_Window *window, char *title);
int SDL_SetTextureBlendMode(SDL_Texture *texture, SDL_BlendMode blendMode);
@@ -148,6 +186,7 @@
void SDL_EnableScreenSaver(void);
Uint32 SDL_GetTicks(void);
int SDL_GetRendererOutputSize(SDL_Renderer *renderer, int *w, int *h);
+int SDL_GetRendererInfo(SDL_Renderer *renderer, SDL_RendererInfo *info);
void SDL_RenderGetViewport(SDL_Renderer *rebderer, SDL_Rect *rect);
int SDL_SaveBMP(SDL_Surface *s, const char *file);
void SDL_ClearError(void);
@@ -164,6 +203,7 @@
void SDL_ShowWindow(SDL_Window *w);
int SDL_RenderSetIntegerScale(SDL_Renderer *r, SDL_bool enable);
int SDL_GetNumVideoDisplays(void);
+int SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture);
void SDL_SetModState(SDL_Keymod modstate);
SDL_mutex* SDL_CreateMutex(void);
void SDL_DestroyMutex(SDL_mutex*);
@@ -176,10 +216,14 @@
int SDL_SetPaletteColors(SDL_Palette *palette, const SDL_Color *colors, int firstcolor, int ncolors);
int SDL_SetSurfacePalette(SDL_Surface *s, SDL_Palette *palette);
int SDL_BlitSurface(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect);
+int SDL_LowerBlit(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect);
int SDL_SoftStretch(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, const SDL_Rect *dstrect);
int SDL_LockTexture(SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch);
int SDL_UnlockTexture(SDL_Texture *texture);
int SDL_GetWindowBordersSize(SDL_Window *window, int *top, int *left, int *bot, int *right);
+
+#define SDL_min(x, y) (((x) < (y)) ? (x) : (y))
+#define SDL_max(x, y) (((x) > (y)) ? (x) : (y))
enum {SDL_QUERY = -1,
@@ -231,6 +275,7 @@
SDL_TEXTUREACCESS_TARGET = 0,
SDL_RENDERER_ACCELERATED = 0,
SDL_RENDERER_PRESENTVSYNC = 0,
+ SDL_RENDERER_TARGETTEXTURE = 0x8,
SDL_INIT_NOPARACHUTE = 0,
SDL_RENDERER_SOFTWARE = 0,
SDL_SWSURFACE = 0,
@@ -278,45 +323,11 @@
int x, y;
};
-struct SDL_Rect {- int x, y, w, h;
-};
-
-struct SDL_Surface {- SDL_PixelFormat *format;
- SDL_Rect clip_rect;
- Uint32 flags;
- Uint32 key;
- int keyset;
- int w, h;
- int pitch;
- int n;
- void *i;
- uchar *pixels;
-};
-
struct SDL_DisplayMode {int format;
int w;
int h;
int refresh_rate;
-};
-
-union SDL_Color {- struct {- Uint8 r, g, b, a;
- };
-};
-
-struct SDL_Palette {- int ncolors;
- SDL_Color *colors;
-};
-
-struct SDL_PixelFormat {- SDL_Palette *palette;
- int format;
- int BytesPerPixel;
};
struct SDL_RendererInfo {--- a/include/npe/SDL2/SDL_audio.h
+++ b/include/npe/SDL2/SDL_audio.h
@@ -52,4 +52,20 @@
void SDL_PauseAudioDevice(SDL_AudioDeviceID, SDL_bool);
void SDL_CloseAudioDevice(SDL_AudioDeviceID);
+void SDL_PauseAudio(int pause_on);
+
+typedef Uint16 SDL_AudioFormat;
+typedef struct SDL_AudioCVT SDL_AudioCVT;
+struct SDL_AudioCVT
+{+ SDL_AudioFormat src_format;
+ SDL_AudioFormat dst_format;
+ Uint8 *buf;
+ int len;
+ int len_mult;
+};
+
+int SDL_BuildAudioCVT(SDL_AudioCVT *cvt, SDL_AudioFormat src_format, Uint8 src_channels, int src_rate, SDL_AudioFormat dst_format, Uint8 dst_channels, int dst_rate);
+int SDL_ConvertAudio(SDL_AudioCVT *cvt);
+
#endif
--- a/include/npe/SDL2/SDL_events.h
+++ b/include/npe/SDL2/SDL_events.h
@@ -2,6 +2,7 @@
#define _npe_SDL_events_h_
enum {+ SDL_FIRSTEVENT,
SDL_KEYDOWN,
SDL_KEYUP,
SDL_JOYAXISMOTION,
@@ -31,6 +32,7 @@
SDL_WINDOWEVENT_CLOSE,
SDL_JOYBALLMOTION,
SDL_JOYHATMOTION,
+ SDL_LASTEVENT,
SDL_PRESSED = SDL_KEYDOWN,
SDL_RELEASED = SDL_KEYUP,
--- a/include/npe/SDL2/SDL_mixer.h
+++ b/include/npe/SDL2/SDL_mixer.h
@@ -20,6 +20,7 @@
typedef void (*Mix_EffectFunc_t)(int chan, void *stream, int len, void *udata);
typedef void (*Mix_EffectDone_t)(int chan, void *udata);
+typedef void (*Mix_MixCallback)(void *udata, Uint8 *stream, int len);
int Mix_OpenAudio(int,Uint16,int,int);
char* Mix_GetError(void);
@@ -41,6 +42,11 @@
int Mix_PlayMusic(Mix_Music *music, int loops);
Mix_Music* Mix_LoadMUS_RW(SDL_RWops *src, int freesrc);
Mix_Music* Mix_LoadMUS(char *filename);
+int Mix_SetPanning(int channel, Uint8 left, Uint8 right);
+int Mix_Playing(int channel);
+int Mix_QuerySpec(int *frequency, Uint16 *format, int *channels);
+int Mix_AllocateChannels(int numchans);
+void Mix_HookMusic(Mix_MixCallback mix_func, void *arg);
enum {MIX_INIT_MID = 1,
@@ -48,6 +54,7 @@
MIX_DEFAULT_FORMAT = 1,
SDL_MIX_MAXVOLUME = 100,
+ MIX_MAX_VOLUME = SDL_MIX_MAXVOLUME,
};
#endif
--- a/include/npe/SDL2/SDL_version.h
+++ b/include/npe/SDL2/SDL_version.h
@@ -9,4 +9,7 @@
void SDL_GetVersion(SDL_version *v);
+#define SDL_VERSIONNUM(X, Y, Z) ((X)*1000 + (Y)*100 + (Z))
+#define SDL_COMPILEDVERSION SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL)
+
#endif
--- a/include/npe/errno.h
+++ b/include/npe/errno.h
@@ -6,6 +6,7 @@
enum {ENOENT = 2,
EACCES = 13,
+ EISDIR = 14,
EINVAL = 22,
ERANGE = 34,
ENAMETOOLONG = 36,
--- a/libnpe_sdl2/audio.c
+++ b/libnpe_sdl2/audio.c
@@ -122,6 +122,12 @@
}
}
+void
+SDL_PauseAudio(int pause_on)
+{+ SDL_PauseAudioDevice(1, pause_on);
+}
+
static int
convspec(SDL_AudioSpec *s, char *spec, int n)
{@@ -142,6 +148,24 @@
ssz = fmts[s->format].ssz;
return ssz;
+}
+
+// https://wiki.libsdl.org/SDL2/SDL_ConvertAudio
+int
+SDL_ConvertAudio(SDL_AudioCVT *cvt)
+{+ USED(cvt);
+ return 0;
+}
+
+// https://wiki.libsdl.org/SDL2/SDL_BuildAudioCVT
+int
+SDL_BuildAudioCVT(SDL_AudioCVT *cvt, SDL_AudioFormat src_format, Uint8 src_channels, int src_rate, SDL_AudioFormat dst_format, Uint8 dst_channels, int dst_rate)
+{+ USED(cvt);
+ USED(src_format, src_channels, src_rate);
+ USED(dst_format, dst_channels, dst_rate);
+ return 0;
}
static void
--- a/libnpe_sdl2/mixer.c
+++ b/libnpe_sdl2/mixer.c
@@ -244,3 +244,46 @@
SDL_RWclose(src);
return m;
}
+
+// https://wiki.libsdl.org/SDL2_mixer/Mix_AllocateChannels
+int
+Mix_AllocateChannels(int numchans)
+{+ USED(numchans);
+ return 0;
+}
+
+// https://wiki.libsdl.org/SDL2_mixer/Mix_SetPanning
+int
+Mix_SetPanning(int channel, Uint8 left, Uint8 right)
+{+ USED(channel, left, right);
+ return 0;
+}
+
+// https://wiki.libsdl.org/SDL2_mixer/Mix_HookMusic
+void
+Mix_HookMusic(Mix_MixCallback mix_func, void *arg)
+{+ USED(mix_func, arg);
+}
+
+int
+Mix_QuerySpec(int *frequency, Uint16 *format, int *channels)
+{+ if(frequency != nil)
+ *frequency = 44100;
+ if(format != nil)
+ *format = AUDIO_S16LSB;
+ if(channels != nil)
+ *channels = 2;
+ return 0;
+}
+
+// https://wiki.libsdl.org/SDL2_mixer/Mix_Playing
+int
+Mix_Playing(int channel)
+{+ USED(channel);
+ return 0;
+}
--- a/libnpe_sdl2/sdl2.c
+++ b/libnpe_sdl2/sdl2.c
@@ -23,6 +23,7 @@
static SDL_Window onewin;
static SDL_Renderer oneren;
+static SDL_Texture backtex, *target = &backtex;
static Memimage *back;
static u8int *backcopy;
static Image *front;
@@ -80,31 +81,54 @@
}
static int
-chan2mask(Uint32 chan, Uint32 *rm, Uint32 *gm, Uint32 *bm, Uint32 *am)
+chan2mask(Uint32 chan, int *bpp, Uint32 *rm, Uint32 *gm, Uint32 *bm, Uint32 *am)
{ switch(chan){case ARGB32:
*am = 0xFF000000;
- if(0){+ *rm = 0x00FF0000;
+ *gm = 0x0000FF00;
+ *bm = 0x000000FF;
+ *bpp = 32;
+ break;
case XRGB32:
*am = 0x00000000;
- }
- case RGB24:
*rm = 0x00FF0000;
*gm = 0x0000FF00;
*bm = 0x000000FF;
+ *bpp = 32;
break;
case ABGR32:
*am = 0xFF000000;
- if(0){+ *rm = 0x000000FF;
+ *gm = 0x0000FF00;
+ *bm = 0x00FF0000;
+ *bpp = 32;
case XBGR32:
*am = 0x00000000;
- }
- case BGR24:
+ *rm = 0x000000FF;
+ *gm = 0x0000FF00;
*bm = 0x00FF0000;
+ *bpp = 32;
+ break;
+ case RGB24:
+ *am = 0x00000000;
+ *rm = 0x00FF0000;
*gm = 0x0000FF00;
+ *bm = 0x000000FF;
+ *bpp = 24;
+ break;
+ case BGR24:
+ *am = 0x00000000;
*rm = 0x000000FF;
+ *gm = 0x0000FF00;
+ *bm = 0x00FF0000;
+ *bpp = 24;
break;
+ case CMAP8:
+ *am = *rm = *gm = *bm = 0x00000000;
+ *bpp = 8;
+ break;
default:
assert(0);
}
@@ -190,6 +214,8 @@
int
SDL_Init(int mask)
{+ int bpp;
+
/* FIXME actually use the mask? */
USED(mask);
@@ -198,6 +224,8 @@
if(mask == 0)
return 0;
+ if(screen != nil)
+ return 0;
if(memimageinit() < 0)
goto err;
@@ -208,7 +236,7 @@
npe_sdl.scale = 1;
physw = Dx(screen->r);
physh = Dy(screen->r);
- if(chan2mask(screen->chan, &defmask.r, &defmask.g, &defmask.b, &defmask.a) < 0){+ if(chan2mask(screen->chan, &bpp, &defmask.r, &defmask.g, &defmask.b, &defmask.a) < 0){ werrstr("SDL_Init: unsupported screen channel");return -1;
}
@@ -527,9 +555,10 @@
}
SDL_Surface *
-SDL_CreateRGBSurfaceWithFormat(Uint32 flags, int w, int h, int bpp, Uint32 fmt)
+SDL_CreateRGBSurfaceWithFormat(Uint32 flags, int w, int h, int fbpp, Uint32 fmt)
{SDL_Surface *s;
+ int bpp;
ulong chan;
Uint32 rm, gm, bm, am;
@@ -537,7 +566,9 @@
werrstr("SDL_CreateRGBSurfaceWithFormat: FIXME format %8ux not implemented", fmt);return nil;
}
- chan2mask(chan, &rm, &gm, &bm, &am);
+ chan2mask(chan, &bpp, &rm, &gm, &bm, &am);
+ if(bpp != fbpp && fbpp != 0)
+ sysfatal("FIXME SDL_CreateRGBSurfaceWithFormat passes wrong bpp for format: %d not %d", fbpp, bpp);if((s = SDL_CreateRGBSurface(flags, w, h, bpp, rm, bm, gm, am)) == nil)
return nil;
return s;
@@ -665,7 +696,27 @@
return 0;
}
+// https://wiki.libsdl.org/SDL2/SDL_LowerBlit
int
+SDL_LowerBlit(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect)
+{+ return SDL_BlitSurface(src, srcrect, dst, dstrect);
+}
+
+// https://wiki.libsdl.org/SDL2/SDL_SetRenderTarget
+int
+SDL_SetRenderTarget(SDL_Renderer *, SDL_Texture *texture)
+{+ if(texture == nil)
+ target = &backtex;
+ else
+ target = texture;
+ back = target->m;
+ npe_sdl.fullredraw = 1;
+ return 0;
+}
+
+int
SDL_SoftStretch(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, const SDL_Rect *dstrect)
{Rectangle r, r2;
@@ -777,6 +828,18 @@
}
}
+SDL_bool
+SDL_PixelFormatEnumToMasks(Uint32 format, int *bpp, Uint32 *Rmask, Uint32 *Gmask, Uint32 *Bmask, Uint32 *Amask)
+{+ ulong c;
+
+ if(bpp == nil || Rmask == nil || Gmask == nil || Bmask == nil || Amask == nil)
+ return SDL_FALSE;
+ c = pixel2chan(format);
+ chan2mask(c, bpp, Rmask, Gmask, Bmask, Amask);
+ return SDL_TRUE;
+}
+
Uint32
SDL_MapRGB(SDL_PixelFormat *fmt, Uint8 r, Uint8 g, Uint8 b)
{@@ -861,6 +924,14 @@
return nil;
}
+Uint32
+SDL_GetWindowPixelFormat(SDL_Window *)
+{+ if(screen != nil)
+ return chan2pixel(screen->chan);
+ return 0;
+}
+
SDL_Cursor *
SDL_GetDefaultCursor(void)
{@@ -1046,6 +1117,7 @@
werrstr("SDL_RenderCopy: %r");return -1;
}
+ target->m = back;
free(backcopy);
backcopy = malloc(logiw*logih*4);
}
@@ -1066,6 +1138,11 @@
uchar *rb;
int logiw, logih;
+ /* may be called before SDL_RenderCopy is ever called;
+ * nanobsp does this during initialization */
+ if(back == nil)
+ return;
+
if(rend->logiw > 0 && rend->logih > 0){logiw = rend->logiw;
logih = rend->logih;
@@ -1243,6 +1320,12 @@
}
}
+void
+SDL_SetWindowMinimumSize(SDL_Window *window, int min_w, int min_h)
+{+ SDL_SetWindowSize(window, min_w, min_h);
+}
+
int
SDL_ShowSimpleMessageBox(Uint32, char *title, char *message, SDL_Window *)
{@@ -1301,6 +1384,12 @@
}
int
+SDL_GetDisplayBounds(int displayIndex, SDL_Rect *r)
+{+ return SDL_GetDisplayUsableBounds(displayIndex, r);
+}
+
+int
SDL_GetDesktopDisplayMode(int displayIndex, SDL_DisplayMode *mode)
{if(displayIndex != 0)
@@ -1340,6 +1429,8 @@
{int f;
+ if(title == nil)
+ return;
if((f = open("/dev/label", OWRITE|OTRUNC|OCEXEC)) >= 0 || (f = open("/mnt/term/dev/label", OWRITE|OTRUNC|OCEXEC)) >= 0){write(f, title, strlen(title));
close(f);
@@ -1425,6 +1516,16 @@
return -1;
}
+ return 0;
+}
+
+int
+SDL_GetRendererInfo(SDL_Renderer *, SDL_RendererInfo *info)
+{+ if(info == nil)
+ return -1;
+ info->max_texture_width = physw;
+ info->max_texture_height = physh;
return 0;
}
--
⑨