Annotation of doom/i_video.c, revision 1.1.1.1

1.1       root        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.
                     11: //
                     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.
                     16: //
                     17: // $Log:$
                     18: //
                     19: // DESCRIPTION:
                     20: //     DOOM graphics stuff for X11, UNIX.
                     21: //
                     22: //-----------------------------------------------------------------------------
                     23: 
                     24: static const char
                     25: rcsid[] = "$Id: i_x.c,v 1.6 1997/02/03 22:45:10 b1 Exp $";
                     26: 
                     27: #include <stdlib.h>
                     28: #include <unistd.h>
                     29: #include <sys/ipc.h>
                     30: #include <sys/shm.h>
                     31: 
                     32: #include <X11/Xlib.h>
                     33: #include <X11/Xutil.h>
                     34: #include <X11/keysym.h>
                     35: 
                     36: #include <X11/extensions/XShm.h>
                     37: // Had to dig up XShm.c for this one.
                     38: // It is in the libXext, but not in the XFree86 headers.
                     39: #ifdef LINUX
                     40: int XShmGetEventBase( Display* dpy ); // problems with g++?
                     41: #endif
                     42: 
                     43: #include <stdarg.h>
                     44: #include <sys/time.h>
                     45: #include <sys/types.h>
                     46: #include <sys/socket.h>
                     47: 
                     48: #include <netinet/in.h>
                     49: #include <errnos.h>
                     50: #include <signal.h>
                     51: 
                     52: #include "doomstat.h"
                     53: #include "i_system.h"
                     54: #include "v_video.h"
                     55: #include "m_argv.h"
                     56: #include "d_main.h"
                     57: 
                     58: #include "doomdef.h"
                     59: 
                     60: #define POINTER_WARP_COUNTDOWN 1
                     61: 
                     62: Display*       X_display=0;
                     63: Window         X_mainWindow;
                     64: Colormap       X_cmap;
                     65: Visual*                X_visual;
                     66: GC             X_gc;
                     67: XEvent         X_event;
                     68: int            X_screen;
                     69: XVisualInfo    X_visualinfo;
                     70: XImage*                image;
                     71: int            X_width;
                     72: int            X_height;
                     73: 
                     74: // MIT SHared Memory extension.
                     75: boolean                doShm;
                     76: 
                     77: XShmSegmentInfo        X_shminfo;
                     78: int            X_shmeventtype;
                     79: 
                     80: // Fake mouse handling.
                     81: // This cannot work properly w/o DGA.
                     82: // Needs an invisible mouse cursor at least.
                     83: boolean                grabMouse;
                     84: int            doPointerWarp = POINTER_WARP_COUNTDOWN;
                     85: 
                     86: // Blocky mode,
                     87: // replace each 320x200 pixel with multiply*multiply pixels.
                     88: // According to Dave Taylor, it still is a bonehead thing
                     89: // to use ....
                     90: static int     multiply=1;
                     91: 
                     92: 
                     93: //
                     94: //  Translates the key currently in X_event
                     95: //
                     96: 
                     97: int xlatekey(void)
                     98: {
                     99: 
                    100:     int rc;
                    101: 
                    102:     switch(rc = XKeycodeToKeysym(X_display, X_event.xkey.keycode, 0))
                    103:     {
                    104:       case XK_Left:    rc = KEY_LEFTARROW;     break;
                    105:       case XK_Right:   rc = KEY_RIGHTARROW;    break;
                    106:       case XK_Down:    rc = KEY_DOWNARROW;     break;
                    107:       case XK_Up:      rc = KEY_UPARROW;       break;
                    108:       case XK_Escape:  rc = KEY_ESCAPE;        break;
                    109:       case XK_Return:  rc = KEY_ENTER;         break;
                    110:       case XK_Tab:     rc = KEY_TAB;           break;
                    111:       case XK_F1:      rc = KEY_F1;            break;
                    112:       case XK_F2:      rc = KEY_F2;            break;
                    113:       case XK_F3:      rc = KEY_F3;            break;
                    114:       case XK_F4:      rc = KEY_F4;            break;
                    115:       case XK_F5:      rc = KEY_F5;            break;
                    116:       case XK_F6:      rc = KEY_F6;            break;
                    117:       case XK_F7:      rc = KEY_F7;            break;
                    118:       case XK_F8:      rc = KEY_F8;            break;
                    119:       case XK_F9:      rc = KEY_F9;            break;
                    120:       case XK_F10:     rc = KEY_F10;           break;
                    121:       case XK_F11:     rc = KEY_F11;           break;
                    122:       case XK_F12:     rc = KEY_F12;           break;
                    123:        
                    124:       case XK_BackSpace:
                    125:       case XK_Delete:  rc = KEY_BACKSPACE;     break;
                    126: 
                    127:       case XK_Pause:   rc = KEY_PAUSE;         break;
                    128: 
                    129:       case XK_KP_Equal:
                    130:       case XK_equal:   rc = KEY_EQUALS;        break;
                    131: 
                    132:       case XK_KP_Subtract:
                    133:       case XK_minus:   rc = KEY_MINUS;         break;
                    134: 
                    135:       case XK_Shift_L:
                    136:       case XK_Shift_R:
                    137:        rc = KEY_RSHIFT;
                    138:        break;
                    139:        
                    140:       case XK_Control_L:
                    141:       case XK_Control_R:
                    142:        rc = KEY_RCTRL;
                    143:        break;
                    144:        
                    145:       case XK_Alt_L:
                    146:       case XK_Meta_L:
                    147:       case XK_Alt_R:
                    148:       case XK_Meta_R:
                    149:        rc = KEY_RALT;
                    150:        break;
                    151:        
                    152:       default:
                    153:        if (rc >= XK_space && rc <= XK_asciitilde)
                    154:            rc = rc - XK_space + ' ';
                    155:        if (rc >= 'A' && rc <= 'Z')
                    156:            rc = rc - 'A' + 'a';
                    157:        break;
                    158:     }
                    159: 
                    160:     return rc;
                    161: 
                    162: }
                    163: 
                    164: void I_ShutdownGraphics(void)
                    165: {
                    166:   // Detach from X server
                    167:   if (!XShmDetach(X_display, &X_shminfo))
                    168:            I_Error("XShmDetach() failed in I_ShutdownGraphics()");
                    169: 
                    170:   // Release shared memory.
                    171:   shmdt(X_shminfo.shmaddr);
                    172:   shmctl(X_shminfo.shmid, IPC_RMID, 0);
                    173: 
                    174:   // Paranoia.
                    175:   image->data = NULL;
                    176: }
                    177: 
                    178: 
                    179: 
                    180: //
                    181: // I_StartFrame
                    182: //
                    183: void I_StartFrame (void)
                    184: {
                    185:     // er?
                    186: 
                    187: }
                    188: 
                    189: static int     lastmousex = 0;
                    190: static int     lastmousey = 0;
                    191: boolean                mousemoved = false;
                    192: boolean                shmFinished;
                    193: 
                    194: void I_GetEvent(void)
                    195: {
                    196: 
                    197:     event_t event;
                    198: 
                    199:     // put event-grabbing stuff in here
                    200:     XNextEvent(X_display, &X_event);
                    201:     switch (X_event.type)
                    202:     {
                    203:       case KeyPress:
                    204:        event.type = ev_keydown;
                    205:        event.data1 = xlatekey();
                    206:        D_PostEvent(&event);
                    207:        // fprintf(stderr, "k");
                    208:        break;
                    209:       case KeyRelease:
                    210:        event.type = ev_keyup;
                    211:        event.data1 = xlatekey();
                    212:        D_PostEvent(&event);
                    213:        // fprintf(stderr, "ku");
                    214:        break;
                    215:       case ButtonPress:
                    216:        event.type = ev_mouse;
                    217:        event.data1 =
                    218:            (X_event.xbutton.state & Button1Mask)
                    219:            | (X_event.xbutton.state & Button2Mask ? 2 : 0)
                    220:            | (X_event.xbutton.state & Button3Mask ? 4 : 0)
                    221:            | (X_event.xbutton.button == Button1)
                    222:            | (X_event.xbutton.button == Button2 ? 2 : 0)
                    223:            | (X_event.xbutton.button == Button3 ? 4 : 0);
                    224:        event.data2 = event.data3 = 0;
                    225:        D_PostEvent(&event);
                    226:        // fprintf(stderr, "b");
                    227:        break;
                    228:       case ButtonRelease:
                    229:        event.type = ev_mouse;
                    230:        event.data1 =
                    231:            (X_event.xbutton.state & Button1Mask)
                    232:            | (X_event.xbutton.state & Button2Mask ? 2 : 0)
                    233:            | (X_event.xbutton.state & Button3Mask ? 4 : 0);
                    234:        // suggest parentheses around arithmetic in operand of |
                    235:        event.data1 =
                    236:            event.data1
                    237:            ^ (X_event.xbutton.button == Button1 ? 1 : 0)
                    238:            ^ (X_event.xbutton.button == Button2 ? 2 : 0)
                    239:            ^ (X_event.xbutton.button == Button3 ? 4 : 0);
                    240:        event.data2 = event.data3 = 0;
                    241:        D_PostEvent(&event);
                    242:        // fprintf(stderr, "bu");
                    243:        break;
                    244:       case MotionNotify:
                    245:        event.type = ev_mouse;
                    246:        event.data1 =
                    247:            (X_event.xmotion.state & Button1Mask)
                    248:            | (X_event.xmotion.state & Button2Mask ? 2 : 0)
                    249:            | (X_event.xmotion.state & Button3Mask ? 4 : 0);
                    250:        event.data2 = (X_event.xmotion.x - lastmousex) << 2;
                    251:        event.data3 = (lastmousey - X_event.xmotion.y) << 2;
                    252: 
                    253:        if (event.data2 || event.data3)
                    254:        {
                    255:            lastmousex = X_event.xmotion.x;
                    256:            lastmousey = X_event.xmotion.y;
                    257:            if (X_event.xmotion.x != X_width/2 &&
                    258:                X_event.xmotion.y != X_height/2)
                    259:            {
                    260:                D_PostEvent(&event);
                    261:                // fprintf(stderr, "m");
                    262:                mousemoved = false;
                    263:            } else
                    264:            {
                    265:                mousemoved = true;
                    266:            }
                    267:        }
                    268:        break;
                    269:        
                    270:       case Expose:
                    271:       case ConfigureNotify:
                    272:        break;
                    273:        
                    274:       default:
                    275:        if (doShm && X_event.type == X_shmeventtype) shmFinished = true;
                    276:        break;
                    277:     }
                    278: 
                    279: }
                    280: 
                    281: Cursor
                    282: createnullcursor
                    283: ( Display*     display,
                    284:   Window       root )
                    285: {
                    286:     Pixmap cursormask;
                    287:     XGCValues xgc;
                    288:     GC gc;
                    289:     XColor dummycolour;
                    290:     Cursor cursor;
                    291: 
                    292:     cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/);
                    293:     xgc.function = GXclear;
                    294:     gc =  XCreateGC(display, cursormask, GCFunction, &xgc);
                    295:     XFillRectangle(display, cursormask, gc, 0, 0, 1, 1);
                    296:     dummycolour.pixel = 0;
                    297:     dummycolour.red = 0;
                    298:     dummycolour.flags = 04;
                    299:     cursor = XCreatePixmapCursor(display, cursormask, cursormask,
                    300:                                 &dummycolour,&dummycolour, 0,0);
                    301:     XFreePixmap(display,cursormask);
                    302:     XFreeGC(display,gc);
                    303:     return cursor;
                    304: }
                    305: 
                    306: //
                    307: // I_StartTic
                    308: //
                    309: void I_StartTic (void)
                    310: {
                    311: 
                    312:     if (!X_display)
                    313:        return;
                    314: 
                    315:     while (XPending(X_display))
                    316:        I_GetEvent();
                    317: 
                    318:     // Warp the pointer back to the middle of the window
                    319:     //  or it will wander off - that is, the game will
                    320:     //  loose input focus within X11.
                    321:     if (grabMouse)
                    322:     {
                    323:        if (!--doPointerWarp)
                    324:        {
                    325:            XWarpPointer( X_display,
                    326:                          None,
                    327:                          X_mainWindow,
                    328:                          0, 0,
                    329:                          0, 0,
                    330:                          X_width/2, X_height/2);
                    331: 
                    332:            doPointerWarp = POINTER_WARP_COUNTDOWN;
                    333:        }
                    334:     }
                    335: 
                    336:     mousemoved = false;
                    337: 
                    338: }
                    339: 
                    340: 
                    341: //
                    342: // I_UpdateNoBlit
                    343: //
                    344: void I_UpdateNoBlit (void)
                    345: {
                    346:     // what is this?
                    347: }
                    348: 
                    349: //
                    350: // I_FinishUpdate
                    351: //
                    352: void I_FinishUpdate (void)
                    353: {
                    354: 
                    355:     static int lasttic;
                    356:     int                tics;
                    357:     int                i;
                    358:     // UNUSED static unsigned char *bigscreen=0;
                    359: 
                    360:     // draws little dots on the bottom of the screen
                    361:     if (devparm)
                    362:     {
                    363: 
                    364:        i = I_GetTime();
                    365:        tics = i - lasttic;
                    366:        lasttic = i;
                    367:        if (tics > 20) tics = 20;
                    368: 
                    369:        for (i=0 ; i<tics*2 ; i+=2)
                    370:            screens[0][ (SCREENHEIGHT-1)*SCREENWIDTH + i] = 0xff;
                    371:        for ( ; i<20*2 ; i+=2)
                    372:            screens[0][ (SCREENHEIGHT-1)*SCREENWIDTH + i] = 0x0;
                    373:     
                    374:     }
                    375: 
                    376:     // scales the screen size before blitting it
                    377:     if (multiply == 2)
                    378:     {
                    379:        unsigned int *olineptrs[2];
                    380:        unsigned int *ilineptr;
                    381:        int x, y, i;
                    382:        unsigned int twoopixels;
                    383:        unsigned int twomoreopixels;
                    384:        unsigned int fouripixels;
                    385: 
                    386:        ilineptr = (unsigned int *) (screens[0]);
                    387:        for (i=0 ; i<2 ; i++)
                    388:            olineptrs[i] = (unsigned int *) &image->data[i*X_width];
                    389: 
                    390:        y = SCREENHEIGHT;
                    391:        while (y--)
                    392:        {
                    393:            x = SCREENWIDTH;
                    394:            do
                    395:            {
                    396:                fouripixels = *ilineptr++;
                    397:                twoopixels =    (fouripixels & 0xff000000)
                    398:                    |   ((fouripixels>>8) & 0xffff00)
                    399:                    |   ((fouripixels>>16) & 0xff);
                    400:                twomoreopixels =        ((fouripixels<<16) & 0xff000000)
                    401:                    |   ((fouripixels<<8) & 0xffff00)
                    402:                    |   (fouripixels & 0xff);
                    403: #ifdef __BIG_ENDIAN__
                    404:                *olineptrs[0]++ = twoopixels;
                    405:                *olineptrs[1]++ = twoopixels;
                    406:                *olineptrs[0]++ = twomoreopixels;
                    407:                *olineptrs[1]++ = twomoreopixels;
                    408: #else
                    409:                *olineptrs[0]++ = twomoreopixels;
                    410:                *olineptrs[1]++ = twomoreopixels;
                    411:                *olineptrs[0]++ = twoopixels;
                    412:                *olineptrs[1]++ = twoopixels;
                    413: #endif
                    414:            } while (x-=4);
                    415:            olineptrs[0] += X_width/4;
                    416:            olineptrs[1] += X_width/4;
                    417:        }
                    418: 
                    419:     }
                    420:     else if (multiply == 3)
                    421:     {
                    422:        unsigned int *olineptrs[3];
                    423:        unsigned int *ilineptr;
                    424:        int x, y, i;
                    425:        unsigned int fouropixels[3];
                    426:        unsigned int fouripixels;
                    427: 
                    428:        ilineptr = (unsigned int *) (screens[0]);
                    429:        for (i=0 ; i<3 ; i++)
                    430:            olineptrs[i] = (unsigned int *) &image->data[i*X_width];
                    431: 
                    432:        y = SCREENHEIGHT;
                    433:        while (y--)
                    434:        {
                    435:            x = SCREENWIDTH;
                    436:            do
                    437:            {
                    438:                fouripixels = *ilineptr++;
                    439:                fouropixels[0] = (fouripixels & 0xff000000)
                    440:                    |   ((fouripixels>>8) & 0xff0000)
                    441:                    |   ((fouripixels>>16) & 0xffff);
                    442:                fouropixels[1] = ((fouripixels<<8) & 0xff000000)
                    443:                    |   (fouripixels & 0xffff00)
                    444:                    |   ((fouripixels>>8) & 0xff);
                    445:                fouropixels[2] = ((fouripixels<<16) & 0xffff0000)
                    446:                    |   ((fouripixels<<8) & 0xff00)
                    447:                    |   (fouripixels & 0xff);
                    448: #ifdef __BIG_ENDIAN__
                    449:                *olineptrs[0]++ = fouropixels[0];
                    450:                *olineptrs[1]++ = fouropixels[0];
                    451:                *olineptrs[2]++ = fouropixels[0];
                    452:                *olineptrs[0]++ = fouropixels[1];
                    453:                *olineptrs[1]++ = fouropixels[1];
                    454:                *olineptrs[2]++ = fouropixels[1];
                    455:                *olineptrs[0]++ = fouropixels[2];
                    456:                *olineptrs[1]++ = fouropixels[2];
                    457:                *olineptrs[2]++ = fouropixels[2];
                    458: #else
                    459:                *olineptrs[0]++ = fouropixels[2];
                    460:                *olineptrs[1]++ = fouropixels[2];
                    461:                *olineptrs[2]++ = fouropixels[2];
                    462:                *olineptrs[0]++ = fouropixels[1];
                    463:                *olineptrs[1]++ = fouropixels[1];
                    464:                *olineptrs[2]++ = fouropixels[1];
                    465:                *olineptrs[0]++ = fouropixels[0];
                    466:                *olineptrs[1]++ = fouropixels[0];
                    467:                *olineptrs[2]++ = fouropixels[0];
                    468: #endif
                    469:            } while (x-=4);
                    470:            olineptrs[0] += 2*X_width/4;
                    471:            olineptrs[1] += 2*X_width/4;
                    472:            olineptrs[2] += 2*X_width/4;
                    473:        }
                    474: 
                    475:     }
                    476:     else if (multiply == 4)
                    477:     {
                    478:        // Broken. Gotta fix this some day.
                    479:        void Expand4(unsigned *, double *);
                    480:        Expand4 ((unsigned *)(screens[0]), (double *) (image->data));
                    481:     }
                    482: 
                    483:     if (doShm)
                    484:     {
                    485: 
                    486:        if (!XShmPutImage(      X_display,
                    487:                                X_mainWindow,
                    488:                                X_gc,
                    489:                                image,
                    490:                                0, 0,
                    491:                                0, 0,
                    492:                                X_width, X_height,
                    493:                                True ))
                    494:            I_Error("XShmPutImage() failed\n");
                    495: 
                    496:        // wait for it to finish and processes all input events
                    497:        shmFinished = false;
                    498:        do
                    499:        {
                    500:            I_GetEvent();
                    501:        } while (!shmFinished);
                    502: 
                    503:     }
                    504:     else
                    505:     {
                    506: 
                    507:        // draw the image
                    508:        XPutImage(      X_display,
                    509:                        X_mainWindow,
                    510:                        X_gc,
                    511:                        image,
                    512:                        0, 0,
                    513:                        0, 0,
                    514:                        X_width, X_height );
                    515: 
                    516:        // sync up with server
                    517:        XSync(X_display, False);
                    518: 
                    519:     }
                    520: 
                    521: }
                    522: 
                    523: 
                    524: //
                    525: // I_ReadScreen
                    526: //
                    527: void I_ReadScreen (byte* scr)
                    528: {
                    529:     memcpy (scr, screens[0], SCREENWIDTH*SCREENHEIGHT);
                    530: }
                    531: 
                    532: 
                    533: //
                    534: // Palette stuff.
                    535: //
                    536: static XColor  colors[256];
                    537: 
                    538: void UploadNewPalette(Colormap cmap, byte *palette)
                    539: {
                    540: 
                    541:     register int       i;
                    542:     register int       c;
                    543:     static boolean     firstcall = true;
                    544: 
                    545: #ifdef __cplusplus
                    546:     if (X_visualinfo.c_class == PseudoColor && X_visualinfo.depth == 8)
                    547: #else
                    548:     if (X_visualinfo.class == PseudoColor && X_visualinfo.depth == 8)
                    549: #endif
                    550:        {
                    551:            // initialize the colormap
                    552:            if (firstcall)
                    553:            {
                    554:                firstcall = false;
                    555:                for (i=0 ; i<256 ; i++)
                    556:                {
                    557:                    colors[i].pixel = i;
                    558:                    colors[i].flags = DoRed|DoGreen|DoBlue;
                    559:                }
                    560:            }
                    561: 
                    562:            // set the X colormap entries
                    563:            for (i=0 ; i<256 ; i++)
                    564:            {
                    565:                c = gammatable[usegamma][*palette++];
                    566:                colors[i].red = (c<<8) + c;
                    567:                c = gammatable[usegamma][*palette++];
                    568:                colors[i].green = (c<<8) + c;
                    569:                c = gammatable[usegamma][*palette++];
                    570:                colors[i].blue = (c<<8) + c;
                    571:            }
                    572: 
                    573:            // store the colors to the current colormap
                    574:            XStoreColors(X_display, cmap, colors, 256);
                    575: 
                    576:        }
                    577: }
                    578: 
                    579: //
                    580: // I_SetPalette
                    581: //
                    582: void I_SetPalette (byte* palette)
                    583: {
                    584:     UploadNewPalette(X_cmap, palette);
                    585: }
                    586: 
                    587: 
                    588: //
                    589: // This function is probably redundant,
                    590: //  if XShmDetach works properly.
                    591: // ddt never detached the XShm memory,
                    592: //  thus there might have been stale
                    593: //  handles accumulating.
                    594: //
                    595: void grabsharedmemory(int size)
                    596: {
                    597: 
                    598:   int                  key = ('d'<<24) | ('o'<<16) | ('o'<<8) | 'm';
                    599:   struct shmid_ds      shminfo;
                    600:   int                  minsize = 320*200;
                    601:   int                  id;
                    602:   int                  rc;
                    603:   // UNUSED int done=0;
                    604:   int                  pollution=5;
                    605:   
                    606:   // try to use what was here before
                    607:   do
                    608:   {
                    609:     id = shmget((key_t) key, minsize, 0777); // just get the id
                    610:     if (id != -1)
                    611:     {
                    612:       rc=shmctl(id, IPC_STAT, &shminfo); // get stats on it
                    613:       if (!rc) 
                    614:       {
                    615:        if (shminfo.shm_nattch)
                    616:        {
                    617:          fprintf(stderr, "User %d appears to be running "
                    618:                  "DOOM.  Is that wise?\n", shminfo.shm_cpid);
                    619:          key++;
                    620:        }
                    621:        else
                    622:        {
                    623:          if (getuid() == shminfo.shm_perm.cuid)
                    624:          {
                    625:            rc = shmctl(id, IPC_RMID, 0);
                    626:            if (!rc)
                    627:              fprintf(stderr,
                    628:                      "Was able to kill my old shared memory\n");
                    629:            else
                    630:              I_Error("Was NOT able to kill my old shared memory");
                    631:            
                    632:            id = shmget((key_t)key, size, IPC_CREAT|0777);
                    633:            if (id==-1)
                    634:              I_Error("Could not get shared memory");
                    635:            
                    636:            rc=shmctl(id, IPC_STAT, &shminfo);
                    637:            
                    638:            break;
                    639:            
                    640:          }
                    641:          if (size >= shminfo.shm_segsz)
                    642:          {
                    643:            fprintf(stderr,
                    644:                    "will use %d's stale shared memory\n",
                    645:                    shminfo.shm_cpid);
                    646:            break;
                    647:          }
                    648:          else
                    649:          {
                    650:            fprintf(stderr,
                    651:                    "warning: can't use stale "
                    652:                    "shared memory belonging to id %d, "
                    653:                    "key=0x%x\n",
                    654:                    shminfo.shm_cpid, key);
                    655:            key++;
                    656:          }
                    657:        }
                    658:       }
                    659:       else
                    660:       {
                    661:        I_Error("could not get stats on key=%d", key);
                    662:       }
                    663:     }
                    664:     else
                    665:     {
                    666:       id = shmget((key_t)key, size, IPC_CREAT|0777);
                    667:       if (id==-1)
                    668:       {
                    669:        extern int errno;
                    670:        fprintf(stderr, "errno=%d\n", errno);
                    671:        I_Error("Could not get any shared memory");
                    672:       }
                    673:       break;
                    674:     }
                    675:   } while (--pollution);
                    676:   
                    677:   if (!pollution)
                    678:   {
                    679:     I_Error("Sorry, system too polluted with stale "
                    680:            "shared memory segments.\n");
                    681:     }  
                    682:   
                    683:   X_shminfo.shmid = id;
                    684:   
                    685:   // attach to the shared memory segment
                    686:   image->data = X_shminfo.shmaddr = shmat(id, 0, 0);
                    687:   
                    688:   fprintf(stderr, "shared memory id=%d, addr=0x%x\n", id,
                    689:          (int) (image->data));
                    690: }
                    691: 
                    692: void I_InitGraphics(void)
                    693: {
                    694: 
                    695:     char*              displayname;
                    696:     char*              d;
                    697:     int                        n;
                    698:     int                        pnum;
                    699:     int                        x=0;
                    700:     int                        y=0;
                    701:     
                    702:     // warning: char format, different type arg
                    703:     char               xsign=' ';
                    704:     char               ysign=' ';
                    705:     
                    706:     int                        oktodraw;
                    707:     unsigned long      attribmask;
                    708:     XSetWindowAttributes attribs;
                    709:     XGCValues          xgcvalues;
                    710:     int                        valuemask;
                    711:     static int         firsttime=1;
                    712: 
                    713:     if (!firsttime)
                    714:        return;
                    715:     firsttime = 0;
                    716: 
                    717:     signal(SIGINT, (void (*)(int)) I_Quit);
                    718: 
                    719:     if (M_CheckParm("-2"))
                    720:        multiply = 2;
                    721: 
                    722:     if (M_CheckParm("-3"))
                    723:        multiply = 3;
                    724: 
                    725:     if (M_CheckParm("-4"))
                    726:        multiply = 4;
                    727: 
                    728:     X_width = SCREENWIDTH * multiply;
                    729:     X_height = SCREENHEIGHT * multiply;
                    730: 
                    731:     // check for command-line display name
                    732:     if ( (pnum=M_CheckParm("-disp")) ) // suggest parentheses around assignment
                    733:        displayname = myargv[pnum+1];
                    734:     else
                    735:        displayname = 0;
                    736: 
                    737:     // check if the user wants to grab the mouse (quite unnice)
                    738:     grabMouse = !!M_CheckParm("-grabmouse");
                    739: 
                    740:     // check for command-line geometry
                    741:     if ( (pnum=M_CheckParm("-geom")) ) // suggest parentheses around assignment
                    742:     {
                    743:        // warning: char format, different type arg 3,5
                    744:        n = sscanf(myargv[pnum+1], "%c%d%c%d", &xsign, &x, &ysign, &y);
                    745:        
                    746:        if (n==2)
                    747:            x = y = 0;
                    748:        else if (n==6)
                    749:        {
                    750:            if (xsign == '-')
                    751:                x = -x;
                    752:            if (ysign == '-')
                    753:                y = -y;
                    754:        }
                    755:        else
                    756:            I_Error("bad -geom parameter");
                    757:     }
                    758: 
                    759:     // open the display
                    760:     X_display = XOpenDisplay(displayname);
                    761:     if (!X_display)
                    762:     {
                    763:        if (displayname)
                    764:            I_Error("Could not open display [%s]", displayname);
                    765:        else
                    766:            I_Error("Could not open display (DISPLAY=[%s])", getenv("DISPLAY"));
                    767:     }
                    768: 
                    769:     // use the default visual 
                    770:     X_screen = DefaultScreen(X_display);
                    771:     if (!XMatchVisualInfo(X_display, X_screen, 8, PseudoColor, &X_visualinfo))
                    772:        I_Error("xdoom currently only supports 256-color PseudoColor screens");
                    773:     X_visual = X_visualinfo.visual;
                    774: 
                    775:     // check for the MITSHM extension
                    776:     doShm = XShmQueryExtension(X_display);
                    777: 
                    778:     // even if it's available, make sure it's a local connection
                    779:     if (doShm)
                    780:     {
                    781:        if (!displayname) displayname = (char *) getenv("DISPLAY");
                    782:        if (displayname)
                    783:        {
                    784:            d = displayname;
                    785:            while (*d && (*d != ':')) d++;
                    786:            if (*d) *d = 0;
                    787:            if (!(!strcasecmp(displayname, "unix") || !*displayname)) doShm = false;
                    788:        }
                    789:     }
                    790: 
                    791:     fprintf(stderr, "Using MITSHM extension\n");
                    792: 
                    793:     // create the colormap
                    794:     X_cmap = XCreateColormap(X_display, RootWindow(X_display,
                    795:                                                   X_screen), X_visual, AllocAll);
                    796: 
                    797:     // setup attributes for main window
                    798:     attribmask = CWEventMask | CWColormap | CWBorderPixel;
                    799:     attribs.event_mask =
                    800:        KeyPressMask
                    801:        | KeyReleaseMask
                    802:        // | PointerMotionMask | ButtonPressMask | ButtonReleaseMask
                    803:        | ExposureMask;
                    804: 
                    805:     attribs.colormap = X_cmap;
                    806:     attribs.border_pixel = 0;
                    807: 
                    808:     // create the main window
                    809:     X_mainWindow = XCreateWindow(      X_display,
                    810:                                        RootWindow(X_display, X_screen),
                    811:                                        x, y,
                    812:                                        X_width, X_height,
                    813:                                        0, // borderwidth
                    814:                                        8, // depth
                    815:                                        InputOutput,
                    816:                                        X_visual,
                    817:                                        attribmask,
                    818:                                        &attribs );
                    819: 
                    820:     XDefineCursor(X_display, X_mainWindow,
                    821:                  createnullcursor( X_display, X_mainWindow ) );
                    822: 
                    823:     // create the GC
                    824:     valuemask = GCGraphicsExposures;
                    825:     xgcvalues.graphics_exposures = False;
                    826:     X_gc = XCreateGC(  X_display,
                    827:                        X_mainWindow,
                    828:                        valuemask,
                    829:                        &xgcvalues );
                    830: 
                    831:     // map the window
                    832:     XMapWindow(X_display, X_mainWindow);
                    833: 
                    834:     // wait until it is OK to draw
                    835:     oktodraw = 0;
                    836:     while (!oktodraw)
                    837:     {
                    838:        XNextEvent(X_display, &X_event);
                    839:        if (X_event.type == Expose
                    840:            && !X_event.xexpose.count)
                    841:        {
                    842:            oktodraw = 1;
                    843:        }
                    844:     }
                    845: 
                    846:     // grabs the pointer so it is restricted to this window
                    847:     if (grabMouse)
                    848:        XGrabPointer(X_display, X_mainWindow, True,
                    849:                     ButtonPressMask|ButtonReleaseMask|PointerMotionMask,
                    850:                     GrabModeAsync, GrabModeAsync,
                    851:                     X_mainWindow, None, CurrentTime);
                    852: 
                    853:     if (doShm)
                    854:     {
                    855: 
                    856:        X_shmeventtype = XShmGetEventBase(X_display) + ShmCompletion;
                    857: 
                    858:        // create the image
                    859:        image = XShmCreateImage(        X_display,
                    860:                                        X_visual,
                    861:                                        8,
                    862:                                        ZPixmap,
                    863:                                        0,
                    864:                                        &X_shminfo,
                    865:                                        X_width,
                    866:                                        X_height );
                    867: 
                    868:        grabsharedmemory(image->bytes_per_line * image->height);
                    869: 
                    870: 
                    871:        // UNUSED
                    872:        // create the shared memory segment
                    873:        // X_shminfo.shmid = shmget (IPC_PRIVATE,
                    874:        // image->bytes_per_line * image->height, IPC_CREAT | 0777);
                    875:        // if (X_shminfo.shmid < 0)
                    876:        // {
                    877:        // perror("");
                    878:        // I_Error("shmget() failed in InitGraphics()");
                    879:        // }
                    880:        // fprintf(stderr, "shared memory id=%d\n", X_shminfo.shmid);
                    881:        // attach to the shared memory segment
                    882:        // image->data = X_shminfo.shmaddr = shmat(X_shminfo.shmid, 0, 0);
                    883:        
                    884: 
                    885:        if (!image->data)
                    886:        {
                    887:            perror("");
                    888:            I_Error("shmat() failed in InitGraphics()");
                    889:        }
                    890: 
                    891:        // get the X server to attach to it
                    892:        if (!XShmAttach(X_display, &X_shminfo))
                    893:            I_Error("XShmAttach() failed in InitGraphics()");
                    894: 
                    895:     }
                    896:     else
                    897:     {
                    898:        image = XCreateImage(   X_display,
                    899:                                X_visual,
                    900:                                8,
                    901:                                ZPixmap,
                    902:                                0,
                    903:                                (char*)malloc(X_width * X_height),
                    904:                                X_width, X_height,
                    905:                                8,
                    906:                                X_width );
                    907: 
                    908:     }
                    909: 
                    910:     if (multiply == 1)
                    911:        screens[0] = (unsigned char *) (image->data);
                    912:     else
                    913:        screens[0] = (unsigned char *) malloc (SCREENWIDTH * SCREENHEIGHT);
                    914: 
                    915: }
                    916: 
                    917: 
                    918: unsigned       exptable[256];
                    919: 
                    920: void InitExpand (void)
                    921: {
                    922:     int                i;
                    923:        
                    924:     for (i=0 ; i<256 ; i++)
                    925:        exptable[i] = i | (i<<8) | (i<<16) | (i<<24);
                    926: }
                    927: 
                    928: double         exptable2[256*256];
                    929: 
                    930: void InitExpand2 (void)
                    931: {
                    932:     int                i;
                    933:     int                j;
                    934:     // UNUSED unsigned iexp, jexp;
                    935:     double*    exp;
                    936:     union
                    937:     {
                    938:        double          d;
                    939:        unsigned        u[2];
                    940:     } pixel;
                    941:        
                    942:     printf ("building exptable2...\n");
                    943:     exp = exptable2;
                    944:     for (i=0 ; i<256 ; i++)
                    945:     {
                    946:        pixel.u[0] = i | (i<<8) | (i<<16) | (i<<24);
                    947:        for (j=0 ; j<256 ; j++)
                    948:        {
                    949:            pixel.u[1] = j | (j<<8) | (j<<16) | (j<<24);
                    950:            *exp++ = pixel.d;
                    951:        }
                    952:     }
                    953:     printf ("done.\n");
                    954: }
                    955: 
                    956: int    inited;
                    957: 
                    958: void
                    959: Expand4
                    960: ( unsigned*    lineptr,
                    961:   double*      xline )
                    962: {
                    963:     double     dpixel;
                    964:     unsigned   x;
                    965:     unsigned   y;
                    966:     unsigned   fourpixels;
                    967:     unsigned   step;
                    968:     double*    exp;
                    969:        
                    970:     exp = exptable2;
                    971:     if (!inited)
                    972:     {
                    973:        inited = 1;
                    974:        InitExpand2 ();
                    975:     }
                    976:                
                    977:                
                    978:     step = 3*SCREENWIDTH/2;
                    979:        
                    980:     y = SCREENHEIGHT-1;
                    981:     do
                    982:     {
                    983:        x = SCREENWIDTH;
                    984: 
                    985:        do
                    986:        {
                    987:            fourpixels = lineptr[0];
                    988:                        
                    989:            dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff0000)>>13) );
                    990:            xline[0] = dpixel;
                    991:            xline[160] = dpixel;
                    992:            xline[320] = dpixel;
                    993:            xline[480] = dpixel;
                    994:                        
                    995:            dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff)<<3 ) );
                    996:            xline[1] = dpixel;
                    997:            xline[161] = dpixel;
                    998:            xline[321] = dpixel;
                    999:            xline[481] = dpixel;
                   1000: 
                   1001:            fourpixels = lineptr[1];
                   1002:                        
                   1003:            dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff0000)>>13) );
                   1004:            xline[2] = dpixel;
                   1005:            xline[162] = dpixel;
                   1006:            xline[322] = dpixel;
                   1007:            xline[482] = dpixel;
                   1008:                        
                   1009:            dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff)<<3 ) );
                   1010:            xline[3] = dpixel;
                   1011:            xline[163] = dpixel;
                   1012:            xline[323] = dpixel;
                   1013:            xline[483] = dpixel;
                   1014: 
                   1015:            fourpixels = lineptr[2];
                   1016:                        
                   1017:            dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff0000)>>13) );
                   1018:            xline[4] = dpixel;
                   1019:            xline[164] = dpixel;
                   1020:            xline[324] = dpixel;
                   1021:            xline[484] = dpixel;
                   1022:                        
                   1023:            dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff)<<3 ) );
                   1024:            xline[5] = dpixel;
                   1025:            xline[165] = dpixel;
                   1026:            xline[325] = dpixel;
                   1027:            xline[485] = dpixel;
                   1028: 
                   1029:            fourpixels = lineptr[3];
                   1030:                        
                   1031:            dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff0000)>>13) );
                   1032:            xline[6] = dpixel;
                   1033:            xline[166] = dpixel;
                   1034:            xline[326] = dpixel;
                   1035:            xline[486] = dpixel;
                   1036:                        
                   1037:            dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff)<<3 ) );
                   1038:            xline[7] = dpixel;
                   1039:            xline[167] = dpixel;
                   1040:            xline[327] = dpixel;
                   1041:            xline[487] = dpixel;
                   1042: 
                   1043:            lineptr+=4;
                   1044:            xline+=8;
                   1045:        } while (x-=16);
                   1046:        xline += step;
                   1047:     } while (y--);
                   1048: }
                   1049: 
                   1050: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.