Subversion Repositories Games.Rick Dangerous

Rev

Rev 2 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * src/sysvid.c
  3.  *
  4.  * Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
  5.  *
  6.  * The use and distribution terms for this software are contained in the file
  7.  * named README, which can be found in the root of this distribution. By
  8.  * using this software in any fashion, you are agreeing to be bound by the
  9.  * terms of this license.
  10.  *
  11.  * You must not remove this notice, or any other, from this software.
  12.  */
  13.  
  14. #include <malloc.h> // malloc
  15. #include <memory.h> // memset
  16.  
  17. #include <SDL.h>
  18.  
  19. #include "system.h"
  20. #include "game.h"
  21. #include "img.h"
  22.  
  23. #define SYSVID_WIDTH 640
  24. #define SYSVID_HEIGHT 480
  25. #define SYSVID_BPP 32
  26.  
  27. U8 *sysvid_fb; // frame buffer
  28. U8 want_fullscreen = TRUE;
  29. U8 want_filter = TRUE;
  30. U8 redraw_screen = FALSE;
  31.  
  32. static SDL_Surface *screen;
  33.  
  34.  
  35. // Initialise video
  36. void sysvid_init (void)
  37. {
  38.    // create frame buffer
  39.    sysvid_fb = malloc (320 * 200);
  40.    if (sysvid_fb == NULL)
  41.       sys_panic ("Fatal error: frame buffer allocation failed.\n");
  42.  
  43.    // SDL init
  44.    if (SDL_Init (SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0)
  45.       sys_panic ("Fatal error: could not initialize SDL.\n");
  46.  
  47.    SDL_WM_SetCaption ("Rick Dangerous", "Rick Dangerous");
  48.    SDL_ShowCursor (SDL_DISABLE);
  49.  
  50.    // check video modes
  51.    if (SDL_ListModes (NULL, SDL_FULLSCREEN) == 0)
  52.       sys_panic ("Fatal error: SDL can not find an appropriate video mode.\n");
  53.  
  54.    // set video mode
  55.    screen = SDL_SetVideoMode (SYSVID_WIDTH, SYSVID_HEIGHT, SYSVID_BPP, (want_fullscreen ? SDL_FULLSCREEN : 0));
  56. }
  57.  
  58.  
  59. // Shutdown video
  60. void sysvid_shutdown (void)
  61. {
  62.    // destroy frame buffer
  63.    if (sysvid_fb)
  64.       free (sysvid_fb);
  65.    sysvid_fb = NULL;
  66.  
  67.    // SDL quit
  68.    SDL_Quit ();
  69. }
  70.  
  71.  
  72. // Clear screen
  73. void sysvid_clear (void)
  74. {
  75.    memset (sysvid_fb, 0, 320 * 200);
  76. }
  77.  
  78.  
  79. // Update screen
  80. void sysvid_paint (rect_t *rects)
  81. {
  82.    static SDL_Rect area;
  83.    static rect_t rect_screen = {0, 0, 320, 200, NULL};
  84.    static int pixel_size = SYSVID_BPP / 8;
  85.    static int zoom = SYSVID_WIDTH / 320;
  86.    static U8 palette[16][3] =
  87.    {
  88.       {0x00, 0x00, 0x00},
  89.       {0xd8, 0x00, 0x00},
  90.       {0xb0, 0x6c, 0x68},
  91.       {0xf8, 0x90, 0x68},
  92.       {0x20, 0x24, 0x20},
  93.       {0x00, 0x48, 0xb0},
  94.       {0x00, 0x6c, 0xd8},
  95.       {0x20, 0x48, 0x00},
  96.       {0x48, 0x6c, 0x20},
  97.       {0x48, 0x24, 0x00},
  98.       {0x90, 0x48, 0x00},
  99.       {0xd8, 0x6c, 0x00},
  100.       {0x48, 0x48, 0x48},
  101.       {0x68, 0x6c, 0x68},
  102.       {0x90, 0x90, 0x90},
  103.       {0xb0, 0xb4, 0xb0}
  104.    };
  105.    U16 x, y, xz, yz;
  106.    U8 *p, *q, *p0, *q0;
  107.  
  108.    if (rects == NULL)
  109.       return;
  110.  
  111.    if (redraw_screen)
  112.    {
  113.       redraw_screen = FALSE;
  114.       screen = SDL_SetVideoMode (SYSVID_WIDTH, SYSVID_HEIGHT, SYSVID_BPP, (want_fullscreen ? SDL_FULLSCREEN : 0));
  115.       sysvid_paint (&rect_screen);
  116.    }
  117.  
  118.    while (rects)
  119.    {
  120.       p0 = sysvid_fb;
  121.       p0 += rects->x + rects->y * 320;
  122.       q0 = (U8 *)screen->pixels;
  123.       q0 += (pixel_size * rects->x + pixel_size * (rects->y + 20) * 320 * zoom) * zoom;
  124.  
  125.       for (y = (rects->y + 20); y < (rects->y + 20) + rects->height; y++)
  126.       {
  127.          for (yz = 0; yz < zoom; yz++)
  128.          {
  129.             p = p0;
  130.             q = q0;
  131.  
  132.             for (x = rects->x; x < rects->x + rects->width; x++)
  133.             {
  134.                for (xz = 0; xz < zoom; xz++)
  135.                {
  136.                   if (want_filter && (y + yz < 220))
  137.                   {
  138.                      *(q + 0) = (U8) ((  (U32) ((zoom - xz) * (U32) palette[*(   p   )][2]
  139.                                                 +    xz     * (U32) palette[*( p + 1 )][2])
  140.                                        + (U32) ((zoom - yz) * (U32) palette[*(   p   )][2]
  141.                                                 +    yz     * (U32) palette[*(p + 320)][2]))
  142.                                       / (zoom * zoom));
  143.  
  144.                      *(q + 1) = (U8) ((  (U32) ((zoom - xz) * (U32) palette[*(   p   )][1]
  145.                                                 +    xz     * (U32) palette[*( p + 1 )][1])
  146.                                        + (U32) ((zoom - yz) * (U32) palette[*(   p   )][1]
  147.                                                 +    yz     * (U32) palette[*(p + 320)][1]))
  148.                                       / (zoom * zoom));
  149.  
  150.                      *(q + 2) = (U8) ((  (U32) ((zoom - xz) * (U32) palette[*(   p   )][0]
  151.                                                 +    xz     * (U32) palette[*( p + 1 )][0])
  152.                                        + (U32) ((zoom - yz) * (U32) palette[*(   p   )][0]
  153.                                                 +    yz     * (U32) palette[*(p + 320)][0]))
  154.                                       / (zoom * zoom));
  155.                      *(q + 3) = 0;
  156.                   }
  157.                   else
  158.                   {
  159.                      *(q + 0) = palette[*p][2];
  160.                      *(q + 1) = palette[*p][1];
  161.                      *(q + 2) = palette[*p][0];
  162.                      *(q + 3) = 0;
  163.                   }
  164.  
  165.                   q += pixel_size;
  166.                }
  167.  
  168.                p++;
  169.             }
  170.  
  171.             q0 += 320 * pixel_size * zoom;
  172.          }
  173.  
  174.          p0 += 320;
  175.       }
  176.      
  177.       area.x = rects->x * zoom;
  178.       area.y = (rects->y + 20) * zoom;
  179.       area.h = rects->height * zoom;
  180.       area.w = rects->width * zoom;
  181.       SDL_UpdateRects (screen, 1, &area);
  182.  
  183.       rects = rects->next;
  184.    }
  185. }
  186.