|
|
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:
128: int graphics_setup(void) {
129: return 1;
130: }
131:
132: int graphics_init(void) {
133: T_ModeType WantedType;
134: int i;
135:
136: /* save produce_sound state */
137: Original_produce_sound = currprefs.produce_sound;
138:
139: switch (currprefs.color_mode) {
140: case 0: WantedType=T256; NeedDither=0; break;
141: case 1: WantedType=T32K; NeedDither=0; break;
142: case 2: WantedType=T64K; NeedDither=0; break;
143: case 3: WantedType=T256; NeedDither=1; break;
144: case 4: WantedType=T16; NeedDither=1; break;
145: case 5: WantedType=T16M; NeedDither=0; break;
146: default:
147: printf("Invalid color mode.\n");
148: return 0;
149: }
150:
151: if (!InitGfxLib()) {
152: printf("Can't init GfxLib.\n");
153: return 0;
154: }
155:
156: if (!currprefs.no_xhair)
157: for (i = 0; i < NumberOfModes; i++) {
158: if ((ModeList[i].ModeType == WantedType) &&
159: (ModeList[i].ModeWidth == currprefs.gfx_width) &&
160: (ModeList[i].ModeHeight == currprefs.gfx_height) &&
161: ModeList[i].HasLinear) {
162: ModeNumber = i;
163: UseLinear = 1;
164: break;
165: }
166: }
167: if (ModeNumber == -1)
168: for (i = 0; i < NumberOfModes; i++) {
169: if ((ModeList[i].ModeType == WantedType) &&
170: (ModeList[i].ModeWidth == currprefs.gfx_width) &&
171: (ModeList[i].ModeHeight == currprefs.gfx_height)) {
172: if (ModeList[i].HasWindow || ((!ModeList[i].HasLinear) && (!ModeList[i].HasWindow))) {
173: ModeNumber = i;
174: break;
175: }
176: }
177: }
178:
179: if (ModeNumber == -1) {
180: printf("Sorry, this combination of color and video mode is not supported.\n");
181: return 0;
182: }
183:
184: if (!SetMode(ModeNumber, UseLinear)) {
185: printf("Can't start graphics mode.\n");
186: return 0;
187: }
188:
189: if (!NeedDither)
190: gfxvidinfo.pixbytes = CurrentMode.BitsPerPixel>>3;
191: else
192: gfxvidinfo.pixbytes = 2;
193:
194: if (UseLinear) {
195: printf("Using linear framebuffer.\n");
196: if (CanMapBuffer) {
197: LinearMem = CurrentMode.MappedAddress;
198: if (LinearMem != NULL)
199: printf("Mapping linear framebuffer into emulator memory.\n");
200: else {
201: printf("Can't map linear framebuffer.\n");
202: return 0;
203: }
204: }
205: }
206:
207: gfxvidinfo.maxblocklines = 0;
208:
209: gfxvidinfo.width = CurrentMode.ModeWidth;
210: gfxvidinfo.height = CurrentMode.ModeHeight;
211: gfxvidinfo.linemem = 0;
212:
213: InitColors();
214: if ((gfxvidinfo.pixbytes == 1) || NeedDither)
215: LoadPalette();
216:
217: if (UseLinear && CanMapBuffer && (!NeedDither) && (LinearMem != NULL)) {
218: gfxvidinfo.bufmem = LinearMem;
219: gfxvidinfo.rowbytes = CurrentMode.LogicalLineLength;
220: } else {
221: gfxvidinfo.rowbytes = (CurrentMode.ModeWidth * gfxvidinfo.pixbytes + 3) & ~3;
222: gfxvidinfo.bufmem = malloc(gfxvidinfo.rowbytes * CurrentMode.ModeHeight);
223: if (gfxvidinfo.bufmem == NULL) {
224: printf("Can't allocate framebuffer.\n");
225: return 0;
226: }
227: }
228:
229: memset(gfxvidinfo.bufmem, 0, gfxvidinfo.rowbytes * CurrentMode.ModeHeight);
230: for(i=0; i<gfxvidinfo.height; i++)
231: flush_line(i);
232:
233: /* set up handlers */
234: if (!InstallHandlers()) {
235: printf("Can't install all handlers.\n");
236: return(0);
237: }
238:
239: return 1;
240: }
241:
242: void graphics_leave(void) {
243: UninstallHandlers();
244: CloseGfxLib();
245: dumpcustom();
246: /* restore produce_sound state */
247: currprefs.produce_sound = Original_produce_sound;
248: }
249:
250: int debuggable(void) {
251: return(1);
252: }
253:
254: int needmousehack(void) {
255: return(0);
256: }
257:
258: void write_log(const char *buf) {
259: printf(buf);
260: }
261:
262: #ifdef PICASSO96
263:
264: void PicassoRefresh(void) {
265: if (ScreenIsPicasso && !picasso_vidinfo.extra_mem) {
266: int i;
267: char *addr = gfxmemory + (picasso96_state.Address - gfxmem_start);
268: for (i = 0; i < picasso_vidinfo.height; i++, addr += picasso96_state.BytesPerRow) {
269: if (!PicassoInvalidLines[i])
270: continue;
271: PicassoInvalidLines[i] = 0;
272: CurrentMode.PutLine(addr, i);
273: }
274: }
275: }
276:
277: void DX_Invalidate (int first, int last) {
278: if (!picasso_vidinfo.extra_mem) {
279: do {
280: PicassoInvalidLines[first] = 1;
281: first++;
282: } while (first <= last);
283: }
284: }
285:
286: int DX_BitsPerCannon (void) {
287: return 8;
288: }
289:
290: void DX_SetPalette(int start, int count) {
291: if (!ScreenIsPicasso || picasso_vidinfo.pixbytes != 1)
292: return;
293:
294: while (count-- > 0) {
295: DelayedSetPalette(start, picasso96_state.CLUT[start].Red * 63 / 255,
296: picasso96_state.CLUT[start].Green * 63 / 255,
297: picasso96_state.CLUT[start].Blue * 63 / 255);
298: start++;
299: }
300: LoadPalette();
301: }
302:
303: int DX_FillResolutions (uae_u16 *ppixel_format) {
304: int i, count = 0;
305: uae_u16 format = 0;
306:
307: for (i = 0; i < NumberOfModes; i++) {
308: if (ModeList[i].ModeType != T16) {
309: DisplayModes[count].res.width = ModeList[i].ModeWidth;
310: DisplayModes[count].res.height = ModeList[i].ModeHeight;
311: DisplayModes[count].depth = ModeList[i].BitsPerPixel>>3;
312: DisplayModes[count].refresh = 75;
313: switch (DisplayModes[count].depth) {
314: case 1: format |= RGBFF_CHUNKY; break;
315: case 2: format |= RGBFF_R5G6B5PC; break;
316: case 3: format |= RGBFF_B8G8R8; break;
317: case 4: format |= RGBFF_B8G8R8A8; break;
318: }
319: count++;
320: }
321: }
322:
323: *ppixel_format = format;
324: return count;
325: }
326:
327: void SetWindowForPicasso(void) {
328: if (!SetMode(PicassoModeNumber, PicassoUseLinear)) {
329: printf("Can't start graphics mode.\n");
330: abort();
331: }
332: if (PicassoUseLinear && (CurrentMode.MappedAddress != NULL)) {
333: LinearMem = CurrentMode.MappedAddress;
334: picasso_vidinfo.extra_mem = 1;
335: } else
336: picasso_vidinfo.extra_mem = 0;
337: DX_SetPalette (0, 256);
338: }
339:
340: void SetWindowForAmiga(void) {
341: if (!SetMode(ModeNumber, UseLinear)) {
342: printf("Can't start graphics mode.\n");
343: abort();
344: }
345: if (UseLinear && (CurrentMode.MappedAddress != NULL) && (!NeedDither)) {
346: LinearMem = CurrentMode.MappedAddress;
347: gfxvidinfo.bufmem = LinearMem;
348: }
349: if ((gfxvidinfo.pixbytes == 1) || NeedDither)
350: LoadPalette();
351: }
352:
353: void gfx_set_picasso_state (int on) {
354: if (on == ScreenIsPicasso)
355: return;
356: ScreenIsPicasso = on;
357: if (on)
358: SetWindowForPicasso();
359: else
360: SetWindowForAmiga();
361: }
362:
363: void gfx_set_picasso_modeinfo (int w, int h, int depth) {
364: T_ModeType WantedType;
365: int i;
366:
367: PicassoModeNumber = -1;
368: PicassoUseLinear = 0;
369: switch (depth) {
370: case 8: WantedType=T256; break;
371: case 16: WantedType=T64K; break;
372: case 24:
373: case 32: WantedType=T16M; break;
374: default:
375: printf("Invalid Picasso mode.\n");
376: abort();
377: }
378:
379: if (!currprefs.no_xhair)
380: for (i = 0; i < NumberOfModes; i++) {
381: if ((ModeList[i].ModeType == WantedType) &&
382: (ModeList[i].ModeWidth == w) &&
383: (ModeList[i].ModeHeight == h) &&
384: ModeList[i].HasLinear) {
385: PicassoModeNumber = i;
386: PicassoUseLinear = 1;
387: break;
388: }
389: }
390: if (PicassoModeNumber == -1)
391: for (i = 0; i < NumberOfModes; i++) {
392: if ((ModeList[i].ModeType == WantedType) &&
393: (ModeList[i].ModeWidth == w) &&
394: (ModeList[i].ModeHeight == h)) {
395: if (ModeList[i].HasWindow || ((!ModeList[i].HasLinear) && (!ModeList[i].HasWindow))) {
396: PicassoModeNumber = i;
397: break;
398: }
399: }
400: }
401:
402: if (PicassoModeNumber == -1) {
403: printf("Invalid Picasso mode.\n");
404: abort ();
405: }
406:
407: picasso_vidinfo.width = w;
408: picasso_vidinfo.height = h;
409: picasso_vidinfo.depth = depth;
410: picasso_vidinfo.pixbytes = depth>>3;
411: picasso_vidinfo.rowbytes = ModeList[PicassoModeNumber].LogicalLineLength;
412: if (ScreenIsPicasso)
413: SetWindowForPicasso ();
414: }
415:
416: uae_u8 *lockscr (void) {
417: return LinearMem;
418: }
419:
420: void unlockscr (void) {
421: }
422:
423: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.