1 /*
2 * IceBreaker
3 * Copyright (c) 2000-2002 Matthew Miller <mattdm@mattdm.org>
4 *
5 * <http://www.mattdm.org/icebreaker/>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc., 59
19 * Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23 #include <SDL.h>
24 #include <stdlib.h>
25 #include "icebreaker.h"
26 #include "globals.h"
27 #include "penguin.h"
28 #include "grid.h"
29 #include "line.h"
30 #include "level.h"
31 #include "options.h"
32 #include "themes.h"
33
34 static int createpenguinbgsave(Penguin* p);
35
createpenguin()36 Penguin createpenguin()
37 {
38 return(createpenguinxy(BORDERLEFT + (random() % (PLAYWIDTH-BLOCKWIDTH)),BORDERTOP + (random() % (PLAYHEIGHT-BLOCKWIDTH))));
39 }
40
createpenguinxy(int x,int y)41 Penguin createpenguinxy(int x, int y)
42 {
43 static Penguin p;
44
45 memset(&p, 0, sizeof(p));
46 switch (random() % 4)
47 {
48 case 0:
49 p.xdelta= PENGUINSPEED;p.ydelta= PENGUINSPEED;
50 p.image = spritemirrorimage;
51 break;
52 case 1:
53 p.xdelta= PENGUINSPEED;p.ydelta=-PENGUINSPEED;
54 p.image = spritemirrorimage;
55 break;
56 case 2:
57 p.xdelta=-PENGUINSPEED;p.ydelta= PENGUINSPEED;
58 p.image = spriteimage;
59 break;
60 case 3:
61 p.xdelta=-PENGUINSPEED;p.ydelta=-PENGUINSPEED;
62 p.image = spriteimage;
63 break;
64 }
65
66 // For debugging only, of course -- this makes crippled penguins.
67 //p.xdelta=0; p.ydelta=0;
68
69 p.speedslower=0;
70
71 p.geom.w=p.image->w;
72 p.geom.h=p.image->h;
73
74 //p.geom.x=BORDERLEFT + (PLAYWIDTH +BLOCKWIDTH )/2;
75 //p.geom.y=BORDERTOP + (PLAYHEIGHT+BLOCKHEIGHT)/2;
76
77 p.geom.x=x;
78 p.geom.y=y;
79
80 createpenguinbgsave(&p);
81
82 return(p);
83 }
84
deletepenguin(Penguin * p)85 void deletepenguin(Penguin* p)
86 {
87 SDL_FreeSurface(p->bgsave);
88 }
89
resetpenguinimage(Penguin * p)90 void resetpenguinimage(Penguin* p)
91 {
92 SDL_FreeSurface(p->bgsave);
93
94 if (p->xdelta>0)
95 p->image=spritemirrorimage;
96 else
97 p->image=spriteimage;
98
99 p->geom.w=p->image->w;
100 p->geom.h=p->image->h;
101
102
103 createpenguinbgsave(p);
104 }
105
106
savebehindpenguin(Penguin * p)107 void savebehindpenguin(Penguin* p)
108 {
109 SDL_BlitSurface(screen, &(p->geom), p->bgsave, NULL);
110 }
111
drawpenguin(Penguin * p)112 void drawpenguin(Penguin* p)
113 {
114 SDL_BlitSurface(p->image, NULL, screen, &(p->geom));
115 }
116
erasepenguin(Penguin * p)117 void erasepenguin(Penguin* p)
118 {
119 SDL_BlitSurface(p->bgsave, NULL, screen, &(p->geom));
120 }
121
movepenguin(Penguin * p)122 void movepenguin(Penguin* p)
123 {
124 int newx, newy;
125 int checkx,checky;
126 int movex=0,movey=0;
127
128 switch (options.difficulty)
129 {
130 case NORMAL:
131 if (p->speedslower)
132 { movex=p->xdelta/2; movey=p->ydelta/2; }
133 else
134 { movex=p->xdelta; movey=p->ydelta; }
135 p->speedslower=!p->speedslower;
136 break;
137 case HARD:
138 movex=p->xdelta; movey=p->ydelta;
139 break;
140 case EASY:
141 movex=p->xdelta/2; movey=p->ydelta/2;
142 break;
143 }
144
145 newx=p->geom.x+movex;
146 newy=p->geom.y+movey;
147
148
149 markgrid(p->geom.x,p->geom.y,BLOCKWIDTH,BLOCKHEIGHT,' ');
150
151 if (movex>0) checkx = newx+BLOCKWIDTH;
152 else checkx = newx;
153
154 if (grid[checkx][p->geom.y]==' ' && grid[checkx][p->geom.y+BLOCKHEIGHT-1]==' ')
155 {
156 p->geom.x+=movex;
157 }
158 else if (grid[checkx][p->geom.y]=='1' || grid[checkx][p->geom.y+BLOCKHEIGHT-1]=='1')
159 {
160 line1.dead=true;
161 p->geom.x+=movex;
162 }
163 else if (grid[checkx][p->geom.y]=='2' || grid[checkx][p->geom.y+BLOCKHEIGHT-1]=='2')
164 {
165 line2.dead=true;
166 p->geom.x+=movex;
167 }
168 else if ((grid[checkx][p->geom.y]=='w' || grid[checkx][p->geom.y]==' ' )
169 && (grid[checkx][p->geom.y+BLOCKHEIGHT-1]=='w' || grid[checkx][p->geom.y+BLOCKHEIGHT-1]==' '))
170 {
171 // this is used in the intro. maybe some place else too in the future.
172 // should it be merged into the first line above? maybe.
173 p->geom.x+=movex;
174 }
175 else
176 {
177 p->xdelta=-p->xdelta;
178 if (p->image==spriteimage)
179 p->image=spritemirrorimage;
180 else
181 p->image=spriteimage;
182 }
183
184 if (movey>0) checky = newy+BLOCKHEIGHT;
185 else checky = newy;
186
187 if (grid[p->geom.x][checky]==' ' && grid[p->geom.x+BLOCKWIDTH-1][checky]==' ')
188 {
189 p->geom.y+=movey;
190 }
191 else if (grid[p->geom.x][checky]=='1' || grid[p->geom.x+BLOCKWIDTH-1][checky]=='1')
192 {
193 //printf("Hit 1\n");
194 line1.dead=true;
195 p->geom.y+=movey;
196 }
197 else if (grid[p->geom.x][checky]=='2' || grid[p->geom.x+BLOCKWIDTH-1][checky]=='2')
198 {
199 //printf("Hit 2\n");
200 line2.dead=true;
201 p->geom.y+=movey;
202 }
203 else if ((grid[p->geom.x][checky]=='w' || grid[p->geom.x][checky]==' ')
204 && (grid[p->geom.x+BLOCKWIDTH-1][checky]=='w' || grid[p->geom.x+BLOCKWIDTH-1][checky]==' '))
205 {
206 // this is used in the intro. maybe some place else too in the future.
207 // should it be merged into the first line above? maybe.
208 p->geom.y+=movey;
209 }
210
211 else
212 {
213 p->ydelta=-p->ydelta;
214 }
215
216 markgrid(p->geom.x,p->geom.y,BLOCKWIDTH,BLOCKHEIGHT,'*');
217 }
218
createpenguinbgsave(Penguin * p)219 int createpenguinbgsave(Penguin* p)
220 {
221 SDL_Surface* tmpsurface;
222
223 tmpsurface = SDL_CreateRGBSurface(SDL_SWSURFACE,p->geom.w,p->geom.h,screen->format->BitsPerPixel,0,0,0,0);
224 // fix -- add error checking
225 p->bgsave = SDL_DisplayFormat(tmpsurface);
226 if (p->bgsave==NULL)
227 p->bgsave=tmpsurface;
228 else
229 SDL_FreeSurface(tmpsurface);
230
231 return 0;
232 }
233
234