From d2cd1de1189b640dfde4a89b9c1f427001cda07c Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Tue, 11 Jul 2023 10:03:40 -0400 Subject: [PATCH] Implement & partial match m_handbill.c --- include/libjsys/jsyswrapper.h | 31 ++ include/m_handbill.h | 76 +++ include/m_msg.h | 1 + include/m_string.h | 4 + rel/m_handbill.c | 881 ++++++++++++++++++++++++++++++++++ 5 files changed, 993 insertions(+) create mode 100644 rel/m_handbill.c diff --git a/include/libjsys/jsyswrapper.h b/include/libjsys/jsyswrapper.h index b29d2a01..9159c9ce 100644 --- a/include/libjsys/jsyswrapper.h +++ b/include/libjsys/jsyswrapper.h @@ -11,7 +11,38 @@ extern "C" { enum resource_index { /* TODO: finish */ + RESOURCE_FGDATA = 0, + RESOURCE_MAIL = 1, + RESOURCE_MAIL_TABLE = 2, + RESOURCE_MAILA = 3, + RESOURCE_MAILA_TABLE = 4, + RESOURCE_MAILB = 5, + RESOURCE_MAILB_TABLE = 6, + RESOURCE_MAILC = 7, + RESOURCE_MAILC_TABLE = 8, + RESOURCE_PALLET_BOY = 9, + RESOURCE_PS = 10, + RESOURCE_PS_TABLE = 11, + RESOURCE_PSZ = 12, + RESOURCE_PSZ_TABLE = 13, + RESOURCE_SELECT = 14, + RESOURCE_SELECT_TABLE = 15, + RESOURCE_STRING = 16, + RESOURCE_STRING_TABLE = 17, + RESOURCE_SUPERZ = 18, + RESOURCE_SUPERZ_TABLE = 19, + RESOURCE_SUPER = 20, + RESOURCE_SUPER_TABLE = 21, + RESOURCE_TEX_BOY = 22, + RESOURCE_FACE_BOY = 23, + RESOURCE_FGNPCDATA = 24, + RESOURCE_MESSAGE = 25, + RESOURCE_MESSAGE_TABLE = 26, RESOURCE_MY_ORIGINAL = 27, + RESOURCE_NEEDLEWORK_JOYBOOT = 28, + RESOURCE_PLAYER_ROOM_FLOOR = 29, + RESOURCE_PLAYER_ROOM_WALL = 30, + RESOURCE_NPC_NAME_STR_TABLE = 31, }; extern void JW_Init(); diff --git a/include/m_handbill.h b/include/m_handbill.h index 5b7e1016..0f0e1082 100644 --- a/include/m_handbill.h +++ b/include/m_handbill.h @@ -3,6 +3,7 @@ #include "types.h" #include "m_mail.h" +#include "m_item_name.h" #ifdef __cplusplus extern "C" { @@ -12,11 +13,86 @@ extern "C" { #define mHandbill_FOOTER_LEN MAIL_FOOTER_LEN #define mHandbill_BODY_LEN MAIL_BODY_LEN +#define mHandbill_FREE_STR_LEN mIN_ITEM_NAME_LEN + +#define mHandbill_MAIL_NUM 982 + +enum { + mHandbill_FREE_STR0, + mHandbill_FREE_STR1, + mHandbill_FREE_STR2, + mHandbill_FREE_STR3, + mHandbill_FREE_STR4, + mHandbill_FREE_STR5, + mHandbill_FREE_STR6, + mHandbill_FREE_STR7, + mHandbill_FREE_STR8, + mHandbill_FREE_STR9, + mHandbill_FREE_STR10, + mHandbill_FREE_STR11, + mHandbill_FREE_STR12, + mHandbill_FREE_STR13, + mHandbill_FREE_STR14, + mHandbill_FREE_STR15, + mHandbill_FREE_STR16, + mHandbill_FREE_STR17, + mHandbill_FREE_STR18, + mHandbill_FREE_STR19, + + mHandbill_FREE_STR_NUM +}; + +enum { + mHandbill_FILL_NONE, + mHandbill_FILL_RETURN, + mHandbill_FILL_SPACE, + + mHandbill_FILL_NUM +}; + +typedef struct handbill_data_s mHandbill_Data_c; + +struct handbill_data_s { + u8 free_str[mHandbill_FREE_STR_NUM][mHandbill_FREE_STR_LEN]; + int free_str_art[mHandbill_FREE_STR_NUM]; + int force_art; + int capital_flag; +}; + extern void mHandbill_Load_HandbillFromRom(u8* header, int* header_back_pos, u8* footer, u8* body, int handbill_no); extern void mHandbill_Load_HandbillFromRom2(u8* header, int header_size, int* header_back_pos, u8* footer, int footer_size, u8* body, int handbill_no); extern void mHandbill_Set_free_str(int free_str_no, u8* str, int str_len); extern void mHandbill_Set_free_str_art(int free_str_no, u8* str, int str_len, int article_no); +enum { + mHandbillz_TYPE_SUPER, + mHandbillz_TYPE_MAILA, + mHandbillz_TYPE_MAILB, + mHandbillz_TYPE_MAILC, + mHandbillz_TYPE_PS, + + mHandbillz_TYPE_NUM +}; + +typedef struct mHandbillz_info_s { + u8* super_buf_p; + size_t super_buf_size; + + u8* mail_buf_p; + size_t mail_buf_size; + + u8* ps_buf_p; + size_t ps_buf_size; + + int super_no; + int maila_no; + int mailb_no; + int mailc_no; + int ps_no; + + int header_back_start; +} mHandbillz_Info_c; + #ifdef __cplusplus } #endif diff --git a/include/m_msg.h b/include/m_msg.h index 00f5ecab..3348eba0 100644 --- a/include/m_msg.h +++ b/include/m_msg.h @@ -232,6 +232,7 @@ extern int mMsg_Check_not_series_main_wait(mMsg_Window_c* msg_win); extern int mMsg_Check_MainDisappear(mMsg_Window_c* msg_win); extern void mMsg_request_main_disappear_wait_type1(mMsg_Window_c* msg_win); extern void mMsg_request_main_appear_wait_type1(mMsg_Window_c* msg_win); +extern void mMsg_Get_BodyParam(u32 table_rom_start, u32 data_rom_start, int entry_no, u32* data_addr, u32* data_size); #ifdef __cplusplus } diff --git a/include/m_string.h b/include/m_string.h index 299329c3..3011cd9c 100644 --- a/include/m_string.h +++ b/include/m_string.h @@ -8,10 +8,14 @@ extern "C" { #endif +#define mString_ARTICLE_START 0x737 + extern void mString_Load_StringFromRom(u8* buf, size_t buf_size, u32 str_no); extern int mString_Load_MonthStringFromRom(u8* buf, lbRTC_month_t month); extern int mString_Load_DayStringFromRom(u8* buf, lbRTC_day_t day); +#define mString_Load_ArticleFromRom(buf, buf_size, art) mString_Load_StringFromRom(buf, buf_size, mString_ARTICLE_START + art) + #ifdef __cplusplus } #endif diff --git a/rel/m_handbill.c b/rel/m_handbill.c new file mode 100644 index 00000000..a7142ba7 --- /dev/null +++ b/rel/m_handbill.c @@ -0,0 +1,881 @@ +#include "m_handbill.h" + +#include "libjsys/jsyswrapper.h" +#include "m_msg.h" +#include "m_string.h" +#include "m_font.h" +#include "libultra/libultra.h" + +static u32 Ps_table_rom_start; +static u32 Ps_rom_start; +static u32 Handbill_table_rom_start; +static u32 Handbill_rom_start; +static u32 Super_table_rom_start; +static u32 Super_rom_start; +static u32 Handbillz_rom_start; +static u32 Handbillz_start; + +static void mHandbillz_aram_init(); + +#pragma pool_data on +extern void mHandbill_aram_init() { + Ps_table_rom_start = JW_GetAramAddress(RESOURCE_PS_TABLE); + Ps_rom_start = JW_GetAramAddress(RESOURCE_PS); + + Handbill_table_rom_start = JW_GetAramAddress(RESOURCE_MAIL_TABLE); + Handbill_rom_start = JW_GetAramAddress(RESOURCE_MAIL); + + Super_table_rom_start = JW_GetAramAddress(RESOURCE_SUPER_TABLE); + Super_rom_start = JW_GetAramAddress(RESOURCE_SUPER); + + Handbillz_rom_start = JW_GetAramAddress(RESOURCE_MAILA); + Handbillz_start = 0; + + mHandbillz_aram_init(); +} +#pragma pool_data reset + +static mHandbill_Data_c mHandbill_data; + +static void mHandbill_clr_force_art() { + mHandbill_data.force_art = mIN_ARTICLE_NUM; +} + +static void mHandbill_clr_capital_flag() { + #ifndef BUGFIXES + mHandbill_data.force_art = mIN_ARTICLE_NUM; // copy-paste error + #else + mHandbill_data.capital_flag = FALSE; + #endif +} + +static void mHandbill_load_init() { + mHandbill_clr_force_art(); + mHandbill_clr_capital_flag(); +} + +extern void mHandbill_Set_free_str(int str_num, u8* str, int str_len) { + int i; + int j; + u8* free_str; + mHandbill_Data_c* handbill_data; + + if (str_num < 0) { + return; + } + + if (str_num >= mHandbill_FREE_STR_NUM) { + return; + } + + if (str == NULL) { + return; + } + + handbill_data = &mHandbill_data; + free_str = handbill_data->free_str[str_num]; + + if (str_len > mHandbill_FREE_STR_LEN) { + str_len = mHandbill_FREE_STR_LEN; + } + + for (i = 0; i < str_len; i++) { + free_str[i] = str[i]; + } + + for (j = i; j < mHandbill_FREE_STR_LEN; j++) { + free_str[j] = CHAR_SPACE; + } + + handbill_data->free_str_art[str_num] = mIN_ARTICLE_NONE; +} + +extern void mHandbill_Set_free_str_art(int str_num, u8* str, int str_len, int article) { + mHandbill_Set_free_str(str_num, str, str_len); + mHandbill_data.free_str_art[str_num] = article; +} + +static void mHandbill_CopyString(u8* dst, u8* src, int len) { + for (len; len > 0; len--) { + *dst++ = *src++; + } +} + +extern int mHandbill_MoveDataCut(u8* data, int buf_size, int dst_idx, int src_idx, int data_len, int fill_type) { + int new_len = data_len; + int i; + + if (dst_idx < src_idx) { + u8* dst = data + dst_idx; + u8* src = data + src_idx; + + for (i = src_idx; i < data_len; i++) { + data[dst_idx] = data[src_idx++]; + dst_idx++; + } + + new_len -= src_idx - dst_idx; + + if (fill_type != mHandbill_FILL_NONE) { + u8 fill_char; + + if (fill_type == mHandbill_FILL_RETURN) { + fill_char = CHAR_NEW_LINE; + } + else { + fill_char = CHAR_SPACE; + } + + while (dst_idx < data_len) { + data[dst_idx++] = fill_char; + } + } + } + else if (dst_idx > src_idx) { + int move_size = data_len - src_idx; + u8* dst; + u8* src; + + new_len += dst_idx - src_idx; + if (new_len > buf_size) { + data_len -= new_len - buf_size; + move_size -= new_len - buf_size; + new_len = buf_size; + } + + dst = data + new_len - 1; + src = data + data_len - 1; + for (i = 0; i < move_size; i++) { + *dst-- = *src--; + } + } + + return new_len; +} + +static int mHandbill_Put_String_FREE(u8* str, int buf_size, int start_idx, int str_len, int str_no, int fill_type) { + int code_size; + int free_str_len; + int cut_len; + int article; + int temp; + + if (str_no < mHandbill_FREE_STR0 || str_no >= mHandbill_FREE_STR_NUM) { + str_no = mHandbill_FREE_STR0; + } + + code_size = mFont_CodeSize_idx_get(str, start_idx); + free_str_len = mMsg_Get_Length_String(mHandbill_data.free_str[str_no], mHandbill_FREE_STR_LEN); + cut_len = mHandbill_MoveDataCut(str, buf_size, start_idx + free_str_len, start_idx + code_size, str_len, fill_type); + + if (cut_len >= buf_size && free_str_len > buf_size - start_idx) { + free_str_len = buf_size - start_idx; + } + + mHandbill_CopyString(&str[start_idx], mHandbill_data.free_str[str_no], free_str_len); + + switch(mHandbill_data.force_art) { + default: + article = mHandbill_data.force_art; + break; + + case mIN_ARTICLE_NUM: + article = mHandbill_data.free_str_art[str_no]; + break; + } + + if (article != mIN_ARTICLE_NONE) { + u8 article_buf[32]; + + mString_Load_ArticleFromRom(article_buf, 16, article); // Load string from string file into buffer + free_str_len = mMsg_Get_Length_String(article_buf, 16); // Get length of article + article_buf[free_str_len] = CHAR_SPACE; // Add a space to the end of the article + cut_len = mHandbill_MoveDataCut(str, buf_size, start_idx + free_str_len + 1, start_idx, cut_len, mHandbill_FILL_NONE); // Create free space for the article + mHandbill_CopyString(&str[start_idx], article_buf, free_str_len + 1); // Copy article to allocated space + } + + if (mHandbill_data.capital_flag) { + str[start_idx] = mFont_small_to_capital(str[start_idx]); + } + + mHandbill_clr_force_art(); + mHandbill_clr_capital_flag(); + + return cut_len; +} + +static int mHandbill_Put_String_FREE0(u8* buf, int buf_size, int start_idx, int str_len, int fill_type) { + return mHandbill_Put_String_FREE(buf, buf_size, start_idx, str_len, mHandbill_FREE_STR0, fill_type); +} + +static int mHandbill_Put_String_FREE1(u8* buf, int buf_size, int start_idx, int str_len, int fill_type) { + return mHandbill_Put_String_FREE(buf, buf_size, start_idx, str_len, mHandbill_FREE_STR1, fill_type); +} + +static int mHandbill_Put_String_FREE2(u8* buf, int buf_size, int start_idx, int str_len, int fill_type) { + return mHandbill_Put_String_FREE(buf, buf_size, start_idx, str_len, mHandbill_FREE_STR2, fill_type); +} + +static int mHandbill_Put_String_FREE3(u8* buf, int buf_size, int start_idx, int str_len, int fill_type) { + return mHandbill_Put_String_FREE(buf, buf_size, start_idx, str_len, mHandbill_FREE_STR3, fill_type); +} + +static int mHandbill_Put_String_FREE4(u8* buf, int buf_size, int start_idx, int str_len, int fill_type) { + return mHandbill_Put_String_FREE(buf, buf_size, start_idx, str_len, mHandbill_FREE_STR4, fill_type); +} + +static int mHandbill_Put_String_FREE5(u8* buf, int buf_size, int start_idx, int str_len, int fill_type) { + return mHandbill_Put_String_FREE(buf, buf_size, start_idx, str_len, mHandbill_FREE_STR5, fill_type); +} + +static int mHandbill_Put_String_FREE6(u8* buf, int buf_size, int start_idx, int str_len, int fill_type) { + return mHandbill_Put_String_FREE(buf, buf_size, start_idx, str_len, mHandbill_FREE_STR6, fill_type); +} + +static int mHandbill_Put_String_FREE7(u8* buf, int buf_size, int start_idx, int str_len, int fill_type) { + return mHandbill_Put_String_FREE(buf, buf_size, start_idx, str_len, mHandbill_FREE_STR7, fill_type); +} + +static int mHandbill_Put_String_FREE8(u8* buf, int buf_size, int start_idx, int str_len, int fill_type) { + return mHandbill_Put_String_FREE(buf, buf_size, start_idx, str_len, mHandbill_FREE_STR8, fill_type); +} + +static int mHandbill_Put_String_FREE9(u8* buf, int buf_size, int start_idx, int str_len, int fill_type) { + return mHandbill_Put_String_FREE(buf, buf_size, start_idx, str_len, mHandbill_FREE_STR9, fill_type); +} + +static int mHandbill_Put_String_FREE10(u8* buf, int buf_size, int start_idx, int str_len, int fill_type) { + return mHandbill_Put_String_FREE(buf, buf_size, start_idx, str_len, mHandbill_FREE_STR10, fill_type); +} + +static int mHandbill_Put_String_FREE11(u8* buf, int buf_size, int start_idx, int str_len, int fill_type) { + return mHandbill_Put_String_FREE(buf, buf_size, start_idx, str_len, mHandbill_FREE_STR11, fill_type); +} + +static int mHandbill_Put_String_FREE12(u8* buf, int buf_size, int start_idx, int str_len, int fill_type) { + return mHandbill_Put_String_FREE(buf, buf_size, start_idx, str_len, mHandbill_FREE_STR12, fill_type); +} + +static int mHandbill_Put_String_FREE13(u8* buf, int buf_size, int start_idx, int str_len, int fill_type) { + return mHandbill_Put_String_FREE(buf, buf_size, start_idx, str_len, mHandbill_FREE_STR13, fill_type); +} + +static int mHandbill_Put_String_FREE14(u8* buf, int buf_size, int start_idx, int str_len, int fill_type) { + return mHandbill_Put_String_FREE(buf, buf_size, start_idx, str_len, mHandbill_FREE_STR14, fill_type); +} + +static int mHandbill_Put_String_FREE15(u8* buf, int buf_size, int start_idx, int str_len, int fill_type) { + return mHandbill_Put_String_FREE(buf, buf_size, start_idx, str_len, mHandbill_FREE_STR15, fill_type); +} + +static int mHandbill_Put_String_FREE16(u8* buf, int buf_size, int start_idx, int str_len, int fill_type) { + return mHandbill_Put_String_FREE(buf, buf_size, start_idx, str_len, mHandbill_FREE_STR16, fill_type); +} + +static int mHandbill_Put_String_FREE17(u8* buf, int buf_size, int start_idx, int str_len, int fill_type) { + return mHandbill_Put_String_FREE(buf, buf_size, start_idx, str_len, mHandbill_FREE_STR17, fill_type); +} + +static int mHandbill_Put_String_FREE18(u8* buf, int buf_size, int start_idx, int str_len, int fill_type) { + return mHandbill_Put_String_FREE(buf, buf_size, start_idx, str_len, mHandbill_FREE_STR18, fill_type); +} + +static int mHandbill_Put_String_FREE19(u8* buf, int buf_size, int start_idx, int str_len, int fill_type) { + return mHandbill_Put_String_FREE(buf, buf_size, start_idx, str_len, mHandbill_FREE_STR19, fill_type); +} + +static int mHandbill_Cut_Article(u8* buf, int buf_size, int start_idx, int str_len, int fill_type) { + int code_size = mFont_CodeSize_idx_get(buf, start_idx); + + mHandbill_data.force_art = mIN_ARTICLE_NONE; + return mHandbill_MoveDataCut(buf, buf_size, start_idx, start_idx + code_size, str_len, mHandbill_FILL_NONE); // remove the control code characters +} + +static int mHandbill_Capital_Letter(u8* buf, int buf_size, int start_idx, int str_len, int fill_type) { + int code_size = mFont_CodeSize_idx_get(buf, start_idx); + + mHandbill_data.capital_flag = TRUE; + return mHandbill_MoveDataCut(buf, buf_size, start_idx, start_idx + code_size, str_len, mHandbill_FILL_NONE); // remove the control code characters +} + +typedef int (*mHandbill_PUT_STRING_PROC)(u8*, int, int, int, int); + +static int mHandbill_Put_String(u8* buf, int buf_size, int start_idx, int str_len, int fill_type) { + static const mHandbill_PUT_STRING_PROC proc[mFont_CONT_CODE_NUM] = { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + &mHandbill_Put_String_FREE0, + &mHandbill_Put_String_FREE1, + &mHandbill_Put_String_FREE2, + &mHandbill_Put_String_FREE3, + &mHandbill_Put_String_FREE4, + &mHandbill_Put_String_FREE5, + &mHandbill_Put_String_FREE6, + &mHandbill_Put_String_FREE7, + &mHandbill_Put_String_FREE8, + &mHandbill_Put_String_FREE9, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + &mHandbill_Put_String_FREE10, + &mHandbill_Put_String_FREE11, + &mHandbill_Put_String_FREE12, + &mHandbill_Put_String_FREE13, + &mHandbill_Put_String_FREE14, + &mHandbill_Put_String_FREE15, + &mHandbill_Put_String_FREE16, + &mHandbill_Put_String_FREE17, + &mHandbill_Put_String_FREE18, + &mHandbill_Put_String_FREE19, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + &mHandbill_Cut_Article, + &mHandbill_Capital_Letter, + NULL, + NULL, + NULL, + NULL, + NULL + }; + + int type = buf[start_idx + 1]; + if (type >= mFont_CONT_CODE_BEGIN &&type < mFont_CONT_CODE_NUM) { + mHandbill_PUT_STRING_PROC p = proc[type]; + + if (p != NULL) { + return (*p)(buf, buf_size, start_idx, str_len, fill_type); + } + } + + return str_len; +} + +static void mHandbill_Change_ControlCode(u8* buf, int buf_size, int str_len, int fill_type) { + int pos = 0; + int len = str_len; + + while (pos < len && pos < buf_size) { + if (buf[pos] == CHAR_CONTROL_CODE) { + len = mHandbill_Put_String(buf, buf_size, pos, len, fill_type); + } + else { + pos++; + } + } +} + +static void mHandbill_Change_ControlCode2(u8* buf, int buf_size, int str_len, int* header_back_start, int fill_type) { + int now_str_len; + + int pos = 0; + int len = str_len; + + while (pos < len && pos < buf_size) { + if (buf[pos] == CHAR_CONTROL_CODE) { + now_str_len = len; + len = mHandbill_Put_String(buf, buf_size, pos, len, fill_type); + + if (pos < *header_back_start) { + *header_back_start += len - now_str_len; + } + } + else { + pos++; + } + } +} + +static void mHandbill_Get_SuperStringDataAddressAndSize(int super_no, u32* addr, u32* size) { + mMsg_Get_BodyParam(Super_table_rom_start, Super_rom_start, super_no, addr, size); +} + +static void mHandbill_Get_PsStringDataAddressAndSize(int ps_no, u32* addr, u32* size) { + mMsg_Get_BodyParam(Ps_table_rom_start, Ps_rom_start, ps_no, addr, size); +} + +static void mHandbill_Get_MailStringDataAddressAndSize(int mail_no, u32* addr, u32* size) { + mMsg_Get_BodyParam(Handbill_table_rom_start, Handbill_rom_start, mail_no, addr, size); +} + +static void mHandbill_CheckSuperStringBorderAndCopy(u8* dst, int dst_size, int* header_back_start, u8* src, int src_size) { + int src_pos; + int lines; + int dst_pos; + u8* src_p = src; + u8* dst_p = dst; + int i; + + lines = 0; + dst_pos = 0; + src_pos = 0; + + for (i = 0; i < src_size; i++) { + if (*src_p == CHAR_NEW_LINE) { + *header_back_start = src_pos; + lines++; + } + else if (dst_pos < dst_size) { + *dst_p = *src_p; + dst_p++; + dst_pos++; + } + + src_p++; + src_pos++; + } + + if (lines != 1) { + *header_back_start = src_size; + } +} + +/* @nonmatching TODO: minor regswap here */ +static void mHandbill_Load_SuperStringFromRom(u8* buf, int buf_size, int* header_back_start, int super_no) { + static u8 buff[90] ATTRIBUTE_ALIGN(32); + u8 super_buf[43]; + int* test = header_back_start; + int b_size = buf_size; + + if (super_no >= 0 && super_no < mHandbill_MAIL_NUM) { + u32 super_address; + u32 super_size; + int temp_header_back_start; + mHandbill_Get_SuperStringDataAddressAndSize(super_no, &super_address, &super_size); + mem_clear(buf, buf_size, CHAR_SPACE); + + if (super_address != 0 && super_size != 0) { + u32 aligned_addr = ALIGN_PREV(super_address, 32); // align to 32 bytes for ARAM DMA + u32 data_ofs = super_address - aligned_addr; // calculate offset for desired data + u32 size = ALIGN_NEXT(data_ofs + super_size, 32); + int move_size; + u8* dst; + u8* src; + int i; + + bzero(buff, 90); + _JW_GetResourceAram(aligned_addr, buff, size); + + src = buff + data_ofs; + dst = buff; + move_size = super_size; + /* Move desired data to begining of buffer */ + for (i = 0; i < move_size; i++) { + *dst++ = *src++; + } + + mem_clear(super_buf, 43, CHAR_SPACE); + mHandbill_CheckSuperStringBorderAndCopy(super_buf, 43, &temp_header_back_start, buff, super_size); + mHandbill_Change_ControlCode2(super_buf, 43, super_size - 1, &temp_header_back_start, mHandbill_FILL_SPACE); + bcopy(super_buf, buf, buf_size < 43 ? buf_size : 43); + *header_back_start = temp_header_back_start; + } + } +} + +static void mHandbill_Load_PsStringFromRom(u8* buf, int buf_size, int ps_no) { + static u8 buff[120] ATTRIBUTE_ALIGN(32); + + if (ps_no >= 0 && ps_no < mHandbill_MAIL_NUM) { + u32 ps_address; + u32 ps_size; + + mHandbill_Get_PsStringDataAddressAndSize(ps_no, &ps_address, &ps_size); + + if (ps_size == 0) { + mem_clear(buf, buf_size, CHAR_SPACE); + } + else if (ps_address != 0) { + u32 aligned_addr = ALIGN_PREV(ps_address, 32); // align to 32 bytes for ARAM DMA + u32 data_ofs = ps_address - aligned_addr; // calculate offset for desired data + u32 size = ALIGN_NEXT(data_ofs + ps_size, 32); + int sz; + int i; + u8* dst; + + _JW_GetResourceAram(aligned_addr, buff, size); + + /* Move desired data to output buffer */ + sz = (int)ps_size < buf_size ? ps_size : buf_size; + dst = buf; + for (i = 0; i < sz; i++) { + *dst = buff[data_ofs + i]; + dst++; + } + + /* Initialize remaining buffer to spaces */ + for (i; i < buf_size; i++) { + *dst = CHAR_SPACE; + dst++; + } + + /* Do any control code processing */ + mHandbill_Change_ControlCode(buf, buf_size, ps_size, mHandbill_FILL_SPACE); + } + } +} + +static u8 mHandbill_mail_buff[263] ATTRIBUTE_ALIGN(32); + +static u8 mHandbill_mail_buff[263] ATTRIBUTE_ALIGN(32); + +static void mHandbill_Load_MailFromRom(u8* buf, int mail_no) { + if (mail_no >= 0 && mail_no < mHandbill_MAIL_NUM) { + u32 mail_address; + u32 mail_size; + + mHandbill_Get_MailStringDataAddressAndSize(mail_no, &mail_address, &mail_size); + + if (mail_size == 0) { + mem_clear(buf, mHandbill_BODY_LEN, CHAR_NEW_LINE); + } + else if (mail_address != 0) { + u32 aligned_addr = ALIGN_PREV(mail_address, 32); // align to 32 bytes for ARAM DMA + u32 data_ofs = mail_address - aligned_addr; // calculate offset for desired data + u32 size = ALIGN_NEXT(data_ofs + mail_size, 32); + + _JW_GetResourceAram(aligned_addr, mHandbill_mail_buff, size); + + /* Move desired data to output buffer */ + { + int i; + int j; + u8* src = &mHandbill_mail_buff[data_ofs]; + u8* dst = buf; + int sz = mHandbill_BODY_LEN; + + if (mail_size < mHandbill_BODY_LEN) { + sz = mail_size; + } + + for (i = 0; i < sz; i++) { + *dst++ = *src++; + } + + /* Initialize remaining buffer to spaces */ + for (i; i < mHandbill_BODY_LEN; i++) { + *dst++ = CHAR_NEW_LINE; + } + + /* Do any control code processing */ + mHandbill_Change_ControlCode(buf, mHandbill_BODY_LEN, sz, mHandbill_FILL_RETURN); + } + } + } +} + +extern void mHandbill_Load_HandbillFromRom(u8* header, int* header_back_start, u8* footer, u8* body, int mail_no) { + mHandbill_load_init(); + mHandbill_Load_SuperStringFromRom(header, mHandbill_HEADER_LEN, header_back_start, mail_no); + mHandbill_Load_PsStringFromRom(footer, mHandbill_FOOTER_LEN, mail_no); + mHandbill_Load_MailFromRom(body, mail_no); +} + +extern void mHandbill_Load_HandbillFromRom2(u8* header, int header_size, int* header_back_start, u8* footer, int footer_size, u8* body, int mail_no) { + mHandbill_load_init(); + mHandbill_Load_SuperStringFromRom(header, header_size, header_back_start, mail_no); + mHandbill_Load_PsStringFromRom(footer, footer_size, mail_no); + mHandbill_Load_MailFromRom(body, mail_no); +} + +static u32 mHandbillz_table_pos[mHandbillz_TYPE_NUM]; +static u32 mHandbillz_data_pos[mHandbillz_TYPE_NUM]; + +static u32 mHandbillz_dummy_size_tbl[mHandbillz_TYPE_NUM] = { + 27, /* SUPER */ + 200, /* MAILA */ + 200, /* MAILB*/ + 200, /* MAILC */ + 34 /* PS */ +}; + +static void mHandbillz_aram_init() { + mHandbillz_table_pos[mHandbillz_TYPE_SUPER] = JW_GetAramAddress(RESOURCE_SUPERZ_TABLE); + mHandbillz_data_pos[mHandbillz_TYPE_SUPER] = JW_GetAramAddress(RESOURCE_SUPERZ); + + mHandbillz_table_pos[mHandbillz_TYPE_MAILA] = JW_GetAramAddress(RESOURCE_MAILA_TABLE); + mHandbillz_data_pos[mHandbillz_TYPE_MAILA] = JW_GetAramAddress(RESOURCE_MAILA); + + mHandbillz_table_pos[mHandbillz_TYPE_MAILB] = JW_GetAramAddress(RESOURCE_MAILB_TABLE); + mHandbillz_data_pos[mHandbillz_TYPE_MAILB] = JW_GetAramAddress(RESOURCE_MAILB); + + mHandbillz_table_pos[mHandbillz_TYPE_MAILC] = JW_GetAramAddress(RESOURCE_MAILC_TABLE); + mHandbillz_data_pos[mHandbillz_TYPE_MAILC] = JW_GetAramAddress(RESOURCE_MAILC); + + mHandbillz_table_pos[mHandbillz_TYPE_PS] = JW_GetAramAddress(RESOURCE_PSZ_TABLE); + mHandbillz_data_pos[mHandbillz_TYPE_PS] = JW_GetAramAddress(RESOURCE_PSZ); +} + +typedef struct { + int type; + int num; + + u8* ram_buf; + size_t ram_buf_size; + + u32 dma_addr; + u32 dma_size; +} mHandbillzDMA_c; + +static int mHandbillzDMA_body_addr_set(mHandbillzDMA_c* dma_info) { + int type = dma_info->type; + int num = dma_info->num; + + mMsg_Get_BodyParam(mHandbillz_table_pos[type], mHandbillz_data_pos[type], num, &dma_info->dma_addr, &dma_info->dma_size); + + if (dma_info->dma_size > mHandbillz_dummy_size_tbl[dma_info->type]) { + return FALSE; + } + return TRUE; +} + +static int mHandbillzDMA_body_load(mHandbillzDMA_c* dma_info) { + if (mHandbillzDMA_body_addr_set(dma_info)) { + mem_clear(dma_info->ram_buf, dma_info->ram_buf_size, CHAR_SPACE); + + if (dma_info->dma_size != 0) { + u32 dma_size = dma_info->dma_size; + u32 aligned_addr = ALIGN_PREV(dma_info->dma_addr, 32); + u32 data_ofs = dma_info->dma_addr & (32-1); + u32 size = ALIGN_NEXT(dma_size + data_ofs, 32); + + _JW_GetResourceAram(aligned_addr, dma_info->ram_buf, size); + + if (data_ofs != 0) { + u8* src; + u8* dst; + int size; + int i; + + dst = dma_info->ram_buf; + src = dst + data_ofs; + size = dma_info->dma_size; + + for (i = 0; i < size; i++) { + u8 b = *src; + src++; + *dst = b; + dst++; + } + } + } + + return TRUE; + } + else { + return FALSE; + } +} + +static int mHandbillz_super_load(mHandbillz_Info_c* info) { + static u8 ram[90] ATTRIBUTE_ALIGN(32); + mHandbillzDMA_c dma_info; + + bzero(ram, 90); + + dma_info.type = mHandbillz_TYPE_SUPER; + dma_info.num = info->super_no; + dma_info.ram_buf = ram; + dma_info.ram_buf_size = 90; + + if (mHandbillzDMA_body_load(&dma_info)) { + u8 super_buf[43]; + int header_back_start; + + mem_clear(super_buf, 43, CHAR_SPACE); + mHandbill_CheckSuperStringBorderAndCopy(super_buf, 43, &header_back_start, ram, dma_info.dma_size); + mHandbill_Change_ControlCode2(super_buf, 43, dma_info.dma_size - 1, &header_back_start, mHandbill_FILL_SPACE); + mem_clear(info->super_buf_p, info->super_buf_size, CHAR_SPACE); + bcopy(super_buf, info->super_buf_p, info->super_buf_size < 43 ? info->super_buf_size : 43); + + info->header_back_start = header_back_start; + return TRUE; + } + else { + return FALSE; + } +} + +static int mHandbillz_mail_load(mHandbillz_Info_c* info) { + mHandbillzDMA_c dma_info[3]; + mHandbillzDMA_c* dma_p; + int i; + int success = TRUE; + u32 total_size = 0; + u8* dst = info->mail_buf_p; + + dma_info[0].type = mHandbillz_TYPE_MAILA; + dma_info[0].num = info->maila_no; + dma_info[1].type = mHandbillz_TYPE_MAILB; + dma_info[1].num = info->mailb_no; + dma_info[2].type = mHandbillz_TYPE_MAILC; + dma_info[2].num = info->mailc_no; + + dma_p = dma_info; + for (i = 0; i < 3 && success; i++, dma_p++) { + bzero(mHandbill_mail_buff, 263); + dma_p->ram_buf = mHandbill_mail_buff; + dma_p->ram_buf_size = 263; + + if (mHandbillzDMA_body_load(dma_p)) { + total_size += dma_p->dma_size; + + if (total_size <= info->mail_buf_size) { + bcopy(mHandbill_mail_buff, dst, dma_p->dma_size); + dst += dma_p->dma_size; + } + else { + success = FALSE; + } + } + else { + success = FALSE; + } + } + + if (success) { + if (info->mail_buf_size > total_size) { + mem_clear(dst, info->mail_buf_size - total_size, CHAR_NEW_LINE); + } + + mHandbill_Change_ControlCode(info->mail_buf_p, info->mail_buf_size, total_size, mHandbill_FILL_RETURN); + } + + return success; +} + +static int mHandbillz_ps_load(mHandbillz_Info_c* info) { + static u8 ram[97] ATTRIBUTE_ALIGN(32); + mHandbillzDMA_c dma_info; + + bzero(ram, 97); + + dma_info.type = mHandbillz_TYPE_PS; + dma_info.num = info->ps_no; + dma_info.ram_buf = ram; + dma_info.ram_buf_size = 97; + + if (mHandbillzDMA_body_load(&dma_info)) { + u8 ps_buf[43]; + + bcopy(ram, info->ps_buf_p, dma_info.dma_size); + + if (info->ps_buf_size > dma_info.dma_size) { + mem_clear(info->ps_buf_p + dma_info.dma_size, info->ps_buf_size - dma_info.dma_size, CHAR_SPACE); + } + + mHandbill_Change_ControlCode(info->ps_buf_p, info->ps_buf_size, dma_info.dma_size, mHandbill_FILL_SPACE); + return TRUE; + } + else { + return FALSE; + } +} + +extern int mHandbillz_load(mHandbillz_Info_c* info) { + int super_res; + int mail_res; + int ps_res; + int res; + + mHandbill_load_init(); + + super_res = mHandbillz_super_load(info); + mail_res = mHandbillz_mail_load(info); + ps_res = mHandbillz_ps_load(info); + res = FALSE; + + if (super_res && mail_res && ps_res) { + res = TRUE; + } + + return res; +}