1 |
cebix |
1.1 |
/* |
2 |
|
|
* video.h - Video/graphics emulation |
3 |
|
|
* |
4 |
cebix |
1.13 |
* Basilisk II (C) 1997-2002 Christian Bauer |
5 |
cebix |
1.1 |
* |
6 |
|
|
* This program is free software; you can redistribute it and/or modify |
7 |
|
|
* it under the terms of the GNU General Public License as published by |
8 |
|
|
* the Free Software Foundation; either version 2 of the License, or |
9 |
|
|
* (at your option) any later version. |
10 |
|
|
* |
11 |
|
|
* This program is distributed in the hope that it will be useful, |
12 |
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 |
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 |
|
|
* GNU General Public License for more details. |
15 |
|
|
* |
16 |
|
|
* You should have received a copy of the GNU General Public License |
17 |
|
|
* along with this program; if not, write to the Free Software |
18 |
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 |
|
|
*/ |
20 |
|
|
|
21 |
|
|
#ifndef VIDEO_H |
22 |
|
|
#define VIDEO_H |
23 |
|
|
|
24 |
cebix |
1.6 |
#include <vector> |
25 |
|
|
|
26 |
cebix |
1.10 |
#ifndef NO_STD_NAMESPACE |
27 |
|
|
using std::vector; |
28 |
|
|
#endif |
29 |
|
|
|
30 |
cebix |
1.9 |
/* |
31 |
|
|
Some of the terminology here is completely frelled. In Basilisk II, a |
32 |
|
|
"video mode" refers to a combination of resolution and color depth, and |
33 |
|
|
this information is stored in a video_mode structure. In Apple |
34 |
|
|
documentation, a "mode" historically refers to the color depth only |
35 |
|
|
(because old Macs had fixed-frequency monitors and could not change the |
36 |
|
|
resolution). These "modes" are assigned a number (0x80, 0x81, etc.), |
37 |
|
|
which we here call "Apple mode". When Macs learned how to deal with |
38 |
|
|
multiscan monitors, Apple introduced another type of "mode", also having |
39 |
|
|
numbers starting from 0x80 but refrerring to the resolution and/or video |
40 |
|
|
timing of the display (it's possible to have two modes with the same |
41 |
|
|
dimension but different refresh rates). We call this a "resolution ID". |
42 |
|
|
The combination of "Apple mode" and "ID" corresponds to a Basilisk II |
43 |
|
|
"video mode". To make the confusion worse, the video driver control call |
44 |
|
|
that sets the color depth is called "SetMode" while the one that sets |
45 |
|
|
both depth and resolution is "SwitchMode"... |
46 |
|
|
*/ |
47 |
|
|
|
48 |
cebix |
1.6 |
// Color depth codes |
49 |
|
|
enum video_depth { |
50 |
|
|
VDEPTH_1BIT, // 2 colors |
51 |
|
|
VDEPTH_2BIT, // 4 colors |
52 |
|
|
VDEPTH_4BIT, // 16 colors |
53 |
|
|
VDEPTH_8BIT, // 256 colors |
54 |
|
|
VDEPTH_16BIT, // "Thousands" |
55 |
|
|
VDEPTH_32BIT // "Millions" |
56 |
cebix |
1.1 |
}; |
57 |
|
|
|
58 |
cebix |
1.12 |
// For compatibility reasons with older (pre-Display Manager) versions of |
59 |
|
|
// MacOS, the Apple modes must start at 0x80 and be contiguous. Therefore |
60 |
|
|
// we construct an array to map the depth codes to the corresponding Apple |
61 |
|
|
// mode. This array is initialized by video_init_depth_list() which must |
62 |
|
|
// be called by the platform-dependant VideoInit() routine after filling |
63 |
|
|
// the VideoModes array. |
64 |
|
|
extern uint16 apple_mode_for_depth[6]; |
65 |
|
|
|
66 |
cebix |
1.8 |
inline uint16 DepthToAppleMode(video_depth depth) |
67 |
|
|
{ |
68 |
cebix |
1.12 |
return apple_mode_for_depth[depth]; |
69 |
cebix |
1.8 |
} |
70 |
|
|
|
71 |
cebix |
1.6 |
inline bool IsDirectMode(video_depth depth) |
72 |
|
|
{ |
73 |
|
|
return depth == VDEPTH_16BIT || depth == VDEPTH_32BIT; |
74 |
|
|
} |
75 |
|
|
|
76 |
cebix |
1.9 |
// Return the depth code that corresponds to the specified bits-per-pixel value |
77 |
cebix |
1.8 |
inline video_depth DepthModeForPixelDepth(int depth) |
78 |
cebix |
1.6 |
{ |
79 |
cebix |
1.8 |
switch (depth) { |
80 |
|
|
case 1: return VDEPTH_1BIT; |
81 |
|
|
case 2: return VDEPTH_2BIT; |
82 |
|
|
case 4: return VDEPTH_4BIT; |
83 |
|
|
case 8: return VDEPTH_8BIT; |
84 |
|
|
case 15: case 16: return VDEPTH_16BIT; |
85 |
|
|
case 24: case 32: return VDEPTH_32BIT; |
86 |
|
|
default: return VDEPTH_1BIT; |
87 |
|
|
} |
88 |
cebix |
1.6 |
} |
89 |
cebix |
1.1 |
|
90 |
cebix |
1.9 |
// Return a bytes-per-row value (assuming no padding) for the specified depth and pixel width |
91 |
cebix |
1.8 |
inline uint32 TrivialBytesPerRow(uint32 width, video_depth depth) |
92 |
cebix |
1.6 |
{ |
93 |
cebix |
1.8 |
switch (depth) { |
94 |
|
|
case VDEPTH_1BIT: return width / 8; |
95 |
|
|
case VDEPTH_2BIT: return width / 4; |
96 |
|
|
case VDEPTH_4BIT: return width / 2; |
97 |
|
|
case VDEPTH_8BIT: return width; |
98 |
|
|
case VDEPTH_16BIT: return width * 2; |
99 |
|
|
case VDEPTH_32BIT: return width * 4; |
100 |
cebix |
1.10 |
default: return width; |
101 |
cebix |
1.8 |
} |
102 |
cebix |
1.6 |
} |
103 |
|
|
|
104 |
cebix |
1.9 |
/* |
105 |
|
|
You are not completely free in your selection of depth/resolution |
106 |
|
|
combinations: |
107 |
|
|
1) the lowest supported color depth must be available in all |
108 |
|
|
resolutions |
109 |
|
|
2) if one resolution provides a certain color depth, it must also |
110 |
|
|
provide all lower supported depths |
111 |
|
|
|
112 |
|
|
For example, it is possible to have this set of modes: |
113 |
|
|
640x480 @ 8 bit |
114 |
|
|
640x480 @ 32 bit |
115 |
|
|
800x600 @ 8 bit |
116 |
|
|
800x600 @ 32 bit |
117 |
|
|
1024x768 @ 8 bit |
118 |
|
|
|
119 |
|
|
But this is not possible (violates rule 1): |
120 |
|
|
640x480 @ 8 bit |
121 |
|
|
800x600 @ 8 bit |
122 |
|
|
1024x768 @ 1 bit |
123 |
|
|
|
124 |
|
|
And neither is this (violates rule 2, 640x480 @ 16 bit is missing): |
125 |
|
|
640x480 @ 8 bit |
126 |
|
|
640x480 @ 32 bit |
127 |
|
|
800x600 @ 8 bit |
128 |
|
|
800x600 @ 16 bit |
129 |
|
|
1024x768 @ 8 bit |
130 |
|
|
*/ |
131 |
|
|
|
132 |
|
|
// Description of a video mode |
133 |
cebix |
1.6 |
struct video_mode { |
134 |
cebix |
1.1 |
uint32 x; // X size of screen (pixels) |
135 |
|
|
uint32 y; // Y size of screen (pixels) |
136 |
cebix |
1.6 |
uint32 resolution_id; // Resolution ID (should be >= 0x80 and uniquely identify the sets of modes with the same X/Y size) |
137 |
|
|
uint32 bytes_per_row; // Bytes per row of frame buffer |
138 |
|
|
video_depth depth; // Color depth (see definitions above) |
139 |
|
|
}; |
140 |
|
|
|
141 |
|
|
inline bool IsDirectMode(const video_mode &mode) |
142 |
|
|
{ |
143 |
|
|
return IsDirectMode(mode.depth); |
144 |
|
|
} |
145 |
|
|
|
146 |
|
|
// List of all supported video modes |
147 |
cebix |
1.10 |
extern vector<video_mode> VideoModes; |
148 |
cebix |
1.6 |
|
149 |
|
|
// Description for one (possibly virtual) monitor |
150 |
|
|
struct monitor_desc { |
151 |
|
|
uint32 mac_frame_base; // Mac frame buffer address |
152 |
|
|
video_mode mode; // Currently selected video mode description |
153 |
cebix |
1.1 |
}; |
154 |
|
|
|
155 |
cebix |
1.9 |
// Description of the main (and currently the only) monitor, set by VideoInit() |
156 |
|
|
extern monitor_desc VideoMonitor; |
157 |
cebix |
1.1 |
|
158 |
cebix |
1.2 |
extern int16 VideoDriverOpen(uint32 pb, uint32 dce); |
159 |
|
|
extern int16 VideoDriverControl(uint32 pb, uint32 dce); |
160 |
|
|
extern int16 VideoDriverStatus(uint32 pb, uint32 dce); |
161 |
cebix |
1.1 |
|
162 |
|
|
// System specific and internal functions/data |
163 |
|
|
extern bool VideoInit(bool classic); |
164 |
|
|
extern void VideoExit(void); |
165 |
|
|
|
166 |
|
|
extern void VideoQuitFullScreen(void); |
167 |
|
|
|
168 |
|
|
extern void VideoInterrupt(void); |
169 |
cebix |
1.4 |
extern void VideoRefresh(void); |
170 |
cebix |
1.1 |
|
171 |
cebix |
1.9 |
// Called by the video driver to switch the video mode |
172 |
cebix |
1.7 |
extern void video_switch_to_mode(const video_mode &mode); |
173 |
cebix |
1.9 |
|
174 |
|
|
// Called by the video driver to set the color palette (in indexed modes) |
175 |
|
|
// or gamma table (in direct modes) |
176 |
cebix |
1.11 |
extern void video_set_palette(uint8 *pal, int num); |
177 |
cebix |
1.12 |
|
178 |
|
|
// Check whether a mode with the specified depth exists |
179 |
|
|
extern bool video_has_depth(video_depth depth); |
180 |
|
|
|
181 |
|
|
// Get bytes-per-row value for specified resolution/depth |
182 |
|
|
extern uint32 video_bytes_per_row(video_depth depth, uint32 id); |
183 |
|
|
|
184 |
|
|
// Initialize apple_mode_for_depth[] array from VideoModes list |
185 |
|
|
extern void video_init_depth_list(void); |
186 |
cebix |
1.1 |
|
187 |
|
|
#endif |