Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. #include <SDL.h>
  2. #include "../PHL.h"
  3. #include "../game.h"
  4. #include "../qda.h"
  5. #include "graphics.h"
  6. #include "scale.h"
  7. #include <stdlib.h>
  8. #include <string.h>
  9.  
  10. #if defined(__amigaos4__) || defined(__MORPHOS__)
  11. #include "../amigaos.h"
  12. #endif
  13.  
  14. SDL_Surface* screen = NULL;
  15. SDL_Surface* drawbuffer = NULL;
  16. SDL_Surface* backbuffer = NULL;
  17.  
  18. int wantFullscreen = 0;
  19. int screenScale = 2;
  20. int desktopFS = 0;
  21.  
  22. int deltaX = 0;
  23. int deltaY = 0;
  24.  
  25. int screenW = 640;
  26. int screenH = 480;
  27.  
  28. int drawscreen = 0;
  29.  
  30. int xbrz = 0;
  31.  
  32. static uint32_t tframe;
  33.  
  34. extern void Input_InitJoystick();
  35. extern void Input_CloseJoystick();
  36.  
  37. int getXBRZ()
  38. {
  39.         return xbrz;
  40. }
  41.  
  42. void setXBRZ(int active)
  43. {
  44. #ifdef _KOLIBRI
  45.         xbrz = 0; // Problems with "xBRZ". Temporarily not used.
  46. #else
  47.         if(active) active = 1;
  48.         if(xbrz==active) return;
  49.         xbrz = active;
  50.  
  51.         // try to reload everything, but boss ressource will not be reloaded
  52.         freeImages();
  53.         loadImages();
  54. #endif
  55. }
  56.  
  57.  
  58. SDL_Color PHL_NewRGB(uint8_t r, uint8_t g, uint8_t b)
  59. {
  60.     SDL_Color ret = {.r = r, .b = b, .g = g};
  61.     return ret;
  62. }
  63.  
  64. void PHL_GraphicsInit()
  65. {
  66.         SDL_ShowCursor(SDL_DISABLE);
  67.  
  68.         Input_InitJoystick();
  69.         #ifdef __MORPHOS__
  70.                 uint32_t flags = SDL_SWSURFACE;
  71.         #else
  72.                 uint32_t flags = SDL_HWSURFACE|SDL_DOUBLEBUF;
  73.         #endif
  74.         if(wantFullscreen || desktopFS)
  75.         flags |= SDL_FULLSCREEN;
  76.     screen = SDL_SetVideoMode((desktopFS)?0:screenW, (desktopFS)?0:screenH, 0, flags);
  77.         if(desktopFS)
  78.         {
  79.                 const SDL_VideoInfo* infos = SDL_GetVideoInfo();
  80.                 screenH = infos->current_h;
  81.                 screenW = infos->current_w;
  82.  
  83.                 if(screenW/320 < screenH/240)
  84.                         screenScale = screenW/320;
  85.                 else
  86.                         screenScale = screenH/240; // automatic guess the scale
  87.                 deltaX = (screenW-320*screenScale)/2;
  88.                 deltaY = (screenH-240*screenScale)/2;
  89.         }
  90.        
  91.         SDL_WM_SetCaption("Hydra Castle Labyrinth", NULL);
  92.        
  93.         drawbuffer = screen;
  94.         drawscreen = 1;
  95.         backbuffer = SDL_CreateRGBSurface(0, 320*screenScale, 240*screenScale, 32, 0, 0, 0, 0);
  96.         tframe = SDL_GetTicks();
  97. }
  98.  
  99. void PHL_GraphicsExit()
  100. {
  101.         Input_CloseJoystick();
  102.     SDL_FreeSurface(backbuffer);
  103.         SDL_Quit();    
  104. }
  105.  
  106. void PHL_StartDrawing()
  107. {
  108.         PHL_ResetDrawbuffer();
  109. }
  110. void PHL_EndDrawing()
  111. {
  112.         //implement some crude frameskiping, limited to 2 frame skip
  113.         static int skip = 0;
  114.         uint32_t tnext = tframe + 1000/60;
  115.         if (SDL_GetTicks()>tnext && skip<2) {
  116.                 tframe += 1000/60;
  117.                 skip++;
  118.                 return;
  119.         }
  120.  
  121.         // handle black borders
  122.         if(deltaX) {
  123.                 SDL_Rect rect = {0, 0, deltaX, screenH};
  124.                 SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, 0, 0, 0));
  125.                 rect.x = screenW - deltaX -1;
  126.                 SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, 0, 0, 0));
  127.         }
  128.         if(deltaY) {
  129.                 SDL_Rect rect = {0, 0, screenW, deltaY};
  130.                 SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, 0, 0, 0));
  131.                 rect.y = screenH - deltaY -1;
  132.                 SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, 0, 0, 0));
  133.         }
  134.  
  135.     SDL_Flip(screen);
  136.         while((tframe = SDL_GetTicks())<tnext)
  137.         SDL_Delay(10);
  138. }
  139.  
  140. void PHL_ForceScreenUpdate()
  141. {
  142.  
  143. }
  144.  
  145. void PHL_SetDrawbuffer(PHL_Surface surf)
  146. {
  147.         drawbuffer = surf;
  148.         drawscreen = (surf==screen);
  149. }
  150. void PHL_ResetDrawbuffer()
  151. {
  152.         drawbuffer = screen;
  153.         drawscreen = 1;
  154. }
  155.  
  156. //PHL_RGB PHL_NewRGB(int r, int g, int b);
  157. void PHL_SetColorKey(PHL_Surface surf, int r, int g, int b)
  158. {
  159.     SDL_SetColorKey(surf, SDL_SRCCOLORKEY|SDL_RLEACCEL, SDL_MapRGB(surf->format, r, g, b));
  160. }
  161.  
  162. PHL_Surface PHL_NewSurface(int w, int h)
  163. {
  164.         if(getXBRZ())
  165.                 return SDL_CreateRGBSurface(0, w, h, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
  166.         else
  167.         return SDL_CreateRGBSurface(0, w, h, 32, 0, 0, 0, 0);
  168. }
  169. void PHL_FreeSurface(PHL_Surface surf)
  170. {
  171.     SDL_FreeSurface(surf);
  172. }
  173.  
  174. //PHL_Surface PHL_LoadBMP(char* fname);
  175. PHL_Surface PHL_LoadBMP(int index)
  176. {
  177.         SDL_Surface* surf;
  178.        
  179.         FILE* f;
  180.         if ( (f = fopen("data/bmp.qda", "rb")) ) {
  181.                 uint8_t* QDAFile = (uint8_t*)malloc(headers[index].size);
  182.                 fseek(f, headers[index].offset, SEEK_SET);
  183.                 int tmp = fread(QDAFile, 1, headers[index].size, f);
  184.                 fclose(f);
  185.                
  186.                 uint16_t w, h;
  187.                
  188.                 //Read data from header
  189.                 memcpy(&w, &QDAFile[18], 2);
  190.                 memcpy(&h, &QDAFile[22], 2);
  191.                 #if defined(__amigaos4__) || defined(__MORPHOS__)
  192.                 BE16(&w); BE16(&h);
  193.                 #endif
  194.                
  195.                 surf = PHL_NewSurface(w * screenScale, h * screenScale);
  196.                 //surf = PHL_NewSurface(200, 200);
  197.  
  198.                 //Load Palette
  199.                 int dx, dy;
  200.                 int count = 0;
  201.  
  202.                 if(getXBRZ()) {
  203. #ifndef _KOLIBRI
  204.                         Uint32 palette[20][18];
  205.  
  206.                         for (dx = 0; dx < 20; dx++) {
  207.                                 for (dy = 0; dy < 16; dy++) {
  208.                                         palette[dx][dy] = 255<<24 | ((Uint32)QDAFile[54 + count])<<0 | ((Uint32)QDAFile[54 + count + 1])<<8 | ((Uint32)QDAFile[54 + count + 2])<<16;
  209.                                         count += 4;
  210.                                 }
  211.                         }
  212.                         Uint32* tmp = NULL;
  213.                         tmp = (Uint32*)malloc(w*h*screenScale*4);
  214.                         Uint32 transp;
  215.                         for (dx = 0; dx < w; dx++) {
  216.                                 for (dy = 0; dy < h; dy++) {
  217.                                
  218.                                         int pix = dx + w * dy;
  219.                                         int px = QDAFile[1078 + pix] / 16;
  220.                                         int py = QDAFile[1078 + pix] % 16;
  221.                                         //Get transparency from first palette color
  222.                                         if (dx == 0 && dy == 0) {                                      
  223.                                                 //Darkness special case
  224.                                                 if (index == 27)
  225.                                                         transp = 255<<24;
  226.                                                 else
  227.                                                         transp = palette[0][0];
  228.                                         }
  229.                                        
  230.                                         Uint32 c = palette[px][py];
  231.                                         if(c==transp)
  232.                                                 c=0;
  233.                                         tmp[(h-1-dy)*w+dx] = c;
  234.                                 }
  235.                         }
  236.  
  237.                     xbrz_scale((void*)tmp, (void*)surf->pixels, w, h, screenScale);
  238.                         free(tmp);
  239. #endif
  240.                 } else {
  241.                         PHL_RGB palette[20][18];
  242.  
  243.                         for (dx = 0; dx < 20; dx++) {
  244.                                 for (dy = 0; dy < 16; dy++) {
  245.                                         palette[dx][dy].b = QDAFile[54 + count];
  246.                                         palette[dx][dy].g = QDAFile[54 + count + 1];
  247.                                         palette[dx][dy].r = QDAFile[54 + count + 2];
  248.                                         count += 4;
  249.                                 }
  250.                         }
  251.                         for (dx = 0; dx < w; dx++) {
  252.                                 for (dy = 0; dy < h; dy++) {
  253.                                
  254.                                         int pix = dx + w * dy;
  255.                                         int px = QDAFile[1078 + pix] / 16;
  256.                                         int py = QDAFile[1078 + pix] % 16;
  257.                                         //Get transparency from first palette color
  258.                                         if (dx == 0 && dy == 0) {                                      
  259.                                                 //Darkness special case
  260.                                                 if (index == 27) {
  261.                                                         SDL_SetColorKey(surf, SDL_SRCCOLORKEY|SDL_RLEACCEL, SDL_MapRGB(surf->format, 0x00, 0x00, 0x00));
  262.                                                 }else{
  263.                                                         SDL_SetColorKey(surf, SDL_SRCCOLORKEY|SDL_RLEACCEL, SDL_MapRGB(surf->format, palette[0][0].r, palette[0][0].g, palette[0][0].b));
  264.                                                 }
  265.                                         }
  266.                                        
  267.                                         PHL_RGB c = palette[px][py];
  268.                                         //PHL_DrawRect(dx * 2, dy * 2, 2, 2, c);
  269.                                         SDL_Rect rect = {dx * screenScale, (h-1-dy) * screenScale, screenScale, screenScale};  
  270.                                         SDL_FillRect(surf, &rect, SDL_MapRGB(surf->format, c.r, c.g, c.b));
  271.                                 }
  272.                         }
  273.                 }
  274.                 free(QDAFile);
  275.         }
  276.        
  277.         return surf;
  278. }
  279.  
  280. void PHL_DrawRect(int x, int y, int w, int h, SDL_Color col)
  281. {
  282.         SDL_Rect rect = {x*screenScale/2 + (drawscreen?deltaX:0), y*screenScale/2 + (drawscreen?deltaY:0), w*screenScale/2, h*screenScale/2};
  283.        
  284.         SDL_FillRect(drawbuffer, &rect, SDL_MapRGB(drawbuffer->format, col.r, col.g, col.b));
  285. }
  286.  
  287. void PHL_DrawSurface(double x, double y, PHL_Surface surface)
  288. {
  289.         if (quakeTimer > 0) {
  290.                 int val = quakeTimer % 4;
  291.                 if (val == 0) {
  292.                         y -= 1;
  293.                 } else if (val == 2) {
  294.                         y += 1;
  295.                 }
  296.         }
  297.        
  298.         SDL_Rect offset;
  299.         offset.x = x*screenScale/2 + (drawscreen?deltaX:0);
  300.         offset.y = y*screenScale/2 + (drawscreen?deltaY:0);
  301.        
  302.         SDL_BlitSurface(surface, NULL, drawbuffer, &offset);
  303. }
  304. void PHL_DrawSurfacePart(double x, double y, int cropx, int cropy, int cropw, int croph, PHL_Surface surface)
  305. {
  306.         if (quakeTimer > 0) {
  307.                 int val = quakeTimer % 4;
  308.                 if (val == 0) {
  309.                         y -= (screenScale==1)?2:1;
  310.                 }else if (val == 2) {
  311.                         y += (screenScale==1)?2:1;
  312.                 }
  313.         }
  314.        
  315.         SDL_Rect crop, offset;
  316.         crop.x = cropx*screenScale/2;
  317.         crop.y = cropy*screenScale/2;
  318.         crop.w = cropw*screenScale/2;
  319.         crop.h = croph*screenScale/2;
  320.        
  321.         offset.x = x*screenScale/2 + (drawscreen?deltaX:0);
  322.         offset.y = y*screenScale/2 + (drawscreen?deltaY:0);
  323.        
  324.         SDL_BlitSurface(surface, &crop, drawbuffer, &offset);
  325. }
  326.  
  327. void PHL_DrawBackground(PHL_Background back, PHL_Background fore)
  328. {
  329.         PHL_DrawSurface(0, 0, backbuffer);
  330. }
  331. void PHL_UpdateBackground(PHL_Background back, PHL_Background fore)
  332. {
  333.         PHL_SetDrawbuffer(backbuffer);
  334.        
  335.         int xx, yy;
  336.  
  337.         for (yy = 0; yy < 12; yy++)
  338.         {
  339.                 for (xx = 0; xx < 16; xx++)
  340.                 {
  341.                         //Draw Background tiles
  342.                         PHL_DrawSurfacePart(xx * 40, yy * 40, back.tileX[xx][yy] * 40, back.tileY[xx][yy] * 40, 40, 40, images[imgTiles]);
  343.                        
  344.                         //Only draw foreground tile if not a blank tile
  345.                         if (fore.tileX[xx][yy] != 0 || fore.tileY[xx][yy] != 0) {
  346.                                 PHL_DrawSurfacePart(xx * 40, yy * 40, fore.tileX[xx][yy] * 40, fore.tileY[xx][yy] * 40, 40, 40, images[imgTiles]);
  347.                         }
  348.                 }
  349.         }
  350.        
  351.         PHL_ResetDrawbuffer();
  352. }
  353.