1 /*
2 * Copyright (C) 2003 Robert Kooima
3 *
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.
8 *
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.
13 */
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18
19 #include "common.h"
20 #include "config.h"
21 #include "course.h"
22 #include "hole.h"
23 #include "fs.h"
24
25 /*---------------------------------------------------------------------------*/
26
27 struct course
28 {
29 char holes[MAXSTR];
30
31 char shot[MAXSTR];
32 char desc[MAXSTR];
33 };
34
35 static int course_state = 0;
36
37 static int course;
38 static int count;
39
40 static struct course course_v[MAXCRS];
41
42 /*---------------------------------------------------------------------------*/
43
course_load(struct course * crs,const char * filename)44 static int course_load(struct course *crs, const char *filename)
45 {
46 fs_file fin;
47 int rc = 0;
48
49 memset(crs, 0, sizeof (*crs));
50
51 strncpy(crs->holes, filename, MAXSTR - 1);
52
53 if ((fin = fs_open(filename, "r")))
54 {
55 if (fs_gets(crs->shot, sizeof (crs->shot), fin) &&
56 fs_gets(crs->desc, sizeof (crs->desc), fin))
57 {
58 strip_newline(crs->shot);
59 strip_newline(crs->desc);
60
61 rc = 1;
62 }
63
64 fs_close(fin);
65 }
66
67 return rc;
68 }
69
cmp_dir_items(const void * A,const void * B)70 static int cmp_dir_items(const void *A, const void *B)
71 {
72 const struct dir_item *a = A, *b = B;
73 return strcmp(a->path, b->path);
74 }
75
course_is_loaded(const char * path)76 static int course_is_loaded(const char *path)
77 {
78 int i;
79
80 for (i = 0; i < count; i++)
81 if (strcmp(course_v[i].holes, path) == 0)
82 return 1;
83
84 return 0;
85 }
86
is_unseen_course(struct dir_item * item)87 static int is_unseen_course(struct dir_item *item)
88 {
89 return (str_starts_with(base_name(item->path), "holes-") &&
90 str_ends_with(item->path, ".txt") &&
91 !course_is_loaded(item->path));
92 }
93
course_init()94 void course_init()
95 {
96 fs_file fin;
97 char *line;
98
99 Array items;
100 int i;
101
102 if (course_state)
103 course_free();
104
105 count = 0;
106
107 if ((fin = fs_open(COURSE_FILE, "r")))
108 {
109 while (count < MAXCRS && read_line(&line, fin))
110 {
111 if (course_load(&course_v[count], line))
112 count++;
113
114 free(line);
115 }
116
117 fs_close(fin);
118
119 course_state = 1;
120 }
121
122 if ((items = fs_dir_scan("", is_unseen_course)))
123 {
124 array_sort(items, cmp_dir_items);
125
126 for (i = 0; i < array_len(items) && count < MAXCRS; i++)
127 if (course_load(&course_v[count], DIR_ITEM_GET(items, i)->path))
128 count++;
129
130 fs_dir_free(items);
131
132 course_state = 1;
133 }
134 }
135
course_exists(int i)136 int course_exists(int i)
137 {
138 return (0 <= i && i < count);
139 }
140
course_count(void)141 int course_count(void)
142 {
143 return count;
144 }
145
course_goto(int i)146 void course_goto(int i)
147 {
148 hole_init(course_v[i].holes);
149 course = i;
150 }
151
course_curr(void)152 int course_curr(void)
153 {
154 return course;
155 }
156
course_free(void)157 void course_free(void)
158 {
159 hole_free();
160 course_state = 0;
161 }
162
course_rand(void)163 void course_rand(void)
164 {
165 course_goto(rand() % count);
166 hole_goto(rand() % curr_count(), 4);
167 }
168
169 /*---------------------------------------------------------------------------*/
170
course_desc(int i)171 const char *course_desc(int i)
172 {
173 return course_exists(i) ? course_v[i].desc : "";
174 }
175
course_shot(int i)176 const char *course_shot(int i)
177 {
178 return course_exists(i) ? course_v[i].shot : course_v[0].shot;
179 }
180
181 /*---------------------------------------------------------------------------*/
182