ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/video.cpp
Revision: 1.11
Committed: 2001-06-28T21:19:59Z (22 years, 11 months ago) by cebix
Branch: MAIN
Changes since 1.10: +192 -65 lines
Log Message:
video_x.cpp supports resolution switching in windowed mode: the available
resolutions are 512x384, 640x480, 800x600, 1024x768 and 1280x1024 (the prefs
editor has to be updated to reflect this). The resolution selected in the
prefs editor is used as the default, but it can be changed in the Monitors
control panel. So far only tested with direct addressing.

File Contents

# Content
1 /*
2 * video.cpp - Video/graphics emulation
3 *
4 * Basilisk II (C) 1997-2001 Christian Bauer
5 * Portions (C) 1997-1999 Marc Hellwig
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22 /*
23 * SEE ALSO
24 * Inside Macintosh: Devices, chapter 1 "Device Manager"
25 * Designing Cards and Drivers for the Macintosh Family, Second Edition
26 */
27
28 #include <stdio.h>
29
30 #include "sysdeps.h"
31 #include "cpu_emulation.h"
32 #include "main.h"
33 #include "macos_util.h"
34 #include "video.h"
35 #include "video_defs.h"
36
37 #define DEBUG 0
38 #include "debug.h"
39
40
41 // List of supported video modes
42 vector<video_mode> VideoModes;
43
44 // Description of the main monitor
45 monitor_desc VideoMonitor;
46
47 // Local variables (per monitor)
48 struct {
49 monitor_desc *desc; // Pointer to description of monitor handled by this instance of the driver
50 uint8 palette[256 * 3]; // Color palette, 256 entries, RGB
51 bool luminance_mapping; // Luminance mapping on/off
52 bool interrupts_enabled; // VBL interrupts on/off
53 uint32 gamma_table; // Mac address of gamma table
54 uint16 current_mode; // Currently selected depth/resolution
55 uint32 current_id;
56 uint16 preferred_mode; // Preferred depth/resolution
57 uint32 preferred_id;
58 uint32 sp; // Mac address of Slot Manager parameter block
59 } VidLocal;
60
61
62 /*
63 * Check whether specified resolution ID is one of the supported resolutions
64 */
65
66 static bool has_resolution(uint32 id)
67 {
68 std::vector<video_mode>::const_iterator i = VideoModes.begin(), end = VideoModes.end();
69 while (i != end) {
70 if (i->resolution_id == id)
71 return true;
72 ++i;
73 }
74 return false;
75 }
76
77
78 /*
79 * Find specified mode (depth/resolution) (or VideoModes.end() if not found)
80 */
81
82 static std::vector<video_mode>::const_iterator find_mode(uint16 mode, uint32 id)
83 {
84 std::vector<video_mode>::const_iterator i = VideoModes.begin(), end = VideoModes.end();
85 while (i != end) {
86 if (i->resolution_id == id && DepthToAppleMode(i->depth) == mode)
87 return i;
88 ++i;
89 }
90 return i;
91 }
92
93
94 /*
95 * Find maximum supported depth for given resolution ID
96 */
97
98 static video_depth max_depth_of_resolution(uint32 id)
99 {
100 video_depth m = VDEPTH_1BIT;
101 vector<video_mode>::const_iterator i = VideoModes.begin(), end = VideoModes.end();
102 while (i != end) {
103 if (i->depth > m)
104 m = i->depth;
105 ++i;
106 }
107 return m;
108 }
109
110
111 /*
112 * Get X/Y size of specified resolution
113 */
114
115 static void get_size_of_resolution(uint32 id, uint32 &x, uint32 &y)
116 {
117 vector<video_mode>::const_iterator i = VideoModes.begin(), end = VideoModes.end();
118 while (i != end) {
119 if (i->resolution_id == id) {
120 x = i->x;
121 y = i->y;
122 return;
123 }
124 ++i;
125 }
126 }
127
128
129 /*
130 * Set palette to 50% gray
131 */
132
133 static void set_gray_palette(void)
134 {
135 if (!IsDirectMode(VidLocal.current_mode)) {
136 for (int i=0; i<256; i++) {
137 VidLocal.palette[i * 3 + 0] = 127;
138 VidLocal.palette[i * 3 + 1] = 127;
139 VidLocal.palette[i * 3 + 2] = 127;
140 }
141 video_set_palette(VidLocal.palette);
142 }
143 }
144
145
146 /*
147 * Driver Open() routine
148 */
149
150 int16 VideoDriverOpen(uint32 pb, uint32 dce)
151 {
152 D(bug("VideoDriverOpen\n"));
153
154 // This shouldn't happen unless the platform-specific video code is broken
155 if (VideoModes.empty())
156 fprintf(stderr, "No valid video modes found (broken video driver?)\n");
157
158 // Init local variables
159 VidLocal.desc = &VideoMonitor;
160 VidLocal.luminance_mapping = false;
161 VidLocal.interrupts_enabled = false;
162 VidLocal.current_mode = DepthToAppleMode(VidLocal.desc->mode.depth);
163 VidLocal.current_id = VidLocal.desc->mode.resolution_id;
164 VidLocal.preferred_mode = VidLocal.current_mode;
165 VidLocal.preferred_id = VidLocal.current_id;
166
167 // Allocate Slot Manager parameter block in Mac RAM
168 M68kRegisters r;
169 r.d[0] = SIZEOF_SPBlock;
170 Execute68kTrap(0xa71e, &r); // NewPtrSysClear()
171 if (r.a[0] == 0)
172 return memFullErr;
173 VidLocal.sp = r.a[0];
174 D(bug("SPBlock at %08x\n", VidLocal.sp));
175
176 // Find and set default gamma table
177 VidLocal.gamma_table = 0; //!!
178
179 // Init color palette (solid gray)
180 set_gray_palette();
181 return noErr;
182 }
183
184
185 /*
186 * Driver Control() routine
187 */
188
189 int16 VideoDriverControl(uint32 pb, uint32 dce)
190 {
191 uint16 code = ReadMacInt16(pb + csCode);
192 uint32 param = ReadMacInt32(pb + csParam);
193 D(bug("VideoDriverControl %d\n", code));
194 switch (code) {
195
196 case cscSetMode: { // Set color depth
197 uint16 mode = ReadMacInt16(param + csMode);
198 D(bug(" SetMode %04x\n", mode));
199
200 // Set old base address in case the switch fails
201 WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
202
203 if (ReadMacInt16(param + csPage))
204 return paramErr;
205
206 if (mode != VidLocal.current_mode) {
207 std::vector<video_mode>::const_iterator i = find_mode(mode, VidLocal.current_id);
208 if (i == VideoModes.end())
209 return paramErr;
210 set_gray_palette();
211 video_switch_to_mode(*i);
212 VidLocal.current_mode = mode;
213 WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
214 WriteMacInt32(dce + dCtlDevBase, VidLocal.desc->mac_frame_base);
215 }
216 D(bug(" base %08x\n", VidLocal.desc->mac_frame_base));
217 return noErr;
218 }
219
220 case cscSetEntries: { // Set palette
221 D(bug(" SetEntries table %08x, count %d, start %d\n", ReadMacInt32(param + csTable), ReadMacInt16(param + csCount), ReadMacInt16(param + csStart)));
222 if (IsDirectMode(VidLocal.current_mode))
223 return controlErr;
224
225 uint32 s_pal = ReadMacInt32(param + csTable); // Source palette
226 uint8 *d_pal; // Destination palette
227 uint16 start = ReadMacInt16(param + csStart);
228 uint16 count = ReadMacInt16(param + csCount);
229 if (s_pal == 0 || count > 255)
230 return paramErr;
231
232 if (start == 0xffff) { // Indexed
233 for (uint32 i=0; i<=count; i++) {
234 d_pal = VidLocal.palette + (ReadMacInt16(s_pal) & 0xff) * 3;
235 uint8 red = (uint16)ReadMacInt16(s_pal + 2) >> 8;
236 uint8 green = (uint16)ReadMacInt16(s_pal + 4) >> 8;
237 uint8 blue = (uint16)ReadMacInt16(s_pal + 6) >> 8;
238 if (VidLocal.luminance_mapping)
239 red = green = blue = (red * 0x4ccc + green * 0x970a + blue * 0x1c29) >> 16;
240 //!! gamma correction
241 *d_pal++ = red;
242 *d_pal++ = green;
243 *d_pal++ = blue;
244 s_pal += 8;
245 }
246 } else { // Sequential
247 if (start + count > 255)
248 return paramErr;
249 d_pal = VidLocal.palette + start * 3;
250 for (uint32 i=0; i<=count; i++) {
251 uint8 red = (uint16)ReadMacInt16(s_pal + 2) >> 8;
252 uint8 green = (uint16)ReadMacInt16(s_pal + 4) >> 8;
253 uint8 blue = (uint16)ReadMacInt16(s_pal + 6) >> 8;
254 if (VidLocal.luminance_mapping)
255 red = green = blue = (red * 0x4ccc + green * 0x970a + blue * 0x1c29) >> 16;
256 //!! gamma correction
257 *d_pal++ = red;
258 *d_pal++ = green;
259 *d_pal++ = blue;
260 s_pal += 8;
261 }
262 }
263 video_set_palette(VidLocal.palette);
264 return noErr;
265 }
266
267 case cscSetGamma: // Set gamma table
268 D(bug(" SetGamma\n"));
269 //!!
270 return controlErr;
271
272 case cscGrayPage: { // Fill page with dithered gray pattern
273 D(bug(" GrayPage %d\n", ReadMacInt16(param + csPage)));
274 if (ReadMacInt16(param + csPage))
275 return paramErr;
276
277 uint32 pattern[6] = {
278 0xaaaaaaaa, // 1 bpp
279 0xcccccccc, // 2 bpp
280 0xf0f0f0f0, // 4 bpp
281 0xff00ff00, // 8 bpp
282 0xffff0000, // 16 bpp
283 0xffffffff // 32 bpp
284 };
285 uint32 p = VidLocal.desc->mac_frame_base;
286 uint32 pat = pattern[VidLocal.desc->mode.depth];
287 bool invert = (VidLocal.desc->mode.depth == VDEPTH_32BIT);
288 for (uint32 y=0; y<VidLocal.desc->mode.y; y++) {
289 for (uint32 x=0; x<VidLocal.desc->mode.bytes_per_row; x+=4) {
290 WriteMacInt32(p + x, pat);
291 if (invert)
292 pat = ~pat;
293 }
294 p += VidLocal.desc->mode.bytes_per_row;
295 pat = ~pat;
296 }
297 //!! if direct mode, load gamma table to CLUT
298 return noErr;
299 }
300
301 case cscSetGray: // Enable/disable luminance mapping
302 D(bug(" SetGray %02x\n", ReadMacInt8(param + csMode)));
303 VidLocal.luminance_mapping = ReadMacInt8(param + csMode);
304 return noErr;
305
306 case cscSetInterrupt: // Enable/disable VBL
307 D(bug(" SetInterrupt %02x\n", ReadMacInt8(param + csMode)));
308 VidLocal.interrupts_enabled = (ReadMacInt8(param + csMode) == 0);
309 return noErr;
310
311 case cscSetDefaultMode: { // Set default color depth
312 uint16 mode = ReadMacInt16(param + csMode);
313 D(bug(" SetDefaultMode %04x\n", mode));
314 VidLocal.preferred_mode = mode;
315 return noErr;
316 }
317
318 case cscSwitchMode: { // Switch video mode (depth and resolution)
319 uint16 mode = ReadMacInt16(param + csMode);
320 uint32 id = ReadMacInt32(param + csData);
321 D(bug(" SwitchMode %04x, %08x\n", mode, id));
322
323 // Set old base address in case the switch fails
324 WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
325
326 if (ReadMacInt16(param + csPage))
327 return paramErr;
328
329 if (mode != VidLocal.current_mode || id != VidLocal.current_id) {
330 std::vector<video_mode>::const_iterator i = find_mode(mode, id);
331 if (i == VideoModes.end())
332 return paramErr;
333 set_gray_palette();
334 video_switch_to_mode(*i);
335 VidLocal.current_mode = mode;
336 VidLocal.current_id = id;
337 uint32 frame_base = VidLocal.desc->mac_frame_base;
338 WriteMacInt32(param + csBaseAddr, frame_base);
339
340 M68kRegisters r;
341 uint32 sp = VidLocal.sp;
342 r.a[0] = sp;
343
344 // Find functional sResource for this display
345 WriteMacInt8(sp + spSlot, ReadMacInt8(dce + dCtlSlot));
346 WriteMacInt8(sp + spID, ReadMacInt8(dce + dCtlSlotId));
347 WriteMacInt8(sp + spExtDev, 0);
348 r.d[0] = 0x0016;
349 Execute68kTrap(0xa06e, &r); // SRsrcInfo()
350 uint32 rsrc = ReadMacInt32(sp + spPointer);
351
352 // Patch minorBase
353 WriteMacInt8(sp + spID, 0x0a); // minorBase
354 r.d[0] = 0x0006;
355 Execute68kTrap(0xa06e, &r); // SFindStruct()
356 uint32 minor_base = ReadMacInt32(sp + spPointer) - ROMBaseMac;
357 ROMBaseHost[minor_base + 0] = frame_base >> 24;
358 ROMBaseHost[minor_base + 1] = frame_base >> 16;
359 ROMBaseHost[minor_base + 2] = frame_base >> 8;
360 ROMBaseHost[minor_base + 3] = frame_base;
361
362 // Patch video mode parameter table
363 WriteMacInt32(sp + spPointer, rsrc);
364 WriteMacInt8(sp + spID, mode);
365 r.d[0] = 0x0006;
366 Execute68kTrap(0xa06e, &r); // SFindStruct()
367 WriteMacInt8(sp + spID, 0x01);
368 r.d[0] = 0x0006;
369 Execute68kTrap(0xa06e, &r); // SFindStruct()
370 uint32 p = ReadMacInt32(sp + spPointer) - ROMBaseMac;
371 ROMBaseHost[p + 8] = i->bytes_per_row >> 8;
372 ROMBaseHost[p + 9] = i->bytes_per_row;
373 ROMBaseHost[p + 14] = i->y >> 8;
374 ROMBaseHost[p + 15] = i->y;
375 ROMBaseHost[p + 16] = i->x >> 8;
376 ROMBaseHost[p + 17] = i->x;
377
378 // Update sResource
379 WriteMacInt8(sp + spID, ReadMacInt8(dce + dCtlSlotId));
380 r.d[0] = 0x002b;
381 Execute68kTrap(0xa06e, &r); // SUpdateSRT()
382
383 // Update frame buffer base in DCE
384 WriteMacInt32(dce + dCtlDevBase, frame_base);
385 }
386 D(bug(" base %08x\n", VidLocal.desc->mac_frame_base));
387 return noErr;
388 }
389
390 case cscSavePreferredConfiguration: {
391 uint16 mode = ReadMacInt16(param + csMode);
392 uint32 id = ReadMacInt32(param + csData);
393 D(bug(" SavePreferredConfiguration %04x, %08x\n", mode, id));
394 VidLocal.preferred_mode = mode;
395 VidLocal.preferred_id = id;
396 return noErr;
397 }
398
399 default:
400 printf("WARNING: Unknown VideoDriverControl(%d)\n", code);
401 return controlErr;
402 }
403 }
404
405
406 /*
407 * Driver Status() routine
408 */
409
410 int16 VideoDriverStatus(uint32 pb, uint32 dce)
411 {
412 uint16 code = ReadMacInt16(pb + csCode);
413 uint32 param = ReadMacInt32(pb + csParam);
414 D(bug("VideoDriverStatus %d\n", code));
415 switch (code) {
416
417 case cscGetMode: // Get current color depth
418 D(bug(" GetMode -> %04x, base %08x\n", VidLocal.current_mode, VidLocal.desc->mac_frame_base));
419 WriteMacInt16(param + csMode, VidLocal.current_mode);
420 WriteMacInt16(param + csPage, 0);
421 WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
422 return noErr;
423
424 case cscGetEntries: { // Read palette
425 D(bug(" GetEntries table %08x, count %d, start %d\n", ReadMacInt32(param + csTable), ReadMacInt16(param + csCount), ReadMacInt16(param + csStart)));
426
427 uint8 *s_pal; // Source palette
428 uint32 d_pal = ReadMacInt32(param + csTable); // Destination palette
429 uint16 start = ReadMacInt16(param + csStart);
430 uint16 count = ReadMacInt16(param + csCount);
431 if (d_pal == 0 || count > 255)
432 return paramErr;
433
434 if (start == 0xffff) { // Indexed
435 for (uint32 i=0; i<=count; i++) {
436 s_pal = VidLocal.palette + (ReadMacInt16(d_pal) & 0xff) * 3;
437 uint8 red = *s_pal++;
438 uint8 green = *s_pal++;
439 uint8 blue = *s_pal++;
440 WriteMacInt16(d_pal + 2, red * 0x0101);
441 WriteMacInt16(d_pal + 4, green * 0x0101);
442 WriteMacInt16(d_pal + 6, blue * 0x0101);
443 d_pal += 8;
444 }
445 } else { // Sequential
446 if (start + count > 255)
447 return paramErr;
448 s_pal = VidLocal.palette + start * 3;
449 for (uint32 i=0; i<=count; i++) {
450 uint8 red = *s_pal++;
451 uint8 green = *s_pal++;
452 uint8 blue = *s_pal++;
453 WriteMacInt16(d_pal + 2, red * 0x0101);
454 WriteMacInt16(d_pal + 4, green * 0x0101);
455 WriteMacInt16(d_pal + 6, blue * 0x0101);
456 d_pal += 8;
457 }
458 }
459 return noErr;
460 }
461
462 case cscGetPages: // Get number of pages
463 D(bug(" GetPages -> 1\n"));
464 WriteMacInt16(param + csPage, 1);
465 return noErr;
466
467 case cscGetBaseAddress: // Get page base address
468 D(bug(" GetBaseAddress -> %08x\n", VidLocal.desc->mac_frame_base));
469 WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
470 if (ReadMacInt16(param + csPage))
471 return paramErr;
472 else
473 return noErr;
474
475 case cscGetGray: // Get luminance mapping flag
476 D(bug(" GetGray -> %d\n", VidLocal.luminance_mapping));
477 WriteMacInt16(param, VidLocal.luminance_mapping ? 0x0100 : 0);
478 return noErr;
479
480 case cscGetInterrupt: // Get interrupt disable flag
481 D(bug(" GetInterrupt -> %d\n", VidLocal.interrupts_enabled));
482 WriteMacInt16(param, VidLocal.interrupts_enabled ? 0 : 0x0100);
483 return noErr;
484
485 case cscGetGamma:
486 D(bug(" GetGamma -> \n"));
487 //!!
488 return statusErr;
489
490 case cscGetDefaultMode: // Get default color depth
491 D(bug(" GetDefaultMode -> %04x\n", VidLocal.preferred_mode));
492 WriteMacInt16(param + csMode, VidLocal.preferred_mode);
493 return noErr;
494
495 case cscGetCurrentMode: // Get current video mode (depth and resolution)
496 D(bug(" GetCurMode -> %04x/%08x, base %08x\n", VidLocal.current_mode, VidLocal.current_id, VidLocal.desc->mac_frame_base));
497 WriteMacInt16(param + csMode, VidLocal.current_mode);
498 WriteMacInt32(param + csData, VidLocal.current_id);
499 WriteMacInt16(param + csPage, 0);
500 WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
501 return noErr;
502
503 case cscGetConnection: // Get monitor information
504 D(bug(" GetConnection\n"));
505 WriteMacInt16(param + csDisplayType, 8); // Modeless connection
506 WriteMacInt8(param + csConnectTaggedType, 0);
507 WriteMacInt8(param + csConnectTaggedData, 0);
508 WriteMacInt32(param + csConnectFlags, 0x43); // All modes valid and safe, non-standard tagging
509 WriteMacInt32(param + csDisplayComponent, 0);
510 return noErr;
511
512 case cscGetModeTiming: { // Get video timing for specified resolution
513 uint32 id = ReadMacInt32(param + csTimingMode);
514 D(bug(" GetModeTiming %08x\n", id));
515 if (!has_resolution(id))
516 return paramErr;
517
518 WriteMacInt32(param + csTimingFormat, FOURCC('d', 'e', 'c', 'l'));
519 WriteMacInt32(param + csTimingData, 0); // unknown
520 uint32 flags = 0xb; // mode valid, safe and shown in Monitors panel
521 if (id == VidLocal.preferred_id)
522 flags |= 4; // default mode
523 WriteMacInt32(param + csTimingFlags, flags);
524 return noErr;
525 }
526
527 case cscGetModeBaseAddress: // Get frame buffer base address
528 D(bug(" GetModeBaseAddress -> base %08x\n", VidLocal.desc->mac_frame_base));
529 WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
530 return noErr;
531
532 case cscGetPreferredConfiguration: // Get default video mode (depth and resolution)
533 D(bug(" GetPreferredConfiguration -> %04x/%08x\n", VidLocal.preferred_mode, VidLocal.preferred_id));
534 WriteMacInt16(param + csMode, VidLocal.preferred_mode);
535 WriteMacInt32(param + csData, VidLocal.preferred_id);
536 return noErr;
537
538 case cscGetNextResolution: { // Called iteratively to obtain a list of all supported resolutions
539 uint32 id = ReadMacInt32(param + csPreviousDisplayModeID);
540 D(bug(" GetNextResolution %08x\n", id));
541
542 switch (id) {
543 case 0:
544 // Return current resolution
545 id = VidLocal.current_id;
546 break;
547
548 case 0xfffffffe:
549 // Return first supported resolution
550 id = 0x80;
551 while (!has_resolution(id))
552 id++;
553 break;
554
555 default:
556 // Get next resolution
557 if (!has_resolution(id))
558 return paramErr;
559 id++;
560 while (!has_resolution(id) && id < 0x100)
561 id++;
562 if (id == 0x100) { // No more resolutions
563 WriteMacInt32(param + csRIDisplayModeID, 0xfffffffd);
564 return noErr;
565 }
566 break;
567 }
568
569 WriteMacInt32(param + csRIDisplayModeID, id);
570 uint32 x, y;
571 get_size_of_resolution(id, x, y);
572 WriteMacInt32(param + csHorizontalPixels, x);
573 WriteMacInt32(param + csVerticalLines, y);
574 WriteMacInt32(param + csRefreshRate, 75 << 16);
575 WriteMacInt16(param + csMaxDepthMode, DepthToAppleMode(max_depth_of_resolution(id)));
576 return noErr;
577 }
578
579 case cscGetVideoParameters: { // Get information about specified resolution/depth
580 uint32 id = ReadMacInt32(param + csDisplayModeID);
581 uint16 mode = ReadMacInt16(param + csDepthMode);
582 D(bug(" GetVideoParameters %04x/%08x\n", mode, id));
583
584 vector<video_mode>::const_iterator i = VideoModes.begin(), end = VideoModes.end();
585 while (i != end) {
586 if (DepthToAppleMode(i->depth) == mode && i->resolution_id == id) {
587 uint32 vp = ReadMacInt32(param + csVPBlockPtr);
588 WriteMacInt32(vp + vpBaseOffset, 0);
589 WriteMacInt16(vp + vpRowBytes, i->bytes_per_row);
590 WriteMacInt16(vp + vpBounds, 0);
591 WriteMacInt16(vp + vpBounds + 2, 0);
592 WriteMacInt16(vp + vpBounds + 4, i->y);
593 WriteMacInt16(vp + vpBounds + 6, i->x);
594 WriteMacInt16(vp + vpVersion, 0);
595 WriteMacInt16(vp + vpPackType, 0);
596 WriteMacInt32(vp + vpPackSize, 0);
597 WriteMacInt32(vp + vpHRes, 0x00480000); // 72 dpi
598 WriteMacInt32(vp + vpVRes, 0x00480000);
599 uint32 pix_type, pix_size, cmp_count, cmp_size, dev_type;
600 switch (i->depth) {
601 case VDEPTH_1BIT:
602 pix_type = 0; pix_size = 1;
603 cmp_count = 1; cmp_size = 1;
604 dev_type = 0; // CLUT
605 break;
606 case VDEPTH_2BIT:
607 pix_type = 0; pix_size = 2;
608 cmp_count = 1; cmp_size = 2;
609 dev_type = 0; // CLUT
610 break;
611 case VDEPTH_4BIT:
612 pix_type = 0; pix_size = 4;
613 cmp_count = 1; cmp_size = 4;
614 dev_type = 0; // CLUT
615 break;
616 case VDEPTH_8BIT:
617 pix_type = 0; pix_size = 8;
618 cmp_count = 1; cmp_size = 8;
619 dev_type = 0; // CLUT
620 break;
621 case VDEPTH_16BIT:
622 pix_type = 0x10; pix_size = 16;
623 cmp_count = 3; cmp_size = 5;
624 dev_type = 2; // direct
625 break;
626 case VDEPTH_32BIT:
627 pix_type = 0x10; pix_size = 32;
628 cmp_count = 3; cmp_size = 8;
629 dev_type = 2; // direct
630 break;
631 }
632 WriteMacInt16(vp + vpPixelType, pix_type);
633 WriteMacInt16(vp + vpPixelSize, pix_size);
634 WriteMacInt16(vp + vpCmpCount, cmp_count);
635 WriteMacInt16(vp + vpCmpSize, cmp_size);
636 WriteMacInt32(param + csPageCount, 1);
637 WriteMacInt32(param + csDeviceType, dev_type);
638 return noErr;
639 }
640 ++i;
641 }
642 return paramErr; // specified resolution/depth not supported
643 }
644
645 default:
646 printf("WARNING: Unknown VideoDriverStatus(%d)\n", code);
647 return statusErr;
648 }
649 }