Fix for invalid break statement outside loop.
[blender-addons-contrib.git] / io_scene_fpx / fpx_spec.py
1 # ##### BEGIN GPL LICENSE BLOCK #####
2 #
3 #  This program is free software; you can redistribute it and/or
4 #  modify it under the terms of the GNU General Public License
5 #  as published by the Free Software Foundation; either version 2
6 #  of the License, or (at your option) any later version.
7 #
8 #  This program is distributed in the hope that it will be useful,
9 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 #  GNU General Public License for more details.
12 #
13 #  You should have received a copy of the GNU General Public License
14 #  along with this program; if not, write to the Free Software Foundation,
15 #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 # <pep8 compliant>
20
21 ###############################################################################
22 #234567890123456789012345678901234567890123456789012345678901234567890123456789
23 #--------1---------2---------3---------4---------5---------6---------7---------
24
25
26 # ##### BEGIN COPYRIGHT BLOCK #####
27 #
28 # initial script copyright (c)2013 Alexander Nussbaumer
29 #
30 # ##### END COPYRIGHT BLOCK #####
31
32 ## this is a basic, partial and stripped implementation to read
33 ## [FPT:FPL:FPM] Future Pinball File Format
34 ## http://futurepinball.com
35 ## this python implementation based on the implementation from:
36 ## https://github.com/PinSimDB/fp-addons-sdk.git
37
38
39 if repr(globals()).find("bpy") != -1:
40     from io_scene_fpx.cfb_spec import (
41             Cfb_RawIO_Reader,
42             Cfb_Stream_Reader,
43             Cfb_Size_Type,
44             Cfb_Extras,
45             )
46     from io_scene_fpx.lzo_spec import (
47             Lzo_Codec,
48             )
49     from io_scene_fpx.fpx_utils import (
50             FpxUtilities,
51             )
52 else:
53     from cfb_spec import (
54             Cfb_RawIO_Reader,
55             Cfb_Stream_Reader,
56             Cfb_Size_Type,
57             Cfb_Extras,
58             )
59     from lzo_spec import (
60             Lzo_Codec,
61             )
62     from fpx_utils import (
63             FpxUtilities,
64             )
65
66
67 from time import (
68         struct_time,
69         gmtime,
70         strftime,
71         time,
72         )
73 from struct import (
74         pack,
75         unpack,
76         )
77 from sys import (
78         exc_info,
79         )
80 from os import (
81         fstat,
82         path,
83         makedirs,
84         )
85 from collections import (
86         OrderedDict,
87         )
88 from io import (
89         SEEK_CUR,
90         FileIO,
91         )
92 from codecs import (
93         register_error,
94         )
95
96
97 class FpxSpec:
98     ## TEST_STR = 'START@€@µ@²@³@©@®@¶@ÿ@A@END.bmp'
99     ## TEST_RAW = b'START@\x80@\xb5@\xb2@\xb3@\xa9@\xae@\xb6@\xff@A@END.bmp\x00'
100     ##
101     STRING_FPX_REPLACE = 'use_fpx_replace'
102     STRING_ERROR = STRING_FPX_REPLACE
103     ##STRING_ERROR = 'replace'
104     ##STRING_ERROR = 'ignore'
105     ##STRING_ERROR = 'surrogateescape'
106     STRING_REPLACE = u'_'
107
108     STRING_ENCODING = 'ascii' # ASCII
109     ##STRING_ENCODING = 'cp437' # US
110     ##STRING_ENCODING = 'cp858' # Europe + €
111     ##STRING_ENCODING = 'cp1252' # WIN EU
112     #STRING_ENCODING = 'utf-8'
113
114     WSTRING_ENCODING = 'utf-16-le'
115
116     @staticmethod
117     def fpx_replace(exc):
118         """ http://www.python.org/dev/peps/pep-0293/ """
119         if isinstance(exc, UnicodeEncodeError):
120             return ((exc.end-exc.start)*FpxSpec.STRING_REPLACE, exc.end)
121         elif isinstance(exc, UnicodeDecodeError):
122             return (FpxSpec.STRING_REPLACE, exc.end)
123         elif isinstance(exc, UnicodeTranslateError):
124             return ((exc.end-exc.start)*FpxSpec.STRING_REPLACE, exc.end)
125         else:
126             raise TypeError("can't handle {}",format(exc.__name__))
127
128     @staticmethod
129     def read_string(raw_io, length):
130         """ read a string of a specific length from raw_io """
131         buffer = raw_io.read(length)
132         if not buffer:
133             raise EOFError()
134         eol = buffer.find(FpxSpec.STRING_TERMINATION)
135         register_error(FpxSpec.STRING_FPX_REPLACE, FpxSpec.fpx_replace)
136         s = buffer[:eol].decode(encoding=FpxSpec.STRING_ENCODING, errors=FpxSpec.STRING_ERROR)
137         return s
138
139     @staticmethod
140     def read_wstring(raw_io, length):
141         """ read a string of a specific length from raw_io """
142         buffer = raw_io.read(length)
143         if not buffer:
144             raise EOFError()
145         eol = buffer.find(FpxSpec.STRING_TERMINATION)
146         register_error(FpxSpec.STRING_FPX_REPLACE, FpxSpec.fpx_replace)
147         s = buffer[:eol].decode(encoding=FpxSpec.WSTRING_ENCODING, errors=FpxSpec.STRING_ERROR)
148         return s
149
150
151
152 ###############################################################################
153 class Fp_Stream_Reader(Cfb_Stream_Reader):
154     pass
155
156
157 class Fp_Size_Type(Cfb_Size_Type):
158     FLOAT = 4
159     pass
160
161
162 """
163 class Fpm_File_Reader(Cfb_RawIO_Reader):
164     pass
165
166
167 class Fpl_File_Reader(Cfb_RawIO_Reader):
168     pass
169 """
170
171 class FpmCollisionData:
172     SIZE =  (4 * Fp_Size_Type.DWORD + 7 * Fp_Size_Type.FLOAT)
173
174     def __init__(self):
175         self.type = 0 #DWORD
176         self.generateHit = 0 #DWORD
177         self.effectBall = 0 #DWORD
178         self.eventID = 0 #DWORD
179         self.x = 0.0 #FLOAT
180         self.y = 0.0 #FLOAT
181         self.z = 0.0 #FLOAT
182         self.value1 = 0.0 #FLOAT
183         self.value2 = 0.0 #FLOAT
184         self.value3 = 0.0 #FLOAT
185         self.value4 = 0.0 #FLOAT
186
187     def __repr__(self):
188         return "<{} type=\"{}\", generateHit=\"{}\", effectBall=\"{}\", x=\"{}\", y=\"{}\", z=\"{}\", value1=\"{}\", value2=\"{}\", value3=\"{}\", value4=\"{}\" />".fomat(
189                 __class__.__name__,
190                 self.type,
191                 self.generateHit,
192                 self.effectBall,
193                 self.eventID,
194                 self.x,
195                 self.y,
196                 self.z,
197                 self.value1,
198                 self.value2,
199                 self.value3,
200                 self.value4,
201                 )
202
203
204 ###############################################################################
205 class Fpm_Model_Type:
206     OBJECT_OBJECT = 0 ## e.g.: BULB, COIN_DOOR, FLIPPER_BUTTON, PLUNGER_CASE, RAMP_PROFILE, SHOOTER_LANE, SLING_HAMMER, WIRE_RING, ...
207     OBJECT_PEG = 1 # # e.g.: GAME_ROOM, CABINE_LEG, LOCK_DOWN_BAR, RAIL,
208     CONTROL_FLIPPER = 2 #
209     CONTROL_BUMPER_BASE = 3 #
210     CONTROL_BUMPER_CAP = 4 #
211     TARGET_TARGET = 5 #
212     TARGET_DROP = 6 #
213     CONTROL_PLUNGER = 7 #
214     OBJECT_ORNAMENT = 8 # # e.g.: BALL
215     CONTROL_KICKER = 9 #
216     GUIDE_LANE = 10 #
217     RUBBER_MODEL = 11 #
218     TRIGGER_TRIGGER = 12 #
219     LIGHT_FLASHER = 13 #
220     LIGHT_BULB = 14 #
221     TRIGGER_GATE = 15 #
222     TRIGGER_SPINNER = 16 #
223     TOY_CUSTOM = 17
224     CONTROL_DIVERTER = 18 #
225     CONTROL_AUTOPLUNGER = 19 #
226     CONTROL_POPUP = 20 #
227     RAMP_MODEL = 21 # e.g.: Scoop-Bracket-T1.fpm
228     RAMP_WIRE_CAP = 22 #
229     TOY_SPINNINGDISK = 23 #
230     CONTROL_EMKICKER = 24 #
231     TRIGGER_OPTO = 25 #
232     TARGET_VARI = 26 ## e.g.: Target-Vari-T1.fpm
233
234     SET_ALIGN_BOTTOM = {
235             OBJECT_ORNAMENT,
236             RAMP_MODEL,
237             TARGET_DROP,
238             TARGET_TARGET,
239             }
240
241     SET_ALIGN_TOP = {
242             TOY_SPINNINGDISK,
243             }
244
245     SET_ALIGN_NONE = {
246             OBJECT_OBJECT,
247             CONTROL_PLUNGER,
248             TARGET_DROP,
249             TRIGGER_GATE,
250             TRIGGER_SPINNER,
251             TRIGGER_OPTO,
252             TARGET_VARI,
253             RAMP_WIRE_CAP
254             }
255
256     VALUE_INT_TO_NAME = {
257             OBJECT_OBJECT: 'OBJECT_OBJECT',
258             OBJECT_PEG: 'OBJECT_PEG',
259             CONTROL_FLIPPER: 'CONTROL_FLIPPER',
260             CONTROL_BUMPER_BASE: 'CONTROL_BUMPER_BASE',
261             CONTROL_BUMPER_CAP: 'CONTROL_BUMPER_CAP',
262             TARGET_TARGET: 'TARGET_TARGET',
263             TARGET_DROP: 'TARGET_DROP',
264             CONTROL_PLUNGER: 'CONTROL_PLUNGER',
265             OBJECT_ORNAMENT: 'OBJECT_ORNAMENT',
266             CONTROL_KICKER: 'CONTROL_KICKER',
267             GUIDE_LANE: 'GUIDE_LANE',
268             RUBBER_MODEL: 'RUBBER_MODEL',
269             TRIGGER_TRIGGER: 'TRIGGER_TRIGGER',
270             LIGHT_FLASHER: 'LIGHT_FLASHER',
271             LIGHT_BULB: 'LIGHT_BULB',
272             TRIGGER_GATE: 'TRIGGER_GATE',
273             TRIGGER_SPINNER: 'TRIGGER_SPINNER',
274             TOY_CUSTOM: 'TOY_CUSTOM',
275             CONTROL_DIVERTER: 'CONTROL_DIVERTER',
276             CONTROL_AUTOPLUNGER: 'CONTROL_AUTOPLUNGER',
277             CONTROL_POPUP: 'CONTROL_POPUP',
278             RAMP_MODEL: 'RAMP_MODEL',
279             RAMP_WIRE_CAP: 'RAMP_WIRE_CAP',
280             TOY_SPINNINGDISK: 'TOY_SPINNINGDISK',
281             CONTROL_EMKICKER: 'CONTROL_EMKICKER',
282             TRIGGER_OPTO: 'TRIGGER_OPTO',
283             TARGET_VARI: 'TARGET_VARI',
284             }
285
286
287 class Fpl_Library_Type:
288     UNKNOWN = 0
289     GRAPHIC = 1
290     SOUND = 2
291     MUSIC = 3
292     MODEL = 4
293     DMDFONT = 5
294     SCRIPT = 6
295
296     TYPE_UNKNOWN = 'UNKNOWN'
297     TYPE_GRAPHIC = 'GRAPHIC'
298     TYPE_SOUND = 'SOUND'
299     TYPE_MUSIC = 'MUSIC'
300     TYPE_MODEL = 'MODEL'
301     TYPE_DMDFONT = 'DMDFONT'
302     TYPE_SCRIPT = 'SCRIPT'
303
304     FILTER_ALL = {TYPE_GRAPHIC, TYPE_SOUND, TYPE_MUSIC, TYPE_MODEL, TYPE_DMDFONT, TYPE_SCRIPT, TYPE_UNKNOWN, }
305
306 class Fpt_PackedLibrary_Type:
307     UNKNOWN = Fpl_Library_Type.UNKNOWN
308     IMAGE = Fpl_Library_Type.GRAPHIC
309     SOUND = Fpl_Library_Type.SOUND
310     MUSIC = Fpl_Library_Type.MUSIC
311     MODEL = Fpl_Library_Type.MODEL
312     DMDFONT = Fpl_Library_Type.DMDFONT
313     SCRIPT = Fpl_Library_Type.SCRIPT
314     IMAGE_LIST = 7
315     LIGHT_LIST = 8
316
317     TYPE_UNKNOWN = Fpl_Library_Type.TYPE_UNKNOWN
318     TYPE_IMAGE = Fpl_Library_Type.TYPE_GRAPHIC
319     TYPE_SOUND = Fpl_Library_Type.TYPE_SOUND
320     TYPE_MUSIC = Fpl_Library_Type.TYPE_MUSIC
321     TYPE_MODEL = Fpl_Library_Type.TYPE_MODEL
322     TYPE_DMDFONT = Fpl_Library_Type.TYPE_DMDFONT
323     TYPE_SCRIPT = Fpl_Library_Type.TYPE_SCRIPT
324     TYPE_IMAGE_LIST = 'IMAGE_LIST'
325     TYPE_LIGHT_LIST = 'LIGHT_LIST'
326
327     FILTER_ALL = {TYPE_IMAGE, TYPE_SOUND, TYPE_MUSIC, TYPE_MODEL, TYPE_DMDFONT, TYPE_SCRIPT, TYPE_IMAGE_LIST, TYPE_LIGHT_LIST, TYPE_UNKNOWN, }
328
329 class Fpt_Resource_Type:
330     BMP = 1
331     JPG = 2
332     TGA = 4
333     WAV = 6
334     MP3 = 7
335     OGG = 9
336     DMD = 15
337
338     TYPE_BMP = 'BMP'
339     TYPE_JPG = 'JPG'
340     TYPE_TGA = 'TGA'
341     TYPE_WAV = 'WAV'
342     TYPE_OGG = 'OGG'
343     TYPE_MP3 = 'MP3'
344     TYPE_DMD = 'DMD'
345
346     VALUE_INT_TO_NAME = {
347             BMP: TYPE_BMP,
348             JPG: TYPE_JPG,
349             TGA: TYPE_TGA,
350             WAV: TYPE_WAV,
351             OGG: TYPE_OGG,
352             MP3: TYPE_MP3,
353             DMD: TYPE_DMD,
354             }
355
356     FILTER_ALL_IMAGES = {TYPE_BMP, TYPE_JPG, TYPE_TGA, }
357     FILTER_ALL_SOUNDS = {TYPE_OGG, TYPE_WAV, }
358     FILTER_ALL_MUSICS = {TYPE_OGG, TYPE_MP3, }
359     FILTER_ALL_DMDFONTS = {TYPE_DMD, }
360
361
362 class Fpt_Chunk_Type:
363     END = -1
364     RAWDATA = 0
365     INT = 1
366     FLOAT = 2
367     COLOR = 3
368     VECTOR2D = 4
369     STRING = 5
370     WSTRING = 6
371     STRINGLIST = 7
372     VALUELIST = 8
373     COLLISIONDATA = 9
374     CHUNKLIST = 10
375     GENERIC = 11
376
377
378 class FptElementType:
379     SURFACE = 2
380     LIGHT_ROUND = 3
381     LIGHT_SHAPEABLE = 4
382     OBJECT_PEG = 6
383     CONTROL_FLIPPER = 7
384     CONTROL_BUMPER = 8
385     TARGET_LEAF = 10
386     TARGET_DROP = 11
387     CONTROL_PLUNGER = 12
388     RUBBER_ROUND = 13
389     RUBBER_SHAPEABLE = 14
390     OBJECT_ORNAMENT = 15
391     GUIDE_WALL = 16
392     SPECIAL_TIMER = 17
393     SPECIAL_DECAL = 18
394     CONTROL_KICKER = 19
395     GUIDE_LANE = 20
396     RUBBER_MODEL = 21
397     TRIGGER_TRIGGER = 22
398     LIGHT_FLASHER = 23
399     GUIDE_WIRE = 24
400     DISPLAY_DISPREEL = 25
401     DISPLAY_HUDREEL = 26
402     SPECIAL_OVERLAY = 27
403     LIGHT_BULB = 29
404     TRIGGER_GATE = 30
405     TRIGGER_SPINNER = 31
406     TOY_CUSTOM = 33
407     LIGHT_SEQUENCER = 34
408     DISPLAY_SEGMENT = 37
409     DISPLAY_HUDSEGMENT = 38
410     DISPLAY_DMD = 39
411     DISPLAY_HUDDMD = 40
412     CONTROL_DIVERTER = 43
413     SPECIAL_STA = 44
414     CONTROL_AUTOPLUNGER = 46
415     TARGET_ROTO = 49
416     CONTROL_POPUP = 50
417     RAMP_MODEL = 51
418     RAMP_WIRE = 53
419     TARGET_SWING = 54
420     RAMP_RAMP = 55
421     TOY_SPINNINGDISK = 56
422     LIGHT_LIGHTIMAGE = 57
423     KICKER_EMKICKER = 58
424     LIGHT_HUDLIGHTIMAGE = 60
425     TRIGGER_OPTO = 61
426     TARGET_VARI = 62
427     TOY_HOLOGRAM = 64
428
429     SET_MESH_OBJECTS = {
430             OBJECT_PEG,
431             CONTROL_FLIPPER,
432             CONTROL_BUMPER,
433             TARGET_LEAF,
434             TARGET_DROP,
435             CONTROL_PLUNGER,
436             OBJECT_ORNAMENT,
437             CONTROL_KICKER,
438             RUBBER_MODEL,
439             TRIGGER_TRIGGER,
440             LIGHT_FLASHER,
441             SPECIAL_OVERLAY,
442             LIGHT_BULB,
443             TRIGGER_GATE,
444             TRIGGER_SPINNER,
445             TOY_CUSTOM,
446             CONTROL_DIVERTER,
447             CONTROL_AUTOPLUNGER,
448             TARGET_ROTO,
449             CONTROL_POPUP,
450             TOY_SPINNINGDISK,
451             KICKER_EMKICKER,
452             TRIGGER_OPTO,
453             TARGET_VARI,
454             TOY_HOLOGRAM,
455             }
456
457     SET_LIGHT_OBJECTS = {
458             LIGHT_ROUND,
459             LIGHT_SHAPEABLE,
460             CONTROL_BUMPER,
461             LIGHT_FLASHER,
462             DISPLAY_DISPREEL,
463             DISPLAY_HUDREEL,
464             LIGHT_BULB,
465             LIGHT_SEQUENCER,
466             DISPLAY_SEGMENT,
467             DISPLAY_HUDSEGMENT,
468             DISPLAY_DMD,
469             DISPLAY_HUDDMD,
470             LIGHT_LIGHTIMAGE,
471             LIGHT_HUDLIGHTIMAGE,
472             TOY_HOLOGRAM,
473             }
474
475     SET_RUBBER_OBJECTS = {
476             RUBBER_ROUND,
477             RUBBER_SHAPEABLE,
478             }
479
480     SET_SPHERE_MAPPING_OBJECTS = {
481             SURFACE,
482             OBJECT_PEG,
483             OBJECT_ORNAMENT,
484             GUIDE_WALL,
485             TRIGGER_TRIGGER,
486             TRIGGER_GATE,
487             TOY_CUSTOM,
488             CONTROL_DIVERTER,
489             CONTROL_POPUP,
490             RAMP_MODEL,
491             RAMP_RAMP,
492             TARGET_VARI,
493             }
494
495     SET_WIRE_OBJECTS = {
496             GUIDE_WIRE,
497             RAMP_WIRE,
498             }
499
500     SET_CURVE_OBJECTS = {
501             SURFACE,
502             LIGHT_ROUND,
503             LIGHT_SHAPEABLE,
504             RUBBER_ROUND,
505             RUBBER_SHAPEABLE,
506             GUIDE_WALL,
507             GUIDE_WIRE,
508             RAMP_WIRE,
509             RAMP_RAMP,
510             }
511
512     VALUE_NAME_TO_INT = {
513             'SURFACE': SURFACE,
514             'LIGHT_ROUND': LIGHT_ROUND,
515             'LIGHT_SHAPEABLE': LIGHT_SHAPEABLE,
516             'OBJECT_PEG': OBJECT_PEG,
517             'CONTROL_FLIPPER': CONTROL_FLIPPER,
518             'CONTROL_BUMPER': CONTROL_BUMPER,
519             'TARGET_LEAF': TARGET_LEAF,
520             'TARGET_DROP': TARGET_DROP,
521             'CONTROL_PLUNGER': CONTROL_PLUNGER,
522             'RUBBER_ROUND': RUBBER_ROUND,
523             'RUBBER_SHAPEABLE': RUBBER_SHAPEABLE,
524             'OBJECT_ORNAMENT': OBJECT_ORNAMENT,
525             'GUIDE_WALL': GUIDE_WALL,
526             'SPECIAL_TIMER': SPECIAL_TIMER,
527             'SPECIAL_DECAL': SPECIAL_DECAL,
528             'CONTROL_KICKER': CONTROL_KICKER,
529             'GUIDE_LANE': GUIDE_LANE,
530             'RUBBER_MODEL': RUBBER_MODEL,
531             'TRIGGER_TRIGGER': TRIGGER_TRIGGER,
532             'LIGHT_FLASHER': LIGHT_FLASHER,
533             'GUIDE_WIRE': GUIDE_WIRE,
534             'DISPLAY_DISPREEL': DISPLAY_DISPREEL,
535             'DISPLAY_HUDREEL': DISPLAY_HUDREEL,
536             'SPECIAL_OVERLAY': SPECIAL_OVERLAY,
537             'LIGHT_BULB': LIGHT_BULB,
538             'TRIGGER_GATE': TRIGGER_GATE,
539             'TRIGGER_SPINNER': TRIGGER_SPINNER,
540             'TOY_CUSTOM': TOY_CUSTOM,
541             'LIGHT_SEQUENCER': LIGHT_SEQUENCER,
542             'DISPLAY_SEGMENT': DISPLAY_SEGMENT,
543             'DISPLAY_HUDSEGMENT': DISPLAY_HUDSEGMENT,
544             'DISPLAY_DMD': DISPLAY_DMD,
545             'DISPLAY_HUDDMD': DISPLAY_HUDDMD,
546             'CONTROL_DIVERTER': CONTROL_DIVERTER,
547             'SPECIAL_STA': SPECIAL_STA,
548             'CONTROL_AUTOPLUNGER': CONTROL_AUTOPLUNGER,
549             'TARGET_ROTO': TARGET_ROTO,
550             'CONTROL_POPUP': CONTROL_POPUP,
551             'RAMP_MODEL': RAMP_MODEL,
552             'RAMP_WIRE': RAMP_WIRE,
553             'TARGET_SWING': TARGET_SWING,
554             'RAMP_RAMP': RAMP_RAMP,
555             'TOY_SPINNINGDISK': TOY_SPINNINGDISK,
556             'LIGHT_LIGHTIMAGE': LIGHT_LIGHTIMAGE,
557             'KICKER_EMKICKER': KICKER_EMKICKER,
558             'LIGHT_HUDLIGHTIMAGE': LIGHT_HUDLIGHTIMAGE,
559             'TRIGGER_OPTO': TRIGGER_OPTO,
560             'TARGET_VARI': TARGET_VARI,
561             'TOY_HOLOGRAM': TOY_HOLOGRAM,
562             }
563
564     VALUE_INT_TO_NAME = {
565             SURFACE: 'SURFACE',
566             LIGHT_ROUND: 'LIGHT_ROUND',
567             LIGHT_SHAPEABLE: 'LIGHT_SHAPEABLE',
568             OBJECT_PEG: 'OBJECT_PEG',
569             CONTROL_FLIPPER: 'CONTROL_FLIPPER',
570             CONTROL_BUMPER: 'CONTROL_BUMPER',
571             TARGET_LEAF: 'TARGET_LEAF',
572             TARGET_DROP: 'TARGET_DROP',
573             CONTROL_PLUNGER: 'CONTROL_PLUNGER',
574             RUBBER_ROUND: 'RUBBER_ROUND',
575             RUBBER_SHAPEABLE: 'RUBBER_SHAPEABLE',
576             OBJECT_ORNAMENT: 'OBJECT_ORNAMENT',
577             GUIDE_WALL: 'GUIDE_WALL',
578             SPECIAL_TIMER: 'SPECIAL_TIMER',
579             SPECIAL_DECAL: 'SPECIAL_DECAL',
580             CONTROL_KICKER: 'CONTROL_KICKER',
581             GUIDE_LANE: 'GUIDE_LANE',
582             RUBBER_MODEL: 'RUBBER_MODEL',
583             TRIGGER_TRIGGER: 'TRIGGER_TRIGGER',
584             LIGHT_FLASHER: 'LIGHT_FLASHER',
585             GUIDE_WIRE: 'GUIDE_WIRE',
586             DISPLAY_DISPREEL: 'DISPLAY_DISPREEL',
587             DISPLAY_HUDREEL: 'DISPLAY_HUDREEL',
588             SPECIAL_OVERLAY: 'SPECIAL_OVERLAY',
589             LIGHT_BULB: 'LIGHT_BULB',
590             TRIGGER_GATE: 'TRIGGER_GATE',
591             TRIGGER_SPINNER: 'TRIGGER_SPINNER',
592             TOY_CUSTOM: 'TOY_CUSTOM',
593             LIGHT_SEQUENCER: 'LIGHT_SEQUENCER',
594             DISPLAY_SEGMENT: 'DISPLAY_SEGMENT',
595             DISPLAY_HUDSEGMENT: 'DISPLAY_HUDSEGMENT',
596             DISPLAY_DMD: 'DISPLAY_DMD',
597             DISPLAY_HUDDMD: 'DISPLAY_HUDDMD',
598             CONTROL_DIVERTER: 'CONTROL_DIVERTER',
599             SPECIAL_STA: 'SPECIAL_STA',
600             CONTROL_AUTOPLUNGER: 'CONTROL_AUTOPLUNGER',
601             TARGET_ROTO: 'TARGET_ROTO',
602             CONTROL_POPUP: 'CONTROL_POPUP',
603             RAMP_MODEL: 'RAMP_MODEL',
604             RAMP_WIRE: 'RAMP_WIRE',
605             TARGET_SWING: 'TARGET_SWING',
606             RAMP_RAMP: 'RAMP_RAMP',
607             TOY_SPINNINGDISK: 'TOY_SPINNINGDISK',
608             LIGHT_LIGHTIMAGE: 'LIGHT_LIGHTIMAGE',
609             KICKER_EMKICKER: 'KICKER_EMKICKER',
610             LIGHT_HUDLIGHTIMAGE: 'LIGHT_HUDLIGHTIMAGE',
611             TRIGGER_OPTO: 'TRIGGER_OPTO',
612             TARGET_VARI: 'TARGET_VARI',
613             TOY_HOLOGRAM: 'TOY_HOLOGRAM',
614             }
615
616
617 ###############################################################################
618 class Fpx_zLZO_RawData_Stream:
619     def __init__(self, stream, n=-1):
620         buffer = stream.read(4)
621         if buffer == b'zLZO':
622             self.signature = buffer
623             self.uncompressed_size = stream.read_dword()
624             if n != -1:
625                 n -= (4 + Fp_Size_Type.DWORD)
626         else:
627             self.signature = None
628             stream.seek(-4, SEEK_CUR)
629         self.src_buffer = stream.read(n)
630
631     def grab_to_file(self, filename):
632         with FileIO(filename, "wb") as raw_io:
633             if not self.signature:
634                 raw_io.write(self.src_buffer)
635             else:
636                 dst_buffer = bytearray(self.uncompressed_size)
637                 src_size = len(self.src_buffer)
638                 Lzo_Codec.Lzo1x_Decompress(self.src_buffer, 0, src_size, dst_buffer, 0)
639                 raw_io.write(dst_buffer)
640
641             raw_io.flush()
642             raw_io.close()
643
644
645 ###############################################################################
646 class Fpt_ChunkDescription:
647     def __init__(self, id=0, type=Fpt_Chunk_Type.RAWDATA, name='', offset=0):
648         self.id = id
649         self.type = type
650         self.name = "val__" + name
651         self.offset = offset
652
653     def __repr__(self):
654         return "<{} id=\"{}\"/, type=\"{}\", name=\"{}\", offset=\"{}\" />".fomat(
655                 __class__.__name__,
656                 self.id,
657                 self.type,
658                 self.name,
659                 self.offset,
660                 )
661
662
663 class Fpt_Data_Reader:
664     NEW_OLD_CORRECTION = 0x15BDECDB
665
666     def __repr__(self):
667         str_list = []
668         str_list.append("<")
669
670         class_name = getattr(self, "obj__class", None)
671         if class_name is None:
672             class_name = __class__
673         str_list.append("{} ".format(class_name))
674
675         obj_name = getattr(self, "obj__name", None)
676         if obj_name is not None:
677             str_list.append("obj__name=\"{}\", ".format(obj_name))
678
679         name = self.get_value("name")
680         if name:
681             str_list.append("name=\"{}\", ".format(name))
682
683         d = dir(self)
684         for attr in d:
685             if attr == "val__end":
686                 continue
687             elif attr == "val__name" and name:
688                 continue
689             elif attr.startswith("val__unknown_"):
690                 continue
691             elif attr.startswith("val__"):
692                 v = getattr(self, attr, None)
693                 if v is not None:
694                     if isinstance(v, bytes) and len(v) > 4:
695                         v = v[:4] + b'...'
696                     str_list.append("{}=\"{}\", ".format(attr.replace("val__", ""), v))
697             else:
698                 pass
699         str_list.append("/>")
700         result = "".join(str_list)
701         return result
702
703     def get_value(self, name, default=None):
704         v = getattr(self, "val__" + name, default)
705         return v
706
707     def get_obj_value(self, name, default=None):
708         v = getattr(self, "obj__" + name, default)
709         return v
710
711     def read(self, stream, owner=None):
712         if owner is None:
713             owner = self
714
715         stream_size = stream.size()
716         while stream.tell() < stream_size:
717             chunk_size = stream.read_dword()
718             stream_pos = stream.tell()
719             chunk_id = stream.read_dword()
720             descriptor = self.obj__chunks.get(chunk_id)
721             if descriptor is None:
722                 # try the alternative chunk_id
723                 descriptor = self.obj__chunks.get(chunk_id - Fpt_Data_Reader.NEW_OLD_CORRECTION)
724             if descriptor is None:
725                 # unknown chunk type
726                 stream.read(chunk_size - Fp_Size_Type.DWORD)
727                 print("#DEBUG unknown chunk id:", "0x{:08X}".format(chunk_id), ", size:", chunk_size - Fp_Size_Type.DWORD, " in ", self.get_obj_value("class"), self)
728             else:
729                 self.read_chunk_data(stream, owner, stream_pos, chunk_size, descriptor)
730
731             if self.read_breaker(owner):
732                 break
733
734     def read_breaker(self, owner):
735         pass
736
737     def read_int(self, stream):
738         return unpack("<i", stream.read(4))[0]
739
740     def read_float(self, stream):
741         return unpack("<f", stream.read(4))[0]
742
743     def read_color(self, stream):
744         return unpack("<BBBB", stream.read(4))
745
746     def read_vector2d(self, stream):
747         return unpack("<ff", stream.read(8))
748
749     def read_string(self, stream):
750         size = stream.read_dword()
751         buffer = stream.read(size)
752         register_error(FpxSpec.STRING_FPX_REPLACE, FpxSpec.fpx_replace)
753         value = buffer.decode(encoding=FpxSpec.STRING_ENCODING, errors=FpxSpec.STRING_ERROR)
754         return value
755
756     def read_wstring(self, stream):
757         size = stream.read_dword()
758         buffer = stream.read(size)
759         register_error(FpxSpec.STRING_FPX_REPLACE, FpxSpec.fpx_replace)
760         value = buffer.decode(encoding=FpxSpec.WSTRING_ENCODING, errors=FpxSpec.STRING_ERROR)
761         return value
762
763     def read_chunk_data(self, stream, owner, stream_pos, chunk_size, descriptor):
764         if descriptor.offset:
765             stream.seek(descriptor.offset, SEEK_CUR)
766
767         if descriptor.type == Fpt_Chunk_Type.RAWDATA:
768             value = Fpx_zLZO_RawData_Stream(stream, chunk_size - Fp_Size_Type.DWORD)
769         elif descriptor.type == Fpt_Chunk_Type.INT:
770             value = self.read_int(stream)
771         elif descriptor.type == Fpt_Chunk_Type.FLOAT:
772             value = self.read_float(stream)
773         elif descriptor.type == Fpt_Chunk_Type.COLOR:
774             value = self.read_color(stream)
775         elif descriptor.type == Fpt_Chunk_Type.VECTOR2D:
776             value = self.read_vector2d(stream)
777         elif descriptor.type == Fpt_Chunk_Type.STRING:
778             value = self.read_string(stream)
779         elif descriptor.type == Fpt_Chunk_Type.WSTRING:
780             value = self.read_wstring(stream)
781         elif descriptor.type == Fpt_Chunk_Type.STRINGLIST:
782             value = []
783             num_items = self.read_int(stream)
784             for i in range(num_items):
785                 value.append(self.read_string(stream))
786         elif descriptor.type == Fpt_Chunk_Type.VALUELIST:
787             value = None # TODO
788         elif descriptor.type == Fpt_Chunk_Type.COLLISIONDATA:
789              # TODO
790             n = chunk_size / FpmCollisionData.SIZE
791             value = None
792         elif descriptor.type == Fpt_Chunk_Type.CHUNKLIST:
793             if descriptor.name == "val__shape_point":
794                 sub_reader = Fpt_SubData_Shape_Point_Reader()
795                 if sub_reader:
796                     sub_reader.read(stream)
797             elif descriptor.name == "val__ramp_point":
798                 sub_reader = Fpt_SubData_Ramp_Point_Reader()
799                 if sub_reader:
800                     sub_reader.read(stream)
801             else:
802                 print("#DEBUG", descriptor.name, "not handled!")
803                 pass
804             value = getattr(owner, descriptor.name, None)
805             if value is None:
806                 value = []
807                 value.append(sub_reader)
808             else:
809                 value.append(sub_reader)
810                 return
811
812         elif descriptor.type == Fpt_Chunk_Type.GENERIC:
813             value = stream.read(chunk_size - Fp_Size_Type.DWORD)
814         elif descriptor.type == Fpt_Chunk_Type.END:
815             value = 1
816         else:
817             value = None
818
819         setattr(owner, descriptor.name, value)
820
821         if value is None:
822             stream.read(chunk_size - Fp_Size_Type.DWORD)
823
824
825 class Fpt_SubData_Shape_Point_Reader(Fpt_Data_Reader):
826     CHUNK_DICTIONARY = {
827             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
828             0xA1EDC5D2: Fpt_ChunkDescription(0xA1EDC5D2, Fpt_Chunk_Type.INT, "smooth"),
829             0xA2F3C6D2: Fpt_ChunkDescription(0xA2F3C6D2, Fpt_Chunk_Type.RAWDATA, "unknown_0xA2F3C6D2"), # slingshot ???
830             0xA8FCC6D2: Fpt_ChunkDescription(0xA8FCC6D2, Fpt_Chunk_Type.RAWDATA, "unknown_0xA8FCC6D2"), # single_leaf ???
831             0x99E9BEE4: Fpt_ChunkDescription(0x99E9BEE4, Fpt_Chunk_Type.INT, "automatic_texture_coordinate"),
832             0x9AFEBAD1: Fpt_ChunkDescription(0x9AFEBAD1, Fpt_Chunk_Type.FLOAT, "texture_coordinate"),
833             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
834             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
835             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
836             0x95F3BCE0: Fpt_ChunkDescription(0x95F3BCE0, Fpt_Chunk_Type.RAWDATA, "unknown_0x95F3BCE0"), # missed event_id ???
837             }
838
839     def __init__(self):
840         self.obj__class = "Shape_Point"
841         self.obj__id = "shape_point"
842         self.obj__chunks = Fpt_SubData_Shape_Point_Reader.CHUNK_DICTIONARY
843
844     def read_breaker(self, owner):
845         return getattr(owner, 'val__end', None)
846
847
848 class Fpt_SubData_Ramp_Point_Reader(Fpt_Data_Reader):
849     CHUNK_DICTIONARY = {
850             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
851             0xA1EDC5D2: Fpt_ChunkDescription(0xA1EDC5D2, Fpt_Chunk_Type.INT, "smooth"),
852             0xA2F3C6D2: Fpt_ChunkDescription(0xA2F3C6D2, Fpt_Chunk_Type.RAWDATA, "unknown_0xA2F3C6D2"), # slingshot ???
853             0xA8FCC6D2: Fpt_ChunkDescription(0xA8FCC6D2, Fpt_Chunk_Type.RAWDATA, "unknown_0xA8FCC6D2"), # single_leaf ???
854             0x99E9BEE4: Fpt_ChunkDescription(0x99E9BEE4, Fpt_Chunk_Type.INT, "automatic_texture_coordinate"),
855             0x9AFEBAD1: Fpt_ChunkDescription(0x9AFEBAD1, Fpt_Chunk_Type.FLOAT, "texture_coordinate"),
856             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
857             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
858             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
859             #0x9AF1CAE0: Fpt_ChunkDescription(0x9AF1CAE0, Fpt_Chunk_Type.RAWDATA, "unknown_0x9AF1CAE0"), # missed mark_as_ramp_end_point
860             #0xA0EFC2D0: Fpt_ChunkDescription(0xA0EFC2D0, Fpt_Chunk_Type.RAWDATA, "unknown_0xA0EFC2D0"), # missed right_upper_guide
861             #0xA0EFC9D8: Fpt_ChunkDescription(0xA0EFC9D8, Fpt_Chunk_Type.RAWDATA, "unknown_0xA0EFC9D8"), # missed right_guide
862             #0xA2F3C9D3: Fpt_ChunkDescription(0xA2F3C9D3, Fpt_Chunk_Type.RAWDATA, "unknown_0xA2F3C9D3"), # missed ring_type
863             #0xA4F5C2D0: Fpt_ChunkDescription(0xA4F5C2D0, Fpt_Chunk_Type.RAWDATA, "unknown_0xA4F5C2D0"), # missed left_upper_guide
864             #0xA4F5C9D8: Fpt_ChunkDescription(0xA4F5C9D8, Fpt_Chunk_Type.RAWDATA, "unknown_0xA4F5C9D8"), # missed left_guide
865             #0x95ECC3D1: Fpt_ChunkDescription(0x95ECC3D1, Fpt_Chunk_Type.RAWDATA, "unknown_0x95ECC3D1"), # missed top_wire
866
867             0xA4F5C9D8: Fpt_ChunkDescription(0xA4F5C9D8, Fpt_Chunk_Type.INT, "left_guide"),
868             0xA4F5C2D0: Fpt_ChunkDescription(0xA4F5C2D0, Fpt_Chunk_Type.INT, "left_upper_guide"),
869             0xA0EFC9D8: Fpt_ChunkDescription(0xA0EFC9D8, Fpt_Chunk_Type.INT, "right_guide"),
870             0xA0EFC2D0: Fpt_ChunkDescription(0xA0EFC2D0, Fpt_Chunk_Type.INT, "right_upper_guide"),
871             0x95ECC3D1: Fpt_ChunkDescription(0x95ECC3D1, Fpt_Chunk_Type.INT, "top_wire"),
872             0x9AF1CAE0: Fpt_ChunkDescription(0x9AF1CAE0, Fpt_Chunk_Type.INT, "mark_as_ramp_end_point"),
873             0xA2F3C9D3: Fpt_ChunkDescription(0xA2F3C9D3, Fpt_Chunk_Type.INT, "ring_type"),
874             }
875
876     def __init__(self):
877         self.obj__class = "Ramp_Point"
878         self.obj__id = "ramp_point"
879         self.obj__chunks = Fpt_SubData_Ramp_Point_Reader.CHUNK_DICTIONARY
880
881     def read_breaker(self, owner):
882         return getattr(owner, 'val__end', None)
883
884
885 class Fpt_Table_Data_Reader(Fpt_Data_Reader):
886     CHUNK_DICTIONARY = {
887             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
888             0xA5F8BBD1: Fpt_ChunkDescription(0xA5F8BBD1, Fpt_Chunk_Type.INT, "width"),
889             0x9BFCC6D1: Fpt_ChunkDescription(0x9BFCC6D1, Fpt_Chunk_Type.INT, "length"),
890             0xA1FACCD1: Fpt_ChunkDescription(0xA1FACCD1, Fpt_Chunk_Type.INT, "glass_height_front"),
891             0xA1FAC0D1: Fpt_ChunkDescription(0xA1FAC0D1, Fpt_Chunk_Type.INT, "glass_height_rear"),
892             0x9AF5BFD1: Fpt_ChunkDescription(0x9AF5BFD1, Fpt_Chunk_Type.FLOAT, "slope"),
893             0x9DF2CFD5: Fpt_ChunkDescription(0x9DF2CFD5, Fpt_Chunk_Type.COLOR, "playfield_color"),
894             0xA2F4C9D5: Fpt_ChunkDescription(0xA2F4C9D5, Fpt_Chunk_Type.STRING, "playfield_texture"),
895             0x9DF2CFE2: Fpt_ChunkDescription(0x9DF2CFE2, Fpt_Chunk_Type.COLOR, "cabinet_wood_color"),
896             0x9DF2CFE3: Fpt_ChunkDescription(0x9DF2CFE3, Fpt_Chunk_Type.COLOR, "button_color"),
897             0x9AFECBE3: Fpt_ChunkDescription(0x9AFECBE3, Fpt_Chunk_Type.COLOR, "translite_color"),
898             0xA2F4C9E3: Fpt_ChunkDescription(0xA2F4C9E3, Fpt_Chunk_Type.STRING, "translite_image"),
899             0x96F2C6DE: Fpt_ChunkDescription(0x96F2C6DE, Fpt_Chunk_Type.INT, "glossiness"),
900             0x95F5C9D1: Fpt_ChunkDescription(0x95F5C9D1, Fpt_Chunk_Type.INT, "warnings_before_tilt"),
901             0xA5F8C0DE: Fpt_ChunkDescription(0xA5F8C0DE, Fpt_Chunk_Type.INT, "display_grid_in_editor"),
902             0x96FDC0DE: Fpt_ChunkDescription(0x96FDC0DE, Fpt_Chunk_Type.INT, "grid_size"),
903             0xA0FBC2E1: Fpt_ChunkDescription(0xA0FBC2E1, Fpt_Chunk_Type.INT, "display_playfield_in_editor"),
904             0xA0FAD0E1: Fpt_ChunkDescription(0xA0FAD0E1, Fpt_Chunk_Type.INT, "display_tranlite_in_editor"),
905             0xA0EACBE3: Fpt_ChunkDescription(0xA0EACBE3, Fpt_Chunk_Type.INT, "translite_width"),
906             0xA4F9CBE3: Fpt_ChunkDescription(0xA4F9CBE3, Fpt_Chunk_Type.INT, "translite_height"),
907             0x99E8BED8: Fpt_ChunkDescription(0x99E8BED8, Fpt_Chunk_Type.INT, "machine_type"),
908             0xA2F4C9E2: Fpt_ChunkDescription(0xA2F4C9E2, Fpt_Chunk_Type.STRING, "cabinet_texture"),
909             0x95EEC3D5: Fpt_ChunkDescription(0x95EEC3D5, Fpt_Chunk_Type.STRING, "poster_image"),
910             0x9BF5CFD1: Fpt_ChunkDescription(0x9BF5CFD1, Fpt_Chunk_Type.FLOAT, "table_center_line"),
911             0x9BF5CCD1: Fpt_ChunkDescription(0x9BF5CCD1, Fpt_Chunk_Type.FLOAT, "table_flipper_line"),
912             0xA0FCBFE1: Fpt_ChunkDescription(0xA0FCBFE1, Fpt_Chunk_Type.RAWDATA, "unknown_0xA0FCBFE1"),
913             0x9AFECDD2: Fpt_ChunkDescription(0x9AFECDD2, Fpt_Chunk_Type.RAWDATA, "unknown_0x9AFECDD2"),
914             0x9BEDC9D1: Fpt_ChunkDescription(0x9BEDC9D1, Fpt_Chunk_Type.STRING, "table_name"),
915             0xA4EBC9D1: Fpt_ChunkDescription(0xA4EBC9D1, Fpt_Chunk_Type.STRING, "version"),
916             0x9500C9D1: Fpt_ChunkDescription(0x9500C9D1, Fpt_Chunk_Type.STRING, "table_authors"),
917             0xA5EFC9D1: Fpt_ChunkDescription(0xA5EFC9D1, Fpt_Chunk_Type.STRING, "release_date"),
918             0x9CFCC9D1: Fpt_ChunkDescription(0x9CFCC9D1, Fpt_Chunk_Type.STRING, "mail"),
919             0x96EAC9D1: Fpt_ChunkDescription(0x96EAC9D1, Fpt_Chunk_Type.STRING, "web_page"),
920             0xA4FDC9D1: Fpt_ChunkDescription(0xA4FDC9D1, Fpt_Chunk_Type.STRING, "description"),
921             0x96EFC9D1: Fpt_ChunkDescription(0x96EFC9D1, Fpt_Chunk_Type.INT, "rules_len"),
922             0x94EFC9D1: Fpt_ChunkDescription(0x94EFC9D1, Fpt_Chunk_Type.RAWDATA, "rules"),
923             0x99F5C9D1: Fpt_ChunkDescription(0x99F5C9D1, Fpt_Chunk_Type.STRING, "loading_picture"),
924             0x95FEC9D1: Fpt_ChunkDescription(0x95FEC9D1, Fpt_Chunk_Type.COLOR, "loading_color"),
925             0xA2F1D0DC: Fpt_ChunkDescription(0xA2F1D0DC, Fpt_Chunk_Type.INT, "ball_per_game"),
926             0xA700C8DC: Fpt_ChunkDescription(0xA700C8DC, Fpt_Chunk_Type.INT, "initial_jackpot"),
927             0x9C10CADC: Fpt_ChunkDescription(0x9C10CADC, Fpt_Chunk_Type.STRING, "high_scores_default_initial_1"),
928             0x9710CADC: Fpt_ChunkDescription(0x9710CADC, Fpt_Chunk_Type.INT, "high_scores_default_score_1"),
929             0x9C0FCADC: Fpt_ChunkDescription(0x9C0FCADC, Fpt_Chunk_Type.STRING, "high_scores_default_initial_2"),
930             0x970FCADC: Fpt_ChunkDescription(0x970FCADC, Fpt_Chunk_Type.INT, "high_scores_default_score_2"),
931             0x9C0ECADC: Fpt_ChunkDescription(0x9C0ECADC, Fpt_Chunk_Type.STRING, "high_scores_default_initial_3"),
932             0x970ECADC: Fpt_ChunkDescription(0x970ECADC, Fpt_Chunk_Type.INT, "high_scores_default_score_3"),
933             0x9C0DCADC: Fpt_ChunkDescription(0x9C0DCADC, Fpt_Chunk_Type.STRING, "high_scores_default_initial_4"),
934             0x970DCADC: Fpt_ChunkDescription(0x970DCADC, Fpt_Chunk_Type.INT, "high_scores_default_score_4"),
935             0x9BFBBFDC: Fpt_ChunkDescription(0x9BFBBFDC, Fpt_Chunk_Type.STRING, "special_score_title"),
936             0x93FBBFDC: Fpt_ChunkDescription(0x93FBBFDC, Fpt_Chunk_Type.INT, "special_score_value"),
937             0x96ECCFE2: Fpt_ChunkDescription(0x96ECCFE2, Fpt_Chunk_Type.RAWDATA, "unknown_0x96ECCFE2"),
938             0xA4FBBFDC: Fpt_ChunkDescription(0xA4FBBFDC, Fpt_Chunk_Type.STRING, "special_score_text"),
939             0x95FDCDD2: Fpt_ChunkDescription(0x95FDCDD2, Fpt_Chunk_Type.RAWDATA, "unknown_0x95FDCDD2"),
940             0xA2F4C9D2: Fpt_ChunkDescription(0xA2F4C9D2, Fpt_Chunk_Type.RAWDATA, "unknown_0xA2F4C9D2"),
941             0xA5F3BFD2: Fpt_ChunkDescription(0xA5F3BFD2, Fpt_Chunk_Type.RAWDATA, "unknown_0xA5F3BFD2"),
942             0x96ECC5D2: Fpt_ChunkDescription(0x96ECC5D2, Fpt_Chunk_Type.RAWDATA, "unknown_0x96ECC5D2"),
943             0xA5F2C5D2: Fpt_ChunkDescription(0xA5F2C5D2, Fpt_Chunk_Type.RAWDATA, "unknown_0xA5F2C5D2"),
944             0x95F5C9D2: Fpt_ChunkDescription(0x95F5C9D2, Fpt_Chunk_Type.RAWDATA, "unknown_0x95F5C9D2"),
945             0x95F5C6D2: Fpt_ChunkDescription(0x95F5C6D2, Fpt_Chunk_Type.RAWDATA, "unknown_0x95F5C6D2"),
946             0x9BFBCED2: Fpt_ChunkDescription(0x9BFBCED2, Fpt_Chunk_Type.RAWDATA, "unknown_0x9BFBCED2"),
947             0xA4FDC3E2: Fpt_ChunkDescription(0xA4FDC3E2, Fpt_Chunk_Type.GENERIC, "unknown_0xA4FDC3E2"),
948             0x4F5A4C7A: Fpt_ChunkDescription(0x4F5A4C7A, Fpt_Chunk_Type.RAWDATA, "script", -Fp_Size_Type.DWORD),
949             0x91FBCCD6: Fpt_ChunkDescription(0x91FBCCD6, Fpt_Chunk_Type.FLOAT, "translate_x"),
950             0x90FBCCD6: Fpt_ChunkDescription(0x90FBCCD6, Fpt_Chunk_Type.FLOAT, "translate_y"),
951             0x9200CFD2: Fpt_ChunkDescription(0x9200CFD2, Fpt_Chunk_Type.FLOAT, "scale_x"),
952             0x9100CFD2: Fpt_ChunkDescription(0x9100CFD2, Fpt_Chunk_Type.FLOAT, "scale_y"),
953             0x91EECCD6: Fpt_ChunkDescription(0x91EECCD6, Fpt_Chunk_Type.FLOAT, "translite_translate_x"),
954             0x90EECCD6: Fpt_ChunkDescription(0x90EECCD6, Fpt_Chunk_Type.FLOAT, "translite_translate_y"),
955             0x91EECFD2: Fpt_ChunkDescription(0x91EECFD2, Fpt_Chunk_Type.FLOAT, "translite_scale_x"),
956             0x90EECFD2: Fpt_ChunkDescription(0x90EECFD2, Fpt_Chunk_Type.FLOAT, "translite_scale_y"),
957             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
958
959             0x00000008: Fpt_ChunkDescription(0x00000008, Fpt_Chunk_Type.RAWDATA, "unknown_0x00000008"), # missed
960             0x95FBBFDC: Fpt_ChunkDescription(0x95FBBFDC, Fpt_Chunk_Type.RAWDATA, "unknown_0x95FBBFDC"), # missed
961             }
962
963     def __init__(self):
964         self.obj__class = "Table_Data"
965         self.obj__chunks = Fpt_Table_Data_Reader.CHUNK_DICTIONARY
966
967
968 class Fpt_File_Version_Reader(Fpt_Data_Reader):
969     def __init__(self):
970         self.obj__class = "File_Version"
971
972     def read(self, stream):
973         self.val__version = stream.read_dword()
974
975
976 class Fpt_Image_Reader(Fpt_Data_Reader):
977     CHUNK_DICTIONARY = {
978                 0xA4F1B9D1: Fpt_ChunkDescription(0xA4F1B9D1, Fpt_Chunk_Type.INT, "type"),
979                 0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.STRING, "name"),
980                 0xA4F4C4DC: Fpt_ChunkDescription(0xA4F4C4DC, Fpt_Chunk_Type.STRING, "id"),
981                 0xA1EDD1D5: Fpt_ChunkDescription(0xA1EDD1D5, Fpt_Chunk_Type.STRING, "linked_path"),
982                 0x9EF3C6D9: Fpt_ChunkDescription(0x9EF3C6D9, Fpt_Chunk_Type.INT, "linked"),
983                 0xA6E9BEE4: Fpt_ChunkDescription(0xA6E9BEE4, Fpt_Chunk_Type.INT, "s3tc_compression"),
984                 0x95F5CCE1: Fpt_ChunkDescription(0x95F5CCE1, Fpt_Chunk_Type.INT, "disable_filtering"),
985                 0x96F3C0D1: Fpt_ChunkDescription(0x96F3C0D1, Fpt_Chunk_Type.COLOR, "transparent_color"),
986                 0xA4E7C9D2: Fpt_ChunkDescription(0xA4E7C9D2, Fpt_Chunk_Type.INT, "data_len"),
987                 0xA8EDD1E1: Fpt_ChunkDescription(0xA8EDD1E1, Fpt_Chunk_Type.RAWDATA, "data"),
988                 0x95EFBBD9: Fpt_ChunkDescription(0x95EFBBD9, Fpt_Chunk_Type.RAWDATA, "unknown_0x95EFBBD9"),
989                 0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
990                 }
991
992     def __init__(self):
993         self.obj__class = "Image"
994         self.obj__chunks = Fpt_Image_Reader.CHUNK_DICTIONARY
995
996
997 class Fpt_Sound_Reader(Fpt_Data_Reader):
998     CHUNK_DICTIONARY = {
999                 0xA4F1B9D1: Fpt_ChunkDescription(0xA4F1B9D1, Fpt_Chunk_Type.INT, "type"),
1000                 0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.STRING, "name"),
1001                 0xA4F4C4DC: Fpt_ChunkDescription(0xA4F4C4DC, Fpt_Chunk_Type.STRING, "id"),
1002                 0xA1EDD1D5: Fpt_ChunkDescription(0xA1EDD1D5, Fpt_Chunk_Type.STRING, "linked_path"),
1003                 0x9EF3C6D9: Fpt_ChunkDescription(0x9EF3C6D9, Fpt_Chunk_Type.INT, "linked"),
1004                 0xA6E9BEE4: Fpt_ChunkDescription(0xA6E9BEE4, Fpt_Chunk_Type.INT, "use_compression"),
1005                 0x95F5CCE1: Fpt_ChunkDescription(0x95F5CCE1, Fpt_Chunk_Type.INT, "disable_filtering"),
1006                 0x96F3C0D1: Fpt_ChunkDescription(0x96F3C0D1, Fpt_Chunk_Type.COLOR, "transparent_color"),
1007                 0xA4E7C9D2: Fpt_ChunkDescription(0xA4E7C9D2, Fpt_Chunk_Type.INT, "data_len"),
1008                 0xA8EDD1E1: Fpt_ChunkDescription(0xA8EDD1E1, Fpt_Chunk_Type.RAWDATA, "data"),
1009                 0x95EFBBD9: Fpt_ChunkDescription(0x95EFBBD9, Fpt_Chunk_Type.RAWDATA, "unknown_0x95EFBBD9"),
1010                 0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
1011                 }
1012
1013     def __init__(self):
1014         self.obj__class = "Sound"
1015         self.obj__chunks = Fpt_Sound_Reader.CHUNK_DICTIONARY
1016
1017
1018 class Fpt_Music_Reader(Fpt_Data_Reader):
1019     CHUNK_DICTIONARY = {
1020                 0xA4F1B9D1: Fpt_ChunkDescription(0xA4F1B9D1, Fpt_Chunk_Type.INT, "type"),
1021                 0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.STRING, "name"),
1022                 0xA4F4C4DC: Fpt_ChunkDescription(0xA4F4C4DC, Fpt_Chunk_Type.STRING, "id"),
1023                 0xA1EDD1D5: Fpt_ChunkDescription(0xA1EDD1D5, Fpt_Chunk_Type.STRING, "linked_path"),
1024                 0x9EF3C6D9: Fpt_ChunkDescription(0x9EF3C6D9, Fpt_Chunk_Type.INT, "linked"),
1025                 0xA6E9BEE4: Fpt_ChunkDescription(0xA6E9BEE4, Fpt_Chunk_Type.INT, "use_compression"),
1026                 0x95F5CCE1: Fpt_ChunkDescription(0x95F5CCE1, Fpt_Chunk_Type.INT, "disable_filtering"),
1027                 0x96F3C0D1: Fpt_ChunkDescription(0x96F3C0D1, Fpt_Chunk_Type.COLOR, "transparent_color"),
1028                 0xA4E7C9D2: Fpt_ChunkDescription(0xA4E7C9D2, Fpt_Chunk_Type.INT, "data_len"),
1029                 0xA8EDD1E1: Fpt_ChunkDescription(0xA8EDD1E1, Fpt_Chunk_Type.RAWDATA, "data"),
1030                 0x95EFBBD9: Fpt_ChunkDescription(0x95EFBBD9, Fpt_Chunk_Type.RAWDATA, "unknown_0x95EFBBD9"),
1031                 0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
1032                 }
1033
1034     def __init__(self):
1035         self.obj__class = "Music"
1036         self.obj__chunks = Fpt_Music_Reader.CHUNK_DICTIONARY
1037
1038
1039 class Fpt_PinModel_Reader(Fpt_Data_Reader):
1040     CHUNK_DICTIONARY = {
1041             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.STRING, "name"),
1042             0xA4F4C4DC: Fpt_ChunkDescription(0xA4F4C4DC, Fpt_Chunk_Type.STRING, "id"),
1043             0x9EF3C6D9: Fpt_ChunkDescription(0x9EF3C6D9, Fpt_Chunk_Type.INT, "linked"),
1044             0xA4F1B9D1: Fpt_ChunkDescription(0xA4F1B9D1, Fpt_Chunk_Type.INT, "type"),
1045             0x99E8BED8: Fpt_ChunkDescription(0x99E8BED8, Fpt_Chunk_Type.INT, "material_type"),
1046             0x9D00C4DC: Fpt_ChunkDescription(0x9D00C4DC, Fpt_Chunk_Type.STRING, "preview_path"),
1047             0x8FF8BFDC: Fpt_ChunkDescription(0x8FF8BFDC, Fpt_Chunk_Type.INT, "preview_data_len"),
1048             0x9600CEDC: Fpt_ChunkDescription(0x9600CEDC, Fpt_Chunk_Type.RAWDATA, "preview_data"),
1049             0x9AFEC2D5: Fpt_ChunkDescription(0x9AFEC2D5, Fpt_Chunk_Type.INT, "per_polygon_collision"),
1050             0xA5F2C6E0: Fpt_ChunkDescription(0xA5F2C6E0, Fpt_Chunk_Type.INT, "secondary_model_enabled"),
1051             0xA5FDC3D9: Fpt_ChunkDescription(0xA5FDC3D9, Fpt_Chunk_Type.INT, "secondary_model_z_distance"),
1052             0xA8EFCBD3: Fpt_ChunkDescription(0xA8EFCBD3, Fpt_Chunk_Type.FLOAT, "special_value"),
1053             0xA5F2C5D5: Fpt_ChunkDescription(0xA5F2C5D5, Fpt_Chunk_Type.INT, "primary_model_enabled"),
1054             0x9D00C4D5: Fpt_ChunkDescription(0x9D00C4D5, Fpt_Chunk_Type.STRING, "primary_model_path"),
1055             0x8FF8BFD5: Fpt_ChunkDescription(0x8FF8BFD5, Fpt_Chunk_Type.INT, "primary_model_data_len"),
1056             0x9600CED5: Fpt_ChunkDescription(0x9600CED5, Fpt_Chunk_Type.RAWDATA, "primary_model_data"),
1057             0xA5F2C5D2: Fpt_ChunkDescription(0xA5F2C5D2, Fpt_Chunk_Type.INT, "secondary_model_enabled_at_z_distance"),
1058             0x9D00C4D2: Fpt_ChunkDescription(0x9D00C4D2, Fpt_Chunk_Type.STRING, "secondary_model_path"),
1059             0x8FF8BFD2: Fpt_ChunkDescription(0x8FF8BFD2, Fpt_Chunk_Type.INT, "secondary_model_data_len"),
1060             0x9600CED2: Fpt_ChunkDescription(0x9600CED2, Fpt_Chunk_Type.RAWDATA, "secondary_model_data"),
1061             0xA5F2C5D1: Fpt_ChunkDescription(0xA5F2C5D1, Fpt_Chunk_Type.INT, "mask_model_enabled"),
1062             0x9D00C4D1: Fpt_ChunkDescription(0x9D00C4D1, Fpt_Chunk_Type.STRING, "mask_model_path"),
1063             0x8FF8BFD1: Fpt_ChunkDescription(0x8FF8BFD1, Fpt_Chunk_Type.INT, "mask_model_data_len"),
1064             0x9600CED1: Fpt_ChunkDescription(0x9600CED1, Fpt_Chunk_Type.RAWDATA, "mask_model_data"),
1065             0x9CF1BDD3: Fpt_ChunkDescription(0x9CF1BDD3, Fpt_Chunk_Type.INT, "reflection_use_primary_model"),
1066             0xA5F2C5D3: Fpt_ChunkDescription(0xA5F2C5D3, Fpt_Chunk_Type.INT, "reflection_model_enabled"),
1067             0x9D00C4D3: Fpt_ChunkDescription(0x9D00C4D3, Fpt_Chunk_Type.STRING, "reflection_model_path"),
1068             0x8FF8BFD3: Fpt_ChunkDescription(0x8FF8BFD3, Fpt_Chunk_Type.INT, "reflection_model_data_len"),
1069             0x9600CED3: Fpt_ChunkDescription(0x9600CED3, Fpt_Chunk_Type.RAWDATA, "reflection_model_data"),
1070             0x8FEEC3E2: Fpt_ChunkDescription(0x8FEEC3E2, Fpt_Chunk_Type.INT, "nb_collision_shapes"),
1071             0x93FBC3E2: Fpt_ChunkDescription(0x93FBC3E2, Fpt_Chunk_Type.INT, "collision_shapes_enabled"),
1072             0x9DFCC3E2: Fpt_ChunkDescription(0x9DFCC3E2, Fpt_Chunk_Type.COLLISIONDATA, "collision_shapes_data"),
1073             0xA1EDD1D5: Fpt_ChunkDescription(0xA1EDD1D5, Fpt_Chunk_Type.STRING, "linked_path"),
1074             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
1075             }
1076
1077     def __init__(self):
1078         self.obj__class = "Pin_Model"
1079         self.obj__chunks = Fpt_PinModel_Reader.CHUNK_DICTIONARY
1080
1081
1082 class Fpt_ImageList_Reader(Fpt_Data_Reader):
1083     CHUNK_DICTIONARY = {
1084             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.STRING, "name"),
1085             0xA8EDD1E1: Fpt_ChunkDescription(0xA8EDD1E1, Fpt_Chunk_Type.STRINGLIST, "images"),
1086             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
1087             }
1088
1089     def __init__(self):
1090         self.obj__class = "Image_List"
1091         self.obj__chunks = Fpt_ImageList_Reader.CHUNK_DICTIONARY
1092
1093
1094 class Fpt_LightList_Reader(Fpt_Data_Reader):
1095     CHUNK_DICTIONARY = {
1096             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.STRING, "name"),
1097             0xA8EDD1E1: Fpt_ChunkDescription(0xA8EDD1E1, Fpt_Chunk_Type.STRINGLIST, "lights"),
1098             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
1099             }
1100
1101     def __init__(self):
1102         self.obj__class = "Light_List"
1103         self.obj__chunks = Fpt_LightList_Reader.CHUNK_DICTIONARY
1104
1105
1106 class Fpt_DmdFont_Reader(Fpt_Data_Reader):
1107     def __init__(self):
1108         self.obj__class = "Dmd_Font"
1109
1110     def read(self, stream):
1111         self.val__raw = stream.read()
1112
1113
1114 class Fpt_Table_MAC_Reader(Fpt_Data_Reader):
1115     def __init__(self):
1116         self.obj__class = "Table_MAC"
1117
1118     def read(self, stream):
1119         self.val__mac = stream.read(16)
1120
1121
1122
1123 ###############################################################################
1124 class FptTableElementReader(Fpt_Data_Reader):
1125     def read(self, stream):
1126         value = stream.read_dword()
1127         if value == FptElementType.SURFACE:
1128             reader = FptTableElementReader_SURFACE(self)
1129         elif value == FptElementType.LIGHT_ROUND:
1130             reader = FptTableElementReader_LIGHT_ROUND(self)
1131         elif value == FptElementType.LIGHT_SHAPEABLE:
1132             reader = FptTableElementReader_LIGHT_SHAPEABLE(self)
1133         elif value == FptElementType.OBJECT_PEG:
1134             reader = FptTableElementReader_OBJECT_PEG(self)
1135         elif value == FptElementType.CONTROL_FLIPPER:
1136             reader = FptTableElementReader_CONTROL_FLIPPER(self)
1137         elif value == FptElementType.CONTROL_BUMPER:
1138             reader = FptTableElementReader_CONTROL_BUMPER(self)
1139         elif value == FptElementType.TARGET_LEAF:
1140             reader = FptTableElementReader_TARGET_LEAF(self)
1141         elif value == FptElementType.TARGET_DROP:
1142             reader = FptTableElementReader_TARGET_DROP(self)
1143         elif value == FptElementType.CONTROL_PLUNGER:
1144             reader = FptTableElementReader_CONTROL_PLUNGER(self)
1145         elif value == FptElementType.RUBBER_ROUND:
1146             reader = FptTableElementReader_RUBBER_ROUND(self)
1147         elif value == FptElementType.RUBBER_SHAPEABLE:
1148             reader = FptTableElementReader_RUBBER_SHAPEABLE(self)
1149         elif value == FptElementType.OBJECT_ORNAMENT:
1150             reader = FptTableElementReader_OBJECT_ORNAMENT(self)
1151         elif value == FptElementType.GUIDE_WALL:
1152             reader = FptTableElementReader_GUIDE_WALL(self)
1153         elif value == FptElementType.SPECIAL_TIMER:
1154             reader = FptTableElementReader_SPECIAL_TIMER(self)
1155         elif value == FptElementType.SPECIAL_DECAL:
1156             reader = FptTableElementReader_SPECIAL_DECAL(self)
1157         elif value == FptElementType.CONTROL_KICKER:
1158             reader = FptTableElementReader_CONTROL_KICKER(self)
1159         elif value == FptElementType.GUIDE_LANE:
1160             reader = FptTableElementReader_GUIDE_LANE(self)
1161         elif value == FptElementType.RUBBER_MODEL:
1162             reader = FptTableElementReader_RUBBER_MODEL(self)
1163         elif value == FptElementType.TRIGGER_TRIGGER:
1164             reader = FptTableElementReader_TRIGGER_TRIGGER(self)
1165         elif value == FptElementType.LIGHT_FLASHER:
1166             reader = FptTableElementReader_LIGHT_FLASHER(self)
1167         elif value == FptElementType.GUIDE_WIRE:
1168             reader = FptTableElementReader_GUIDE_WIRE(self)
1169         elif value == FptElementType.DISPLAY_DISPREEL:
1170             reader = FptTableElementReader_DISPLAY_DISPREEL(self)
1171         elif value == FptElementType.DISPLAY_HUDREEL:
1172             reader = FptTableElementReader_DISPLAY_HUDREEL(self)
1173         elif value == FptElementType.SPECIAL_OVERLAY:
1174             reader = FptTableElementReader_SPECIAL_OVERLAY(self)
1175         elif value == FptElementType.LIGHT_BULB:
1176             reader = FptTableElementReader_LIGHT_BULB(self)
1177         elif value == FptElementType.TRIGGER_GATE:
1178             reader = FptTableElementReader_TRIGGER_GATE(self)
1179         elif value == FptElementType.TRIGGER_SPINNER:
1180             reader = FptTableElementReader_TRIGGER_SPINNER(self)
1181         elif value == FptElementType.TOY_CUSTOM:
1182             reader = FptTableElementReader_TOY_CUSTOM(self)
1183         elif value == FptElementType.LIGHT_SEQUENCER:
1184             reader = FptTableElementReader_LIGHT_SEQUENCER(self)
1185         elif value == FptElementType.DISPLAY_SEGMENT:
1186             reader = FptTableElementReader_DISPLAY_SEGMENT(self)
1187         elif value == FptElementType.DISPLAY_HUDSEGMENT:
1188             reader = FptTableElementReader_DISPLAY_HUDSEGMENT(self)
1189         elif value == FptElementType.DISPLAY_DMD:
1190             reader = FptTableElementReader_DISPLAY_DMD(self)
1191         elif value == FptElementType.DISPLAY_HUDDMD:
1192             reader = FptTableElementReader_DISPLAY_HUDDMD(self)
1193         elif value == FptElementType.CONTROL_DIVERTER:
1194             reader = FptTableElementReader_CONTROL_DIVERTER(self)
1195         elif value == FptElementType.SPECIAL_STA:
1196             reader = FptTableElementReader_SPECIAL_STA(self)
1197         elif value == FptElementType.CONTROL_AUTOPLUNGER:
1198             reader = FptTableElementReader_CONTROL_AUTOPLUNGER(self)
1199         elif value == FptElementType.TARGET_ROTO:
1200             reader = FptTableElementReader_TARGET_ROTO(self)
1201         elif value == FptElementType.CONTROL_POPUP:
1202             reader = FptTableElementReader_CONTROL_POPUP(self)
1203         elif value == FptElementType.RAMP_MODEL:
1204             reader = FptTableElementReader_RAMP_MODEL(self)
1205         elif value == FptElementType.RAMP_WIRE:
1206             reader = FptTableElementReader_RAMP_WIRE(self)
1207         elif value == FptElementType.TARGET_SWING:
1208             reader = FptTableElementReader_TARGET_SWING(self)
1209         elif value == FptElementType.RAMP_RAMP:
1210             reader = FptTableElementReader_RAMP_RAMP(self)
1211         elif value == FptElementType.TOY_SPINNINGDISK:
1212             reader = FptTableElementReader_TOY_SPINNINGDISK(self)
1213         elif value == FptElementType.LIGHT_LIGHTIMAGE:
1214             reader = FptTableElementReader_LIGHT_LIGHTIMAGE(self)
1215         elif value == FptElementType.KICKER_EMKICKER:
1216             reader = FptTableElementReader_KICKER_EMKICKER(self)
1217         elif value == FptElementType.LIGHT_HUDLIGHTIMAGE:
1218             reader = FptTableElementReader_LIGHT_HUDLIGHTIMAGE(self)
1219         elif value == FptElementType.TRIGGER_OPTO:
1220             reader = FptTableElementReader_TRIGGER_OPTO(self)
1221         elif value == FptElementType.TARGET_VARI:
1222             reader = FptTableElementReader_TARGET_VARI(self)
1223         elif value == FptElementType.TOY_HOLOGRAM:
1224             reader = FptTableElementReader_TOY_HOLOGRAM(self)
1225         else:
1226             print("#DEBUG", "unknown element type", value)
1227             pass
1228
1229         if reader:
1230             reader.read(stream, self)
1231
1232
1233 ###############################################################################
1234 class FptTableElementReader_SURFACE(Fpt_Data_Reader):
1235     CHUNK_DICTIONARY = {
1236             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
1237             0x91EDBEE1: Fpt_ChunkDescription(0x91EDBEE1, Fpt_Chunk_Type.INT, "display_image_in_editor"),
1238             0x9DF2CFD1: Fpt_ChunkDescription(0x9DF2CFD1, Fpt_Chunk_Type.COLOR, "top_color"),
1239             0xA2F4C9D1: Fpt_ChunkDescription(0xA2F4C9D1, Fpt_Chunk_Type.STRING, "top_texture"),
1240             0x91EDCFE2: Fpt_ChunkDescription(0x91EDCFE2, Fpt_Chunk_Type.INT, "cookie_cut"),
1241             0x95F4C2D2: Fpt_ChunkDescription(0x95F4C2D2, Fpt_Chunk_Type.INT, "sphere_map_the_top"),
1242             0x9DF2CFD2: Fpt_ChunkDescription(0x9DF2CFD2, Fpt_Chunk_Type.COLOR, "side_color"),
1243             0xA2F4C9D2: Fpt_ChunkDescription(0xA2F4C9D2, Fpt_Chunk_Type.STRING, "side_texture"),
1244             0x9C00C0D1: Fpt_ChunkDescription(0x9C00C0D1, Fpt_Chunk_Type.INT, "transparency"),
1245             0x99F2BEDD: Fpt_ChunkDescription(0x99F2BEDD, Fpt_Chunk_Type.FLOAT, "top_height"),
1246             0x95F2D0DD: Fpt_ChunkDescription(0x95F2D0DD, Fpt_Chunk_Type.FLOAT, "bottom_height"),
1247             0x99E8BED8: Fpt_ChunkDescription(0x99E8BED8, Fpt_Chunk_Type.INT, "material_type"),
1248             0x96F4C2D2: Fpt_ChunkDescription(0x96F4C2D2, Fpt_Chunk_Type.INT, "sphere_map_the_side"),
1249             0x97F2C4DF: Fpt_ChunkDescription(0x97F2C4DF, Fpt_Chunk_Type.INT, "flat_shading"),
1250             0x9100C6D5: Fpt_ChunkDescription(0x9100C6D5, Fpt_Chunk_Type.INT, "surface_is_a_playfield"),
1251             0x9DFBCDD3: Fpt_ChunkDescription(0x9DFBCDD3, Fpt_Chunk_Type.INT, "reflects_off_playfield"),
1252             0x9A00C5E0: Fpt_ChunkDescription(0x9A00C5E0, Fpt_Chunk_Type.STRING, "enamel_map"),
1253             0x95E9BED3: Fpt_ChunkDescription(0x95E9BED3, Fpt_Chunk_Type.INT, "reflect_texture"),
1254             0x97ECBFD3: Fpt_ChunkDescription(0x97ECBFD3, Fpt_Chunk_Type.STRING, "playfield"),
1255             0x99F2C0E1: Fpt_ChunkDescription(0x99F2C0E1, Fpt_Chunk_Type.INT, "dropped"),
1256             0x9DF5C3E2: Fpt_ChunkDescription(0x9DF5C3E2, Fpt_Chunk_Type.INT, "collidable"),
1257             0x97FDC4D3: Fpt_ChunkDescription(0x97FDC4D3, Fpt_Chunk_Type.INT, "render_object"),
1258             0x95EBCDDD: Fpt_ChunkDescription(0x95EBCDDD, Fpt_Chunk_Type.INT, "generate_hit_event"),
1259             0x95F3C2D2: Fpt_ChunkDescription(0x95F3C2D2, Fpt_Chunk_Type.CHUNKLIST, "shape_point"),
1260             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
1261             0xA1EDC5D2: Fpt_ChunkDescription(0xA1EDC5D2, Fpt_Chunk_Type.INT, "smooth"),
1262             0xA2F3C6D2: Fpt_ChunkDescription(0xA2F3C6D2, Fpt_Chunk_Type.RAWDATA, "unknown_0xA2F3C6D2"), # slingshot ???
1263             0xA8FCC6D2: Fpt_ChunkDescription(0xA8FCC6D2, Fpt_Chunk_Type.RAWDATA, "unknown_0xA8FCC6D2"), # single_leaf ???
1264             0x99E9BEE4: Fpt_ChunkDescription(0x99E9BEE4, Fpt_Chunk_Type.INT, "automatic_texture_coordinate"),
1265             0x9AFEBAD1: Fpt_ChunkDescription(0x9AFEBAD1, Fpt_Chunk_Type.FLOAT, "texture_coordinate"),
1266             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
1267             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
1268             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
1269         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
1270             }
1271
1272     def __init__(self, owner=None):
1273         if owner is None:
1274             owner = self
1275         owner.obj__class = "Table_Element_2"
1276         owner.obj__id = FptElementType.SURFACE
1277         owner.obj__name = "Surface"
1278         self.obj__chunks = FptTableElementReader_SURFACE.CHUNK_DICTIONARY
1279
1280
1281 class FptTableElementReader_LIGHT_ROUND(Fpt_Data_Reader):
1282     CHUNK_DICTIONARY = {
1283             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
1284             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
1285             0x9BFCCFDD: Fpt_ChunkDescription(0x9BFCCFDD, Fpt_Chunk_Type.VECTOR2D, "glow_center"),
1286             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"),
1287             0x96F3CDD9: Fpt_ChunkDescription(0x96F3CDD9, Fpt_Chunk_Type.STRING, "lens_texture"),
1288             0x9D00C9E1: Fpt_ChunkDescription(0x9D00C9E1, Fpt_Chunk_Type.INT, "diameter"),
1289             0x9DF2CFD9: Fpt_ChunkDescription(0x9DF2CFD9, Fpt_Chunk_Type.COLOR, "lit_color"),
1290             0xA6ECBFE4: Fpt_ChunkDescription(0xA6ECBFE4, Fpt_Chunk_Type.INT, "auto_set_unlit_color"),
1291             0x9DF2CFD0: Fpt_ChunkDescription(0x9DF2CFD0, Fpt_Chunk_Type.COLOR, "unlit_color"),
1292             0xA5F8BBE3: Fpt_ChunkDescription(0xA5F8BBE3, Fpt_Chunk_Type.INT, "border_width"),
1293             0x9DF2CFE3: Fpt_ChunkDescription(0x9DF2CFE3, Fpt_Chunk_Type.COLOR, "border_color"),
1294             0x91EDCFE2: Fpt_ChunkDescription(0x91EDCFE2, Fpt_Chunk_Type.INT, "cookie_cut"),
1295             0x96FDD1D3: Fpt_ChunkDescription(0x96FDD1D3, Fpt_Chunk_Type.INT, "glow_radius"),
1296             0x9600BED2: Fpt_ChunkDescription(0x9600BED2, Fpt_Chunk_Type.INT, "state"),
1297             0x95F3C9E3: Fpt_ChunkDescription(0x95F3C9E3, Fpt_Chunk_Type.INT, "blink_interval"),
1298             0x9600C2E3: Fpt_ChunkDescription(0x9600C2E3, Fpt_Chunk_Type.STRING, "blink_pattern"),
1299         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
1300             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
1301             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
1302             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
1303             }
1304
1305     def __init__(self, owner=None):
1306         if owner is None:
1307             owner = self
1308         owner.obj__class = "Table_Element_3"
1309         owner.obj__id = FptElementType.LIGHT_ROUND
1310         owner.obj__name = "Light_Round"
1311         self.obj__chunks = FptTableElementReader_LIGHT_ROUND.CHUNK_DICTIONARY
1312
1313
1314 class FptTableElementReader_LIGHT_SHAPEABLE(Fpt_Data_Reader):
1315     CHUNK_DICTIONARY = {
1316             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
1317             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "texture_position"),
1318             0x9BFCCFDD: Fpt_ChunkDescription(0x9BFCCFDD, Fpt_Chunk_Type.VECTOR2D, "halo_position"),
1319             0x96F3CDD9: Fpt_ChunkDescription(0x96F3CDD9, Fpt_Chunk_Type.STRING, "lens_texture"),
1320             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"), ## corrected
1321             #0xB9ADAAAD: Fpt_ChunkDescription(0xB9ADAAAD, Fpt_Chunk_Type.STRING, "surface"), ## wrong chunk id
1322             0x9DF2CFD9: Fpt_ChunkDescription(0x9DF2CFD9, Fpt_Chunk_Type.COLOR, "lit_color"),
1323             0xA6ECBFE4: Fpt_ChunkDescription(0xA6ECBFE4, Fpt_Chunk_Type.INT, "auto_set_unlit_color"),
1324             0x9DF2CFD0: Fpt_ChunkDescription(0x9DF2CFD0, Fpt_Chunk_Type.COLOR, "unlit_color"),
1325             0xA5F8BBE3: Fpt_ChunkDescription(0xA5F8BBE3, Fpt_Chunk_Type.INT, "border_width"),
1326             0x9DF2CFE3: Fpt_ChunkDescription(0x9DF2CFE3, Fpt_Chunk_Type.COLOR, "border_color"),
1327             0x91EDCFE2: Fpt_ChunkDescription(0x91EDCFE2, Fpt_Chunk_Type.INT, "cookie_cut"),
1328             0x96FDD1D3: Fpt_ChunkDescription(0x96FDD1D3, Fpt_Chunk_Type.INT, "glow_radius"),
1329             0x9600BED2: Fpt_ChunkDescription(0x9600BED2, Fpt_Chunk_Type.INT, "state"),
1330             0x95F3C9E3: Fpt_ChunkDescription(0x95F3C9E3, Fpt_Chunk_Type.INT, "blink_interval"),
1331             0x9600C2E3: Fpt_ChunkDescription(0x9600C2E3, Fpt_Chunk_Type.STRING, "blink_pattern"),
1332         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
1333             0x95F3C2D2: Fpt_ChunkDescription(0x95F3C2D2, Fpt_Chunk_Type.CHUNKLIST, "shape_point"),
1334             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
1335             0xA1EDC5D2: Fpt_ChunkDescription(0xA1EDC5D2, Fpt_Chunk_Type.INT, "smooth"),
1336             0xA2F3C6D2: Fpt_ChunkDescription(0xA2F3C6D2, Fpt_Chunk_Type.RAWDATA, "unknown_0xA2F3C6D2"), # slingshot ???
1337             0xA8FCC6D2: Fpt_ChunkDescription(0xA8FCC6D2, Fpt_Chunk_Type.RAWDATA, "unknown_0xA8FCC6D2"), # single_leaf ???
1338             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
1339             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
1340             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
1341             }
1342
1343
1344     def __init__(self, owner=None):
1345         if owner is None:
1346             owner = self
1347         owner.obj__class = "Table_Element_4"
1348         owner.obj__id = FptElementType.LIGHT_SHAPEABLE
1349         owner.obj__name = "Light_Shapeable"
1350         self.obj__chunks = FptTableElementReader_LIGHT_SHAPEABLE.CHUNK_DICTIONARY
1351
1352
1353 class FptTableElementReader_OBJECT_PEG(Fpt_Data_Reader):
1354     CHUNK_DICTIONARY = {
1355             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
1356             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
1357             0x9DFDC3D8: Fpt_ChunkDescription(0x9DFDC3D8, Fpt_Chunk_Type.STRING, "model"),
1358             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"),
1359             0xA300C5DC: Fpt_ChunkDescription(0xA300C5DC, Fpt_Chunk_Type.STRING, "texture"),
1360             0x99F4C2D2: Fpt_ChunkDescription(0x99F4C2D2, Fpt_Chunk_Type.INT, "sphere_mapping"),
1361             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "color"),
1362             0xA8F3C0D6: Fpt_ChunkDescription(0xA8F3C0D6, Fpt_Chunk_Type.INT, "mask_as_ornamental"),
1363             0xA8EDC3D3: Fpt_ChunkDescription(0xA8EDC3D3, Fpt_Chunk_Type.INT, "rotation"),
1364             0x96E8C0E2: Fpt_ChunkDescription(0x96E8C0E2, Fpt_Chunk_Type.INT, "crystal"),
1365             0x9DFBCDD3: Fpt_ChunkDescription(0x9DFBCDD3, Fpt_Chunk_Type.INT, "reflects_off_playfield"),
1366             0xA5F3BFDD: Fpt_ChunkDescription(0xA5F3BFDD, Fpt_Chunk_Type.STRING, "sound_when_hit"),
1367             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
1368             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
1369             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
1370         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
1371             }
1372
1373     def __init__(self, owner=None):
1374         if owner is None:
1375             owner = self
1376         owner.obj__class = "Table_Element_6"
1377         owner.obj__id = FptElementType.OBJECT_PEG
1378         owner.obj__name = "Object_Peg"
1379         self.obj__chunks = FptTableElementReader_OBJECT_PEG.CHUNK_DICTIONARY
1380
1381
1382 class FptTableElementReader_CONTROL_FLIPPER(Fpt_Data_Reader):
1383     CHUNK_DICTIONARY = {
1384             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
1385             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
1386             0x9DFDC3D8: Fpt_ChunkDescription(0x9DFDC3D8, Fpt_Chunk_Type.STRING, "model"),
1387             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"),
1388             0xA300C5DC: Fpt_ChunkDescription(0xA300C5DC, Fpt_Chunk_Type.STRING, "texture"),
1389             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "color"),
1390             0xA900BED2: Fpt_ChunkDescription(0xA900BED2, Fpt_Chunk_Type.INT, "start_angle"),
1391             0xA1FABED2: Fpt_ChunkDescription(0xA1FABED2, Fpt_Chunk_Type.INT, "strength"),
1392             0xA2EABFE4: Fpt_ChunkDescription(0xA2EABFE4, Fpt_Chunk_Type.INT, "swing"),
1393             0x9700C6E0: Fpt_ChunkDescription(0x9700C6E0, Fpt_Chunk_Type.INT, "elasticity"),
1394             0x9BEEBDDF: Fpt_ChunkDescription(0x9BEEBDDF, Fpt_Chunk_Type.STRING, "flipper_up_sound"),
1395             0x9BEECEDF: Fpt_ChunkDescription(0x9BEECEDF, Fpt_Chunk_Type.STRING, "flipper_down_sound"),
1396             0x9DFBCDD3: Fpt_ChunkDescription(0x9DFBCDD3, Fpt_Chunk_Type.INT, "reflects_off_playfield"),
1397             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
1398             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
1399             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
1400         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
1401             }
1402
1403     def __init__(self, owner=None):
1404         if owner is None:
1405             owner = self
1406         owner.obj__class = "Table_Element_7"
1407         owner.obj__id = FptElementType.CONTROL_FLIPPER
1408         owner.obj__name = "Control_Flipper"
1409         self.obj__chunks = FptTableElementReader_CONTROL_FLIPPER.CHUNK_DICTIONARY
1410
1411
1412 class FptTableElementReader_CONTROL_BUMPER(Fpt_Data_Reader):
1413     CHUNK_DICTIONARY = {
1414             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
1415             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
1416             0xA5F2C5E2: Fpt_ChunkDescription(0xA5F2C5E2, Fpt_Chunk_Type.STRING, "model_cap"),
1417             0xA5F2C5E3: Fpt_ChunkDescription(0xA5F2C5E3, Fpt_Chunk_Type.STRING, "model_base"),
1418             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"),
1419             0x96F3CDD9: Fpt_ChunkDescription(0x96F3CDD9, Fpt_Chunk_Type.STRING, "cap_texture"),
1420             0xA0EED1D5: Fpt_ChunkDescription(0xA0EED1D5, Fpt_Chunk_Type.INT, "passive"),
1421             0x9EEED1DD: Fpt_ChunkDescription(0x9EEED1DD, Fpt_Chunk_Type.INT, "trigger_skirt"),
1422             0x9AFEC7D2: Fpt_ChunkDescription(0x9AFEC7D2, Fpt_Chunk_Type.COLOR, "skirt_color"),
1423             0x9DF2CFD9: Fpt_ChunkDescription(0x9DF2CFD9, Fpt_Chunk_Type.COLOR, "lit_color"),
1424             0xA6ECBFE4: Fpt_ChunkDescription(0xA6ECBFE4, Fpt_Chunk_Type.INT, "auto_set_unlit_color"),
1425             0xA1FDC0D6: Fpt_ChunkDescription(0xA1FDC0D6, Fpt_Chunk_Type.INT, "ordered_halo_glow"),
1426             0x9DF2CFD0: Fpt_ChunkDescription(0x9DF2CFD0, Fpt_Chunk_Type.COLOR, "unlit_color"),
1427             0x9DF2CFE3: Fpt_ChunkDescription(0x9DF2CFE3, Fpt_Chunk_Type.COLOR, "base_color"),
1428             0xA8EDC3D3: Fpt_ChunkDescription(0xA8EDC3D3, Fpt_Chunk_Type.RAWDATA, "unknown_0xA8EDC3D3"),
1429             0x96E8C0E2: Fpt_ChunkDescription(0x96E8C0E2, Fpt_Chunk_Type.INT, "crystal"),
1430             0x9DFBCDD3: Fpt_ChunkDescription(0x9DFBCDD3, Fpt_Chunk_Type.INT, "reflects_off_playfield"),
1431             0xA1FABED2: Fpt_ChunkDescription(0xA1FABED2, Fpt_Chunk_Type.INT, "strength"),
1432             0xA5F3BFE3: Fpt_ChunkDescription(0xA5F3BFE3, Fpt_Chunk_Type.STRING, "solenoid_sound"),
1433             0x95F9BBDF: Fpt_ChunkDescription(0x95F9BBDF, Fpt_Chunk_Type.INT, "flash_when_hit"),
1434             0x9600BED2: Fpt_ChunkDescription(0x9600BED2, Fpt_Chunk_Type.INT, "state"),
1435             0x95F3C9E3: Fpt_ChunkDescription(0x95F3C9E3, Fpt_Chunk_Type.INT, "blink_interval"),
1436             0x9600C2E3: Fpt_ChunkDescription(0x9600C2E3, Fpt_Chunk_Type.STRING, "blink_pattern"),
1437             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
1438             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
1439             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
1440         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
1441             }
1442
1443     def __init__(self, owner=None):
1444         if owner is None:
1445             owner = self
1446         owner.obj__class = "Table_Element_8"
1447         owner.obj__id = FptElementType.CONTROL_BUMPER
1448         owner.obj__name = "Control_Bumper"
1449         self.obj__chunks = FptTableElementReader_CONTROL_BUMPER.CHUNK_DICTIONARY
1450
1451
1452 class FptTableElementReader_TARGET_LEAF(Fpt_Data_Reader):
1453     CHUNK_DICTIONARY = {
1454             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
1455             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
1456             0x9DFDC3D8: Fpt_ChunkDescription(0x9DFDC3D8, Fpt_Chunk_Type.STRING, "model"),
1457             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"),
1458             0xA300C5DC: Fpt_ChunkDescription(0xA300C5DC, Fpt_Chunk_Type.STRING, "texture"),
1459             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "color"),
1460             0xA8EDC3D3: Fpt_ChunkDescription(0xA8EDC3D3, Fpt_Chunk_Type.INT, "rotation"),
1461             0x9DFBCDD3: Fpt_ChunkDescription(0x9DFBCDD3, Fpt_Chunk_Type.INT, "reflects_off_playfield"),
1462             0xA5F3BFD1: Fpt_ChunkDescription(0xA5F3BFD1, Fpt_Chunk_Type.STRING, "sound_when_hit"),
1463             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
1464             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
1465             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
1466         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
1467             }
1468
1469     def __init__(self, owner=None):
1470         if owner is None:
1471             owner = self
1472         owner.obj__class = "Table_Element_10"
1473         owner.obj__id = FptElementType.TARGET_LEAF
1474         owner.obj__name = "Target_Leaf"
1475         self.obj__chunks = FptTableElementReader_TARGET_LEAF.CHUNK_DICTIONARY
1476
1477
1478 class FptTableElementReader_TARGET_DROP(Fpt_Data_Reader):
1479     CHUNK_DICTIONARY = {
1480             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
1481             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
1482             0x9DFDC3D8: Fpt_ChunkDescription(0x9DFDC3D8, Fpt_Chunk_Type.STRING, "model"),
1483             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"),
1484             0xA300C5DC: Fpt_ChunkDescription(0xA300C5DC, Fpt_Chunk_Type.STRING, "texture"),
1485             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "color"),
1486             0xA8EDC3D3: Fpt_ChunkDescription(0xA8EDC3D3, Fpt_Chunk_Type.INT, "rotation"),
1487             0x9DFBCDD3: Fpt_ChunkDescription(0x9DFBCDD3, Fpt_Chunk_Type.INT, "reflects_off_playfield"),
1488             0x9035D306: Fpt_ChunkDescription(0x9035D306, Fpt_Chunk_Type.STRING, "sound_when_hit"),
1489             0x9035D2F8: Fpt_ChunkDescription(0x9035D2F8, Fpt_Chunk_Type.STRING, "sound_when_reset"),
1490             0x8035E308: Fpt_ChunkDescription(0x8035E308, Fpt_Chunk_Type.INT, "bank_count"),
1491             0x9133D308: Fpt_ChunkDescription(0x9133D308, Fpt_Chunk_Type.INT, "bank_spacing"),
1492             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
1493             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
1494             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
1495         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
1496             }
1497
1498     def __init__(self, owner=None):
1499         if owner is None:
1500             owner = self
1501         owner.obj__class = "Table_Element_11"
1502         owner.obj__id = FptElementType.TARGET_DROP
1503         owner.obj__name = "Target_Drop"
1504         self.obj__chunks = FptTableElementReader_TARGET_DROP.CHUNK_DICTIONARY
1505
1506
1507 class FptTableElementReader_CONTROL_PLUNGER(Fpt_Data_Reader):
1508     CHUNK_DICTIONARY = {
1509             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
1510             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
1511             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"), ## added ???
1512             0x9DFDC3D8: Fpt_ChunkDescription(0x9DFDC3D8, Fpt_Chunk_Type.STRING, "model"),
1513             0xA300C5DC: Fpt_ChunkDescription(0xA300C5DC, Fpt_Chunk_Type.STRING, "texture"),
1514             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "plunger_color"),
1515             0x9DF2CFE2: Fpt_ChunkDescription(0x9DF2CFE2, Fpt_Chunk_Type.COLOR, "face_plate_color"),
1516             0xA1FABED2: Fpt_ChunkDescription(0xA1FABED2, Fpt_Chunk_Type.INT, "strength"),
1517             0x9DFBCDD3: Fpt_ChunkDescription(0x9DFBCDD3, Fpt_Chunk_Type.INT, "reflects_off_playfield"),
1518             0x95ECCFCF: Fpt_ChunkDescription(0x95ECCFCF, Fpt_Chunk_Type.INT, "include_v_cut"),
1519             0x90E9CFCF: Fpt_ChunkDescription(0x90E9CFCF, Fpt_Chunk_Type.VECTOR2D, "v_cut_position"),
1520             0x9BFCC6CF: Fpt_ChunkDescription(0x9BFCC6CF, Fpt_Chunk_Type.INT, "v_cut_lenght"),
1521             0xA2F4C9CF: Fpt_ChunkDescription(0xA2F4C9CF, Fpt_Chunk_Type.STRING, "v_cut_texture"),
1522             0x9DF2CFCF: Fpt_ChunkDescription(0x9DF2CFCF, Fpt_Chunk_Type.COLOR, "v_cut_color"),
1523             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
1524             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
1525             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
1526         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
1527             }
1528
1529     def __init__(self, owner=None):
1530         if owner is None:
1531             owner = self
1532         owner.obj__class = "Table_Element_12"
1533         owner.obj__id = FptElementType.CONTROL_PLUNGER
1534         owner.obj__name = "Control_Plunger"
1535         self.obj__chunks = FptTableElementReader_CONTROL_PLUNGER.CHUNK_DICTIONARY
1536
1537
1538 class FptTableElementReader_RUBBER_ROUND(Fpt_Data_Reader):
1539     CHUNK_DICTIONARY = {
1540             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
1541             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
1542             0xA4F1B9D1: Fpt_ChunkDescription(0xA4F1B9D1, Fpt_Chunk_Type.INT, "subtype"),
1543             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"),
1544             0x96FBCCD6: Fpt_ChunkDescription(0x96FBCCD6, Fpt_Chunk_Type.INT, "offset"),
1545             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "color"),
1546             0x9700C6E0: Fpt_ChunkDescription(0x9700C6E0, Fpt_Chunk_Type.INT, "elasticity"),
1547             0x9DFBCDD3: Fpt_ChunkDescription(0x9DFBCDD3, Fpt_Chunk_Type.INT, "reflects_off_playfield"),
1548             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
1549             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
1550             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
1551         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
1552             }
1553
1554     def __init__(self, owner=None):
1555         if owner is None:
1556             owner = self
1557         owner.obj__class = "Table_Element_13"
1558         owner.obj__id = FptElementType.RUBBER_ROUND
1559         owner.obj__name = "Rubber_Round"
1560         self.obj__chunks = FptTableElementReader_RUBBER_ROUND.CHUNK_DICTIONARY
1561
1562
1563 class FptTableElementReader_RUBBER_SHAPEABLE(Fpt_Data_Reader):
1564     CHUNK_DICTIONARY = {
1565             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
1566             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"),
1567             0x9DF2CFD9: Fpt_ChunkDescription(0x9DF2CFD9, Fpt_Chunk_Type.COLOR, "color"),
1568             0x96FBCCD6: Fpt_ChunkDescription(0x96FBCCD6, Fpt_Chunk_Type.INT, "offset"),
1569             0x9DFBCDD3: Fpt_ChunkDescription(0x9DFBCDD3, Fpt_Chunk_Type.INT, "reflects_off_playfield"),
1570             0xA1FABED2: Fpt_ChunkDescription(0xA1FABED2, Fpt_Chunk_Type.INT, "strength"),
1571             0x9700C6E0: Fpt_ChunkDescription(0x9700C6E0, Fpt_Chunk_Type.INT, "elasticity"),
1572             0xA5F3BFD2: Fpt_ChunkDescription(0xA5F3BFD2, Fpt_Chunk_Type.STRING, "sound_slingshot"),
1573             0x95F3C2D2: Fpt_ChunkDescription(0x95F3C2D2, Fpt_Chunk_Type.CHUNKLIST, "shape_point"),
1574             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
1575             0xA1EDC5D2: Fpt_ChunkDescription(0xA1EDC5D2, Fpt_Chunk_Type.INT, "smooth"),
1576             0xA2F3C6D2: Fpt_ChunkDescription(0xA2F3C6D2, Fpt_Chunk_Type.INT, "slingshot"),
1577             0xA8FCC6D2: Fpt_ChunkDescription(0xA8FCC6D2, Fpt_Chunk_Type.INT, "single_leaf"),
1578             0x95F3BCE0: Fpt_ChunkDescription(0x95F3BCE0, Fpt_Chunk_Type.INT, "event_id"),
1579             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
1580             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
1581             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
1582         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
1583             }
1584
1585     def __init__(self, owner=None):
1586         if owner is None:
1587             owner = self
1588         owner.obj__class = "Table_Element_14"
1589         owner.obj__id = FptElementType.RUBBER_SHAPEABLE
1590         owner.obj__name = "Rubber_Shapeable"
1591         self.obj__chunks = FptTableElementReader_RUBBER_SHAPEABLE.CHUNK_DICTIONARY
1592
1593
1594 class FptTableElementReader_OBJECT_ORNAMENT(Fpt_Data_Reader):
1595     CHUNK_DICTIONARY = {
1596             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
1597             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
1598             0x9DFDC3D8: Fpt_ChunkDescription(0x9DFDC3D8, Fpt_Chunk_Type.STRING, "model"),
1599             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"),
1600             0xA300C5DC: Fpt_ChunkDescription(0xA300C5DC, Fpt_Chunk_Type.STRING, "texture"),
1601             0x99F4C2D2: Fpt_ChunkDescription(0x99F4C2D2, Fpt_Chunk_Type.INT, "sphere_mapping"),
1602             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "color"),
1603             0xA8F3C0D6: Fpt_ChunkDescription(0xA8F3C0D6, Fpt_Chunk_Type.INT, "mask_as_ornamental"),
1604             0xA8EDC3D3: Fpt_ChunkDescription(0xA8EDC3D3, Fpt_Chunk_Type.INT, "rotation"),
1605             0x96FBCCD6: Fpt_ChunkDescription(0x96FBCCD6, Fpt_Chunk_Type.INT, "offset"),
1606             0x9DFBCDD3: Fpt_ChunkDescription(0x9DFBCDD3, Fpt_Chunk_Type.INT, "reflects_off_playfield"),
1607             0x97ECBFD3: Fpt_ChunkDescription(0x97ECBFD3, Fpt_Chunk_Type.STRING, "playfield"),
1608             0x9A00C5E0: Fpt_ChunkDescription(0x9A00C5E0, Fpt_Chunk_Type.STRING, "enamel_map"), #
1609             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
1610             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
1611             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
1612         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
1613             }
1614
1615     def __init__(self, owner=None):
1616         if owner is None:
1617             owner = self
1618         owner.obj__class = "Table_Element_15"
1619         owner.obj__id = FptElementType.OBJECT_ORNAMENT
1620         owner.obj__name = "Object_Ornament"
1621         self.obj__chunks = FptTableElementReader_OBJECT_ORNAMENT.CHUNK_DICTIONARY
1622
1623
1624 class FptTableElementReader_GUIDE_WALL(Fpt_Data_Reader):
1625     CHUNK_DICTIONARY = {
1626             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
1627             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"),
1628             0x91EDBEE1: Fpt_ChunkDescription(0x91EDBEE1, Fpt_Chunk_Type.INT, "display_image_in_editor"),
1629             0x9DF2CFD1: Fpt_ChunkDescription(0x9DF2CFD1, Fpt_Chunk_Type.COLOR, "top_color"),
1630             0xA2F4C9D1: Fpt_ChunkDescription(0xA2F4C9D1, Fpt_Chunk_Type.STRING, "top_texture"),
1631             0x91EDCFE2: Fpt_ChunkDescription(0x91EDCFE2, Fpt_Chunk_Type.INT, "cookie_cut"),
1632             0x95F4C2D2: Fpt_ChunkDescription(0x95F4C2D2, Fpt_Chunk_Type.INT, "sphere_map_the_top"),
1633             0x9DF2CFD2: Fpt_ChunkDescription(0x9DF2CFD2, Fpt_Chunk_Type.COLOR, "side_color"),
1634             0xA2F4C9D2: Fpt_ChunkDescription(0xA2F4C9D2, Fpt_Chunk_Type.STRING, "side_texture"),
1635             0x96F4C2D2: Fpt_ChunkDescription(0x96F4C2D2, Fpt_Chunk_Type.INT, "sphere_map_the_side"),
1636             0x97F2C4DF: Fpt_ChunkDescription(0x97F2C4DF, Fpt_Chunk_Type.INT, "flat_shading"),
1637             0x9C00C0D1: Fpt_ChunkDescription(0x9C00C0D1, Fpt_Chunk_Type.INT, "transparency"),
1638             0xA2F8CDDD: Fpt_ChunkDescription(0xA2F8CDDD, Fpt_Chunk_Type.FLOAT, "height"),
1639             0x95FDC9CE: Fpt_ChunkDescription(0x95FDC9CE, Fpt_Chunk_Type.FLOAT, "width"),
1640             0x99E8BED8: Fpt_ChunkDescription(0x99E8BED8, Fpt_Chunk_Type.INT, "material_type"),
1641             0x9DFBCDD3: Fpt_ChunkDescription(0x9DFBCDD3, Fpt_Chunk_Type.INT, "reflects_off_playfield"),
1642             0x99F2C0E1: Fpt_ChunkDescription(0x99F2C0E1, Fpt_Chunk_Type.INT, "dropped"),
1643             0x9DF5C3E2: Fpt_ChunkDescription(0x9DF5C3E2, Fpt_Chunk_Type.INT, "collidable"),
1644             0x97FDC4D3: Fpt_ChunkDescription(0x97FDC4D3, Fpt_Chunk_Type.INT, "render_object"),
1645             0x95EBCDDD: Fpt_ChunkDescription(0x95EBCDDD, Fpt_Chunk_Type.INT, "generate_hit_event"),
1646             0x95F3C2D2: Fpt_ChunkDescription(0x95F3C2D2, Fpt_Chunk_Type.CHUNKLIST, "shape_point"),
1647             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
1648             0xA1EDC5D2: Fpt_ChunkDescription(0xA1EDC5D2, Fpt_Chunk_Type.INT, "smooth"),
1649             0xA2F3C6D2: Fpt_ChunkDescription(0xA2F3C6D2, Fpt_Chunk_Type.RAWDATA, "unknown_0xA2F3C6D2"), # slingshot ???
1650             0xA8FCC6D2: Fpt_ChunkDescription(0xA8FCC6D2, Fpt_Chunk_Type.RAWDATA, "unknown_0xA8FCC6D2"), # single_leaf ???
1651             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
1652             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
1653             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
1654         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
1655             }
1656
1657     def __init__(self, owner=None):
1658         if owner is None:
1659             owner = self
1660         owner.obj__class = "Table_Element_16"
1661         owner.obj__id = FptElementType.GUIDE_WALL
1662         owner.obj__name = "Guide_Wall"
1663         self.obj__chunks = FptTableElementReader_GUIDE_WALL.CHUNK_DICTIONARY
1664
1665
1666 class FptTableElementReader_SPECIAL_TIMER(Fpt_Data_Reader):
1667     CHUNK_DICTIONARY = {
1668             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
1669             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
1670             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"), ## added ???
1671             0xA800C4E0: Fpt_ChunkDescription(0xA800C4E0, Fpt_Chunk_Type.INT, "enabled"),
1672             0x97EDC4DC: Fpt_ChunkDescription(0x97EDC4DC, Fpt_Chunk_Type.INT, "timer_interval"),
1673         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
1674             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
1675             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
1676             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
1677             }
1678
1679     def __init__(self, owner=None):
1680         if owner is None:
1681             owner = self
1682         owner.obj__class = "Table_Element_17"
1683         owner.obj__id = FptElementType.SPECIAL_TIMER
1684         owner.obj__name = "Special_Timer"
1685         self.obj__chunks = FptTableElementReader_SPECIAL_TIMER.CHUNK_DICTIONARY
1686
1687
1688 class FptTableElementReader_SPECIAL_DECAL(Fpt_Data_Reader):
1689     CHUNK_DICTIONARY = {
1690             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
1691             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
1692             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"),
1693             0xA300C5DC: Fpt_ChunkDescription(0xA300C5DC, Fpt_Chunk_Type.STRING, "texture"),
1694             0xA8EDC3D3: Fpt_ChunkDescription(0xA8EDC3D3, Fpt_Chunk_Type.INT, "rotation"),
1695             0xA2F8CDDD: Fpt_ChunkDescription(0xA2F8CDDD, Fpt_Chunk_Type.INT, "width"),
1696             0x95FDC9CE: Fpt_ChunkDescription(0x95FDC9CE, Fpt_Chunk_Type.INT, "height"),
1697             0x9C00C0D1: Fpt_ChunkDescription(0x9C00C0D1, Fpt_Chunk_Type.INT, "transparency"),
1698             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "color"),
1699         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
1700             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
1701             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
1702             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
1703             }
1704
1705     def __init__(self, owner=None):
1706         if owner is None:
1707             owner = self
1708         owner.obj__class = "Table_Element_18"
1709         owner.obj__id = FptElementType.SPECIAL_DECAL
1710         owner.obj__name = "Special_Decal"
1711         self.obj__chunks = FptTableElementReader_SPECIAL_DECAL.CHUNK_DICTIONARY
1712
1713
1714 class FptTableElementReader_CONTROL_KICKER(Fpt_Data_Reader):
1715     CHUNK_DICTIONARY = {
1716             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
1717             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
1718             0x9DFDC3D8: Fpt_ChunkDescription(0x9DFDC3D8, Fpt_Chunk_Type.STRING, "model"),
1719             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"),
1720             0xA300C5DC: Fpt_ChunkDescription(0xA300C5DC, Fpt_Chunk_Type.STRING, "texture"),
1721             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "color"),
1722             0xA8EDC3D3: Fpt_ChunkDescription(0xA8EDC3D3, Fpt_Chunk_Type.INT, "rotation"),
1723             0x99E8BEDA: Fpt_ChunkDescription(0x99E8BEDA, Fpt_Chunk_Type.INT, "type"),
1724             0xA1FABED2: Fpt_ChunkDescription(0xA1FABED2, Fpt_Chunk_Type.INT, "strength"),
1725             0xA5F2C5D3: Fpt_ChunkDescription(0xA5F2C5D3, Fpt_Chunk_Type.INT, "render_model"),
1726             0xA5F3BFDA: Fpt_ChunkDescription(0xA5F3BFDA, Fpt_Chunk_Type.STRING, "sound_when_hit"),
1727             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
1728             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
1729             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
1730         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
1731             }
1732
1733     def __init__(self, owner=None):
1734         if owner is None:
1735             owner = self
1736         owner.obj__class = "Table_Element_19"
1737         owner.obj__id = FptElementType.CONTROL_KICKER
1738         owner.obj__name = "Control_Kicker"
1739         self.obj__chunks = FptTableElementReader_CONTROL_KICKER.CHUNK_DICTIONARY
1740
1741
1742 class FptTableElementReader_GUIDE_LANE(Fpt_Data_Reader):
1743     CHUNK_DICTIONARY = {
1744             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
1745             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
1746             0x9DFDC3D8: Fpt_ChunkDescription(0x9DFDC3D8, Fpt_Chunk_Type.STRING, "model"),
1747             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"),
1748             0xA300C5DC: Fpt_ChunkDescription(0xA300C5DC, Fpt_Chunk_Type.STRING, "texture"),
1749             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "color"),
1750             0xA8EDC3D3: Fpt_ChunkDescription(0xA8EDC3D3, Fpt_Chunk_Type.INT, "rotation"),
1751             0x96FBCCD6: Fpt_ChunkDescription(0x96FBCCD6, Fpt_Chunk_Type.INT, "offset"),
1752             0x96E8C0E2: Fpt_ChunkDescription(0x96E8C0E2, Fpt_Chunk_Type.INT, "crystal"),
1753             0x9A00C5E0: Fpt_ChunkDescription(0x9A00C5E0, Fpt_Chunk_Type.STRING, "enamel_map"), #
1754             0x9DFBCDD3: Fpt_ChunkDescription(0x9DFBCDD3, Fpt_Chunk_Type.INT, "reflects_off_playfield"),
1755             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
1756             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
1757             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
1758         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
1759             }
1760
1761     def __init__(self, owner=None):
1762         if owner is None:
1763             owner = self
1764         owner.obj__class = "Table_Element_20"
1765         owner.obj__id = FptElementType.GUIDE_LANE
1766         owner.obj__name = "Guide_Lane"
1767         self.obj__chunks = FptTableElementReader_GUIDE_LANE.CHUNK_DICTIONARY
1768
1769
1770 class FptTableElementReader_RUBBER_MODEL(Fpt_Data_Reader):
1771     CHUNK_DICTIONARY = {
1772             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
1773             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
1774             0x9DFDC3D8: Fpt_ChunkDescription(0x9DFDC3D8, Fpt_Chunk_Type.STRING, "model"),
1775             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"),
1776             0xA300C5DC: Fpt_ChunkDescription(0xA300C5DC, Fpt_Chunk_Type.STRING, "texture"),
1777             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "color"),
1778             0xA8EDC3D3: Fpt_ChunkDescription(0xA8EDC3D3, Fpt_Chunk_Type.INT, "rotation"),
1779             0x96FBCCD6: Fpt_ChunkDescription(0x96FBCCD6, Fpt_Chunk_Type.INT, "offset"),
1780             0x9700C6E0: Fpt_ChunkDescription(0x9700C6E0, Fpt_Chunk_Type.INT, "elasticity"),
1781             0x9DFBCDD3: Fpt_ChunkDescription(0x9DFBCDD3, Fpt_Chunk_Type.INT, "reflects_off_playfield"),
1782             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
1783             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
1784             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
1785         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
1786             }
1787
1788     def __init__(self, owner=None):
1789         if owner is None:
1790             owner = self
1791         owner.obj__class = "Table_Element_21"
1792         owner.obj__id = FptElementType.RUBBER_MODEL
1793         owner.obj__name = "Rubber_Model"
1794         self.obj__chunks = FptTableElementReader_RUBBER_MODEL.CHUNK_DICTIONARY
1795
1796
1797 class FptTableElementReader_TRIGGER_TRIGGER(Fpt_Data_Reader):
1798     CHUNK_DICTIONARY = {
1799             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
1800             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
1801             0x9DFDC3D8: Fpt_ChunkDescription(0x9DFDC3D8, Fpt_Chunk_Type.STRING, "model"),
1802             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"),
1803             0xA300C5DC: Fpt_ChunkDescription(0xA300C5DC, Fpt_Chunk_Type.STRING, "texture"),
1804             0x99F4C2D2: Fpt_ChunkDescription(0x99F4C2D2, Fpt_Chunk_Type.INT, "sphere_mapping"),
1805             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "color"),
1806             0xA8EDC3D3: Fpt_ChunkDescription(0xA8EDC3D3, Fpt_Chunk_Type.INT, "rotation"),
1807             0xA3F1C3D2: Fpt_ChunkDescription(0xA3F1C3D2, Fpt_Chunk_Type.INT, "sits_on_playfield"),
1808             0xA5F2C5D3: Fpt_ChunkDescription(0xA5F2C5D3, Fpt_Chunk_Type.INT, "render_model"),
1809             0x9DFBCDD3: Fpt_ChunkDescription(0x9DFBCDD3, Fpt_Chunk_Type.INT, "reflects_off_playfield"),
1810             0xA5F3BFD1: Fpt_ChunkDescription(0xA5F3BFD1, Fpt_Chunk_Type.STRING, "sound_when_hit"),
1811             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
1812             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
1813             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
1814         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
1815             }
1816
1817     def __init__(self, owner=None):
1818         if owner is None:
1819             owner = self
1820         owner.obj__class = "Table_Element_22"
1821         owner.obj__id = FptElementType.TRIGGER_TRIGGER
1822         owner.obj__name = "Trigger_Trigger"
1823         self.obj__chunks = FptTableElementReader_TRIGGER_TRIGGER.CHUNK_DICTIONARY
1824
1825
1826 class FptTableElementReader_LIGHT_FLASHER(Fpt_Data_Reader):
1827     CHUNK_DICTIONARY = {
1828             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
1829             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
1830             0x9DFDC3D8: Fpt_ChunkDescription(0x9DFDC3D8, Fpt_Chunk_Type.STRING, "model"),
1831             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"),
1832             0x9DF2CFD9: Fpt_ChunkDescription(0x9DF2CFD9, Fpt_Chunk_Type.COLOR, "lit_color"),
1833             0xA6ECBFE4: Fpt_ChunkDescription(0xA6ECBFE4, Fpt_Chunk_Type.INT, "auto_set_unlit_color"),
1834             0x9DF2CFD0: Fpt_ChunkDescription(0x9DF2CFD0, Fpt_Chunk_Type.COLOR, "unlit_color"),
1835             0xA8EDC3D3: Fpt_ChunkDescription(0xA8EDC3D3, Fpt_Chunk_Type.INT, "rotation"),
1836             0xA1FDC0D6: Fpt_ChunkDescription(0xA1FDC0D6, Fpt_Chunk_Type.INT, "ordered_halo_glow"),
1837             0x9DFBCDD3: Fpt_ChunkDescription(0x9DFBCDD3, Fpt_Chunk_Type.INT, "reflects_off_playfield"),
1838             0x97ECBFD3: Fpt_ChunkDescription(0x97ECBFD3, Fpt_Chunk_Type.STRING, "playfield"),
1839             0x9600BED2: Fpt_ChunkDescription(0x9600BED2, Fpt_Chunk_Type.INT, "state"),
1840             0x95F3C9E3: Fpt_ChunkDescription(0x95F3C9E3, Fpt_Chunk_Type.INT, "blink_interval"),
1841             0x9600C2E3: Fpt_ChunkDescription(0x9600C2E3, Fpt_Chunk_Type.STRING, "blink_pattern"),
1842             0x9134D9F8: Fpt_ChunkDescription(0x9134D9F8, Fpt_Chunk_Type.RAWDATA, "unknown_0x9134D9F8"),
1843             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
1844             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
1845             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
1846         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
1847             }
1848
1849     def __init__(self, owner=None):
1850         if owner is None:
1851             owner = self
1852         owner.obj__class = "Table_Element_23"
1853         owner.obj__id = FptElementType.LIGHT_FLASHER
1854         owner.obj__name = "Light_Flasher"
1855         self.obj__chunks = FptTableElementReader_LIGHT_FLASHER.CHUNK_DICTIONARY
1856
1857
1858 class FptTableElementReader_GUIDE_WIRE(Fpt_Data_Reader):
1859     CHUNK_DICTIONARY = {
1860             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
1861             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"),
1862             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "color"),
1863             0xA4FAC5DC: Fpt_ChunkDescription(0xA4FAC5DC, Fpt_Chunk_Type.STRING, "texture"),
1864             0x99F4C2D2: Fpt_ChunkDescription(0x99F4C2D2, Fpt_Chunk_Type.INT, "sphere_mapping"),
1865             0xA2F8CDDD: Fpt_ChunkDescription(0xA2F8CDDD, Fpt_Chunk_Type.INT, "height"),
1866             0x95FDC9CE: Fpt_ChunkDescription(0x95FDC9CE, Fpt_Chunk_Type.INT, "width"),
1867             0xA8F3C0D6: Fpt_ChunkDescription(0xA8F3C0D6, Fpt_Chunk_Type.INT, "mark_as_ornamental"),
1868             0x9DFBCDD3: Fpt_ChunkDescription(0x9DFBCDD3, Fpt_Chunk_Type.INT, "reflects_off_playfield"),
1869             0x95F3C2D2: Fpt_ChunkDescription(0x95F3C2D2, Fpt_Chunk_Type.CHUNKLIST, "shape_point"),
1870             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
1871             0xA1EDC5D2: Fpt_ChunkDescription(0xA1EDC5D2, Fpt_Chunk_Type.INT, "smooth"),
1872             0xA2F3C6D2: Fpt_ChunkDescription(0xA2F3C6D2, Fpt_Chunk_Type.RAWDATA, "unknown_0xA2F3C6D2"), # slingshot ???
1873             0xA8FCC6D2: Fpt_ChunkDescription(0xA8FCC6D2, Fpt_Chunk_Type.RAWDATA, "unknown_0xA8FCC6D2"), # single_leaf ???
1874             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
1875             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
1876             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
1877         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
1878             }
1879
1880     def __init__(self, owner=None):
1881         if owner is None:
1882             owner = self
1883         owner.obj__class = "Table_Element_24"
1884         owner.obj__id = FptElementType.GUIDE_WIRE
1885         owner.obj__name = "Guide_Wire"
1886         self.obj__chunks = FptTableElementReader_GUIDE_WIRE.CHUNK_DICTIONARY
1887
1888
1889 class FptTableElementReader_DISPLAY_DISPREEL(Fpt_Data_Reader):
1890     CHUNK_DICTIONARY = {
1891             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
1892             0xB8EFCDCF: Fpt_ChunkDescription(0xB8EFCDCF, Fpt_Chunk_Type.VECTOR2D, "position"),
1893             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"), ## added ???
1894             0x90EDBFD3: Fpt_ChunkDescription(0x90EDBFD3, Fpt_Chunk_Type.INT, "number_style"),
1895             0xA700CCD3: Fpt_ChunkDescription(0xA700CCD3, Fpt_Chunk_Type.INT, "render_face_plate"),
1896             0x9DF2CFDF: Fpt_ChunkDescription(0x9DF2CFDF, Fpt_Chunk_Type.COLOR, "face_color"),
1897             0x95F3CFD3: Fpt_ChunkDescription(0x95F3CFD3, Fpt_Chunk_Type.INT, "reels"),
1898             0xA700C2D2: Fpt_ChunkDescription(0xA700C2D2, Fpt_Chunk_Type.INT, "spacing"),
1899             0xA6F1BFDF: Fpt_ChunkDescription(0xA6F1BFDF, Fpt_Chunk_Type.INT, "face_spacing"),
1900             0xA2F8CDDD: Fpt_ChunkDescription(0xA2F8CDDD, Fpt_Chunk_Type.INT, "height"),
1901             0x95FDC9CE: Fpt_ChunkDescription(0x95FDC9CE, Fpt_Chunk_Type.INT, "width"),
1902             0xA5F1BFD2: Fpt_ChunkDescription(0xA5F1BFD2, Fpt_Chunk_Type.INT, "spin_speed"),
1903             0x9BECC3D2: Fpt_ChunkDescription(0x9BECC3D2, Fpt_Chunk_Type.STRING, "spin_sound"),
1904             0x9DF2CFD9: Fpt_ChunkDescription(0x9DF2CFD9, Fpt_Chunk_Type.COLOR, "lit_color"),
1905             0xA6ECBFE4: Fpt_ChunkDescription(0xA6ECBFE4, Fpt_Chunk_Type.INT, "auto_set_unlit_color"),
1906             0x9DF2CFD0: Fpt_ChunkDescription(0x9DF2CFD0, Fpt_Chunk_Type.COLOR, "unlit_color"),
1907             0x9600BED2: Fpt_ChunkDescription(0x9600BED2, Fpt_Chunk_Type.INT, "state"),
1908             0x95F3C9E3: Fpt_ChunkDescription(0x95F3C9E3, Fpt_Chunk_Type.INT, "blink_interval"),
1909             0x9600C2E3: Fpt_ChunkDescription(0x9600C2E3, Fpt_Chunk_Type.STRING, "blink_pattern"),
1910         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
1911             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
1912             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
1913             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
1914             }
1915
1916     def __init__(self, owner=None):
1917         if owner is None:
1918             owner = self
1919         owner.obj__class = "Table_Element_25"
1920         owner.obj__id = FptElementType.DISPLAY_DISPREEL
1921         owner.obj__name = "Display_DispReel"
1922         self.obj__chunks = FptTableElementReader_DISPLAY_DISPREEL.CHUNK_DICTIONARY
1923
1924
1925 class FptTableElementReader_DISPLAY_HUDREEL(Fpt_Data_Reader):
1926     CHUNK_DICTIONARY = {
1927             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
1928             0xB8EFCDCF: Fpt_ChunkDescription(0xB8EFCDCF, Fpt_Chunk_Type.VECTOR2D, "position"),
1929             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"), ## added ???
1930             0x90EDBFD3: Fpt_ChunkDescription(0x90EDBFD3, Fpt_Chunk_Type.INT, "number_style"),
1931             0xA700CCD3: Fpt_ChunkDescription(0xA700CCD3, Fpt_Chunk_Type.INT, "render_face_plate"),
1932             0x9DF2CFDF: Fpt_ChunkDescription(0x9DF2CFDF, Fpt_Chunk_Type.COLOR, "face_color"),
1933             0x95F3CFD3: Fpt_ChunkDescription(0x95F3CFD3, Fpt_Chunk_Type.INT, "reels"),
1934             0xA700C2D2: Fpt_ChunkDescription(0xA700C2D2, Fpt_Chunk_Type.INT, "spacing"),
1935             0xA6F1BFDF: Fpt_ChunkDescription(0xA6F1BFDF, Fpt_Chunk_Type.INT, "face_spacing"),
1936             0xA2F8CDDD: Fpt_ChunkDescription(0xA2F8CDDD, Fpt_Chunk_Type.INT, "height"),
1937             0x95FDC9CE: Fpt_ChunkDescription(0x95FDC9CE, Fpt_Chunk_Type.INT, "width"),
1938             0xA5F1BFD2: Fpt_ChunkDescription(0xA5F1BFD2, Fpt_Chunk_Type.INT, "spin_speed"),
1939             0x9BECC3D2: Fpt_ChunkDescription(0x9BECC3D2, Fpt_Chunk_Type.STRING, "spin_sound"),
1940             0x9DF2CFD9: Fpt_ChunkDescription(0x9DF2CFD9, Fpt_Chunk_Type.COLOR, "lit_color"),
1941             0xA6ECBFE4: Fpt_ChunkDescription(0xA6ECBFE4, Fpt_Chunk_Type.INT, "auto_set_unlit_color"),
1942             0x9DF2CFD0: Fpt_ChunkDescription(0x9DF2CFD0, Fpt_Chunk_Type.COLOR, "unlit_color"),
1943             0x9600BED2: Fpt_ChunkDescription(0x9600BED2, Fpt_Chunk_Type.INT, "state"),
1944             0x95F3C9E3: Fpt_ChunkDescription(0x95F3C9E3, Fpt_Chunk_Type.INT, "blink_interval"),
1945             0x9600C2E3: Fpt_ChunkDescription(0x9600C2E3, Fpt_Chunk_Type.STRING, "blink_pattern"),
1946         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
1947             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
1948             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
1949             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
1950             }
1951
1952     def __init__(self, owner=None):
1953         if owner is None:
1954             owner = self
1955         owner.obj__class = "Table_Element_26"
1956         owner.obj__id = FptElementType.DISPLAY_HUDREEL
1957         owner.obj__name = "Display_HudReel"
1958         self.obj__chunks = FptTableElementReader_DISPLAY_HUDREEL.CHUNK_DICTIONARY
1959
1960
1961 class FptTableElementReader_SPECIAL_OVERLAY(Fpt_Data_Reader):
1962     CHUNK_DICTIONARY = {
1963             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
1964             0x9BEFBED3: Fpt_ChunkDescription(0x9BEFBED3, Fpt_Chunk_Type.INT, "render_onto_translite"),
1965             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"),
1966             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
1967             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "color"),
1968             0xA2F8CDDD: Fpt_ChunkDescription(0xA2F8CDDD, Fpt_Chunk_Type.INT, "unknown_0x95FDC9CE"),
1969             0x95FDC9CE: Fpt_ChunkDescription(0x95FDC9CE, Fpt_Chunk_Type.INT, "width"),
1970             0xA8EDC3D3: Fpt_ChunkDescription(0xA8EDC3D3, Fpt_Chunk_Type.INT, "rotation"),
1971             0x96F5C5DC: Fpt_ChunkDescription(0x96F5C5DC, Fpt_Chunk_Type.STRING, "image_list"),
1972             0x95F3C9D0: Fpt_ChunkDescription(0x95F3C9D0, Fpt_Chunk_Type.INT, "update_interval"),
1973         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
1974             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
1975             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
1976             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
1977             }
1978
1979     def __init__(self, owner=None):
1980         if owner is None:
1981             owner = self
1982         owner.obj__class = "Table_Element_27"
1983         owner.obj__id = FptElementType.SPECIAL_OVERLAY
1984         owner.obj__name = "Special_Overlay"
1985         self.obj__chunks = FptTableElementReader_SPECIAL_OVERLAY.CHUNK_DICTIONARY
1986
1987
1988 class FptTableElementReader_LIGHT_BULB(Fpt_Data_Reader):
1989     CHUNK_DICTIONARY = {
1990             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
1991             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
1992             0x9DFDC3D8: Fpt_ChunkDescription(0x9DFDC3D8, Fpt_Chunk_Type.STRING, "model"),
1993             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"),
1994             0xA5F2C5D3: Fpt_ChunkDescription(0xA5F2C5D3, Fpt_Chunk_Type.INT, "render_model"),
1995             0x96F3CDD9: Fpt_ChunkDescription(0x96F3CDD9, Fpt_Chunk_Type.STRING, "lens_texture"),
1996             0x96FDD1D3: Fpt_ChunkDescription(0x96FDD1D3, Fpt_Chunk_Type.INT, "glow_radius"),
1997             0xA1FDC0D6: Fpt_ChunkDescription(0xA1FDC0D6, Fpt_Chunk_Type.INT, "ordered_halo_glow"),
1998             0x9DF2CFD9: Fpt_ChunkDescription(0x9DF2CFD9, Fpt_Chunk_Type.COLOR, "lit_color"),
1999             0xA6ECBFE4: Fpt_ChunkDescription(0xA6ECBFE4, Fpt_Chunk_Type.INT, "auto_set_unlit_color"),
2000             0x9DF2CFD0: Fpt_ChunkDescription(0x9DF2CFD0, Fpt_Chunk_Type.COLOR, "unlit_color"),
2001             0x96E8C0E2: Fpt_ChunkDescription(0x96E8C0E2, Fpt_Chunk_Type.INT, "crystal"),
2002             0xA8EDC3D3: Fpt_ChunkDescription(0xA8EDC3D3, Fpt_Chunk_Type.INT, "rotation"),
2003             0x9DFBCDD3: Fpt_ChunkDescription(0x9DFBCDD3, Fpt_Chunk_Type.INT, "reflects_off_playfield"),
2004             0x9600BED2: Fpt_ChunkDescription(0x9600BED2, Fpt_Chunk_Type.INT, "state"),
2005             0x95F3C9E3: Fpt_ChunkDescription(0x95F3C9E3, Fpt_Chunk_Type.INT, "blink_interval"),
2006             0x9600C2E3: Fpt_ChunkDescription(0x9600C2E3, Fpt_Chunk_Type.STRING, "blink_pattern"),
2007         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
2008             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
2009             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
2010             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
2011             }
2012
2013     def __init__(self, owner=None):
2014         if owner is None:
2015             owner = self
2016         owner.obj__class = "Table_Element_29"
2017         owner.obj__id = FptElementType.LIGHT_BULB
2018         owner.obj__name = "Light_Bulb"
2019         self.obj__chunks = FptTableElementReader_LIGHT_BULB.CHUNK_DICTIONARY
2020
2021
2022 class FptTableElementReader_TRIGGER_GATE(Fpt_Data_Reader):
2023     CHUNK_DICTIONARY = {
2024             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
2025             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
2026             0x9DFDC3D8: Fpt_ChunkDescription(0x9DFDC3D8, Fpt_Chunk_Type.STRING, "model"),
2027             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"),
2028             0xA300C5DC: Fpt_ChunkDescription(0xA300C5DC, Fpt_Chunk_Type.STRING, "texture"),
2029             0x99F4C2D2: Fpt_ChunkDescription(0x99F4C2D2, Fpt_Chunk_Type.INT, "sphere_mapping"),
2030             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "color"),
2031             0xA8EDC3D3: Fpt_ChunkDescription(0xA8EDC3D3, Fpt_Chunk_Type.INT, "rotation"),
2032             0x9100BBD6: Fpt_ChunkDescription(0x9100BBD6, Fpt_Chunk_Type.INT, "one_way"),
2033             0x9DFBCDD3: Fpt_ChunkDescription(0x9DFBCDD3, Fpt_Chunk_Type.INT, "reflects_off_playfield"),
2034             0x97ECBFD3: Fpt_ChunkDescription(0x97ECBFD3, Fpt_Chunk_Type.STRING, "playfield"),
2035             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
2036             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
2037             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
2038         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
2039             }
2040
2041     def __init__(self, owner=None):
2042         if owner is None:
2043             owner = self
2044         owner.obj__class = "Table_Element_30"
2045         owner.obj__id = FptElementType.TRIGGER_GATE
2046         owner.obj__name = "Trigger_Gate"
2047         self.obj__chunks = FptTableElementReader_TRIGGER_GATE.CHUNK_DICTIONARY
2048
2049
2050 class FptTableElementReader_TRIGGER_SPINNER(Fpt_Data_Reader):
2051     CHUNK_DICTIONARY = {
2052             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
2053             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
2054             0x9DFDC3D8: Fpt_ChunkDescription(0x9DFDC3D8, Fpt_Chunk_Type.STRING, "model"),
2055             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"),
2056             0xA300C5DC: Fpt_ChunkDescription(0xA300C5DC, Fpt_Chunk_Type.STRING, "texture"),
2057             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "color"),
2058             0xA8EDC3D3: Fpt_ChunkDescription(0xA8EDC3D3, Fpt_Chunk_Type.INT, "rotation"),
2059             0x9DFBCDD3: Fpt_ChunkDescription(0x9DFBCDD3, Fpt_Chunk_Type.INT, "reflects_off_playfield"),
2060             0x99F4D1E1: Fpt_ChunkDescription(0x99F4D1E1, Fpt_Chunk_Type.INT, "damping"),
2061             0x97ECBFD3: Fpt_ChunkDescription(0x97ECBFD3, Fpt_Chunk_Type.STRING, "playfield"),
2062             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
2063             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
2064             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
2065         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
2066             }
2067
2068     def __init__(self, owner=None):
2069         if owner is None:
2070             owner = self
2071         owner.obj__class = "Table_Element_31"
2072         owner.obj__id = FptElementType.TRIGGER_SPINNER
2073         owner.obj__name = "Trigger_Spinner"
2074         self.obj__chunks = FptTableElementReader_TRIGGER_SPINNER.CHUNK_DICTIONARY
2075
2076
2077 class FptTableElementReader_TOY_CUSTOM(Fpt_Data_Reader):
2078     CHUNK_DICTIONARY = {
2079             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
2080             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
2081             0x9DFDC3D8: Fpt_ChunkDescription(0x9DFDC3D8, Fpt_Chunk_Type.STRING, "model"),
2082             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"),
2083             0xA300C5DC: Fpt_ChunkDescription(0xA300C5DC, Fpt_Chunk_Type.STRING, "texture"),
2084             0x99F4C2D2: Fpt_ChunkDescription(0x99F4C2D2, Fpt_Chunk_Type.INT, "sphere_mapping"),
2085             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "color"),
2086             0x9C00C0D1: Fpt_ChunkDescription(0x9C00C0D1, Fpt_Chunk_Type.INT, "transparency"),
2087             0xA8EDC3D3: Fpt_ChunkDescription(0xA8EDC3D3, Fpt_Chunk_Type.INT, "rotation"),
2088             0x96FBCCD6: Fpt_ChunkDescription(0x96FBCCD6, Fpt_Chunk_Type.INT, "offset"),
2089             0x9DFBCDD3: Fpt_ChunkDescription(0x9DFBCDD3, Fpt_Chunk_Type.INT, "reflects_off_playfield"),
2090             0x95F3C9D0: Fpt_ChunkDescription(0x95F3C9D0, Fpt_Chunk_Type.INT, "update_interval"),
2091             0x97ECBFD3: Fpt_ChunkDescription(0x97ECBFD3, Fpt_Chunk_Type.STRING, "playfield"),
2092             0x9035D306: Fpt_ChunkDescription(0x9035D306, Fpt_Chunk_Type.STRING, "sound_when_hit"),
2093             0x9035D2F8: Fpt_ChunkDescription(0x9035D2F8, Fpt_Chunk_Type.STRING, "sound_when_reset"),
2094             0x8035E308: Fpt_ChunkDescription(0x8035E308, Fpt_Chunk_Type.INT, "bank_count"),
2095             0x9133D308: Fpt_ChunkDescription(0x9133D308, Fpt_Chunk_Type.INT, "bank_spacing"),
2096             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
2097             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
2098             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
2099         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
2100             }
2101
2102     def __init__(self, owner=None):
2103         if owner is None:
2104             owner = self
2105         owner.obj__class = "Table_Element_33"
2106         owner.obj__id = FptElementType.TOY_CUSTOM
2107         owner.obj__name = "Toy_Custom"
2108         self.obj__chunks = FptTableElementReader_TOY_CUSTOM.CHUNK_DICTIONARY
2109
2110
2111 class FptTableElementReader_LIGHT_SEQUENCER(Fpt_Data_Reader):
2112     CHUNK_DICTIONARY = {
2113             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
2114             0xB8EFCDCF: Fpt_ChunkDescription(0xB8EFCDCF, Fpt_Chunk_Type.VECTOR2D, "position"),
2115             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"), ## added ???
2116             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "virtual_center"),
2117             0x95EEC6D9: Fpt_ChunkDescription(0x95EEC6D9, Fpt_Chunk_Type.STRING, "light_list"),
2118             0x95F3C9D0: Fpt_ChunkDescription(0x95F3C9D0, Fpt_Chunk_Type.INT, "update_interval"),
2119             0xA1EECCDF: Fpt_ChunkDescription(0xA1EECCDF, Fpt_Chunk_Type.INT, "flasher_blink"),
2120             0x9BF8BDDF: Fpt_ChunkDescription(0x9BF8BDDF, Fpt_Chunk_Type.INT, "blink_interval"),
2121             0x96EFBEDC: Fpt_ChunkDescription(0x96EFBEDC, Fpt_Chunk_Type.INT, "include_translite_light"),
2122             0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.RAWDATA, "unknown_0xA6F2C6D3"),
2123             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
2124             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
2125             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
2126         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
2127             }
2128
2129     def __init__(self, owner=None):
2130         if owner is None:
2131             owner = self
2132         owner.obj__class = "Table_Element_34"
2133         owner.obj__id = FptElementType.LIGHT_SEQUENCER
2134         owner.obj__name = "Light_Sequencer"
2135         self.obj__chunks = FptTableElementReader_LIGHT_SEQUENCER.CHUNK_DICTIONARY
2136
2137
2138 class FptTableElementReader_DISPLAY_SEGMENT(Fpt_Data_Reader):
2139     CHUNK_DICTIONARY = {
2140             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
2141             0xB8EFCDCF: Fpt_ChunkDescription(0xB8EFCDCF, Fpt_Chunk_Type.VECTOR2D, "position"),
2142             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"), ## added ???
2143             0x99E8BED2: Fpt_ChunkDescription(0x99E8BED2, Fpt_Chunk_Type.INT, "segment_style"),
2144             0x95F3CFD2: Fpt_ChunkDescription(0x95F3CFD2, Fpt_Chunk_Type.INT, "digits"),
2145             0x95FDC9CE: Fpt_ChunkDescription(0x95FDC9CE, Fpt_Chunk_Type.INT, "size"),
2146             0xA700C2D2: Fpt_ChunkDescription(0xA700C2D2, Fpt_Chunk_Type.INT, "spacing"),
2147             0xA6F1BFDF: Fpt_ChunkDescription(0xA6F1BFDF, Fpt_Chunk_Type.INT, "face_spacing"),
2148             0x9BF8C2D0: Fpt_ChunkDescription(0x9BF8C2D0, Fpt_Chunk_Type.INT, "update_interval"),
2149             0xA2F8C6E4: Fpt_ChunkDescription(0xA2F8C6E4, Fpt_Chunk_Type.INT, "alignment"),
2150             0x99EED0D2: Fpt_ChunkDescription(0x99EED0D2, Fpt_Chunk_Type.INT, "slow_blink_speed"),
2151             0x99EED0DF: Fpt_ChunkDescription(0x99EED0DF, Fpt_Chunk_Type.INT, "fast_blink_speed"),
2152             0x90F5CEE3: Fpt_ChunkDescription(0x90F5CEE3, Fpt_Chunk_Type.INT, "boredom_delay"),
2153             0x9DF2CFD9: Fpt_ChunkDescription(0x9DF2CFD9, Fpt_Chunk_Type.COLOR, "lit_color"),
2154         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
2155             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
2156             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
2157             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
2158             }
2159
2160     def __init__(self, owner=None):
2161         if owner is None:
2162             owner = self
2163         owner.obj__class = "Table_Element_37"
2164         owner.obj__id = FptElementType.DISPLAY_SEGMENT
2165         owner.obj__name = "Display_Segment"
2166         self.obj__chunks = FptTableElementReader_DISPLAY_SEGMENT.CHUNK_DICTIONARY
2167
2168
2169 class FptTableElementReader_DISPLAY_HUDSEGMENT(Fpt_Data_Reader):
2170     CHUNK_DICTIONARY = {
2171             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
2172             0xB8EFCDCF: Fpt_ChunkDescription(0xB8EFCDCF, Fpt_Chunk_Type.VECTOR2D, "position"),
2173             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"), ## added ???
2174             0x99E8BED2: Fpt_ChunkDescription(0x99E8BED2, Fpt_Chunk_Type.INT, "segment_style"),
2175             0x95F3CFD2: Fpt_ChunkDescription(0x95F3CFD2, Fpt_Chunk_Type.INT, "digits"),
2176             0x95FDC9CE: Fpt_ChunkDescription(0x95FDC9CE, Fpt_Chunk_Type.INT, "size"),
2177             0xA700C2D2: Fpt_ChunkDescription(0xA700C2D2, Fpt_Chunk_Type.INT, "spacing"),
2178             0xA6F1BFDF: Fpt_ChunkDescription(0xA6F1BFDF, Fpt_Chunk_Type.INT, "face_spacing"),
2179             0x9BF8C2D0: Fpt_ChunkDescription(0x9BF8C2D0, Fpt_Chunk_Type.INT, "update_interval"),
2180             0xA2F8C6E4: Fpt_ChunkDescription(0xA2F8C6E4, Fpt_Chunk_Type.INT, "alignment"),
2181             0x99EED0D2: Fpt_ChunkDescription(0x99EED0D2, Fpt_Chunk_Type.INT, "slow_blink_speed"),
2182             0x99EED0DF: Fpt_ChunkDescription(0x99EED0DF, Fpt_Chunk_Type.INT, "fast_blink_speed"),
2183             0x90F5CEE3: Fpt_ChunkDescription(0x90F5CEE3, Fpt_Chunk_Type.INT, "boredom_delay"),
2184             0x9DF2CFD9: Fpt_ChunkDescription(0x9DF2CFD9, Fpt_Chunk_Type.COLOR, "lit_color"),
2185         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
2186             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
2187             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
2188             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
2189             }
2190
2191     def __init__(self, owner=None):
2192         if owner is None:
2193             owner = self
2194         owner.obj__class = "Table_Element_38"
2195         owner.obj__id = FptElementType.DISPLAY_HUDSEGMENT
2196         owner.obj__name = "Display_HudSegment"
2197         self.obj__chunks = FptTableElementReader_DISPLAY_HUDSEGMENT.CHUNK_DICTIONARY
2198
2199
2200 class FptTableElementReader_DISPLAY_DMD(Fpt_Data_Reader):
2201     CHUNK_DICTIONARY = {
2202             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
2203             0xB8EFCDCF: Fpt_ChunkDescription(0xB8EFCDCF, Fpt_Chunk_Type.VECTOR2D, "position"),
2204             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"), ## added ???
2205             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "matrix_color"),
2206             0x9E00CFD2: Fpt_ChunkDescription(0x9E00CFD2, Fpt_Chunk_Type.INT, "scale"),
2207             0x99E8BEE1: Fpt_ChunkDescription(0x99E8BEE1, Fpt_Chunk_Type.INT, "type"),
2208             0x9BF8C2D0: Fpt_ChunkDescription(0x9BF8C2D0, Fpt_Chunk_Type.INT, "update_interval"),
2209             0xA2F8C6E4: Fpt_ChunkDescription(0xA2F8C6E4, Fpt_Chunk_Type.INT, "alignment"),
2210             0x99EED0D2: Fpt_ChunkDescription(0x99EED0D2, Fpt_Chunk_Type.INT, "slow_blink_speed"),
2211             0x99EED0DF: Fpt_ChunkDescription(0x99EED0DF, Fpt_Chunk_Type.INT, "fast_blink_speed"),
2212         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
2213             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
2214             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
2215             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
2216             }
2217
2218     def __init__(self, owner=None):
2219         if owner is None:
2220             owner = self
2221         owner.obj__class = "Table_Element_39"
2222         owner.obj__id = FptElementType.DISPLAY_DMD
2223         owner.obj__name = "Display_Dmd"
2224         self.obj__chunks = FptTableElementReader_DISPLAY_DMD.CHUNK_DICTIONARY
2225
2226
2227 class FptTableElementReader_DISPLAY_HUDDMD(Fpt_Data_Reader):
2228     CHUNK_DICTIONARY = {
2229             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
2230             0xB8EFCDCF: Fpt_ChunkDescription(0xB8EFCDCF, Fpt_Chunk_Type.VECTOR2D, "position"),
2231             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"), ## added ???
2232             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "matrix_color"),
2233             0x9E00CFD2: Fpt_ChunkDescription(0x9E00CFD2, Fpt_Chunk_Type.INT, "scale"),
2234             0x99E8BEE1: Fpt_ChunkDescription(0x99E8BEE1, Fpt_Chunk_Type.INT, "type"),
2235             0x9BF8C2D0: Fpt_ChunkDescription(0x9BF8C2D0, Fpt_Chunk_Type.INT, "update_interval"),
2236             0xA2F8C6E4: Fpt_ChunkDescription(0xA2F8C6E4, Fpt_Chunk_Type.INT, "alignment"),
2237             0x99EED0D2: Fpt_ChunkDescription(0x99EED0D2, Fpt_Chunk_Type.INT, "slow_blink_speed"),
2238             0x99EED0DF: Fpt_ChunkDescription(0x99EED0DF, Fpt_Chunk_Type.INT, "fast_blink_speed"),
2239         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
2240             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
2241             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
2242             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
2243             }
2244
2245
2246     def __init__(self, owner=None):
2247         if owner is None:
2248             owner = self
2249         owner.obj__class = "Table_Element_40"
2250         owner.obj__id = FptElementType.DISPLAY_HUDDMD
2251         owner.obj__name = "Display_HudDmd"
2252         self.obj__chunks = FptTableElementReader_DISPLAY_HUDDMD.CHUNK_DICTIONARY
2253
2254
2255 class FptTableElementReader_CONTROL_DIVERTER(Fpt_Data_Reader):
2256     CHUNK_DICTIONARY = {
2257             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
2258             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
2259             0x9DFDC3D8: Fpt_ChunkDescription(0x9DFDC3D8, Fpt_Chunk_Type.STRING, "model"),
2260             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"),
2261             0xA300C5DC: Fpt_ChunkDescription(0xA300C5DC, Fpt_Chunk_Type.STRING, "texture"),
2262             0x99F4C2D2: Fpt_ChunkDescription(0x99F4C2D2, Fpt_Chunk_Type.INT, "sphere_mapping"),
2263             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "color"),
2264             0xA900BED2: Fpt_ChunkDescription(0xA900BED2, Fpt_Chunk_Type.INT, "start_angle"),
2265             0xA8EDC3D3: Fpt_ChunkDescription(0xA8EDC3D3, Fpt_Chunk_Type.INT, "rotation"),
2266             0xA2EABFE4: Fpt_ChunkDescription(0xA2EABFE4, Fpt_Chunk_Type.INT, "swing"),
2267             0x9DFBCDD3: Fpt_ChunkDescription(0x9DFBCDD3, Fpt_Chunk_Type.INT, "reflects_off_playfield"),
2268             0x9035D306: Fpt_ChunkDescription(0x9035D306, Fpt_Chunk_Type.STRING, "solenoid"),
2269             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
2270             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
2271             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
2272         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
2273             }
2274
2275     def __init__(self, owner=None):
2276         if owner is None:
2277             owner = self
2278         owner.obj__class = "Table_Element_43"
2279         owner.obj__id = FptElementType.CONTROL_DIVERTER
2280         owner.obj__name = "Control_Diverter"
2281         self.obj__chunks = FptTableElementReader_CONTROL_DIVERTER.CHUNK_DICTIONARY
2282
2283
2284 class FptTableElementReader_SPECIAL_STA(Fpt_Data_Reader):
2285     CHUNK_DICTIONARY = {
2286             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
2287             0xB8EFCDCF: Fpt_ChunkDescription(0xB8EFCDCF, Fpt_Chunk_Type.VECTOR2D, "position"),
2288             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"), ## added ???
2289             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "color"),
2290             0xA2F8CDDD: Fpt_ChunkDescription(0xA2F8CDDD, Fpt_Chunk_Type.INT, "height"),
2291             0x95FDC9CE: Fpt_ChunkDescription(0x95FDC9CE, Fpt_Chunk_Type.INT, "width"),
2292             0x96F5C5DC: Fpt_ChunkDescription(0x96F5C5DC, Fpt_Chunk_Type.STRING, "image_list"),
2293             0x95F3C9D0: Fpt_ChunkDescription(0x95F3C9D0, Fpt_Chunk_Type.INT, "update_interval"),
2294         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
2295             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
2296             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
2297             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
2298             }
2299
2300     def __init__(self, owner=None):
2301         if owner is None:
2302             owner = self
2303         owner.obj__class = "Table_Element_44"
2304         owner.obj__id = FptElementType.SPECIAL_STA
2305         owner.obj__name = "Special_STA"
2306         self.obj__chunks = FptTableElementReader_SPECIAL_STA.CHUNK_DICTIONARY
2307
2308
2309 class FptTableElementReader_CONTROL_AUTOPLUNGER(Fpt_Data_Reader):
2310     CHUNK_DICTIONARY = {
2311             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
2312             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
2313             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"), ## added ???
2314             0xA300C5DC: Fpt_ChunkDescription(0xA300C5DC, Fpt_Chunk_Type.STRING, "texture"),
2315             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "color"),
2316             0xA8EDC3D3: Fpt_ChunkDescription(0xA8EDC3D3, Fpt_Chunk_Type.INT, "rotation"),
2317             0xA1FABED2: Fpt_ChunkDescription(0xA1FABED2, Fpt_Chunk_Type.INT, "strength"),
2318             0x9DFBCDD3: Fpt_ChunkDescription(0x9DFBCDD3, Fpt_Chunk_Type.INT, "reflects_off_playfield"),
2319             0x97ECBFD3: Fpt_ChunkDescription(0x97ECBFD3, Fpt_Chunk_Type.STRING, "playfield"),
2320             0x95ECCFCF: Fpt_ChunkDescription(0x95ECCFCF, Fpt_Chunk_Type.INT, "include_v_cut"),
2321             0x90E9CFCF: Fpt_ChunkDescription(0x90E9CFCF, Fpt_Chunk_Type.VECTOR2D, "v_cut_position"),
2322             0x9BFCC6CF: Fpt_ChunkDescription(0x9BFCC6CF, Fpt_Chunk_Type.INT, "v_cut_lenght"),
2323             0xA2F4C9CF: Fpt_ChunkDescription(0xA2F4C9CF, Fpt_Chunk_Type.STRING, "v_cut_texture"),
2324             0x9DF2CFCF: Fpt_ChunkDescription(0x9DF2CFCF, Fpt_Chunk_Type.COLOR, "v_cut_color"),
2325             0xA5F3BFE4: Fpt_ChunkDescription(0xA5F3BFE4, Fpt_Chunk_Type.STRING, "solenoid"),
2326             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
2327             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
2328             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
2329         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
2330             }
2331
2332     def __init__(self, owner=None):
2333         if owner is None:
2334             owner = self
2335         owner.obj__class = "Table_Element_46"
2336         owner.obj__id = FptElementType.CONTROL_AUTOPLUNGER
2337         owner.obj__name = "Control_AutoPlunger"
2338         self.obj__chunks = FptTableElementReader_CONTROL_AUTOPLUNGER.CHUNK_DICTIONARY
2339
2340
2341 class FptTableElementReader_TARGET_ROTO(Fpt_Data_Reader):
2342     CHUNK_DICTIONARY = {
2343             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
2344             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
2345             0x9DFDC3D8: Fpt_ChunkDescription(0x9DFDC3D8, Fpt_Chunk_Type.STRING, "model"),
2346             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"), ## added ???
2347             0x96F5C5DC: Fpt_ChunkDescription(0x96F5C5DC, Fpt_Chunk_Type.STRING, "image_list"),
2348             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "color"),
2349             0xA8EDC3D3: Fpt_ChunkDescription(0xA8EDC3D3, Fpt_Chunk_Type.INT, "rotation"),
2350             0x96FBCCD6: Fpt_ChunkDescription(0x96FBCCD6, Fpt_Chunk_Type.INT, "offset"),
2351             0x9DFBCDD3: Fpt_ChunkDescription(0x9DFBCDD3, Fpt_Chunk_Type.INT, "reflects_off_playfield"),
2352             0x9035D306: Fpt_ChunkDescription(0x9035D306, Fpt_Chunk_Type.STRING, "sound_motor_whir"),
2353             0x9035D2F8: Fpt_ChunkDescription(0x9035D2F8, Fpt_Chunk_Type.STRING, "sound_when_hit"),
2354             0x95F3CFD3: Fpt_ChunkDescription(0x95F3CFD3, Fpt_Chunk_Type.INT, "target_count"),
2355             0x90F5CED3: Fpt_ChunkDescription(0x90F5CED3, Fpt_Chunk_Type.INT, "step_delay"),
2356             0x95FEBEDF: Fpt_ChunkDescription(0x95FEBEDF, Fpt_Chunk_Type.INT, "firt_target_centered"),
2357             0x9AEFD1E2: Fpt_ChunkDescription(0x9AEFD1E2, Fpt_Chunk_Type.INT, "carrousel_roto_target"),
2358             0x96FDD1D3: Fpt_ChunkDescription(0x96FDD1D3, Fpt_Chunk_Type.INT, "radius"),
2359             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
2360             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
2361             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
2362         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
2363             }
2364
2365     def __init__(self, owner=None):
2366         if owner is None:
2367             owner = self
2368         owner.obj__class = "Table_Element_49"
2369         owner.obj__id = FptElementType.TARGET_ROTO
2370         owner.obj__name = "Target_Roto"
2371         self.obj__chunks = FptTableElementReader_TARGET_ROTO.CHUNK_DICTIONARY
2372
2373
2374 class FptTableElementReader_CONTROL_POPUP(Fpt_Data_Reader):
2375     CHUNK_DICTIONARY = {
2376             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
2377             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
2378             0x9DFDC3D8: Fpt_ChunkDescription(0x9DFDC3D8, Fpt_Chunk_Type.STRING, "model"),
2379             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"),
2380             0xA300C5DC: Fpt_ChunkDescription(0xA300C5DC, Fpt_Chunk_Type.STRING, "texture"),
2381             0x96E8C0E2: Fpt_ChunkDescription(0x96E8C0E2, Fpt_Chunk_Type.INT, "crystal"),
2382             0x99F4C2D2: Fpt_ChunkDescription(0x99F4C2D2, Fpt_Chunk_Type.INT, "sphere_mapping"),
2383             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "color"),
2384             0xA8EDC3D3: Fpt_ChunkDescription(0xA8EDC3D3, Fpt_Chunk_Type.INT, "rotation"),
2385             0x96FBCCD6: Fpt_ChunkDescription(0x96FBCCD6, Fpt_Chunk_Type.INT, "offset"),
2386             0x9DFBCDD3: Fpt_ChunkDescription(0x9DFBCDD3, Fpt_Chunk_Type.INT, "reflects_off_playfield"),
2387             0x97ECBFD3: Fpt_ChunkDescription(0x97ECBFD3, Fpt_Chunk_Type.STRING, "playfield"),
2388             0xA5F3BFD2: Fpt_ChunkDescription(0xA5F3BFD2, Fpt_Chunk_Type.STRING, "solenoid"),
2389             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
2390             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
2391             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
2392         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
2393             }
2394
2395     def __init__(self, owner=None):
2396         if owner is None:
2397             owner = self
2398         owner.obj__class = "Table_Element_50"
2399         owner.obj__id = FptElementType.CONTROL_POPUP
2400         owner.obj__name = "Control_Popup"
2401         self.obj__chunks = FptTableElementReader_CONTROL_POPUP.CHUNK_DICTIONARY
2402
2403
2404 class FptTableElementReader_RAMP_MODEL(Fpt_Data_Reader):
2405     CHUNK_DICTIONARY = {
2406             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
2407             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
2408             0x9DFDC3D8: Fpt_ChunkDescription(0x9DFDC3D8, Fpt_Chunk_Type.STRING, "model"),
2409             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"),
2410             0xA300C5DC: Fpt_ChunkDescription(0xA300C5DC, Fpt_Chunk_Type.STRING, "texture"),
2411             0x99F4C2D2: Fpt_ChunkDescription(0x99F4C2D2, Fpt_Chunk_Type.INT, "sphere_mapping"),
2412             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "color"),
2413             0xA8EDC3D3: Fpt_ChunkDescription(0xA8EDC3D3, Fpt_Chunk_Type.FLOAT, "rotation"),
2414             0x96FBCCD6: Fpt_ChunkDescription(0x96FBCCD6, Fpt_Chunk_Type.INT, "offset"),
2415             0x9C00C0D1: Fpt_ChunkDescription(0x9C00C0D1, Fpt_Chunk_Type.INT, "transparency"),
2416             0x9DECCFE1: Fpt_ChunkDescription(0x9DECCFE1, Fpt_Chunk_Type.INT, "disable_culling"),
2417             0x9DFBCDD3: Fpt_ChunkDescription(0x9DFBCDD3, Fpt_Chunk_Type.INT, "reflects_off_playfield"),
2418             0x97ECBFD3: Fpt_ChunkDescription(0x97ECBFD3, Fpt_Chunk_Type.STRING, "playfield"),
2419             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
2420             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
2421             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
2422         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
2423             }
2424
2425     def __init__(self, owner=None):
2426         if owner is None:
2427             owner = self
2428         owner.obj__class = "Table_Element_51"
2429         owner.obj__id = FptElementType.RAMP_MODEL
2430         owner.obj__name = "Ramp_RampModel"
2431         self.obj__chunks = FptTableElementReader_RAMP_MODEL.CHUNK_DICTIONARY
2432
2433
2434 class FptTableElementReader_RAMP_WIRE(Fpt_Data_Reader):
2435     CHUNK_DICTIONARY = {
2436             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
2437             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"),
2438             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "color"),
2439             0xA4FAC5DC: Fpt_ChunkDescription(0xA4FAC5DC, Fpt_Chunk_Type.STRING, "texture"),
2440             0xA2F8CAD2: Fpt_ChunkDescription(0xA2F8CAD2, Fpt_Chunk_Type.INT, "start_height"),
2441             0xA2F8CAE0: Fpt_ChunkDescription(0xA2F8CAE0, Fpt_Chunk_Type.INT, "end_height"),
2442             0x96FCBBD3: Fpt_ChunkDescription(0x96FCBBD3, Fpt_Chunk_Type.STRING, "model_start"),
2443             0xA4FCBBD3: Fpt_ChunkDescription(0xA4FCBBD3, Fpt_Chunk_Type.STRING, "model_end"),
2444             0x9DFBCDD3: Fpt_ChunkDescription(0x9DFBCDD3, Fpt_Chunk_Type.INT, "reflects_off_playfield"),
2445             0x97ECBFD3: Fpt_ChunkDescription(0x97ECBFD3, Fpt_Chunk_Type.STRING, "playfield"),
2446             0x95F3C2D2: Fpt_ChunkDescription(0x95F3C2D2, Fpt_Chunk_Type.CHUNKLIST, "ramp_point"),
2447             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
2448             0xA1EDC5D2: Fpt_ChunkDescription(0xA1EDC5D2, Fpt_Chunk_Type.INT, "smooth"),
2449             0xA4F5C9D8: Fpt_ChunkDescription(0xA4F5C9D8, Fpt_Chunk_Type.INT, "left_guide"),
2450             0xA4F5C2D0: Fpt_ChunkDescription(0xA4F5C2D0, Fpt_Chunk_Type.INT, "left_upper_guide"),
2451             0xA0EFC9D8: Fpt_ChunkDescription(0xA0EFC9D8, Fpt_Chunk_Type.INT, "right_guide"),
2452             0xA0EFC2D0: Fpt_ChunkDescription(0xA0EFC2D0, Fpt_Chunk_Type.INT, "right_upper_guide"),
2453             0x95ECC3D1: Fpt_ChunkDescription(0x95ECC3D1, Fpt_Chunk_Type.INT, "top_wire"),
2454             0x9AF1CAE0: Fpt_ChunkDescription(0x9AF1CAE0, Fpt_Chunk_Type.INT, "mark_as_ramp_end_point"),
2455             0xA2F3C9D3: Fpt_ChunkDescription(0xA2F3C9D3, Fpt_Chunk_Type.INT, "ring_type"),
2456             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
2457             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
2458             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
2459         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
2460             }
2461
2462     def __init__(self, owner=None):
2463         if owner is None:
2464             owner = self
2465         owner.obj__class = "Table_Element_53"
2466         owner.obj__id = FptElementType.RAMP_WIRE
2467         owner.obj__name = "Ramp_WireRamp"
2468         self.obj__chunks = FptTableElementReader_RAMP_WIRE.CHUNK_DICTIONARY
2469
2470
2471 class FptTableElementReader_TARGET_SWING(Fpt_Data_Reader):
2472     CHUNK_DICTIONARY = {
2473             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
2474             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
2475             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"), ## added ???
2476             0x9DFDC3D8: Fpt_ChunkDescription(0x9DFDC3D8, Fpt_Chunk_Type.STRING, "model"),
2477             0xA300C5DC: Fpt_ChunkDescription(0xA300C5DC, Fpt_Chunk_Type.STRING, "texture"),
2478             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "color"),
2479             0xA8EDC3D3: Fpt_ChunkDescription(0xA8EDC3D3, Fpt_Chunk_Type.INT, "rotation"),
2480             0x9DFBCDD3: Fpt_ChunkDescription(0x9DFBCDD3, Fpt_Chunk_Type.INT, "reflects_off_playfield"),
2481             0xA5F3BFD1: Fpt_ChunkDescription(0xA5F3BFD1, Fpt_Chunk_Type.STRING, "sound_when_hit"),
2482             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
2483             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
2484             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
2485         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
2486             }
2487
2488     def __init__(self, owner=None):
2489         if owner is None:
2490             owner = self
2491         owner.obj__class = "Table_Element_54"
2492         owner.obj__id = FptElementType.TARGET_SWING
2493         owner.obj__name = "Target_Swing"
2494         self.obj__chunks = FptTableElementReader_TARGET_SWING.CHUNK_DICTIONARY
2495
2496
2497 class FptTableElementReader_RAMP_RAMP(Fpt_Data_Reader):
2498     CHUNK_DICTIONARY = {
2499             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
2500             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"),
2501             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "color"),
2502             0xA3F2C0D5: Fpt_ChunkDescription(0xA3F2C0D5, Fpt_Chunk_Type.INT, "ramp_profile"),
2503             0xA4FAC5DC: Fpt_ChunkDescription(0xA4FAC5DC, Fpt_Chunk_Type.STRING, "texture"),
2504             0xA2F8CAD2: Fpt_ChunkDescription(0xA2F8CAD2, Fpt_Chunk_Type.INT, "start_height"),
2505             0xA5F8BBD2: Fpt_ChunkDescription(0xA5F8BBD2, Fpt_Chunk_Type.INT, "start_width"),
2506             0xA2F8CAE0: Fpt_ChunkDescription(0xA2F8CAE0, Fpt_Chunk_Type.INT, "end_height"),
2507             0xA5F8BBE0: Fpt_ChunkDescription(0xA5F8BBE0, Fpt_Chunk_Type.INT, "end_width"),
2508             0xA2F8CAD9: Fpt_ChunkDescription(0xA2F8CAD9, Fpt_Chunk_Type.INT, "left_side_height"),
2509             0xA2F8CAD3: Fpt_ChunkDescription(0xA2F8CAD3, Fpt_Chunk_Type.INT, "right_side_height"),
2510             0x9DFBCDD3: Fpt_ChunkDescription(0x9DFBCDD3, Fpt_Chunk_Type.INT, "reflects_off_playfield"),
2511             0x97ECBFD3: Fpt_ChunkDescription(0x97ECBFD3, Fpt_Chunk_Type.STRING, "playfield"),
2512             0x9A00C5E0: Fpt_ChunkDescription(0x9A00C5E0, Fpt_Chunk_Type.STRING, "enamel_map"), #
2513             0x99F4C2D2: Fpt_ChunkDescription(0x99F4C2D2, Fpt_Chunk_Type.INT, "sphere_mapping"),
2514             0x9C00C0D1: Fpt_ChunkDescription(0x9C00C0D1, Fpt_Chunk_Type.INT, "transparency"),
2515             0x95F3C2D2: Fpt_ChunkDescription(0x95F3C2D2, Fpt_Chunk_Type.CHUNKLIST, "ramp_point"),
2516             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
2517             0xA1EDC5D2: Fpt_ChunkDescription(0xA1EDC5D2, Fpt_Chunk_Type.INT, "smooth"),
2518
2519             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
2520             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
2521             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
2522
2523             #0xA4F5C9D8: Fpt_ChunkDescription(0xA4F5C9D8, Fpt_Chunk_Type.RAWDATA, "unknown_0xA4F5C9D8"), # left_guide
2524             #0xA4F5C2D0: Fpt_ChunkDescription(0xA4F5C2D0, Fpt_Chunk_Type.RAWDATA, "unknown_0xA4F5C2D0"), # left_upper_guide
2525             #0xA0EFC9D8: Fpt_ChunkDescription(0xA0EFC9D8, Fpt_Chunk_Type.RAWDATA, "unknown_0xA0EFC9D8"), # right_guide
2526             #0xA0EFC2D0: Fpt_ChunkDescription(0xA0EFC2D0, Fpt_Chunk_Type.RAWDATA, "unknown_0xA0EFC2D0"), # right_upper_guide
2527             #0x95ECC3D1: Fpt_ChunkDescription(0x95ECC3D1, Fpt_Chunk_Type.RAWDATA, "unknown_0x95ECC3D1"),
2528             #0x9AF1CAE0: Fpt_ChunkDescription(0x9AF1CAE0, Fpt_Chunk_Type.INT, "mark_as_ramp_end_point"),
2529             #0xA2F3C9D3: Fpt_ChunkDescription(0xA2F3C9D3, Fpt_Chunk_Type.RAWDATA, "unknown_0xA2F3C9D3"), # ring_type
2530
2531             0xA4F5C9D8: Fpt_ChunkDescription(0xA4F5C9D8, Fpt_Chunk_Type.INT, "left_guide"),
2532             0xA4F5C2D0: Fpt_ChunkDescription(0xA4F5C2D0, Fpt_Chunk_Type.INT, "left_upper_guide"),
2533             0xA0EFC9D8: Fpt_ChunkDescription(0xA0EFC9D8, Fpt_Chunk_Type.INT, "right_guide"),
2534             0xA0EFC2D0: Fpt_ChunkDescription(0xA0EFC2D0, Fpt_Chunk_Type.INT, "right_upper_guide"),
2535             0x95ECC3D1: Fpt_ChunkDescription(0x95ECC3D1, Fpt_Chunk_Type.INT, "top_wire"),
2536             0x9AF1CAE0: Fpt_ChunkDescription(0x9AF1CAE0, Fpt_Chunk_Type.INT, "mark_as_ramp_end_point"),
2537             0xA2F3C9D3: Fpt_ChunkDescription(0xA2F3C9D3, Fpt_Chunk_Type.INT, "ring_type"),
2538         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
2539             }
2540
2541     def __init__(self, owner=None):
2542         if owner is None:
2543             owner = self
2544         owner.obj__class = "Table_Element_55"
2545         owner.obj__id = FptElementType.RAMP_RAMP
2546         owner.obj__name = "Ramp_Ramp"
2547         self.obj__chunks = FptTableElementReader_RAMP_RAMP.CHUNK_DICTIONARY
2548
2549
2550 class FptTableElementReader_TOY_SPINNINGDISK(Fpt_Data_Reader):
2551     CHUNK_DICTIONARY = {
2552             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
2553             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
2554             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"), ## was missing
2555             0x9DFDC3D8: Fpt_ChunkDescription(0x9DFDC3D8, Fpt_Chunk_Type.STRING, "model"),
2556             0xA300C5DC: Fpt_ChunkDescription(0xA300C5DC, Fpt_Chunk_Type.STRING, "texture"),
2557             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "color"),
2558             0xA1FABED2: Fpt_ChunkDescription(0xA1FABED2, Fpt_Chunk_Type.INT, "motor_power"),
2559             0x99F4D1E1: Fpt_ChunkDescription(0x99F4D1E1, Fpt_Chunk_Type.INT, "damping"),
2560             0x9DFBCDD3: Fpt_ChunkDescription(0x9DFBCDD3, Fpt_Chunk_Type.INT, "reflects_off_playfield"),
2561             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
2562             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
2563             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
2564         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
2565             }
2566
2567     def __init__(self, owner=None):
2568         if owner is None:
2569             owner = self
2570         owner.obj__class = "Table_Element_56"
2571         owner.obj__id = FptElementType.TOY_SPINNINGDISK
2572         owner.obj__name = "Toy_SpinningDisk"
2573         self.obj__chunks = FptTableElementReader_TOY_SPINNINGDISK.CHUNK_DICTIONARY
2574
2575
2576 class FptTableElementReader_LIGHT_LIGHTIMAGE(Fpt_Data_Reader):
2577     CHUNK_DICTIONARY = {
2578             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
2579             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
2580             0x9BFCCFDD: Fpt_ChunkDescription(0x9BFCCFDD, Fpt_Chunk_Type.VECTOR2D, "glow_center"),
2581             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"),
2582             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "color"),
2583             0xA2F8CDDD: Fpt_ChunkDescription(0xA2F8CDDD, Fpt_Chunk_Type.FLOAT, "height"),
2584             0x95FDC9CE: Fpt_ChunkDescription(0x95FDC9CE, Fpt_Chunk_Type.FLOAT, "width"),
2585             #0xA2F8CDDD: Fpt_ChunkDescription(0xA2F8CDDD, Fpt_Chunk_Type.INT, "height"),
2586             #0x95FDC9CE: Fpt_ChunkDescription(0x95FDC9CE, Fpt_Chunk_Type.INT, "width"),
2587             0x96F5C5DC: Fpt_ChunkDescription(0x96F5C5DC, Fpt_Chunk_Type.STRING, "image_list"),
2588             0xA8EDC3D3: Fpt_ChunkDescription(0xA8EDC3D3, Fpt_Chunk_Type.INT, "rotation"),
2589             0x95F3C9D0: Fpt_ChunkDescription(0x95F3C9D0, Fpt_Chunk_Type.INT, "animation_update_interval"),
2590             0x9E00CAD3: Fpt_ChunkDescription(0x9E00CAD3, Fpt_Chunk_Type.INT, "render_halo_glow"),
2591             0x96FDD1D3: Fpt_ChunkDescription(0x96FDD1D3, Fpt_Chunk_Type.INT, "glow_radius"),
2592             0x9DF2CFDD: Fpt_ChunkDescription(0x9DF2CFDD, Fpt_Chunk_Type.COLOR, "halo_color"),
2593             0x9600BED2: Fpt_ChunkDescription(0x9600BED2, Fpt_Chunk_Type.INT, "state"),
2594             0x95F3C9E3: Fpt_ChunkDescription(0x95F3C9E3, Fpt_Chunk_Type.INT, "blink_interval"),
2595             0x9600C2E3: Fpt_ChunkDescription(0x9600C2E3, Fpt_Chunk_Type.STRING, "blink_pattern"),
2596         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
2597             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
2598             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
2599             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
2600             }
2601
2602     def __init__(self, owner=None):
2603         if owner is None:
2604             owner = self
2605         owner.obj__class = "Table_Element_57"
2606         owner.obj__id = FptElementType.LIGHT_LIGHTIMAGE
2607         owner.obj__name = "Light_LightImage"
2608         self.obj__chunks = FptTableElementReader_LIGHT_LIGHTIMAGE.CHUNK_DICTIONARY
2609
2610
2611 class FptTableElementReader_KICKER_EMKICKER(Fpt_Data_Reader):
2612     CHUNK_DICTIONARY = {
2613             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
2614             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
2615             0x9DFDC3D8: Fpt_ChunkDescription(0x9DFDC3D8, Fpt_Chunk_Type.STRING, "model"),
2616             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"),
2617             0xA300C5DC: Fpt_ChunkDescription(0xA300C5DC, Fpt_Chunk_Type.STRING, "texture"),
2618             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "color"),
2619             0xA8EDC3D3: Fpt_ChunkDescription(0xA8EDC3D3, Fpt_Chunk_Type.INT, "rotation"),
2620             0xA1FABED2: Fpt_ChunkDescription(0xA1FABED2, Fpt_Chunk_Type.INT, "strength"),
2621             0xA5F3BFE4: Fpt_ChunkDescription(0xA5F3BFE4, Fpt_Chunk_Type.STRING, "solenoid"),
2622             0x9DFBCDD3: Fpt_ChunkDescription(0x9DFBCDD3, Fpt_Chunk_Type.INT, "reflects_off_playfield"),
2623             0x95ECCFCF: Fpt_ChunkDescription(0x95ECCFCF, Fpt_Chunk_Type.INT, "include_v_cut"),
2624             0x90E9CFCF: Fpt_ChunkDescription(0x90E9CFCF, Fpt_Chunk_Type.VECTOR2D, "v_cut_position"),
2625             0x9BFCC6CF: Fpt_ChunkDescription(0x9BFCC6CF, Fpt_Chunk_Type.INT, "v_cut_lenght"),
2626             0xA2F4C9CF: Fpt_ChunkDescription(0xA2F4C9CF, Fpt_Chunk_Type.STRING, "v_cut_texture"),
2627             0x9DF2CFCF: Fpt_ChunkDescription(0x9DF2CFCF, Fpt_Chunk_Type.COLOR, "v_cut_color"),
2628             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
2629             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
2630             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
2631         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
2632             }
2633
2634     def __init__(self, owner=None):
2635         if owner is None:
2636             owner = self
2637         owner.obj__class = "Table_Element_58"
2638         owner.obj__id = FptElementType.KICKER_EMKICKER
2639         owner.obj__name = "Kicker_EMKicker"
2640         self.obj__chunks = FptTableElementReader_KICKER_EMKICKER.CHUNK_DICTIONARY
2641
2642
2643 class FptTableElementReader_LIGHT_HUDLIGHTIMAGE(Fpt_Data_Reader):
2644     CHUNK_DICTIONARY = {
2645             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
2646             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
2647             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"), ## added ???
2648             0x9BFCCFDD: Fpt_ChunkDescription(0x9BFCCFDD, Fpt_Chunk_Type.VECTOR2D, "glow_center"),
2649             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "color"),
2650             0xA2F8CDDD: Fpt_ChunkDescription(0xA2F8CDDD, Fpt_Chunk_Type.INT, "height"),
2651             0x95FDC9CE: Fpt_ChunkDescription(0x95FDC9CE, Fpt_Chunk_Type.INT, "width"),
2652             0x96F5C5DC: Fpt_ChunkDescription(0x96F5C5DC, Fpt_Chunk_Type.STRING, "image_list"),
2653             0xA8EDC3D3: Fpt_ChunkDescription(0xA8EDC3D3, Fpt_Chunk_Type.INT, "rotation"),
2654             0x95F3C9D0: Fpt_ChunkDescription(0x95F3C9D0, Fpt_Chunk_Type.INT, "animation_update_interval"),
2655             0x9E00CAD3: Fpt_ChunkDescription(0x9E00CAD3, Fpt_Chunk_Type.INT, "render_halo_glow"),
2656             0x96FDD1D3: Fpt_ChunkDescription(0x96FDD1D3, Fpt_Chunk_Type.INT, "glow_radius"),
2657             0x9DF2CFDD: Fpt_ChunkDescription(0x9DF2CFDD, Fpt_Chunk_Type.COLOR, "halo_color"),
2658             0x9600BED2: Fpt_ChunkDescription(0x9600BED2, Fpt_Chunk_Type.INT, "state"),
2659             0x95F3C9E3: Fpt_ChunkDescription(0x95F3C9E3, Fpt_Chunk_Type.INT, "blink_interval"),
2660             0x9600C2E3: Fpt_ChunkDescription(0x9600C2E3, Fpt_Chunk_Type.STRING, "blink_pattern"),
2661         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
2662             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
2663             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
2664             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
2665             }
2666
2667     def __init__(self, owner=None):
2668         if owner is None:
2669             owner = self
2670         owner.obj__class = "Table_Element_60"
2671         owner.obj__id = FptElementType.LIGHT_HUDLIGHTIMAGE
2672         owner.obj__name = "Light_HudLightImage"
2673         self.obj__chunks = FptTableElementReader_LIGHT_HUDLIGHTIMAGE.CHUNK_DICTIONARY
2674
2675
2676 class FptTableElementReader_TRIGGER_OPTO(Fpt_Data_Reader):
2677     CHUNK_DICTIONARY = {
2678             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
2679             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
2680             0x9DFDC3D8: Fpt_ChunkDescription(0x9DFDC3D8, Fpt_Chunk_Type.STRING, "model"),
2681             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"),
2682             0xA6FAC5DC: Fpt_ChunkDescription(0xA6FAC5DC, Fpt_Chunk_Type.STRING, "texture_collector"),
2683             0xA4FAC5DC: Fpt_ChunkDescription(0xA4FAC5DC, Fpt_Chunk_Type.STRING, "texture_emitter"),
2684             0x9CEBC4DC: Fpt_ChunkDescription(0x9CEBC4DC, Fpt_Chunk_Type.INT, "invert"),
2685             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "color"),
2686             0xA8EDC3D3: Fpt_ChunkDescription(0xA8EDC3D3, Fpt_Chunk_Type.INT, "rotation"),
2687             0x95FDC9CE: Fpt_ChunkDescription(0x95FDC9CE, Fpt_Chunk_Type.INT, "beam_width"),
2688             0x9DFBCDD3: Fpt_ChunkDescription(0x9DFBCDD3, Fpt_Chunk_Type.INT, "reflects_off_playfield"),
2689             0xA5F3BFD1: Fpt_ChunkDescription(0xA5F3BFD1, Fpt_Chunk_Type.STRING, "sound_when_hit"),
2690             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
2691             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
2692             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
2693         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
2694             }
2695
2696     def __init__(self, owner=None):
2697         if owner is None:
2698             owner = self
2699         owner.obj__class = "Table_Element_61"
2700         owner.obj__id = FptElementType.TRIGGER_OPTO
2701         owner.obj__name = "Trigger_Opto"
2702         self.obj__chunks = FptTableElementReader_TRIGGER_OPTO.CHUNK_DICTIONARY
2703
2704
2705 class FptTableElementReader_TARGET_VARI(Fpt_Data_Reader):
2706     CHUNK_DICTIONARY = {
2707             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
2708             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
2709             0x9DFDC3D8: Fpt_ChunkDescription(0x9DFDC3D8, Fpt_Chunk_Type.STRING, "model"),
2710             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"), ## added ???
2711             0xA300C5DC: Fpt_ChunkDescription(0xA300C5DC, Fpt_Chunk_Type.STRING, "texture"),
2712             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "color"),
2713             0x99F4C2D2: Fpt_ChunkDescription(0x99F4C2D2, Fpt_Chunk_Type.INT, "sphere_mapping"),
2714             0xA8EDC3D3: Fpt_ChunkDescription(0xA8EDC3D3, Fpt_Chunk_Type.INT, "rotation"),
2715             0x95F3CFD2: Fpt_ChunkDescription(0x95F3CFD2, Fpt_Chunk_Type.INT, "switch_count"),
2716             0x9BFCBED2: Fpt_ChunkDescription(0x9BFCBED2, Fpt_Chunk_Type.INT, "tension"),
2717             0x9DFBCDD3: Fpt_ChunkDescription(0x9DFBCDD3, Fpt_Chunk_Type.INT, "reflects_off_playfield"),
2718             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
2719             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
2720             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
2721         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
2722             }
2723
2724     def __init__(self, owner=None):
2725         if owner is None:
2726             owner = self
2727         owner.obj__class = "Table_Element_62"
2728         owner.obj__id = FptElementType.TARGET_VARI
2729         owner.obj__name = "Target_Vari"
2730         self.obj__chunks = FptTableElementReader_TARGET_VARI.CHUNK_DICTIONARY
2731
2732
2733 class FptTableElementReader_TOY_HOLOGRAM(Fpt_Data_Reader):
2734     CHUNK_DICTIONARY = {
2735             0xA4F4D1D7: Fpt_ChunkDescription(0xA4F4D1D7, Fpt_Chunk_Type.WSTRING, "name"),
2736             0x9BFCCFCF: Fpt_ChunkDescription(0x9BFCCFCF, Fpt_Chunk_Type.VECTOR2D, "position"),
2737             0x9DFDC3D8: Fpt_ChunkDescription(0x9DFDC3D8, Fpt_Chunk_Type.STRING, "model"),
2738             0xA3EFBDD2: Fpt_ChunkDescription(0xA3EFBDD2, Fpt_Chunk_Type.STRING, "surface"),
2739             0x97F5C3E2: Fpt_ChunkDescription(0x97F5C3E2, Fpt_Chunk_Type.COLOR, "color"),
2740             0xA2F8CDDD: Fpt_ChunkDescription(0xA2F8CDDD, Fpt_Chunk_Type.INT, "height"),
2741             0x95FDC9CE: Fpt_ChunkDescription(0x95FDC9CE, Fpt_Chunk_Type.INT, "width"),
2742             0xA8EDC3D3: Fpt_ChunkDescription(0xA8EDC3D3, Fpt_Chunk_Type.INT, "rotation"),
2743             0x95F5C9D1: Fpt_ChunkDescription(0x95F5C9D1, Fpt_Chunk_Type.INT, "tilt"),
2744             0x96FBCCD6: Fpt_ChunkDescription(0x96FBCCD6, Fpt_Chunk_Type.INT, "offset"),
2745             0x96F5C5DC: Fpt_ChunkDescription(0x96F5C5DC, Fpt_Chunk_Type.STRING, "image_list"),
2746             0x95F3C9D0: Fpt_ChunkDescription(0x95F3C9D0, Fpt_Chunk_Type.INT, "animation_update_interval"),
2747             0x97F5CFE1: Fpt_ChunkDescription(0x97F5CFE1, Fpt_Chunk_Type.COLOR, "matrix_color"),
2748             0x9CFDD1D3: Fpt_ChunkDescription(0x9CFDD1D3, Fpt_Chunk_Type.INT, "render_as_dmd_matrix"),
2749             0x95F3CFCD: Fpt_ChunkDescription(0x95F3CFCD, Fpt_Chunk_Type.INT, "x_dot_count"),
2750             0x95F3CFCC: Fpt_ChunkDescription(0x95F3CFCC, Fpt_Chunk_Type.INT, "y_dot_count"),
2751             0xA0F1BDE1: Fpt_ChunkDescription(0xA0F1BDE1, Fpt_Chunk_Type.INT, "update_interval"),
2752             0xA2F8C6E4: Fpt_ChunkDescription(0xA2F8C6E4, Fpt_Chunk_Type.INT, "alignment"),
2753             0x99EED0D2: Fpt_ChunkDescription(0x99EED0D2, Fpt_Chunk_Type.INT, "slow_blink_speed"),
2754             0x99EED0DF: Fpt_ChunkDescription(0x99EED0DF, Fpt_Chunk_Type.INT, "fast_blink_speed"),
2755         0xA6F2C6D3: Fpt_ChunkDescription(0xA6F2C6D3, Fpt_Chunk_Type.INT, "object_appers_on"),
2756             0x9EFEC3D9: Fpt_ChunkDescription(0x9EFEC3D9, Fpt_Chunk_Type.INT, "locked"),
2757             0x9100C6E4: Fpt_ChunkDescription(0x9100C6E4, Fpt_Chunk_Type.INT, "layer"),
2758             0xA7FDC4E0: Fpt_ChunkDescription(0xA7FDC4E0, Fpt_Chunk_Type.END, "end"),
2759             }
2760
2761     def __init__(self, owner=None):
2762         if owner is None:
2763             owner = self
2764         owner.obj__class = "Table_Element_64"
2765         owner.obj__id = FptElementType.TOY_HOLOGRAM
2766         owner.obj__name = "Toy_Hologram"
2767         self.obj__chunks = FptTableElementReader_TOY_HOLOGRAM.CHUNK_DICTIONARY
2768
2769
2770 ###############################################################################
2771 class Fpl_Library_Element():
2772     pass
2773
2774
2775 ###############################################################################
2776 class Fpm_File_Reader(Cfb_RawIO_Reader):
2777     def read_model(self):
2778         self.PinModel = None
2779
2780         stream_names = self.get_stream_directory_names()
2781         for stream_name in stream_names:
2782             stream = self.get_stream(stream_name)
2783             if stream and stream.size():
2784                 self.read_component(stream)
2785
2786     def read_component(self, stream):
2787         name = stream.directory_entry().Directory_Entry_Name
2788         if name:
2789             name = name.lower()
2790         if name.startswith("modeldata"):
2791             reader = Fpt_PinModel_Reader()
2792             self.PinModel = reader
2793         else:
2794             print("#DEBUG skip read_component:", name)
2795             reader = None
2796
2797         if reader:
2798             reader.read(stream)
2799
2800         #print("#DEBUG", reader)
2801
2802     def grab_content(self, dst_path=None):
2803         dst_sub_path_names = {}
2804
2805         if not dst_path:
2806             dst_path = "fpm_grab"
2807             dst_path = path.normpath(dst_path)
2808             #while path.exists(dst_path):
2809             #    u_time = unpack("<Q", pack("<d", time()))[0]
2810             #    dst_path = "fpl_grab_{:016X}".format(u_time)
2811             #    dst_path = path.normpath(dst_path)
2812         else:
2813             dst_path = path.normpath(dst_path)
2814
2815         makedirs(dst_path, mode=0o777, exist_ok=True)
2816         self.__dst_path = dst_path
2817
2818         return Fpm_File_Reader.grab_content_ex(dst_path, { "modeldata": self.PinModel, }, dst_sub_path_names)
2819
2820     @staticmethod
2821     def grab_content_ex(dst_path, pinmodel_dict, dst_sub_path_names):
2822         for key, reader in pinmodel_dict.items():
2823             item_name = reader.get_value("name")
2824             item_name = FpxUtilities.toGoodName(item_name) ###
2825             if item_name:
2826                 dst_sub_path = path.join(dst_path, item_name)
2827                 makedirs(dst_sub_path, mode=0o777, exist_ok=True)
2828                 #print("#DEBUG", item_name, dst_path, dst_sub_path)
2829                 dst_sub_path_names["sub_dir"] = dst_sub_path
2830             else:
2831                 dst_sub_path = dst_path
2832
2833             dst_sub_path_names[key] = dst_sub_path
2834
2835             item_type = reader.get_value("type")
2836             dst_sub_path_names["type"] = item_type
2837
2838             # grab preview
2839             win_item_path = reader.get_value("preview_path")
2840             item_path = FpxUtilities.toGoodFilePath(win_item_path)
2841             item_data_len = reader.get_value("preview_data_len")
2842             item_data = reader.get_value("preview_data")
2843             if item_path and item_data:
2844                 full_path = path.normpath(path.join(dst_sub_path, item_path))
2845                 item_data.grab_to_file(full_path)
2846                 dst_sub_path_names["preview_data"] = full_path
2847
2848             # grab primary_model
2849             win_item_path = reader.get_value("primary_model_path")
2850             item_path = FpxUtilities.toGoodFilePath(win_item_path)
2851             item_data_len = reader.get_value("primary_model_data_len")
2852             item_data = reader.get_value("primary_model_data")
2853             if item_path and item_data:
2854                 full_path = path.normpath(path.join(dst_sub_path, item_path))
2855                 item_data.grab_to_file(full_path)
2856                 dst_sub_path_names["primary_model_data"] = full_path
2857
2858             # grab secondary_model
2859             win_item_path = reader.get_value("secondary_model_path")
2860             item_path = FpxUtilities.toGoodFilePath(win_item_path)
2861             item_data_len = reader.get_value("secondary_model_data_len")
2862             item_data = reader.get_value("secondary_model_data")
2863             if item_path and item_data:
2864                 full_path = path.normpath(path.join(dst_sub_path, item_path))
2865                 item_data.grab_to_file(full_path)
2866                 dst_sub_path_names["secondary_model_data"] = full_path
2867
2868             # grab mask_model
2869             win_item_path = reader.get_value("mask_model_path")
2870             item_path = FpxUtilities.toGoodFilePath(win_item_path)
2871             item_data_len = reader.get_value("mask_model_data_len")
2872             item_data = reader.get_value("mask_model_data")
2873             if item_path and item_data:
2874                 full_path = path.normpath(path.join(dst_sub_path, item_path))
2875                 item_data.grab_to_file(full_path)
2876                 dst_sub_path_names["mask_model_data"] = full_path
2877
2878             # grab reflection_model
2879             win_item_path = reader.get_value("reflection_model_path")
2880             item_path = FpxUtilities.toGoodFilePath(win_item_path)
2881             item_data_len = reader.get_value("reflection_model_data_len")
2882             item_data = reader.get_value("reflection_model_data")
2883             if item_path and item_data:
2884                 full_path = path.normpath(path.join(dst_sub_path, item_path))
2885                 item_data.grab_to_file(full_path)
2886                 dst_sub_path_names["reflection_model_data"] = full_path
2887
2888         return dst_path, dst_sub_path_names
2889
2890
2891 ###############################################################################
2892 class Fpl_File_Reader(Cfb_RawIO_Reader):
2893     def read_library(self):
2894         self.__data = {}
2895
2896         self.Graphic = {}
2897         self.Sound = {}
2898         self.Music = {}
2899         self.PinModel = {}
2900         self.DmdFont = {}
2901         self.Script = {}
2902
2903         stream_names = self.get_stream_directory_names()
2904         for stream_name in stream_names:
2905             stream = self.get_stream(stream_name)
2906             if stream and stream.size():
2907                 name_root, name_item, name_type = stream_name.split(Fpl_File_Reader.SEPARATOR)
2908                 self.read_component(stream, name_item)
2909
2910     def read_component(self, stream, name):
2911         name = FpxUtilities.toGoodName(name) ####
2912         data = self.__data.get(name)
2913         if not data:
2914             data = Fpl_Library_Element()
2915             self.__data[name] = data
2916
2917         name_type = stream.directory_entry().Directory_Entry_Name
2918         if name_type == "FTYP":
2919             data.FTYP = stream.read_dword()
2920             if data.FTYP == Fpl_Library_Type.GRAPHIC:
2921                 data._FTYP = Fpl_Library_Type.TYPE_GRAPHIC
2922                 self.Graphic[name] = data
2923             elif data.FTYP == Fpl_Library_Type.SOUND:
2924                 data._FTYP = Fpl_Library_Type.TYPE_SOUND
2925                 self.Sound[name] = data
2926             elif data.FTYP == Fpl_Library_Type.MUSIC:
2927                 data._FTYP = Fpl_Library_Type.TYPE_MUSIC
2928                 self.Music[name] = data
2929             elif data.FTYP == Fpl_Library_Type.MODEL:
2930                 data._FTYP = Fpl_Library_Type.TYPE_MODEL
2931                 self.PinModel[name] = data
2932             elif data.FTYP == Fpl_Library_Type.DMDFONT:
2933                 data._FTYP = Fpl_Library_Type.TYPE_DMDFONT
2934                 self.DmdFont[name] = data
2935             elif data.FTYP == Fpl_Library_Type.SCRIPT:
2936                 data._FTYP = Fpl_Library_Type.TYPE_SCRIPT
2937                 self.Script[name] = data
2938             else:
2939                 data._FTYP = Fpl_Library_Type.TYPE_UNKNOWN
2940         elif name_type == "FLAD":
2941             data.FLAD = Cfb_Extras.to_time(stream.read_qword())
2942         elif name_type == "FPAT":
2943             data.FPAT = bytes.decode(stream.read())
2944         elif name_type == "FDAT":
2945             data.FDAT = Fpx_zLZO_RawData_Stream(stream)
2946         pass
2947
2948     def grab_content(self, dst_path=None, filter={}, name=None):
2949         if not dst_path:
2950             dst_path = "fpl_grab"
2951             dst_path = path.normpath(dst_path)
2952             #while path.exists(dst_path):
2953             #    u_time = unpack("<Q", pack("<d", time()))[0]
2954             #    dst_path = "fpl_grab_{:016X}".format(u_time)
2955             #    dst_path = path.normpath(dst_path)
2956         else:
2957             #BUG in makedirs. does not create a folder ending with a blank
2958             #dst_path = path.normpath(dst_path)
2959             dst_path = path.normpath(dst_path.rstrip('. '))
2960
2961         makedirs(dst_path, mode=0o777, exist_ok=True)
2962         self.__dst_path = dst_path
2963
2964         dst_sub_path_names = {}
2965
2966         if name:
2967             items = [[name, self.__data.get(name)], ]
2968         else:
2969             items = self.__data.items()
2970
2971         if not filter:
2972             filter = Fpl_Library_Type.FILTER_ALL
2973
2974         for item_name, value in items:
2975             if value._FTYP not in filter:
2976                 continue
2977
2978             dst_sub_path = path.join(dst_path, item_name)
2979             makedirs(dst_sub_path, mode=0o777, exist_ok=True)
2980
2981             dst_sub_path_names["sub_dir_{}".format(item_name)] = dst_sub_path
2982             dst_sub_path_names["type_{}".format(item_name)] = value._FTYP
2983
2984             # grab item
2985             win_file_path = value.FPAT
2986             file_path = FpxUtilities.toGoodFilePath(win_file_path)
2987             item_path=path.split(file_path)[1]
2988             item_data=value.FDAT
2989             if item_path and item_data:
2990                 full_path = path.normpath(path.join(dst_sub_path, item_path))
2991                 item_data.grab_to_file(full_path)
2992                 dst_sub_path_names[item_name] = full_path
2993
2994         return dst_path, dst_sub_path_names
2995
2996
2997 ###############################################################################
2998 class Fpt_File_Reader(Cfb_RawIO_Reader):
2999     def read_table(self):
3000         self.__data = {}
3001
3002         self.Image = {}
3003         self.Sound = {}
3004         self.Music = {}
3005         self.PinModel = {}
3006         self.DmdFont = {}
3007
3008         self.ImageList = {}
3009         self.LightList = {}
3010
3011         self.Table_Data = None
3012         self.File_Version = None
3013         self.Table_Element = {}
3014         self.Table_MAC = None
3015
3016         self.Surfaces = {}
3017         self.Walls = {}
3018
3019         stream_names = self.get_stream_directory_names()
3020         for stream_name in stream_names:
3021             stream = self.get_stream(stream_name)
3022             if stream and stream.size():
3023                 self.read_component(stream)
3024
3025     def read_component(self, stream):
3026         name = stream.directory_entry().Directory_Entry_Name
3027         if name:
3028             name = name.lower()
3029         if name.startswith("table data"):
3030             reader = Fpt_Table_Data_Reader()
3031             self.Table_Data = reader
3032         elif name.startswith("file version"):
3033             reader = Fpt_File_Version_Reader()
3034             self.File_Version = reader
3035         elif name.startswith("table element "):
3036             reader = FptTableElementReader()
3037             self.Table_Element[name] = reader
3038         elif name.startswith("image "):
3039             reader = Fpt_Image_Reader()
3040             self.Image[name] = reader
3041             self.__data[name] = reader
3042         elif name.startswith("sound "):
3043             reader = Fpt_Sound_Reader()
3044             self.Sound[name] = reader
3045             self.__data[name] = reader
3046         elif name.startswith("music "):
3047             reader = Fpt_Music_Reader()
3048             self.Music[name] = reader
3049             self.__data[name] = reader
3050         elif name.startswith("pinmodel "):
3051             reader = Fpt_PinModel_Reader()
3052             self.PinModel[name] = reader
3053             self.__data[name] = reader
3054         elif name.startswith("imagelist "):
3055             reader = Fpt_ImageList_Reader()
3056             self.ImageList[name] = reader
3057             self.__data[name] = reader
3058         elif name.startswith("lightlist "):
3059             reader = Fpt_LightList_Reader()
3060             self.LightList[name] = reader
3061             self.__data[name] = reader
3062         elif name.startswith("dmdfont "):
3063             reader = Fpt_DmdFont_Reader()
3064             self.DmdFont[name] = reader
3065             self.__data[name] = reader
3066         elif name.startswith("table mac"):
3067             reader = Fpt_Table_MAC_Reader()
3068             self.Table_MAC = reader
3069         else:
3070             reader = None
3071
3072         if reader:
3073             reader.read(stream)
3074
3075             item_name = reader.get_value("name")
3076             item_name = FpxUtilities.toGoodName(item_name) ###
3077             if not item_name:
3078                 return
3079
3080             fpx_id = reader.get_obj_value("id")
3081             if fpx_id == FptElementType.SURFACE:
3082                 self.Surfaces[item_name] = reader
3083             elif fpx_id == FptElementType.GUIDE_WALL:
3084                 self.Walls[item_name] = reader
3085
3086         ##print("#DEBUG", reader)
3087
3088     def grab_stream(self, dst_path=None):
3089         if not dst_path:
3090             u_time = unpack("<Q", pack("<d", time()))[0]
3091             dst_path = "fpt_grab_{:016X}".format(unpack("<Q", pack("<d", time()))[0])
3092         dst_path = path.normpath(dst_path)
3093         if path.exists(dst_path):
3094             raise OSError
3095         makedirs(dst_path, mode=0o777, exist_ok=False)
3096         self.__dst_path = dst_path
3097
3098     def grab_content(self, dst_path=None, name=None, filter=None):
3099         if not dst_path:
3100             dst_path = "fpt_grab"
3101             dst_path = path.normpath(dst_path)
3102             #while path.exists(dst_path):
3103             #    u_time = unpack("<Q", pack("<d", time()))[0]
3104             #    dst_path = "fpl_grab_{:016X}".format(u_time)
3105             #    dst_path = path.normpath(dst_path)
3106         else:
3107             dst_path = path.normpath(dst_path)
3108
3109         makedirs(dst_path, mode=0o777, exist_ok=True)
3110         self.__dst_path = dst_path
3111
3112         dst_sub_path_names = {}
3113
3114         if name:
3115             items = [[name, self.__data.get(name)], ]
3116         else:
3117             items = self.__data.items()
3118
3119         for key, reader in items:
3120             if not reader or reader.get_value("linked"):
3121                 continue
3122
3123             item_name = reader.get_value("name")
3124             item_name = FpxUtilities.toGoodName(item_name) ####
3125             if not item_name:
3126                 continue
3127
3128             dst_sub_path = dst_path.rstrip('. ')
3129
3130             item_data_dict = {}
3131
3132             if isinstance(reader, Fpt_Image_Reader):
3133                 type = Fpt_PackedLibrary_Type.TYPE_IMAGE
3134                 item_type = reader.get_value("type")
3135                 item_ext = Fpt_Resource_Type.VALUE_INT_TO_NAME[item_type]
3136                 item_data = reader.get_value("data")
3137                 item_data_dict[item_name] = item_data
3138
3139             elif isinstance(reader, Fpt_Sound_Reader):
3140                 ##TODO
3141                 #type = Fpt_PackedLibrary_Type.TYPE_SOUND
3142                 #item_type = reader.get_value("type")
3143                 #item_ext = Fpt_Resource_Type.VALUE_INT_TO_NAME[item_type]
3144                 #item_data = reader.get_value("data")
3145                 #item_data_dict[item_name] = item_data
3146                 continue
3147
3148             elif isinstance(reader, Fpt_Music_Reader):
3149                 ##TODO
3150                 #type = Fpt_PackedLibrary_Type.TYPE_MUSIC
3151                 #item_type = reader.get_value("type")
3152                 #item_ext = Fpt_Resource_Type.VALUE_INT_TO_NAME[item_type]
3153                 #item_data = reader.get_value("data")
3154                 #item_data_dict[item_name] = item_data
3155                 continue
3156
3157             elif isinstance(reader, Fpt_PinModel_Reader):
3158                 type = Fpt_PackedLibrary_Type.TYPE_MODEL
3159
3160                 fpm_sub_path_names = {}
3161                 dst_sub_path_names["data_{}".format(item_name)] = Fpm_File_Reader.grab_content_ex(dst_path, { item_name: reader, }, fpm_sub_path_names)
3162                 dst_sub_path_names["type_{}".format(item_name)] = type
3163
3164             elif isinstance(reader, Fpt_ImageList_Reader):
3165                 ##TODO
3166                 #type = Fpt_PackedLibrary_Type.TYPE_IMAGE_LIST
3167                 continue
3168
3169             elif isinstance(reader, Fpt_LightList_Reader):
3170                 ##TODO
3171                 #type = Fpt_PackedLibrary_Type.TYPE_LIGHT_LIST
3172                 continue
3173
3174             elif isinstance(reader, Fpt_DmdFont_Reader):
3175                 ##TODO
3176                 #type = Fpt_PackedLibrary_Type.TYPE_DMDFONT
3177                 continue
3178
3179             else:
3180                 #type = Fpt_PackedLibrary_Type.TYPE_UNKNOWN
3181                 continue
3182
3183             for sub_item_name, sub_item_data in item_data_dict.items():
3184                 if not sub_item_data:
3185                     continue
3186                 full_path = path.normpath(path.join(dst_sub_path, "{}.{}".format(sub_item_name, item_ext))).lower()
3187                 sub_item_data.grab_to_file(full_path)
3188             &