Annotation of doom/i_video.c, revision 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.