Files
cell-sdl3/render.c
2025-12-11 10:39:24 -06:00

251 lines
7.8 KiB
C

#include "cell.h"
#include <SDL3/SDL.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "sdl.h"
#include <assert.h>
void SDL_Renderer_free(JSRuntime *rt, SDL_Renderer *renderer) {
if (renderer) SDL_DestroyRenderer(renderer);
}
void SDL_Texture_free(JSRuntime *rt, SDL_Texture *texture) {
if (texture) SDL_DestroyTexture(texture);
}
QJSCLASS(SDL_Renderer,)
QJSCLASS(SDL_Texture,)
JSC_CCALL(SDL_Renderer_clear,
SDL_Renderer *renderer = js2SDL_Renderer(js,self);
SDL_RenderClear(renderer);
)
JSC_CCALL(SDL_Renderer_present,
SDL_Renderer *ren = js2SDL_Renderer(js,self);
SDL_RenderPresent(ren);
)
JSC_CCALL(SDL_Renderer_draw_color,
SDL_Renderer *renderer = js2SDL_Renderer(js,self);
colorf color = js2color(js,argv[0]);
SDL_SetRenderDrawColorFloat(renderer, color.x, color.y, color.z, color.w);
)
JSC_CCALL(SDL_Renderer_rect,
SDL_Renderer *r = js2SDL_Renderer(js,self);
if (!JS_IsNull(argv[1])) {
colorf color = js2color(js,argv[1]);
SDL_SetRenderDrawColorFloat(r, color.x, color.y, color.z, color.w);
}
if (JS_IsArray(js,argv[0])) {
int len = JS_ArrayLength(js,argv[0]);
rect rects[len];
for (int i = 0; i < len; i++) {
JSValue val = JS_GetPropertyUint32(js,argv[0],i);
rects[i] = js2rect(js,val);
JS_FreeValue(js,val);
}
SDL_RenderFillRects(r,rects,len);
} else {
rect rect_var = js2rect(js,argv[0]);
SDL_RenderFillRect(r,&rect_var);
}
)
JSC_CCALL(SDL_Renderer_fillrect,
SDL_Renderer *r = js2SDL_Renderer(js,self);
if (!JS_IsNull(argv[1])) {
colorf color = js2color(js,argv[1]);
SDL_SetRenderDrawColorFloat(r, color.x, color.y, color.z, color.w);
}
if (JS_IsArray(js,argv[0])) {
int len = JS_ArrayLength(js,argv[0]);
rect rects[len];
for (int i = 0; i < len; i++) {
JSValue val = JS_GetPropertyUint32(js,argv[0],i);
rects[i] = js2rect(js,val);
JS_FreeValue(js,val);
}
SDL_RenderFillRects(r,rects,len);
} else {
rect rect_var = js2rect(js,argv[0]);
SDL_RenderFillRect(r,&rect_var);
}
return JS_NULL;
)
JSC_CCALL(renderer_texture,
SDL_Renderer *renderer = js2SDL_Renderer(js,self);
SDL_Texture *tex = js2SDL_Texture(js,argv[0]);
rect dst = js2rect(js,argv[1]);
if (!JS_IsNull(argv[3])) {
colorf color = js2color(js,argv[3]);
SDL_SetTextureColorModFloat(tex, color.x, color.y, color.z);
SDL_SetTextureAlphaModFloat(tex,color.w);
}
if (JS_IsNull(argv[2]))
SDL_RenderTexture(renderer,tex,NULL,&dst);
else {
rect src = js2rect(js,argv[2]);
SDL_RenderTextureRotated(renderer, tex, &src, &dst, 0, NULL, SDL_FLIP_NONE);
}
)
JSC_CCALL(renderer_load_texture,
SDL_Renderer *renderer = js2SDL_Renderer(js, self);
SDL_Surface *surf = js2SDL_Surface(js, argv[0]);
SDL_Texture *tex = SDL_CreateTextureFromSurface(renderer, surf);
if (!tex) return JS_ThrowReferenceError(js, "Could not create texture from surface: %s", SDL_GetError());
ret = SDL_Texture2js(js, tex);
JS_SetPropertyStr(js, ret, "width", number2js(js,tex->w));
JS_SetPropertyStr(js,ret,"height", number2js(js,tex->h));
)
JSC_CCALL(renderer_get_image,
SDL_Renderer *r = js2SDL_Renderer(js,self);
SDL_Surface *surf;
rect rect;
if (JS_IsNull(argv[0]))
surf = SDL_RenderReadPixels(r,NULL);
else {
rect = js2rect(js,argv[0]);
surf = SDL_RenderReadPixels(r,&rect);
}
if (!surf) return JS_ThrowReferenceError(js, "could not make surface from renderer");
return SDL_Surface2js(js,surf);
)
JSC_CCALL(renderer_line,
SDL_Renderer *r = js2SDL_Renderer(js,self);
if (!JS_IsNull(argv[1])) {
colorf color = js2color(js,argv[1]);
SDL_SetRenderDrawColorFloat(r, color.x, color.y, color.z, color.w);
}
if (JS_IsArray(js,argv[0])) {
int len = JS_ArrayLength(js,argv[0]);
vec2 points[len];
assert(sizeof(vec2) == sizeof(SDL_FPoint));
for (int i = 0; i < len; i++) {
JSValue val = JS_GetPropertyUint32(js,argv[0],i);
points[i] = js2vec2(js,val);
JS_FreeValue(js,val);
}
SDL_RenderLines(r,points,len);
}
)
JSC_CCALL(renderer_point,
SDL_Renderer *r = js2SDL_Renderer(js,self);
if (!JS_IsNull(argv[1])) {
colorf color = js2color(js,argv[1]);
SDL_SetRenderDrawColorFloat(r, color.x, color.y, color.z, color.w);
}
if (JS_IsArray(js,argv[0])) {
int len = JS_ArrayLength(js,argv[0]);
vec2 points[len];
assert(sizeof(vec2) ==sizeof(SDL_FPoint));
for (int i = 0; i < len; i++) {
JSValue val = JS_GetPropertyUint32(js,argv[0],i);
points[i] = js2vec2(js,val);
JS_FreeValue(js,val);
}
SDL_RenderPoints(r, points, len);
return JS_NULL;
}
vec2 point = js2vec2(js,argv[0]);
SDL_RenderPoint(r,point.x,point.y);
)
JSC_CCALL(renderer_logical_size,
SDL_Renderer *r = js2SDL_Renderer(js,self);
vec2 v = js2vec2(js,argv[0]);
SDL_SetRenderLogicalPresentation(r,v.x,v.y,SDL_LOGICAL_PRESENTATION_INTEGER_SCALE);
)
JSC_CCALL(renderer_viewport,
SDL_Renderer *r = js2SDL_Renderer(js,self);
if (JS_IsNull(argv[0]))
SDL_SetRenderViewport(r,NULL);
else {
rect view = js2rect(js,argv[0]);
SDL_SetRenderViewport(r,&view);
}
return JS_NULL;
)
JSC_CCALL(renderer_clip,
SDL_Renderer *r = js2SDL_Renderer(js,self);
if (JS_IsNull(argv[0]))
SDL_SetRenderClipRect(r,NULL);
else {
rect view = js2rect(js,argv[0]);
SDL_SetRenderClipRect(r,&view);
}
)
JSC_CCALL(renderer_scale,
SDL_Renderer *r = js2SDL_Renderer(js,self);
vec2 v = js2vec2(js,argv[0]);
SDL_SetRenderScale(r, v.x, v.y);
)
JSC_CCALL(renderer_vsync,
SDL_Renderer *r = js2SDL_Renderer(js,self);
SDL_SetRenderVSync(r,js2number(js,argv[0]));
)
JSC_CCALL(renderer_target,
SDL_Renderer *r = js2SDL_Renderer(js,self);
if (JS_IsNull(argv[0]))
SDL_SetRenderTarget(r, NULL);
else {
SDL_Texture *tex = js2SDL_Texture(js,argv[0]);
SDL_SetRenderTarget(r,tex);
}
)
static const JSCFunctionListEntry js_SDL_Renderer_funcs[] = {
JS_CFUNC_DEF("clear", 0, js_SDL_Renderer_clear),
JS_CFUNC_DEF("present", 0, js_SDL_Renderer_present),
JS_CFUNC_DEF("draw_color", 1, js_SDL_Renderer_draw_color),
JS_CFUNC_DEF("rect", 2, js_SDL_Renderer_rect),
JS_CFUNC_DEF("fillrect", 2, js_SDL_Renderer_fillrect),
JS_CFUNC_DEF("line", 2, js_renderer_line),
JS_CFUNC_DEF("point", 2, js_renderer_point),
JS_CFUNC_DEF("texture", 4, js_renderer_texture),
JS_CFUNC_DEF("get_image", 1, js_renderer_get_image),
JS_CFUNC_DEF("scale", 1, js_renderer_scale),
JS_CFUNC_DEF("logical_size", 1, js_renderer_logical_size),
JS_CFUNC_DEF("viewport", 1, js_renderer_viewport),
JS_CFUNC_DEF("clip", 1, js_renderer_clip),
JS_CFUNC_DEF("vsync", 1, js_renderer_vsync),
JS_CFUNC_DEF("target", 1, js_renderer_target),
JS_CFUNC_DEF("load_texture", 1, js_renderer_load_texture),
};
JSC_CCALL(SDL_Renderer_constructor,
if (argc < 1) return JS_ThrowTypeError(js, "Renderer constructor requires a window argument");
SDL_Window *win = js2SDL_Window(js, argv[0]);
SDL_Renderer *r = SDL_CreateRenderer(win, NULL);
if (!r) return JS_ThrowReferenceError(js, "Error creating renderer: %s",SDL_GetError());
SDL_SetRenderDrawBlendMode(r, SDL_BLENDMODE_BLEND);
return SDL_Renderer2js(js, r);
)
CELL_USE_INIT(
SDL_Init(SDL_INIT_VIDEO);
JSValue renderer_ctor = QJSCLASSPREP_FUNCS_CTOR(SDL_Renderer,1);
QJSCLASSPREP_NO_FUNCS(SDL_Texture)
return renderer_ctor;
)