// // Created by rov on 12/26/25. // #include "render.h" #include "window.h" #include "gui.h" #define MAP_WIDTH_TILES 15 #define MAP_HEIGHT_TILES 11 #define TILE_SIZE 32 typedef struct { uint16_t groundSpriteID; } MapTile; MapTile g_ClientMapData[MAP_WIDTH_TILES][MAP_HEIGHT_TILES]; void Map_LoadSampleData() { SDL_Log("Map_LoadSampleData: Populating dummy map..."); // These IDs are guesses for Tibia 1.03 based on standard asset order. // If these show up as items (like swords/apples), try swapping them. // Usually: 0-100 contains basic ground tiles. uint16_t ID_GRASS = 45; uint16_t ID_DIRT = 40; uint16_t ID_STONE = 50; for (int x = 0; x < MAP_WIDTH_TILES; x++) { for (int y = 0; y < MAP_HEIGHT_TILES; y++) { // 1. Default to Grass uint16_t tileID = ID_GRASS; // 2. Create a Checkerboard pattern if ((x + y) % 2 == 0) { tileID = ID_DIRT; } // 3. Create a Stone path in the middle row if (y == 5) { tileID = ID_STONE; } // 4. Assign to the map g_ClientMapData[x][y].groundSpriteID = x * MAP_HEIGHT_TILES + y; } } } void Render_Frame(App_t* app) { Gui_StartRender(); SDL_Renderer *renderer = Window_GetRenderer(); SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_RenderClear(renderer); Render_MainWindowBackground(app); Render_GameView(app); Gui_Render(&app->gui, &app->configParams, app->isInGame); Gui_FinishRender(); SDL_RenderPresent(renderer); } void Render_MainWindowBackground(const App_t *app) { SDL_Renderer *renderer = Window_GetRenderer(); if (app->bitmap.marbleTexture == NULL) { SDL_SetRenderDrawColor(renderer, 64, 64, 64, 255); SDL_RenderClear(renderer); return; } // const int TILE_SIZE = 128; // Calculate how many tiles we need to cover the screen const int tilesX = app->metrics.screenWidth / TILE_SIZE + 1; const int tilesY = app->metrics.screenHeight / TILE_SIZE + 1; for (int y = 0; y < tilesY; y++) { for (int x = 0; x < tilesX; x++) { SDL_FRect destRect = { (float) (x * TILE_SIZE), (float) (y * TILE_SIZE), (float) TILE_SIZE, (float) TILE_SIZE }; SDL_RenderTexture(renderer, app->bitmap.marbleTexture, NULL, &destRect); } } } void Render_GameView(const App_t *app) { if (!app->isInGame) { Render_TitleScreen(app); return; } Render_Game(app); } void Render_TitleScreen(const App_t *app) { // TODO: properly calculate the window sizes and spacings SDL_Renderer *renderer = Window_GetRenderer(); int winW, winH; SDL_GetRenderOutputSize(renderer, &winW, &winH); const SDL_FRect destRect = { 0.0f, 30.0f, (float)winW, (float)winH - 150.0f }; SDL_RenderTexture(renderer, app->bitmap.tibiaTexture, NULL, &destRect); } void Render_Game(const App_t *app) { SDL_Renderer *renderer = Window_GetRenderer(); for (int x = 0; x < MAP_WIDTH_TILES; x++) { for (int y = 0; y < MAP_HEIGHT_TILES; y++) { const MapTile* tile = &g_ClientMapData[x][y]; if (tile->groundSpriteID == 0) { continue; } const int screenX = x * TILE_SIZE; const int screenY = y * TILE_SIZE; SDL_Texture* texture = Objects_GetSpriteTexture(&app->objects, tile->groundSpriteID); if (texture) { SDL_FRect destRect = { (float)screenX, (float)screenY, (float)TILE_SIZE, (float)TILE_SIZE }; SDL_RenderTexture(renderer, texture, NULL, &destRect); } else { SDL_FRect destRect = { (float)screenX, (float)screenY, 32.0f, 32.0f }; SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255); // Green for ground SDL_RenderFillRect(renderer, &destRect); } } } }