Provide callback API for end-of-video-frame

This commit is contained in:
Aaron Culliney 2019-06-01 07:01:42 -07:00
parent 9e8a5e2134
commit ef3944a4dd
4 changed files with 73 additions and 18 deletions

View File

@ -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);
}

View File

@ -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);

View File

@ -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) {

View File

@ -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);