Annotation of doom/i_viorig, 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 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.