hbmap: fix iterator truncation when size_t < 32bit
[rofl0r-agsutils.git] / RoomFile.c
blobf51c71793eb1a7b46dc640e950236fa7e2876098
1 #include "RoomFile.h"
2 #include <stdlib.h>
4 off_t ARF_find_code_start(AF* f, off_t start) {
5 if(!AF_set_pos(f, start)) return -1LL;
6 char buf[4];
7 unsigned match = 0;
8 while(1) {
9 if(AF_read(f, buf, 1) != 1) break;;
10 switch(match) {
11 case 0:
12 if(*buf == 'S') match++;
13 else match = 0;
14 break;
15 case 1:
16 if(*buf == 'C') match++;
17 else match = 0;
18 break;
19 case 2:
20 if(*buf == 'O') match++;
21 else match = 0;
22 break;
23 case 3:
24 if(*buf == 'M') return AF_get_pos(f) - 4;
25 else match = 0;
26 break;
27 default:
28 assert(0);
31 return -1LL;
34 static void roomfile_decrypt_text(char *s, int len) {
35 unsigned i = 0;
36 while (i < len) {
37 *s += "Avis Durgan"[i % 11];
38 if (!*s) break;
39 ++i; ++s;
43 char *RoomFile_extract_source(AF *f, struct RoomFile *r, size_t *sizep) {
44 *sizep = 0;
45 off_t pos = r->blockpos[BLOCKTYPE_SCRIPT];
46 if(!pos || !AF_set_pos(f, pos)) return 0;
47 int scriptlen = AF_read_int(f);
48 assert(r->blocklen[BLOCKTYPE_SCRIPT] == scriptlen + 4);
49 char* out = malloc(scriptlen+1);
50 if(!out) return out;
51 if((size_t) -1 == AF_read(f, out, scriptlen)) {
52 free(out);
53 return 0;
55 *sizep = scriptlen;
56 roomfile_decrypt_text(out, scriptlen);
57 out[scriptlen] = 0;
58 return out;
62 int RoomFile_read(AF *f, struct RoomFile *r) {
63 if(!AF_set_pos(f, 0)) return 0;
64 r->version = AF_read_short(f);
65 while(1) {
66 unsigned char blocktype;
67 if((size_t) -1 == AF_read(f, &blocktype, 1)) return 0;
68 if(blocktype == BLOCKTYPE_EOF) break;
69 if(blocktype < BLOCKTYPE_MIN || blocktype > BLOCKTYPE_MAX) return 0;
70 long long blocklen;
71 if(blocktype == BLOCKTYPE_EXT) {
72 if(r->version < 32) {
73 fprintf(stderr, "%s", "error: found blocktype_ext in incompatible room version\n");
74 return 0;
76 char buf[16];
77 AF_read(f, buf, 16);
78 if(0);
79 else if(!strcmp(buf, "Main"))
80 blocktype = BLOCKTYPE_MAIN;
81 else if(!strcmp(buf, "TextScript"))
82 blocktype = BLOCKTYPE_SCRIPT;
83 else if(!strcmp(buf, "CompScript"))
84 blocktype = BLOCKTYPE_COMPSCRIPT;
85 else if(!strcmp(buf, "CompScript2"))
86 blocktype = BLOCKTYPE_COMPSCRIPT2;
87 else if(!strcmp(buf, "CompScript3"))
88 blocktype = BLOCKTYPE_COMPSCRIPT3;
89 else if(!strcmp(buf, "ObjNames"))
90 blocktype = BLOCKTYPE_OBJECTNAMES;
91 else if(!strcmp(buf, "AnimBg"))
92 blocktype = BLOCKTYPE_ANIMBKGRND;
93 else if(!strcmp(buf, "Properties"))
94 blocktype = BLOCKTYPE_PROPERTIES;
95 else if(!strcmp(buf, "ObjScNames"))
96 blocktype = BLOCKTYPE_OBJECTSCRIPTNAMES;
98 if(r->version < 32) blocklen = AF_read_int(f);
99 else blocklen = AF_read_longlong(f);
100 off_t curr_pos = AF_get_pos(f), next_block = curr_pos + blocklen;
101 r->blockpos[blocktype] = curr_pos;
102 r->blocklen[blocktype] = blocklen;
103 switch(blocktype) {
104 case BLOCKTYPE_COMPSCRIPT3:
106 char sig[4];
107 AF_read(f, sig, 4);
108 assert(!memcmp(sig, "SCOM", 4));
110 break;
111 /* the older script types weren't supported by the released AGS sources ever */
112 default:
113 break;
115 if(!AF_set_pos(f, next_block)) return 0;
117 return 1;