From dc84ed79d6b0f8e5bdb96613d7700da053588cb5 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Tue, 25 Oct 2022 21:51:30 +0200 Subject: [PATCH] Implementado el cambio de paleta durante el juego --- data/font/smb2.png | Bin 1404 -> 1389 bytes data/room/06.room | 32 ++++++++++ data/room/06.tmx | 18 +++--- data/tilesets/standard.png | Bin 7351 -> 7306 bytes data/tilesets/standard_zxarne.png | Bin 3087 -> 8853 bytes data/title/loading_screen_bn.png | Bin 4852 -> 4815 bytes data/title/loading_screen_bn_zxarne.png | Bin 0 -> 4841 bytes data/title/loading_screen_color.png | Bin 7028 -> 7009 bytes data/title/loading_screen_color_zxarne.png | Bin 0 -> 7455 bytes source/common/screen.cpp | 2 +- source/common/utils.cpp | 8 +-- source/common/utils.h | 10 ++- source/credits.cpp | 58 +++++++++-------- source/credits.h | 3 +- source/demo.cpp | 19 +++--- source/demo.h | 3 +- source/director.cpp | 38 +++++++++-- source/game.cpp | 39 +++++++---- source/game.h | 3 +- source/intro.cpp | 17 +++-- source/intro.h | 3 +- source/logo.cpp | 71 +++++++++++---------- source/logo.h | 19 +++--- source/player.cpp | 5 +- source/player.h | 3 +- source/room.cpp | 53 +++++++++------ source/room.h | 3 +- source/scoreboard.cpp | 22 +++++-- source/scoreboard.h | 3 +- source/title.cpp | 26 +++++--- source/title.h | 3 +- 31 files changed, 297 insertions(+), 164 deletions(-) create mode 100644 data/title/loading_screen_bn_zxarne.png create mode 100644 data/title/loading_screen_color_zxarne.png diff --git a/data/font/smb2.png b/data/font/smb2.png index 45fa64b9facb38d14b27e057de26db32468519e7..7f71dd53a45d72a16970ba149fc86f367a5300dc 100644 GIT binary patch delta 1357 zcmV-T1+x153hfGzF@GmXL_t(|ob6oOw(2kltSGd?`+tH96={S#0nbpIBhJSb%E#j&8Sm9xXl%0Il z$Bz8zCwSZN$z{Aqzd!XW_rT!&Mr+yoUHv=42s^=9b)w`d`nsKFmbOAi)o&*M=ql*K zpW18&qIElS?fa^)k*qqO8Ba#L@Q1PI?HX2;(neQag49a{Yu8o%nS92h>R*j&C;e#A z-q|SGwvDkMDSz@xJIpFP+OQgsXfK)n%Kj8T6hCLi4ZAEWCcj25Oad zZS|!jORo1D?I~-o*(l2jWoFNhqmvua)mB+O(SHS_8-MxPzHLd1t_*jiAfvOYV?341 zNXI{>ccp%YN|F9A1${w8`Qq{toID|lY$k8%vlpPjr*s(Aes(d8bTb=O{a)|GDq{WJ zZ+7q^nZXlnFp{zSNIs(bfMoh3RK`LDQKBOItmvw~yuMB9+|-8L0CH&9sM?9DzZ0Yi zR_R%RnSVli`=A4zfT&GHC!`Y)rOG?V^egrm&k@B?jSKuFi*2467(CHNvjAi*xQp2q z?Rlbo%yf@xQCH*gN^q9IRl%{g6rg~13$cQ3S6Yeej)Cylw%!NbQ2=HF996U37}KBa z!~3cFi0oH@3e=83)cM#!V@ck7%w700&>z9s>VJyp_WhgUq#Z|>w-xf4Zp()%9_>G) z&&ID}engR%FOt;Ts9caNZvqp7wOK& z8TsmQ=4{&w4X`!5^R7Ng3KwI~2A z*emR_F2VG6=?b0>jAz!yg&)JzFFGo%NX7HXKYpvWIyT2F9m%V$ly#a+53(P1r_4uY z+8Z_NOBecd;0d+L#9u$$41di z_sEJWd=5UlwIHmRU)#nXC6r5N*Zz_C_~SEFVc(c+gs7Uwp41krv{%OGf$Ud+@_%9P zJht#iXOBUMzFMB?WNUjPi*E$@eekUFnektk?Hdl z_5ti%hV}yLAn3LAeXNHqde#Y6Ab;KBK^utZkvx*UIauBe&;VmE);Oh>F>fn{4`Aayna{O P00000NkvXXu0mjfc-+Wf delta 1372 zcmV-i1*7`y3j7L?F@H8mL_t(|ob6oOb^ut>9{XNUo+a+s;PVkc#o>mPt9xX@6)Bqgi`0HfHv)MDlKa z)W!<`M6%1JSzdx$=G1R*N^#|E zB?wBc5xdVqWI&U6o)2wendj|`8WGK8?>*DQZWxl0sU9OOW)vegx8o)S%rr_u%a7yyz=U`GA~g^&U`;RxE4KHDzi8GuYaIdBi-9ub4qlkxg!A{on;-{ zlNm-T_A$9LB!30a_>?Q ztMB@-eJ|qad#nRmJaRwcx9Hj-o_q_Lwvd4pC`&&}x~whFZ<8vMTIcIP26Y`-Jy!Nt zoRq;VIe#-Sl4vg8Of0K3;ZOD9iA!Zd#r06Daph#6F?(oA?W2Ex6y+6Ud114bNdWwSgO zlkc5F+ZnYH>CXTqsBD3#^0AA?g1oxTZG0H$kAL7~c3E`!{zb4;j;-Ns2EQj;?n4=m z&hODj{g=@{;)9#skR6b;fnLxxeKtRn$<|iG^RI3`L0Y-V7x5zWKP4UX3Mi~`NeN~o3DdQBeqj9aVqM(mgNA$ru_YFRJ;Wka;YMEU!g zC;Ix?jwipPV0{FW_stdB`L;*XY6R%tvrNWWE` zJR6ygx94EX(1`OZ0}gYRH>4mtb)RN*$$uY_Z~4QbYyH^^V6_WNzg)XTv(+;|_L$K= z6R8Z@B(eg@oRpD2qW?_1{Gy{9G#a3*QEd}d`4RnW&x&MteqHztLG~OVZ{LbDc=96p zSSuQ-9$r$J&%sxh7K9o7t2O>85g9tG`p?AMAD^KN`@~=)SlQgq6fLol^2+vUAb-eVA=&*o<`+1hG&{edeVx@P)D1Vi75SUjlw^?(}6caRsu{Xbc3&FXc#PgQ&l;4eC? z0Dao?;f9a&|H<-#{ML(&GQ7+4Ik;tl%bqPI^kb9`<__+8aHnXm2X~q`Ww-V_P4D1- eId-4^Ec^f{CPedYoiRKB0000 diff --git a/data/tilesets/standard.png b/data/tilesets/standard.png index a1f9e20f12193612aa66e66aaf944a04302dbf8e..5ae050a526baeb981702c6d75d834a7952f1c7da 100644 GIT binary patch literal 7306 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 literal 7351 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 K(vYI>7WHpEHPFHU diff --git a/data/title/loading_screen_bn.png b/data/title/loading_screen_bn.png index 6ec08b7301da60b903d06763a905a478942764f3..11c0e3c78a391b6baf949925b796eb03cf3bc96f 100644 GIT binary patch delta 4782 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 IM6N<$f}Yb>)&Kwi delta 4803 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 AdH?_b literal 0 HcmV?d00001 diff --git a/data/title/loading_screen_color.png b/data/title/loading_screen_color.png index 3b68f0d411e92ce25ab3101518d2979669774d51..92c55f80be2e1b4be70f38258fb3b56ecffa76ef 100644 GIT binary patch delta 6979 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 Vn^YL}3dR5c002ovPDHLkV1i7bcAx+N delta 6967 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 f2GReUx vColors = {"black", "blue", "red", "magenta", "green", "cyan", "yellow", "bright_white"}; for (auto v : vColors) { - spectrumColor.push_back(stringToColor(v)); + spectrumColor.push_back(stringToColor(options->palette, v)); } } diff --git a/source/common/utils.cpp b/source/common/utils.cpp index bc0117d..df6a3dd 100644 --- a/source/common/utils.cpp +++ b/source/common/utils.cpp @@ -380,11 +380,9 @@ bool checkCollision(SDL_Point &p, d_line_t &l) } // Devuelve un color_t a partir de un string -color_t stringToColor(std::string str) +color_t stringToColor(palette_e pal, std::string str) { - const std::string palette = "spectrum"; - - if (palette == "spectrum") + if (pal == p_zxspectrum) { if (str == "black") { @@ -467,7 +465,7 @@ color_t stringToColor(std::string str) } } - else + else if (pal == p_zxarne) { // zxarne if (str == "black") { diff --git a/source/common/utils.h b/source/common/utils.h index 3707511..1cd10f5 100644 --- a/source/common/utils.h +++ b/source/common/utils.h @@ -47,6 +47,13 @@ struct color_t Uint8 b; }; +// Tipos de paleta +enum palette_e +{ + p_zxspectrum, + p_zxarne +}; + // Estructura para saber la seccion y subseccion del programa struct section_t { @@ -67,6 +74,7 @@ struct options_t bool keepAspect; // Indica si se ha de mantener la relación de aspecto al poner el modo a pantalla completa bool borderEnabled; // Indica si ha de mostrar el borde en el modo de ventana float borderSize; // Porcentaje de borde que se añade a lo ventana + palette_e palette; // Paleta de colores a usar en el juego }; // Calcula el cuadrado de la distancia entre dos puntos @@ -106,7 +114,7 @@ bool checkCollision(SDL_Point &p, d_line_t &l); void normalizeLine(d_line_t &l); // Devuelve un color_t a partir de un string -color_t stringToColor(std::string str); +color_t stringToColor(palette_e pal, std::string str); // Convierte una cadena en un valor booleano bool stringToBool(std::string str); diff --git a/source/credits.cpp b/source/credits.cpp index 11ff1e4..7301f7c 100644 --- a/source/credits.cpp +++ b/source/credits.cpp @@ -1,12 +1,13 @@ #include "credits.h" // Constructor -Credits::Credits(SDL_Renderer *renderer, Screen *screen, Asset *asset) +Credits::Credits(SDL_Renderer *renderer, Screen *screen, Asset *asset, options_t *options) { // Copia la dirección de los objetos this->renderer = renderer; this->screen = screen; this->asset = asset; + this->options = options; // Reserva memoria para los punteros eventHandler = new SDL_Event(); @@ -25,36 +26,36 @@ Credits::Credits(SDL_Renderer *renderer, Screen *screen, Asset *asset) sprite->setRect({194, 174, 8, 8}); // Cambia el color del borde - screen->setBorderColor(stringToColor("black")); + screen->setBorderColor(stringToColor(options->palette, "black")); // Inicializa los textos - texts.push_back({"", stringToColor("white")}); - texts.push_back({"INSTRUCTIONS:", stringToColor("yellow")}); - texts.push_back({"", stringToColor("white")}); - texts.push_back({"HELP JAILDOC TO GET BACK ALL HIS", stringToColor("white")}); - texts.push_back({"PROJECTS AND GO TO THE JAIL TO", stringToColor("white")}); - texts.push_back({"FINISH THEM", stringToColor("white")}); - texts.push_back({"", stringToColor("white")}); - texts.push_back({"", stringToColor("white")}); + texts.push_back({"", stringToColor(options->palette, "white")}); + texts.push_back({"INSTRUCTIONS:", stringToColor(options->palette, "yellow")}); + texts.push_back({"", stringToColor(options->palette, "white")}); + texts.push_back({"HELP JAILDOC TO GET BACK ALL HIS", stringToColor(options->palette, "white")}); + texts.push_back({"PROJECTS AND GO TO THE JAIL TO", stringToColor(options->palette, "white")}); + texts.push_back({"FINISH THEM", stringToColor(options->palette, "white")}); + texts.push_back({"", stringToColor(options->palette, "white")}); + texts.push_back({"", stringToColor(options->palette, "white")}); - texts.push_back({"KEYS:", stringToColor("yellow")}); - texts.push_back({"", stringToColor("white")}); - texts.push_back({"USE CURSORS TO MOVE AND JUMP", stringToColor("white")}); - texts.push_back({"F1-F4 TO CHANGE WINDOWS SIZE", stringToColor("white")}); - texts.push_back({"F TO SWITCH TO FULLSCREEN", stringToColor("white")}); - texts.push_back({"B TO DE/ACTIVATE THE BORDER SC.", stringToColor("white")}); - texts.push_back({"M TO TURN ON/OFF THE MUSIC", stringToColor("white")}); - texts.push_back({"ESC TO EXIT GAME", stringToColor("white")}); - texts.push_back({"", stringToColor("white")}); - texts.push_back({"", stringToColor("white")}); + texts.push_back({"KEYS:", stringToColor(options->palette, "yellow")}); + texts.push_back({"", stringToColor(options->palette, "white")}); + texts.push_back({"USE CURSORS TO MOVE AND JUMP", stringToColor(options->palette, "white")}); + texts.push_back({"F1-F4 TO CHANGE WINDOWS SIZE", stringToColor(options->palette, "white")}); + texts.push_back({"F TO SWITCH TO FULLSCREEN", stringToColor(options->palette, "white")}); + texts.push_back({"B TO DE/ACTIVATE THE BORDER SC.", stringToColor(options->palette, "white")}); + texts.push_back({"M TO TURN ON/OFF THE MUSIC", stringToColor(options->palette, "white")}); + texts.push_back({"ESC TO EXIT GAME", stringToColor(options->palette, "white")}); + texts.push_back({"", stringToColor(options->palette, "white")}); + texts.push_back({"", stringToColor(options->palette, "white")}); - texts.push_back({"A GAME BY JAILDESIGNER", stringToColor("yellow")}); - texts.push_back({"MADE ON SUMMER/FALL 2022", stringToColor("yellow")}); - texts.push_back({"", stringToColor("white")}); - texts.push_back({"", stringToColor("white")}); + texts.push_back({"A GAME BY JAILDESIGNER", stringToColor(options->palette, "yellow")}); + texts.push_back({"MADE ON SUMMER/FALL 2022", stringToColor(options->palette, "yellow")}); + texts.push_back({"", stringToColor(options->palette, "white")}); + texts.push_back({"", stringToColor(options->palette, "white")}); - texts.push_back({"I LOVE JAILGAMES!}", stringToColor("white")}); - texts.push_back({"", stringToColor("white")}); + texts.push_back({"I LOVE JAILGAMES!", stringToColor(options->palette, "white")}); + texts.push_back({"", stringToColor(options->palette, "white")}); // Crea la textura para el texto que se escribe en pantalla textTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT); @@ -124,7 +125,7 @@ void Credits::fillTexture() { // Rellena la textura de texto SDL_SetRenderTarget(renderer, textTexture); - const color_t c = stringToColor("black"); + const color_t c = stringToColor(options->palette, "black"); SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b, 0x00); SDL_RenderClear(renderer); @@ -138,6 +139,9 @@ void Credits::fillTexture() i++; } + // Escribe el corazón + text->writeColored(194, 176, "}", stringToColor(options->palette, "bright_red")); + SDL_SetRenderTarget(renderer, nullptr); // Rellena la textura que cubre el texto diff --git a/source/credits.h b/source/credits.h index 0b192b8..47d9b22 100644 --- a/source/credits.h +++ b/source/credits.h @@ -34,6 +34,7 @@ private: SDL_Texture *coverTexture; // Textura para cubrir el texto Texture *texture; // Textura para el sprite de brillo AnimatedSprite *sprite; // Sprite para el brillo del corazón + options_t *options; // Puntero a las opciones del juego // Variables int counter; // Contador @@ -61,7 +62,7 @@ private: public: // Constructor - Credits(SDL_Renderer *renderer, Screen *screen, Asset *asset); + Credits(SDL_Renderer *renderer, Screen *screen, Asset *asset, options_t *options); // Destructor ~Credits(); diff --git a/source/demo.cpp b/source/demo.cpp index abc82b9..ffb66e1 100644 --- a/source/demo.cpp +++ b/source/demo.cpp @@ -1,7 +1,7 @@ #include "demo.h" // Constructor -Demo::Demo(SDL_Renderer *renderer, Screen *screen, Asset *asset, Debug *debug) +Demo::Demo(SDL_Renderer *renderer, Screen *screen, Asset *asset, options_t *options, Debug *debug) { // Inicia algunas variables board.iniClock = SDL_GetTicks(); @@ -19,11 +19,12 @@ Demo::Demo(SDL_Renderer *renderer, Screen *screen, Asset *asset, Debug *debug) this->asset = asset; this->screen = screen; this->debug = debug; + this->options = options; // Crea los objetos itemTracker = new ItemTracker(); - scoreboard = new ScoreBoard(renderer, asset, &board); - room = new Room(asset->get(currentRoom), renderer, screen, asset, itemTracker, &board.items, debug); + scoreboard = new ScoreBoard(renderer, asset, options, &board); + room = new Room(asset->get(currentRoom), renderer, screen, asset, options, itemTracker, &board.items, debug); eventHandler = new SDL_Event(); text = new Text(asset->get("smb2.png"), asset->get("smb2.txt"), renderer); @@ -35,7 +36,7 @@ Demo::Demo(SDL_Renderer *renderer, Screen *screen, Asset *asset, Debug *debug) board.items = 0; board.rooms = 1; const color_t c = room->getBorderColor(); - board.color = (c.r + c.g + c.b == 0) ? stringToColor("white") : c; // Si el color es negro lo cambia a blanco + board.color = (c.r + c.g + c.b == 0) ? stringToColor(options->palette, "white") : c; // Si el color es negro lo cambia a blanco board.music = !debug->getEnabled(); @@ -63,7 +64,7 @@ void Demo::checkEventHandler() if (eventHandler->type == SDL_QUIT) { section.name = SECTION_PROG_QUIT; - screen->setBorderColor(stringToColor("black")); + screen->setBorderColor(stringToColor(options->palette, "black")); break; } else if ((eventHandler->type == SDL_KEYDOWN) and (eventHandler->key.repeat == 0)) @@ -163,7 +164,7 @@ void Demo::renderRoomName() { // Texto en el centro de la pantalla SDL_Rect rect = {0, 16 * BLOCK, PLAY_AREA_WIDTH, BLOCK * 2}; - color_t color = stringToColor("white"); + color_t color = stringToColor(options->palette, "white"); SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, 0xFF); SDL_RenderFillRect(renderer, &rect); @@ -191,11 +192,11 @@ bool Demo::changeRoom(std::string file) room = nullptr; // Crea un objeto habitación nuevo a partir del fichero - room = new Room(asset->get(file), renderer, screen, asset, itemTracker, &board.items, debug); + room = new Room(asset->get(file), renderer, screen, asset, options, itemTracker, &board.items, debug); // Actualiza el marcador - const color_t c = room->getBorderColor(); // Pone el color del marcador - board.color = (c.r + c.g + c.b == 0) ? stringToColor("white") : c; // Si el color es negro lo cambia a blanco + const color_t c = room->getBorderColor(); // Pone el color del marcador + board.color = (c.r + c.g + c.b == 0) ? stringToColor(options->palette, "white") : c; // Si el color es negro lo cambia a blanco return true; } diff --git a/source/demo.h b/source/demo.h index 30e28b5..8e3058b 100644 --- a/source/demo.h +++ b/source/demo.h @@ -31,6 +31,7 @@ private: ScoreBoard *scoreboard; // Objeto encargado de gestionar el marcador ItemTracker *itemTracker; // Lleva el control de los objetos recogidos Debug *debug; // Objeto para gestionar la información de debug + options_t *options; // Puntero a las opciones del juego // Variables Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa @@ -65,7 +66,7 @@ private: public: // Constructor - Demo(SDL_Renderer *renderer, Screen *screen, Asset *asset, Debug *debug); + Demo(SDL_Renderer *renderer, Screen *screen, Asset *asset, options_t *options, Debug *debug); // Destructor ~Demo(); diff --git a/source/director.cpp b/source/director.cpp index 2b0f702..00c5dd5 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -9,7 +9,7 @@ Director::Director(std::string path) section.name = SECTION_PROG_LOGO; section.subsection = SUBSECTION_LOGO_TO_INTRO; - section.name = SECTION_PROG_CREDITS; + section.name = SECTION_PROG_LOGO; // Crea el objeto que controla los ficheros de recursos asset = new Asset(path.substr(0, path.find_last_of("\\/"))); @@ -70,6 +70,7 @@ bool Director::loadConfig() options->keepAspect = true; options->borderEnabled = true; options->borderSize = 0.1f; + options->palette = p_zxspectrum; // Indicador de éxito en la carga bool success = true; @@ -167,6 +168,7 @@ bool Director::saveConfig() file << "keepAspect=" + boolToString(options->keepAspect) + "\n"; file << "borderEnabled=" + boolToString(options->borderEnabled) + "\n"; file << "borderSize=" + std::to_string(options->borderSize) + "\n"; + file << "palette=" + std::to_string(options->palette) + "\n"; // Cierra el fichero file.close(); @@ -246,6 +248,21 @@ bool Director::setOptions(options_t *options, std::string var, std::string value } } + else if (var == "palette") + { + const int pal = std::stoi(value); + + if (pal == 0) + { + options->palette = p_zxspectrum; + } + + else if (pal == 1) + { + options->palette = p_zxarne; + } + } + else if (var == "") { } @@ -623,6 +640,8 @@ bool Director::setFileList() // Intro asset->add("/data/title/loading_screen_bn.png", t_bitmap); asset->add("/data/title/loading_screen_color.png", t_bitmap); + asset->add("/data/title/loading_screen_bn_zxarne.png", t_bitmap); + asset->add("/data/title/loading_screen_color_zxarne.png", t_bitmap); // Credits asset->add("/data/credits/shine.png", t_bitmap); @@ -652,7 +671,7 @@ void Director::setSection(section_t section) // Ejecuta la seccion de juego con el logo void Director::runLogo() { - logo = new Logo(renderer, screen, asset, section.subsection); + logo = new Logo(renderer, screen, asset, options, section.subsection); setSection(logo->run()); delete logo; } @@ -660,7 +679,7 @@ void Director::runLogo() // Ejecuta la seccion de juego de la introducción void Director::runIntro() { - intro = new Intro(renderer, screen, asset); + intro = new Intro(renderer, screen, asset, options); setSection(intro->run()); delete intro; } @@ -672,7 +691,7 @@ void Director::runTitle() { JA_PlayMusic(music); } - title = new Title(renderer, screen, asset); + title = new Title(renderer, screen, asset, options); setSection(title->run()); delete title; } @@ -680,7 +699,7 @@ void Director::runTitle() // Ejecuta la seccion de los creditos del juego void Director::runCredits() { - credits = new Credits(renderer, screen, asset); + credits = new Credits(renderer, screen, asset, options); setSection(credits->run()); delete credits; } @@ -688,7 +707,7 @@ void Director::runCredits() // Ejecuta la seccion de la demo, donde se ven pantallas del juego void Director::runDemo() { - demo = new Demo(renderer, screen, asset, debug); + demo = new Demo(renderer, screen, asset, options, debug); setSection(demo->run()); delete demo; } @@ -697,7 +716,7 @@ void Director::runDemo() void Director::runGame() { JA_StopMusic(); - game = new Game(renderer, screen, asset, input, debug); + game = new Game(renderer, screen, asset, options, input, debug); setSection(game->run()); delete game; } @@ -712,18 +731,23 @@ void Director::run() case SECTION_PROG_LOGO: runLogo(); break; + case SECTION_PROG_INTRO: runIntro(); break; + case SECTION_PROG_TITLE: runTitle(); break; + case SECTION_PROG_CREDITS: runCredits(); break; + case SECTION_PROG_DEMO: runDemo(); break; + case SECTION_PROG_GAME: runGame(); break; diff --git a/source/game.cpp b/source/game.cpp index ad04b06..bb8ed06 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -1,7 +1,7 @@ #include "game.h" // Constructor -Game::Game(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input, Debug *debug) +Game::Game(SDL_Renderer *renderer, Screen *screen, Asset *asset, options_t *options, Input *input, Debug *debug) { // Inicia algunas variables board.iniClock = SDL_GetTicks(); @@ -14,6 +14,7 @@ Game::Game(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input, D this->screen = screen; this->input = input; this->debug = debug; + this->options = options; // **** // this->debug->setEnabled(true); @@ -24,11 +25,11 @@ Game::Game(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input, D // **** // Crea los objetos - scoreboard = new ScoreBoard(renderer, asset, &board); + scoreboard = new ScoreBoard(renderer, asset, options, &board); itemTracker = new ItemTracker(); roomTracker = new RoomTracker(); - room = new Room(asset->get(currentRoom), renderer, screen, asset, itemTracker, &board.items, debug); - player = new Player(spawnPoint, asset->get("player.png"), asset->get("player.ani"), renderer, asset, input, room, debug); + room = new Room(asset->get(currentRoom), renderer, screen, asset, options, itemTracker, &board.items, debug); + player = new Player(spawnPoint, asset->get("player.png"), asset->get("player.ani"), renderer, asset, options, input, room, debug); eventHandler = new SDL_Event(); text = new Text(asset->get("smb2.png"), asset->get("smb2.txt"), renderer); music = JA_LoadMusic(asset->get("game.ogg").c_str()); @@ -42,7 +43,7 @@ Game::Game(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input, D board.items = 0; board.rooms = 1; const color_t c = room->getBorderColor(); - board.color = (c.r + c.g + c.b == 0) ? stringToColor("white") : c; // Si el color es negro lo cambia a blanco + board.color = (c.r + c.g + c.b == 0) ? stringToColor(options->palette, "white") : c; // Si el color es negro lo cambia a blanco roomTracker->addRoom(currentRoom); paused = false; blackScreen = false; @@ -82,7 +83,7 @@ void Game::checkEventHandler() if (eventHandler->type == SDL_QUIT) { section.name = SECTION_PROG_QUIT; - screen->setBorderColor(stringToColor("black")); + screen->setBorderColor(stringToColor(options->palette, "black")); break; } else if ((eventHandler->type == SDL_KEYDOWN) and (eventHandler->key.repeat == 0)) @@ -152,6 +153,18 @@ void Game::checkEventHandler() reLoadTextures(); break; + case SDL_SCANCODE_F5: + if (options->palette == p_zxspectrum) + { + options->palette = p_zxarne; + } + else + { + options->palette = p_zxspectrum; + } + reLoadTextures(); + break; + default: break; } @@ -273,7 +286,7 @@ void Game::renderRoomName() { // Texto en el centro de la pantalla SDL_Rect rect = {0, 16 * BLOCK, PLAY_AREA_WIDTH, BLOCK * 2}; - color_t color = stringToColor("white"); + color_t color = stringToColor(options->palette, "white"); SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, 0xFF); SDL_RenderFillRect(renderer, &rect); @@ -293,11 +306,11 @@ bool Game::changeRoom(std::string file) room = nullptr; // Crea un objeto habitación nuevo a partir del fichero - room = new Room(asset->get(file), renderer, screen, asset, itemTracker, &board.items, debug); + room = new Room(asset->get(file), renderer, screen, asset, options, itemTracker, &board.items, debug); // Actualiza el marcador - const color_t c = room->getBorderColor(); // Pone el color del marcador - board.color = (c.r + c.g + c.b == 0) ? stringToColor("white") : c; // Si el color es negro lo cambia a blanco + const color_t c = room->getBorderColor(); // Pone el color del marcador + board.color = (c.r + c.g + c.b == 0) ? stringToColor(options->palette, "white") : c; // Si el color es negro lo cambia a blanco if (roomTracker->addRoom(file)) { // Incrementa el contador de habitaciones visitadas board.rooms++; @@ -382,8 +395,8 @@ void Game::killPlayer() setBlackScreen(); // Crea la nueva habitación y el nuevo jugador - room = new Room(asset->get(currentRoom), renderer, screen, asset, itemTracker, &board.items, debug); - player = new Player(spawnPoint, asset->get("player.png"), asset->get("player.ani"), renderer, asset, input, room, debug); + room = new Room(asset->get(currentRoom), renderer, screen, asset, options, itemTracker, &board.items, debug); + player = new Player(spawnPoint, asset->get("player.png"), asset->get("player.ani"), renderer, asset, options, input, room, debug); room->pause(); player->pause(); @@ -428,6 +441,6 @@ void Game::renderBlackScreen() if (blackScreen) { screen->clean(); - screen->setBorderColor(stringToColor("black")); + screen->setBorderColor(stringToColor(options->palette, "black")); } } \ No newline at end of file diff --git a/source/game.h b/source/game.h index 70853c8..721ceda 100644 --- a/source/game.h +++ b/source/game.h @@ -37,6 +37,7 @@ private: Text *text; // Objeto para los textos del juego ScoreBoard *scoreboard; // Objeto encargado de gestionar el marcador Debug *debug; // Objeto para gestionar la información de debug + options_t *options; // Puntero a las opciones del juego Test *test; // Variables @@ -105,7 +106,7 @@ private: public: // Constructor - Game(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input, Debug *debug); + Game(SDL_Renderer *renderer, Screen *screen, Asset *asset, options_t *options, Input *input, Debug *debug); // Destructor ~Game(); diff --git a/source/intro.cpp b/source/intro.cpp index ec92274..13600a1 100644 --- a/source/intro.cpp +++ b/source/intro.cpp @@ -1,17 +1,26 @@ #include "intro.h" // Constructor -Intro::Intro(SDL_Renderer *renderer, Screen *screen, Asset *asset) +Intro::Intro(SDL_Renderer *renderer, Screen *screen, Asset *asset, options_t *options) { // Copia la dirección de los objetos this->renderer = renderer; this->screen = screen; this->asset = asset; + this->options = options; // Reserva memoria para los punteros eventHandler = new SDL_Event(); - loadingScreenTexture1 = new Texture(renderer, asset->get("loading_screen_bn.png")); - loadingScreenTexture2 = new Texture(renderer, asset->get("loading_screen_color.png")); + if (options->palette == p_zxspectrum) + { + loadingScreenTexture1 = new Texture(renderer, asset->get("loading_screen_bn.png")); + loadingScreenTexture2 = new Texture(renderer, asset->get("loading_screen_color.png")); + } + else if (options->palette == p_zxarne) + { + loadingScreenTexture1 = new Texture(renderer, asset->get("loading_screen_bn_zxarne.png")); + loadingScreenTexture2 = new Texture(renderer, asset->get("loading_screen_color_zxarne.png")); + } sprite1 = new Sprite(0, 0, loadingScreenTexture1->getWidth(), loadingScreenTexture1->getHeight(), loadingScreenTexture1, renderer); sprite2 = new Sprite(0, 0, loadingScreenTexture2->getWidth(), loadingScreenTexture2->getHeight(), loadingScreenTexture2, renderer); loadingSound1 = JA_LoadMusic(asset->get("loading_sound1.ogg").c_str()); @@ -57,7 +66,7 @@ Intro::Intro(SDL_Renderer *renderer, Screen *screen, Asset *asset) } // Cambia el color del borde - screen->setBorderColor(stringToColor("black")); + screen->setBorderColor(stringToColor(options->palette, "black")); } // Destructor diff --git a/source/intro.h b/source/intro.h index b4017d1..e1b02d0 100644 --- a/source/intro.h +++ b/source/intro.h @@ -27,6 +27,7 @@ private: SDL_Event *eventHandler; // Manejador de eventos Sprite *sprite1; // Sprite para manejar la textura loadingScreenTexture1 Sprite *sprite2; // Sprite para manejar la textura loadingScreenTexture2 + options_t *options; // Puntero a las opciones del juego // Variables int preCounter; // Contador previo para realizar una pausa inicial @@ -63,7 +64,7 @@ private: public: // Constructor - Intro(SDL_Renderer *renderer, Screen *screen, Asset *asset); + Intro(SDL_Renderer *renderer, Screen *screen, Asset *asset, options_t *options); // Destructor ~Intro(); diff --git a/source/logo.cpp b/source/logo.cpp index c914097..bcdb2fc 100644 --- a/source/logo.cpp +++ b/source/logo.cpp @@ -1,12 +1,13 @@ #include "logo.h" // Constructor -Logo::Logo(SDL_Renderer *renderer, Screen *screen, Asset *asset, int subsection) +Logo::Logo(SDL_Renderer *renderer, Screen *screen, Asset *asset, options_t *options, int subsection) { // Copia la dirección de los objetos this->renderer = renderer; this->screen = screen; this->asset = asset; + this->options = options; // Reserva memoria para los punteros eventHandler = new SDL_Event(); @@ -21,13 +22,13 @@ Logo::Logo(SDL_Renderer *renderer, Screen *screen, Asset *asset, int subsection) sprite.push_back(new Sprite(0, i, texture->getWidth(), 1, texture, renderer)); if (i % 2 == 0) { - sprite[i]->setPosX(256 + (i * 3)); + sprite.at(i)->setPosX(256 + (i * 3)); } else { - sprite[i]->setPosX(-181 - (i * 3)); + sprite.at(i)->setPosX(-181 - (i * 3)); } - sprite[i]->setPosY(83 + i); + sprite.at(i)->setPosY(83 + i); } // Inicializa variables @@ -44,11 +45,11 @@ Logo::Logo(SDL_Renderer *renderer, Screen *screen, Asset *asset, int subsection) const std::vector vColors = {"black", "blue", "red", "magenta", "green", "cyan", "yellow", "bright_white"}; for (auto v : vColors) { - color.push_back(stringToColor(v)); + color.push_back(stringToColor(options->palette, v)); } // Cambia el color del borde - screen->setBorderColor(stringToColor("black")); + screen->setBorderColor(stringToColor(options->palette, "black")); } // Destructor @@ -97,22 +98,22 @@ void Logo::updateJAILGAMES() { const int speed = 8; const int dest = 37; - if (sprite[i]->getPosX() != 37) + if (sprite.at(i)->getPosX() != 37) { if (i % 2 == 0) { - sprite[i]->incPosX(-speed); - if (sprite[i]->getPosX() < dest) + sprite.at(i)->incPosX(-speed); + if (sprite.at(i)->getPosX() < dest) { - sprite[i]->setPosX(dest); + sprite.at(i)->setPosX(dest); } } else { - sprite[i]->incPosX(speed); - if (sprite[i]->getPosX() > dest) + sprite.at(i)->incPosX(speed); + if (sprite.at(i)->getPosX() > dest) { - sprite[i]->setPosX(dest); + sprite.at(i)->setPosX(dest); } } } @@ -128,72 +129,72 @@ void Logo::updateTextureColors() if (counter == ini + inc * 0) { - texture2->setColor(color[0].r, color[0].g, color[0].b); + texture2->setColor(color.at(0).r, color.at(0).g, color.at(0).b); } else if (counter == ini + inc * 1) { - texture2->setColor(color[1].r, color[1].g, color[1].b); + texture2->setColor(color.at(1).r, color.at(1).g, color.at(1).b); } else if (counter == ini + inc * 2) { - texture2->setColor(color[2].r, color[2].g, color[2].b); + texture2->setColor(color.at(2).r, color.at(2).g, color.at(2).b); } else if (counter == ini + inc * 3) { - texture2->setColor(color[3].r, color[3].g, color[3].b); + texture2->setColor(color.at(3).r, color.at(3).g, color.at(3).b); } else if (counter == ini + inc * 4) { - texture2->setColor(color[4].r, color[4].g, color[4].b); + texture2->setColor(color.at(4).r, color.at(4).g, color.at(4).b); } else if (counter == ini + inc * 5) { - texture2->setColor(color[5].r, color[5].g, color[5].b); + texture2->setColor(color.at(5).r, color.at(5).g, color.at(5).b); } else if (counter == ini + inc * 6) { - texture2->setColor(color[6].r, color[6].g, color[6].b); + texture2->setColor(color.at(6).r, color.at(6).g, color.at(6).b); } else if (counter == ini + inc * 7) { - texture2->setColor(color[7].r, color[7].g, color[7].b); + texture2->setColor(color.at(7).r, color.at(7).g, color.at(7).b); } else if (counter == initFade + inc * 0) { - texture->setColor(color[6].r, color[6].g, color[6].b); - texture2->setColor(color[6].r, color[6].g, color[6].b); + texture->setColor(color.at(6).r, color.at(6).g, color.at(6).b); + texture2->setColor(color.at(6).r, color.at(6).g, color.at(6).b); } else if (counter == initFade + inc * 1) { - texture->setColor(color[5].r, color[5].g, color[5].b); - texture2->setColor(color[5].r, color[5].g, color[5].b); + texture->setColor(color.at(5).r, color.at(5).g, color.at(5).b); + texture2->setColor(color.at(5).r, color.at(5).g, color.at(5).b); } else if (counter == initFade + inc * 2) { - texture->setColor(color[4].r, color[4].g, color[4].b); - texture2->setColor(color[4].r, color[4].g, color[4].b); + texture->setColor(color.at(4).r, color.at(4).g, color.at(4).b); + texture2->setColor(color.at(4).r, color.at(4).g, color.at(4).b); } else if (counter == initFade + inc * 3) { - texture->setColor(color[3].r, color[3].g, color[3].b); - texture2->setColor(color[3].r, color[3].g, color[3].b); + texture->setColor(color.at(3).r, color.at(3).g, color.at(3).b); + texture2->setColor(color.at(3).r, color.at(3).g, color.at(3).b); } else if (counter == initFade + inc * 4) { - texture->setColor(color[2].r, color[2].g, color[2].b); - texture2->setColor(color[2].r, color[2].g, color[2].b); + texture->setColor(color.at(2).r, color.at(2).g, color.at(2).b); + texture2->setColor(color.at(2).r, color.at(2).g, color.at(2).b); } else if (counter == initFade + inc * 5) { - texture->setColor(color[1].r, color[1].g, color[1].b); - texture2->setColor(color[1].r, color[1].g, color[1].b); + texture->setColor(color.at(1).r, color.at(1).g, color.at(1).b); + texture2->setColor(color.at(1).r, color.at(1).g, color.at(1).b); } else if (counter == initFade + inc * 6) { - texture->setColor(color[0].r, color[0].g, color[0].b); - texture2->setColor(color[0].r, color[0].g, color[0].b); + texture->setColor(color.at(0).r, color.at(0).g, color.at(0).b); + texture2->setColor(color.at(0).r, color.at(0).g, color.at(0).b); } } diff --git a/source/logo.h b/source/logo.h index 066e8a5..07083c5 100644 --- a/source/logo.h +++ b/source/logo.h @@ -24,16 +24,17 @@ private: SDL_Event *eventHandler; // Manejador de eventos std::vector sprite; // Vector con los sprites de cada linea que forman el bitmap JAILGAMES Sprite *sprite2; // Sprite para manejar la textura2 + options_t *options; // Puntero a las opciones del juego // Variables - std::vector color; // Vector con los colores para el fade - int counter; // Contador - section_t section; // Estado del bucle principal para saber si continua o se sale - Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa - Uint32 ticksSpeed; // Velocidad a la que se repiten los bucles del programa - int initFade; // Tiempo del contador cuando inicia el fade a negro - int endLogo; // Tiempo del contador para terminar el logo - int postLogo; // Tiempo que dura el logo con el fade al maximo + std::vector color; // Vector con los colores para el fade + int counter; // Contador + section_t section; // Estado del bucle principal para saber si continua o se sale + Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa + Uint32 ticksSpeed; // Velocidad a la que se repiten los bucles del programa + int initFade; // Tiempo del contador cuando inicia el fade a negro + int endLogo; // Tiempo del contador para terminar el logo + int postLogo; // Tiempo que dura el logo con el fade al maximo // Actualiza las variables void update(); @@ -52,7 +53,7 @@ private: public: // Constructor - Logo(SDL_Renderer *renderer, Screen *screen, Asset *asset, int subsection); + Logo(SDL_Renderer *renderer, Screen *screen, Asset *asset, options_t *options, int subsection); // Destructor ~Logo(); diff --git a/source/player.cpp b/source/player.cpp index 2fca8bb..838ff64 100644 --- a/source/player.cpp +++ b/source/player.cpp @@ -3,7 +3,7 @@ #include // Constructor -Player::Player(player_t ini, std::string tileset, std::string animation, SDL_Renderer *renderer, Asset *asset, Input *input, Room *room, Debug *debug) +Player::Player(player_t ini, std::string tileset, std::string animation, SDL_Renderer *renderer, Asset *asset, options_t *options, Input *input, Room *room, Debug *debug) { // Obten punteros a objetos this->asset = asset; @@ -11,13 +11,14 @@ Player::Player(player_t ini, std::string tileset, std::string animation, SDL_Ren this->input = input; this->room = room; this->debug = debug; + this->options = options; // Crea objetos texture = new Texture(renderer, asset->get(tileset)); sprite = new AnimatedSprite(texture, renderer, animation); // Inicializa variables - color = stringToColor("white"); + color = stringToColor(options->palette, "white"); onBorder = false; border = BORDER_TOP; invincible = false; diff --git a/source/player.h b/source/player.h index 7ec751c..df0bb3f 100644 --- a/source/player.h +++ b/source/player.h @@ -43,6 +43,7 @@ public: Texture *texture; // Textura con los graficos del enemigo AnimatedSprite *sprite; // Sprite del enemigo Debug *debug; // Objeto para gestionar la información de debug + options_t *options; // Puntero a las opciones del juego // Variables float x; // Posición del jugador en el eje X @@ -127,7 +128,7 @@ public: public: // Constructor - Player(player_t ini, std::string tileset, std::string animation, SDL_Renderer *renderer, Asset *asset, Input *input, Room *room, Debug *debug); + Player(player_t ini, std::string tileset, std::string animation, SDL_Renderer *renderer, Asset *asset, options_t *options, Input *input, Room *room, Debug *debug); // Destructor ~Player(); diff --git a/source/room.cpp b/source/room.cpp index 0f5b945..c6c6a3a 100644 --- a/source/room.cpp +++ b/source/room.cpp @@ -4,18 +4,8 @@ #include // Constructor -Room::Room(std::string file, SDL_Renderer *renderer, Screen *screen, Asset *asset, ItemTracker *itemTracker, int *items, Debug *debug) +Room::Room(std::string file, SDL_Renderer *renderer, Screen *screen, Asset *asset, options_t *options, ItemTracker *itemTracker, int *items, Debug *debug) { - // Inicializa variables - tileSize = 8; - mapWidth = 32; - mapHeight = 16; - paused = false; - itemColor1 = stringToColor("magenta"); - itemColor2 = stringToColor("yellow"); - autoSurfaceDirection = 1; - counter = 0; - // Copia los punteros a objetos this->renderer = renderer; this->asset = asset; @@ -23,6 +13,17 @@ Room::Room(std::string file, SDL_Renderer *renderer, Screen *screen, Asset *asse this->itemTracker = itemTracker; this->itemsPicked = items; this->debug = debug; + this->options = options; + + // Inicializa variables + tileSize = 8; + mapWidth = 32; + mapHeight = 16; + paused = false; + itemColor1 = stringToColor(options->palette, "magenta"); + itemColor2 = stringToColor(options->palette, "yellow"); + autoSurfaceDirection = 1; + counter = 0; // Crea los objetos loadMapFile(file); @@ -297,27 +298,35 @@ bool Room::setVars(std::string var, std::string value) else if (var == "bgColor") { - bgColor = stringToColor(value); + bgColor = stringToColor(options->palette, value); } else if (var == "border") { - borderColor = stringToColor(value); + borderColor = stringToColor(options->palette, value); } else if (var == "itemColor1") { - itemColor1 = stringToColor(value); + itemColor1 = stringToColor(options->palette, value); } else if (var == "itemColor2") { - itemColor2 = stringToColor(value); + itemColor2 = stringToColor(options->palette, value); } else if (var == "tileset") { tileset = value; + if (options->palette == p_zxspectrum) + { + tileset = "standard.png"; + } + else if (options->palette == p_zxarne) + { + tileset = "standard_zxarne.png"; + } } else if (var == "roomUp") @@ -437,7 +446,7 @@ bool Room::setEnemy(enemy_t *enemy, std::string var, std::string value) else if (var == "color") { - enemy->color = stringToColor(value); + enemy->color = stringToColor(options->palette, value); } else if (var == "[/enemy]") @@ -746,7 +755,7 @@ tile_e Room::getTile(int index) { return t_passable; } - + // Las filas 18-20 es de tiles t_animated else if ((tilemap[index] >= 18 * tilesetWidth) && (tilemap[index] < 21 * tilesetWidth)) { @@ -810,7 +819,15 @@ bool Room::itemCollision(SDL_Rect &rect) // Recarga la textura void Room::reLoadTexture() { - texture->reLoad(); + if (options->palette == p_zxspectrum) + { + texture->loadFromFile(asset->get("standard.png"), renderer); + } + else if (options->palette == p_zxarne) + { + texture->loadFromFile(asset->get("standard_zxarne.png"), renderer); + } + // texture->reLoad(); fillMapTexture(); for (auto enemy : enemies) { diff --git a/source/room.h b/source/room.h index 6645c68..695af30 100644 --- a/source/room.h +++ b/source/room.h @@ -48,6 +48,7 @@ private: SDL_Texture *mapTexture; // Textura para dibujar el mapa de la habitación int *itemsPicked; // Puntero a la cantidad de items recogidos que lleva el juego Debug *debug; // Objeto para gestionar la información de debug + options_t *options; // Puntero a las opciones del juego // Variables std::string name; // Nombre de la habitación @@ -132,7 +133,7 @@ private: public: // Constructor - Room(std::string file, SDL_Renderer *renderer, Screen *screen, Asset *asset, ItemTracker *item_tracker, int *items, Debug *debug); + Room(std::string file, SDL_Renderer *renderer, Screen *screen, Asset *asset, options_t *options, ItemTracker *item_tracker, int *items, Debug *debug); // Destructor ~Room(); diff --git a/source/scoreboard.cpp b/source/scoreboard.cpp index a9b9286..4438f9a 100644 --- a/source/scoreboard.cpp +++ b/source/scoreboard.cpp @@ -3,12 +3,13 @@ #include // Constructor -ScoreBoard::ScoreBoard(SDL_Renderer *renderer, Asset *asset, board_t *board) +ScoreBoard::ScoreBoard(SDL_Renderer *renderer, Asset *asset, options_t *options, board_t *board) { // Obten punteros a objetos this->asset = asset; this->renderer = renderer; this->board = board; + this->options = options; // Reserva memoria para los objetos playerTexture = new Texture(renderer, asset->get("player.png")); @@ -28,7 +29,7 @@ ScoreBoard::ScoreBoard(SDL_Renderer *renderer, Asset *asset, board_t *board) const std::vector vColors = {"blue", "magenta", "green", "cyan", "yellow", "white", "bright_blue", "bright_magenta", "bright_green", "bright_cyan", "bright_yellow", "bright_white"}; for (auto v : vColors) { - color.push_back(stringToColor(v)); + color.push_back(stringToColor(options->palette, v)); } } @@ -53,7 +54,6 @@ void ScoreBoard::render() SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_RenderFillRect(renderer, &rect); - // Dibuja las vidas const int desp = (counter / 40) % 8; const int frame = desp % 4; @@ -80,13 +80,13 @@ void ScoreBoard::render() const std::string timeTxt = std::to_string((clock.minutes % 60) / 10) + std::to_string(clock.minutes % 10) + clock.separator + std::to_string((clock.seconds % 60) / 10) + std::to_string(clock.seconds % 10); const std::string itemsTxt = std::to_string(board->items / 100) + std::to_string((board->items % 100) / 10) + std::to_string(board->items % 10); this->text->writeColored(BLOCK, line1, "Items collected ", board->color); - this->text->writeColored(17 * BLOCK, line1, itemsTxt, stringToColor("white")); + this->text->writeColored(17 * BLOCK, line1, itemsTxt, stringToColor(options->palette, "white")); this->text->writeColored(20 * BLOCK, line1, " Time ", board->color); - this->text->writeColored(26 * BLOCK, line1, timeTxt, stringToColor("white")); + this->text->writeColored(26 * BLOCK, line1, timeTxt, stringToColor(options->palette, "white")); const std::string roomsTxt = std::to_string(board->rooms / 100) + std::to_string((board->rooms % 100) / 10) + std::to_string(board->rooms % 10); - this->text->writeColored(22 * BLOCK, line2, "Rooms", stringToColor("white")); - this->text->writeColored(28 * BLOCK, line2, roomsTxt, stringToColor("white")); + this->text->writeColored(22 * BLOCK, line2, "Rooms", stringToColor(options->palette, "white")); + this->text->writeColored(28 * BLOCK, line2, roomsTxt, stringToColor(options->palette, "white")); } // Actualiza las variables del objeto @@ -121,6 +121,14 @@ void ScoreBoard::reLoadTexture() playerTexture->reLoad(); itemTexture->reLoad(); text->reLoadTexture(); + + // Reinicia el vector de colores + const std::vector vColors = {"blue", "magenta", "green", "cyan", "yellow", "white", "bright_blue", "bright_magenta", "bright_green", "bright_cyan", "bright_yellow", "bright_white"}; + color.clear(); + for (auto v : vColors) + { + color.push_back(stringToColor(options->palette, v)); + } } // Pone el marcador en modo pausa diff --git a/source/scoreboard.h b/source/scoreboard.h index 8c87d73..504500a 100644 --- a/source/scoreboard.h +++ b/source/scoreboard.h @@ -40,6 +40,7 @@ private: Text *text; // Objeto para escribir texto Texture *itemTexture; // Textura con los graficos para las vidas board_t *board; // Contiene las variables a mostrar en el marcador + options_t *options; // Puntero a las opciones del juego // Variables std::vector color; // Vector con los colores del objeto @@ -55,7 +56,7 @@ private: public: // Constructor - ScoreBoard(SDL_Renderer *renderer, Asset *asset, board_t *board); + ScoreBoard(SDL_Renderer *renderer, Asset *asset, options_t *options, board_t *board); // Destructor ~ScoreBoard(); diff --git a/source/title.cpp b/source/title.cpp index 14cff75..f99fb5d 100644 --- a/source/title.cpp +++ b/source/title.cpp @@ -1,16 +1,24 @@ #include "title.h" // Constructor -Title::Title(SDL_Renderer *renderer, Screen *screen, Asset *asset) +Title::Title(SDL_Renderer *renderer, Screen *screen, Asset *asset, options_t *options) { // Copia la dirección de los objetos this->renderer = renderer; this->screen = screen; this->asset = asset; + this->options = options; // Reserva memoria para los punteros eventHandler = new SDL_Event(); - texture = new Texture(renderer, asset->get("loading_screen_color.png")); + if (options->palette == p_zxspectrum) + { + texture = new Texture(renderer, asset->get("loading_screen_color.png")); + } + else if (options->palette == p_zxarne) + { + texture = new Texture(renderer, asset->get("loading_screen_color_zxarne.png")); + } sprite = new Sprite(0, 0, texture->getWidth(), texture->getHeight(), texture, renderer); text = new Text(asset->get("smb2.png"), asset->get("smb2.txt"), renderer); @@ -21,7 +29,7 @@ Title::Title(SDL_Renderer *renderer, Screen *screen, Asset *asset) ticks = 0; ticksSpeed = 15; longText = "HEY JAILERS!! IT'S 2022 AND WE'RE STILL ROCKING LIKE IT'S 1998!!! HAVE YOU HEARD IT? JAILGAMES ARE BACK!! YEEESSS BACK!! MORE THAN 10 TITLES ON JAILDOC'S KITCHEN!! THATS A LOOOOOOT OF JAILGAMES, BUT WHICH ONE WILL STRIKE FIRST? THERE IS ALSO A NEW DEVICE TO COME P.A.C.O. THAT WILL BLOW YOUR MIND WITH JAILGAMES ON THE GO. BUT WAIT! WHAT'S THAT BEAUTY I'M SEEING RIGHT OVER THERE?? OOOH THAT TINY MINIASCII IS PURE LOVE!! I WANT TO LICK EVERY BYTE OF IT!! OH SHIT! AND DON'T FORGET TO BRING BACK THOSE OLD AND FAT MS-DOS JAILGAMES TO GITHUB TO KEEP THEM ALIVE!! WHAT WILL BE THE NEXT JAILDOC RELEASE? WHAT WILL BE THE NEXT PROJECT TO COME ALIVE?? OH BABY WE DON'T KNOW BUT HERE YOU CAN FIND THE ANSWER, YOU JUST HAVE TO COMPLETE JAILDOCTOR'S DILEMMA ... COULD YOU?"; - //longText = "HEY JAILERS!! IT'S 2022 AND WE'RE STILL ROCKING LIKE IT'S 1998!!!"; + // longText = "HEY JAILERS!! IT'S 2022 AND WE'RE STILL ROCKING LIKE IT'S 1998!!!"; for (int i = 0; i < (int)longText.length(); ++i) { letter_t l; @@ -33,7 +41,7 @@ Title::Title(SDL_Renderer *renderer, Screen *screen, Asset *asset) letters[0].enabled = true; // Cambia el color del borde - screen->setBorderColor(stringToColor("bright_blue")); + screen->setBorderColor(stringToColor(options->palette, "bright_blue")); } // Destructor @@ -134,8 +142,7 @@ void Title::renderMarquee() { if (l.enabled) { - // text->writeColored(l.x, 176, l.letter, {0, 0, 0}); - text->write(l.x, 184, l.letter); + text->writeColored(l.x, 184, l.letter, stringToColor(options->palette, "white")); } } } @@ -188,11 +195,12 @@ void Title::render() // text->writeCentered(256 / 2, 192 / 5 * 4, "PRESS ENTER TO PLAY"); //} + // Dibuja el texto de PRESS ENTER TO PLAY if (counter % 80 < 60) { - const color_t textColor = stringToColor("white"); - const color_t strokeColor = stringToColor("bright_blue"); - text->writeDX(TXT_CENTER | TXT_COLOR| TXT_STROKE, 256 / 2, 192 / 5 * 4, "PRESS ENTER TO PLAY", 1, textColor, 1, strokeColor); + const color_t textColor = stringToColor(options->palette, "white"); + const color_t strokeColor = stringToColor(options->palette, "bright_blue"); + text->writeDX(TXT_CENTER | TXT_COLOR | TXT_STROKE, 256 / 2, 192 / 5 * 4, "PRESS ENTER TO PLAY", 1, textColor, 1, strokeColor); } // Dibuja la marquesina diff --git a/source/title.h b/source/title.h index 8da4f0e..188b2d0 100644 --- a/source/title.h +++ b/source/title.h @@ -31,6 +31,7 @@ private: Texture *texture; // Textura con los graficos Sprite *sprite; // Sprite para manejar la textura Text *text; // Objeto para escribir texto en pantalla + options_t *options; // Puntero a las opciones del juego // Variables int counter; // Contador @@ -57,7 +58,7 @@ private: public: // Constructor - Title(SDL_Renderer *renderer, Screen *screen, Asset *asset); + Title(SDL_Renderer *renderer, Screen *screen, Asset *asset, options_t *options); // Destructor ~Title();