1 /* Version 1.3 - 990522
2 ******************************************************************************
3
4 LibGGI display code for Doom and Heretic
5
6 Copyright (C) 1999 Marcus Sundberg [marcus@ggi-project.org]
7
8 Permission is hereby granted, free of charge, to any person obtaining a
9 copy of this software and associated documentation files (the "Software"),
10 to deal in the Software without restriction, including without limitation
11 the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 and/or sell copies of the Software, and to permit persons to whom the
13 Software is furnished to do so, subject to the following conditions:
14
15 The above copyright notice and this permission notice shall be included in
16 all copies or substantial portions of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
22 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
25 ******************************************************************************
26 */
27
28 /* Comment this out to disable support for FPS meter */
29 #define SHOW_FPS
30
31 /* Uncomment this is you have a Linux Heretic prior to 1.0beta1 */
32 /*
33 #define NO_FILTERING
34 */
35
36 #include <stdlib.h>
37 #include <ctype.h>
38 #include <ggi/ggi.h>
39
40 #ifdef I_GGI_DOOM
41 #include "doomstat.h"
42 #include "i_system.h"
43 #include "v_video.h"
44 #include "m_argv.h"
45 #include "d_main.h"
46 #include "r_draw.h"
47 #endif
48 #ifdef I_GGI_HERETIC
49 void R_InitBuffer (int width, int height);
50 #endif
51
52 #include "doomdef.h"
53
54 #if defined(I_GGI_DOOM)
55 #define SCREEN0_PTR (screens[0])
56 #elif defined(I_GGI_HERETIC)
57 #define SCREEN0_PTR (screen)
58 #else
59 #error You must define I_GGI_DOOM or I_GGI_HERETIC!
60 #endif
61
62 /* Needed by reset_framecounter() */
63 static ggi_visual_t ggivis=NULL;
64
65 #ifdef SHOW_FPS
66 #include <unistd.h>
67 #include <sys/time.h>
68
69 static struct timeval starttime;
70 static long totalframes;
71 static int showfps = 0;
72
reset_framecounter(void)73 static void reset_framecounter(void)
74 {
75 ggi_color black = { 0x0, 0x0, 0x0 };
76 ggi_color white = { 0xffff, 0xffff, 0xffff };
77
78 /* Set text colors */
79 ggiSetGCForeground(ggivis, ggiMapColor(ggivis, &white));
80 ggiSetGCBackground(ggivis, ggiMapColor(ggivis, &black));
81
82 totalframes = 0;
83 gettimeofday(&starttime, NULL);
84 }
85 #endif
86
87 static int lastmousex = 0;
88 static int lastmousey = 0;
89 boolean mousemoved = false;
90 int buttonstate=0;
91
92 static int realwidth, realheight;
93 static int doublebuffer;
94 static int scale;
95 static int stride;
96 static int pixelsize;
97
98 static const ggi_directbuffer *dbuf1, *dbuf2;
99 static int usedbuf, havedbuf;
100 static void *frameptr[2] = { NULL, NULL };
101 static void *oneline = NULL;
102 static void *palette = NULL;
103 static int curframe = 0;
104 static int modexrefresh=0;
105 static int dontdraw = 0;
106
107
108 static inline void
do_scale8(int xsize,int ysize,uint8 * dest,uint8 * src)109 do_scale8(int xsize, int ysize, uint8 *dest, uint8 *src)
110 {
111 int i, j, destinc = stride*2-xsize*2;
112 for (j = 0; j < ysize; j++) {
113 for (i = 0; i < xsize; /* i is incremented below */) {
114 register uint32 pix1 = src[i++], pix2 = src[i++];
115 #ifdef GGI_LITTLE_ENDIAN
116 *((uint32 *) (dest + stride))
117 = *((uint32 *) dest)
118 = (pix1 | (pix1 << 8)
119 | (pix2 << 16) | (pix2 << 24));
120 #else
121 *((uint32 *) (dest + stride))
122 = *((uint32 *) dest)
123 = (pix2 | (pix2 << 8)
124 | (pix1 << 16) | (pix1 << 24));
125 #endif
126 dest += 4;
127 }
128 dest += destinc;
129 src += xsize;
130 }
131 }
132
133 static inline void
do_scale16(int xsize,int ysize,uint8 * dest,uint8 * src)134 do_scale16(int xsize, int ysize, uint8 *dest, uint8 *src)
135 {
136 int i, j, destinc = stride*2-xsize*4;
137 uint16 *palptr = palette;
138 for (j = 0; j < ysize; j++) {
139 for (i = 0; i < xsize; /* i is incremented below */) {
140 register uint32 pixel = palptr[src[i++]];
141 *((uint32 *) (dest + stride))
142 = *((uint32 *) dest)
143 = pixel | (pixel << 16);
144 dest += 4;
145 }
146 dest += destinc;
147 src += xsize;
148 }
149 }
150
151 static inline void
do_scale32(int xsize,int ysize,uint8 * dest,uint8 * src)152 do_scale32(int xsize, int ysize, uint8 *dest, uint8 *src)
153 {
154 int i, j, destinc = stride*2-xsize*8;
155 uint32 *palptr = palette;
156 for (j = 0; j < ysize; j++) {
157 for (i = 0; i < xsize; /* i is incremented below */) {
158 register uint32 pixel = palptr[src[i++]];
159 *((uint32 *) (dest + stride))
160 = *((uint32 *) (dest)) = pixel;
161 dest += 4;
162 *((uint32 *) (dest + stride))
163 = *((uint32 *) (dest)) = pixel;
164 dest += 4;
165 }
166 dest += destinc;
167 src += xsize;
168 }
169 }
170
171
172 static inline void
do_copy8(int xsize,int ysize,uint8 * dest,uint8 * src)173 do_copy8(int xsize, int ysize, uint8 *dest, uint8 *src)
174 {
175 int i, j;
176 uint8 *palptr = palette;
177
178 for (j = 0; j < ysize; j++) {
179 for (i = 0; i < xsize; i++) {
180 dest[i] = palptr[src[i]];
181 }
182 dest += stride;
183 src += xsize;
184 }
185 }
186
187 static inline void
do_copy16(int xsize,int ysize,uint16 * dest,uint8 * src)188 do_copy16(int xsize, int ysize, uint16 *dest, uint8 *src)
189 {
190 int i, j, destinc = stride/2;
191 uint16 *palptr = palette;
192
193 for (j = 0; j < ysize; j++) {
194 for (i = 0; i < xsize; i++) {
195 dest[i] = palptr[src[i]];
196 }
197 dest += destinc;
198 src += xsize;
199 }
200 }
201
202 static inline void
do_copy32(int xsize,int ysize,uint32 * dest,uint8 * src)203 do_copy32(int xsize, int ysize, uint32 *dest, uint8 *src)
204 {
205 int i, j, destinc = stride/4;
206 uint32 *palptr = palette;
207
208 for (j = 0; j < ysize; j++) {
209 for (i = 0; i < xsize; i++) {
210 dest[i] = palptr[src[i]];
211 }
212 dest += destinc;
213 src += xsize;
214 }
215 }
216
217
key(int label,int sym)218 int key(int label, int sym)
219 {
220 int rc=0;
221 switch(label) {
222 case GIIK_CtrlL: case GIIK_CtrlR: rc=KEY_RCTRL; break;
223 case GIIK_ShiftL: case GIIK_ShiftR: rc=KEY_RSHIFT; break;
224 case GIIK_MetaL: case GIIK_MetaR:
225 case GIIK_AltL: case GIIK_AltR: rc=KEY_RALT; break;
226
227 case GIIUC_BackSpace: rc = KEY_BACKSPACE; break;
228 case GIIUC_Escape: rc = KEY_ESCAPE; break;
229 #ifdef I_GGI_HERETIC
230 case GIIK_Delete: rc = KEY_DELETE; break;
231 case GIIK_Insert: rc = KEY_INSERT; break;
232 case GIIK_PageUp: rc = KEY_PAGEUP; break;
233 case GIIK_PageDown: rc = KEY_PAGEDOWN; break;
234 case GIIK_Home: rc = KEY_HOME; break;
235 case GIIK_End: rc = KEY_END; break;
236 #endif /* I_GGI_HERETIC */
237 case GIIUC_Tab: rc = KEY_TAB; break;
238 case GIIK_Up: rc = KEY_UPARROW; break;
239 case GIIK_Down: rc = KEY_DOWNARROW; break;
240 case GIIK_Left: rc = KEY_LEFTARROW; break;
241 case GIIK_Right:rc = KEY_RIGHTARROW; break;
242 case GIIK_Enter:rc = KEY_ENTER; break;
243 case GIIK_F1: rc = KEY_F1; break;
244 case GIIK_F2: rc = KEY_F2; break;
245 case GIIK_F3: rc = KEY_F3; break;
246 case GIIK_F4: rc = KEY_F4; break;
247 case GIIK_F5: rc = KEY_F5; break;
248 case GIIK_F6: rc = KEY_F6; break;
249 case GIIK_F7: rc = KEY_F7; break;
250 case GIIK_F8: rc = KEY_F8; break;
251 case GIIK_F9: rc = KEY_F9; break;
252 case GIIK_F10: rc = KEY_F10; break;
253 case GIIK_F11: rc = KEY_F11; break;
254 case GIIK_F12: rc = KEY_F12; break;
255 case GIIK_Pause:rc = KEY_PAUSE; break;
256
257 default:
258 /* Must use label here, or it won't work when shift is down */
259 if ((label >= '0' && label <= '9') ||
260 (label >= 'A' && label <= 'Z') ||
261 label == '.' ||
262 label == ',') {
263 /* We want lowercase */
264 rc = tolower(label);
265 } else if (sym < 256) {
266 /* ASCII key - we want those */
267 rc = sym;
268 switch (sym) {
269 /* Some special cases */
270 case '+': rc = KEY_EQUALS; break;
271 case '-': rc = KEY_MINUS;
272 default: break;
273 }
274 }
275 }
276 return rc;
277 }
278
I_ShutdownGraphics(void)279 void I_ShutdownGraphics(void)
280 {
281 if (ggivis != NULL) {
282 if (!usedbuf) {
283 free(SCREEN0_PTR);
284 }
285 if (oneline) {
286 free(oneline);
287 oneline = NULL;
288 }
289 if (palette) {
290 free(palette);
291 palette = NULL;
292 }
293 ggiClose(ggivis);
294 ggivis = NULL;
295 }
296 ggiExit();
297 }
298
299
I_StartFrame(void)300 void I_StartFrame (void)
301 {
302 }
303
I_GetEvent(void)304 void I_GetEvent(void)
305 {
306 event_t event;
307 int nev;
308 ggi_event ev;
309 struct timeval t = {0,0};
310 ggi_event_mask mask;
311
312 mask = ggiEventPoll(ggivis, emAll, &t);
313 if (!mask) return;
314
315 nev = ggiEventsQueued(ggivis, mask);
316
317 while (nev) {
318 ggiEventRead(ggivis, &ev, mask);
319 switch (ev.any.type) {
320 case evKeyPress:
321 event.type = ev_keydown;
322 event.data1 = key(ev.key.label,ev.key.sym);
323 #ifdef SHOW_FPS
324 if (event.data1 == KEY_BACKSPACE &&
325 gamestate == GS_LEVEL) {
326 /* Toggle and reset the FPS counter */
327 showfps = !showfps;
328 reset_framecounter();
329 }
330 #endif
331 D_PostEvent(&event);
332 break;
333 case evKeyRelease:
334 event.type = ev_keyup;
335 event.data1 = key(ev.key.label,ev.key.sym);
336 D_PostEvent(&event);
337 break;
338 case evPtrButtonPress:
339 event.type = ev_mouse;
340 buttonstate = event.data1 =
341 buttonstate | 1<<(ev.pbutton.button-1);
342 event.data2 = event.data3 = 0;
343 D_PostEvent(&event);
344 break;
345 case evPtrButtonRelease:
346 event.type = ev_mouse;
347 buttonstate = event.data1 =
348 buttonstate ^ 1<<(ev.pbutton.button-1);
349 event.data2 = event.data3 = 0;
350 D_PostEvent(&event);
351 break;
352 case evPtrAbsolute:
353 event.type = ev_mouse;
354 event.data1 = buttonstate;
355 event.data2 = (ev.pmove.x - lastmousex) << 2;
356 event.data3 = (lastmousey - ev.pmove.y) << 2;
357
358 if (event.data2 || event.data3) {
359 lastmousex = ev.pmove.x;
360 lastmousey = ev.pmove.y;
361 if (ev.pmove.x != screenwidth/2 &&
362 ev.pmove.y != screenheight/2) {
363 D_PostEvent(&event);
364 mousemoved = false;
365 } else {
366 mousemoved = true;
367 }
368 }
369 break;
370 case evPtrRelative:
371 event.type = ev_mouse;
372 event.data1 = buttonstate;
373 event.data2 = ev.pmove.x << 2;
374 event.data3 = -ev.pmove.y << 2;
375
376 if (event.data2 || event.data3) {
377 lastmousex += ev.pmove.x;
378 lastmousey += ev.pmove.y;
379 if (ev.pmove.x != screenwidth/2 &&
380 ev.pmove.y != screenheight/2) {
381 D_PostEvent(&event);
382 mousemoved = false;
383 } else {
384 mousemoved = true;
385 }
386 }
387 break;
388 case evCommand:
389 if (ev.cmd.code == GGICMD_REQUEST_SWITCH) {
390 ggi_cmddata_switchrequest *data = (void*)
391 ev.cmd.data;
392 if (data->request == GGI_REQSW_UNMAP) {
393 ggi_event ev;
394 ev.cmd.size = sizeof(gii_cmd_nodata_event);
395 ev.cmd.type = evCommand;
396 ev.cmd.code =GGICMD_ACKNOWLEDGE_SWITCH;
397 ggiEventSend(ggivis, &ev);
398 dontdraw = 1;
399 }
400 }
401 break;
402 case evExpose:
403 dontdraw = 0;
404 break;
405 }
406 nev--;
407 }
408 }
409
I_StartTic(void)410 void I_StartTic (void)
411 {
412 if (ggivis) I_GetEvent();
413 }
414
I_UpdateNoBlit(void)415 void I_UpdateNoBlit (void)
416 {
417 }
418
I_FinishUpdate(void)419 void I_FinishUpdate (void)
420 {
421 if (dontdraw) return;
422
423 #ifdef I_GGI_HERETIC
424 #ifndef NO_FILTERING
425 /* Filters the first 32 palette-entry-color'd(gray-color) pixels
426 if wanted */
427 if (lifilter && !bilifilter) {
428 V_Filter_Screen_linear(SCREEN0_PTR);
429 }
430 if (bilifilter && !lifilter) {
431 V_Filter_Screen_bilinear(SCREEN0_PTR);
432 }
433 #endif
434 #endif
435
436 if (!usedbuf) {
437 int i;
438
439 if (havedbuf) {
440 if (ggiResourceAcquire(dbuf1->resource,
441 GGI_ACTYPE_WRITE) != 0 ||
442 (doublebuffer ?
443 ggiResourceAcquire(dbuf2->resource,
444 GGI_ACTYPE_WRITE) != 0
445 : 0)) {
446 ggiPanic("Unable to acquire DirectBuffer!\n");
447 }
448 frameptr[0] = dbuf1->write;
449 if (doublebuffer) {
450 frameptr[1] = dbuf2->write;
451 } else {
452 frameptr[1] = frameptr[0];
453 }
454 }
455 if (scale) {
456 switch (pixelsize) {
457 case 1: if (havedbuf) {
458 do_scale8(screenwidth, screenheight,
459 frameptr[curframe], SCREEN0_PTR);
460 } else {
461 uint8 *buf = SCREEN0_PTR;
462 for (i=0; i < screenheight; i++) {
463 do_scale8(screenwidth, 1, oneline,buf);
464 ggiPutBox(ggivis, 0, i*2, realwidth,
465 2, oneline);
466 buf += screenwidth;
467 }
468 }
469 break;
470 case 2: if (havedbuf) {
471 do_scale16(screenwidth, screenheight,
472 frameptr[curframe], SCREEN0_PTR);
473 } else {
474 uint8 *buf = SCREEN0_PTR;
475 for (i=0; i < screenheight; i++) {
476 do_scale16(screenwidth, 1,
477 oneline, buf);
478 ggiPutBox(ggivis, 0, i*2, realwidth,
479 2, oneline);
480 buf += screenwidth;
481 }
482 }
483 break;
484 case 4: if (havedbuf) {
485 do_scale32(screenwidth, screenheight,
486 frameptr[curframe], SCREEN0_PTR);
487 } else {
488 uint8 *buf = SCREEN0_PTR;
489 for (i=0; i < screenheight; i++) {
490 do_scale32(screenwidth, 1,
491 oneline, buf);
492 ggiPutBox(ggivis, 0, i*2, realwidth,
493 2, oneline);
494 buf += screenwidth;
495 }
496 }
497 break;
498 }
499 } else if (palette) {
500 switch (pixelsize) {
501 case 1: if (havedbuf) {
502 do_copy8(screenwidth, screenheight,
503 frameptr[curframe], SCREEN0_PTR);
504 } else {
505 uint8 *buf = SCREEN0_PTR;
506 for (i=0; i < screenheight; i++) {
507 do_copy8(screenwidth, 1, oneline,buf);
508 ggiPutBox(ggivis, 0, i, realwidth,
509 1, oneline);
510 buf += screenwidth;
511 }
512 }
513 break;
514 case 2: if (havedbuf) {
515 do_copy16(screenwidth, screenheight,
516 frameptr[curframe], SCREEN0_PTR);
517 } else {
518 uint8 *buf = SCREEN0_PTR;
519 for (i=0; i < screenheight; i++) {
520 do_copy16(screenwidth, 1,
521 oneline, buf);
522 ggiPutBox(ggivis, 0, i, realwidth,
523 1, oneline);
524 buf += screenwidth;
525 }
526 }
527 break;
528 case 4: if (havedbuf) {
529 do_copy32(screenwidth, screenheight,
530 frameptr[curframe], SCREEN0_PTR);
531 } else {
532 uint8 *buf = SCREEN0_PTR;
533 for (i=0; i < screenheight; i++) {
534 do_copy32(screenwidth, 1,
535 oneline, buf);
536 ggiPutBox(ggivis, 0, i, realwidth,
537 1, oneline);
538 buf += screenwidth;
539 }
540 }
541 break;
542 }
543 } else if (!modexrefresh) {
544 /* faster, but ugly in ModeX modes */
545 ggiPutBox(ggivis, 0, 0, screenwidth, screenheight,
546 SCREEN0_PTR);
547 } else {
548 /* slower, but nicer in ModeX modes */
549 uint8 *buf = SCREEN0_PTR;
550 for (i = 0; i < screenheight; i++) {
551 ggiPutHLine(ggivis, 0, i, screenwidth, buf);
552 buf += screenwidth;
553 }
554 }
555 if (havedbuf) {
556 ggiResourceRelease(dbuf1->resource);
557 if (doublebuffer) {
558 ggiResourceRelease(dbuf2->resource);
559 }
560 }
561
562 }
563 #ifdef SHOW_FPS
564 if (showfps) {
565 struct timeval curtime;
566 double diff;
567 char str[64];
568
569 totalframes++;
570 gettimeofday(&curtime, NULL);
571 diff = (curtime.tv_sec - starttime.tv_sec);
572 diff += ((double)curtime.tv_usec - starttime.tv_usec)/1000000;
573 if (diff != 0) {
574 sprintf(str, "FPS: %.1f", totalframes/diff);
575 ggiPuts(ggivis, 1, 1, str);
576 }
577 }
578 #endif
579 if (doublebuffer) {
580 ggiSetDisplayFrame(ggivis, curframe);
581 curframe = !curframe;
582 if (usedbuf) {
583 SCREEN0_PTR = frameptr[curframe];
584 /* Ouch, we need to recalculate the line offsets */
585 R_InitBuffer(scaledviewwidth, viewheight);
586 }
587 ggiSetWriteFrame(ggivis, curframe);
588 }
589
590 ggiFlush(ggivis);
591 }
592
I_SetPalette(byte * pal)593 void I_SetPalette (byte* pal)
594 {
595 int i;
596 ggi_color col[256];
597 byte *gamma = gammatable[usegamma];
598
599 for (i = 0; i < 256; i++) {
600 col[i].r = gamma[(*pal++)] << (GGI_COLOR_PRECISION-8);
601 col[i].g = gamma[(*pal++)] << (GGI_COLOR_PRECISION-8);
602 col[i].b = gamma[(*pal++)] << (GGI_COLOR_PRECISION-8);
603 }
604 if (palette) {
605 ggiPackColors(ggivis, palette, col, 256);
606 } else {
607 ggiSetPalette(ggivis, 0, 256, col);
608 }
609 }
610
I_CheckRes()611 void I_CheckRes()
612 {
613 }
614
InitGraphLib(void)615 void InitGraphLib(void)
616 {
617 }
618
I_InitGraphics(void)619 void I_InitGraphics(void)
620 {
621 ggi_mode mode;
622 int noflicker = 0;
623
624 fprintf(stderr, "I_InitGraphics: Init GGI-visual.\n");
625
626 if (ggiInit() < 0) I_Error("Unable to init LibGGI!\n");
627 if ((ggivis = ggiOpen(NULL)) == NULL) {
628 I_Error("Unable to open default visual!\n");
629 }
630 ggiSetFlags(ggivis, GGIFLAG_ASYNC);
631 ggiSetEventMask(ggivis, emKey | emPointer);
632
633 modexrefresh = M_CheckParm("-modex") > 0;
634 doublebuffer = M_CheckParm("-doublebuffer") > 0;
635 scale = M_CheckParm("-scale") > 0;
636 noflicker = M_CheckParm("-noflicker") > 0;
637
638 realwidth = screenwidth;
639 realheight = screenheight;
640 if (scale) {
641 realwidth *= 2;
642 realheight *= 2;
643 }
644
645 if ((!doublebuffer || ggiCheckSimpleMode(ggivis, realwidth, realheight,
646 2, GT_8BIT, &mode) < 0) &&
647 (ggiCheckSimpleMode(ggivis, realwidth, realheight, GGI_AUTO,
648 GT_8BIT, &mode) < 0) &&
649 #if defined(I_GGI_HERETIC)
650 /* Heretic still only works reliably in 320x200 (640x400 if scaled) */
651 (ggiCheckSimpleMode(ggivis, realwidth, realheight, GGI_AUTO,
652 GT_AUTO, &mode) < 0 )) {
653 I_Error("Can't set %ix%i mode\n",
654 realwidth, realheight);
655 #elif defined(I_GGI_DOOM)
656 (ggiCheckSimpleMode(ggivis, realwidth, realheight, GGI_AUTO,
657 GT_AUTO, &mode) < 0) &&
658 (mode.visible.x > MAXSCREENWIDTH ||
659 mode.visible.y > MAXSCREENHEIGHT)) {
660 I_Error("Can't find a suitable mode\n",
661 realwidth, realheight);
662 #endif
663 }
664 if (ggiSetMode(ggivis, &mode) < 0) {
665 I_Error("LibGGI can't set any modes at all?!\n");
666 }
667
668 realwidth = mode.visible.x;
669 realheight = mode.visible.y;
670 if (scale) {
671 screenwidth = realwidth / 2;
672 screenheight = realheight / 2;
673 } else {
674 screenwidth = realwidth;
675 screenheight = realheight;
676 }
677
678 pixelsize = (GT_SIZE(mode.graphtype)+7) / 8;
679 if (mode.graphtype != GT_8BIT) {
680 if ((palette = malloc(pixelsize*256)) == NULL) {
681 I_Error("Unable to allocate memory?!\n");
682 }
683 }
684
685
686 usedbuf = havedbuf = 0;
687 stride = realwidth*pixelsize;
688 if ((dbuf1 = ggiDBGetBuffer(ggivis, 0)) != NULL &&
689 (dbuf1->type & GGI_DB_SIMPLE_PLB) &&
690 (doublebuffer ? ((dbuf2 = ggiDBGetBuffer(ggivis, 1)) != NULL &&
691 (dbuf2->type & GGI_DB_SIMPLE_PLB)) : 1)) {
692 havedbuf = 1;
693 stride = dbuf1->buffer.plb.stride;
694 fprintf(stderr, "I_InitGraphics: Have DirectBuffer visual\n");
695 if (!noflicker && !scale && !palette &&
696 stride == pixelsize*realwidth &&
697 !ggiResourceMustAcquire(dbuf1->resource) &&
698 (doublebuffer ? !ggiResourceMustAcquire(dbuf2->resource)
699 : 1)) {
700 usedbuf = 1;
701 frameptr[0] = dbuf1->write;
702 if (doublebuffer) {
703 frameptr[1] = dbuf2->write;
704 } else {
705 frameptr[1] = frameptr[0];
706 }
707 SCREEN0_PTR = frameptr[0];
708 fprintf(stderr,
709 "I_InitGraphics: Using DirectBuffer with");
710 if (doublebuffer) {
711 fprintf(stderr, " doublebuffering\n");
712 } else {
713 fprintf(stderr, " singlebuffering\n");
714 }
715 }
716 }
717 if (!usedbuf) {
718 ggi_event ev;
719 ev.cmd.size = sizeof(gii_cmd_nodata_event);
720 ev.cmd.type = evCommand;
721 ev.cmd.code = GGICMD_NOHALT_ON_UNMAP;
722 ggiEventSend(ggivis, &ev);
723
724 ggiAddEventMask(ggivis, emCommand | emExpose);
725
726 if ((SCREEN0_PTR = malloc(screenwidth*screenheight)) == NULL) {
727 I_Error("Unable to allocate memory?!\n");
728 }
729 if (!havedbuf && (scale || palette)) {
730 int linesize = pixelsize*realwidth;
731 if (scale) linesize *= 4;
732 if ((oneline = malloc(linesize)) == NULL) {
733 I_Error("Unable to allocate memory?!\n");
734 }
735 }
736 fprintf(stderr,
737 "I_InitGraphics: Drawing into offscreen memory\n");
738 }
739 /* We will start drawing to frame 0, and start displaying frame 1 */
740 if (doublebuffer) {
741 ggiSetWriteFrame(ggivis, 0);
742 ggiSetDisplayFrame(ggivis, 1);
743 }
744
745 curframe = 0;
746 }
747