--- BasiliskII/src/include/video.h 2001/07/03 19:20:47 1.12 +++ BasiliskII/src/include/video.h 2008/01/01 09:40:35 1.17 @@ -1,7 +1,7 @@ /* * video.h - Video/graphics emulation * - * Basilisk II (C) 1997-2001 Christian Bauer + * Basilisk II (C) 1997-2008 Christian Bauer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,6 +27,7 @@ using std::vector; #endif + /* Some of the terminology here is completely frelled. In Basilisk II, a "video mode" refers to a combination of resolution and color depth, and @@ -55,19 +56,7 @@ enum video_depth { VDEPTH_32BIT // "Millions" }; -// For compatibility reasons with older (pre-Display Manager) versions of -// MacOS, the Apple modes must start at 0x80 and be contiguous. Therefore -// we construct an array to map the depth codes to the corresponding Apple -// mode. This array is initialized by video_init_depth_list() which must -// be called by the platform-dependant VideoInit() routine after filling -// the VideoModes array. -extern uint16 apple_mode_for_depth[6]; - -inline uint16 DepthToAppleMode(video_depth depth) -{ - return apple_mode_for_depth[depth]; -} - +// 1, 2, 4 and 8 bit depths use a color palette inline bool IsDirectMode(video_depth depth) { return depth == VDEPTH_16BIT || depth == VDEPTH_32BIT; @@ -101,6 +90,7 @@ inline uint32 TrivialBytesPerRow(uint32 } } + /* You are not completely free in your selection of depth/resolution combinations: @@ -134,8 +124,9 @@ struct video_mode { uint32 x; // X size of screen (pixels) uint32 y; // Y size of screen (pixels) uint32 resolution_id; // Resolution ID (should be >= 0x80 and uniquely identify the sets of modes with the same X/Y size) - uint32 bytes_per_row; // Bytes per row of frame buffer video_depth depth; // Color depth (see definitions above) + uint32 bytes_per_row; // Bytes per row of frame buffer + uint32 user_data; // Free for use by platform-specific code }; inline bool IsDirectMode(const video_mode &mode) @@ -143,22 +134,132 @@ inline bool IsDirectMode(const video_mod return IsDirectMode(mode.depth); } -// List of all supported video modes -extern vector VideoModes; -// Description for one (possibly virtual) monitor -struct monitor_desc { - uint32 mac_frame_base; // Mac frame buffer address - video_mode mode; // Currently selected video mode description +// Mac video driver per-display private variables (opaque) +struct video_locals; + + +// Abstract base class representing one (possibly virtual) monitor +// ("monitor" = rectangular display with a contiguous frame buffer) +class monitor_desc { +public: + monitor_desc(const vector &available_modes, video_depth default_depth, uint32 default_id); + virtual ~monitor_desc() {} + + // Get Mac slot ID number + uint8 get_slot_id(void) const {return slot_id;} + + // Get current Mac frame buffer base address + uint32 get_mac_frame_base(void) const {return mac_frame_base;} + + // Set Mac frame buffer base address (called from switch_to_mode()) + void set_mac_frame_base(uint32 base) {mac_frame_base = base;} + + // Get current video mode + const video_mode &get_current_mode(void) const {return *current_mode;} + + // Get Apple mode id for given depth + uint16 depth_to_apple_mode(video_depth depth) const {return apple_mode_for_depth[depth];} + + // Get current color depth + uint16 get_apple_mode(void) const {return depth_to_apple_mode(current_mode->depth);} + + // Get bytes-per-row value for specified resolution/depth + // (if the mode isn't supported, make a good guess) + uint32 get_bytes_per_row(video_depth depth, uint32 id) const; + + // Check whether a mode with the specified depth exists on this display + bool has_depth(video_depth depth) const; + + // Mac video driver functions + int16 driver_open(void); + int16 driver_control(uint16 code, uint32 param, uint32 dce); + int16 driver_status(uint16 code, uint32 param); + +protected: + vector modes; // List of supported video modes + vector::const_iterator current_mode; // Currently selected video mode + + uint32 mac_frame_base; // Mac frame buffer address for current mode + +// Mac video driver per-display private variables/functions +private: + // Check whether the specified resolution ID is one of the supported resolutions + bool has_resolution(uint32 id) const; + + // Return iterator signifying "invalid mode" + vector::const_iterator invalid_mode(void) const {return modes.end();} + + // Find specified mode (depth/resolution) (or invalid_mode() if not found) + vector::const_iterator find_mode(uint16 apple_mode, uint32 id) const; + + // Find maximum supported depth for given resolution ID + video_depth max_depth_of_resolution(uint32 id) const; + + // Get X/Y size of specified resolution + void get_size_of_resolution(uint32 id, uint32 &x, uint32 &y) const; + + // Set palette to 50% gray + void set_gray_palette(void); + + // Load gamma-corrected black-to-white ramp to palette for direct-color mode + void load_ramp_palette(void); + + // Allocate gamma table of specified size + bool allocate_gamma_table(int size); + + // Set gamma table (0 = build linear ramp) + bool set_gamma_table(uint32 user_table); + + // Switch video mode + void switch_mode(vector::const_iterator it, uint32 param, uint32 dce); + + uint8 slot_id; // NuBus slot ID number + static uint8 next_slot_id; // Next available slot ID + + uint8 palette[256 * 3]; // Color palette, 256 entries, RGB + + bool luminance_mapping; // Luminance mapping on/off + bool interrupts_enabled; // VBL interrupts on/off + bool dm_present; // We received a GetVideoParameters call, so the Display Manager seems to be present + + uint32 gamma_table; // Mac address of gamma table + int alloc_gamma_table_size; // Allocated size of gamma table + + uint16 current_apple_mode; // Currently selected depth/resolution + uint32 current_id; + uint16 preferred_apple_mode; // Preferred depth/resolution + uint32 preferred_id; + + uint32 slot_param; // Mac address of Slot Manager parameter block + + // For compatibility reasons with older (pre-Display Manager) versions of + // MacOS, the Apple modes must start at 0x80 and be contiguous. Therefore + // we maintain an array to map the depth codes to the corresponding Apple + // mode. + uint16 apple_mode_for_depth[6]; + +// The following functions are implemented by platform-specific code +public: + + // Called by the video driver to switch the video mode on this display + // (must call set_mac_frame_base()) + virtual void switch_to_current_mode(void) = 0; + + // Called by the video driver to set the color palette (in indexed modes) + // or the gamma table (in direct modes) + virtual void set_palette(uint8 *pal, int num) = 0; }; -// Description of the main (and currently the only) monitor, set by VideoInit() -extern monitor_desc VideoMonitor; +// Vector of pointers to available monitor descriptions, filled by VideoInit() +extern vector VideoMonitors; + extern int16 VideoDriverOpen(uint32 pb, uint32 dce); extern int16 VideoDriverControl(uint32 pb, uint32 dce); extern int16 VideoDriverStatus(uint32 pb, uint32 dce); + // System specific and internal functions/data extern bool VideoInit(bool classic); extern void VideoExit(void); @@ -168,20 +269,4 @@ extern void VideoQuitFullScreen(void); extern void VideoInterrupt(void); extern void VideoRefresh(void); -// Called by the video driver to switch the video mode -extern void video_switch_to_mode(const video_mode &mode); - -// Called by the video driver to set the color palette (in indexed modes) -// or gamma table (in direct modes) -extern void video_set_palette(uint8 *pal, int num); - -// Check whether a mode with the specified depth exists -extern bool video_has_depth(video_depth depth); - -// Get bytes-per-row value for specified resolution/depth -extern uint32 video_bytes_per_row(video_depth depth, uint32 id); - -// Initialize apple_mode_for_depth[] array from VideoModes list -extern void video_init_depth_list(void); - #endif