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