From 74cb8cb0f829f3c4d6ad6fa6a53d3e4fcd4cc796 Mon Sep 17 00:00:00 2001 From: Raimon Zamora Date: Sat, 21 Mar 2026 10:15:23 +0100 Subject: [PATCH] =?UTF-8?q?VERSI=C3=93=201.4.8:=20-=20[NEW]=20draw.surfrot?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data/main.lua | 4 +- lua.cpp | 6 +- mini.cpp | 137 +++++++++++++++++++++++++++++++++++++++++++++ mini.h | 3 +- version.h | 2 +- vscode/library.lua | 10 +++- 6 files changed, 156 insertions(+), 6 deletions(-) diff --git a/data/main.lua b/data/main.lua index 8bc70c2..d98863d 100644 --- a/data/main.lua +++ b/data/main.lua @@ -1,6 +1,7 @@ --require "ia.other" x=0 +rot=0 function mini.init() s = surf.load("gfx/logo.gif") @@ -21,7 +22,7 @@ end function mini.update() surf.cls(0) - draw.surf(0, 0, 160, 144, 0, 0) + draw.surfrot(0, 0, 160, 144, 120, 78, rot) draw.text("PRESS START", 60, 110, 28) if key.press(key.ESCAPE) then sys.quit() end @@ -48,4 +49,5 @@ function mini.update() font.spacing(0) draw.text("0146",100,50,28) font.current(font.DEFAULT) + rot=rot+1 end diff --git a/lua.cpp b/lua.cpp index 9221b70..766f6f2 100644 --- a/lua.cpp +++ b/lua.cpp @@ -577,7 +577,11 @@ extern "C" { int dx = luaL_checknumber(L, 5); int dy = luaL_checknumber(L, 6); float a = luaL_checknumber(L, 7); - blit_r(sx, sy, sw, sh, dx, dy, a); + int dw = luaL_optnumber(L, 8, 0); + int dh = luaL_optnumber(L, 9, 0); + bool flip_x = lua_toboolean(L, 10); + bool flip_y = lua_toboolean(L, 11); + blit_r(sx, sy, sw, sh, dx, dy, dw, dh, flip_x, flip_y, a); return 0; } diff --git a/mini.cpp b/mini.cpp index 544f493..cffb6de 100644 --- a/mini.cpp +++ b/mini.cpp @@ -1351,6 +1351,7 @@ void blit(int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, bool f } } +/* void blit_r(int sx, int sy, int sw, int sh, int x, int y, float a) { const int x0 = sw>>1; @@ -1373,6 +1374,142 @@ void blit_r(int sx, int sy, int sw, int sh, int x, int y, float a) } } } +*/ + +void blit_r(int sx, int sy, int sw, int sh, + int dx, int dy, int dw, int dh, + bool flip_x, bool flip_y, + float angle_deg) +{ + if (dw == 0) dw = sw; + if (dh == 0) dh = sh; + + // Centro del destino (rectángulo sin rotar) + float dcx = dx + dw * 0.5f; + float dcy = dy + dh * 0.5f; + + // Centro del subrectángulo origen + float scx = sx + sw * 0.5f; + float scy = sy + sh * 0.5f; + + // Escalado destino -> origen + float inv_scale_x = float(sw) / float(dw); + float inv_scale_y = float(sh) / float(dh); + + // Flips integrados en la escala + if (flip_x) inv_scale_x = -inv_scale_x; + if (flip_y) inv_scale_y = -inv_scale_y; + + // Ángulo en radianes + float a = angle_deg * 3.14159265f / 180.0f; + float ca = SDL_cosf(a); + float sa = SDL_sinf(a); + + // --- 1. Bounding box rotado del rectángulo destino --- + + float hx = dw * 0.5f; + float hy = dh * 0.5f; + + float vx[4] = { -hx, hx, -hx, hx }; + float vy[4] = { -hy, -hy, hy, hy }; + + float min_x = 1e9f, max_x = -1e9f; + float min_y = 1e9f, max_y = -1e9f; + + for (int i = 0; i < 4; ++i) { + float rr_x = vx[i] * ca - vy[i] * sa; + float rr_y = vx[i] * sa + vy[i] * ca; + + float dxp = dcx + rr_x; + float dyp = dcy + rr_y; + + if (dxp < min_x) min_x = dxp; + if (dxp > max_x) max_x = dxp; + if (dyp < min_y) min_y = dyp; + if (dyp > max_y) max_y = dyp; + } + + int bb_x0 = (int)SDL_floorf(min_x); + int bb_x1 = (int)SDL_ceilf (max_x); + int bb_y0 = (int)SDL_floorf(min_y); + int bb_y1 = (int)SDL_ceilf (max_y); + + // --- 2. Rotación inversa + escalado + clipping estricto --- + + for (int y = bb_y0; y <= bb_y1; ++y) { + for (int x = bb_x0; x <= bb_x1; ++x) { + + // Coordenadas relativas al centro destino + float rx = x - dcx; + float ry = y - dcy; + + // Rotación inversa + float ux = rx * ca + ry * sa; + float uy = -rx * sa + ry * ca; + + // Escalado destino -> origen (con flips) + float sxp = scx + ux * inv_scale_x; + float syp = scy + uy * inv_scale_y; + + // Clipping estricto al subrectángulo origen + if (sxp < sx || sxp >= sx + sw || + syp < sy || syp >= sy + sh) + continue; // no pintamos nada + + uint8_t color = sget((int)sxp, (int)syp); + pset(x, y, color); + } + } +} + +/*void blit_r(int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, bool flip_x, bool flip_y, float angle_deg) +{ + if (dw == 0) dw = sw; + if (dh == 0) dh = sh; + + // Escalado origen→destino + float sdx = float(sw) / float(dw); + float sdy = float(sh) / float(dh); + + // Centro del destino + float dcx = dx + dw * 0.5f; + float dcy = dy + dh * 0.5f; + + // Centro del origen + float scx = sx + sw * 0.5f; + float scy = sy + sh * 0.5f; + + // Flips: invertir escala + if (flip_x) sdx = -sdx; + if (flip_y) sdy = -sdy; + + // Ángulo en radianes + float a = angle_deg * 3.14159265f / 180.0f; + float ca = SDL_cosf(a); + float sa = SDL_sinf(a); + + // Bucle principal + for (int y = dy; y < dy + dh; ++y) { + for (int x = dx; x < dx + dw; ++x) { + + // Coordenadas destino relativas al centro + float rx = x - dcx; + float ry = y - dcy; + + // Rotación inversa (para muestreo) + float orx = rx * ca + ry * sa; + float ory = -rx * sa + ry * ca; + + // Convertir a coordenadas de la fuente + float sxp = scx + orx * sdx; + float syp = scy + ory * sdy; + + // Muestreo nearest neighbor + uint8_t color = sget(int(sxp), int(syp)); + pset(x, y, color); + } + } +}*/ void tline(int x0, int y0, int x1, int y1, float mx, float my, float mdx, float mdy) { int x, y; diff --git a/mini.h b/mini.h index a051a8f..7b1eefe 100644 --- a/mini.h +++ b/mini.h @@ -217,7 +217,8 @@ void sset(int x, int y, uint8_t color); void spr(uint8_t n, int x, int y, float w = 1.0f, float h = 1.0f, bool flip_x = false, bool flip_y = false); void blit(int sx, int sy, int sw, int sh, int dx, int dy, int dw=0, int dh=0, bool flip_x = false, bool flip_y = false, bool invert = false); -void blit_r(int sx, int sy, int sw, int sh, int x, int y, float a); +//void blit_r(int sx, int sy, int sw, int sh, int x, int y, float a); +void blit_r(int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, bool flip_x, bool flip_y, float angle_deg); void tline(int x0, int y0, int x1, int y1, float mx, float my, float mdx=0.125f, float mdy=0.0f); void thline(int x0, int y, int x1, float mx, float my, float mdx=0.125f, float mdy=0.0f); diff --git a/version.h b/version.h index 3bd2f34..a84ab09 100644 --- a/version.h +++ b/version.h @@ -1,3 +1,3 @@ #pragma once -#define MINI_VERSION "1.4.7" +#define MINI_VERSION "1.4.8" diff --git a/vscode/library.lua b/vscode/library.lua index bfae7e5..a1e9d02 100644 --- a/vscode/library.lua +++ b/vscode/library.lua @@ -320,9 +320,15 @@ function draw.surf(sx, sy, sw, sh, dx, dy, dw, dh, flip_x, flip_y, invert) end ---@param x number ---@param y number ---@param a number +---@optional dw number +---@optional dh number +---@optional boolean flip_x +---@optional boolean flip_y +---@optional boolean invert ---Blit the region starting at (sx,sy) and size (sw, sh) from the source surface ----to the position (dx, dy) of the target surface, rotating it by a degrees -function draw.surfrot(sx, sy, sw, sh, x, y, a) end +---to the position (dx, dy) of the target surface, rotating it by a degrees, +---(and optionally of size (dw, dh)) optionally flipping it horizontally or vertically +function draw.surfrot(sx, sy, sw, sh, x, y, a, dw, dh, flip_x, flip_y) end ---@param text string ---@param x number