summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arm9/arm9.lcf1
-rw-r--r--arm9/asm/unk_0200A384.s343
-rw-r--r--arm9/src/msgdata.c166
-rw-r--r--arm9/src/nutdata.c8
-rw-r--r--arm9/src/pokemon.c5
-rw-r--r--include/msg_data.h35
-rw-r--r--include/proto.h7
-rw-r--r--include/string16.h1
-rw-r--r--tools/msgenc/Makefile13
-rw-r--r--tools/msgenc/msgenc.c7
10 files changed, 220 insertions, 366 deletions
diff --git a/arm9/arm9.lcf b/arm9/arm9.lcf
index 594783bf..70b309a0 100644
--- a/arm9/arm9.lcf
+++ b/arm9/arm9.lcf
@@ -145,7 +145,6 @@ SECTIONS {
unk_02008DEC.o (.text)
unk_02009EAC.o (.text)
msgdata.o (.text)
- unk_0200A384.o (.text)
unk_0200AA80.o (.text)
unk_0200BA78.o (.text)
unk_0200BB14.o (.text)
diff --git a/arm9/asm/unk_0200A384.s b/arm9/asm/unk_0200A384.s
deleted file mode 100644
index 0016d0d7..00000000
--- a/arm9/asm/unk_0200A384.s
+++ /dev/null
@@ -1,343 +0,0 @@
- .include "asm/macros.inc"
- .include "global.inc"
-
- .text
-
-.extern LoadSingleElementFromNarc
-.extern FreeMsgDataRawData
-.extern DecryptMessageDirect
-.extern DecryptMessageViaNewNarcHandle
-.extern CopyEncryptedMessage16
-.extern FUN_0200A4D4
-.extern FUN_0200A584
-.extern FUN_0200A648
-.extern FUN_0200A670
-.extern FUN_0200A76C
-
- thumb_func_start FUN_0200A848
-FUN_0200A848: ; 0x0200A848
- ldrh r0, [r0, #0x0]
- bx lr
-
- thumb_func_start FUN_0200A84C
-FUN_0200A84C: ; 0x0200A84C
- push {r3, lr}
- sub sp, #0x8
- add r3, r0, #0x0
- mov r0, #0x4
- add r2, r1, #0x0
- str r0, [sp, #0x0]
- add r1, r3, #0x0
- add r0, sp, #0x4
- mov r3, #0x0
- bl ReadFromNarcMemberByIdPair
- add r0, sp, #0x4
- ldrh r0, [r0, #0x0]
- add sp, #0x8
- pop {r3, pc}
- .balign 4
-
-; struct MsgData
-; {
-; u16 unk0;
-; u16 unk2;
-; u16 unk4;
-; u16 unk6;
-; union {
-; u16 * raw;
-; NARC * narc;
-; } data;
-; };
-
- thumb_func_start NewMsgDataFromNarc
-NewMsgDataFromNarc: ; 0x0200A86C
- ; r0: msg data type
- ; r1: NARC ID
- ; r2: File ID
- ; r3: heap_id
- push {r3-r7, lr}
- add r5, r0, #0x0
- add r6, r1, #0x0
- add r0, r3, #0x0
- mov r1, #0xc
- add r7, r2, #0x0
- str r3, [sp, #0x0]
- bl AllocFromHeapAtEnd
- add r4, r0, #0x0
- beq _0200A8B4
- cmp r5, #0x0
- bne _0200A8A0
- ldr r2, [sp, #0x0]
- add r0, r6, #0x0
- add r1, r7, #0x0
- bl LoadSingleElementFromNarc
- str r0, [r4, #0x8]
- cmp r0, #0x0
- bne _0200A8AA
- add r0, r4, #0x0
- bl FreeToHeap
- mov r0, #0x0
- pop {r3-r7, pc}
-_0200A8A0:
- ldr r1, [sp, #0x0]
- add r0, r6, #0x0
- bl NARC_ctor
- str r0, [r4, #0x8]
-_0200A8AA:
- strh r5, [r4, #0x0]
- strh r6, [r4, #0x4]
- ldr r0, [sp, #0x0]
- strh r7, [r4, #0x6]
- strh r0, [r4, #0x2]
-_0200A8B4:
- add r0, r4, #0x0
- pop {r3-r7, pc}
-
- thumb_func_start DestroyMsgData
-DestroyMsgData: ; 0x0200A8B8
- push {r4, lr}
- add r4, r0, #0x0
- beq _0200A8DE
- ldrh r0, [r4, #0x0]
- cmp r0, #0x0
- beq _0200A8CA
- cmp r0, #0x1
- beq _0200A8D2
- b _0200A8D8
-_0200A8CA:
- ldr r0, [r4, #0x8]
- bl FreeMsgDataRawData
- b _0200A8D8
-_0200A8D2:
- ldr r0, [r4, #0x8]
- bl NARC_dtor
-_0200A8D8:
- add r0, r4, #0x0
- bl FreeToHeap
-_0200A8DE:
- pop {r4, pc}
-
- thumb_func_start FUN_0200A8E0
-FUN_0200A8E0: ; 0x0200A8E0
- push {r3-r4, lr}
- sub sp, #0x4
- add r4, r0, #0x0
- ldrh r0, [r4, #0x0]
- add r3, r1, #0x0
- cmp r0, #0x0
- beq _0200A8F6
- cmp r0, #0x1
- beq _0200A900
- add sp, #0x4
- pop {r3-r4, pc}
-_0200A8F6:
- ldr r0, [r4, #0x8]
- bl FUN_0200A4D4
- add sp, #0x4
- pop {r3-r4, pc}
-_0200A900:
- str r2, [sp, #0x0]
- add r2, r3, #0x0
- ldrh r1, [r4, #0x6]
- ldrh r3, [r4, #0x2]
- ldr r0, [r4, #0x8]
- bl FUN_0200A670
- add sp, #0x4
- pop {r3-r4, pc}
- .balign 4
-
- thumb_func_start FUN_0200A914
-FUN_0200A914: ; 0x0200A914
- push {r3, lr}
- add r3, r0, #0x0
- ldrh r0, [r3, #0x0]
- add r2, r1, #0x0
- cmp r0, #0x0
- beq _0200A926
- cmp r0, #0x1
- beq _0200A930
- b _0200A93C
-_0200A926:
- ldrh r2, [r3, #0x2]
- ldr r0, [r3, #0x8]
- bl FUN_0200A584
- pop {r3, pc}
-_0200A930:
- ldr r0, [r3, #0x8]
- ldrh r1, [r3, #0x6]
- ldrh r3, [r3, #0x2]
- bl FUN_0200A76C
- pop {r3, pc}
-_0200A93C:
- mov r0, #0x0
- pop {r3, pc}
-
- thumb_func_start FUN_0200A940
-FUN_0200A940: ; 0x0200A940
- push {r3, lr}
- add r1, r0, #0x0
- ldrh r0, [r1, #0x0]
- cmp r0, #0x0
- beq _0200A950
- cmp r0, #0x1
- beq _0200A958
- b _0200A962
-_0200A950:
- ldr r0, [r1, #0x8]
- bl FUN_0200A848
- pop {r3, pc}
-_0200A958:
- ldrh r0, [r1, #0x4]
- ldrh r1, [r1, #0x6]
- bl FUN_0200A84C
- pop {r3, pc}
-_0200A962:
- mov r0, #0x0
- pop {r3, pc}
- .balign 4
-
- thumb_func_start DecryptCopyString
-DecryptCopyString: ; 0x0200A968
- push {r3-r4, lr}
- sub sp, #0x4
- add r4, r0, #0x0
- ldrh r0, [r4, #0x0]
- add r3, r1, #0x0
- cmp r0, #0x0
- beq _0200A97E
- cmp r0, #0x1
- beq _0200A988
- add sp, #0x4
- pop {r3-r4, pc}
-_0200A97E:
- ldr r0, [r4, #0x8]
- bl DecryptMessageDirect
- add sp, #0x4
- pop {r3-r4, pc}
-_0200A988:
- str r2, [sp, #0x0]
- add r2, r3, #0x0
- ldrh r0, [r4, #0x4]
- ldrh r1, [r4, #0x6]
- ldrh r3, [r4, #0x2]
- bl DecryptMessageViaNewNarcHandle
- add sp, #0x4
- pop {r3-r4, pc}
- .balign 4
-
- thumb_func_start GetSpeciesName
-GetSpeciesName: ; 0x0200A99C
- ; r0: species
- ; r1: heap_id
- ; r2: dest
- push {r4-r6, lr}
- add r4, r2, #0x0
- add r5, r0, #0x0
- add r3, r1, #0x0
- ldr r2, _0200A9C0 ; =0x0000016A
- mov r0, #0x1
- mov r1, #0x1a ; NARC_MSGDATA_MSG
- bl NewMsgDataFromNarc
- add r6, r0, #0x0
- add r1, r5, #0x0
- add r2, r4, #0x0
- bl DecryptCopyString
- add r0, r6, #0x0
- bl DestroyMsgData
- pop {r4-r6, pc}
- .balign 4
-_0200A9C0: .word 0x0000016A
-
- thumb_func_start FUN_0200A9C4
-FUN_0200A9C4: ; 0x0200A9C4
- push {r3-r7, lr}
- sub sp, #0x8
- add r7, r0, #0x0
- mov r0, #0x0
- str r0, [sp, #0x4]
- add r5, r1, #0x0
- mov r0, #0x1
- ldr r1, [sp, #0x4]
- lsl r0, r0, #0xa
- add r6, r2, #0x0
- str r3, [sp, #0x0]
- bl FUN_020219F4
- add r4, r0, #0x0
- beq _0200AA0E
- add r0, r5, #0x0
- add r1, r6, #0x0
- bl FUN_0200A914
- add r5, r0, #0x0
- beq _0200AA08
- add r0, r7, #0x0
- add r1, r4, #0x0
- add r2, r5, #0x0
- bl FUN_0200B7B8
- ldr r1, [sp, #0x0]
- add r0, r4, #0x0
- bl FUN_02021ACC
- str r0, [sp, #0x4]
- add r0, r5, #0x0
- bl FUN_02021A20
-_0200AA08:
- add r0, r4, #0x0
- bl FUN_02021A20
-_0200AA0E:
- ldr r0, [sp, #0x4]
- add sp, #0x8
- pop {r3-r7, pc}
-
- thumb_func_start FUN_0200AA14
-FUN_0200AA14: ; 0x0200AA14
- push {r4-r6, lr}
- add r5, r1, #0x0
- mov r2, #0x93
- add r6, r0, #0x0
- mov r0, #0x1
- mov r1, #0x1a
- lsl r2, r2, #0x2
- add r3, r5, #0x0
- bl NewMsgDataFromNarc
- add r4, r0, #0x0
- beq _0200AA4C
- mov r0, #0x10
- add r1, r5, #0x0
- bl FUN_020219F4
- add r5, r0, #0x0
- beq _0200AA42
- add r0, r4, #0x0
- add r1, r6, #0x0
- add r2, r5, #0x0
- bl FUN_0200A8E0
-_0200AA42:
- add r0, r4, #0x0
- bl DestroyMsgData
- add r0, r5, #0x0
- pop {r4-r6, pc}
-_0200AA4C:
- mov r0, #0x0
- pop {r4-r6, pc}
-
- thumb_func_start FUN_0200AA50
-FUN_0200AA50: ; 0x0200AA50
- push {r3-r5, lr}
- ldr r2, _0200AA7C ; =0x0000016A
- add r4, r0, #0x0
- add r3, r1, #0x0
- mov r0, #0x1
- mov r1, #0x1a
- bl NewMsgDataFromNarc
- add r5, r0, #0x0
- beq _0200AA76
- add r1, r4, #0x0
- bl FUN_0200A914
- add r4, r0, #0x0
- add r0, r5, #0x0
- bl DestroyMsgData
- add r0, r4, #0x0
- pop {r3-r5, pc}
-_0200AA76:
- mov r0, #0x0
- pop {r3-r5, pc}
- nop
-_0200AA7C: .word 0x0000016A
diff --git a/arm9/src/msgdata.c b/arm9/src/msgdata.c
index 007cb471..76d44338 100644
--- a/arm9/src/msgdata.c
+++ b/arm9/src/msgdata.c
@@ -4,6 +4,7 @@
#include "heap.h"
#include "MI_memory.h"
#include "string16.h"
+#include "proto.h"
#pragma thumb on
@@ -18,6 +19,8 @@ void FUN_0200A648(NarcId narc_id, u32 group, u32 num, u32 heap_id, struct String
void FUN_0200A670(NARC * narc, u32 group, u32 num, u32 heap_id, struct String * dest);
struct String * FUN_0200A738(NarcId narc_id, u32 group, u32 num, u32 heap_id);
struct String * FUN_0200A76C(NARC * narc, u32 group, u32 num, u32 heap_id);
+u16 FUN_0200A848(struct UnkStruct_200A394 * tbl);
+u16 FUN_0200A84C(NarcId narc_id, s32 file_id);
void * LoadSingleElementFromNarc(NarcId narc_id, s32 file_id, u32 heap_id)
{
@@ -234,3 +237,166 @@ struct String * FUN_0200A76C(NARC * narc, u32 group, u32 num, u32 heap_id)
return FUN_020219F4(4, heap_id);
}
}
+
+u16 FUN_0200A848(struct UnkStruct_200A394 * tbl)
+{
+ return tbl->unk0;
+}
+
+u16 FUN_0200A84C(NarcId narc_id, s32 file_id)
+{
+ u16 n[2];
+ ReadFromNarcMemberByIdPair(&n, narc_id, file_id, 0, 4);
+ return n[0];
+}
+
+struct MsgData * NewMsgDataFromNarc(u32 type, NarcId narc_id, s32 file_id, u32 heap_id)
+{
+ struct MsgData * msgData = AllocFromHeapAtEnd(heap_id, sizeof(struct MsgData));
+ if (msgData != NULL)
+ {
+ if (type == 0)
+ {
+ msgData->data.raw = LoadSingleElementFromNarc(narc_id, file_id, heap_id);
+ if (msgData->data.raw == NULL)
+ {
+ FreeToHeap(msgData);
+ return NULL;
+ }
+ }
+ else
+ {
+ msgData->data.narc = NARC_ctor(narc_id, heap_id);
+ }
+ msgData->type = (u16)type;
+ msgData->narc_id = (u16)narc_id;
+ msgData->file_id = (u16)file_id;
+ msgData->heap_id = (u16)heap_id;
+ }
+ return msgData;
+}
+
+void DestroyMsgData(struct MsgData * msgData)
+{
+ if (msgData != NULL)
+ {
+ switch (msgData->type)
+ {
+ case 0:
+ FreeMsgDataRawData(msgData->data.raw);
+ break;
+ case 1:
+ NARC_dtor(msgData->data.narc);
+ break;
+ }
+ FreeToHeap(msgData);
+ }
+}
+
+void FUN_0200A8E0(struct MsgData * msgData, u32 msg_no, struct String * dest)
+{
+ switch (msgData->type)
+ {
+ case 0:
+ FUN_0200A4D4(msgData->data.raw, msg_no, dest);
+ break;
+ case 1:
+ FUN_0200A670(msgData->data.narc, msgData->file_id, msg_no, msgData->heap_id, dest);
+ break;
+ }
+}
+
+struct String * FUN_0200A914(struct MsgData * msgData, u32 msg_no)
+{
+ switch (msgData->type)
+ {
+ case 0:
+ return FUN_0200A584(msgData->data.raw, msg_no, msgData->heap_id);
+ case 1:
+ return FUN_0200A76C(msgData->data.narc, msgData->file_id, msg_no, msgData->heap_id);
+ default:
+ return NULL;
+ }
+}
+
+u16 FUN_0200A940(struct MsgData * msgData)
+{
+ switch (msgData->type)
+ {
+ case 0:
+ return FUN_0200A848(msgData->data.raw);
+ case 1:
+ return FUN_0200A84C((NarcId)msgData->narc_id, msgData->file_id);
+ default:
+ return 0;
+ }
+}
+
+void DecryptCopyString(struct MsgData * msgData, u32 msg_no, u16 * dest)
+{
+ switch (msgData->type)
+ {
+ case 0:
+ DecryptMessageDirect(msgData->data.raw, msg_no, dest);
+ break;
+ case 1:
+ DecryptMessageViaNewNarcHandle((NarcId)msgData->narc_id, msgData->file_id, msg_no, msgData->heap_id, dest);
+ break;
+ }
+}
+
+void GetSpeciesName(u16 species, u32 heap_id, u16 * dest)
+{
+ struct MsgData * msgData = NewMsgDataFromNarc(1, NARC_MSGDATA_MSG, 362, heap_id);
+ DecryptCopyString(msgData, species, dest);
+ DestroyMsgData(msgData);
+}
+
+struct String * FUN_0200A9C4(u32 * a0, struct MsgData * msgData, u32 msgno, struct String * a3)
+{
+ struct String * ret = NULL;
+ struct String * r4 = FUN_020219F4(1024, 0);
+ struct String * r5;
+ if (r4 != NULL)
+ {
+ r5 = FUN_0200A914(msgData, msgno);
+ if (r5 != NULL)
+ {
+ FUN_0200B7B8(a0, r4, r5);
+ ret = FUN_02021ACC(r4, a3);
+ FUN_02021A20(r5);
+ }
+ FUN_02021A20(r4);
+ }
+ return ret;
+}
+
+struct String * FUN_0200AA14(u32 msg_no, u32 heapno)
+{
+ struct MsgData * msgData = NewMsgDataFromNarc(1, NARC_MSGDATA_MSG, 588, heapno);
+ struct String * ret;
+ if (msgData != NULL)
+ {
+ ret = FUN_020219F4(16, heapno);
+ if (ret != NULL)
+ {
+ FUN_0200A8E0(msgData, msg_no, ret);
+ }
+ DestroyMsgData(msgData);
+ return ret;
+ }
+ return NULL;
+}
+
+struct String * FUN_0200AA50(u16 species, u32 heap_id)
+{
+ struct String * ret;
+ struct MsgData * msgData = NewMsgDataFromNarc(1, NARC_MSGDATA_MSG, 362, heap_id);
+ if (msgData != NULL)
+ {
+ ret = FUN_0200A914(msgData, species);
+ DestroyMsgData(msgData);
+ return ret;
+ }
+ return NULL;
+}
diff --git a/arm9/src/nutdata.c b/arm9/src/nutdata.c
index 09542052..bce5c291 100644
--- a/arm9/src/nutdata.c
+++ b/arm9/src/nutdata.c
@@ -61,18 +61,18 @@ u32 GetNutAttr(struct NutData * nut, u32 attr)
}
}
-u16 * GetNutName(u32 berry_idx, u32 heap_id)
+struct String * GetNutName(u32 berry_idx, u32 heap_id)
{
struct MsgData * msgData = NewMsgDataFromNarc(1, NARC_MSGDATA_MSG, 373, heap_id);
- u16 * ret = FUN_0200A914(msgData, berry_idx);
+ struct String * ret = FUN_0200A914(msgData, berry_idx);
DestroyMsgData(msgData);
return ret;
}
-u16 * GetNutDesc(u32 berry_idx, u32 heap_id)
+struct String * GetNutDesc(u32 berry_idx, u32 heap_id)
{
struct MsgData * msgData = NewMsgDataFromNarc(1, NARC_MSGDATA_MSG, 372, heap_id);
- u16 * ret = FUN_0200A914(msgData, berry_idx);
+ struct String * ret = FUN_0200A914(msgData, berry_idx);
DestroyMsgData(msgData);
return ret;
}
diff --git a/arm9/src/pokemon.c b/arm9/src/pokemon.c
index 8df597a6..f3f094bb 100644
--- a/arm9/src/pokemon.c
+++ b/arm9/src/pokemon.c
@@ -10,6 +10,7 @@
#include "move_data.h"
#include "string_util.h"
#include "text.h"
+#include "msg_data.h"
#include "constants/abilities.h"
#include "constants/items.h"
#include "constants/moves.h"
@@ -860,7 +861,7 @@ u32 GetBoxMonDataInternal(struct BoxPokemon * boxmon, int attr, void * dest)
case MON_DATA_NICKNAME_3:
if (boxmon->checksum_fail)
{
- u16 * buffer = FUN_0200AA50(SPECIES_MANAPHY_EGG, 0);
+ struct String * buffer = FUN_0200AA50(SPECIES_MANAPHY_EGG, 0);
FUN_02021A74(dest, buffer);
FUN_02021A20(buffer);
}
@@ -1090,7 +1091,7 @@ void SetBoxMonDataInternal(struct BoxPokemon * boxmon, int attr, void * value)
u16 namebuf[POKEMON_NAME_LENGTH + 1];
u16 namebuf2[POKEMON_NAME_LENGTH + 1];
u16 namebuf3[POKEMON_NAME_LENGTH + 1];
- u16 * speciesName;
+ struct String * speciesName;
PokemonDataBlockA *blockA = &GetSubstruct(boxmon, boxmon->pid, 0)->blockA;
PokemonDataBlockB *blockB = &GetSubstruct(boxmon, boxmon->pid, 1)->blockB;
diff --git a/include/msg_data.h b/include/msg_data.h
index b03fcdb6..5d8dd387 100644
--- a/include/msg_data.h
+++ b/include/msg_data.h
@@ -1,17 +1,7 @@
#ifndef POKEDIAMOND_MSG_DATA_H
#define POKEDIAMOND_MSG_DATA_H
-struct MsgData
-{
- u16 unk0;
- u16 unk2;
- u16 unk4;
- u16 unk6;
- union {
- u16 * raw;
- NARC * narc;
- } data;
-};
+#include "string16.h"
struct UnkStruct_200A394_4
{
@@ -26,8 +16,27 @@ struct UnkStruct_200A394
struct UnkStruct_200A394_4 unk4[1];
};
-struct MsgData * NewMsgDataFromNarc(u32 type, u32 narcId, u32 msgId, u32 heapno);
-u16 * FUN_0200A914(struct MsgData *, u32);
+struct MsgData
+{
+ u16 type;
+ u16 heap_id;
+ u16 narc_id;
+ u16 file_id;
+ union {
+ struct UnkStruct_200A394 * raw;
+ NARC * narc;
+ } data;
+};
+
+struct MsgData * NewMsgDataFromNarc(u32 type, NarcId narcId, s32 msgId, u32 heapno);
void DestroyMsgData(struct MsgData *);
+void FUN_0200A8E0(struct MsgData * msgData, u32 msg_no, struct String * dest);
+struct String * FUN_0200A914(struct MsgData *, u32);
+u16 FUN_0200A940(struct MsgData * msgData);
+void DecryptCopyString(struct MsgData * msgData, u32 msg_no, u16 * dest);
+void GetSpeciesName(u16 species, u32 heap_id, u16 * dest);
+struct String * FUN_0200A9C4(u32 * a0, struct MsgData * msgData, u32 msgno, struct String * a3);
+struct String * FUN_0200AA14(u32 msg_no, u32 heapno);
+struct String * FUN_0200AA50(u16 species, u32 heap_id);
#endif //POKEDIAMOND_MSG_DATA_H
diff --git a/include/proto.h b/include/proto.h
index 2e7d19b3..70cb8aa6 100644
--- a/include/proto.h
+++ b/include/proto.h
@@ -4,12 +4,12 @@
// For homeless function declarations
#include "pokemon.h" // for struct definitions
+#include "string16.h" // for struct definitions
-u16 * FUN_0200AA50(u16 species, u32 heap_id);
-void FUN_02021A74(u16 * dest, u16 * src);
+void FUN_02021A74(u16 * dest, struct String * src);
void FUN_02021A20(void * ptr);
void FUN_02021E28(u16 * dest, u16 * src);
-void FUN_02021EF0(const u16 * src, u16 * dest, u32 count);
+void FUN_02021EF0(const struct String * src, u16 * dest, u32 count);
u32 FUN_0206E7B8(u16 item, u32 a1, u32 a2);
int FUN_02014C3C(u8);
void FUN_02014C54(int, int, struct UnkStruct_02069038 *, u8);
@@ -20,5 +20,6 @@ void FUN_02005E90(int, int, int, int);
void FUN_020056AC(int, int, int, int, int);
void FUN_020808AC(struct BoxPokemon *, int, int, int, int);
void * FUN_02022610(void *, int);
+void FUN_0200B7B8(u32 *, struct String *, struct String *);
#endif //POKEDIAMOND_PROTO_H
diff --git a/include/string16.h b/include/string16.h
index 6bbf567d..71f15672 100644
--- a/include/string16.h
+++ b/include/string16.h
@@ -15,5 +15,6 @@ int FUN_02021CE0(struct String *, struct String *);
int FUN_0206AE00(int x);
void FUN_02021E8C(struct String *, u16 *, u32); // copy
void FUN_02021A4C(struct String *); // set empty
+struct String * FUN_02021ACC(struct String *, struct String *);
#endif //POKEDIAMOND_STRING16_H
diff --git a/tools/msgenc/Makefile b/tools/msgenc/Makefile
new file mode 100644
index 00000000..da455633
--- /dev/null
+++ b/tools/msgenc/Makefile
@@ -0,0 +1,13 @@
+CC := gcc
+CFLAGS := -O2
+
+.PHONY: all clean
+
+all: msgenc
+ @:
+
+clean:
+ $(RM) msgenc msgenc.exe
+
+msgenc: msgenc.c
+ $(CC) $(CFLAGS) -o $@ $^
diff --git a/tools/msgenc/msgenc.c b/tools/msgenc/msgenc.c
new file mode 100644
index 00000000..f3d8ce5e
--- /dev/null
+++ b/tools/msgenc/msgenc.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main(int argc, char ** argv)
+{
+ printf("Hello, world!\n");
+ return 0;
+}