Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * OpenTyrian: A modern cross-platform port of Tyrian
  3.  * Copyright (C) 2007-2009  The OpenTyrian Development Team
  4.  *
  5.  * This program is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU General Public License
  7.  * as published by the Free Software Foundation; either version 2
  8.  * of the License, or (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  18.  */
  19. #include "video.h"
  20.  
  21. #include "keyboard.h"
  22. #include "opentyr.h"
  23. #include "palette.h"
  24. #include "video_scale.h"
  25.  
  26. #include <assert.h>
  27. #include <stdbool.h>
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30.  
  31. bool fullscreen_enabled = false;
  32.  
  33. SDL_Surface *VGAScreen, *VGAScreenSeg;
  34. SDL_Surface *VGAScreen2;
  35. SDL_Surface *game_screen;
  36.  
  37. static ScalerFunction scaler_function;
  38.  
  39. void init_video( void )
  40. {
  41.         SDL_ShowCursor(0);
  42.         if (SDL_WasInit(SDL_INIT_VIDEO))
  43.                 return;
  44.  
  45.         if (SDL_InitSubSystem(SDL_INIT_VIDEO) == -1)
  46.         {
  47.                 fprintf(stderr, "error: failed to initialize SDL video: %s\n", SDL_GetError());
  48.                 exit(1);
  49.         }
  50.  
  51.         SDL_WM_SetCaption("OpenTyrian", NULL);
  52.  
  53.         VGAScreen = VGAScreenSeg = SDL_CreateRGBSurface(SDL_SWSURFACE, vga_width, vga_height, 8, 0, 0, 0, 0);
  54.         VGAScreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, vga_width, vga_height, 8, 0, 0, 0, 0);
  55.         game_screen = SDL_CreateRGBSurface(SDL_SWSURFACE, vga_width, vga_height, 8, 0, 0, 0, 0);
  56.  
  57.         SDL_FillRect(VGAScreen, NULL, 0);
  58.         if (!init_scaler(scaler, fullscreen_enabled) &&  // try desired scaler and desired fullscreen state
  59.             !init_any_scaler(fullscreen_enabled) &&      // try any scaler in desired fullscreen state
  60.             !init_any_scaler(!fullscreen_enabled))       // try any scaler in other fullscreen state
  61.         {
  62.                 fprintf(stderr, "error: failed to initialize any supported video mode\n");
  63.                 exit(EXIT_FAILURE);
  64.         }
  65. }
  66.  
  67. int can_init_scaler( unsigned int new_scaler, bool fullscreen )
  68. {
  69.         if (new_scaler >= scalers_count)
  70.                 return false;
  71.  
  72.         int w = scalers[new_scaler].width,
  73.             h = scalers[new_scaler].height;
  74.         int flags = SDL_SWSURFACE | SDL_HWPALETTE | (fullscreen ? SDL_FULLSCREEN : 0);
  75.  
  76.         // test each bitdepth
  77.         for (uint bpp = 32; bpp > 0; bpp -= 8)
  78.         {
  79.                 uint temp_bpp = SDL_VideoModeOK(w, h, bpp, flags);
  80.  
  81.                 if ((temp_bpp == 32 && scalers[new_scaler].scaler32) ||
  82.                     (temp_bpp == 16 && scalers[new_scaler].scaler16) ||
  83.                     (temp_bpp == 8  && scalers[new_scaler].scaler8 ))
  84.                 {
  85.                         return temp_bpp;
  86.                 }
  87.                 else if (temp_bpp == 24 && scalers[new_scaler].scaler32)
  88.                 {
  89.                         // scalers don't support 24 bpp because it's a pain
  90.                         // so let SDL handle the conversion
  91.                         return 32;
  92.                 }
  93.         }
  94.  
  95.         return 0;
  96. }
  97.  
  98. bool init_scaler( unsigned int new_scaler, bool fullscreen )
  99. {
  100.         int w = scalers[new_scaler].width,
  101.             h = scalers[new_scaler].height;
  102.         int bpp = can_init_scaler(new_scaler, fullscreen);
  103.         int flags = SDL_SWSURFACE | SDL_HWPALETTE | (fullscreen ? SDL_FULLSCREEN : 0);
  104.  
  105.         if (bpp == 0)
  106.                 return false;
  107.         #ifdef _KOLIBRI
  108.         bpp=16; // DEBUG
  109. #endif
  110.         SDL_Surface *const surface = SDL_SetVideoMode(w, h, bpp, flags);
  111.  
  112.         if (surface == NULL)
  113.         {
  114.                 fprintf(stderr, "error: failed to initialize %s video mode %dx%dx%d: %s\n", fullscreen ? "fullscreen" : "windowed", w, h, bpp, SDL_GetError());
  115.                 return false;
  116.         }
  117.  
  118.         w = surface->w;
  119.         h = surface->h;
  120.  
  121. #ifdef _KOLIBRI
  122.         uSDL_SetWinCenter(w,h);
  123. #endif
  124.         //bpp = surface->format->BitsPerPixel;
  125.  
  126.         printf("initialized video: %dx%dx%d %s\n", w, h, bpp, fullscreen ? "fullscreen" : "windowed");
  127.  
  128.         scaler = new_scaler;
  129.         fullscreen_enabled = fullscreen;
  130.  
  131.         switch (bpp)
  132.         {
  133.         case 32:
  134.                 scaler_function = scalers[scaler].scaler32;
  135.                 break;
  136.         case 16:
  137.                 scaler_function = scalers[scaler].scaler16;
  138.                 break;
  139.         case 8:
  140.                 scaler_function = scalers[scaler].scaler8;
  141.                 break;
  142.         default:
  143.                 scaler_function = NULL;
  144.                 break;
  145.         }
  146.  
  147.         if (scaler_function == NULL)
  148.         {
  149.                 assert(false);
  150.                 return false;
  151.         }
  152.  
  153.         input_grab(input_grab_enabled);
  154.         JE_showVGA();
  155.  
  156.         return true;
  157. }
  158.  
  159. bool can_init_any_scaler( bool fullscreen )
  160. {
  161.         for (int i = scalers_count - 1; i >= 0; --i)
  162.                 if (can_init_scaler(i, fullscreen) != 0)
  163.                         return true;
  164.  
  165.         return false;
  166. }
  167.  
  168. bool init_any_scaler( bool fullscreen )
  169. {
  170.         // attempts all scalers from last to first
  171.         for (int i = scalers_count - 1; i >= 0; --i)
  172.                 if (init_scaler(i, fullscreen))
  173.                         return true;
  174.  
  175.         return false;
  176. }
  177.  
  178. void deinit_video( void )
  179. {
  180.         SDL_FreeSurface(VGAScreenSeg);
  181.         SDL_FreeSurface(VGAScreen2);
  182.         SDL_FreeSurface(game_screen);
  183.  
  184.         SDL_QuitSubSystem(SDL_INIT_VIDEO);
  185. }
  186.  
  187. void JE_clr256( SDL_Surface * screen)
  188. {
  189.         memset(screen->pixels, 0, screen->pitch * screen->h);
  190. }
  191. void JE_showVGA( void ) { scale_and_flip(VGAScreen); }
  192.  
  193. void scale_and_flip( SDL_Surface *src_surface )
  194. {
  195.         assert(src_surface->format->BitsPerPixel == 8);
  196.  
  197.         SDL_Surface *dst_surface = SDL_GetVideoSurface();
  198.  
  199.         assert(scaler_function != NULL);
  200.         scaler_function(src_surface, dst_surface);
  201.  
  202.         SDL_Flip(dst_surface);
  203. }
  204.  
  205.