1 #include "link2.h"
2 #include <SDL.h>
3 #include <SDL_image.h>
4 #include "SFont.h"
5 #include <string.h>
6 
7 extern int SCR_X;
8 extern int SCR_Y;
9 extern SDL_Surface *screen;
10 extern void (*commander) (Node*);
11 
12 #include "ai.h"
13 #include "files.h"
14 
15 extern int ai;
16 extern object adam, david, ball;
17 extern int difficult;
18 extern char file_path[];
19 
20 int number_points = 0;
21 
22 SDL_Surface *blue, *red;
23 
24 void really_quit(Node*);
25 SDL_Surface *LoadImage(char *datafile);
26 void main_menu(Node*);
27 void quit(Node*);
28 void options(Node*);
29 void toggle_ai(Node*);
30 void game_menu(Node*);
31 void change_name(Node*);
32 void change_user_adam(Node*);
33 void change_user_david(Node*);
34 void change_difficulty(Node*);
35 void change_points(Node*);
36 void points_up(Node*);
37 void points_down(Node*);
38 void write_my_config(Node*);
39 
putpixel(SDL_Surface * surface,int x,int y,Uint32 pixel)40 void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
41 {
42     int bpp = surface->format->BytesPerPixel;
43     /* Here p is the address to the pixel we want to set */
44     Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
45 
46     switch(bpp) {
47     case 1:
48         *p = pixel;
49         break;
50 
51     case 2:
52         *(Uint16 *)p = pixel;
53         break;
54 
55     case 3:
56         if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
57             p[0] = (pixel >> 16) & 0xff;
58             p[1] = (pixel >> 8) & 0xff;
59             p[2] = pixel & 0xff;
60         } else {
61             p[0] = pixel & 0xff;
62             p[1] = (pixel >> 8) & 0xff;
63             p[2] = (pixel >> 16) & 0xff;
64         }
65         break;
66 
67     case 4:
68         *(Uint32 *)p = pixel;
69         break;
70     }
71 }
72 
73 	//Loads an image using the right path
74 
LoadImage(char * datafile)75 SDL_Surface *LoadImage(char *datafile)
76 {
77 	SDL_Surface  *image;
78 	char datatemp[70];
79 	sprintf(datatemp, "%s%s", file_path, datafile);
80 	image = IMG_Load(datafile);
81 	if(image == NULL)
82 	{
83 		image = IMG_Load(datatemp);
84 	}
85 
86 	return (image);
87 }
88 
89 	// generates a horizonal line
h_line(int x,int y,int dest_x,Uint32 color)90 void h_line(int x, int y, int dest_x, Uint32 color)
91 {
92 	for( ; x < dest_x; x++)
93 		putpixel(screen, x, y, color);
94 }
95 
96 	// generates a vertical line line
v_line(int x,int y,int dest_y,Uint32 color)97 void v_line(int x, int y, int dest_y, Uint32 color)
98 {
99 	for( ; y < dest_y; y++)
100 		putpixel(screen, x, y, color);
101 }
102 	// inserts a new menu option into the list
make_option(Node * & head,int y,char * message,void (* command_pointer)(Node *),Node * ptr)103 void make_option(Node *&head, int y, char * message, void (*command_pointer)
104 (Node*), Node *ptr)
105 {
106 	Node temp;
107 	SDL_Rect rect;
108 
109 	rect.x = SCR_X/2 - TextWidth(message)/2;
110 	rect.y = y;
111 	rect.w = TextWidth(message);
112 	rect.h = blue->h;
113 
114 	temp.data.rect = rect;
115 	temp.data.mesg = message;
116 	temp.data.command = command_pointer;
117 	temp.data.ptr = ptr;
118 	list_head_insert(head, temp);
119 }
120 
121   // goes through the linked list and displays the menu options
display_options(Node * head,SDL_Surface * font)122 void display_options(Node *head, SDL_Surface *font)
123 
124 {
125 	Node * cursor;
126 	cursor = head;
127 
128 	InitFont(font);
129 
130 	while(cursor != NULL)
131 	{
132 		PutString(screen, cursor->data.rect.x, cursor->data.rect.y, cursor->data.mesg);
133 		SDL_UpdateRects(screen, 1, &cursor->data.rect);
134 		cursor = cursor->link;
135 	}
136 
137 }
138 
139 	// loads the fonts and initializes the cursor
start_me()140 void start_me()
141 {
142 
143 	blue=LoadImage("24P_Copperplate_Blue.png");
144 
145 	if(blue == NULL)
146 	{
147 		fprintf(stderr, "Can't load blue.  Get it stupid!");
148 		SDL_Quit();
149 		exit(1);
150 	}
151 
152 	red = LoadImage("red.png");
153 
154 	if(red == NULL)
155 	{
156 		fprintf(stderr, "Can't load red.  Get it stupid!");
157 		SDL_Quit();
158 		exit(1);
159 	}
160 
161 	InitFont(blue);
162 	SDL_ShowCursor(1);
163 }
164 
165 
166 	// check to see if the x and y coordinates are within a predefined rect region
check_rect(SDL_Rect rect,int x,int y)167 int check_rect(SDL_Rect rect, int x, int y)
168 {
169 
170 	if((x >= rect.x) && (x <= (rect.x + rect.w)))
171 	{
172 		if((y >= rect.y) && (y <= (rect.y + rect.h)))
173 
174 			return 1;
175 	}
176 
177 	return 0;
178 }
179 
180 	// checks to see if the mouse is over a menu option
check_region(Node * head,SDL_Event event)181 int check_region(Node *head, SDL_Event event)
182 {
183 	Node *cursor;
184 	cursor = head;
185 	int number = 1;
186 
187 	while(cursor!=NULL)
188 	{
189 		if(check_rect(cursor->data.rect, event.motion.x, event.motion.y))
190 			return number;
191 		else
192 		{
193 			cursor = cursor->link;
194 			number++;
195 		}
196 	}
197 
198 	return 0;
199 }
200 
201 
202 	// makes a box around a rect
make_box(SDL_Rect rect)203 void make_box(SDL_Rect rect)
204 {
205 	Uint32 c_red = SDL_MapRGB(screen->format, 255, 0, 0);
206 	h_line(rect.x, rect.y, rect.x + rect.w, c_red);
207 	v_line(rect.x, rect.y, rect.y + rect.h - 1, c_red);
208 	v_line(rect.x + rect.w - 1, rect.y, rect.y + rect.h, c_red);
209 	h_line(rect.x, rect.y + rect.h - 1, rect.x + rect.w, c_red);
210 }
211 
212 	// updates a single menu option with a specified font
update_region(Node * region,SDL_Surface * font,int underline)213 void update_region(Node *region, SDL_Surface *font, int underline)
214 {
215 	InitFont(font);
216 
217 	if(!underline)
218 	{
219 		Uint32 black = SDL_MapRGB(font->format, 0, 0, 0);
220 		SDL_FillRect(screen, &region->data.rect, black);
221 	}
222 
223 	PutString(screen, region->data.rect.x, region->data.rect.y, region->data.mesg);
224 
225 
226 	if(underline)
227 	{
228 		//Uint32 c_red = SDL_MapRGB(screen->format, 0xff, 0x00, 0x00);
229 
230 		SDL_LockSurface(screen);
231 		make_box(region->data.rect);
232 
233 	     	SDL_UnlockSurface(screen);
234 
235 	}
236 
237 	SDL_UpdateRects(screen, 1, &region->data.rect);
238 }
239 
240 
241 	// Handles menu events
menu(Node * head)242 void menu(Node *head)
243 {
244 
245 	Node *temp;
246 
247 	SDL_Event event;
248 	int region, new_region = 0;
249 
250 	while(1)
251 	{
252 		while(SDL_WaitEvent(&event))
253 		{
254 			switch(event.type)
255 			{
256 				case SDL_QUIT:
257 					SDL_Quit();
258 					exit(0);
259 					break;
260 
261 				case SDL_MOUSEMOTION:
262 					region = check_region(head, event);
263 
264 
265 
266 						if(region != new_region)
267 						{
268 
269 							if(region != 0)
270 							{
271 								if(list_locate(head, region)->data.command != NULL)
272 									update_region(list_locate(head, region), red, 1);
273 							}
274 
275 							if(region == 0)
276 								update_region(list_locate(head, new_region), blue, 0);
277 
278 							new_region = region;
279 						}
280 
281 
282 					break;
283 
284 				case SDL_MOUSEBUTTONDOWN:
285 					region = check_region(head, event);
286 
287 					if(region != 0)
288 					{
289 						temp = list_locate(head,region);
290 
291 						if(temp->data.command != NULL)
292 						{
293 							temp->data.command(temp->data.ptr);
294 						}
295 					}
296 
297 
298 					break;
299 			}
300 		}
301 	}
302 }
303 
304 	// clears a specified surface
clear_surface(SDL_Surface * surface)305 void clear_surface(SDL_Surface *surface)
306 {
307 	Uint32 black;
308 	SDL_Rect rect;
309 	rect.x = 0;
310 	rect.y = 0;
311 	rect.w = surface->w;
312 	rect.h = surface->h;
313 	black = SDL_MapRGB(surface->format, 0, 0, 0);
314 	SDL_FillRect(surface, &rect, black);
315 	SDL_UpdateRects(surface, 1, &rect);
316 }
317 
start_menu(Node * head,SDL_Surface * font)318 void start_menu(Node *head, SDL_Surface *font)
319 {
320 	if(head != NULL)
321 	{
322 		//SDL_WarpMouse(SCR_X/2, (list_locate(head, list_length(head))->data.rect.y + list_locate(head, list_length(head))->data.rect.h/2));
323 		display_options(head, font);
324 		menu(head);
325 	}
326 }
327 
328 	// quits the program
quit(Node * head)329 void quit(Node* head)
330 {
331 	printf("Destroying data . . . \n");
332 	write_config_file();
333 	SDL_Quit();
334 	exit(0);
335 }
336 
change_user_adam(Node * head)337 void change_user_adam(Node* head)
338 {
339 	clear_surface(screen);
340 	PutString(screen, SCR_X/2-TextWidth("Enter Name:"), 100, "Enter Name:");
341 	SDL_UpdateRect(screen, 0,0,0,0);
342 	SFont_Input(screen,SCR_X/2-100, 150 ,200, adam.name);
343 	change_name(head);
344 }
345 
change_user_david(Node * head)346 void change_user_david(Node*head)
347 {
348 	clear_surface(screen);
349 	PutString(screen, SCR_X/2-TextWidth("Enter Name:"), 100, "Enter Name:");
350 	SDL_UpdateRect(screen, 0,0,0,0);
351 	SFont_Input(screen,SCR_X/2-100, 150 ,200, david.name);
352 	change_name(head);
353 }
change_name(Node * head)354 void change_name(Node* head)
355 {
356 	char temp[50];
357 	char temp2[50];
358 
359 	sprintf(temp, "Change %s\'s Name", adam.name);
360 	clear_surface(screen);
361 	make_option(head, 100, temp, &change_user_adam, head);
362 
363 	sprintf(temp2, "Change %s\'s Name", david.name);
364 	make_option(head, 200, temp2, &change_user_david, head);
365 	make_option(head, 300, "Return to Main Menu", &game_menu, head);
366 
367 	start_menu(head, blue);
368 }
369 /*
370 void points_up(Node *head)
371 {
372 
373 	number_points++;
374 	david.points++;
375 	adam.points++;
376 	change_points(head);
377 }
378 
379 void points_down(Node *head)
380 {
381 
382 	number_points--;
383 	david.points--;
384 	adam.points--;
385 	change_points(head);
386 }
387 
388 void change_points(Node* head)
389 {
390 	list_clear(head);
391 	clear_surface(screen);
392 	char temp[50];
393 	sprintf(temp, "Number of Lives: %d", number_points);
394 	InitFont(blue);
395 	PutString(screen, SCR_X/2-TextWidth(temp)/2, 50, temp);
396 	SDL_UpdateRect(screen, 0,0,0,0);
397 
398 	make_option(head, 175, "Have More Lives", &points_up, head);
399 	make_option(head, 250, "Have Less Lives", &points_down, head);
400 	make_option(head, 450, "Return to Main Menu", &options, head);
401 	start_menu(head, blue);
402 }
403 
404 
405 */
406 
change_difficulty(Node * head)407 void change_difficulty(Node* head)
408 {
409 	switch(difficult)
410 	{
411 		case 0: difficult++;
412 			break;
413 		case 1: difficult++;
414 			break;
415 		case 2: difficult = 0;
416 			break;
417 		default:
418 			break;
419 	}
420 
421 	options(head);
422 }
423 
write_my_config(Node * head)424 void write_my_config(Node* head)
425 {
426 	write_config_file();
427 }
428 
429 	// turns on/off ai
430 
toggle_ai(Node * head)431 void toggle_ai(Node* head)
432 {
433 	if(ai == 0)
434 		ai = 1;
435 	else
436 		ai = 0;
437 
438 	options(head);
439 }
440 
441 	// option menu
options(Node * head)442 void options(Node* head)
443 {
444 	list_clear(head);
445 	clear_surface(screen);
446 	make_option(head, 50, "Change Name", &change_name, head);
447 
448 
449 
450 	if(ai == 0)
451 		make_option(head, 120, "Turn on AI", &toggle_ai, head);
452 	else
453 		{
454 			make_option(head, 120, "Turn off AI", &toggle_ai, head);
455 
456 			make_option(head, 190, "Difficulty (click to change):", NULL, NULL);
457 
458 			switch(difficult)
459 			{
460 				case 0:
461 					make_option(head, 260, "Easy",
462 					&change_difficulty, head);
463 					break;
464 				case 1: make_option(head, 260, "Hard",
465 					&change_difficulty, head);
466 					break;
467 				case 2: make_option(head, 260, "Impossible",
468 					&change_difficulty, head);
469 					break;
470 			}
471 
472 		}
473 
474 	//make_option(head, 330, "Change the Number of Lives", &change_points, head);
475 
476 	//make_option(head, 400, "Save Options to Config File", &write_my_config, head);
477 
478 	make_option(head, 470, "Return to Main Menu", &game_menu, head);
479 	start_menu(head, blue);
480 }
481 
482 	// displays the main option menu
483 	// just change make_option so that you can add your own menu
484 	// options and pass functions into them
main_menu(Node * head)485 void main_menu(Node *head)
486 {
487 	head = NULL;
488 	clear_surface(screen);
489 	make_option(head, 100, "New Game", commander, head);
490 	make_option(head, 200, "Options", &options, head);
491 	make_option(head, 300, "Quit", &really_quit, head);
492 	//start_menu(head, blue);
493 }
494 
game_menu(Node * head)495 void game_menu(Node *head)
496 {
497 	head = NULL;
498 	clear_surface(screen);
499 	make_option(head, 150, "Continue", commander, head);
500 	make_option(head, 225, "Options", &options, head);
501 	make_option(head, 300, "Quit", &really_quit, head);
502 	start_menu(head, blue);
503 }
504 
505 	// hmm . . .really quit?? this asks the user if he/she wants to quit
really_quit(Node * original)506 void really_quit(Node *original)
507 {
508 	Node *head;
509 
510 	list_clear(head);
511 
512 	clear_surface(screen);
513 	make_option(head, 100, "Are you sure?", NULL, NULL);
514 
515 	make_option(head, 250, "Yes", &quit, original);
516 	make_option(head, 310, "No", &game_menu, head);
517 	start_menu(head, blue);
518 }
519