apple2ix/src/video/video.h

231 lines
5.6 KiB
C

/*
* Apple // emulator for *ix
*
* This software package is subject to the GNU General Public License
* version 3 or later (your choice) as published by the Free Software
* Foundation.
*
* Copyright 1994 Alexander Jean-Claude Bottema
* Copyright 1995 Stephen Lee
* Copyright 1997, 1998 Aaron Culliney
* Copyright 1998, 1999, 2000 Michael Deutschmann
* Copyright 2013-2015 Aaron Culliney
*
*/
#ifndef A2_VIDEO_H
#define A2_VIDEO_H
/*
* Animation
*/
typedef struct video_animation_s {
#if INTERFACE_TOUCH
// touch HUD functions
void (*animation_showTouchKeyboard)(void);
void (*animation_hideTouchKeyboard)(void);
void (*animation_showTouchJoystick)(void);
void (*animation_hideTouchJoystick)(void);
void (*animation_showTouchMenu)(void);
void (*animation_hideTouchMenu)(void);
#endif
// misc animations
void (*animation_showMessage)(char *message, unsigned int cols, unsigned int rows);
void (*animation_showPaused)(void);
void (*animation_showCPUSpeed)(void);
void (*animation_showDiskChosen)(int drive);
void (*animation_showTrackSector)(int drive, int track, int sect);
} video_animation_s;
/*
* Prepare the video system, converting console to graphics mode, or opening X window, or whatever.
*/
void video_init(void);
/*
* Enters emulator-managed main video loop (if backend rendering system requires it). Currently only used by desktop
* X11 and desktop OpenGL/GLUT.
*/
void video_main_loop(void);
/*
* Shutdown video system. Should only be called on the render thread (unless render thread is in emulator-managed main
* video loop).
*/
void video_shutdown(void);
/*
* Begin a render pass (only for non-emulator-managed main video). This should only be called on the render thread.
*/
void video_render(void) CALL_ON_UI_THREAD;
/*
* Set the render thread ID. Use with caution.
*/
void _video_setRenderThread(pthread_t id);
/*
* Check if the current code is running on render thread.
*/
bool video_isRenderThread(void);
#define A2_DIRTY_FLAG 0x1 // Apple //e video is dirty
#define FB_DIRTY_FLAG 0x2 // Internal framebuffer is dirty
/*
* True if dirty bit(s) are set for flag(s)
*/
bool video_isDirty(unsigned long flags);
/*
* Called primary from VM routines to flag when graphics mode or video memory data changes
*/
void video_setDirty(unsigned long flags);
/*
* Atomically clear dirty bit(s), return previous bit(s) value
*/
unsigned long video_clearDirty(unsigned long flags);
/*
* State save support for video subsystem.
*/
bool video_saveState(StateHelper_s *helper);
/*
* State restore support for video subsystem.
*/
bool video_loadState(StateHelper_s *helper);
/*
* Get current animation driver
*/
video_animation_s *video_getAnimationDriver(void);
// ----------------------------------------------------------------------------
// Video scanner
static inline drawpage_mode_t video_currentMainMode(uint32_t currswitches) {
if (currswitches & SS_TEXT) {
return DRAWPAGE_TEXT;
} else {
if (currswitches & SS_HIRES) {
return DRAWPAGE_HIRES;
} else {
return DRAWPAGE_TEXT; // (LORES)
}
}
}
static inline drawpage_mode_t video_currentMixedMode(uint32_t currswitches) {
if (currswitches & (SS_TEXT|SS_MIXED)) {
return DRAWPAGE_TEXT;
} else {
if (currswitches & SS_HIRES) {
return DRAWPAGE_HIRES;
} else {
return DRAWPAGE_TEXT; // (LORES)
}
}
}
static inline int video_currentPage(uint32_t currswitches) {
// UTAIIe : 5-25
if (currswitches & SS_80STORE) {
return 0;
}
return !!(currswitches & SS_PAGE2);
}
/*
* Update text flashing state
*/
void video_flashText(void);
/*
* Reset video scanner
*/
void video_scannerReset(void);
/*
* Update video scanner position and generate video output
*/
void video_scannerUpdate(void) CALL_ON_CPU_THREAD;
/*
* Get current video scanner address
*/
uint16_t video_scannerAddress(OUTPARM bool *ptrIsVBL);
/*
* Return current video scanner data
*/
uint8_t floating_bus(void);
#if VIDEO_TRACING
void video_scannerTraceBegin(const char *trace_file, unsigned long frameCount);
void video_scannerTraceEnd(void);
void video_scannerTraceCheckpoint(void);
bool video_scannerTraceShouldStop(void);
#endif
// ----------------------------------------------------------------------------
// Video Backend API
typedef struct video_backend_s {
const char *(*name)(void);
void (*init)(void *context);
void (*main_loop)(void);
void (*render)(void);
void (*shutdown)(void);
#if INTERFACE_CLASSIC
// interface plotting callbacks
void (*plotChar)(const uint8_t col, const uint8_t row, const interface_colorscheme_t cs, const uint8_t c);
void (*plotLine)(const uint8_t col, const uint8_t row, const interface_colorscheme_t cs, const char *message);
#endif
void (*flashText)(void);
void (*flushScanline)(scan_data_t *scandata) CALL_ON_CPU_THREAD;
void (*frameComplete)(void) CALL_ON_CPU_THREAD;
video_animation_s *anim;
} video_backend_s;
#if VIDEO_X11
// X11 scaling ...
typedef enum a2_video_mode_t {
VIDEO_FULLSCREEN = 0,
VIDEO_1X,
VIDEO_2X,
NUM_VIDOPTS
} a2_video_mode_t;
extern a2_video_mode_t a2_video_mode;
#endif
enum {
VID_PRIO_GRAPHICS_GL = 10,
VID_PRIO_GRAPHICS_X = 20,
VID_PRIO_TERMINAL = 30,
VID_PRIO_NULL = 100,
};
/*
* Register a video backend at the specific prioritization
*/
void video_registerBackend(video_backend_s *backend, long prio);
void video_printBackends(FILE *out);
void video_chooseBackend(const char *name);
video_backend_s *video_getCurrentBackend(void);
#endif /* !A2_VIDEO_H */