fixes to resource unpacker and resource builder
[awish.git] / src / gameglobals.c
blob6fdef2de15078d924d8293bea871674e571d58f8
1 /*
2 * This program is free software: you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation, either version 3 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 #include "gameglobals.h"
18 ////////////////////////////////////////////////////////////////////////////////
19 #include "vm_gamelabelsdef.c"
22 ////////////////////////////////////////////////////////////////////////////////
23 ResFile resfile; // NOT STATIC!
25 SDL_Surface *backs[8]; //0: title
26 SpriteBank banks[256];
28 static LabelInfo *labels = NULL;
31 ////////////////////////////////////////////////////////////////////////////////
32 __attribute__((__noreturn__)) __attribute__((format(printf, 1, 2))) void fatal (const char *fmt, ...) {
33 va_list ap;
35 fprintf(stderr, "AWISH FATAL: ");
36 va_start(ap, fmt);
37 vfprintf(stderr, fmt, ap);
38 va_end(ap);
39 fprintf(stderr, "\n");
40 exit(1);
44 ////////////////////////////////////////////////////////////////////////////////
45 void freeLabels (void) {
46 while (labels != NULL) {
47 LabelInfo *l = labels;
49 labels = l->next;
50 if (l->name) free(l->name);
51 free(l);
57 static int readW (FILE *fl, int *v) {
58 unsigned char b;
59 int t0, t1;
61 if (fread(&b, 1, 1, fl) != 1) return -1;
62 t0 = b;
63 if (fread(&b, 1, 1, fl) != 1) return -1;
64 t1 = b;
65 if (v) *v = t0+(t1<<8);
66 return 0;
71 #define XREAD(dest,size) do { \
72 if (pos+(size) > rsz) goto quit; \
73 if ((size) > 0) memcpy((dest), buf+pos, (size)); \
74 pos += (size); \
75 } while (0)
78 #define XREADW(dest) do { \
79 if (pos+2 > rsz) goto quit; \
80 dest = buf[pos+1]; \
81 dest <<= 8; \
82 dest |= buf[pos+0]; \
83 pos += 2; \
84 } while (0)
87 int loadVMCode (ResFile *resfile) {
88 int rsz = 0, pos = 0;
89 char sign[4];
90 int lcnt;
91 uint8_t *buf = loadResFile(resfile, 93, &rsz);
93 memset(vmCode, 0, sizeof(vmCode));
94 memset(vmGVars, 0, sizeof(vmGVars));
95 vmCodeSize = 0;
96 freeLabels();
98 if (buf == NULL) return -1;
100 XREAD(sign, 4);
101 if (memcmp(sign, "AVM0", 4) != 0) goto quit;
103 XREADW(vmCodeSize);
104 XREAD(vmCode, vmCodeSize);
105 for (int f = 0; f < vmCodeSize; ++f) vmCode[f] ^= 42;
107 XREADW(lcnt);
108 //printf("code: %d bytes, %d labels\n", vmCodeSize, lcnt);
110 for (int f = 0; f < lcnt; ++f) {
111 unsigned char type, namelen, b;
112 int value;
114 XREAD(&type, 1);
116 switch (type) {
117 case LB_GVAR:
118 case LB_TVAR:
119 XREAD(&b, 1);
120 value = b;
121 break;
122 case LB_SVAR:
123 case LB_CODE:
124 case LB_CONST:
125 XREADW(value);
126 if (type != LB_CODE && value >= 32768) value -= 65536;
127 break;
128 default:
129 fatal("invalid label type: %d\n", type);
130 goto quit;
133 XREAD(&namelen, 1);
134 if (namelen > 0) {
135 LabelInfo *l = malloc(sizeof(LabelInfo));
137 if (l == NULL) goto quit;
138 l->name = calloc(namelen+1, 1);
139 if (l->name == NULL) { free(l); goto quit; }
140 l->type = type;
141 l->value = value;
142 l->next = labels;
143 labels = l;
144 XREAD(l->name, namelen);
145 for (int f = 0; f < namelen; ++f) l->name[f] ^= 0xa5;
146 //printf("%d/%d: [%s]\n", f, lcnt, l->name);
150 free(buf);
151 return 0;
152 quit:
153 free(buf);
154 freeLabels();
155 return -1;
159 ////////////////////////////////////////////////////////////////////////////////
160 LabelInfo *findLabel (const char *name) {
161 if (name != NULL && name[0]) {
162 for (LabelInfo *l = labels; l != NULL; l = l->next) {
163 if (strcasecmp(l->name, name) == 0) return l;
166 return NULL;
170 int findPC (const char *name) {
171 LabelInfo *l = findLabel(name);
173 if (l == NULL) fatal("no code label: '%s'", name);
174 return l->value;
178 int findVarIndex (const char *name) {
179 LabelInfo *l = findLabel(name);
181 if (l == NULL || (l->type != LB_GVAR && l->type != LB_TVAR && l->type != LB_SVAR)) fatal("no var label: '%s'", name);
182 return l->value;
186 int findGVarIndex (const char *name) {
187 LabelInfo *l = findLabel(name);
189 if (l == NULL || l->type != LB_GVAR) fatal("no global var label: '%s'", name);
190 return l->value;
194 int findTVarIndex (const char *name) {
195 LabelInfo *l = findLabel(name);
197 if (l == NULL || l->type != LB_TVAR) fatal("no thread var label: '%s'", name);
198 return l->value;
202 int findSVarIndex (const char *name) {
203 LabelInfo *l = findLabel(name);
205 if (l == NULL || l->type != LB_SVAR) fatal("no thread var label: '%s'", name);
206 return l->value;
210 int findConst (const char *name) {
211 LabelInfo *l = findLabel(name);
213 if (l == NULL || l->type != LB_CONST) fatal("no const label: '%s'", name);
214 return l->value;
218 ////////////////////////////////////////////////////////////////////////////////
219 void initLabels (void) {
220 #include "vm_gamelabelsinit.c"