- [WIP] Acabant la fase 2

- [NEW] Preparant codi per a la fase 3
This commit is contained in:
2026-04-14 21:45:25 +02:00
parent 380295aed0
commit c0d1b1fecf
12 changed files with 269 additions and 228 deletions

View File

@@ -3,7 +3,7 @@
#include "mini/view/view.h"
#include "mini/font/font.h"
#include <SDL3/SDL.h>
#include <math.h>
#define DEST(x, y) surf::state.dest_surface->p[x+y*surf::state.dest_surface->w]
#define SOURCE(x, y) surf::state.source_surface->p[x+y*surf::state.source_surface->w]
@@ -14,6 +14,16 @@ namespace mini
{
state_t state;
void init() {
state.mode = DRAWMODE_NORMAL;
state.fill_pattern = 0b1111111111111111;
}
void quit() {
}
namespace pixel {
static inline void pset_fast(int x, int y, uint8_t color) {
if (state.trans != color) DEST(x, y) = state.draw_palette[color];
@@ -343,8 +353,8 @@ namespace mini
// Ángulo en radianes
float a = angle_deg * 3.14159265f / 180.0f;
float ca = SDL_cosf(a);
float sa = SDL_sinf(a);
float ca = cosf(a);
float sa = sinf(a);
// --- 1. Bounding box rotado del rectángulo destino ---
@@ -370,10 +380,10 @@ namespace mini
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);
int bb_x0 = (int)floorf(min_x);
int bb_x1 = (int)ceilf (max_x);
int bb_y0 = (int)floorf(min_y);
int bb_y1 = (int)ceilf (max_y);
// --- 2. Rotación inversa + escalado + clipping estricto ---

View File

@@ -21,6 +21,9 @@ namespace mini
};
extern state_t state;
void init();
void quit();
namespace pixel {
void set(int x, int y, uint8_t color);
uint8_t get(int x, int y);

View File

@@ -2,7 +2,7 @@
#include "external/lua/lua.hpp"
#include "mini/win/win.h"
#include <SDL3/SDL.h>
//#include <SDL3/SDL.h>
#include <nlohmann/json.hpp>
#include <stack>
@@ -1136,7 +1136,7 @@ namespace mini
}
}
SDL_Delay(1);
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}
@@ -1293,7 +1293,7 @@ namespace mini
}
sendLogOutput(lastExceptionMessage);
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Mini Runtime Exception", lastExceptionTraceback.c_str(), NULL);
//SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Mini Runtime Exception", lastExceptionTraceback.c_str(), NULL);
return false;
}
return true;
@@ -1320,7 +1320,7 @@ namespace mini
printf("COMANDO RECIBIDO: %s\n", line.c_str());
}
} else {
SDL_Delay(1);
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}
});

View File

@@ -4,6 +4,7 @@
#include "mini/mini.h"
#include "mini/surf/surf.h"
#include "mini/draw/draw.h"
#include "mini/map/map.h"
#include "mini/pal/pal.h"
#include "mini/font/font.h"
#include "mini/win/win.h"
@@ -111,7 +112,8 @@ namespace mini
const char* str = luaL_checkstring(L, 2);
if (lua_istable(L, -1)) {
const int len = SDL_min(256, lua_rawlen(L, -1));
int len = lua_rawlen(L, -1);
if (len > 256) len = 256;
uint8_t *pal = (uint8_t*)malloc(len*3);
uint8_t *p=pal;
for (int i=1;i<=len;++i) {
@@ -283,7 +285,8 @@ namespace mini
int r,g,b;
if (lua_istable(L, -1)) {
uint32_t pal[256];
const int len = SDL_min(256, lua_rawlen(L, -1));
int len = lua_rawlen(L, -1);
if (len > 256) len = 256;
for (int i=0;i<len;++i) {
lua_rawgeti(L, -1, i+1);
lua_getfield(L, -1, "r");

122
source/mini/map/map.cpp Normal file
View File

@@ -0,0 +1,122 @@
#include "map.h"
#include "mini/surf/surf.h"
#include "mini/view/view.h"
#include "mini/draw/draw.h"
#define TILES(x, y) map_surface->p[x+y*map_surface->w]
namespace mini
{
namespace map
{
uint8_t tile_width = 8;
uint8_t tile_height = 8;
mini::surf::surface_t* map_surface = nullptr;
void init() {
}
void quit() {
map_surface = nullptr;
}
namespace surf {
void set(uint8_t surface) {
map_surface = &mini::surf::state.surfaces[surface];
}
uint8_t get()
{
for (unsigned int i=0; i<MAX_SURFACES; ++i) if (map_surface == &mini::surf::state.surfaces[i]) return i;
return 0;
}
}
void draw() {
if (!map_surface || !mini::surf::state.source_surface) return;
const int tw = tile_width;
const int th = tile_height;
int celw = map_surface->w;
int celh = map_surface->h;
int celx = 0;
int cely = 0;
int ox = view::state.origin[0];
int oy = view::state.origin[1];
int sx = ox;
int sy = oy;
// Clipping global rápido
if (sx + celw * tw < mini::surf::state.dest_surface->clip[0] ||
sy + celh * th < mini::surf::state.dest_surface->clip[1] ||
sx > mini::surf::state.dest_surface->clip[2] ||
sy > mini::surf::state.dest_surface->clip[3])
return;
// Recorte por izquierda
if (sx < mini::surf::state.dest_surface->clip[0]) {
int diff = (mini::surf::state.dest_surface->clip[0] - sx) / tw;
celx += diff;
celw -= diff;
sx += diff * tw;
}
// Recorte por arriba
if (sy < mini::surf::state.dest_surface->clip[1]) {
int diff = (mini::surf::state.dest_surface->clip[1] - sy) / th;
cely += diff;
celh -= diff;
sy += diff * th;
}
// Recorte por derecha
int max_x = mini::surf::state.dest_surface->clip[2] - sx;
if (max_x < celw * tw) celw = max_x / tw + 1;
// Recorte por abajo
int max_y = mini::surf::state.dest_surface->clip[3] - sy;
if (max_y < celh * th) celh = max_y / th + 1;
// Ahora sx, sy son relativos al origen y ya están recortados
for (int y = 0; y < celh; ++y) {
int ty = sy + y * th;
for (int x = 0; x < celw; ++x) {
uint8_t tile = tile::get(celx + x, cely + y);
if (!tile) continue;
int tx = sx + x * tw;
draw::tileblit(tile, tx - ox, ty - oy, tile_width, tile_height);
}
}
}
namespace tile {
uint8_t get(int celx, int cely) {
if (!map_surface) return 0;
if (celx < 0 || celx > (map_surface->w-1) || cely < 0 || cely > (map_surface->h-1)) return 0;
return TILES(celx, cely);
}
void set(int celx, int cely, uint8_t snum) {
if (!map_surface) return;
if (celx < 0 || celx > (map_surface->w-1) || cely < 0 || cely > (map_surface->h-1)) return;
TILES(celx, cely) = snum;
}
}
namespace cell {
uint8_t getw() { return tile_width; }
uint8_t geth() { return tile_height; }
void set(int w, int h) {
tile_width = w;
tile_height = h;
}
}
}
}

28
source/mini/map/map.h Normal file
View File

@@ -0,0 +1,28 @@
#pragma once
#include <stdint.h>
namespace mini
{
namespace map
{
void init();
void quit();
namespace surf {
void set(uint8_t surface);
uint8_t get();
}
void draw(); //int celx, int cely, int sx, int sy, uint8_t celw, uint8_t celh, uint8_t layer=0);
namespace tile {
uint8_t get(int celx, int cely);
void set(int celx, int cely, uint8_t snum);
}
namespace cell {
uint8_t getw();
uint8_t geth();
void set(int w, int h);
}
}
}

View File

@@ -4,6 +4,7 @@
#include "surf/surf.h"
#include "pal/pal.h"
#include "font/font.h"
#include "map/map.h"
#include "draw/draw.h"
#include "win/win.h"
#include "view/view.h"
@@ -22,8 +23,6 @@
#include <string.h>
#define UPDATE_ALWAYS 0
#define UPDATE_WAIT 1
#define UPDATE_TIMEOUT 2
@@ -32,37 +31,21 @@
#include <libgen.h>
#endif
int fps=0;
char config_folder[256];
uint8_t tile_width = 8;
uint8_t tile_height = 8;
char main_lua_file[200] = "main.lua";
bool override_ini = false;
int update_mode = UPDATE_ALWAYS;
int timeout = 0;
int fps=0;
uint32_t last_update = 0;
float delta_time = 0.0f;
bool should_exit = false;
bool should_quit = false;
Uint32 *pixels;
int pitch;
mini::surf::surface_t* map_surface = NULL;
int16_t beats, num_beats = 0;
void createNewProject();
@@ -100,115 +83,11 @@ void read_ini() {
//SDL_Log("'game.ini' carregat!\n");
}
#define TILES(x, y) map_surface->p[x+y*map_surface->w]
#define CURRENT(x, y) surfaces[i].p[(x)+(y)*surfaces[i].w]
namespace mini
{
namespace map
{
namespace surf {
void set(uint8_t surface) {
map_surface = &mini::surf::state.surfaces[surface];
}
uint8_t get()
{
for (unsigned int i=0; i<MAX_SURFACES; ++i) if (map_surface == &mini::surf::state.surfaces[i]) return i;
return 0;
}
}
void draw() {
if (!map_surface || !mini::surf::state.source_surface) return;
const int tw = tile_width;
const int th = tile_height;
int celw = map_surface->w;
int celh = map_surface->h;
int celx = 0;
int cely = 0;
int ox = view::state.origin[0];
int oy = view::state.origin[1];
int sx = ox;
int sy = oy;
// Clipping global rápido
if (sx + celw * tw < mini::surf::state.dest_surface->clip[0] ||
sy + celh * th < mini::surf::state.dest_surface->clip[1] ||
sx > mini::surf::state.dest_surface->clip[2] ||
sy > mini::surf::state.dest_surface->clip[3])
return;
// Recorte por izquierda
if (sx < mini::surf::state.dest_surface->clip[0]) {
int diff = (mini::surf::state.dest_surface->clip[0] - sx) / tw;
celx += diff;
celw -= diff;
sx += diff * tw;
}
// Recorte por arriba
if (sy < mini::surf::state.dest_surface->clip[1]) {
int diff = (mini::surf::state.dest_surface->clip[1] - sy) / th;
cely += diff;
celh -= diff;
sy += diff * th;
}
// Recorte por derecha
int max_x = mini::surf::state.dest_surface->clip[2] - sx;
if (max_x < celw * tw) celw = max_x / tw + 1;
// Recorte por abajo
int max_y = mini::surf::state.dest_surface->clip[3] - sy;
if (max_y < celh * th) celh = max_y / th + 1;
// Ahora sx, sy son relativos al origen y ya están recortados
for (int y = 0; y < celh; ++y) {
int ty = sy + y * th;
for (int x = 0; x < celw; ++x) {
uint8_t tile = tile::get(celx + x, cely + y);
if (!tile) continue;
int tx = sx + x * tw;
draw::tileblit(tile, tx - ox, ty - oy, tile_width, tile_height);
}
}
}
namespace tile {
uint8_t get(int celx, int cely) {
if (!map_surface) return 0;
if (celx < 0 || celx > (map_surface->w-1) || cely < 0 || cely > (map_surface->h-1)) return 0;
return TILES(celx, cely);
}
void set(int celx, int cely, uint8_t snum) {
if (!map_surface) return;
if (celx < 0 || celx > (map_surface->w-1) || cely < 0 || cely > (map_surface->h-1)) return;
TILES(celx, cely) = snum;
}
}
namespace cell {
uint8_t getw() { return tile_width; }
uint8_t geth() { return tile_height; }
void set(int w, int h) {
tile_width = w;
tile_height = h;
}
}
}
namespace sys
{
@@ -254,26 +133,6 @@ namespace mini
void reinit() {
log_msg(LOG_INFO, "STARTING A SYSTEM REINITIALIZATION\n");
// Reset view state
mini::view::init();
// Reset draw state
mini::draw::state.mode = DRAWMODE_NORMAL;
mini::draw::state.fill_pattern = 0b1111111111111111;
// Reset surf state
for (unsigned int i=0; i<MAX_SURFACES; ++i) mini::surf::destroy(i);
mini::surf::target::set(mini::surf::create(mini::win::state.width, mini::win::state.height));
mini::surf::state.dest_surface = mini::surf::state.screen_surface;
// Reset pal state
mini::pal::subpal::reset();
mini::draw::state.trans=0;
}
using namespace mini;
int main(int argc,char*argv[]){
@@ -339,12 +198,14 @@ int main(int argc,char*argv[]){
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_GAMEPAD);
log_msg(LOG_INFO, "STARTING A SYSTEM REINITIALIZATION\n");
win::init();
pad::init();
audio::init();
reinit();
view::init();
draw::init();
surf::init();
pal::init();
font::init();
lua::init(main_lua_file);
@@ -363,55 +224,58 @@ int main(int argc,char*argv[]){
uint32_t fps_timer=0;
while(!should_exit) {
if (update_mode==UPDATE_WAIT) SDL_WaitEvent(NULL);
else if (update_mode==UPDATE_TIMEOUT) SDL_WaitEventTimeout(NULL, timeout);
SDL_Event mini_eve;
while(SDL_PollEvent(&mini_eve)) {
if (mini_eve.type == SDL_EVENT_QUIT) { should_exit=true; should_quit=true; break; }
if (mini_eve.type == SDL_EVENT_TEXT_INPUT) {
SDL_strlcpy(key::state.text_input_buffer, mini_eve.text.text, sizeof(key::state.text_input_buffer));
if (update_mode==UPDATE_WAIT)
SDL_WaitEvent(NULL);
else if (update_mode==UPDATE_TIMEOUT)
SDL_WaitEventTimeout(NULL, timeout);
SDL_Event e;
while(SDL_PollEvent(&e)) {
if (e.type == SDL_EVENT_QUIT) {
should_exit=true;
should_quit=true;
break;
}
else if (e.type == SDL_EVENT_TEXT_INPUT) {
SDL_strlcpy(key::state.text_input_buffer, e.text.text, sizeof(key::state.text_input_buffer));
key::state.has_text_input = true;
}
if (mini_eve.type == SDL_EVENT_KEY_DOWN) {
#ifdef DEBUG
if (mini_eve.key.scancode == SDL_SCANCODE_F12) {
else if (e.type == SDL_EVENT_KEY_DOWN) {
#ifdef DEBUG
if (e.key.scancode == SDL_SCANCODE_F12) {
mini::surf::reloadsurfs();
//} else if (mini_eve.key.scancode == SDL_SCANCODE_F11) {
//} else if (e.key.scancode == SDL_SCANCODE_F11) {
// mini::lua::debug::toggle();
} else if (mini_eve.key.scancode == SDL_SCANCODE_F5) {
} else if (e.key.scancode == SDL_SCANCODE_F5) {
should_exit=true;
} else {
key::state.just_pressed = mini_eve.key.scancode;
key::state.just_pressed = e.key.scancode;
}
#else
key::state.just_pressed = mini_eve.key.scancode;
#endif
#else
key::state.just_pressed = e.key.scancode;
#endif
}
if (mini_eve.type == SDL_EVENT_MOUSE_BUTTON_UP) {
else if (e.type == SDL_EVENT_MOUSE_BUTTON_UP) {
if (mouse::state.discard)
mouse::state.discard = false;
else
if (mini_eve.button.clicks==2 && mini_eve.button.button==SDL_BUTTON_LEFT) {
if (e.button.clicks==2 && e.button.button==SDL_BUTTON_LEFT) {
mouse::state.double_click = true;
} else {
mouse::state.just_pressed = mini_eve.button.button;
mouse::state.just_pressed = e.button.button;
}
}
if (mini_eve.type == SDL_EVENT_MOUSE_WHEEL) {
mouse::state.wheel = mini_eve.wheel.y;
else if (e.type == SDL_EVENT_MOUSE_WHEEL) {
mouse::state.wheel = e.wheel.y;
}
if (mini_eve.type == SDL_EVENT_GAMEPAD_BUTTON_DOWN) {
pad::state.just_pressed = mini_eve.gbutton.button;
else if (e.type == SDL_EVENT_GAMEPAD_BUTTON_DOWN) {
pad::state.just_pressed = e.gbutton.button;
}
/*if ( (mini_eve.type == SDL_WINDOWEVENT) &&
(mini_eve.window.windowID == windowID) &&
(mini_eve.window.event == SDL_WINDOWEVENT_MOVED) ) {
windowpos_x = mini_eve.window.data1-4;
windowpos_y = mini_eve.window.data2-36;
//SDL_GetWindowPosition(mini_win, &windowpos_x, &windowpos_y);
}*/
}
key::state.keys = SDL_GetKeyboardState(NULL);
// Update mouse
float real_mouse_x, real_mouse_y;
mouse::state.buttons = SDL_GetMouseState(&real_mouse_x, &real_mouse_y);
float mx, my;
@@ -419,6 +283,7 @@ int main(int argc,char*argv[]){
mouse::state.x = int(mx/win::state.zoom);
mouse::state.y = int(my/win::state.zoom);
// Do update
if (SDL_GetTicks()-dt>13) {
dt = SDL_GetTicks();
@@ -430,19 +295,27 @@ int main(int argc,char*argv[]){
} else {
exception_loop();
}
if (beats==0)beats=num_beats;
if (beats>0)beats--;
if (beats == 0) beats = num_beats;
if (beats > 0) beats--;
// Reset keyboard, mouse and pad
key::state.just_pressed = 0;
mouse::state.just_pressed = 0;
key::state.has_text_input = false;
key::state.text_input_buffer[0] = '\0';
mouse::state.just_pressed = 0;
mouse::state.double_click = false;
mouse::state.wheel = 0;
pad::state.just_pressed = SDL_GAMEPAD_BUTTON_INVALID;
}
// Render frame
SDL_SetRenderTarget(win::state.renderer, win::state.tex_shader);
SDL_SetRenderDrawColor(win::state.renderer, 0, 0, 0, 255);
SDL_RenderClear(win::state.renderer);
//SDL_SetRenderDrawColor(win::state.renderer, 0, 0, 0, 255);
//SDL_RenderClear(win::state.renderer);
uint32_t *pixels;
int pitch;
SDL_LockTexture(win::state.tex_back, NULL, (void**)&pixels, &pitch);
for (uint32_t i=0;i<surf::state.screen_surface->size;++i) pixels[i] = pal::palette[surf::state.screen_surface->p[i]];
SDL_UnlockTexture(win::state.tex_back);
@@ -459,17 +332,19 @@ int main(int argc,char*argv[]){
fps_timer = SDL_GetTicks();
}
}
lua::quit();
audio::quit();
//Mix_Quit();
for (unsigned int i=0;i<MAX_SURFACES;++i) surf::destroy(i);
surf::state.dest_surface = surf::state.source_surface = map_surface = NULL;
surf::quit();
map::quit();
win::quit();
SDL_Quit();
}
lua::cleanup();
return 0;
}

View File

@@ -7,25 +7,6 @@ void exception_loop();
namespace mini
{
namespace map
{
namespace surf {
void set(uint8_t surface);
uint8_t get();
}
void draw(); //int celx, int cely, int sx, int sy, uint8_t celw, uint8_t celh, uint8_t layer=0);
namespace tile {
uint8_t get(int celx, int cely);
void set(int celx, int cely, uint8_t snum);
}
namespace cell {
uint8_t getw();
uint8_t geth();
void set(int w, int h);
}
}
namespace sys
{

View File

@@ -2,10 +2,10 @@
#include "mini/file/file.h"
#include "mini/draw/draw.h"
#include <SDL3/SDL.h>
#include <stdlib.h>
#define clamp(x,a,b) (((x) < (a)) ? (a) : (((x) > (b)) ? (b) : (x)))
namespace mini
{
namespace pal
@@ -13,6 +13,11 @@ namespace mini
uint32_t palette[256] = { 0xFF1a1c2c, 0xFF5d275d, 0xFFb13e53, 0xFFef7d57, 0xFFffcd75, 0xFFa7f070, 0xFF38b764, 0xFF257179,
0xFF29366f, 0xFF3b5dc9, 0xFF41a6f6, 0xFF73eff7, 0xFFf4f4f4, 0xFF94b0c2, 0xFF566c86, 0xFF333c57 };
void init() {
pal::subpal::reset();
draw::state.trans=0;
}
uint32_t* LoadPalette(uint8_t *buffer, uint16_t *size = NULL )
{
buffer += 10;
@@ -67,8 +72,8 @@ namespace mini
namespace subpal {
uint8_t set(uint8_t index, uint8_t color) {
const uint8_t old = draw::state.draw_palette[SDL_clamp(index,0,255)];
draw::state.draw_palette[SDL_clamp(index,0,255)] = SDL_clamp(color,0,255);
const uint8_t old = draw::state.draw_palette[clamp(index,0,255)];
draw::state.draw_palette[clamp(index,0,255)] = clamp(color,0,255);
return old;
}

View File

@@ -8,6 +8,8 @@ namespace mini
{
extern uint32_t palette[256];
void init();
uint32_t *load(const char* filename, uint16_t *palsize=nullptr);
void set(uint32_t *pal);
namespace color {

View File

@@ -5,8 +5,7 @@
#include "aux/log.h"
#include "mini/file/file.h"
#include "mini/draw/draw.h"
#include <SDL3/SDL.h>
#include "mini/win/win.h"
#include <stdlib.h>
@@ -17,6 +16,16 @@ namespace mini
state_t state;
void init() {
target::set(create(win::state.width, win::state.height));
state.dest_surface = state.screen_surface;
}
void quit() {
for (unsigned int i=0;i<MAX_SURFACES;++i) surf::destroy(i);
state.dest_surface = state.source_surface = NULL;
}
uint8_t create(int w, int h) {
unsigned int i = 0;
while (i<MAX_SURFACES && state.surfaces[i].p != NULL) ++i;
@@ -150,7 +159,7 @@ namespace mini
void cls(uint8_t color) {
const uint8_t col = draw::state.draw_palette[color];
SDL_memset(state.dest_surface->p, col, state.dest_surface->size);
memset(state.dest_surface->p, col, state.dest_surface->size);
}
namespace target {

View File

@@ -29,6 +29,9 @@ namespace mini
};
extern state_t state;
void init();
void quit();
uint8_t create(int w, int h);
uint8_t load(const char* filename, const bool external = false);
uint8_t load(uint8_t* buffer, const char* name);