fix remapping behavior. Remapping is only necessary if we are rendering on the workbe...
[AROS-Contrib.git] / Games / Doom / i_video.c
blobd147905e2e53999b54f713b255dd0b1a0b927b09
1 // Emacs style mode select -*- C++ -*-
2 //-----------------------------------------------------------------------------
3 //
4 // $Id$
5 //
6 // Copyright (C) 1993-1996 by id Software, Inc.
7 //
8 // This source is available for distribution and/or modification
9 // only under the terms of the DOOM Source Code License as
10 // published by id Software. All rights reserved.
12 // The source is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
15 // for more details.
17 // $Log$
18 // Revision 1.1 2000/02/29 18:21:04 stegerg
19 // Doom port based on ADoomPPC. Read README.AROS!
22 // DESCRIPTION:
23 // DOOM graphics stuff for X11, UNIX.
25 //-----------------------------------------------------------------------------
27 static const char
28 rcsid[] = "$Id$";
30 #include <stdlib.h>
31 #include <unistd.h>
32 #include <sys/ipc.h>
33 #include <sys/shm.h>
35 #include <X11/Xlib.h>
36 #include <X11/Xutil.h>
37 #include <X11/keysym.h>
39 #include <X11/extensions/XShm.h>
40 // Had to dig up XShm.c for this one.
41 // It is in the libXext, but not in the XFree86 headers.
42 #ifdef LINUX
43 int XShmGetEventBase( Display* dpy ); // problems with g++?
44 #endif
46 #include <stdarg.h>
47 #include <sys/time.h>
48 #include <sys/types.h>
49 #include <sys/socket.h>
51 #include <netinet/in.h>
52 #include <errnos.h>
53 #include <signal.h>
55 #include "doomstat.h"
56 #include "i_system.h"
57 #include "v_video.h"
58 #include "m_argv.h"
59 #include "d_main.h"
61 #include "doomdef.h"
63 #define POINTER_WARP_COUNTDOWN 1
65 Display* X_display=0;
66 Window X_mainWindow;
67 Colormap X_cmap;
68 Visual* X_visual;
69 GC X_gc;
70 XEvent X_event;
71 int X_screen;
72 XVisualInfo X_visualinfo;
73 XImage* image;
74 int X_width;
75 int X_height;
77 // MIT SHared Memory extension.
78 boolean doShm;
80 XShmSegmentInfo X_shminfo;
81 int X_shmeventtype;
83 // Fake mouse handling.
84 // This cannot work properly w/o DGA.
85 // Needs an invisible mouse cursor at least.
86 boolean grabMouse;
87 int doPointerWarp = POINTER_WARP_COUNTDOWN;
89 // Blocky mode,
90 // replace each 320x200 pixel with multiply*multiply pixels.
91 // According to Dave Taylor, it still is a bonehead thing
92 // to use ....
93 static int multiply=1;
97 // Translates the key currently in X_event
100 int xlatekey(void)
103 int rc;
105 switch(rc = XKeycodeToKeysym(X_display, X_event.xkey.keycode, 0))
107 case XK_Left: rc = KEY_LEFTARROW; break;
108 case XK_Right: rc = KEY_RIGHTARROW; break;
109 case XK_Down: rc = KEY_DOWNARROW; break;
110 case XK_Up: rc = KEY_UPARROW; break;
111 case XK_Escape: rc = KEY_ESCAPE; break;
112 case XK_Return: rc = KEY_ENTER; break;
113 case XK_Tab: rc = KEY_TAB; break;
114 case XK_F1: rc = KEY_F1; break;
115 case XK_F2: rc = KEY_F2; break;
116 case XK_F3: rc = KEY_F3; break;
117 case XK_F4: rc = KEY_F4; break;
118 case XK_F5: rc = KEY_F5; break;
119 case XK_F6: rc = KEY_F6; break;
120 case XK_F7: rc = KEY_F7; break;
121 case XK_F8: rc = KEY_F8; break;
122 case XK_F9: rc = KEY_F9; break;
123 case XK_F10: rc = KEY_F10; break;
124 case XK_F11: rc = KEY_F11; break;
125 case XK_F12: rc = KEY_F12; break;
127 case XK_BackSpace:
128 case XK_Delete: rc = KEY_BACKSPACE; break;
130 case XK_Pause: rc = KEY_PAUSE; break;
132 case XK_KP_Equal:
133 case XK_equal: rc = KEY_EQUALS; break;
135 case XK_KP_Subtract:
136 case XK_minus: rc = KEY_MINUS; break;
138 case XK_Shift_L:
139 case XK_Shift_R:
140 rc = KEY_RSHIFT;
141 break;
143 case XK_Control_L:
144 case XK_Control_R:
145 rc = KEY_RCTRL;
146 break;
148 case XK_Alt_L:
149 case XK_Meta_L:
150 case XK_Alt_R:
151 case XK_Meta_R:
152 rc = KEY_RALT;
153 break;
155 default:
156 if (rc >= XK_space && rc <= XK_asciitilde)
157 rc = rc - XK_space + ' ';
158 if (rc >= 'A' && rc <= 'Z')
159 rc = rc - 'A' + 'a';
160 break;
163 return rc;
167 void I_ShutdownGraphics(void)
169 // Detach from X server
170 if (!XShmDetach(X_display, &X_shminfo))
171 I_Error("XShmDetach() failed in I_ShutdownGraphics()");
173 // Release shared memory.
174 shmdt(X_shminfo.shmaddr);
175 shmctl(X_shminfo.shmid, IPC_RMID, 0);
177 // Paranoia.
178 image->data = NULL;
184 // I_StartFrame
186 void I_StartFrame (void)
188 // er?
192 static int lastmousex = 0;
193 static int lastmousey = 0;
194 boolean mousemoved = false;
195 boolean shmFinished;
197 void I_GetEvent(void)
200 event_t event;
202 // put event-grabbing stuff in here
203 XNextEvent(X_display, &X_event);
204 switch (X_event.type)
206 case KeyPress:
207 event.type = ev_keydown;
208 event.data1 = xlatekey();
209 D_PostEvent(&event);
210 // fprintf(stderr, "k");
211 break;
212 case KeyRelease:
213 event.type = ev_keyup;
214 event.data1 = xlatekey();
215 D_PostEvent(&event);
216 // fprintf(stderr, "ku");
217 break;
218 case ButtonPress:
219 event.type = ev_mouse;
220 event.data1 =
221 (X_event.xbutton.state & Button1Mask)
222 | (X_event.xbutton.state & Button2Mask ? 2 : 0)
223 | (X_event.xbutton.state & Button3Mask ? 4 : 0)
224 | (X_event.xbutton.button == Button1)
225 | (X_event.xbutton.button == Button2 ? 2 : 0)
226 | (X_event.xbutton.button == Button3 ? 4 : 0);
227 event.data2 = event.data3 = 0;
228 D_PostEvent(&event);
229 // fprintf(stderr, "b");
230 break;
231 case ButtonRelease:
232 event.type = ev_mouse;
233 event.data1 =
234 (X_event.xbutton.state & Button1Mask)
235 | (X_event.xbutton.state & Button2Mask ? 2 : 0)
236 | (X_event.xbutton.state & Button3Mask ? 4 : 0);
237 // suggest parentheses around arithmetic in operand of |
238 event.data1 =
239 event.data1
240 ^ (X_event.xbutton.button == Button1 ? 1 : 0)
241 ^ (X_event.xbutton.button == Button2 ? 2 : 0)
242 ^ (X_event.xbutton.button == Button3 ? 4 : 0);
243 event.data2 = event.data3 = 0;
244 D_PostEvent(&event);
245 // fprintf(stderr, "bu");
246 break;
247 case MotionNotify:
248 event.type = ev_mouse;
249 event.data1 =
250 (X_event.xmotion.state & Button1Mask)
251 | (X_event.xmotion.state & Button2Mask ? 2 : 0)
252 | (X_event.xmotion.state & Button3Mask ? 4 : 0);
253 event.data2 = (X_event.xmotion.x - lastmousex) << 2;
254 event.data3 = (lastmousey - X_event.xmotion.y) << 2;
256 if (event.data2 || event.data3)
258 lastmousex = X_event.xmotion.x;
259 lastmousey = X_event.xmotion.y;
260 if (X_event.xmotion.x != X_width/2 &&
261 X_event.xmotion.y != X_height/2)
263 D_PostEvent(&event);
264 // fprintf(stderr, "m");
265 mousemoved = false;
266 } else
268 mousemoved = true;
271 break;
273 case Expose:
274 case ConfigureNotify:
275 break;
277 default:
278 if (doShm && X_event.type == X_shmeventtype) shmFinished = true;
279 break;
284 Cursor
285 createnullcursor
286 ( Display* display,
287 Window root )
289 Pixmap cursormask;
290 XGCValues xgc;
291 GC gc;
292 XColor dummycolour;
293 Cursor cursor;
295 cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/);
296 xgc.function = GXclear;
297 gc = XCreateGC(display, cursormask, GCFunction, &xgc);
298 XFillRectangle(display, cursormask, gc, 0, 0, 1, 1);
299 dummycolour.pixel = 0;
300 dummycolour.red = 0;
301 dummycolour.flags = 04;
302 cursor = XCreatePixmapCursor(display, cursormask, cursormask,
303 &dummycolour,&dummycolour, 0,0);
304 XFreePixmap(display,cursormask);
305 XFreeGC(display,gc);
306 return cursor;
310 // I_StartTic
312 void I_StartTic (void)
315 if (!X_display)
316 return;
318 while (XPending(X_display))
319 I_GetEvent();
321 // Warp the pointer back to the middle of the window
322 // or it will wander off - that is, the game will
323 // loose input focus within X11.
324 if (grabMouse)
326 if (!--doPointerWarp)
328 XWarpPointer( X_display,
329 None,
330 X_mainWindow,
331 0, 0,
332 0, 0,
333 X_width/2, X_height/2);
335 doPointerWarp = POINTER_WARP_COUNTDOWN;
339 mousemoved = false;
345 // I_UpdateNoBlit
347 void I_UpdateNoBlit (void)
349 // what is this?
353 // I_FinishUpdate
355 void I_FinishUpdate (void)
358 static int lasttic;
359 int tics;
360 int i;
361 // UNUSED static unsigned char *bigscreen=0;
363 // draws little dots on the bottom of the screen
364 if (devparm)
367 i = I_GetTime();
368 tics = i - lasttic;
369 lasttic = i;
370 if (tics > 20) tics = 20;
372 for (i=0 ; i<tics*2 ; i+=2)
373 screens[0][ (SCREENHEIGHT-1)*SCREENWIDTH + i] = 0xff;
374 for ( ; i<20*2 ; i+=2)
375 screens[0][ (SCREENHEIGHT-1)*SCREENWIDTH + i] = 0x0;
379 // scales the screen size before blitting it
380 if (multiply == 2)
382 unsigned int *olineptrs[2];
383 unsigned int *ilineptr;
384 int x, y, i;
385 unsigned int twoopixels;
386 unsigned int twomoreopixels;
387 unsigned int fouripixels;
389 ilineptr = (unsigned int *) (screens[0]);
390 for (i=0 ; i<2 ; i++)
391 olineptrs[i] = (unsigned int *) &image->data[i*X_width];
393 y = SCREENHEIGHT;
394 while (y--)
396 x = SCREENWIDTH;
399 fouripixels = *ilineptr++;
400 twoopixels = (fouripixels & 0xff000000)
401 | ((fouripixels>>8) & 0xffff00)
402 | ((fouripixels>>16) & 0xff);
403 twomoreopixels = ((fouripixels<<16) & 0xff000000)
404 | ((fouripixels<<8) & 0xffff00)
405 | (fouripixels & 0xff);
406 #ifdef __BIG_ENDIAN__
407 *olineptrs[0]++ = twoopixels;
408 *olineptrs[1]++ = twoopixels;
409 *olineptrs[0]++ = twomoreopixels;
410 *olineptrs[1]++ = twomoreopixels;
411 #else
412 *olineptrs[0]++ = twomoreopixels;
413 *olineptrs[1]++ = twomoreopixels;
414 *olineptrs[0]++ = twoopixels;
415 *olineptrs[1]++ = twoopixels;
416 #endif
417 } while (x-=4);
418 olineptrs[0] += X_width/4;
419 olineptrs[1] += X_width/4;
423 else if (multiply == 3)
425 unsigned int *olineptrs[3];
426 unsigned int *ilineptr;
427 int x, y, i;
428 unsigned int fouropixels[3];
429 unsigned int fouripixels;
431 ilineptr = (unsigned int *) (screens[0]);
432 for (i=0 ; i<3 ; i++)
433 olineptrs[i] = (unsigned int *) &image->data[i*X_width];
435 y = SCREENHEIGHT;
436 while (y--)
438 x = SCREENWIDTH;
441 fouripixels = *ilineptr++;
442 fouropixels[0] = (fouripixels & 0xff000000)
443 | ((fouripixels>>8) & 0xff0000)
444 | ((fouripixels>>16) & 0xffff);
445 fouropixels[1] = ((fouripixels<<8) & 0xff000000)
446 | (fouripixels & 0xffff00)
447 | ((fouripixels>>8) & 0xff);
448 fouropixels[2] = ((fouripixels<<16) & 0xffff0000)
449 | ((fouripixels<<8) & 0xff00)
450 | (fouripixels & 0xff);
451 #ifdef __BIG_ENDIAN__
452 *olineptrs[0]++ = fouropixels[0];
453 *olineptrs[1]++ = fouropixels[0];
454 *olineptrs[2]++ = fouropixels[0];
455 *olineptrs[0]++ = fouropixels[1];
456 *olineptrs[1]++ = fouropixels[1];
457 *olineptrs[2]++ = fouropixels[1];
458 *olineptrs[0]++ = fouropixels[2];
459 *olineptrs[1]++ = fouropixels[2];
460 *olineptrs[2]++ = fouropixels[2];
461 #else
462 *olineptrs[0]++ = fouropixels[2];
463 *olineptrs[1]++ = fouropixels[2];
464 *olineptrs[2]++ = fouropixels[2];
465 *olineptrs[0]++ = fouropixels[1];
466 *olineptrs[1]++ = fouropixels[1];
467 *olineptrs[2]++ = fouropixels[1];
468 *olineptrs[0]++ = fouropixels[0];
469 *olineptrs[1]++ = fouropixels[0];
470 *olineptrs[2]++ = fouropixels[0];
471 #endif
472 } while (x-=4);
473 olineptrs[0] += 2*X_width/4;
474 olineptrs[1] += 2*X_width/4;
475 olineptrs[2] += 2*X_width/4;
479 else if (multiply == 4)
481 // Broken. Gotta fix this some day.
482 void Expand4(unsigned *, double *);
483 Expand4 ((unsigned *)(screens[0]), (double *) (image->data));
486 if (doShm)
489 if (!XShmPutImage( X_display,
490 X_mainWindow,
491 X_gc,
492 image,
493 0, 0,
494 0, 0,
495 X_width, X_height,
496 True ))
497 I_Error("XShmPutImage() failed\n");
499 // wait for it to finish and processes all input events
500 shmFinished = false;
503 I_GetEvent();
504 } while (!shmFinished);
507 else
510 // draw the image
511 XPutImage( X_display,
512 X_mainWindow,
513 X_gc,
514 image,
515 0, 0,
516 0, 0,
517 X_width, X_height );
519 // sync up with server
520 XSync(X_display, False);
528 // I_ReadScreen
530 void I_ReadScreen (byte* scr)
532 memcpy (scr, screens[0], SCREENWIDTH*SCREENHEIGHT);
537 // Palette stuff.
539 static XColor colors[256];
541 void UploadNewPalette(Colormap cmap, byte *palette)
544 register int i;
545 register int c;
546 static boolean firstcall = true;
548 #ifdef __cplusplus
549 if (X_visualinfo.c_class == PseudoColor && X_visualinfo.depth == 8)
550 #else
551 if (X_visualinfo.class == PseudoColor && X_visualinfo.depth == 8)
552 #endif
554 // initialize the colormap
555 if (firstcall)
557 firstcall = false;
558 for (i=0 ; i<256 ; i++)
560 colors[i].pixel = i;
561 colors[i].flags = DoRed|DoGreen|DoBlue;
565 // set the X colormap entries
566 for (i=0 ; i<256 ; i++)
568 c = gammatable[usegamma][*palette++];
569 colors[i].red = (c<<8) + c;
570 c = gammatable[usegamma][*palette++];
571 colors[i].green = (c<<8) + c;
572 c = gammatable[usegamma][*palette++];
573 colors[i].blue = (c<<8) + c;
576 // store the colors to the current colormap
577 XStoreColors(X_display, cmap, colors, 256);
583 // I_SetPalette
585 void I_SetPalette (byte* palette)
587 UploadNewPalette(X_cmap, palette);
592 // This function is probably redundant,
593 // if XShmDetach works properly.
594 // ddt never detached the XShm memory,
595 // thus there might have been stale
596 // handles accumulating.
598 void grabsharedmemory(int size)
601 int key = ('d'<<24) | ('o'<<16) | ('o'<<8) | 'm';
602 struct shmid_ds shminfo;
603 int minsize = 320*200;
604 int id;
605 int rc;
606 // UNUSED int done=0;
607 int pollution=5;
609 // try to use what was here before
612 id = shmget((key_t) key, minsize, 0777); // just get the id
613 if (id != -1)
615 rc=shmctl(id, IPC_STAT, &shminfo); // get stats on it
616 if (!rc)
618 if (shminfo.shm_nattch)
620 fprintf(stderr, "User %d appears to be running "
621 "DOOM. Is that wise?\n", shminfo.shm_cpid);
622 key++;
624 else
626 if (getuid() == shminfo.shm_perm.cuid)
628 rc = shmctl(id, IPC_RMID, 0);
629 if (!rc)
630 fprintf(stderr,
631 "Was able to kill my old shared memory\n");
632 else
633 I_Error("Was NOT able to kill my old shared memory");
635 id = shmget((key_t)key, size, IPC_CREAT|0777);
636 if (id==-1)
637 I_Error("Could not get shared memory");
639 rc=shmctl(id, IPC_STAT, &shminfo);
641 break;
644 if (size >= shminfo.shm_segsz)
646 fprintf(stderr,
647 "will use %d's stale shared memory\n",
648 shminfo.shm_cpid);
649 break;
651 else
653 fprintf(stderr,
654 "warning: can't use stale "
655 "shared memory belonging to id %d, "
656 "key=0x%x\n",
657 shminfo.shm_cpid, key);
658 key++;
662 else
664 I_Error("could not get stats on key=%d", key);
667 else
669 id = shmget((key_t)key, size, IPC_CREAT|0777);
670 if (id==-1)
672 extern int errno;
673 fprintf(stderr, "errno=%d\n", errno);
674 I_Error("Could not get any shared memory");
676 break;
678 } while (--pollution);
680 if (!pollution)
682 I_Error("Sorry, system too polluted with stale "
683 "shared memory segments.\n");
686 X_shminfo.shmid = id;
688 // attach to the shared memory segment
689 image->data = X_shminfo.shmaddr = shmat(id, 0, 0);
691 fprintf(stderr, "shared memory id=%d, addr=0x%x\n", id,
692 (int) (image->data));
695 void I_InitGraphics(void)
698 char* displayname;
699 char* d;
700 int n;
701 int pnum;
702 int x=0;
703 int y=0;
705 // warning: char format, different type arg
706 char xsign=' ';
707 char ysign=' ';
709 int oktodraw;
710 unsigned long attribmask;
711 XSetWindowAttributes attribs;
712 XGCValues xgcvalues;
713 int valuemask;
714 static int firsttime=1;
716 if (!firsttime)
717 return;
718 firsttime = 0;
720 signal(SIGINT, (void (*)(int)) I_Quit);
722 if (M_CheckParm("-2"))
723 multiply = 2;
725 if (M_CheckParm("-3"))
726 multiply = 3;
728 if (M_CheckParm("-4"))
729 multiply = 4;
731 X_width = SCREENWIDTH * multiply;
732 X_height = SCREENHEIGHT * multiply;
734 // check for command-line display name
735 if ( (pnum=M_CheckParm("-disp")) ) // suggest parentheses around assignment
736 displayname = myargv[pnum+1];
737 else
738 displayname = 0;
740 // check if the user wants to grab the mouse (quite unnice)
741 grabMouse = !!M_CheckParm("-grabmouse");
743 // check for command-line geometry
744 if ( (pnum=M_CheckParm("-geom")) ) // suggest parentheses around assignment
746 // warning: char format, different type arg 3,5
747 n = sscanf(myargv[pnum+1], "%c%d%c%d", &xsign, &x, &ysign, &y);
749 if (n==2)
750 x = y = 0;
751 else if (n==6)
753 if (xsign == '-')
754 x = -x;
755 if (ysign == '-')
756 y = -y;
758 else
759 I_Error("bad -geom parameter");
762 // open the display
763 X_display = XOpenDisplay(displayname);
764 if (!X_display)
766 if (displayname)
767 I_Error("Could not open display [%s]", displayname);
768 else
769 I_Error("Could not open display (DISPLAY=[%s])", getenv("DISPLAY"));
772 // use the default visual
773 X_screen = DefaultScreen(X_display);
774 if (!XMatchVisualInfo(X_display, X_screen, 8, PseudoColor, &X_visualinfo))
775 I_Error("xdoom currently only supports 256-color PseudoColor screens");
776 X_visual = X_visualinfo.visual;
778 // check for the MITSHM extension
779 doShm = XShmQueryExtension(X_display);
781 // even if it's available, make sure it's a local connection
782 if (doShm)
784 if (!displayname) displayname = (char *) getenv("DISPLAY");
785 if (displayname)
787 d = displayname;
788 while (*d && (*d != ':')) d++;
789 if (*d) *d = 0;
790 if (!(!strcasecmp(displayname, "unix") || !*displayname)) doShm = false;
794 fprintf(stderr, "Using MITSHM extension\n");
796 // create the colormap
797 X_cmap = XCreateColormap(X_display, RootWindow(X_display,
798 X_screen), X_visual, AllocAll);
800 // setup attributes for main window
801 attribmask = CWEventMask | CWColormap | CWBorderPixel;
802 attribs.event_mask =
803 KeyPressMask
804 | KeyReleaseMask
805 // | PointerMotionMask | ButtonPressMask | ButtonReleaseMask
806 | ExposureMask;
808 attribs.colormap = X_cmap;
809 attribs.border_pixel = 0;
811 // create the main window
812 X_mainWindow = XCreateWindow( X_display,
813 RootWindow(X_display, X_screen),
814 x, y,
815 X_width, X_height,
816 0, // borderwidth
817 8, // depth
818 InputOutput,
819 X_visual,
820 attribmask,
821 &attribs );
823 XDefineCursor(X_display, X_mainWindow,
824 createnullcursor( X_display, X_mainWindow ) );
826 // create the GC
827 valuemask = GCGraphicsExposures;
828 xgcvalues.graphics_exposures = False;
829 X_gc = XCreateGC( X_display,
830 X_mainWindow,
831 valuemask,
832 &xgcvalues );
834 // map the window
835 XMapWindow(X_display, X_mainWindow);
837 // wait until it is OK to draw
838 oktodraw = 0;
839 while (!oktodraw)
841 XNextEvent(X_display, &X_event);
842 if (X_event.type == Expose
843 && !X_event.xexpose.count)
845 oktodraw = 1;
849 // grabs the pointer so it is restricted to this window
850 if (grabMouse)
851 XGrabPointer(X_display, X_mainWindow, True,
852 ButtonPressMask|ButtonReleaseMask|PointerMotionMask,
853 GrabModeAsync, GrabModeAsync,
854 X_mainWindow, None, CurrentTime);
856 if (doShm)
859 X_shmeventtype = XShmGetEventBase(X_display) + ShmCompletion;
861 // create the image
862 image = XShmCreateImage( X_display,
863 X_visual,
865 ZPixmap,
867 &X_shminfo,
868 X_width,
869 X_height );
871 grabsharedmemory(image->bytes_per_line * image->height);
874 // UNUSED
875 // create the shared memory segment
876 // X_shminfo.shmid = shmget (IPC_PRIVATE,
877 // image->bytes_per_line * image->height, IPC_CREAT | 0777);
878 // if (X_shminfo.shmid < 0)
879 // {
880 // perror("");
881 // I_Error("shmget() failed in InitGraphics()");
882 // }
883 // fprintf(stderr, "shared memory id=%d\n", X_shminfo.shmid);
884 // attach to the shared memory segment
885 // image->data = X_shminfo.shmaddr = shmat(X_shminfo.shmid, 0, 0);
888 if (!image->data)
890 perror("");
891 I_Error("shmat() failed in InitGraphics()");
894 // get the X server to attach to it
895 if (!XShmAttach(X_display, &X_shminfo))
896 I_Error("XShmAttach() failed in InitGraphics()");
899 else
901 image = XCreateImage( X_display,
902 X_visual,
904 ZPixmap,
906 (char*)malloc(X_width * X_height),
907 X_width, X_height,
909 X_width );
913 if (multiply == 1)
914 screens[0] = (unsigned char *) (image->data);
915 else
916 screens[0] = (unsigned char *) malloc (SCREENWIDTH * SCREENHEIGHT);
921 unsigned exptable[256];
923 void InitExpand (void)
925 int i;
927 for (i=0 ; i<256 ; i++)
928 exptable[i] = i | (i<<8) | (i<<16) | (i<<24);
931 double exptable2[256*256];
933 void InitExpand2 (void)
935 int i;
936 int j;
937 // UNUSED unsigned iexp, jexp;
938 double* exp;
939 union
941 double d;
942 unsigned u[2];
943 } pixel;
945 printf ("building exptable2...\n");
946 exp = exptable2;
947 for (i=0 ; i<256 ; i++)
949 pixel.u[0] = i | (i<<8) | (i<<16) | (i<<24);
950 for (j=0 ; j<256 ; j++)
952 pixel.u[1] = j | (j<<8) | (j<<16) | (j<<24);
953 *exp++ = pixel.d;
956 printf ("done.\n");
959 int inited;
961 void
962 Expand4
963 ( unsigned* lineptr,
964 double* xline )
966 double dpixel;
967 unsigned x;
968 unsigned y;
969 unsigned fourpixels;
970 unsigned step;
971 double* exp;
973 exp = exptable2;
974 if (!inited)
976 inited = 1;
977 InitExpand2 ();
981 step = 3*SCREENWIDTH/2;
983 y = SCREENHEIGHT-1;
986 x = SCREENWIDTH;
990 fourpixels = lineptr[0];
992 dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff0000)>>13) );
993 xline[0] = dpixel;
994 xline[160] = dpixel;
995 xline[320] = dpixel;
996 xline[480] = dpixel;
998 dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff)<<3 ) );
999 xline[1] = dpixel;
1000 xline[161] = dpixel;
1001 xline[321] = dpixel;
1002 xline[481] = dpixel;
1004 fourpixels = lineptr[1];
1006 dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff0000)>>13) );
1007 xline[2] = dpixel;
1008 xline[162] = dpixel;
1009 xline[322] = dpixel;
1010 xline[482] = dpixel;
1012 dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff)<<3 ) );
1013 xline[3] = dpixel;
1014 xline[163] = dpixel;
1015 xline[323] = dpixel;
1016 xline[483] = dpixel;
1018 fourpixels = lineptr[2];
1020 dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff0000)>>13) );
1021 xline[4] = dpixel;
1022 xline[164] = dpixel;
1023 xline[324] = dpixel;
1024 xline[484] = dpixel;
1026 dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff)<<3 ) );
1027 xline[5] = dpixel;
1028 xline[165] = dpixel;
1029 xline[325] = dpixel;
1030 xline[485] = dpixel;
1032 fourpixels = lineptr[3];
1034 dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff0000)>>13) );
1035 xline[6] = dpixel;
1036 xline[166] = dpixel;
1037 xline[326] = dpixel;
1038 xline[486] = dpixel;
1040 dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff)<<3 ) );
1041 xline[7] = dpixel;
1042 xline[167] = dpixel;
1043 xline[327] = dpixel;
1044 xline[487] = dpixel;
1046 lineptr+=4;
1047 xline+=8;
1048 } while (x-=16);
1049 xline += step;
1050 } while (y--);