- [WIP] Puta que susto, una regla mal feta en el .gitignore i ja no comitaba res

- Canvi de comp
This commit is contained in:
2026-04-11 16:39:47 +02:00
parent 14a7fda8b7
commit 0142d79d91
37 changed files with 6375 additions and 2 deletions

586
source/mini/mini.cpp Normal file
View File

@@ -0,0 +1,586 @@
#include "mini.h"
#include "version.h"
#include "surf/surf.h"
#include "font/font.h"
#include "draw/draw.h"
#include "win/win.h"
#include "view/view.h"
#include "shader/shader.h"
#include "audio/audio.h"
#include "mouse/mouse.h"
#include "key/key.h"
#include "pad/pad.h"
#include "file/file.h"
#include "lua/lua.h"
#include "aux/log.h"
#include "aux/default_font_gif.h"
#include "aux/default_font_fnt.h"
#include <SDL3/SDL.h>
#include <string.h>
#define UPDATE_ALWAYS 0
#define UPDATE_WAIT 1
#define UPDATE_TIMEOUT 2
#ifdef MACOS_BUNDLE
#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;
uint32_t last_update = 0;
float delta_time = 0.0f;
bool should_exit = false;
bool should_quit = false;
Uint32 *pixels;
int pitch;
uint32_t palette[256] = { 0xFF1a1c2c, 0xFF5d275d, 0xFFb13e53, 0xFFef7d57, 0xFFffcd75, 0xFFa7f070, 0xFF38b764, 0xFF257179,
0xFF29366f, 0xFF3b5dc9, 0xFF41a6f6, 0xFF73eff7, 0xFFf4f4f4, 0xFF94b0c2, 0xFF566c86, 0xFF333c57 };
surf::surface_t* map_surface = NULL;
int16_t beats, num_beats = 0;
void createNewProject();
char* get_value_from_line(char* line) {
char* equal_character = strchr(line, '=');
if (equal_character == NULL) return NULL;
*equal_character = '\0';
return ++equal_character;
}
void read_ini() {
int size;
FILE *f = mini::file::getfilepointer("game.ini", size); // fopen("game.ini", "r");
char line[1024];
if (f == NULL) { log_msg(LOG_FAIL, "No s'ha pogut obrir 'game.ini'\n"); exit(-1); }
log_msg(LOG_OK, "'game.ini' carregat\n");
while (fgets(line, sizeof(line), f)) {
char *value = get_value_from_line(line);
if (value != NULL) {
value[strlen(value)-1] = '\0';
if (strcmp(line, "title") == 0) { strcpy(mini::win::state.title, value); log_msg(LOG_VERBOSE, "title = %s\n", mini::win::state.title); }
else if (strcmp(line, "config") == 0) { strcpy(config_folder, value); log_msg(LOG_VERBOSE, "config = %s\n", config_folder); }
else if (strcmp(line, "width") == 0) { mini::win::state.width = atoi(value); log_msg(LOG_VERBOSE, "screen width = %i\n", mini::win::state.width); }
else if (strcmp(line, "height") == 0) { mini::win::state.height = atoi(value); log_msg(LOG_VERBOSE, "screen height = %i\n", mini::win::state.height); }
else if (strcmp(line, "zoom") == 0) { mini::win::state.zoom = atoi(value); log_msg(LOG_VERBOSE, "screen zoom = %i\n", mini::win::state.zoom); }
else if (strcmp(line, "fullscreen") == 0) { mini::win::state.fullscreen = atoi(value); log_msg(LOG_VERBOSE, "screen sullscreen = %i\n", mini::win::state.fullscreen); }
//else if (strcmp(line, "files") == 0) {
//lua_files = (char*)malloc(strlen(value));
// strcpy(lua_files, value);
//}
}
}
fclose(f);
//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;
}
}
static inline void tileblit(uint8_t n, int x, int y) {
const int tw = tile_width;
const int th = tile_height;
const int tiles_per_row = mini::surf::state.source_surface->w / tw;
// Coordenadas del tile dentro del spritesheet
int tx = (n % tiles_per_row) * tw;
int ty = (n / tiles_per_row) * th;
int src_y = ty;
for (int yi = 0; yi < th; ++yi) {
int src_x = tx;
for (int xi = 0; xi < tw; ++xi) {
uint8_t c = mini::draw::pixel::get(src_x, src_y);
mini::draw::pixel::subst_pset(x + xi, y + yi, c);
src_x++;
}
src_y++;
}
}
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;
tileblit(tile, tx - ox, ty - oy);
}
}
}
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 pal
{
uint32_t *load(const char* filename, uint16_t *palsize) {
int size;
uint8_t *buffer = (uint8_t*)file::getfilebuffer(filename, size);
// [TODO]
uint32_t *pal = nullptr; //LoadPalette(buffer, palsize);
free(buffer);
return pal;
}
void set(uint32_t *pal) {
for (int i=0; i<256; ++i) palette[i] = pal[i] | 0xff000000;
}
namespace color {
void set(uint8_t index, uint32_t color) {
palette[index] = color | 0xff000000;
}
uint32_t get(uint8_t index) {
return palette[index];
}
}
namespace trans {
void set(uint8_t index) {
ds::trans = index;
}
uint8_t get() {
return ds::trans;
}
}
namespace subpal {
uint8_t set(uint8_t index, uint8_t color) {
const uint8_t old = ds::draw_palette[SDL_clamp(index,0,255)];
ds::draw_palette[SDL_clamp(index,0,255)] = SDL_clamp(color,0,255);
return old;
}
void reset() {
for (int i=0;i<256;++i) ds::draw_palette[i]=i;
}
}
}
namespace sys
{
float delta() {
return delta_time;
}
float time() {
return float(SDL_GetTicks())/1000.0f;
}
bool beat(int16_t i) {
if (i<0) {
return beats==0;
} else {
beats=num_beats=i;
return false;
}
}
int getfps() {
return fps;
}
namespace update {
void set(const int value, const int t) {
update_mode = value;
timeout = t;
}
int get() {
return update_mode;
}
}
void exit() {
should_exit = true;
should_quit = true;
}
}
}
void reinit() {
log_msg(LOG_INFO, "STARTING A SYSTEM REINITIALIZATION\n");
// Reset view state
mini::view::init();
// Reset draw state
ds::mode = DRAWMODE_NORMAL;
ds::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();
ds::trans=0;
}
using namespace mini;
int main(int argc,char*argv[]){
#ifdef DEBUG
SDL_SetLogPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG);
log_msg(LOG_UNSALTED, "MINI v%s\n",MINI_VERSION);
#endif
// Gestió de arguments
// ===============================================================
if (argc>1)
{
if (argv[1][0]=='-' && argv[1][1]=='-') {
const char *command = &argv[1][2];
if (strcmp(command, "new")==0) {
createNewProject();
exit(0);
} else if (strcmp(command, "version")==0) {
exit(0);
}
} else if (strstr(argv[1], ".lua")!=nullptr) {
file::setresourcefolder("./");
file::setsource(SOURCE_FOLDER);
strcpy(main_lua_file, argv[1]);
strcpy(mini::win::state.title, argv[1]);
override_ini = true;
} else if (strstr(argv[1], ".jf2")!=nullptr) {
file::setresourcefilename(argv[1]);
file::setsource(SOURCE_FILE);
} else {
char path[256] = "./";
strcat(path, argv[1]);
file::setresourcefolder(path);
}
}
#ifdef MACOS_BUNDLE
char res_file[255] = "";
strcpy(res_file, dirname(argv[0]));
strcat(res_file, "/../Resources/data.jrf");
file::setresourcefilename(res_file);
#endif
while (!should_quit) {
should_exit=false;
// READ INI
if (!override_ini)
{
read_ini();
file::setconfigfolder(config_folder);
const char *zoom = file::getconfigvalue("zoom");
if (zoom) win::state.zoom=atoi(zoom);
const char *fullscreen = file::getconfigvalue("fullscreen");
if (fullscreen) win::state.fullscreen=strcmp(fullscreen, "true")==0?true:false;
const char *cursor = file::getconfigvalue("cursor");
if (cursor) win::state.cursor=strcmp(cursor, "true")?true:false;
const char *music_enabled = file::getconfigvalue("music");
if (music_enabled) audio::music::enable::set(strcmp(music_enabled, "true")==0?true:false);
const char *sound_enabled = file::getconfigvalue("sound");
if (sound_enabled) audio::sound::enable::set(strcmp(sound_enabled, "true")==0?true:false);
}
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_GAMEPAD);
win::init();
pad::init();
audio::init();
reinit();
uint8_t font_surf = surf::load(default_font_gif, "default_font");
//surfaces[font_surf].flags |= SURF_GENERATED;
font::load_from_buffer((const char*)default_font_fnt, 0, "default_font");
current_font = &fonts[0];
lua::init(main_lua_file);
lua::callbacks::init();
Uint32 dt=SDL_GetTicks();
key::state.just_pressed = 0;
key::state.has_text_input = false;
pad::state.just_pressed = SDL_GAMEPAD_BUTTON_INVALID;
mouse::state.just_pressed = 0;
mouse::state.wheel = 0;
mouse::state.double_click = false;
int fps_counter=0;
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));
key::state.has_text_input = true;
}
if (mini_eve.type == SDL_EVENT_KEY_DOWN) {
#ifdef DEBUG
if (mini_eve.key.scancode == SDL_SCANCODE_F12) {
mini::surf::reloadsurfs();
//} else if (mini_eve.key.scancode == SDL_SCANCODE_F11) {
// mini::lua::debug::toggle();
} else if (mini_eve.key.scancode == SDL_SCANCODE_F5) {
should_exit=true;
} else {
key::state.just_pressed = mini_eve.key.scancode;
}
#else
key::state.just_pressed = mini_eve.key.scancode;
#endif
}
if (mini_eve.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) {
mouse::state.double_click = true;
} else {
mouse::state.just_pressed = mini_eve.button.button;
}
}
if (mini_eve.type == SDL_EVENT_MOUSE_WHEEL) {
mouse::state.wheel = mini_eve.wheel.y;
}
if (mini_eve.type == SDL_EVENT_GAMEPAD_BUTTON_DOWN) {
pad::state.just_pressed = mini_eve.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);
float real_mouse_x, real_mouse_y;
mouse::state.buttons = SDL_GetMouseState(&real_mouse_x, &real_mouse_y);
float mx, my;
SDL_RenderCoordinatesFromWindow(win::state.renderer, real_mouse_x, real_mouse_y, &mx, &my);
mouse::state.x = int(mx/win::state.zoom)-view::state.origin[0];
mouse::state.y = int(my/win::state.zoom)-view::state.origin[1];
if (SDL_GetTicks()-dt>13) {
dt = SDL_GetTicks();
if (lua::running()) {
delta_time = float(SDL_GetTicks() - last_update)/1000.0f;
last_update = SDL_GetTicks();
lua::callbacks::update();
} else {
exception_loop();
}
if (beats==0)beats=num_beats;
if (beats>0)beats--;
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.double_click = false;
mouse::state.wheel = 0;
pad::state.just_pressed = SDL_GAMEPAD_BUTTON_INVALID;
}
SDL_SetRenderTarget(win::state.renderer, win::state.tex_shader);
SDL_SetRenderDrawColor(win::state.renderer, 0, 0, 0, 255);
SDL_RenderClear(win::state.renderer);
SDL_LockTexture(win::state.tex_back, NULL, (void**)&pixels, &pitch);
for (uint32_t i=0;i<surf::state.screen_surface->size;++i) pixels[i] = palette[surf::state.screen_surface->p[i]];
SDL_UnlockTexture(win::state.tex_back);
SDL_RenderTexture(win::state.renderer, win::state.tex_back, NULL, NULL); //NEW
shader::render();
//SDL_RenderTexture(mini_ren, mini_bak, NULL, NULL);
//SDL_RenderPresent(mini_ren);
fps_counter++;
if (SDL_GetTicks()>=(fps_timer+1000)) {
fps = fps_counter;
fps_counter=0;
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;
win::quit();
SDL_Quit();
}
lua::cleanup();
return 0;
}
void createNewProject() {
if (mini::file::createFolder("data")) {
log_msg(LOG_OK, "Directori 'data' creat\n");
} else {
log_msg(LOG_FAIL, "No s'ha pogut crear la carpeta 'data'\n");
exit(-1);
}
FILE *f = fopen("./data/game.ini", "w");
if (f) {
log_msg(LOG_OK, "Arxiu 'data/game.ini' creat\n");
} else {
log_msg(LOG_FAIL, "No s'ha pogut crear l'arxiu 'data/game.ini'\n");
exit(-1);
}
fprintf(f, "title=NEW MINI PROJECT\nconfig=newminiproject\nwidth=320\nheight=240\nzoom=2\n");
fclose(f);
f = fopen("./data/main.lua", "w");
if (f) {
log_msg(LOG_OK, "Arxiu 'data/main.lua' creat\n");
} else {
log_msg(LOG_FAIL, "No s'ha pogut crear l'arxiu 'data/main.lua'\n");
exit(-1);
}
fprintf(f, "function mini.init()\n\nend\n\nfunction mini.update()\n surf.cls(0)\nend\n");
fclose(f);
log_msg(LOG_OK, "Projecte nou creat. Ja està fet lo més dificil del jailgame!\n");
}