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

unix.superglobalmegacorp.com

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