1 /*
2 * Triplane Classic - a side-scrolling dogfighting game.
3 * Copyright (C) 1996,1997,2009 Dodekaedron Software Creations Oy
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * tjt@users.sourceforge.net
19 */
20
21 /*******************************************************************************
22
23 Purpose:
24 DKS-datafile handling routines for Wsystem 2.0 for DJGPP v.2.0�5
25
26 *******************************************************************************/
27
28
29 #include <stdio.h>
30 #include <string.h>
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <unistd.h>
34 #include <stdlib.h>
35 #include "util/wutil.h"
36 #include "io/dksfile.h"
37
38 #define MAX_ENTRIES 8192
39
40 #pragma pack(1)
41 struct main_directory_entry {
42 char nimi[7];
43 unsigned long int offset __attribute__ ((packed));
44 unsigned long int koko __attribute__ ((packed));
45 };
46
47 #pragma pack()
48
49 main_directory_entry *dirri;
50
51 class Dirrikka {
52 public:
53 Dirrikka(void);
54 ~Dirrikka();
55
56 };
57
Dirrikka(void)58 Dirrikka::Dirrikka(void) {
59 dirri = (main_directory_entry *)
60 walloc(MAX_ENTRIES * sizeof(main_directory_entry));
61 }
62
~Dirrikka()63 Dirrikka::~Dirrikka() {
64 free(dirri);
65 }
66
67 Dirrikka dirrikka;
68 FILE *dks_faili;
69 char dks_tiedosto[FILENAME_MAX];
70 int nykyinen_faili;
71
72 /*
73 * Find absolute path to given datafile. The following paths are tried
74 * (in that order):
75 *
76 * $TRIPLANE_DATA/$name
77 * TRIPLANE_DATA/$name
78 * $name
79 *
80 * @param name name of datafile
81 * @param path pointer to FILENAME_MAX bytes where absolute path can be
82 * written.
83 */
get_datafile_path(const char * name,char * path)84 static void get_datafile_path(const char *name, char *path) {
85 const char *data;
86
87 data = getenv("TRIPLANE_DATA");
88 if (data) {
89 strncpy(path, data, FILENAME_MAX - 1);
90 strncat(path, "/", FILENAME_MAX - 1);
91 strncat(path, name, FILENAME_MAX - 1);
92 return;
93 }
94
95 data = TRIPLANE_DATA;
96 {
97 int ret;
98 struct stat st;
99
100 ret = stat(data, &st);
101 if (!ret) {
102 strncpy(path, data, FILENAME_MAX - 1);
103 strncat(path, "/", FILENAME_MAX - 1);
104 strncat(path, name, FILENAME_MAX - 1);
105 return;
106 }
107 }
108
109 strncpy(path, name, FILENAME_MAX - 1);
110 }
111
dksinit(const char * tiedosto)112 int dksinit(const char *tiedosto) {
113
114 char tekstia[20];
115
116 get_datafile_path(tiedosto, dks_tiedosto);
117
118 if ((dks_faili = fopen(dks_tiedosto, "rb")) == NULL)
119 return (0);
120
121 fread(tekstia, sizeof(tekstia), 1, dks_faili);
122 fread(dirri, sizeof(main_directory_entry) * MAX_ENTRIES, 1, dks_faili);
123
124 fclose(dks_faili);
125
126 return (1);
127 }
128
dksopen(const char * nimi)129 int dksopen(const char *nimi) {
130 int lask;
131 int kohta = -1;
132
133 for (lask = 0; lask < MAX_ENTRIES; lask++) {
134 if (!strcmp(dirri[lask].nimi, nimi)) {
135 kohta = lask;
136 break;
137 }
138 }
139
140 if (kohta == -1) {
141
142 return (0);
143 }
144
145
146 if ((dks_faili = fopen(dks_tiedosto, "rb")) == NULL)
147 return (0);
148
149 fseek(dks_faili, dirri[kohta].offset, SEEK_SET);
150
151 nykyinen_faili = kohta;
152
153 return (1);
154 }
155
extdksopen(const char * nimi)156 int extdksopen(const char *nimi) {
157 int lask;
158 int kohta = -1;
159 int faili = 0;
160
161 for (lask = 0; lask < MAX_ENTRIES; lask++) {
162 if (!strcmp(dirri[lask].nimi, nimi)) {
163 kohta = lask;
164 break;
165 }
166 }
167
168 if (kohta == -1) {
169 dks_faili = fopen(nimi, "rb");
170 faili = 1;
171 if (dks_faili == NULL)
172 return (0);
173 } else {
174 if ((dks_faili = fopen(dks_tiedosto, "rb")) == NULL)
175 return (0);
176
177 fseek(dks_faili, dirri[kohta].offset, SEEK_SET);
178
179 nykyinen_faili = kohta;
180 }
181
182 return (1);
183 }
184
185
186
dksclose(void)187 void dksclose(void) {
188 fclose(dks_faili);
189
190 }
191
dkssize(void)192 int dkssize(void) {
193 return dirri[nykyinen_faili].koko;
194 }
195
dksread(void * mihin,unsigned long int koko)196 int dksread(void *mihin, unsigned long int koko) {
197 if (fread(mihin, koko, 1, dks_faili))
198 return 1;
199 else
200 return 0;
201 }
202
dksseek(int offset,int mode)203 int dksseek(int offset, int mode) {
204 switch (mode) {
205 case SEEK_SET:
206 return (fseek(dks_faili, dirri[nykyinen_faili].offset + offset, SEEK_SET));
207 break;
208
209 case SEEK_CUR:
210 return (fseek(dks_faili, offset, SEEK_CUR));
211 break;
212
213 case SEEK_END:
214 return (fseek(dks_faili, dirri[nykyinen_faili].offset + dirri[nykyinen_faili].koko + offset, SEEK_SET));
215 break;
216
217
218 }
219
220
221 return 1;
222 }
223
dksgetc(void)224 int dksgetc(void) {
225 return (fgetc(dks_faili));
226 }
227
dkstell(void)228 long dkstell(void) {
229 return (ftell(dks_faili) - dirri[nykyinen_faili].offset);
230 }
231