9 #define ADS ":::AGSinject " VERSION " by rofl0r:::"
11 __attribute__((noreturn
))
12 void usage(char *argv0
) {
14 ADS
"\nusage:\n%s index input.o inject_to.crm\n"
15 "index is the number of script to replace, i.e. 0 for first script\n"
16 "only relevant if the output file is a gamefile which contains multiple scripts\n"
17 "for example gamescript is 0, dialogscript is 1 (if existing), etc\n"
18 "a room file (.crm) only has one script so you can pass 0.\n", argv0
);
22 /* inj = filename of file to inject in */
23 static int inject(char *o
, char *inj
, unsigned which
) {
28 int isroom
= (which
== 0 && !strcmp(".crm", inj
+ strlen(inj
) - 4));
32 if((start
= ARF_find_code_start(f
, index
)) == -1) {
33 dprintf(2, "error, only %zu scripts found\n", found
);
37 char *tmp
= tempnam(".", "agsinject.tmp");
38 FILE *out
= fopen(tmp
, "w");
42 AF_dump_chunk_stream(f
, 0, isroom
? start
-4 : start
, out
);
45 /* open replacement object file */
48 ByteArray_open_file(&b
, o
);
51 /* 2a) if room, write length */
52 /* room files, unlike game files, have a length field of size 4 before
53 * the compiled script starts. */
54 unsigned l
= ByteArray_get_length(&b
);
57 ByteArray_open_mem(&c
, 0, 0);
58 ByteArray_set_flags(&c
, BAF_CANGROW
);
59 ByteArray_set_endian(&c
, BAE_LITTLE
);
60 ByteArray_writeInt(&c
, l
);
61 ByteArray_dump_to_stream(&c
, out
);
64 /* 2b) dump object file */
65 ByteArray_dump_to_stream(&b
, out
);
66 ByteArray_close_file(&b
);
69 if(!ASI_read_script(f
, &s
)) {
70 dprintf(2, "trouble finding script in %s\n", inj
);
73 /* 3) dump rest of file */
74 AF_dump_chunk_stream(f
, start
+ s
.len
, ByteArray_get_length(f
->b
) - (start
+ s
.len
), out
);
77 return !rename(tmp
, inj
);
89 int main(int argc
, char**argv
) {
90 if(argc
!= 4) usage(argv
[0]);
91 char *o
= argv
[2], *inj
= argv
[3], *p
;
92 if(!(p
= strrchr(o
, '.')) || strcmp(p
, ".o")) {
93 dprintf(2, "error: object file has no .o extension\n");
96 int which
= atoi(argv
[1]);
97 dprintf(1, "injecting %s into %s as %d'th script ...", o
, inj
, which
);
98 int ret
= inject(o
, inj
, which
);
99 if(ret
) dprintf(1, "OK\n");
101 dprintf(1, "FAIL\n");