|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * DOS video interface.
5: *
6: * (c) 1997 Gustavo Goedert
7: *
8: * Originaly based on svga.c -- (c) 1995 Bernd Schmidt
9: */
10:
11: #include "sysconfig.h"
12: #include "sysdeps.h"
13:
14: #include <dos.h>
15: #include <go32.h>
16: #include <dpmi.h>
17: #include <sys/exceptn.h>
18: #include <crt0.h>
19: #include <signal.h>
20:
21: #include "config.h"
22: #include "options.h"
23: #include "threaddep/penguin.h"
24: #include "memory.h"
25: #include "custom.h"
26: #include "xwin.h"
27: #include "disk.h"
28: #include "uae.h"
29: #include "debug.h"
30: #include "picasso96.h"
31: #include "misc/handlers.h"
32: #include "misc/misc.h"
33: #include "video/vbe.h"
34:
35: int GetColor(int r, int g, int b, xcolnr *cnp);
36: void InitColors(void);
37: void SetWindowForPicasso(void);
38: void SetWindowForAmiga(void);
39: uae_u8 *lockscr (void);
40: void unlockscr (void);
41:
42: extern int debugging;
43:
44: xcolnr xcolors[4096];
45: struct vidbuf_description gfxvidinfo;
46: int NeedDither;
47: UBYTE DitherBuf[1000];
48: int ColorsAllocated;
49: char *LinearMem = NULL;
50: int ModeNumber = -1, UseLinear = 0;
51: int PicassoModeNumber = -1, PicassoUseLinear = 0;
52: int ScreenIsPicasso = 0;
53: char PicassoInvalidLines[1200];
54:
55: struct bstring *video_mode_menu = NULL;
56:
57: void setup_brkhandler(void) {
58: }
59:
60: void flush_line(int y) {
61: int target_y = y;
62: char *addr;
63:
64: if (debugging)
65: return;
66: if (LinearMem == NULL) {
67: addr = gfxvidinfo.bufmem + y*gfxvidinfo.rowbytes;
68: if (target_y < CurrentMode.ModeHeight && target_y >= 0) {
69: if (NeedDither) {
70: DitherLine(DitherBuf, (UWORD *)addr, 0, y, gfxvidinfo.width, CurrentMode.BitsPerPixel);
71: addr = DitherBuf;
72: }
73: CurrentMode.PutLine(addr, target_y);
74: }
75: } else if (NeedDither && target_y >= 0) {
76: addr = gfxvidinfo.bufmem + y*gfxvidinfo.rowbytes;
77: DitherLine(LinearMem + CurrentMode.LogicalLineLength * target_y, (UWORD *)addr, 0, y, gfxvidinfo.width, CurrentMode.BitsPerPixel);
78: }
79: }
80:
81: void flush_block(int a, int b) {
82: abort();
83: }
84:
85: void flush_screen(int a, int b) {
86: }
87:
88: int GetColor(int r, int g, int b, xcolnr *cnp) {
89: if ((CurrentMode.ModeType == T16) && (ColorsAllocated == 16))
90: return -1;
91: else if (ColorsAllocated == 256)
92: return -1;
93: *cnp = ColorsAllocated;
94: DelayedSetPalette(ColorsAllocated, doMask(r, 6, 0), doMask(g, 6, 0), doMask(b, 6, 0));
95: ColorsAllocated++;
96: return 1;
97: }
98:
99: void InitColors(void) {
100: int i;
101:
102: gfxvidinfo.can_double = 0;
103: if (NeedDither)
104: setup_dither(CurrentMode.BitsPerColor, GetColor);
105: else {
106: ColorsAllocated = 0;
107: if (gfxvidinfo.pixbytes == 1)
108: alloc_colors256(GetColor);
109: else
110: alloc_colors64k(CurrentMode.RedSize,
111: CurrentMode.GreenSize,
112: CurrentMode.BlueSize,
113: CurrentMode.RedPosition,
114: CurrentMode.GreenPosition,
115: CurrentMode.BluePosition);
116: if (gfxvidinfo.pixbytes == 1) {
117: for (i = 0; i < 4096; i++)
118: xcolors[i] = xcolors[i] * 0x01010101;
119: gfxvidinfo.can_double = 1;
120: } else if (gfxvidinfo.pixbytes == 2) {
121: for (i = 0; i < 4096; i++)
122: xcolors[i] = xcolors[i] * 0x00010001;
123: gfxvidinfo.can_double = 1;
124: }
125: }
126: }
127:
1.1.1.3 ! root 128: struct gfxstring *gfxmenu;
! 129: int numgfxitems = 0;
! 130:
! 131: struct gfxstring{
! 132: char data[32];
! 133: int val;
! 134: };
! 135:
! 136: int gfxmenusort(const void *a, const void *b) {
! 137: struct gfxstring *ga, *gb;
! 138:
! 139: ga = (struct gfxstring *) a;
! 140: gb = (struct gfxstring *) b;
! 141: if (ModeList[ga->val].ModeWidth < ModeList[gb->val].ModeWidth)
! 142: return(-1);
! 143: else if (ModeList[ga->val].ModeWidth > ModeList[gb->val].ModeWidth)
! 144: return(1);
! 145: else if (ModeList[ga->val].ModeHeight < ModeList[gb->val].ModeHeight)
! 146: return(-1);
! 147: else if (ModeList[ga->val].ModeHeight > ModeList[gb->val].ModeHeight)
! 148: return(1);
! 149: else if (ModeList[ga->val].ModeType < ModeList[gb->val].ModeType)
! 150: return(-1);
! 151: else if (ModeList[ga->val].ModeType > ModeList[gb->val].ModeType)
! 152: return(1);
! 153: return(0);
! 154: }
! 155:
1.1 root 156: int graphics_setup(void) {
1.1.1.3 ! root 157: int i, j, hasres;
! 158: struct gfxstring gfxmenuitem;
! 159:
! 160: gfxmenu = (struct gfxstring *)calloc(NumberOfModes, sizeof(struct gfxstring));
! 161:
! 162: for (i = 0; i < NumberOfModes; i++) {
! 163: hasres = 0;
! 164: for (j = 0; j < numgfxitems; j++)
! 165: if ((ModeList[gfxmenu[j].val].ModeType == ModeList[i].ModeType) &&
! 166: (ModeList[gfxmenu[j].val].ModeWidth == ModeList[i].ModeWidth) &&
! 167: (ModeList[gfxmenu[j].val].ModeHeight == ModeList[i].ModeHeight))
! 168: hasres = 1;
! 169: if (!hasres) {
! 170: sprintf(gfxmenu[numgfxitems].data, "%dx%d ", ModeList[i].ModeWidth, ModeList[i].ModeHeight);
! 171: switch (ModeList[i].ModeType) {
! 172: case T16:
! 173: strcat(gfxmenu[numgfxitems].data, "16 colors");
! 174: break;
! 175: case T256:
! 176: strcat(gfxmenu[numgfxitems].data, "256 colors");
! 177: break;
! 178: case T32K:
! 179: strcat(gfxmenu[numgfxitems].data, "32k colors");
! 180: break;
! 181: case T64K:
! 182: strcat(gfxmenu[numgfxitems].data, "64k colors");
! 183: break;
! 184: case T16M:
! 185: strcat(gfxmenu[numgfxitems].data, "16M colors");
! 186: break;
! 187: }
! 188: gfxmenu[numgfxitems].val = i;
! 189: numgfxitems++;
! 190: }
! 191: }
! 192: qsort((void *)gfxmenu, numgfxitems, sizeof(struct gfxstring), gfxmenusort);
! 193:
! 194: video_mode_menu = (struct bstring *)malloc(sizeof (struct bstring)*(numgfxitems+1));
! 195: for (i = 0; i < numgfxitems; i++) {
! 196: video_mode_menu[i].val = -1;
! 197: video_mode_menu[i].data = strdup(gfxmenu[i].data);
! 198: }
! 199: video_mode_menu[numgfxitems].val = -3;
! 200: video_mode_menu[numgfxitems].data = NULL;
! 201:
1.1 root 202: return 1;
203: }
204:
1.1.1.3 ! root 205: void vidmode_menu_selected(int a) {
! 206: currprefs.gfx_width = ModeList[gfxmenu[a].val].ModeWidth;
! 207: currprefs.gfx_height = ModeList[gfxmenu[a].val].ModeHeight;
! 208: switch (ModeList[gfxmenu[a].val].ModeType) {
! 209: case T16:
! 210: currprefs.color_mode = 4;
! 211: break;
! 212: case T256:
! 213: currprefs.color_mode = 0;
! 214: break;
! 215: case T32K:
! 216: currprefs.color_mode = 1;
! 217: break;
! 218: case T64K:
! 219: currprefs.color_mode = 2;
! 220: break;
! 221: case T16M:
! 222: currprefs.color_mode = 5;
! 223: break;
! 224: }
! 225: currprefs.gfx_lores=currprefs.gfx_width<640;
! 226: currprefs.gfx_xcenter=2;
! 227: currprefs.gfx_ycenter=2;
! 228: currprefs.gfx_linedbl=0;
! 229: if (currprefs.gfx_height > 285)
! 230: currprefs.gfx_linedbl = 1;
! 231: currprefs.gfx_correct_aspect = 1;
! 232: if (currprefs.gfx_height > 570)
! 233: currprefs.gfx_correct_aspect = 0;
! 234: }
! 235:
1.1 root 236: int graphics_init(void) {
237: T_ModeType WantedType;
238: int i;
239:
240: /* save produce_sound state */
241: Original_produce_sound = currprefs.produce_sound;
242:
243: switch (currprefs.color_mode) {
244: case 0: WantedType=T256; NeedDither=0; break;
245: case 1: WantedType=T32K; NeedDither=0; break;
246: case 2: WantedType=T64K; NeedDither=0; break;
247: case 3: WantedType=T256; NeedDither=1; break;
248: case 4: WantedType=T16; NeedDither=1; break;
249: case 5: WantedType=T16M; NeedDither=0; break;
250: default:
251: printf("Invalid color mode.\n");
252: return 0;
253: }
254:
255: if (!InitGfxLib()) {
256: printf("Can't init GfxLib.\n");
257: return 0;
258: }
259:
260: if (!currprefs.no_xhair)
261: for (i = 0; i < NumberOfModes; i++) {
262: if ((ModeList[i].ModeType == WantedType) &&
263: (ModeList[i].ModeWidth == currprefs.gfx_width) &&
264: (ModeList[i].ModeHeight == currprefs.gfx_height) &&
265: ModeList[i].HasLinear) {
266: ModeNumber = i;
267: UseLinear = 1;
268: break;
269: }
270: }
271: if (ModeNumber == -1)
272: for (i = 0; i < NumberOfModes; i++) {
273: if ((ModeList[i].ModeType == WantedType) &&
274: (ModeList[i].ModeWidth == currprefs.gfx_width) &&
275: (ModeList[i].ModeHeight == currprefs.gfx_height)) {
276: if (ModeList[i].HasWindow || ((!ModeList[i].HasLinear) && (!ModeList[i].HasWindow))) {
277: ModeNumber = i;
278: break;
279: }
280: }
281: }
282:
283: if (ModeNumber == -1) {
284: printf("Sorry, this combination of color and video mode is not supported.\n");
285: return 0;
286: }
287:
1.1.1.3 ! root 288: if (!SetMode(ModeNumber, UseLinear, 1)) {
1.1 root 289: printf("Can't start graphics mode.\n");
290: return 0;
291: }
292:
293: if (!NeedDither)
294: gfxvidinfo.pixbytes = CurrentMode.BitsPerPixel>>3;
295: else
296: gfxvidinfo.pixbytes = 2;
297:
298: if (UseLinear) {
299: printf("Using linear framebuffer.\n");
300: if (CanMapBuffer) {
301: LinearMem = CurrentMode.MappedAddress;
302: if (LinearMem != NULL)
303: printf("Mapping linear framebuffer into emulator memory.\n");
304: else {
305: printf("Can't map linear framebuffer.\n");
306: return 0;
307: }
308: }
309: }
310:
311: gfxvidinfo.maxblocklines = 0;
312:
313: gfxvidinfo.width = CurrentMode.ModeWidth;
314: gfxvidinfo.height = CurrentMode.ModeHeight;
315: gfxvidinfo.linemem = 0;
316:
317: InitColors();
318: if ((gfxvidinfo.pixbytes == 1) || NeedDither)
319: LoadPalette();
320:
321: if (UseLinear && CanMapBuffer && (!NeedDither) && (LinearMem != NULL)) {
322: gfxvidinfo.bufmem = LinearMem;
323: gfxvidinfo.rowbytes = CurrentMode.LogicalLineLength;
324: } else {
325: gfxvidinfo.rowbytes = (CurrentMode.ModeWidth * gfxvidinfo.pixbytes + 3) & ~3;
326: gfxvidinfo.bufmem = malloc(gfxvidinfo.rowbytes * CurrentMode.ModeHeight);
327: if (gfxvidinfo.bufmem == NULL) {
328: printf("Can't allocate framebuffer.\n");
329: return 0;
330: }
331: }
332:
333: memset(gfxvidinfo.bufmem, 0, gfxvidinfo.rowbytes * CurrentMode.ModeHeight);
334: for(i=0; i<gfxvidinfo.height; i++)
335: flush_line(i);
336:
337: /* set up handlers */
338: if (!InstallHandlers()) {
339: printf("Can't install all handlers.\n");
340: return(0);
341: }
342:
343: return 1;
344: }
345:
346: void graphics_leave(void) {
347: UninstallHandlers();
348: CloseGfxLib();
349: dumpcustom();
350: /* restore produce_sound state */
351: currprefs.produce_sound = Original_produce_sound;
352: }
353:
1.1.1.3 ! root 354: int debuggable(void) {
! 355: return(1);
! 356: }
! 357:
! 358: int needmousehack(void) {
! 359: return(0);
1.1 root 360: }
361:
1.1.1.3 ! root 362: void write_log(const char *buf) {
! 363: printf(buf);
1.1 root 364: }
365:
366: #ifdef PICASSO96
367:
368: void PicassoRefresh(void) {
369: if (ScreenIsPicasso && !picasso_vidinfo.extra_mem) {
370: int i;
371: char *addr = gfxmemory + (picasso96_state.Address - gfxmem_start);
372: for (i = 0; i < picasso_vidinfo.height; i++, addr += picasso96_state.BytesPerRow) {
373: if (!PicassoInvalidLines[i])
374: continue;
375: PicassoInvalidLines[i] = 0;
376: CurrentMode.PutLine(addr, i);
377: }
378: }
379: }
380:
381: void DX_Invalidate (int first, int last) {
382: if (!picasso_vidinfo.extra_mem) {
383: do {
384: PicassoInvalidLines[first] = 1;
385: first++;
386: } while (first <= last);
387: }
388: }
389:
390: int DX_BitsPerCannon (void) {
391: return 8;
392: }
393:
394: void DX_SetPalette(int start, int count) {
395: if (!ScreenIsPicasso || picasso_vidinfo.pixbytes != 1)
396: return;
397:
398: while (count-- > 0) {
399: DelayedSetPalette(start, picasso96_state.CLUT[start].Red * 63 / 255,
400: picasso96_state.CLUT[start].Green * 63 / 255,
401: picasso96_state.CLUT[start].Blue * 63 / 255);
402: start++;
403: }
404: LoadPalette();
405: }
406:
407: int DX_FillResolutions (uae_u16 *ppixel_format) {
408: int i, count = 0;
409: uae_u16 format = 0;
410:
411: for (i = 0; i < NumberOfModes; i++) {
412: if (ModeList[i].ModeType != T16) {
413: DisplayModes[count].res.width = ModeList[i].ModeWidth;
414: DisplayModes[count].res.height = ModeList[i].ModeHeight;
415: DisplayModes[count].depth = ModeList[i].BitsPerPixel>>3;
416: DisplayModes[count].refresh = 75;
417: switch (DisplayModes[count].depth) {
418: case 1: format |= RGBFF_CHUNKY; break;
419: case 2: format |= RGBFF_R5G6B5PC; break;
420: case 3: format |= RGBFF_B8G8R8; break;
421: case 4: format |= RGBFF_B8G8R8A8; break;
422: }
423: count++;
424: }
425: }
426:
427: *ppixel_format = format;
428: return count;
429: }
430:
431: void SetWindowForPicasso(void) {
1.1.1.3 ! root 432: if (!SetMode(PicassoModeNumber, PicassoUseLinear, 0)) {
1.1 root 433: printf("Can't start graphics mode.\n");
434: abort();
435: }
436: if (PicassoUseLinear && (CurrentMode.MappedAddress != NULL)) {
437: LinearMem = CurrentMode.MappedAddress;
438: picasso_vidinfo.extra_mem = 1;
439: } else
440: picasso_vidinfo.extra_mem = 0;
441: DX_SetPalette (0, 256);
442: }
443:
444: void SetWindowForAmiga(void) {
1.1.1.3 ! root 445: if (!SetMode(ModeNumber, UseLinear, 0)) {
1.1 root 446: printf("Can't start graphics mode.\n");
447: abort();
448: }
449: if (UseLinear && (CurrentMode.MappedAddress != NULL) && (!NeedDither)) {
450: LinearMem = CurrentMode.MappedAddress;
451: gfxvidinfo.bufmem = LinearMem;
452: }
453: if ((gfxvidinfo.pixbytes == 1) || NeedDither)
454: LoadPalette();
455: }
456:
457: void gfx_set_picasso_state (int on) {
458: if (on == ScreenIsPicasso)
459: return;
460: ScreenIsPicasso = on;
461: if (on)
462: SetWindowForPicasso();
463: else
464: SetWindowForAmiga();
465: }
466:
467: void gfx_set_picasso_modeinfo (int w, int h, int depth) {
468: T_ModeType WantedType;
469: int i;
470:
471: PicassoModeNumber = -1;
472: PicassoUseLinear = 0;
473: switch (depth) {
474: case 8: WantedType=T256; break;
475: case 16: WantedType=T64K; break;
476: case 24:
477: case 32: WantedType=T16M; break;
478: default:
479: printf("Invalid Picasso mode.\n");
480: abort();
481: }
482:
483: if (!currprefs.no_xhair)
484: for (i = 0; i < NumberOfModes; i++) {
485: if ((ModeList[i].ModeType == WantedType) &&
486: (ModeList[i].ModeWidth == w) &&
487: (ModeList[i].ModeHeight == h) &&
488: ModeList[i].HasLinear) {
489: PicassoModeNumber = i;
490: PicassoUseLinear = 1;
491: break;
492: }
493: }
494: if (PicassoModeNumber == -1)
495: for (i = 0; i < NumberOfModes; i++) {
496: if ((ModeList[i].ModeType == WantedType) &&
497: (ModeList[i].ModeWidth == w) &&
498: (ModeList[i].ModeHeight == h)) {
499: if (ModeList[i].HasWindow || ((!ModeList[i].HasLinear) && (!ModeList[i].HasWindow))) {
500: PicassoModeNumber = i;
501: break;
502: }
503: }
504: }
505:
506: if (PicassoModeNumber == -1) {
507: printf("Invalid Picasso mode.\n");
508: abort ();
509: }
510:
511: picasso_vidinfo.width = w;
512: picasso_vidinfo.height = h;
513: picasso_vidinfo.depth = depth;
514: picasso_vidinfo.pixbytes = depth>>3;
515: picasso_vidinfo.rowbytes = ModeList[PicassoModeNumber].LogicalLineLength;
516: if (ScreenIsPicasso)
517: SetWindowForPicasso ();
518: }
519:
520: uae_u8 *lockscr (void) {
521: return LinearMem;
522: }
523:
524: void unlockscr (void) {
525: }
526:
527: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.