mirror of
https://github.com/risingPhil/PokeMe64.git
synced 2026-09-07 16:25:10 -05:00
Implement TransferPakRTCReader and add a "Print Game Clock" menu option temporarily
This commit is contained in:
3
Makefile
3
Makefile
@@ -11,6 +11,9 @@ N64_ROM_REGIONFREE=1
|
||||
N64_ROM_CONTROLLER_TYPE1=n64,pak=transfer
|
||||
N64_ROM_TITLE="PokeMe64"
|
||||
|
||||
# Uncomment this when generating a dev build
|
||||
N64_C_AND_CXX_FLAGS += -DDEV_BUILD
|
||||
|
||||
SRCS := $(shell find $(SOURCE_DIR) -type f -name '*.cpp')
|
||||
OBJS := $(patsubst $(SOURCE_DIR)/%.cpp,$(BUILD_DIR)/%.o,$(SRCS))
|
||||
|
||||
|
||||
@@ -116,4 +116,6 @@ void askConfirmationWipeSave(void* context, const void* param);
|
||||
*/
|
||||
void resetRTC(void* context, const void* param);
|
||||
|
||||
void printClock(void* context, const void* param);
|
||||
|
||||
#endif
|
||||
@@ -22,6 +22,7 @@ public:
|
||||
void render(RDPQGraphics& gfx, const Rectangle& sceneBounds) override;
|
||||
protected:
|
||||
private:
|
||||
char headerTextString_[128];
|
||||
uint8_t fontIdMainFont_;
|
||||
uint8_t fontMainFontStyleWhiteId_;
|
||||
sprite_t* logoLibDragon_;
|
||||
|
||||
@@ -32,6 +32,7 @@ private:
|
||||
void loadSaveMetadata();
|
||||
const char* getGameTypeString();
|
||||
|
||||
char pokeMe64String_[48];
|
||||
sprite_t* menu9SliceSprite_;
|
||||
TransferPakDetectionWidget tpakDetectWidget_;
|
||||
WidgetFocusChainSegment tpakDetectWidgetSegment_;
|
||||
|
||||
@@ -54,6 +54,11 @@ public:
|
||||
*/
|
||||
void switchGBROMBank(uint8_t bankIndex);
|
||||
|
||||
/**
|
||||
* @brief Returns whether we called setRAMEnabled(true) on this TransferPakManager instance before
|
||||
*/
|
||||
bool isRAMEnabled() const;
|
||||
|
||||
/**
|
||||
* @brief This function enables/disables gameboy RAM/RTC access.
|
||||
* WARNING: it switches to transfer pak bank 0
|
||||
@@ -110,6 +115,7 @@ protected:
|
||||
private:
|
||||
joypad_port_t port_;
|
||||
bool isPoweredOn_;
|
||||
bool ramEnabled_;
|
||||
uint8_t currentSRAMBank_;
|
||||
uint16_t readBufferBankOffset_;
|
||||
uint16_t writeBufferSRAMBankOffset_;
|
||||
|
||||
28
include/transferpak/TransferPakRTCReader.h
Normal file
28
include/transferpak/TransferPakRTCReader.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef _TRANSFERPAKRTCREADER_H
|
||||
#define _TRANSFERPAKRTCREADER_H
|
||||
|
||||
#include "RTCReader.h"
|
||||
|
||||
class TransferPakManager;
|
||||
|
||||
/**
|
||||
* @brief This class implements the IRTCReader interface specifically for the N64 Transfer Pak with libdragon
|
||||
*/
|
||||
class TransferPakRTCReader : public BaseRTCReader
|
||||
{
|
||||
public:
|
||||
TransferPakRTCReader(TransferPakManager& tpakManager);
|
||||
virtual ~TransferPakRTCReader();
|
||||
|
||||
/**
|
||||
* This function will grab the current values of the RTC chip and store them internally
|
||||
*
|
||||
* Use the getXYZ() functions to actually retrieve this data
|
||||
*/
|
||||
void latch() override;
|
||||
protected:
|
||||
private:
|
||||
TransferPakManager& tpakManager_;
|
||||
};
|
||||
|
||||
#endif
|
||||
8
include/version.h
Normal file
8
include/version.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef _VERSION_H
|
||||
#define _VERSION_H
|
||||
|
||||
#define POKEME64_VERSION_NUMBER "0.4"
|
||||
|
||||
const char* getPokeMe64VersionString();
|
||||
|
||||
#endif
|
||||
Submodule libpokemegb updated: aedb58832c...58fa35f882
@@ -70,6 +70,10 @@ MenuItemData gen2MenuEntries[] = {
|
||||
.title = "Reset Game Clock",
|
||||
.onConfirmAction = resetRTC
|
||||
},
|
||||
{
|
||||
.title = "Print Game Clock",
|
||||
.onConfirmAction = printClock
|
||||
},
|
||||
{
|
||||
.title = "About",
|
||||
.onConfirmAction = goToAboutScene
|
||||
@@ -107,6 +111,10 @@ MenuItemData gen2CrystalMenuEntries[] = {
|
||||
.title = "Reset Game Clock",
|
||||
.onConfirmAction = resetRTC
|
||||
},
|
||||
{
|
||||
.title = "Print Game Clock",
|
||||
.onConfirmAction = printClock
|
||||
},
|
||||
{
|
||||
.title = "About",
|
||||
.onConfirmAction = goToAboutScene
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "transferpak/TransferPakManager.h"
|
||||
#include "transferpak/TransferPakRomReader.h"
|
||||
#include "transferpak/TransferPakSaveManager.h"
|
||||
#include "transferpak/TransferPakRTCReader.h"
|
||||
|
||||
#define POKEMON_CRYSTAL_ITEM_ID_GS_BALL 0x73
|
||||
|
||||
@@ -795,13 +796,47 @@ void resetRTC(void* context, const void* param)
|
||||
TransferPakManager& tpakManager = scene->getDependencies().tpakManager;
|
||||
TransferPakRomReader romReader(tpakManager);
|
||||
TransferPakSaveManager saveManager(tpakManager);
|
||||
TransferPakRTCReader rtcReader(tpakManager);
|
||||
Gen2GameReader gameReader(romReader, saveManager, gameType, language);
|
||||
|
||||
tpakManager.setRAMEnabled(true);
|
||||
gameReader.resetRTC();
|
||||
gameReader.getClockManager(rtcReader).resetRTC();
|
||||
tpakManager.finishWrites();
|
||||
tpakManager.setRAMEnabled(false);
|
||||
|
||||
setDialogDataText(*diag, "The games' clock was reset! Start the game to reconfigure it! Don't forget to save!");
|
||||
scene->showDialog(diag);
|
||||
}
|
||||
|
||||
void printClock(void* context, const void* param)
|
||||
{
|
||||
MenuScene* scene = static_cast<MenuScene*>(context);
|
||||
|
||||
auto diag = new DialogData{
|
||||
.shouldDeleteWhenDone = true
|
||||
};
|
||||
|
||||
if(scene->getDependencies().generation != 2)
|
||||
{
|
||||
setDialogDataText(*diag, "Sorry! This is only supported for Gen 2 Pokémon games!");
|
||||
scene->showDialog(diag);
|
||||
return;
|
||||
}
|
||||
|
||||
const Gen2GameType gameType = static_cast<Gen2GameType>(scene->getDependencies().specificGenVersion);
|
||||
const Gen2LocalizationLanguage language = static_cast<Gen2LocalizationLanguage>(scene->getDependencies().localization);
|
||||
TransferPakManager& tpakManager = scene->getDependencies().tpakManager;
|
||||
TransferPakRomReader romReader(tpakManager);
|
||||
TransferPakSaveManager saveManager(tpakManager);
|
||||
TransferPakRTCReader rtcReader(tpakManager);
|
||||
Gen2GameReader gameReader(romReader, saveManager, gameType, language);
|
||||
Gen2ClockManager clockManager = gameReader.getClockManager(rtcReader);
|
||||
|
||||
tpakManager.setRAMEnabled(true);
|
||||
clockManager.latchRTC();
|
||||
tpakManager.setRAMEnabled(false);
|
||||
|
||||
setDialogDataText(*diag, "The current time is set to %s, %02hhu:%02hhu:%02hhu!\nRTC: %04hx %02hhx %02hhx %02hhx, off: %02hhx %02hhx %02hhx %02hhx", toString(clockManager.getDay()), clockManager.getHours(), clockManager.getMinutes(), clockManager.getSeconds(), rtcReader.getDaysCounter(), rtcReader.getHours(), rtcReader.getMinutes(), rtcReader.getSeconds(), clockManager.getRTCDayOffset(), clockManager.getRTCHourOffset(), clockManager.getRTCMinuteOffset(), clockManager.getRTCSecondOffset());
|
||||
|
||||
scene->showDialog(diag);
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "scenes/AboutScene.h"
|
||||
#include "core/FontManager.h"
|
||||
#include "scenes/SceneManager.h"
|
||||
#include "version.h"
|
||||
|
||||
static const ScrollWidgetStyle scrollWidgetStyle = {
|
||||
.scrollStep = 15,
|
||||
@@ -37,7 +38,7 @@ TESTING/VALIDATION
|
||||
MajorUpgrade
|
||||
)delim";
|
||||
|
||||
static const char* headerTextString = R"delim(PokeMe64 Version 0.3
|
||||
static const char* headerTextStringFormat = R"delim(PokeMe64 Version %s
|
||||
by risingPhil
|
||||
|
||||
SPECIAL THANKS TO:
|
||||
@@ -46,6 +47,7 @@ SPECIAL THANKS TO:
|
||||
|
||||
AboutScene::AboutScene(SceneDependencies& deps, void*)
|
||||
: AbstractUIScene(deps)
|
||||
, headerTextString_()
|
||||
, fontIdMainFont_(1)
|
||||
, fontMainFontStyleWhiteId_(0)
|
||||
, logoLibDragon_(nullptr)
|
||||
@@ -76,6 +78,7 @@ AboutScene::AboutScene(SceneDependencies& deps, void*)
|
||||
})
|
||||
, bButtonPressed_(false)
|
||||
{
|
||||
snprintf(headerTextString_, sizeof(headerTextString_), headerTextStringFormat, getPokeMe64VersionString());
|
||||
fontIdMainFont_ = deps.fontManager.getFont("rom://Arial.font64");
|
||||
|
||||
const rdpq_fontstyle_t mainFontWhite = {
|
||||
@@ -129,7 +132,7 @@ void AboutScene::init()
|
||||
|
||||
headerText_.setBounds(headerTextBounds);
|
||||
headerText_.setStyle(headerTextStyle);
|
||||
headerText_.setData(headerTextString);
|
||||
headerText_.setData(headerTextString_);
|
||||
scrollWidget_.addWidget(&headerText_);
|
||||
|
||||
const ImageWidgetStyle imgDragonStyle = {
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "gen1/Gen1GameReader.h"
|
||||
#include "gen2/Gen2GameReader.h"
|
||||
#include "menu/MenuEntries.h"
|
||||
#include "version.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -27,6 +28,7 @@ static void tpakWidgetStateChangedCallback(void* context, TransferPakWidgetState
|
||||
|
||||
InitTransferPakScene::InitTransferPakScene(SceneDependencies& deps, void*)
|
||||
: SceneWithDialogWidget(deps)
|
||||
, pokeMe64String_()
|
||||
, menu9SliceSprite_(nullptr)
|
||||
, tpakDetectWidget_(deps.animationManager, deps.tpakManager)
|
||||
, tpakDetectWidgetSegment_(WidgetFocusChainSegment{
|
||||
@@ -45,6 +47,8 @@ InitTransferPakScene::~InitTransferPakScene()
|
||||
void InitTransferPakScene::init()
|
||||
{
|
||||
uint8_t systemEntropy[4];
|
||||
|
||||
snprintf(pokeMe64String_, sizeof(pokeMe64String_), "PokeMe64 by risingPhil. Version %s", getPokeMe64VersionString());
|
||||
menu9SliceSprite_ = sprite_load("rom://menu-bg-9slice.sprite");
|
||||
|
||||
SceneWithDialogWidget::init();
|
||||
@@ -77,7 +81,7 @@ void InitTransferPakScene::destroy()
|
||||
|
||||
void InitTransferPakScene::render(RDPQGraphics& gfx, const Rectangle& sceneBounds)
|
||||
{
|
||||
gfx.drawText(Rectangle{0, 10, 320, 16}, "PokeMe64 by risingPhil. Version 0.3", pokeMe64TextSettings_);
|
||||
gfx.drawText(Rectangle{0, 10, 320, 16}, pokeMe64String_, pokeMe64TextSettings_);
|
||||
tpakDetectWidget_.render(gfx, sceneBounds);
|
||||
|
||||
SceneWithDialogWidget::render(gfx, sceneBounds);
|
||||
|
||||
@@ -11,6 +11,7 @@ static const uint16_t sramBankStartGBAddress = 0xA000;
|
||||
TransferPakManager::TransferPakManager()
|
||||
: port_(JOYPAD_PORT_1)
|
||||
, isPoweredOn_(false)
|
||||
, ramEnabled_(false)
|
||||
, currentSRAMBank_(0)
|
||||
, readBufferBankOffset_(0xFFFF)
|
||||
, writeBufferSRAMBankOffset_(0xFFFF)
|
||||
@@ -139,6 +140,11 @@ void TransferPakManager::switchGBROMBank(uint8_t bankIndex)
|
||||
readBufferBankOffset_ = 0xFFFF;
|
||||
}
|
||||
|
||||
bool TransferPakManager::isRAMEnabled() const
|
||||
{
|
||||
return ramEnabled_;
|
||||
}
|
||||
|
||||
void TransferPakManager::setRAMEnabled(bool enabled)
|
||||
{
|
||||
uint8_t data[TPAK_BLOCK_SIZE];
|
||||
@@ -157,6 +163,7 @@ void TransferPakManager::setRAMEnabled(bool enabled)
|
||||
debugf("[TransferPakManager]: %s: ERROR: transfer pak not ready yet. Current status is %hu\r\n", __FUNCTION__, status);
|
||||
status = getStatus();
|
||||
}
|
||||
ramEnabled_ = enabled;
|
||||
}
|
||||
|
||||
void TransferPakManager::switchGBSRAMBank(uint8_t bankIndex)
|
||||
|
||||
57
src/transferpak/TransferPakRTCReader.cpp
Normal file
57
src/transferpak/TransferPakRTCReader.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
#include "transferpak/TransferPakRTCReader.h"
|
||||
#include "transferpak/TransferPakManager.h"
|
||||
|
||||
TransferPakRTCReader::TransferPakRTCReader(TransferPakManager& tpakManager)
|
||||
: tpakManager_(tpakManager)
|
||||
{
|
||||
}
|
||||
|
||||
TransferPakRTCReader::~TransferPakRTCReader()
|
||||
{
|
||||
}
|
||||
|
||||
void TransferPakRTCReader::latch()
|
||||
{
|
||||
uint8_t data[TPAK_BLOCK_SIZE];
|
||||
const int port = tpakManager_.getPort();
|
||||
|
||||
// enable SRAM and RTC first
|
||||
const bool previousRAMState = tpakManager_.isRAMEnabled();
|
||||
tpakManager_.setRAMEnabled(true);
|
||||
tpakManager_.finishWrites();
|
||||
|
||||
// now latch the RTC data into the RTC registers
|
||||
// https://gbdev.io/pandocs/MBC3.html
|
||||
memset(data, 0, sizeof(data));
|
||||
tpak_write(port, 0x6000, data, TPAK_BLOCK_SIZE);
|
||||
memset(data, 1, sizeof(data));
|
||||
tpak_write(port, 0x6000, data, TPAK_BLOCK_SIZE);
|
||||
|
||||
// RTC S (seconds)
|
||||
tpakManager_.switchGBSRAMBank(0x08);
|
||||
tpak_read(port, 0xA000, data, sizeof(data));
|
||||
seconds_ = data[0];
|
||||
|
||||
// RTC M (minutes)
|
||||
tpakManager_.switchGBSRAMBank(0x09);
|
||||
tpak_read(port, 0xA000, data, sizeof(data));
|
||||
minutes_ = data[0];
|
||||
|
||||
// RTC H (hours)
|
||||
tpakManager_.switchGBSRAMBank(0x0A);
|
||||
tpak_read(port, 0xA000, data, sizeof(data));
|
||||
hours_ = data[0];
|
||||
|
||||
// RTC DH (days counter upper 8 bits)
|
||||
tpakManager_.switchGBSRAMBank(0x0C);
|
||||
tpak_read(port, 0xA000, data, sizeof(data));
|
||||
daysRaw_ = data[0];
|
||||
daysRaw_ <<= 8;
|
||||
|
||||
// RTC DL (days counter lower 8 bits)
|
||||
tpakManager_.switchGBSRAMBank(0x0B);
|
||||
tpak_read(port, 0xA000, data, sizeof(data));
|
||||
daysRaw_ |= data[0];
|
||||
|
||||
tpakManager_.setRAMEnabled(previousRAMState);
|
||||
}
|
||||
52
src/version.cpp
Normal file
52
src/version.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
#include "version.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <cstdint>
|
||||
|
||||
#ifdef DEV_BUILD
|
||||
static const char DEV_SUFFIX_STRING[] = "-dev";
|
||||
|
||||
static const char *months[] = {
|
||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||
};
|
||||
|
||||
static uint8_t get_month_number(const char *month)
|
||||
{
|
||||
for (uint8_t i = 0; i < 12; ++i)
|
||||
{
|
||||
if (strcmp(month, months[i]) == 0)
|
||||
{
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
return 0; // Should never happen
|
||||
}
|
||||
#endif
|
||||
|
||||
const char* getPokeMe64VersionString()
|
||||
{
|
||||
static char versionString[20];
|
||||
|
||||
memcpy(versionString, POKEME64_VERSION_NUMBER, sizeof(POKEME64_VERSION_NUMBER));
|
||||
|
||||
#ifdef DEV_BUILD
|
||||
size_t currentStringLength;
|
||||
char month[4];
|
||||
uint16_t year;
|
||||
int day;
|
||||
uint8_t monthNumber;
|
||||
|
||||
strcat(versionString, DEV_SUFFIX_STRING);
|
||||
// -2 to not count the null terminators
|
||||
currentStringLength = sizeof(POKEME64_VERSION_NUMBER) + sizeof(DEV_SUFFIX_STRING) - 2;
|
||||
|
||||
// Parse __DATE__ ("MMM DD YYYY")
|
||||
// We can't use strptime() because libdragon doesn't appear to have it.
|
||||
sscanf(__DATE__, "%3s %d %hu", month, &day, &year);
|
||||
monthNumber = get_month_number(month);
|
||||
snprintf(versionString + currentStringLength, sizeof(versionString) - currentStringLength, "%04hu%02hhu%02d", year, monthNumber, day);
|
||||
#endif
|
||||
return versionString;
|
||||
}
|
||||
Reference in New Issue
Block a user