diff --git a/desmume/src/NDSSystem.c b/desmume/src/NDSSystem.c index a6b98048d..6f753dba8 100644 --- a/desmume/src/NDSSystem.c +++ b/desmume/src/NDSSystem.c @@ -30,11 +30,13 @@ #include "cflash.h" #include "ROMReader.h" +/* the count of bytes copied from the firmware into memory */ +#define NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT 0x70 + NDSSystem nds; -NDSFirmware firmware; static u32 -calc_CRC16( u32 start, u8 *data, int count) { +calc_CRC16( u32 start, const u8 *data, int count) { int i,j; u32 crc = start & 0xffff; static u16 val[] = { 0xC0C1,0xC181,0xC301,0xC601,0xCC01,0xD801,0xF001,0xA001 }; @@ -58,6 +60,82 @@ calc_CRC16( u32 start, u8 *data, int count) { return crc; } +static int +copy_firmware_user_data( u8 *dest_buffer, const u8 *fw_data) { + /* + * Determine which of the two user settings in the firmware is the current + * and valid one and then copy this into the destination buffer. + * + * The current setting will have a greater count. + * Settings are only valid if its CRC16 is correct. + */ + int user1_valid = 0; + int user2_valid = 0; + u32 user_settings_offset; + u32 fw_crc; + u32 crc; + int copy_good = 0; + + user_settings_offset = fw_data[0x20]; + user_settings_offset |= fw_data[0x21] << 8; + user_settings_offset <<= 3; + + if ( user_settings_offset <= 0x3FE00) { + s32 copy_settings_offset = -1; + + crc = calc_CRC16( 0xffff, &fw_data[user_settings_offset], + NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT); + fw_crc = fw_data[user_settings_offset + 0x72]; + fw_crc |= fw_data[user_settings_offset + 0x73] << 8; + if ( crc == fw_crc) { + user1_valid = 1; + } + + crc = calc_CRC16( 0xffff, &fw_data[user_settings_offset + 0x100], + NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT); + fw_crc = fw_data[user_settings_offset + 0x100 + 0x72]; + fw_crc |= fw_data[user_settings_offset + 0x100 + 0x73] << 8; + if ( crc == fw_crc) { + user2_valid = 1; + } + + if ( user1_valid) { + if ( user2_valid) { + u16 count1, count2; + + count1 = fw_data[user_settings_offset + 0x70]; + count1 |= fw_data[user_settings_offset + 0x71] << 8; + + count2 = fw_data[user_settings_offset + 0x100 + 0x70]; + count2 |= fw_data[user_settings_offset + 0x100 + 0x71] << 8; + + if ( count2 > count1) { + copy_settings_offset = user_settings_offset + 0x100; + } + else { + copy_settings_offset = user_settings_offset; + } + } + else { + copy_settings_offset = user_settings_offset; + } + } + else if ( user2_valid) { + /* copy the second user settings */ + copy_settings_offset = user_settings_offset + 0x100; + } + + if ( copy_settings_offset > 0) { + memcpy( dest_buffer, &fw_data[copy_settings_offset], + NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT); + copy_good = 1; + } + } + + return copy_good; +} + + int NDS_Init( struct armcpu_memory_iface *arm9_mem_if, struct armcpu_ctrl_iface **arm9_ctrl_iface, struct armcpu_memory_iface *arm7_mem_if, @@ -78,15 +156,6 @@ int NDS_Init( struct armcpu_memory_iface *arm9_mem_if, if (SPU_Init(SNDCORE_DUMMY, 735) != 0) return -1; - - sprintf(firmware.nickName,"yopyop"); - firmware.nickLen = strlen(firmware.nickName); - sprintf(firmware.message,"Hi,it/s me!"); - firmware.msgLen = strlen(firmware.message); - firmware.bDay = 15; - firmware.bMonth = 7; - firmware.favColor = 10; - firmware.language = 2; #ifdef EXPERIMENTAL_WIFI WIFI_Init(&wifiMac) ; @@ -339,6 +408,8 @@ void NDS_FreeROM(void) MMU.bupmem.fp = NULL; } + + void NDS_Reset( void) { BOOL oldexecute=execute; @@ -392,36 +463,20 @@ void NDS_Reset( void) MMU_writeHWord(1, 0x04000130, 0x3FF); MMU_writeByte(1, 0x04000136, 0x43); - MMU_writeByte(0, 0x027FFCDC, 0x20); - MMU_writeByte(0, 0x027FFCDD, 0x20); - MMU_writeByte(0, 0x027FFCE2, 0xE0); - MMU_writeByte(0, 0x027FFCE3, 0x80); - - MMU_writeHWord(0, 0x027FFCD8, 0x20<<4); - MMU_writeHWord(0, 0x027FFCDA, 0x20<<4); - MMU_writeHWord(0, 0x027FFCDE, 0xE0<<4); - MMU_writeHWord(0, 0x027FFCE0, 0x80<<4); + /* + * Setup a copy of the firmware user settings in memory. + * (this is what the DS firmware would do). + */ + { + u8 temp_buffer[NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT]; + int fw_index; - MMU_writeWord(0, 0x027FFE40, 0xE188); - MMU_writeWord(0, 0x027FFE44, 0x9); - MMU_writeWord(0, 0x027FFE48, 0xE194); - MMU_writeWord(0, 0x027FFE4C, 0x0); -// logcount = 0; - - MMU_writeByte(0, 0x023FFC80, 1); - MMU_writeByte(0, 0x023FFC82, firmware.favColor); - MMU_writeByte(0, 0x023FFC83, firmware.bMonth); - MMU_writeByte(0, 0x023FFC84, firmware.bDay); - - for(i=0; iFNameTblOff); MMU_writeWord(0, 0x027FFE44, header->FNameTblSize); @@ -458,16 +513,16 @@ void NDS_Reset( void) MMU_writeWord(1, 0x34, 0xE25EF004); //ARM9 BIOS IRQ HANDLER - MMU_writeWord(0, 0xFFF0018, 0xEA000000); - MMU_writeWord(0, 0xFFF0020, 0xE92D500F); - MMU_writeWord(0, 0xFFF0024, 0xEE190F11); - MMU_writeWord(0, 0xFFF0028, 0xE1A00620); - MMU_writeWord(0, 0xFFF002C, 0xE1A00600); - MMU_writeWord(0, 0xFFF0030, 0xE2800C40); - MMU_writeWord(0, 0xFFF0034, 0xE28FE000); - MMU_writeWord(0, 0xFFF0038, 0xE510F004); - MMU_writeWord(0, 0xFFF003C, 0xE8BD500F); - MMU_writeWord(0, 0xFFF0040, 0xE25EF004); + MMU_writeWord(0, 0xFFFF0018, 0xEA000000); + MMU_writeWord(0, 0xFFFF0020, 0xE92D500F); + MMU_writeWord(0, 0xFFFF0024, 0xEE190F11); + MMU_writeWord(0, 0xFFFF0028, 0xE1A00620); + MMU_writeWord(0, 0xFFFF002C, 0xE1A00600); + MMU_writeWord(0, 0xFFFF0030, 0xE2800C40); + MMU_writeWord(0, 0xFFFF0034, 0xE28FE000); + MMU_writeWord(0, 0xFFFF0038, 0xE510F004); + MMU_writeWord(0, 0xFFFF003C, 0xE8BD500F); + MMU_writeWord(0, 0xFFFF0040, 0xE25EF004); MMU_writeWord(0, 0x0000004, 0xE3A0010E); MMU_writeWord(0, 0x0000008, 0xE3A01020); @@ -482,8 +537,6 @@ void NDS_Reset( void) GPU_Reset(SubScreen.gpu, 1); SPU_Reset(); - NDS_CreateDummyFirmware() ; - execute = oldexecute; } @@ -587,9 +640,12 @@ int NDS_WriteBMP(const char *filename) return 1; } -static -void create_user_data( u8 *data, int count) { +static void +fill_user_data_area( struct NDS_fw_config_data *user_settings, + u8 *data, int count) { u32 crc; + int i; + u8 *ts_cal_data_area; memset( data, 0, 0x100); @@ -598,75 +654,46 @@ void create_user_data( u8 *data, int count) { data[0x01] = 0; /* colour */ - data[0x02] = 7; + data[0x02] = user_settings->fav_colour; /* birthday month and day */ - data[0x03] = 6; - data[0x04] = 23; + data[0x03] = user_settings->birth_month; + data[0x04] = user_settings->birth_day; /* nickname and length */ - data[0x06] = 'y'; - data[0x08] = 'o'; - data[0x0a] = 'p'; - data[0x0c] = 'y'; - data[0x0e] = 'o'; - data[0x10] = 'p'; + for ( i = 0; i < MAX_FW_NICKNAME_LENGTH; i++) { + data[0x06 + (i * 2)] = user_settings->nickname[i] & 0xff; + data[0x06 + (i * 2) + 1] = (user_settings->nickname[i] >> 8) & 0xff; + } - data[0x1a] = 6; + data[0x1a] = user_settings->nickname_len; /* Message */ - data[0x1c] = 'D'; - data[0x1e] = 'e'; - data[0x20] = 'S'; - data[0x22] = 'm'; - data[0x24] = 'u'; - data[0x26] = 'M'; - data[0x28] = 'E'; - data[0x2a] = ' '; - data[0x2c] = 'm'; - data[0x2e] = 'a'; - data[0x30] = 'k'; - data[0x32] = 'e'; - data[0x34] = 's'; - data[0x36] = ' '; - data[0x38] = 'y'; - data[0x3a] = 'o'; - data[0x3c] = 'u'; - data[0x3e] = ' '; - data[0x40] = 'h'; - data[0x42] = 'a'; - data[0x44] = 'p'; - data[0x46] = 'p'; - data[0x48] = 'y'; - data[0x4a] = '!'; + for ( i = 0; i < MAX_FW_MESSAGE_LENGTH; i++) { + data[0x1c + (i * 2)] = user_settings->message[i] & 0xff; + data[0x1c + (i * 2) + 1] = (user_settings->message[i] >> 8) & 0xff; + } - data[0x50] = 24; + data[0x50] = user_settings->message_len; /* * touch screen calibration */ - /* ADC position 1, x y */ - data[0x58] = 0x00; - data[0x59] = 0x02; - data[0x5a] = 0x00; - data[0x5b] = 0x02; + ts_cal_data_area = &data[0x58]; + for ( i = 0; i < 2; i++) { + /* ADC x y */ + *ts_cal_data_area++ = user_settings->touch_cal[i].adc_x & 0xff; + *ts_cal_data_area++ = (user_settings->touch_cal[i].adc_x >> 8) & 0xff; + *ts_cal_data_area++ = user_settings->touch_cal[i].adc_y & 0xff; + *ts_cal_data_area++ = (user_settings->touch_cal[i].adc_y >> 8) & 0xff; - /* screen pos 1, x y */ - data[0x5c] = 0x20; - data[0x5d] = 0x20; - - /* ADC position 2, x y */ - data[0x5e] = 0x00; - data[0x5f] = 0x0e; - data[0x60] = 0x00; - data[0x61] = 0x08; - - /* screen pos 2, x y */ - data[0x62] = 0xe0; - data[0x63] = 0x80; + /* screen x y */ + *ts_cal_data_area++ = user_settings->touch_cal[i].screen_x; + *ts_cal_data_area++ = user_settings->touch_cal[i].screen_y; + } /* language and flags */ - data[0x64] = 0x01; + data[0x64] = user_settings->language; data[0x65] = 0xfc; /* update count and crc */ @@ -681,7 +708,7 @@ void create_user_data( u8 *data, int count) { } /* creates an firmware flash image, which contains all needed info to initiate a wifi connection */ -int NDS_CreateDummyFirmware(void) +int NDS_CreateDummyFirmware( struct NDS_fw_config_data *user_settings) { /* * Create the firmware header @@ -694,8 +721,11 @@ int NDS_CreateDummyFirmware(void) MMU.fw.data[0x8 + 2] = 'C'; MMU.fw.data[0x8 + 3] = 'P'; - /* DS type (phat) */ - MMU.fw.data[0x1d] = 0xff; + /* DS type */ + if ( user_settings->ds_type == NDS_FW_DS_TYPE_LITE) + MMU.fw.data[0x1d] = 0x20; + else + MMU.fw.data[0x1d] = 0xff; /* User Settings offset 0x3fe00 / 8 */ MMU.fw.data[0x20] = 0xc0; @@ -705,8 +735,8 @@ int NDS_CreateDummyFirmware(void) /* * User settings (at 0x3FE00 and 0x3FE00) */ - create_user_data( &MMU.fw.data[ 0x3FE00], 0); - create_user_data( &MMU.fw.data[ 0x3FF00], 1); + fill_user_data_area( user_settings, &MMU.fw.data[ 0x3FE00], 0); + fill_user_data_area( user_settings, &MMU.fw.data[ 0x3FF00], 1); #ifdef EXPERIMENTAL_WIFI @@ -724,6 +754,48 @@ int NDS_CreateDummyFirmware(void) return TRUE ; } +void +NDS_FillDefaultFirmwareConfigData( struct NDS_fw_config_data *fw_config) { + const char *default_nickname = "yopyop"; + const char *default_message = "DeSmuME makes you happy!"; + int i; + int str_length; + + memset( fw_config, 0, sizeof( struct NDS_fw_config_data)); + fw_config->ds_type = NDS_FW_DS_TYPE_FAT; + + fw_config->fav_colour = 7; + + fw_config->birth_day = 23; + fw_config->birth_month = 6; + + str_length = strlen( default_nickname); + for ( i = 0; i < str_length; i++) { + fw_config->nickname[i] = default_nickname[i]; + } + fw_config->nickname_len = str_length; + + str_length = strlen( default_message); + for ( i = 0; i < str_length; i++) { + fw_config->message[i] = default_message[i]; + } + fw_config->message_len = str_length; + + /* default to English */ + fw_config->language = 1; + + /* default touchscreen calibration */ + fw_config->touch_cal[0].adc_x = 0x200; + fw_config->touch_cal[0].adc_y = 0x200; + fw_config->touch_cal[0].screen_x = 0x20; + fw_config->touch_cal[0].screen_y = 0x20; + + fw_config->touch_cal[1].adc_x = 0xe00; + fw_config->touch_cal[1].adc_y = 0x800; + fw_config->touch_cal[1].screen_x = 0xe0; + fw_config->touch_cal[1].screen_y = 0x80; +} + int NDS_LoadFirmware(const char *filename) { int i; diff --git a/desmume/src/NDSSystem.h b/desmume/src/NDSSystem.h index fb8cd7ad7..c6ed5f188 100644 --- a/desmume/src/NDSSystem.h +++ b/desmume/src/NDSSystem.h @@ -35,9 +35,23 @@ extern "C" { #endif + extern volatile BOOL execute; extern BOOL click; +/* + * The firmware language values + */ +#define NDS_FW_LANG_JAP 0 +#define NDS_FW_LANG_ENG 1 +#define NDS_FW_LANG_FRE 2 +#define NDS_FW_LANG_GER 3 +#define NDS_FW_LANG_ITA 4 +#define NDS_FW_LANG_SPA 5 +#define NDS_FW_LANG_CHI 6 +#define NDS_FW_LANG_RES 7 + + //#define LOG_ARM9 //#define LOG_ARM7 @@ -111,27 +125,54 @@ typedef struct u16 touchY; } NDSSystem; -typedef struct -{ - u8 favColor; - u8 bMonth; - u8 bDay; - char nickName[10]; - u8 nickLen; - char message[26]; - u8 msgLen; - u8 language; - -} NDSFirmware; +/** /brief A touchscreen calibration point. + */ +struct NDS_fw_touchscreen_cal { + u16 adc_x; + u16 adc_y; + + u8 screen_x; + u8 screen_y; +}; + +/** /brief The type of DS + */ +enum nds_fw_ds_type { + NDS_FW_DS_TYPE_FAT, + NDS_FW_DS_TYPE_LITE +}; + +#define MAX_FW_NICKNAME_LENGTH 10 +#define MAX_FW_MESSAGE_LENGTH 26 + +struct NDS_fw_config_data { + enum nds_fw_ds_type ds_type; + + u8 fav_colour; + u8 birth_month; + u8 birth_day; + + u16 nickname[MAX_FW_NICKNAME_LENGTH]; + u8 nickname_len; + + u16 message[MAX_FW_MESSAGE_LENGTH]; + u8 message_len; + + u8 language; + + /* touchscreen calibration */ + struct NDS_fw_touchscreen_cal touch_cal[2]; +}; extern NDSSystem nds; -extern NDSFirmware firmware; int NDS_Init( struct armcpu_memory_iface *arm9_mem_if, struct armcpu_ctrl_iface **arm9_ctrl_iface, struct armcpu_memory_iface *arm7_mem_if, struct armcpu_ctrl_iface **arm7_ctrl_iface); void NDS_DeInit(void); +void +NDS_FillDefaultFirmwareConfigData( struct NDS_fw_config_data *fw_config); BOOL NDS_SetROM(u8 * rom, u32 mask); NDS_header * NDS_getROMHeader(void); @@ -147,7 +188,7 @@ int NDS_ImportSave(const char *filename); int NDS_WriteBMP(const char *filename); int NDS_LoadFirmware(const char *filename); -int NDS_CreateDummyFirmware(void); +int NDS_CreateDummyFirmware( struct NDS_fw_config_data *user_settings); u32 NDS_exec(s32 nb, BOOL force); diff --git a/desmume/src/cli/main.c b/desmume/src/cli/main.c index 654f7399f..ff1614f42 100644 --- a/desmume/src/cli/main.c +++ b/desmume/src/cli/main.c @@ -109,6 +109,8 @@ struct my_config { #endif int disable_limiter; + int firmware_language; + const char *nds_file; const char *cflash_disk_image_file; }; @@ -130,6 +132,9 @@ init_config( struct my_config *config) { config->opengl_2d = 0; config->soft_colour_convert = 0; #endif + + /* use the default language */ + config->firmware_language = -1; } @@ -152,6 +157,14 @@ fill_config( struct my_config *config, printf( " screen rendering. May produce better or worse\n"); printf( " frame rates depending on hardware.\n"); #endif + printf( "\n"); + printf( " --fwlang=LANG Set the language in the firmware, LANG as follows:\n"); + printf( " 0 = Japanese\n"); + printf( " 1 = English\n"); + printf( " 2 = French\n"); + printf( " 3 = German\n"); + printf( " 4 = Italian\n"); + printf( " 5 = Spanish\n"); printf( "\n"); printf( " --arm9gdb=PORT_NUM Enable the ARM9 GDB stub on the given port\n"); printf( " --arm7gdb=PORT_NUM Enable the ARM7 GDB stub on the given port\n"); @@ -177,6 +190,18 @@ fill_config( struct my_config *config, else if ( strcmp( argv[i], "--disable-limiter") == 0) { config->disable_limiter = 1; } + else if ( strncmp( argv[i], "--fwlang=", 9) == 0) { + char *end_char; + int lang = strtoul( &argv[i][9], &end_char, 10); + + if ( lang >= 0 && lang <= 5) { + config->firmware_language = lang; + } + else { + fprintf( stderr, "Firmware language must be set to a value from 0 to 5.\n"); + good_args = 0; + } + } else if ( strncmp( argv[i], "--arm9gdb=", 10) == 0) { char *end_char; unsigned long port_num = strtoul( &argv[i][10], &end_char, 10); @@ -532,12 +557,23 @@ int main(int argc, char ** argv) { /* this holds some info about our display */ const SDL_VideoInfo *videoInfo; + /* the firmware settings */ + struct NDS_fw_config_data fw_config; + + /* default the firmware settings, they may get changed later */ + NDS_FillDefaultFirmwareConfigData( &fw_config); + init_config( &my_config); if ( !fill_config( &my_config, argc, argv)) { exit(1); } + /* use any language set on the command line */ + if ( my_config.firmware_language != -1) { + fw_config.language = my_config.firmware_language; + } + if ( my_config.arm9_gdb_port != 0) { arm9_gdb_stub = createStub_gdb( my_config.arm9_gdb_port, &arm9_memio, @@ -567,6 +603,9 @@ int main(int argc, char ** argv) { NDS_Init( arm9_memio, &arm9_ctrl_iface, arm7_memio, &arm7_ctrl_iface); + /* Create the dummy firmware */ + NDS_CreateDummyFirmware( &fw_config); + if ( !my_config.disable_sound) { SPU_ChangeSoundCore(SNDCORE_SDL, 735 * 4); } diff --git a/desmume/src/gtk-glade/main.c b/desmume/src/gtk-glade/main.c index 90c942162..a81c8a31c 100755 --- a/desmume/src/gtk-glade/main.c +++ b/desmume/src/gtk-glade/main.c @@ -72,6 +72,8 @@ struct configured_features { u16 arm9_gdb_port; u16 arm7_gdb_port; + int firmware_language; + const char *nds_file; }; @@ -87,6 +89,9 @@ init_configured_features( struct configured_features *config) { config->disable_limiter = 0; config->nds_file = NULL; + + /* use the default language */ + config->firmware_language = -1; } static int @@ -110,6 +115,14 @@ fill_configured_features( struct configured_features *config, #endif g_print( " --disable-limiter Disables the 60 fps limiter\n"); g_print( "\n"); + g_print( " --fwlang=LANG Set the language in the firmware, LANG as follows:\n"); + g_print( " 0 = Japanese\n"); + g_print( " 1 = English\n"); + g_print( " 2 = French\n"); + g_print( " 3 = German\n"); + g_print( " 4 = Italian\n"); + g_print( " 5 = Spanish\n"); + g_print( "\n"); g_print( " --arm9gdb=PORT_NUM Enable the ARM9 GDB stub on the given port\n"); g_print( " --arm7gdb=PORT_NUM Enable the ARM7 GDB stub on the given port\n"); //g_print( " --sticky Enable sticky keys and stylus\n"); @@ -125,6 +138,18 @@ fill_configured_features( struct configured_features *config, config->disable_3d = 1; } #endif + else if ( strncmp( argv[i], "--fwlang=", 9) == 0) { + char *end_char; + int lang = strtoul( &argv[i][9], &end_char, 10); + + if ( lang >= 0 && lang <= 5) { + config->firmware_language = lang; + } + else { + g_print( stderr, "Firmware language must be set to a value from 0 to 5.\n"); + good_args = 0; + } + } else if ( strncmp( argv[i], "--arm9gdb=", 10) == 0) { char *end_char; unsigned long port_num = strtoul( &argv[i][10], &end_char, 10); @@ -403,6 +428,16 @@ common_gtk_glade_main( struct configured_features *my_config) { struct armcpu_memory_iface *arm7_memio = &arm7_base_memory_iface; struct armcpu_ctrl_iface *arm9_ctrl_iface; struct armcpu_ctrl_iface *arm7_ctrl_iface; + /* the firmware settings */ + struct NDS_fw_config_data fw_config; + + /* default the firmware settings, they may get changed later */ + NDS_FillDefaultFirmwareConfigData( &fw_config); + + /* use any language set on the command line */ + if ( my_config->firmware_language != -1) { + fw_config.language = my_config->firmware_language; + } #ifdef GTKGLEXT_AVAILABLE // check if you have GTHREAD when running configure script @@ -449,6 +484,10 @@ common_gtk_glade_main( struct configured_features *my_config) { desmume_init( arm9_memio, &arm9_ctrl_iface, arm7_memio, &arm7_ctrl_iface); + + /* Create the dummy firmware */ + NDS_CreateDummyFirmware( &fw_config); + /* * Activate the GDB stubs * This has to come after the NDS_Init (called in desmume_init) diff --git a/desmume/src/gtk/main.c b/desmume/src/gtk/main.c index 329b1f085..0dc548c1b 100644 --- a/desmume/src/gtk/main.c +++ b/desmume/src/gtk/main.c @@ -112,6 +112,8 @@ struct configured_features { u16 arm9_gdb_port; u16 arm7_gdb_port; + int firmware_language; + const char *nds_file; const char *cflash_disk_image_file; }; @@ -133,6 +135,9 @@ init_configured_features( struct configured_features *config) { config->nds_file = NULL; config->cflash_disk_image_file = NULL; + + /* use the default language */ + config->firmware_language = -1; } static int @@ -158,6 +163,14 @@ fill_configured_features( struct configured_features *config, printf( " --disable-sound Disables the sound emulation\n"); printf( " --disable-limiter Disables the 60 fps limiter\n"); printf( "\n"); + printf( " --fwlang=LANG Set the language in the firmware, LANG as follows:\n"); + printf( " 0 = Japanese\n"); + printf( " 1 = English\n"); + printf( " 2 = French\n"); + printf( " 3 = German\n"); + printf( " 4 = Italian\n"); + printf( " 5 = Spanish\n"); + printf( "\n"); printf( " --arm9gdb=PORT_NUM Enable the ARM9 GDB stub on the given port\n"); printf( " --arm7gdb=PORT_NUM Enable the ARM7 GDB stub on the given port\n"); //printf( " --sticky Enable sticky keys and stylus\n"); @@ -185,6 +198,18 @@ fill_configured_features( struct configured_features *config, else if ( strcmp( argv[i], "--disable-limiter") == 0) { config->disable_limiter = 1; } + else if ( strncmp( argv[i], "--fwlang=", 9) == 0) { + char *end_char; + int lang = strtoul( &argv[i][9], &end_char, 10); + + if ( lang >= 0 && lang <= 5) { + config->firmware_language = lang; + } + else { + fprintf( stderr, "Firmware language must be set to a value from 0 to 5.\n"); + good_args = 0; + } + } else if ( strncmp( argv[i], "--arm9gdb=", 10) == 0) { char *end_char; unsigned long port_num = strtoul( &argv[i][10], &end_char, 10); @@ -1553,6 +1578,17 @@ common_gtk_main( struct configured_features *my_config) { struct armcpu_ctrl_iface *arm9_ctrl_iface; struct armcpu_ctrl_iface *arm7_ctrl_iface; + /* the firmware settings */ + struct NDS_fw_config_data fw_config; + + /* default the firmware settings, they may get changed later */ + NDS_FillDefaultFirmwareConfigData( &fw_config); + + /* use any language set on the command line */ + if ( my_config->firmware_language != -1) { + fw_config.language = my_config->firmware_language; + } + bad_glob_cflash_disk_image_file = my_config->cflash_disk_image_file; #ifdef DEBUG @@ -1627,6 +1663,9 @@ common_gtk_main( struct configured_features *my_config) { activateStub_gdb( arm7_gdb_stub, arm7_ctrl_iface); } + /* Create the dummy firmware */ + NDS_CreateDummyFirmware( &fw_config); + /* Initialize joysticks */ if(!init_joy()) return 1; diff --git a/desmume/src/windows/FirmConfig.c b/desmume/src/windows/FirmConfig.c index 930c729c7..f29bae200 100644 --- a/desmume/src/windows/FirmConfig.c +++ b/desmume/src/windows/FirmConfig.c @@ -37,6 +37,9 @@ char IniName[MAX_PATH]; u32 keytab[12]; +static char nickname_buffer[11]; +static char message_buffer[27]; + const char firmLang[6][16] = {"Japanese","English","French","German","Italian","Spanish"}; const char firmColor[16][16] = {"Gray","Brown","Red","Pink","Orange","Yellow","Lime Green", "Green","Dark Green","Sea Green","Turquoise","Blue", @@ -47,68 +50,110 @@ const char firmDay[31][16] = {"1","2","3","4","5","6","7","8","9","10","11","1 const char firmMonth[12][16] = {"January","Feburary","March","April","May","June","July", "August","September","October","November","December"}; -void ReadFirmConfig(void) +static void WriteFirmConfig( struct NDS_fw_config_data *fw_config) { + char temp_str[27]; + int i; GetINIPath(IniName,MAX_PATH); - memset(&firmware,0,sizeof(firmware)); - firmware.favColor = GetPrivateProfileInt("Firmware","favColor", 10, IniName); - firmware.bMonth = GetPrivateProfileInt("Firmware","bMonth", 7, IniName); - firmware.bDay = GetPrivateProfileInt("Firmware","bDay", 15, IniName); - GetPrivateProfileString("Firmware","nickName", "yopyop", firmware.nickName, 10, IniName); - firmware.nickLen = strlen(firmware.nickName); - GetPrivateProfileString("Firmware","Message", "Hi,it/s me!", firmware.message, 26, IniName); - firmware.msgLen = strlen(firmware.message); - firmware.language = GetPrivateProfileInt("Firmware","Language", 2, IniName); -} + WritePrivateProfileInt("Firmware","favColor", fw_config->fav_colour,IniName); + WritePrivateProfileInt("Firmware","bMonth", fw_config->birth_month,IniName); + WritePrivateProfileInt("Firmware","bDay",fw_config->birth_day,IniName); + WritePrivateProfileInt("Firmware","Language",fw_config->language,IniName); -void WriteFirmConfig(void) -{ - GetINIPath(IniName,MAX_PATH); + /* FIXME: harshly only use the lower byte of the UTF-16 character. + * This would cause strange behaviour if the user could set UTF-16 but + * they cannot yet. + */ + for ( i = 0; i < fw_config->nickname_len; i++) { + temp_str[i] = fw_config->nickname[i]; + } + temp_str[i] = '\0'; + WritePrivateProfileString("Firmware", "nickName", temp_str, IniName); - WritePrivateProfileInt("Firmware","favColor",firmware.favColor,IniName); - WritePrivateProfileInt("Firmware","bMonth",firmware.bMonth,IniName); - WritePrivateProfileInt("Firmware","bDay",firmware.bDay,IniName); - WritePrivateProfileInt("Firmware","Language",firmware.language,IniName); - WritePrivateProfileString("Firmware","nickName", firmware.nickName, IniName); - WritePrivateProfileString("Firmware","Message", firmware.message, IniName); + for ( i = 0; i < fw_config->message_len; i++) { + temp_str[i] = fw_config->message[i]; + } + temp_str[i] = '\0'; + WritePrivateProfileString("Firmware","Message", temp_str, IniName); } BOOL CALLBACK FirmConfig_Proc(HWND dialog,UINT komunikat,WPARAM wparam,LPARAM lparam) { - int i,j; - char tempstring[256]; + struct NDS_fw_config_data *fw_config = &win_fw_config; + int i; + char temp_str[27]; + switch(komunikat) { case WM_INITDIALOG: - ReadConfig(); for(i=0;i<6;i++) SendDlgItemMessage(dialog,IDC_COMBO4,CB_ADDSTRING,0,(LPARAM)&firmLang[i]); for(i=0;i<12;i++) SendDlgItemMessage(dialog,IDC_COMBO2,CB_ADDSTRING,0,(LPARAM)&firmMonth[i]); for(i=0;i<16;i++) SendDlgItemMessage(dialog,IDC_COMBO1,CB_ADDSTRING,0,(LPARAM)&firmColor[i]); for(i=0;i<31;i++) SendDlgItemMessage(dialog,IDC_COMBO3,CB_ADDSTRING,0,(LPARAM)&firmDay[i]); - SendDlgItemMessage(dialog,IDC_COMBO1,CB_SETCURSEL,firmware.favColor,0); - SendDlgItemMessage(dialog,IDC_COMBO2,CB_SETCURSEL,firmware.bMonth-1,0); - SendDlgItemMessage(dialog,IDC_COMBO3,CB_SETCURSEL,firmware.bDay-1,0); - SendDlgItemMessage(dialog,IDC_COMBO4,CB_SETCURSEL,firmware.language,0); + SendDlgItemMessage(dialog,IDC_COMBO1,CB_SETCURSEL,fw_config->fav_colour,0); + SendDlgItemMessage(dialog,IDC_COMBO2,CB_SETCURSEL,fw_config->birth_month-1,0); + SendDlgItemMessage(dialog,IDC_COMBO3,CB_SETCURSEL,fw_config->birth_day-1,0); + SendDlgItemMessage(dialog,IDC_COMBO4,CB_SETCURSEL,fw_config->language,0); SendDlgItemMessage(dialog,IDC_EDIT1,EM_SETLIMITTEXT,10,0); SendDlgItemMessage(dialog,IDC_EDIT2,EM_SETLIMITTEXT,26,0); SendDlgItemMessage(dialog,IDC_EDIT1,EM_SETSEL,0,10); SendDlgItemMessage(dialog,IDC_EDIT2,EM_SETSEL,0,26); - SendDlgItemMessage(dialog,IDC_EDIT1,EM_REPLACESEL,0,(LPARAM)&firmware.nickName); - SendDlgItemMessage(dialog,IDC_EDIT2,EM_REPLACESEL,0,(LPARAM)&firmware.message); + + for ( i = 0; i < fw_config->nickname_len; i++) { + nickname_buffer[i] = fw_config->nickname[i]; + } + nickname_buffer[i] = '\0'; + SendDlgItemMessage(dialog,IDC_EDIT1,WM_SETTEXT,0,(LPARAM)nickname_buffer); + + for ( i = 0; i < fw_config->message_len; i++) { + message_buffer[i] = fw_config->message[i]; + } + message_buffer[i] = '\0'; + SendDlgItemMessage(dialog,IDC_EDIT2,WM_SETTEXT,0,(LPARAM)message_buffer); break; case WM_COMMAND: if((HIWORD(wparam)==BN_CLICKED)&&(((int)LOWORD(wparam))==IDOK)) { - firmware.favColor=SendDlgItemMessage(dialog,IDC_COMBO1,CB_GETCURSEL,0,0); - firmware.bMonth=1+SendDlgItemMessage(dialog,IDC_COMBO2,CB_GETCURSEL,0,0); - firmware.bDay=1+SendDlgItemMessage(dialog,IDC_COMBO3,CB_GETCURSEL,0,0); - firmware.language=SendDlgItemMessage(dialog,IDC_COMBO4,CB_GETCURSEL,0,0); - SendDlgItemMessage(dialog,IDC_EDIT1,EM_GETLINE,0,(LPARAM)&firmware.nickName); - SendDlgItemMessage(dialog,IDC_EDIT2,EM_GETLINE,0,(LPARAM)&firmware.message); - WriteFirmConfig(); + int char_index; + LRESULT res; + fw_config->fav_colour = SendDlgItemMessage(dialog,IDC_COMBO1,CB_GETCURSEL,0,0); + fw_config->birth_month = 1 + SendDlgItemMessage(dialog,IDC_COMBO2,CB_GETCURSEL,0,0); + fw_config->birth_day = 1 + SendDlgItemMessage(dialog,IDC_COMBO3,CB_GETCURSEL,0,0); + fw_config->language = SendDlgItemMessage(dialog,IDC_COMBO4,CB_GETCURSEL,0,0); + + *(WORD *)temp_str = 10; + res = SendDlgItemMessage(dialog,IDC_EDIT1,EM_GETLINE,0,(LPARAM)temp_str); + + if ( res > 0) { + temp_str[res] = '\0'; + fw_config->nickname_len = strlen( temp_str); + } + else { + strcpy( temp_str, "yopyop"); + fw_config->nickname_len = strlen( temp_str); + } + for ( char_index = 0; char_index < fw_config->nickname_len; char_index++) { + fw_config->nickname[char_index] = temp_str[char_index]; + } + + *(WORD *)temp_str = 26; + res = SendDlgItemMessage(dialog,IDC_EDIT2,EM_GETLINE,0,(LPARAM)temp_str); + if ( res > 0) { + temp_str[res] = '\0'; + fw_config->message_len = strlen( temp_str); + } + else { + fw_config->message_len = 0; + } + for ( char_index = 0; char_index < fw_config->message_len; char_index++) { + fw_config->message[char_index] = temp_str[char_index]; + } + + WriteFirmConfig( fw_config); EndDialog(dialog,0); + NDS_CreateDummyFirmware( fw_config); return 1; } else diff --git a/desmume/src/windows/FirmConfig.h b/desmume/src/windows/FirmConfig.h index dd674e98d..245bf25f9 100644 --- a/desmume/src/windows/FirmConfig.h +++ b/desmume/src/windows/FirmConfig.h @@ -21,7 +21,7 @@ #ifndef FIRMCONFIG_H #define FIRMCONFIG_H -void ReadFirmConfig(void); +extern struct NDS_fw_config_data win_fw_config; BOOL CALLBACK FirmConfig_Proc(HWND dialog,UINT komunikat,WPARAM wparam,LPARAM lparam); diff --git a/desmume/src/windows/main.c b/desmume/src/windows/main.c index 7bc3d425b..bc3f77864 100644 --- a/desmume/src/windows/main.c +++ b/desmume/src/windows/main.c @@ -115,6 +115,10 @@ int frameskiprate=0; static int backupmemorytype=MC_TYPE_AUTODETECT; static u32 backupmemorysize=1; +/* the firmware settings */ +struct NDS_fw_config_data win_fw_config; + + LRESULT CALLBACK SoundSettingsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); @@ -600,6 +604,9 @@ int WINAPI WinMain (HINSTANCE hThisInstance, HACCEL hAccel; hAppInst=hThisInstance; + /* default the firmware settings, they may get changed later */ + NDS_FillDefaultFirmwareConfigData( &win_fw_config); + InitializeCriticalSection(§ion); GetINIPath(IniName, MAX_PATH); @@ -667,6 +674,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance, NDS_Init( arm9_memio, &arm9_ctrl_iface, arm7_memio, &arm7_ctrl_iface); + /* * Activate the GDB stubs * This has to come after the NDS_Init where the cpus are set up. @@ -707,17 +715,42 @@ int WINAPI WinMain (HINSTANCE hThisInstance, sndvolume = GetPrivateProfileInt("Sound","Volume",100, IniName); SPU_SetVolume(sndvolume); - - memset(&firmware,0,sizeof(firmware)); - firmware.favColor = GetPrivateProfileInt("Firmware","favColor", 10, IniName); - firmware.bMonth = GetPrivateProfileInt("Firmware","bMonth", 7, IniName); - firmware.bDay = GetPrivateProfileInt("Firmware","bDay", 15, IniName); - GetPrivateProfileString("Firmware","nickName", "yopyop", firmware.nickName, 10, IniName); - firmware.nickLen = strlen(firmware.nickName); - GetPrivateProfileString("Firmware","Message", "Hi,it/s me!", firmware.message, 26, IniName); - firmware.msgLen = strlen(firmware.message); - firmware.language = GetPrivateProfileInt("Firmware","Language", 2, IniName); - + + /* Read the firmware settings from the init file */ + win_fw_config.fav_colour = GetPrivateProfileInt("Firmware","favColor", 10, IniName); + win_fw_config.birth_month = GetPrivateProfileInt("Firmware","bMonth", 7, IniName); + win_fw_config.birth_day = GetPrivateProfileInt("Firmware","bDay", 15, IniName); + win_fw_config.language = GetPrivateProfileInt("Firmware","Language", 1, IniName); + + { + /* + * Read in the nickname and message. + * Convert the strings into Unicode UTF-16 characters. + */ + char temp_str[27]; + int char_index; + GetPrivateProfileString("Firmware","nickName", "yopyop", temp_str, 11, IniName); + win_fw_config.nickname_len = strlen( temp_str); + + if ( win_fw_config.nickname_len == 0) { + strcpy( temp_str, "yopyop"); + win_fw_config.nickname_len = strlen( temp_str); + } + + for ( char_index = 0; char_index < win_fw_config.nickname_len; char_index++) { + win_fw_config.nickname[char_index] = temp_str[char_index]; + } + + GetPrivateProfileString("Firmware","Message", "DeSmuME makes you happy!", temp_str, 27, IniName); + win_fw_config.message_len = strlen( temp_str); + for ( char_index = 0; char_index < win_fw_config.message_len; char_index++) { + win_fw_config.message[char_index] = temp_str[char_index]; + } + } + + /* Create the dummy firmware */ + NDS_CreateDummyFirmware( &win_fw_config); + runthread = CreateThread(NULL, 0, run, NULL, 0, &threadID); // Make sure any quotes from lpszArgument are removed @@ -1497,7 +1530,8 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM { cwindow_struct FirmConfig; - if (CWindow_Init2(&FirmConfig, hAppInst, HWND_DESKTOP, "Configure Controls", IDD_FIRMSETTINGS, FirmConfig_Proc) == 0) + if (CWindow_Init2(&FirmConfig, hAppInst, HWND_DESKTOP, + "Configure Controls", IDD_FIRMSETTINGS, FirmConfig_Proc) == 0) CWindow_Show(&FirmConfig); }