VERSIÓ 1.4.8:

- [NEW] draw.surfrot
This commit is contained in:
2026-03-21 10:15:23 +01:00
parent d573c159fa
commit 74cb8cb0f8
6 changed files with 156 additions and 6 deletions

View File

@@ -1,6 +1,7 @@
--require "ia.other" --require "ia.other"
x=0 x=0
rot=0
function mini.init() function mini.init()
s = surf.load("gfx/logo.gif") s = surf.load("gfx/logo.gif")
@@ -21,7 +22,7 @@ end
function mini.update() function mini.update()
surf.cls(0) 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) draw.text("PRESS START", 60, 110, 28)
if key.press(key.ESCAPE) then sys.quit() end if key.press(key.ESCAPE) then sys.quit() end
@@ -48,4 +49,5 @@ function mini.update()
font.spacing(0) font.spacing(0)
draw.text("0146",100,50,28) draw.text("0146",100,50,28)
font.current(font.DEFAULT) font.current(font.DEFAULT)
rot=rot+1
end end

View File

@@ -577,7 +577,11 @@ extern "C" {
int dx = luaL_checknumber(L, 5); int dx = luaL_checknumber(L, 5);
int dy = luaL_checknumber(L, 6); int dy = luaL_checknumber(L, 6);
float a = luaL_checknumber(L, 7); 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; return 0;
} }

137
mini.cpp
View File

@@ -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) void blit_r(int sx, int sy, int sw, int sh, int x, int y, float a)
{ {
const int x0 = sw>>1; 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) { void tline(int x0, int y0, int x1, int y1, float mx, float my, float mdx, float mdy) {
int x, y; int x, y;

3
mini.h
View File

@@ -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 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(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 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); void thline(int x0, int y, int x1, float mx, float my, float mdx=0.125f, float mdy=0.0f);

View File

@@ -1,3 +1,3 @@
#pragma once #pragma once
#define MINI_VERSION "1.4.7" #define MINI_VERSION "1.4.8"

View File

@@ -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 x number
---@param y number ---@param y number
---@param a 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 ---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 ---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 ---(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 text string
---@param x number ---@param x number