Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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 SDL library
  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.  
  29. #include "SDL.h"
  30.  
  31. #include "m_swap.h"
  32. #include "doomstat.h"
  33. #include "i_system.h"
  34. #include "v_video.h"
  35. #include "m_argv.h"
  36. #include "d_main.h"
  37.  
  38. #include "doomdef.h"
  39.  
  40.  
  41. SDL_Surface *screen;
  42.  
  43. // Fake mouse handling.
  44. boolean         grabMouse;
  45.  
  46. // Blocky mode,
  47. // replace each 320x200 pixel with multiply*multiply pixels.
  48. // According to Dave Taylor, it still is a bonehead thing
  49. // to use ....
  50. static int      multiply=2;
  51.  
  52.  
  53. //
  54. //  Translates the key
  55. //
  56.  
  57. int xlatekey(SDL_keysym *key)
  58. {
  59.  
  60.     int rc;
  61.  
  62.     switch(key->sym)
  63.     {
  64.       case SDLK_LEFT:   rc = KEY_LEFTARROW;     break;
  65.       case SDLK_RIGHT:  rc = KEY_RIGHTARROW;    break;
  66.       case SDLK_DOWN:   rc = KEY_DOWNARROW;     break;
  67.       case SDLK_UP:     rc = KEY_UPARROW;       break;
  68.       case SDLK_ESCAPE: rc = KEY_ESCAPE;        break;
  69.       case SDLK_RETURN: rc = KEY_ENTER;         break;
  70.       case SDLK_TAB:    rc = KEY_TAB;           break;
  71.       case SDLK_F1:     rc = KEY_F1;            break;
  72.       case SDLK_F2:     rc = KEY_F2;            break;
  73.       case SDLK_F3:     rc = KEY_F3;            break;
  74.       case SDLK_F4:     rc = KEY_F4;            break;
  75.       case SDLK_F5:     rc = KEY_F5;            break;
  76.       case SDLK_F6:     rc = KEY_F6;            break;
  77.       case SDLK_F7:     rc = KEY_F7;            break;
  78.       case SDLK_F8:     rc = KEY_F8;            break;
  79.       case SDLK_F9:     rc = KEY_F9;            break;
  80.       case SDLK_F10:    rc = KEY_F10;           break;
  81.       case SDLK_F11:    rc = KEY_F11;           break;
  82.       case SDLK_F12:    rc = KEY_F12;           break;
  83.        
  84.       case SDLK_BACKSPACE:
  85.       case SDLK_DELETE: rc = KEY_BACKSPACE;     break;
  86.  
  87.       case SDLK_PAUSE:  rc = KEY_PAUSE;         break;
  88.  
  89.       case SDLK_EQUALS: rc = KEY_EQUALS;        break;
  90.  
  91.       case SDLK_KP_MINUS:
  92.       case SDLK_MINUS:  rc = KEY_MINUS;         break;
  93.  
  94.       case SDLK_LSHIFT:
  95.       case SDLK_RSHIFT:
  96.         rc = KEY_RSHIFT;
  97.         break;
  98.        
  99.       case SDLK_LCTRL:
  100.       case SDLK_RCTRL:
  101.         rc = KEY_RCTRL;
  102.         break;
  103.        
  104.       case SDLK_LALT:
  105.       case SDLK_LMETA:
  106.       case SDLK_RALT:
  107.       case SDLK_RMETA:
  108.         rc = KEY_RALT;
  109.         break;
  110.        
  111.       default:
  112.         rc = key->sym;
  113.         break;
  114.     }
  115.  
  116.     return rc;
  117.  
  118. }
  119.  
  120. void I_ShutdownGraphics(void)
  121. {
  122.   SDL_Quit();
  123. }
  124.  
  125.  
  126.  
  127. //
  128. // I_StartFrame
  129. //
  130. void I_StartFrame (void)
  131. {
  132.     // er?
  133.  
  134. }
  135.  
  136. /* This processes SDL events */
  137. void I_GetEvent(SDL_Event *Event)
  138. {
  139.     Uint8 buttonstate;
  140.     event_t event;
  141.  
  142.     switch (Event->type)
  143.     {
  144.       case SDL_KEYDOWN:
  145.         event.type = ev_keydown;
  146.         event.data1 = xlatekey(&Event->key.keysym);
  147.         D_PostEvent(&event);
  148.         break;
  149.  
  150.       case SDL_KEYUP:
  151.         event.type = ev_keyup;
  152.         event.data1 = xlatekey(&Event->key.keysym);
  153.         D_PostEvent(&event);
  154.         break;
  155.  
  156.       case SDL_MOUSEBUTTONDOWN:
  157.       case SDL_MOUSEBUTTONUP:
  158.         buttonstate = SDL_GetMouseState(NULL, NULL);
  159.         event.type = ev_mouse;
  160.         event.data1 = 0
  161.             | (buttonstate & SDL_BUTTON(1) ? 1 : 0)
  162.             | (buttonstate & SDL_BUTTON(2) ? 2 : 0)
  163.             | (buttonstate & SDL_BUTTON(3) ? 4 : 0);
  164.         event.data2 = event.data3 = 0;
  165.         D_PostEvent(&event);
  166.         break;
  167.  
  168. #if (SDL_MAJOR_VERSION >= 0) && (SDL_MINOR_VERSION >= 9)
  169.       case SDL_MOUSEMOTION:
  170.         /* Ignore mouse warp events */
  171.         if ((Event->motion.x != screen->w/2)||(Event->motion.y != screen->h/2))
  172.         {
  173.             /* Warp the mouse back to the center */
  174.             if (grabMouse) {
  175.                 SDL_WarpMouse(screen->w/2, screen->h/2);
  176.             }
  177.             event.type = ev_mouse;
  178.             event.data1 = 0
  179.                 | (Event->motion.state & SDL_BUTTON(1) ? 1 : 0)
  180.                 | (Event->motion.state & SDL_BUTTON(2) ? 2 : 0)
  181.                 | (Event->motion.state & SDL_BUTTON(3) ? 4 : 0);
  182.             event.data2 = Event->motion.xrel << 2;
  183.             event.data3 = -Event->motion.yrel << 2;
  184.             D_PostEvent(&event);
  185.         }
  186.         break;
  187. #endif
  188.  
  189.       case SDL_QUIT:
  190.         I_Quit();
  191.     }
  192.  
  193. }
  194.  
  195. //
  196. // I_StartTic
  197. //
  198. void I_StartTic (void)
  199. {
  200.     SDL_Event Event;
  201.  
  202.     while ( SDL_PollEvent(&Event) )
  203.         I_GetEvent(&Event);
  204. }
  205.  
  206.  
  207. //
  208. // I_UpdateNoBlit
  209. //
  210. void I_UpdateNoBlit (void)
  211. {
  212.     // what is this?
  213. }
  214.  
  215. //
  216. // I_FinishUpdate
  217. //
  218. void I_FinishUpdate (void)
  219. {
  220.  
  221.     static int  lasttic;
  222.     int         tics;
  223.     int         i;
  224.  
  225.     // draws little dots on the bottom of the screen
  226.     if (devparm)
  227.     {
  228.  
  229.         i = I_GetTime();
  230.         tics = i - lasttic;
  231.         lasttic = i;
  232.         if (tics > 20) tics = 20;
  233.  
  234.         for (i=0 ; i<tics*2 ; i+=2)
  235.             screens[0][ (SCREENHEIGHT-1)*SCREENWIDTH + i] = 0xff;
  236.         for ( ; i<20*2 ; i+=2)
  237.             screens[0][ (SCREENHEIGHT-1)*SCREENWIDTH + i] = 0x0;
  238.     }
  239.  
  240.     // scales the screen size before blitting it
  241.     if ( SDL_MUSTLOCK(screen) ) {
  242.         if ( SDL_LockSurface(screen) < 0 ) {
  243.             return;
  244.         }
  245.     }
  246.     if ((multiply == 1) && SDL_MUSTLOCK(screen))
  247.     {
  248.         unsigned char *olineptr;
  249.         unsigned char *ilineptr;
  250.         int y;
  251.  
  252.         ilineptr = (unsigned char *) screens[0];
  253.         olineptr = (unsigned char *) screen->pixels;
  254.  
  255.         y = SCREENHEIGHT;
  256.         while (y--)
  257.         {
  258.             memcpy(olineptr, ilineptr, screen->w);
  259.             ilineptr += SCREENWIDTH;
  260.             olineptr += screen->pitch;
  261.         }
  262.     }
  263.     else if (multiply == 2)
  264.     {
  265.         unsigned int *olineptrs[2];
  266.         unsigned int *ilineptr;
  267.         int x, y, i;
  268.         unsigned int twoopixels;
  269.         unsigned int twomoreopixels;
  270.         unsigned int fouripixels;
  271.  
  272.         ilineptr = (unsigned int *) (screens[0]);
  273.         for (i=0 ; i<2 ; i++) {
  274.             olineptrs[i] =
  275.                 (unsigned int *)&((Uint8 *)screen->pixels)[i*screen->pitch];
  276.         }
  277.  
  278.         y = SCREENHEIGHT;
  279.         while (y--)
  280.         {
  281.             x = SCREENWIDTH;
  282.             do
  283.             {
  284.                 fouripixels = *ilineptr++;
  285.                 twoopixels =    (fouripixels & 0xff000000)
  286.                     |   ((fouripixels>>8) & 0xffff00)
  287.                     |   ((fouripixels>>16) & 0xff);
  288.                 twomoreopixels =        ((fouripixels<<16) & 0xff000000)
  289.                     |   ((fouripixels<<8) & 0xffff00)
  290.                     |   (fouripixels & 0xff);
  291. #ifdef __BIG_ENDIAN__
  292.                 *olineptrs[0]++ = twoopixels;
  293.                 *olineptrs[1]++ = twoopixels;
  294.                 *olineptrs[0]++ = twomoreopixels;
  295.                 *olineptrs[1]++ = twomoreopixels;
  296. #else
  297.                 *olineptrs[0]++ = twomoreopixels;
  298.                 *olineptrs[1]++ = twomoreopixels;
  299.                 *olineptrs[0]++ = twoopixels;
  300.                 *olineptrs[1]++ = twoopixels;
  301. #endif
  302.             } while (x-=4);
  303.             olineptrs[0] += screen->pitch/4;
  304.             olineptrs[1] += screen->pitch/4;
  305.         }
  306.  
  307.     }
  308.     else if (multiply == 3)
  309.     {
  310.         unsigned int *olineptrs[3];
  311.         unsigned int *ilineptr;
  312.         int x, y, i;
  313.         unsigned int fouropixels[3];
  314.         unsigned int fouripixels;
  315.  
  316.         ilineptr = (unsigned int *) (screens[0]);
  317.         for (i=0 ; i<3 ; i++) {
  318.             olineptrs[i] =
  319.                 (unsigned int *)&((Uint8 *)screen->pixels)[i*screen->pitch];
  320.         }
  321.  
  322.         y = SCREENHEIGHT;
  323.         while (y--)
  324.         {
  325.             x = SCREENWIDTH;
  326.             do
  327.             {
  328.                 fouripixels = *ilineptr++;
  329.                 fouropixels[0] = (fouripixels & 0xff000000)
  330.                     |   ((fouripixels>>8) & 0xff0000)
  331.                     |   ((fouripixels>>16) & 0xffff);
  332.                 fouropixels[1] = ((fouripixels<<8) & 0xff000000)
  333.                     |   (fouripixels & 0xffff00)
  334.                     |   ((fouripixels>>8) & 0xff);
  335.                 fouropixels[2] = ((fouripixels<<16) & 0xffff0000)
  336.                     |   ((fouripixels<<8) & 0xff00)
  337.                     |   (fouripixels & 0xff);
  338. #ifdef __BIG_ENDIAN__
  339.                 *olineptrs[0]++ = fouropixels[0];
  340.                 *olineptrs[1]++ = fouropixels[0];
  341.                 *olineptrs[2]++ = fouropixels[0];
  342.                 *olineptrs[0]++ = fouropixels[1];
  343.                 *olineptrs[1]++ = fouropixels[1];
  344.                 *olineptrs[2]++ = fouropixels[1];
  345.                 *olineptrs[0]++ = fouropixels[2];
  346.                 *olineptrs[1]++ = fouropixels[2];
  347.                 *olineptrs[2]++ = fouropixels[2];
  348. #else
  349.                 *olineptrs[0]++ = fouropixels[2];
  350.                 *olineptrs[1]++ = fouropixels[2];
  351.                 *olineptrs[2]++ = fouropixels[2];
  352.                 *olineptrs[0]++ = fouropixels[1];
  353.                 *olineptrs[1]++ = fouropixels[1];
  354.                 *olineptrs[2]++ = fouropixels[1];
  355.                 *olineptrs[0]++ = fouropixels[0];
  356.                 *olineptrs[1]++ = fouropixels[0];
  357.                 *olineptrs[2]++ = fouropixels[0];
  358. #endif
  359.             } while (x-=4);
  360.             olineptrs[0] += 2*screen->pitch/4;
  361.             olineptrs[1] += 2*screen->pitch/4;
  362.             olineptrs[2] += 2*screen->pitch/4;
  363.         }
  364.  
  365.     }
  366.     if ( SDL_MUSTLOCK(screen) ) {
  367.         SDL_UnlockSurface(screen);
  368.     }
  369.     SDL_UpdateRect(screen, 0, 0, 0, 0);
  370. }
  371.  
  372.  
  373. //
  374. // I_ReadScreen
  375. //
  376. void I_ReadScreen (byte* scr)
  377. {
  378.     memcpy (scr, screens[0], SCREENWIDTH*SCREENHEIGHT);
  379. }
  380.  
  381.  
  382. //
  383. // I_SetPalette
  384. //
  385. void I_SetPalette (byte* palette)
  386. {
  387.     int i;
  388.     SDL_Color colors[256];
  389.  
  390.     for ( i=0; i<256; ++i ) {
  391.         colors[i].r = gammatable[usegamma][*palette++];
  392.         colors[i].g = gammatable[usegamma][*palette++];
  393.         colors[i].b = gammatable[usegamma][*palette++];
  394.         colors[i].unused = 0;
  395.     }
  396.     SDL_SetColors(screen, colors, 0, 256);
  397. }
  398.  
  399.  
  400. void I_InitGraphics(void)
  401. {
  402.  
  403.     static int  firsttime=1;
  404.     Uint16 video_w, video_h, w, h;
  405.     Uint8 video_bpp;
  406.     Uint32 video_flags;
  407.  
  408.     if (!firsttime)
  409.         return;
  410.     firsttime = 0;
  411.  
  412.     video_flags = (SDL_SWSURFACE|SDL_HWPALETTE);
  413.     if (!!M_CheckParm("-fullscreen"))
  414.         video_flags |= SDL_FULLSCREEN;
  415.  
  416.     if (M_CheckParm("-2"))
  417.         multiply = 2;
  418.  
  419.     if (M_CheckParm("-3"))
  420.         multiply = 3;
  421.  
  422.     // check if the user wants to grab the mouse (quite unnice)
  423.     grabMouse = !!M_CheckParm("-grabmouse");
  424.  
  425.     video_w = w = SCREENWIDTH * multiply;
  426.     video_h = h = SCREENHEIGHT * multiply;
  427.     video_bpp = 8;
  428.  
  429.     /* We need to allocate a software surface because the DOOM! code expects
  430.        the screen surface to be valid all of the time.  Properly done, the
  431.        rendering code would allocate the video surface in video memory and
  432.        then call SDL_LockSurface()/SDL_UnlockSurface() around frame rendering.
  433.        Eventually SDL will support flipping, which would be really nice in
  434.        a complete-frame rendering application like this.
  435.     */
  436.     switch (video_w/w) {
  437.         case 3:
  438.             multiply *= 3;
  439.             break;
  440.         case 2:
  441.             multiply *= 2;
  442.             break;
  443.         case 1:
  444.             multiply *= 1;
  445.             break;
  446.         default:
  447.                 ;
  448.     }
  449.     if ( multiply > 3 ) {
  450.         I_Error("Smallest available mode (%dx%d) is too large!",
  451.                                                 video_w, video_h);
  452.     }
  453.     screen = SDL_SetVideoMode(video_w, video_h, 8, video_flags);
  454.     if ( screen == NULL ) {
  455.         I_Error("Could not set %dx%d video mode: %s", video_w, video_h,
  456.                                                         SDL_GetError());
  457.     }
  458.     SDL_ShowCursor(0);
  459.     SDL_WM_SetCaption("SDL DOOM! v1.10", "doom");
  460.  
  461.     /* Set up the screen displays */
  462.     w = SCREENWIDTH * multiply;
  463.     h = SCREENHEIGHT * multiply;
  464.     if (multiply == 1 && !SDL_MUSTLOCK(screen) ) {
  465.         screens[0] = (unsigned char *) screen->pixels;
  466.     } else {
  467.         screens[0] = (unsigned char *) malloc (SCREENWIDTH * SCREENHEIGHT);
  468.         if ( screens[0] == NULL )
  469.             I_Error("Couldn't allocate screen memory");
  470.     }
  471. }
  472.