
Originally Posted by
limnique
squarepusher2, thx, work nice, but have black screen problem

Yeah, it does that after having swapped five or so ROMs. A good rule of thumb at the moment is to select 'Quit Game' from the XMB after having loaded the third ROM or so until I can figure out the source of the problem.
It sucks that S9xExit() doesn't really do what I would have expected it to do - according to the Porting manual, this callback is only called when something majorly bad happens (with the emulator), or when the debugger stops the emulator (the debugger which is not enabled at the moment). I could perhaps try to implement S9xExit() as a callback and then have it go back to the ROM screen - perhaps that can get around the black screen after having loaded the fourth/fifth ROM or so.
EDIT: Just tried that - didn't seem to fix the black screen problem. Perhaps eisz might want to check out my code - he should PM me and I will give him the source of the latest changes I made.
All the changes have been made in cell.cpp.
Here's what I changed to implement the Quit ROM functionality:
First I have declared a global int variable called 'mode_switch'.
In the main loop, I have split off the entire block of main code into separate functions - so you now have 'start_display', 'rom_menu' and 'start_snes9x'.
start_display
I've simply moved over a lot of the code inside main to a separate function that I can then call from the infinite main loop whenever I need to re-render the rom_menu (you don't need to explicitly call this before calling rom_menu, but whether you call it again or not, it will still give a black screen after loading 4/5 ROMs.
Code:
void start_display()
{
init_display();
init_shader();
dma_label = cellGcmGetLabelAddress(dma_label_id);
*dma_label = dma_label_value;
is_running = true;
uint32_t buf_size = sizeof(color4_t) * color_buf[0].width * color_buf[0].height;
buf_size = (buf_size + 1024 * 1024) & (~(1024 * 1024 - 1));
color4_t *buf = (color4_t *)memalign(1024 * 1024, buf_size);
cellGcmMapMainMemory(buf, buf_size, &display_back_offset);
memset(buf, 0, buf_size);
display_back = buf;
buf = (color4_t *)memalign(1024 * 1024, buf_size);
cellGcmMapMainMemory(buf, buf_size, &display_offset);
memset(buf, 0, buf_size);
display = buf;
setDrawEnv();
set_render_state();
setRenderTarget(frame_index);
} The following changes has been made in rom_menu:
rom_menu
Code:
if (buttons & CTRL_CROSS) {
if (is_dir[current_index]) {
sprintf(path, "%s/%s", path, file_names[current_index]);
needs_update = true;
continue;
} else {
sprintf(rom_path, "%s/%s", path, file_names[current_index]);
[b]mode_switch = 1; //new[/n]
return;
}
} start_snes9x
Code:
void start_snes9x()
{
bool snes9x_loaded = false;
if (!(snes9x_loaded = init_snes9x())) {
Settings.Paused = TRUE;
}
int count = 0;
init_sound();
S9xSetSoundMute(FALSE);
S9xReset();
memset(display, 0, color_buf[0].height * color_buf[0].pitch);
memset(display_back, 0, color_buf[0].height * color_buf[0].pitch);
while (is_running) {
read_pad();
if (!Settings.Paused) {
make_noise();
if (S9xSyncSound())
S9xMainLoop();
}
if (debug_text)
debugOutStr(100, 100, debug_text);
render(false);
}
if (snes9x_loaded)
Memory.SaveSRAM(S9xGetFilename(".srm", SRAM_DIR));
snes9x_loaded = false;
Memory.Deinit();
S9xGraphicsDeinit();
S9xDeinitAPU();
is_running = true;
} Then near the end of the main loop, I run an infinite loop where the mode switching will occur. The code is basically trapped inside one of either functions (rom_menu or start_snes9x) as long as no user input takes them out of it (in-game, this is achieved by pressing L2 + R2, which sets mode_switch to 0 and is_running to false, and will return the code from the start_snes9x body back to the infinite loop inside main().
Main
Code:
int main (void) {
cellSysmoduleLoadModule(CELL_SYSMODULE_FS);
cellSysmoduleLoadModule(CELL_SYSMODULE_IO);
cellSysmoduleLoadModule(CELL_SYSMODULE_AUDIO);
cellSysutilRegisterCallback(0, sysutil_exit_callback, NULL);
cellPadInit(7);
start_display();
rom_menu();
while(1)
{
switch(mode_switch)
{
case 0:
start_display();
rom_menu();
break;
case 1:
start_snes9x();
break;
case 2:
return 0;
}
}
return 0;
} S9Exit callback
Was previously empty, now takes care of the deinitialization process. Not sure if it is actually called though - or whether the 'black screen' even constitutes an error occurring in Snes9x, or whether it's the display code.
Code:
void S9xExit (void) {
Memory.Deinit(); // new
S9xGraphicsDeinit(); // new
S9xDeinitAPU(); //new
is_running = false; //new
mode_switch = 0; //when set to 0, will go to the ROM menu
} The following changes has been made in rom_menu:
rom_menu
[/quote]
Forgot to add the following change:
Code:
S9xReportButton(MAKE_BUTTON(pad_id, BTN_RIGHT), (buttons & CTRL_RIGHT) != 0); //old
// below is new
if ((buttons & CTRL_R2) != 0 && (buttons & CTRL_L2) != 0)
{
is_running = false;
S9xExit();
mode_switch = 0;
} The following changes has been made in rom_menu:
rom_menu
[/quote]
Forgot to add the following change:
Code:
S9xReportButton(MAKE_BUTTON(pad_id, BTN_RIGHT), (buttons & CTRL_RIGHT) != 0); //old
// below is new
if ((buttons & CTRL_R2) != 0 && (buttons & CTRL_L2) != 0)
{
is_running = false;
S9xExit();
mode_switch = 0;
} Slight typo there - S9xExit(); should not be in there since it should not be called before we've got the chance to do the Memory.SaveRAM call.