/* * 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 2016 Aaron Culliney * */ #ifndef _DISPLAY_H_ #define _DISPLAY_H_ #if USE_RGBA4444 #error HACK FIXME TODO : 2018/09/23 currently untested # define PIXEL_TYPE uint16_t # define MAX_SATURATION 0xf # define SHIFT_R 12 # define SHIFT_G 8 # define SHIFT_B 4 # define SHIFT_A 0 # define RGB_MASK 0xFFF0 #else // assuming RGBA8888 ... # define PIXEL_TYPE uint32_t # define MAX_SATURATION 0xff # define SHIFT_R 0 # define SHIFT_G 8 # define SHIFT_B 16 # define SHIFT_A 24 # define RGB_MASK 0xFFFFFF #endif #define PIXEL_STRIDE (sizeof(PIXEL_TYPE)) /* * Scanline data */ typedef struct scan_data_t { uint8_t *scanline; // CYCLES_VIS<<1 == 80 uint32_t softswitches; unsigned int scanrow; // 0 >= x < 192 unsigned int scancol; // 0 > x <= 80 unsigned int scanend; // 0 >= x < 80 } scan_data_t; #define IDX_BLACK 0x00 // 0000 #define IDX_MAGENTA 0x01 // 0001 #define IDX_DARKBLUE 0x02 // 0010 #define IDX_PURPLE 0x03 // 0011 - HIRES40 #define IDX_DARKGREEN 0x04 // 0100 #define IDX_DARKGREY 0x05 // 0101 #define IDX_MEDBLUE 0x06 // 0110 - HIRES40 #define IDX_LIGHTBLUE 0x07 // 0111 #define IDX_BROWN 0x08 // 1000 #define IDX_ORANGE 0x09 // 1001 - HIRES40 #define IDX_LIGHTGREY 0x0a // 1010 #define IDX_PINK 0x0b // 1011 #define IDX_GREEN 0x0c // 1100 - HIRES40 #define IDX_YELLOW 0x0d // 1101 #define IDX_AQUA 0x0e // 1110 #define IDX_WHITE 0x0f // 1111 // Colors duplicated and muted at this offset #define IDX_LUMINANCE_HALF 0x40 // Interface colors #define IDX_ICOLOR_R 0x21 #define IDX_ICOLOR_G 0x22 #define IDX_ICOLOR_B 0x23 typedef enum interface_colorscheme_t { GREEN_ON_BLACK = 0, GREEN_ON_BLUE, RED_ON_BLACK, BLUE_ON_BLACK, WHITE_ON_BLACK, // WARNING : changing here requires updating display.c ncvideo.c BLACK_ON_RED, // 16 COLORS -- ncvideo.c BLACK_ON_BLACK, BLACK_ON_MAGENTA, BLACK_ON_DARKBLUE, BLACK_ON_PURPLE, BLACK_ON_DARKGREEN, BLACK_ON_DARKGREY, BLACK_ON_MEDBLUE, BLACK_ON_LIGHTBLUE, BLACK_ON_BROWN, BLACK_ON_ORANGE, BLACK_ON_LIGHTGREY, BLACK_ON_PINK, BLACK_ON_GREEN, BLACK_ON_YELLOW, BLACK_ON_AQUA, BLACK_ON_WHITE, NUM_INTERFACE_COLORSCHEMES, COLOR16 = 0x80, INVALID_COLORSCHEME = 0xFF, } interface_colorscheme_t; /* * Color options */ typedef enum color_mode_t { // original modes ... COLOR_MODE_MONO = 0, COLOR_MODE_COLOR, COLOR_MODE_INTERP, // NTSC color modes ... COLOR_MODE_COLOR_MONITOR, COLOR_MODE_MONO_TV, COLOR_MODE_COLOR_TV, NUM_COLOROPTS, } color_mode_t; #define COLOR_MODE_DEFAULT COLOR_MODE_COLOR_TV static inline color_mode_t getColorMode(long lVal) { if (lVal < 0 || lVal >= NUM_COLOROPTS) { lVal = COLOR_MODE_DEFAULT; } return (color_mode_t)lVal; } typedef enum mono_mode_t { MONO_MODE_BW = 0, MONO_MODE_GREEN, NUM_MONOOPTS, } mono_mode_t; #define MONO_MODE_DEFAULT MONO_MODE_BW static inline mono_mode_t getMonoMode(long lVal) { if (lVal < 0 || lVal >= NUM_MONOOPTS) { lVal = MONO_MODE_DEFAULT; } return (mono_mode_t)lVal; } /* * Font mode */ typedef enum font_mode_t { FONT_MODE_NORMAL=0, FONT_MODE_MOUSETEXT, FONT_MODE_INVERSE, FONT_MODE_FLASH, NUM_FONT_MODES, } font_mode_t; /* * Graphics mode */ typedef enum drawpage_mode_t { DRAWPAGE_TEXT = 0, DRAWPAGE_HIRES, NUM_DRAWPAGE_MODES, } drawpage_mode_t; /* * Set the font used by the display. QTY characters are loaded starting * with FIRST, from DATA. DATA contains 8 bytes for each character, each * byte representing a row (top-to-bottom). The row byte contains 7 * pixels in little-endian format. * * MODE selects the colors to use * * 0 - Normal text * 1 - MouseText (usually treat as Normal) * 2 - Inverse * 3 - Flash * * The extra MouseText mode is in case we want to emulate certain RGB * adaptors which color normal text and MouseText differently. I had one * once for a //c. */ void display_loadFont(const uint8_t start, const uint8_t qty, const uint8_t *data, font_mode_t mode); /* * Toggles FLASHing text between NORMAL and INVERSE character sets. */ void display_flashText(void); // ---------------------------------------------------------------------------- #if INTERFACE_CLASSIC /* * Plot character into interface framebuffer. * - This should only be called from video backends/interface */ void display_plotChar(const uint8_t col, const uint8_t row, const interface_colorscheme_t cs, const uint8_t c); /* * Plot NULL_terminated string into interface framebuffer. * - See display_plotChar() ... */ void display_plotLine(const uint8_t col, const uint8_t row, const interface_colorscheme_t cs, const char *message); #endif /* * Plot multi-line message into given framebuffer (not the interface framebuffer). * - See display_plotChar() ... */ void display_plotMessage(PIXEL_TYPE *fb, const interface_colorscheme_t cs, const char *message, const uint8_t message_cols, const uint8_t message_rows); /* * Get video line offset for TEXT mode row */ uint16_t display_getVideoLineOffset(uint8_t txtRow); // ---------------------------------------------------------------------------- // video generation /* * Called by video backend to get the current complete staging framebuffer. * - Framebuffer is exactly SCANWIDTH*SCANHEIGHT*sizeof(PIXEL_TYPE) */ PIXEL_TYPE *display_getCurrentFramebuffer(void) CALL_ON_UI_THREAD; /* * Handler for toggling text flashing */ void display_flashText(void) CALL_ON_CPU_THREAD; /* * Handler for video scanner scanline completion */ void display_flushScanline(scan_data_t *scandata) CALL_ON_CPU_THREAD; /* * Handler called when entire frame is complete */ void display_frameComplete(void) CALL_ON_CPU_THREAD; #if TESTING /* * Wait for frame complete and return staging framebuffer. */ PIXEL_TYPE *display_waitForNextCompleteFramebuffer(void); #endif // ---------------------------------------------------------------------------- #define TEXT_ROWS 24 #define BEGIN_MIX 20 #define TEXT_COLS 40 #define TEXT80_COLS (TEXT_COLS*2) #define FONT_HEIGHT_PIXELS 16 #define FONT_WIDTH_PIXELS 14 #define FONT80_WIDTH_PIXELS (FONT_WIDTH_PIXELS>>1) #define _SCANWIDTH (TEXT_COLS * FONT_WIDTH_PIXELS) // 560 #define SCANHEIGHT (TEXT_ROWS * FONT_HEIGHT_PIXELS) // 384 // Extra bytes on each side of internal framebuffer to allow overdraw for NTSC modes #define _FB_OFF 4 #define _FB_WIDTH_EXTRA (_FB_OFF<<1) #define SCANWIDTH (_SCANWIDTH+_FB_WIDTH_EXTRA) // 568 #define FONT_GLYPH_X (7+/*unused*/1) // generated font.c uses a single byte (8bits) per font glyph line #define FONT_GLYPH_Y (FONT_HEIGHT_PIXELS>>1) // ... 8 bytes total for whole glyph #define FONT_GLYPH_SCALE_Y (FONT_HEIGHT_PIXELS/FONT_GLYPH_Y) // FIXME NOTE : implicit 2x scaling in display.c ... #define MOUSETEXT_BEGIN 0x80 // offset + 0x20 length #define MOUSETEXT_RETURN (MOUSETEXT_BEGIN+0x0d) #define MOUSETEXT_UP (MOUSETEXT_BEGIN+0x0b) #define MOUSETEXT_LEFT (MOUSETEXT_BEGIN+0x08) #define MOUSETEXT_RIGHT (MOUSETEXT_BEGIN+0x15) #define MOUSETEXT_DOWN (MOUSETEXT_BEGIN+0x0a) #define MOUSETEXT_OPENAPPLE (MOUSETEXT_BEGIN+0x01) #define MOUSETEXT_CLOSEDAPPLE (MOUSETEXT_BEGIN+0x00) #define MOUSETEXT_HOURGLASS (MOUSETEXT_BEGIN+0x03) #define MOUSETEXT_CHECKMARK (MOUSETEXT_BEGIN+0x04) #define MOUSETEXT_CURSOR0 (MOUSETEXT_BEGIN+0x16) #define MOUSETEXT_CURSOR1 (MOUSETEXT_BEGIN+0x17) #define ICONTEXT_BEGIN 0xA0 // offset + 0x22 length #define ICONTEXT_MENU_BEGIN ICONTEXT_BEGIN #define ICONTEXT_MENU_END (ICONTEXT_MENU_BEGIN+0x0A) #define ICONTEXT_DISK_UL (ICONTEXT_BEGIN+0x0B) #define ICONTEXT_DISK_UR (ICONTEXT_BEGIN+0x0C) #define ICONTEXT_DISK_LL (ICONTEXT_BEGIN+0x0D) #define ICONTEXT_DISK_LR (ICONTEXT_BEGIN+0x0E) #define ICONTEXT_UNLOCK (ICONTEXT_BEGIN+0x0F) #define ICONTEXT_GOTO (ICONTEXT_BEGIN+0x10) #define ICONTEXT_SPACE_VISUAL (ICONTEXT_BEGIN+0x11) #define ICONTEXT_MENU_SPROUT (MOUSETEXT_BEGIN+0x1B) #define ICONTEXT_MENU_TOUCHJOY (ICONTEXT_BEGIN+0x12) #define ICONTEXT_MENU_TOUCHJOY_KPAD (ICONTEXT_BEGIN+0x18) #define ICONTEXT_KBD_BEGIN (ICONTEXT_BEGIN+0x13) #define ICONTEXT_CTRL (ICONTEXT_KBD_BEGIN+0x00) #define ICONTEXT_LOWERCASE (ICONTEXT_KBD_BEGIN+0x01) #define ICONTEXT_UPPERCASE (ICONTEXT_KBD_BEGIN+0x02) #define ICONTEXT_SHOWALT1 (ICONTEXT_KBD_BEGIN+0x03) #define ICONTEXT_BACKSPACE (ICONTEXT_KBD_BEGIN+0x04) #define ICONTEXT_LEFTSPACE (ICONTEXT_KBD_BEGIN+0x06) #define ICONTEXT_MIDSPACE (ICONTEXT_KBD_BEGIN+0x07) #define ICONTEXT_RIGHTSPACE (ICONTEXT_KBD_BEGIN+0x08) #define ICONTEXT_ESC (ICONTEXT_KBD_BEGIN+0x09) #define ICONTEXT_RETURN_L (ICONTEXT_KBD_BEGIN+0x0A) #define ICONTEXT_RETURN_R (ICONTEXT_KBD_BEGIN+0x0B) #define ICONTEXT_NONACTIONABLE (ICONTEXT_KBD_BEGIN+0x0C) #define ICONTEXT_LEFT_TAB (ICONTEXT_KBD_BEGIN+0x..) #define ICONTEXT_RIGHT_TAB (ICONTEXT_KBD_BEGIN+0x..) /* ---------------------------------- generic graphics globals ---------------------------------- */ /* * font glyph data */ extern const unsigned char ucase_glyphs[0x200]; extern const unsigned char lcase_glyphs[0x100]; extern const unsigned char mousetext_glyphs[0x100]; extern const unsigned char interface_glyphs[88]; #endif // whole file