shithub: npe

ref: 979ae53cfee913c2d303ab0f95aaa65dace1c7b5
dir: /libnpe_sdl3/sdl3.c/

View raw version
#include "_sdl.h"
#include <bio.h>

struct npe_sdl npe_sdl;

static char basepath[PATH_MAX];

bool
SDL_InitSubSystem(int mask)
{
	if(basepath[0] == 0){
		if(getwd(basepath, sizeof(basepath)) == nil)
			strcpy(basepath, "/");
	}
	if(mask & SDL_INIT_VIDEO && npe_sdl_init_draw() < 0)
		goto err;
	if(mask & SDL_INIT_AUDIO && npe_sdl_init_audio() < 0)
		goto err;
	if(mask & SDL_INIT_EVENTS && npe_sdl_init_input() < 0)
		goto err;
	if(mask & SDL_INIT_GAMEPAD && npe_sdl_init_gamepad() < 0)
		goto err;
	return true;
err:
	return false;
}

bool
SDL_QuitSubSystem(int mask)
{
	if(mask & SDL_INIT_AUDIO)
		npe_sdl_kill_audio();
	if(mask & SDL_INIT_VIDEO)
		npe_sdl_kill_draw();
	if(mask & SDL_INIT_EVENTS)
		npe_sdl_kill_input();
	if(mask & SDL_INIT_GAMEPAD)
		npe_sdl_kill_gamepad();
	/* FIXME: ... */
	return true;
}

bool
SDL_Init(int mask)
{
	return SDL_InitSubSystem(mask);
}

bool
SDL_SetAppMetadata(const char *name, const char *ver, const char *id)
{
	USED(name, ver, id);
	return true;
}

Uint64
SDL_GetPerformanceFrequency(void)
{
	return _tos->cyclefreq;
}

Uint64
SDL_GetPerformanceCounter(void)
{
	u64int x;

	cycles(&x);

	return x;
}

char *
SDL_GetError(void)
{
	static char err[256];

	snprint(err, sizeof(err), "%r");

	return err;
}

static void *
readfile(char *path, int *got)
{
	void *data, *data2;
	int f, n, r, sz;

	if((f = open(path, OREAD|OCEXEC)) < 0)
		return nil;

	sz = 32768;
	data = nil;
	for(n = 0;; n += r){
		if(sz-n < 65536){
			sz *= 2;
			if((data2 = realloc(data, sz)) == nil)
				goto err;
			data = data2;
		}
		if((r = read(f, (char*)data+n, sz-n-1)) < 0)
			goto err;
		if(r == 0)
			break;
	}

	if(got != nil)
		*got = n;
	((char*)data)[n] = 0;

	return data;
err:
	free(data);
	close(f);
	return nil;
}

char *
SDL_GetClipboardText(void)
{
	return readfile("/dev/snarf", nil);
}

int
SDL_SetClipboardText(char *s)
{
	int f, n;

	n = -1;
	if((f = open("/dev/snarf", OWRITE|OTRUNC|OCEXEC)) >= 0){
		n = strlen(s);
		n = write(f, s, n) == n ? 0 : -1;
		close(f);
	}

	if(n != 0)
		werrstr("SDL_SetClipboardText: %r");

	return n;
}

bool
SDL_GetWindowDisplayIndex(SDL_Window *)
{
	return true;
}

void
SDL_Quit(void)
{
	/* FIXME deinitialize */
}

bool
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:
	case SDL_PIXELFORMAT_XBGR8888:
	case SDL_PIXELFORMAT_ABGR8888:
		p = (Uint32*)dst->pixels;
		for(i = 0; i < dst->n / sizeof(*p); i++)
			p[i] = color;
		break;
	case SDL_PIXELFORMAT_RGB24:
		for(i = 0; i < dst->n; i += 3){
			dst->pixels[i+0] = color;
			dst->pixels[i+1] = color>>8;
			dst->pixels[i+2] = color>>16;
		}
		break;
	case SDL_PIXELFORMAT_INDEX8:
		for(i = 0; i < dst->n; i++)
			dst->pixels[i] = color;
		break;
	}
	return true;
}

SDL_Palette*
SDL_AllocPalette(int ncolors)
{
	SDL_Palette *p;

	p = malloc(sizeof(*p));
	p->ncolors = ncolors;
	p->colors = mallocz(sizeof(SDL_Color)*ncolors, 1);
	return p;
}

bool
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 true;
}

void
SDL_WarpMouseInWindow(SDL_Window *, int x, int y)
{
	moveto(npe_sdl.mctl, Pt(screen->r.min.x+x, screen->r.min.y+y));
}

Uint32
SDL_GetGlobalMouseState(int *x, int *y)
{
	Uint32 b;

	if(x != nil)
		*x = npe_sdl.m.xy.x;
	if(y != nil)
		*y = npe_sdl.m.xy.y;

	b = 0;
	if(npe_sdl.m.buttons & 1)
		b |= SDL_BUTTON_LMASK;
	if(npe_sdl.m.buttons & 2)
		b |= SDL_BUTTON_MMASK;
	if(npe_sdl.m.buttons & 4)
		b |= SDL_BUTTON_RMASK;

	return b;
}

Uint32
SDL_GetMouseState(int *x, int *y)
{
	Uint32 b;

	b = SDL_GetGlobalMouseState(nil, nil);
	if(x != nil)
		*x = npe_sdl.m.xy.x - screen->r.min.x;
	if(y != nil)
		*y = npe_sdl.m.xy.y - screen->r.min.y;

	return b;
}

void
SDL_RenderGetScale(SDL_Renderer *, float *scaleX, float *scaleY)
{
	*scaleX = 1.0;
	*scaleY = 1.0;
}

bool
SDL_RenderSetIntegerScale(SDL_Renderer *, SDL_bool enable)
{
	/* FIXME */
	USED(enable);
	return true;
}

SDL_bool
SDL_IsTextInputActive(void)
{
	return npe_sdl.textinput;
}

void
SDL_StartTextInput(void)
{
	npe_sdl.textinput = SDL_TRUE;
}

void
SDL_StopTextInput(void)
{
	npe_sdl.textinput = SDL_FALSE;
}

void
SDL_Delay(Uint32 ms)
{
	npe_nsleep((uvlong)ms * Nmsec);
}

Uint32
SDL_GetWindowFlags(SDL_Window *)
{
	/* FIXME is this correct? */
	return SDL_WINDOW_INPUT_FOCUS;
}

bool
SDL_GetDisplayUsableBounds(int displayIndex, SDL_Rect *r)
{
	if(displayIndex != 0)
		return false;

	if(r == nil)
		return true;

	r->x = display->image->r.min.x;
	r->y = display->image->r.min.y;
	r->w = Dx(display->image->r);
	r->h = Dy(display->image->r);
	return true;
}

bool
SDL_GetDisplayBounds(int displayIndex, SDL_Rect *r)
{
	return SDL_GetDisplayUsableBounds(displayIndex, r);
}

bool
SDL_GetDesktopDisplayMode(int displayIndex, SDL_DisplayMode *mode)
{
	if(displayIndex != 0)
		return false;
	mode->w = Dx(display->image->r);
	mode->h = Dy(display->image->r);
	mode->format = SDL_PIXELFORMAT_ARGB8888;
	mode->refresh_rate = 0;
	return true;
}

int
SDL_GetCurrentDisplayMode(int displayIndex, SDL_DisplayMode *mode)
{
	return SDL_GetDesktopDisplayMode(displayIndex, mode);
}

int
SDL_GetNumDisplayModes(int displayIndex)
{
	if(displayIndex != 0)
		return -1;
	return 1;
}

bool
SDL_GetDisplayMode(int displayIndex, int modeIndex, SDL_DisplayMode *mode)
{
	USED(modeIndex);
	return SDL_GetDesktopDisplayMode(displayIndex, mode);
}

void
SDL_SetWindowTitle(SDL_Window *, char *title)
{
	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);
	}
}

int
SDL_GetNumVideoDisplays(void)
{
	/* FIXME implement multihead for plan9 */
	return 1;
}

SDL_bool
SDL_SetHint(char *name, char *value)
{
	/* FIXME anyone cares about name="SDL_RENDER_SCALE_QUALITY" value="(best|nearest)"? */
	if(strcmp(name, SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4) == 0){
		npe_sdl.hints = (npe_sdl.hints & ~Altf4noclose) | (atoi(value) ? Altf4noclose : 0);
		return SDL_TRUE;
	}

	return SDL_FALSE;
}

char *
SDL_GetCurrentVideoDriver(void)
{
	return "/dev/draw";
}

Uint32
SDL_GetTicks(void)
{
	return npe_nanosec() / Nmsec;
}

bool
SDL_OpenURL(char *url)
{
	char tmp[PATH_MAX];
	Plumbmsg m;
	int f, r;

	if((f = plumbopen("send", OWRITE|OCEXEC)) < 0)
		return false;

	memset(&m, 0, sizeof(m));
	m.src = argv0;
	m.wdir = getwd(tmp, sizeof(tmp));
	m.type = "text";
	m.data = url;
	m.ndata = -1;
	r = plumbsend(f, &m);
	close(f);

	return r < 0 ? false : true;
}

char *
SDL_GetBasePath(void)
{
	return strdup(basepath);
}

char *
SDL_GetPrefPath(char *, char *app)
{
	char *home, *p;

	p = nil;
	if((home = getenv("home")) != nil){
		if((p = smprint("%s/lib/%s/", home, app)) != nil)
			npe_mkdirp(p, 0755);
	}

	return p;
}

SDL_bool
SDL_HasClipboardText(void)
{
	/* most def */
	return SDL_TRUE;
}

SDL_bool
SDL_HasSSE(void)
{
	/* it's not like we have builtins anyway */
	return SDL_FALSE;
}

SDL_bool
SDL_HasSSE2(void)
{
	/* it's not like we have builtins anyway */
	return SDL_FALSE;
}

void
SDL_EnableScreenSaver(void)
{
}

void
SDL_ClearError(void)
{
}

int
SDL_PeepEvents(SDL_Event *events, int numevents, SDL_eventaction action, Uint32 minType, Uint32 maxType)
{
	/* FIXME implement */
	USED(events, numevents, action, minType, maxType);
	return 0;
}

int
SDL_NumJoysticks(void)
{
	/* FIXME implement */
	return 0;
}

SDL_Joystick *
SDL_JoystickOpen(int n)
{
	/* FIXME implement */
	USED(n);
	return nil;
}

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;
}

/* FIXME: not sdl3 */
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_HideCursor();
		else
			SDL_ShowCursor();
	}
	npe_sdl.mgrab = enabled;
	return 0;
}

void
SDL_SetMainReady(void)
{
}

int
SDL_GetRelativeMouseMode(void)
{
	return npe_sdl.mgrab;
}

Uint32
SDL_GetRelativeMouseState(int *x, int *y)
{
	Uint32 b;

	b = SDL_GetGlobalMouseState(nil, nil);
	if(x != nil)
		*x = npe_sdl.Δ.x;
	if(y != nil)
		*y = npe_sdl.Δ.y;
	npe_sdl.Δ = ZP;
	return b;
}

void
SDL_SetModState(SDL_Keymod modstate)
{
	/* FIXME: do we care? */
	USED(modstate);
}

/* FIXME */
void
SDL_GetVersion(SDL_version *v)
{
	/* these are arbitrary */
	v->major = 2;
	v->minor = 24;
	v->patch = 1;
}