1 |
|
/* |
2 |
|
* video.cpp - Video/graphics emulation |
3 |
|
* |
4 |
< |
* SheepShaver (C) 1997-2002 Marc Hellwig and Christian Bauer |
4 |
> |
* SheepShaver (C) 1997-2004 Marc Hellwig and Christian Bauer |
5 |
|
* |
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 |
35 |
|
#include "macos_util.h" |
36 |
|
#include "user_strings.h" |
37 |
|
#include "version.h" |
38 |
+ |
#include "thunks.h" |
39 |
|
|
40 |
|
#define DEBUG 0 |
41 |
|
#include "debug.h" |
168 |
|
set_gamma(csSave, 0); |
169 |
|
|
170 |
|
// Install and activate interrupt service |
171 |
< |
csSave->vslServiceID = 0; |
172 |
< |
VSLNewInterruptService(csSave->regEntryID, FOURCC('v','b','l',' '), &(csSave->vslServiceID)); |
171 |
> |
SheepVar32 theServiceID = 0; |
172 |
> |
VSLNewInterruptService(csSave->regEntryID, FOURCC('v','b','l',' '), (uint32 *)theServiceID.addr()); |
173 |
> |
csSave->vslServiceID = theServiceID.value(); |
174 |
|
D(bug(" Interrupt ServiceID %08lx\n", csSave->vslServiceID)); |
175 |
|
csSave->interruptsEnabled = true; |
176 |
|
|
287 |
|
case cscSetEntries: { // SetEntries |
288 |
|
D(bug("SetEntries\n")); |
289 |
|
if (VModes[cur_mode].viAppleMode > APPLE_8_BIT) return controlErr; |
290 |
< |
ColorSpec *s_pal = (ColorSpec *)Mac2HostAddr(ReadMacInt32(param + csTable)); |
291 |
< |
int16 start = ReadMacInt16(param + csStart); |
292 |
< |
int16 count = ReadMacInt16(param + csCount); |
293 |
< |
if (s_pal == NULL || count > 256) return controlErr; |
290 |
> |
uint32 s_pal = ReadMacInt32(param + csTable); |
291 |
> |
uint16 start = ReadMacInt16(param + csStart); |
292 |
> |
uint16 count = ReadMacInt16(param + csCount); |
293 |
> |
if (s_pal == 0 || count > 256) return controlErr; |
294 |
|
|
295 |
|
// Preparations for gamma correction |
296 |
|
bool do_gamma = false; |
313 |
|
|
314 |
|
// Set palette |
315 |
|
rgb_color *d_pal; |
316 |
< |
if (start == -1) { // Indexed |
316 |
> |
if (start == 0xffff) { // Indexed |
317 |
|
for (int i=0; i<=count; i++) { |
318 |
< |
d_pal = &(mac_pal[(*s_pal).value]); |
319 |
< |
uint8 red = (*s_pal).red >> 8; |
320 |
< |
uint8 green = (*s_pal).green >> 8; |
321 |
< |
uint8 blue = (*s_pal).blue >> 8; |
318 |
> |
d_pal = mac_pal + (ReadMacInt16(s_pal + csValue) & 0xff); |
319 |
> |
uint8 red = (uint16)ReadMacInt16(s_pal + csRed) >> 8; |
320 |
> |
uint8 green = (uint16)ReadMacInt16(s_pal + csGreen) >> 8; |
321 |
> |
uint8 blue = (uint16)ReadMacInt16(s_pal + csBlue) >> 8; |
322 |
|
if (csSave->luminanceMapping) |
323 |
|
red = green = blue = (red * 0x4ccc + green * 0x970a + blue * 0x1c29) >> 16; |
324 |
|
if (do_gamma) { |
329 |
|
(*d_pal).red = red; |
330 |
|
(*d_pal).green = green; |
331 |
|
(*d_pal).blue = blue; |
332 |
< |
s_pal++; |
332 |
> |
s_pal += 8; |
333 |
|
} |
334 |
< |
} else { // Sequential |
335 |
< |
d_pal = &(mac_pal[start]); |
334 |
> |
} else { // Sequential |
335 |
> |
d_pal = mac_pal + start; |
336 |
|
for (int i=0; i<=count; i++) { |
337 |
< |
uint8 red = (*s_pal).red >> 8; |
338 |
< |
uint8 green = (*s_pal).green >> 8; |
339 |
< |
uint8 blue = (*s_pal).blue >> 8; |
337 |
> |
uint8 red = (uint16)ReadMacInt16(s_pal + csRed) >> 8; |
338 |
> |
uint8 green = (uint16)ReadMacInt16(s_pal + csGreen) >> 8; |
339 |
> |
uint8 blue = (uint16)ReadMacInt16(s_pal + csBlue) >> 8; |
340 |
|
if (csSave->luminanceMapping) |
341 |
|
red = green = blue = (red * 0x4ccc + green * 0x970a + blue * 0x1c29) >> 16; |
342 |
|
if (do_gamma) { |
347 |
|
(*d_pal).red = red; |
348 |
|
(*d_pal).green = green; |
349 |
|
(*d_pal).blue = blue; |
350 |
< |
d_pal++; s_pal++; |
350 |
> |
d_pal++; |
351 |
> |
s_pal += 8; |
352 |
|
} |
353 |
|
} |
354 |
|
video_set_palette(); |
360 |
|
return set_gamma(csSave, ReadMacInt32(param)); |
361 |
|
|
362 |
|
case cscGrayPage: { // GrayPage |
363 |
< |
D(bug("GrayPage\n")); |
364 |
< |
uint32 *screen = (uint32 *)csSave->saveBaseAddr; |
365 |
< |
uint32 pattern; |
366 |
< |
uint32 row_bytes = VModes[cur_mode].viRowBytes; |
367 |
< |
switch (VModes[cur_mode].viAppleMode) { |
368 |
< |
case APPLE_8_BIT: |
369 |
< |
pattern=0xff00ff00; |
370 |
< |
for (int i=0;i<VModes[cur_mode].viYsize;i++) { |
371 |
< |
for (int j=0;j<(VModes[cur_mode].viXsize>>2);j++) |
372 |
< |
screen[j] = pattern; |
373 |
< |
pattern = ~pattern; |
374 |
< |
screen = (uint32 *)((uint32)screen + row_bytes); |
375 |
< |
} |
376 |
< |
break; |
377 |
< |
case APPLE_16_BIT: |
378 |
< |
pattern=0xffff0000; |
379 |
< |
for (int i=0;i<VModes[cur_mode].viYsize;i++) { |
380 |
< |
for (int j=0;j<(VModes[cur_mode].viXsize>>1);j++) |
381 |
< |
screen[j]=pattern; |
382 |
< |
pattern = ~pattern; |
383 |
< |
screen = (uint32 *)((uint32)screen + row_bytes); |
384 |
< |
} |
385 |
< |
break; |
383 |
< |
case APPLE_32_BIT: |
384 |
< |
pattern=0xffffffff; |
385 |
< |
for (int i=0;i<VModes[cur_mode].viYsize;i++) { |
386 |
< |
for (int j=0;j<VModes[cur_mode].viXsize;j++) { |
387 |
< |
screen[j]=pattern; |
388 |
< |
pattern = ~pattern; |
389 |
< |
} |
390 |
< |
screen = (uint32 *)((uint32)screen + row_bytes); |
391 |
< |
} |
392 |
< |
break; |
363 |
> |
D(bug("GrayPage %d\n", ReadMacInt16(param + csPage))); |
364 |
> |
if (ReadMacInt16(param + csPage)) |
365 |
> |
return paramErr; |
366 |
> |
|
367 |
> |
uint32 pattern[6] = { |
368 |
> |
0xaaaaaaaa, // 1 bpp |
369 |
> |
0xcccccccc, // 2 bpp |
370 |
> |
0xf0f0f0f0, // 4 bpp |
371 |
> |
0xff00ff00, // 8 bpp |
372 |
> |
0xffff0000, // 16 bpp |
373 |
> |
0xffffffff // 32 bpp |
374 |
> |
}; |
375 |
> |
uint32 p = csSave->saveBaseAddr; |
376 |
> |
uint32 pat = pattern[VModes[cur_mode].viAppleMode - APPLE_1_BIT]; |
377 |
> |
bool invert = (VModes[cur_mode].viAppleMode == APPLE_32_BIT); |
378 |
> |
for (uint32 y=0; y<VModes[cur_mode].viYsize; y++) { |
379 |
> |
for (uint32 x=0; x<VModes[cur_mode].viRowBytes; x+=4) { |
380 |
> |
WriteMacInt32(p + x, pat); |
381 |
> |
if (invert) |
382 |
> |
pat = ~pat; |
383 |
> |
} |
384 |
> |
p += VModes[cur_mode].viRowBytes; |
385 |
> |
pat = ~pat; |
386 |
|
} |
387 |
|
return noErr; |
388 |
|
} |
448 |
|
MacCursor[3] = ReadMacInt8(0x887); |
449 |
|
|
450 |
|
// Set new cursor image |
451 |
< |
if (display_type == DIS_SCREEN) |
451 |
> |
if (!video_can_change_cursor()) |
452 |
|
return controlErr; |
453 |
|
if (changed) |
454 |
|
video_set_cursor(); |
538 |
|
|
539 |
|
case cscGetEntries: { // GetEntries |
540 |
|
D(bug("GetEntries\n")); |
541 |
< |
ColorSpec *d_pal = (ColorSpec *)Mac2HostAddr(ReadMacInt32(param + csTable)); |
542 |
< |
int16 start = ReadMacInt16(param + csStart); |
543 |
< |
int16 count = ReadMacInt16(param + csCount); |
541 |
> |
uint32 d_pal = ReadMacInt32(param + csTable); |
542 |
> |
uint16 start = ReadMacInt16(param + csStart); |
543 |
> |
uint16 count = ReadMacInt16(param + csCount); |
544 |
|
rgb_color *s_pal; |
545 |
|
if ((VModes[cur_mode].viAppleMode == APPLE_32_BIT)|| |
546 |
|
(VModes[cur_mode].viAppleMode == APPLE_16_BIT)) { |
547 |
|
D(bug("ERROR: GetEntries in direct mode \n")); |
548 |
|
return statusErr; |
549 |
|
} |
550 |
< |
if (start >= 0) { // indexed get |
551 |
< |
s_pal = &(mac_pal[start]); |
550 |
> |
|
551 |
> |
if (start == 0xffff) { // Indexed |
552 |
|
for (uint16 i=0;i<count;i++) { |
553 |
< |
(*d_pal).red=(uint16)((*s_pal).red)*0x101; |
554 |
< |
(*d_pal).green=(uint16)((*s_pal).green)*0x101; |
555 |
< |
(*d_pal).blue=(uint16)((*s_pal).blue)*0x101; |
556 |
< |
d_pal++; s_pal++; |
553 |
> |
s_pal = mac_pal + (ReadMacInt16(d_pal + csValue) & 0xff); |
554 |
> |
uint8 red = (*s_pal).red; |
555 |
> |
uint8 green = (*s_pal).green; |
556 |
> |
uint8 blue = (*s_pal).blue; |
557 |
> |
WriteMacInt16(d_pal + csRed, red * 0x0101); |
558 |
> |
WriteMacInt16(d_pal + csGreen, green * 0x0101); |
559 |
> |
WriteMacInt16(d_pal + csBlue, blue * 0x0101); |
560 |
> |
d_pal += 8; |
561 |
|
} |
562 |
< |
} else { // selected set |
562 |
> |
} else { // Sequential |
563 |
> |
if (start + count > 255) |
564 |
> |
return paramErr; |
565 |
> |
s_pal = mac_pal + start; |
566 |
|
for (uint16 i=0;i<count;i++) { |
567 |
< |
s_pal = &(mac_pal[(*d_pal).value]); |
568 |
< |
(*d_pal).red=(uint16)((*s_pal).red)*0x101; |
569 |
< |
(*d_pal).green=(uint16)((*s_pal).green)*0x101; |
570 |
< |
(*d_pal).blue=(uint16)((*s_pal).blue)*0x101; |
571 |
< |
d_pal++; |
567 |
> |
uint8 red = (*s_pal).red; |
568 |
> |
uint8 green = (*s_pal).green; |
569 |
> |
uint8 blue = (*s_pal).blue; |
570 |
> |
s_pal++; |
571 |
> |
WriteMacInt16(d_pal + csRed, red * 0x0101); |
572 |
> |
WriteMacInt16(d_pal + csGreen, green * 0x0101); |
573 |
> |
WriteMacInt16(d_pal + csBlue, blue * 0x0101); |
574 |
> |
d_pal += 8; |
575 |
|
} |
576 |
|
}; |
577 |
|
return noErr; |
690 |
|
WriteMacInt32(param + csVerticalLines, 768); |
691 |
|
WriteMacInt32(param + csRefreshRate, 75<<16); |
692 |
|
break; |
693 |
+ |
case APPLE_1152x768: |
694 |
+ |
WriteMacInt32(param + csHorizontalPixels, 1152); |
695 |
+ |
WriteMacInt32(param + csVerticalLines, 768); |
696 |
+ |
WriteMacInt32(param + csRefreshRate, 75<<16); |
697 |
+ |
break; |
698 |
|
case APPLE_1152x900: |
699 |
|
WriteMacInt32(param + csHorizontalPixels, 1152); |
700 |
|
WriteMacInt32(param + csVerticalLines, 900); |
813 |
|
case APPLE_1024x768: |
814 |
|
timing = timingVESA_1024x768_75hz; |
815 |
|
break; |
816 |
+ |
case APPLE_1152x768: |
817 |
+ |
timing = timingApple_1152x870_75hz; // FIXME |
818 |
+ |
break; |
819 |
|
case APPLE_1152x900: |
820 |
|
timing = timingApple_1152x870_75hz; |
821 |
|
break; |