mirror of
https://github.com/mauiaaron/apple2.git
synced 2024-06-24 11:29:33 +00:00
Refactor timing locking behavior
- Do not start CPU thread until after splash screen - Insure that only CPU thread can actually create/destroy the audio interfaces
This commit is contained in:
parent
fa1de4dee7
commit
a0cadc83c6
|
@ -140,9 +140,6 @@ void Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnCreate(JNIEnv *env, jobje
|
|||
c_initialize_firsttime();
|
||||
pthread_create(&cpu_thread_id, NULL, (void *) &cpu_thread, (void *)NULL);
|
||||
#endif
|
||||
|
||||
sleep(1);
|
||||
#warning FIXME TODO instead of problematic sleep ... need to preempt CPU thread by holding interface lock and displaying a splash screen and setting preferences/settings defaults before starting CPU
|
||||
}
|
||||
|
||||
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeGraphicsChanged(JNIEnv *env, jobject obj, jint width, jint height) {
|
||||
|
|
|
@ -57,18 +57,16 @@ void Java_org_deadc0de_apple2ix_Apple2Preferences_nativeSetSpeakerVolume(JNIEnv
|
|||
|
||||
void Java_org_deadc0de_apple2ix_Apple2Preferences_nativeSetAudioLatency(JNIEnv *env, jclass cls, jfloat latencySecs) {
|
||||
LOG("native set audio latency : %f", latencySecs);
|
||||
//assert(cpu_isPaused());
|
||||
assert(cpu_isPaused());
|
||||
audio_setLatency(latencySecs);
|
||||
timing_reinitializeAudio();
|
||||
}
|
||||
|
||||
jboolean Java_org_deadc0de_apple2ix_Apple2Preferences_nativeSetMockingboardEnabled(JNIEnv *env, jclass cls, jboolean enabled) {
|
||||
LOG("native set set mockingboard enabled : %d", enabled);
|
||||
//assert(cpu_isPaused());
|
||||
#warning FIXME ^^^ this should be true
|
||||
MB_Destroy();
|
||||
if (enabled) {
|
||||
MB_Initialize();
|
||||
}
|
||||
assert(cpu_isPaused());
|
||||
MB_SetEnabled(enabled);
|
||||
timing_reinitializeAudio();
|
||||
return MB_ISEnabled();
|
||||
}
|
||||
|
||||
|
|
|
@ -177,9 +177,7 @@
|
|||
[self.altSliderLabel setStringValue:[NSString stringWithFormat:@"%.0f%%", value*100]];
|
||||
}
|
||||
|
||||
#warning HACK TODO FIXME ... refactor timing stuff
|
||||
timing_toggle_cpu_speed();
|
||||
timing_toggle_cpu_speed();
|
||||
timing_initialize();
|
||||
|
||||
[self _savePrefs];
|
||||
}
|
||||
|
@ -198,9 +196,7 @@
|
|||
cpu_altscale_factor = ([maxButton state] == NSOnState) ? CPU_SCALE_FASTEST : [self.altSlider doubleValue];
|
||||
}
|
||||
|
||||
#warning HACK TODO FIXME ... refactor timing stuff
|
||||
timing_toggle_cpu_speed();
|
||||
timing_toggle_cpu_speed();
|
||||
timing_initialize();
|
||||
|
||||
[self _savePrefs];
|
||||
}
|
||||
|
|
|
@ -97,7 +97,9 @@
|
|||
|
||||
- (IBAction)toggleCPUSpeed:(id)sender
|
||||
{
|
||||
timing_toggle_cpu_speed();
|
||||
cpu_pause();
|
||||
timing_toggleCPUSpeed();
|
||||
cpu_resume();
|
||||
}
|
||||
|
||||
- (IBAction)togglePause:(id)sender
|
||||
|
@ -117,7 +119,7 @@
|
|||
if (paused)
|
||||
{
|
||||
[[self pauseMenuItem] setTitle:@"Resume Emulation"];
|
||||
pthread_mutex_lock(&interface_mutex);
|
||||
cpu_pause();
|
||||
#ifdef AUDIO_ENABLED
|
||||
SoundSystemPause();
|
||||
#endif
|
||||
|
@ -128,7 +130,7 @@
|
|||
#ifdef AUDIO_ENABLED
|
||||
SoundSystemUnpause();
|
||||
#endif
|
||||
pthread_mutex_unlock(&interface_mutex);
|
||||
cpu_resume();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1689,11 +1689,12 @@ static void MB_DSUninit()
|
|||
void MB_Initialize()
|
||||
{
|
||||
#ifdef APPLE2IX
|
||||
assert(pthread_self() == cpu_thread_id);
|
||||
memset(SSI263Voice, 0x0, sizeof(AudioBuffer_s)*MAX_VOICES);
|
||||
#endif
|
||||
if (g_bDisableDirectSoundMockingboard)
|
||||
{
|
||||
MockingboardVoice->bMute = true;
|
||||
//MockingboardVoice->bMute = true;
|
||||
g_SoundcardType = CT_Empty;
|
||||
}
|
||||
else
|
||||
|
@ -1745,6 +1746,7 @@ void MB_Reinitialize()
|
|||
|
||||
void MB_Destroy()
|
||||
{
|
||||
assert(pthread_self() == cpu_thread_id);
|
||||
MB_DSUninit();
|
||||
|
||||
for(int i=0; i<NUM_VOICES; i++)
|
||||
|
@ -1757,6 +1759,10 @@ void MB_Destroy()
|
|||
}
|
||||
}
|
||||
|
||||
void MB_SetEnabled(bool enabled) {
|
||||
g_bDisableDirectSoundMockingboard = true;
|
||||
}
|
||||
|
||||
bool MB_ISEnabled(void) {
|
||||
return (MockingboardVoice != NULL);
|
||||
}
|
||||
|
|
|
@ -98,6 +98,7 @@ extern uint32_t g_uTimer1IrqCount; // DEBUG
|
|||
void MB_Initialize();
|
||||
void MB_Reinitialize();
|
||||
void MB_Destroy();
|
||||
void MB_SetEnabled(bool enabled);
|
||||
bool MB_ISEnabled(void);
|
||||
void MB_Reset();
|
||||
void MB_InitializeIO(char *pCxRomPeripheral, unsigned int uSlot4, unsigned int uSlot5);
|
||||
|
|
|
@ -61,6 +61,7 @@ void audio_destroySoundBuffer(INOUT AudioBuffer_s **audioBuffer) {
|
|||
}
|
||||
|
||||
bool audio_init(void) {
|
||||
assert(pthread_self() == cpu_thread_id);
|
||||
if (audio_isAvailable) {
|
||||
return true;
|
||||
}
|
||||
|
@ -88,6 +89,7 @@ bool audio_init(void) {
|
|||
}
|
||||
|
||||
void audio_shutdown(void) {
|
||||
assert(pthread_self() == cpu_thread_id);
|
||||
if (!audio_isAvailable) {
|
||||
return;
|
||||
}
|
||||
|
@ -110,17 +112,7 @@ void audio_resume(void) {
|
|||
}
|
||||
|
||||
void audio_setLatency(float latencySecs) {
|
||||
#warning FIXME TODO ... dynamically changing buffer size is really heavyweight since this buffer size percolates up to speaker/mockingboard allocations ... ugh we will live with this for now ... pumping this will be a great test for Valgrind heap profiling =P
|
||||
speaker_destroy();
|
||||
MB_Destroy();
|
||||
audio_shutdown();
|
||||
|
||||
audio_latencySecs = latencySecs;
|
||||
|
||||
audio_init();
|
||||
speaker_init();
|
||||
MB_Initialize();
|
||||
#warning FIXME TODO ... also ugh we should have a registration mechanism of audio devices so we don't need to explicitly list them here, suggest something similar to the glnode registration stuff in video
|
||||
}
|
||||
|
||||
float audio_getLatency(void) {
|
||||
|
|
|
@ -324,6 +324,7 @@ static unsigned int _submit_samples_buffer(const unsigned long num_channel_sampl
|
|||
// speaker public API functions
|
||||
|
||||
void speaker_destroy(void) {
|
||||
assert(pthread_self() == cpu_thread_id);
|
||||
speaker_isAvailable = false;
|
||||
audio_destroySoundBuffer(&speakerBuffer);
|
||||
FREE(samples_buffer);
|
||||
|
@ -331,6 +332,8 @@ void speaker_destroy(void) {
|
|||
}
|
||||
|
||||
void speaker_init(void) {
|
||||
assert(pthread_self() == cpu_thread_id);
|
||||
|
||||
long err = 0;
|
||||
speaker_isAvailable = false;
|
||||
do {
|
||||
|
@ -479,9 +482,11 @@ GLUE_C_READ(speaker_toggle)
|
|||
speaker_accessed_since_last_flush = true;
|
||||
speaker_recently_active = true;
|
||||
|
||||
if (timing_should_auto_adjust_speed()) {
|
||||
#if !defined(MOBILE_DEVICE)
|
||||
if (timing_shouldAutoAdjustSpeed()) {
|
||||
is_fullspeed = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (speaker_isAvailable) {
|
||||
_speaker_update(/*toggled:true*/);
|
||||
|
|
|
@ -160,7 +160,6 @@ static void _interface_plotMessageCentered(uint8_t *fb, int fb_cols, int fb_rows
|
|||
|
||||
static struct stat statbuf = { 0 };
|
||||
static int altdrive = 0;
|
||||
bool in_interface = false;
|
||||
|
||||
void video_plotchar(const int col, const int row, const interface_colorscheme_t cs, const uint8_t c) {
|
||||
unsigned int off = row * SCANWIDTH * FONT_HEIGHT_PIXELS + col * FONT80_WIDTH_PIXELS + _INTERPOLATED_PIXEL_ADJUSTMENT_PRE;
|
||||
|
@ -1547,11 +1546,7 @@ void c_interface_keyboard_layout()
|
|||
|
||||
static void *interface_thread(void *current_key)
|
||||
{
|
||||
pthread_mutex_lock(&interface_mutex);
|
||||
#ifdef AUDIO_ENABLED
|
||||
audio_pause();
|
||||
#endif
|
||||
in_interface = true;
|
||||
cpu_pause();
|
||||
|
||||
switch ((__SWORD_TYPE)current_key) {
|
||||
case kF1:
|
||||
|
@ -1592,11 +1587,7 @@ static void *interface_thread(void *current_key)
|
|||
break;
|
||||
}
|
||||
|
||||
#ifdef AUDIO_ENABLED
|
||||
audio_resume();
|
||||
#endif
|
||||
pthread_mutex_unlock(&interface_mutex);
|
||||
in_interface = false;
|
||||
cpu_resume();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ typedef enum interface_colorscheme_t {
|
|||
} interface_colorscheme_t;
|
||||
|
||||
#ifdef INTERFACE_CLASSIC
|
||||
extern bool in_interface;
|
||||
void video_plotchar(int col, int row, interface_colorscheme_t cs, uint8_t c);
|
||||
void c_interface_begin(int current_key);
|
||||
void c_interface_print(int x, int y, const interface_colorscheme_t cs, const char *s);
|
||||
|
|
20
src/keys.c
20
src/keys.c
|
@ -234,7 +234,7 @@ void c_keys_handle_input(int scancode, int pressed, int is_cooked)
|
|||
|
||||
if ((next_key >= 0)
|
||||
#ifdef INTERFACE_CLASSIC
|
||||
&& !in_interface
|
||||
&& !cpu_isPaused()
|
||||
#endif
|
||||
)
|
||||
{
|
||||
|
@ -252,7 +252,9 @@ void c_keys_handle_input(int scancode, int pressed, int is_cooked)
|
|||
#ifdef INTERFACE_CLASSIC
|
||||
if (current_key == kF9)
|
||||
{
|
||||
timing_toggle_cpu_speed();
|
||||
cpu_pause();
|
||||
timing_toggleCPUSpeed();
|
||||
cpu_resume();
|
||||
if (video_backend->animation_showCPUSpeed) {
|
||||
video_backend->animation_showCPUSpeed();
|
||||
}
|
||||
|
@ -287,9 +289,10 @@ void c_keys_handle_input(int scancode, int pressed, int is_cooked)
|
|||
if (video_backend->animation_showCPUSpeed) {
|
||||
video_backend->animation_showCPUSpeed();
|
||||
}
|
||||
#warning HACK TODO FIXME ... refactor timing stuff
|
||||
timing_toggle_cpu_speed();
|
||||
timing_toggle_cpu_speed();
|
||||
|
||||
cpu_pause();
|
||||
timing_initialize();
|
||||
cpu_resume();
|
||||
break;
|
||||
}
|
||||
if (current_key == kF4) {
|
||||
|
@ -316,9 +319,10 @@ void c_keys_handle_input(int scancode, int pressed, int is_cooked)
|
|||
if (video_backend->animation_showCPUSpeed) {
|
||||
video_backend->animation_showCPUSpeed();
|
||||
}
|
||||
#warning HACK TODO FIXME ... refactor timing stuff
|
||||
timing_toggle_cpu_speed();
|
||||
timing_toggle_cpu_speed();
|
||||
|
||||
cpu_pause();
|
||||
timing_initialize();
|
||||
cpu_resume();
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -40,6 +40,11 @@ static unsigned int stepping_timeout = 0;
|
|||
|
||||
volatile bool is_debugging = false;
|
||||
|
||||
extern pthread_mutex_t interface_mutex;
|
||||
extern pthread_cond_t cpu_thread_cond;
|
||||
extern pthread_cond_t dbg_thread_cond;
|
||||
#warning ^^^ HACK FIXME TODO ... debugger should not have raw access to mutex variables
|
||||
|
||||
#define BUF_X DEBUGGER_BUF_X
|
||||
#define BUF_Y DEBUGGER_BUF_Y
|
||||
#define SCREEN_X 81 // 80col + 1
|
||||
|
|
130
src/timing.c
130
src/timing.c
|
@ -42,6 +42,16 @@
|
|||
|
||||
#define DISK_MOTOR_QUIET_NSECS 2000000
|
||||
|
||||
#define _LOCK_CPU_THREAD() \
|
||||
if (pthread_self() != cpu_thread_id) { \
|
||||
pthread_mutex_lock(&interface_mutex); \
|
||||
}
|
||||
|
||||
#define _UNLOCK_CPU_THREAD() \
|
||||
if (pthread_self() != cpu_thread_id) { \
|
||||
pthread_mutex_unlock(&interface_mutex); \
|
||||
}
|
||||
|
||||
// VBL constants?
|
||||
#define uCyclesPerLine 65 // 25 cycles of HBL & 40 cycles of HBL'
|
||||
#define uVisibleLinesPerFrame (64*3) // 192
|
||||
|
@ -59,8 +69,9 @@ static unsigned int g_dwCyclesThisFrame = 0;
|
|||
|
||||
// scaling and speed adjustments
|
||||
#if MOBILE_DEVICE
|
||||
static bool auto_adjust_speed = false;
|
||||
static bool is_paused = true;
|
||||
#else
|
||||
static bool is_paused = false;
|
||||
static bool auto_adjust_speed = true;
|
||||
#endif
|
||||
double cpu_scale_factor = 1.0;
|
||||
|
@ -69,7 +80,8 @@ bool is_fullspeed = false;
|
|||
bool alt_speed_enabled = false;
|
||||
|
||||
// misc
|
||||
volatile uint8_t emul_reinitialize = 0;
|
||||
volatile uint8_t emul_reinitialize = 1;
|
||||
unsigned long emul_reinitialize_audio = 1UL;
|
||||
pthread_t cpu_thread_id = 0;
|
||||
pthread_mutex_t interface_mutex = { 0 };
|
||||
pthread_cond_t dbg_thread_cond = PTHREAD_COND_INITIALIZER;
|
||||
|
@ -145,67 +157,77 @@ static void _timing_initialize(double scale) {
|
|||
#endif
|
||||
}
|
||||
|
||||
static inline void _lock_gui_thread(void) {
|
||||
if (pthread_self() != cpu_thread_id) {
|
||||
pthread_mutex_lock(&interface_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void _unlock_gui_thread(void) {
|
||||
if (pthread_self() != cpu_thread_id) {
|
||||
pthread_mutex_unlock(&interface_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
void timing_initialize(void) {
|
||||
_lock_gui_thread();
|
||||
assert(cpu_isPaused() || (pthread_self() == cpu_thread_id));
|
||||
_timing_initialize(alt_speed_enabled ? cpu_altscale_factor : cpu_scale_factor);
|
||||
_unlock_gui_thread();
|
||||
}
|
||||
|
||||
void timing_toggle_cpu_speed(void) {
|
||||
_lock_gui_thread();
|
||||
void timing_toggleCPUSpeed(void) {
|
||||
assert(cpu_isPaused() || (pthread_self() == cpu_thread_id));
|
||||
alt_speed_enabled = !alt_speed_enabled;
|
||||
timing_initialize();
|
||||
_unlock_gui_thread();
|
||||
}
|
||||
|
||||
void timing_set_auto_adjust_speed(bool auto_adjust) {
|
||||
_lock_gui_thread();
|
||||
auto_adjust_speed = auto_adjust;
|
||||
timing_initialize();
|
||||
_unlock_gui_thread();
|
||||
void timing_reinitializeAudio(void) {
|
||||
assert(cpu_isPaused() || (pthread_self() == cpu_thread_id));
|
||||
__sync_fetch_and_or(&emul_reinitialize_audio, 1UL);
|
||||
}
|
||||
|
||||
void cpu_pause(void) {
|
||||
_lock_gui_thread();
|
||||
_LOCK_CPU_THREAD();
|
||||
#ifdef AUDIO_ENABLED
|
||||
audio_pause();
|
||||
#endif
|
||||
is_paused = true;
|
||||
}
|
||||
|
||||
static void _cpu_thread_really_start(void) {
|
||||
int err = 0;
|
||||
if ( (err = pthread_cond_signal(&cpu_thread_cond)) ) {
|
||||
ERRLOG("pthread_cond_signal : %d", err);
|
||||
}
|
||||
}
|
||||
|
||||
void cpu_resume(void) {
|
||||
assert(cpu_isPaused());
|
||||
is_paused = false;
|
||||
|
||||
static pthread_once_t onceToken = PTHREAD_ONCE_INIT;
|
||||
if (onceToken == PTHREAD_ONCE_INIT) {
|
||||
int err = 0;
|
||||
if ( (err = pthread_once(&onceToken, _cpu_thread_really_start)) ) {
|
||||
ERRLOG("pthread_once : %d", err);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef AUDIO_ENABLED
|
||||
audio_resume();
|
||||
_unlock_gui_thread();
|
||||
#endif
|
||||
|
||||
_UNLOCK_CPU_THREAD();
|
||||
}
|
||||
|
||||
bool timing_should_auto_adjust_speed(void) {
|
||||
bool cpu_isPaused(void) {
|
||||
return is_paused;
|
||||
}
|
||||
|
||||
#if !MOBILE_DEVICE
|
||||
bool timing_shouldAutoAdjustSpeed(void) {
|
||||
double speed = alt_speed_enabled ? cpu_altscale_factor : cpu_scale_factor;
|
||||
return auto_adjust_speed && (speed < CPU_SCALE_FASTEST);
|
||||
}
|
||||
#endif
|
||||
|
||||
void *cpu_thread(void *dummyptr) {
|
||||
|
||||
assert(pthread_self() == cpu_thread_id);
|
||||
|
||||
#ifdef AUDIO_ENABLED
|
||||
audio_init();
|
||||
speaker_init();
|
||||
MB_Initialize();
|
||||
#endif
|
||||
|
||||
reinitialize();
|
||||
LOG("cpu_thread : initialized...");
|
||||
|
||||
struct timespec deltat;
|
||||
#if !MOBILE_DEVICE
|
||||
struct timespec disk_motor_time;
|
||||
#endif
|
||||
struct timespec t0; // the target timer
|
||||
struct timespec ti, tj; // actual time samples
|
||||
bool negative = false;
|
||||
|
@ -221,13 +243,37 @@ void *cpu_thread(void *dummyptr) {
|
|||
unsigned int dbg_cycles_executed = 0;
|
||||
#endif
|
||||
|
||||
#if !TESTING
|
||||
pthread_mutex_lock(&interface_mutex);
|
||||
int err = 0;
|
||||
LOG("cpu_thread : waiting for splash screen completion...");
|
||||
pthread_cond_wait(&cpu_thread_cond, &interface_mutex);
|
||||
pthread_mutex_unlock(&interface_mutex);
|
||||
LOG("cpu_thread : starting...");
|
||||
#endif
|
||||
|
||||
do
|
||||
{
|
||||
#ifdef AUDIO_ENABLED
|
||||
bool reinit_audio = __sync_fetch_and_and(&emul_reinitialize_audio, 0UL);
|
||||
if (reinit_audio) {
|
||||
speaker_destroy();
|
||||
MB_Destroy();
|
||||
audio_shutdown();
|
||||
|
||||
audio_init();
|
||||
speaker_init();
|
||||
MB_Initialize();
|
||||
}
|
||||
#endif
|
||||
if (emul_reinitialize) {
|
||||
reinitialize();
|
||||
}
|
||||
|
||||
LOG("cpu_thread : begin main loop ...");
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &t0);
|
||||
|
||||
emul_reinitialize = 1;
|
||||
do {
|
||||
// -LOCK----------------------------------------------------------------------------------------- SAMPLE ti
|
||||
pthread_mutex_lock(&interface_mutex);
|
||||
|
@ -321,7 +367,8 @@ void *cpu_thread(void *dummyptr) {
|
|||
pthread_mutex_unlock(&interface_mutex);
|
||||
// -UNLOCK--------------------------------------------------------------------------------------- SAMPLE tj
|
||||
|
||||
if (timing_should_auto_adjust_speed()) {
|
||||
#if !MOBILE_DEVICE
|
||||
if (timing_shouldAutoAdjustSpeed()) {
|
||||
disk_motor_time = timespec_diff(disk6.motor_time, tj, &negative);
|
||||
assert(!negative);
|
||||
if (!is_fullspeed &&
|
||||
|
@ -334,6 +381,7 @@ void *cpu_thread(void *dummyptr) {
|
|||
_timing_initialize(CPU_SCALE_FASTEST);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!is_fullspeed) {
|
||||
deltat = timespec_diff(ti, tj, &negative);
|
||||
|
@ -384,7 +432,8 @@ void *cpu_thread(void *dummyptr) {
|
|||
#endif
|
||||
}
|
||||
|
||||
if (timing_should_auto_adjust_speed()) {
|
||||
#if !MOBILE_DEVICE
|
||||
if (timing_shouldAutoAdjustSpeed()) {
|
||||
if (is_fullspeed && (
|
||||
#ifdef AUDIO_ENABLED
|
||||
speaker_isActive() ||
|
||||
|
@ -398,11 +447,16 @@ void *cpu_thread(void *dummyptr) {
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (UNLIKELY(emul_reinitialize)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (UNLIKELY(emul_reinitialize_audio)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (UNLIKELY(emulator_shutting_down)) {
|
||||
break;
|
||||
}
|
||||
|
@ -411,8 +465,6 @@ void *cpu_thread(void *dummyptr) {
|
|||
if (UNLIKELY(emulator_shutting_down)) {
|
||||
break;
|
||||
}
|
||||
|
||||
reinitialize();
|
||||
} while (1);
|
||||
|
||||
#ifdef AUDIO_ENABLED
|
||||
|
|
26
src/timing.h
26
src/timing.h
|
@ -62,10 +62,7 @@ extern double cpu_altscale_factor; // scale factor #2
|
|||
extern bool is_fullspeed; // emulation in full native speed?
|
||||
extern bool alt_speed_enabled;
|
||||
|
||||
extern pthread_t cpu_thread_id;
|
||||
extern pthread_mutex_t interface_mutex;
|
||||
extern pthread_cond_t cpu_thread_cond;
|
||||
extern pthread_cond_t dbg_thread_cond;
|
||||
extern READONLY pthread_t cpu_thread_id;
|
||||
|
||||
/*
|
||||
* calculate the difference between two timespec structures
|
||||
|
@ -75,23 +72,25 @@ struct timespec timespec_diff(struct timespec start, struct timespec end, bool *
|
|||
/*
|
||||
* toggles CPU speed between configured values
|
||||
*/
|
||||
void timing_toggle_cpu_speed(void);
|
||||
|
||||
/*
|
||||
* (dis)allow automatic adjusting of CPU speed between presently configured and max (when loading disk images).
|
||||
*/
|
||||
void timing_set_auto_adjust_speed(bool auto_adjust);
|
||||
void timing_toggleCPUSpeed(void);
|
||||
|
||||
#if !defined(MOBILE_DEVICE)
|
||||
/*
|
||||
* check whether automatic adjusting of CPU speed is configured.
|
||||
*/
|
||||
bool timing_should_auto_adjust_speed(void);
|
||||
bool timing_shouldAutoAdjustSpeed(void);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* initialize timing
|
||||
*/
|
||||
void timing_initialize(void);
|
||||
|
||||
/*
|
||||
* force audio reinitialization
|
||||
*/
|
||||
void timing_reinitializeAudio(void);
|
||||
|
||||
/*
|
||||
* timing/CPU thread entry point
|
||||
*/
|
||||
|
@ -107,6 +106,11 @@ void cpu_pause(void);
|
|||
*/
|
||||
void cpu_resume(void);
|
||||
|
||||
/*
|
||||
* Is the CPU paused?
|
||||
*/
|
||||
bool cpu_isPaused(void);
|
||||
|
||||
/*
|
||||
* checkpoints current cycle count and updates total (for timing-dependent I/O)
|
||||
*/
|
||||
|
|
|
@ -185,11 +185,11 @@ static inline void _screen_to_menu(float x, float y, OUTPARM int *col, OUTPARM i
|
|||
*row = 0;
|
||||
}
|
||||
|
||||
LOG("SCREEN TO MENU : menuX:%d menuXMax:%d menuW:%d keyW:%d ... scrn:(%f,%f)->kybd:(%d,%d)", touchport.topLeftX, touchport.topLeftXMax, touchport.width, keyW, x, y, *col, *row);
|
||||
//LOG("SCREEN TO MENU : menuX:%d menuXMax:%d menuW:%d keyW:%d ... scrn:(%f,%f)->kybd:(%d,%d)", touchport.topLeftX, touchport.topLeftXMax, touchport.width, keyW, x, y, *col, *row);
|
||||
}
|
||||
|
||||
static void _increase_cpu_speed(void) {
|
||||
pthread_mutex_lock(&interface_mutex);
|
||||
cpu_pause();
|
||||
|
||||
int percent_scale = (int)round(cpu_scale_factor * 100.0);
|
||||
if (percent_scale >= 100) {
|
||||
|
@ -209,15 +209,13 @@ static void _increase_cpu_speed(void) {
|
|||
video_backend->animation_showCPUSpeed();
|
||||
}
|
||||
|
||||
#warning HACK TODO FIXME ... refactor timing stuff
|
||||
timing_toggle_cpu_speed();
|
||||
timing_toggle_cpu_speed();
|
||||
timing_initialize();
|
||||
|
||||
pthread_mutex_unlock(&interface_mutex);
|
||||
cpu_resume();
|
||||
}
|
||||
|
||||
void _decrease_cpu_speed(void) {
|
||||
pthread_mutex_lock(&interface_mutex);
|
||||
cpu_pause();
|
||||
|
||||
int percent_scale = (int)round(cpu_scale_factor * 100.0);
|
||||
if (cpu_scale_factor == CPU_SCALE_FASTEST) {
|
||||
|
@ -242,11 +240,9 @@ void _decrease_cpu_speed(void) {
|
|||
video_backend->animation_showCPUSpeed();
|
||||
}
|
||||
|
||||
#warning HACK TODO FIXME ... refactor timing stuff
|
||||
timing_toggle_cpu_speed();
|
||||
timing_toggle_cpu_speed();
|
||||
timing_initialize();
|
||||
|
||||
pthread_mutex_unlock(&interface_mutex);
|
||||
cpu_resume();
|
||||
}
|
||||
|
||||
static inline bool _sprout_menu(float x, float y) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user