231 lines
5.6 KiB
C
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 */
|
|
|