diff --git a/lib/bin/types/window.h b/lib/bin/types/window.h index 1b5c816..d3a5339 100644 --- a/lib/bin/types/window.h +++ b/lib/bin/types/window.h @@ -1,6 +1,10 @@ #pragma once #include +#if GMENG_SDLIMAGE +#include +#endif +#include #include "../gmeng.h" #include "../src/renderer.cpp" @@ -24,8 +28,80 @@ namespace Gmeng { {40, 40, 40}, {249, 128, 25} }; + static SDL_Color scolors[9] = { + {255,255,255 ,255}, + {131, 165, 152,255}, + {184, 187, 38 ,255}, + {134, 180, 117,255}, + {244, 73, 52 ,255}, + {211, 134, 155,255}, + {249, 188, 47 ,255}, + {40, 40, 40 ,255}, + {249, 128, 25 ,255}, + }; }; +static uint32_t color_to_uint32(const SDL_Color& color) { + return (color.r << 24) | (color.g << 16) | (color.b << 8) | color.a; +} + +// Function to create an SDL texture from a vector of SDL_Color +static SDL_Texture* make_texture(SDL_Renderer* renderer, Gmeng::sImage image) { + uint32_t width = image.width; + uint32_t height = image.height; + std::vector units; + for (auto color : image.content) units.push_back(scolors[color]); + + if (units.size() != width * height) return nullptr; + + // Create an SDL surface + SDL_Surface* surface = SDL_CreateRGBSurfaceFrom( + units.data(), // Pixel data + width, // Width of the surface + height, // Height of the surface + 32, // Bits per pixel + width * sizeof(uint32_t), // Pitch (bytes per row) + 0xFF000000, // Red mask + 0x00FF0000, // Green mask + 0x0000FF00, // Blue mask + 0x000000FF // Alpha mask + ); + + if (!surface) { + std::cerr << "Error creating surface: " << SDL_GetError() << std::endl; + return nullptr; + } + + // Create texture from surface + SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface); + SDL_FreeSurface(surface); // Free the surface after creating the texture + if (!texture) { + std::cerr << "Error creating texture: " << SDL_GetError() << std::endl; + return nullptr; + } + + return texture; +} + +#if GMENG_SDLIMAGE +static SDL_Texture* from_png(SDL_Renderer* renderer, const char* file_path) { + // Load the PNG file into an SDL_Surface + SDL_Surface* surface = IMG_Load(file_path); + if (!surface) { + std::cerr << "Error loading image: " << IMG_GetError() << std::endl; + return nullptr; + } + + // Create an SDL_Texture from the SDL_Surface + SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface); + SDL_FreeSurface(surface); // Free the surface after creating the texture + if (!texture) { + std::cerr << "Error creating texture: " << SDL_GetError() << std::endl; + return nullptr; + } + return texture; +} +#endif #define GMENG_SDL_ENABLED true diff --git a/lib/bin/utils/script.cpp b/lib/bin/utils/script.cpp index afec5f0..69072b5 100644 --- a/lib/bin/utils/script.cpp +++ b/lib/bin/utils/script.cpp @@ -46,6 +46,11 @@ namespace Gmeng::script_parser_util { inline object_class* parse_value(string data) { object_class* obj = new object_class(); + string v_data = trim(data); + if (v_data.starts_with("\"")) { + if (!v_data.ends_with("\"")) throw script_syntax_exception("string not closed, missing '\"' character at the end of string"); + // make it a string + }; return obj; }; }; diff --git a/lib/bin/utils/window.cpp b/lib/bin/utils/window.cpp index 2aa1ed9..aafbee0 100644 --- a/lib/bin/utils/window.cpp +++ b/lib/bin/utils/window.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -51,7 +52,7 @@ namespace Gmeng { SDL_Quit(); return; }; - std::string font_path = "./assets/press_start.ttf"; + std::string font_path = "press_start.ttf"; font = TTF_OpenFont(font_path.c_str(), 24); // Default font and size if (!font) { throw std::runtime_error("TTF_OpenFont Error: " + std::string(TTF_GetError())); @@ -65,28 +66,23 @@ namespace Gmeng { SDL_Quit(); }; - void draw(const Gmeng::sImage& img, SDL_Point position, int pixelSize = 10) { - this->clear(); - for (int y = 0; y < img.height; ++y) { - for (int x = 0; x < img.width; ++x) { - int index = y * img.width + x; - color_t unit = RED; - try { - unit = img.content.at(index); - } catch (std::out_of_range& e) { - gm_log("!! buffer_overflow (" + v_str(index) + ")"); - }; - auto& color = rgb_colors[unit]; - SDL_SetRenderDrawColor(renderer, color[0], color[1], color[2], 255); - SDL_Rect rect = { - position.x + x * pixelSize, - position.y + y * pixelSize, - pixelSize, - pixelSize - }; - SDL_RenderFillRect(renderer, &rect); - } - } + void draw(const Gmeng::sImage& img, SDL_Point position, int pixelSize = 15) { + SDL_Texture* txtr = make_texture(this->renderer, img); + SDL_Rect source_rect = {0, 0, img.width, img.height}; + SDL_Rect destination_rect = {position.x, position.y, img.width*pixelSize, img.height*pixelSize}; + SDL_RenderCopy(renderer, txtr, &source_rect, &destination_rect); + }; + + void text(string message, SDL_Point pos, SDL_Color color, SDL_Color bgcolor = { 0, 0, 0, 255 }) { + SDL_Surface* text_surface = TTF_RenderText_Solid(this->font, message.c_str(), color); + SDL_Texture* text_texture = SDL_CreateTextureFromSurface(this->renderer, text_surface); + SDL_Rect text_rect = { pos.x, pos.y, text_surface->w, text_surface->h }; + SDL_FreeSurface(text_surface); + + SDL_RenderCopy(renderer, text_texture, NULL, &text_rect); + }; + + void refresh() { SDL_RenderPresent(renderer); }; @@ -112,20 +108,6 @@ namespace Gmeng { GameWindow w(title, width, height); return w; }; - - inline sImage window_frame(Gmeng::Level& lvl) { - ASSERT("pref.log", p_yes); - sImage image; - image.width = lvl.base.width; - image.height = lvl.base.height; - for (int indx = 0; indx < image.width*image.height; indx++) { - Unit fd = { .color = ((indx % 2) + ( (indx % image.height) % 2 == 0 ? 0 : 1 ) == 0 ? RED : BLACK) }; - if (indx < CONSTANTS::UNITMAP_SIZE) fd = lvl.display.camera.display_map.unitmap[indx]; - image.content.push_back((color_t)fd.color); - gm_log("losing your mind? unit(" + v_str(indx) + ") color: " + v_str(fd.color)); - }; - return image; - }; }; #define GMENG_SDL_INIT true diff --git a/tests/out/test.o b/tests/out/test.o index 590773c..caaa5c1 100755 Binary files a/tests/out/test.o and b/tests/out/test.o differ diff --git a/tests/test.cpp b/tests/test.cpp index 9f4982d..7b2e145 100755 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -1,3 +1,5 @@ +#include +#include #if GMENG_SDL #include "SDL2/SDL.h" #endif @@ -9,6 +11,7 @@ #include #include "../lib/bin/gmeng.h" #include "../lib/bin/src/renderer.cpp" +#include #if GMENG_SDL #include "../lib/bin/types/window.h" @@ -311,21 +314,6 @@ int test_vwhole_renderer() { std::cout << "emplace_lvl_camera done" << '\n'; lvl.display.camera.clear_screen(); std::cout << lvl.display.camera.draw() << '\n'; -#if GMENG_SDL - Gmeng::GameWindow window = Gmeng::create_window("PREVIEW", 800, 600); - std::cout << sizeof(lvl.display.camera.display_map.unitmap)/sizeof(Gmeng::Unit) << '\n'; - sImage img; - img.width = 88; img.height = 44; - img.content.push_back(RED); - window.draw(Gmeng::window_frame(lvl), {0,0}); - SDL_Event e; - bool quit = false; - while (!quit) { - while (SDL_PollEvent(&e) != 0) { - if (e.type == SDL_QUIT) quit = true; - } - }; -#endif do { cout << "Press [enter] to continue..."; @@ -381,6 +369,43 @@ int test_vwhole_renderer() { return 0; }; +#if GMENG_SDL +int test_sdl_text() { + _uread_into_vgm("./envs/models"); + Gmeng::GameWindow window = Gmeng::create_window("PREVIEW", 850, 700); + SDL_Event e; + bool quit = false; + Gmeng::sImage img; + gm::texture txtr = gm::vd_find_texture(gm::vgm_defaults::vg_textures, "allah"); + img.width = 88; img.height = 44; + for (int i = 0; i < img.width * img.height; i++) { + img.content.push_back( (color_t)txtr.units.at(i).color ); + }; + Uint32 frame_start, frame_time; + float fps = 0; + Uint32 last_displayed = 0; + Uint32 last_frame_time = 1000; + while (!quit) { + while (SDL_PollEvent(&e) != 0) { + if (e.type == SDL_QUIT) quit = true; + } + Uint32 tm = SDL_GetTicks(); + frame_start = tm; + window.clear(); + window.draw(img, { 0, 0 }, 10); + window.text("frame time: " + v_str(frame_time) + "ms | fps: " + v_str(1000 / frame_time), {0,600}, {255, 0, 0, 255}); + window.refresh(); + frame_time = SDL_GetTicks() - frame_start; + if (last_displayed == 0 || tm - last_displayed >= 1000) { + last_displayed = tm; + last_frame_time = frame_time; + fps = 1000 / frame_time; + } else fps = 1000 / last_frame_time; + }; + return 0; +}; +#endif + static std::vector testids = { &test_vgmcontent, &test_caketxtr, @@ -390,7 +415,10 @@ static std::vector testids = { &test_loadglvl, &test_chunkvpoint, &test_vpointrender, - &test_vwhole_renderer + &test_vwhole_renderer, +#if GMENG_SDL + &test_sdl_text, +#endif }; int main(int argc, char* argv[]) {