Subversion Repositories Games.Rick Dangerous

Rev

Rev 7 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 pmbaty 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
 
2 pmbaty 14
#include <stdlib.h> // malloc
15
#include <string.h> // memset
7 pmbaty 16
#include <stdbool.h> // bool
1 pmbaty 17
 
11 pmbaty 18
#include <SDL2/SDL.h>
1 pmbaty 19
 
20
#include "system.h"
21
#include "game.h"
22
#include "img.h"
23
 
7 pmbaty 24
#define SCALE_FACTOR 4
1 pmbaty 25
 
7 pmbaty 26
U8 sysvid_fb[320 * 200]; // the framebuffer for this game is really 320x200
2 pmbaty 27
U8 want_fullscreen = FALSE;// TRUE;
1 pmbaty 28
U8 want_filter = TRUE;
7 pmbaty 29
U8 recreate_screen = FALSE;
1 pmbaty 30
 
7 pmbaty 31
static SDL_Window *window;
32
static SDL_Renderer *renderer;
33
static SDL_Texture *screen_texture;
1 pmbaty 34
 
35
 
7 pmbaty 36
// XBRZ scaler
37
void xbrz_scale (size_t factor, const uint32_t *src, uint32_t *trg, int srcWidth, int srcHeight, bool has_alpha_channel);
38
void nearest_neighbor_scale (const uint32_t *src, int srcWidth, int srcHeight, uint32_t *trg, int trgWidth, int trgHeight);
39
 
40
 
1 pmbaty 41
// Initialise video
42
void sysvid_init (void)
43
{
44
   // SDL init
45
   if (SDL_Init (SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0)
46
      sys_panic ("Fatal error: could not initialize SDL.\n");
47
 
7 pmbaty 48
   // create game window
49
   window = SDL_CreateWindow ("Rick Dangerous",
50
                              SDL_WINDOWPOS_UNDEFINED, // x
51
                              SDL_WINDOWPOS_UNDEFINED, // y
52
                              (want_fullscreen ? 0 : 1024), // let system assign width in fullscreen mode
53
                              (want_fullscreen ? 0 : 768), // let system assign height in fullscreen mode
54
                              (want_fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0));
55
   if (window == NULL)
56
      sys_panic ("Fatal error: SDL can not create game window.\n");
1 pmbaty 57
 
7 pmbaty 58
   // create renderer
59
   renderer = SDL_CreateRenderer (window, -1, 0);
60
   if (renderer == NULL)
61
      sys_panic ("Fatal error: SDL can not create renderer\n");
1 pmbaty 62
 
7 pmbaty 63
   // amke the scaled rendering look smoother
64
   SDL_RenderSetLogicalSize (renderer, 320 * SCALE_FACTOR, 200 * SCALE_FACTOR);
65
 
66
   // create a texture that will cover the whole window
67
   screen_texture = SDL_CreateTexture (renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 320 * SCALE_FACTOR, 200 * SCALE_FACTOR);
68
   if (screen_texture == NULL)
69
      sys_panic ("Fatal error: SDL can not create rendering surface\n");
70
 
71
   // clear the screen to black
72
   sysvid_clear ();
1 pmbaty 73
}
74
 
75
 
76
// Shutdown video
77
void sysvid_shutdown (void)
78
{
79
   // SDL quit
80
   SDL_Quit ();
81
}
82
 
83
 
84
// Clear screen
85
void sysvid_clear (void)
86
{
7 pmbaty 87
   SDL_SetRenderDrawColor (renderer, 0, 0, 0, 255);
88
   SDL_RenderClear (renderer);
89
   SDL_RenderPresent (renderer);
90
 
91
   memset (sysvid_fb, 0, sizeof (sysvid_fb));
1 pmbaty 92
}
93
 
94
 
95
// Update screen
96
void sysvid_paint (rect_t *rects)
97
{
7 pmbaty 98
   static uint8_t screen_pixels[320 * 200 * 4];
99
   static uint8_t upscaled_pixels[320 * SCALE_FACTOR * 200 * SCALE_FACTOR * 4];
100
   static rect_t rect_whole = {0, 0, 320, 200, NULL}; // framebuffer coordinates. The framebuffer is 320x200.
1 pmbaty 101
   static U8 palette[16][3] =
102
   {
103
      {0x00, 0x00, 0x00},
104
      {0xd8, 0x00, 0x00},
105
      {0xb0, 0x6c, 0x68},
106
      {0xf8, 0x90, 0x68},
107
      {0x20, 0x24, 0x20},
108
      {0x00, 0x48, 0xb0},
109
      {0x00, 0x6c, 0xd8},
110
      {0x20, 0x48, 0x00},
111
      {0x48, 0x6c, 0x20},
112
      {0x48, 0x24, 0x00},
113
      {0x90, 0x48, 0x00},
114
      {0xd8, 0x6c, 0x00},
115
      {0x48, 0x48, 0x48},
116
      {0x68, 0x6c, 0x68},
117
      {0x90, 0x90, 0x90},
118
      {0xb0, 0xb4, 0xb0}
119
   };
7 pmbaty 120
   U16 x, y;
1 pmbaty 121
   U8 *p, *q, *p0, *q0;
122
 
123
   if (rects == NULL)
124
      return;
125
 
7 pmbaty 126
   if (recreate_screen)
1 pmbaty 127
   {
7 pmbaty 128
      recreate_screen = FALSE;
129
      SDL_SetWindowFullscreen (window, (want_fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0));
130
      sysvid_paint (&rect_whole);
1 pmbaty 131
   }
132
 
7 pmbaty 133
   // expand what's in the 320x200x1 frame buffer to the 320x200x4 SDL texture buffer
1 pmbaty 134
   while (rects)
135
   {
7 pmbaty 136
      p0 = &sysvid_fb[rects->y * 320 + rects->x];
137
      q0 = &screen_pixels[(rects->y * 320 + rects->x) * 4];
1 pmbaty 138
 
7 pmbaty 139
      for (y = rects->y; y < rects->y + rects->height; y++)
1 pmbaty 140
      {
7 pmbaty 141
         p = p0;
142
         q = q0;
143
 
144
         for (x = rects->x; x < rects->x + rects->width; x++)
1 pmbaty 145
         {
7 pmbaty 146
            *(q + 0) = palette[*p][2]; // blue
147
            *(q + 1) = palette[*p][1]; // green
148
            *(q + 2) = palette[*p][0]; // red
149
            *(q + 3) = 0; // alpha
1 pmbaty 150
 
7 pmbaty 151
            q += 4;
152
            p++;
1 pmbaty 153
         }
154
 
7 pmbaty 155
         q0 += 320 * 4;
1 pmbaty 156
         p0 += 320;
157
      }
158
 
159
      rects = rects->next;
160
   }
7 pmbaty 161
 
162
   // now upscale with a little bit of magic
163
   if (want_filter)
164
      xbrz_scale (SCALE_FACTOR, (uint32_t *) screen_pixels, (uint32_t *) upscaled_pixels, 320, 200, false);
165
   else
166
      nearest_neighbor_scale ((uint32_t *) screen_pixels, 320, 200, (uint32_t *) upscaled_pixels, 320 * SCALE_FACTOR, 200 * SCALE_FACTOR);
167
 
168
   SDL_UpdateTexture (screen_texture, NULL, upscaled_pixels, 320 * SCALE_FACTOR * 4);
169
   SDL_RenderClear (renderer);
170
   SDL_RenderCopy (renderer, screen_texture, NULL, NULL);
171
   SDL_RenderPresent (renderer);
1 pmbaty 172
}