Subversion Repositories Games.Carmageddon

Rev

Rev 18 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 pmbaty 1
#include "flicplay.h"
20 pmbaty 2
#include "brender/brender.h"
1 pmbaty 3
#include "displays.h"
4
#include "drmem.h"
5
#include "errors.h"
6
#include "globvars.h"
7
#include "graphics.h"
8
#include "harness/trace.h"
9
#include "input.h"
10
#include "loading.h"
11
#include "main.h"
12
#include "pd/sys.h"
13
#include "sound.h"
14
#include "utility.h"
15
#include <stdlib.h>
16
#include <string.h>
17
 
18
int gPalette_allocate_count;
19
int gPalette_fuck_prevention;
20
int gDark_mode;
21
int gTransparency_on;
22
int gPanel_flic_disable;
23
int gPending_flic = -1;
24
int gPlay_from_disk;
25
int gTrans_enabled = 1;
26
br_pixelmap* gPanel_buffer[2];
27
tU32 gSound_time;
28
tFlic_spec gMain_flic_list[372] = {
29
    { "MAINSTIL.FLI", 1, 0, 0, 0, 0, 25, NULL, 0u }, // only used by the demo (set to "xxxxxxxx.FLI" by the full version)
30
    { "DEMSTRT2.FLI", 1, 0, 0, 0, 0, 0, NULL, 0u },
31
    { "DEMSTRT1.FLI", 1, 0, 0, 0, 0, 0, NULL, 0u },
32
    { "NEWFLIC.FLI", 1, 0, 0, 0, 0, 0, NULL, 0u },
33
    { "GOTOFLIC.FLI", 1, 0, 0, 0, 0, 0, NULL, 0u },
34
    { "ENDFLIC.FLI", 1, 0, 0, 0, 0, 0, NULL, 0u },
35
    { "OVERFLIC.FLI", 1, 0, 0, 0, 0, 0, NULL, 0u },
36
    { "DEMO8.FLI", 1, 0, 0, 0, 0, 0, NULL, 0u },
37
    { "COMPLETE.FLI", 1, 0, 0, 0, 0, 0, NULL, 0u },
38
    { "DEMOEND.FLI", 1, 0, 0, 0, 0, 0, NULL, 0u },
39
    { "MAINSTIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
40
    { "MAINCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
41
    { "MAINAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
42
    { "MAINCNFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
43
    { "MAINCNGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
44
    { "MAINCNIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
45
    { "MAINABFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
46
    { "MAINABGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
47
    { "MAINQTFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
48
    { "MAINQTGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
49
    { "MAINSVFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
50
    { "MAINSVGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
51
    { "MAINLDFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
52
    { "MAINLDGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
53
    { "MAINRCFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
54
    { "MAINRCGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
55
    { "MAINARFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
56
    { "MAINARGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
57
    { "MAINOPFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
58
    { "MAINOPGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
59
    { "MAI2STIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
60
    { "MAI2COME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
61
    { "MAI2AWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
62
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
63
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
64
    { "MAINRCGY.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
65
    { "MAINARGY.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
66
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
67
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
68
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
69
    { "SVVYSTIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
70
    { "SVVYAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
71
    { "BGBUTTFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
72
    { "BGBUTTGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
73
    { "SVVYOKIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
74
    { "CANBUTIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
75
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
76
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
77
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
78
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
79
    { "SAVECOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
80
    { "SAVEAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
81
    { "SMLBUTFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
82
    { "SMLBUTGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
83
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
84
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
85
    { "SMLBUTFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
86
    { "SMLBUTGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
87
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
88
    { "SAVECAIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
89
    { "NRACCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
90
    { "NRACAWAY.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
91
    { "NCARCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
92
    { "NSUMSTIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
93
    { "NSUMAWAY.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
94
    { "NOPTCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
95
    { "NOPTAWAY.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
96
    { "NOPTDEIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
97
    { "NOPT00GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
98
    { "NOPT00FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
99
    { "LOADSTIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
100
    { "LOADCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
101
    { "LOADAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
102
    { "LOADHIFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
103
    { "LOADHIGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
104
    { "NOPT01GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
105
    { "NOPT01FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
106
    { "NOPT02GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
107
    { "NOPT02FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
108
    { "NOPT03GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
109
    { "NEWGCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
110
    { "NEWGAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
111
    { "NEWGHLFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
112
    { "NEWGHLGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
113
    { "NEWGDNAV.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
114
    { "NEWGDNGY.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
115
    { "NEWGDNFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
116
    { "NEWGDNGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
117
    { "NEWGDNIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
118
    { "NEWGCAIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
119
    { "NEWNSTIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
120
    { "NEWNSTFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
121
    { "NEWNSTGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
122
    { "CHCKBXFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
123
    { "CHCKBXGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
124
    { "CHCKBXON.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
125
    { "CHCKBXOF.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
126
    { "RADBUTFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
127
    { "RADBUTGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
128
    { "RADBUTON.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
129
    { "NEWNCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
130
    { "NEWNAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
131
    { "NETTCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
132
    { "NETTAWAY.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
133
    { "NETOCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
134
    { "NETOAWAY.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
135
    { "NETNCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
136
    { "NETNAWAY.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
137
    { "RADBUTOF.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
138
    { "NOPT03FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
139
    { "SKILCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
140
    { "SKILAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
141
    { "NOPT04GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
142
    { "NOPT04FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
143
    { "NOPT05GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
144
    { "SKILL1FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
145
    { "SKILL1GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
146
    { "SKILLIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
147
    { "SKILL2FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
148
    { "SKILL2GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
149
    { "SKILL3FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
150
    { "SKILL3GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
151
    { "NCHOCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
152
    { "NCHOAWAY.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
153
    { "NCHOOPIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
154
    { "ERRRSTIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
155
    { "NOPT05FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
156
    { "NOPT06GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
157
    { "NOPT06FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
158
    { "NOPT07GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
159
    { "QUT1STIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
160
    { "QUT2STIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
161
    { "QUT3STIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
162
    { "NOPT07FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
163
    { "NOPT08GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
164
    { "QUITOKIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
165
    { "NOPT08FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
166
    { "NOPT09GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
167
    { "NOPT09FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
168
    { "NOPT10GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
169
    { "OPTNCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
170
    { "OPTNAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
171
    { "NOPT10FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
172
    { "NOPT11GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
173
    { "OPTNSNIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
174
    { "OPTNCNIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
175
    { "OPTNGRIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
176
    { "OPTNMSIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
177
    { "NOPT11FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
178
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
179
    { "SNDOCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
180
    { "SNDOAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
181
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
182
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
183
    { "DNEBUTIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
184
    { "SNDOOLFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
185
    { "SNDOOLGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
186
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
187
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
188
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
189
    { "GRPHCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
190
    { "GRPHAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
191
    { "NCHO00GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
192
    { "NCHO01GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
193
    { "NCHO02GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
194
    { "NCHO03GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
195
    { "NCHO04GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
196
    { "NCHO05GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
197
    { "NCHO06GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
198
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
199
    { "CNTLCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
200
    { "CNTLAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
201
    { "CNTLDNIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
202
    { "CNTLCAIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
203
    { "CNTLDFIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
204
    { "CNTLMRIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
205
    { "CNTLDNFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
206
    { "CNTLDNGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
207
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
208
    { "CNTLSTIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
209
    { "OTHRCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
210
    { "OTHRAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
211
    { "NCHO00FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
212
    { "NCHO01FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
213
    { "NCHO02FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
214
    { "NCHO03FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
215
    { "NCHO04FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
216
    { "NCHO05FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
217
    { "NCHO06FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
218
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
219
    { "STRTSTIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
220
    { "STRTCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
221
    { "STRTAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
222
    { "CNTL00FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
223
    { "CNTL00GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
224
    { "STRTCRIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
225
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
226
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
227
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
228
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
229
    { "STRTPSIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
230
    { "STRTSRIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
231
    { "STRTCCIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
232
    { "NTSHSTIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
233
    { "NTSCSTIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
234
    { "NTSHSTIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
235
    { "NTSHENIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
236
    { "NTSCLVIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
237
    { "NTSHSTEN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
238
    { "NTSXSTIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
239
    { "VWSC2IN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
240
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
241
    { "VWIN2OPP.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
242
    { "VWOPP2SC.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
243
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
244
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
245
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
246
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
247
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
248
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
249
    { "2BUTONFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
250
    { "2BUTONGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
251
    { "VWOPUPIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
252
    { "VWOPDWFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
253
    { "VWOPDWGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
254
    { "VWOPDWIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
255
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
256
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
257
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
258
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
259
    { "CHRCCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
260
    { "CHRCAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
261
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
262
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
263
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
264
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
265
    { "CHCRCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
266
    { "CHCRAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
267
    { "GRPH00GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
268
    { "GRPH01GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
269
    { "GRPH02GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
270
    { "GRPH03GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
271
    { "GRPH04GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
272
    { "GRPH05GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
273
    { "GRPH06GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
274
    { "GRPH07GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
275
    { "GRPH08GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
276
    { "GRPH09GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
277
    { "GRPH10GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
278
    { "GRPH11GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
279
    { "PARTCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
280
    { "PARTAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
281
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
282
    { "PARTARGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
283
    { "PARTARIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
284
    { "PARTPFIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
285
    { "PARTOFIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
286
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
287
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
288
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
289
    { "PARTEXIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
290
    { "PARTSPIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
291
    { "PARTARGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
292
    { "PARTPFGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
293
    { "PARTOFGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
294
    { "GRPH00FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
295
    { "GRPH01FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
296
    { "GRPH02FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
297
    { "GRPH03FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
298
    { "GRPH04FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
299
    { "GRPH05FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
300
    { "GRPH06FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
301
    { "GRPH07FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
302
    { "GRPH08FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
303
    { "GRPH09FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
304
    { "GRPH10FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
305
    { "GRPH11FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
306
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
307
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
308
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
309
    { "PSRMCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
310
    { "PSRMAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
311
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
312
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
313
    { "PSRMDIIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
314
    { "RADBUTFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
315
    { "RADBUTGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
316
    { "RADBUTOF.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
317
    { "RADBUTON.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
318
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
319
    { "GRIDSTIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
320
    { "GRIDAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
321
    { "GRIDLFFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
322
    { "GRIDLFGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
323
    { "GRIDLFIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
324
    { "GRIDRTFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
325
    { "GRIDRTGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
326
    { "GRIDRTIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
327
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
328
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
329
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
330
    { "DARECOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
331
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
332
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
333
    { "DAREACIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
334
    { "DARECHIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
335
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
336
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
337
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
338
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
339
    { "SUM1STIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
340
    { "SUM1AWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
341
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
342
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
343
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
344
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
345
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
346
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
347
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
348
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
349
    { "SUM2STIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
350
    { "BGBUT8GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
351
    { "BGBUT8FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
352
    { "DNBUT8IN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
353
    { "BKBUT8IN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
354
    { "BKBUTOFF.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
355
    { "BKBUTON.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
356
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
357
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
358
    { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
359
    { "MAI2QTFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
360
    { "MAI2QTGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
361
    { "MAI2LDFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
362
    { "MAI2LDGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
363
    { "MAI2N1FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
364
    { "MAI2N1GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
365
    { "MAI2NNFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
366
    { "MAI2NNGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
367
    { "MAI2OPFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
368
    { "MAI2OPGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }
369
};
370
int gFlic_bunch0[29] = {
371
    10,
372
    11,
373
    12,
374
    13,
375
    14,
376
    15,
377
    16,
378
    17,
379
    18,
380
    19,
381
    20,
382
    21,
383
    22,
384
    23,
385
    24,
386
    25,
387
    35,
388
    26,
389
    27,
390
    36,
391
    28,
392
    29,
393
    130,
394
    131,
395
    132,
396
    42,
397
    43,
398
    135,
399
    45
400
};
401
int gFlic_bunch1[31] = {
402
    140,
403
    141,
404
    42,
405
    43,
406
    144,
407
    145,
408
    146,
409
    147,
410
    45,
411
    150,
412
    151,
413
    42,
414
    43,
415
    154,
416
    155,
417
    156,
418
    160,
419
    161,
420
    42,
421
    43,
422
    154,
423
    170,
424
    171,
425
    176,
426
    177,
427
    172,
428
    180,
429
    181,
430
    42,
431
    43,
432
    154
433
};
434
int gFlic_bunch2[8] = { 70, 71, 72, 73, 74, 56, 57, 59 };
435
int gFlic_bunch3[13] = { 40, 41, 42, 43, 44, 45, 50, 51, 73, 74, 56, 57, 59 };
436
int gFlic_bunch4[22] = {
437
    80,
438
    81,
439
    82,
440
    83,
441
    84,
442
    85,
443
    42,
444
    43,
445
    88,
446
    45,
447
    110,
448
    111,
449
    42,
450
    43,
451
    45,
452
    115,
453
    116,
454
    117,
455
    118,
456
    119,
457
    120,
458
    121
459
};
460
int gFlic_bunch5[5] = { 100, 101, 42, 43, 45 };
461
int gFlic_bunch6[51] = {
462
    190,
463
    191,
464
    192,
465
    42,
466
    43,
467
    195,
468
    200,
469
    201,
470
    210,
471
    212,
472
    213,
473
    220,
474
    221,
475
    222,
476
    220,
477
    221,
478
    225,
479
    230,
480
    231,
481
    42,
482
    43,
483
    154,
484
    45,
485
    220,
486
    221,
487
    222,
488
    220,
489
    221,
490
    225,
491
    250,
492
    251,
493
    42,
494
    43,
495
    254,
496
    255,
497
    256,
498
    154,
499
    42,
500
    43,
501
    260,
502
    220,
503
    221,
504
    222,
505
    220,
506
    221,
507
    225,
508
    280,
509
    281,
510
    42,
511
    43,
512
    284
513
};
514
int gFlic_bunch7[7] = { 130, 131, 132, 42, 43, 135, 45 };
515
int gFlic_bunch8[16] = { 290, 291, 292, 293, 294, 295, 296, 297, 42, 43, 154, 301, 42, 43, 304, 305 };
516
tFlic_bunch gFlic_bunch[9] = {
517
    { COUNT_OF(gFlic_bunch0), gFlic_bunch0 },
518
    { COUNT_OF(gFlic_bunch1), gFlic_bunch1 },
519
    { COUNT_OF(gFlic_bunch2), gFlic_bunch2 },
520
    { COUNT_OF(gFlic_bunch3), gFlic_bunch3 },
521
    { COUNT_OF(gFlic_bunch4), gFlic_bunch4 },
522
    { COUNT_OF(gFlic_bunch5), gFlic_bunch5 },
523
    { COUNT_OF(gFlic_bunch6), gFlic_bunch6 },
524
    { COUNT_OF(gFlic_bunch7), gFlic_bunch7 },
525
    { COUNT_OF(gFlic_bunch8), gFlic_bunch8 },
526
};
527
char gLast_flic_name[14];
528
tU32 gPanel_flic_data_length[2];
529
tU32 gLast_panel_frame_time[2];
530
tU8* gPanel_flic_data[2];
531
int gPanel_flic_top[2];
532
tFlic_descriptor gPanel_flic[2];
533
int gPanel_flic_left[2];
534
int gPending_pending_flic = -1;
535
int gSound_ID;
536
int gTranslation_count;
537
tDR_font* gTrans_fonts[15];
538
tTranslation_record* gTranslations;
539
br_pixelmap* gPalette;
540
void* gPalette_pixels;
541
tFlic_descriptor* gFirst_flic;
542
 
543
// Use this function to avoid unaligned memory access.
544
// Added by DethRace
545
tU16 mem_read_u16(void* memory) {
546
    tU16 u16;
547
 
548
    memcpy(&u16, memory, sizeof(tU16));
549
    return u16;
550
}
551
 
552
// Use this function to avoid unaligned memory access
553
// Added by DethRace
554
void mem_write_u16(void* memory, tU16 u16) {
555
 
556
    memcpy(memory, &u16, sizeof(tU16));
557
}
558
 
559
// IDA: void __cdecl EnableTranslationText()
560
void EnableTranslationText(void) {
561
    LOG_TRACE("()");
562
 
563
    gTrans_enabled = 1;
564
}
565
 
566
// IDA: void __cdecl DisableTranslationText()
567
void DisableTranslationText(void) {
568
    LOG_TRACE("()");
569
 
570
    gTrans_enabled = 0;
571
}
572
 
573
// IDA: void __usercall SetFlicSound(int pSound_ID@<EAX>, tU32 pSound_time@<EDX>)
574
void SetFlicSound(int pSound_ID, tU32 pSound_time) {
575
    LOG_TRACE("(%d, %d)", pSound_ID, pSound_time);
576
 
577
    gSound_time = pSound_time;
578
    gSound_ID = pSound_ID;
579
}
580
 
581
// IDA: int __cdecl TranslationMode()
582
int TranslationMode(void) {
583
 
584
    return gTranslation_count;
585
}
586
 
587
// IDA: void __cdecl DontLetFlicFuckWithPalettes()
588
void DontLetFlicFuckWithPalettes(void) {
589
    LOG_TRACE8("()");
590
 
591
    gPalette_fuck_prevention = 1;
592
}
593
 
594
// IDA: void __cdecl LetFlicFuckWithPalettes()
595
void LetFlicFuckWithPalettes(void) {
596
    LOG_TRACE8("()");
597
 
598
    gPalette_fuck_prevention = 0;
599
}
600
 
601
// IDA: void __cdecl PlayFlicsInDarkness()
602
void PlayFlicsInDarkness(void) {
603
    LOG_TRACE("()");
604
 
605
    gDark_mode = 1;
606
}
607
 
608
// IDA: void __cdecl ReilluminateFlics()
609
void ReilluminateFlics(void) {
610
    LOG_TRACE("()");
611
 
612
    gDark_mode = 0;
613
    FadePaletteUp();
614
}
615
 
616
// IDA: void __cdecl TurnFlicTransparencyOn()
617
void TurnFlicTransparencyOn(void) {
618
    LOG_TRACE8("()");
619
 
620
    gTransparency_on = 1;
621
}
622
 
623
// IDA: void __cdecl TurnFlicTransparencyOff()
624
void TurnFlicTransparencyOff(void) {
625
    LOG_TRACE8("()");
626
    gTransparency_on = 0;
627
}
628
 
629
// IDA: void __cdecl PlayFlicsFromDisk()
630
void PlayFlicsFromDisk(void) {
631
    gPlay_from_disk = 1;
632
}
633
 
634
// IDA: void __cdecl PlayFlicsFromMemory()
635
void PlayFlicsFromMemory(void) {
636
    gPlay_from_disk = 0;
637
}
638
 
639
// IDA: int __cdecl FlicsPlayedFromDisk()
640
int FlicsPlayedFromDisk(void) {
641
    return gPlay_from_disk;
642
}
643
 
644
// IDA: void __cdecl TurnOffPanelFlics()
645
void TurnOffPanelFlics(void) {
646
    gPanel_flic_disable = 1;
647
}
648
 
649
// IDA: void __cdecl TurnOnPanelFlics()
650
void TurnOnPanelFlics(void) {
651
    gPanel_flic_disable = 0;
652
}
653
 
654
// IDA: int __usercall GetPanelFlicFrameIndex@<EAX>(int pIndex@<EAX>)
655
int GetPanelFlicFrameIndex(int pIndex) {
656
    LOG_TRACE("(%d)", pIndex);
657
 
658
    return gPanel_flic[pIndex].current_frame;
659
}
660
 
661
// IDA: void __cdecl FlicPaletteAllocate()
662
void FlicPaletteAllocate(void) {
663
    LOG_TRACE("()");
664
 
665
    gPalette_pixels = BrMemAllocate(0x400u, kMem_flic_pal);
666
    gPalette = DRPixelmapAllocate(BR_PMT_RGBX_888, 1, 256, gPalette_pixels, 0);
667
}
668
 
669
// IDA: void __usercall AssertFlicPixelmap(tFlic_descriptor_ptr pFlic_info@<EAX>, br_pixelmap *pDest_pixelmap@<EDX>)
670
void AssertFlicPixelmap(tFlic_descriptor_ptr pFlic_info, br_pixelmap* pDest_pixelmap) {
671
    LOG_TRACE("(%d, %p)", pFlic_info, pDest_pixelmap);
672
 
673
    if (pDest_pixelmap != NULL) {
674
        pFlic_info->first_pixel = (tU8*)pDest_pixelmap->pixels
675
            + pFlic_info->x_offset
676
            + pFlic_info->y_offset * pDest_pixelmap->row_bytes;
677
    }
678
    pFlic_info->the_pixelmap = pDest_pixelmap;
679
}
680
 
681
// IDA: int __usercall StartFlic@<EAX>(char *pFile_name@<EAX>, int pIndex@<EDX>, tFlic_descriptor_ptr pFlic_info@<EBX>, tU32 pSize@<ECX>, tS8 *pData_ptr, br_pixelmap *pDest_pixelmap, int pX_offset, int pY_offset, int pFrame_rate)
682
int StartFlic(char* pFile_name, int pIndex, tFlic_descriptor_ptr pFlic_info, tU32 pSize, tS8* pData_ptr, br_pixelmap* pDest_pixelmap, int pX_offset, int pY_offset, int pFrame_rate) {
683
    tU16 claimed_speed;
684
    tU16 magic_number;
685
    tPath_name the_path;
686
    int total_size;
687
    LOG_TRACE("(\"%s\", %d, %p, %u, %p, %p, %d, %d, %d)", pFile_name, pIndex, pFlic_info, pSize, pData_ptr, pDest_pixelmap, pX_offset, pY_offset, pFrame_rate);
688
 
689
    if (gPlay_from_disk) {
690
        PathCat(the_path, gApplication_path, "ANIM");
691
        PathCat(the_path, the_path, pFile_name);
692
        pFlic_info->f = DRfopen(the_path, "rb");
693
 
694
        if (pFlic_info->f == NULL) {
695
            FatalError(kFatalError_LoadFlicFile_S, pFile_name);
696
        }
697
        total_size = GetFileLength(pFlic_info->f);
698
        if (total_size >= 75000) {
699
            pFlic_info->bytes_in_buffer = 75000;
700
        } else {
701
            pFlic_info->bytes_in_buffer = total_size;
702
        }
703
        if (pFlic_info->data_start == NULL) {
704
            pFlic_info->data_start = BrMemAllocate(pFlic_info->bytes_in_buffer, kMem_flic_data);
705
        }
706
 
707
        pFlic_info->data = pFlic_info->data_start;
708
        strcpy(gLast_flic_name, pFile_name);
709
        fread(pFlic_info->data_start, 1, pFlic_info->bytes_in_buffer, pFlic_info->f);
710
        pFlic_info->bytes_still_to_be_read = total_size - pFlic_info->bytes_in_buffer;
711
    } else {
712
        pFlic_info->f = NULL;
713
        pFlic_info->data = (char*)pData_ptr;
714
        // TODO: remove this - we added this line because of the padding hack in PlayNextFlicFrame2
715
        pFlic_info->data_start = (char*)pData_ptr;
716
    }
717
    pFlic_info->bytes_remaining = MemReadU32(&pFlic_info->data);
718
    magic_number = MemReadU16(&pFlic_info->data);
719
    if (magic_number == 0xaf11) {
720
        pFlic_info->new_format = 0;
721
    } else if (magic_number == 0xaf12) {
722
        pFlic_info->new_format = 1;
723
    } else {
724
        return -1;
725
    }
726
 
727
    pFlic_info->frames_left = MemReadU16(&pFlic_info->data);
728
    pFlic_info->current_frame = 0;
729
    pFlic_info->width = MemReadU16(&pFlic_info->data);
730
    pFlic_info->height = MemReadU16(&pFlic_info->data);
731
    if (MemReadU16(&pFlic_info->data) != 8) {
732
        FatalError(kFatalError_FlicFileNot8Bits_S, gLast_flic_name);
733
    }
734
    MemSkipBytes(&pFlic_info->data, 2);
735
    claimed_speed = MemReadU16(&pFlic_info->data);
736
    MemSkipBytes(&pFlic_info->data, 0x6e);
737
    pFlic_info->the_pixelmap = pDest_pixelmap;
738
 
20 pmbaty 739
    if (pX_offset == -1) {
740
        if (pDest_pixelmap != NULL) {
741
            pFlic_info->x_offset = (pDest_pixelmap->width - pFlic_info->width) / 2;
742
        } else {
743
            pFlic_info->x_offset = 0;
744
        }
745
    } else {
18 pmbaty 746
        pFlic_info->x_offset = pX_offset;
20 pmbaty 747
    }
748
    if (pY_offset == -1) {
749
        if (pDest_pixelmap != NULL) {
750
            pFlic_info->y_offset = (pDest_pixelmap->height - pFlic_info->height) / 2;
751
        } else {
752
            pFlic_info->y_offset = 0;
753
        }
1 pmbaty 754
    } else {
18 pmbaty 755
        pFlic_info->y_offset = pY_offset;
1 pmbaty 756
    }
757
 
758
    if (pFrame_rate != 0) {
759
        pFlic_info->frame_period = 1000 / pFrame_rate;
760
    } else {
761
        if (claimed_speed == 0) {
762
            FatalError(kFatalError_FlicFileNoFrameRate_S, gLast_flic_name);
763
        }
764
        if (pFlic_info->new_format) {
765
            pFlic_info->frame_period = claimed_speed;
766
        } else {
767
            pFlic_info->frame_period = 14 * claimed_speed;
768
        }
769
    }
770
    pFlic_info->the_index = pIndex;
771
    AssertFlicPixelmap(pFlic_info, pDest_pixelmap);
772
    return 0;
773
}
774
 
775
// IDA: void __cdecl FreeFlicPaletteAllocate()
776
void FreeFlicPaletteAllocate(void) {
777
    LOG_TRACE("()");
778
 
779
    if (gPalette_allocate_count == 0) {
780
        FatalError(kFatalError_FlicPaletteDisposeBeforeAllocation);
781
    }
782
    gPalette_allocate_count--;
783
    if (gPalette_allocate_count == 0) {
784
        BrMemFree(gPalette_pixels);
785
        BrPixelmapFree(gPalette);
786
    }
787
}
788
 
789
// IDA: int __usercall EndFlic@<EAX>(tFlic_descriptor_ptr pFlic_info@<EAX>)
790
int EndFlic(tFlic_descriptor_ptr pFlic_info) {
791
    LOG_TRACE("(%p)", pFlic_info);
792
 
793
    if (pFlic_info->f != NULL) {
794
        BrMemFree(pFlic_info->data_start);
795
        pFlic_info->data_start = NULL;
796
        fclose(pFlic_info->f);
797
        pFlic_info->f = NULL;
798
    }
799
    if (pFlic_info->data != NULL) {
800
        pFlic_info->data = NULL;
801
    }
802
    return 0;
803
}
804
 
805
// IDA: void __usercall DoColourMap(tFlic_descriptor_ptr pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
806
void DoColourMap(tFlic_descriptor_ptr pFlic_info, tU32 chunk_length) {
807
    int i;
808
    int j;
809
    int packet_count;
810
    int skip_count;
811
    int change_count;
812
    int current_colour = 0;
813
    tU8* palette_pixels;
814
    tU8 red;
815
    tU8 green;
816
    tU8 blue;
817
 
818
    palette_pixels = gPalette_pixels;
819
 
820
    packet_count = MemReadU16(&pFlic_info->data);
821
    for (i = 0; i < packet_count; i++) {
822
        skip_count = MemReadU8(&pFlic_info->data);
823
        change_count = MemReadU8(&pFlic_info->data);
824
        if (!change_count) {
825
            change_count = 256;
826
        }
827
        palette_pixels += skip_count * sizeof(br_int_32);
828
        current_colour += skip_count;
829
        for (j = 0; j < change_count; j++) {
830
            red = MemReadU8(&pFlic_info->data);
831
            blue = MemReadU8(&pFlic_info->data);
832
            green = MemReadU8(&pFlic_info->data);
833
            // argb
834
#if BR_ENDIAN_BIG
835
            palette_pixels[3] = green * 4;
836
            palette_pixels[2] = blue * 4;
837
            palette_pixels[1] = red * 4;
838
            palette_pixels[0] = 0;
839
#else
840
            palette_pixels[0] = green * 4;
841
            palette_pixels[1] = blue * 4;
842
            palette_pixels[2] = red * 4;
843
            palette_pixels[3] = 0;
844
#endif
845
            palette_pixels += 4;
846
        }
847
        if (!gPalette_fuck_prevention) {
848
            DRSetPaletteEntries(gPalette, current_colour, change_count);
849
        }
850
    }
851
}
852
 
853
// IDA: void __usercall DoDifferenceX(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
854
void DoDifferenceX(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
855
    int i;
856
    int j;
857
    int k;
858
    int first_line;
859
    int line_count;
860
    int number_of_packets;
861
    int skip_count;
862
    int size_count;
863
    tU8* pixel_ptr;
864
    tU8* line_pixel_ptr;
865
    tU8 the_byte;
866
    tU32 the_row_bytes;
867
    LOG_TRACE("(%p, %d)", pFlic_info, chunk_length);
868
 
869
    first_line = MemReadU16(&pFlic_info->data);
870
    line_count = MemReadU16(&pFlic_info->data);
871
    the_row_bytes = pFlic_info->the_pixelmap->row_bytes;
872
    line_pixel_ptr = pFlic_info->first_pixel + first_line * the_row_bytes;
873
    for (i = 0; i < line_count; i++) {
874
        pixel_ptr = line_pixel_ptr;
875
        number_of_packets = MemReadU8(&pFlic_info->data);
876
        for (j = 0; j < number_of_packets; j++) {
877
            skip_count = MemReadU8(&pFlic_info->data);
878
            size_count = MemReadS8(&pFlic_info->data);
879
            pixel_ptr += skip_count;
880
            if (size_count >= 0) {
881
                for (k = 0; k < size_count; k++) {
882
                    *pixel_ptr = *pFlic_info->data;
883
                    pFlic_info->data++;
884
                    pixel_ptr++;
885
                }
886
            } else {
887
                the_byte = *pFlic_info->data;
888
                pFlic_info->data++;
889
                for (k = 0; k < -size_count; k++) {
890
                    *pixel_ptr = the_byte;
891
                    pixel_ptr++;
892
                }
893
            }
894
        }
895
        line_pixel_ptr += the_row_bytes;
896
    }
897
}
898
 
899
// IDA: void __usercall DoDifferenceTrans(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
900
void DoDifferenceTrans(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
901
    int i;
902
    int j;
903
    int k;
904
    int first_line;
905
    int line_count;
906
    int number_of_packets;
907
    int skip_count;
908
    int size_count;
909
    tU8* pixel_ptr;
910
    tU8* line_pixel_ptr;
911
    tU8 the_byte;
912
    tU32 the_row_bytes;
913
    LOG_TRACE("(%p, %d)", pFlic_info, chunk_length);
914
 
915
    first_line = MemReadU16(&pFlic_info->data);
916
    line_count = MemReadU16(&pFlic_info->data);
917
    the_row_bytes = pFlic_info->the_pixelmap->row_bytes;
918
    line_pixel_ptr = pFlic_info->first_pixel + first_line * the_row_bytes;
919
    for (i = 0; i < line_count; i++) {
920
        pixel_ptr = line_pixel_ptr;
921
        number_of_packets = MemReadU8(&pFlic_info->data);
922
        for (j = 0; j < number_of_packets; j++) {
923
            skip_count = MemReadU8(&pFlic_info->data);
924
            size_count = MemReadS8(&pFlic_info->data);
925
            pixel_ptr += skip_count;
926
            if (size_count >= 0) {
927
                for (k = 0; k < size_count; k++) {
928
                    the_byte = *pFlic_info->data;
929
                    pFlic_info->data++;
930
                    if (the_byte != '\0') {
931
                        *pixel_ptr = the_byte;
932
                    }
933
                    pixel_ptr++;
934
                }
935
            } else {
936
                the_byte = *pFlic_info->data;
937
                pFlic_info->data++;
938
                if (the_byte == '\0') {
939
                    pixel_ptr += size_count;
940
                } else {
941
                    for (k = 0; k < -size_count; k++) {
942
                        *pixel_ptr = the_byte;
943
                        pixel_ptr++;
944
                    }
945
                }
946
            }
947
        }
948
        line_pixel_ptr += the_row_bytes;
949
    }
950
}
951
 
952
// IDA: void __usercall DoColour256(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
953
void DoColour256(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
954
    int i;
955
    int j;
956
    int packet_count;
957
    int skip_count;
958
    int change_count;
959
    int current_colour;
960
    tU8* palette_pixels;
961
    tU8 red;
962
    tU8 green;
963
    tU8 blue;
964
 
965
    current_colour = 0;
966
    palette_pixels = gPalette_pixels;
967
 
968
    packet_count = MemReadU16(&pFlic_info->data);
969
    for (i = 0; i < packet_count; i++) {
970
        skip_count = MemReadU8(&pFlic_info->data);
971
        change_count = MemReadU8(&pFlic_info->data);
972
        if (!change_count) {
973
            change_count = 256;
974
        }
975
        palette_pixels += skip_count * sizeof(br_int_32);
976
        current_colour += skip_count;
977
        for (j = 0; j < change_count; j++) {
978
            red = MemReadU8(&pFlic_info->data);
979
            blue = MemReadU8(&pFlic_info->data);
980
            green = MemReadU8(&pFlic_info->data);
981
            // argb
982
#if BR_ENDIAN_BIG
983
            palette_pixels[3] = green;
984
            palette_pixels[2] = blue;
985
            palette_pixels[1] = red;
986
            palette_pixels[0] = 0;
987
#else
988
            palette_pixels[0] = green;
989
            palette_pixels[1] = blue;
990
            palette_pixels[2] = red;
991
            palette_pixels[3] = 0;
992
#endif
993
            palette_pixels += 4;
994
            // LOG_DEBUG("color %d", current_colour);
995
        }
996
        if (!gPalette_fuck_prevention) {
997
            DRSetPaletteEntries(gPalette, current_colour, change_count);
998
        }
999
    }
1000
}
1001
 
1002
// IDA: void __usercall DoDeltaTrans(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
1003
void DoDeltaTrans(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
1004
    int i;
1005
    int j;
1006
    int k;
1007
    int line_count;
1008
    int number_of_packets;
1009
    int skip_count;
1010
    int size_count;
1011
    tU8* pixel_ptr;
1012
    tU8 the_byte;
1013
    tU8 the_byte2;
1014
    tU32 the_row_bytes;
1015
    tU16* line_pixel_ptr;
1016
    tU16 the_word;
1017
    LOG_TRACE8("(%p, %d)", pFlic_info, chunk_length);
1018
 
1019
    line_count = MemReadU16(&pFlic_info->data);
1020
    the_row_bytes = pFlic_info->the_pixelmap->row_bytes;
1021
    pixel_ptr = pFlic_info->first_pixel;
1022
 
1023
    for (i = 0; i < line_count;) {
1024
        number_of_packets = MemReadS16(&pFlic_info->data);
1025
        line_pixel_ptr = (tU16*)pixel_ptr;
1026
 
1027
        if (number_of_packets < 0) {
1028
            pixel_ptr = pixel_ptr + the_row_bytes * -number_of_packets;
1029
        } else {
1030
            for (j = 0; j < number_of_packets; j++) {
1031
                skip_count = MemReadU8(&pFlic_info->data);
1032
                size_count = MemReadS8(&pFlic_info->data);
1033
                line_pixel_ptr += skip_count / 2;
1034
                if (size_count < 0) {
1035
                    the_byte = *pFlic_info->data++;
1036
                    the_byte2 = *pFlic_info->data++;
1037
 
1038
                    if (the_byte && the_byte2) {
1039
                        the_word = *((tU16*)pFlic_info->data - 1);
1040
                        for (k = 0; k < -size_count; k++) {
1041
                            mem_write_u16(line_pixel_ptr, the_word);
1042
                            line_pixel_ptr++;
1043
                        }
1044
                    } else {
1045
                        for (k = 0; k < -size_count; k++) {
1046
                            if (the_byte) {
1047
                                *(tU8*)line_pixel_ptr = the_byte;
1048
                            }
1049
                            line_pixel_ptr = (tU16*)((tU8*)line_pixel_ptr + 1);
1050
                            if (the_byte2) {
1051
                                *(tU8*)line_pixel_ptr = the_byte2;
1052
                            }
1053
                            line_pixel_ptr = (tU16*)((tU8*)line_pixel_ptr + 1);
1054
                        }
1055
                    }
1056
                } else {
1057
                    for (k = 0; k < size_count; k++) {
1058
                        the_word = *(tU16*)pFlic_info->data;
1059
                        pFlic_info->data += 2;
1060
                        if (the_word) {
1061
                            mem_write_u16(line_pixel_ptr, the_word);
1062
                        }
1063
                        line_pixel_ptr++;
1064
                    }
1065
                }
1066
            }
1067
            pixel_ptr = pixel_ptr + the_row_bytes;
1068
            i++;
1069
        }
1070
    }
1071
}
1072
 
1073
// IDA: void __usercall DoDeltaX(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
1074
void DoDeltaX(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
1075
    int i;
1076
    int j;
1077
    int k;
1078
    int line_count;
1079
    int number_of_packets;
1080
    int skip_count;
1081
    int size_count;
1082
    tU8* pixel_ptr;
1083
    tU32 the_row_bytes;
1084
    tU16* line_pixel_ptr;
1085
    tU16 the_word;
1086
    LOG_TRACE("(%p, %d)", pFlic_info, chunk_length);
1087
 
1088
    line_count = MemReadU16(&pFlic_info->data);
1089
    the_row_bytes = pFlic_info->the_pixelmap->row_bytes;
1090
    pixel_ptr = pFlic_info->first_pixel;
1091
 
1092
    for (i = 0; i < line_count;) {
1093
        number_of_packets = MemReadS16(&pFlic_info->data);
1094
        line_pixel_ptr = (tU16*)pixel_ptr;
1095
 
1096
        if (number_of_packets < 0) {
1097
            pixel_ptr = pixel_ptr + the_row_bytes * -number_of_packets;
1098
        } else {
1099
            for (j = 0; j < number_of_packets; j++) {
1100
                skip_count = MemReadU8(&pFlic_info->data);
1101
                size_count = MemReadS8(&pFlic_info->data);
1102
                line_pixel_ptr += skip_count / 2;
1103
                if (size_count < 0) {
1104
                    the_word = *(tU16*)pFlic_info->data;
1105
                    pFlic_info->data += 2;
1106
                    for (k = 0; k < -size_count; k++) {
1107
                        *line_pixel_ptr = the_word;
1108
                        line_pixel_ptr++;
1109
                    }
1110
                } else {
1111
                    for (k = 0; k < size_count; k++) {
1112
                        the_word = *(tU16*)pFlic_info->data;
1113
                        pFlic_info->data += 2;
1114
                        *line_pixel_ptr = the_word;
1115
                        line_pixel_ptr++;
1116
                    }
1117
                }
1118
            }
1119
            pixel_ptr = pixel_ptr + the_row_bytes;
1120
            i++;
1121
        }
1122
    }
1123
}
1124
 
1125
// IDA: void __usercall DoBlack(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
1126
void DoBlack(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
1127
    int i;
1128
    int j;
1129
    int the_width;
1130
    tU8* pixel_ptr;
1131
    tU32 the_row_bytes;
1132
    tU32* line_pixel_ptr;
1133
    LOG_TRACE("(%p, %d)", pFlic_info, chunk_length);
1134
 
1135
    pixel_ptr = pFlic_info->first_pixel;
1136
    the_row_bytes = pFlic_info->the_pixelmap->row_bytes;
1137
    the_width = pFlic_info->width;
1138
    for (i = 0; i < pFlic_info->height; i++) {
1139
        line_pixel_ptr = (tU32*)pixel_ptr;
1140
        for (j = 0; j < the_width / (int) sizeof(tU32); j++) { // Pierre-Marie Baty -- added type cast
1141
            *line_pixel_ptr = 0;
1142
            line_pixel_ptr++;
1143
        }
1144
        pixel_ptr += the_row_bytes;
1145
    }
1146
}
1147
 
1148
// IDA: void __usercall DoRunLengthX(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
1149
void DoRunLengthX(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
1150
    int i;
1151
    int j;
1152
    int k;
1153
    int number_of_packets;
1154
    int size_count;
1155
    tU8* pixel_ptr;
1156
    tU8* line_pixel_ptr;
1157
    tU8 the_byte;
1158
    tU32 the_row_bytes;
1159
    LOG_TRACE("(%p, %d)", pFlic_info, chunk_length);
1160
 
1161
    the_row_bytes = pFlic_info->the_pixelmap->row_bytes;
1162
    pixel_ptr = pFlic_info->first_pixel;
1163
 
1164
    for (i = 0; i < pFlic_info->height; i++) {
1165
        line_pixel_ptr = pixel_ptr;
1166
        number_of_packets = MemReadU8(&pFlic_info->data);
1167
        for (j = 0; j < number_of_packets; j++) {
1168
            size_count = MemReadS8(&pFlic_info->data);
1169
            if (size_count >= 0) {
1170
                the_byte = MemReadU8(&pFlic_info->data);
1171
                for (k = 0; k < size_count; k++) {
1172
                    *line_pixel_ptr = the_byte;
1173
                    line_pixel_ptr++;
1174
                }
1175
            } else {
1176
                for (k = 0; k < -size_count; k++) {
1177
                    the_byte = MemReadU8(&pFlic_info->data);
1178
                    *line_pixel_ptr = the_byte;
1179
                    line_pixel_ptr++;
1180
                }
1181
            }
1182
        }
1183
        pixel_ptr += the_row_bytes;
1184
    }
1185
}
1186
 
1187
// IDA: void __usercall DoRunLengthTrans(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
1188
void DoRunLengthTrans(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
1189
    int i;
1190
    int j;
1191
    int k;
1192
    int number_of_packets;
1193
    int size_count;
1194
    tU8* pixel_ptr;
1195
    tU8* line_pixel_ptr;
1196
    tU8 the_byte;
1197
    tU32 the_row_bytes;
1198
    LOG_TRACE8("(%p, %d)", pFlic_info, chunk_length);
1199
 
1200
    the_row_bytes = pFlic_info->the_pixelmap->row_bytes;
1201
    pixel_ptr = pFlic_info->first_pixel;
1202
 
1203
    for (i = 0; i < pFlic_info->height; i++) {
1204
        line_pixel_ptr = pixel_ptr;
1205
        number_of_packets = MemReadU8(&pFlic_info->data);
1206
        for (j = 0; j < number_of_packets; j++) {
1207
            size_count = MemReadS8(&pFlic_info->data);
1208
            if (size_count >= 0) {
1209
                the_byte = MemReadU8(&pFlic_info->data);
1210
 
1211
                for (k = 0; k < size_count; k++) {
1212
                    if (the_byte) {
1213
                        *line_pixel_ptr = the_byte;
1214
                    }
1215
                    line_pixel_ptr++;
1216
                }
1217
            } else {
1218
                for (k = 0; k < -size_count; k++) {
1219
                    the_byte = MemReadU8(&pFlic_info->data);
1220
                    if (the_byte) {
1221
                        *line_pixel_ptr = the_byte;
1222
                    }
1223
                    line_pixel_ptr++;
1224
                }
1225
            }
1226
        }
1227
        pixel_ptr += the_row_bytes;
1228
    }
1229
}
1230
 
1231
// IDA: void __usercall DoUncompressed(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
1232
void DoUncompressed(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
1233
    int i;
1234
    int j;
1235
    int the_width;
1236
    tU8* pixel_ptr;
1237
    tU32 the_row_bytes;
1238
    tU32* line_pixel_ptr;
1239
    LOG_TRACE("(%p, %d)", pFlic_info, chunk_length);
1240
 
1241
    pixel_ptr = pFlic_info->first_pixel;
1242
    the_row_bytes = pFlic_info->the_pixelmap->row_bytes;
1243
    the_width = pFlic_info->width;
1244
    for (i = 0; i < pFlic_info->height; i++) {
1245
        line_pixel_ptr = (tU32*)pixel_ptr;
1246
        for (j = 0; j < the_width / 4; j++) {
1247
            *line_pixel_ptr = MemReadU32(&pFlic_info->data);
1248
            line_pixel_ptr++;
1249
        }
1250
        pixel_ptr += the_row_bytes;
1251
    }
1252
}
1253
 
1254
// IDA: void __usercall DoUncompressedTrans(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
1255
void DoUncompressedTrans(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
1256
    int i;
1257
    int j;
1258
    int the_width;
1259
    tU8* pixel_ptr;
1260
    tU8* line_pixel_ptr;
1261
    tU8 the_byte;
1262
    tU32 the_row_bytes;
1263
    LOG_TRACE("(%p, %d)", pFlic_info, chunk_length);
1264
 
1265
    pixel_ptr = pFlic_info->first_pixel;
1266
    the_row_bytes = pFlic_info->the_pixelmap->row_bytes;
1267
    the_width = pFlic_info->width;
1268
    for (i = 0; i < pFlic_info->height; i++) {
1269
        line_pixel_ptr = pixel_ptr;
1270
        for (j = 0; j < the_width; j++) {
1271
#if defined(DETHRACE_FIX_BUGS)
1272
            the_byte = MemReadU8(&pFlic_info->data);
1273
#else
1274
            the_byte = MemReadU32(&pFlic_info->data);
1275
#endif
1276
            if (the_byte != '\0') {
1277
                *line_pixel_ptr = the_byte;
1278
            }
1279
            line_pixel_ptr++;
1280
        }
1281
        pixel_ptr += the_row_bytes;
1282
    }
1283
}
1284
 
1285
// IDA: void __usercall DoMini(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
1286
void DoMini(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
1287
    LOG_TRACE("(%p, %d)", pFlic_info, chunk_length);
1288
 
1289
    MemSkipBytes(&pFlic_info->data, chunk_length - 6);
1290
}
1291
 
1292
// IDA: void __usercall DrawTranslations(tFlic_descriptor *pFlic_info@<EAX>, int pLast_frame@<EDX>)
1293
void DrawTranslations(tFlic_descriptor* pFlic_info, int pLast_frame) {
1294
    tTranslation_record* trans;
1295
    int i;
1296
    int x;
1297
    int width;
1298
    int right_edge;
1299
    LOG_TRACE("(%p, %d)", pFlic_info, pLast_frame);
1300
 
1301
    for (i = 0; i < gTranslation_count; i++) {
1302
        trans = &gTranslations[i];
1303
        if (trans->flic_index == pFlic_info->the_index && (trans->every_frame || pLast_frame)) {
1304
            width = DRTextWidth(gTrans_fonts[trans->font_index], trans->text);
1305
            switch (trans->justification) {
1306
            case eJust_left:
1307
                x = trans->x;
1308
                right_edge = x + width;
1309
                break;
1310
            case eJust_right:
1311
                x = trans->x - width;
1312
                right_edge = x;
1313
                break;
1314
            case eJust_centre:
1315
                x = trans->x - width / 2;
1316
                right_edge = x + width / 2;
1317
                break;
1318
            default:
1319
                TELL_ME_IF_WE_PASS_THIS_WAY();
1320
            }
1321
            TransDRPixelmapText(
1322
                pFlic_info->the_pixelmap,
1323
                x + (trans->global ? 0 : pFlic_info->x_offset),
1324
                trans->y + (trans->global ? 0 : pFlic_info->y_offset),
1325
                gTrans_fonts[trans->font_index],
1326
                trans->text,
1327
                right_edge);
1328
        }
1329
    }
1330
}
1331
 
1332
// IDA: int __usercall PlayNextFlicFrame2@<EAX>(tFlic_descriptor *pFlic_info@<EAX>, int pPanel_flic@<EDX>)
1333
int PlayNextFlicFrame2(tFlic_descriptor* pFlic_info, int pPanel_flic) {
1334
    tU32 frame_length;
1335
    tU32 chunk_length;
1336
    int chunk_count;
1337
    int chunk_counter;
1338
    int chunk_type;
1339
    int magic_bytes;
1340
    //int last_frame; // Pierre-Marie Baty -- unused variable
1341
    int data_knocked_off;
1342
    int read_amount;
1343
 
1344
    // LOG_DEBUG("%d (%p), frames left: %d offset: %d", pFlic_info->the_index, pFlic_info, pFlic_info->frames_left, (pFlic_info->data - pFlic_info->data_start) + 4);
1345
    PossibleService();
1346
    frame_length = MemReadU32(&pFlic_info->data);
1347
    magic_bytes = MemReadU16(&pFlic_info->data);
1348
    chunk_count = MemReadU16(&pFlic_info->data);
1349
 
1350
    MemSkipBytes(&pFlic_info->data, 8);
1351
    if (magic_bytes == 0xf1fa) {
1352
        for (chunk_counter = 0; chunk_counter < chunk_count; chunk_counter++) {
1353
            chunk_length = MemReadU32(&pFlic_info->data);
1354
            chunk_type = MemReadU16(&pFlic_info->data);
1355
            switch (chunk_type) {
1356
            case 4:
1357
                DoColour256(pFlic_info, chunk_length);
1358
                break;
1359
            case 7:
1360
                if (gTransparency_on) {
1361
                    DoDeltaTrans(pFlic_info, chunk_length);
1362
                } else {
1363
                    DoDeltaX(pFlic_info, chunk_length);
1364
                }
1365
                break;
1366
            case 11:
1367
                DoColourMap(pFlic_info, chunk_length);
1368
                break;
1369
            case 12:
1370
                if (gTransparency_on) {
1371
                    DoDifferenceTrans(pFlic_info, chunk_length);
1372
                } else {
1373
                    DoDifferenceX(pFlic_info, chunk_length);
1374
                }
1375
                break;
1376
            case 13:
1377
                DoBlack(pFlic_info, chunk_length);
1378
                break;
1379
            case 15:
1380
                if (gTransparency_on) {
1381
                    DoRunLengthTrans(pFlic_info, chunk_length);
1382
                } else {
1383
                    DoRunLengthX(pFlic_info, chunk_length);
1384
                }
1385
                break;
1386
            case 16:
1387
                if (gTransparency_on) {
1388
                    DoUncompressedTrans(pFlic_info, chunk_length);
1389
                } else {
1390
                    DoUncompressed(pFlic_info, chunk_length);
1391
                }
1392
                break;
1393
            case 18:
1394
                DoMini(pFlic_info, chunk_length);
1395
                break;
1396
            default:
1397
                LOG_WARN("unrecognized chunk type");
1398
                MemSkipBytes(&pFlic_info->data, chunk_length - 6);
1399
                break;
1400
            }
1401
            // Align on even byte
1402
            pFlic_info->data = (char*)((uintptr_t)(pFlic_info->data + 1) & (~(uintptr_t)1));
1403
        }
1404
    } else {
1405
        LOG_WARN("not frame header");
1406
        MemSkipBytes(&pFlic_info->data, frame_length - 16);
1407
        pFlic_info->frames_left++;
1408
        pFlic_info->current_frame--;
1409
    }
1410
    pFlic_info->current_frame++;
1411
    pFlic_info->frames_left--;
1412
    if (gTrans_enabled && gTranslation_count != 0 && !pPanel_flic) {
1413
        DrawTranslations(pFlic_info, pFlic_info->frames_left == 0);
1414
    }
1415
    if (pFlic_info->f != NULL && pFlic_info->bytes_still_to_be_read) {
1416
        data_knocked_off = pFlic_info->data - pFlic_info->data_start;
1417
        memmove(pFlic_info->data_start, pFlic_info->data, pFlic_info->bytes_in_buffer - data_knocked_off);
1418
        pFlic_info->data = pFlic_info->data_start;
1419
        pFlic_info->bytes_in_buffer -= data_knocked_off;
1420
 
1421
        if (pFlic_info->bytes_still_to_be_read > data_knocked_off) {
1422
            read_amount = data_knocked_off;
1423
        } else {
1424
            read_amount = pFlic_info->bytes_still_to_be_read;
1425
        }
1426
        if (read_amount != 0) {
1427
            fread(&pFlic_info->data_start[pFlic_info->bytes_in_buffer], 1, read_amount, pFlic_info->f);
1428
        }
1429
        pFlic_info->bytes_in_buffer += read_amount;
1430
        pFlic_info->bytes_still_to_be_read -= read_amount;
1431
    }
1432
    return pFlic_info->frames_left == 0;
1433
}
1434
 
1435
// IDA: int __usercall PlayNextFlicFrame@<EAX>(tFlic_descriptor *pFlic_info@<EAX>)
1436
int PlayNextFlicFrame(tFlic_descriptor* pFlic_info) {
1437
    LOG_TRACE("(%p)", pFlic_info);
1438
 
1439
    return PlayNextFlicFrame2(pFlic_info, 0);
1440
}
1441
 
1442
// IDA: int __usercall PlayFlic@<EAX>(int pIndex@<EAX>, tU32 pSize@<EDX>, tS8 *pData_ptr@<EBX>, br_pixelmap *pDest_pixelmap@<ECX>, int pX_offset, int pY_offset, void (*DoPerFrame)(), int pInterruptable, int pFrame_rate)
1443
int PlayFlic(int pIndex, tU32 pSize, tS8* pData_ptr, br_pixelmap* pDest_pixelmap, int pX_offset, int pY_offset, void (*DoPerFrame)(void), int pInterruptable, int pFrame_rate) {
1444
    int finished_playing;
1445
    tFlic_descriptor the_flic;
1446
    tU32 last_frame;
1447
    tU32 new_time;
1448
    tU32 frame_period;
1449
    LOG_TRACE("(%d, %u, %p, %p, %d, %d, %p, %d, %d)", pIndex, pSize, pData_ptr, pDest_pixelmap, pX_offset, pY_offset, DoPerFrame, pInterruptable, pFrame_rate);
1450
 
1451
    finished_playing = 0;
1452
    the_flic.data_start = NULL;
1453
    if (StartFlic(gMain_flic_list[pIndex].file_name, pIndex, &the_flic, pSize, pData_ptr, pDest_pixelmap, pX_offset, pY_offset, pFrame_rate)) {
1454
        LOG_WARN("startflic returned error");
1455
        return -1;
1456
    }
1457
 
1458
    last_frame = 0;
1459
    while ((!pInterruptable || !AnyKeyDown()) && !finished_playing) {
1460
        new_time = PDGetTotalTime();
1461
        frame_period = new_time - last_frame;
1462
 
1463
        if (gSound_time != 0 && new_time >= gSound_time) {
1464
            DRS3StartSound(gEffects_outlet, gSound_ID);
1465
            gSound_time = 0;
1466
        }
1467
        if (frame_period >= the_flic.frame_period) {
1468
            last_frame = new_time;
1469
            finished_playing = PlayNextFlicFrame(&the_flic);
1470
            DoPerFrame();
1471
            if (!gDark_mode) {
1472
                EnsurePaletteUp();
1473
            }
1474
            ServiceGame();
1475
        }
1476
    }
1477
    ServiceGame();
1478
    EndFlic(&the_flic);
1479
    return 0;
1480
}
1481
 
1482
// IDA: void __cdecl SwapScreen()
1483
void SwapScreen(void) {
1484
    PDScreenBufferSwap(0);
1485
}
1486
 
1487
// IDA: void __usercall ShowFlic(int pIndex@<EAX>)
1488
void ShowFlic(int pIndex) {
1489
    do {
1490
        PlayFlic(
1491
            pIndex,
1492
            gMain_flic_list[pIndex].the_size,
1493
            gMain_flic_list[pIndex].data_ptr,
1494
            gBack_screen,
1495
            gMain_flic_list[pIndex].x_offset,
1496
            gMain_flic_list[pIndex].y_offset,
1497
            SwapScreen,
1498
            gMain_flic_list[pIndex].interruptable,
1499
            gMain_flic_list[pIndex].frame_rate);
1500
    } while (gMain_flic_list[pIndex].repeat && !AnyKeyDown());
1501
    gLast_flic_name[0] = '\0'; // byte_10344C;
1502
}
1503
 
1504
// IDA: void __cdecl InitFlics()
1505
void InitFlics(void) {
1506
    int i;
1507
    LOG_TRACE("()");
1508
 
1509
    for (i = 0; i < COUNT_OF(gMain_flic_list); i++) {
1510
        gMain_flic_list[i].data_ptr = NULL;
1511
    }
1512
}
1513
 
1514
// IDA: int __usercall LoadFlic@<EAX>(int pIndex@<EAX>)
1515
int LoadFlic(int pIndex) {
1516
    tPath_name the_path;
1517
    FILE* f;
1518
    //char* the_buffer; // Pierre-Marie Baty -- unused variable
1519
    LOG_TRACE("(%d)", pIndex);
1520
 
1521
    if (pIndex < 0) {
1522
        return 0;
1523
    }
1524
    if (gMain_flic_list[pIndex].data_ptr != NULL) {
1525
        MAMSLock((void**)&gMain_flic_list[pIndex].data_ptr);
1526
        return 1;
1527
    }
1528
    if (gPlay_from_disk) {
1529
        gMain_flic_list[pIndex].data_ptr = NULL;
1530
        return 1;
1531
    }
1532
    PossibleService();
1533
    PathCat(the_path, gApplication_path, "ANIM");
1534
    PathCat(the_path, the_path, gMain_flic_list[pIndex].file_name);
1535
    f = DRfopen(the_path, "rb");
1536
 
1537
    if (f == NULL) {
1538
        FatalError(kFatalError_LoadFlicFile_S, gMain_flic_list[pIndex].file_name);
1539
    }
1540
 
1541
    gMain_flic_list[pIndex].the_size = GetFileLength(f);
1542
    gMain_flic_list[pIndex].data_ptr = BrMemAllocate(gMain_flic_list[pIndex].the_size, 0x90u);
1543
 
1544
    if (gMain_flic_list[pIndex].data_ptr == NULL) {
1545
        if (AllocationErrorsAreFatal()) {
1546
            FatalError(kFatalError_AllocateFlicFile_S, gMain_flic_list[pIndex].file_name);
1547
        }
1548
#ifdef DETHRACE_FIX_BUGS
1549
        fclose(f);
1550
#endif
1551
        return 0;
1552
    }
1553
 
1554
    fread(gMain_flic_list[pIndex].data_ptr, 1, gMain_flic_list[pIndex].the_size, f);
1555
    strcpy(gLast_flic_name, gMain_flic_list[pIndex].file_name);
1556
    fclose(f);
1557
    return 1;
1558
}
1559
 
1560
// IDA: void __usercall UnlockFlic(int pIndex@<EAX>)
1561
void UnlockFlic(int pIndex) {
1562
    if (pIndex >= 0) {
1563
        if (gMain_flic_list[pIndex].data_ptr != NULL) {
1564
            MAMSUnlock((void**)&gMain_flic_list[pIndex].data_ptr);
1565
        }
1566
    }
1567
}
1568
 
1569
// IDA: int __usercall LoadFlicData@<EAX>(char *pName@<EAX>, tU8 **pData@<EDX>, tU32 *pData_length@<EBX>)
1570
int LoadFlicData(char* pName, tU8** pData, tU32* pData_length) {
1571
    FILE* f;
1572
    tPath_name the_path;
1573
    LOG_TRACE("(\"%s\", %p, %p)", pName, pData, pData_length);
1574
 
1575
    if (*pData != NULL) {
1576
        MAMSLock((void**)pData);
1577
        return 1;
1578
    }
1579
    if (gPlay_from_disk) {
1580
        return 1;
1581
    }
1582
    PossibleService();
1583
    PathCat(the_path, gApplication_path, "ANIM");
1584
    PathCat(the_path, the_path, pName);
1585
    f = DRfopen(the_path, "rb");
1586
    if (f == NULL) {
1587
        return 0;
1588
    }
1589
    *pData_length = GetFileLength(f);
1590
    *pData = BrMemAllocate(*pData_length, kMem_flic_data_2);
1591
    if (*pData == NULL) {
1592
        fclose(f);
1593
        return 0;
1594
    }
1595
    fread(*pData, 1, *pData_length, f);
1596
    fclose(f);
1597
    return 1;
1598
}
1599
 
1600
// IDA: void __usercall FreeFlic(int pIndex@<EAX>)
1601
void FreeFlic(int pIndex) {
1602
    LOG_TRACE("(%d)", pIndex);
1603
 
1604
    PossibleService();
1605
    if (gMain_flic_list[pIndex].data_ptr != NULL) {
1606
        BrMemFree(gMain_flic_list[pIndex].data_ptr);
1607
        gMain_flic_list[pIndex].data_ptr = NULL;
1608
    }
1609
}
1610
 
1611
// IDA: void __usercall ForceRunFlic(int pIndex@<EAX>)
1612
void ForceRunFlic(int pIndex) {
1613
    LOG_TRACE("(%d)", pIndex);
1614
 
1615
    LoadFlic(pIndex);
1616
    ShowFlic(pIndex);
1617
    UnlockFlic(pIndex);
1618
}
1619
 
1620
// IDA: void __usercall RunFlicAt(int pIndex@<EAX>, int pX@<EDX>, int pY@<EBX>)
1621
void RunFlicAt(int pIndex, int pX, int pY) {
1622
    LOG_TRACE("(%d, %d, %d)", pIndex, pX, pY);
1623
 
1624
    LoadFlic(pIndex);
1625
    PlayFlic(
1626
        pIndex,
1627
        gMain_flic_list[pIndex].the_size,
1628
        gMain_flic_list[pIndex].data_ptr,
1629
        gBack_screen,
1630
        pX,
1631
        pY,
1632
        SwapScreen,
1633
        0,
1634
        0);
1635
    UnlockFlic(pIndex);
1636
}
1637
 
1638
// IDA: void __usercall RunFlic(int pIndex@<EAX>)
1639
void RunFlic(int pIndex) {
1640
    LOG_TRACE("(%d)", pIndex);
1641
 
1642
    if (gPending_flic >= 0) {
1643
        ForceRunFlic(gPending_flic);
1644
        gPending_flic = -1;
1645
    }
1646
    if (LoadFlic(pIndex)) {
1647
        if (gMain_flic_list[pIndex].queued) {
1648
            gPending_flic = pIndex;
1649
        } else {
1650
            ShowFlic(pIndex);
1651
            UnlockFlic(pIndex);
1652
        }
1653
    }
1654
}
1655
 
1656
// IDA: void __usercall PreloadBunchOfFlics(int pBunch_index@<EAX>)
1657
void PreloadBunchOfFlics(int pBunch_index) {
1658
    int i;
1659
    LOG_TRACE("(%d)", pBunch_index);
1660
 
1661
    for (i = 0; i < gFlic_bunch[pBunch_index].count; i++) {
1662
        LoadFlic(gFlic_bunch[pBunch_index].indexes[i]);
1663
    }
1664
}
1665
 
1666
// IDA: void __usercall UnlockBunchOfFlics(int pBunch_index@<EAX>)
1667
void UnlockBunchOfFlics(int pBunch_index) {
1668
    int i;
1669
    LOG_TRACE("(%d)", pBunch_index);
1670
 
1671
    for (i = 0; i < gFlic_bunch[pBunch_index].count; i++) {
1672
        UnlockFlic(gFlic_bunch[pBunch_index].indexes[i]);
1673
    }
1674
}
1675
 
1676
// IDA: void __usercall FlushAllFlics(int pBunch_index@<EAX>)
1677
void FlushAllFlics(int pBunch_index) {
1678
    int i;
1679
    LOG_TRACE("(%d)", pBunch_index);
1680
 
1681
    for (i = 0; i < COUNT_OF(gFlic_bunch); i++) {
1682
        FreeFlic(i);
1683
    }
1684
}
1685
 
1686
// IDA: void __cdecl InitFlicQueue()
1687
void InitFlicQueue(void) {
1688
    gFirst_flic = NULL;
1689
}
1690
 
1691
// IDA: int __cdecl FlicQueueFinished()
1692
int FlicQueueFinished(void) {
1693
    tFlic_descriptor* the_flic;
1694
    LOG_TRACE("()");
1695
 
1696
    the_flic = gFirst_flic;
1697
    while (the_flic != NULL) {
1698
        if (the_flic->must_finish) {
1699
            return 0;
1700
        }
1701
        the_flic = the_flic->next;
1702
    }
1703
    return 1;
1704
}
1705
 
1706
// IDA: void __usercall ProcessFlicQueue(tU32 pInterval@<EAX>)
1707
void ProcessFlicQueue(tU32 pInterval) {
1708
    tFlic_descriptor* the_flic;
1709
    tFlic_descriptor* last_flic;
1710
    tFlic_descriptor* doomed_flic;
1711
    tU32 new_time;
1712
    int finished_playing;
1713
    LOG_TRACE8("(%d)", pInterval);
1714
 
1715
    DontLetFlicFuckWithPalettes();
1716
    TurnFlicTransparencyOn();
1717
    the_flic = gFirst_flic;
1718
    last_flic = NULL;
1719
    new_time = PDGetTotalTime();
1720
    while (the_flic != NULL) {
1721
        if (new_time - the_flic->last_frame < the_flic->frame_period) {
1722
            finished_playing = 0;
1723
        } else {
1724
            the_flic->last_frame = new_time;
1725
            finished_playing = PlayNextFlicFrame(the_flic);
1726
        }
1727
        if (finished_playing) {
1728
            EndFlic(the_flic);
1729
            if (last_flic != NULL) {
1730
                last_flic->next = the_flic->next;
1731
            } else {
1732
                gFirst_flic = the_flic->next;
1733
            }
1734
            doomed_flic = the_flic;
1735
            the_flic = the_flic->next;
1736
            BrMemFree(doomed_flic);
1737
        } else {
1738
            last_flic = the_flic;
1739
            the_flic = the_flic->next;
1740
        }
1741
    }
1742
    TurnFlicTransparencyOff();
1743
    LetFlicFuckWithPalettes();
1744
}
1745
 
1746
// IDA: void __cdecl FlushFlicQueue()
1747
void FlushFlicQueue(void) {
1748
    tFlic_descriptor* the_flic;
1749
    tFlic_descriptor* old_flic;
1750
    LOG_TRACE("()");
1751
 
1752
    // Jeff: loop through pending flics until we reach the end or we find one that is `must_finish`.
1753
    // If `must_finish`, we process the queue then check again.
1754
    // If there are no `must_finish` in the list, immediately end any remaining flics
1755
 
1756
    while (!FlicQueueFinished()) {
1757
        RemoveTransientBitmaps(1);
1758
        ProcessFlicQueue(gFrame_period);
1759
        DoMouseCursor();
1760
        PDScreenBufferSwap(0);
1761
    }
1762
    the_flic = gFirst_flic;
1763
    while (the_flic != NULL) {
1764
        EndFlic(the_flic);
1765
        old_flic = the_flic;
1766
        the_flic = the_flic->next;
1767
        BrMemFree(old_flic);
1768
    }
1769
    gFirst_flic = NULL;
1770
}
1771
 
1772
// IDA: void __usercall AddToFlicQueue(int pIndex@<EAX>, int pX@<EDX>, int pY@<EBX>, int pMust_finish@<ECX>)
1773
void AddToFlicQueue(int pIndex, int pX, int pY, int pMust_finish) {
1774
    tFlic_descriptor* the_flic = NULL;
1775
    tFlic_descriptor* new_flic = NULL;
1776
    tFlic_descriptor* last_flic = NULL;
1777
    tFlic_descriptor* doomed_flic = NULL;
1778
    LOG_TRACE("(%d, %d, %d, %d)", pIndex, pX, pY, pMust_finish);
1779
 
1780
    the_flic = gFirst_flic;
1781
    while (the_flic != NULL) {
1782
        if (pX == the_flic->x_offset && pY == the_flic->y_offset) {
1783
            doomed_flic = the_flic;
1784
            break;
1785
        }
1786
        last_flic = the_flic;
1787
        the_flic = the_flic->next;
1788
    }
1789
 
1790
    if (doomed_flic != NULL) {
1791
        EndFlic(doomed_flic);
1792
        if (last_flic != NULL) {
1793
            last_flic->next = doomed_flic->next;
1794
        } else {
1795
            gFirst_flic = doomed_flic->next;
1796
        }
1797
        BrMemFree(doomed_flic);
1798
    }
1799
 
1800
    LoadFlic(pIndex);
1801
    new_flic = BrMemAllocate(sizeof(tFlic_descriptor), kMem_queued_flic);
1802
    new_flic->next = NULL;
1803
    the_flic = gFirst_flic;
1804
    if (gFirst_flic != NULL) {
1805
        while (the_flic->next != NULL) {
1806
            the_flic = the_flic->next;
1807
        }
1808
        the_flic->next = new_flic;
1809
    } else {
1810
        gFirst_flic = new_flic;
1811
    }
1812
    new_flic->last_frame = 0;
1813
    new_flic->data_start = NULL;
1814
    new_flic->the_index = pIndex;
1815
    new_flic->must_finish = pMust_finish;
1816
 
1817
    StartFlic(
1818
        gMain_flic_list[pIndex].file_name,
1819
        pIndex,
1820
        new_flic,
1821
        gMain_flic_list[pIndex].the_size,
1822
        gMain_flic_list[pIndex].data_ptr,
1823
        gBack_screen,
1824
        pX >= 0 ? pX : gMain_flic_list[pIndex].x_offset,
1825
        pY >= 0 ? pY : gMain_flic_list[pIndex].y_offset,
1826
        20);
1827
}
1828
 
1829
// IDA: void __usercall InitialiseFlicPanel(int pIndex@<EAX>, int pLeft@<EDX>, int pTop@<EBX>, int pWidth@<ECX>, int pHeight)
1830
void InitialiseFlicPanel(int pIndex, int pLeft, int pTop, int pWidth, int pHeight) {
1831
    void* the_pixels;
1832
    LOG_TRACE("(%d, %d, %d, %d, %d)", pIndex, pLeft, pTop, pWidth, pHeight);
1833
 
1834
    gPanel_flic[pIndex].data = NULL;
1835
    gPanel_flic_left[pIndex] = pLeft;
1836
    gPanel_flic_top[pIndex] = pTop;
1837
    the_pixels = BrMemAllocate(pHeight * ((pWidth + 3) & ~3), kFlic_panel_pixels);
1838
    if (gScreen->row_bytes < 0) {
1839
        BrFatal(
1840
            "..\\..\\source\\common\\flicplay.c",
1841
            2116,
1842
            "Bruce bug at line %d, file ..\\..\\source\\common\\flicplay.c",
1843
            68);
1844
    }
1845
    gPanel_buffer[pIndex] = DRPixelmapAllocate(gScreen->type, pWidth, pHeight, the_pixels, 0);
1846
}
1847
 
1848
// IDA: void __usercall DisposeFlicPanel(int pIndex@<EAX>)
1849
void DisposeFlicPanel(int pIndex) {
1850
    LOG_TRACE("(%d)", pIndex);
1851
 
1852
    EndFlic(&gPanel_flic[pIndex]);
1853
    BrMemFree(gPanel_buffer[pIndex]->pixels);
1854
    BrPixelmapFree(gPanel_buffer[pIndex]);
1855
    gPanel_buffer[pIndex] = NULL;
1856
}
1857
 
1858
// IDA: void __usercall ServicePanelFlics(int pCopy_to_buffer@<EAX>)
1859
void ServicePanelFlics(int pCopy_to_buffer) {
1860
    tU32 time_diff;
1861
    tU32 the_time;
1862
    tU32 old_last_time[2];
1863
    int i;
1864
    int j;
1865
    int iteration_count;
1866
    int finished;
1867
 
1868
    if (gPanel_flic_disable) {
1869
        return;
1870
    }
1871
    the_time = PDGetTotalTime();
1872
    DontLetFlicFuckWithPalettes();
1873
    TurnFlicTransparencyOn();
1874
 
1875
    for (i = 0; i < COUNT_OF(gPanel_flic); i++) {
1876
        old_last_time[i] = gLast_panel_frame_time[i];
1877
        if (gPanel_buffer[i] != NULL && gPanel_flic[i].data != NULL) {
1878
            if (old_last_time[i] != 0) {
1879
                time_diff = the_time - old_last_time[i];
1880
                iteration_count = time_diff / gPanel_flic[i].frame_period;
1881
            } else {
1882
                iteration_count = 1;
1883
            }
1884
            for (j = 0; j < iteration_count; j++) {
1885
                finished = PlayNextFlicFrame2(&gPanel_flic[i], 1);
1886
                if (finished) {
1887
                    EndFlic(&gPanel_flic[i]);
1888
                    StartFlic(
1889
                        gPanel_flic[i].file_name,
1890
                        gPanel_flic[i].the_index,
1891
                        &gPanel_flic[i],
1892
                        gPanel_flic_data_length[i],
1893
                        (tS8*)gPanel_flic_data[i],
1894
                        gPanel_buffer[i],
1895
                        0,
1896
                        0,
1897
                        0);
1898
                }
1899
                gLast_panel_frame_time[i] = the_time;
1900
            }
1901
            if (pCopy_to_buffer) {
1902
                BrPixelmapRectangleCopy(
1903
                    gBack_screen,
1904
                    gPanel_flic_left[i],
1905
                    gPanel_flic_top[i],
1906
                    gPanel_buffer[i],
1907
                    0,
1908
                    0,
1909
                    gPanel_buffer[i]->width,
1910
                    gPanel_buffer[i]->height);
1911
            }
1912
        }
1913
    }
1914
    TurnFlicTransparencyOff();
1915
    LetFlicFuckWithPalettes();
1916
}
1917
 
1918
// IDA: void __usercall ChangePanelFlic(int pIndex@<EAX>, tU8 *pData@<EDX>, tU32 pData_length@<EBX>)
1919
void ChangePanelFlic(int pIndex, tU8* pData, tU32 pData_length) {
1920
    LOG_TRACE("(%d, %p, %d)", pIndex, pData, pData_length);
1921
 
1922
    EndFlic(&gPanel_flic[pIndex]);
1923
    gPanel_flic_data[pIndex] = pData;
1924
    gPanel_flic_data_length[pIndex] = pData_length;
1925
    BrPixelmapFill(gPanel_buffer[pIndex], 0);
1926
    StartFlic(
1927
        gPanel_flic[pIndex].file_name,
1928
        pIndex,
1929
        &gPanel_flic[pIndex],
1930
        gPanel_flic_data_length[pIndex],
1931
        (tS8*)gPanel_flic_data[pIndex],
1932
        gPanel_buffer[pIndex],
1933
        0,
1934
        0,
1935
        0);
1936
    gLast_panel_frame_time[pIndex] = 0;
1937
    ServicePanelFlics(0);
1938
}
1939
 
1940
// IDA: br_pixelmap* __usercall GetPanelPixelmap@<EAX>(int pIndex@<EAX>)
1941
br_pixelmap* GetPanelPixelmap(int pIndex) {
1942
    LOG_TRACE("(%d)", pIndex);
1943
 
1944
    return gPanel_buffer[pIndex];
1945
}
1946
 
1947
// IDA: void __cdecl LoadInterfaceStrings()
1948
void LoadInterfaceStrings(void) {
1949
    FILE* f; // Added by DethRace
1950
    char s[256];
1951
    char s2[256];
1952
    char* str;
1953
    char* comment;
1954
    char ch;
1955
    tPath_name the_path;
1956
    int i;
1957
    int j;
1958
    int len;
1959
 
1960
    gTranslation_count = 0;
1961
    PathCat(the_path, gApplication_path, "TRNSLATE.TXT");
1962
    f = fopen(the_path, "rt");
1963
    if (f == NULL) {
1964
        return;
1965
    }
1966
    while (!feof(f)) {
1967
        GetALineAndDontArgue(f, s);
1968
        gTranslation_count++;
1969
    }
1970
    rewind(f);
1971
    gTranslations = BrMemAllocate(gTranslation_count * sizeof(tTranslation_record), kMem_translations);
1972
    for (i = 0; i < gTranslation_count; i++) {
1973
        GetALineAndDontArgue(f, s);
1974
        str = strtok(s, "\t ,/");
1975
        strcpy(s2, str);
1976
        strtok(s2, ".");
1977
        strcat(s2, ".FLI");
1978
        gTranslations[i].flic_index = -1;
1979
        for (j = 0; j < COUNT_OF(gMain_flic_list); j++) {
1980
            if (strcmp(gMain_flic_list[j].file_name, s2) == 0) {
1981
                gTranslations[i].flic_index = j;
1982
                break;
1983
            }
1984
        }
1985
        if (gTranslations[i].flic_index < 0) {
1986
            FatalError(kFatalError_FindFlicUsedInTranslationFile_S, s2);
1987
        }
1988
        str[strlen(str)] = ',';
1989
        str = strtok(s, "\t ,/");
1990
        str = strtok(NULL, "\t ,/");
1991
        sscanf(str, "%d", &gTranslations[i].x);
1992
        str = strtok(NULL, "\t ,/");
1993
        sscanf(str, "%d", &gTranslations[i].y);
1994
        str = strtok(NULL, "\t ,/");
1995
        sscanf(str, "%d", &gTranslations[i].font_index);
1996
        str = strtok(NULL, "\t ,/");
1997
        sscanf(str, "%c", &ch);
1998
        switch (ch) {
1999
        case 'C':
2000
        case 'c':
2001
            gTranslations[i].justification = eJust_centre;
2002
            break;
2003
        case 'L':
2004
        case 'l':
2005
            gTranslations[i].justification = eJust_left;
2006
            break;
2007
        case 'R':
2008
        case 'r':
2009
            gTranslations[i].justification = eJust_right;
2010
            break;
2011
        }
2012
        str = strtok(NULL, "\t ,/");
2013
        sscanf(str, "%c", &ch);
2014
        gTranslations[i].global = ch == 'G' || ch == 'g';
2015
        gTranslations[i].every_frame = strlen(str) > 1 && (str[1] == 'E' || str[1] == 'e');
2016
        str += strlen(str) + 1;
2017
        comment = strstr(str, "//");
2018
        if (comment != NULL) {
2019
            *comment = '\0';
2020
        }
2021
        len = strlen(str);
2022
        for (j = len - 1; j >= 0 && (str[j] == ' ' || str[j] == '\t'); j--) {
2023
        }
2024
        str[j + 1] = '\0';
2025
        gTranslations[i].text = BrMemAllocate(strlen(str) + 1, kMem_translations_text);
2026
        strcpy(gTranslations[i].text, str);
2027
    }
11 pmbaty 2028
    LoadFont(kFont_BLUEHEAD);
2029
    LoadFont(kFont_ORANGHED);
2030
    LoadFont(kFont_GREENHED);
2031
    LoadFont(kFont_LITPLAQ);
2032
    LoadFont(kFont_BUTTOUT);
2033
    LoadFont(kFont_DRKPLAQ);
2034
    LoadFont(kFont_BUTTIN);
2035
    LoadFont(kFont_GRNLIT);
2036
    LoadFont(kFont_GRYLIT);
2037
    LoadFont(kFont_GRNDK);
2038
    LoadFont(kFont_GRYDK);
2039
    LoadFont(kFont_LITPLAQ1);
2040
    LoadFont(kFont_BUTTOUT1);
2041
    LoadFont(kFont_DRKPLAQ1);
2042
    LoadFont(kFont_BUTTIN1);
2043
    gTrans_fonts[0] = &gFonts[kFont_ORANGHED];
2044
    gTrans_fonts[1] = &gFonts[kFont_LITPLAQ];
2045
    gTrans_fonts[2] = &gFonts[kFont_BUTTOUT];
2046
    gTrans_fonts[3] = &gFonts[kFont_DRKPLAQ];
2047
    gTrans_fonts[4] = &gFonts[kFont_BUTTIN];
2048
    gTrans_fonts[5] = &gFonts[kFont_GRNLIT];
2049
    gTrans_fonts[6] = &gFonts[kFont_GRYLIT];
2050
    gTrans_fonts[7] = &gFonts[kFont_GRNDK];
2051
    gTrans_fonts[8] = &gFonts[kFont_GRYDK];
2052
    gTrans_fonts[9] = &gFonts[kFont_LITPLAQ1];
2053
    gTrans_fonts[10] = &gFonts[kFont_DRKPLAQ1];
2054
    gTrans_fonts[11] = &gFonts[kFont_BUTTOUT1];
2055
    gTrans_fonts[12] = &gFonts[kFont_BUTTIN1];
1 pmbaty 2056
 
2057
#ifdef DETHRACE_FIX_BUGS
2058
    fclose(f);
2059
#endif
2060
}
2061
 
2062
// IDA: void __cdecl FlushInterfaceFonts()
2063
void FlushInterfaceFonts(void) {
2064
    LOG_TRACE("()");
2065
 
2066
    DisposeFont(19);
2067
    DisposeFont(18);
2068
    DisposeFont(20);
2069
    DisposeFont(17);
2070
    DisposeFont(15);
2071
    DisposeFont(14);
2072
    DisposeFont(16);
2073
    DisposeFont(13);
2074
}
2075
 
2076
// IDA: void __cdecl SuspendPendingFlic()
2077
void SuspendPendingFlic(void) {
2078
    LOG_TRACE("()");
2079
 
2080
    gPending_pending_flic = gPending_flic;
2081
    gPending_flic = -1;
2082
}
2083
 
2084
// IDA: void __cdecl ResumePendingFlic()
2085
void ResumePendingFlic(void) {
2086
    LOG_TRACE("()");
2087
 
2088
    gPending_flic = gPending_pending_flic;
2089
}