summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Scheibenpflug <zorchenhimer@gmail.com>2014-09-02 02:04:15 (GMT)
committerNick Scheibenpflug <zorchenhimer@gmail.com>2014-09-02 02:04:15 (GMT)
commit02ee45fba605314fea9cf04cf6daabcf8f961e5e (patch)
treedfa4149fe8e1e51164a586a7c13ef8cf02d68e97
parentdd3c0071ac758f8d13ef90cbf236f64a01a6e146 (diff)
downloadspace-zap-02ee45fba605314fea9cf04cf6daabcf8f961e5e.zip
space-zap-02ee45fba605314fea9cf04cf6daabcf8f961e5e.tar.gz
Started adding some render code for bullets. Added player, enemy, and bullet sprites. Borrowing SDL_rotozoom from SDL_gfx.
-rw-r--r--Bullet.cpp93
-rw-r--r--Bullet.h8
-rw-r--r--Player.cpp13
-rw-r--r--Player.h3
-rw-r--r--SDL_rotozoom.c1682
-rw-r--r--SDL_rotozoom.h103
-rw-r--r--Utils.h2
-rw-r--r--img/enemyBlack1.pngbin0 -> 3019 bytes
-rw-r--r--img/laserBlue01.pngbin0 -> 744 bytes
-rw-r--r--img/laserRed02.pngbin0 -> 310 bytes
-rw-r--r--img/player.pngbin0 -> 17892 bytes
-rw-r--r--space-zap.vcxproj5
-rw-r--r--space-zap.vcxproj.filters6
13 files changed, 1909 insertions, 6 deletions
diff --git a/Bullet.cpp b/Bullet.cpp
index e69de29..729d34c 100644
--- a/Bullet.cpp
+++ b/Bullet.cpp
@@ -0,0 +1,93 @@
1#include "Bullet.h"
2
3Bullet::Bullet(Directions quad) {
4 this->info->Quadrant = quad;
5 this->info->Who = PLAYER;
6 this->info->Location = 0;
7 this->sprite = LoadImage("img/laserBlue01.png");
8
9 switch (this->info->Quadrant) {
10 case EAST:
11 this->sprite = rotateSurface90Degrees(this->sprite, 1);
12 case SOUTH:
13 this->sprite = rotateSurface90Degrees(this->sprite, 1);
14 case WEST:
15 this->sprite = rotateSurface90Degrees(this->sprite, 1);
16 case NORTH:
17 default:
18 // do nothing.
19 break;
20 }
21}
22
23Bullet::Bullet(Directions quad, int difficulty) {
24 this->info->Quadrant = quad;
25 this->info->Who = ENEMY;
26 this->info->Location = 0;
27 this->Difficulty = difficulty;
28 this->sprite = LoadImage("img/laserRed02.png");
29
30 // FIXME: yea, this is wrong. It's just copypasta'd from the player init.
31 switch (this->info->Quadrant) {
32 case EAST:
33 this->sprite = rotateSurface90Degrees(this->sprite, 1);
34 case SOUTH:
35 this->sprite = rotateSurface90Degrees(this->sprite, 1);
36 case WEST:
37 this->sprite = rotateSurface90Degrees(this->sprite, 1);
38 case NORTH:
39 default:
40 // do nothing.
41 break;
42 }
43}
44
45void Bullet::draw(SDL_Surface* surf) {
46 int startx, starty;
47 startx = VideoSurface->w / 2;
48 starty = VideoSurface->h / 2;
49 SDL_Rect destrect;
50
51 if (this->info->Who == PLAYER) {
52 int startoffset = 194; // (0.5 * player_width) + bullet_length
53
54 switch (this->info->Quadrant) {
55 case NORTH:
56 destrect.x = startx - startoffset;
57 break;
58 case SOUTH:
59 destrect.x = startx + startoffset;
60 break;
61 case EAST:
62 destrect.y = starty + startoffset;
63 break;
64 case WEST:
65 default:
66 destrect.y = starty - startoffset;
67 }
68 // this->info->Who == ENEMY
69 } else {
70 int startoffset = 84; // enemy_length
71 switch (this->info->Quadrant) {
72 case NORTH:
73 destrect.y = startoffset;
74 break;
75 case SOUTH:
76 destrect.y = VideoSurface->h - startoffset;
77 break;
78 case EAST:
79 destrect.x = VideoSurface->w - startoffset;
80 break;
81 case WEST:
82 default:
83 destrect.x = startoffset;
84 }
85 }
86
87 // Center the coordinates.
88 destrect.x = destrect.x - (this->sprite->w / 2);
89 destrect.y = destrect.y - (this->sprite->h / 2);
90
91 // TODO: time offsets so the damn thing moves.
92 SDL_BlitSurface(this->sprite, NULL, surf, &destrect);
93} \ No newline at end of file
diff --git a/Bullet.h b/Bullet.h
index 1af40c7..82f3037 100644
--- a/Bullet.h
+++ b/Bullet.h
@@ -2,6 +2,7 @@
2#define __BULLET_H_ 2#define __BULLET_H_
3 3
4#include "Enums.h" 4#include "Enums.h"
5#include "Utils.h"
5 6
6#include <SDL.h> 7#include <SDL.h>
7#include <SDL_image.h> 8#include <SDL_image.h>
@@ -14,7 +15,8 @@ struct BulletInfo {
14 15
15class Bullet { 16class Bullet {
16public: 17public:
17 Bullet(Owner who, Directions quad, int difficulty); 18 Bullet(Directions quad, int difficulty); // Enemy bullet
19 Bullet(Directions quad); // Player bullet
18 ~Bullet(); 20 ~Bullet();
19 void update(); 21 void update();
20 void draw(SDL_Surface* surf); 22 void draw(SDL_Surface* surf);
@@ -26,9 +28,7 @@ private:
26 static const int PlayerSpeed = 100; // This should be constant, but really fast (faster than an enemy bullet can travel). 28 static const int PlayerSpeed = 100; // This should be constant, but really fast (faster than an enemy bullet can travel).
27 int Difficulty; // Speed modifier for EnemySpeed. 29 int Difficulty; // Speed modifier for EnemySpeed.
28 30
29 Directions Quadrant; 31 BulletInfo* info; // 1d as this is linear and depends on the quadrant and owner
30 Owner Who;
31 int location; // 1d as this is linear and depends on the quadrant and owner
32 32
33 SDL_Surface* sprite; 33 SDL_Surface* sprite;
34}; 34};
diff --git a/Player.cpp b/Player.cpp
index f2961cd..bdae47b 100644
--- a/Player.cpp
+++ b/Player.cpp
@@ -7,3 +7,16 @@ Player::Player() {
7Player::~Player() { 7Player::~Player() {
8 8
9} 9}
10
11void Player::Orient(Directions direction) {
12 this->orientation = direction;
13}
14
15void Player::update() {
16
17}
18
19Bullet* Player::Fire() {
20 Bullet* newbullet = new Bullet(this->orientation);
21 return newbullet;
22} \ No newline at end of file
diff --git a/Player.h b/Player.h
index 33f210a..befc115 100644
--- a/Player.h
+++ b/Player.h
@@ -2,6 +2,7 @@
2#define __PLAYER_H_ 2#define __PLAYER_H_
3 3
4#include "Enums.h" 4#include "Enums.h"
5#include "Bullet.h"
5 6
6#include <SDL.h> 7#include <SDL.h>
7#include <SDL_image.h> 8#include <SDL_image.h>
@@ -11,7 +12,7 @@ public:
11 Player(); 12 Player();
12 ~Player(); 13 ~Player();
13 void Orient(Directions direction); 14 void Orient(Directions direction);
14 void Fire(); 15 Bullet* Fire();
15 void update(); 16 void update();
16 void draw(SDL_Surface* surf); 17 void draw(SDL_Surface* surf);
17 18
diff --git a/SDL_rotozoom.c b/SDL_rotozoom.c
new file mode 100644
index 0000000..ccaf5b5
--- /dev/null
+++ b/SDL_rotozoom.c
@@ -0,0 +1,1682 @@
1/*
2
3SDL_rotozoom.c - rotozoomer, zoomer and shrinker for 32bit or 8bit surfaces
4
5LGPL (c) A. Schiffler
6
7*/
8
9#ifdef WIN32
10#include <windows.h>
11#endif
12
13#include <stdlib.h>
14#include <string.h>
15
16#include "SDL_rotozoom.h"
17
18/* ---- Internally used structures */
19
20/*!
21\brief A 32 bit RGBA pixel.
22*/
23typedef struct tColorRGBA {
24 Uint8 r;
25 Uint8 g;
26 Uint8 b;
27 Uint8 a;
28} tColorRGBA;
29
30/*!
31\brief A 8bit Y/palette pixel.
32*/
33typedef struct tColorY {
34 Uint8 y;
35} tColorY;
36
37/*!
38\brief Returns maximum of two numbers a and b.
39*/
40#define MAX(a,b) (((a) > (b)) ? (a) : (b))
41
42/*!
43\brief Number of guard rows added to destination surfaces.
44
45This is a simple but effective workaround for observed issues.
46These rows allocate extra memory and are then hidden from the surface.
47Rows are added to the end of destination surfaces when they are allocated.
48This catches any potential overflows which seem to happen with
49just the right src image dimensions and scale/rotation and can lead
50to a situation where the program can segfault.
51*/
52#define GUARD_ROWS (2)
53
54/*!
55\brief Lower limit of absolute zoom factor or rotation degrees.
56*/
57#define VALUE_LIMIT 0.001
58
59/*!
60\brief Returns colorkey info for a surface
61*/
62Uint32 _colorkey(SDL_Surface *src)
63{
64 Uint32 key = 0;
65#if (SDL_MINOR_VERSION == 3)
66 SDL_GetColorKey(src, &key);
67#else
68 if (src)
69 {
70 key = src->format->colorkey;
71 }
72#endif
73 return key;
74}
75
76
77/*!
78\brief Internal 32 bit integer-factor averaging Shrinker.
79
80Shrinks 32 bit RGBA/ABGR 'src' surface to 'dst' surface.
81Averages color and alpha values values of src pixels to calculate dst pixels.
82Assumes src and dst surfaces are of 32 bit depth.
83Assumes dst surface was allocated with the correct dimensions.
84
85\param src The surface to shrink (input).
86\param dst The shrunken surface (output).
87\param factorx The horizontal shrinking ratio.
88\param factory The vertical shrinking ratio.
89
90\return 0 for success or -1 for error.
91*/
92int _shrinkSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int factorx, int factory)
93{
94 int x, y, dx, dy, sgap, dgap, ra, ga, ba, aa;
95 int n_average;
96 tColorRGBA *sp, *osp, *oosp;
97 tColorRGBA *dp;
98
99 /*
100 * Averaging integer shrink
101 */
102
103 /* Precalculate division factor */
104 n_average = factorx*factory;
105
106 /*
107 * Scan destination
108 */
109 sp = (tColorRGBA *) src->pixels;
110 sgap = src->pitch - src->w * 4;
111
112 dp = (tColorRGBA *) dst->pixels;
113 dgap = dst->pitch - dst->w * 4;
114
115 for (y = 0; y < dst->h; y++) {
116
117 osp=sp;
118 for (x = 0; x < dst->w; x++) {
119
120 /* Trace out source box and accumulate */
121 oosp=sp;
122 ra=ga=ba=aa=0;
123 for (dy=0; dy < factory; dy++) {
124 for (dx=0; dx < factorx; dx++) {
125 ra += sp->r;
126 ga += sp->g;
127 ba += sp->b;
128 aa += sp->a;
129
130 sp++;
131 }
132 /* src dx loop */
133 sp = (tColorRGBA *)((Uint8*)sp + (src->pitch - 4*factorx)); // next y
134 }
135 /* src dy loop */
136
137 /* next box-x */
138 sp = (tColorRGBA *)((Uint8*)oosp + 4*factorx);
139
140 /* Store result in destination */
141 dp->r = ra/n_average;
142 dp->g = ga/n_average;
143 dp->b = ba/n_average;
144 dp->a = aa/n_average;
145
146 /*
147 * Advance destination pointer
148 */
149 dp++;
150 }
151 /* dst x loop */
152
153 /* next box-y */
154 sp = (tColorRGBA *)((Uint8*)osp + src->pitch*factory);
155
156 /*
157 * Advance destination pointers
158 */
159 dp = (tColorRGBA *) ((Uint8 *) dp + dgap);
160 }
161 /* dst y loop */
162
163 return (0);
164}
165
166/*!
167\brief Internal 8 bit integer-factor averaging shrinker.
168
169Shrinks 8bit Y 'src' surface to 'dst' surface.
170Averages color (brightness) values values of src pixels to calculate dst pixels.
171Assumes src and dst surfaces are of 8 bit depth.
172Assumes dst surface was allocated with the correct dimensions.
173
174\param src The surface to shrink (input).
175\param dst The shrunken surface (output).
176\param factorx The horizontal shrinking ratio.
177\param factory The vertical shrinking ratio.
178
179\return 0 for success or -1 for error.
180*/
181int _shrinkSurfaceY(SDL_Surface * src, SDL_Surface * dst, int factorx, int factory)
182{
183 int x, y, dx, dy, sgap, dgap, a;
184 int n_average;
185 Uint8 *sp, *osp, *oosp;
186 Uint8 *dp;
187
188 /*
189 * Averaging integer shrink
190 */
191
192 /* Precalculate division factor */
193 n_average = factorx*factory;
194
195 /*
196 * Scan destination
197 */
198 sp = (Uint8 *) src->pixels;
199 sgap = src->pitch - src->w;
200
201 dp = (Uint8 *) dst->pixels;
202 dgap = dst->pitch - dst->w;
203
204 for (y = 0; y < dst->h; y++) {
205
206 osp=sp;
207 for (x = 0; x < dst->w; x++) {
208
209 /* Trace out source box and accumulate */
210 oosp=sp;
211 a=0;
212 for (dy=0; dy < factory; dy++) {
213 for (dx=0; dx < factorx; dx++) {
214 a += (*sp);
215 /* next x */
216 sp++;
217 }
218 /* end src dx loop */
219 /* next y */
220 sp = (Uint8 *)((Uint8*)sp + (src->pitch - factorx));
221 }
222 /* end src dy loop */
223
224 /* next box-x */
225 sp = (Uint8 *)((Uint8*)oosp + factorx);
226
227 /* Store result in destination */
228 *dp = a/n_average;
229
230 /*
231 * Advance destination pointer
232 */
233 dp++;
234 }
235 /* end dst x loop */
236
237 /* next box-y */
238 sp = (Uint8 *)((Uint8*)osp + src->pitch*factory);
239
240 /*
241 * Advance destination pointers
242 */
243 dp = (Uint8 *)((Uint8 *)dp + dgap);
244 }
245 /* end dst y loop */
246
247 return (0);
248}
249
250/*!
251\brief Internal 32 bit Zoomer with optional anti-aliasing by bilinear interpolation.
252
253Zooms 32 bit RGBA/ABGR 'src' surface to 'dst' surface.
254Assumes src and dst surfaces are of 32 bit depth.
255Assumes dst surface was allocated with the correct dimensions.
256
257\param src The surface to zoom (input).
258\param dst The zoomed surface (output).
259\param flipx Flag indicating if the image should be horizontally flipped.
260\param flipy Flag indicating if the image should be vertically flipped.
261\param smooth Antialiasing flag; set to SMOOTHING_ON to enable.
262
263\return 0 for success or -1 for error.
264*/
265int _zoomSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy, int smooth)
266{
267 int x, y, sx, sy, *sax, *say, *csax, *csay, csx, csy, ex, ey, t1, t2, sstep, lx, ly;
268 tColorRGBA *c00, *c01, *c10, *c11, *cswap;
269 tColorRGBA *sp, *csp, *dp;
270 int dgap;
271
272 /*
273 * Variable setup
274 */
275 if (smooth) {
276 /*
277 * For interpolation: assume source dimension is one pixel
278 * smaller to avoid overflow on right and bottom edge.
279 */
280 sx = (int) (65536.0 * (float) (src->w - 1) / (float) dst->w);
281 sy = (int) (65536.0 * (float) (src->h - 1) / (float) dst->h);
282 } else {
283 sx = (int) (65536.0 * (float) src->w / (float) dst->w);
284 sy = (int) (65536.0 * (float) src->h / (float) dst->h);
285 }
286
287 /*
288 * Allocate memory for row increments
289 */
290 if ((sax = (int *) malloc((dst->w + 1) * sizeof(Uint32))) == NULL) {
291 return (-1);
292 }
293 if ((say = (int *) malloc((dst->h + 1) * sizeof(Uint32))) == NULL) {
294 free(sax);
295 return (-1);
296 }
297
298 /*
299 * Precalculate row increments
300 */
301 sp = csp = (tColorRGBA *) src->pixels;
302 dp = (tColorRGBA *) dst->pixels;
303
304 if (flipx) csp += (src->w-1);
305 if (flipy) csp += ((src->pitch/4)*(src->h-1));
306
307 csx = 0;
308 csax = sax;
309 for (x = 0; x <= dst->w; x++) {
310 *csax = csx;
311 csax++;
312 csx &= 0xffff;
313 csx += sx;
314 }
315 csy = 0;
316 csay = say;
317 for (y = 0; y <= dst->h; y++) {
318 *csay = csy;
319 csay++;
320 csy &= 0xffff;
321 csy += sy;
322 }
323
324 dgap = dst->pitch - dst->w * 4;
325
326 /*
327 * Switch between interpolating and non-interpolating code
328 */
329 if (smooth) {
330
331 /*
332 * Interpolating Zoom
333 */
334
335 /*
336 * Scan destination
337 */
338 csay = say;
339 ly = 0;
340 for (y = 0; y < dst->h; y++) {
341 /*
342 * Setup color source pointers
343 */
344 c00 = csp;
345 c01 = csp;
346 c01++;
347 c10 = csp;
348 c10 += src->pitch/4;
349 c11 = c10;
350 c11++;
351 if (flipx) {
352 cswap = c00; c00=c01; c01=cswap;
353 cswap = c10; c10=c11; c11=cswap;
354 }
355 if (flipy) {
356 cswap = c00; c00=c10; c10=cswap;
357 cswap = c01; c01=c11; c11=cswap;
358 }
359
360 csax = sax;
361 lx = 0;
362 for (x = 0; x < dst->w; x++) {
363 /*
364 * Draw and interpolate colors
365 */
366 ex = (*csax & 0xffff);
367 ey = (*csay & 0xffff);
368 t1 = ((((c01->r - c00->r) * ex) >> 16) + c00->r) & 0xff;
369 t2 = ((((c11->r - c10->r) * ex) >> 16) + c10->r) & 0xff;
370 dp->r = (((t2 - t1) * ey) >> 16) + t1;
371 t1 = ((((c01->g - c00->g) * ex) >> 16) + c00->g) & 0xff;
372 t2 = ((((c11->g - c10->g) * ex) >> 16) + c10->g) & 0xff;
373 dp->g = (((t2 - t1) * ey) >> 16) + t1;
374 t1 = ((((c01->b - c00->b) * ex) >> 16) + c00->b) & 0xff;
375 t2 = ((((c11->b - c10->b) * ex) >> 16) + c10->b) & 0xff;
376 dp->b = (((t2 - t1) * ey) >> 16) + t1;
377 t1 = ((((c01->a - c00->a) * ex) >> 16) + c00->a) & 0xff;
378 t2 = ((((c11->a - c10->a) * ex) >> 16) + c10->a) & 0xff;
379 dp->a = (((t2 - t1) * ey) >> 16) + t1;
380
381 /*
382 * Advance source pointers
383 */
384 csax++;
385 if (*csax > 0)
386 {
387 sstep = (*csax >> 16);
388 lx += sstep;
389 if (flipx) sstep = -sstep;
390 if (lx <= src->w)
391 {
392 c00 += sstep;
393 c01 += sstep;
394 c10 += sstep;
395 c11 += sstep;
396 }
397 }
398
399 /*
400 * Advance destination pointer
401 */
402 dp++;
403 }
404
405 /*
406 * Advance source pointer
407 */
408 csay++;
409 if (*csay > 0)
410 {
411 sstep = (*csay >> 16);
412 ly += sstep;
413 if (flipy) sstep = -sstep;
414 if (ly < src->h)
415 {
416 csp += (sstep * (src->pitch/4));
417 }
418 }
419
420 /*
421 * Advance destination pointers
422 */
423 dp = (tColorRGBA *) ((Uint8 *) dp + dgap);
424 }
425 } else {
426
427 /*
428 * Non-Interpolating Zoom
429 */
430 csay = say;
431 for (y = 0; y < dst->h; y++) {
432 sp = csp;
433 csax = sax;
434 for (x = 0; x < dst->w; x++) {
435 /*
436 * Draw
437 */
438 *dp = *sp;
439 /*
440 * Advance source pointers
441 */
442 csax++;
443 if (*csax > 0)
444 {
445 sstep = (*csax >> 16);
446 if (flipx) sstep = -sstep;
447 sp += sstep;
448 }
449 /*
450 * Advance destination pointer
451 */
452 dp++;
453 }
454 /*
455 * Advance source pointer
456 */
457 csay++;
458 if (*csay > 0)
459 {
460 sstep = (*csay >> 16) * (src->pitch/4);
461 if (flipy) sstep = -sstep;
462 csp += sstep;
463 }
464
465 /*
466 * Advance destination pointers
467 */
468 dp = (tColorRGBA *) ((Uint8 *) dp + dgap);
469 }
470 }
471
472 /*
473 * Remove temp arrays
474 */
475 free(sax);
476 free(say);
477
478 return (0);
479}
480
481/*!
482
483\brief Internal 8 bit Zoomer without smoothing.
484
485Zooms 8bit palette/Y 'src' surface to 'dst' surface.
486Assumes src and dst surfaces are of 8 bit depth.
487Assumes dst surface was allocated with the correct dimensions.
488
489\param src The surface to zoom (input).
490\param dst The zoomed surface (output).
491\param flipx Flag indicating if the image should be horizontally flipped.
492\param flipy Flag indicating if the image should be vertically flipped.
493
494\return 0 for success or -1 for error.
495*/
496int _zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy)
497{
498 int x, y;
499 Uint32 *sax, *say, *csax, *csay;
500 int csx, csy;
501 Uint8 *sp, *dp, *csp;
502 int dgap;
503
504 /*
505 * Allocate memory for row increments
506 */
507 if ((sax = (Uint32 *) malloc((dst->w + 1) * sizeof(Uint32))) == NULL) {
508 return (-1);
509 }
510 if ((say = (Uint32 *) malloc((dst->h + 1) * sizeof(Uint32))) == NULL) {
511 free(sax);
512 return (-1);
513 }
514
515 /*
516 * Pointer setup
517 */
518 sp = csp = (Uint8 *) src->pixels;
519 dp = (Uint8 *) dst->pixels;
520 dgap = dst->pitch - dst->w;
521
522 if (flipx) csp += (src->w-1);
523 if (flipy) csp = ( (Uint8*)csp + src->pitch*(src->h-1) );
524
525 /*
526 * Precalculate row increments
527 */
528 csx = 0;
529 csax = sax;
530 for (x = 0; x < dst->w; x++) {
531 csx += src->w;
532 *csax = 0;
533 while (csx >= dst->w) {
534 csx -= dst->w;
535 (*csax)++;
536 }
537 csax++;
538 }
539 csy = 0;
540 csay = say;
541 for (y = 0; y < dst->h; y++) {
542 csy += src->h;
543 *csay = 0;
544 while (csy >= dst->h) {
545 csy -= dst->h;
546 (*csay)++;
547 }
548 csay++;
549 }
550
551 /*
552 * Draw
553 */
554 csay = say;
555 for (y = 0; y < dst->h; y++) {
556 csax = sax;
557 sp = csp;
558 for (x = 0; x < dst->w; x++) {
559 /*
560 * Draw
561 */
562 *dp = *sp;
563 /*
564 * Advance source pointers
565 */
566 sp += (*csax) * (flipx ? -1 : 1);
567 csax++;
568 /*
569 * Advance destination pointer
570 */
571 dp++;
572 }
573 /*
574 * Advance source pointer (for row)
575 */
576 csp += ((*csay) * src->pitch) * (flipy ? -1 : 1);
577 csay++;
578
579 /*
580 * Advance destination pointers
581 */
582 dp += dgap;
583 }
584
585 /*
586 * Remove temp arrays
587 */
588 free(sax);
589 free(say);
590
591 return (0);
592}
593
594/*!
595\brief Internal 32 bit rotozoomer with optional anti-aliasing.
596
597Rotates and zooms 32 bit RGBA/ABGR 'src' surface to 'dst' surface based on the control
598parameters by scanning the destination surface and applying optionally anti-aliasing
599by bilinear interpolation.
600Assumes src and dst surfaces are of 32 bit depth.
601Assumes dst surface was allocated with the correct dimensions.
602
603\param src Source surface.
604\param dst Destination surface.
605\param cx Horizontal center coordinate.
606\param cy Vertical center coordinate.
607\param isin Integer version of sine of angle.
608\param icos Integer version of cosine of angle.
609\param flipx Flag indicating horizontal mirroring should be applied.
610\param flipy Flag indicating vertical mirroring should be applied.
611\param smooth Flag indicating anti-aliasing should be used.
612*/
613void _transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy, int smooth)
614{
615 int x, y, t1, t2, dx, dy, xd, yd, sdx, sdy, ax, ay, ex, ey, sw, sh;
616 tColorRGBA c00, c01, c10, c11, cswap;
617 tColorRGBA *pc, *sp;
618 int gap;
619
620 /*
621 * Variable setup
622 */
623 xd = ((src->w - dst->w) << 15);
624 yd = ((src->h - dst->h) << 15);
625 ax = (cx << 16) - (icos * cx);
626 ay = (cy << 16) - (isin * cx);
627 sw = src->w - 1;
628 sh = src->h - 1;
629 pc = (tColorRGBA*) dst->pixels;
630 gap = dst->pitch - dst->w * 4;
631
632 /*
633 * Switch between interpolating and non-interpolating code
634 */
635 if (smooth) {
636 for (y = 0; y < dst->h; y++) {
637 dy = cy - y;
638 sdx = (ax + (isin * dy)) + xd;
639 sdy = (ay - (icos * dy)) + yd;
640 for (x = 0; x < dst->w; x++) {
641 dx = (sdx >> 16);
642 dy = (sdy >> 16);
643 if (flipx) dx = sw - dx;
644 if (flipy) dy = sh - dy;
645 if ((dx > -1) && (dy > -1) && (dx < (src->w-1)) && (dy < (src->h-1))) {
646 sp = (tColorRGBA *)src->pixels;;
647 sp += ((src->pitch/4) * dy);
648 sp += dx;
649 c00 = *sp;
650 sp += 1;
651 c01 = *sp;
652 sp += (src->pitch/4);
653 c11 = *sp;
654 sp -= 1;
655 c10 = *sp;
656 if (flipx) {
657 cswap = c00; c00=c01; c01=cswap;
658 cswap = c10; c10=c11; c11=cswap;
659 }
660 if (flipy) {
661 cswap = c00; c00=c10; c10=cswap;
662 cswap = c01; c01=c11; c11=cswap;
663 }
664 /*
665 * Interpolate colors
666 */
667 ex = (sdx & 0xffff);
668 ey = (sdy & 0xffff);
669 t1 = ((((c01.r - c00.r) * ex) >> 16) + c00.r) & 0xff;
670 t2 = ((((c11.r - c10.r) * ex) >> 16) + c10.r) & 0xff;
671 pc->r = (((t2 - t1) * ey) >> 16) + t1;
672 t1 = ((((c01.g - c00.g) * ex) >> 16) + c00.g) & 0xff;
673 t2 = ((((c11.g - c10.g) * ex) >> 16) + c10.g) & 0xff;
674 pc->g = (((t2 - t1) * ey) >> 16) + t1;
675 t1 = ((((c01.b - c00.b) * ex) >> 16) + c00.b) & 0xff;
676 t2 = ((((c11.b - c10.b) * ex) >> 16) + c10.b) & 0xff;
677 pc->b = (((t2 - t1) * ey) >> 16) + t1;
678 t1 = ((((c01.a - c00.a) * ex) >> 16) + c00.a) & 0xff;
679 t2 = ((((c11.a - c10.a) * ex) >> 16) + c10.a) & 0xff;
680 pc->a = (((t2 - t1) * ey) >> 16) + t1;
681 }
682 sdx += icos;
683 sdy += isin;
684 pc++;
685 }
686 pc = (tColorRGBA *) ((Uint8 *) pc + gap);
687 }
688 } else {
689 for (y = 0; y < dst->h; y++) {
690 dy = cy - y;
691 sdx = (ax + (isin * dy)) + xd;
692 sdy = (ay - (icos * dy)) + yd;
693 for (x = 0; x < dst->w; x++) {
694 dx = (short) (sdx >> 16);
695 dy = (short) (sdy >> 16);
696 if (flipx) dx = (src->w-1)-dx;
697 if (flipy) dy = (src->h-1)-dy;
698 if ((dx >= 0) && (dy >= 0) && (dx < src->w) && (dy < src->h)) {
699 sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy);
700 sp += dx;
701 *pc = *sp;
702 }
703 sdx += icos;
704 sdy += isin;
705 pc++;
706 }
707 pc = (tColorRGBA *) ((Uint8 *) pc + gap);
708 }
709 }
710}
711
712/*!
713
714\brief Rotates and zooms 8 bit palette/Y 'src' surface to 'dst' surface without smoothing.
715
716Rotates and zooms 8 bit RGBA/ABGR 'src' surface to 'dst' surface based on the control
717parameters by scanning the destination surface.
718Assumes src and dst surfaces are of 8 bit depth.
719Assumes dst surface was allocated with the correct dimensions.
720
721\param src Source surface.
722\param dst Destination surface.
723\param cx Horizontal center coordinate.
724\param cy Vertical center coordinate.
725\param isin Integer version of sine of angle.
726\param icos Integer version of cosine of angle.
727\param flipx Flag indicating horizontal mirroring should be applied.
728\param flipy Flag indicating vertical mirroring should be applied.
729*/
730void transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy)
731{
732 int x, y, dx, dy, xd, yd, sdx, sdy, ax, ay, sw, sh;
733 tColorY *pc, *sp;
734 int gap;
735
736 /*
737 * Variable setup
738 */
739 xd = ((src->w - dst->w) << 15);
740 yd = ((src->h - dst->h) << 15);
741 ax = (cx << 16) - (icos * cx);
742 ay = (cy << 16) - (isin * cx);
743 sw = src->w - 1;
744 sh = src->h - 1;
745 pc = (tColorY*) dst->pixels;
746 gap = dst->pitch - dst->w;
747 /*
748 * Clear surface to colorkey
749 */
750 memset(pc, (int)(_colorkey(src) & 0xff), dst->pitch * dst->h);
751 /*
752 * Iterate through destination surface
753 */
754 for (y = 0; y < dst->h; y++) {
755 dy = cy - y;
756 sdx = (ax + (isin * dy)) + xd;
757 sdy = (ay - (icos * dy)) + yd;
758 for (x = 0; x < dst->w; x++) {
759 dx = (short) (sdx >> 16);
760 dy = (short) (sdy >> 16);
761 if (flipx) dx = (src->w-1)-dx;
762 if (flipy) dy = (src->h-1)-dy;
763 if ((dx >= 0) && (dy >= 0) && (dx < src->w) && (dy < src->h)) {
764 sp = (tColorY *) (src->pixels);
765 sp += (src->pitch * dy + dx);
766 *pc = *sp;
767 }
768 sdx += icos;
769 sdy += isin;
770 pc++;
771 }
772 pc += gap;
773 }
774}
775
776/*!
777\brief Rotates a 32 bit surface in increments of 90 degrees.
778
779Specialized 90 degree rotator which rotates a 'src' surface in 90 degree
780increments clockwise returning a new surface. Faster than rotozoomer since
781not scanning or interpolation takes place. Input surface must be 32 bit.
782(code contributed by J. Schiller, improved by C. Allport and A. Schiffler)
783
784\param src Source surface to rotate.
785\param numClockwiseTurns Number of clockwise 90 degree turns to apply to the source.
786
787\returns The new, rotated surface; or NULL for surfaces with incorrect input format.
788*/
789SDL_Surface* rotateSurface90Degrees(SDL_Surface* src, int numClockwiseTurns)
790{
791 int row, col, newWidth, newHeight;
792 int bpp, src_ipr, dst_ipr;
793 SDL_Surface* dst;
794 Uint32* srcBuf;
795 Uint32* dstBuf;
796
797 /* Has to be a valid surface pointer and only 32-bit surfaces (for now) */
798 if (!src || src->format->BitsPerPixel != 32) { return NULL; }
799
800 /* normalize numClockwiseTurns */
801 while(numClockwiseTurns < 0) { numClockwiseTurns += 4; }
802 numClockwiseTurns = (numClockwiseTurns % 4);
803
804 /* if it's even, our new width will be the same as the source surface */
805 newWidth = (numClockwiseTurns % 2) ? (src->h) : (src->w);
806 newHeight = (numClockwiseTurns % 2) ? (src->w) : (src->h);
807 dst = SDL_CreateRGBSurface( src->flags, newWidth, newHeight, src->format->BitsPerPixel,
808 src->format->Rmask,
809 src->format->Gmask,
810 src->format->Bmask,
811 src->format->Amask);
812 if(!dst) {
813 return NULL;
814 }
815
816 if (SDL_MUSTLOCK(dst)) {
817 SDL_LockSurface(dst);
818 }
819 if (SDL_MUSTLOCK(dst)) {
820 SDL_LockSurface(dst);
821 }
822
823 /* Calculate int-per-row */
824 bpp = src->format->BitsPerPixel / 8;
825 src_ipr = src->pitch / bpp;
826 dst_ipr = dst->pitch / bpp;
827
828 switch(numClockwiseTurns) {
829 case 0: /* Make a copy of the surface */
830 {
831 /* Unfortunately SDL_BlitSurface cannot be used to make a copy of the surface
832 since it does not preserve alpha. */
833
834 if (src->pitch == dst->pitch) {
835 /* If the pitch is the same for both surfaces, the memory can be copied all at once. */
836 memcpy(dst->pixels, src->pixels, (src->h * src->pitch));
837 }
838 else
839 {
840 /* If the pitch differs, copy each row separately */
841 srcBuf = (Uint32*)(src->pixels);
842 dstBuf = (Uint32*)(dst->pixels);
843 for (row = 0; row < src->h; row++) {
844 memcpy(dstBuf, srcBuf, dst->w * bpp);
845 srcBuf += src_ipr;
846 dstBuf += dst_ipr;
847 } /* end for(col) */
848 } /* end for(row) */
849 }
850 break;
851
852 /* rotate clockwise */
853 case 1: /* rotated 90 degrees clockwise */
854 {
855 for (row = 0; row < src->h; ++row) {
856 srcBuf = (Uint32*)(src->pixels) + (row * src_ipr);
857 dstBuf = (Uint32*)(dst->pixels) + (dst->w - row - 1);
858 for (col = 0; col < src->w; ++col) {
859 *dstBuf = *srcBuf;
860 ++srcBuf;
861 dstBuf += dst_ipr;
862 }
863 /* end for(col) */
864 }
865 /* end for(row) */
866 }
867 break;
868
869 case 2: /* rotated 180 degrees clockwise */
870 {
871 for (row = 0; row < src->h; ++row) {
872 srcBuf = (Uint32*)(src->pixels) + (row * src_ipr);
873 dstBuf = (Uint32*)(dst->pixels) + ((dst->h - row - 1) * dst_ipr) + (dst->w - 1);
874 for (col = 0; col < src->w; ++col) {
875 *dstBuf = *srcBuf;
876 ++srcBuf;
877 --dstBuf;
878 }
879 }
880 }
881 break;
882
883 case 3:
884 {
885 for (row = 0; row < src->h; ++row) {
886 srcBuf = (Uint32*)(src->pixels) + (row * src_ipr);
887 dstBuf = (Uint32*)(dst->pixels) + row + ((dst->h - 1) * dst_ipr);
888 for (col = 0; col < src->w; ++col) {
889 *dstBuf = *srcBuf;
890 ++srcBuf;
891 dstBuf -= dst_ipr;
892 }
893 }
894 }
895 break;
896 }
897 /* end switch */
898
899 if (SDL_MUSTLOCK(src)) {
900 SDL_UnlockSurface(src);
901 }
902 if (SDL_MUSTLOCK(dst)) {
903 SDL_UnlockSurface(dst);
904 }
905
906 return dst;
907}
908
909
910/*!
911\brief Internal target surface sizing function for rotozooms with trig result return.
912
913\param width The source surface width.
914\param height The source surface height.
915\param angle The angle to rotate in degrees.
916\param zoomx The horizontal scaling factor.
917\param zoomy The vertical scaling factor.
918\param dstwidth The calculated width of the destination surface.
919\param dstheight The calculated height of the destination surface.
920\param canglezoom The sine of the angle adjusted by the zoom factor.
921\param sanglezoom The cosine of the angle adjusted by the zoom factor.
922
923*/
924void _rotozoomSurfaceSizeTrig(int width, int height, double angle, double zoomx, double zoomy,
925 int *dstwidth, int *dstheight,
926 double *canglezoom, double *sanglezoom)
927{
928 double x, y, cx, cy, sx, sy;
929 double radangle;
930 int dstwidthhalf, dstheighthalf;
931
932 /*
933 * Determine destination width and height by rotating a centered source box
934 */
935 radangle = angle * (M_PI / 180.0);
936 *sanglezoom = sin(radangle);
937 *canglezoom = cos(radangle);
938 *sanglezoom *= zoomx;
939 *canglezoom *= zoomx;
940 x = (double)(width / 2);
941 y = (double)(height / 2);
942 cx = *canglezoom * x;
943 cy = *canglezoom * y;
944 sx = *sanglezoom * x;
945 sy = *sanglezoom * y;
946
947 dstwidthhalf = MAX((int)
948 ceil(MAX(MAX(MAX(fabs(cx + sy), fabs(cx - sy)), fabs(-cx + sy)), fabs(-cx - sy))), 1);
949 dstheighthalf = MAX((int)
950 ceil(MAX(MAX(MAX(fabs(sx + cy), fabs(sx - cy)), fabs(-sx + cy)), fabs(-sx - cy))), 1);
951 *dstwidth = 2 * dstwidthhalf;
952 *dstheight = 2 * dstheighthalf;
953}
954
955/*!
956\brief Returns the size of the resulting target surface for a rotozoomSurfaceXY() call.
957
958\param width The source surface width.
959\param height The source surface height.
960\param angle The angle to rotate in degrees.
961\param zoomx The horizontal scaling factor.
962\param zoomy The vertical scaling factor.
963\param dstwidth The calculated width of the rotozoomed destination surface.
964\param dstheight The calculated height of the rotozoomed destination surface.
965*/
966void rotozoomSurfaceSizeXY(int width, int height, double angle, double zoomx, double zoomy, int *dstwidth, int *dstheight)
967{
968 double dummy_sanglezoom, dummy_canglezoom;
969
970 _rotozoomSurfaceSizeTrig(width, height, angle, zoomx, zoomy, dstwidth, dstheight, &dummy_sanglezoom, &dummy_canglezoom);
971}
972
973/*!
974\brief Returns the size of the resulting target surface for a rotozoomSurface() call.
975
976\param width The source surface width.
977\param height The source surface height.
978\param angle The angle to rotate in degrees.
979\param zoom The scaling factor.
980\param dstwidth The calculated width of the rotozoomed destination surface.
981\param dstheight The calculated height of the rotozoomed destination surface.
982*/
983void rotozoomSurfaceSize(int width, int height, double angle, double zoom, int *dstwidth, int *dstheight)
984{
985 double dummy_sanglezoom, dummy_canglezoom;
986
987 _rotozoomSurfaceSizeTrig(width, height, angle, zoom, zoom, dstwidth, dstheight, &dummy_sanglezoom, &dummy_canglezoom);
988}
989
990/*!
991\brief Rotates and zooms a surface and optional anti-aliasing.
992
993Rotates and zoomes a 32bit or 8bit 'src' surface to newly created 'dst' surface.
994'angle' is the rotation in degrees and 'zoom' a scaling factor. If 'smooth' is set
995then the destination 32bit surface is anti-aliased. If the surface is not 8bit
996or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly.
997
998\param src The surface to rotozoom.
999\param angle The angle to rotate in degrees.
1000\param zoom The scaling factor.
1001\param smooth Antialiasing flag; set to SMOOTHING_ON to enable.
1002
1003\return The new rotozoomed surface.
1004*/
1005SDL_Surface *rotozoomSurface(SDL_Surface * src, double angle, double zoom, int smooth)
1006{
1007 return rotozoomSurfaceXY(src, angle, zoom, zoom, smooth);
1008}
1009
1010/*!
1011\brief Rotates and zooms a surface with different horizontal and vertival scaling factors and optional anti-aliasing.
1012
1013Rotates and zooms a 32bit or 8bit 'src' surface to newly created 'dst' surface.
1014'angle' is the rotation in degrees, 'zoomx and 'zoomy' scaling factors. If 'smooth' is set
1015then the destination 32bit surface is anti-aliased. If the surface is not 8bit
1016or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly.
1017
1018\param src The surface to rotozoom.
1019\param angle The angle to rotate in degrees.
1020\param zoomx The horizontal scaling factor.
1021\param zoomy The vertical scaling factor.
1022\param smooth Antialiasing flag; set to SMOOTHING_ON to enable.
1023
1024\return The new rotozoomed surface.
1025*/
1026SDL_Surface *rotozoomSurfaceXY(SDL_Surface * src, double angle, double zoomx, double zoomy, int smooth)
1027{
1028 SDL_Surface *rz_src;
1029 SDL_Surface *rz_dst;
1030 double zoominv;
1031 double sanglezoom, canglezoom, sanglezoominv, canglezoominv;
1032 int dstwidthhalf, dstwidth, dstheighthalf, dstheight;
1033 int is32bit;
1034 int i, src_converted;
1035 int flipx,flipy;
1036 Uint8 r,g,b;
1037 Uint32 colorkey = 0;
1038 int colorKeyAvailable = 0;
1039
1040 /*
1041 * Sanity check
1042 */
1043 if (src == NULL)
1044 return (NULL);
1045
1046 if (src->flags & SDL_SRCCOLORKEY)
1047 {
1048 colorkey = _colorkey(src);
1049 SDL_GetRGB(colorkey, src->format, &r, &g, &b);
1050 colorKeyAvailable = 1;
1051 }
1052 /*
1053 * Determine if source surface is 32bit or 8bit
1054 */
1055 is32bit = (src->format->BitsPerPixel == 32);
1056 if ((is32bit) || (src->format->BitsPerPixel == 8)) {
1057 /*
1058 * Use source surface 'as is'
1059 */
1060 rz_src = src;
1061 src_converted = 0;
1062 } else {
1063 /*
1064 * New source surface is 32bit with a defined RGBA ordering
1065 */
1066 rz_src =
1067 SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32,
1068#if SDL_BYTEORDER == SDL_LIL_ENDIAN
1069 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000
1070#else
1071 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff
1072#endif
1073 );
1074 if(colorKeyAvailable)
1075 SDL_SetColorKey(src, 0, 0);
1076
1077 SDL_BlitSurface(src, NULL, rz_src, NULL);
1078
1079 if(colorKeyAvailable)
1080 SDL_SetColorKey(src, SDL_SRCCOLORKEY, colorkey);
1081 src_converted = 1;
1082 is32bit = 1;
1083 }
1084
1085 /*
1086 * Sanity check zoom factor
1087 */
1088 flipx = (zoomx<0.0);
1089 if (flipx) zoomx=-zoomx;
1090 flipy = (zoomy<0.0);
1091 if (flipy) zoomy=-zoomy;
1092 if (zoomx < VALUE_LIMIT) zoomx = VALUE_LIMIT;
1093 if (zoomy < VALUE_LIMIT) zoomy = VALUE_LIMIT;
1094 zoominv = 65536.0 / (zoomx * zoomx);
1095
1096 /*
1097 * Check if we have a rotozoom or just a zoom
1098 */
1099 if (fabs(angle) > VALUE_LIMIT) {
1100
1101 /*
1102 * Angle!=0: full rotozoom
1103 */
1104 /*
1105 * -----------------------
1106 */
1107
1108 /* Determine target size */
1109 _rotozoomSurfaceSizeTrig(rz_src->w, rz_src->h, angle, zoomx, zoomy, &dstwidth, &dstheight, &canglezoom, &sanglezoom);
1110
1111 /*
1112 * Calculate target factors from sin/cos and zoom
1113 */
1114 sanglezoominv = sanglezoom;
1115 canglezoominv = canglezoom;
1116 sanglezoominv *= zoominv;
1117 canglezoominv *= zoominv;
1118
1119 /* Calculate half size */
1120 dstwidthhalf = dstwidth / 2;
1121 dstheighthalf = dstheight / 2;
1122
1123 /*
1124 * Alloc space to completely contain the rotated surface
1125 */
1126 rz_dst = NULL;
1127 if (is32bit) {
1128 /*
1129 * Target surface is 32bit with source RGBA/ABGR ordering
1130 */
1131 rz_dst =
1132 SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 32,
1133 rz_src->format->Rmask, rz_src->format->Gmask,
1134 rz_src->format->Bmask, rz_src->format->Amask);
1135 } else {
1136 /*
1137 * Target surface is 8bit
1138 */
1139 rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 8, 0, 0, 0, 0);
1140 }
1141
1142 /* Check target */
1143 if (rz_dst == NULL)
1144 return NULL;
1145
1146 /* Adjust for guard rows */
1147 rz_dst->h = dstheight;
1148
1149 if (colorKeyAvailable == 1){
1150 colorkey = SDL_MapRGB(rz_dst->format, r, g, b);
1151
1152 SDL_FillRect(rz_dst, NULL, colorkey );
1153 }
1154
1155 /*
1156 * Lock source surface
1157 */
1158 if (SDL_MUSTLOCK(rz_src)) {
1159 SDL_LockSurface(rz_src);
1160 }
1161
1162 /*
1163 * Check which kind of surface we have
1164 */
1165 if (is32bit) {
1166 /*
1167 * Call the 32bit transformation routine to do the rotation (using alpha)
1168 */
1169 _transformSurfaceRGBA(rz_src, rz_dst, dstwidthhalf, dstheighthalf,
1170 (int) (sanglezoominv), (int) (canglezoominv),
1171 flipx, flipy,
1172 smooth);
1173 /*
1174 * Turn on source-alpha support
1175 */
1176 SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255);
1177 SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, _colorkey(rz_src));
1178 } else {
1179 /*
1180 * Copy palette and colorkey info
1181 */
1182 for (i = 0; i < rz_src->format->palette->ncolors; i++) {
1183 rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i];
1184 }
1185 rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors;
1186 /*
1187 * Call the 8bit transformation routine to do the rotation
1188 */
1189 transformSurfaceY(rz_src, rz_dst, dstwidthhalf, dstheighthalf,
1190 (int) (sanglezoominv), (int) (canglezoominv),
1191 flipx, flipy);
1192 SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, _colorkey(rz_src));
1193 }
1194 /*
1195 * Unlock source surface
1196 */
1197 if (SDL_MUSTLOCK(rz_src)) {
1198 SDL_UnlockSurface(rz_src);
1199 }
1200
1201 } else {
1202
1203 /*
1204 * Angle=0: Just a zoom
1205 */
1206 /*
1207 * --------------------
1208 */
1209
1210 /*
1211 * Calculate target size
1212 */
1213 zoomSurfaceSize(rz_src->w, rz_src->h, zoomx, zoomy, &dstwidth, &dstheight);
1214
1215 /*
1216 * Alloc space to completely contain the zoomed surface
1217 */
1218 rz_dst = NULL;
1219 if (is32bit) {
1220 /*
1221 * Target surface is 32bit with source RGBA/ABGR ordering
1222 */
1223 rz_dst =
1224 SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 32,
1225 rz_src->format->Rmask, rz_src->format->Gmask,
1226 rz_src->format->Bmask, rz_src->format->Amask);
1227 } else {
1228 /*
1229 * Target surface is 8bit
1230 */
1231 rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 8, 0, 0, 0, 0);
1232 }
1233
1234 /* Check target */
1235 if (rz_dst == NULL)
1236 return NULL;
1237
1238 /* Adjust for guard rows */
1239 rz_dst->h = dstheight;
1240
1241 if (colorKeyAvailable == 1){
1242 colorkey = SDL_MapRGB(rz_dst->format, r, g, b);
1243
1244 SDL_FillRect(rz_dst, NULL, colorkey );
1245 }
1246
1247 /*
1248 * Lock source surface
1249 */
1250 if (SDL_MUSTLOCK(rz_src)) {
1251 SDL_LockSurface(rz_src);
1252 }
1253
1254 /*
1255 * Check which kind of surface we have
1256 */
1257 if (is32bit) {
1258 /*
1259 * Call the 32bit transformation routine to do the zooming (using alpha)
1260 */
1261 _zoomSurfaceRGBA(rz_src, rz_dst, flipx, flipy, smooth);
1262
1263 /*
1264 * Turn on source-alpha support
1265 */
1266 SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255);
1267 SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, _colorkey(rz_src));
1268 } else {
1269 /*
1270 * Copy palette and colorkey info
1271 */
1272 for (i = 0; i < rz_src->format->palette->ncolors; i++) {
1273 rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i];
1274 }
1275 rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors;
1276
1277 /*
1278 * Call the 8bit transformation routine to do the zooming
1279 */
1280 _zoomSurfaceY(rz_src, rz_dst, flipx, flipy);
1281 SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, _colorkey(rz_src));
1282 }
1283
1284 /*
1285 * Unlock source surface
1286 */
1287 if (SDL_MUSTLOCK(rz_src)) {
1288 SDL_UnlockSurface(rz_src);
1289 }
1290 }
1291
1292 /*
1293 * Cleanup temp surface
1294 */
1295 if (src_converted) {
1296 SDL_FreeSurface(rz_src);
1297 }
1298
1299 /*
1300 * Return destination surface
1301 */
1302 return (rz_dst);
1303}
1304
1305/*!
1306\brief Calculates the size of the target surface for a zoomSurface() call.
1307
1308The minimum size of the target surface is 1. The input factors can be positive or negative.
1309
1310\param width The width of the source surface to zoom.
1311\param height The height of the source surface to zoom.
1312\param zoomx The horizontal zoom factor.
1313\param zoomy The vertical zoom factor.
1314\param dstwidth Pointer to an integer to store the calculated width of the zoomed target surface.
1315\param dstheight Pointer to an integer to store the calculated height of the zoomed target surface.
1316*/
1317void zoomSurfaceSize(int width, int height, double zoomx, double zoomy, int *dstwidth, int *dstheight)
1318{
1319 /*
1320 * Make zoom factors positive
1321 */
1322 int flipx, flipy;
1323 flipx = (zoomx<0.0);
1324 if (flipx) zoomx = -zoomx;
1325 flipy = (zoomy<0.0);
1326 if (flipy) zoomy = -zoomy;
1327
1328 /*
1329 * Sanity check zoom factors
1330 */
1331 if (zoomx < VALUE_LIMIT) {
1332 zoomx = VALUE_LIMIT;
1333 }
1334 if (zoomy < VALUE_LIMIT) {
1335 zoomy = VALUE_LIMIT;
1336 }
1337
1338 /*
1339 * Calculate target size
1340 */
1341 *dstwidth = (int) ((double) width * zoomx);
1342 *dstheight = (int) ((double) height * zoomy);
1343 if (*dstwidth < 1) {
1344 *dstwidth = 1;
1345 }
1346 if (*dstheight < 1) {
1347 *dstheight = 1;
1348 }
1349}
1350
1351/*!
1352\brief Zoom a surface by independent horizontal and vertical factors with optional smoothing.
1353
1354Zooms a 32bit or 8bit 'src' surface to newly created 'dst' surface.
1355'zoomx' and 'zoomy' are scaling factors for width and height. If 'smooth' is on
1356then the destination 32bit surface is anti-aliased. If the surface is not 8bit
1357or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly.
1358If zoom factors are negative, the image is flipped on the axes.
1359
1360\param src The surface to zoom.
1361\param zoomx The horizontal zoom factor.
1362\param zoomy The vertical zoom factor.
1363\param smooth Antialiasing flag; set to SMOOTHING_ON to enable.
1364
1365\return The new, zoomed surface.
1366*/
1367SDL_Surface *zoomSurface(SDL_Surface * src, double zoomx, double zoomy, int smooth)
1368{
1369 SDL_Surface *rz_src;
1370 SDL_Surface *rz_dst;
1371 int dstwidth, dstheight;
1372 int is32bit;
1373 int i, src_converted;
1374 int flipx, flipy;
1375
1376 /*
1377 * Sanity check
1378 */
1379 if (src == NULL)
1380 return (NULL);
1381
1382 /*
1383 * Determine if source surface is 32bit or 8bit
1384 */
1385 is32bit = (src->format->BitsPerPixel == 32);
1386 if ((is32bit) || (src->format->BitsPerPixel == 8)) {
1387 /*
1388 * Use source surface 'as is'
1389 */
1390 rz_src = src;
1391 src_converted = 0;
1392 } else {
1393 /*
1394 * New source surface is 32bit with a defined RGBA ordering
1395 */
1396 rz_src =
1397 SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32,
1398#if SDL_BYTEORDER == SDL_LIL_ENDIAN
1399 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000
1400#else
1401 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff
1402#endif
1403 );
1404 SDL_BlitSurface(src, NULL, rz_src, NULL);
1405 src_converted = 1;
1406 is32bit = 1;
1407 }
1408
1409 flipx = (zoomx<0.0);
1410 if (flipx) zoomx = -zoomx;
1411 flipy = (zoomy<0.0);
1412 if (flipy) zoomy = -zoomy;
1413
1414 /* Get size if target */
1415 zoomSurfaceSize(rz_src->w, rz_src->h, zoomx, zoomy, &dstwidth, &dstheight);
1416
1417 /*
1418 * Alloc space to completely contain the zoomed surface
1419 */
1420 rz_dst = NULL;
1421 if (is32bit) {
1422 /*
1423 * Target surface is 32bit with source RGBA/ABGR ordering
1424 */
1425 rz_dst =
1426 SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 32,
1427 rz_src->format->Rmask, rz_src->format->Gmask,
1428 rz_src->format->Bmask, rz_src->format->Amask);
1429 } else {
1430 /*
1431 * Target surface is 8bit
1432 */
1433 rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 8, 0, 0, 0, 0);
1434 }
1435
1436 /* Check target */
1437 if (rz_dst == NULL)
1438 return NULL;
1439
1440 /* Adjust for guard rows */
1441 rz_dst->h = dstheight;
1442
1443 /*
1444 * Lock source surface
1445 */
1446 if (SDL_MUSTLOCK(rz_src)) {
1447 SDL_LockSurface(rz_src);
1448 }
1449
1450 /*
1451 * Check which kind of surface we have
1452 */
1453 if (is32bit) {
1454 /*
1455 * Call the 32bit transformation routine to do the zooming (using alpha)
1456 */
1457 _zoomSurfaceRGBA(rz_src, rz_dst, flipx, flipy, smooth);
1458 /*
1459 * Turn on source-alpha support
1460 */
1461 SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255);
1462 } else {
1463 /*
1464 * Copy palette and colorkey info
1465 */
1466 for (i = 0; i < rz_src->format->palette->ncolors; i++) {
1467 rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i];
1468 }
1469 rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors;
1470 /*
1471 * Call the 8bit transformation routine to do the zooming
1472 */
1473 _zoomSurfaceY(rz_src, rz_dst, flipx, flipy);
1474 SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, _colorkey(rz_src));
1475 }
1476 /*
1477 * Unlock source surface
1478 */
1479 if (SDL_MUSTLOCK(rz_src)) {
1480 SDL_UnlockSurface(rz_src);
1481 }
1482
1483 /*
1484 * Cleanup temp surface
1485 */
1486 if (src_converted) {
1487 SDL_FreeSurface(rz_src);
1488 }
1489
1490 /*
1491 * Return destination surface
1492 */
1493 return (rz_dst);
1494}
1495
1496/*!
1497\brief Shrink a surface by an integer ratio using averaging.
1498
1499Shrinks a 32bit or 8bit 'src' surface to a newly created 'dst' surface.
1500'factorx' and 'factory' are the shrinking ratios (i.e. 2=1/2 the size,
15013=1/3 the size, etc.) The destination surface is antialiased by averaging
1502the source box RGBA or Y information. If the surface is not 8bit
1503or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly.
1504The input surface is not modified. The output surface is newly allocated.
1505
1506\param src The surface to shrink.
1507\param factorx The horizontal shrinking ratio.
1508\param factory The vertical shrinking ratio.
1509
1510\return The new, shrunken surface.
1511*/
1512/*@null@*/
1513SDL_Surface *shrinkSurface(SDL_Surface *src, int factorx, int factory)
1514{
1515 int result;
1516 SDL_Surface *rz_src;
1517 SDL_Surface *rz_dst = NULL;
1518 int dstwidth, dstheight;
1519 int is32bit;
1520 int i, src_converted;
1521 int haveError = 0;
1522
1523 /*
1524 * Sanity check
1525 */
1526 if (src == NULL) {
1527 return (NULL);
1528 }
1529
1530 /*
1531 * Determine if source surface is 32bit or 8bit
1532 */
1533 is32bit = (src->format->BitsPerPixel == 32);
1534 if ((is32bit) || (src->format->BitsPerPixel == 8)) {
1535 /*
1536 * Use source surface 'as is'
1537 */
1538 rz_src = src;
1539 src_converted = 0;
1540 } else {
1541 /*
1542 * New source surface is 32bit with a defined RGBA ordering
1543 */
1544 rz_src = SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32,
1545#if SDL_BYTEORDER == SDL_LIL_ENDIAN
1546 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000
1547#else
1548 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff
1549#endif
1550 );
1551 if (rz_src==NULL) {
1552 haveError = 1;
1553 goto exitShrinkSurface;
1554 }
1555
1556 SDL_BlitSurface(src, NULL, rz_src, NULL);
1557 src_converted = 1;
1558 is32bit = 1;
1559 }
1560
1561 /*
1562 * Lock the surface
1563 */
1564 if (SDL_MUSTLOCK(rz_src)) {
1565 if (SDL_LockSurface(rz_src) < 0) {
1566 haveError = 1;
1567 goto exitShrinkSurface;
1568 }
1569 }
1570
1571 /* Get size for target */
1572 dstwidth=rz_src->w/factorx;
1573 while (dstwidth*factorx>rz_src->w) { dstwidth--; }
1574 dstheight=rz_src->h/factory;
1575 while (dstheight*factory>rz_src->h) { dstheight--; }
1576
1577 /*
1578 * Alloc space to completely contain the shrunken surface
1579 * (with added guard rows)
1580 */
1581 if (is32bit==1) {
1582 /*
1583 * Target surface is 32bit with source RGBA/ABGR ordering
1584 */
1585 rz_dst =
1586 SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 32,
1587 rz_src->format->Rmask, rz_src->format->Gmask,
1588 rz_src->format->Bmask, rz_src->format->Amask);
1589 } else {
1590 /*
1591 * Target surface is 8bit
1592 */
1593 rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 8, 0, 0, 0, 0);
1594 }
1595
1596 /* Check target */
1597 if (rz_dst == NULL) {
1598 haveError = 1;
1599 goto exitShrinkSurface;
1600 }
1601
1602 /* Adjust for guard rows */
1603 rz_dst->h = dstheight;
1604
1605 /*
1606 * Check which kind of surface we have
1607 */
1608 if (is32bit==1) {
1609 /*
1610 * Call the 32bit transformation routine to do the shrinking (using alpha)
1611 */
1612 result = _shrinkSurfaceRGBA(rz_src, rz_dst, factorx, factory);
1613 if ((result!=0) || (rz_dst==NULL)) {
1614 haveError = 1;
1615 goto exitShrinkSurface;
1616 }
1617
1618 /*
1619 * Turn on source-alpha support
1620 */
1621 result = SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255);
1622 if (result!=0) {
1623 haveError = 1;
1624 goto exitShrinkSurface;
1625 }
1626 } else {
1627 /*
1628 * Copy palette and colorkey info
1629 */
1630 for (i = 0; i < rz_src->format->palette->ncolors; i++) {
1631 rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i];
1632 }
1633 rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors;
1634 /*
1635 * Call the 8bit transformation routine to do the shrinking
1636 */
1637 result = _shrinkSurfaceY(rz_src, rz_dst, factorx, factory);
1638 if (result!=0) {
1639 haveError = 1;
1640 goto exitShrinkSurface;
1641 }
1642
1643 /*
1644 * Set colorkey on target
1645 */
1646 result = SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, _colorkey(rz_src));
1647 if (result!=0) {
1648 haveError = 1;
1649 goto exitShrinkSurface;
1650 }
1651 }
1652
1653exitShrinkSurface:
1654 if (rz_src!=NULL) {
1655 /*
1656 * Unlock source surface
1657 */
1658 if (SDL_MUSTLOCK(rz_src)) {
1659 SDL_UnlockSurface(rz_src);
1660 }
1661
1662 /*
1663 * Cleanup temp surface
1664 */
1665 if (src_converted==1) {
1666 SDL_FreeSurface(rz_src);
1667 }
1668 }
1669
1670 /* Check error state; maybe need to cleanup destination */
1671 if (haveError==1) {
1672 if (rz_dst!=NULL) {
1673 SDL_FreeSurface(rz_dst);
1674 }
1675 rz_dst=NULL;
1676 }
1677
1678 /*
1679 * Return destination surface
1680 */
1681 return (rz_dst);
1682}
diff --git a/SDL_rotozoom.h b/SDL_rotozoom.h
new file mode 100644
index 0000000..0d38b28
--- /dev/null
+++ b/SDL_rotozoom.h
@@ -0,0 +1,103 @@
1
2/*
3
4SDL_rotozoom - rotozoomer
5
6LGPL (c) A. Schiffler
7
8*/
9
10#ifndef _SDL_rotozoom_h
11#define _SDL_rotozoom_h
12
13#include <math.h>
14
15/* Set up for C function definitions, even when using C++ */
16#ifdef __cplusplus
17extern "C" {
18#endif
19
20#ifndef M_PI
21#define M_PI 3.141592654
22#endif
23
24#include "SDL.h"
25
26 /* ---- Defines */
27
28 /*!
29 \brief Disable anti-aliasing (no smoothing).
30 */
31#define SMOOTHING_OFF 0
32
33 /*!
34 \brief Enable anti-aliasing (smoothing).
35 */
36#define SMOOTHING_ON 1
37
38 /* ---- Function Prototypes */
39
40#ifdef _MSC_VER
41# if defined(DLL_EXPORT) && !defined(LIBSDL_GFX_DLL_IMPORT)
42# define SDL_ROTOZOOM_SCOPE __declspec(dllexport)
43# else
44# ifdef LIBSDL_GFX_DLL_IMPORT
45# define SDL_ROTOZOOM_SCOPE __declspec(dllimport)
46# endif
47# endif
48#endif
49#ifndef SDL_ROTOZOOM_SCOPE
50# define SDL_ROTOZOOM_SCOPE extern
51#endif
52
53 /*
54
55 Rotozoom functions
56
57 */
58
59 SDL_ROTOZOOM_SCOPE SDL_Surface *rotozoomSurface(SDL_Surface * src, double angle, double zoom, int smooth);
60
61 SDL_ROTOZOOM_SCOPE SDL_Surface *rotozoomSurfaceXY
62 (SDL_Surface * src, double angle, double zoomx, double zoomy, int smooth);
63
64
65 SDL_ROTOZOOM_SCOPE void rotozoomSurfaceSize(int width, int height, double angle, double zoom, int *dstwidth,
66 int *dstheight);
67
68 SDL_ROTOZOOM_SCOPE void rotozoomSurfaceSizeXY
69 (int width, int height, double angle, double zoomx, double zoomy,
70 int *dstwidth, int *dstheight);
71
72 /*
73
74 Zooming functions
75
76 */
77
78 SDL_ROTOZOOM_SCOPE SDL_Surface *zoomSurface(SDL_Surface * src, double zoomx, double zoomy, int smooth);
79
80 SDL_ROTOZOOM_SCOPE void zoomSurfaceSize(int width, int height, double zoomx, double zoomy, int *dstwidth, int *dstheight);
81
82 /*
83
84 Shrinking functions
85
86 */
87
88 SDL_ROTOZOOM_SCOPE SDL_Surface *shrinkSurface(SDL_Surface * src, int factorx, int factory);
89
90 /*
91
92 Specialized rotation functions
93
94 */
95
96 SDL_ROTOZOOM_SCOPE SDL_Surface* rotateSurface90Degrees(SDL_Surface* src, int numClockwiseTurns);
97
98 /* Ends C function definitions when using C++ */
99#ifdef __cplusplus
100}
101#endif
102
103#endif /* _SDL_rotozoom_h */
diff --git a/Utils.h b/Utils.h
index debcd07..49f6c3c 100644
--- a/Utils.h
+++ b/Utils.h
@@ -6,6 +6,8 @@
6#include <SDL_image.h> 6#include <SDL_image.h>
7#include <limits.h> 7#include <limits.h>
8 8
9#include "SDL_rotozoom.h"
10
9// 4:3 because _reasons_ 11// 4:3 because _reasons_
10#define WINDOW_WIDTH 1024 12#define WINDOW_WIDTH 1024
11#define WINDOW_HEIGHT 768 13#define WINDOW_HEIGHT 768
diff --git a/img/enemyBlack1.png b/img/enemyBlack1.png
new file mode 100644
index 0000000..bc2fa4c
--- /dev/null
+++ b/img/enemyBlack1.png
Binary files differ
diff --git a/img/laserBlue01.png b/img/laserBlue01.png
new file mode 100644
index 0000000..b76aaf7
--- /dev/null
+++ b/img/laserBlue01.png
Binary files differ
diff --git a/img/laserRed02.png b/img/laserRed02.png
new file mode 100644
index 0000000..1127fff
--- /dev/null
+++ b/img/laserRed02.png
Binary files differ
diff --git a/img/player.png b/img/player.png
new file mode 100644
index 0000000..9eddb93
--- /dev/null
+++ b/img/player.png
Binary files differ
diff --git a/space-zap.vcxproj b/space-zap.vcxproj
index 909ca3e..35401d1 100644
--- a/space-zap.vcxproj
+++ b/space-zap.vcxproj
@@ -112,7 +112,8 @@ copy D:\code\cpp\SDL_image-1.2.12\lib\x86\*.dll $(OutDir)</Command>
112 </Link> 112 </Link>
113 <PostBuildEvent> 113 <PostBuildEvent>
114 <Command>copy D:\code\cpp\SDL-1.2.15\lib\x64\SDL.dll $(OutDir) 114 <Command>copy D:\code\cpp\SDL-1.2.15\lib\x64\SDL.dll $(OutDir)
115copy D:\code\cpp\SDL_image-1.2.12\lib\x64\*.dll $(OutDir)</Command> 115copy D:\code\cpp\SDL_image-1.2.12\lib\x64\*.dll $(OutDir)
116copy $(MSBuildProjectDirectory)\img $(OutDir)</Command>
116 </PostBuildEvent> 117 </PostBuildEvent>
117 </ItemDefinitionGroup> 118 </ItemDefinitionGroup>
118 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> 119 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -161,6 +162,7 @@ copy D:\code\cpp\SDL_image-1.2.12\lib\x64\*.dll $(OutDir)</Command>
161 <ClCompile Include="Level.cpp" /> 162 <ClCompile Include="Level.cpp" />
162 <ClCompile Include="main.cpp" /> 163 <ClCompile Include="main.cpp" />
163 <ClCompile Include="Player.cpp" /> 164 <ClCompile Include="Player.cpp" />
165 <ClCompile Include="SDL_rotozoom.c" />
164 <ClCompile Include="Utils.cpp" /> 166 <ClCompile Include="Utils.cpp" />
165 </ItemGroup> 167 </ItemGroup>
166 <ItemGroup> 168 <ItemGroup>
@@ -170,6 +172,7 @@ copy D:\code\cpp\SDL_image-1.2.12\lib\x64\*.dll $(OutDir)</Command>
170 <ClInclude Include="Level.h" /> 172 <ClInclude Include="Level.h" />
171 <ClInclude Include="main.h" /> 173 <ClInclude Include="main.h" />
172 <ClInclude Include="Player.h" /> 174 <ClInclude Include="Player.h" />
175 <ClInclude Include="SDL_rotozoom.h" />
173 <ClInclude Include="Utils.h" /> 176 <ClInclude Include="Utils.h" />
174 </ItemGroup> 177 </ItemGroup>
175 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> 178 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
diff --git a/space-zap.vcxproj.filters b/space-zap.vcxproj.filters
index 4e85e78..4418398 100644
--- a/space-zap.vcxproj.filters
+++ b/space-zap.vcxproj.filters
@@ -36,6 +36,9 @@
36 <ClCompile Include="Player.cpp"> 36 <ClCompile Include="Player.cpp">
37 <Filter>Source Files</Filter> 37 <Filter>Source Files</Filter>
38 </ClCompile> 38 </ClCompile>
39 <ClCompile Include="SDL_rotozoom.c">
40 <Filter>Source Files</Filter>
41 </ClCompile>
39 </ItemGroup> 42 </ItemGroup>
40 <ItemGroup> 43 <ItemGroup>
41 <ClInclude Include="main.h"> 44 <ClInclude Include="main.h">
@@ -59,5 +62,8 @@
59 <ClInclude Include="Enemy.h"> 62 <ClInclude Include="Enemy.h">
60 <Filter>Header Files</Filter> 63 <Filter>Header Files</Filter>
61 </ClInclude> 64 </ClInclude>
65 <ClInclude Include="SDL_rotozoom.h">
66 <Filter>Header Files</Filter>
67 </ClInclude>
62 </ItemGroup> 68 </ItemGroup>
63</Project> \ No newline at end of file 69</Project> \ No newline at end of file