Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 37 additions & 10 deletions include/game/bases/d_message.hpp
Original file line number Diff line number Diff line change
@@ -1,17 +1,44 @@
#pragma once

#include <types.h>
#include <egg/core/eggHeap.h>
#include <egg/core/eggMsgRes.h>
#include <game/bases/d_msg_res.hpp>
#include <game/bases/d_dvd.hpp>

class MsgRes_c : public EGG::MsgRes {
/// @brief Helper class for managing message resources.
/// @ingroup bases
class dMessage_c {
public:
u8 getFont(ulong messageGroup, ulong messageID);
u16 getScale(ulong messageGroup, ulong messageID);
};
dMessage_c(); ///< Constructs a new @p dMessage_c instance.
~dMessage_c(); ///< Destroys the @p dMessage_c instance.

private:
void buildMsgRes(EGG::Heap *heap); ///< Creates a new @p MsgRes_c instance from the loaded message resource file.

class dMessage_c {
public:
static bool create(EGG::Heap *heap);
static MsgRes_c *getMesRes();
static bool create(EGG::Heap *heap); ///< Loads the message resource file from disk and initializes it.
static wchar_t *getMsg(ulong messageGroup, ulong messageID); ///< Gets a message from the group number and ID.
static MsgRes_c *getMesRes(); ///< Gets the @p MsgRes_c instance used.

/**
* @brief Writes @p num into @p dst with @p digitCount decimal digits, replacing
* suppressed leading zeros with spaces. At most @p writeLimit characters are
* written, followed by a null terminator.
* @unofficial
*
* @param num The number to convert.
* @param dst The destination buffer.
* @param writeLimit The maximum number of characters to write.
* @param digitCount The number of digits to write.
* @param suppressLeadingZero Whether to suppress leading zeros (1) or not (0).
*/
static void numToString(int num, wchar_t *dst, size_t writeLimit, int digitCount, int suppressLeadingZero);

/// @brief Same as ::numToString, but uses full-width characters.
/// @unofficial
static void numToFullWidth(int num, wchar_t *dst, size_t writeLimit, int digitCount, int suppressLeadingZero);

static void changetoFullSize(wchar_t *str); ///< Converts regular ASCII characters in @p str to full-width characters.

dDvd::loader_c mLoader; ///< The loader for loading the message resource file from disk.
void *mpFileData; ///< The raw message resource file data.
MsgRes_c *mpMsgRes; ///< The message resource instance used to retrieve messages.
};
15 changes: 15 additions & 0 deletions include/game/bases/d_msg_res.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once

#include <egg/core/eggHeap.h>
#include <egg/core/eggMsgRes.h>

/// @brief A simple wrapper around EGG::MsgRes.
/// @ingroup bases
class MsgRes_c : public EGG::MsgRes {
public:
MsgRes_c(const void *p, EGG::Heap *heap); ///< Constructs a new message resource.
virtual ~MsgRes_c(); ///< Destroys the @p MsgRes_c instance.

u8 getFont(ulong messageGroup, ulong messageID); ///< Gets the font for a message.
u16 getScale(ulong messageGroup, ulong messageID); ///< Gets the scale for a message.
};
4 changes: 4 additions & 0 deletions include/lib/egg/core/eggArchive.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#include <revolution/ARC.h>

namespace EGG {
class Heap;

class Archive {
public:
struct FileInfo {
Expand All @@ -12,6 +14,8 @@ namespace EGG {

typedef void (*searchCallback)(void *, void *, const ARCDirEntry *, const char *);

static Archive *mount(void *arcStart, EGG::Heap *heap, int alignment);

void unmount();
int countFile();

Expand Down
15 changes: 15 additions & 0 deletions include/lib/egg/core/eggMsgRes.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,24 @@

namespace EGG {

/// @unofficial
struct MsgEntry {
u8 mPad[4];
u16 mScale;
u8 mFont;
};

class MsgRes {
private:
u8 mPad[0x1c];

public:
MsgRes(const void *p);
virtual ~MsgRes();

wchar_t *getMsg(ulong messageGroup, ulong messageID);
MsgEntry *getMsgEntry(ulong messageGroup, ulong messageID);

};

} // namespace EGG
16 changes: 16 additions & 0 deletions slices/wiimj2d.json
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,15 @@
".sdata2": "0x1918-0x1930"
}
},
{
"source": "dol/bases/d_message.cpp",
"memoryRanges": {
".text": "0xc73e0-0xc7830",
".ctors": "0x12c-0x130",
".data": "0x195f0-0x19618",
".bss": "0x8610-0x8638"
}
},
{
"source": "dol/bases/d_mj2d_data.cpp",
"memoryRanges": {
Expand All @@ -423,6 +432,13 @@
".sdata": "0x5f0-0x5f8"
}
},
{
"source": "dol/bases/d_msg_res.cpp",
"memoryRanges": {
".text": "0xc8070-0xc8170",
".data": "0x19618-0x19628"
}
},
{

"source": "dol/bases/d_multi_manager.cpp",
Expand Down
89 changes: 89 additions & 0 deletions source/dol/bases/d_message.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#include <game/bases/d_message.hpp>
#include <game/bases/d_game_com.hpp>
#include <egg/core/eggArchive.h>
#include <wchar.h>

static dMessage_c l_dMessage_obj;

dMessage_c::dMessage_c() : mpFileData(nullptr), mpMsgRes(nullptr) {}

dMessage_c::~dMessage_c() {
delete mpMsgRes;
}

bool dMessage_c::create(EGG::Heap *heap) {
char path[100];
if (l_dMessage_obj.mpFileData == nullptr) {
dGameCom::AreaLanguageFolder("Message/Message.arc", path);

void *buffer = l_dMessage_obj.mLoader.request(path, 0, heap);
if (buffer == nullptr) {
return false;
}

EGG::Archive *archive = EGG::Archive::mount(buffer, heap, 4);
EGG::Archive::FileInfo fileInfo;
l_dMessage_obj.mpFileData = archive->getFile("wii_mj2d.bmg", &fileInfo);
l_dMessage_obj.buildMsgRes(heap);
Comment thread
RootCubed marked this conversation as resolved.
Resolved
}

return true;
}

void dMessage_c::buildMsgRes(EGG::Heap *heap) {
mpMsgRes = new (heap, 4) MsgRes_c(mpFileData, nullptr);
}

wchar_t *dMessage_c::getMsg(ulong messageGroup, ulong messageID) {
return l_dMessage_obj.mpMsgRes->getMsg(messageGroup, messageID);
}

MsgRes_c *dMessage_c::getMesRes() {
return l_dMessage_obj.mpMsgRes;
}

void dMessage_c::numToString(int num, wchar_t *dst, size_t writeLimit, int digitCount, int suppressLeadingZero) {
size_t count = 0;
int digitPos = digitCount - 1;
bool skipOverZeros = suppressLeadingZero == 1;

while (digitPos >= 0) {
int pow10 = 1;
for (int exp = 0; exp < digitPos; exp++) {
pow10 *= 10;
}

int digit = (num % (pow10 * 10)) / pow10;

if (digit == 0 && skipOverZeros && digitPos != 0) {
dst[count] = L' ';
} else {
dst[count] = L'0' + digit;
skipOverZeros = false;
}

count++;
digitPos--;
if (writeLimit <= count) {
break;
}
}

dst[count] = L'\0';
}

void dMessage_c::numToFullWidth(int num, wchar_t *dst, size_t writeLimit, int digitCount, int suppressLeadingZero) {
numToString(num, dst, writeLimit, digitCount, suppressLeadingZero);
dMessage_c::changetoFullSize(dst);
}

void dMessage_c::changetoFullSize(wchar_t *str) {
size_t len = wcslen(str);
for (size_t i = 0; i < len; i++) {
if (str[i] == L' ') {
str[i] = 0x3000;
} else if (0x21 <= str[i] && str[i] <= 0x7E) {
str[i] = 0xFEE0 + str[i];
}
}
}
13 changes: 13 additions & 0 deletions source/dol/bases/d_msg_res.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include <game/bases/d_message.hpp>

MsgRes_c::MsgRes_c(const void *p, EGG::Heap *heap) : EGG::MsgRes(p) {}

MsgRes_c::~MsgRes_c() {}

u16 MsgRes_c::getScale(ulong messageGroup, ulong messageID) {
return getMsgEntry(messageGroup, messageID)->mScale;
}

u8 MsgRes_c::getFont(ulong messageGroup, ulong messageID) {
return getMsgEntry(messageGroup, messageID)->mFont;
}
7 changes: 5 additions & 2 deletions syms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,6 @@ setHeadID__11dMarioMdl_cFQ211dMarioMdl_c10HeadType_e=0x800CAB00
isCaveMask__8dMaskMngFv=0x800CD3B0
create__10dMessage_cFPQ23EGG4Heap=0x800CDC20
getMesRes__10dMessage_cFv=0x800CDD50
getScale__8MsgRes_cFUlUl=0x800CE890
getFont__8MsgRes_cFUlUl=0x800CE8C0
cmdExistCheck__13dNandThread_cFv=0x800CEF10
cmdSpaceCheck__13dNandThread_cFv=0x800CF060
create__13dNandThread_cFPQ23EGG4Heap=0x800CFBA0
Expand Down Expand Up @@ -689,6 +687,7 @@ Attach__Q34nw4r3lyt19ArcResourceAccessorFPvPCc=0x802B67C0
Detach__Q34nw4r3lyt19ArcResourceAccessorFv=0x802B6840
GetResource__Q34nw4r3lyt19ArcResourceAccessorFUlPCcPUl=0x802B6860
BindAnimation__Q24nw4r3lytFPQ34nw4r3lyt5GroupPQ34nw4r3lyt13AnimTransformbb=0x802B7450
mount__Q23EGG7ArchiveFPvPQ23EGG4Heapi=0x802B76F0
unmount__Q23EGG7ArchiveFv=0x802B77C0
getFile__Q23EGG7ArchiveFPCcPQ33EGG7Archive8FileInfo=0x802B7800
convertPathToEntryID__Q23EGG7ArchiveFPCc=0x802B78A0
Expand Down Expand Up @@ -766,7 +765,10 @@ resetGXCache__Q23EGG7StateGXFv=0x802D3140
initialize__Q23EGG13TextureBufferFUlPQ23EGG4Heap=0x802D3780
create__Q23EGG9ExceptionFUsUsUsPQ23EGG4Heapi=0x802D7700
setPadInfo__Q23EGG9ExceptionFPCUs=0x802D77A0
__ct__Q23EGG6MsgResFPCv=0x802D7970
__dt__Q23EGG6MsgResFv=0x802D7AD0
getMsg__Q23EGG6MsgResFUlUl=0x802D7B50
getMsgEntry__Q23EGG6MsgResFUlUl=0x802D7C90
__ct__Q23EGG6EffectFv=0x802D7D90
__dt__Q23EGG6EffectFv=0x802D7E10
create__Q23EGG6EffectFv=0x802D7E70
Expand Down Expand Up @@ -808,6 +810,7 @@ getEffect__Q23EGG6EffectCFv=0x802D8A30
getRootEmitter__Q23EGG6EffectCFv=0x802D8AB0
reset__Q23EGG6EffectFv=0x802D8B30
strlen=0x802DC98C
wcslen=0x802E470C
__ptmf_test=0x802DCE80
__ptmf_cmpr=0x802DCEB0
__ptmf_scall=0x802DCEEC
Expand Down
Loading