Subversion Repositories Games.Rick Dangerous

Rev

Rev 1 | 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 <stdlib.h> // malloc
  15. #include <string.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. #ifdef __APPLE__
  28. #define INDEX_A 0
  29. #define INDEX_R 1
  30. #define INDEX_G 2
  31. #define INDEX_B 3
  32. #else // !__APPLE__
  33. #define INDEX_B 0
  34. #define INDEX_G 1
  35. #define INDEX_R 2
  36. #define INDEX_A 3
  37. #endif // __APPLE__
  38.  
  39. U8 *sysvid_fb; // frame buffer
  40. U8 want_fullscreen = FALSE;// TRUE;
  41. U8 want_filter = TRUE;
  42. U8 redraw_screen = FALSE;
  43.  
  44. static SDL_Surface *screen;
  45.  
  46.  
  47. // Initialise video
  48. void sysvid_init (void)
  49. {
  50.    // create frame buffer
  51.    sysvid_fb = malloc (320 * 200);
  52.    if (sysvid_fb == NULL)
  53.       sys_panic ("Fatal error: frame buffer allocation failed.\n");
  54.  
  55.    // SDL init
  56.    if (SDL_Init (SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0)
  57.       sys_panic ("Fatal error: could not initialize SDL.\n");
  58.  
  59.    SDL_WM_SetCaption ("Rick Dangerous", "Rick Dangerous");
  60.    SDL_ShowCursor (SDL_DISABLE);
  61.  
  62.    // check video modes
  63.    if (SDL_ListModes (NULL, SDL_FULLSCREEN) == 0)
  64.       sys_panic ("Fatal error: SDL can not find an appropriate video mode.\n");
  65.  
  66.    // set video mode
  67.    screen = SDL_SetVideoMode (SYSVID_WIDTH, SYSVID_HEIGHT, SYSVID_BPP, (want_fullscreen ? SDL_FULLSCREEN : 0));
  68. }
  69.  
  70.  
  71. // Shutdown video
  72. void sysvid_shutdown (void)
  73. {
  74.    // destroy frame buffer
  75.    if (sysvid_fb)
  76.       free (sysvid_fb);
  77.    sysvid_fb = NULL;
  78.  
  79.    // SDL quit
  80.    SDL_Quit ();
  81. }
  82.  
  83.  
  84. // Clear screen
  85. void sysvid_clear (void)
  86. {
  87.    memset (sysvid_fb, 0, 320 * 200);
  88. }
  89.  
  90.  
  91. // Update screen
  92. void sysvid_paint (rect_t *rects)
  93. {
  94.    static SDL_Rect area;
  95.    static rect_t rect_screen = {0, 0, 320, 200, NULL};
  96.    static int pixel_size = SYSVID_BPP / 8;
  97.    static int zoom = SYSVID_WIDTH / 320;
  98.    static U8 palette[16][3] =
  99.    {
  100.       {0x00, 0x00, 0x00},
  101.       {0xd8, 0x00, 0x00},
  102.       {0xb0, 0x6c, 0x68},
  103.       {0xf8, 0x90, 0x68},
  104.       {0x20, 0x24, 0x20},
  105.       {0x00, 0x48, 0xb0},
  106.       {0x00, 0x6c, 0xd8},
  107.       {0x20, 0x48, 0x00},
  108.       {0x48, 0x6c, 0x20},
  109.       {0x48, 0x24, 0x00},
  110.       {0x90, 0x48, 0x00},
  111.       {0xd8, 0x6c, 0x00},
  112.       {0x48, 0x48, 0x48},
  113.       {0x68, 0x6c, 0x68},
  114.       {0x90, 0x90, 0x90},
  115.       {0xb0, 0xb4, 0xb0}
  116.    };
  117.    U16 x, y, xz, yz;
  118.    U8 *p, *q, *p0, *q0;
  119.  
  120.    if (rects == NULL)
  121.       return;
  122.  
  123.    if (redraw_screen)
  124.    {
  125.       redraw_screen = FALSE;
  126.       screen = SDL_SetVideoMode (SYSVID_WIDTH, SYSVID_HEIGHT, SYSVID_BPP, (want_fullscreen ? SDL_FULLSCREEN : 0));
  127.       sysvid_paint (&rect_screen);
  128.    }
  129.  
  130.    while (rects)
  131.    {
  132.       p0 = sysvid_fb;
  133.       p0 += rects->x + rects->y * 320;
  134.       q0 = (U8 *)screen->pixels;
  135.       q0 += (pixel_size * rects->x + pixel_size * (rects->y + 20) * 320 * zoom) * zoom;
  136.  
  137.       for (y = (rects->y + 20); y < (rects->y + 20) + rects->height; y++)
  138.       {
  139.          for (yz = 0; yz < zoom; yz++)
  140.          {
  141.             p = p0;
  142.             q = q0;
  143.  
  144.             for (x = rects->x; x < rects->x + rects->width; x++)
  145.             {
  146.                for (xz = 0; xz < zoom; xz++)
  147.                {
  148.                   if (want_filter && (y + yz < 220))
  149.                   {
  150.                      *(q + INDEX_B) = (U8) ((  (U32) ((zoom - xz) * (U32) palette[*(   p   )][2]
  151.                                                       +    xz     * (U32) palette[*( p + 1 )][2])
  152.                                              + (U32) ((zoom - yz) * (U32) palette[*(   p   )][2]
  153.                                                       +    yz     * (U32) palette[*(p + 320)][2]))
  154.                                             / (zoom * zoom));
  155.  
  156.                      *(q + INDEX_G) = (U8) ((  (U32) ((zoom - xz) * (U32) palette[*(   p   )][1]
  157.                                                       +    xz     * (U32) palette[*( p + 1 )][1])
  158.                                              + (U32) ((zoom - yz) * (U32) palette[*(   p   )][1]
  159.                                                       +    yz     * (U32) palette[*(p + 320)][1]))
  160.                                             / (zoom * zoom));
  161.  
  162.                      *(q + INDEX_R) = (U8) ((  (U32) ((zoom - xz) * (U32) palette[*(   p   )][0]
  163.                                                       +    xz     * (U32) palette[*( p + 1 )][0])
  164.                                              + (U32) ((zoom - yz) * (U32) palette[*(   p   )][0]
  165.                                                       +    yz     * (U32) palette[*(p + 320)][0]))
  166.                                             / (zoom * zoom));
  167.                      *(q + INDEX_A) = 0;
  168.                   }
  169.                   else
  170.                   {
  171.                      *(q + INDEX_B) = palette[*p][2]; // pc: blue. mac: alpha
  172.                      *(q + INDEX_G) = palette[*p][1]; // pc: green. mac: red
  173.                      *(q + INDEX_R) = palette[*p][0]; // pc: red. mac: green
  174.                      *(q + INDEX_A) = 0; // pc: alpha. mac: blue
  175.                   }
  176.  
  177.                   q += pixel_size;
  178.                }
  179.  
  180.                p++;
  181.             }
  182.  
  183.             q0 += 320 * pixel_size * zoom;
  184.          }
  185.  
  186.          p0 += 320;
  187.       }
  188.      
  189.       area.x = rects->x * zoom;
  190.       area.y = (rects->y + 20) * zoom;
  191.       area.h = rects->height * zoom;
  192.       area.w = rects->width * zoom;
  193.       SDL_UpdateRects (screen, 1, &area);
  194.  
  195.       rects = rects->next;
  196.    }
  197. }
  198.