avoid overwriting persistent aspect ratio option when forcing aspect

ratio due to a widescreen hack being enabled
This commit is contained in:
Anthony Pesch 2017-07-23 12:20:57 -04:00
parent 843199c277
commit 817e91e058
1 changed files with 75 additions and 52 deletions

View File

@ -40,8 +40,8 @@ DEFINE_AGGREGATE_COUNTER(frames);
DEFINE_PERSISTENT_OPTION_STRING(aspect_ratio, "stretch", "Video aspect ratio");
enum {
ASPECT_STRETCH,
ASPECT_4BY3,
ASPECT_RATIO_STRETCH,
ASPECT_RATIO_4BY3,
};
static const char *aspect_ratios[] = {
@ -71,15 +71,15 @@ struct emu {
struct host *host;
struct dreamcast *dc;
volatile int video_width;
volatile int video_height;
volatile unsigned frame;
struct render_backend *r;
struct imgui *imgui;
struct microprofile *mp;
struct trace_writer *trace_writer;
int video_width;
int video_height;
int aspect_ratio;
/* when running with multiple threads, the dreamcast emulation is ran on a
secondary thread, in order to allow rendering to be done asynchronously on
the main thread. the original hardware rendered asynchronously, so many
@ -89,6 +89,7 @@ struct emu {
/* emulation thread synchronization primitives */
volatile int state;
volatile unsigned frame;
thread_t run_thread;
mutex_t run_mutex;
cond_t run_cond;
@ -482,45 +483,33 @@ static void emu_host_resized(void *userdata) {
}
/*
* frame running logic
* options
*/
static void emu_run_frame(struct emu *emu);
static void emu_set_aspect_ratio(struct emu *emu, const char *new_ratio) {
int i;
int num_aspect_ratios = array_size(aspect_ratios);
static void *emu_run_thread(void *data) {
struct emu *emu = data;
for (i = 0; i < num_aspect_ratios; i++) {
const char *aspect_ratio = aspect_ratios[i];
while (1) {
/* wait for video thread to request a frame to be ran */
{
mutex_lock(emu->run_mutex);
while (emu->state == EMU_WAITING) {
cond_wait(emu->run_cond, emu->run_mutex);
}
if (emu->state == EMU_SHUTDOWN) {
break;
}
emu_run_frame(emu);
emu->state = EMU_WAITING;
mutex_unlock(emu->run_mutex);
}
/* in case no context was submitted before the frame end, signal the video
thread to continue, reusing the previous context */
{
mutex_lock(emu->frame_mutex);
cond_signal(emu->frame_cond);
mutex_unlock(emu->frame_mutex);
if (!strcmp(aspect_ratio, new_ratio)) {
break;
}
}
return NULL;
/* force to stretch if the new ratio isn't a valid one */
if (i == num_aspect_ratios) {
i = ASPECT_RATIO_STRETCH;
}
/* update persistent option as well as this session's aspect ratio */
strncpy(OPTION_aspect_ratio, aspect_ratios[i], sizeof(OPTION_aspect_ratio));
emu->aspect_ratio = i;
/* if a widescreen hack is enabled, force to stretch for the session */
if (gdrom_widescreen_enabled(emu->dc->gdrom)) {
emu->aspect_ratio = ASPECT_RATIO_STRETCH;
}
}
static void emu_debug_menu(struct emu *emu) {
@ -553,8 +542,7 @@ static void emu_debug_menu(struct emu *emu) {
int selected = !strcmp(OPTION_aspect_ratio, aspect_ratio);
if (igMenuItem(aspect_ratio, NULL, selected, 1)) {
strncpy(OPTION_aspect_ratio, aspect_ratio,
sizeof(OPTION_aspect_ratio));
emu_set_aspect_ratio(emu, aspect_ratio);
}
}
@ -628,6 +616,48 @@ static void emu_debug_menu(struct emu *emu) {
#endif
}
/*
* frame running logic
*/
static void emu_run_frame(struct emu *emu);
static void *emu_run_thread(void *data) {
struct emu *emu = data;
while (1) {
/* wait for video thread to request a frame to be ran */
{
mutex_lock(emu->run_mutex);
while (emu->state == EMU_WAITING) {
cond_wait(emu->run_cond, emu->run_mutex);
}
if (emu->state == EMU_SHUTDOWN) {
break;
}
emu_run_frame(emu);
emu->state = EMU_WAITING;
mutex_unlock(emu->run_mutex);
}
/* in case no context was submitted before the frame end, signal the video
thread to continue, reusing the previous context */
{
mutex_lock(emu->frame_mutex);
cond_signal(emu->frame_cond);
mutex_unlock(emu->frame_mutex);
}
}
return NULL;
}
static void emu_run_frame(struct emu *emu) {
const int64_t MACHINE_STEP = HZ_TO_NANO(1000);
unsigned start_frame = emu->frame;
@ -644,18 +674,18 @@ void emu_render_frame(struct emu *emu) {
int frame_height, frame_width;
int frame_x, frame_y;
if (!strcmp(OPTION_aspect_ratio, aspect_ratios[ASPECT_STRETCH])) {
if (emu->aspect_ratio == ASPECT_RATIO_STRETCH) {
frame_height = emu->video_height;
frame_width = emu->video_width;
frame_x = 0;
frame_y = 0;
} else if (!strcmp(OPTION_aspect_ratio, aspect_ratios[ASPECT_4BY3])) {
} else if (emu->aspect_ratio == ASPECT_RATIO_4BY3) {
frame_height = emu->video_height;
frame_width = frame_height * (4.0f / 3.0f);
frame_x = (emu->video_width - frame_width) / 2.0f;
frame_y = 0;
} else {
LOG_FATAL("unexpected aspect ratio %s", OPTION_aspect_ratio);
LOG_FATAL("unexpected aspect ratio %d", emu->aspect_ratio);
}
int debug_height = emu->video_height;
@ -740,14 +770,7 @@ int emu_load_game(struct emu *emu, const char *path) {
return 0;
}
/* stretch to fill if the game has a widescreen hack enabled */
if (gdrom_widescreen_enabled(emu->dc->gdrom)) {
strncpy(OPTION_aspect_ratio, aspect_ratios[ASPECT_STRETCH],
sizeof(OPTION_aspect_ratio));
} else {
strncpy(OPTION_aspect_ratio, aspect_ratios[ASPECT_4BY3],
sizeof(OPTION_aspect_ratio));
}
emu_set_aspect_ratio(emu, OPTION_aspect_ratio);
dc_resume(emu->dc);