fixed minor memory leaks in main_window. when the nds core sets execution to false, an error message is now displayed to let the user know that emulation has stopped. video output frame rate is now limited, which makes the gui more responsive especially when emulation is provided new frames as fast or faster than they can be blitted to the screen
This commit is contained in:
parent
e42186683d
commit
6f92277993
|
@ -27,7 +27,6 @@ Based on work by yopyop and the DeSmuME team!
|
|||
#import "preferences.h"
|
||||
|
||||
/*
|
||||
FIXME: When cross-platform (core) components end emulation due to error - pause should be called (set the menu checkmark)
|
||||
FIXME: .nds.gba support?
|
||||
*/
|
||||
|
||||
|
|
|
@ -114,11 +114,11 @@ NSMenuItem *screenshot_to_file_item;
|
|||
}
|
||||
|
||||
- (id)init
|
||||
{//fixme non leaky exception handling
|
||||
{
|
||||
//Create the NDS
|
||||
self = [super init];
|
||||
|
||||
if(self == nil)return nil;
|
||||
if(self == nil)return nil; //superclass will display it's own error messages if needed
|
||||
|
||||
//
|
||||
NSRect rect;
|
||||
|
@ -139,6 +139,14 @@ NSMenuItem *screenshot_to_file_item;
|
|||
backing:NSBackingStoreBuffered defer:NO screen:nil])==nil)
|
||||
{
|
||||
messageDialog(NSLocalizedString(@"Error", nil), @"Couldn't create window");
|
||||
|
||||
//release the superclass (this will probably call our own destructor, so set nil members)
|
||||
controller = nil;
|
||||
video_output_view = nil;
|
||||
status_view = nil;
|
||||
input = nil;
|
||||
[super release];
|
||||
|
||||
return nil;
|
||||
}
|
||||
[window setTitle:NSLocalizedString(@"DeSmuME Emulator", nil)];
|
||||
|
@ -148,7 +156,8 @@ NSMenuItem *screenshot_to_file_item;
|
|||
rect.origin.y = status_bar_height;
|
||||
rect.size.width = DS_SCREEN_WIDTH;
|
||||
rect.size.height = DS_SCREEN_HEIGHT_COMBINED;
|
||||
video_output_view = [[VideoOutputView alloc] initWithFrame:rect]; //no nil check - will do it's own error messages
|
||||
//video_output_view = [[VideoOutputView alloc] initWithFrame:rect]; //no nil check - will do it's own error messages
|
||||
video_output_view = nil;
|
||||
[video_output_view setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable]; //view will automatically resize with the window
|
||||
|
||||
[[window contentView] addSubview:video_output_view];
|
||||
|
@ -167,7 +176,7 @@ NSMenuItem *screenshot_to_file_item;
|
|||
[window setDelegate:self]; //we do this after making the ouput/statusbar incase some delegate method gets called suddenly
|
||||
[controller = [[NSWindowController alloc] initWithWindow:window] showWindow:nil];
|
||||
|
||||
//Create the input manager
|
||||
//Create the input manager and insert it into the cocoa responder chain
|
||||
input = [[InputHandler alloc] initWithWindow:(id)self];
|
||||
NSResponder *temp = [window nextResponder];
|
||||
[window setNextResponder:input];
|
||||
|
@ -178,11 +187,11 @@ NSMenuItem *screenshot_to_file_item;
|
|||
|
||||
- (void)dealloc
|
||||
{
|
||||
[controller release];
|
||||
[window release];
|
||||
[video_output_view release];
|
||||
[status_view release];
|
||||
|
||||
[self retain]; //see the comment in init after we initialize the window controller
|
||||
[controller release];
|
||||
[input release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
|
|
@ -472,14 +472,26 @@ struct NDS_fw_config_data firmware;
|
|||
|
||||
- (void)reset
|
||||
{
|
||||
[execution_lock lock];
|
||||
//note that the execution_lock method would probably be a little better
|
||||
|
||||
//but the NDS_Reset() function sets execution to false for some reason
|
||||
//we treat execution == false as an emulation error
|
||||
//pausing allows the other thread to not think theres an emulation error
|
||||
|
||||
//[execution_lock lock];
|
||||
bool old_run = run;
|
||||
if(old_run)
|
||||
{
|
||||
run = false;
|
||||
while(!paused){}
|
||||
}
|
||||
|
||||
NDS_Reset();
|
||||
|
||||
[execution_lock unlock];
|
||||
//[execution_lock unlock];
|
||||
run = old_run;
|
||||
|
||||
//set the execute variable incase
|
||||
//of a previous emulation error
|
||||
//if there was a previous emulation error, clear it, since we reset
|
||||
execute = true;
|
||||
}
|
||||
|
||||
|
@ -1186,7 +1198,7 @@ struct NDS_fw_config_data firmware;
|
|||
if(!run)paused = true;
|
||||
|
||||
//run the emulator
|
||||
while(run)
|
||||
while(run && execute) //run controls when the emulator runs, execute prevents it from continuing execution if there are errors
|
||||
{
|
||||
|
||||
paused = false;
|
||||
|
@ -1198,7 +1210,9 @@ struct NDS_fw_config_data firmware;
|
|||
cycles = NDS_exec((560190<<1)-cycles, FALSE);
|
||||
|
||||
[sound_lock lock];
|
||||
SPU_Emulate();
|
||||
int x;
|
||||
for(x = 0; x <= frames_to_skip; x++)
|
||||
SPU_Emulate();
|
||||
[sound_lock unlock];
|
||||
|
||||
[execution_lock unlock];
|
||||
|
@ -1227,40 +1241,39 @@ struct NDS_fw_config_data firmware;
|
|||
|
||||
}
|
||||
|
||||
//update the screen
|
||||
ScreenState *new_screen_data = [[ScreenState alloc] init];
|
||||
[new_screen_data setColorData:GPU_screen];
|
||||
if(timer_based)
|
||||
//update the screen (and limit frame rate of video output)
|
||||
static long long last_video_update = 0;
|
||||
if(frame_end_time - last_video_update > 10000)
|
||||
{
|
||||
[video_update_lock lock];
|
||||
[current_screen release];
|
||||
current_screen = new_screen_data;
|
||||
[video_update_lock unlock];
|
||||
} else
|
||||
{
|
||||
//this will generate a warning when compiling on tiger or earlier, but it should
|
||||
//be ok since the purpose of the if statement is to check if this will work
|
||||
[self performSelector:@selector(videoUpdateHelper:) onThread:gui_thread withObject:new_screen_data waitUntilDone:NO];
|
||||
[new_screen_data release]; //performSelector will auto retain the screen data while the other thread displays
|
||||
last_video_update = frame_end_time;
|
||||
|
||||
ScreenState *new_screen_data = [[ScreenState alloc] init];
|
||||
[new_screen_data setColorData:GPU_screen];
|
||||
|
||||
if(timer_based)
|
||||
{ //for tiger compatibility
|
||||
[video_update_lock lock];
|
||||
[current_screen release];
|
||||
current_screen = new_screen_data;
|
||||
[video_update_lock unlock];
|
||||
} else
|
||||
{ //for leopard and later
|
||||
|
||||
//this will generate a warning when compiling on tiger or earlier, but it should
|
||||
//be ok since the purpose of the if statement is to check if this will work
|
||||
[self performSelector:@selector(videoUpdateHelper:) onThread:gui_thread withObject:new_screen_data waitUntilDone:NO];
|
||||
[new_screen_data release]; //performSelector will auto retain the screen data while the other thread displays
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/* FIXME
|
||||
|
||||
//execute is set to false sometimes by the emulation core
|
||||
//when there is an error, if this happens notify the other
|
||||
//thread that emulation has stopped.
|
||||
//when there is an error, if this happens notify the other thread that emulation has stopped.
|
||||
if(!execute)
|
||||
{
|
||||
run = false; //stop executing
|
||||
execute = true; //reset the var, so if someone tries to execute again, we get the error again
|
||||
if(!timer_based) //wont display an error on tiger or earlier
|
||||
[error_object performSelector:error_func onThread:gui_thread withObject:nil waitUntilDone:YES];
|
||||
|
||||
[self performSelector:@selector(pause) onThread:gui_thread withObject:nil
|
||||
waitUntilDone:NO modes:[NSArray arrayWithObject:NSDefaultRunLoopMode]];
|
||||
|
||||
[error_object performSelector:error_func onThread:gui_thread withObject:nil
|
||||
waitUntilDone:NO modes:[NSArray arrayWithObject:NSDefaultRunLoopMode]];
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
//when emulation is paused, return CPU time to the OS
|
||||
|
|
Loading…
Reference in New Issue