📄 vmu.c
字号:
dirblock--;
}
free(dir_entry);
}
void do_crc (uint8 *buffer, uint16 bytes) {
uint16 crc = calcCRC (buffer, bytes);
file_hdr_vmu * vmu_hdr = (file_hdr_vmu *)buffer;
vmu_hdr->crc = crc;
}
uint8 check_free_blocks (uint8 *free_mem) {
uint8 addr = maple_first_vmu();
uint16 fatblock;
uint8 buf[512];
uint16 *buf16 = (uint16*)buf;
uint8 free_blocks = 0;
int i;
if (vmu_block_read(addr, 255, buf)) {
return 0;
}
thd_sleep(30);
fatblock = buf16[0x46/2];
if (vmu_block_read(addr, fatblock, buf) != 0) {
return 0;
}
thd_sleep (30);
for (i=0; i<200; i++) {
if (buf16[i] == 0xfffc) {
free_blocks++;
free_mem[i] = 1;
}
else {
// print_uint32 ((uint32)buf16[i]);
// thd_sleep (3000);
}
}
return free_blocks;
}
uint16 find_first_free_block (uint8 *fat_table) {
uint16 first_free = 0;
int i;
for (i=0; i<200; i++) {
if (fat_table[i] == 1) {
first_free = i;
}
}
return first_free;
}
void create_dir_vmu (dirent_vmu *dir_entry, const char *rom_name, uint16 first_free_block, uint8 blocks) {
uint8 *temp_ptr = (uint8 *)dir_entry;
uint8 filename_size = strlen (rom_name);
int i;
/* zero out dir_entry */
for (i=0; i<32; i++) {
temp_ptr[i] = 0x00;
}
for (i=0; i<11; i++) {
if (i < filename_size)
dir_entry->filename[i] = rom_name[i];
else
dir_entry->filename[i] = ' ';
}
dir_entry->filename[11] = '&';
//strcpy (dir_entry->filename, rom_name);
dir_entry->firstblk = first_free_block;
dir_entry->filetype = 0x33;
dir_entry->copyprotect = 0x00;
dir_entry->filesize = blocks;
dir_entry->hdroff = 0;
}
void create_vmu_header(uint8 *header, const char *rom_name, const char *desc_long, uint16 filesize) {
file_hdr_vmu *vmu_h = (file_hdr_vmu *)header;
uint8 *temp_ptr = header;
int i;
/* zero header mem */
for (i=0; i<640; i++) {
*temp_ptr++ = 0x00;
}
strcpy (vmu_h->desc_short, rom_name);
strcpy (vmu_h->desc_long, desc_long);
strcpy (vmu_h->app_id, "SMSPlus!_SAVE_");
vmu_h->icon_cnt = 1;
vmu_h->file_bytes = filesize;
for (i=0; i<512; i++) {
if (i < 128)
header[i+128] = 0;
else if (i < 256)
header[i+128] = 5;
else if (i < 384)
header[i+128] = 33;
else
header[i+128] = 51;
}
}
/* this routine came from the ghettoplay example that comes
with libdream */
void vmu_icon_draw(const char *vmu_icon, uint8 vmu) {
uint8 bitmap[48*32/8] = {0};
int x, y, xi, xb;
if (vmu_icon) {
for (y=0; y<32; y++)
for (x=0; x<48; x++) {
xi = x / 8;
xb = 0x80 >> (x % 8);
if (vmu_icon[(31-y)*48+(47-x)] == '+')
bitmap[y*(48/8)+xi] |= xb;
}
}
vmu_draw_lcd(vmu, bitmap);
}
/* the save and load routines contain some nasty code.
* i should rewrite these, but they seem to be working. */
void check_user_settings(uint8 vmu_mem1) {
uint16 block_number;
uint8 buf[1024];
uint8 *buf_ptr = (uint8 *)buf;
user_settings *settings_ptr;
//uint16 crc;
/* return if there is no vmu present */
if (!vmu_mem1) return;
thd_sleep(3000);
/* look in the vmu memory for a NesterDC settings file */
block_number = check_vmu_for_game("Settings");
/* a return value of 0 indicates that we didn't find it */
if (block_number == 0) return;
dc_print("Loading User Settings...");
/* used to store data read from the vmu (2 blocks) */
buf_ptr = (uint8 *)buf;
/* read the header vmu block */
if (vmu_block_read(vmu_mem1, block_number, buf_ptr) != 0) {
dc_print("Error loading block number");
print_uint32 ((uint32)block_number);
thd_sleep(3000);
return;
}
thd_sleep(100);
/* get the next block in the vmu for the settings file */
block_number = get_next_block_from_fat (block_number);
buf_ptr += 512;
/* read the next block */
if (vmu_block_read(vmu_mem1, block_number, buf_ptr) != 0) {
dc_print("Error loading block number");
print_uint32 ((uint32)block_number);
thd_sleep(3000);
return;
}
thd_sleep(100);
/* debug code to make sure that what went into the vmu, came
* out of the vmu :) */
/*file_hdr_vmu *testing = (file_hdr_vmu *)buf;
dc_print ("The CRC from the file is");
print_uint32 ((uint32)testing->crc);
thd_sleep (5000);
testing->crc = 0;
crc = calcCRC(buf, 1024);
dc_print("The calculated crc is");
print_uint32 ((uint32)crc);
thd_sleep (5000);*/
/* the way the vmu file structure is set up, user settings are
actually 128 bytes into the second vmu block */
settings_ptr = (user_settings *)(buf_ptr + 128);
/* here are the settings */
settings.cont_scheme = settings_ptr->cont_scheme;
settings.frame_skip = settings_ptr->frame_skip;
settings.sound_on = settings_ptr->sound_on;
settings.player_2 = settings_ptr->player_2;
settings.save = settings_ptr->save;
/* print_uint32 (settings.cont_scheme);
print_uint32 (settings.frame_skip);
print_uint32 (settings.sound_on);
print_uint32 (settings.player_2);
print_uint32 (settings.save);*/
}
void save_user_settings(uint8 vmu_mem1) {
/* free mem is an */
uint8 *free_mem;
uint8 *temp_ptr = free_mem;
int i;
uint16 block_number;
/* don't need to be here is there is no vmu */
if (!vmu_mem1) return;
free_mem = (uint8 *)malloc(200);
for (i=0; i<200; i++) {
*temp_ptr++ = '0';
}
block_number = check_vmu_for_game("Settings");
/* found the game in SaveRAM */
if (block_number != 0) {
uint8 buf[1024];
uint8 *vmu_file = (uint8 *)buf;
//uint8 free_blocks = check_free_blocks (free_mem);
uint16 crc;
//file_hdr_vmu *testing;
user_settings *settings_ptr;
dc_print("Saving User Settings...");
create_vmu_header (vmu_file, "Settings", "SMSPlus! Settings File", 384);
for (i=640; i<1024; i++) {
vmu_file[i] = 0;
}
settings_ptr = (user_settings *)(vmu_file + 640);
settings_ptr->cont_scheme = settings.cont_scheme;
settings_ptr->frame_skip = settings.frame_skip;
settings_ptr->sound_on = settings.sound_on;
settings_ptr->player_2 = settings.player_2;
settings_ptr->save = settings.save;
crc = calcCRC(vmu_file, 1024);
/*dc_print ("The CRC is");
print_uint32 ((uint32)crc);
thd_sleep(5000);
do_crc (vmu_file, 1024);
testing = (file_hdr_vmu *)vmu_file;
dc_print ("Test the File CRC");
print_uint32 ((uint32)testing->crc);
thd_sleep(5000);*/
upload_data_by_block (vmu_file, (uint32)block_number, 2);
} else {
uint8 free_blocks = check_free_blocks (free_mem);
uint8 buf[1024];
uint8 *vmu_file = (uint8 *)buf;
uint8 first_free_block;
user_settings *settings_ptr;
if (free_blocks < 2) {
dc_print ("You need 2 free blocks to Save user settings");
thd_sleep(5000);
free(free_mem);
return;
}
dc_print("Saving User Settings...");
create_vmu_header (vmu_file, "Settings", "SMSPlus! Settings File", 384);
/* filler */
for (i=640; i<1024; i++) {
vmu_file[i] = 0;
}
settings_ptr = (user_settings *)(vmu_file + 640);
settings_ptr->cont_scheme = settings.cont_scheme;
settings_ptr->frame_skip = settings.frame_skip;
settings_ptr->sound_on = settings.sound_on;
settings_ptr->player_2 = settings.player_2;
settings_ptr->save = settings.save;
do_crc (vmu_file, 1024);
first_free_block = find_first_free_block(free_mem);
update_fat (free_mem, 2);
upload_vmu_data (vmu_file, free_mem, 2);
update_vmu_dir (first_free_block, "Settings", 2);
}
free(free_mem);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -