1 /*  Sarien - A Sierra AGI resource interpreter engine
2  *  Copyright (C) 1999,2001 Stuart George and Claudio Matsuoka
3  *
4  *  $Id: logic.c,v 1.12 2001/09/13 17:24:01 cmatsuoka Exp $
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; see docs/COPYING for further details.
9  */
10 
11 #include <stdio.h>
12 #include <string.h>
13 #include "sarien.h"
14 #include "agi.h"
15 
16 
17 /* decodes messages into message list from raw logic files */
decode_logic(int n)18 int decode_logic (int n)
19 {
20 	int ec = err_OK;
21 	int mstart, mend, mc;
22 	UINT8 *m0;
23 
24 	/* decrypt messages at end of logic + build message list */
25 
26 	/* report ("decoding logic #%d\n", n); */
27 	m0 = game.logics[n].data;
28 
29 	mstart = lohi_getword (m0) + 2;
30 	mc = lohi_getbyte (m0 + mstart);
31 	mend = lohi_getword (m0 + mstart + 1);
32 	m0 += mstart + 3;			/* cover header info */
33 	mstart = mc << 1;
34 
35 	/* if the logic was not compressed, decrypt the text messages
36 	 * only if there are more than 0 messages
37 	 */
38 	if ((~game.dir_logic[n].flags & RES_COMPRESSED) && mc > 0)
39 		decrypt (m0 + mstart, mend - mstart);	/* decrypt messages */
40 
41 	/* build message list */
42 	m0 = game.logics[n].data;
43 	mstart = lohi_getword (m0) + 2;			/* +2 covers pointer */
44 	game.logics[n].num_texts = lohi_getbyte (m0 + mstart);
45 
46 	/* resetp logic pointers */
47 	game.logics[n].sIP = 2;
48 	game.logics[n].cIP = 2;
49 	game.logics[n].size = lohi_getword (m0) + 2; /* logic end pointer */
50 
51 	/* allocate list of pointers to point into our data */
52 	game.logics[n].texts = calloc (1 + game.logics[n].num_texts,
53 		sizeof (char*));
54 
55 	/* cover header info */
56 	m0 += mstart+3;
57 
58 	if (game.logics[n].texts != NULL) {
59 		/* move list of strings into list to make real pointers */
60 		for(mc = 0; mc < game.logics[n].num_texts; mc++) {
61 			mend = lohi_getword(m0+mc*2);
62 			game.logics[n].texts[mc] = mend ?
63 				(char *)m0 + mend - 2 : "";
64 		}
65 		/* set loaded flag now its all completly loaded */
66 		game.dir_logic[n].flags |= RES_LOADED;
67 	} else {
68 		/* unload data
69 		 * blah DF YA WANKER!!@!@# frag. i'm so dumb. not every logic
70 		 * has text
71 		 */
72 		free (game.logics[n].data);
73 		ec = err_NotEnoughMemory;
74 	}
75 
76 	return ec;
77 }
78 
79 
unload_logic(int n)80 void unload_logic (int n)
81 {
82 	if (game.dir_logic[n].flags & RES_LOADED) {
83 		free (game.logics[n].data);
84 		if (game.logics[n].num_texts)
85 			free (game.logics[n].texts);
86 		game.logics[n].num_texts = 0;
87 		game.dir_logic[n].flags &= ~RES_LOADED;
88 	}
89 
90 	/* if cached, we end up here */
91 	game.logics[n].sIP = 2;
92 	game.logics[n].cIP = 2;
93 }
94 
95