diff --git a/assets/cartridge-icon.png b/assets/cartridge-icon.png new file mode 100644 index 0000000..59714b9 Binary files /dev/null and b/assets/cartridge-icon.png differ diff --git a/assets/cartridge-label-blue.png b/assets/cartridge-label-blue.png new file mode 100644 index 0000000..7fe5cbe Binary files /dev/null and b/assets/cartridge-label-blue.png differ diff --git a/assets/cartridge-label-crystal.png b/assets/cartridge-label-crystal.png new file mode 100644 index 0000000..25873ca Binary files /dev/null and b/assets/cartridge-label-crystal.png differ diff --git a/assets/cartridge-label-gold.png b/assets/cartridge-label-gold.png new file mode 100644 index 0000000..ce74b25 Binary files /dev/null and b/assets/cartridge-label-gold.png differ diff --git a/assets/cartridge-label-red.png b/assets/cartridge-label-red.png new file mode 100644 index 0000000..aa5a4f1 Binary files /dev/null and b/assets/cartridge-label-red.png differ diff --git a/assets/cartridge-label-silver.png b/assets/cartridge-label-silver.png new file mode 100644 index 0000000..e5f90bf Binary files /dev/null and b/assets/cartridge-label-silver.png differ diff --git a/assets/cartridge-label-unknown.png b/assets/cartridge-label-unknown.png new file mode 100644 index 0000000..f23ae1e Binary files /dev/null and b/assets/cartridge-label-unknown.png differ diff --git a/assets/cartridge-label-yellow.png b/assets/cartridge-label-yellow.png new file mode 100644 index 0000000..8fc7bc1 Binary files /dev/null and b/assets/cartridge-label-yellow.png differ diff --git a/include/core/Sprite.h b/include/core/Sprite.h index 70e7738..c4400a8 100755 --- a/include/core/Sprite.h +++ b/include/core/Sprite.h @@ -58,6 +58,16 @@ typedef struct SpriteRenderSettings * @brief Rotation angle in radians */ float rotationAngle; + struct { + /** + * WARNING: needs to be a multiple of 8 + */ + uint8_t numColors; + /** + * @brief If set, this RGBA16 array will replace the original color palette for the specified sprite + */ + const uint16_t* colorsRGBA16; + } customPalette; } SpriteRenderSettings; typedef struct SurfaceRenderSettings diff --git a/include/scenes/InitTransferPakScene.h b/include/scenes/InitTransferPakScene.h index 509af6e..2aab4de 100755 --- a/include/scenes/InitTransferPakScene.h +++ b/include/scenes/InitTransferPakScene.h @@ -37,6 +37,7 @@ private: TransferPakDetectionWidget tpakDetectWidget_; WidgetFocusChainSegment tpakDetectWidgetSegment_; DialogData diagData_; + TextRenderSettings pokeMe64TextSettings_; char playerName_[PLAYER_NAME_SIZE]; const char* gameTypeString_; }; diff --git a/include/scenes/StatsScene.h b/include/scenes/StatsScene.h index eab08b3..6fa45c1 100644 --- a/include/scenes/StatsScene.h +++ b/include/scenes/StatsScene.h @@ -54,7 +54,7 @@ private: TextRenderSettings smallTextSettings_; TextRenderSettings statsSettings_; Rectangle spriteBounds_; - char nameBuffer_[15]; + char nameBuffer_[25]; char levelAndNumberBuffer_[40]; char pokeStatsString_[150]; char otInfoString_[40]; diff --git a/include/widget/TransferPakDetectionWidget.h b/include/widget/TransferPakDetectionWidget.h index 1b8d65b..6c514e3 100755 --- a/include/widget/TransferPakDetectionWidget.h +++ b/include/widget/TransferPakDetectionWidget.h @@ -130,17 +130,22 @@ private: */ bool detectGameType(); + void updateCartridgeIcon(); + TransferPakDetectionWidgetStyle style_; AnimationManager& animManager_; TransferPakManager& tpakManager_; Rectangle bounds_; - Rectangle textBounds_; TransferPakWidgetState currentState_; joypad_inputs_t previousInputState_; Gen1GameType gen1Type_; Gen2GameType gen2Type_; void (*stateChangedCallback_)(void*, TransferPakWidgetState); void* stateChangedCallbackContext_; + sprite_t* cartridgeIconSprite_; + sprite_t* cartridgeLabelSprite_; + SpriteRenderSettings cartridgeIconRenderSettings_; + SpriteRenderSettings cartridgeLabelRenderSettings_; bool focused_; bool visible_; }; diff --git a/src/core/RDPQGraphics.cpp b/src/core/RDPQGraphics.cpp index 168fdc6..e3c8dd8 100755 --- a/src/core/RDPQGraphics.cpp +++ b/src/core/RDPQGraphics.cpp @@ -1,6 +1,47 @@ #include "core/RDPQGraphics.h" #include "core/Sprite.h" +/** + * @brief Custom version of sprite_upload_palette() from rdpq_sprite.c + * This variant allows you to override the sprites' palette with the SpriteRenderSettings instead of using the one + * embedded in the sprite itself + */ +static void custom_sprite_upload_palette(sprite_t *sprite, const SpriteRenderSettings& renderSettings) +{ + // Check if the sprite has a palette + tex_format_t fmt = sprite_get_format(sprite); + rdpq_tlut_t tlut_mode = rdpq_tlut_from_format(fmt); + + // Configure the TLUT render mode + rdpq_mode_tlut(tlut_mode); + + if (tlut_mode != TLUT_NONE) { + // Load the palette (if any). We account for sprites being CI4 + // but without embedded palette: mksprite doesn't create sprites like + // this today, but it could in the future (eg: sharing a palette across + // multiple sprites). + if(renderSettings.customPalette.numColors) + { + rdpq_tex_upload_tlut(const_cast(renderSettings.customPalette.colorsRGBA16), 0, renderSettings.customPalette.numColors); + } + else + { + uint16_t *pal = sprite_get_palette(sprite); + if (pal) rdpq_tex_upload_tlut(pal, 0, fmt == FMT_CI4 ? 16 : 256); + } + } +} + +/** + * @brief Custom version of rdpq_sprite_blit which allows you to call custom_sprite_upload_palette separately + */ +static void custom_rdpq_sprite_blit(sprite_t* sprite, float x0, float y0, const rdpq_blitparms_t *parms) +{ + // Get the sprite surface + surface_t surf = sprite_get_pixels(sprite); + rdpq_tex_blit(&surf, x0, y0, parms); +} + static void render_sprite_normal(const Rectangle &dstRect, sprite_t *sprite, const SpriteRenderSettings &renderSettings) { if (!isZeroSizeRectangle(renderSettings.srcRect)) @@ -15,7 +56,8 @@ static void render_sprite_normal(const Rectangle &dstRect, sprite_t *sprite, con .theta = renderSettings.rotationAngle }; - rdpq_sprite_blit(sprite, dstRect.x, dstRect.y, &blitParams); + custom_sprite_upload_palette(sprite, renderSettings); + custom_rdpq_sprite_blit(sprite, dstRect.x, dstRect.y, &blitParams); } else { @@ -25,7 +67,8 @@ static void render_sprite_normal(const Rectangle &dstRect, sprite_t *sprite, con .theta = renderSettings.rotationAngle }; - rdpq_sprite_blit(sprite, dstRect.x, dstRect.y, &blitParams); + custom_sprite_upload_palette(sprite, renderSettings); + custom_rdpq_sprite_blit(sprite, dstRect.x, dstRect.y, &blitParams); } } @@ -44,7 +87,7 @@ static void render_sprite_ninegrid(const Rectangle &dstRect, sprite_t *sprite, c .width = renderSettings.srcRect.x, .height = renderSettings.srcRect.y }; - render_sprite_normal(curDest, sprite, {.renderMode = SpriteRenderMode::NORMAL, .srcRect = curSrc}); + render_sprite_normal(curDest, sprite, {.renderMode = SpriteRenderMode::NORMAL, .srcRect = curSrc, .customPalette = renderSettings.customPalette}); // top edge curDest = { @@ -59,7 +102,7 @@ static void render_sprite_ninegrid(const Rectangle &dstRect, sprite_t *sprite, c .width = sprite->width - renderSettings.srcRect.width - renderSettings.srcRect.x, .height = renderSettings.srcRect.y }; - render_sprite_normal(curDest, sprite, {.renderMode = SpriteRenderMode::NORMAL, .srcRect = curSrc}); + render_sprite_normal(curDest, sprite, {.renderMode = SpriteRenderMode::NORMAL, .srcRect = curSrc, .customPalette = renderSettings.customPalette}); // right top corner curDest = { @@ -210,13 +253,13 @@ RDPQGraphics::~RDPQGraphics() void RDPQGraphics::init() { rdpq_init(); - rdpq_debug_start(); +// rdpq_debug_start(); initialized_ = true; } void RDPQGraphics::destroy() { - rdpq_debug_stop(); +// rdpq_debug_stop(); rdpq_close(); initialized_ = false; } diff --git a/src/menu/MenuFunctions.cpp b/src/menu/MenuFunctions.cpp index e57b22d..cbf275d 100755 --- a/src/menu/MenuFunctions.cpp +++ b/src/menu/MenuFunctions.cpp @@ -52,6 +52,9 @@ static void goToDistributionPokemonListMenu(void* context, DistributionPokemonLi { auto sceneContext = new DistributionPokemonListSceneContext; sceneContext->listType = type; + sceneContext->bButtonMeansUserWantsToSwitchCartridge = false; + sceneContext->numMenuEntries = 0; + sceneContext->menuEntries = nullptr; MenuScene* scene = static_cast(context); SceneManager& sceneManager = scene->getDependencies().sceneManager; diff --git a/src/scenes/InitTransferPakScene.cpp b/src/scenes/InitTransferPakScene.cpp index 8dd3326..357f0f6 100755 --- a/src/scenes/InitTransferPakScene.cpp +++ b/src/scenes/InitTransferPakScene.cpp @@ -8,6 +8,8 @@ #include "gen2/Gen2GameReader.h" #include "menu/MenuEntries.h" +static const Rectangle tpakDetectWidgetBounds = {60, 44, 200, 116}; + static void dialogFinishedCallback(void* context) { InitTransferPakScene* scene = (InitTransferPakScene*)context; @@ -28,6 +30,7 @@ InitTransferPakScene::InitTransferPakScene(SceneDependencies& deps, void*) .current = &tpakDetectWidget_ }) , diagData_({0}) + , pokeMe64TextSettings_() , playerName_() , gameTypeString_(nullptr) { @@ -47,6 +50,12 @@ void InitTransferPakScene::init() setupTPakDetectWidget(); setFocusChain(&tpakDetectWidgetSegment_); + + pokeMe64TextSettings_ = TextRenderSettings{ + .fontId = arialId_, + .fontStyleId = fontStyleWhiteId_, + .halign = ALIGN_CENTER + }; } void InitTransferPakScene::destroy() @@ -59,7 +68,7 @@ void InitTransferPakScene::destroy() void InitTransferPakScene::render(RDPQGraphics& gfx, const Rectangle& sceneBounds) { - //gfx.fillRectangle(Rectangle{.x = 0, .y = 0, .width = 100, .height = 100}, RGBA16(31, 0, 0, 1)); + gfx.drawText(Rectangle{0, 10, 320, 16}, "PokeMe64 by risingPhil. Version 0.1", pokeMe64TextSettings_); tpakDetectWidget_.render(gfx, sceneBounds); SceneWithDialogWidget::render(gfx, sceneBounds); @@ -134,6 +143,22 @@ void InitTransferPakScene::onTransferPakWidgetStateChanged(TransferPakWidgetStat dialogWidget_.setVisible(true); setFocusChain(&dialogFocusChainSegment_); } + else + { + switch(newState) + { + case TransferPakWidgetState::GB_HEADER_VALIDATION_FAILED: + case TransferPakWidgetState::NO_GAME_FOUND: + case TransferPakWidgetState::NO_TRANSFER_PAK_FOUND: + setDialogDataText(diagData_, "We could not find a suitable game cartridge! Please turn the console off and try again!"); + diagData_.userAdvanceBlocked = true; + dialogWidget_.appendDialogData(&diagData_); + dialogWidget_.setVisible(true); + break; + default: + break; + } + } } void InitTransferPakScene::setupTPakDetectWidget() @@ -141,13 +166,14 @@ void InitTransferPakScene::setupTPakDetectWidget() const TransferPakDetectionWidgetStyle style = { .textSettings = { .fontId = arialId_, - .fontStyleId = fontStyleWhiteId_ + .fontStyleId = fontStyleWhiteId_, + .halign = ALIGN_CENTER } }; tpakDetectWidget_.setStyle(style); tpakDetectWidget_.setStateChangedCallback(tpakWidgetStateChangedCallback, this); - tpakDetectWidget_.setBounds(Rectangle{60, 90, 200, 60}); + tpakDetectWidget_.setBounds(tpakDetectWidgetBounds); } void InitTransferPakScene::setupDialog(DialogWidgetStyle& style) diff --git a/src/scenes/MenuScene.cpp b/src/scenes/MenuScene.cpp index 7972537..2dc0251 100755 --- a/src/scenes/MenuScene.cpp +++ b/src/scenes/MenuScene.cpp @@ -142,6 +142,8 @@ void MenuScene::onDialogDone() dialogWidget_.setVisible(false); menuList_.setVisible(true); cursorWidget_.setVisible(true); + // make sure the relevant scroll arrows are made visible again + menuList_.notifyScrollWindowListeners(); setFocusChain(&listFocusChainSegment_); } @@ -267,6 +269,8 @@ void MenuScene::showDialog(DialogData* diagData) { SceneWithDialogWidget::showDialog(diagData); menuList_.setVisible(false); + scrollArrowUp_.setVisible(false); + scrollArrowDown_.setVisible(false); cursorWidget_.setVisible(false); setFocusChain(&dialogFocusChainSegment_); } diff --git a/src/scenes/StatsScene.cpp b/src/scenes/StatsScene.cpp index db63c85..6d304e0 100644 --- a/src/scenes/StatsScene.cpp +++ b/src/scenes/StatsScene.cpp @@ -114,6 +114,7 @@ void StatsScene::init() const char* move4Str; const char* pokeName; const char* trainerName; + const char* shinyText; bool shiny; menu9SliceSprite_ = sprite_load("rom://menu-bg-9slice.sprite"); @@ -147,7 +148,7 @@ void StatsScene::init() pokeName = gen1GameReader_.getPokemonName(pokeIndex); trainerName = gen1GameReader_.getTrainerName(); shiny = false; - snprintf(pokeStatsString_, sizeof(pokeStatsString_), "ATK: %u\nDEF: %u\nSPEC: %u\nSPEED: %u", atk, def, specAtk, speed); + snprintf(pokeStatsString_, sizeof(pokeStatsString_), "ATK: %u\nDEF: %u\nSPEC: %u\nSPEED: %u", atk, def, specAtk, speed); break; case 2: gen2_recalculatePokeStats(gen2GameReader_, context_->poke_g2); @@ -178,7 +179,8 @@ void StatsScene::init() loadPokemonSprite(pokeIndex, shiny); - strncpy(nameBuffer_, pokeName, sizeof(nameBuffer_) - 1); + shinyText = (shiny) ? "Shiny " : ""; + snprintf(nameBuffer_, sizeof(nameBuffer_) - 1, "%s%s", shinyText, pokeName); snprintf(levelAndNumberBuffer_, sizeof(levelAndNumberBuffer_), "L %hu No. %hu\nHP: %u/%u", level, pokeNumber, hp, hp); snprintf(otInfoString_, sizeof(otInfoString_), "TID: %u\nOT: %s", trainerID, context_->trainerName); snprintf(movesString, sizeof(movesString), "%s\n%s\n%s\n%s", move1Str, move2Str, move3Str, move4Str); @@ -187,11 +189,11 @@ void StatsScene::init() { if(context_->isEgg) { - setDialogDataText(diag_, "%s received a %s EGG!Take good care of it!", trainerName, pokeName); + setDialogDataText(diag_, "%s received a %s%s EGG!Take good care of it!", trainerName, shinyText, pokeName); } else { - setDialogDataText(diag_, "%s received %s!\nTake good care of it!", trainerName, pokeName); + setDialogDataText(diag_, "%s received a %s%s!\nTake good care of it!", trainerName, shinyText, pokeName); } showDialog(&diag_); } diff --git a/src/widget/TransferPakDetectionWidget.cpp b/src/widget/TransferPakDetectionWidget.cpp index da694b0..1d4b7f4 100755 --- a/src/widget/TransferPakDetectionWidget.cpp +++ b/src/widget/TransferPakDetectionWidget.cpp @@ -3,6 +3,30 @@ #include "transferpak/TransferPakRomReader.h" #include "transferpak/TransferPakSaveManager.h" +/** + * @brief This function allows you to specify a 32 bit RGBA color by specifying separate color components + * and converting it to a RGBA16 uint16_t value at compile time + * + * @param r 8 bit red value + * @param g 8 bit green value + * @param b 8 bit blue value + * @param a 8 bit alpha value + */ +constexpr uint16_t colorToRGBA16(uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + return (((uint16_t)r >> 3) << 11) | (((uint16_t)g >> 3) << 6) | (((uint16_t)b >> 3) << 1) | (a >> 7); +} + +static const Rectangle textBounds = {0, 100, 200, 20}; +static const Rectangle cartridgeLabelBounds = {9, 26, 70, 62}; + +static const uint16_t paletteBlue[] = {0, colorToRGBA16(0x20, 0x30, 0x81, 0xFF), colorToRGBA16(0x15, 0x3B, 0xB0, 0xFF), 0, 0, 0, 0, 0}; +static const uint16_t paletteRed[] = {0, colorToRGBA16(0xA7, 0x1F, 0x1B, 0xFF), colorToRGBA16(0xAA, 0x2A, 0x2A, 0xFF), 0, 0, 0, 0, 0}; +static const uint16_t paletteYellow[] = {0, colorToRGBA16(0xEA, 0xA8, 0x2C, 0xFF), colorToRGBA16(0xF4, 0xB0, 0x2E, 0xFF), 0, 0, 0, 0, 0}; +static const uint16_t paletteGold[] = {0, colorToRGBA16(0x8A, 0x86, 0x48, 0xFF), colorToRGBA16(0x88, 0x89, 0x4B, 0xFF), 0, 0, 0, 0, 0}; +static const uint16_t paletteSilver[] = {0, colorToRGBA16(0x90, 0x8D, 0x85, 0xFF), colorToRGBA16(0xA2, 0x9E, 0x98, 0xFF), 0, 0, 0, 0, 0}; +static const uint16_t paletteCrystal[] = {0, colorToRGBA16(0x55, 0x7A, 0x77, 0xFF), colorToRGBA16(0x72, 0x9E, 0xA4, 0xFF), 0, 0, 0, 0, 0}; + #if 0 #include "gen2/Gen2GameReader.h" static void doRandomShit(TransferPakManager& tpakManager) @@ -22,20 +46,33 @@ TransferPakDetectionWidget::TransferPakDetectionWidget(AnimationManager& animMan , animManager_(animManager) , tpakManager_(pakManager) , bounds_({0}) - , textBounds_({.x = 0, .y = 0, .width = 200, .height = 20}) , currentState_(TransferPakWidgetState::UNKNOWN) , previousInputState_({0}) , gen1Type_(Gen1GameType::INVALID) , gen2Type_(Gen2GameType::INVALID) , stateChangedCallback_(nullptr) , stateChangedCallbackContext_(nullptr) + , cartridgeIconSprite_(nullptr) + , cartridgeLabelSprite_(nullptr) + , cartridgeIconRenderSettings_() + , cartridgeLabelRenderSettings_() , focused_(false) , visible_(true) { + cartridgeIconSprite_ = sprite_load("rom://cartridge-icon.sprite"); + cartridgeLabelSprite_ = sprite_load("rom://cartridge-label-unknown.sprite"); } TransferPakDetectionWidget::~TransferPakDetectionWidget() { + sprite_free(cartridgeIconSprite_); + cartridgeIconSprite_ = nullptr; + + if(cartridgeLabelSprite_) + { + sprite_free(cartridgeLabelSprite_); + cartridgeLabelSprite_ = nullptr; + } } bool TransferPakDetectionWidget::isFocused() const @@ -95,6 +132,16 @@ bool TransferPakDetectionWidget::handleUserInput(const joypad_inputs_t& userInpu void TransferPakDetectionWidget::render(RDPQGraphics& gfx, const Rectangle& parentBounds) { + //gfx.fillRectangle(bounds_, RGBA32(0xFF, 0, 0, 0xFF)); + const Rectangle absoluteIconBounds = {bounds_.x + ((bounds_.width - 88) / 2), bounds_.y, 88, 100}; + gfx.drawSprite(absoluteIconBounds, cartridgeIconSprite_, cartridgeIconRenderSettings_); + + if(cartridgeLabelSprite_) + { + const Rectangle absoluteLabelBounds = addOffset(cartridgeLabelBounds, absoluteIconBounds); + gfx.drawSprite(absoluteLabelBounds, cartridgeLabelSprite_, cartridgeLabelRenderSettings_); + } + switch(currentState_) { case TransferPakWidgetState::UNKNOWN: @@ -155,6 +202,7 @@ void TransferPakDetectionWidget::switchState(TransferPakWidgetState previousStat switchState(state, newState); return; case TransferPakWidgetState::GAME_FOUND: + updateCartridgeIcon(); // doRandomShit(tpakManager_); break; default: @@ -170,13 +218,13 @@ void TransferPakDetectionWidget::switchState(TransferPakWidgetState previousStat void TransferPakDetectionWidget::renderUnknownState(RDPQGraphics& gfx, const Rectangle& parentBounds) { - const Rectangle absoluteTextBounds = addOffset(textBounds_, bounds_); - gfx.drawText(absoluteTextBounds, "Press A to check the transfer pak...", style_.textSettings); + const Rectangle absoluteTextBounds = addOffset(textBounds, bounds_); + gfx.drawText(absoluteTextBounds, "Press A to start", style_.textSettings); } void TransferPakDetectionWidget::renderErrorState(RDPQGraphics& gfx, const Rectangle& parentBounds) { - const Rectangle absoluteTextBounds = addOffset(textBounds_, bounds_); + const Rectangle absoluteTextBounds = addOffset(textBounds, bounds_); const char* errorText; switch(currentState_) @@ -238,4 +286,64 @@ bool TransferPakDetectionWidget::detectGameType() gen2Type_ = gen2_determineGameType(cartridgeHeader); return (gen1Type_ != Gen1GameType::INVALID || gen2Type_ != Gen2GameType::INVALID); +} + +void TransferPakDetectionWidget::updateCartridgeIcon() +{ + const char* labelSpritePath = nullptr; + if(gen1Type_ != Gen1GameType::INVALID) + { + switch(gen1Type_) + { + case Gen1GameType::BLUE: + cartridgeIconRenderSettings_.customPalette.numColors = sizeof(paletteBlue) / sizeof(paletteBlue[0]); + cartridgeIconRenderSettings_.customPalette.colorsRGBA16 = paletteBlue; + labelSpritePath = "rom://cartridge-label-blue.sprite"; + break; + case Gen1GameType::RED: + cartridgeIconRenderSettings_.customPalette.numColors = sizeof(paletteRed) / sizeof(paletteRed[0]); + cartridgeIconRenderSettings_.customPalette.colorsRGBA16 = paletteRed; + labelSpritePath = "rom://cartridge-label-red.sprite"; + break; + case Gen1GameType::YELLOW: + cartridgeIconRenderSettings_.customPalette.numColors = sizeof(paletteYellow) / sizeof(paletteYellow[0]); + cartridgeIconRenderSettings_.customPalette.colorsRGBA16 = paletteYellow; + labelSpritePath = "rom://cartridge-label-yellow.sprite"; + break; + default: + break; + } + } + else if(gen2Type_ != Gen2GameType::INVALID) + { + switch(gen2Type_) + { + case Gen2GameType::GOLD: + cartridgeIconRenderSettings_.customPalette.numColors = sizeof(paletteGold) / sizeof(paletteGold[0]); + cartridgeIconRenderSettings_.customPalette.colorsRGBA16 = paletteGold; + labelSpritePath = "rom://cartridge-label-gold.sprite"; + break; + case Gen2GameType::SILVER: + cartridgeIconRenderSettings_.customPalette.numColors = sizeof(paletteSilver) / sizeof(paletteSilver[0]); + cartridgeIconRenderSettings_.customPalette.colorsRGBA16 = paletteSilver; + labelSpritePath = "rom://cartridge-label-silver.sprite"; + break; + case Gen2GameType::CRYSTAL: + cartridgeIconRenderSettings_.customPalette.numColors = sizeof(paletteCrystal) / sizeof(paletteCrystal[0]); + cartridgeIconRenderSettings_.customPalette.colorsRGBA16 = paletteCrystal; + labelSpritePath = "rom://cartridge-label-crystal.sprite"; + break; + default: + break; + } + } + + if(labelSpritePath) + { + if(cartridgeLabelSprite_) + { + sprite_free(cartridgeLabelSprite_); + } + cartridgeLabelSprite_ = sprite_load(labelSpritePath); + } } \ No newline at end of file