Import from neverball-1.4.0.tar.gz
[neverball-archive.git] / putt / hole.c
blob45b56e5238818d05fe598e29bb4f17e4fac3b373
1 /*
2 * Copyright (C) 2003 Robert Kooima
4 * NEVERPUTT is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation; either version 2 of the License,
7 * or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
15 #include <stdio.h>
16 #include <string.h>
17 #include <math.h>
19 #include "hole.h"
20 #include "glext.h"
21 #include "image.h"
22 #include "game.h"
23 #include "geom.h"
24 #include "hud.h"
25 #include "back.h"
26 #include "audio.h"
27 #include "config.h"
29 /*---------------------------------------------------------------------------*/
31 struct hole
33 char file[MAXSTR];
34 char back[MAXSTR];
35 char song[MAXSTR];
36 int par;
39 static int hole;
40 static int party;
41 static int player;
42 static int count;
43 static int done;
45 static int stat_v[MAXPLY];
46 static float ball_p[MAXPLY][3];
47 static float ball_e[MAXPLY][3][3];
48 static struct hole hole_v[MAXHOL];
49 static int score_v[MAXHOL][MAXPLY];
51 /*---------------------------------------------------------------------------*/
53 static void hole_init_rc(const char *filename)
55 FILE *fin;
57 hole = 0;
58 player = 0;
59 count = 0;
60 done = 0;
62 /* Load the holes list. */
64 if ((fin = fopen(config_data(filename), "r")))
66 while (fscanf(fin, "%s %s %d %s",
67 hole_v[count].file,
68 hole_v[count].back,
69 &hole_v[count].par,
70 hole_v[count].song) == 4)
71 count++;
73 fclose(fin);
77 /*---------------------------------------------------------------------------*/
79 void hole_init(const char *filename)
81 int i;
83 memset(hole_v, 0, sizeof (struct hole) * MAXHOL);
84 memset(score_v, 0, sizeof (int) * MAXPLY * MAXHOL);
86 hole_init_rc(filename);
88 for (i = 0; i < count; i++)
89 score_v[i][0] = hole_v[i].par;
92 void hole_free(void)
94 game_free();
95 back_free();
97 count = 0;
100 /*---------------------------------------------------------------------------*/
102 char *hole_player(int p)
104 if (p == 0) return "Par";
106 if (p == 1 && 1 <= party) return "P1";
107 if (p == 2 && 2 <= party) return "P2";
108 if (p == 3 && 3 <= party) return "P3";
109 if (p == 4 && 4 <= party) return "P4";
111 return NULL;
114 char *hole_score(int h, int p)
116 static char str[MAXSTR];
118 if (1 <= h && h <= hole)
120 if (h <= hole && 0 <= p && p <= party)
122 sprintf(str, "%d", score_v[h][p]);
123 return str;
126 return NULL;
129 char *hole_tot(int p)
131 static char str[MAXSTR];
133 int h, T = 0;
135 if (p <= party)
137 for (h = 1; h <= hole && h <= 18; h++)
138 T += score_v[h][p];
140 sprintf(str, "%d", T);
142 return str;
144 return NULL;
147 char *hole_out(int p)
149 static char str[MAXSTR];
151 int h, T = 0;
153 if (p <= party)
155 for (h = 1; h <= hole && h <= 9; h++)
156 T += score_v[h][p];
158 sprintf(str, "%d", T);
160 return str;
162 return NULL;
165 char *hole_in(int p)
167 static char str[MAXSTR];
169 int h, T = 0;
171 if (hole > 9 && p <= party)
173 for (h = 10; h <= hole && h <= 18; h++)
174 T += score_v[h][p];
176 sprintf(str, "%d", T);
178 return str;
180 return NULL;
183 /*---------------------------------------------------------------------------*/
185 int curr_hole(void) { return hole; }
186 int curr_party(void) { return party; }
187 int curr_player(void) { return player; }
188 int curr_count(void) { return count; }
190 const char *curr_scr(void)
192 static char buf[8];
194 sprintf(buf, "%d", score_v[hole][player]);
196 return buf;
199 const char *curr_par(void)
201 static char buf[8];
203 sprintf(buf, "%d", score_v[hole][0]);
205 return buf;
208 /*---------------------------------------------------------------------------*/
210 void hole_goto(int h, int p)
212 int i;
214 if (h < count)
216 if (h >= 0) hole = h;
217 if (p >= 0) party = p;
219 player = (hole - 1) % party + 1;
220 done = 0;
222 back_init(hole_v[hole].back, 1);
223 game_init(hole_v[hole].file);
225 for (i = 1; i <= party; i++)
227 game_get_pos(ball_p[i], ball_e[i]);
228 stat_v[i] = 0;
230 game_ball(player);
231 hole_song();
235 int hole_next(void)
237 if (done < party)
241 player = player % party + 1;
243 while (stat_v[player]);
245 game_ball(player);
246 game_get_pos(ball_p[player], ball_e[player]);
248 return 1;
250 return 0;
253 int hole_move(void)
255 if (hole + 1 < count)
257 hole++;
259 game_free();
260 back_free();
262 hole_goto(hole, party);
264 return 1;
266 return 0;
269 void hole_goal(void)
271 score_v[hole][player]++;
273 if (score_v[hole][player] == 1)
274 audio_play(AUD_ONE, 1.0f);
276 else if (score_v[hole][player] == score_v[hole][0] - 2)
277 audio_play(AUD_EAGLE, 1.0f);
278 else if (score_v[hole][player] == score_v[hole][0] - 1)
279 audio_play(AUD_BIRDIE, 1.0f);
280 else if (score_v[hole][player] == score_v[hole][0])
281 audio_play(AUD_PAR, 1.0f);
282 else if (score_v[hole][player] == score_v[hole][0] + 1)
283 audio_play(AUD_BOGEY, 1.0f);
284 else if (score_v[hole][player] == score_v[hole][0] + 2)
285 audio_play(AUD_DOUBLE, 1.0f);
286 else
287 audio_play(AUD_SUCCESS, 1.0f);
289 stat_v[player] = 1;
290 done++;
292 if (done == party)
293 audio_music_fade_out(2.0f);
296 void hole_stop(void)
298 score_v[hole][player]++;
300 /* Cap scores at 12. */
302 if (score_v[hole][player] >= 12)
304 score_v[hole][player] = 12;
305 stat_v[player] = 1;
306 done++;
310 void hole_fall(void)
312 audio_play(AUD_PENALTY, 1.0f);
314 /* Reset to the position of the putt, and apply a one-stroke penalty. */
316 game_set_pos(ball_p[player], ball_e[player]);
317 score_v[hole][player] += 2;
319 /* Cap scores at 12. */
321 if (score_v[hole][player] >= 12)
323 score_v[hole][player] = 12;
324 stat_v[player] = 1;
325 done++;
329 /*---------------------------------------------------------------------------*/
331 void hole_song(void)
333 audio_music_fade_to(0.5f, hole_v[hole].song);