mirror of
https://github.com/mauiaaron/apple2.git
synced 2025-01-11 14:30:08 +00:00
Provide callback API for end-of-video-frame
This commit is contained in:
parent
9e8a5e2134
commit
ef3944a4dd
@ -2341,8 +2341,11 @@ void MB_StartOfCpuExecute()
|
||||
}
|
||||
|
||||
// Called by ContinueExecution() at the end of every video frame
|
||||
void MB_EndOfVideoFrame()
|
||||
static void MB_EndOfVideoFrame(uint8_t unused)
|
||||
{
|
||||
#if 1 // APPLE2IX
|
||||
(void)unused;
|
||||
#endif
|
||||
if(g_SoundcardType == CT_Empty)
|
||||
return;
|
||||
#if MB_TRACING
|
||||
@ -2616,10 +2619,6 @@ static void mb_prefsChanged(const char *domain) {
|
||||
MB_SetVolumeZeroToTen(goesToTen);
|
||||
}
|
||||
|
||||
static __attribute__((constructor)) void _init_mockingboard(void) {
|
||||
prefs_registerListener(PREF_DOMAIN_AUDIO, &mb_prefsChanged);
|
||||
}
|
||||
|
||||
static bool _sy6522_saveState(StateHelper_s *helper, SY6522 *sy6522) {
|
||||
int fd = helper->fd;
|
||||
|
||||
@ -3396,3 +3395,13 @@ void mb_traceEnd(void) {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void _init_mockingboard(void) {
|
||||
prefs_registerListener(PREF_DOMAIN_AUDIO, &mb_prefsChanged);
|
||||
static video_frame_callback_fn frameCallback = &MB_EndOfVideoFrame;
|
||||
video_registerFrameCallback(&frameCallback);
|
||||
}
|
||||
|
||||
static __attribute__((constructor)) void __init_mockingboard(void) {
|
||||
emulator_registerStartupCallback(CTOR_PRIORITY_EARLY, &_init_mockingboard);
|
||||
}
|
||||
|
@ -105,7 +105,6 @@ void MB_InitializeIO(char *pCxRomPeripheral, unsigned int uSlot4, unsigned in
|
||||
void MB_Mute(void);
|
||||
void MB_Demute(void);
|
||||
void MB_StartOfCpuExecute(void);
|
||||
void MB_EndOfVideoFrame(void);
|
||||
void MB_UpdateCycles(void);
|
||||
SS_CARDTYPE MB_GetSoundcardType(void);
|
||||
void MB_SetSoundcardType(SS_CARDTYPE NewSoundcardType);
|
||||
|
@ -11,6 +11,11 @@
|
||||
|
||||
#include "common.h"
|
||||
|
||||
typedef struct eof_node_s {
|
||||
struct eof_node_s *next;
|
||||
video_frame_callback_fn *cbPtr;
|
||||
} eof_node_s;
|
||||
|
||||
typedef struct backend_node_s {
|
||||
struct backend_node_s *next;
|
||||
long order;
|
||||
@ -19,10 +24,12 @@ typedef struct backend_node_s {
|
||||
|
||||
static bool video_initialized = false;
|
||||
static bool null_backend_running = true;
|
||||
static backend_node_s *head = NULL;
|
||||
static backend_node_s *backends = NULL;
|
||||
static video_backend_s *currentBackend = NULL;
|
||||
static pthread_t render_thread_id = 0;
|
||||
|
||||
static eof_node_s *eofs = NULL;
|
||||
|
||||
static unsigned int cyclesFrameLast = 0;
|
||||
static unsigned int cyclesDirty = CYCLES_FRAME;
|
||||
static unsigned long dirty = 0UL;
|
||||
@ -279,9 +286,10 @@ static void _endOfFrame() {
|
||||
cyclesFrameLast %= CYCLES_FRAME;
|
||||
cycles_video_frame %= CYCLES_FRAME;
|
||||
|
||||
static uint8_t textFlashCounter = 0;
|
||||
// FLASH counter and keyboard auto-strobe mod-16 counter ...
|
||||
static uint8_t textFlashCounter = 0x0;
|
||||
textFlashCounter = (textFlashCounter+1) & 0xf;
|
||||
if (!textFlashCounter) {
|
||||
if (textFlashCounter == 0x0) {
|
||||
video_flashText();
|
||||
if (!(run_args.softswitches & SS_80COL) && (run_args.softswitches & (SS_TEXT|SS_MIXED))) {
|
||||
cyclesFrameLast = 0;
|
||||
@ -290,11 +298,17 @@ static void _endOfFrame() {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO FIXME : modularize these (and moar) handlers for video frame completion
|
||||
MB_EndOfVideoFrame();
|
||||
// run frame completion callbacks ...
|
||||
eof_node_s *p = eofs;
|
||||
while (p) {
|
||||
video_frame_callback_fn cb = *(p->cbPtr);
|
||||
if (cb) {
|
||||
cb(textFlashCounter);
|
||||
}
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
// UtAIIe 3-17 :
|
||||
// - keyboard auto-repeat ...
|
||||
// Also MAYBE TODO UtAIIe 3-17 :
|
||||
// - power-up reset timing ...
|
||||
}
|
||||
|
||||
@ -558,6 +572,31 @@ bool video_loadState(StateHelper_s *helper) {
|
||||
return loaded;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Video frame completion callback registration
|
||||
|
||||
void video_registerFrameCallback(video_frame_callback_fn *cbPtr) {
|
||||
assert(!video_initialized); // backends cannot be registered after we've picked one to use
|
||||
|
||||
eof_node_s *node = MALLOC(sizeof(eof_node_s));
|
||||
assert((uintptr_t)node);
|
||||
node->next = NULL;
|
||||
node->cbPtr = cbPtr;
|
||||
|
||||
eof_node_s *p0 = NULL;
|
||||
eof_node_s *p = eofs;
|
||||
while (p) {
|
||||
p0 = p;
|
||||
p = p->next;
|
||||
}
|
||||
if (p0) {
|
||||
p0->next = node;
|
||||
} else {
|
||||
eofs = node;
|
||||
}
|
||||
node->next = p;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Video backend registration and selection
|
||||
|
||||
@ -571,7 +610,7 @@ void video_registerBackend(video_backend_s *backend, long order) {
|
||||
node->backend = backend;
|
||||
|
||||
backend_node_s *p0 = NULL;
|
||||
backend_node_s *p = head;
|
||||
backend_node_s *p = backends;
|
||||
while (p && (order > p->order)) {
|
||||
p0 = p;
|
||||
p = p->next;
|
||||
@ -579,15 +618,15 @@ void video_registerBackend(video_backend_s *backend, long order) {
|
||||
if (p0) {
|
||||
p0->next = node;
|
||||
} else {
|
||||
head = node;
|
||||
backends = node;
|
||||
}
|
||||
node->next = p;
|
||||
|
||||
currentBackend = head->backend;
|
||||
currentBackend = backends->backend;
|
||||
}
|
||||
|
||||
void video_printBackends(FILE *out) {
|
||||
backend_node_s *p = head;
|
||||
backend_node_s *p = backends;
|
||||
int count = 0;
|
||||
while (p) {
|
||||
const char *name = p->backend->name();
|
||||
@ -605,7 +644,7 @@ void video_chooseBackend(const char *name) {
|
||||
name = _null_backend_name();
|
||||
}
|
||||
|
||||
backend_node_s *p = head;
|
||||
backend_node_s *p = backends;
|
||||
while (p) {
|
||||
const char *bname = p->backend->name();
|
||||
if (strcasecmp(name, bname) == 0) {
|
||||
|
@ -166,6 +166,14 @@ uint16_t video_scannerAddress(OUTPARM bool *ptrIsVBL);
|
||||
*/
|
||||
uint8_t floating_bus(void);
|
||||
|
||||
/*
|
||||
* Video frame completion callbacks
|
||||
*/
|
||||
|
||||
typedef void (*video_frame_callback_fn)(uint8_t textFlashCounter) CALL_ON_CPU_THREAD;
|
||||
|
||||
void video_registerFrameCallback(video_frame_callback_fn *cbPtr);
|
||||
|
||||
#if VIDEO_TRACING
|
||||
void video_scannerTraceBegin(const char *trace_file, unsigned long frameCount);
|
||||
void video_scannerTraceEnd(void);
|
||||
|
Loading…
x
Reference in New Issue
Block a user