1 /*
2 BStone: A Source port of
3 Blake Stone: Aliens of Gold and Blake Stone: Planet Strike
4 
5 Copyright (c) 1992-2013 Apogee Entertainment, LLC
6 Copyright (c) 2013-2015 Boris I. Bendovsky (bibendovsky@hotmail.com)
7 
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the
20 Free Software Foundation, Inc.,
21 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 */
23 
24 
25 // --------------------------------------------------------------------------
26 //
27 //                             TEXT PRESENTER
28 //                    Programmed by Michael D. Maynard
29 //                  Copyright 1993, JAM Productions, Inc.
30 //                          All rights reserved.
31 //
32 // Active control codes:
33 //
34 //  ^ANnn   - define animation
35 //  ^AXnn   - alter X coordinate (nn = signed char)
36 //  ^AYnn   - alter Y coordinate (nn = signed char)
37 //  ^BCnn   - set background color
38 //  ^BE     - ring bell
39 //  ^BXn    - draw box around shape (0 = no box, 1 = box)
40 //  ^CE     - center text between 'left margin' and 'right margin'
41 //  ^DCnn   - dark color (dark-light for boxes)
42 //  ^DM     - use default margins
43 //  ^DSnn   - Display String Number 'nn'
44 //  ^EP     - end of page (waits for up/down arrow)
45 //  ^FCnn   - set font color
46 //  ^FNn    - set font number
47 //  ^HI     - hide cursor
48 //  ^HCnn   - highlight color
49 //  ^HF     - highlight color off
50 //  ^HO     - highlight color on
51 //  ^LCnn   - light color (highlight for boxes)
52 //  ^LJ     - left justify  --\ ^RJ doesn't handle imbedded control
53 //  ^LMnnn  - set left margin (if 'nnn' == "fff" uses current x)
54 //  ^MO     - wait for action from any input device
55 //  ^PA     - pause 1/2 second
56 //  ^PMnn   - Play Music Number 'nn'
57 //  ^PSnn   - Play Sound Number 'nn'
58 //  ^PXnnn  - move x to coordinate 'n'
59 //  ^PYnnn  - move y to coordinate 'n'
60 //  ^RMnnn  - set right margin (if 'nnn' == "fff" uses current x)
61 //  ^RJ     - right justify --/ codes properly. Use with caution.
62 //  ^RL     - restore cursor location.
63 //  ^RXn    - restore x location
64 //  ^RYn    - restore y location
65 //  ^SBn    - clear scaled background (0 = no clear, 1 = clear)
66 //  ^SCnn   - shadow color (shadow for text / pics)
67 //  ^SHnnn  - display shape 'n' at current x,y
68 //  ^SPn    - shadow pics (0 = no shadow, 1 = shadow)
69 //  ^STn    - shadow text (0 = no shadow, 1 = shadow)
70 //  ^SL     - save cursor location.
71 //  ^SXn    - save x location
72 //  ^SYn    - save y location
73 //  ^XX     - exit presenter
74 //  ^ZZ     - NOP ... This code is ignored.
75 //
76 // Other info:
77 //
78 // All 'n' values are hex numbers (0 - f), case insensitive.
79 // The number of N's listed is the number of digits REQUIRED by that control
80 // code. (IE: ^LMnnn MUST have 3 values! --> 003, 1a2, 01f, etc...)
81 //
82 // If a line consists only of control codes, the cursor is NOT advanced
83 // to the next line (the ending <CR><LF> is skipped). If just ONE non-control
84 // code is added, the number "8" for example, then the "8" is displayed
85 // and the cursor is advanced to the next line.
86 //
87 // ^CE must be on the same line as the text it should center!
88 //
89 // The text presenter now handles sprites, but they are NOT masked! Also,
90 // sprite animations will be difficult to implement unless all frames are
91 // of the same dimensions.
92 //
93 // A shape of type "pis_latchpic" is assumed to already be loaded in latch
94 // memory. No caching is performed on this type of shape! If a pic needs to
95 // be cached, specify "pis_pic".
96 //
97 // You can comment-out a line by beginning the line with a semi-colon.
98 // Commented lines are ignored by the parser. Do not comment-out the last
99 // line of the file for this may cause harm to all things great and small!
100 //
101 // --------------------------------------------------------------------------
102 
103 
104 #include "3d_def.h"
105 
106 
107 void VWL_MeasureString(
108     const char* string,
109     int* width,
110     int* height,
111     fontstruct* font);
112 
113 void VH_UpdateScreen();
114 void ClearMemory();
115 
116 void draw_wall_ui(
117     const int x,
118     const int y,
119     const void* raw_wall);
120 
121 
122 // string array table is a quick, easy and expandable way to print
123 // any number of strings in a text file using the ^DS codes...
124 //
125 // See Macro TP_INIT_DISPLAY_STR(num,str_ptr) - JM_TP.h
126 // To init strings and handle range checking....
127 char* piStringTable[PI_MAX_NUM_DISP_STRS];
128 
129 
130 // shape table provides a way for the presenter to access and
131 // display any shape.
132 //
133 PiShapeInfos piShapeTable;
134 
initialize_tp_shape_table()135 void initialize_tp_shape_table()
136 {
137     if (::is_aog_sw()) {
138         piShapeTable = {
139             { SPR_PRO_W3_7, pis_scaled, },
140             { SPR_STAT_32, pis_scaled, },
141             { SPR_STAT_33, pis_scaled, },
142             { SPR_STAT_34, pis_scaled, },
143             { SPR_STAT_35, pis_scaled, },
144             { SPR_STAT_36, pis_scaled, },
145             { SPR_STAT_26, pis_scaled, },
146             { SPR_STAT_24, pis_scaled, },
147             { SPR_STAT_27, pis_scaled, },
148             { SPR_STAT_28, pis_scaled, },
149             { SPR_STAT_29, pis_scaled, },
150             { SPR_DEMO, pis_scaled, },
151             { SPR_STAT_48, pis_scaled, },
152             { SPR_STAT_49, pis_scaled, },
153             { SPR_STAT_50, pis_scaled, },
154             { SPR_STAT_51, pis_scaled, },
155             { SPR_STAT_42, pis_scaled, },
156             { SPR_STAT_44, pis_scaled, },
157             { SPR_STAT_40, pis_scaled, },
158             { SPR_STAT_0, pis_scaled, },
159             { SPR_RENT_W1_8, pis_scaled, },
160             { SPR_RENT_W2_8, pis_scaled, },
161             { SPR_RENT_W3_8, pis_scaled, },
162             { SPR_RENT_W4_8, pis_scaled, },
163             { SPR_TERROT_1, pis_scaled, },
164             { SPR_TERROT_2, pis_scaled, },
165             { SPR_TERROT_3, pis_scaled, },
166             { SPR_TERROT_4, pis_scaled, },
167             { SPR_TERROT_5, pis_scaled, },
168             { SPR_TERROT_6, pis_scaled, },
169             { SPR_TERROT_7, pis_scaled, },
170             { SPR_TERROT_8, pis_scaled, },
171             { SPR_STAT_77, pis_scaled, },
172             { SPR_STAT_78, pis_scaled, },
173             { SPR_STAT_79, pis_scaled, },
174             { 14 * 2, pis_scwall, },
175             { 16 * 2, pis_scwall, },
176             { 20 * 2 + 1, pis_scwall, },
177             { 44 * 2, pis_scwall, },
178             { 31 * 2, pis_scwall, },
179             { BIGGOLDSTERNPIC, pis_pic, },
180             { STARLOGOPIC, pis_pic, },
181             { BLAKEWITHGUNPIC, pis_pic, },
182             { STARINSTITUTEPIC, pis_pic, },
183             { MEDALOFHONORPIC, pis_pic, },
184             { SMALLGOLDSTERNPIC, pis_pic, },
185             { BLAKEWINPIC, pis_pic, },
186             { AUTOMAPPIC, pis_pic, },
187             { SPR_ELEC_POST1, pis_scaled, },
188             { SPR_ELEC_POST2, pis_scaled, },
189             { SPR_ELEC_POST3, pis_scaled, },
190             { SHUTTLEEXPPIC, pis_pic, },
191             { PLANETSPIC, pis_pic, },
192             { SPR_DECO_ARC_3, pis_scaled, },
193             { H_PPIC, pis_pic, },
194             { MOUSEPIC, pis_pic, },
195             { SPR_OFC_W1_8, pis_scaled, },
196             { SPR_OFC_W2_8, pis_scaled, },
197             { SPR_OFC_W3_8, pis_scaled, },
198             { SPR_OFC_W4_8, pis_scaled, },
199             { SPR_POD_WALK1, pis_scaled, },
200             { SPR_POD_WALK2, pis_scaled, },
201             { SPR_POD_WALK3, pis_scaled, },
202             { SPR_POD_WALK4, pis_scaled, },
203             { SPR_ELEC_WALK1, pis_scaled, },
204             { SPR_ELEC_WALK2, pis_scaled, },
205             { SPR_ELEC_WALK3, pis_scaled, },
206             { SPR_ELEC_WALK4, pis_scaled, },
207             { SPR_ELECTRO_SPHERE_ROAM1, pis_scaled, },
208             { SPR_ELECTRO_SPHERE_ROAM2, pis_scaled, },
209             { SPR_ELECTRO_SPHERE_ROAM3, pis_scaled, },
210             { SPR_PRO_W1_8, pis_scaled, },
211             { SPR_PRO_W2_8, pis_scaled, },
212             { SPR_PRO_W3_8, pis_scaled, },
213             { SPR_PRO_W4_8, pis_scaled, },
214             { SPR_GENETIC_W1, pis_scaled, },
215             { SPR_GENETIC_W2, pis_scaled, },
216             { SPR_GENETIC_W3, pis_scaled, },
217             { SPR_GENETIC_W4, pis_scaled, },
218             { SPR_MUTHUM1_W1, pis_scaled, },
219             { SPR_MUTHUM1_W2, pis_scaled, },
220             { SPR_MUTHUM1_W3, pis_scaled, },
221             { SPR_MUTHUM1_W4, pis_scaled, },
222             { SPR_RENT_S_3, pis_scaled, },
223             { SPR_RENT_S_4, pis_scaled, },
224             { SPR_RENT_S_5, pis_scaled, },
225             { SPR_RENT_S_6, pis_scaled, },
226             { SPR_RENT_W2_3, pis_scaled, },
227             { SPR_RENT_W2_8, pis_scaled, },
228             { SPR_RENT_W3_1, pis_scaled, },
229             { SPR_RENT_W3_2, pis_scaled, },
230             { SPR_RENT_W3_3, pis_scaled, },
231             { SPR_SCAN_ALIEN_READY, pis_scaled, },
232             { SPR_SCAN_ALIEN_W1, pis_scaled, },
233             { SPR_SCAN_ALIEN_W2, pis_scaled, },
234             { SPR_SCAN_ALIEN_W3, pis_scaled, },
235             { SPR_SCAN_ALIEN_W4, pis_scaled, },
236             { SPR_RENT_W4_8, pis_scaled, },
237             { SPR_RENT_PAIN_1, pis_scaled, },
238             { SPR_RENT_DEAD, pis_scaled, },
239             { SPR_RENT_SHOOT1, pis_scaled, },
240             { SPR_RENT_SHOOT2, pis_scaled, },
241             { SPR_PRO_W1_8, pis_scaled, },
242             { SPR_PRO_W2_1, pis_scaled, },
243             { SPR_PRO_W2_2, pis_scaled, },
244             { SPR_SWAT_W1_8, pis_scaled, },
245             { SPR_SWAT_W2_8, pis_scaled, },
246             { SPR_SWAT_W3_8, pis_scaled, },
247             { SPR_SWAT_W4_8, pis_scaled, },
248             { SPR_GOLD_W1_8, pis_scaled, },
249             { SPR_GOLD_W2_8, pis_scaled, },
250             { SPR_GOLD_W3_8, pis_scaled, },
251             { SPR_GOLD_W4_8, pis_scaled, },
252             { JOYSTICKPIC, pis_pic, },
253             { SPR_STAT_13, pis_scaled, },
254             { SPR_STAT_29, pis_scaled, },
255             { SPR_STAT_40, pis_scaled, },
256             { SPR_STAT_48, pis_scaled, },
257             { SPR_FSCOUT_W1_8, pis_scaled, },
258             { SPR_STAT_67, pis_scaled, },
259             { SPR_BLOOD_DRIP2, pis_scaled, },
260             { SPR_DECO_ARC_2, pis_scaled, },
261             { SPR_DECO_ARC_3, pis_scaled, },
262             { SPR_ELEC_SHOT1, pis_scaled, },
263             { SPR_ELEC_SHOT2, pis_scaled, },
264             { SPR_SECURITY_NORMAL, pis_scaled, },
265             { SPR_SECURITY_ALERT, pis_scaled, },
266             { SPR_PRO_W3_1, pis_scaled, },
267             { SPR_PRO_W3_2, pis_scaled, },
268             { SPR_PRO_W3_3, pis_scaled, },
269             { SPR_POD_EGG, pis_scaled, },
270             { SPR_DECO_ARC_1, pis_scaled, },
271             { SPR_DECO_ARC_2, pis_scaled, },
272             { SPR_DECO_ARC_3, pis_scaled, },
273             { GRAVISPADPIC, pis_pic, },
274             { H_MPIC, pis_pic, },
275             { SPR_CANDY_BAR, pis_scaled, },
276             { SPR_SANDWICH, pis_scaled, },
277             { SPR_STAT_46, pis_scaled, },
278             { SPR_EXPLOSION_3, pis_scaled, },
279             { SPR_PRO_W4_2, pis_scaled, },
280             { SPR_ELEC_ARC1, pis_scaled, },
281             { SPR_ELEC_ARC2, pis_scaled, },
282             { SPR_ELEC_ARC3, pis_scaled, },
283             { C_EPISODE1PIC, pis_pic, },
284             { C_EPISODE2PIC, pis_pic, },
285             { C_EPISODE3PIC, pis_pic, },
286             { C_EPISODE4PIC, pis_pic, },
287             { C_EPISODE5PIC, pis_pic, },
288             { C_EPISODE6PIC, pis_pic, },
289             { SPR_BOSS1_W1, pis_scaled, },
290             { SPR_BOSS1_W2, pis_scaled, },
291             { SPR_BOSS1_W3, pis_scaled, },
292             { SPR_BOSS1_W4, pis_scaled, },
293             { SPR_PRO_W4_5, pis_scaled, },
294             { SPR_PRO_W4_6, pis_scaled, },
295             { SPR_PRO_W4_7, pis_scaled, },
296             { SPR_PRO_W4_8, pis_scaled, },
297             { SPR_SWAT_W1_1, pis_scaled, },
298             { SPR_SWAT_W1_2, pis_scaled, },
299             { SPR_SWAT_W1_3, pis_scaled, },
300             { SPR_SWAT_W1_4, pis_scaled, },
301             { SPR_SWAT_W3_7, pis_scaled, },
302             { SPR_SWAT_W3_8, pis_scaled, },
303             { SPR_SWAT_W4_1, pis_scaled, },
304             { SPR_SWAT_W4_2, pis_scaled, },
305             { SPR_SWAT_WOUNDED3, pis_scaled, },
306             { SPR_SWAT_WOUNDED4, pis_scaled, },
307             { SPR_OFC_S_1, pis_scaled, },
308             { SPR_OFC_S_2, pis_scaled, },
309             { SPR_OFC_W2_5, pis_scaled, },
310             { SPR_OFC_W2_6, pis_scaled, },
311             { SPR_OFC_W2_7, pis_scaled, },
312             { SPR_OFC_W2_8, pis_scaled, },
313             { H_ALTPIC, pis_pic, },
314             { H_CTRLPIC, pis_pic, },
315             { H_SPACEPIC, pis_pic, },
316             { H_PAUSEPIC, pis_pic, },
317             { H_ESCPIC, pis_pic, },
318             { H_LTARROWPIC, pis_pic, },
319             { H_UPARROWPIC, pis_pic, },
320             { H_DNARROWPIC, pis_pic, },
321             { H_RTARROWPIC, pis_pic, },
322             { H_QPIC, pis_pic, },
323             { H_WPIC, pis_pic, },
324             { H_EPIC, pis_pic, },
325             { H_IPIC, pis_pic, },
326             { H_HPIC, pis_pic, },
327             { H_1PIC, pis_pic, },
328             { H_2PIC, pis_pic, },
329             { H_3PIC, pis_pic, },
330             { H_4PIC, pis_pic, },
331             { H_5PIC, pis_pic, },
332             { H_F1PIC, pis_pic, },
333             { H_F2PIC, pis_pic, },
334             { H_F3PIC, pis_pic, },
335             { H_F4PIC, pis_pic, },
336             { H_F5PIC, pis_pic, },
337             { H_F6PIC, pis_pic, },
338             { H_F7PIC, pis_pic, },
339             { H_F8PIC, pis_pic, },
340             { H_F9PIC, pis_pic, },
341             { H_F10PIC, pis_pic, },
342             { H_ENTERPIC, pis_pic, },
343             { H_TABPIC, pis_pic, },
344             { H_CPIC, pis_pic, },
345             { H_FPIC, pis_pic, },
346             { SPR_CRATE_1, pis_scaled, },
347             { SPR_STAT_0, pis_scaled, },
348             { SPR_FSCOUT_W1_1, pis_scaled, },
349             { APOGEE_LOGOPIC, pis_pic, },
350             { VISAPIC, pis_pic, },
351             { MCPIC, pis_pic, },
352             { FAXPIC, pis_pic, },
353             { H_LPIC, pis_pic, },
354             { H_SHIFTPIC, pis_pic, },
355             { PSPROMO1PIC, pis_pic, },
356             { PSPROMO2PIC, pis_pic, },
357             { PSPROMO3PIC, pis_pic, },
358         }; // piShapeTable
359     } else if (::is_aog_full_v1_0()) {
360         piShapeTable = {
361             { SPR_GREEN_OOZE1, pis_scaled, },
362             { SPR_STAT_32, pis_scaled, },
363             { SPR_STAT_33, pis_scaled, },
364             { SPR_STAT_34, pis_scaled, },
365             { SPR_STAT_35, pis_scaled, },
366             { SPR_STAT_36, pis_scaled, },
367             { SPR_STAT_26, pis_scaled, },
368             { SPR_STAT_24, pis_scaled, },
369             { SPR_STAT_27, pis_scaled, },
370             { SPR_STAT_28, pis_scaled, },
371             { SPR_STAT_29, pis_scaled, },
372             { SPR_STAT_30, pis_scaled, },
373             { SPR_STAT_48, pis_scaled, },
374             { SPR_STAT_49, pis_scaled, },
375             { SPR_STAT_50, pis_scaled, },
376             { SPR_STAT_51, pis_scaled, },
377             { SPR_STAT_42, pis_scaled, },
378             { SPR_STAT_44, pis_scaled, },
379             { SPR_STAT_40, pis_scaled, },
380             { SPR_STAT_0, pis_scaled, },
381             { SPR_RENT_W1_8, pis_scaled, },
382             { SPR_RENT_W2_8, pis_scaled, },
383             { SPR_RENT_W3_8, pis_scaled, },
384             { SPR_RENT_W4_8, pis_scaled, },
385             { SPR_TERROT_1, pis_scaled, },
386             { SPR_TERROT_2, pis_scaled, },
387             { SPR_TERROT_3, pis_scaled, },
388             { SPR_TERROT_4, pis_scaled, },
389             { SPR_TERROT_5, pis_scaled, },
390             { SPR_TERROT_6, pis_scaled, },
391             { SPR_TERROT_7, pis_scaled, },
392             { SPR_TERROT_8, pis_scaled, },
393             { SPR_STAT_77, pis_scaled, },
394             { SPR_STAT_78, pis_scaled, },
395             { SPR_STAT_79, pis_scaled, },
396             { 14 * 2, pis_scwall, },
397             { 16 * 2, pis_scwall, },
398             { 20 * 2 + 1, pis_scwall, },
399             { 44 * 2, pis_scwall, },
400             { 31 * 2, pis_scwall, },
401             { BIGGOLDSTERNPIC, pis_pic, },
402             { STARLOGOPIC, pis_pic, },
403             { BLAKEWITHGUNPIC, pis_pic, },
404             { STARINSTITUTEPIC, pis_pic, },
405             { MEDALOFHONORPIC, pis_pic, },
406             { SMALLGOLDSTERNPIC, pis_pic, },
407             { BLAKEWINPIC, pis_pic, },
408             { AUTOMAPPIC, pis_pic, },
409             { SPR_ELEC_POST1, pis_scaled, },
410             { SPR_ELEC_POST2, pis_scaled, },
411             { SPR_ELEC_POST3, pis_scaled, },
412             { SHUTTLEEXPPIC, pis_pic, },
413             { PLANETSPIC, pis_pic, },
414             { SPR_VITAL_STAND, pis_scaled, },
415             { H_PPIC, pis_pic, },
416             { MOUSEPIC, pis_pic, },
417             { SPR_OFC_W1_8, pis_scaled, },
418             { SPR_OFC_W2_8, pis_scaled, },
419             { SPR_OFC_W3_8, pis_scaled, },
420             { SPR_OFC_W4_8, pis_scaled, },
421             { SPR_POD_WALK1, pis_scaled, },
422             { SPR_POD_WALK2, pis_scaled, },
423             { SPR_POD_WALK3, pis_scaled, },
424             { SPR_POD_WALK4, pis_scaled, },
425             { SPR_ELEC_WALK1, pis_scaled, },
426             { SPR_ELEC_WALK2, pis_scaled, },
427             { SPR_ELEC_WALK3, pis_scaled, },
428             { SPR_ELEC_WALK4, pis_scaled, },
429             { SPR_ELECTRO_SPHERE_ROAM1, pis_scaled, },
430             { SPR_ELECTRO_SPHERE_ROAM2, pis_scaled, },
431             { SPR_ELECTRO_SPHERE_ROAM3, pis_scaled, },
432             { SPR_PRO_W1_8, pis_scaled, },
433             { SPR_PRO_W2_8, pis_scaled, },
434             { SPR_PRO_W3_8, pis_scaled, },
435             { SPR_PRO_W4_8, pis_scaled, },
436             { SPR_GENETIC_W1, pis_scaled, },
437             { SPR_GENETIC_W2, pis_scaled, },
438             { SPR_GENETIC_W3, pis_scaled, },
439             { SPR_GENETIC_W4, pis_scaled, },
440             { SPR_MUTHUM1_W1, pis_scaled, },
441             { SPR_MUTHUM1_W2, pis_scaled, },
442             { SPR_MUTHUM1_W3, pis_scaled, },
443             { SPR_MUTHUM1_W4, pis_scaled, },
444             { SPR_MUTHUM2_W1, pis_scaled, },
445             { SPR_MUTHUM2_W2, pis_scaled, },
446             { SPR_MUTHUM2_W3, pis_scaled, },
447             { SPR_MUTHUM2_W4, pis_scaled, },
448             { SPR_LCAN_ALIEN_READY, pis_scaled, },
449             { SPR_LCAN_ALIEN_W1, pis_scaled, },
450             { SPR_LCAN_ALIEN_W2, pis_scaled, },
451             { SPR_LCAN_ALIEN_W3, pis_scaled, },
452             { SPR_LCAN_ALIEN_W4, pis_scaled, },
453             { SPR_SCAN_ALIEN_READY, pis_scaled, },
454             { SPR_SCAN_ALIEN_W1, pis_scaled, },
455             { SPR_SCAN_ALIEN_W2, pis_scaled, },
456             { SPR_SCAN_ALIEN_W3, pis_scaled, },
457             { SPR_SCAN_ALIEN_W4, pis_scaled, },
458             { SPR_GURNEY_MUT_READY, pis_scaled, },
459             { SPR_GURNEY_MUT_W1, pis_scaled, },
460             { SPR_GURNEY_MUT_W2, pis_scaled, },
461             { SPR_GURNEY_MUT_W3, pis_scaled, },
462             { SPR_GURNEY_MUT_W4, pis_scaled, },
463             { SPR_LIQUID_S1, pis_scaled, },
464             { SPR_LIQUID_S2, pis_scaled, },
465             { SPR_LIQUID_S3, pis_scaled, },
466             { SPR_SWAT_W1_8, pis_scaled, },
467             { SPR_SWAT_W2_8, pis_scaled, },
468             { SPR_SWAT_W3_8, pis_scaled, },
469             { SPR_SWAT_W4_8, pis_scaled, },
470             { SPR_GOLD_W1_8, pis_scaled, },
471             { SPR_GOLD_W2_8, pis_scaled, },
472             { SPR_GOLD_W3_8, pis_scaled, },
473             { SPR_GOLD_W4_8, pis_scaled, },
474             { JOYSTICKPIC, pis_pic, },
475             { SPR_GSCOUT_W1_8, pis_scaled, },
476             { SPR_GSCOUT_W2_8, pis_scaled, },
477             { SPR_GSCOUT_W3_8, pis_scaled, },
478             { SPR_GSCOUT_W4_8, pis_scaled, },
479             { SPR_FSCOUT_W1_8, pis_scaled, },
480             { SPR_FSCOUT_W2_8, pis_scaled, },
481             { SPR_FSCOUT_W3_8, pis_scaled, },
482             { SPR_FSCOUT_W4_8, pis_scaled, },
483             { SPR_VITAL_STAND, pis_scaled, },
484             { SPR_ELEC_SHOT1, pis_scaled, },
485             { SPR_ELEC_SHOT2, pis_scaled, },
486             { SPR_SECURITY_NORMAL, pis_scaled, },
487             { SPR_SECURITY_ALERT, pis_scaled, },
488             { SPR_LIQUID_SHOT_FLY_1, pis_scaled, },
489             { SPR_LIQUID_SHOT_FLY_2, pis_scaled, },
490             { SPR_LIQUID_SHOT_FLY_3, pis_scaled, },
491             { SPR_POD_EGG, pis_scaled, },
492             { SPR_DECO_ARC_1, pis_scaled, },
493             { SPR_DECO_ARC_2, pis_scaled, },
494             { SPR_DECO_ARC_3, pis_scaled, },
495             { GRAVISPADPIC, pis_pic, },
496             { H_MPIC, pis_pic, },
497             { SPR_CANDY_BAR, pis_scaled, },
498             { SPR_SANDWICH, pis_scaled, },
499             { SPR_STAT_46, pis_scaled, },
500             { SPR_EXPLOSION_3, pis_scaled, },
501             { SPR_BLACK_OOZE1, pis_scaled, },
502             { SPR_ELEC_ARC1, pis_scaled, },
503             { SPR_ELEC_ARC2, pis_scaled, },
504             { SPR_ELEC_ARC3, pis_scaled, },
505             { C_EPISODE1PIC, pis_pic, },
506             { C_EPISODE2PIC, pis_pic, },
507             { C_EPISODE3PIC, pis_pic, },
508             { C_EPISODE4PIC, pis_pic, },
509             { C_EPISODE5PIC, pis_pic, },
510             { C_EPISODE6PIC, pis_pic, },
511             { SPR_BOSS1_W1, pis_scaled, },
512             { SPR_BOSS1_W2, pis_scaled, },
513             { SPR_BOSS1_W3, pis_scaled, },
514             { SPR_BOSS1_W4, pis_scaled, },
515             { SPR_BOSS2_W1, pis_scaled, },
516             { SPR_BOSS2_W2, pis_scaled, },
517             { SPR_BOSS2_W3, pis_scaled, },
518             { SPR_BOSS2_W4, pis_scaled, },
519             { SPR_BOSS3_W1, pis_scaled, },
520             { SPR_BOSS3_W2, pis_scaled, },
521             { SPR_BOSS3_W3, pis_scaled, },
522             { SPR_BOSS3_W4, pis_scaled, },
523             { SPR_BOSS4_W1, pis_scaled, },
524             { SPR_BOSS4_W2, pis_scaled, },
525             { SPR_BOSS4_W3, pis_scaled, },
526             { SPR_BOSS4_W4, pis_scaled, },
527             { SPR_BOSS5_W1, pis_scaled, },
528             { SPR_BOSS5_W2, pis_scaled, },
529             { SPR_BOSS5_W3, pis_scaled, },
530             { SPR_BOSS5_W4, pis_scaled, },
531             { SPR_BOSS6_W1, pis_scaled, },
532             { SPR_BOSS6_W2, pis_scaled, },
533             { SPR_BOSS6_W3, pis_scaled, },
534             { SPR_BOSS6_W4, pis_scaled, },
535             { H_ALTPIC, pis_pic, },
536             { H_CTRLPIC, pis_pic, },
537             { H_SPACEPIC, pis_pic, },
538             { H_PAUSEPIC, pis_pic, },
539             { H_ESCPIC, pis_pic, },
540             { H_LTARROWPIC, pis_pic, },
541             { H_UPARROWPIC, pis_pic, },
542             { H_DNARROWPIC, pis_pic, },
543             { H_RTARROWPIC, pis_pic, },
544             { H_QPIC, pis_pic, },
545             { H_WPIC, pis_pic, },
546             { H_EPIC, pis_pic, },
547             { H_IPIC, pis_pic, },
548             { H_HPIC, pis_pic, },
549             { H_1PIC, pis_pic, },
550             { H_2PIC, pis_pic, },
551             { H_3PIC, pis_pic, },
552             { H_4PIC, pis_pic, },
553             { H_5PIC, pis_pic, },
554             { H_F1PIC, pis_pic, },
555             { H_F2PIC, pis_pic, },
556             { H_F3PIC, pis_pic, },
557             { H_F4PIC, pis_pic, },
558             { H_F5PIC, pis_pic, },
559             { H_F6PIC, pis_pic, },
560             { H_F7PIC, pis_pic, },
561             { H_F8PIC, pis_pic, },
562             { H_F9PIC, pis_pic, },
563             { H_F10PIC, pis_pic, },
564             { H_ENTERPIC, pis_pic, },
565             { H_TABPIC, pis_pic, },
566             { H_CPIC, pis_pic, },
567             { H_FPIC, pis_pic, },
568             { SPR_CRATE_1, pis_scaled, },
569             { SPR_GSCOUT_W1_1, pis_scaled, },
570             { SPR_FSCOUT_W1_1, pis_scaled, },
571             { APOGEE_LOGOPIC, pis_pic, },
572             { VISAPIC, pis_pic, },
573             { MCPIC, pis_pic, },
574             { FAXPIC, pis_pic, },
575             { H_LPIC, pis_pic, },
576             { H_SHIFTPIC, pis_pic, },
577         }; // piShapeTable
578     } else if (::is_aog_full_v2_x()) {
579         piShapeTable = {
580             { SPR_GREEN_OOZE1, pis_scaled, },
581             { SPR_STAT_32, pis_scaled, },
582             { SPR_STAT_33, pis_scaled, },
583             { SPR_STAT_34, pis_scaled, },
584             { SPR_STAT_35, pis_scaled, },
585             { SPR_STAT_36, pis_scaled, },
586             { SPR_STAT_26, pis_scaled, },
587             { SPR_STAT_24, pis_scaled, },
588             { SPR_STAT_27, pis_scaled, },
589             { SPR_STAT_28, pis_scaled, },
590             { SPR_STAT_29, pis_scaled, },
591             { SPR_STAT_30, pis_scaled, },
592             { SPR_STAT_48, pis_scaled, },
593             { SPR_STAT_49, pis_scaled, },
594             { SPR_STAT_50, pis_scaled, },
595             { SPR_STAT_51, pis_scaled, },
596             { SPR_STAT_42, pis_scaled, },
597             { SPR_STAT_44, pis_scaled, },
598             { SPR_STAT_40, pis_scaled, },
599             { SPR_STAT_0, pis_scaled, },
600             { SPR_RENT_W1_8, pis_scaled, },
601             { SPR_RENT_W2_8, pis_scaled, },
602             { SPR_RENT_W3_8, pis_scaled, },
603             { SPR_RENT_W4_8, pis_scaled, },
604             { SPR_TERROT_1, pis_scaled, },
605             { SPR_TERROT_2, pis_scaled, },
606             { SPR_TERROT_3, pis_scaled, },
607             { SPR_TERROT_4, pis_scaled, },
608             { SPR_TERROT_5, pis_scaled, },
609             { SPR_TERROT_6, pis_scaled, },
610             { SPR_TERROT_7, pis_scaled, },
611             { SPR_TERROT_8, pis_scaled, },
612             { SPR_STAT_77, pis_scaled, },
613             { SPR_STAT_78, pis_scaled, },
614             { SPR_STAT_79, pis_scaled, },
615             { 14 * 2, pis_scwall, },
616             { 16 * 2, pis_scwall, },
617             { 20 * 2 + 1, pis_scwall, },
618             { 44 * 2, pis_scwall, },
619             { 31 * 2, pis_scwall, },
620             { BIGGOLDSTERNPIC, pis_pic, },
621             { STARLOGOPIC, pis_pic, },
622             { BLAKEWITHGUNPIC, pis_pic, },
623             { STARINSTITUTEPIC, pis_pic, },
624             { MEDALOFHONORPIC, pis_pic, },
625             { SMALLGOLDSTERNPIC, pis_pic, },
626             { BLAKEWINPIC, pis_pic, },
627             { AUTOMAPPIC, pis_pic, },
628             { SPR_ELEC_POST1, pis_scaled, },
629             { SPR_ELEC_POST2, pis_scaled, },
630             { SPR_ELEC_POST3, pis_scaled, },
631             { SHUTTLEEXPPIC, pis_pic, },
632             { PLANETSPIC, pis_pic, },
633             { SPR_VITAL_STAND, pis_scaled, },
634             { H_PPIC, pis_pic, },
635             { MOUSEPIC, pis_pic, },
636             { SPR_OFC_W1_8, pis_scaled, },
637             { SPR_OFC_W2_8, pis_scaled, },
638             { SPR_OFC_W3_8, pis_scaled, },
639             { SPR_OFC_W4_8, pis_scaled, },
640             { SPR_POD_WALK1, pis_scaled, },
641             { SPR_POD_WALK2, pis_scaled, },
642             { SPR_POD_WALK3, pis_scaled, },
643             { SPR_POD_WALK4, pis_scaled, },
644             { SPR_ELEC_WALK1, pis_scaled, },
645             { SPR_ELEC_WALK2, pis_scaled, },
646             { SPR_ELEC_WALK3, pis_scaled, },
647             { SPR_ELEC_WALK4, pis_scaled, },
648             { SPR_ELECTRO_SPHERE_ROAM1, pis_scaled, },
649             { SPR_ELECTRO_SPHERE_ROAM2, pis_scaled, },
650             { SPR_ELECTRO_SPHERE_ROAM3, pis_scaled, },
651             { SPR_PRO_W1_8, pis_scaled, },
652             { SPR_PRO_W2_8, pis_scaled, },
653             { SPR_PRO_W3_8, pis_scaled, },
654             { SPR_PRO_W4_8, pis_scaled, },
655             { SPR_GENETIC_W1, pis_scaled, },
656             { SPR_GENETIC_W2, pis_scaled, },
657             { SPR_GENETIC_W3, pis_scaled, },
658             { SPR_GENETIC_W4, pis_scaled, },
659             { SPR_MUTHUM1_W1, pis_scaled, },
660             { SPR_MUTHUM1_W2, pis_scaled, },
661             { SPR_MUTHUM1_W3, pis_scaled, },
662             { SPR_MUTHUM1_W4, pis_scaled, },
663             { SPR_MUTHUM2_W1, pis_scaled, },
664             { SPR_MUTHUM2_W2, pis_scaled, },
665             { SPR_MUTHUM2_W3, pis_scaled, },
666             { SPR_MUTHUM2_W4, pis_scaled, },
667             { SPR_LCAN_ALIEN_READY, pis_scaled, },
668             { SPR_LCAN_ALIEN_W1, pis_scaled, },
669             { SPR_LCAN_ALIEN_W2, pis_scaled, },
670             { SPR_LCAN_ALIEN_W3, pis_scaled, },
671             { SPR_LCAN_ALIEN_W4, pis_scaled, },
672             { SPR_SCAN_ALIEN_READY, pis_scaled, },
673             { SPR_SCAN_ALIEN_W1, pis_scaled, },
674             { SPR_SCAN_ALIEN_W2, pis_scaled, },
675             { SPR_SCAN_ALIEN_W3, pis_scaled, },
676             { SPR_SCAN_ALIEN_W4, pis_scaled, },
677             { SPR_GURNEY_MUT_READY, pis_scaled, },
678             { SPR_GURNEY_MUT_W1, pis_scaled, },
679             { SPR_GURNEY_MUT_W2, pis_scaled, },
680             { SPR_GURNEY_MUT_W3, pis_scaled, },
681             { SPR_GURNEY_MUT_W4, pis_scaled, },
682             { SPR_LIQUID_S1, pis_scaled, },
683             { SPR_LIQUID_S2, pis_scaled, },
684             { SPR_LIQUID_S3, pis_scaled, },
685             { SPR_SWAT_W1_8, pis_scaled, },
686             { SPR_SWAT_W2_8, pis_scaled, },
687             { SPR_SWAT_W3_8, pis_scaled, },
688             { SPR_SWAT_W4_8, pis_scaled, },
689             { SPR_GOLD_W1_8, pis_scaled, },
690             { SPR_GOLD_W2_8, pis_scaled, },
691             { SPR_GOLD_W3_8, pis_scaled, },
692             { SPR_GOLD_W4_8, pis_scaled, },
693             { JOYSTICKPIC, pis_pic, },
694             { SPR_GSCOUT_W1_8, pis_scaled, },
695             { SPR_GSCOUT_W2_8, pis_scaled, },
696             { SPR_GSCOUT_W3_8, pis_scaled, },
697             { SPR_GSCOUT_W4_8, pis_scaled, },
698             { SPR_FSCOUT_W1_8, pis_scaled, },
699             { SPR_FSCOUT_W2_8, pis_scaled, },
700             { SPR_FSCOUT_W3_8, pis_scaled, },
701             { SPR_FSCOUT_W4_8, pis_scaled, },
702             { SPR_VITAL_STAND, pis_scaled, },
703             { SPR_ELEC_SHOT1, pis_scaled, },
704             { SPR_ELEC_SHOT2, pis_scaled, },
705             { SPR_SECURITY_NORMAL, pis_scaled, },
706             { SPR_SECURITY_ALERT, pis_scaled, },
707             { SPR_LIQUID_SHOT_FLY_1, pis_scaled, },
708             { SPR_LIQUID_SHOT_FLY_2, pis_scaled, },
709             { SPR_LIQUID_SHOT_FLY_3, pis_scaled, },
710             { SPR_POD_EGG, pis_scaled, },
711             { SPR_DECO_ARC_1, pis_scaled, },
712             { SPR_DECO_ARC_2, pis_scaled, },
713             { SPR_DECO_ARC_3, pis_scaled, },
714             { GRAVISPADPIC, pis_pic, },
715             { H_MPIC, pis_pic, },
716             { SPR_CANDY_BAR, pis_scaled, },
717             { SPR_SANDWICH, pis_scaled, },
718             { SPR_STAT_46, pis_scaled, },
719             { SPR_EXPLOSION_3, pis_scaled, },
720             { SPR_BLACK_OOZE1, pis_scaled, },
721             { SPR_ELEC_ARC1, pis_scaled, },
722             { SPR_ELEC_ARC2, pis_scaled, },
723             { SPR_ELEC_ARC3, pis_scaled, },
724             { C_EPISODE1PIC, pis_pic, },
725             { C_EPISODE2PIC, pis_pic, },
726             { C_EPISODE3PIC, pis_pic, },
727             { C_EPISODE4PIC, pis_pic, },
728             { C_EPISODE5PIC, pis_pic, },
729             { C_EPISODE6PIC, pis_pic, },
730             { SPR_BOSS1_W1, pis_scaled, },
731             { SPR_BOSS1_W2, pis_scaled, },
732             { SPR_BOSS1_W3, pis_scaled, },
733             { SPR_BOSS1_W4, pis_scaled, },
734             { SPR_BOSS2_W1, pis_scaled, },
735             { SPR_BOSS2_W2, pis_scaled, },
736             { SPR_BOSS2_W3, pis_scaled, },
737             { SPR_BOSS2_W4, pis_scaled, },
738             { SPR_BOSS3_W1, pis_scaled, },
739             { SPR_BOSS3_W2, pis_scaled, },
740             { SPR_BOSS3_W3, pis_scaled, },
741             { SPR_BOSS3_W4, pis_scaled, },
742             { SPR_BOSS4_W1, pis_scaled, },
743             { SPR_BOSS4_W2, pis_scaled, },
744             { SPR_BOSS4_W3, pis_scaled, },
745             { SPR_BOSS4_W4, pis_scaled, },
746             { SPR_BOSS5_W1, pis_scaled, },
747             { SPR_BOSS5_W2, pis_scaled, },
748             { SPR_BOSS5_W3, pis_scaled, },
749             { SPR_BOSS5_W4, pis_scaled, },
750             { SPR_BOSS6_W1, pis_scaled, },
751             { SPR_BOSS6_W2, pis_scaled, },
752             { SPR_BOSS6_W3, pis_scaled, },
753             { SPR_BOSS6_W4, pis_scaled, },
754             { H_ALTPIC, pis_pic, },
755             { H_CTRLPIC, pis_pic, },
756             { H_SPACEPIC, pis_pic, },
757             { H_PAUSEPIC, pis_pic, },
758             { H_ESCPIC, pis_pic, },
759             { H_LTARROWPIC, pis_pic, },
760             { H_UPARROWPIC, pis_pic, },
761             { H_DNARROWPIC, pis_pic, },
762             { H_RTARROWPIC, pis_pic, },
763             { H_QPIC, pis_pic, },
764             { H_WPIC, pis_pic, },
765             { H_EPIC, pis_pic, },
766             { H_IPIC, pis_pic, },
767             { H_HPIC, pis_pic, },
768             { H_1PIC, pis_pic, },
769             { H_2PIC, pis_pic, },
770             { H_3PIC, pis_pic, },
771             { H_4PIC, pis_pic, },
772             { H_5PIC, pis_pic, },
773             { H_F1PIC, pis_pic, },
774             { H_F2PIC, pis_pic, },
775             { H_F3PIC, pis_pic, },
776             { H_F4PIC, pis_pic, },
777             { H_F5PIC, pis_pic, },
778             { H_F6PIC, pis_pic, },
779             { H_F7PIC, pis_pic, },
780             { H_F8PIC, pis_pic, },
781             { H_F9PIC, pis_pic, },
782             { H_F10PIC, pis_pic, },
783             { H_ENTERPIC, pis_pic, },
784             { H_TABPIC, pis_pic, },
785             { H_CPIC, pis_pic, },
786             { H_FPIC, pis_pic, },
787             { SPR_CRATE_1, pis_scaled, },
788             { SPR_GSCOUT_W1_1, pis_scaled, },
789             { SPR_FSCOUT_W1_1, pis_scaled, },
790             { APOGEE_LOGOPIC, pis_pic, },
791             { VISAPIC, pis_pic, },
792             { MCPIC, pis_pic, },
793             { FAXPIC, pis_pic, },
794             { H_LPIC, pis_pic, },
795             { H_SHIFTPIC, pis_pic, },
796         }; // piShapeTable
797     } else if (::is_aog_full_v3_0()) {
798         piShapeTable = {
799             { SPR_GREEN_OOZE1, pis_scaled, },
800             { SPR_STAT_32, pis_scaled, },
801             { SPR_STAT_33, pis_scaled, },
802             { SPR_STAT_34, pis_scaled, },
803             { SPR_STAT_35, pis_scaled, },
804             { SPR_STAT_36, pis_scaled, },
805             { SPR_STAT_26, pis_scaled, },
806             { SPR_STAT_24, pis_scaled, },
807             { SPR_STAT_27, pis_scaled, },
808             { SPR_STAT_28, pis_scaled, },
809             { SPR_STAT_29, pis_scaled, },
810             { SPR_STAT_30, pis_scaled, },
811             { SPR_STAT_48, pis_scaled, },
812             { SPR_STAT_49, pis_scaled, },
813             { SPR_STAT_50, pis_scaled, },
814             { SPR_STAT_51, pis_scaled, },
815             { SPR_STAT_42, pis_scaled, },
816             { SPR_STAT_44, pis_scaled, },
817             { SPR_STAT_40, pis_scaled, },
818             { SPR_STAT_0, pis_scaled, },
819             { SPR_RENT_W1_8, pis_scaled, },
820             { SPR_RENT_W2_8, pis_scaled, },
821             { SPR_RENT_W3_8, pis_scaled, },
822             { SPR_RENT_W4_8, pis_scaled, },
823             { SPR_TERROT_1, pis_scaled, },
824             { SPR_TERROT_2, pis_scaled, },
825             { SPR_TERROT_3, pis_scaled, },
826             { SPR_TERROT_4, pis_scaled, },
827             { SPR_TERROT_5, pis_scaled, },
828             { SPR_TERROT_6, pis_scaled, },
829             { SPR_TERROT_7, pis_scaled, },
830             { SPR_TERROT_8, pis_scaled, },
831             { SPR_STAT_77, pis_scaled, },
832             { SPR_STAT_78, pis_scaled, },
833             { SPR_STAT_79, pis_scaled, },
834             { 14 * 2, pis_scwall, },
835             { 16 * 2, pis_scwall, },
836             { 20 * 2 + 1, pis_scwall, },
837             { 44 * 2, pis_scwall, },
838             { 31 * 2, pis_scwall, },
839             { BIGGOLDSTERNPIC, pis_pic, },
840             { STARLOGOPIC, pis_pic, },
841             { BLAKEWITHGUNPIC, pis_pic, },
842             { STARINSTITUTEPIC, pis_pic, },
843             { MEDALOFHONORPIC, pis_pic, },
844             { SMALLGOLDSTERNPIC, pis_pic, },
845             { BLAKEWINPIC, pis_pic, },
846             { AUTOMAPPIC, pis_pic, },
847             { SPR_ELEC_POST1, pis_scaled, },
848             { SPR_ELEC_POST2, pis_scaled, },
849             { SPR_ELEC_POST3, pis_scaled, },
850             { SHUTTLEEXPPIC, pis_pic, },
851             { PLANETSPIC, pis_pic, },
852             { SPR_VITAL_STAND, pis_scaled, },
853             { H_PPIC, pis_pic, },
854             { MOUSEPIC, pis_pic, },
855             { SPR_OFC_W1_8, pis_scaled, },
856             { SPR_OFC_W2_8, pis_scaled, },
857             { SPR_OFC_W3_8, pis_scaled, },
858             { SPR_OFC_W4_8, pis_scaled, },
859             { SPR_POD_WALK1, pis_scaled, },
860             { SPR_POD_WALK2, pis_scaled, },
861             { SPR_POD_WALK3, pis_scaled, },
862             { SPR_POD_WALK4, pis_scaled, },
863             { SPR_ELEC_WALK1, pis_scaled, },
864             { SPR_ELEC_WALK2, pis_scaled, },
865             { SPR_ELEC_WALK3, pis_scaled, },
866             { SPR_ELEC_WALK4, pis_scaled, },
867             { SPR_ELECTRO_SPHERE_ROAM1, pis_scaled, },
868             { SPR_ELECTRO_SPHERE_ROAM2, pis_scaled, },
869             { SPR_ELECTRO_SPHERE_ROAM3, pis_scaled, },
870             { SPR_PRO_W1_8, pis_scaled, },
871             { SPR_PRO_W2_8, pis_scaled, },
872             { SPR_PRO_W3_8, pis_scaled, },
873             { SPR_PRO_W4_8, pis_scaled, },
874             { SPR_GENETIC_W1, pis_scaled, },
875             { SPR_GENETIC_W2, pis_scaled, },
876             { SPR_GENETIC_W3, pis_scaled, },
877             { SPR_GENETIC_W4, pis_scaled, },
878             { SPR_MUTHUM1_W1, pis_scaled, },
879             { SPR_MUTHUM1_W2, pis_scaled, },
880             { SPR_MUTHUM1_W3, pis_scaled, },
881             { SPR_MUTHUM1_W4, pis_scaled, },
882             { SPR_MUTHUM2_W1, pis_scaled, },
883             { SPR_MUTHUM2_W2, pis_scaled, },
884             { SPR_MUTHUM2_W3, pis_scaled, },
885             { SPR_MUTHUM2_W4, pis_scaled, },
886             { SPR_LCAN_ALIEN_READY, pis_scaled, },
887             { SPR_LCAN_ALIEN_W1, pis_scaled, },
888             { SPR_LCAN_ALIEN_W2, pis_scaled, },
889             { SPR_LCAN_ALIEN_W3, pis_scaled, },
890             { SPR_LCAN_ALIEN_W4, pis_scaled, },
891             { SPR_SCAN_ALIEN_READY, pis_scaled, },
892             { SPR_SCAN_ALIEN_W1, pis_scaled, },
893             { SPR_SCAN_ALIEN_W2, pis_scaled, },
894             { SPR_SCAN_ALIEN_W3, pis_scaled, },
895             { SPR_SCAN_ALIEN_W4, pis_scaled, },
896             { SPR_GURNEY_MUT_READY, pis_scaled, },
897             { SPR_GURNEY_MUT_W1, pis_scaled, },
898             { SPR_GURNEY_MUT_W2, pis_scaled, },
899             { SPR_GURNEY_MUT_W3, pis_scaled, },
900             { SPR_GURNEY_MUT_W4, pis_scaled, },
901             { SPR_LIQUID_S1, pis_scaled, },
902             { SPR_LIQUID_S2, pis_scaled, },
903             { SPR_LIQUID_S3, pis_scaled, },
904             { SPR_SWAT_W1_8, pis_scaled, },
905             { SPR_SWAT_W2_8, pis_scaled, },
906             { SPR_SWAT_W3_8, pis_scaled, },
907             { SPR_SWAT_W4_8, pis_scaled, },
908             { SPR_GOLD_W1_8, pis_scaled, },
909             { SPR_GOLD_W2_8, pis_scaled, },
910             { SPR_GOLD_W3_8, pis_scaled, },
911             { SPR_GOLD_W4_8, pis_scaled, },
912             { JOYSTICKPIC, pis_pic, },
913             { SPR_GSCOUT_W1_8, pis_scaled, },
914             { SPR_GSCOUT_W2_8, pis_scaled, },
915             { SPR_GSCOUT_W3_8, pis_scaled, },
916             { SPR_GSCOUT_W4_8, pis_scaled, },
917             { SPR_FSCOUT_W1_8, pis_scaled, },
918             { SPR_FSCOUT_W2_8, pis_scaled, },
919             { SPR_FSCOUT_W3_8, pis_scaled, },
920             { SPR_FSCOUT_W4_8, pis_scaled, },
921             { SPR_VITAL_STAND, pis_scaled, },
922             { SPR_ELEC_SHOT1, pis_scaled, },
923             { SPR_ELEC_SHOT2, pis_scaled, },
924             { SPR_SECURITY_NORMAL, pis_scaled, },
925             { SPR_SECURITY_ALERT, pis_scaled, },
926             { SPR_LIQUID_SHOT_FLY_1, pis_scaled, },
927             { SPR_LIQUID_SHOT_FLY_2, pis_scaled, },
928             { SPR_LIQUID_SHOT_FLY_3, pis_scaled, },
929             { SPR_POD_EGG, pis_scaled, },
930             { SPR_DECO_ARC_1, pis_scaled, },
931             { SPR_DECO_ARC_2, pis_scaled, },
932             { SPR_DECO_ARC_3, pis_scaled, },
933             { GRAVISPADPIC, pis_pic, },
934             { H_MPIC, pis_pic, },
935             { SPR_CANDY_BAR, pis_scaled, },
936             { SPR_SANDWICH, pis_scaled, },
937             { SPR_STAT_46, pis_scaled, },
938             { SPR_EXPLOSION_3, pis_scaled, },
939             { SPR_BLACK_OOZE1, pis_scaled, },
940             { SPR_ELEC_ARC1, pis_scaled, },
941             { SPR_ELEC_ARC2, pis_scaled, },
942             { SPR_ELEC_ARC3, pis_scaled, },
943             { C_EPISODE1PIC, pis_pic, },
944             { C_EPISODE2PIC, pis_pic, },
945             { C_EPISODE3PIC, pis_pic, },
946             { C_EPISODE4PIC, pis_pic, },
947             { C_EPISODE5PIC, pis_pic, },
948             { C_EPISODE6PIC, pis_pic, },
949             { SPR_BOSS1_W1, pis_scaled, },
950             { SPR_BOSS1_W2, pis_scaled, },
951             { SPR_BOSS1_W3, pis_scaled, },
952             { SPR_BOSS1_W4, pis_scaled, },
953             { SPR_BOSS2_W1, pis_scaled, },
954             { SPR_BOSS2_W2, pis_scaled, },
955             { SPR_BOSS2_W3, pis_scaled, },
956             { SPR_BOSS2_W4, pis_scaled, },
957             { SPR_BOSS3_W1, pis_scaled, },
958             { SPR_BOSS3_W2, pis_scaled, },
959             { SPR_BOSS3_W3, pis_scaled, },
960             { SPR_BOSS3_W4, pis_scaled, },
961             { SPR_BOSS4_W1, pis_scaled, },
962             { SPR_BOSS4_W2, pis_scaled, },
963             { SPR_BOSS4_W3, pis_scaled, },
964             { SPR_BOSS4_W4, pis_scaled, },
965             { SPR_BOSS5_W1, pis_scaled, },
966             { SPR_BOSS5_W2, pis_scaled, },
967             { SPR_BOSS5_W3, pis_scaled, },
968             { SPR_BOSS5_W4, pis_scaled, },
969             { SPR_BOSS6_W1, pis_scaled, },
970             { SPR_BOSS6_W2, pis_scaled, },
971             { SPR_BOSS6_W3, pis_scaled, },
972             { SPR_BOSS6_W4, pis_scaled, },
973             { H_ALTPIC, pis_pic, },
974             { H_CTRLPIC, pis_pic, },
975             { H_SPACEPIC, pis_pic, },
976             { H_PAUSEPIC, pis_pic, },
977             { H_ESCPIC, pis_pic, },
978             { H_LTARROWPIC, pis_pic, },
979             { H_UPARROWPIC, pis_pic, },
980             { H_DNARROWPIC, pis_pic, },
981             { H_RTARROWPIC, pis_pic, },
982             { H_QPIC, pis_pic, },
983             { H_WPIC, pis_pic, },
984             { H_EPIC, pis_pic, },
985             { H_IPIC, pis_pic, },
986             { H_HPIC, pis_pic, },
987             { H_1PIC, pis_pic, },
988             { H_2PIC, pis_pic, },
989             { H_3PIC, pis_pic, },
990             { H_4PIC, pis_pic, },
991             { H_5PIC, pis_pic, },
992             { H_F1PIC, pis_pic, },
993             { H_F2PIC, pis_pic, },
994             { H_F3PIC, pis_pic, },
995             { H_F4PIC, pis_pic, },
996             { H_F5PIC, pis_pic, },
997             { H_F6PIC, pis_pic, },
998             { H_F7PIC, pis_pic, },
999             { H_F8PIC, pis_pic, },
1000             { H_F9PIC, pis_pic, },
1001             { H_F10PIC, pis_pic, },
1002             { H_ENTERPIC, pis_pic, },
1003             { H_TABPIC, pis_pic, },
1004             { H_CPIC, pis_pic, },
1005             { H_FPIC, pis_pic, },
1006             { SPR_CRATE_1, pis_scaled, },
1007             { SPR_GSCOUT_W1_1, pis_scaled, },
1008             { SPR_FSCOUT_W1_1, pis_scaled, },
1009             { APOGEE_LOGOPIC, pis_pic, },
1010             { VISAPIC, pis_pic, },
1011             { MCPIC, pis_pic, },
1012             { FAXPIC, pis_pic, },
1013             { H_LPIC, pis_pic, },
1014             { H_SHIFTPIC, pis_pic, },
1015             { PSPROMO1PIC, pis_pic, },
1016             { PSPROMO2PIC, pis_pic, },
1017             { PSPROMO3PIC, pis_pic, },
1018         }; // piShapeTable
1019     } else if (::is_ps()) {
1020         piShapeTable = {
1021             { SPR_GREEN_OOZE1, pis_scaled, }, // 0 - Green Ooze
1022             { SPR_STAT_32, pis_scaled, }, // 1 - Red Key
1023             { SPR_STAT_33, pis_scaled, }, // 2 - Yellow Key
1024             { SPR_STAT_34, pis_scaled, }, // 3 - Green Key
1025             { SPR_STAT_35, pis_scaled, }, // 4 - Blue Key
1026             { SPR_STAT_36, pis_scaled, }, // 5 - Gold Key
1027             { SPR_STAT_26, pis_scaled, }, // 6 - Charge Unit
1028             { SPR_STAT_24, pis_scaled, }, // 7 - PISTOL
1029             { SPR_STAT_27, pis_scaled, }, // 8 - Auto-Burst Rifle
1030             { SPR_STAT_28, pis_scaled, }, // 9 - Particle Charged ION
1031             { SPR_STAT_29, pis_scaled, }, // 10 - First Aid
1032             { SPR_STAT_30, pis_scaled, }, // 11 - Full Heal
1033             { SPR_STAT_48, pis_scaled, }, // 12 - money bag
1034             { SPR_STAT_49, pis_scaled, }, // 13 - loot
1035             { SPR_STAT_50, pis_scaled, }, // 14 - gold
1036             { SPR_STAT_51, pis_scaled, }, // 15 - bonus
1037             { SPR_STAT_42, pis_scaled, }, // 16 - Chicken Leg
1038             { SPR_STAT_44, pis_scaled, }, // 17 - Ham
1039             { SPR_STAT_40, pis_scaled, }, // 18 - Full Water Bowl
1040             { SPR_STAT_0, pis_scaled, }, // 19 - Water Puddle
1041             { SPR_RENT_W1_8, pis_scaled, }, // 20 - rentacopobj, Walking
1042             { SPR_RENT_W2_8, pis_scaled, }, // 21 - rentacopobj, Walking
1043             { SPR_RENT_W3_8, pis_scaled, }, // 22 - rentacopobj, Walking
1044             { SPR_RENT_W4_8, pis_scaled, }, // 23 - rentacopobj, Walking
1045             { SPR_TERROT_1, pis_scaled, }, // 24 - hang_terrotobj, Rotating
1046             { SPR_TERROT_2, pis_scaled, }, // 25 - hang_terrotobj, Rotating
1047             { SPR_TERROT_3, pis_scaled, }, // 26 - hang_terrotobj, Rotating
1048             { SPR_TERROT_4, pis_scaled, }, // 27 - hang_terrotobj, Rotating
1049             { SPR_TERROT_5, pis_scaled, }, // 28 - hang_terrotobj, Rotating
1050             { SPR_TERROT_6, pis_scaled, }, // 29 - hang_terrotobj, Rotating
1051             { SPR_TERROT_7, pis_scaled, }, // 30 - hang_terrotobj, Rotating
1052             { SPR_TERROT_8, pis_scaled, }, // 31 - hang_terrotobj, Rotating
1053             { SPR_STAT_77, pis_scaled, }, // 32 - 1 Credit Food Unit Token
1054             { SPR_STAT_78, pis_scaled, }, // 33 - 5 Credit Food Unit Token
1055             { SPR_STAT_79, pis_scaled, }, // 34 - Auto-Charge Pistol
1056             { 14 * 2, pis_scwall, }, // 35 - Food Unit Wall
1057             { 16 * 2, pis_scwall, }, // 36 - Terminal Wall
1058             { 20 * 2 + 1, pis_scwall, }, // 37 - Teleport w/Pannel on it
1059             { 44 * 2, pis_scwall, }, // 38 - Barrier Switch Wall
1060             { 31 * 2, pis_scwall, }, // 39 - Warp Tile
1061             { BIGGOLDSTERNPIC, pis_pic, }, // 40 - Big Goldstern
1062             { STARLOGOPIC, pis_pic, }, // 41 - Star Logo
1063             { BLAKEWITHGUNPIC, pis_pic, }, // 42 - Blake With Gun
1064             { STARINSTITUTEPIC, pis_pic, }, // 43 - Star Institute
1065             { MEDALOFHONORPIC, pis_pic, }, // 44 - Medal Of Honor
1066             { SMALLGOLDSTERNPIC, pis_pic, }, // 45 - Small Goldstern
1067             { BLAKEWINPIC, pis_pic, }, // 46 - Blake Win
1068             { AUTOMAPPIC, pis_pic, }, // 47 - AutoMap Pic
1069             { SPR_ELEC_POST1, pis_scaled, }, // 48 - Barrier Post 1
1070             { SPR_ELEC_POST2, pis_scaled, }, // 49 - Barrier Post 2
1071             { SPR_ELEC_POST3, pis_scaled, }, // 50 - Barrier Post 3
1072             { SHUTTLEEXPPIC, pis_pic, }, // 51 - Shuttle Explode
1073             { PLANETSPIC, pis_pic, }, // 52 - Planets Pic
1074             { SPR_CUBE1, pis_scaled, }, // 53 - Rotating Cube
1075             { H_PPIC, pis_pic, }, // 54 - P key
1076             { MOUSEPIC, pis_pic, }, // 55 - Mouse Pad
1077             { SPR_OFC_W1_8, pis_scaled, }, // 56 - gen_scientist, walking
1078             { SPR_OFC_W2_8, pis_scaled, }, // 57 - gen_scientist, walking
1079             { SPR_OFC_W3_8, pis_scaled, }, // 58 - gen_scientist, walking
1080             { SPR_OFC_W4_8, pis_scaled, }, // 59 - gen_scientist, walking
1081             { SPR_POD_WALK1, pis_scaled, }, // 60 - podalien - walking
1082             { SPR_POD_WALK2, pis_scaled, }, // 61 - podalien - walking
1083             { SPR_POD_WALK3, pis_scaled, }, // 62 - podalien - walking
1084             { SPR_POD_WALK4, pis_scaled, }, // 63 - podalien - walking
1085             { SPR_ELEC_WALK1, pis_scaled, }, // 64 - electro alien - walking
1086             { SPR_ELEC_WALK2, pis_scaled, }, // 65 - electro alien - walking
1087             { SPR_ELEC_WALK3, pis_scaled, }, // 66 - electro alien - walking
1088             { SPR_ELEC_WALK4, pis_scaled, }, // 67 - electro alien - walking
1089             { SPR_ELECTRO_SPHERE_ROAM1, pis_scaled, }, // 68 - electrosphere - Roaming
1090             { SPR_ELECTRO_SPHERE_ROAM2, pis_scaled, }, // 69 - electrosphere - Roaming
1091             { SPR_ELECTRO_SPHERE_ROAM3, pis_scaled, }, // 70 - electrosphere - Roaming
1092             { SPR_PRO_W1_8, pis_scaled, }, // 71 - proguard - Walking
1093             { SPR_PRO_W2_8, pis_scaled, }, // 72 - proguard - Walking
1094             { SPR_PRO_W3_8, pis_scaled, }, // 73 - proguard - Walking
1095             { SPR_PRO_W4_8, pis_scaled, }, // 74 - proguard - Walking
1096             { SPR_GENETIC_W1, pis_scaled, }, // 75 - genetic_guard - Walking
1097             { SPR_GENETIC_W2, pis_scaled, }, // 76 - genetic_guard - Walking
1098             { SPR_GENETIC_W3, pis_scaled, }, // 77 - genetic_guard - Walking
1099             { SPR_GENETIC_W4, pis_scaled, }, // 78 - genetic_guard - Walking
1100             { SPR_MUTHUM1_W1, pis_scaled, }, // 79 - mutant_human1 - walking
1101             { SPR_MUTHUM1_W2, pis_scaled, }, // 80 - mutant_human1 - walking
1102             { SPR_MUTHUM1_W3, pis_scaled, }, // 81 - mutant_human1 - walking
1103             { SPR_MUTHUM1_W4, pis_scaled, }, // 82 - mutant_human1 - walking
1104             { SPR_MUTHUM2_W1, pis_scaled, }, // 83 - mutant_human2 - walking
1105             { SPR_MUTHUM2_W2, pis_scaled, }, // 84 - mutant_human2 - walking
1106             { SPR_MUTHUM2_W3, pis_scaled, }, // 85 - mutant_human2 - walking
1107             { SPR_MUTHUM2_W4, pis_scaled, }, // 86 - mutant_human2 - walking
1108             { SPR_LCAN_ALIEN_READY, pis_scaled, }, // 87 - Large canister for lg_Aln
1109             { SPR_LCAN_ALIEN_W1, pis_scaled, }, // 88 - Large Canister Alien
1110             { SPR_LCAN_ALIEN_W2, pis_scaled, }, // 89 - Large Canister Alien
1111             { SPR_LCAN_ALIEN_W3, pis_scaled, }, // 90 - Large Canister Alien
1112             { SPR_LCAN_ALIEN_W4, pis_scaled, }, // 91 - Large Canister Alien
1113             { SPR_SCAN_ALIEN_READY, pis_scaled, }, // 92 - Small Cansiter
1114             { SPR_SCAN_ALIEN_W1, pis_scaled, }, // 93 - Sm Can Alien - Walking
1115             { SPR_SCAN_ALIEN_W2, pis_scaled, }, // 94 - Sm Can Alien - Walking
1116             { SPR_SCAN_ALIEN_W3, pis_scaled, }, // 95 - Sm Can Alien - Walking
1117             { SPR_SCAN_ALIEN_W4, pis_scaled, }, // 96 - Sm Can Alien - Walking
1118             { SPR_GURNEY_MUT_READY, pis_scaled, }, // 97 - Gurney Mutant on gurney
1119             { SPR_GURNEY_MUT_W1, pis_scaled, }, // 98  - Gurney Mutant - Walking
1120             { SPR_GURNEY_MUT_W2, pis_scaled, }, // 99  - Gurney Mutant - Walking
1121             { SPR_GURNEY_MUT_W3, pis_scaled, }, // 100 - Gurney Mutant - Walking
1122             { SPR_GURNEY_MUT_W4, pis_scaled, }, // 101 - Gurney Mutant - Walking
1123             { SPR_LIQUID_S1, pis_scaled, }, // 102 - liquid Alien - Shooting
1124             { SPR_LIQUID_S2, pis_scaled, }, // 103 - liquid Alien - Shooting
1125             { SPR_LIQUID_S3, pis_scaled, }, // 104 - liquid Alien - Shooting
1126             { SPR_SWAT_W1_8, pis_scaled, }, // 105 - SWAT guard - Walking
1127             { SPR_SWAT_W2_8, pis_scaled, }, // 106 - SWAT guard - Walking
1128             { SPR_SWAT_W3_8, pis_scaled, }, // 107 - SWAT guard - Walking
1129             { SPR_SWAT_W4_8, pis_scaled, }, // 108 - SWAT guard - Walking
1130             { SPR_GOLD_W1_8, pis_scaled, }, // 109 - Dr Goldstern - Walking
1131             { SPR_GOLD_W2_8, pis_scaled, }, // 110 - Dr Goldstern - Walking
1132             { SPR_GOLD_W3_8, pis_scaled, }, // 111 - Dr Goldstern - Walking
1133             { SPR_GOLD_W4_8, pis_scaled, }, // 112 - Dr Goldstern - Walking
1134             { JOYSTICKPIC, pis_pic, }, // 113 - Joystick
1135             { SPR_GSCOUT_W1_8, pis_scaled, }, // 114 - Volatile Transport - moving
1136             { SPR_GSCOUT_W2_8, pis_scaled, }, // 115 - Volatile Transport - moving
1137             { SPR_GSCOUT_W3_8, pis_scaled, }, // 116 - Volatile Transport - moving
1138             { SPR_GSCOUT_W4_8, pis_scaled, }, // 117 - Volatile Transport - moving
1139             { SPR_FSCOUT_W1_8, pis_scaled, }, // 118 - Floating Bomb - moving
1140             { SPR_FSCOUT_W2_8, pis_scaled, }, // 119 - Floating Bomb - moving
1141             { SPR_FSCOUT_W3_8, pis_scaled, }, // 120 - Floating Bomb - moving
1142             { SPR_FSCOUT_W4_8, pis_scaled, }, // 121 - Floating Bomb - moving
1143             { SPR_CUBE1, pis_scaled, }, // 122 - ** OPEN **
1144             { SPR_ELEC_SHOT1, pis_scaled, }, // 123 - Electro Aln Shot - floating
1145             { SPR_ELEC_SHOT2, pis_scaled, }, // 124 - Electro Aln Shot - floating
1146             { SPR_SECURITY_NORMAL, pis_scaled, }, // 125 - Security_light - normal
1147             { SPR_SECURITY_ALERT, pis_scaled, }, // 126 - Security_light - Alerted
1148             { SPR_LIQUID_SHOT_FLY_1, pis_scaled, }, // 127 - Liquid Aln Sht - float'n
1149             { SPR_LIQUID_SHOT_FLY_2, pis_scaled, }, // 128 - Liquid Aln Sht - float'n
1150             { SPR_LIQUID_SHOT_FLY_3, pis_scaled, }, // 129 - Liquid Aln Sht - float'n
1151             { SPR_POD_EGG, pis_scaled, }, // 130 - POD Alien Egg
1152             { SPR_DECO_ARC_1, pis_scaled, }, // 131 - DecoArc
1153             { SPR_DECO_ARC_2, pis_scaled, }, // 132 - DecoArc
1154             { SPR_DECO_ARC_3, pis_scaled, }, // 133 - DecoArc
1155             { GRAVISPADPIC, pis_pic, }, // 134 - Gravis Pad
1156             { H_MPIC, pis_pic, }, // 135 - M key
1157             { SPR_CANDY_BAR, pis_scaled, }, // 136 - Candy bar
1158             { SPR_SANDWICH, pis_scaled, }, // 137 - Sandwich
1159             { SPR_STAT_46, pis_scaled, }, // 138 - Grenade Launcher
1160             { SPR_EXPLOSION_3, pis_scaled, }, // 139 - General Explosion
1161             { SPR_BLACK_OOZE1, pis_scaled, }, // 140 - Black Ooze
1162             { SPR_ELEC_ARC1, pis_scaled, }, // 141 - Electric Arc Barrier 1
1163             { SPR_ELEC_ARC2, pis_scaled, }, // 142 - Electric Arc Barrier 2
1164             { SPR_ELEC_ARC3, pis_scaled, }, // 143 - Electric Arc Barrier 3
1165             { C_EPISODE1PIC, pis_pic, }, // 144 - STAR Institute
1166             { C_EPISODE2PIC, pis_pic, }, // 145 - Floating Fortress
1167             { C_EPISODE3PIC, pis_pic, }, // 146 - Underground Network
1168             { C_EPISODE4PIC, pis_pic, }, // 147 - STAR Port
1169             { C_EPISODE5PIC, pis_pic, }, // 148 - Habitat II
1170             { C_EPISODE6PIC, pis_pic, }, // 149 - Defense Center
1171             { SPR_BOSS1_W1, pis_scaled, }, // 150 - Boss 1 - walking
1172             { SPR_BOSS1_W2, pis_scaled, }, // 151 - Boss 1 - walking
1173             { SPR_BOSS1_W3, pis_scaled, }, // 152 - Boss 1 - walking
1174             { SPR_BOSS1_W4, pis_scaled, }, // 153 - Boss 1 - walking
1175             { SPR_BOSS2_W1, pis_scaled, }, // 154 - Boss 2 - walking
1176             { SPR_BOSS2_W2, pis_scaled, }, // 155 - Boss 2 - walking
1177             { SPR_BOSS2_W3, pis_scaled, }, // 156 - Boss 2 - walking
1178             { SPR_BOSS2_W4, pis_scaled, }, // 157 - Boss 2 - walking
1179             { SPR_BOSS3_W1, pis_scaled, }, // 158 - Boss 3 - walking
1180             { SPR_BOSS3_W2, pis_scaled, }, // 159 - Boss 3 - walking
1181             { SPR_BOSS3_W3, pis_scaled, }, // 160 - Boss 3 - walking
1182             { SPR_BOSS3_W4, pis_scaled, }, // 161 - Boss 3 - walking
1183             { SPR_BOSS4_W1, pis_scaled, }, // 162 - Boss 4 - walking
1184             { SPR_BOSS4_W2, pis_scaled, }, // 163 - Boss 4 - walking
1185             { SPR_BOSS4_W3, pis_scaled, }, // 164 - Boss 4 - walking
1186             { SPR_BOSS4_W4, pis_scaled, }, // 165 - Boss 4 - walking
1187             { SPR_BOSS5_W1, pis_scaled, }, // 166 - Boss 5 - walking
1188             { SPR_BOSS5_W2, pis_scaled, }, // 167 - Boss 5 - walking
1189             { SPR_BOSS5_W3, pis_scaled, }, // 168 - Boss 5 - walking
1190             { SPR_BOSS5_W4, pis_scaled, }, // 169 - Boss 5 - walking
1191             { SPR_BOSS6_W1, pis_scaled, }, // 170 - Boss 6 - walking
1192             { SPR_BOSS6_W2, pis_scaled, }, // 171 - Boss 6 - walking
1193             { SPR_BOSS6_W3, pis_scaled, }, // 172 - Boss 6 - walking
1194             { SPR_BOSS6_W4, pis_scaled, }, // 173 - Boss 6 - walking
1195             { H_ALTPIC, pis_pic, }, // 174 - ALT key
1196             { H_CTRLPIC, pis_pic, }, // 175 - CTRL key
1197             { H_SPACEPIC, pis_pic, }, // 176 - SPACE key
1198             { H_PAUSEPIC, pis_pic, }, // 177 - PAUSE key
1199             { H_ESCPIC, pis_pic, }, // 178 - ESC key
1200             { H_LTARROWPIC, pis_pic, }, // 179 - LEFT ARROW key
1201             { H_UPARROWPIC, pis_pic, }, // 180 - UP ARROW key
1202             { H_DNARROWPIC, pis_pic, }, // 181 - DOWN ARROW key
1203             { H_RTARROWPIC, pis_pic, }, // 182 - RIGHT ARROW key
1204             { H_QPIC, pis_pic, }, // 183 - Q key
1205             { H_WPIC, pis_pic, }, // 184 - W key
1206             { H_EPIC, pis_pic, }, // 185 - E key
1207             { H_IPIC, pis_pic, }, // 186 - I key
1208             { H_HPIC, pis_pic, }, // 187 - H key
1209             { H_1PIC, pis_pic, }, // 188 - 1 key
1210             { H_2PIC, pis_pic, }, // 189 - 2 key
1211             { H_3PIC, pis_pic, }, // 190 - 3 key
1212             { H_4PIC, pis_pic, }, // 191 - 4 key
1213             { H_5PIC, pis_pic, }, // 192 - 5 key
1214             { H_F1PIC, pis_pic, }, // 193 - F1 key
1215             { H_F2PIC, pis_pic, }, // 194 - F2 key
1216             { H_F3PIC, pis_pic, }, // 195 - F3 key
1217             { H_F4PIC, pis_pic, }, // 196 - F4 key
1218             { H_F5PIC, pis_pic, }, // 197 - F5 key
1219             { H_F6PIC, pis_pic, }, // 198 - F6 key
1220             { H_F7PIC, pis_pic, }, // 199 - F7 key
1221             { H_F8PIC, pis_pic, }, // 200 - F8 key
1222             { H_F9PIC, pis_pic, }, // 201 - F9 key
1223             { H_F10PIC, pis_pic, }, // 202 - F10 key
1224             { H_ENTERPIC, pis_pic, }, // 203 - ENTER key
1225             { H_TABPIC, pis_pic, }, // 204 - TAB key
1226             { H_CPIC, pis_pic, }, // 205 - C key
1227             { H_FPIC, pis_pic, }, // 206 - F key
1228             { SPR_CRATE_1, pis_scaled, }, // 207 - Crate
1229             { SPR_GSCOUT_W1_1, pis_scaled, }, // 208 - VMT
1230             { SPR_FSCOUT_W1_1, pis_scaled, }, // 209 - PerScan
1231             { APOGEE_LOGOPIC, pis_pic, }, // 210 - Apogee Logo
1232             { VISAPIC, pis_pic, }, // 211 - Visa Card
1233             { MCPIC, pis_pic, }, // 212 - Master Card
1234             { FAXPIC, pis_pic, }, // 213 - Fax Machine
1235             { H_LPIC, pis_pic, }, // 214 - L key
1236             { H_SHIFTPIC, pis_pic, }, // 215 - Shift key
1237             { SPR_DOORBOMB, pis_scaled, }, // 216 - DoorBomb
1238             { SPR_AUTOMAPPER, pis_scaled, }, // 217 - Radar Powerup.
1239             { STARPORTPIC, pis_pic, }, // 218 - Star Port
1240             { BOSSPIC, pis_pic, }, // 219 - AOG Boss
1241             { THREEPLANETSPIC, pis_pic, }, // 220 - Three Planets
1242             { SOLARSYSTEMPIC, pis_pic, }, // 221 - Solar System
1243             { AOGENDINGPIC, pis_pic, }, // 222 - AOG Ending
1244             { GFLOGOSPIC, pis_pic, }, // 223 - Goldfire 'n Logos
1245             { BLAKEHEADPIC, pis_pic, }, // 224 - Blake's Big Head
1246             { PROJECTFOLDERPIC, pis_pic, }, // 225 - Project Folder
1247             { SPR_GREEN2_OOZE1, pis_scaled, }, // 226 - Green2 Ooze
1248             { SPR_BLACK2_OOZE1, pis_scaled, }, // 227 - Black2 Ooze
1249             { SPR_STAT_34, pis_scaled, }, // 228 - BFG Cannon AKA Anti-Plasma Cannon
1250             { H_PLUSPIC, pis_pic, }, // 229 - PLUS key
1251             { SPR_DOORBOMB, pis_scaled, }, // 230 - Plasma Detonator
1252             { SPR_DETONATOR_EXP3, pis_scaled, }, // 231 - Plasma Detonator Explosion
1253             { SPR_MGOLD_WALK1, pis_scaled, }, // 232 - Morphed Dr Goldstern - Walking
1254             { SPR_MGOLD_WALK2, pis_scaled, }, // 233 - Morphed Dr Goldstern - Walking
1255             { SPR_MGOLD_WALK3, pis_scaled, }, // 234 - Morphed Dr Goldstern - Walking
1256             { SPR_MGOLD_WALK4, pis_scaled, }, // 235 - Morphed Dr Goldstern - Walking
1257             { H_MINUSPIC, pis_pic, }, // 236 - MINUS key
1258             { H_6PIC, pis_pic, }, // 237 - 6 KEY
1259             { H_TILDEPIC, pis_pic, }, // 238 - TILDE KEY
1260             { AUTOMAP_MAG1PIC, pis_pic, }, // 239 - AutoMap pic MAG1 (normal)
1261             { AUTOMAP_MAG2PIC, pis_pic, }, // 240 - AutoMap pic MAG2
1262             { AUTOMAP_MAG4PIC, pis_pic, }, // 241 - AutoMap pic MAG4
1263             { SPR_VPOST1, pis_scaled, }, // 242 - VPost Barrier
1264             { SPR_VPOST2, pis_scaled, }, // 243 - VPost Barrier
1265             { SPR_VPOST3, pis_scaled, }, // 244 - VPost Barrier
1266             { SPR_VPOST4, pis_scaled, }, // 245 - VPost Barrier
1267             { SPR_VPOST5, pis_scaled, }, // 246 - VPost Barrier
1268             { SPR_VPOST6, pis_scaled, }, // 247 - VPost Barrier
1269             { SPR_VPOST7, pis_scaled, }, // 248 - VPost Barrier
1270             { SPR_VPOST8, pis_scaled, }, // 249 - VPost Barrier
1271             { SPR_VSPIKE1, pis_scaled, }, // 250 - VSpike Barrier
1272             { SPR_VSPIKE2, pis_scaled, }, // 251 - VSpike Barrier
1273             { SPR_VSPIKE3, pis_scaled, }, // 252 - VSpike Barrier
1274             { SPR_VSPIKE4, pis_scaled, }, // 253 - VSpike Barrier
1275             { SPR_VSPIKE5, pis_scaled, }, // 254 - VSpike Barrier
1276             { SPR_VSPIKE6, pis_scaled, }, // 255 - VSpike Barrier
1277             { SPR_VSPIKE7, pis_scaled, }, // 256 - VSpike Barrier
1278             { SPR_VSPIKE8, pis_scaled, }, // 257 - VSpike Barrier
1279             { SPR_CUBE1, pis_scaled, }, // 258 - Security Cube - Rotating
1280             { SPR_CUBE2, pis_scaled, }, // 259 - Security Cube - Rotating
1281             { SPR_CUBE3, pis_scaled, }, // 260 - Security Cube - Rotating
1282             { SPR_CUBE4, pis_scaled, }, // 261 - Security Cube - Rotating
1283             { SPR_CUBE5, pis_scaled, }, // 262 - Security Cube - Rotating
1284             { SPR_CUBE6, pis_scaled, }, // 263 - Security Cube - Rotating
1285             { SPR_CUBE7, pis_scaled, }, // 264 - Security Cube - Rotating
1286             { SPR_CUBE8, pis_scaled, }, // 265 - Security Cube - Rotating
1287             { SPR_CUBE9, pis_scaled, }, // 266 - Security Cube - Rotating
1288             { SPR_CUBE10, pis_scaled, }, // 267 - Security Cube - Rotating
1289             { SPR_BOSS7_W1, pis_scaled, }, // 268 - Final Boss 1 Walking
1290             { SPR_BOSS7_W2, pis_scaled, }, // 269 - Final Boss 1 Walking
1291             { SPR_BOSS7_W3, pis_scaled, }, // 270 - Final Boss 1 Walking
1292             { SPR_BOSS7_W4, pis_scaled, }, // 271 - Final Boss 1 Walking
1293             { SPR_BOSS8_W1, pis_scaled, }, // 272 - Final Boss 2 Walking
1294             { SPR_BOSS8_W2, pis_scaled, }, // 273 - Final Boss 2 Walking
1295             { SPR_BOSS8_W3, pis_scaled, }, // 274 - Final Boss 2 Walking
1296             { SPR_BOSS8_W4, pis_scaled, }, // 275 - Final Boss 2 Walking
1297             { SPR_BOSS9_W1, pis_scaled, }, // 276 - Final Boss 3 Walking
1298             { SPR_BOSS9_W2, pis_scaled, }, // 277 - Final Boss 3 Walking
1299             { SPR_BOSS9_W3, pis_scaled, }, // 278 - Final Boss 3 Walking
1300             { SPR_BOSS9_W4, pis_scaled, }, // 279 - Final Boss 3 Walking
1301             { SPR_BOSS10_W1, pis_scaled, }, // 280 - Final Boss 4 Walking
1302             { SPR_BOSS10_W2, pis_scaled, }, // 281 - Final Boss 4 Walking
1303             { SPR_BOSS10_W3, pis_scaled, }, // 282 - Final Boss 4 Walking
1304             { SPR_BOSS10_W4, pis_scaled, }, // 283 - Final Boss 4 Walking
1305         }; // piShapeTable
1306     }
1307 }
1308 
1309 // anim table holds info about each different animation.
1310 PiAnimationInfos piAnimTable;
1311 
initialize_tp_animation_table()1312 void initialize_tp_animation_table()
1313 {
1314     if (::is_aog_sw()) {
1315         piAnimTable = {
1316             { 0, 0, 0, 0, 0, pia_grabscript, pid_cycle, },
1317             { 0, 0, 0, 0, 0, pia_grabscript, pid_cycle, },
1318             { 123, 0, 2, 0, 20, pia_shapetable, pid_cycle, },
1319             { 126, 0, 1, 0, 20, pia_shapetable, pid_cycle, },
1320             { 20, 0, 4, 0, 20, pia_shapetable, pid_cycle, },
1321             { 24, 0, 8, 0, 20, pia_shapetable, pid_cycle, },
1322             { 0, 0, 0, 0, 0, pia_grabscript, pid_cycle, },
1323             { 0, 0, 0, 0, 0, pia_grabscript, pid_cycle, },
1324             { 0, 0, 0, 0, 0, pia_grabscript, pid_cycle, },
1325             { 56, 0, 4, 0, 20, pia_shapetable, pid_cycle, },
1326             { 60, 0, 4, 0, 20, pia_shapetable, pid_cycle, },
1327             { 64, 0, 4, 0, 20, pia_shapetable, pid_cycle, },
1328             { 68, 0, 3, 0, 20, pia_shapetable, pid_cycle, },
1329             { 71, 0, 4, 0, 20, pia_shapetable, pid_cycle, },
1330             { 75, 0, 4, 0, 20, pia_shapetable, pid_cycle, },
1331             { 79, 0, 4, 0, 20, pia_shapetable, pid_cycle, },
1332             { 0, 0, 0, 0, 0, pia_grabscript, pid_cycle, },
1333             { 0, 0, 0, 0, 0, pia_grabscript, pid_cycle, },
1334             { 0, 0, 0, 0, 0, pia_grabscript, pid_cycle, },
1335             { 92, 0, 1, 0, 20, pia_shapetable, pid_cycle, },
1336             { 93, 0, 4, 0, 20, pia_shapetable, pid_cycle, },
1337             { 0, 0, 0, 0, 0, pia_grabscript, pid_cycle, },
1338             { 0, 0, 0, 0, 0, pia_grabscript, pid_cycle, },
1339             { 0, 0, 0, 0, 0, pia_grabscript, pid_cycle, },
1340             { 105, 0, 4, 0, 20, pia_shapetable, pid_cycle, },
1341             { 109, 0, 4, 0, 20, pia_shapetable, pid_cycle, },
1342             { 0, 0, 0, 0, 0, pia_grabscript, pid_cycle, },
1343             { 131, 0, 3, 0, 20, pia_shapetable, pid_cycle, },
1344             { 0, 0, 0, 0, 0, pia_grabscript, pid_cycle, },
1345             { 141, 0, 3, 0, 20, pia_shapetable, pid_cycle, },
1346             { 150, 0, 4, 0, 20, pia_shapetable, pid_cycle, },
1347             { 0, 0, 0, 0, 0, pia_grabscript, pid_cycle, },
1348             { 0, 0, 0, 0, 0, pia_grabscript, pid_cycle, },
1349             { 0, 0, 0, 0, 0, pia_grabscript, pid_cycle, },
1350             { 0, 0, 0, 0, 0, pia_grabscript, pid_cycle, },
1351             { 0, 0, 0, 0, 0, pia_grabscript, pid_cycle, },
1352             { 48, 0, 3, 0, 10, pia_shapetable, pid_cycle, },
1353             { 141, 0, 3, 0, 10, pia_shapetable, pid_cycle, },
1354             { 0, 0, 0, 0, 0, pia_grabscript, pid_cycle, },
1355             { 209, 0, 8, 0, 8, pia_grabscript, pid_cycle, },
1356         }; // piAnimTable
1357     } else if (::is_aog_full()) {
1358         piAnimTable = {
1359             { 0, 0, 0, 0, 0, pia_grabscript, pid_cycle, },
1360             { 0, 0, 0, 0, 0, pia_grabscript, pid_cycle, },
1361             { 123, 0, 2, 0, 20, pia_shapetable, pid_cycle, },
1362             { 126, 0, 1, 0, 20, pia_shapetable, pid_cycle, },
1363             { 20, 0, 4, 0, 20, pia_shapetable, pid_cycle, },
1364             { 24, 0, 8, 0, 20, pia_shapetable, pid_cycle, },
1365             { 0, 0, 0, 0, 0, pia_grabscript, pid_cycle, },
1366             { 0, 0, 0, 0, 0, pia_grabscript, pid_cycle, },
1367             { 0, 0, 0, 0, 0, pia_grabscript, pid_cycle, },
1368             { 56, 0, 4, 0, 20, pia_shapetable, pid_cycle, },
1369             { 60, 0, 4, 0, 20, pia_shapetable, pid_cycle, },
1370             { 64, 0, 4, 0, 20, pia_shapetable, pid_cycle, },
1371             { 68, 0, 3, 0, 20, pia_shapetable, pid_cycle, },
1372             { 71, 0, 4, 0, 20, pia_shapetable, pid_cycle, },
1373             { 75, 0, 4, 0, 20, pia_shapetable, pid_cycle, },
1374             { 79, 0, 4, 0, 20, pia_shapetable, pid_cycle, },
1375             { 83, 0, 4, 0, 20, pia_shapetable, pid_cycle, },
1376             { 87, 0, 1, 0, 20, pia_shapetable, pid_cycle, },
1377             { 88, 0, 4, 0, 20, pia_shapetable, pid_cycle, },
1378             { 92, 0, 1, 0, 20, pia_shapetable, pid_cycle, },
1379             { 93, 0, 4, 0, 20, pia_shapetable, pid_cycle, },
1380             { 97, 0, 1, 0, 20, pia_shapetable, pid_cycle, },
1381             { 98, 0, 4, 0, 20, pia_shapetable, pid_cycle, },
1382             { 102, 0, 3, 0, 20, pia_shapetable, pid_cycle, },
1383             { 105, 0, 4, 0, 20, pia_shapetable, pid_cycle, },
1384             { 109, 0, 4, 0, 20, pia_shapetable, pid_cycle, },
1385             { 0, 0, 0, 0, 0, pia_grabscript, pid_cycle, },
1386             { 131, 0, 3, 0, 20, pia_shapetable, pid_cycle, },
1387             { 0, 0, 0, 0, 0, pia_grabscript, pid_cycle, },
1388             { 141, 0, 3, 0, 20, pia_shapetable, pid_cycle, },
1389             { 150, 0, 4, 0, 20, pia_shapetable, pid_cycle, },
1390             { 154, 0, 4, 0, 20, pia_shapetable, pid_cycle, },
1391             { 158, 0, 4, 0, 20, pia_shapetable, pid_cycle, },
1392             { 162, 0, 4, 0, 20, pia_shapetable, pid_cycle, },
1393             { 166, 0, 4, 0, 20, pia_shapetable, pid_cycle, },
1394             { 170, 0, 4, 0, 20, pia_shapetable, pid_cycle, },
1395             { 48, 0, 3, 0, 10, pia_shapetable, pid_cycle, },
1396             { 141, 0, 3, 0, 10, pia_shapetable, pid_cycle, },
1397             { 208, 0, 8, 0, 10, pia_grabscript, pid_cycle, },
1398             { 209, 0, 8, 0, 8, pia_grabscript, pid_cycle, },
1399         }; // piAnimTable
1400     } else if (::is_ps()) {
1401         piAnimTable = {
1402             { 136, 0, 2, 0, 20, pia_shapetable, pid_cycle, }, // 0 -  OPEN
1403             { 127, 0, 3, 0, 20, pia_shapetable, pid_cycle, }, // 1 -  podeggobj,
1404             { 123, 0, 2, 0, 20, pia_shapetable, pid_cycle, }, // 2 -  electroshotobj,
1405             { 126, 0, 1, 0, 20, pia_shapetable, pid_cycle, }, // 3 -  security_lightobj - Alerted
1406             { 20, 0, 4, 0, 20, pia_shapetable, pid_cycle, }, // 4 -  rentacopobj,
1407             { 24, 0, 8, 0, 20, pia_shapetable, pid_cycle, }, // 5 -  hang_terrotobj,
1408             { 242, 0, 8, 0, 20, pia_shapetable, pid_rebound, }, // 6 -   VPost
1409             { 250, 0, 8, 0, 20, pia_shapetable, pid_rebound, }, // 7 -  VSpike
1410             { 258, 0, 10, 0, 10, pia_shapetable, pid_cycle, }, // 8 -   Security Cube
1411             { 56, 0, 4, 0, 20, pia_shapetable, pid_cycle, }, // 9 -  gen_scientistobj,
1412             { 60, 0, 4, 0, 20, pia_shapetable, pid_cycle, }, // 10 - podobj,
1413             { 64, 0, 4, 0, 20, pia_shapetable, pid_cycle, }, // 11 - electroobj,
1414             { 68, 0, 3, 0, 20, pia_shapetable, pid_cycle, }, // 12 - electrosphereobj,
1415             { 71, 0, 4, 0, 20, pia_shapetable, pid_cycle, }, // 13 -         proguardobj,
1416             { 75, 0, 4, 0, 20, pia_shapetable, pid_cycle, }, // 14 - genetic_guardobj,
1417             { 79, 0, 4, 0, 20, pia_shapetable, pid_cycle, }, // 15 - mutant_human1obj,
1418             { 83, 0, 4, 0, 20, pia_shapetable, pid_cycle, }, // 16 - mutant_human2obj,
1419             { 87, 0, 1, 0, 20, pia_shapetable, pid_cycle, }, // 17 - lcan_wait_alienobj,
1420             { 88, 0, 4, 0, 20, pia_shapetable, pid_cycle, }, // 18 - lcan_alienobj,
1421             { 92, 0, 1, 0, 20, pia_shapetable, pid_cycle, }, // 19 - scan_wait_alienobj,
1422             { 93, 0, 4, 0, 20, pia_shapetable, pid_cycle, }, // 20 - scan_alienobj,
1423             { 97, 0, 1, 0, 20, pia_shapetable, pid_cycle, }, // 21 -         gurney_waitobj,
1424             { 98, 0, 4, 0, 20, pia_shapetable, pid_cycle, }, // 22 - gurneyobj,
1425             { 102, 0, 3, 0, 20, pia_shapetable, pid_cycle, }, // 23 - liquidobj,
1426             { 105, 0, 4, 0, 20, pia_shapetable, pid_cycle, }, // 24 - swatobj,
1427             { 109, 0, 4, 0, 20, pia_shapetable, pid_cycle, }, // 25 - goldsternobj,
1428             { 113, 0, 1, 0, 20, pia_shapetable, pid_cycle, }, // 26 - OPEN
1429             { 131, 0, 3, 0, 20, pia_shapetable, pid_cycle, }, // 27 - flickerlightobj,
1430             { 134, 0, 2, 0, 20, pia_shapetable, pid_cycle, }, // 28 - playerspshotobj,
1431             { 141, 0, 3, 0, 20, pia_shapetable, pid_cycle, }, // 29 -  Electric Arc barrier
1432             { 150, 0, 4, 0, 20, pia_shapetable, pid_cycle, }, // 30 -  Boss 1
1433             { 154, 0, 4, 0, 20, pia_shapetable, pid_cycle, }, // 31 -  Boss 2
1434             { 158, 0, 4, 0, 20, pia_shapetable, pid_cycle, }, // 32 -  Boss 3
1435             { 162, 0, 4, 0, 20, pia_shapetable, pid_cycle, }, // 33 -  Boss 4
1436             { 166, 0, 4, 0, 20, pia_shapetable, pid_cycle, }, // 34 -  Boss 5
1437             { 170, 0, 4, 0, 20, pia_shapetable, pid_cycle, }, // 35 -  Boss 6
1438             { 48, 0, 3, 0, 10, pia_shapetable, pid_cycle, }, // 36 -  Barrier Post
1439             { 141, 0, 3, 0, 10, pia_shapetable, pid_cycle, }, // 37 -  Barrier Arc
1440             { 208, 0, 8, 0, 10, pia_grabscript, pid_cycle, }, // 38 -  VMT
1441             { 209, 0, 8, 0, 8, pia_grabscript, pid_cycle, }, // 39 -  PerScan
1442             { 232, 0, 4, 0, 20, pia_shapetable, pid_cycle, }, // 40 - Dr. Goldstern Morph Walking
1443             { 268, 0, 4, 0, 20, pia_shapetable, pid_cycle, }, // 41 - Final Boss #1 - Walking
1444             { 272, 0, 4, 0, 20, pia_shapetable, pid_cycle, }, // 42 - Final Boss #2 - Walking
1445             { 276, 0, 4, 0, 20, pia_shapetable, pid_cycle, }, // 43 - Final Boss #3 - Walking
1446             { 280, 0, 4, 0, 20, pia_shapetable, pid_cycle, }, // 44 - Final Boss #4 - Walking
1447         }; // piAnimTable
1448     }
1449 }
1450 
1451 // anim list is created on the fly from the anim table...
1452 // this allows a single animation to be displayed in more than
1453 // one place...
1454 //
1455 piAnimInfo piAnimList[TP_MAX_ANIMS];
1456 ScanCode TPscan;
1457 
1458 // Bunch of general globals!
1459 //
1460 static int8_t old_fontnumber;
1461 
1462 enum JustifyMode {
1463     jm_left,
1464     jm_right,
1465     jm_flush
1466 }; // JustifyMode
1467 
1468 static int8_t justify_mode = jm_left;
1469 
1470 static uint16_t flags;
1471 
1472 static int16_t bgcolor, ltcolor, dkcolor, shcolor, anim_bgcolor = -1;
1473 static int16_t xl;
1474 static int16_t yl;
1475 static int16_t xh;
1476 static int16_t yh;
1477 static int16_t cur_x;
1478 static int16_t cur_y;
1479 static int16_t last_cur_x;
1480 static int16_t last_cur_y;
1481 static const char* first_ch;
1482 
1483 static const char* scan_ch;
1484 static int16_t scan_x;
1485 static int16_t numanims;
1486 static int16_t stemp;
1487 
1488 static fontstruct* font;
1489 
1490 static PresenterInfo* pi;
1491 
1492 static int16_t disp_str_num = -1;
1493 static int16_t music_num;
1494 static int16_t save_cx[TP_CURSOR_SAVES + 1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1495 static int16_t save_cy[TP_CURSOR_SAVES + 1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1496 static int16_t pagex[2], pagey[2];
1497 
TP_Presenter(PresenterInfo * pinfo)1498 void TP_Presenter(
1499     PresenterInfo* pinfo)
1500 {
1501     pi = pinfo;
1502     bgcolor = pi->bgcolor;
1503     ltcolor = pi->ltcolor;
1504     dkcolor = pi->dkcolor;
1505     shcolor = pi->shcolor;
1506     xl = pi->xl + TP_MARGIN;
1507     yl = pi->yl + TP_MARGIN;
1508     xh = pi->xh - TP_MARGIN;
1509     yh = pi->yh - TP_MARGIN;
1510     music_num = -1;
1511 
1512     flags |= fl_clearscback;
1513     if ((pi->flags & TPF_USE_CURRENT) && (pi->cur_x != 0xffff) && (pi->cur_y != 0xffff)) {
1514         if (pi->flags & TPF_SHOW_CURSOR) {
1515             cur_x = px;
1516             cur_y = py;
1517         } else {
1518             cur_x = pi->cur_x;
1519             cur_y = pi->cur_y;
1520         }
1521     } else {
1522         cur_x = xl;
1523         cur_y = yl;
1524     }
1525     first_ch = pi->script[0];
1526     pi->pagenum = 0;
1527     numanims = 0;
1528     disp_str_num = -1;
1529 
1530     old_fontnumber = static_cast<int8_t>(fontnumber);
1531     fontnumber = pi->fontnumber;
1532     TP_PurgeAllGfx();
1533     TP_CachePage(first_ch);
1534     font = (fontstruct*)grsegs[STARTFONT + fontnumber];
1535     flags = fl_presenting | fl_startofline;
1536     if (*first_ch == TP_CONTROL_CHAR) {
1537         TP_HandleCodes();
1538     }
1539 
1540 // Display info UNDER defined region.
1541 //
1542     if (pi->infoline) {
1543         auto oldf = static_cast<int8_t>(fontnumber);
1544         auto oldc = fontcolor;
1545 
1546         px = xl;
1547         py = yh + TP_MARGIN + 1;
1548         fontnumber = 2;
1549         fontcolor = 0x39;
1550         VWB_Bar(xl - TP_MARGIN, py, xh - xl + 1 + (TP_MARGIN * 2), 8, static_cast<uint8_t>(bgcolor));
1551         ShPrint(pi->infoline, static_cast<int8_t>(shcolor), false);
1552 
1553         if (pi->flags & TPF_SHOW_PAGES) {
1554             px = 246;
1555             py = 190;
1556             ShPrint("PAGE ", static_cast<int8_t>(shcolor), false);
1557             pagex[0] = px;
1558             pagey[0] = py;
1559             ShPrint("   OF ", static_cast<int8_t>(shcolor), false);
1560             pagex[1] = px;
1561             pagey[1] = py;
1562 
1563             TP_PrintPageNumber();
1564         }
1565 
1566         fontcolor = oldc;
1567         fontnumber = oldf;
1568     }
1569 
1570     font = (fontstruct*)grsegs[STARTFONT + fontnumber];
1571     if (!(pi->flags & TPF_USE_CURRENT)) {
1572         VWB_Bar(xl - TP_MARGIN, yl - TP_MARGIN, xh - xl + 1 + (TP_MARGIN * 2), yh - yl + 1 + (TP_MARGIN * 2), static_cast<uint8_t>(bgcolor));
1573     }
1574 
1575     if (pi->flags & TPF_SHOW_CURSOR) {
1576         px = cur_x;
1577         py = cur_y;
1578         TP_Print("@", true);
1579     }
1580 
1581     while (flags & fl_presenting) {
1582         if (*first_ch == TP_CONTROL_CHAR) {
1583             TP_HandleCodes();
1584         } else {
1585             TP_WrapText();
1586         }
1587     }
1588 
1589     if (flags & fl_uncachefont) {
1590         UNCACHEGRCHUNK(STARTFONT + fontnumber);
1591     }
1592     fontnumber = old_fontnumber;
1593     pi->cur_x = cur_x;
1594     pi->cur_y = cur_y;
1595 
1596     if (pi->flags & TPF_SHOW_CURSOR) {
1597         cur_x = px = last_cur_x;
1598         cur_y = py = last_cur_y;
1599     } else {
1600         px = cur_x;
1601         py = cur_y;
1602     }
1603 
1604     pi->cur_x = cur_x;
1605     pi->cur_y = cur_y;
1606 }
1607 
TP_WrapText()1608 void TP_WrapText()
1609 {
1610     char temp;
1611 
1612     flags &= ~fl_startofline;
1613 
1614     if ((stemp = TP_LineCommented(first_ch)) != 0) {
1615         first_ch += stemp;
1616         return;
1617     }
1618 
1619 // Parse script until one of the following:
1620 //
1621 // 1) text extends beyond right margin
1622 // 2) NULL termination is reached
1623 // 3) TP_RETURN_CHAR is reached
1624 // 4) TP_CONTROL_CHAR is reached
1625 //
1626     scan_x = cur_x;
1627     scan_ch = first_ch;
1628     while (((uint16_t)(scan_x) + (uint16_t)(ch_width(*scan_ch)) <= xh) && (*scan_ch) &&
1629            (*scan_ch != TP_RETURN_CHAR) && (*scan_ch != TP_CONTROL_CHAR))
1630     {
1631         scan_x += ch_width(*scan_ch++);
1632     }
1633 
1634 // If 'text extends beyond right margin', scan backwards for
1635 // a SPACE
1636 //
1637     if ((uint16_t)scan_x + (uint16_t)(ch_width(*scan_ch)) > xh) {
1638         int16_t last_x = scan_x;
1639         const char* last_ch = scan_ch;
1640 
1641         while ((scan_ch != first_ch) && (*scan_ch != ' ') && (*scan_ch != TP_RETURN_CHAR)) {
1642             scan_x -= ch_width(*scan_ch--);
1643         }
1644 
1645         if (scan_ch == first_ch) {
1646             if (cur_x != xl) {
1647                 goto tp_newline;
1648             }
1649 
1650             scan_ch = last_ch;
1651             scan_x = last_x;
1652         }
1653     }
1654 
1655 // print current line
1656 //
1657     temp = *scan_ch;
1658 
1659     const_cast<char*>(scan_ch)[0] = '\0';
1660 
1661     if ((justify_mode == jm_right) && (!(flags & fl_center))) {
1662         int width, height;
1663 
1664         VWL_MeasureString(first_ch, &width, &height, font);
1665         cur_x = static_cast<int16_t>(xh - width + 1);
1666         if (cur_x < xl) {
1667             cur_x = xl;
1668         }
1669     }
1670 
1671     px = cur_x;
1672     py = cur_y;
1673 
1674     if (*first_ch != TP_RETURN_CHAR) {
1675         if (pi->print_delay) {
1676             TP_SlowPrint(first_ch, pi->print_delay);
1677         } else {
1678             TP_Print(first_ch, false);
1679         }
1680     }
1681 
1682     const_cast<char*>(scan_ch)[0] = temp;
1683 
1684     first_ch = scan_ch;
1685 
1686 tp_newline:;
1687     flags &= ~fl_center;
1688 
1689 // Skip SPACE at end of wrapped line.
1690 //
1691     if ((first_ch[0] == ' ') && (first_ch[1] != ' ')) {
1692         first_ch++;
1693     }
1694 
1695 // Skip end-of-line designators
1696 //
1697     if (first_ch[0] == TP_RETURN_CHAR) {
1698         if (first_ch[1] == '\n') {
1699             first_ch += 2;
1700         } else {
1701             first_ch++;
1702         }
1703     }
1704 
1705 // TP_CONTROL_CHARs don't advance to next character line
1706 //
1707     if ((*scan_ch != TP_CONTROL_CHAR) && *scan_ch) {
1708         auto old_color = fontcolor;
1709 
1710         // Remove cursor.
1711         //
1712         if (pi->flags & TPF_SHOW_CURSOR) {
1713             fontcolor = static_cast<uint8_t>(bgcolor);
1714             px = last_cur_x;
1715             py = last_cur_y;
1716             TP_Print("@", true);
1717             fontcolor = old_color;
1718         }
1719 
1720         cur_x = xl;
1721 
1722         // If next line will be printed out of defined region, scroll up!
1723         //
1724         if ((pi->flags & TPF_SCROLL_REGION) && (cur_y + (font_height * 2) > yh)) {
1725             VL_ScreenToScreen(bufferofs + (((yl + font_height + is_shadowed) * 320) + xl),
1726                               bufferofs + ((yl * 320) + xl),
1727                               xh - xl + 1,
1728                               (yh - yl + 1) - font_height + is_shadowed);
1729 
1730             VWB_Bar(cur_x, cur_y, xh - xl + 1 + (TP_MARGIN * 2), yh - cur_y + 1, static_cast<uint8_t>(bgcolor));
1731 
1732             if (cur_y + font_height > yh) {
1733                 cur_y = yh - font_height + 1 - is_shadowed;
1734             }
1735         } else {
1736             if (pi->custom_line_height > 0) {
1737                 cur_y = static_cast<uint16_t>(cur_y + pi->custom_line_height + is_shadowed);
1738             } else {
1739                 cur_y += font_height + is_shadowed;
1740             }
1741         }
1742 
1743         // Display cursor.
1744         //
1745         if (pi->flags & TPF_SHOW_CURSOR) {
1746             px = cur_x;
1747             py = cur_y;
1748             TP_Print("@", true);
1749         }
1750     }
1751 }
1752 
TP_HandleCodes()1753 void TP_HandleCodes()
1754 {
1755     ControlInfo ci;
1756     piAnimInfo* anim;
1757     piShapeInfo* shape;
1758     uint16_t shapenum;
1759     int16_t length;
1760     const char* s;
1761     int16_t old_bgcolor = 0;
1762     int8_t c;
1763 
1764     if ((first_ch[-2] == TP_RETURN_CHAR) && (first_ch[-1] == '\n')) {
1765         flags |= fl_startofline;
1766     }
1767 
1768     while (*first_ch == TP_CONTROL_CHAR) {
1769         const char* const TP_MORE_TEXT = "<MORE>";
1770 
1771         char temp;
1772 
1773         first_ch++;
1774 #ifndef TP_CASE_SENSITIVE
1775         *first_ch = toupper(*first_ch);
1776         *(first_ch + 1) = toupper(*(first_ch + 1));
1777 #endif
1778         uint16_t subcode;
1779         uint16_t code = *reinterpret_cast<const uint16_t*>(first_ch);
1780         first_ch += 2;
1781 
1782         switch (code) {
1783         // CENTER TEXT ------------------------------------------------------
1784         //
1785         case TP_CNVT_CODE('C', 'E'):
1786             length = 0;
1787             s = first_ch;
1788             while (*s && (*s != TP_RETURN_CHAR)) {
1789                 switch (*s) {
1790                 case TP_CONTROL_CHAR:
1791                     s++;
1792                     subcode = *reinterpret_cast<const uint16_t*>(s);
1793                     s += 2;
1794                     switch (subcode) {
1795                     case TP_CNVT_CODE('S', 'X'):
1796                     case TP_CNVT_CODE('R', 'X'):
1797                     case TP_CNVT_CODE('S', 'Y'):
1798                     case TP_CNVT_CODE('R', 'Y'):
1799                     case TP_CNVT_CODE('F', 'N'):
1800                     case TP_CNVT_CODE('S', 'T'):
1801                     case TP_CNVT_CODE('B', 'X'):
1802                     case TP_CNVT_CODE('S', 'P'):
1803                         s++;
1804                         break;
1805 
1806                     case TP_CNVT_CODE('F', 'C'):
1807                     case TP_CNVT_CODE('B', 'C'):
1808                     case TP_CNVT_CODE('S', 'C'):
1809                     case TP_CNVT_CODE('L', 'C'):
1810                     case TP_CNVT_CODE('D', 'C'):
1811                     case TP_CNVT_CODE('A', 'X'):
1812                     case TP_CNVT_CODE('A', 'Y'):
1813                     case TP_CNVT_CODE('H', 'C'):
1814                         s += 2;
1815                         break;
1816 
1817                     case TP_CNVT_CODE('L', 'M'):
1818                     case TP_CNVT_CODE('R', 'M'):
1819                     case TP_CNVT_CODE('P', 'X'):
1820                     case TP_CNVT_CODE('P', 'Y'):
1821                         s += 3;
1822                         break;
1823 
1824                     case TP_CNVT_CODE('S', 'H'):
1825                         shapenum = TP_VALUE(first_ch, 3);
1826                         s += 3;
1827                         shape = &piShapeTable[shapenum];
1828                         length += TP_BoxAroundShape(-1, -1, shape->shapenum, shape->shapetype);
1829                         break;
1830 
1831                     case TP_CNVT_CODE('A', 'N'):
1832                         shapenum = TP_VALUE(first_ch, 2);
1833                         s += 2;
1834                         anim = &piAnimTable[shapenum];
1835                         switch (anim->animtype) {
1836                         case pia_shapetable:
1837                             shape = &piShapeTable[anim->baseshape + anim->frame];
1838                             length += TP_BoxAroundShape(-1, -1, shape->shapenum, shape->shapetype);
1839                             break;
1840 
1841                         case pia_grabscript:
1842                             shape = &piShapeTable[anim->baseshape];
1843                             length += TP_BoxAroundShape(-1, -1, shape->shapenum + anim->frame, shape->shapetype);
1844                             break;
1845                         }
1846                         break;
1847 
1848                     case TP_CNVT_CODE('Z', 'Z'):
1849                     case TP_CNVT_CODE('D', 'M'):
1850                     case TP_CNVT_CODE('C', 'E'):
1851                     case TP_CNVT_CODE('E', 'P'):
1852                     case TP_CNVT_CODE('L', 'J'):
1853                     case TP_CNVT_CODE('R', 'J'):
1854                     case TP_CNVT_CODE('X', 'X'):
1855                     case TP_CNVT_CODE('S', 'L'):
1856                     case TP_CNVT_CODE('R', 'L'):
1857                     case TP_CNVT_CODE('B', 'E'):
1858                     case TP_CNVT_CODE('H', 'I'):
1859                     case TP_CNVT_CODE('P', 'A'):
1860                     case TP_CNVT_CODE('M', 'O'):
1861                     case TP_CNVT_CODE('H', 'O'):
1862                     case TP_CNVT_CODE('H', 'F'):
1863                     case TP_CNVT_CODE('S', 'B'):
1864                         // No parameters to pass over!
1865                         break;
1866                     }
1867                     break;
1868 
1869                 default:
1870                     length += ch_width(*s++);
1871                     break;
1872                 }
1873             }
1874             cur_x += (uint16_t)((xh - cur_x + 1) - length) / 2;
1875             flags |= fl_center;
1876 
1877             if (pi->flags & TPF_SHOW_CURSOR) {
1878                 TP_JumpCursor();
1879             }
1880             break;
1881 
1882         // DRAW SHAPE -------------------------------------------------------
1883         //
1884         case TP_CNVT_CODE('S', 'H'):
1885             shapenum = TP_VALUE(first_ch, 3);
1886             first_ch += 3;
1887             shape = &piShapeTable[shapenum];
1888             TP_DrawShape(cur_x, cur_y, shape->shapenum, shape->shapetype);
1889             break;
1890 
1891         // CLEAR SCALED BACKGROUND -------------------------------------------
1892         //
1893         case TP_CNVT_CODE('S', 'B'):
1894             if (TP_VALUE(first_ch++, 1)) {
1895                 flags |= fl_clearscback;
1896             } else {
1897                 flags &= ~fl_clearscback;
1898             }
1899             break;
1900 
1901         // HIGHLIGHT COLOR ---------------------------------------------------
1902         //
1903         case TP_CNVT_CODE('H', 'C'):
1904             pi->highlight_color = static_cast<uint8_t>(TP_VALUE(first_ch, 2));
1905             first_ch += 2;
1906             break;
1907 
1908         // HIGHLIGHT ON ------------------------------------------------------
1909         //
1910         case TP_CNVT_CODE('H', 'O'):
1911             pi->fontcolor = fontcolor;
1912             fontcolor = pi->highlight_color;
1913             break;
1914 
1915         // HIGHLIGHT OFF -----------------------------------------------------
1916         //
1917         case TP_CNVT_CODE('H', 'F'):
1918             fontcolor = pi->fontcolor;
1919             break;
1920 
1921         // ALTER X ----------------------------------------------------------
1922         //
1923         case TP_CNVT_CODE('A', 'X'):
1924             c = static_cast<int8_t>(TP_VALUE(first_ch, 2));
1925             first_ch += 2;
1926             cur_x += c;
1927             break;
1928 
1929         // ALTER Y ----------------------------------------------------------
1930         //
1931         case TP_CNVT_CODE('A', 'Y'):
1932             c = static_cast<int8_t>(TP_VALUE(first_ch, 2));
1933             first_ch += 2;
1934             cur_y += c;
1935             break;
1936 
1937         // INIT ANIMATION ---------------------------------------------------
1938         //
1939         case TP_CNVT_CODE('A', 'N'):
1940             shapenum = TP_VALUE(first_ch, 2);
1941             first_ch += 2;
1942             memcpy(&piAnimList[numanims], &piAnimTable[shapenum], sizeof(piAnimInfo));
1943             anim = &piAnimList[numanims++];
1944 
1945             anim->y = cur_y;
1946             switch (anim->animtype) {
1947             case pia_shapetable:
1948                 shape = &piShapeTable[anim->baseshape + anim->frame];
1949                 anim->x = TP_DrawShape(cur_x, cur_y, shape->shapenum, shape->shapetype);
1950                 break;
1951 
1952             case pia_grabscript:
1953                 shape = &piShapeTable[anim->baseshape];
1954                 anim->x = TP_DrawShape(cur_x, cur_y, shape->shapenum + anim->frame, shape->shapetype);
1955                 break;
1956             }
1957 
1958             anim->diradd = 1;
1959 
1960             if (anim_bgcolor == -1) {
1961                 anim_bgcolor = bgcolor;
1962             }
1963             break;
1964 
1965         // FONT COLOR -------------------------------------------------------
1966         //
1967         case TP_CNVT_CODE('F', 'C'):
1968             fontcolor = static_cast<uint8_t>(TP_VALUE(first_ch, 2));
1969             first_ch += 2;
1970             break;
1971 
1972         // SHADOW COLOR ------------------------------------------------------
1973         //
1974         case TP_CNVT_CODE('S', 'C'):
1975             shcolor = TP_VALUE(first_ch, 2);
1976             first_ch += 2;
1977             break;
1978 
1979         // LIGHT COLOR -------------------------------------------------------
1980         //
1981         case TP_CNVT_CODE('L', 'C'):
1982             ltcolor = TP_VALUE(first_ch, 2);
1983             first_ch += 2;
1984             break;
1985 
1986         // SAVE LOCATION -----------------------------------------------------
1987         //
1988         case TP_CNVT_CODE('S', 'L'):
1989             save_cx[TP_CURSOR_SAVES] = cur_x;
1990             save_cy[TP_CURSOR_SAVES] = cur_y;
1991             break;
1992 
1993         // RESTORE LOCATION --------------------------------------------------
1994         //
1995         case TP_CNVT_CODE('R', 'L'):
1996             cur_x = save_cx[TP_CURSOR_SAVES];
1997             cur_y = save_cy[TP_CURSOR_SAVES];
1998 
1999             if (pi->flags & TPF_SHOW_CURSOR) {
2000                 TP_JumpCursor();
2001             }
2002             break;
2003 
2004         // SAVE X LOCATION ---------------------------------------------------
2005         //
2006         case TP_CNVT_CODE('S', 'X'):
2007             temp = static_cast<char>(TP_VALUE(first_ch++, 1));
2008             if (pi->flags & TPF_SHOW_CURSOR) {
2009                 save_cx[static_cast<int>(temp)] = last_cur_x;
2010             } else {
2011                 save_cx[static_cast<int>(temp)] = cur_x;
2012             }
2013             break;
2014 
2015         // RESTORE X LOCATION ------------------------------------------------
2016         //
2017         case TP_CNVT_CODE('R', 'X'):
2018             temp = static_cast<char>(TP_VALUE(first_ch++, 1));
2019             cur_x = save_cx[static_cast<int>(temp)];
2020 
2021             if (pi->flags & TPF_SHOW_CURSOR) {
2022                 TP_JumpCursor();
2023             }
2024             break;
2025 
2026         // SAVE Y LOCATION ---------------------------------------------------
2027         //
2028         case TP_CNVT_CODE('S', 'Y'):
2029             temp = static_cast<char>(TP_VALUE(first_ch++, 1));
2030             if (pi->flags & TPF_SHOW_CURSOR) {
2031                 save_cy[static_cast<int>(temp)] = last_cur_y;
2032             } else {
2033                 save_cy[static_cast<int>(temp)] = cur_y;
2034             }
2035             break;
2036 
2037         // RESTORE Y LOCATION ------------------------------------------------
2038         //
2039         case TP_CNVT_CODE('R', 'Y'):
2040             temp = static_cast<char>(TP_VALUE(first_ch++, 1));
2041             cur_y = save_cy[static_cast<int>(temp)];
2042 
2043             if (pi->flags & TPF_SHOW_CURSOR) {
2044                 TP_JumpCursor();
2045             }
2046             break;
2047 
2048         // NOP ---------------------------------------------------------------
2049         //
2050         case TP_CNVT_CODE('Z', 'Z'):
2051             break;
2052 
2053         // DARK COLOR --------------------------------------------------------
2054         //
2055         case TP_CNVT_CODE('D', 'C'):
2056             dkcolor = TP_VALUE(first_ch, 2); // ^ bgcolor;
2057             first_ch += 2;
2058             break;
2059 
2060         // FONT NUMBER -------------------------------------------------------
2061         //
2062         case TP_CNVT_CODE('F', 'N'):
2063             if (flags & fl_uncachefont) {
2064                 UNCACHEGRCHUNK(STARTFONT + fontnumber);
2065                 flags &= ~fl_uncachefont;
2066             }
2067             fontnumber = TP_VALUE(first_ch++, 1);
2068             if (!grsegs[STARTFONT + fontnumber]) {
2069                 TP_CacheIn(ct_chunk, STARTFONT + fontnumber);
2070                 flags |= fl_uncachefont;
2071             } else {
2072                 font = (fontstruct*)grsegs[STARTFONT + fontnumber];
2073             }
2074             break;
2075 
2076         // BACKGROUND COLOR -------------------------------------------------
2077         //
2078         case TP_CNVT_CODE('B', 'C'):
2079             bgcolor = TP_VALUE(first_ch, 2);
2080             first_ch += 2;
2081             break;
2082 
2083         // SHADOW TEXT ------------------------------------------------------
2084         //
2085         case TP_CNVT_CODE('S', 'T'):
2086             if (TP_VALUE(first_ch++, 1)) {
2087                 flags |= fl_shadowtext;
2088             } else {
2089                 flags &= ~fl_shadowtext;
2090             }
2091             break;
2092 
2093         // SHADOW PIC -------------------------------------------------------
2094         //
2095         case TP_CNVT_CODE('S', 'P'):
2096             if (TP_VALUE(first_ch++, 1)) {
2097                 flags |= fl_shadowpic;
2098             } else {
2099                 flags &= ~fl_shadowpic;
2100             }
2101             break;
2102 
2103         // BOX SHAPES -------------------------------------------------------
2104         //
2105         case TP_CNVT_CODE('B', 'X'):
2106             if (TP_VALUE(first_ch++, 1)) {
2107                 flags |= fl_boxshape;
2108             } else {
2109                 flags &= ~fl_boxshape;
2110             }
2111             break;
2112 
2113         // LEFT MARGIN ------------------------------------------------------
2114         //
2115         case TP_CNVT_CODE('L', 'M'):
2116             shapenum = TP_VALUE(first_ch, 3);
2117             first_ch += 3;
2118             if (shapenum == 0xfff) {
2119                 xl = cur_x;
2120             } else {
2121                 xl = shapenum;
2122             }
2123             if (cur_x < xl) {
2124                 cur_x = xl;
2125             }
2126             break;
2127 
2128         // RIGHT MARGIN -----------------------------------------------------
2129         //
2130         case TP_CNVT_CODE('R', 'M'):
2131             shapenum = TP_VALUE(first_ch, 3);
2132             first_ch += 3;
2133             if (shapenum == 0xfff) {
2134                 xh = cur_x;
2135             } else {
2136                 xh = shapenum;
2137             }
2138             break;
2139 
2140         // DEFAULT MARGINS --------------------------------------------------
2141         //
2142         case TP_CNVT_CODE('D', 'M'):
2143             xl = pi->xl + TP_MARGIN;
2144             yl = pi->yl + TP_MARGIN;
2145             xh = pi->xh - TP_MARGIN;
2146             yh = pi->yh - TP_MARGIN;
2147             break;
2148 
2149         // SET X COORDINATE -------------------------------------------------
2150         //
2151         case TP_CNVT_CODE('P', 'X'):
2152             cur_x = TP_VALUE(first_ch, 3);
2153             first_ch += 3;
2154 
2155             if (pi->flags & TPF_SHOW_CURSOR) {
2156                 TP_JumpCursor();
2157             }
2158             break;
2159 
2160         // SET Y COORDINATE -------------------------------------------------
2161         //
2162         case TP_CNVT_CODE('P', 'Y'):
2163             cur_y = TP_VALUE(first_ch, 3);
2164             first_ch += 3;
2165 
2166             if (pi->flags & TPF_SHOW_CURSOR) {
2167                 TP_JumpCursor();
2168             }
2169             break;
2170 
2171         // LEFT JUSTIFY -----------------------------------------------------
2172         //
2173         case TP_CNVT_CODE('L', 'J'):
2174             justify_mode = jm_left;
2175             break;
2176 
2177         // RIGHT JUSTIFY ----------------------------------------------------
2178         //
2179         case TP_CNVT_CODE('R', 'J'):
2180             justify_mode = jm_right;
2181             break;
2182 
2183         // BELL -------------------------------------------------------------
2184         //
2185         case TP_CNVT_CODE('B', 'E'):
2186             ::sd_play_player_sound(TERM_BEEPSND, bstone::AC_ITEM);
2187 
2188             SD_WaitSoundDone();
2189             break;
2190 
2191         // HIDE CURSOR ------------------------------------------------------
2192         //
2193         case TP_CNVT_CODE('H', 'I'):
2194             break;
2195 
2196         // PAUSE -----------------------------------------------------------
2197         //
2198         case TP_CNVT_CODE('P', 'A'): {
2199             int8_t i;
2200 
2201             for (i = 0; i < 30; i++) {
2202                 VW_WaitVBL(1);
2203                 CycleColors();
2204             }
2205         }
2206         break;
2207 
2208 
2209         // MORE ------------------------------------------------------------
2210         //
2211         case TP_CNVT_CODE('M', 'O'):
2212             if (pi->print_delay) {
2213                 TP_SlowPrint(TP_MORE_TEXT, pi->print_delay);
2214             } else {
2215                 TP_Print(TP_MORE_TEXT, false);
2216             }
2217 
2218             LastScan = ScanCode::sc_none;
2219             do {
2220                 IN_ReadControl(0, &ci);
2221             } while (!ci.button0 && !ci.button1 && !ci.button2 &&
2222                      !ci.button3 && (ci.dir == dir_None) &&
2223                      (LastScan == ScanCode::sc_none));
2224 
2225             cur_x = xl;
2226             VWB_Bar(cur_x, cur_y, xh - xl + 1 + (TP_MARGIN * 2), font_height + is_shadowed, static_cast<uint8_t>(bgcolor));
2227             if (pi->flags & TPF_SHOW_CURSOR) {
2228                 TP_JumpCursor();
2229             }
2230 
2231             if (LastScan == ScanCode::sc_escape) {
2232                 flags &= ~fl_presenting;
2233             }
2234             TPscan = LastScan;
2235             break;
2236 
2237         // DISPLAY STRING --------------------------------------------------
2238         //
2239         case TP_CNVT_CODE('D', 'S'): {
2240             const char* old_first_ch;
2241 
2242             disp_str_num = TP_VALUE(first_ch, 2);
2243             if (disp_str_num >= PI_MAX_NUM_DISP_STRS) {
2244                 ::Quit("String number exceeds max array size.");
2245             }
2246 
2247             old_first_ch = first_ch + 2;
2248 
2249             first_ch = const_cast<const char*>(piStringTable[disp_str_num]);
2250 
2251             if (first_ch) {
2252                 while (flags & fl_presenting && *first_ch) {
2253                     if (*first_ch == TP_CONTROL_CHAR) {
2254                         TP_HandleCodes();
2255                     } else {
2256                         TP_WrapText();
2257                     }
2258                 }
2259             }
2260 
2261             first_ch = old_first_ch;
2262         }
2263         break;
2264 
2265         // PLAY MUSIC -------------------------------------------------------
2266         //
2267         case TP_CNVT_CODE('P', 'M'):
2268             temp = static_cast<char>(TP_VALUE(first_ch, 2));
2269             if ((temp < LASTMUSIC) && (temp != music_num)) {
2270                 music_num = temp;
2271                 TP_CacheIn(ct_music, music_num);
2272             }
2273             first_ch += 2;
2274             break;
2275 
2276         // PLAY SOUND -------------------------------------------------------
2277         //
2278         case TP_CNVT_CODE('P', 'S'):
2279             temp = static_cast<char>(TP_VALUE(first_ch, 2));
2280             if ((temp < LASTSOUND)) {
2281                 TP_CacheIn(ct_scaled, 0);
2282                 ::sd_play_player_sound(temp, bstone::AC_ITEM);
2283             }
2284             first_ch += 2;
2285             break;
2286 
2287 
2288         // END OF PAGE ------------------------------------------------------
2289         //
2290         case TP_CNVT_CODE('E', 'P'):
2291             VW_UpdateScreen();
2292 
2293             if (screenfaded) {
2294                 VW_FadeIn();
2295             }
2296 
2297             if (anim_bgcolor != -1) {
2298                 old_bgcolor = bgcolor;
2299                 bgcolor = anim_bgcolor;
2300             }
2301 
2302             while (true) {
2303                 CycleColors(); // specific for VGA 3D engine!
2304                 CalcTics();
2305 
2306                 TP_AnimatePage(numanims);
2307                 VW_UpdateScreen();
2308                 ReadAnyControl(&ci);
2309 
2310                 if (Keyboard[ScanCode::sc_page_up]) {
2311                     ci.dir = dir_North;
2312                 } else if (Keyboard[ScanCode::sc_page_down]) {
2313                     ci.dir = dir_South;
2314                 }
2315 
2316                 if (pi->flags & TPF_CONTINUE && (ci.button0 || Keyboard[ScanCode::sc_space] || Keyboard[ScanCode::sc_return])) {
2317                     EscPressed = false;
2318                     flags &= ~fl_presenting;
2319                     break;
2320                 }
2321 
2322                 if (ci.button1 || Keyboard[ScanCode::sc_escape]) {
2323                     EscPressed = true;
2324                     flags &= ~fl_presenting;
2325                     TPscan = ScanCode::sc_escape;
2326                     break;
2327                 } else {
2328                     if (((ci.dir == dir_North) || (ci.dir == dir_West)) && (pi->pagenum)) {
2329                         if (flags & fl_upreleased) {
2330                             pi->pagenum--;
2331                             flags &= ~fl_upreleased;
2332                             break;
2333                         }
2334                     } else {
2335                         flags |= fl_upreleased;
2336                         if (((ci.dir == dir_South) || (ci.dir == dir_East)) && (pi->pagenum < pi->numpages - 1)) {
2337                             if (flags & fl_dnreleased) {
2338                                 pi->pagenum++;
2339                                 flags &= ~fl_dnreleased;
2340                                 break;
2341                             }
2342                         } else {
2343                             flags |= fl_dnreleased;
2344                         }
2345                     }
2346                 }
2347             }
2348 
2349             if (anim_bgcolor != -1) {
2350                 bgcolor = old_bgcolor;
2351                 anim_bgcolor = -1;
2352             }
2353 
2354             cur_x = xl;
2355             cur_y = yl;
2356             if (cur_y + font_height > yh) {
2357                 cur_y = yh - font_height;
2358             }
2359             first_ch = pi->script[static_cast<int>(pi->pagenum)];
2360 
2361             numanims = 0;
2362             TP_PurgeAllGfx();
2363             TP_CachePage(first_ch);
2364 
2365             if (*first_ch == TP_CONTROL_CHAR) {
2366                 TP_HandleCodes();
2367                 flags &= ~fl_startofline;
2368             }
2369             VWB_Bar(xl, yl, xh - xl + 1, yh - yl + 1, static_cast<uint8_t>(bgcolor));
2370             TP_PrintPageNumber();
2371             break;
2372 
2373         // EXIT PRESENTER ---------------------------------------------------
2374         //
2375         case TP_CNVT_CODE('X', 'X'):
2376             flags &= ~fl_presenting;
2377             VW_UpdateScreen();
2378             break;
2379         }
2380     }
2381 
2382     if ((first_ch[0] == TP_RETURN_CHAR) && (first_ch[1] == '\n') && (flags & fl_startofline)) {
2383         first_ch += 2;
2384     }
2385 }
2386 
TP_PrintPageNumber()2387 void TP_PrintPageNumber()
2388 {
2389     char buffer[5];
2390     auto oldf = static_cast<int8_t>(fontnumber);
2391     auto oldc = fontcolor;
2392 
2393     if (!(pi->flags & TPF_SHOW_PAGES)) {
2394         return;
2395     }
2396 
2397     fontnumber = 2;
2398     fontcolor = 0x39;
2399 
2400 // Print current page number.
2401 //
2402     px = pagex[0];
2403     py = pagey[0];
2404     VW_Bar(px, py, 12, 7, 0xe3);
2405     sprintf(buffer, "%02d", pi->pagenum + 1);
2406     ShPrint(buffer, static_cast<int8_t>(shcolor), false);
2407 
2408 // Print current page number.
2409 //
2410     if ((px = pagex[1]) > -1) {
2411         py = pagey[1];
2412         sprintf(buffer, "%02d", pi->numpages);
2413         ShPrint(buffer, static_cast<int8_t>(shcolor), false);
2414         pagex[1] = -1;
2415     }
2416 
2417     fontnumber = oldf;
2418     fontcolor = oldc;
2419 }
2420 
TP_DrawShape(int16_t x,int16_t y,int16_t shapenum,pisType shapetype)2421 int16_t TP_DrawShape(
2422     int16_t x,
2423     int16_t y,
2424     int16_t shapenum,
2425     pisType shapetype)
2426 {
2427     int16_t width;
2428     void* addr;
2429 
2430 // Mask 'x coordinate' when displaying certain shapes
2431 //
2432     switch (shapetype) {
2433     case pis_pic:
2434     case pis_latchpic:
2435         x = (x + 7) & 0xFFF8;
2436         break;
2437     default:
2438         break;
2439     }
2440 
2441 // Get width of shape (also, draws a box/shadow, if needed)
2442 //
2443     width = TP_BoxAroundShape(x, y, shapenum, shapetype);
2444 
2445 // Draw this shape!
2446 //
2447     switch (shapetype) {
2448     case pis_scwall:
2449         ::TP_CacheIn(ct_scaled, 0);
2450         addr = ::PM_GetPage(shapenum);
2451 
2452         draw_wall_ui(
2453             x,
2454             y,
2455             addr);
2456 
2457         break;
2458 
2459     case pis_scaled:
2460         TP_CacheIn(ct_scaled, 0);
2461         if (flags & fl_clearscback) {
2462             VWB_Bar(x, y, 64, 64, static_cast<uint8_t>(bgcolor));
2463         }
2464 
2465         ::vid_draw_ui_sprite(shapenum, x + 32, y + 32);
2466         break;
2467 
2468     case pis_latchpic:
2469         LatchDrawPic(x >> 3, y, shapenum);
2470         break;
2471 
2472     case pis_pic:
2473 #if TP_640x200
2474     case pis_pic2x:
2475 #endif
2476         VWB_DrawPic(x, y, shapenum);
2477         break;
2478 
2479     default:
2480         break;
2481     }
2482 
2483 // Advance current x position past shape and tell calling function where
2484 // (horizontally) this shape was drawn.
2485 //
2486     cur_x += width;
2487     return x;
2488 }
2489 
TP_ResetAnims()2490 void TP_ResetAnims()
2491 {
2492     piAnimList[0].baseshape = -1;
2493 }
2494 
TP_AnimatePage(int16_t num_anims)2495 void TP_AnimatePage(
2496     int16_t num_anims)
2497 {
2498     piAnimInfo* anim = piAnimList;
2499     piShapeInfo* shape;
2500 
2501     while (num_anims--) {
2502         anim->delay += tics;
2503         if (anim->delay >= anim->maxdelay) {
2504             anim->delay = 0;
2505             anim->frame += anim->diradd;
2506             if ((anim->frame == anim->maxframes) || (anim->frame < 0)) {
2507                 switch (anim->dirtype) {
2508                 case pid_cycle:
2509                     anim->frame = 0;
2510                     break;
2511 
2512                 case pid_rebound:
2513                     anim->diradd = -anim->diradd;
2514                     anim->frame += anim->diradd;
2515                     break;
2516                 }
2517             }
2518 
2519             switch (anim->animtype) {
2520             case pia_shapetable:
2521                 shape = &piShapeTable[anim->baseshape + anim->frame];
2522                 TP_DrawShape(anim->x, anim->y, shape->shapenum, shape->shapetype);
2523                 break;
2524 
2525             case pia_grabscript:
2526                 shape = &piShapeTable[anim->baseshape];
2527                 TP_DrawShape(anim->x, anim->y, shape->shapenum + anim->frame, shape->shapetype);
2528                 break;
2529             }
2530         }
2531         anim++;
2532     }
2533 }
2534 
TP_BoxAroundShape(int16_t x1,int16_t y1,uint16_t shapenum,pisType shapetype)2535 int16_t TP_BoxAroundShape(
2536     int16_t x1,
2537     int16_t y1,
2538     uint16_t shapenum,
2539     pisType shapetype)
2540 {
2541     int16_t x2 = 0, y2 = 0;
2542 
2543     switch (shapetype) {
2544         uint16_t width;
2545 
2546     case pis_scwall:
2547     case pis_scaled:
2548         x2 = x1 + 63;
2549         y2 = y1 + 63;
2550         break;
2551 
2552     case pis_pic:
2553     case pis_latchpic:
2554 #if TP_640x200
2555     case pis_pic2x:
2556         width = pictable[shapenum - STARTPICS].width << (3 + (shapetype == pis_pic2x));
2557 #else
2558         width = pictable[shapenum - STARTPICS].width;
2559 #endif
2560         x2 = x1 + width - 1;
2561         y2 = y1 + (pictable[shapenum - STARTPICS].height) - 1;
2562         break;
2563 
2564     default:
2565         break;
2566     }
2567 
2568     if (flags & fl_boxshape) {
2569         x1 -= 1 + TP_640x200;
2570         x2 += 1 + TP_640x200;
2571         y1--;
2572         y2++;
2573 
2574         if (x1 >= 0 && y1 >= 0) {
2575             VWB_Hlin(x1, x2, y1, static_cast<uint8_t>(ltcolor));
2576             VWB_Hlin(x1, x2, y2, static_cast<uint8_t>(dkcolor));
2577             VWB_Vlin(y1, y2, x1, static_cast<uint8_t>(ltcolor));
2578             VWB_Vlin(y1, y2, x2, static_cast<uint8_t>(dkcolor));
2579 
2580 #if TP_640x200
2581             VWB_Vlin(y1, y2, x1 + 1, ltcolor);
2582             VWB_Vlin(y1, y2, x2 + 1, dkcolor);
2583 #endif
2584         }
2585     }
2586 
2587     if (flags & fl_shadowpic) {
2588         x2 += 1 + TP_640x200;
2589         y2++;
2590         if (x1 >= 0 && y1 >= 0) {
2591             VWB_Hlin(x1 + 1 + TP_640x200, x2, y2, static_cast<uint8_t>(shcolor));
2592             VWB_Vlin(y1 + 1, y2, x2, static_cast<uint8_t>(shcolor));
2593         }
2594     }
2595 
2596     return x2 - x1 + 1;
2597 }
2598 
TP_PurgeAllGfx()2599 void TP_PurgeAllGfx()
2600 {
2601     int16_t loop;
2602 
2603     if (pi->flags & TPF_CACHE_NO_GFX) {
2604         return;
2605     }
2606 
2607     TP_ResetAnims();
2608 
2609     for (loop = STARTPICS; loop < CONTROLS_LUMP_START; loop++) {
2610         if (grsegs[loop]) {
2611             UNCACHEGRCHUNK(loop);
2612         }
2613     }
2614 
2615     for (loop = CONTROLS_LUMP_END + 1; loop < STARTPICS + NUMPICS; loop++) {
2616         if (grsegs[loop]) {
2617             UNCACHEGRCHUNK(loop);
2618         }
2619     }
2620 }
2621 
TP_CachePage(const char * script)2622 void TP_CachePage(
2623     const char* script)
2624 {
2625     piAnimInfo* anim;
2626     int16_t loop;
2627     uint16_t shapenum;
2628     bool end_of_page = false;
2629     int16_t num_anims = 0;
2630 
2631     if (pi->flags & TPF_CACHE_NO_GFX) {
2632         return;
2633     }
2634 
2635     uint16_t code;
2636 
2637     while (!end_of_page) {
2638         while ((stemp = TP_LineCommented(script)) != 0) {
2639             script += stemp;
2640         }
2641 
2642         switch (*script++) {
2643         case TP_CONTROL_CHAR:
2644 #ifndef TP_CASE_SENSITIVE
2645             *script = toupper(*script);
2646             *(script + 1) = toupper(*(script + 1));
2647 #endif
2648             code = *reinterpret_cast<const uint16_t*>(script);
2649             script += 2;
2650             switch (code) {
2651             case TP_CNVT_CODE('S', 'H'):
2652                 shapenum = TP_VALUE(script, 3);
2653                 script += 3;
2654                 if (piShapeTable[shapenum].shapetype == pis_pic) {
2655                     CA_MarkGrChunk(piShapeTable[shapenum].shapenum);
2656                 }
2657                 break;
2658 
2659             case TP_CNVT_CODE('A', 'N'):
2660                 shapenum = TP_VALUE(script, 2);
2661                 script += 2;
2662 
2663                 if (num_anims++ == TP_MAX_ANIMS) {
2664                     ::Quit("Too many anims on one page.");
2665                 }
2666 
2667                 anim = &piAnimTable[shapenum];
2668                 switch (anim->animtype) {
2669                 case pia_shapetable:
2670                     for (loop = anim->baseshape; loop < anim->baseshape + anim->maxframes; loop++) {
2671                         if (piShapeTable[loop].shapetype == pis_pic) {
2672                             CA_MarkGrChunk(piShapeTable[loop].shapenum);
2673                         }
2674                     }
2675                     break;
2676 
2677                 case pia_grabscript:
2678                     shapenum = piShapeTable[anim->baseshape].shapenum;
2679                     if (piShapeTable[anim->baseshape].shapetype == pis_pic) {
2680                         for (loop = 0; loop < anim->maxframes; loop++) {
2681                             CA_MarkGrChunk(shapenum + loop);
2682                         }
2683                     }
2684                     break;
2685                 }
2686                 break;
2687 
2688             case TP_CNVT_CODE('X', 'X'):
2689             case TP_CNVT_CODE('E', 'P'):
2690                 end_of_page = true;
2691                 break;
2692             }
2693             break;
2694         }
2695     }
2696 
2697     TP_CacheIn(ct_marks, 0);
2698 }
2699 
TP_VALUE(const char * ptr,int8_t num_nybbles)2700 uint16_t TP_VALUE(
2701     const char* ptr,
2702     int8_t num_nybbles)
2703 {
2704     char ch;
2705     int8_t nybble;
2706     int8_t shift;
2707     uint16_t value = 0;
2708 
2709     for (nybble = 0; nybble < num_nybbles; nybble++) {
2710         shift = 4 * (num_nybbles - nybble - 1);
2711 
2712         ch = *ptr++;
2713         if (isxdigit(ch)) {
2714             if (isalpha(ch)) {
2715                 value |= (toupper(ch) - 'A' + 10) << shift;
2716             } else {
2717                 value |= (ch - '0') << shift;
2718             }
2719         }
2720     }
2721 
2722     return value;
2723 }
2724 
TP_JumpCursor()2725 void TP_JumpCursor()
2726 {
2727     auto old_color = fontcolor;
2728 
2729     fontcolor = static_cast<uint8_t>(bgcolor);
2730     px = last_cur_x;
2731     py = last_cur_y;
2732     TP_Print("@", true);
2733     px = cur_x = last_cur_x;
2734     py = cur_y = last_cur_y;
2735     fontcolor = old_color;
2736     TP_Print("@", true);
2737 }
2738 
TP_Print(const char * string,bool single_char)2739 void TP_Print(
2740     const char* string,
2741     bool single_char)
2742 {
2743 
2744 //
2745 // The only test needed SHOULD be the first one ...
2746 // "flags & fl shadowtext" ... Testing for '@' keeps the terminal's
2747 // cursor from being shadowed -- sorta' specific for AOG...
2748 //
2749 // This should eventually be changed...
2750 //
2751     LastScan = ScanCode::sc_none;
2752 
2753     last_cur_x = cur_x;
2754     last_cur_y = cur_y;
2755 
2756     if ((flags & fl_shadowtext) && (*string != '@')) {
2757         if (fontcolor == bgcolor) {
2758             ShPrint(string, static_cast<int8_t>(bgcolor), single_char);
2759         } else {
2760             ShPrint(string, static_cast<int8_t>(shcolor), single_char);
2761         }
2762     } else if (single_char) {
2763         char buf[2] = { 0, 0 };
2764 
2765         buf[0] = *string;
2766         USL_DrawString(buf);
2767     } else {
2768         USL_DrawString(string);
2769     }
2770 
2771     cur_x = px;
2772     cur_y = py;
2773 
2774     if ((pi->flags & TPF_ABORTABLE) && LastScan != ScanCode::sc_none) {
2775         flags &= ~fl_presenting;
2776     }
2777 }
2778 
TP_SlowPrint(const char * string,int8_t delay)2779 bool TP_SlowPrint(
2780     const char* string,
2781     int8_t delay)
2782 {
2783     auto old_color = fontcolor;
2784     int16_t old_x, old_y;
2785     int32_t tc;
2786     bool aborted = false;
2787 
2788     while (*string) {
2789         if (pi->flags & TPF_SHOW_CURSOR) {
2790             // Remove the cursor.
2791             //
2792             fontcolor = static_cast<uint8_t>(bgcolor);
2793             px = old_x = last_cur_x;
2794             py = old_y = last_cur_y;
2795             TP_Print("@", true);
2796             px = old_x;
2797             py = old_y;
2798             fontcolor = old_color;
2799         }
2800 
2801         // If user aborted, print the whole string ...
2802         // Otherwise, just print a character ...
2803         //
2804         if (aborted) {
2805             TP_Print(string, false);
2806         } else {
2807             TP_Print(string++, true);
2808         }
2809 
2810         // Print cursor
2811         //
2812         if (pi->flags & TPF_SHOW_CURSOR) {
2813             TP_Print("@", true);
2814         }
2815 
2816         VW_UpdateScreen();
2817 
2818         // Break out on abort!
2819         //
2820         if (aborted) {
2821             break;
2822         }
2823 
2824         // Liven up the audio aspect!
2825         //
2826         if (pi->flags & TPF_TERM_SOUND) {
2827             if (*string != ' ') {
2828                 ::sd_play_player_sound(TERM_TYPESND, bstone::AC_ITEM);
2829             }
2830         }
2831 
2832         // Delay and check for abort (if needed).
2833         //
2834         if (!aborted) {
2835             LastScan = ScanCode::sc_none;
2836             tc = TimeCount;
2837             while (static_cast<int32_t>(TimeCount) - tc < delay) {
2838                 VW_WaitVBL(1);
2839                 CycleColors();
2840                 if (pi->flags & TPF_ABORTABLE) {
2841                     if ((pi->flags & TPF_ABORTABLE) && LastScan != ScanCode::sc_none) {
2842                         aborted = true;
2843                         break;
2844                     }
2845                 }
2846             }
2847         }
2848     }
2849 
2850     if (aborted) {
2851         flags &= ~fl_presenting;
2852     }
2853 
2854     return aborted;
2855 }
2856 
TP_LoadScript(const char * filename,PresenterInfo * p_i,uint16_t id_cache)2857 int32_t TP_LoadScript(
2858     const char* filename,
2859     PresenterInfo* p_i,
2860     uint16_t id_cache)
2861 {
2862     int32_t size;
2863 
2864     if (id_cache) {
2865         const char* p;
2866 
2867         p_i->id_cache = id_cache;
2868         CA_CacheGrChunk(id_cache);
2869         p_i->scriptstart = grsegs[id_cache];
2870         p = strstr(static_cast<const char*>(grsegs[id_cache]), "^XX");
2871 
2872         if (!p) {
2873             ::Quit("Can't find the ^XX doc terminator string.");
2874         }
2875         size = static_cast<int32_t>(p - static_cast<const char*>(p_i->scriptstart) - 1);
2876     } else {
2877         p_i->id_cache = -1;
2878         if ((size = IO_LoadFile(filename, &p_i->scriptstart)) == 0) {
2879             return 0;
2880         }
2881     }
2882 
2883     p_i->script[0] = (char*)p_i->scriptstart;
2884     const_cast<char*>(p_i->script[0])[size + 4] = '\0'; // Last byte is trashed!
2885 
2886     p_i->flags |= TPF_CACHED_SCRIPT;
2887     TP_InitScript(p_i);
2888 
2889     return size;
2890 }
2891 
TP_FreeScript(PresenterInfo * p_i,uint16_t id_cache)2892 void TP_FreeScript(
2893     PresenterInfo* p_i,
2894     uint16_t id_cache)
2895 {
2896     TP_PurgeAllGfx();
2897 
2898     if (id_cache) {
2899         UNCACHEGRCHUNK(id_cache);
2900     } else if ((p_i->script) && (p_i->flags & TPF_CACHED_SCRIPT)) {
2901         delete [] static_cast<char*>(p_i->scriptstart);
2902         p_i->scriptstart = nullptr;
2903     }
2904 }
2905 
TP_InitScript(PresenterInfo * p_i)2906 void TP_InitScript(
2907     PresenterInfo* p_i)
2908 {
2909     const char* script = p_i->script[0];
2910     uint16_t code;
2911 
2912     p_i->numpages = 1; // Assume at least 1 page
2913     while (*script) {
2914         while ((stemp = TP_LineCommented(script)) != 0) {
2915             script += stemp;
2916             if (!*script) {
2917                 goto end_func;
2918             }
2919         }
2920 
2921         switch (*script++) {
2922         case TP_CONTROL_CHAR:
2923 #ifndef TP_CASE_SENSITIVE
2924             *script = toupper(*script);
2925             *(script + 1) = toupper(*(script + 1));
2926 #endif
2927             code = *reinterpret_cast<const uint16_t*>(script);
2928             script += 2;
2929             switch (code) {
2930             case TP_CNVT_CODE('E', 'P'):
2931                 if (p_i->numpages < TP_MAX_PAGES) {
2932                     p_i->script[static_cast<int>(p_i->numpages++)] = script;
2933                 } else {
2934                     ::Quit("Too many pages in presenter.");
2935                 }
2936                 break;
2937             }
2938             break;
2939         }
2940     }
2941 
2942 end_func:;
2943     p_i->numpages--;     // Last page defined is not a real page.
2944 }
2945 
TP_CacheIn(tpCacheType type,int16_t chunk)2946 void TP_CacheIn(
2947     tpCacheType type,
2948     int16_t chunk)
2949 {
2950     int16_t first_ch_offset = static_cast<int16_t>(first_ch - pi->script[0]);
2951     int16_t loop, offset[TP_MAX_PAGES];
2952 
2953 // Cache graphics and re-assign pointers
2954 //
2955     switch (type) {
2956     case ct_scaled:
2957         if (flags & fl_pagemanager) {
2958             break;
2959         }
2960 
2961         flags |= fl_pagemanager;
2962         break;
2963 
2964     case ct_music:
2965     case ct_marks:
2966     case ct_chunk:
2967         if (flags & fl_pagemanager) {
2968             ClearMemory();
2969             flags &= ~fl_pagemanager;
2970         }
2971 
2972         switch (type) {
2973         case ct_chunk:
2974             CA_CacheGrChunk(chunk);
2975             break;
2976 
2977         case ct_marks:
2978             CA_CacheMarks();
2979             break;
2980 
2981         case ct_music:
2982             StartCPMusic(chunk);
2983             break;
2984 
2985         default:
2986             break;
2987         }
2988         break;
2989     }
2990 
2991 // Re-assign font pointer
2992 //
2993     font = (fontstruct*)grsegs[STARTFONT + fontnumber];
2994 
2995 // Re-assign script pointers IF this is a cached script!
2996 //
2997     if (pi->flags & TPF_CACHED_SCRIPT) {
2998         // Calc offset of each page pointer
2999         //
3000         for (loop = 1; loop < pi->numpages; loop++) {
3001             offset[loop] = static_cast<int16_t>(pi->script[loop] - pi->script[loop - 1]);
3002         }
3003 
3004         // Re-assign all page pointers
3005         //
3006         if (pi->id_cache != -1) {
3007             pi->scriptstart = grsegs[pi->id_cache];
3008         }
3009         pi->script[0] = static_cast<char*>(pi->scriptstart);
3010         for (loop = 1; loop < pi->numpages; loop++) {
3011             pi->script[loop] = pi->script[loop - 1] + offset[loop];
3012         }
3013 
3014         // Reset text pointer
3015         //
3016         first_ch = pi->script[0] + first_ch_offset;
3017     }
3018 }
3019 
TP_LineCommented(const char * s)3020 int16_t TP_LineCommented(
3021     const char* s)
3022 {
3023     const char* o = s;
3024 
3025 // If a line starts with a semi-colon, the entire line is considered a
3026 // comment and is ignored!
3027 //
3028     if ((*s == ';') && (*(s - 2) == TP_RETURN_CHAR)) {
3029         while (*s != TP_RETURN_CHAR) {
3030             s++;
3031         }
3032         s += 2;
3033     }
3034 
3035     return static_cast<int8_t>(s - o);
3036 }
3037