Subversion Repositories Games.Carmageddon

Rev

Rev 11 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 pmbaty 1
#include "flicplay.h"
18 pmbaty 2
#include "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
 
18 pmbaty 739
    if (pX_offset != -1) {
740
        pFlic_info->x_offset = pX_offset;
741
    } else if (pDest_pixelmap != NULL) {
742
        pFlic_info->x_offset = (pDest_pixelmap->width - pFlic_info->width) / 2;
1 pmbaty 743
    } else {
18 pmbaty 744
        pFlic_info->x_offset = 0;
1 pmbaty 745
    }
18 pmbaty 746
    if (pY_offset != -1) {
747
        pFlic_info->y_offset = pY_offset;
748
    } else if (pDest_pixelmap != NULL) {
749
        pFlic_info->y_offset = (pDest_pixelmap->height - pFlic_info->height) / 2;
1 pmbaty 750
    } else {
18 pmbaty 751
        pFlic_info->y_offset = 0;
1 pmbaty 752
    }
753
 
754
    if (pFrame_rate != 0) {
755
        pFlic_info->frame_period = 1000 / pFrame_rate;
756
    } else {
757
        if (claimed_speed == 0) {
758
            FatalError(kFatalError_FlicFileNoFrameRate_S, gLast_flic_name);
759
        }
760
        if (pFlic_info->new_format) {
761
            pFlic_info->frame_period = claimed_speed;
762
        } else {
763
            pFlic_info->frame_period = 14 * claimed_speed;
764
        }
765
    }
766
    pFlic_info->the_index = pIndex;
767
    AssertFlicPixelmap(pFlic_info, pDest_pixelmap);
768
    return 0;
769
}
770
 
771
// IDA: void __cdecl FreeFlicPaletteAllocate()
772
void FreeFlicPaletteAllocate(void) {
773
    LOG_TRACE("()");
774
 
775
    if (gPalette_allocate_count == 0) {
776
        FatalError(kFatalError_FlicPaletteDisposeBeforeAllocation);
777
    }
778
    gPalette_allocate_count--;
779
    if (gPalette_allocate_count == 0) {
780
        BrMemFree(gPalette_pixels);
781
        BrPixelmapFree(gPalette);
782
    }
783
}
784
 
785
// IDA: int __usercall EndFlic@<EAX>(tFlic_descriptor_ptr pFlic_info@<EAX>)
786
int EndFlic(tFlic_descriptor_ptr pFlic_info) {
787
    LOG_TRACE("(%p)", pFlic_info);
788
 
789
    if (pFlic_info->f != NULL) {
790
        BrMemFree(pFlic_info->data_start);
791
        pFlic_info->data_start = NULL;
792
        fclose(pFlic_info->f);
793
        pFlic_info->f = NULL;
794
    }
795
    if (pFlic_info->data != NULL) {
796
        pFlic_info->data = NULL;
797
    }
798
    return 0;
799
}
800
 
801
// IDA: void __usercall DoColourMap(tFlic_descriptor_ptr pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
802
void DoColourMap(tFlic_descriptor_ptr pFlic_info, tU32 chunk_length) {
803
    int i;
804
    int j;
805
    int packet_count;
806
    int skip_count;
807
    int change_count;
808
    int current_colour = 0;
809
    tU8* palette_pixels;
810
    tU8 red;
811
    tU8 green;
812
    tU8 blue;
813
 
814
    palette_pixels = gPalette_pixels;
815
 
816
    packet_count = MemReadU16(&pFlic_info->data);
817
    for (i = 0; i < packet_count; i++) {
818
        skip_count = MemReadU8(&pFlic_info->data);
819
        change_count = MemReadU8(&pFlic_info->data);
820
        if (!change_count) {
821
            change_count = 256;
822
        }
823
        palette_pixels += skip_count * sizeof(br_int_32);
824
        current_colour += skip_count;
825
        for (j = 0; j < change_count; j++) {
826
            red = MemReadU8(&pFlic_info->data);
827
            blue = MemReadU8(&pFlic_info->data);
828
            green = MemReadU8(&pFlic_info->data);
829
            // argb
830
#if BR_ENDIAN_BIG
831
            palette_pixels[3] = green * 4;
832
            palette_pixels[2] = blue * 4;
833
            palette_pixels[1] = red * 4;
834
            palette_pixels[0] = 0;
835
#else
836
            palette_pixels[0] = green * 4;
837
            palette_pixels[1] = blue * 4;
838
            palette_pixels[2] = red * 4;
839
            palette_pixels[3] = 0;
840
#endif
841
            palette_pixels += 4;
842
        }
843
        if (!gPalette_fuck_prevention) {
844
            DRSetPaletteEntries(gPalette, current_colour, change_count);
845
        }
846
    }
847
}
848
 
849
// IDA: void __usercall DoDifferenceX(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
850
void DoDifferenceX(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
851
    int i;
852
    int j;
853
    int k;
854
    int first_line;
855
    int line_count;
856
    int number_of_packets;
857
    int skip_count;
858
    int size_count;
859
    tU8* pixel_ptr;
860
    tU8* line_pixel_ptr;
861
    tU8 the_byte;
862
    tU32 the_row_bytes;
863
    LOG_TRACE("(%p, %d)", pFlic_info, chunk_length);
864
 
865
    first_line = MemReadU16(&pFlic_info->data);
866
    line_count = MemReadU16(&pFlic_info->data);
867
    the_row_bytes = pFlic_info->the_pixelmap->row_bytes;
868
    line_pixel_ptr = pFlic_info->first_pixel + first_line * the_row_bytes;
869
    for (i = 0; i < line_count; i++) {
870
        pixel_ptr = line_pixel_ptr;
871
        number_of_packets = MemReadU8(&pFlic_info->data);
872
        for (j = 0; j < number_of_packets; j++) {
873
            skip_count = MemReadU8(&pFlic_info->data);
874
            size_count = MemReadS8(&pFlic_info->data);
875
            pixel_ptr += skip_count;
876
            if (size_count >= 0) {
877
                for (k = 0; k < size_count; k++) {
878
                    *pixel_ptr = *pFlic_info->data;
879
                    pFlic_info->data++;
880
                    pixel_ptr++;
881
                }
882
            } else {
883
                the_byte = *pFlic_info->data;
884
                pFlic_info->data++;
885
                for (k = 0; k < -size_count; k++) {
886
                    *pixel_ptr = the_byte;
887
                    pixel_ptr++;
888
                }
889
            }
890
        }
891
        line_pixel_ptr += the_row_bytes;
892
    }
893
}
894
 
895
// IDA: void __usercall DoDifferenceTrans(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
896
void DoDifferenceTrans(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
897
    int i;
898
    int j;
899
    int k;
900
    int first_line;
901
    int line_count;
902
    int number_of_packets;
903
    int skip_count;
904
    int size_count;
905
    tU8* pixel_ptr;
906
    tU8* line_pixel_ptr;
907
    tU8 the_byte;
908
    tU32 the_row_bytes;
909
    LOG_TRACE("(%p, %d)", pFlic_info, chunk_length);
910
 
911
    first_line = MemReadU16(&pFlic_info->data);
912
    line_count = MemReadU16(&pFlic_info->data);
913
    the_row_bytes = pFlic_info->the_pixelmap->row_bytes;
914
    line_pixel_ptr = pFlic_info->first_pixel + first_line * the_row_bytes;
915
    for (i = 0; i < line_count; i++) {
916
        pixel_ptr = line_pixel_ptr;
917
        number_of_packets = MemReadU8(&pFlic_info->data);
918
        for (j = 0; j < number_of_packets; j++) {
919
            skip_count = MemReadU8(&pFlic_info->data);
920
            size_count = MemReadS8(&pFlic_info->data);
921
            pixel_ptr += skip_count;
922
            if (size_count >= 0) {
923
                for (k = 0; k < size_count; k++) {
924
                    the_byte = *pFlic_info->data;
925
                    pFlic_info->data++;
926
                    if (the_byte != '\0') {
927
                        *pixel_ptr = the_byte;
928
                    }
929
                    pixel_ptr++;
930
                }
931
            } else {
932
                the_byte = *pFlic_info->data;
933
                pFlic_info->data++;
934
                if (the_byte == '\0') {
935
                    pixel_ptr += size_count;
936
                } else {
937
                    for (k = 0; k < -size_count; k++) {
938
                        *pixel_ptr = the_byte;
939
                        pixel_ptr++;
940
                    }
941
                }
942
            }
943
        }
944
        line_pixel_ptr += the_row_bytes;
945
    }
946
}
947
 
948
// IDA: void __usercall DoColour256(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
949
void DoColour256(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
950
    int i;
951
    int j;
952
    int packet_count;
953
    int skip_count;
954
    int change_count;
955
    int current_colour;
956
    tU8* palette_pixels;
957
    tU8 red;
958
    tU8 green;
959
    tU8 blue;
960
 
961
    current_colour = 0;
962
    palette_pixels = gPalette_pixels;
963
 
964
    packet_count = MemReadU16(&pFlic_info->data);
965
    for (i = 0; i < packet_count; i++) {
966
        skip_count = MemReadU8(&pFlic_info->data);
967
        change_count = MemReadU8(&pFlic_info->data);
968
        if (!change_count) {
969
            change_count = 256;
970
        }
971
        palette_pixels += skip_count * sizeof(br_int_32);
972
        current_colour += skip_count;
973
        for (j = 0; j < change_count; j++) {
974
            red = MemReadU8(&pFlic_info->data);
975
            blue = MemReadU8(&pFlic_info->data);
976
            green = MemReadU8(&pFlic_info->data);
977
            // argb
978
#if BR_ENDIAN_BIG
979
            palette_pixels[3] = green;
980
            palette_pixels[2] = blue;
981
            palette_pixels[1] = red;
982
            palette_pixels[0] = 0;
983
#else
984
            palette_pixels[0] = green;
985
            palette_pixels[1] = blue;
986
            palette_pixels[2] = red;
987
            palette_pixels[3] = 0;
988
#endif
989
            palette_pixels += 4;
990
            // LOG_DEBUG("color %d", current_colour);
991
        }
992
        if (!gPalette_fuck_prevention) {
993
            DRSetPaletteEntries(gPalette, current_colour, change_count);
994
        }
995
    }
996
}
997
 
998
// IDA: void __usercall DoDeltaTrans(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
999
void DoDeltaTrans(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
1000
    int i;
1001
    int j;
1002
    int k;
1003
    int line_count;
1004
    int number_of_packets;
1005
    int skip_count;
1006
    int size_count;
1007
    tU8* pixel_ptr;
1008
    tU8 the_byte;
1009
    tU8 the_byte2;
1010
    tU32 the_row_bytes;
1011
    tU16* line_pixel_ptr;
1012
    tU16 the_word;
1013
    LOG_TRACE8("(%p, %d)", pFlic_info, chunk_length);
1014
 
1015
    line_count = MemReadU16(&pFlic_info->data);
1016
    the_row_bytes = pFlic_info->the_pixelmap->row_bytes;
1017
    pixel_ptr = pFlic_info->first_pixel;
1018
 
1019
    for (i = 0; i < line_count;) {
1020
        number_of_packets = MemReadS16(&pFlic_info->data);
1021
        line_pixel_ptr = (tU16*)pixel_ptr;
1022
 
1023
        if (number_of_packets < 0) {
1024
            pixel_ptr = pixel_ptr + the_row_bytes * -number_of_packets;
1025
        } else {
1026
            for (j = 0; j < number_of_packets; j++) {
1027
                skip_count = MemReadU8(&pFlic_info->data);
1028
                size_count = MemReadS8(&pFlic_info->data);
1029
                line_pixel_ptr += skip_count / 2;
1030
                if (size_count < 0) {
1031
                    the_byte = *pFlic_info->data++;
1032
                    the_byte2 = *pFlic_info->data++;
1033
 
1034
                    if (the_byte && the_byte2) {
1035
                        the_word = *((tU16*)pFlic_info->data - 1);
1036
                        for (k = 0; k < -size_count; k++) {
1037
                            mem_write_u16(line_pixel_ptr, the_word);
1038
                            line_pixel_ptr++;
1039
                        }
1040
                    } else {
1041
                        for (k = 0; k < -size_count; k++) {
1042
                            if (the_byte) {
1043
                                *(tU8*)line_pixel_ptr = the_byte;
1044
                            }
1045
                            line_pixel_ptr = (tU16*)((tU8*)line_pixel_ptr + 1);
1046
                            if (the_byte2) {
1047
                                *(tU8*)line_pixel_ptr = the_byte2;
1048
                            }
1049
                            line_pixel_ptr = (tU16*)((tU8*)line_pixel_ptr + 1);
1050
                        }
1051
                    }
1052
                } else {
1053
                    for (k = 0; k < size_count; k++) {
1054
                        the_word = *(tU16*)pFlic_info->data;
1055
                        pFlic_info->data += 2;
1056
                        if (the_word) {
1057
                            mem_write_u16(line_pixel_ptr, the_word);
1058
                        }
1059
                        line_pixel_ptr++;
1060
                    }
1061
                }
1062
            }
1063
            pixel_ptr = pixel_ptr + the_row_bytes;
1064
            i++;
1065
        }
1066
    }
1067
}
1068
 
1069
// IDA: void __usercall DoDeltaX(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
1070
void DoDeltaX(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
1071
    int i;
1072
    int j;
1073
    int k;
1074
    int line_count;
1075
    int number_of_packets;
1076
    int skip_count;
1077
    int size_count;
1078
    tU8* pixel_ptr;
1079
    tU32 the_row_bytes;
1080
    tU16* line_pixel_ptr;
1081
    tU16 the_word;
1082
    LOG_TRACE("(%p, %d)", pFlic_info, chunk_length);
1083
 
1084
    line_count = MemReadU16(&pFlic_info->data);
1085
    the_row_bytes = pFlic_info->the_pixelmap->row_bytes;
1086
    pixel_ptr = pFlic_info->first_pixel;
1087
 
1088
    for (i = 0; i < line_count;) {
1089
        number_of_packets = MemReadS16(&pFlic_info->data);
1090
        line_pixel_ptr = (tU16*)pixel_ptr;
1091
 
1092
        if (number_of_packets < 0) {
1093
            pixel_ptr = pixel_ptr + the_row_bytes * -number_of_packets;
1094
        } else {
1095
            for (j = 0; j < number_of_packets; j++) {
1096
                skip_count = MemReadU8(&pFlic_info->data);
1097
                size_count = MemReadS8(&pFlic_info->data);
1098
                line_pixel_ptr += skip_count / 2;
1099
                if (size_count < 0) {
1100
                    the_word = *(tU16*)pFlic_info->data;
1101
                    pFlic_info->data += 2;
1102
                    for (k = 0; k < -size_count; k++) {
1103
                        *line_pixel_ptr = the_word;
1104
                        line_pixel_ptr++;
1105
                    }
1106
                } else {
1107
                    for (k = 0; k < size_count; k++) {
1108
                        the_word = *(tU16*)pFlic_info->data;
1109
                        pFlic_info->data += 2;
1110
                        *line_pixel_ptr = the_word;
1111
                        line_pixel_ptr++;
1112
                    }
1113
                }
1114
            }
1115
            pixel_ptr = pixel_ptr + the_row_bytes;
1116
            i++;
1117
        }
1118
    }
1119
}
1120
 
1121
// IDA: void __usercall DoBlack(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
1122
void DoBlack(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
1123
    int i;
1124
    int j;
1125
    int the_width;
1126
    tU8* pixel_ptr;
1127
    tU32 the_row_bytes;
1128
    tU32* line_pixel_ptr;
1129
    LOG_TRACE("(%p, %d)", pFlic_info, chunk_length);
1130
 
1131
    pixel_ptr = pFlic_info->first_pixel;
1132
    the_row_bytes = pFlic_info->the_pixelmap->row_bytes;
1133
    the_width = pFlic_info->width;
1134
    for (i = 0; i < pFlic_info->height; i++) {
1135
        line_pixel_ptr = (tU32*)pixel_ptr;
1136
        for (j = 0; j < the_width / (int) sizeof(tU32); j++) { // Pierre-Marie Baty -- added type cast
1137
            *line_pixel_ptr = 0;
1138
            line_pixel_ptr++;
1139
        }
1140
        pixel_ptr += the_row_bytes;
1141
    }
1142
}
1143
 
1144
// IDA: void __usercall DoRunLengthX(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
1145
void DoRunLengthX(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
1146
    int i;
1147
    int j;
1148
    int k;
1149
    int number_of_packets;
1150
    int size_count;
1151
    tU8* pixel_ptr;
1152
    tU8* line_pixel_ptr;
1153
    tU8 the_byte;
1154
    tU32 the_row_bytes;
1155
    LOG_TRACE("(%p, %d)", pFlic_info, chunk_length);
1156
 
1157
    the_row_bytes = pFlic_info->the_pixelmap->row_bytes;
1158
    pixel_ptr = pFlic_info->first_pixel;
1159
 
1160
    for (i = 0; i < pFlic_info->height; i++) {
1161
        line_pixel_ptr = pixel_ptr;
1162
        number_of_packets = MemReadU8(&pFlic_info->data);
1163
        for (j = 0; j < number_of_packets; j++) {
1164
            size_count = MemReadS8(&pFlic_info->data);
1165
            if (size_count >= 0) {
1166
                the_byte = MemReadU8(&pFlic_info->data);
1167
                for (k = 0; k < size_count; k++) {
1168
                    *line_pixel_ptr = the_byte;
1169
                    line_pixel_ptr++;
1170
                }
1171
            } else {
1172
                for (k = 0; k < -size_count; k++) {
1173
                    the_byte = MemReadU8(&pFlic_info->data);
1174
                    *line_pixel_ptr = the_byte;
1175
                    line_pixel_ptr++;
1176
                }
1177
            }
1178
        }
1179
        pixel_ptr += the_row_bytes;
1180
    }
1181
}
1182
 
1183
// IDA: void __usercall DoRunLengthTrans(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
1184
void DoRunLengthTrans(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
1185
    int i;
1186
    int j;
1187
    int k;
1188
    int number_of_packets;
1189
    int size_count;
1190
    tU8* pixel_ptr;
1191
    tU8* line_pixel_ptr;
1192
    tU8 the_byte;
1193
    tU32 the_row_bytes;
1194
    LOG_TRACE8("(%p, %d)", pFlic_info, chunk_length);
1195
 
1196
    the_row_bytes = pFlic_info->the_pixelmap->row_bytes;
1197
    pixel_ptr = pFlic_info->first_pixel;
1198
 
1199
    for (i = 0; i < pFlic_info->height; i++) {
1200
        line_pixel_ptr = pixel_ptr;
1201
        number_of_packets = MemReadU8(&pFlic_info->data);
1202
        for (j = 0; j < number_of_packets; j++) {
1203
            size_count = MemReadS8(&pFlic_info->data);
1204
            if (size_count >= 0) {
1205
                the_byte = MemReadU8(&pFlic_info->data);
1206
 
1207
                for (k = 0; k < size_count; k++) {
1208
                    if (the_byte) {
1209
                        *line_pixel_ptr = the_byte;
1210
                    }
1211
                    line_pixel_ptr++;
1212
                }
1213
            } else {
1214
                for (k = 0; k < -size_count; k++) {
1215
                    the_byte = MemReadU8(&pFlic_info->data);
1216
                    if (the_byte) {
1217
                        *line_pixel_ptr = the_byte;
1218
                    }
1219
                    line_pixel_ptr++;
1220
                }
1221
            }
1222
        }
1223
        pixel_ptr += the_row_bytes;
1224
    }
1225
}
1226
 
1227
// IDA: void __usercall DoUncompressed(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
1228
void DoUncompressed(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
1229
    int i;
1230
    int j;
1231
    int the_width;
1232
    tU8* pixel_ptr;
1233
    tU32 the_row_bytes;
1234
    tU32* line_pixel_ptr;
1235
    LOG_TRACE("(%p, %d)", pFlic_info, chunk_length);
1236
 
1237
    pixel_ptr = pFlic_info->first_pixel;
1238
    the_row_bytes = pFlic_info->the_pixelmap->row_bytes;
1239
    the_width = pFlic_info->width;
1240
    for (i = 0; i < pFlic_info->height; i++) {
1241
        line_pixel_ptr = (tU32*)pixel_ptr;
1242
        for (j = 0; j < the_width / 4; j++) {
1243
            *line_pixel_ptr = MemReadU32(&pFlic_info->data);
1244
            line_pixel_ptr++;
1245
        }
1246
        pixel_ptr += the_row_bytes;
1247
    }
1248
}
1249
 
1250
// IDA: void __usercall DoUncompressedTrans(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
1251
void DoUncompressedTrans(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
1252
    int i;
1253
    int j;
1254
    int the_width;
1255
    tU8* pixel_ptr;
1256
    tU8* line_pixel_ptr;
1257
    tU8 the_byte;
1258
    tU32 the_row_bytes;
1259
    LOG_TRACE("(%p, %d)", pFlic_info, chunk_length);
1260
 
1261
    pixel_ptr = pFlic_info->first_pixel;
1262
    the_row_bytes = pFlic_info->the_pixelmap->row_bytes;
1263
    the_width = pFlic_info->width;
1264
    for (i = 0; i < pFlic_info->height; i++) {
1265
        line_pixel_ptr = pixel_ptr;
1266
        for (j = 0; j < the_width; j++) {
1267
#if defined(DETHRACE_FIX_BUGS)
1268
            the_byte = MemReadU8(&pFlic_info->data);
1269
#else
1270
            the_byte = MemReadU32(&pFlic_info->data);
1271
#endif
1272
            if (the_byte != '\0') {
1273
                *line_pixel_ptr = the_byte;
1274
            }
1275
            line_pixel_ptr++;
1276
        }
1277
        pixel_ptr += the_row_bytes;
1278
    }
1279
}
1280
 
1281
// IDA: void __usercall DoMini(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
1282
void DoMini(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
1283
    LOG_TRACE("(%p, %d)", pFlic_info, chunk_length);
1284
 
1285
    MemSkipBytes(&pFlic_info->data, chunk_length - 6);
1286
}
1287
 
1288
// IDA: void __usercall DrawTranslations(tFlic_descriptor *pFlic_info@<EAX>, int pLast_frame@<EDX>)
1289
void DrawTranslations(tFlic_descriptor* pFlic_info, int pLast_frame) {
1290
    tTranslation_record* trans;
1291
    int i;
1292
    int x;
1293
    int width;
1294
    int right_edge;
1295
    LOG_TRACE("(%p, %d)", pFlic_info, pLast_frame);
1296
 
1297
    for (i = 0; i < gTranslation_count; i++) {
1298
        trans = &gTranslations[i];
1299
        if (trans->flic_index == pFlic_info->the_index && (trans->every_frame || pLast_frame)) {
1300
            width = DRTextWidth(gTrans_fonts[trans->font_index], trans->text);
1301
            switch (trans->justification) {
1302
            case eJust_left:
1303
                x = trans->x;
1304
                right_edge = x + width;
1305
                break;
1306
            case eJust_right:
1307
                x = trans->x - width;
1308
                right_edge = x;
1309
                break;
1310
            case eJust_centre:
1311
                x = trans->x - width / 2;
1312
                right_edge = x + width / 2;
1313
                break;
1314
            default:
1315
                TELL_ME_IF_WE_PASS_THIS_WAY();
1316
            }
1317
            TransDRPixelmapText(
1318
                pFlic_info->the_pixelmap,
1319
                x + (trans->global ? 0 : pFlic_info->x_offset),
1320
                trans->y + (trans->global ? 0 : pFlic_info->y_offset),
1321
                gTrans_fonts[trans->font_index],
1322
                trans->text,
1323
                right_edge);
1324
        }
1325
    }
1326
}
1327
 
1328
// IDA: int __usercall PlayNextFlicFrame2@<EAX>(tFlic_descriptor *pFlic_info@<EAX>, int pPanel_flic@<EDX>)
1329
int PlayNextFlicFrame2(tFlic_descriptor* pFlic_info, int pPanel_flic) {
1330
    tU32 frame_length;
1331
    tU32 chunk_length;
1332
    int chunk_count;
1333
    int chunk_counter;
1334
    int chunk_type;
1335
    int magic_bytes;
1336
    //int last_frame; // Pierre-Marie Baty -- unused variable
1337
    int data_knocked_off;
1338
    int read_amount;
1339
 
1340
    // 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);
1341
    PossibleService();
1342
    frame_length = MemReadU32(&pFlic_info->data);
1343
    magic_bytes = MemReadU16(&pFlic_info->data);
1344
    chunk_count = MemReadU16(&pFlic_info->data);
1345
 
1346
    MemSkipBytes(&pFlic_info->data, 8);
1347
    if (magic_bytes == 0xf1fa) {
1348
        for (chunk_counter = 0; chunk_counter < chunk_count; chunk_counter++) {
1349
            chunk_length = MemReadU32(&pFlic_info->data);
1350
            chunk_type = MemReadU16(&pFlic_info->data);
1351
            switch (chunk_type) {
1352
            case 4:
1353
                DoColour256(pFlic_info, chunk_length);
1354
                break;
1355
            case 7:
1356
                if (gTransparency_on) {
1357
                    DoDeltaTrans(pFlic_info, chunk_length);
1358
                } else {
1359
                    DoDeltaX(pFlic_info, chunk_length);
1360
                }
1361
                break;
1362
            case 11:
1363
                DoColourMap(pFlic_info, chunk_length);
1364
                break;
1365
            case 12:
1366
                if (gTransparency_on) {
1367
                    DoDifferenceTrans(pFlic_info, chunk_length);
1368
                } else {
1369
                    DoDifferenceX(pFlic_info, chunk_length);
1370
                }
1371
                break;
1372
            case 13:
1373
                DoBlack(pFlic_info, chunk_length);
1374
                break;
1375
            case 15:
1376
                if (gTransparency_on) {
1377
                    DoRunLengthTrans(pFlic_info, chunk_length);
1378
                } else {
1379
                    DoRunLengthX(pFlic_info, chunk_length);
1380
                }
1381
                break;
1382
            case 16:
1383
                if (gTransparency_on) {
1384
                    DoUncompressedTrans(pFlic_info, chunk_length);
1385
                } else {
1386
                    DoUncompressed(pFlic_info, chunk_length);
1387
                }
1388
                break;
1389
            case 18:
1390
                DoMini(pFlic_info, chunk_length);
1391
                break;
1392
            default:
1393
                LOG_WARN("unrecognized chunk type");
1394
                MemSkipBytes(&pFlic_info->data, chunk_length - 6);
1395
                break;
1396
            }
1397
            // Align on even byte
1398
            pFlic_info->data = (char*)((uintptr_t)(pFlic_info->data + 1) & (~(uintptr_t)1));
1399
        }
1400
    } else {
1401
        LOG_WARN("not frame header");
1402
        MemSkipBytes(&pFlic_info->data, frame_length - 16);
1403
        pFlic_info->frames_left++;
1404
        pFlic_info->current_frame--;
1405
    }
1406
    pFlic_info->current_frame++;
1407
    pFlic_info->frames_left--;
1408
    if (gTrans_enabled && gTranslation_count != 0 && !pPanel_flic) {
1409
        DrawTranslations(pFlic_info, pFlic_info->frames_left == 0);
1410
    }
1411
    if (pFlic_info->f != NULL && pFlic_info->bytes_still_to_be_read) {
1412
        data_knocked_off = pFlic_info->data - pFlic_info->data_start;
1413
        memmove(pFlic_info->data_start, pFlic_info->data, pFlic_info->bytes_in_buffer - data_knocked_off);
1414
        pFlic_info->data = pFlic_info->data_start;
1415
        pFlic_info->bytes_in_buffer -= data_knocked_off;
1416
 
1417
        if (pFlic_info->bytes_still_to_be_read > data_knocked_off) {
1418
            read_amount = data_knocked_off;
1419
        } else {
1420
            read_amount = pFlic_info->bytes_still_to_be_read;
1421
        }
1422
        if (read_amount != 0) {
1423
            fread(&pFlic_info->data_start[pFlic_info->bytes_in_buffer], 1, read_amount, pFlic_info->f);
1424
        }
1425
        pFlic_info->bytes_in_buffer += read_amount;
1426
        pFlic_info->bytes_still_to_be_read -= read_amount;
1427
    }
1428
    return pFlic_info->frames_left == 0;
1429
}
1430
 
1431
// IDA: int __usercall PlayNextFlicFrame@<EAX>(tFlic_descriptor *pFlic_info@<EAX>)
1432
int PlayNextFlicFrame(tFlic_descriptor* pFlic_info) {
1433
    LOG_TRACE("(%p)", pFlic_info);
1434
 
1435
    return PlayNextFlicFrame2(pFlic_info, 0);
1436
}
1437
 
1438
// 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)
1439
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) {
1440
    int finished_playing;
1441
    tFlic_descriptor the_flic;
1442
    tU32 last_frame;
1443
    tU32 new_time;
1444
    tU32 frame_period;
1445
    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);
1446
 
1447
    finished_playing = 0;
1448
    the_flic.data_start = NULL;
1449
    if (StartFlic(gMain_flic_list[pIndex].file_name, pIndex, &the_flic, pSize, pData_ptr, pDest_pixelmap, pX_offset, pY_offset, pFrame_rate)) {
1450
        LOG_WARN("startflic returned error");
1451
        return -1;
1452
    }
1453
 
1454
    last_frame = 0;
1455
    while ((!pInterruptable || !AnyKeyDown()) && !finished_playing) {
1456
        new_time = PDGetTotalTime();
1457
        frame_period = new_time - last_frame;
1458
 
1459
        if (gSound_time != 0 && new_time >= gSound_time) {
1460
            DRS3StartSound(gEffects_outlet, gSound_ID);
1461
            gSound_time = 0;
1462
        }
1463
        if (frame_period >= the_flic.frame_period) {
1464
            last_frame = new_time;
1465
            finished_playing = PlayNextFlicFrame(&the_flic);
1466
            DoPerFrame();
1467
            if (!gDark_mode) {
1468
                EnsurePaletteUp();
1469
            }
1470
            ServiceGame();
1471
        }
1472
    }
1473
    ServiceGame();
1474
    EndFlic(&the_flic);
1475
    return 0;
1476
}
1477
 
1478
// IDA: void __cdecl SwapScreen()
1479
void SwapScreen(void) {
1480
    PDScreenBufferSwap(0);
1481
}
1482
 
1483
// IDA: void __usercall ShowFlic(int pIndex@<EAX>)
1484
void ShowFlic(int pIndex) {
1485
    do {
1486
        PlayFlic(
1487
            pIndex,
1488
            gMain_flic_list[pIndex].the_size,
1489
            gMain_flic_list[pIndex].data_ptr,
1490
            gBack_screen,
1491
            gMain_flic_list[pIndex].x_offset,
1492
            gMain_flic_list[pIndex].y_offset,
1493
            SwapScreen,
1494
            gMain_flic_list[pIndex].interruptable,
1495
            gMain_flic_list[pIndex].frame_rate);
1496
    } while (gMain_flic_list[pIndex].repeat && !AnyKeyDown());
1497
    gLast_flic_name[0] = '\0'; // byte_10344C;
1498
}
1499
 
1500
// IDA: void __cdecl InitFlics()
1501
void InitFlics(void) {
1502
    int i;
1503
    LOG_TRACE("()");
1504
 
1505
    for (i = 0; i < COUNT_OF(gMain_flic_list); i++) {
1506
        gMain_flic_list[i].data_ptr = NULL;
1507
    }
1508
}
1509
 
1510
// IDA: int __usercall LoadFlic@<EAX>(int pIndex@<EAX>)
1511
int LoadFlic(int pIndex) {
1512
    tPath_name the_path;
1513
    FILE* f;
1514
    //char* the_buffer; // Pierre-Marie Baty -- unused variable
1515
    LOG_TRACE("(%d)", pIndex);
1516
 
1517
    if (pIndex < 0) {
1518
        return 0;
1519
    }
1520
    if (gMain_flic_list[pIndex].data_ptr != NULL) {
1521
        MAMSLock((void**)&gMain_flic_list[pIndex].data_ptr);
1522
        return 1;
1523
    }
1524
    if (gPlay_from_disk) {
1525
        gMain_flic_list[pIndex].data_ptr = NULL;
1526
        return 1;
1527
    }
1528
    PossibleService();
1529
    PathCat(the_path, gApplication_path, "ANIM");
1530
    PathCat(the_path, the_path, gMain_flic_list[pIndex].file_name);
1531
    f = DRfopen(the_path, "rb");
1532
 
1533
    if (f == NULL) {
1534
        FatalError(kFatalError_LoadFlicFile_S, gMain_flic_list[pIndex].file_name);
1535
    }
1536
 
1537
    gMain_flic_list[pIndex].the_size = GetFileLength(f);
1538
    gMain_flic_list[pIndex].data_ptr = BrMemAllocate(gMain_flic_list[pIndex].the_size, 0x90u);
1539
 
1540
    if (gMain_flic_list[pIndex].data_ptr == NULL) {
1541
        if (AllocationErrorsAreFatal()) {
1542
            FatalError(kFatalError_AllocateFlicFile_S, gMain_flic_list[pIndex].file_name);
1543
        }
1544
#ifdef DETHRACE_FIX_BUGS
1545
        fclose(f);
1546
#endif
1547
        return 0;
1548
    }
1549
 
1550
    fread(gMain_flic_list[pIndex].data_ptr, 1, gMain_flic_list[pIndex].the_size, f);
1551
    strcpy(gLast_flic_name, gMain_flic_list[pIndex].file_name);
1552
    fclose(f);
1553
    return 1;
1554
}
1555
 
1556
// IDA: void __usercall UnlockFlic(int pIndex@<EAX>)
1557
void UnlockFlic(int pIndex) {
1558
    if (pIndex >= 0) {
1559
        if (gMain_flic_list[pIndex].data_ptr != NULL) {
1560
            MAMSUnlock((void**)&gMain_flic_list[pIndex].data_ptr);
1561
        }
1562
    }
1563
}
1564
 
1565
// IDA: int __usercall LoadFlicData@<EAX>(char *pName@<EAX>, tU8 **pData@<EDX>, tU32 *pData_length@<EBX>)
1566
int LoadFlicData(char* pName, tU8** pData, tU32* pData_length) {
1567
    FILE* f;
1568
    tPath_name the_path;
1569
    LOG_TRACE("(\"%s\", %p, %p)", pName, pData, pData_length);
1570
 
1571
    if (*pData != NULL) {
1572
        MAMSLock((void**)pData);
1573
        return 1;
1574
    }
1575
    if (gPlay_from_disk) {
1576
        return 1;
1577
    }
1578
    PossibleService();
1579
    PathCat(the_path, gApplication_path, "ANIM");
1580
    PathCat(the_path, the_path, pName);
1581
    f = DRfopen(the_path, "rb");
1582
    if (f == NULL) {
1583
        return 0;
1584
    }
1585
    *pData_length = GetFileLength(f);
1586
    *pData = BrMemAllocate(*pData_length, kMem_flic_data_2);
1587
    if (*pData == NULL) {
1588
        fclose(f);
1589
        return 0;
1590
    }
1591
    fread(*pData, 1, *pData_length, f);
1592
    fclose(f);
1593
    return 1;
1594
}
1595
 
1596
// IDA: void __usercall FreeFlic(int pIndex@<EAX>)
1597
void FreeFlic(int pIndex) {
1598
    LOG_TRACE("(%d)", pIndex);
1599
 
1600
    PossibleService();
1601
    if (gMain_flic_list[pIndex].data_ptr != NULL) {
1602
        BrMemFree(gMain_flic_list[pIndex].data_ptr);
1603
        gMain_flic_list[pIndex].data_ptr = NULL;
1604
    }
1605
}
1606
 
1607
// IDA: void __usercall ForceRunFlic(int pIndex@<EAX>)
1608
void ForceRunFlic(int pIndex) {
1609
    LOG_TRACE("(%d)", pIndex);
1610
 
1611
    LoadFlic(pIndex);
1612
    ShowFlic(pIndex);
1613
    UnlockFlic(pIndex);
1614
}
1615
 
1616
// IDA: void __usercall RunFlicAt(int pIndex@<EAX>, int pX@<EDX>, int pY@<EBX>)
1617
void RunFlicAt(int pIndex, int pX, int pY) {
1618
    LOG_TRACE("(%d, %d, %d)", pIndex, pX, pY);
1619
 
1620
    LoadFlic(pIndex);
1621
    PlayFlic(
1622
        pIndex,
1623
        gMain_flic_list[pIndex].the_size,
1624
        gMain_flic_list[pIndex].data_ptr,
1625
        gBack_screen,
1626
        pX,
1627
        pY,
1628
        SwapScreen,
1629
        0,
1630
        0);
1631
    UnlockFlic(pIndex);
1632
}
1633
 
1634
// IDA: void __usercall RunFlic(int pIndex@<EAX>)
1635
void RunFlic(int pIndex) {
1636
    LOG_TRACE("(%d)", pIndex);
1637
 
1638
    if (gPending_flic >= 0) {
1639
        ForceRunFlic(gPending_flic);
1640
        gPending_flic = -1;
1641
    }
1642
    if (LoadFlic(pIndex)) {
1643
        if (gMain_flic_list[pIndex].queued) {
1644
            gPending_flic = pIndex;
1645
        } else {
1646
            ShowFlic(pIndex);
1647
            UnlockFlic(pIndex);
1648
        }
1649
    }
1650
}
1651
 
1652
// IDA: void __usercall PreloadBunchOfFlics(int pBunch_index@<EAX>)
1653
void PreloadBunchOfFlics(int pBunch_index) {
1654
    int i;
1655
    LOG_TRACE("(%d)", pBunch_index);
1656
 
1657
    for (i = 0; i < gFlic_bunch[pBunch_index].count; i++) {
1658
        LoadFlic(gFlic_bunch[pBunch_index].indexes[i]);
1659
    }
1660
}
1661
 
1662
// IDA: void __usercall UnlockBunchOfFlics(int pBunch_index@<EAX>)
1663
void UnlockBunchOfFlics(int pBunch_index) {
1664
    int i;
1665
    LOG_TRACE("(%d)", pBunch_index);
1666
 
1667
    for (i = 0; i < gFlic_bunch[pBunch_index].count; i++) {
1668
        UnlockFlic(gFlic_bunch[pBunch_index].indexes[i]);
1669
    }
1670
}
1671
 
1672
// IDA: void __usercall FlushAllFlics(int pBunch_index@<EAX>)
1673
void FlushAllFlics(int pBunch_index) {
1674
    int i;
1675
    LOG_TRACE("(%d)", pBunch_index);
1676
 
1677
    for (i = 0; i < COUNT_OF(gFlic_bunch); i++) {
1678
        FreeFlic(i);
1679
    }
1680
}
1681
 
1682
// IDA: void __cdecl InitFlicQueue()
1683
void InitFlicQueue(void) {
1684
    gFirst_flic = NULL;
1685
}
1686
 
1687
// IDA: int __cdecl FlicQueueFinished()
1688
int FlicQueueFinished(void) {
1689
    tFlic_descriptor* the_flic;
1690
    LOG_TRACE("()");
1691
 
1692
    the_flic = gFirst_flic;
1693
    while (the_flic != NULL) {
1694
        if (the_flic->must_finish) {
1695
            return 0;
1696
        }
1697
        the_flic = the_flic->next;
1698
    }
1699
    return 1;
1700
}
1701
 
1702
// IDA: void __usercall ProcessFlicQueue(tU32 pInterval@<EAX>)
1703
void ProcessFlicQueue(tU32 pInterval) {
1704
    tFlic_descriptor* the_flic;
1705
    tFlic_descriptor* last_flic;
1706
    tFlic_descriptor* doomed_flic;
1707
    tU32 new_time;
1708
    int finished_playing;
1709
    LOG_TRACE8("(%d)", pInterval);
1710
 
1711
    DontLetFlicFuckWithPalettes();
1712
    TurnFlicTransparencyOn();
1713
    the_flic = gFirst_flic;
1714
    last_flic = NULL;
1715
    new_time = PDGetTotalTime();
1716
    while (the_flic != NULL) {
1717
        if (new_time - the_flic->last_frame < the_flic->frame_period) {
1718
            finished_playing = 0;
1719
        } else {
1720
            the_flic->last_frame = new_time;
1721
            finished_playing = PlayNextFlicFrame(the_flic);
1722
        }
1723
        if (finished_playing) {
1724
            EndFlic(the_flic);
1725
            if (last_flic != NULL) {
1726
                last_flic->next = the_flic->next;
1727
            } else {
1728
                gFirst_flic = the_flic->next;
1729
            }
1730
            doomed_flic = the_flic;
1731
            the_flic = the_flic->next;
1732
            BrMemFree(doomed_flic);
1733
        } else {
1734
            last_flic = the_flic;
1735
            the_flic = the_flic->next;
1736
        }
1737
    }
1738
    TurnFlicTransparencyOff();
1739
    LetFlicFuckWithPalettes();
1740
}
1741
 
1742
// IDA: void __cdecl FlushFlicQueue()
1743
void FlushFlicQueue(void) {
1744
    tFlic_descriptor* the_flic;
1745
    tFlic_descriptor* old_flic;
1746
    LOG_TRACE("()");
1747
 
1748
    // Jeff: loop through pending flics until we reach the end or we find one that is `must_finish`.
1749
    // If `must_finish`, we process the queue then check again.
1750
    // If there are no `must_finish` in the list, immediately end any remaining flics
1751
 
1752
    while (!FlicQueueFinished()) {
1753
        RemoveTransientBitmaps(1);
1754
        ProcessFlicQueue(gFrame_period);
1755
        DoMouseCursor();
1756
        PDScreenBufferSwap(0);
1757
    }
1758
    the_flic = gFirst_flic;
1759
    while (the_flic != NULL) {
1760
        EndFlic(the_flic);
1761
        old_flic = the_flic;
1762
        the_flic = the_flic->next;
1763
        BrMemFree(old_flic);
1764
    }
1765
    gFirst_flic = NULL;
1766
}
1767
 
1768
// IDA: void __usercall AddToFlicQueue(int pIndex@<EAX>, int pX@<EDX>, int pY@<EBX>, int pMust_finish@<ECX>)
1769
void AddToFlicQueue(int pIndex, int pX, int pY, int pMust_finish) {
1770
    tFlic_descriptor* the_flic = NULL;
1771
    tFlic_descriptor* new_flic = NULL;
1772
    tFlic_descriptor* last_flic = NULL;
1773
    tFlic_descriptor* doomed_flic = NULL;
1774
    LOG_TRACE("(%d, %d, %d, %d)", pIndex, pX, pY, pMust_finish);
1775
 
1776
    the_flic = gFirst_flic;
1777
    while (the_flic != NULL) {
1778
        if (pX == the_flic->x_offset && pY == the_flic->y_offset) {
1779
            doomed_flic = the_flic;
1780
            break;
1781
        }
1782
        last_flic = the_flic;
1783
        the_flic = the_flic->next;
1784
    }
1785
 
1786
    if (doomed_flic != NULL) {
1787
        EndFlic(doomed_flic);
1788
        if (last_flic != NULL) {
1789
            last_flic->next = doomed_flic->next;
1790
        } else {
1791
            gFirst_flic = doomed_flic->next;
1792
        }
1793
        BrMemFree(doomed_flic);
1794
    }
1795
 
1796
    LoadFlic(pIndex);
1797
    new_flic = BrMemAllocate(sizeof(tFlic_descriptor), kMem_queued_flic);
1798
    new_flic->next = NULL;
1799
    the_flic = gFirst_flic;
1800
    if (gFirst_flic != NULL) {
1801
        while (the_flic->next != NULL) {
1802
            the_flic = the_flic->next;
1803
        }
1804
        the_flic->next = new_flic;
1805
    } else {
1806
        gFirst_flic = new_flic;
1807
    }
1808
    new_flic->last_frame = 0;
1809
    new_flic->data_start = NULL;
1810
    new_flic->the_index = pIndex;
1811
    new_flic->must_finish = pMust_finish;
1812
 
1813
    StartFlic(
1814
        gMain_flic_list[pIndex].file_name,
1815
        pIndex,
1816
        new_flic,
1817
        gMain_flic_list[pIndex].the_size,
1818
        gMain_flic_list[pIndex].data_ptr,
1819
        gBack_screen,
1820
        pX >= 0 ? pX : gMain_flic_list[pIndex].x_offset,
1821
        pY >= 0 ? pY : gMain_flic_list[pIndex].y_offset,
1822
        20);
1823
}
1824
 
1825
// IDA: void __usercall InitialiseFlicPanel(int pIndex@<EAX>, int pLeft@<EDX>, int pTop@<EBX>, int pWidth@<ECX>, int pHeight)
1826
void InitialiseFlicPanel(int pIndex, int pLeft, int pTop, int pWidth, int pHeight) {
1827
    void* the_pixels;
1828
    LOG_TRACE("(%d, %d, %d, %d, %d)", pIndex, pLeft, pTop, pWidth, pHeight);
1829
 
1830
    gPanel_flic[pIndex].data = NULL;
1831
    gPanel_flic_left[pIndex] = pLeft;
1832
    gPanel_flic_top[pIndex] = pTop;
1833
    the_pixels = BrMemAllocate(pHeight * ((pWidth + 3) & ~3), kFlic_panel_pixels);
1834
    if (gScreen->row_bytes < 0) {
1835
        BrFatal(
1836
            "..\\..\\source\\common\\flicplay.c",
1837
            2116,
1838
            "Bruce bug at line %d, file ..\\..\\source\\common\\flicplay.c",
1839
            68);
1840
    }
1841
    gPanel_buffer[pIndex] = DRPixelmapAllocate(gScreen->type, pWidth, pHeight, the_pixels, 0);
1842
}
1843
 
1844
// IDA: void __usercall DisposeFlicPanel(int pIndex@<EAX>)
1845
void DisposeFlicPanel(int pIndex) {
1846
    LOG_TRACE("(%d)", pIndex);
1847
 
1848
    EndFlic(&gPanel_flic[pIndex]);
1849
    BrMemFree(gPanel_buffer[pIndex]->pixels);
1850
    BrPixelmapFree(gPanel_buffer[pIndex]);
1851
    gPanel_buffer[pIndex] = NULL;
1852
}
1853
 
1854
// IDA: void __usercall ServicePanelFlics(int pCopy_to_buffer@<EAX>)
1855
void ServicePanelFlics(int pCopy_to_buffer) {
1856
    tU32 time_diff;
1857
    tU32 the_time;
1858
    tU32 old_last_time[2];
1859
    int i;
1860
    int j;
1861
    int iteration_count;
1862
    int finished;
1863
 
1864
    if (gPanel_flic_disable) {
1865
        return;
1866
    }
1867
    the_time = PDGetTotalTime();
1868
    DontLetFlicFuckWithPalettes();
1869
    TurnFlicTransparencyOn();
1870
 
1871
    for (i = 0; i < COUNT_OF(gPanel_flic); i++) {
1872
        old_last_time[i] = gLast_panel_frame_time[i];
1873
        if (gPanel_buffer[i] != NULL && gPanel_flic[i].data != NULL) {
1874
            if (old_last_time[i] != 0) {
1875
                time_diff = the_time - old_last_time[i];
1876
                iteration_count = time_diff / gPanel_flic[i].frame_period;
1877
            } else {
1878
                iteration_count = 1;
1879
            }
1880
            for (j = 0; j < iteration_count; j++) {
1881
                finished = PlayNextFlicFrame2(&gPanel_flic[i], 1);
1882
                if (finished) {
1883
                    EndFlic(&gPanel_flic[i]);
1884
                    StartFlic(
1885
                        gPanel_flic[i].file_name,
1886
                        gPanel_flic[i].the_index,
1887
                        &gPanel_flic[i],
1888
                        gPanel_flic_data_length[i],
1889
                        (tS8*)gPanel_flic_data[i],
1890
                        gPanel_buffer[i],
1891
                        0,
1892
                        0,
1893
                        0);
1894
                }
1895
                gLast_panel_frame_time[i] = the_time;
1896
            }
1897
            if (pCopy_to_buffer) {
1898
                BrPixelmapRectangleCopy(
1899
                    gBack_screen,
1900
                    gPanel_flic_left[i],
1901
                    gPanel_flic_top[i],
1902
                    gPanel_buffer[i],
1903
                    0,
1904
                    0,
1905
                    gPanel_buffer[i]->width,
1906
                    gPanel_buffer[i]->height);
1907
            }
1908
        }
1909
    }
1910
    TurnFlicTransparencyOff();
1911
    LetFlicFuckWithPalettes();
1912
}
1913
 
1914
// IDA: void __usercall ChangePanelFlic(int pIndex@<EAX>, tU8 *pData@<EDX>, tU32 pData_length@<EBX>)
1915
void ChangePanelFlic(int pIndex, tU8* pData, tU32 pData_length) {
1916
    LOG_TRACE("(%d, %p, %d)", pIndex, pData, pData_length);
1917
 
1918
    EndFlic(&gPanel_flic[pIndex]);
1919
    gPanel_flic_data[pIndex] = pData;
1920
    gPanel_flic_data_length[pIndex] = pData_length;
1921
    BrPixelmapFill(gPanel_buffer[pIndex], 0);
1922
    StartFlic(
1923
        gPanel_flic[pIndex].file_name,
1924
        pIndex,
1925
        &gPanel_flic[pIndex],
1926
        gPanel_flic_data_length[pIndex],
1927
        (tS8*)gPanel_flic_data[pIndex],
1928
        gPanel_buffer[pIndex],
1929
        0,
1930
        0,
1931
        0);
1932
    gLast_panel_frame_time[pIndex] = 0;
1933
    ServicePanelFlics(0);
1934
}
1935
 
1936
// IDA: br_pixelmap* __usercall GetPanelPixelmap@<EAX>(int pIndex@<EAX>)
1937
br_pixelmap* GetPanelPixelmap(int pIndex) {
1938
    LOG_TRACE("(%d)", pIndex);
1939
 
1940
    return gPanel_buffer[pIndex];
1941
}
1942
 
1943
// IDA: void __cdecl LoadInterfaceStrings()
1944
void LoadInterfaceStrings(void) {
1945
    FILE* f; // Added by DethRace
1946
    char s[256];
1947
    char s2[256];
1948
    char* str;
1949
    char* comment;
1950
    char ch;
1951
    tPath_name the_path;
1952
    int i;
1953
    int j;
1954
    int len;
1955
 
1956
    gTranslation_count = 0;
1957
    PathCat(the_path, gApplication_path, "TRNSLATE.TXT");
1958
    f = fopen(the_path, "rt");
1959
    if (f == NULL) {
1960
        return;
1961
    }
1962
    while (!feof(f)) {
1963
        GetALineAndDontArgue(f, s);
1964
        gTranslation_count++;
1965
    }
1966
    rewind(f);
1967
    gTranslations = BrMemAllocate(gTranslation_count * sizeof(tTranslation_record), kMem_translations);
1968
    for (i = 0; i < gTranslation_count; i++) {
1969
        GetALineAndDontArgue(f, s);
1970
        str = strtok(s, "\t ,/");
1971
        strcpy(s2, str);
1972
        strtok(s2, ".");
1973
        strcat(s2, ".FLI");
1974
        gTranslations[i].flic_index = -1;
1975
        for (j = 0; j < COUNT_OF(gMain_flic_list); j++) {
1976
            if (strcmp(gMain_flic_list[j].file_name, s2) == 0) {
1977
                gTranslations[i].flic_index = j;
1978
                break;
1979
            }
1980
        }
1981
        if (gTranslations[i].flic_index < 0) {
1982
            FatalError(kFatalError_FindFlicUsedInTranslationFile_S, s2);
1983
        }
1984
        str[strlen(str)] = ',';
1985
        str = strtok(s, "\t ,/");
1986
        str = strtok(NULL, "\t ,/");
1987
        sscanf(str, "%d", &gTranslations[i].x);
1988
        str = strtok(NULL, "\t ,/");
1989
        sscanf(str, "%d", &gTranslations[i].y);
1990
        str = strtok(NULL, "\t ,/");
1991
        sscanf(str, "%d", &gTranslations[i].font_index);
1992
        str = strtok(NULL, "\t ,/");
1993
        sscanf(str, "%c", &ch);
1994
        switch (ch) {
1995
        case 'C':
1996
        case 'c':
1997
            gTranslations[i].justification = eJust_centre;
1998
            break;
1999
        case 'L':
2000
        case 'l':
2001
            gTranslations[i].justification = eJust_left;
2002
            break;
2003
        case 'R':
2004
        case 'r':
2005
            gTranslations[i].justification = eJust_right;
2006
            break;
2007
        }
2008
        str = strtok(NULL, "\t ,/");
2009
        sscanf(str, "%c", &ch);
2010
        gTranslations[i].global = ch == 'G' || ch == 'g';
2011
        gTranslations[i].every_frame = strlen(str) > 1 && (str[1] == 'E' || str[1] == 'e');
2012
        str += strlen(str) + 1;
2013
        comment = strstr(str, "//");
2014
        if (comment != NULL) {
2015
            *comment = '\0';
2016
        }
2017
        len = strlen(str);
2018
        for (j = len - 1; j >= 0 && (str[j] == ' ' || str[j] == '\t'); j--) {
2019
        }
2020
        str[j + 1] = '\0';
2021
        gTranslations[i].text = BrMemAllocate(strlen(str) + 1, kMem_translations_text);
2022
        strcpy(gTranslations[i].text, str);
2023
    }
11 pmbaty 2024
    LoadFont(kFont_BLUEHEAD);
2025
    LoadFont(kFont_ORANGHED);
2026
    LoadFont(kFont_GREENHED);
2027
    LoadFont(kFont_LITPLAQ);
2028
    LoadFont(kFont_BUTTOUT);
2029
    LoadFont(kFont_DRKPLAQ);
2030
    LoadFont(kFont_BUTTIN);
2031
    LoadFont(kFont_GRNLIT);
2032
    LoadFont(kFont_GRYLIT);
2033
    LoadFont(kFont_GRNDK);
2034
    LoadFont(kFont_GRYDK);
2035
    LoadFont(kFont_LITPLAQ1);
2036
    LoadFont(kFont_BUTTOUT1);
2037
    LoadFont(kFont_DRKPLAQ1);
2038
    LoadFont(kFont_BUTTIN1);
2039
    gTrans_fonts[0] = &gFonts[kFont_ORANGHED];
2040
    gTrans_fonts[1] = &gFonts[kFont_LITPLAQ];
2041
    gTrans_fonts[2] = &gFonts[kFont_BUTTOUT];
2042
    gTrans_fonts[3] = &gFonts[kFont_DRKPLAQ];
2043
    gTrans_fonts[4] = &gFonts[kFont_BUTTIN];
2044
    gTrans_fonts[5] = &gFonts[kFont_GRNLIT];
2045
    gTrans_fonts[6] = &gFonts[kFont_GRYLIT];
2046
    gTrans_fonts[7] = &gFonts[kFont_GRNDK];
2047
    gTrans_fonts[8] = &gFonts[kFont_GRYDK];
2048
    gTrans_fonts[9] = &gFonts[kFont_LITPLAQ1];
2049
    gTrans_fonts[10] = &gFonts[kFont_DRKPLAQ1];
2050
    gTrans_fonts[11] = &gFonts[kFont_BUTTOUT1];
2051
    gTrans_fonts[12] = &gFonts[kFont_BUTTIN1];
1 pmbaty 2052
 
2053
#ifdef DETHRACE_FIX_BUGS
2054
    fclose(f);
2055
#endif
2056
}
2057
 
2058
// IDA: void __cdecl FlushInterfaceFonts()
2059
void FlushInterfaceFonts(void) {
2060
    LOG_TRACE("()");
2061
 
2062
    DisposeFont(19);
2063
    DisposeFont(18);
2064
    DisposeFont(20);
2065
    DisposeFont(17);
2066
    DisposeFont(15);
2067
    DisposeFont(14);
2068
    DisposeFont(16);
2069
    DisposeFont(13);
2070
}
2071
 
2072
// IDA: void __cdecl SuspendPendingFlic()
2073
void SuspendPendingFlic(void) {
2074
    LOG_TRACE("()");
2075
 
2076
    gPending_pending_flic = gPending_flic;
2077
    gPending_flic = -1;
2078
}
2079
 
2080
// IDA: void __cdecl ResumePendingFlic()
2081
void ResumePendingFlic(void) {
2082
    LOG_TRACE("()");
2083
 
2084
    gPending_flic = gPending_pending_flic;
2085
}