ref: 3ad15c411ee11022d633b655f7b42066a52eb60e
parent: 2b10549c4fcfed1d97488ba633f045ae6da393e3
parent: 5c0d011f240bb77c9889c3d92548a6f799cf0fca
author: Jacob Moody <moody@posixcafe.org>
date: Mon Mar 6 00:22:47 EST 2023
merge
--- a/include/npe/SDL2/SDL.h
+++ b/include/npe/SDL2/SDL.h
@@ -33,6 +33,8 @@
typedef int SDL_SystemCursor;
typedef union SDL_Color SDL_Color;
typedef struct SDL_Palette SDL_Palette;
+typedef struct SDL_RendererInfo SDL_RendererInfo;
+typedef struct SDL_mutex SDL_mutex;
#pragma incomplete SDL_Cursor
#pragma incomplete SDL_Renderer
@@ -60,6 +62,12 @@
SDL_bool SDL_HasSSE(void);
SDL_bool SDL_HasSSE2(void);
int SDL_Init(int);
+int SDL_InitSubSystem(int);
+int SDL_QuitSubSystem(int);
+int SDL_SetRelativeMouseMode(SDL_bool enabled);
+int SDL_GetRelativeMouseMode(void);
+void SDL_SetWindowIcon(SDL_Window*,SDL_Surface*);
+void SDL_SetWindowBordered(SDL_Window*,SDL_bool);
SDL_Keymod SDL_GetModState(void);
int SDL_ShowCursor(int toggle);
Uint64 SDL_GetPerformanceFrequency(void);
@@ -135,8 +143,21 @@
char *SDL_GetPrefPath(char *org, char *app);
int SDL_SetRenderDrawColor(SDL_Renderer *r, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
int SDL_GetCurrentDisplayMode(int displayIndex, SDL_DisplayMode *mode);
+int SDL_GetNumDisplayModes(int displayIndex);
void SDL_ShowWindow(SDL_Window *w);
int SDL_RenderSetIntegerScale(SDL_Renderer *r, SDL_bool enable);
+int SDL_GetNumVideoDisplays(void);
+void SDL_SetModState(SDL_Keymod modstate);
+SDL_mutex* SDL_CreateMutex(void);
+void SDL_DestroyMutex(SDL_mutex*);
+int SDL_LockMutex(SDL_mutex*);
+int SDL_UnlockMutex(SDL_mutex*);
+#define SDL_mutexV(x) SDL_UnlockMutex(x)
+#define SDL_mutexP(x) SDL_LockMutex(x)
+int SDL_FillRect(SDL_Surface *dst, const SDL_Rect *rect, Uint32 color);
+int SDL_SetPaletteColors(SDL_Palette *palette, const SDL_Color *colors, int firstcolor, int ncolors);
+int SDL_BlitSurface(SDL_Surface *src, const 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);
enum {
SDL_QUERY = -1,
@@ -156,9 +177,10 @@
SDL_WINDOWPOS_CENTERED = -1,
SDL_WINDOWPOS_UNDEFINED = -2,
- SDL_INIT_AUDIO = 1<<0,
- SDL_INIT_VIDEO = 1<<1,
- SDL_INIT_JOYSTICK = 1<<2,
+ SDL_INIT_TIMER = 1<<0,
+ SDL_INIT_AUDIO = 1<<1,
+ SDL_INIT_VIDEO = 1<<2,
+ SDL_INIT_JOYSTICK = 0,
SDL_BLENDMODE_NONE = 0,
SDL_BLENDMODE_BLEND,
@@ -169,6 +191,7 @@
SDL_PIXELFORMAT_ARGB8888 = 0x30128888,
SDL_PIXELFORMAT_XRGB8888 = 0x16161804,
+ SDL_PIXELFORMAT_INDEX8 = 0x13000801,
SDL_PIXELFORMAT_RGB24 = 0x17101803,
SDL_PIXELFORMAT_RGB888 = SDL_PIXELFORMAT_XRGB8888,
@@ -175,8 +198,12 @@
/* shit no one cares about */
SDL_TEXTUREACCESS_STREAMING = 0,
SDL_TEXTUREACCESS_STATIC = 0,
+ SDL_TEXTUREACCESS_TARGET = 0,
SDL_RENDERER_ACCELERATED = 0,
SDL_RENDERER_PRESENTVSYNC = 0,
+ SDL_INIT_NOPARACHUTE = 0,
+ SDL_RENDERER_SOFTWARE = 0,
+ SDL_SWSURFACE = 0,
/* FIXME steal from rio and add missing? */
SDL_SYSTEM_CURSOR_ARROW = 0,
@@ -201,13 +228,19 @@
SDL_BUTTON_LMASK = 1<<SDL_BUTTON_LEFT,
SDL_BUTTON_MMASK = 1<<SDL_BUTTON_MIDDLE,
SDL_BUTTON_RMASK = 1<<SDL_BUTTON_RIGHT,
+
+ KMOD_NONE = 0,
};
+
#define SDL_BUTTON(x) (1<<(x))
+#define SDL_MUSTLOCK(surface) (SDL_FALSE)
+
#define SDL_HINT_RENDER_SCALE_QUALITY "SDL_HINT_RENDER_SCALE_QUALITY"
#define SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4 "SDL_WINDOWS_NO_CLOSE_ON_ALT_F4"
#define SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH "SDL_MOUSE_FOCUS_CLICKTHROUGH"
+#define SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING "SDL_WINDOWS_DISABLE_THREAD_NAMING"
struct SDL_Point {
int x, y;
@@ -225,7 +258,9 @@
int keyset;
int w, h;
int pitch;
- uchar pixels[];
+ int n;
+ void *i;
+ uchar *pixels;
};
struct SDL_DisplayMode {
@@ -249,6 +284,15 @@
struct SDL_PixelFormat {
SDL_Palette *palette;
int format;
+};
+
+struct SDL_RendererInfo {
+ int max_texture_width;
+ int max_texture_height;
+};
+
+struct SDL_mutex {
+ Lock l;
};
#endif
--- /dev/null
+++ b/include/npe/SDL2/SDL_endian.h
@@ -1,0 +1,60 @@
+#ifndef _npe_SDL_endian_h_
+#define _npe_SDL_endian_h_
+
+#define SDL_LIL_ENDIAN 1234
+#define SDL_BIG_ENDIAN 4321
+
+#if defined(__amd64__) || defined(__386__) || defined(__arm__) || defined(__arm64__) || defined(__spim__)
+#define SDL_BYTEORDER SDL_LIL_ENDIAN
+#elif defined(__mips__) || defined(__power__)
+#define SDL_BYTEORDER SDL_BIG_ENDIAN
+#endif
+
+static u16int
+SDL_Swap16(u16int x)
+{
+ return (x<<8) | (x>>8);
+}
+
+static u32int
+SDL_Swap32(u32int x)
+{
+ return ((x << 24) | ((x << 8) & 0x00FF0000) | ((x >> 8) & 0x0000FF00) | (x >> 24));
+}
+
+static u64int
+SDL_Swap64(u64int x)
+{
+ u32int hi, lo;
+
+ /* Separate into high and low 32-bit values and swap them */
+ lo = x & 0xFFFFFFFF;
+ x >>= 32;
+ hi = x & 0xFFFFFFFF;
+ x = SDL_Swap32(lo);
+ x <<= 32;
+ x |= SDL_Swap32(hi);
+ return (x);
+}
+
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN
+#define SDL_SwapLE16(X) (X)
+#define SDL_SwapLE32(X) (X)
+#define SDL_SwapLE64(X) (X)
+#define SDL_SwapFloatLE(X) (X)
+#define SDL_SwapBE16(X) SDL_Swap16(X)
+#define SDL_SwapBE32(X) SDL_Swap32(X)
+#define SDL_SwapBE64(X) SDL_Swap64(X)
+#define SDL_SwapFloatBE(X) SDL_SwapFloat(X)
+#else
+#define SDL_SwapLE16(X) SDL_Swap16(X)
+#define SDL_SwapLE32(X) SDL_Swap32(X)
+#define SDL_SwapLE64(X) SDL_Swap64(X)
+#define SDL_SwapFloatLE(X) SDL_SwapFloat(X)
+#define SDL_SwapBE16(X) (X)
+#define SDL_SwapBE32(X) (X)
+#define SDL_SwapBE64(X) (X)
+#define SDL_SwapFloatBE(X) (X)
+#endif
+
+#endif
--- a/include/npe/SDL2/SDL_events.h
+++ b/include/npe/SDL2/SDL_events.h
@@ -17,12 +17,23 @@
SDL_WINDOWEVENT,
SDL_WINDOWEVENT_HIDDEN,
SDL_WINDOWEVENT_SHOWN,
- SDL_WINDOWEVENT_MINIMIZED,
SDL_WINDOWEVENT_FOCUS_LOST,
+ SDL_WINDOWEVENT_FOCUS_GAINED,
+ SDL_WINDOWEVENT_MOVED,
SDL_WINDOWEVENT_EXPOSED,
SDL_WINDOWEVENT_SIZE_CHANGED,
SDL_WINDOWEVENT_RESIZED = SDL_WINDOWEVENT_SIZE_CHANGED, /* FIXME I don't even fucking know... */
+ SDL_WINDOWEVENT_MINIMIZED,
+ SDL_WINDOWEVENT_MAXIMIZED,
+ SDL_WINDOWEVENT_RESTORED,
+ SDL_WINDOWEVENT_ENTER,
+ SDL_WINDOWEVENT_LEAVE,
+ SDL_WINDOWEVENT_CLOSE,
+ SDL_JOYBALLMOTION,
+ SDL_PRESSED = SDL_KEYDOWN,
+ SDL_RELEASED = SDL_KEYUP,
+
SDL_TEXTINPUTEVENT_TEXT_SIZE = UTFmax,
SDL_ADDEVENT = 0,
@@ -30,27 +41,61 @@
SDL_GETEVENT,
};
+typedef struct SDL_WindowEvent SDL_WindowEvent;
+typedef struct SDL_MouseWheelEvent SDL_MouseWheelEvent;
+typedef struct SDL_MouseButtonEvent SDL_MouseButtonEvent;
+typedef struct SDL_Keysym SDL_Keysym;
typedef struct SDL_Event SDL_Event;
typedef int SDL_eventaction;
+struct SDL_WindowEvent {
+ Uint32 type;
+ Uint32 timestamp;
+ Uint32 windowID;
+ Uint8 event;
+ Sint32 data1;
+ Sint32 data;
+};
+
+struct SDL_Keysym {
+ SDL_Scancode scancode;
+ SDL_Keycode sym;
+ Uint16 mod;
+};
+
+struct SDL_MouseWheelEvent {
+ Uint32 type;
+ Uint32 timestamp;
+ Uint32 windowID;
+ Uint32 which;
+ Sint32 x;
+ Sint32 y;
+ Uint32 direction;
+};
+
+struct SDL_MouseButtonEvent {
+ Uint32 type;
+ Uint32 timestamp;
+ Uint32 windowID;
+ Uint32 which;
+ Uint8 button;
+ Uint8 state;
+ Uint8 clicks;
+ Sint32 x;
+ Sint32 y;
+};
+
struct SDL_Event {
int type;
+ SDL_WindowEvent window;
struct {
- int event;
- }window;
- struct {
- struct {
- SDL_Scancode scancode;
- SDL_Keycode sym;
- }keysym;
+ SDL_Keysym keysym;
int repeat;
+ int state;
}key;
+ SDL_MouseButtonEvent button;
struct {
- int x, y;
int button;
- }button;
- struct {
- int button;
int state;
}cbutton;
struct {
@@ -61,15 +106,18 @@
int axis;
}jaxis;
struct {
+ int xrel;
+ int yrel;
+ }jball;
+ struct {
int x, y;
+ int xrel, yrel;
}motion;
struct {
char text[SDL_TEXTINPUTEVENT_TEXT_SIZE+1];
}text;
+ SDL_MouseWheelEvent wheel;
struct {
- int x, y;
- }wheel;
- struct {
char *file;
}drop;
};
@@ -80,5 +128,7 @@
int SDL_WaitEvent(SDL_Event *event);
int SDL_RegisterEvents(int);
int SDL_PeepEvents(SDL_Event *events, int numevents, SDL_eventaction action, Uint32 minType, Uint32 maxType);
+Uint32 SDL_GetWindowID(SDL_Window *window);
+void SDL_PumpEvents(void);
#endif
--- a/include/npe/SDL2/SDL_joystick.h
+++ b/include/npe/SDL2/SDL_joystick.h
@@ -5,5 +5,16 @@
int SDL_NumJoysticks(void);
SDL_Joystick *SDL_JoystickOpen(int n);
+void SDL_JoystickClose(SDL_Joystick*);
+int SDL_JoystickNumAxes(SDL_Joystick*);
+int SDL_JoystickNumButtons(SDL_Joystick*);
+int SDL_JoystickNumHats(SDL_Joystick*);
+int SDL_JoystickNumBalls(SDL_Joystick*);
+int SDL_JoystickEventState(int);
+void SDL_JoystickUpdate(void);
+Uint8 SDL_JoystickGetHat(SDL_Joystick*,int);
+Sint16 SDL_JoystickGetAxis(SDL_Joystick*,int);
+Uint8 SDL_JoystickGetButton(SDL_Joystick*,int);
+char* SDL_JoystickName(SDL_Joystick*);
#endif
--- a/include/npe/SDL2/SDL_keycode.h
+++ b/include/npe/SDL2/SDL_keycode.h
@@ -76,6 +76,15 @@
SDLK_PLUS = '+',
SDLK_EQUALS = '=',
SDLK_UNDERSCORE = '_',
+ SDLK_LEFTBRACKET = '[',
+ SDLK_RIGHTBRACKET = ']',
+ SDLK_SEMICOLON = ';',
+ SDLK_QUOTE = '\'',
+ SDLK_BACKQUOTE = '`',
+ SDLK_BACKSLASH = '\\',
+ SDLK_COMMA = ',',
+ SDLK_PERIOD = '.',
+ SDLK_SLASH = '/',
SDLK_LALT = Kalt,
SDLK_RALT = Kaltgr, /* FIXME what about keyboards without it? */
@@ -90,6 +99,24 @@
SDLK_CAPSLOCK,
SDLK_KP_ENTER,
SDLK_AC_BACK,
+ SDLK_PAUSE,
+ SDLK_KP_DIVIDE,
+ SDLK_MODE,
+ SDLK_KP_PLUS,
+ SDLK_NUMLOCKCLEAR,
+ SDLK_SCROLLLOCK,
+ SDLK_KP_PERIOD,
+ SDLK_KP_7,
+ SDLK_KP_8,
+ SDLK_KP_9,
+ SDLK_KP_MINUS,
+ SDLK_KP_4,
+ SDLK_KP_5,
+ SDLK_KP_6,
+ SDLK_KP_1,
+ SDLK_KP_2,
+ SDLK_KP_3,
+ SDLK_KP_0,
/* FIXME no distinction */
KMOD_LSHIFT = 1<<0,
--- /dev/null
+++ b/include/npe/SDL2/SDL_mixer.h
@@ -1,0 +1,51 @@
+#ifndef _npe_SDL_mixer_h_
+#define _npe_SDL_mixer_h_
+
+#include <SDL2/SDL_rwops.h>
+
+/* The internal format for an audio chunk */
+typedef struct Mix_Chunk {
+ int allocated;
+ Uint8 *abuf;
+ Uint32 alen;
+ Uint8 volume; /* Per-sample volume, 0-128 */
+} Mix_Chunk;
+
+typedef struct Mix_Music {
+ int type;
+ int loops;
+ int fd;
+ char *loc;
+} Mix_Music;
+
+typedef void (*Mix_EffectFunc_t)(int chan, void *stream, int len, void *udata);
+typedef void (*Mix_EffectDone_t)(int chan, void *udata);
+
+int Mix_OpenAudio(int,Uint16,int,int);
+char* Mix_GetError(void);
+int Mix_RegisterEffect(int,Mix_EffectFunc_t,Mix_EffectDone_t,void*);
+Mix_Chunk* Mix_QuickLoad_RAW(Uint8*, Uint32);
+int Mix_PlayChannel(int,Mix_Chunk*,int);
+int Mix_HaltChannel(int);
+void Mix_FreeChunk(Mix_Chunk*);
+void Mix_CloseAudio(void);
+int Mix_Init(int);
+int Mix_VolumeMusic(int);
+int Mix_PlayingMusic(void);
+int Mix_PausedMusic(void);
+void Mix_ResumeMusic(void);
+void Mix_PauseMusic(void);
+int Mix_PlayingMusic(void);
+int Mix_PausedMusic(void);
+int Mix_HaltMusic(void);
+int Mix_PlayMusic(Mix_Music *music, int loops);
+Mix_Music* Mix_LoadMUS_RW(SDL_RWops *src, int freesrc);
+Mix_Music* Mix_LoadMUS(char *filename);
+
+enum {
+ MIX_INIT_MID = 1,
+
+ MIX_DEFAULT_FORMAT = 1,
+};
+
+#endif
--- a/include/npe/SDL2/SDL_rwops.h
+++ b/include/npe/SDL2/SDL_rwops.h
@@ -21,6 +21,7 @@
};
SDL_RWops *SDL_RWFromFile(const char *, const char *);
+SDL_RWops *SDL_RWFromMem(void*, int);
size_t SDL_RWread(SDL_RWops *, void *, size_t, size_t);
size_t SDL_RWwrite(SDL_RWops *, const void *, size_t, size_t);
vlong SDL_RWseek(SDL_RWops *, vlong, int);
--- a/include/npe/SDL2/SDL_scancode.h
+++ b/include/npe/SDL2/SDL_scancode.h
@@ -101,6 +101,9 @@
SDL_SCANCODE_KP_0,
SDL_SCANCODE_KP_PERIOD,
SDL_SCANCODE_NONUSBACKSLASH,
+ SDL_SCANCODE_COMMA,
+ SDL_SCANCODE_PERIOD,
+ SDL_SCANCODE_SYSREQ,
SDL_SCANCODE_MENU = 0x76,
@@ -119,6 +122,8 @@
SDL_SCANCODE_MODE = 0x101,
SDL_SCANCODE_AUDIOMUTE = 0x106,
+
+ SDL_NUM_SCANCODES,
};
#endif
--- /dev/null
+++ b/include/npe/config.h
@@ -1,0 +1,4 @@
+#ifndef _npe_config_h_
+#define _npe_config_h_
+
+#endif
--- a/include/npe/inttypes.h
+++ b/include/npe/inttypes.h
@@ -3,7 +3,9 @@
#include <stdint.h>
+#ifndef CHAR_BIT
#define CHAR_BIT 8
+#endif
#define PRId64 "%lld"
#define PRIu64 "%llud"
--- /dev/null
+++ b/include/npe/locale.h
@@ -1,0 +1,4 @@
+#ifndef _npe_locale_h_
+#define _npe_locale_h_
+
+#endif
--- a/include/npe/wchar.h
+++ b/include/npe/wchar.h
@@ -1,1 +1,6 @@
#include <npe.h>
+
+typedef Rune wchar_t;
+
+#define mblen(r,n) (utfnlen(r, n))
+#define mbtowc(r,s,n) (chartorune(r,s))
--- a/libnpe_sdl2/_sdl.h
+++ b/libnpe_sdl2/_sdl.h
@@ -12,6 +12,9 @@
struct npe_sdl {
Mousectl *mctl;
+ Rectangle grabout;
+ Point center;
+ int mgrab;
Mouse m, om;
int hints;
int mredraw;
--- a/libnpe_sdl2/events.c
+++ b/libnpe_sdl2/events.c
@@ -28,6 +28,7 @@
static int rune2scancode(Rune r);
static void kbdproc(void *);
+static void mouseproc(void *);
int
npe_sdl_init_input(void)
@@ -37,16 +38,26 @@
salt[Ckey].c = chancreate(sizeof(Rune), 20);
salt[Ckeytype].c = chancreate(sizeof(int), 20);
- salt[Cmouse].c = npe_sdl.mctl->c;
+ salt[Cmouse].c = chancreate(sizeof(Mouse), 20);
salt[Cresize].c = npe_sdl.mctl->resizec;
kctl.c = salt[Ckey].c; /* for enter() */
- if(salt[Ckey].c == nil || salt[Ckeytype].c == nil || proccreate(kbdproc, nil, 4096) < 0)
+ if(salt[Ckey].c == nil || salt[Ckeytype].c == nil || salt[Cmouse].c == nil)
return -1;
+ if(proccreate(kbdproc, nil, 4096) < 0 || proccreate(mouseproc, nil, 4096) < 0)
+ return -1;
+
return 0;
}
+Uint32
+SDL_GetWindowID(SDL_Window *win)
+{
+ USED(win);
+ return 1;
+}
+
SDL_Keymod
SDL_GetModState(void)
{
@@ -80,6 +91,12 @@
return quitreq;
}
+void
+SDL_PumpEvents(void)
+{
+ /* FIXME does it matter? */
+}
+
#define ISTEXT(r) ((r) >= 0x20 && ((r) < KF || (r) >= KF+0x1000))
int
@@ -109,14 +126,27 @@
e->key.repeat = t == Rrepeat;
e->key.keysym.scancode = rune2scancode(rune);
e->key.keysym.sym = rune;
+ e->key.state = e->type;
return 1;
}
break;
case Cmouse:
+ if(screen == nil)
+ break;
+
+ if(eqpt(npe_sdl.m.xy, Pt(-1, -1))){
+ npe_sdl.m.xy = npe_sdl.center;
+ npe_sdl.om.xy = npe_sdl.center;
+ return 0; /* swallow */
+ }
+
memset(e, 0, sizeof(*e));
e->motion.x = (npe_sdl.m.xy.x - screen->r.min.x) * npe_sdl.scale;
e->motion.y = (npe_sdl.m.xy.y - screen->r.min.y) * npe_sdl.scale;
+ e->motion.xrel = (npe_sdl.m.xy.x - npe_sdl.om.xy.x) * npe_sdl.scale;
+ e->motion.yrel = (npe_sdl.m.xy.y - npe_sdl.om.xy.y) * npe_sdl.scale;
+
if(!eqpt(npe_sdl.m.xy, npe_sdl.om.xy)){
npe_sdl.mredraw = 1;
if(npe_sdl.m.buttons == npe_sdl.om.buttons){
@@ -156,13 +186,11 @@
case Cresize:
memset(e, 0, sizeof(*e));
npe_sdl.fullredraw = 1;
- if(getwindow(display, Refnone) < 0){
- fprint(2, "%r\n");
- /* FIXME do something here? */
- //threadexitsall(nil);
- }
+ while(getwindow(display, Refnone) != 1)
+ ;
e->type = SDL_WINDOWEVENT;
e->window.event = SDL_WINDOWEVENT_EXPOSED;
+ e->window.windowID = 1; //TODO more then one?
return 1;
}
@@ -335,11 +363,10 @@
kmod &= ~KMOD_LSHIFT;
else if(r == Kctl)
kmod &= ~KMOD_LCTRL;
- else{
- t = Rup;
- send(salt[Ckey].c, &r);
- send(salt[Ckeytype].c, &t);
- }
+
+ t = Rup;
+ send(salt[Ckey].c, &r);
+ send(salt[Ckeytype].c, &t);
}
}
break;
@@ -348,4 +375,20 @@
}
threadexits(nil);
+}
+
+static void
+mouseproc(void *)
+{
+ Mouse m;
+ for(;;){
+ recv(npe_sdl.mctl->c, &m);
+ if(npe_sdl.mgrab == SDL_TRUE){
+ if(!ptinrect(m.xy, npe_sdl.grabout)){
+ moveto(npe_sdl.mctl, npe_sdl.center);
+ m.xy = Pt(-1,-1);
+ }
+ }
+ send(salt[Cmouse].c, &m);
+ }
}
--- /dev/null
+++ b/libnpe_sdl2/mixer.c
@@ -1,0 +1,285 @@
+#include "_sdl.h"
+
+#include <SDL2/SDL_mixer.h>
+
+int audiofd = -1;
+int musicpipe[2] = {-1, -1};
+
+static int forkerpid = -1;
+static int audiopid = -1;
+
+void musicproc(void *);
+
+static int musicvol = 128;
+static int musicpaused = 0;
+
+/* FIXME proper chains per channel */
+Mix_EffectFunc_t effunc = nil;
+
+static int doneinit = 0;
+static int devopen = 0;
+
+enum { Maxchan = 16 };
+SDL_AudioSpec channels[Maxchan];
+int nchannels = 0;
+
+int
+Mix_OpenAudio(int freq, Uint16 format, int nch, int chunk)
+{
+ SDL_AudioSpec *as;
+ int sz;
+
+ if(devopen)
+ return 0;
+
+ switch(format){
+ case 1:
+ case 2:
+ sz = 1;
+ break;
+ case 3:
+ case 4:
+ sz = 2;
+ break;
+ default:
+ werrstr("unsupported format");
+ return -1;
+ }
+
+ as = &channels[nchannels++];
+ assert(nchannels < Maxchan);
+ as->freq = freq;
+ as->format = format;
+ as->channels = nch;
+ as->samples = chunk / sz;
+ return 0;
+}
+
+char*
+Mix_GetError(void)
+{
+ return "";
+}
+
+static void
+translate(void *arg, Uint8 *buf, int len)
+{
+ Mix_EffectFunc_t f;
+
+ f = (Mix_EffectFunc_t)arg;
+
+ f(0, buf, len, nil);
+}
+
+int
+Mix_RegisterEffect(int chan, Mix_EffectFunc_t f, Mix_EffectDone_t d, void *arg)
+{
+ SDL_AudioSpec *as;
+ int n;
+
+ USED(arg); USED(d);
+ as = channels + chan;
+ as->userdata = f;
+ as->callback = translate;
+ if(devopen){
+ werrstr("device already open");
+ return -1;
+ }
+ n = SDL_OpenAudioDevice(nil, 0, as, nil, 0);
+ assert(n >= 0);
+ SDL_PauseAudioDevice(n, 0);
+ return 1;
+}
+
+Mix_Chunk*
+Mix_QuickLoad_RAW(Uint8 *mem, Uint32 len)
+{
+ USED(mem);
+ USED(len);
+ return nil;
+}
+
+int
+Mix_PlayChannel(int chan, Mix_Chunk *chunk, int loops)
+{
+ USED(chan);
+ USED(chunk);
+ USED(loops);
+ return -1;
+}
+
+int
+Mix_HaltChannel(int channel)
+{
+ USED(channel);
+ return 0;
+}
+
+void
+Mix_FreeChunk(Mix_Chunk *c)
+{
+ USED(c);
+}
+
+void
+Mix_CloseAudio(void)
+{
+ if(audiopid > 0)
+ postnote(PNPROC, audiopid, "quit");
+ audiopid = -1;
+}
+
+int
+Mix_Init(int flags)
+{
+ if(doneinit)
+ return flags;
+ doneinit = 1;
+ memset(channels, 0, sizeof channels);
+ rfork(RFNAMEG);
+ if(fork() == 0){
+ execl("/bin/audio/mixfs", "mixfs", nil);
+ sysfatal("exec: %r\n");
+ }
+ waitpid();
+ pipe(musicpipe);
+ if(fork() == 0){
+ musicproc(nil);
+ sysfatal("exec musicproc: %r");
+ }
+ return flags;
+}
+
+int
+Mix_VolumeMusic(int vol)
+{
+ if(vol < 0)
+ vol = 0;
+ else if(vol > 128)
+ vol = 128;
+ musicvol = vol;
+ return 0;
+}
+
+int
+Mix_PlayingMusic(void)
+{
+ return forkerpid > 0 && !musicpaused;
+}
+
+int
+Mix_PausedMusic(void)
+{
+ return musicpaused;
+}
+void
+Mix_ResumeMusic(void)
+{
+ musicpaused = 0;
+}
+
+void
+Mix_PauseMusic(void)
+{
+ musicpaused = 1;
+}
+
+int
+Mix_HaltMusic(void)
+{
+ if(forkerpid < 0)
+ return 0;
+
+ postnote(PNGROUP, forkerpid, "halt");
+ forkerpid = -1;
+ return 0;
+}
+
+int
+Mix_PlayMusic(Mix_Music *music, int loops)
+{
+ Waitmsg *wm;
+ int n;
+
+ if(forkerpid > 0)
+ Mix_HaltMusic();
+
+ if((forkerpid = rfork(RFPROC|RFNOTEG)) != 0)
+ return 0;
+
+ n = loops;
+ while(loops == -1 || n-- > 0){
+ switch(rfork(RFPROC|RFFDG)){
+ case 0:
+ dup(musicpipe[1], 1);
+ close(musicpipe[1]);
+ close(musicpipe[0]);
+ execl("/bin/games/midi", "midi", "-c", music->loc, nil);
+ sysfatal("exec: %r");
+ break;
+ default:
+ wm = wait();
+ if(wm->msg != nil && wm->msg[0] != '\0'){
+ fprint(2, "playmusic: %s\n", wm->msg);
+ threadexits(nil);
+ }
+ free(wm);
+ break;
+ }
+ }
+ threadexits(nil);
+ return -1;
+}
+
+Mix_Music*
+Mix_LoadMUS(char *filename)
+{
+ Mix_Music *m;
+
+ m = calloc(1, sizeof(*m));
+ m->loc = strdup(filename);
+ m->fd = open(filename, OREAD);
+ if(m->fd < 0)
+ sysfatal("LoadMUS: %r");
+ return m;
+}
+
+Mix_Music*
+Mix_LoadMUS_RW(SDL_RWops *src, int freesrc)
+{
+ Mix_Music *m;
+ char buf[1024];
+ int n;
+
+ m = calloc(1, sizeof(*m));
+ m->loc = smprint("/tmp/npesdl.mus.%d", getpid());
+ m->fd = create(m->loc, ORDWR|ORCLOSE, 0666);
+ while((n = SDL_RWread(src, buf, 1, sizeof buf)) > 0)
+ write(m->fd, buf, n);
+ seek(m->fd, 0, 0);
+
+ if(freesrc)
+ SDL_RWclose(src);
+ return m;
+}
+
+void
+musicproc(void *)
+{
+ int fd;
+ static char buf[8192];
+ int n;
+
+ fd = open("/dev/audio", OWRITE);
+ if(fd < 0)
+ sysfatal("musicproc: %r");
+
+ close(musicpipe[1]);
+ threadsetname("musicproc");
+ for(;;){
+ n = read(musicpipe[0], buf, sizeof buf);
+ if(n < 0)
+ threadexits(nil);
+ write(fd, buf, n);
+ }
+}
--- a/libnpe_sdl2/mkfile
+++ b/libnpe_sdl2/mkfile
@@ -12,6 +12,7 @@
rwops.$O\
scale.$O\
sdl2.$O\
+ mixer.$O\
threads.$O\
UPDATE=\
--- a/libnpe_sdl2/rwops.c
+++ b/libnpe_sdl2/rwops.c
@@ -1,8 +1,23 @@
#include "_sdl.h"
#include <bio.h>
+typedef struct {
+ uchar *memdata;
+ int memn;
+ int mempos;
+} Membuf;
+
+static vlong memsize(struct SDL_RWops *);
+static vlong memseek(struct SDL_RWops *, vlong, int);
+static size_t memread(struct SDL_RWops *, void *, size_t, size_t);
+static size_t memwrite(struct SDL_RWops *, const void *, size_t, size_t);
+static int memclose(struct SDL_RWops *);
+
struct npe_sdl_rwops {
- Biobuf;
+ union {
+ Biobuf;
+ Membuf;
+ };
};
static vlong bsize(struct SDL_RWops *);
@@ -54,6 +69,30 @@
return nil;
}
+SDL_RWops*
+SDL_RWFromMem(void *mem, int size)
+{
+ SDL_RWops *o;
+ Membuf *b;
+
+ o = calloc(1, sizeof(*o)+sizeof(npe_sdl_rwops));
+ if(o == nil)
+ return nil;
+ o->p = (void*)(o+1);
+ b = (void*)o->p;
+ b->memdata = mem;
+ b->memn = size;
+ b->mempos = 0;
+
+
+ o->size = memsize;
+ o->seek = memseek;
+ o->read = memread;
+ o->write = memwrite;
+ o->close = memclose;
+ return o;
+}
+
size_t
SDL_RWread(SDL_RWops *o, void *b, size_t sz, size_t n)
{
@@ -153,4 +192,86 @@
bclose(struct SDL_RWops *o)
{
return Bterm(o->p);
+}
+
+static vlong
+memseek(struct SDL_RWops *o, vlong off, int whence)
+{
+ Membuf *b;
+
+ b = (Membuf*)o->p;
+ switch(whence){
+ case 0:
+ b->mempos = off;
+ break;
+ case 1:
+ b->mempos += off;
+ break;
+ case 2:
+ b->mempos = b->memn - 1;
+ b->mempos -= off;
+ break;
+ }
+ if(b->mempos < 0)
+ b->mempos = 0;
+
+ return b->mempos;
+}
+
+static size_t
+memread(struct SDL_RWops *o, void *b, size_t sz, size_t n)
+{
+ Membuf *buf;
+ uchar *p, *dot;
+ uchar *end;
+ size_t i;
+
+ buf = (Membuf*)o->p;
+ end = buf->memdata + buf->memn;
+ for(i = 0, p = b; i < n; i++, p += sz){
+ dot = buf->memdata + buf->mempos;
+ if(dot + sz >= end){
+ memmove(p, dot, end - dot);
+ buf->mempos = buf->memn;
+ dot = end;
+ }
+ if(dot == end)
+ return i;
+
+ assert(dot < end);
+ memmove(p, dot, sz);
+ buf->mempos += sz;
+ }
+
+ return i;
+}
+
+static size_t
+memwrite(struct SDL_RWops *o, const void *b, size_t sz, size_t n)
+{
+ Membuf *buf;
+ const uchar *p;
+ size_t i;
+
+ buf = (Membuf*)o->p;
+ for(i = 0, p = b; i < n; i++, p += sz){
+ memmove(buf->mempos + buf->memdata, p, sz);
+ buf->mempos += sz;
+ }
+ return i;
+}
+
+static vlong
+memsize(struct SDL_RWops *o)
+{
+ Membuf *b;
+ b = (Membuf*)o->p;
+
+ return b->memn;
+}
+
+static int
+memclose(struct SDL_RWops *o)
+{
+ return 0;
}
--- a/libnpe_sdl2/sdl2.c
+++ b/libnpe_sdl2/sdl2.c
@@ -55,8 +55,35 @@
},
};
+int
+SDL_InitSubSystem(int mask)
+{
+ /* FIXME implement */
+ USED(mask);
+ return 0;
+}
int
+SDL_QuitSubSystem(int mask)
+{
+ /* FIXME implement */
+ USED(mask);
+ return 0;
+}
+
+void
+SDL_SetWindowIcon(SDL_Window *w, SDL_Surface *icon)
+{
+ USED(w); USED(icon);
+}
+
+void
+SDL_SetWindowBordered(SDL_Window *w, SDL_bool flag)
+{
+ USED(w); USED(flag);
+}
+
+int
SDL_Init(int mask)
{
/* FIXME actually use the mask? */
@@ -305,15 +332,34 @@
{
SDL_Surface *s;
int n;
+ Memimage *i;
USED(flags, rm, gm, bm, am); /* FIXME flags & masks */
n = w*h*bpp/8;
- if((s = calloc(1, sizeof(*s)+n)) == nil){
+ if((s = calloc(1, sizeof(*s))) == nil){
werrstr("SDL_CreateRGBSurface: memory");
return nil;
}
- s->format = &argb8888;
+ s->i = i = allocmemimage(Rect(0,0,w,h), screen->chan);
+ s->format = calloc(1, sizeof(SDL_PixelFormat));
+ switch(bpp){
+ case 32:
+ s->format->format = SDL_PIXELFORMAT_ARGB8888;
+ s->pixels = i->data->bdata;
+ break;
+ case 8:
+ s->format->format = SDL_PIXELFORMAT_INDEX8;
+ s->format->palette = calloc(1, sizeof(SDL_Palette));
+ s->format->palette->ncolors = 256;
+ s->format->palette->colors = calloc(1, sizeof(SDL_Color) * 256);
+ s->pixels = calloc(1, n);
+ break;
+ default:
+ werrstr("non supported bpp");
+ return nil;
+ }
+
s->w = w;
s->h = h;
s->pitch = w*bpp/8;
@@ -321,6 +367,7 @@
s->clip_rect.y = 0;
s->clip_rect.w = w;
s->clip_rect.h = h;
+ s->n = n;
return s;
}
@@ -365,9 +412,149 @@
return s;
}
+int
+SDL_FillRect(SDL_Surface *dst, const SDL_Rect *rect, Uint32 color)
+{
+ Uint32 *p;
+ int i;
+ USED(rect);
+
+ switch(dst->format->format){
+ case SDL_PIXELFORMAT_XRGB8888:
+ case SDL_PIXELFORMAT_ARGB8888:
+ p = (Uint32*)dst->pixels;
+ for(i = 0; i < dst->n / sizeof(*p); i++)
+ p[i] = color;
+ break;
+ case SDL_PIXELFORMAT_INDEX8:
+ for(i = 0; i < dst->n; i++)
+ dst->pixels[i] = color;
+ break;
+ }
+
+ return 0;
+}
+
+int
+SDL_SetPaletteColors(SDL_Palette *palette, const SDL_Color *colors, int firstcolor, int ncolors)
+{
+ int i;
+
+ assert(palette->ncolors >= firstcolor + ncolors);
+ for(i = firstcolor; i < firstcolor + ncolors; i++)
+ palette->colors[i] = colors[i - firstcolor];
+ return 0;
+}
+
+static void
+syncpalette(SDL_Surface *s)
+{
+ SDL_Color *c;
+ Uint8 *to;
+ int j;
+
+ to = ((Memimage*)s->i)->data->bdata;
+ for(j = 0; j < s->n; j++){
+ c = s->format->palette->colors + s->pixels[j];
+ *to++ = c->b;
+ *to++ = c->g;
+ *to++ = c->r;
+ *to++ = c->a;
+ }
+}
+
+int
+SDL_BlitSurface(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect)
+{
+ Rectangle r, r2;
+
+ r = srcrect == nil ? Rect(0, 0, src->w, src->h) : Rect(srcrect->x, srcrect->y, srcrect->x+srcrect->w, srcrect->y+srcrect->h);
+ r2 = dstrect == nil ? Rect(0, 0, dst->w, dst->h) : Rect(dstrect->x, dstrect->y, dstrect->x+dstrect->w, dstrect->y+dstrect->h);
+
+ if(src->format->format == SDL_PIXELFORMAT_INDEX8)
+ syncpalette(src);
+
+ /* FIXME */
+ assert(dst->format->format != SDL_PIXELFORMAT_INDEX8);
+ memimagedraw(dst->i, r2, src->i, ZP, nil, ZP, S);
+ return 0;
+}
+
+int
+SDL_SoftStretch(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, const SDL_Rect *dstrect)
+{
+ Rectangle r, r2;
+ Memimage *rowimg;
+ int w, h;
+ int scale;
+ ulong *s, *d, *e;
+ ulong *out;
+ int i, y;
+
+ r = srcrect == nil ? Rect(0, 0, src->w, src->h) : Rect(srcrect->x, srcrect->y, srcrect->x+srcrect->w, srcrect->y+srcrect->h);
+ r2 = dstrect == nil ? Rect(0, 0, dst->w, dst->h) : Rect(dstrect->x, dstrect->y, dstrect->x+dstrect->w, dstrect->y+dstrect->h);
+
+ w = Dx(r);
+ h = Dy(r);
+
+ scale = Dx(r2)/w;
+ if(scale <= 0)
+ scale = 1;
+ else if(scale > 12)
+ scale = 12;
+
+ rowimg = allocmemimage(Rect(0, 0, scale*w, 1), ((Memimage*)src->i)->chan);
+
+ assert(dst->format->format != SDL_PIXELFORMAT_INDEX8);
+ if(src->format->format == SDL_PIXELFORMAT_INDEX8)
+ syncpalette(src);
+
+ for(y = 0; y < h; y++){
+ s = wordaddr(src->i, Pt(0, y));
+ d = (ulong*)rowimg->data->bdata;
+ e = s + w;
+ for(; s < e; s++){
+ switch(scale){
+ case 12:
+ *d++ = *s;
+ case 11:
+ *d++ = *s;
+ case 10:
+ *d++ = *s;
+ case 9:
+ *d++ = *s;
+ case 8:
+ *d++ = *s;
+ case 7:
+ *d++ = *s;
+ case 6:
+ *d++ = *s;
+ case 5:
+ *d++ = *s;
+ case 4:
+ *d++ = *s;
+ case 3:
+ *d++ = *s;
+ case 2:
+ *d++ = *s;
+ case 1:
+ *d++ = *s;
+ }
+ }
+ d = (ulong*)rowimg->data->bdata;
+ for(i = 0; i < scale; i++){
+ out = wordaddr(dst->i, Pt(0, y*scale + i));
+ memcpy(out, d, scale*w*4);
+ }
+ }
+ freememimage(rowimg);
+ return 0;
+}
+
void
SDL_FreeSurface(SDL_Surface *surface)
{
+ freememimage(surface->i);
memset(surface, 0, sizeof(surface));
free(surface);
}
@@ -581,6 +768,7 @@
{
Rectangle sr, dr;
int logiw, logih;
+ ulong chan;
if(rend->logiw > 0 && rend->logih > 0){
logiw = rend->logiw;
@@ -604,7 +792,11 @@
if(back == nil || Dx(back->r) != logiw || Dy(back->r) != logih){
freememimage(back);
- back = allocmemimage(Rect(0, 0, logiw, logih), ARGB32);
+ if(screen)
+ chan = screen->chan;
+ else
+ chan = ARGB32;
+ back = allocmemimage(Rect(0, 0, logiw, logih), chan);
if(back == nil){
werrstr("SDL_RenderCopy: %r");
return -1;
@@ -675,6 +867,8 @@
replclipr(screen, 0, clipr);
}
}
+ while(screen == nil && getwindow(display, Refnone) != 1)
+ /* drawterm window change lag */;
draw(screen, screen->r, front, nil, ZP);
if(cursor != nil && showcursor)
draw(screen, r, cursor->i, cursor->m, ZP);
@@ -755,7 +949,8 @@
n = fprint(f, "resize -dx %d -dy %d", w+Borderwidth*2, h+Borderwidth*2);
close(f);
if(n > 0){
- getwindow(display, Refnone);
+ while(getwindow(display, Refnone) != 1)
+ ;
npe_sdl.fullredraw = 1;
}
}
@@ -794,8 +989,11 @@
n = fprint(f, "move -minx %d -miny %d", x, y);
close(f);
if(n > 0){
- getwindow(display, Refnone);
+ while(getwindow(display, Refnone) != 1)
+ ;
npe_sdl.fullredraw = 1;
+ npe_sdl.grabout = insetrect(screen->r, Dx(screen->r)/8);
+ npe_sdl.center = addpt(screen->r.min, Pt(Dx(screen->r)/2, Dy(screen->r)/2));
}
}
}
@@ -820,6 +1018,23 @@
return SDL_GetDesktopDisplayMode(displayIndex, mode);
}
+int
+SDL_GetNumDisplayModes(int displayIndex)
+{
+ if(displayIndex != 0)
+ return -1;
+ return 1;
+}
+
+int
+SDL_GetDisplayMode(int displayIndex, int modeIndex, SDL_DisplayMode *mode)
+{
+ USED(modeIndex);
+ physw = 1280;
+ physh = 960;
+ return SDL_GetDesktopDisplayMode(displayIndex, mode);
+}
+
void
SDL_SetWindowTitle(SDL_Window *, char *title)
{
@@ -831,6 +1046,13 @@
}
}
+int
+SDL_GetNumVideoDisplays(void)
+{
+ /* FIXME implement multihead for plan9 */
+ return 1;
+}
+
void
SDL_DestroyTexture(SDL_Texture *t)
{
@@ -1077,15 +1299,137 @@
}
void
+SDL_JoystickClose(SDL_Joystick *js)
+{
+ USED(js);
+}
+
+int
+SDL_JoystickNumAxes(SDL_Joystick *js)
+{
+ USED(js);
+ return -1;
+}
+
+int
+SDL_JoystickNumButtons(SDL_Joystick *js)
+{
+ USED(js);
+ return -1;
+}
+
+int
+SDL_JoystickNumHats(SDL_Joystick *js)
+{
+ USED(js);
+ return -1;
+}
+
+int
+SDL_JoystickNumBalls(SDL_Joystick *js)
+{
+ USED(js);
+ return -1;
+}
+
+int
+SDL_JoystickEventState(int state)
+{
+ USED(state);
+ return 0;
+}
+
+void
+SDL_JoystickUpdate(void)
+{
+}
+
+char*
+SDL_JoystickName(SDL_Joystick *js)
+{
+ USED(js);
+ return nil;
+}
+
+Sint16
+SDL_JoystickGetAxis(SDL_Joystick *js, int axis)
+{
+ USED(js); USED(axis);
+ return 0;
+}
+
+Uint8
+SDL_JoystickGetHat(SDL_Joystick *js, int hat)
+{
+ USED(js); USED(hat);
+ return 0;
+}
+
+Uint8
+SDL_JoystickGetButton(SDL_Joystick *js, int button)
+{
+ USED(js); USED(button);
+ return 0;
+}
+
+int
+SDL_SetRelativeMouseMode(SDL_bool enabled)
+{
+ if(screen){
+ npe_sdl.grabout = insetrect(screen->r, Dx(screen->r)/8);
+ npe_sdl.center = addpt(screen->r.min, Pt(Dx(screen->r)/2, Dy(screen->r)/2));
+ if(enabled)
+ SDL_ShowCursor(0);
+ else
+ SDL_ShowCursor(1);
+ }
+ npe_sdl.mgrab = enabled;
+ return 0;
+}
+
+void
SDL_SetMainReady(void)
{
}
+int
+SDL_GetRelativeMouseMode(void)
+{
+ return npe_sdl.mgrab;
+}
+
+SDL_mutex*
+SDL_CreateMutex(void)
+{
+ SDL_mutex *m;
+
+ m = mallocz(sizeof *m, 1);
+ return m;
+}
+
void
-SDL_GetVersion(SDL_version *v)
+SDL_DestroyMutex(SDL_mutex *m)
{
- /* these are arbitrary */
- v->major = 2;
- v->minor = 24;
- v->patch = 1;
+ free(m);
+}
+
+int
+SDL_LockMutex(SDL_mutex *m)
+{
+ lock(&m->l);
+ return 0;
+}
+
+int
+SDL_UnlockMutex(SDL_mutex *m)
+{
+ unlock(&m->l);
+ return 0;
+}
+
+void
+SDL_SetModState(SDL_Keymod modstate)
+{
+ /* FIXME: do we care? */
+ USED(modstate);
}