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, ®ion->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, ®ion->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