sdlbase.c

  • タグ:
  • タグはありません
#include <assert.h>
#include <stdlib.h>
#define SDL_MAIN_HANDLED
#include <SDL.h>
#include <squirrel.h>
#include "squirrel_wrap.h"

#define sqfunc_argment_test(V, NUM) \
	if(sq_gettop(V) != ((NUM) + 1)){ \
		sq_throwerror(v, "arguments num is must be " #NUM); \
		sq_settop(v, 1); \
		return SQ_ERROR; \
	}

struct sdl_member{
	SDL_Window *w;
	SDL_Renderer *r;
};
static SQInteger sq_sdl_init(HSQUIRRELVM v)
{
	SDL_SetMainReady();
	SDL_Init(SDL_INIT_VIDEO);
	return 0;
}

static SQInteger sq_sdl_quit(HSQUIRRELVM v)
{
	SDL_Quit();
	return 0;
}

static SQInteger sq_sdl_window_create(HSQUIRRELVM v)
{
	SQInteger top = sq_gettop(v);
	const SQChar *windowname = "SDL window";
	if(top > 3){
		sq_throwerror(v, "arguments num is must be 1 or 2");
		return SQ_ERROR;
	}
	if(top == 2){
		if(qr_string_get(v, 2, &windowname) == SQFalse){
			return SQ_ERROR;
		}
	}
	SDL_Window *w = SDL_CreateWindow(windowname, 100, 100, 100, 100, SDL_WINDOW_HIDDEN);
	SDL_Renderer *r = SDL_CreateRenderer(w, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
	SDL_SetRenderDrawBlendMode(r, SDL_BLENDMODE_BLEND);
	if(w == NULL || r == NULL){
		sq_throwerror(v, "SDL window initial error");
		return SQ_ERROR;
	}
	struct sdl_member *t = malloc(sizeof(struct sdl_member));
	t->w = w;
	t->r = r;
	sq_pushuserpointer(v, t);
	return 1;
}
static struct sdl_member *sdl_member_userpointer_get(HSQUIRRELVM v)
{
	SQUserPointer w;
	if(SQ_FAILED(sq_getuserpointer(v, -1, &w))){
		return NULL;
	}
	sq_pop(v, 1);
	struct sdl_member *s = w;
	return s;
}

static SQInteger sq_sdl_window_destroy(HSQUIRRELVM v)
{
	sqfunc_argment_test(v, 1);
	struct sdl_member *t = sdl_member_userpointer_get(v);
	SDL_DestroyRenderer(t->r);
	SDL_DestroyWindow(t->w);
	free(t);

	return 0;
}
static SQInteger sq_sdl_window_show(HSQUIRRELVM v)
{
	struct sdl_member *t = sdl_member_userpointer_get(v);
	SDL_ShowWindow(t->w);
	return 0;
}
static SQInteger sq_sdl_window_hide(HSQUIRRELVM v)
{
	struct sdl_member *t = sdl_member_userpointer_get(v);
	SDL_HideWindow(t->w);
	return 0;
}

static void table_member_int_set(HSQUIRRELVM v, const SQChar *name, SQInteger val)
{
	sq_pushstring(v, name, -1);
	sq_pushinteger(v, val);
	sq_newslot(v, -3, SQFalse);
}

static SQInteger sq_sdl_window_rect_get(HSQUIRRELVM v)
{
	sqfunc_argment_test(v, 1);
	struct sdl_member *t = sdl_member_userpointer_get(v);
	int x, y, w, h;
	SDL_GetWindowPosition(t->w, &x, &y);
	SDL_GetWindowSize(t->w, &w, &h);
	sq_newtable(v);
	
	table_member_int_set(v, "x", x);
	table_member_int_set(v, "y", y);
	table_member_int_set(v, "w", w);
	table_member_int_set(v, "h", h);
	return 1;
}
static SQInteger sq_sdl_window_rect_set(HSQUIRRELVM v)
{
	sqfunc_argment_test(v, 2);
	int x, y, w, h;
	if(qr_member_int_get(v, "x", &x) == SQFalse){
		sq_throwerror(v, "table x get error");
		return SQ_ERROR;
	}
	if(qr_member_int_get(v, "y", &y) == SQFalse){
		sq_throwerror(v, "table y get error");
		return SQ_ERROR;
	}
	if(qr_member_int_get(v, "w", &w) == SQFalse){
		sq_throwerror(v, "table w get error");
		return SQ_ERROR;
	}
	if(qr_member_int_get(v, "h", &h) == SQFalse){
		sq_throwerror(v, "table h get error");
		return SQ_ERROR;
	}
	sq_pop(v, 1);
	struct sdl_member *t = sdl_member_userpointer_get(v);
	assert(t != NULL);
	SDL_SetWindowPosition(t->w, x, y);
	SDL_SetWindowSize(t->w, w, h);
	return 0;
}
static SQInteger sq_sdl_vsync_wait(HSQUIRRELVM v)
{
	SDL_Event e;
	SQBool eend = SQFalse;
	while(SDL_PollEvent(&e) != 0){
		if(e.type == SDL_QUIT || (e.type == SDL_KEYUP && e.key.keysym.sym == SDLK_q)){
			eend = SQTrue;
		}
		//ここどうしましょう
/*		if(e.type == SDL_KEYDOWN){
			switch(e.key.keysym.sym){
			case SDLK_r:
				plot_redraw = 1;
				break;
			}
		}*/
	}
	sq_pushbool(v, eend);
	return 1;
}
static SQInteger sq_sdl_mainscreen_update(HSQUIRRELVM v)
{
	sqfunc_argment_test(v, 3);
	struct sdl_member *t = sdl_member_userpointer_get(v);
	int n = SDL_SetRenderTarget(t->r, NULL);
	assert(n == 0);
/*	if(n < 0){
		puts(SDL_GetError());
		assert(0);
		break;
	}*/
	//atode kesu
	SDL_SetRenderDrawColor(t->r, 0, 0x3f, 0x3f, 0xff);
	SDL_RenderClear(t->r);
	if(sq_gettype(v, -1) != OT_ARRAY){
		sq_pop(v, 1);
		sq_throwerror(v, "texture is not array");
		return SQ_ERROR;
	}
	SQBool bb = SQFalse;
	for(SQInteger i = 0; i < sq_getsize(v, -1); i++){
		sq_pushinteger(v, i);
		if(SQ_FAILED(sq_get(v, -2))){
			bb = SQTrue;
			break;
		}
		SQUserPointer w;
		if(SQ_FAILED(sq_getuserpointer(v, -1, &w))){
			bb = SQTrue;
			break;
		}
		sq_pop(v, 1);
		
		SDL_RenderCopy(t->r, (SDL_Texture *) w, NULL, NULL);
	}
	sq_pop(v, 1);
	if(bb == SQTrue){
		sq_throwerror(v, "texture is not userpointer");
		return SQ_ERROR;
	}
	SDL_RenderPresent(t->r);
	return 0;
}
const struct sq_funclist sdl_function[] = {
	{sq_sdl_init, "sdl_init"},
	{sq_sdl_quit, "sdl_quit"},
	{sq_sdl_window_create, "sdl_window_create"},
	{sq_sdl_window_destroy, "sdl_window_destroy"},
	{sq_sdl_window_rect_get, "sdl_window_rect_get"},
	{sq_sdl_window_rect_set, "sdl_window_rect_set"},
	{sq_sdl_window_show, "sdl_window_show"},
	{sq_sdl_window_hide, "sdl_window_hide"},
	{sq_sdl_vsync_wait, "sdl_vsync_wait"},
	{sq_sdl_mainscreen_update, "sdl_mainscreen_update"},
	{NULL, NULL}
};