Subversion Repositories Games.Rick Dangerous

Rev

Rev 2 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2 Rev 7
Line 11... Line 11...
11
 * You must not remove this notice, or any other, from this software.
11
 * You must not remove this notice, or any other, from this software.
12
 */
12
 */
13
 
13
 
14
#include <stdlib.h> // malloc
14
#include <stdlib.h> // malloc
15
#include <string.h> // memset
15
#include <string.h> // memset
-
 
16
#include <stdbool.h> // bool
16
 
17
 
17
#include <SDL.h>
18
#include <SDL.h>
18
 
19
 
19
#include "system.h"
20
#include "system.h"
20
#include "game.h"
21
#include "game.h"
21
#include "img.h"
22
#include "img.h"
22
 
23
 
23
#define SYSVID_WIDTH 640
24
#define SCALE_FACTOR 4
24
#define SYSVID_HEIGHT 480
-
 
25
#define SYSVID_BPP 32
-
 
26
 
25
 
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
26
U8 sysvid_fb[320 * 200]; // the framebuffer for this game is really 320x200
40
U8 want_fullscreen = FALSE;// TRUE;
27
U8 want_fullscreen = FALSE;// TRUE;
41
U8 want_filter = TRUE;
28
U8 want_filter = TRUE;
42
U8 redraw_screen = FALSE;
29
U8 recreate_screen = FALSE;
43
 
30
 
-
 
31
static SDL_Window *window;
-
 
32
static SDL_Renderer *renderer;
44
static SDL_Surface *screen;
33
static SDL_Texture *screen_texture;
-
 
34
 
-
 
35
 
-
 
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);
45
 
39
 
46
 
40
 
47
// Initialise video
41
// Initialise video
48
void sysvid_init (void)
42
void sysvid_init (void)
49
{
43
{
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
44
   // SDL init
56
   if (SDL_Init (SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0)
45
   if (SDL_Init (SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0)
57
      sys_panic ("Fatal error: could not initialize SDL.\n");
46
      sys_panic ("Fatal error: could not initialize SDL.\n");
58
 
47
 
-
 
48
   // create game window
59
   SDL_WM_SetCaption ("Rick Dangerous", "Rick Dangerous");
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));
60
   SDL_ShowCursor (SDL_DISABLE);
55
   if (window == NULL)
-
 
56
      sys_panic ("Fatal error: SDL can not create game window.\n");
61
 
57
 
62
   // check video modes
58
   // create renderer
63
   if (SDL_ListModes (NULL, SDL_FULLSCREEN) == 0)
59
   renderer = SDL_CreateRenderer (window, -1, 0);
-
 
60
   if (renderer == NULL)
64
      sys_panic ("Fatal error: SDL can not find an appropriate video mode.\n");
61
      sys_panic ("Fatal error: SDL can not create renderer\n");
65
 
62
 
66
   // set video mode
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 = SDL_SetVideoMode (SYSVID_WIDTH, SYSVID_HEIGHT, SYSVID_BPP, (want_fullscreen ? SDL_FULLSCREEN : 0));
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 ();
68
}
73
}
69
 
74
 
70
 
75
 
71
// Shutdown video
76
// Shutdown video
72
void sysvid_shutdown (void)
77
void sysvid_shutdown (void)
73
{
78
{
74
   // destroy frame buffer
-
 
75
   if (sysvid_fb)
-
 
76
      free (sysvid_fb);
-
 
77
   sysvid_fb = NULL;
-
 
78
 
-
 
79
   // SDL quit
79
   // SDL quit
80
   SDL_Quit ();
80
   SDL_Quit ();
81
}
81
}
82
 
82
 
83
 
83
 
84
// Clear screen
84
// Clear screen
85
void sysvid_clear (void)
85
void sysvid_clear (void)
86
{
86
{
-
 
87
   SDL_SetRenderDrawColor (renderer, 0, 0, 0, 255);
-
 
88
   SDL_RenderClear (renderer);
-
 
89
   SDL_RenderPresent (renderer);
-
 
90
 
87
   memset (sysvid_fb, 0, 320 * 200);
91
   memset (sysvid_fb, 0, sizeof (sysvid_fb));
88
}
92
}
89
 
93
 
90
 
94
 
91
// Update screen
95
// Update screen
92
void sysvid_paint (rect_t *rects)
96
void sysvid_paint (rect_t *rects)
93
{
97
{
94
   static SDL_Rect area;
-
 
95
   static rect_t rect_screen = {0, 0, 320, 200, NULL};
98
   static uint8_t screen_pixels[320 * 200 * 4];
96
   static int pixel_size = SYSVID_BPP / 8;
99
   static uint8_t upscaled_pixels[320 * SCALE_FACTOR * 200 * SCALE_FACTOR * 4];
97
   static int zoom = SYSVID_WIDTH / 320;
100
   static rect_t rect_whole = {0, 0, 320, 200, NULL}; // framebuffer coordinates. The framebuffer is 320x200.
98
   static U8 palette[16][3] =
101
   static U8 palette[16][3] =
99
   {
102
   {
100
      {0x00, 0x00, 0x00},
103
      {0x00, 0x00, 0x00},
101
      {0xd8, 0x00, 0x00},
104
      {0xd8, 0x00, 0x00},
102
      {0xb0, 0x6c, 0x68},
105
      {0xb0, 0x6c, 0x68},
Line 112... Line 115...
112
      {0x48, 0x48, 0x48},
115
      {0x48, 0x48, 0x48},
113
      {0x68, 0x6c, 0x68},
116
      {0x68, 0x6c, 0x68},
114
      {0x90, 0x90, 0x90},
117
      {0x90, 0x90, 0x90},
115
      {0xb0, 0xb4, 0xb0}
118
      {0xb0, 0xb4, 0xb0}
116
   };
119
   };
117
   U16 x, y, xz, yz;
120
   U16 x, y;
118
   U8 *p, *q, *p0, *q0;
121
   U8 *p, *q, *p0, *q0;
119
 
122
 
120
   if (rects == NULL)
123
   if (rects == NULL)
121
      return;
124
      return;
122
 
125
 
123
   if (redraw_screen)
126
   if (recreate_screen)
124
   {
127
   {
125
      redraw_screen = FALSE;
128
      recreate_screen = FALSE;
126
      screen = SDL_SetVideoMode (SYSVID_WIDTH, SYSVID_HEIGHT, SYSVID_BPP, (want_fullscreen ? SDL_FULLSCREEN : 0));
129
      SDL_SetWindowFullscreen (window, (want_fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0));
127
      sysvid_paint (&rect_screen);
130
      sysvid_paint (&rect_whole);
128
   }
131
   }
129
 
132
 
-
 
133
   // expand what's in the 320x200x1 frame buffer to the 320x200x4 SDL texture buffer
130
   while (rects)
134
   while (rects)
131
   {
135
   {
132
      p0 = sysvid_fb;
-
 
133
      p0 += rects->x + rects->y * 320;
136
      p0 = &sysvid_fb[rects->y * 320 + rects->x];
134
      q0 = (U8 *)screen->pixels;
-
 
135
      q0 += (pixel_size * rects->x + pixel_size * (rects->y + 20) * 320 * zoom) * zoom;
137
      q0 = &screen_pixels[(rects->y * 320 + rects->x) * 4];
136
 
138
 
137
      for (y = (rects->y + 20); y < (rects->y + 20) + rects->height; y++)
139
      for (y = rects->y; y < rects->y + rects->height; y++)
138
      {
140
      {
-
 
141
         p = p0;
-
 
142
         q = q0;
-
 
143
 
139
         for (yz = 0; yz < zoom; yz++)
144
         for (x = rects->x; x < rects->x + rects->width; x++)
140
         {
145
         {
-
 
146
            *(q + 0) = palette[*p][2]; // blue
-
 
147
            *(q + 1) = palette[*p][1]; // green
141
            p = p0;
148
            *(q + 2) = palette[*p][0]; // red
142
            q = q0;
149
            *(q + 3) = 0; // alpha
143
 
150
 
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
                  {
151
            q += 4;
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++;
152
            p++;
181
            }
-
 
182
 
-
 
183
            q0 += 320 * pixel_size * zoom;
-
 
184
         }
153
         }
185
 
154
 
-
 
155
         q0 += 320 * 4;
186
         p0 += 320;
156
         p0 += 320;
187
      }
157
      }
188
     
158
     
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;
159
      rects = rects->next;
196
   }
160
   }
-
 
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);
197
}
172
}