1 #include <math.h>
2 #include "config.h"
3 #include "sparkles.h"
4 #include "datafun.h"
5 #include "guru_meditation.h"
6 #include "ship.h"
7 #include "globals.h"
8 #include "random_gen.h"
9
10 struct black_point_struct {
11 int x, y;
12 };
13 static struct black_point_struct black_point[MAX_BLACK_POINTS], *blackptr =
14 black_point;
15
16 SDL_Surface *surf_small_ship;
17 sdl_surfaces_t *surfaces_ship;
18 struct sprite ship_sprite;
19 ship_t shipdata;
20
21
draw_little_ships(int nships,SDL_Surface * surf_screen)22 void draw_little_ships(int nships, SDL_Surface * surf_screen) {
23 int i;
24 SDL_Rect dest;
25
26 for(i = 0; i < nships - 1; i++) {
27 dest.w = surf_small_ship->w;
28 dest.h = surf_small_ship->h;
29 dest.x = (i + 1) * (surf_small_ship->w + 10);
30 dest.y = 40;
31 SDL_BlitSurface(surf_small_ship, NULL, surf_screen, &dest);
32 }
33 }
34
draw_ship(SDL_Surface * surf_screen)35 void draw_ship(SDL_Surface * surf_screen) {
36 static SDL_Rect dest;
37 dest.w = 0; //src.w;
38 dest.h = 0; //src.h;
39 dest.x = (int) shipdata.xship;
40 dest.y = (int) shipdata.yship;
41 SDL_BlitSurface(get_current_sprite_surface(&ship_sprite, last_ticks), NULL, surf_screen, &dest);
42 }
43
outline_detector()44 void outline_detector() {
45 char buf[256][256];
46 int x, y;
47 SDL_Surface *surf_ship = get_current_sprite_surface(&ship_sprite, last_ticks);
48
49 SDL_LockSurface(surf_ship);
50 RD_VIDEO_TYPE *raw_pixels = (RD_VIDEO_TYPE *) surf_ship->pixels;
51 x = surf_ship->w - 1;
52 y = surf_ship->h - 1;
53 RD_VIDEO_TYPE background = raw_pixels[y * surf_ship->pitch / sizeof(RD_VIDEO_TYPE) + x];
54 memset(buf, 0, sizeof(buf));
55 for(y = 0; y < surf_ship->h; y++) {
56 for(x = 0; x < surf_ship->w; x++) {
57 buf[x + 1][y + 1] = raw_pixels[y * surf_ship->pitch / sizeof(RD_VIDEO_TYPE) + x] != background;
58 }
59 }
60 for(y = 0; y < surf_ship->h + 2; y++) {
61 for(x = 0; x < surf_ship->w + 2; x++) {
62 if(buf[x][y] && (!buf[x][y - 1] || !buf[x][y + 1] || !buf[x - 1][y] || !buf[x + 1][y])) printf("%d %d\t", x - 1, y - 1);
63 }
64 putchar('\n');
65 }
66 SDL_UnlockSurface(surf_ship);
67 }
68
init_ship()69 SDL_Surface *init_ship() {
70 int i, j, numblack;
71 SDL_Surface *surf_ship;
72
73 // Load the spaceship surface from the spaceship file
74 if((surfaces_ship = load_images_ck("ship.%02x.png", 0, 255, 0)) == NULL) {
75 fprintf(stderr, "%s\n", SDL_GetError());
76 guru_meditation(GM_FLAGS_DEADEND | GM_FLAGS_ABORTIFY, GM_SS_Graphics | GM_GE_IOError | GURU_SEC_ship, (void*)0x53484950);
77 //We never return from there...
78 }
79 init_sprite2(&ship_sprite, surfaces_ship, 117, initticks);
80
81 /*
82 * Remember that we assume that the ship has always *exactly* the
83 * same size. If not you will get funny effects. And you will
84 * explode all the time, of course.
85 */
86 surf_ship = surfaces_ship->surfaces[0];
87 // Create the array of black points;
88 SDL_LockSurface(surf_ship);
89 RD_VIDEO_TYPE *raw_pixels = (RD_VIDEO_TYPE *) surf_ship->pixels;
90 numblack = 0;
91 for(i = 0; i < surf_ship->w; i++)
92 for(j = 0; j < surf_ship->h; j++)
93 if(raw_pixels[j * surf_ship->pitch / sizeof(RD_VIDEO_TYPE) + i] == 0) {
94 blackptr->x = i;
95 blackptr->y = j;
96 blackptr++;
97 if(++numblack > MAX_BLACK_POINTS)
98 return NULL;
99 }
100 SDL_UnlockSurface(surf_ship);
101 //outline_detector();
102 return surf_ship;
103 }
104
draw_ship_shield(SDL_Surface * surf_screen)105 void draw_ship_shield(SDL_Surface * surf_screen) {
106 // Show the freaky shields
107 RD_VIDEO_TYPE *raw_pixels = (RD_VIDEO_TYPE *) surf_screen->pixels;
108 struct black_point_struct *p;
109 int x, y;
110 RD_VIDEO_TYPE c;
111
112 SDL_LockSurface(surf_screen);
113 if(initialshield > 0) {
114 initialshield -= movementrate;
115 c = SDL_MapRGB(surf_screen->format, 0, 255, 255);
116 } else {
117 c = heatcolor[(int) shieldlevel];
118 shieldlevel -= movementrate;
119 }
120
121 shieldpulse += 0.1;
122 for(p = black_point; p < blackptr; p++) {
123 x = p->x + (int) shipdata.xship + (rnd() + rnd() - 1) * sin(shieldpulse) * 4 + 1;
124 y = p->y + (int) shipdata.yship + (rnd() + rnd() - 1) * sin(shieldpulse) * 4 + 1;
125 if(x > 0 && y > 0 && x < xsize && y < ysize) {
126 int offset = surf_screen->pitch / sizeof(RD_VIDEO_TYPE) * y + x;
127 raw_pixels[offset] = c;
128 }
129 }
130 SDL_UnlockSurface(surf_screen);
131 }
132
133
ship_check_collision(SDL_Surface * surf_screen)134 int ship_check_collision(SDL_Surface * surf_screen) {
135 struct black_point_struct *p;
136 RD_VIDEO_TYPE *raw_pixels;
137 int bang = 0;
138
139 SDL_LockSurface(surf_screen);
140 raw_pixels = (RD_VIDEO_TYPE *) surf_screen->pixels;
141 // When the shields are off, check that the black points
142 // on the ship are still black, and not covered up by rocks
143 for(p = black_point; p < blackptr; p++) {
144 int offset =
145 surf_screen->pitch / sizeof(RD_VIDEO_TYPE) * (p->y + (int) shipdata.yship) + p->x + (int) shipdata.xship;
146 if(raw_pixels[offset]) {
147 // Set the bang flag, a collision with something happened
148 bang = 1;
149 break;
150 }
151 }
152 SDL_UnlockSurface(surf_screen);
153 return bang;
154 }
155
ship_update_position(void)156 void ship_update_position(void) {
157 SDL_Surface *surf_ship = get_current_sprite_surface(&ship_sprite, last_ticks);
158
159 // FRICTION? In space? Oh well.
160 shipdata.xvel *= powf(0.9, movementrate);
161 shipdata.yvel *= powf(0.9, movementrate);
162 // if (abs(shipdata.xvel)<0.00001) shipdata.xvel=0;
163 // if (abs(shipdata.yvel)<0.00001) shipdata.yvel=0;
164
165 // INERTIA
166 shipdata.xship += shipdata.xvel * movementrate;
167 shipdata.yship += shipdata.yvel * movementrate;
168
169 // BOUNCE X (okay, throwing all pretense of realism out the
170 // window)
171 if(shipdata.xship < 0 || shipdata.xship > xsize - surf_ship->w) {
172 // BOUNCE from left and right wall
173 shipdata.xship -= shipdata.xvel * movementrate;
174 shipdata.xvel *= -0.99;
175 }
176 // BOUNCE Y
177 if(shipdata.yship < 0 || shipdata.yship > ysize - surf_ship->h) {
178 // BOUNCE from top and bottom wall
179 shipdata.yship -= shipdata.yvel * movementrate;
180 shipdata.yvel *= -0.99;
181 }
182 }
183
way_of_the_exploding_ship(void)184 void way_of_the_exploding_ship(void) {
185 makebangdots(shipdata.xship, shipdata.yship, shipdata.xvel, shipdata.yvel, get_current_sprite_surface(&ship_sprite, last_ticks), 30, 3);
186 }
187