1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
|
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <SDL/SDL.h>
#include <vorbis/vorbisfile.h>
#include "Support.h"
#include "Files.h"
int Random()
{
#if RAND_MAX >= 65535
return (rand() % 65535) - 32767;
#else
#error please fix this for your platform
#endif
}
void Microseconds(UnsignedWide *microTickCount)
{
/* NOTE: hi isn't used in BS, so it's not implemented here */
/* TODO: does game need microsecond precision? */
microTickCount->hi = 0;
microTickCount->lo = SDL_GetTicks() * 1000;
}
void GetMouse(Point *p)
{
int x;
int y;
SDL_GetMouseState(&x, &y);
p->h = x;
p->v = y;
}
void GetMouseRel(Point *p)
{
int x;
int y;
SDL_GetRelativeMouseState(&x, &y);
p->h = x;
p->v = y;
}
int Button(void)
{
return (SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(1));
}
void InitMouse()
{
// STUB_FUNCTION;
}
void MoveMouse(int xcoord, int ycoord, Point *mouseloc)
{
/* TODO: mouse warp is annoying when we can just grab the mouse */
#ifdef FULLSCREEN
SDL_WarpMouse(xcoord, ycoord);
SDL_PumpEvents();
#endif
GetMouse(mouseloc);
}
void DisposeMouse()
{
// STUB_FUNCTION;
}
#ifndef O_BINARY
#define O_BINARY 0
#endif
#ifndef MAX_PATH
#define MAX_PATH 256
#endif
static int find_filename(char *filename)
{
char *ptr;
char *cur;
char *next;
DIR *dir;
struct dirent *dirent;
if (access(filename, R_OK) == 0) {
return 1;
}
ptr = filename;
while (*ptr) {
if (ptr == filename || *ptr == '/') {
if (*ptr == '/') {
cur = ptr+1;
} else {
cur = ptr;
}
if (*cur == 0) {
/* hit the end */
break;
}
next = strchr(cur, '/');
if (ptr != filename) {
*ptr = 0;
}
if (next) {
*next = 0;
}
if (ptr == filename && *ptr == '/') {
dir = opendir("/");
} else {
dir = opendir(filename);
}
if (dir == NULL) {
if (ptr != filename) {
*ptr = '/';
}
if (next) {
*next = 0;
}
return 0;
}
while ((dirent = readdir(dir)) != NULL) {
if (strcasecmp(cur, dirent->d_name) == 0) {
strcpy(cur, dirent->d_name);
break;
}
}
closedir(dir);
if (ptr != filename) {
*ptr = '/';
}
if (next) {
*next = '/';
ptr = next;
} else {
ptr++;
}
} else {
ptr++;
}
}
if (access(filename, R_OK) == 0) {
return 1;
}
return 0;
}
static void fix_filename(const char *original, char *fixed)
{
const char *start;
int i;
int len;
start = original;
if (original[0] == ':') {
start = &original[1];
}
fixed[MAX_PATH-1] = 0;
strncpy(fixed, start, MAX_PATH);
/* check to see if strncpy overwrote the terminator */
if (fixed[MAX_PATH-1] != 0) {
fixed[MAX_PATH-1] = 0;
fprintf(stderr, "ERROR: file truncation error: %s -> %s\n",
original, fixed);
}
len = strlen(fixed);
for (i = 0; i < len; i++) {
if (fixed[i] == ':') {
fixed[i] = '/';
}
}
/*
here we would try to see if the file is available (game dir),
else try another dir
really, this function also needs a flag to indicate whether
it should only go to local (write) or both (read)
*/
if (find_filename(fixed) == 0) {
fprintf(stderr, "find failed: %s\n", fixed);
}
}
/*
Convenient Filename Hacks
*/
FILE *cfh_fopen(const char *filename, const char *mode)
{
char filename1[MAX_PATH];
fix_filename(filename, filename1);
return fopen(filename1, mode);
}
int Files::OpenFile(Str255 Name)
{
char filename1[MAX_PATH];
fix_filename((char *)Name, filename1);
sFile = open(filename1, O_RDONLY | O_BINARY);
return sFile;
}
void Files::EndLoad()
{
if (sFile != -1) {
FSClose( sFile );
}
sFile = -1;
}
/*
Read the requested OGG file into memory, and extract the information required
by OpenAL
*/
void LoadOGG_CFH(char *filename, ALenum *format, void **wave,
unsigned int *size, ALsizei *freq)
{
char filename1[MAX_PATH];
ALsizei format1, size1, freq1;
void *wave1;
OggVorbis_File vf;
vorbis_info *vi;
FILE *fp;
int current_section;
char *buf;
int asize;
int err;
int eof;
#if BYTE_ORDER == BIG_ENDIAN
const int endian = 1;
#else
const int endian = 0;
#endif
/* try to find the real file (and place it in filename1) */
fix_filename(filename, filename1);
/* open it for reading */
fp = fopen(filename1, "rb");
if (fp == NULL) {
fprintf(stderr, "ERROR: unable to open %s\n", filename1);
exit(EXIT_FAILURE);
}
/* open it up */
err = ov_open(fp, &vf, NULL, 0);
if (err < 0) {
fprintf(stderr, "ERROR: vorbis error %d opening %s\n", -err, filename1);
exit(EXIT_FAILURE);
}
/* get the ogg information */
vi = ov_info(&vf, -1);
if (vi == NULL) {
fprintf(stderr, "ERROR: vorbis error opening %s (ov_info failed)\n", filename1);
exit(EXIT_FAILURE);
}
/* calculate the byte size */
size1 = vi->channels * 2 * ov_pcm_total(&vf, -1);
/* hack around some possible ogg vorbis weirdness */
asize = ((size1 + 2047) / 2048 + 1) * 2048;
/* allocate our buffer */
wave1 = malloc(asize);
if (wave1 == NULL) {
fprintf(stderr, "ERROR: could not allocate %d bytes while loading %s\n", size1, filename1);
exit(EXIT_FAILURE);
}
/* read it in */
eof = 0;
buf = (char *)wave1;
while(!eof) {
long ret = ov_read(&vf, buf, 1024, endian, 2, 1,
¤t_section);
if (ret == 0) {
/* end of file */
eof = 1;
} else if (ret < 0) {
/* some sort of error */
/* TODO: is this ok to ignore? */
} else {
buf += ret;
}
}
/* get the rest of the information */
if (vi->channels == 1) {
format1 = AL_FORMAT_MONO16;
} else if (vi->channels == 2) {
format1 = AL_FORMAT_STEREO16;
} else {
fprintf(stderr, "ERROR: ogg %s has %d channels\n", filename1, vi->channels);
exit(EXIT_FAILURE);
}
freq1 = vi->rate;
/* we are done with the ogg, so free it */
ov_clear(&vf);
/* finall, give the values to the caller */
*format = format1;
*size = size1;
*freq = freq1;
*wave = wave1;
}
/*
Free the OGG buffer
*/
void FreeOGG(ALenum format, void *wave, unsigned int size,
ALsizei freq)
{
free(wave);
}
|