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