[Scummvm-git-logs] scummvm master -> 6a1dc05132ba658f228a5d5335a72a567a6d414a

sev- noreply at scummvm.org
Sun Nov 6 21:43:15 UTC 2022


This automated email contains information about 434 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
1458492a82 FREESCAPE: added initial files
de83c18416 FREESCAPE: initial fixes
3e414ba6b1 FREESCAPE: first attempt to merge phantasma code
56f4fdca10 FREESCAPE: added more code from phantasma
1edba8cfb2 FREESCAPE: used clang-format to improve code style
7606960ec8 FREESCAPE: refactored old phantasma code
b5df126667 FREESCAPE: used clang-format to improve code style
424a2e967c FREESCAPE: added first code for 8-bit parsing
9c1391e957 FREESCAPE: used clang-format to improve code style
5cc47a4077 FREESCAPE: added more code for 8-bit parsing
8d0b3b3e04 FREESCAPE: added more code for 8-bit parsing
f4558be547 FREESCAPE: used clang-format to improve code
a7c57a39b1 FREESCAPE: first attempt to do palette parsing
085c083d2b FREESCAPE: initial tinygl support
868d07e2df FREESCAPE: start area support and empty draw code
62aa8d4bf5 FREESCAPE: fixes in the main and object class
0cd58b40ca FREESCAPE: fixes in the area and object class
26573ae048 FREESCAPE: more fixes
3956250e63 FREESCAPE: initial rendering of sky and ground
3a9491a2a3 FREESCAPE: fixed rendering sky and ground with border
a36dc0bd75 FREESCAPE: fixes and added one cube example
c6d703414a FREESCAPE: added more code for rendering areas
2a15014719 FREESCAPE: better parsing of Driller and fixes
e0cbcd074d FREESCAPE: improve palette handling
6f328337f9 FREESCAPE: better parsing of 3DK games
56f692a67c FREESCAPE: some parsing of instruments in 3DK games
38f8663880 FREESCAPE: entraces support for Driller
ad0f96ad11 FREESCAPE: better parser for Driller
fcd721c90a FREESCAPE: better detection and starting to parse Driller frame image
d18ef03d1a FREESCAPE: code clean-up
1f4ae36d19 FREESCAPE: removed clearAllDebugChannels when rebased with master
0110695d31 FREESCAPE: refactoring to better integrate exe parsing
7ecb3169ee FREESCAPE: preliminary movement functions and fixes
3e6c07f5fa FREESCAPE: preliminary rotation/movement code
9a2479465b FREESCAPE: removed useless code from the renderer
364c0f3174 FREESCAPE: using Math::Vector3d instead of TinyGL::Vector3
5fa47a0188 FREESCAPE: added some code to determinate how to render a cube
8bdfd73559 FREESCAPE: refactoring detection code and first attempt to render cubes
829afc2325 FREESCAPE: fixes
359884615b FREESCAPE: improved mouse look and some other fixes
227b5f535d FREESCAPE: fixed colors and improved rendering to avoid the mirror effect
7dfc5e7894 FREESCAPE: refactored rendering code and added more games
79e2e0b542 FREESCAPE: added more detected games, better parsing and added polygon rendering
a2f764a61d FREESCAPE: better polygon rendering and object code refactoring
4594050af5 FREESCAPE: fixes regarding tinygl changes upstream
2045ecfb81 FREESCAPE: removed some old code and add call to destroyContext
b8c4488cde FREESCAPE: removed more old code
edcfe272ce FREESCAPE: removed more old code
99c19f3441 FREESCAPE: refactor drawing code into drawFrame
43166fbb39 FREESCAPE: refactor input into processInput
3255d04c2f FREESCAPE: initialize _playerHeight when using 8-bit engines
e04e631472 FREESCAPE: removed more old code
099bb5eed1 FREESCAPE: some changes to make the code render some levels of Driller
2bccd8c6f5 FREESCAPE: avoid rendering sky and floor in Driller
6eb56f8e5c FREESCAPE: disable transparent color face in Driller
bbf7656f0a FREESCAPE: corrected some colors in Driller
a74d18cfb2 FREESCAPE: corrected some colors in the first level of Driller
c3512c30f3 FREESCAPE: added most of the Driller EGA palette
00143272df FREESCAPE: improved initial position in Driller
f8dac295ca FREESCAPE: refactor 8-bit binary loading to use scummvm API
0d3ee56960 FREESCAPE: prototype of shooting code and refactor
786f70782e FREESCAPE: improved handling of mouse rotation and bounding boxes
dcc631ff3d FREESCAPE: improved validation of polygon when rendering
7e8653487d FREESCAPE: some changes to allow to parse and render castle master levels
92ca9ab6a4 FREESCAPE: improved detection of castle
c6af73a7b2 FREESCAPE: added basic detection of space station oblivion
6a9b2a8b03 FREESCAPE: fixed mirrored rendering and basic ray collision
420f2346d8 FREESCAPE: proof of concept of collision with geometric objects
18c4de3eb0 FREESCAPE: removed game.cpp and game.h files
24fa074f15 FREESCAPE: improved detection tables for several games
6f500da3f8 FREESCAPE: removed StreamLoader and replaced with scummvm API in the 16bit binary loader
d3f29493e8 FREESCAPE: fixed rendering of planar objects and enforced more constrains on 8-bits binary loading
45b2731a2f FREESCAPE: initial implementation of pyramid rendering
213698c53d FREESCAPE: more code to help debuging and testing
6df44a7391 FREESCAPE: detection of total eclipse and more debugging code
8830dce83a FREESCAPE: show code to execute when colliding
9fb29ea4ca FREESCAPE: proof of concept of fcl execution
e65c905eff FREESCAPE: refactor area changing code
263d710d64 FREESCAPE: improved detection code to perform an inverse search on the drawable objects
ab4030ecb0 FREESCAPE: implemented invis opcode and improved collision detection when shooting
5a1026d54a FREESCAPE: fixed ordinate scales for 8-bit binaries
3d63dc44b7 FREESCAPE: improved detection collision considering distance to object
93de5a6d60 FREESCAPE: avoid collisions with invisible objects
a684bc9506 FREESCAPE: added basic VIS implementation
8442d007e7 FREESCAPE: added basic TOGVIS implementation
773fffc048 FREESCAPE: added basic crossair implementation
f3779e2901 FREESCAPE: avoid collisions with invisible objects
7d8c52d02e FREESCAPE: render basic shoot line
e9dffc6ef9 FREESCAPE: improved header, namespaces and removed useless files
3647405514 FREESCAPE: more debugging code
b479b395ec FREESCAPE: implemented bounding box for pyramids
66c4c8c70b FREESCAPE: basic implementation of solid objects using current collision checking
239aa6a49d FREESCAPE: coloring pyramid implementation and refactoring of palette code
4283f9b4e6 FREESCAPE: added one cga palette and refactored palette code
1a3e7af413 FREESCAPE: fixed position rendering of polygons
cc1bfdf84e FREESCAPE: implemented the DESTROY instruction
03291ca0b0 FREESCAPE: basic support for border rendering in driller
3e5f02f346 FREESCAPE: avoid crashing when there is no border file and added support for cga border
18feecbb69 FREESCAPE: initial implementation of variable increment and game state in Driller
ee973d346f FREESCAPE: initial implementation of variable decrement and fix in global condition parsing Driller
6d6d104115 FREESCAPE: initial implementation of end if not equal instruction
93129f9c76 FREESCAPE: initial implementations of redraw and delay instructions
e87876e400 FREESCAPE: refactored instruction code
5cd4f59dcb FREESCAPE: improved 8bit instruction parsing
91ba5e177e FREESCAPE: improved 8bit instruction parsing and line rendering
a6fcc20d45 FREESCAPE: mapped more castle master areas
6cb783daa0 FREESCAPE: improved player collisions and added basic detection of darkside
2b35817292 FREESCAPE: implemented bit instructions
6840ce7ba2 FREESCAPE: basic implementation of step up/down
da75afe544 FREESCAPE: initial parsing of Total Eclipse
fc07a47c61 FREESCAPE: initial parsing of Dark Side and some rendering fixes for eclipse
a76317afb4 FREESCAPE: added more Castle Master releases and some fixes
26d1918b73 FREESCAPE: load all the Castle Master data from amstrad
327cff4fea FREESCAPE: fixed for castle in cpc amstrad
87ff5766e3 FREESCAPE: improved collision detection code considering area scale
ee5d57849f FREESCAPE: planar rendering fixes
19fcfae609 FREESCAPE: simplified and improved ray collision code
22c722d02c FREESCAPE: first implementation of area conditions when shooting
7993864cc0 FREESCAPE: improved ray hit detection and finished implementation of toggle visibility opcode
1085cf6b50 FREESCAPE: corrected end if not equal opcode
580e9b1854 FREESCAPE: allow users to fit in small areas reducing its width
af059a695e FREESCAPE: basic sound implementation and adding floor to castle master levels
359bd5c950 FREESCAPE: minor changes in collision detections
c821a6164c FREESCAPE: removed unusued variables
59328b7114 FREESCAPE: reworked collision detection code
d140a9fd2f FREESCAPE: basic castle EGA palette
ea663d580a FREESCAPE: sensor objects are created
39fc195dc9 FREESCAPE: improved collision detection when running effects
f161f75250 FREESCAPE: improved fcl parsing and load some global objects in driller
0206ca0998 FREESCAPE: improved rendering in eclipse
0a68494845 FREESCAPE: improved rendering in castle
10b26d1afc FREESCAPE: refactor some code for eclipse
c9effe9312 FREESCAPE: start in area 1 when using 3dck games
c4e0484271 FREESCAPE: fixed parsing of global bytecode table
eedc9f213b FREESCAPE: refactored bit operations and removed unused code
2500e58597 FREESCAPE: fixed entrance angle when changing areas
5d2b569d12 FREESCAPE: correct viewport for driller
78b2ea28cf FREESCAPE: fixed code style
1f55d4b03d FREESCAPE: added fly mode and improved entrance handling
30351a2c67 FREESCAPE: basic implementation of swapjet opcode
78eeb68cc5 FREESCAPE: added basic debug levels
b62fcf64ac FREESCAPE: correctly registred debug levels
4806895eea FREESCAPE: basic save/load implementation without level state
291c5465cf FREESCAPE: initial implementation of loading of level state
11b6700f87 FREESCAPE: removed use of pointer and renamed area map
13631f3770 FREESCAPE: save and restore level flags
91c0529a85 FREESCAPE: improved check collision detection
1984138437 FREESCAPE: correctly allocate an speaker audio object for each sound
9d566d20d8 FREESCAPE: save and restore vehicle information
7dcd4b2be6 FREESCAPE: execute room/global conditions
0864babe56 FREESCAPE: refector code that executes object/room/global conditions
32cba24397 FREESCAPE: better transition between levels
67249c9c85 FREESCAPE: implemented additional opcode for driller
999c7785b6 FREESCAPE: removed useless assert
095709ac45 FREESCAPE: added basic implementation of room structure for eclipse and castle
16fcdfb27e FREESCAPE: implement some area flags
a8ad0f7b93 FREESCAPE: move palettes to another file
2bf32efe82 FREESCAPE: refactored palette code
191a7ce2cb FREESCAPE: improved palette for total eclipse and added some fixes
b863506abc FREESCAPE: if an object is destroyed, restore it while loading
b7ba3d2049 FREESCAPE: implement border and view port for driller and eclipse
6d41bc9829 FREESCAPE: improved destroy opcode implementation
9cd387cff9 FREESCAPE: improved player size for driller and eclipse
453e713200 FREESCAPE: improved game selection
78d247ea71 FREESCAPE: read gas pockets and allow driller deployment
96ab09bced FREESCAPE: parse area names for driller and dark
f118754db9 FREESCAPE: parse area names for eclipse
4aa4667a34 FREESCAPE: only allow to add drill in driller
ab155f3c09 FREESCAPE: removed old code
347f1a857c FREESCAPE: removed old code
44de3eebd3 FREESCAPE: removed more old code
62eeb5121f FREESCAPE: removed more old code
71257b980b FREESCAPE: make sure line bounding boxes are valid
90c3ff28a6 FREESCAPE: corrected IFINVISQ opcode implementation
f668a6e6a1 FREESCAPE: improved detection of castle
1758d54909 FREESCAPE: loading of castle from dos release
c90d2620ba FREESCAPE: parse more fcd opcodes
98352edc3b FREESCAPE: improved parsing of fcd opcodes
8cf72c7e5c FREESCAPE: correctly parse sky and ground color
45ba823fc9 FREESCAPE: correctly set keys for driller and implement basic adding/removing of drill
a6532770de FREESCAPE: only allow to drill when radious is positive
82ac1f6f41 FREESCAPE: increase variable 32 when drilling
59146c1667 FREESCAPE: added detection of another release of castle
2bbb638f37 FREESCAPE: allow save and load drill position
907dae22be FREESCAPE: add drill at the correct y position
22395f0300 FREESCAPE: added new licenses and cleaned up includes
5115cc1f68 FREESCAPE: allow to rise or lower player height in driller
a42b93078e FREESCAPE: fix mouselook in fullscreen
6e04dc224e FREESCAPE: correctly render up-pyramids
a06b72736e FREESCAPE: correctly initialize flags for sensors/entrance
da79f0f685 FREESCAPE: add room structure after all the areas are parsed
43e4a62dea FREESCAPE: skip intro screen when loading
d4e26ef512 FREESCAPE: fixed most of the c++ compiler warnings
d27837140d FREESCAPE: handle some of the special eclipse entrances
a0b69a148e FREESCAPE: implemented shield and energy UI in driller
4c7d22874b FREESCAPE: check if is energy is enough to deploy/return drill
72331e5e36 FREESCAPE: improved ui given the current viewport
1f212caa92 FREESCAPE: improved ui given the current viewport
c89a48d327 FREESCAPE: splited driller into a separated class
d7adf4a620 FREESCAPE: splited eclipse into a separated class
78e61e6985 FREESCAPE: load assets code for driller and eclipse in different files
174a773802 FREESCAPE: splited castle into a separated class
59882c7434 FREESCAPE: splited dark into a separated class
b86e4ccbd6 FREESCAPE: removed specific code from common class
9a7692c97b FREESCAPE: splited dark into a separated class
95b3be0ad6 FREESCAPE: moved ui code from driller into a separated class
be64f76e9e FREESCAPE: moved key processing code from driller into a separated class
c567f890b5 FREESCAPE: moved game init code from driller into a separated class
3f4c5c92e9 FREESCAPE: moved palettes.cpp into the games directory
0050f7a5b7 FREESCAPE: moved more specific code into the game classess
c2869480bc FREESCAPE: load an object from the global area if it is not available in the current one
dd5866e769 FREESCAPE: load an object from the global area if it is not available in the current one
40cca49db2 FREESCAPE: use area scale when stepping foward
64c2933027 FREESCAPE: show NOPs in bytecode
ff32048a02 FREESCAPE: improved how drill is positioned by the player
d6041b940c FREESCAPE: refactored code that adds the drill
6f9c009115 FREESCAPE: renamed object fields
ecc422537a FREESCAPE: renamed object fields
ac8d79f1c4 FREESCAPE: partially aligned dril elements
0ed1d90834 FREESCAPE: correctly save and restore global objects
de8fa81bcf FREESCAPE: use deg2rad in updateProjectionMatrix
1bebf5b578 FREESCAPE: added some code to end the game is shield is zero
5365e9bcd6 FREESCAPE: font loading in driller
39d068e8ce FREESCAPE: message loading and rendering in driller
e4e06ab948 FREESCAPE: refactored checkIfGameEnded for driller
855fe6dec8 FREESCAPE: basic font rendering for eclipse
2d637044e9 FREESCAPE: show score for driller and eclipse
b9ebb7970b FREESCAPE: show position in driller ui
ad6cbcca05 FREESCAPE: specialized gotoArea function for driller and eclipse
9e1afc82d0 FREESCAPE: print text instruction for eclipse
f66b8b90c7 FREESCAPE: added freescape.dat to dists
09885b6a05 FREESCAPE: load border bmps from data bundle
59a033a974 FREESCAPE: initial prove and jet energy/shield in driller
a2dce1f7bf FREESCAPE: improved handling of the palette used for the ega games
3aceefa5af FREESCAPE: renamed and moved findColor
50e1e7e3f4 FREESCAPE: refactored area constructor
3588fe7e8a FREESCAPE: removed getFontCharacterRect function
6eeb8a371d FREESCAPE: initial refact of palette and color map code
4c2293f25d FREESCAPE: initial implementation of freescape sounds using pc speaker
75c4e8fdfc FREESCAPE: initial implementation of freescape sounds using prerecorded wavs
96b54016e9 FREESCAPE: improved rendering of ui
4801685bb0 FREESCAPE: avoid crashing with unknown sounds
fd03e9e127 FREESCAPE: fixed in handling certain opcodes
5bba4ab46b FREESCAPE: moved color remapping inside gfx
ff9b083593 FREESCAPE: improved pyramid rendering
a3c3bb2a65 FREESCAPE: improved pyramid rendering
2e414c5071 FREESCAPE: removed _missingColor variable from gfx class
4e5aca393e FREESCAPE: correclty load area in eclipse
7d08f4249b FREESCAPE: force a screen update when executing a redraw opcode
085af6ef83 FREESCAPE: inverted ifrvis and ifrinvis opcodes
f1cecfabc8 FREESCAPE: relocated movement functions into a separated file
9e68f6fe1f FREESCAPE: improved detection collision in driller
0f8a55e256 FREESCAPE: added missing space when printing bytecode
f5b7b34e91 FREESCAPE: added more code to replicate sounds
e35d0aec9e FREESCAPE: avoid crashing when an object is not found in the current/global area
3d08b94f57 FREESCAPE: refactor area/global condition execution
d15ed5bd0c FREESCAPE: added border for dark in ega mode
d8f1c3d0cb FREESCAPE: basic ui for dark in ega mode
03f0298e99 FREESCAPE: improved handling of rise/fall for all the games
1a02e483ac FREESCAPE: show height level in the driller ui
60ad427d29 FREESCAPE: palette fixes for rendering sky
0388784ae8 FREESCAPE: added special case to convert rectangles that are really lines
8777a3c9db FREESCAPE: refactor sky drawing for each game
560a3e85a4 FREESCAPE: specialized gotoArea function for castle
9cf282a514 FREESCAPE: fixes in the position
e108873791 FREESCAPE: adjusted collision detection using last position
de83f3a1e8 FREESCAPE: no drilling in fly mode
ec7375cb5e FREESCAPE: show proper messages related with drilling in driller
756c4d3b03 FREESCAPE: moved some driller specific code outside the area class
4e2dbd51f3 FREESCAPE: fixed initial rotation when traversing entrances
b30eb9e04c FREESCAPE: removed driller specific code from area class
d7c076fb53 FREESCAPE: recompute bounding box when an object is moved
6a9afc56fe FREESCAPE: avoid crashing with an unknown sound
77f21d24e1 FREESCAPE: added no clip cheat using N key
698b7ea4a0 FREESCAPE: entrance fixes for eclipse
fdd5e1f0fe FREESCAPE: replace some debug by debugC calls
37aa8924aa FREESCAPE: replace some debug by debugC calls
003cb43efd FREESCAPE: fixed compiler warnings
4aec147f97 FREESCAPE: improved handling of sync/async sounds
2e51636088 FREESCAPE: refactored and added some code to parse data from the amiga releases
9ba81add8c FREESCAPE: refactored and added some code to parse data from the amiga releases
6e109d6b94 FREESCAPE: refactored some game-specific code
c47aaa866a FREESCAPE: refactored some game-specific code
9846e162f9 FREESCAPE: disable execution of local/global condition for castle
96fbece4ea FREESCAPE: refactored asset loading code for castle
5333d4ee8f FREESCAPE: fixed texture memory leak
9db5a84d4d FREESCAPE: implemented isDemo
bccbaee3b7 FREESCAPE: allow to load driller data from amiga
09cfcf3886 FREESCAPE: simplify loading of driller data in amiga
99d9c5f86d FREESCAPE: improved detection of driller data from amiga
8a73bb978e FREESCAPE: avoid crashing if fonts are not loaded
e46b050972 FREESCAPE: allow the TinyGL to render in different resolutions
b78ad84775 FREESCAPE: adding preliminary border for amiga release of driller
761497b7c1 FREESCAPE: correctly parse the palettes from amiga release of driller
b90b7f7b53 FREESCAPE: correctly parse the palettes and border from amiga demo of driller
c40875f974 FREESCAPE: correctly parse another amiga release from driller
814bec5fe5 FREESCAPE: initial support for reading and playing driller sounds from amiga releases
d5730209f8 FREESCAPE: initial support for driller demo from atari release
380fdb4a0c FREESCAPE: atari sounds are unimplemented yet
182f20dc3c FREESCAPE: correctly parse global conditions in amiga and atari
81e93cff37 FREESCAPE: neo image loader to parse images in driller for amiga and atari
6400b4d5b3 FREESCAPE: refactor code that load images for every game
550a82e62f FREESCAPE: implemented title display for some driller releases
00c44c4c85 FREESCAPE: refactored neochrome decoder to allow to read images without palettes
2699defeb7 FREESCAPE: parse strings in driller demos
854c904140 FREESCAPE: proof of concept of the upcoming demo mode for all the games
f5aba68844 FREESCAPE: sound fx for some releases of driller in amiga and atari
c0be129237 FREESCAPE: move shoot function to movement.cpp
b4bfb4bf7d FREESCAPE: removed debug calls and use debugging chanels instead
46608d037c FREESCAPE: rename palette function names
831bc9eb1f FREESCAPE: added some code to read demo tables
c08dde3996 FREESCAPE: added border image for space station oblivion and make sure it is loaded
3d620f9cf6 FREESCAPE: correctly draw the first frame without getting any input
75abc87a09 FREESCAPE: play restored music in driller, if it is available
0626f55090 FREESCAPE: bind keys for turn left/right and look up/down in driller
0fb16f16da FREESCAPE: improved demo replaying to decode all the presed keys in DOS
b620c2a407 FREESCAPE: move/shoot move first implementation
402ddc5d95 FREESCAPE: renamed Movement data type
c99e9c8bfb FREESCAPE: parse demo bytes in Amiga/AtariST
54399a3e37 FREESCAPE: enable mouse generation event in Amiga/AtariST demos
e1f07e3229 FREESCAPE: added key to turn 180 degrees
a58fcbc0b8 FREESCAPE: added variable rotation angles
2250833724 FREESCAPE: load sounds for driller atari st demo
7ac42e846d FREESCAPE: load replay demo for driller atari st demo
1dc00bf7d1 FREESCAPE: improved decodeAmigaAtariKey
8466ff5ad2 FREESCAPE: fixed override warnings
cb50cdc359 FREESCAPE: removed unused variables
b66fe39138 FREESCAPE: refactored GlobalStucture into a separated file
5df94787ea FREESCAPE: free memory of the border and title images
95630cc9d9 FREESCAPE: correctly deallocate hash tables and arrays in each areas
5df7776f37 FREESCAPE: correctly deallocate geometric objects and the data bundle
6c3dbcb183 FREESCAPE: correctly deallocate bitmap decoder after usage
5ed0c4a0cf FREESCAPE: avoid reallocing memory from colours and ordinates
f694efb7de FREESCAPE: deallocate duplicated font data
0e0026db5d FREESCAPE: properly initialize all the class variables
0340ce775f FREESCAPE: removed some debug statements
8c74b956ba FREESCAPE: removed 16bit game code until is ready
9680afd677 FREESCAPE: removed 16bit game detection code until the rest of engine is added
3e4b23f241 FREESCAPE: used clang-format to improve code formatting
e562c0ce5c FREESCAPE: removed useless comments in the tinygl renderer
637f22ed9b FREESCAPE: corrected farClipPlane value
a7ad8d87d5 FREESCAPE: removed old debug statements
ceb5aaa50d FREESCAPE: use platform enumerated type to implement the platform specific detection
fdce66ded0 FREESCAPE: Added some 3DCK games to the detection tables
632da50c02 FREESCAPE: Fixed curly bracket position in local structure definition
24c2a0b8d4 FREESCAPE: Avoid type conversion on float definitions
d1a22f76bf FREESCAPE: Simplify loops to use auto keywords
1717ef7c98 FREESCAPE: Simplify more loops to use auto keywords
a5220abe4f FREESCAPE: Removed unreachable line in processInput
1567b31443 FREESCAPE: Use ABS instead of abs
6792afe9b3 FREESCAPE: Removed old comments in headers
232be624d2 FREESCAPE: Moved include from gfx file to the specialized class
5f353076ac FREESCAPE: Avoid type conversion from int to float
cdbd58d6a6 FREESCAPE: Added the copyright year
c7f7382eea FREESCAPE: Removed full stop from the tooltip message
8a5dd8e6a4 FREESCAPE: Use better ADGF flags for each game
eaf69c7fee FREESCAPE: Use better ADGF flags for each game
8174cf7369 FREESCAPE: correctly open and close files when reading assets in driller
fe6fed03a3 FREESCAPE: correctly open and close files when reading assets in eclipse
2ddbb8c15d FREESCAPE: correctly open and close files when reading assets in dark
362338c624 FREESCAPE: correctly open and close files when reading assets in castle
b5c1a6ef46 FREESCAPE: removed redudant strings in the detection tables
882797ea17 FREESCAPE: use the RenderMode type instead of string to load game assets
64b575ea79 FREESCAPE: use the RenderMode type in gfx
5406ed5929 FREESCAPE: specify RGB colors with a portable function
4b79f528dd FREESCAPE: renamed variable names from Area class to follow code conventions
ae9f7d64d6 FREESCAPE: renamed variable names from Instruction class to follow code conventions
da4ac7f456 FREESCAPE: use uint for loop variables and avoid type conversion
aba5bac2ed FREESCAPE: renamed variable names from Object classes to follow code conventions
8c6ee3163e FREESCAPE: renamed variable names from Token class to follow code conventions
5af2aa097d FREESCAPE: renamed variable names from the Texture classes to follow code conventions
5e736da809 FREESCAPE: renamed ObjectType enum to follow code conventions
1c19a5d701 FREESCAPE: removed redudant enum
f8ad388573 FREESCAPE: improved demo decoding loop
81acd105c3 FREESCAPE: added proper comment next to each endif
3f56b2e009 FREESCAPE: added new line at the end of each file
2ea1b339ee FREESCAPE: use ADGF flags instead of strings
81717815f2 FREESCAPE: added POTFILES
76d1f26d6e FREESCAPE: simplify palette handling and allow to compile without TinyGL
d35cbc41cb FREESCAPE: removed pointers to strings to avoid memory leaks
8db4952775 FREESCAPE: use GUI::MessageDialog instead of error and return to launcher, when there are no available renderers
119d663943 FREESCAPE: sorted, removed and simplified a number of includes
679b0281a4 FREESCAPE: improved user message when a renderer cannot be created
2ac4af2347 FREESCAPE: improved comments on original code atribution
640687a8d0 FREESCAPE: added devtools/create_freescape directory with a script and data to create freescape.dat
63555f3f53 FREESCAPE: regenerate freescape.dat using dedicated script
57af8e2cc3 FREESCAPE: change API in detection class
3c6c95c7ec FREESCAPE: removed unused string field in token class
e847698122 FREESCAPE: avoid leaking memory when reading global area data
bbc6b8987a FREESCAPE: refactored large if into a switch when handling pressed keys
51fbc89b30 FREESCAPE: avoid use-after-free when deallocating global areas in eclipse and castle
a71ccf3019 FREESCAPE: parse each area name in castle
cb2d09b5b8 FREESCAPE: corrected the number of total areas in castle (thanks to @farmboy0)
e397eba42c FREESCAPE: added detection and preliminary code of driller release for AtariST
5aca1cda80 FREESCAPE: added detection for space station oblivion for AtariST (but unsupported)
ad9297eb8b FREESCAPE: first attempt to use DrawArray in TinyGL renderer
4c26d13dd5 FREESCAPE: rewrite renderCube to use renderFace
8abfc52836 FREESCAPE: rewrite drawFloor to use DrawArrays
42bc152f1a FREESCAPE: rewrite drawRect2D to use DrawArrays
5730f1106d FREESCAPE: moved common code for rendering to Renderer
bcedbac36a FREESCAPE: preliminar code for OpenGL renderer
28418d0def FREESCAPE: use TinyGL renderer by default
a816adcd36 FREESCAPE: improved OpenGL texture handling with preliminary code
1c12bb6040 FREESCAPE: define texture pixel format and convert images if necessary
a72378c35d FREESCAPE: enable arbitrary resolution for OpenGL renderer
46e135e9f1 FREESCAPE: recompute screen viewport on every EVENT_SCREEN_CHANGED
d2816b55c2 FREESCAPE: removed unused code in engines/freescape/gfx_opengl_texture.cpp
2efe162556 FREESCAPE: use inplace conversion for texture surface
791abdcb23 FREESCAPE: fixed incorrect parameters in drawTexturedRect2D (OpenGL renderer)
4a48c9929e FREESCAPE: forced a flush in drawTexturedRect2D (OpenGL renderer)
76c2799736 FREESCAPE: allow transparent pixels in drawTexturedRect2D (OpenGL renderer)
95c2ccaa4a FREESCAPE: reimplemented driller UI using only 2d surfaces
c5fc1cae3e FREESCAPE: removed drawRect2D function from renderer
1f3f7f4287 FREESCAPE: avoid blurry textures in OpenGL
dff5d76629 FREESCAPE: use wider lines when rendering shots and crossair in OpenGL
57b5af8cdf FREESCAPE: small fix in driller UI
43a694913d FREESCAPE: tweak polygon offset in OpenGL
8a81870cf1 FREESCAPE: removed unused global pointer to the engine
ec2d8fb67f FREESCAPE: reworded original copyright statement
b105f05a3d FREESCAPE: added missing EOL
c4f683d20a FREESCAPE: use texture format when building the eclipse UI
c20e5af8b8 FREESCAPE: simplify low-level byte operations
3fc21a8080 FREESCAPE: sorted filenames in module.mk
5d6e0edc5b FREESCAPE: Object is a header-only class
3450bb7474 FREESCAPE: Sensor is a header-only class
5d21f8b223 FREESCAPE: GlobalStructure is a header-only class
d135f25e7e FREESCAPE: removed FrameLimiter class
9002723d73 FREESCAPE: make sure the border surface is always correctly used in driller
ec31a66b2a FREESCAPE: make sure the border surface is always correctly used in dark
1210c6ff85 FREESCAPE: removed redudant pointer to OSystem
401ebf9c26 FREESCAPE: added missing headers to the renderers implementations
5b335031a5 FREESCAPE: reimplemented playMusic using Audio::SeekableAudioStream::openStreamFile
cdeec2977a FREESCAPE: moved NeoDecoder into the Freescape namespace
6a1dc05132 FREESCAPE: check bounds in copyToVertexArray


Commit: 1458492a8225ef38a9d78e84c58ca6316a2bd687
    https://github.com/scummvm/scummvm/commit/1458492a8225ef38a9d78e84c58ca6316a2bd687
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:33+01:00

Commit Message:
FREESCAPE: added initial files

Changed paths:
  A engines/freescape/configure.engine
  A engines/freescape/detection.cpp
  A engines/freescape/freescape.cpp
  A engines/freescape/freescape.h
  A engines/freescape/metaengine.cpp
  A engines/freescape/module.mk


diff --git a/engines/freescape/configure.engine b/engines/freescape/configure.engine
new file mode 100644
index 00000000000..757ed0bc680
--- /dev/null
+++ b/engines/freescape/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine freescape "Freescape" no
diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
new file mode 100644
index 00000000000..b6e6701b10a
--- /dev/null
+++ b/engines/freescape/detection.cpp
@@ -0,0 +1,44 @@
+#include "base/plugins.h"
+#include "engines/advancedDetector.h"
+
+namespace Freescape {
+static const PlainGameDescriptor freescapeGames[] = {
+	{ "3dkitgame", "Quux the Example Module" },
+	{ "quuxcd", "Quux the Example Module (CD version)" },
+	{ 0, 0 }
+};
+
+
+static const ADGameDescription gameDescriptions[] = {
+	{
+		"3Dkitgame",
+		0,
+		AD_ENTRY1s("3DKIT.RUN", "f35147729a2f5b6852a504223aeb6a57", 112158),
+		Common::EN_ANY,
+		Common::kPlatformDOS,
+		ADGF_NO_FLAGS,
+		GUIO1(GUIO_NOMIDI)
+	},
+	AD_TABLE_END_MARKER
+};
+} // End of namespace Freescape
+
+class FreescapeMetaEngineDetection : public AdvancedMetaEngineDetection {
+public:
+	FreescapeMetaEngineDetection() : AdvancedMetaEngineDetection(Freescape::gameDescriptions, sizeof(ADGameDescription), Freescape::freescapeGames) {
+	}	
+
+	const char *getEngineId() const override {
+		return "freescape";
+	}
+
+	const char *getName() const override {
+		return "Freescape";
+	}
+
+	const char *getOriginalCopyright() const override {
+		return "Copyright (C) TODO Entertainment Ltd.";
+	}
+};
+
+REGISTER_PLUGIN_STATIC(FREESCAPE_DETECTION, PLUGIN_TYPE_ENGINE_DETECTION, FreescapeMetaEngineDetection);
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
new file mode 100644
index 00000000000..68d6b6fa517
--- /dev/null
+++ b/engines/freescape/freescape.cpp
@@ -0,0 +1,162 @@
+#include "common/scummsys.h"
+
+#include "common/config-manager.h"
+#include "common/debug.h"
+#include "common/debug-channels.h"
+#include "common/error.h"
+#include "common/events.h"
+#include "common/file.h"
+#include "common/fs.h"
+#include "common/system.h"
+
+#include "engines/util.h"
+
+#include "freescape/freescape.h"
+
+namespace Freescape {
+
+FreescapeEngine::FreescapeEngine(OSystem *syst)
+	: Engine(syst) {
+	// Put your engine in a sane state, but do nothing big yet;
+	// in particular, do not load data from files; rather, if you
+	// need to do such things, do them from run().
+
+	// Do not initialize graphics here
+	// Do not initialize audio devices here
+
+	// However this is the place to specify all default directories
+	const Common::FSNode gameDataDir(ConfMan.get("path"));
+	SearchMan.addSubDirectoryMatching(gameDataDir, "sound");
+
+	// Here is the right place to set up the engine specific debug channels
+	DebugMan.addDebugChannel(kQuuxDebugExample, "example", "this is just an example for a engine specific debug channel");
+	DebugMan.addDebugChannel(kQuuxDebugExample2, "example2", "also an example");
+
+	// Don't forget to register your random source
+	_rnd = new Common::RandomSource("freescape");
+
+	debug("FreescapeEngine::FreescapeEngine");
+}
+
+FreescapeEngine::~FreescapeEngine() {
+	debug("QuuxEngine::~QuuxEngine");
+
+	// Dispose your resources here
+	delete _rnd;
+
+	// Remove all of our debug levels here
+	DebugMan.clearAllDebugChannels();
+}
+
+Common::Error FreescapeEngine::run() {
+	// Initialize graphics using following:
+	initGraphics(320, 200);
+
+	// You could use backend transactions directly as an alternative,
+	// but it isn't recommended, until you want to handle the error values
+	// from OSystem::endGFXTransaction yourself.
+	// This is just an example template:
+	//_system->beginGFXTransaction();
+	//	// This setup the graphics mode according to users seetings
+	//	initCommonGFX(false);
+	//
+	//	// Specify dimensions of game graphics window.
+	//	// In this example: 320x200
+	//	_system->initSize(320, 200);
+	//FIXME: You really want to handle
+	//OSystem::kTransactionSizeChangeFailed here
+	//_system->endGFXTransaction();
+
+    Common::File *file = new Common::File();
+
+    if (!file->open("3DKIT.RUN")) {
+        delete file;
+    	return Common::kNoError;
+    }
+
+	const int32 fileSize = file->size();
+	byte *buf = (byte *)malloc(fileSize);
+	file->read(buf, fileSize);
+
+	int i = 0;
+	int j = 0;
+	byte *p = buf;
+
+	_pixelFormat = g_system->getScreenFormat();
+	//if (_pixelFormat == Graphics::PixelFormat::createFormatCLUT8())
+	//	return Common::kUnsupportedColorMode;
+
+	//changeCursor("default");
+	//_compositeSurface = new Graphics::Surface();
+	//_compositeSurface->create(300, 200, _pixelFormat);
+    static const byte PALETTE[16][3] = {
+                { 0, 0, 0 },{ 0x00, 0x00, 0x80 },{ 0x00, 0x80, 0x00 },{ 0x00, 0x80, 0x80 },
+                { 0x80, 0x00, 0x00 },{ 0x80, 0x00, 0x80 },{ 0x80, 0x80, 0x00 },{ 0xC0, 0xC0, 0xC0 },
+                { 0x80, 0x80, 0x80 },{ 0x00, 0x00, 0xFF },{ 0x00, 0xFF, 0x00 },{ 0x00, 0xFF, 0xFF },
+                { 0xFF, 0x40, 0x40 },{ 0xFF, 0x00, 0xFF },{ 0xFF, 0xFF, 0x00 },{ 0xFF, 0xFF, 0xFF }
+    };
+    g_system->getPaletteManager()->setPalette(&PALETTE[0][0], 0, 16);
+
+
+	while(i < fileSize-4) {
+		if(*((uint32*) p) == 0xfa002445) {
+			debug("found at %d", i);
+			g_system->copyRectToScreen((const void*) p, 320, 0, 0, 320, 200);
+		}
+		p++;
+		i++;
+
+	}
+
+	// Create debugger console. It requires GFX to be initialized
+	Console *console = new Console(this);
+	setDebugger(console);
+
+	// Additional setup.
+	debug("QuuxEngine::init");
+
+	// Your main even loop should be (invoked from) here.
+	debug("QuuxEngine::go: Hello, World!");
+
+	// This test will show up if -d1 and --debugflags=example are specified on the commandline
+	debugC(1, kQuuxDebugExample, "Example debug call");
+
+	// This test will show up if --debugflags=example or --debugflags=example2 or both of them and -d3 are specified on the commandline
+	debugC(3, kQuuxDebugExample | kQuuxDebugExample2, "Example debug call two");
+
+	// Simple main event loop
+	Common::Event evt;
+	while (!shouldQuit()) {
+		g_system->getEventManager()->pollEvent(evt);
+		g_system->delayMillis(10);
+	}
+
+	return Common::kNoError;
+}
+
+bool FreescapeEngine::hasFeature(EngineFeature f) const {
+	return
+		(f == kSupportsReturnToLauncher) ||
+		(f == kSupportsLoadingDuringRuntime) ||
+		(f == kSupportsSavingDuringRuntime);
+}
+
+Common::Error FreescapeEngine::loadGameStream(Common::SeekableReadStream *stream) {
+	Common::Serializer s(stream, nullptr);
+	syncGameStream(s);
+	return Common::kNoError;
+}
+
+Common::Error FreescapeEngine::saveGameStream(Common::WriteStream *stream, bool isAutosave) {
+	Common::Serializer s(nullptr, stream);
+	syncGameStream(s);
+	return Common::kNoError;
+}
+
+void FreescapeEngine::syncGameStream(Common::Serializer &s) {
+	// Use methods of Serializer to save/load fields
+	int dummy = 0;
+	s.syncAsUint16LE(dummy);
+}
+
+} // End of namespace Quux
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
new file mode 100644
index 00000000000..c52d7d20481
--- /dev/null
+++ b/engines/freescape/freescape.h
@@ -0,0 +1,54 @@
+#ifndef FREESCAPE_H
+#define FREESCAPE_H
+
+#include "common/random.h"
+#include "common/serializer.h"
+#include "engines/engine.h"
+#include "gui/debugger.h"
+#include "graphics/surface.h"
+#include "graphics/palette.h"
+
+namespace Freescape {
+
+class Console;
+
+// our engine debug channels
+enum {
+	kQuuxDebugExample = 1 << 0,
+	kQuuxDebugExample2 = 1 << 1
+	// next new channel must be 1 << 2 (4)
+	// the current limitation is 32 debug channels (1 << 31 is the last one)
+};
+
+class FreescapeEngine : public Engine {
+private:
+	// We need random numbers
+	Common::RandomSource *_rnd;
+	Graphics::PixelFormat _pixelFormat;
+public:
+	FreescapeEngine(OSystem *syst);
+	~FreescapeEngine();
+
+	Graphics::Surface *_compositeSurface;
+
+	Common::Error run() override;
+	bool hasFeature(EngineFeature f) const override;
+	bool canLoadGameStateCurrently() override { return true; }
+	bool canSaveGameStateCurrently() override { return true; }
+	Common::Error loadGameStream(Common::SeekableReadStream *stream) override;
+	Common::Error saveGameStream(Common::WriteStream *stream, bool isAutosave = false) override;
+	void syncGameStream(Common::Serializer &s);
+};
+
+// Example console class
+class Console : public GUI::Debugger {
+public:
+	Console(FreescapeEngine *vm) {
+	}
+	virtual ~Console(void) {
+	}
+};
+
+} // End of namespace Quux
+
+#endif
diff --git a/engines/freescape/metaengine.cpp b/engines/freescape/metaengine.cpp
new file mode 100644
index 00000000000..821b7448c50
--- /dev/null
+++ b/engines/freescape/metaengine.cpp
@@ -0,0 +1,22 @@
+#include "freescape/freescape.h"
+#include "engines/advancedDetector.h"
+
+class FreescapeMetaEngine : public AdvancedMetaEngine {
+public:
+	const char *getName() const override {
+		return "freescape";
+	}
+
+	Common::Error createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override;
+};
+
+Common::Error FreescapeMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
+	*engine = new Freescape::FreescapeEngine(syst);
+	return Common::kNoError;
+}
+
+#if PLUGIN_ENABLED_DYNAMIC(FREESCAPE)
+REGISTER_PLUGIN_DYNAMIC(FREESCAPE, PLUGIN_TYPE_ENGINE, FreescapeMetaEngine);
+#else
+REGISTER_PLUGIN_STATIC(FREESCAPE, PLUGIN_TYPE_ENGINE, FreescapeMetaEngine);
+#endif
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
new file mode 100644
index 00000000000..25d4853c9b8
--- /dev/null
+++ b/engines/freescape/module.mk
@@ -0,0 +1,19 @@
+MODULE := engines/freescape
+ 
+MODULE_OBJS := \
+	metaengine.o \
+	freescape.o
+ 
+MODULE_DIRS += \
+	engines/freescape
+ 
+# This module can be built as a plugin
+ifeq ($(ENABLE_FREESCAPE), DYNAMIC_PLUGIN)
+PLUGIN := 1
+endif
+ 
+# Include common rules 
+include $(srcdir)/rules.mk
+
+# Detection objects
+DETECT_OBJS += $(MODULE)/detection.o


Commit: de83c18416a40f465c49827890a078b47d44f756
    https://github.com/scummvm/scummvm/commit/de83c18416a40f465c49827890a078b47d44f756
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:33+01:00

Commit Message:
FREESCAPE: initial fixes

Changed paths:
    engines/freescape/detection.cpp
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index b6e6701b10a..e99614b424d 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -3,15 +3,13 @@
 
 namespace Freescape {
 static const PlainGameDescriptor freescapeGames[] = {
-	{ "3dkitgame", "Quux the Example Module" },
-	{ "quuxcd", "Quux the Example Module (CD version)" },
+	{ "3dkit", "3D Kit Constructor example game" },
 	{ 0, 0 }
 };
 
-
 static const ADGameDescription gameDescriptions[] = {
 	{
-		"3Dkitgame",
+		"3Dkit",
 		0,
 		AD_ENTRY1s("3DKIT.RUN", "f35147729a2f5b6852a504223aeb6a57", 112158),
 		Common::EN_ANY,
@@ -37,7 +35,7 @@ public:
 	}
 
 	const char *getOriginalCopyright() const override {
-		return "Copyright (C) TODO Entertainment Ltd.";
+		return "Copyright (C) Incentive Software";
 	}
 };
 
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 68d6b6fa517..c3df04e4d17 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -78,17 +78,8 @@ Common::Error FreescapeEngine::run() {
 	byte *buf = (byte *)malloc(fileSize);
 	file->read(buf, fileSize);
 
-	int i = 0;
-	int j = 0;
-	byte *p = buf;
-
 	_pixelFormat = g_system->getScreenFormat();
-	//if (_pixelFormat == Graphics::PixelFormat::createFormatCLUT8())
-	//	return Common::kUnsupportedColorMode;
-
-	//changeCursor("default");
-	//_compositeSurface = new Graphics::Surface();
-	//_compositeSurface->create(300, 200, _pixelFormat);
+	// 16 colors palette from ultima
     static const byte PALETTE[16][3] = {
                 { 0, 0, 0 },{ 0x00, 0x00, 0x80 },{ 0x00, 0x80, 0x00 },{ 0x00, 0x80, 0x80 },
                 { 0x80, 0x00, 0x00 },{ 0x80, 0x00, 0x80 },{ 0x80, 0x80, 0x00 },{ 0xC0, 0xC0, 0xC0 },
@@ -97,10 +88,12 @@ Common::Error FreescapeEngine::run() {
     };
     g_system->getPaletteManager()->setPalette(&PALETTE[0][0], 0, 16);
 
+	int i = 0;
+	byte *p = buf;
 
 	while(i < fileSize-4) {
 		if(*((uint32*) p) == 0xfa002445) {
-			debug("found at %d", i);
+			debug("Border found at %x", i);
 			g_system->copyRectToScreen((const void*) p, 320, 0, 0, 320, 200);
 		}
 		p++;
@@ -112,17 +105,7 @@ Common::Error FreescapeEngine::run() {
 	Console *console = new Console(this);
 	setDebugger(console);
 
-	// Additional setup.
-	debug("QuuxEngine::init");
-
-	// Your main even loop should be (invoked from) here.
-	debug("QuuxEngine::go: Hello, World!");
-
-	// This test will show up if -d1 and --debugflags=example are specified on the commandline
-	debugC(1, kQuuxDebugExample, "Example debug call");
-
-	// This test will show up if --debugflags=example or --debugflags=example2 or both of them and -d3 are specified on the commandline
-	debugC(3, kQuuxDebugExample | kQuuxDebugExample2, "Example debug call two");
+	debug("FreescapeEngine::init");
 
 	// Simple main event loop
 	Common::Event evt;


Commit: 3e414ba6b1a71290a1539fa16fa5afee4b9a2acf
    https://github.com/scummvm/scummvm/commit/3e414ba6b1a71290a1539fa16fa5afee4b9a2acf
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:33+01:00

Commit Message:
FREESCAPE: first attempt to merge phantasma code

Changed paths:
  A engines/freescape/area.cpp
  A engines/freescape/area.h
  A engines/freescape/game.cpp
  A engines/freescape/game.h
  A engines/freescape/gamestate.h
  A engines/freescape/language/16bitDetokeniser.cpp
  A engines/freescape/language/16bitDetokeniser.h
  A engines/freescape/language/instruction.h
  A engines/freescape/language/token.h
  A engines/freescape/loaders/16bitBinaryLoader.cpp
  A engines/freescape/loaders/16bitBinaryLoader.h
  A engines/freescape/objects/geometricobject.cpp
  A engines/freescape/objects/geometricobject.h
  A engines/freescape/objects/object.cpp
  A engines/freescape/objects/object.h
    engines/freescape/freescape.cpp
    engines/freescape/module.mk


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
new file mode 100644
index 00000000000..1b79c741312
--- /dev/null
+++ b/engines/freescape/area.cpp
@@ -0,0 +1,99 @@
+//
+//  Area.cpp
+//  Phantasma
+//
+//  Created by Thomas Harte on 25/12/2013.
+//  Copyright (c) 2013 Thomas Harte. All rights reserved.
+//
+
+#include "common/algorithm.h"
+#include "freescape/area.h"
+#include "freescape/objects/object.h"
+
+Object *Area::objectWithIDFromMap(ObjectMap *map, uint16 objectID)
+{
+	if(!map) return nullptr;
+	//TODO //if(!map->count(objectID)) return nullptr;
+	return (*map)[objectID];
+}
+
+Object *Area::objectWithID(uint16 objectID)
+{
+	return objectWithIDFromMap(objectsByID, objectID);
+}
+
+Object *Area::entranceWithID(uint16 objectID)
+{
+	return objectWithIDFromMap(entrancesByID, objectID);
+}
+
+uint16 Area::getAreaID()
+{
+	return areaID;
+}
+
+Area::Area(
+	uint16 _areaID,
+	ObjectMap *_objectsByID,
+	ObjectMap *_entrancesByID)
+{
+	areaID = _areaID;
+	objectsByID = _objectsByID;
+	entrancesByID = _entrancesByID;
+	vertexBuffer = nullptr;
+	drawElementsBuffer = nullptr;
+
+	// create a list of drawable objects only
+	for(ObjectMap::iterator iterator = objectsByID->begin(); iterator != objectsByID->end(); iterator++)
+	{
+		if(iterator->_value->isDrawable())
+		{
+			drawableObjects.push_back(iterator->_value);
+		}
+	}
+
+	// sort so that those that are planar are drawn last
+	struct
+	{
+		bool operator() (Object *object1, Object *object2)
+		{
+			if(!object1->isPlanar() && object2->isPlanar()) return true;
+			if(object1->isPlanar() && !object2->isPlanar()) return false;
+			return object1->getObjectID() < object2->getObjectID();
+		};
+	} compareObjects;
+	
+	Common::sort(drawableObjects.begin(), drawableObjects.end(), compareObjects);
+}
+
+Area::~Area()
+{
+	for(ObjectMap::iterator iterator = entrancesByID->begin(); iterator != entrancesByID->end(); iterator++)
+		delete iterator->_value;
+
+	for(ObjectMap::iterator iterator = objectsByID->begin(); iterator != objectsByID->end(); iterator++)
+		delete iterator->_value;
+
+	delete entrancesByID;
+	delete objectsByID;
+}
+
+/*void Area::setupOpenGL()
+{
+	delete vertexBuffer;
+	vertexBuffer = GeometricObject::newVertexBuffer();
+
+	delete drawElementsBuffer;
+	drawElementsBuffer = GeometricObject::newDrawElementsBuffer();
+
+	for(std::vector<Object *>::iterator iterator = drawableObjects.begin(); iterator != drawableObjects.end(); iterator++)
+		(*iterator)->setupOpenGL(vertexBuffer, drawElementsBuffer);
+}
+
+void Area::draw(bool allowPolygonOffset, BatchDrawer *batchDrawer)
+{
+	for(std::vector<Object *>::iterator iterator = drawableObjects.begin(); iterator != drawableObjects.end(); iterator++)
+	{
+		(*iterator)->draw(vertexBuffer, drawElementsBuffer, batchDrawer, allowPolygonOffset);
+	}
+}*/
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
new file mode 100644
index 00000000000..c8a971366f3
--- /dev/null
+++ b/engines/freescape/area.h
@@ -0,0 +1,48 @@
+//
+//  Area.h
+//  Phantasma
+//
+//  Created by Thomas Harte on 25/12/2013.
+//  Copyright (c) 2013 Thomas Harte. All rights reserved.
+//
+
+#ifndef __Phantasma__Area__
+#define __Phantasma__Area__
+
+#include "common/hashmap.h"
+#include "freescape/objects/object.h"
+//#include "VertexBuffer.h"
+//#include "DrawElementsBuffer.h"
+
+typedef Common::HashMap<uint16, Object *> ObjectMap;
+
+class BatchDrawer;
+class Area
+{
+	public:
+		Area(
+			uint16 areaID,
+			ObjectMap *objectsByID,
+			ObjectMap *entrancesByID);
+		virtual ~Area();
+
+		Object *objectWithID(uint16 objectID);
+		Object *entranceWithID(uint16 objectID);
+		uint16 getAreaID();
+
+		//void setupOpenGL();
+		//void draw(bool allowPolygonOffset, BatchDrawer *batchDrawer);
+
+	private:
+		uint16 areaID;
+		ObjectMap *objectsByID;
+		ObjectMap *entrancesByID;
+		Common::Array<Object *> drawableObjects;
+
+		Object *objectWithIDFromMap(ObjectMap *map, uint16 objectID);
+
+		VertexBuffer *vertexBuffer;
+		DrawElementsBuffer *drawElementsBuffer;
+};
+
+#endif /* defined(__Phantasma__Area__) */
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index c3df04e4d17..2310243f86e 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -13,6 +13,13 @@
 
 #include "freescape/freescape.h"
 
+#include "freescape/loaders/16bitBinaryLoader.h"
+//#include "freescape/loaders/8bitBinaryLoader.h"
+
+#define OFFSET_DARKSIDE       0xc9ce
+#define OFFSET_DRILLER        0xcf3e
+#define OFFSET_TOTALECLIPSE   0xcdb7
+
 namespace Freescape {
 
 FreescapeEngine::FreescapeEngine(OSystem *syst)
@@ -67,6 +74,7 @@ Common::Error FreescapeEngine::run() {
 	//OSystem::kTransactionSizeChangeFailed here
 	//_system->endGFXTransaction();
 
+    Game *_game = load16bitBinary("3DKIT.RUN");
     Common::File *file = new Common::File();
 
     if (!file->open("3DKIT.RUN")) {
@@ -81,10 +89,10 @@ Common::Error FreescapeEngine::run() {
 	_pixelFormat = g_system->getScreenFormat();
 	// 16 colors palette from ultima
     static const byte PALETTE[16][3] = {
-                { 0, 0, 0 },{ 0x00, 0x00, 0x80 },{ 0x00, 0x80, 0x00 },{ 0x00, 0x80, 0x80 },
-                { 0x80, 0x00, 0x00 },{ 0x80, 0x00, 0x80 },{ 0x80, 0x80, 0x00 },{ 0xC0, 0xC0, 0xC0 },
-                { 0x80, 0x80, 0x80 },{ 0x00, 0x00, 0xFF },{ 0x00, 0xFF, 0x00 },{ 0x00, 0xFF, 0xFF },
-                { 0xFF, 0x40, 0x40 },{ 0xFF, 0x00, 0xFF },{ 0xFF, 0xFF, 0x00 },{ 0xFF, 0xFF, 0xFF }
+                { 0, 0, 0 },{ 0xe0, 0xc0, 0x70 },{ 0xb0, 0x80, 0x40 },{ 0x80, 0x60, 0x10 },
+                { 0x50, 0x30, 0x00 },{ 0x20, 0x80, 0xd0 },{ 0x20, 0x50, 0xb0 },{ 0x20, 0x30, 0x70 },
+                { 0x30, 0x40, 0x30 },{ 0x30, 0x30, 0x30 },{ 0x40, 0x40, 0x40 },{ 0x60, 0x60, 0x60 },
+                { 0x70, 0x70, 0x70 },{ 0x90, 0x90, 0x90 },{ 0xa0, 0xa0, 0xa0 },{ 0xc0, 0xc0, 0xc0 }
     };
     g_system->getPaletteManager()->setPalette(&PALETTE[0][0], 0, 16);
 
diff --git a/engines/freescape/game.cpp b/engines/freescape/game.cpp
new file mode 100644
index 00000000000..154779b0b5e
--- /dev/null
+++ b/engines/freescape/game.cpp
@@ -0,0 +1,140 @@
+//
+//  Game.cpp
+//  Phantasma
+//
+//  Created by Thomas Harte on 17/12/2013.
+//  Copyright (c) 2013 Thomas Harte. All rights reserved.
+//
+
+#include "freescape/game.h"
+//#include "GeometricObject.h"
+//#include "Matrix.h"
+//#include "VertexBuffer.h"
+
+Game::Game(AreaMap *_areasByAreaID)
+{
+	hasReceivedTime = false;
+	areasByAreaID = _areasByAreaID;
+
+	rotation[0] =
+	rotation[1] =
+	rotation[2] = 0.0f;
+
+	position[0] = 1000.0f;
+	position[1] = 300.0f;
+	position[2] = 1000.0f;
+
+	velocity[0] =
+	velocity[1] =
+	velocity[2] = 0.0f;
+}
+
+Game::~Game()
+{
+	delete areasByAreaID;
+}
+/*
+void Game::setAspectRatio(float aspectRatio)
+{
+	// create a projection matrix; the 16-bit kit permits the range 0-8192 to
+	// be used along all three axes and from that comes the far plane distance
+	// of 14189.
+	Matrix projectionMatrix = Matrix::projectionMatrix(60.0f, aspectRatio, 1.0f, 14189.0f);
+	GeometricObject::setProjectionMatrix(projectionMatrix.contents);
+}
+
+void Game::draw()
+{
+	// set the clear colour to salmon; we're not catching floor/ceiling
+	// colours yet
+	glClearColor(1.0f, 0.5f, 0.5f, 1.0f);
+
+	// clear depth and colour
+	glDepthMask(GL_TRUE);
+	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+	// establish the view matrix
+	GeometricObject::setViewMatrix((rotationMatrix * translationMatrix).contents);
+
+	// 4 is the rocket
+	const uint16_t areaNumber = 1;
+
+	// draw once to populate the z buffer without a polygon offset applied
+	glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+	glDisable(GL_POLYGON_OFFSET_FILL);
+	(*areasByAreaID)[areaNumber]->draw(false, &batchDrawer);
+	batchDrawer.flush();
+
+	// draw with a polygon offset, allowing only reading from the depth buffer —
+	// the overall objective here is to allow arbitrary coplanar rendering
+	glDepthMask(GL_FALSE);
+	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+	glEnable(GL_POLYGON_OFFSET_FILL);
+	(*areasByAreaID)[areaNumber]->draw(true, &batchDrawer);
+	batchDrawer.flush();
+}
+
+void Game::setupOpenGL()
+{
+	GeometricObject::setupOpenGL();
+
+	glEnable(GL_DEPTH_TEST);
+	glDepthFunc(GL_LEQUAL);
+	glLineWidth(4.0f);
+
+	for(AreaMap::iterator iterator = areasByAreaID->begin(); iterator != areasByAreaID->end(); iterator++)
+		iterator->second->setupOpenGL();
+}
+
+void Game::advanceToTime(uint32 millisecondsSinceArbitraryMoment)
+{
+	if(!hasReceivedTime)
+	{
+		timeOfLastTick = millisecondsSinceArbitraryMoment;
+		hasReceivedTime = true;
+		return;
+	}
+
+	// so how many milliseconds is that since we last paid attention?
+	uint32 timeDifference = millisecondsSinceArbitraryMoment - timeOfLastTick;
+
+	// TODO: player movement updates out here
+	float velocityMultiplier = (float)timeDifference;
+//	position[0] -= velocityMultiplier * (velocity[0] * rotationMatrix.contents[0] + velocity[2] * rotationMatrix.contents[2]);
+//	position[1] -= velocityMultiplier * velocity[1];
+//	position[2] -= velocityMultiplier * (velocity[0] * rotationMatrix.contents[8] + velocity[2] * rotationMatrix.contents[10]);
+
+	position[0] -= velocityMultiplier * (velocity[0] * rotationMatrix.contents[0] + velocity[1] * rotationMatrix.contents[1] + velocity[2] * rotationMatrix.contents[2]);
+	position[1] -= velocityMultiplier * (velocity[0] * rotationMatrix.contents[4] + velocity[1] * rotationMatrix.contents[5] + velocity[2] * rotationMatrix.contents[6]);
+	position[2] -= velocityMultiplier * (velocity[0] * rotationMatrix.contents[8] + velocity[1] * rotationMatrix.contents[9] + velocity[2] * rotationMatrix.contents[10]);
+
+	translationMatrix = Matrix::translationMatrix(-position[0], -position[1], -position[2]);
+
+	// we'll advance at 50hz, which makes for some easy integer arithmetic here
+	while(timeDifference > 20)
+	{
+		timeOfLastTick += 20;
+		timeDifference -= 20;
+
+		// TODO: in-game timed events here
+	}
+}*/
+
+/*void Game::rotateView(float x, float y, float z)
+{
+	rotation[0] -= x;
+	rotation[1] -= y;
+	rotation[2] -= z;
+
+	Matrix xRotationMatrix = Matrix::rotationMatrix(rotation[0], 1.0f, 0.0f, 0.0f);
+	Matrix yRotationMatrix = Matrix::rotationMatrix(rotation[1], 0.0f, 1.0f, 0.0f);
+	Matrix zRotationMatrix = Matrix::rotationMatrix(rotation[2], 0.0f, 0.0f, 1.0f);
+	rotationMatrix = zRotationMatrix * xRotationMatrix * yRotationMatrix;
+}*/
+
+/*void Game::setMovementVelocity(float x, float y, float z)
+{
+	velocity[0] = x;
+	velocity[1] = y;
+	velocity[2] = z;
+}*/
diff --git a/engines/freescape/game.h b/engines/freescape/game.h
new file mode 100644
index 00000000000..82e8a0ba971
--- /dev/null
+++ b/engines/freescape/game.h
@@ -0,0 +1,47 @@
+//
+//  Game.h
+//  Phantasma
+//
+//  Created by Thomas Harte on 17/12/2013.
+//  Copyright (c) 2013 Thomas Harte. All rights reserved.
+//
+
+#ifndef __Phantasma__Game__
+#define __Phantasma__Game__
+
+#include "common/hashmap.h"
+#include "freescape/area.h"
+//#include "Matrix.h"
+//#include "BatchDrawer.h"
+
+typedef Common::HashMap<uint16, Area*> AreaMap;
+class Game
+{
+	public:
+
+		Game(AreaMap *areasByAreaID);
+		virtual ~Game();
+
+		/*void setAspectRatio(float aspectRatio);
+		void draw();*/
+		//void advanceToTime(uint32 millisecondsSinceArbitraryMoment);
+
+		//void setupOpenGL();
+
+		//void rotateView(float x, float y, float z);
+		//void setMovementVelocity(float x, float y, float z);
+		
+	private:
+		uint32 timeOfLastTick;
+		bool hasReceivedTime;
+
+		AreaMap *areasByAreaID;
+
+		float rotation[3], velocity[3], position[3];
+		//Matrix rotationMatrix;
+		//Matrix translationMatrix;
+
+		//BatchDrawer batchDrawer;*/
+};
+
+#endif /* defined(__Phantasma__Game__) */
diff --git a/engines/freescape/gamestate.h b/engines/freescape/gamestate.h
new file mode 100644
index 00000000000..6ef51cce549
--- /dev/null
+++ b/engines/freescape/gamestate.h
@@ -0,0 +1,21 @@
+//
+//  GameState.h
+//  Phantasma
+//
+//  Created by Thomas Harte on 08/12/2013.
+//  Copyright (c) 2013 Thomas Harte. All rights reserved.
+//
+
+#ifndef __Phantasma__GameState__
+#define __Phantasma__GameState__
+
+//#include <iostream>
+
+class CGameState
+{
+	public:
+		int32_t getVariable(int32_t variableNumber);
+		bool getBit(int32_t bitNumber);
+};
+
+#endif /* defined(__Phantasma__GameState__) */
diff --git a/engines/freescape/language/16bitDetokeniser.cpp b/engines/freescape/language/16bitDetokeniser.cpp
new file mode 100644
index 00000000000..c54835c736b
--- /dev/null
+++ b/engines/freescape/language/16bitDetokeniser.cpp
@@ -0,0 +1,182 @@
+//
+//  16bitDetokeniser.cpp
+//  Phantasma
+//
+//  Created by Thomas Harte on 15/12/2013.
+//  Copyright (c) 2013 Thomas Harte. All rights reserved.
+//
+
+#include "16bitDetokeniser.h"
+
+Common::String *detokenise16bitCondition(Common::Array <uint8> &tokenisedCondition)
+{
+	Common::String detokenisedStream;
+	Common::Array <uint8>::size_type bytePointer = 0;
+	Common::Array <uint8>::size_type sizeOfTokenisedContent = tokenisedCondition.size();
+
+	while(bytePointer < sizeOfTokenisedContent-1)
+	{
+		// byte 1 = number of arguments, byte 2 = opcode
+		uint8 numberOfArguments	= tokenisedCondition[bytePointer];
+		uint8 opcode			= tokenisedCondition[bytePointer+1];
+		bytePointer += 2;
+
+		// make sure we have enough buffer left to read all the arguments
+		if(bytePointer + numberOfArguments*2 > sizeOfTokenisedContent) break;
+
+		// write out the operation
+		switch(opcode)
+		{
+			case 0x01:	detokenisedStream += "ACTIVATED? ";		break;
+			case 0x02:	detokenisedStream += "COLLIDED? ";		break;
+			case 0x03:	detokenisedStream += "SHOT? ";			break;
+			case 0x04:	detokenisedStream += "TIMER? ";			break;
+
+			case 0x10:	detokenisedStream += "SETVAR ";			break;
+			case 0x11:	detokenisedStream += "ADDVAR ";			break;
+			case 0x12:	detokenisedStream += "SUBVAR ";			break;
+
+			case 0x13:	detokenisedStream += "ANDV ";			break;
+			case 0x14:	detokenisedStream += "ORV ";			break;
+			case 0x15:	detokenisedStream += "NOTV ";			break;
+
+			case 0x16:	detokenisedStream += "VAR=? ";			break;
+			case 0x17:	detokenisedStream += "VAR>? ";			break;
+			case 0x18:	detokenisedStream += "VAR<? ";			break;
+
+			case 0x2f:	detokenisedStream += "DESTROYED? ";		break;
+
+			case 0x30:	detokenisedStream += "INVIS ";			break;
+			case 0x31:	detokenisedStream += "VIS ";			break;
+			case 0x32:	detokenisedStream += "TOGVIS ";			break;
+			case 0x33:	detokenisedStream += "DESTROY ";		break;
+
+			case 0x34:	detokenisedStream += "INVIS? ";			break;
+			case 0x35:	detokenisedStream += "VIS? ";			break;
+
+			case 0x36:	detokenisedStream += "MOVE ";			break;
+
+			case 0x37:	detokenisedStream += "GETXPOS ";		break;
+			case 0x38:	detokenisedStream += "GETYPOS ";		break;
+			case 0x39:	detokenisedStream += "GETZPOS ";		break;
+
+			case 0x3a:	detokenisedStream += "MOVETO ";			break;
+
+			case 0x40:	detokenisedStream += "IF ";				break;
+			case 0x41:	detokenisedStream += "THEN ";			break;
+			case 0x42:	detokenisedStream += "ELSE ";			break;
+			case 0x43:	detokenisedStream += "ENDIF ";			break;
+			case 0x44:	detokenisedStream += "AND ";			break;
+			case 0x45:	detokenisedStream += "OR ";				break;
+
+			case 0x50:	detokenisedStream += "STARTANIM ";		break;
+			case 0x51:	detokenisedStream += "STOPANIM ";		break;
+
+			case 0x52:	detokenisedStream += "START ";			break;
+			case 0x53:	detokenisedStream += "RESTART ";		break;
+
+			case 0x54:	detokenisedStream += "INCLUDE ";		break;
+
+			case 0x55:	detokenisedStream += "WAITTRIG ";		break;
+			case 0x56:	detokenisedStream += "TRIGANIM ";		break;
+			case 0x57:	detokenisedStream += "REMOVE ";			break;
+
+			case 0x60:	detokenisedStream += "LOOP ";			break;
+			case 0x61:	detokenisedStream += "AGAIN ";			break;
+
+			case 0x70:	detokenisedStream += "SOUND ";			break;
+			case 0x71:	detokenisedStream += "SYNCSND ";		break;
+
+			case 0x80:	detokenisedStream += "WAIT ";			break;
+			case 0x81:	detokenisedStream += "DELAY ";			break;
+
+			case 0x82:	detokenisedStream += "UPDATEI ";		break;
+			case 0x83:	detokenisedStream += "PRINT ";			break;
+			case 0x84:	detokenisedStream += "REDRAW ";			break;
+
+			case 0x85:	detokenisedStream += "MODE ";			break;
+			case 0x86:	detokenisedStream += "ENDGAME ";		break;
+
+			case 0x87:	detokenisedStream += "EXECUTE ";		break;
+			case 0x90:	detokenisedStream += "GOTO ";			break;
+
+			case 0xff:	detokenisedStream += "END ";			break;
+
+			default:
+				detokenisedStream += "<UNKNOWN 16 bit: ";
+				detokenisedStream += Common::String::format("%x", (int)opcode);
+				detokenisedStream += " > ";
+			break;
+		}
+
+		// PRINT is a special case, requiring us to grab a string,
+		// but everything else is uniform
+		if(numberOfArguments)
+		{
+			// arguments are enclosed in brackets
+			detokenisedStream += "(";
+
+			if(opcode == 0x83)
+			{
+				// the first argument is a string, which is encoded as
+				// a two-byte string length (in big endian form)
+				uint16 stringLength =
+					(uint16)(
+						(tokenisedCondition[bytePointer] << 8) |
+						tokenisedCondition[bytePointer+1]
+					);
+				bytePointer += 2;
+				numberOfArguments--;
+
+				detokenisedStream += "\"";
+				for(uint16 stringPosition = 0; stringPosition < stringLength; stringPosition++)
+				{
+					char nextChar = (char)tokenisedCondition[bytePointer + stringPosition];
+
+					// TODO: spot special characters here
+
+					if(nextChar)
+						detokenisedStream += nextChar;
+				}
+				detokenisedStream += "\"";
+				bytePointer += stringLength;
+
+				// strings are rounded up in length to the end
+				// of this two-byte quantity
+				if(stringLength&1) bytePointer++;
+				numberOfArguments -= (stringLength+1) >> 1;
+
+				// that should leave an argument, but you can't be too safe
+				if(numberOfArguments) detokenisedStream += ", ";
+			}
+
+			for(uint8 argumentNumber = 0; argumentNumber < numberOfArguments; argumentNumber++)
+			{
+				// each argument is encoded in two bytes...
+				uint8 indexHighByte		= tokenisedCondition[bytePointer];
+				uint8 indexLowByte		= tokenisedCondition[bytePointer+1];
+				bytePointer += 2;
+
+				// if the high bit of the first byte is clear then this
+				// argument is a constant; if it's set then this is a variable
+				if(indexHighByte&0x80) detokenisedStream += "V";
+				indexHighByte &= 0x7f;
+
+				// the second byte is either the constant or the index of
+				// the variable
+				detokenisedStream += Common::String::format("%d", (int)(indexLowByte | (indexHighByte << 8)));
+
+				// ... and arguments are separated by commas, of course
+				if(argumentNumber+1 < numberOfArguments)
+					detokenisedStream += ", ";
+			}
+
+			// add a closing bracket
+			detokenisedStream += ")";
+		}
+
+		detokenisedStream +=  "\n";
+	}
+
+	return (new Common::String(detokenisedStream));
+}
diff --git a/engines/freescape/language/16bitDetokeniser.h b/engines/freescape/language/16bitDetokeniser.h
new file mode 100644
index 00000000000..2a79b25bd89
--- /dev/null
+++ b/engines/freescape/language/16bitDetokeniser.h
@@ -0,0 +1,17 @@
+//
+//  16bitDetokeniser.h
+//  Phantasma
+//
+//  Created by Thomas Harte on 15/12/2013.
+//  Copyright (c) 2013 Thomas Harte. All rights reserved.
+//
+
+#ifndef __Phantasma___6bitDetokeniser__
+#define __Phantasma___6bitDetokeniser__
+
+#include "common/str.h"
+#include "common/array.h"
+
+Common::String *detokenise16bitCondition(Common::Array <uint8> &tokenisedCondition);
+
+#endif /* defined(__Phantasma___6bitDetokeniser__) */
diff --git a/engines/freescape/language/instruction.h b/engines/freescape/language/instruction.h
new file mode 100644
index 00000000000..0c2f4d17607
--- /dev/null
+++ b/engines/freescape/language/instruction.h
@@ -0,0 +1,53 @@
+//
+//  Instruction.h
+//  Phantasma
+//
+//  Created by Thomas Harte on 08/12/2013.
+//  Copyright (c) 2013 Thomas Harte. All rights reserved.
+//
+
+#ifndef __Phantasma__Instruction__
+#define __Phantasma__Instruction__
+
+#include "freescape/language/token.h"
+#include "common/array.h"
+
+class CGameState;
+
+class FCLInstruction;
+typedef Common::Array<FCLInstruction> *FCLInstructionVector;
+
+class FCLInstruction
+{
+	public:
+		FCLInstruction(Token::Type type);
+		FCLInstruction(const FCLInstruction &source);
+
+		void setArguments(Token &);
+		void setArguments(Token &, Token &);
+		void setArguments(Token &, Token &, Token &);
+
+		Token::Type getType();
+
+		void getValue(CGameState &, int32_t &);
+		void getValue(CGameState &, int32_t &, int32_t &);
+		void getValue(CGameState &, int32_t &, int32_t &, int32 &);
+
+		void setBranches(FCLInstructionVector thenBranch, FCLInstructionVector elseBranch);
+
+	private:
+		enum Token::Type type;
+
+		struct
+		{
+			Token source, destination, option;
+		} arguments;
+
+		struct
+		{
+			FCLInstructionVector thenInstructions, elseInstructions;
+		} conditional;
+};
+
+
+#endif /* defined(__Phantasma__Instruction__) */
diff --git a/engines/freescape/language/token.h b/engines/freescape/language/token.h
new file mode 100644
index 00000000000..9a0550836b1
--- /dev/null
+++ b/engines/freescape/language/token.h
@@ -0,0 +1,61 @@
+//
+//  Token.h
+//  Phantasma
+//
+//  Created by Thomas Harte on 08/12/2013.
+//  Copyright (c) 2013 Thomas Harte. All rights reserved.
+//
+
+#ifndef __Phantasma__Token__
+#define __Phantasma__Token__
+
+#include "common/str.h"
+
+#include "freescape/gamestate.h"
+
+struct Token
+{
+	public:
+		enum Type
+		{
+			ACTIVATEDQ, ADDVAR, AGAIN, AND, ANDV,
+			COLLIDEDQ,
+			DELAY, DESTROY, DESTROYEDQ,
+			ELSE, END, ENDGAME, ENDIF, EXECUTE,
+			GOTO,
+			IF, INVIS, INVISQ, INCLUDE,
+			LOOP,
+			MODE, MOVE, MOVETO,
+			NOTV,
+			OR, ORV,
+			GETXPOS, GETYPOS, GETZPOS, 
+			PRINT,
+			RESTART, REDRAW, REMOVE,
+			SOUND, SETVAR, SHOTQ, START, STARTANIM, STOPANIM, SUBVAR, SYNCSND,
+			THEN, TIMERQ, TOGVIS, TRIGANIM,
+			UPDATEI,
+			VAREQ, VARGQ, VARLQ, VISQ, VIS,
+			WAIT, WAITTRIG,
+			COMMA, OPENBRACKET, CLOSEBRACKET, CONSTANT, VARIABLE, STRINGLITERAL,
+			UNKNOWN, ENDOFFILE,
+			SETBIT, CLEARBIT, TOGGLEBIT, SWAPJET, BITNOTEQ, VARNOTEQ
+		};
+
+		int32_t getValue(CGameState &, int32_t suggestedValue = 0);
+		Type getType();
+
+		Token();
+		Token(Type type);
+		Token(Common::String &string);
+		Token(Type type, int32_t value);
+		Token(const Token &other);
+		Token &operator = (const Token &rhs);
+
+	private:
+		Type type;
+
+		int32_t value;
+		Common::String string;
+};
+
+#endif /* defined(__Phantasma__Token__) */
diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
new file mode 100644
index 00000000000..1ded294b947
--- /dev/null
+++ b/engines/freescape/loaders/16bitBinaryLoader.cpp
@@ -0,0 +1,484 @@
+//
+//  16bitBinaryLoader.cpp
+//  Phantasma
+//
+//  Created by Thomas Harte on 17/12/2013.
+//  Copyright (c) 2013 Thomas Harte. All rights reserved.
+//
+
+
+//#include "freescape/language/parser.h"
+
+#include "common/debug.h"
+#include "common/array.h"
+#include "common/file.h"
+
+#include "freescape/area.h"
+#include "freescape/objects/object.h"
+#include "freescape/objects/geometricobject.h"
+#include "freescape/loaders/16bitBinaryLoader.h"
+#include "freescape/language/16bitDetokeniser.h"
+#include "freescape/language/instruction.h"
+
+class StreamLoader
+{
+	private:
+
+		Common::Array<uint8>::size_type bytePointer;
+		Common::Array<uint8> binary;
+		uint8 readMaskByte1;
+		uint8 readMaskByte2;
+
+	public:
+		StreamLoader(Common::Array <uint8> &_binary)
+		{
+			binary = _binary;
+			bytePointer = 0;
+			readMaskByte1 = 0;
+			readMaskByte2 = 0;
+		}
+
+		uint8 get8()
+		{
+			if(!eof())
+			{
+				uint8 sourceByte = binary[bytePointer];
+				
+				if(bytePointer&1)
+					sourceByte ^= readMaskByte2;
+				else
+					sourceByte ^= readMaskByte1;
+
+				bytePointer++;
+				return sourceByte;
+			} else
+				error("eof");
+
+			return 0;
+		}
+
+		uint16 get16()
+		{
+			uint16 result = (uint16)(get8() << 8);
+			result |= get8();
+			return result;
+		}
+
+		uint32 get32()
+		{
+			uint32 result = (uint32)(get16() << 16);
+			result |= get16();
+			return result;
+		}
+
+		bool eof()
+		{
+			return bytePointer >= binary.size();
+		}
+		
+		void alignPointer()
+		{
+			if(bytePointer&1) bytePointer++;
+		}
+		
+		void skipBytes(Common::Array<uint8>::size_type numberOfBytes)
+		{
+			bytePointer += numberOfBytes;
+		}
+
+		Common::Array<uint8> *nextBytes(Common::Array<uint8>::size_type numberOfBytes)
+		{
+			Common::Array<uint8> *returnBuffer(new Common::Array<uint8>);
+			debug("give me the next %d bytes", numberOfBytes);
+
+			while(numberOfBytes--)
+				returnBuffer->push_back(get8());
+
+			return returnBuffer;
+		}
+
+		Common::Array<uint8>::size_type getFileOffset()
+		{
+			return bytePointer;
+		}
+
+		void setFileOffset(Common::Array<uint8>::size_type newOffset)
+		{
+			bytePointer = newOffset;
+		}
+		
+		void setReadMask(uint8 byte1, uint8 byte2)
+		{
+			readMaskByte1 = byte1;
+			readMaskByte2 = byte2;
+		}
+};
+
+
+static Object *loadObject(StreamLoader &stream)
+{
+	// get object flags and type
+	uint8 objectFlags = stream.get8();
+	Object::Type objectType = (Object::Type)stream.get8();
+
+	/*
+		Notes to self:
+		
+			0 = no flags
+			128 = Movable, Animated
+			134 = Movable, Animated, Default invis, invis
+			6 = Default invis, Invis
+			32 = collided
+	*/
+
+	// get unknown value
+	uint16 skippedShort = stream.get16();
+	debug("skippedShort: %d", skippedShort);
+
+	// grab location, size
+	Vector3d position, size;
+	position.x		= stream.get16();
+	position.y		= stream.get16();
+	position.z		= stream.get16();
+	size.x			= stream.get16();
+	size.y			= stream.get16();
+	size.z			= stream.get16();
+
+	// object ID
+	uint16 objectID = stream.get16();
+
+	// size of object on disk; we've accounted for 20 bytes
+	// already so we can subtract that to get the remaining
+	// length beyond here
+	uint32 byteSizeOfObject = (uint32)(stream.get16() << 1) - 20;
+
+	debug("Object %d ; type %d ; flags %d ; size %d" , objectID , (int)objectType, (int)objectFlags, byteSizeOfObject);
+
+	switch(objectType)
+	{
+		default:
+		{
+			// read the appropriate number of colours
+			int numberOfColours = GeometricObject::numberOfColoursForObjectOfType(objectType);
+			Common::Array<uint8> *colours = new Common::Array<uint8>;
+			for(uint8 colour = 0; colour < numberOfColours; colour++)
+			{
+				colours->push_back(stream.get8());
+				byteSizeOfObject--;
+			}
+
+			// read extra vertices if required...
+			int numberOfOrdinates = GeometricObject::numberOfOrdinatesForType(objectType);
+			debug("number of ordinates %d", numberOfOrdinates);
+			Common::Array<uint16> *ordinates = nullptr;
+
+			if(numberOfOrdinates)
+			{
+				ordinates = new Common::Array<uint16>;
+
+				for(int ordinate = 0; ordinate < numberOfOrdinates; ordinate++)
+				{
+					ordinates->push_back(stream.get16());
+					byteSizeOfObject -= 2;
+				}
+			}
+
+			// grab the object condition, if there is one
+			FCLInstructionVector instructions;
+			if(byteSizeOfObject)
+			{
+				Common::Array<uint8> *conditionData = stream.nextBytes(byteSizeOfObject);
+
+				Common::String *conditionSource = detokenise16bitCondition(*conditionData);
+				instructions = nullptr; //getInstructions(conditionSource.get());
+			}
+			byteSizeOfObject = 0;
+
+			// create an object
+			return
+				new GeometricObject(
+					objectType,
+					objectID,
+					position,
+					size,
+					colours,
+					ordinates,
+					instructions);
+		}
+		break;
+
+		case Object::Entrance:
+		case Object::Sensor:
+		case Object::Group:
+		break;
+	}
+
+	// skip whatever we didn't understand
+	//cout << "bytes we don't understand:" << endl;
+	//int i = 0;
+	//int j = 0;
+	//for (i = 0; i < byteSizeOfObject/2; i++)
+	//	cout << i << stream.get16() << endl;
+	stream.skipBytes(byteSizeOfObject);
+
+	return nullptr;
+	
+}
+
+Area *loadArea(StreamLoader &stream)
+{
+	// the lowest bit of this value seems to indicate
+	// horizon on or off; this is as much as I currently know
+	uint16 skippedValue		= stream.get16();
+	uint16 numberOfObjects	= stream.get16();
+	uint16 areaNumber			= stream.get16();
+
+	debug("Area %d", areaNumber);
+	debug("Skipped value %d", skippedValue);
+	debug("Objects: %d", numberOfObjects);
+
+	// I've yet to decipher this fully
+	uint16 horizonColour	= stream.get16();
+	debug("Horizon colour %x", (int)horizonColour);
+
+	// this is just a complete guess
+	for(int paletteEntry = 0; paletteEntry < 22; paletteEntry++)
+	{
+		uint8 paletteColour		= stream.get8();
+		debug("Palette colour (?) %x", (int)paletteColour);
+	}
+
+	// we'll need to collate all objects and entrances; it's likely a
+	// plain C array would do but maps are safer and the total application
+	// cost is going to be negligible regardless
+	ObjectMap *objectsByID = new ObjectMap;
+	ObjectMap *entrancesByID = new ObjectMap;
+
+	// get the objects or whatever; entrances use a unique numbering
+	// system and have the high bit of their IDs set in the original file
+	for(uint16 object = 0; object < numberOfObjects; object++)
+	{
+		Object *newObject = loadObject(stream);
+
+		if(newObject)
+		{
+			if(newObject->getType() == Object::Entrance)
+			{
+				(*entrancesByID)[newObject->getObjectID() & 0x7fff] = newObject;
+			}
+			else
+			{
+				(*objectsByID)[newObject->getObjectID()] = newObject;
+			}
+		}
+	}
+
+	return (new Area(areaNumber, objectsByID, entrancesByID));
+}
+
+Game *load16bitBinary(Common::String filename)
+{
+	Common::File *file = new Common::File();
+
+    if (!file->open(filename)) {
+        delete file;
+    	return NULL;
+    }
+
+	const uint32 fileSize = file->size();
+	byte *buf = (byte *)malloc(fileSize);
+	file->read(buf, fileSize);
+
+	Common::Array <uint8> binary;
+
+	uint32 i = 0;
+	while (i < fileSize) {
+		binary.push_back(buf[i]);
+		i++;
+	}
+
+	StreamLoader streamLoader(binary);
+
+	Common::Array<uint8>::size_type baseOffset = 0;
+
+	// check whether this looks like an Amiga game; if so it'll start with AM
+	// XOR'd with the repeating byte pattern 0x71, 0xc1 or with the pattern
+	// 0x88 0x2c if it's on the ST (though the signature will still be AM)
+	uint16 platformID = streamLoader.get16();
+	debug("%d", platformID);
+
+	if(
+//		(platformID != 0x4120) && (platformID != 0x5043)
+		(platformID == 12428) || (platformID == 51553)
+	)
+	{
+		// TODO: record original platform type, so we can decode the palette
+		// and possibly the border properly
+		//cout << "AMIGA" << endl;
+
+		streamLoader.setReadMask((platformID >> 8) ^ 'A', (platformID & 0xff) ^ 'M');
+	}
+	else
+	{
+		debug("DOS");
+		// find DOS end of file and consume it
+		while(!streamLoader.eof()) {
+			uint8 b = streamLoader.get8();
+			if (b == 0x1a)
+			   break;
+		}
+		streamLoader.get8();
+
+		// advance to the next two-byte boundary if necessary
+		streamLoader.alignPointer();
+
+		// skip bytes with meaning unknown
+		streamLoader.get16();
+
+		// this brings us to the beginning of the embedded
+		// .KIT file, so we'll grab the base offset for
+		// finding areas later
+		baseOffset = streamLoader.getFileOffset();
+
+		// check that the next two bytes are "PC", then
+		// skip the number that comes after
+		if(streamLoader.get8() != 'C' || streamLoader.get8() != 'P') return nullptr;
+	}
+
+	
+	// skip an unknown meaning
+	streamLoader.get16();
+
+	// start grabbing some of the basics...
+
+	uint16 numberOfAreas = streamLoader.get16();
+	streamLoader.get16(); // meaning unknown
+
+	debug("Number of areas: %d", numberOfAreas);
+
+	uint16 windowCentreX	= streamLoader.get16();
+	uint16 windowCentreY	= streamLoader.get16();
+	uint16 windowWidth	= streamLoader.get16();
+	uint16 windowHeight	= streamLoader.get16();
+
+	
+	debug("Window centre: (%d, %d)", windowCentreX, windowCentreY);
+	debug("Window size: (%d, %d)", windowWidth,  windowHeight);
+
+	uint16 scaleX	= streamLoader.get16();
+	uint16 scaleY	= streamLoader.get16();
+	uint16 scaleZ	= streamLoader.get16();
+
+	debug("Scale %d, %d, %d", scaleX, scaleY, scaleZ);
+	uint16 timerReload	= streamLoader.get16();
+
+	debug("Timer: every %d 50Hz frames", timerReload);
+
+	uint16 maximumActivationDistance	= streamLoader.get16();
+	uint16 maximumFallDistance		= streamLoader.get16();
+	uint16 maximumClimbDistance		= streamLoader.get16();
+
+	debug("Maximum activation distance: %d", maximumActivationDistance);
+	debug("Maximum fall distance: %d",  maximumFallDistance);
+	debug("Maximum climb distance: %d", maximumClimbDistance);
+
+	uint16 startArea					= streamLoader.get16();
+	uint16 startEntrance				= streamLoader.get16();
+
+	debug("Start at entrance %d in area %d", startEntrance, startArea);
+
+	uint16 playerHeight				= streamLoader.get16();
+	uint16 playerStep				= streamLoader.get16();
+	uint16 playerAngle				= streamLoader.get16();
+
+	debug("Height %d, step %d, angle %d)", playerHeight, playerStep, playerAngle);
+
+	uint16 startVehicle				= streamLoader.get16();
+	uint16 executeGlobalCondition	= streamLoader.get16();
+
+	debug("Start vehicle %d, execute global condition %d", startVehicle, executeGlobalCondition);
+
+	// I haven't figured out what the next 106
+	// bytes mean, so we'll skip them — global objects
+	// maybe? Likely not 106 bytes in every file.
+	//
+	// ADDED: having rediscovered my source for the 8bit
+	// file format, could this be shading information by
+	// analogy with that?
+	/*cout << "global unknown:";
+	int i; 
+	int j;
+	for (i = 0; i < 106/2; i++)
+		cout << streamLoader.get16() << endl;*/
+
+	streamLoader.skipBytes(106);
+
+	// at this point I should properly load the border/key/mouse
+	// bindings, but I'm not worried about it for now.
+	//
+	// Format is:
+	//		(left x, top y, right x, bottom y) - all 16 bit
+	//		keyboard key as an ASCII character (or zero for none)
+	//		mouse button masl; 00 = both, 01 = left, 02 = right
+	//
+	// So, 10 bytes per binding. Bindings are listed in the order:
+	//
+	//	move forwards, move backwards, move right, move left, rise,
+	//	fall, turn left, turn right, look up, look down, tilt left,
+	//	tilt right, face forward, u-turn, change vehicle type,
+	//	select this vehicle, quit game, fire, activate object,
+	//	centre cursor on/off, save game position, load game position
+	//
+	// So 35 total. Which means this area takes up 350 bytes.
+	//cout << "more global unknown:";
+	//for (i = 0; i < 350/2; i++)
+	//	cout << streamLoader.get16() << endl;
+
+	streamLoader.skipBytes(350);
+
+	// there are then file pointers for every area — these are
+	// the number of shorts from the 'PC' tag, so multiply by
+	// two for bytes. Each is four bytes
+	uint32 *fileOffsetForArea = new uint32[numberOfAreas];
+	for(uint16 area = 0; area < numberOfAreas; area++)
+		fileOffsetForArea[area] = (uint32)streamLoader.get32() << 1;
+
+	// now come the global conditions
+	uint16 numberOfGlobalConditions = streamLoader.get16();
+	for(uint16 globalCondition = 0; globalCondition < numberOfGlobalConditions; globalCondition++)
+	{
+		// 12 bytes for the name of the condition;
+		// we don't care
+		streamLoader.skipBytes(12);
+
+		// get the length and the data itself, converting from
+		// shorts to bytes
+		uint32 lengthOfCondition = (uint32)streamLoader.get16() << 1;
+
+		// get the condition
+		Common::Array<uint8> *conditionData = streamLoader.nextBytes(lengthOfCondition);
+
+		debug("Global condition %d", globalCondition+1);
+		debug("%s", detokenise16bitCondition(*conditionData)->c_str());
+	}
+
+	// grab the areas
+	AreaMap *areaMap = new AreaMap;
+	for(uint16 area = 0; area < numberOfAreas; area++)
+	{
+		debug("Area offset %d", fileOffsetForArea[area]);
+
+		streamLoader.setFileOffset(fileOffsetForArea[area] + baseOffset);
+		Area *newArea = loadArea(streamLoader);
+		
+		if(newArea)
+		{
+			(*areaMap)[newArea->getAreaID()] = newArea;
+		}
+
+	}
+	streamLoader.setFileOffset(fileOffsetForArea[numberOfAreas-1] + baseOffset);
+
+	delete[] fileOffsetForArea;
+	return new Game(areaMap);
+}
diff --git a/engines/freescape/loaders/16bitBinaryLoader.h b/engines/freescape/loaders/16bitBinaryLoader.h
new file mode 100644
index 00000000000..821ee2b799a
--- /dev/null
+++ b/engines/freescape/loaders/16bitBinaryLoader.h
@@ -0,0 +1,24 @@
+//
+//  16bitBinaryLoader.h
+//  Phantasma
+//
+//  Created by Thomas Harte on 17/12/2013.
+//  Copyright (c) 2013 Thomas Harte. All rights reserved.
+//
+
+#ifndef __Phantasma___16bitBinaryLoader__
+#define __Phantasma___16bitBinaryLoader__
+
+//#include <iostream>
+//#include <vector>
+//#include <stdint.h>
+#include "common/str.h"
+
+#include "freescape/game.h"
+
+
+using namespace std;
+
+Game *load16bitBinary(Common::String);
+
+#endif /* defined(__Phantasma___16bitBinaryLoader__) */
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index 25d4853c9b8..bfc8ee695b0 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -2,10 +2,17 @@ MODULE := engines/freescape
  
 MODULE_OBJS := \
 	metaengine.o \
-	freescape.o
+	freescape.o \
+	game.o \
+	area.o \
+	objects/object.o \
+	objects/geometricobject.o \
+	loaders/16bitBinaryLoader.o \
+	language/16bitDetokeniser.o
  
 MODULE_DIRS += \
 	engines/freescape
+
  
 # This module can be built as a plugin
 ifeq ($(ENABLE_FREESCAPE), DYNAMIC_PLUGIN)
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
new file mode 100644
index 00000000000..0fb08675454
--- /dev/null
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -0,0 +1,100 @@
+//
+//  GeometricObject.cpp
+//  Phantasma
+//
+//  Created by Thomas Harte on 25/12/2013.
+//  Copyright (c) 2013 Thomas Harte. All rights reserved.
+//
+
+#include "common/str.h"
+
+#include "freescape/objects/geometricobject.h"
+
+#pragma mark -
+#pragma mark Static Getters
+
+int GeometricObject::numberOfColoursForObjectOfType(Type type)
+{
+	switch(type)
+	{
+		default:
+		case Entrance:
+		case Group:
+		case Sensor:			return 0;
+
+		case Line:				return 2;
+
+		case Rectangle:
+		case Triangle:
+		case Quadrilateral:
+		case Pentagon:
+		case Hexagon:			return 2;
+
+		case Cube:
+		case EastPyramid:
+		case WestPyramid:
+		case UpPyramid:
+		case DownPyramid:
+		case NorthPyramid:
+		case SouthPyramid:		return 6;
+	}
+}
+
+int GeometricObject::numberOfOrdinatesForType(Type type)
+{
+	switch(type)
+	{
+		default:
+		case Entrance:
+		case Group:
+		case Rectangle:
+		case Sensor:			return 0;
+
+		case EastPyramid:
+		case WestPyramid:
+		case UpPyramid:
+		case DownPyramid:
+		case NorthPyramid:
+		case SouthPyramid:		return 4;
+
+		case Line:
+		case Triangle:
+		case Quadrilateral:
+		case Pentagon:
+		case Hexagon:			return 3*(2 + type - Line);
+	}
+}
+
+
+#pragma mark -
+#pragma mark Construction/Destruction
+
+GeometricObject::GeometricObject(
+	Type _type,
+	uint16 _objectID,
+	const Vector3d &_origin,
+	const Vector3d &_size,
+	Common::Array<uint8> *_colours,
+	Common::Array<uint16> *_ordinates,
+	FCLInstructionVector _condition)
+{
+	type = _type;
+	objectID = _objectID;
+	origin = _origin;
+	size = _size;
+
+	if(_colours)	colours		= new Common::Array<uint8>(*_colours);
+	if(_ordinates)	ordinates	= new Common::Array<uint16>(*_ordinates);
+	condition = _condition;
+}
+
+GeometricObject::~GeometricObject()
+{
+}
+
+bool GeometricObject::isDrawable()								{	return true;	}
+bool GeometricObject::isPlanar()
+{
+	Type type = this->getType();
+	return (type >= Object::Line) || !size.x || !size.y || !size.z;
+}
diff --git a/engines/freescape/objects/geometricobject.h b/engines/freescape/objects/geometricobject.h
new file mode 100644
index 00000000000..e9d681297ef
--- /dev/null
+++ b/engines/freescape/objects/geometricobject.h
@@ -0,0 +1,60 @@
+//
+//  GeometricObject.h
+//  Phantasma
+//
+//  Created by Thomas Harte on 25/12/2013.
+//  Copyright (c) 2013 Thomas Harte. All rights reserved.
+//
+
+#ifndef __Phantasma__GeometricObject__
+#define __Phantasma__GeometricObject__
+
+#include "common/array.h"
+#include "freescape/objects/object.h"
+#include "freescape/language/instruction.h"
+
+class BatchDrawer;
+class GeometricObject: public Object
+{
+	public:
+
+		static int numberOfColoursForObjectOfType(Type type);
+		static int numberOfOrdinatesForType(Type type);
+
+		/*static void setupOpenGL();
+		static void setProjectionMatrix(const GLfloat *projectionMatrix);
+		static void setViewMatrix(const GLfloat *projectionMatrix);
+
+		static VertexBuffer *newVertexBuffer();
+		static DrawElementsBuffer *newDrawElementsBuffer();*/
+
+		GeometricObject(
+			Type type,
+			uint16 objectID,
+			const Vector3d &origin,
+			const Vector3d &size,
+			Common::Array<uint8> *colours,
+			Common::Array<uint16> *ordinates,
+			FCLInstructionVector condition);
+		virtual ~GeometricObject();
+
+		/*void setupOpenGL(VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer);
+		void draw(VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer, BatchDrawer *areaBatchDrawer, bool allowPolygonOffset);*/
+		bool isDrawable();
+		bool isPlanar();
+
+	private:
+		/*static GLuint openGLProgram;
+		static GLuint compileShader(const GLchar *source, GLenum shaderType);
+		static GLint viewMatrixUniform, projectionMatrixUniform;*/
+
+		FCLInstructionVector condition;
+		Common::Array<uint8> *colours;
+		Common::Array<uint16> *ordinates;
+
+		size_t drawElementsStartIndex;
+		//GLsizei drawElementsCount;
+		//GLenum drawElementsMode;
+};
+
+#endif /* defined(__Phantasma__GeometricObject__) */
diff --git a/engines/freescape/objects/object.cpp b/engines/freescape/objects/object.cpp
new file mode 100644
index 00000000000..7ff4dbd63af
--- /dev/null
+++ b/engines/freescape/objects/object.cpp
@@ -0,0 +1,21 @@
+//
+//  Object.cpp
+//  Phantasma
+//
+//  Created by Thomas Harte on 18/12/2013.
+//  Copyright (c) 2013 Thomas Harte. All rights reserved.
+//
+
+#include "freescape/objects/object.h"
+
+Object::Type Object::getType()	{	return type;		}
+uint16 Object::getObjectID()	{	return objectID;	}
+//Vector3d Object::getOrigin()	{	return origin;		}
+//Vector3d Object::getSize()		{	return size;		}
+
+//void Object::setupOpenGL(VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer)					{}
+//void Object::draw(VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer, BatchDrawer *batchDrawer, bool allowPolygonOffset)	{}
+bool Object::isDrawable()								{	return false;	}
+bool Object::isPlanar()									{	return false;	}
+
+Object::~Object()				{}
diff --git a/engines/freescape/objects/object.h b/engines/freescape/objects/object.h
new file mode 100644
index 00000000000..1eda9b135d3
--- /dev/null
+++ b/engines/freescape/objects/object.h
@@ -0,0 +1,87 @@
+//
+//  Object.h
+//  Phantasma
+//
+//  Created by Thomas Harte on 18/12/2013.
+//  Copyright (c) 2013 Thomas Harte. All rights reserved.
+//
+
+#ifndef __Phantasma__Object__
+#define __Phantasma__Object__
+
+#include "common/system.h"
+
+//#include <vector>
+//#include "freescape/language/instruction.h"
+
+typedef struct Vector3d
+{
+	uint16 x, y, z;
+	uint16 &operator [](int index)
+	{
+		switch(index)
+		{
+			default: return x;
+			case 1: return y;
+			case 2: return z;
+		}
+	};
+} Vector3d;
+
+class VertexBuffer;
+class DrawElementsBuffer;
+class BatchDrawer;
+class Object
+{
+	public:
+		typedef enum
+		{
+			Entrance		= 0,
+			Cube			= 1,
+			Sensor			= 2,
+			Rectangle		= 3,
+
+			EastPyramid		= 4,
+			WestPyramid		= 5,
+			UpPyramid		= 6,
+			DownPyramid		= 7,
+			NorthPyramid	= 8,
+			SouthPyramid	= 9,
+
+			Line			= 10,
+			Triangle		= 11,
+			Quadrilateral	= 12,
+			Pentagon		= 13,
+			Hexagon			= 14,
+
+			Group			= 15
+		} Type;
+
+		Type		getType();
+		uint16	getObjectID();
+		Vector3d	getOrigin();
+		Vector3d	getSize();
+
+		/*
+		virtual void setupOpenGL(VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer);
+		virtual void draw(VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer, BatchDrawer *batchDrawer, bool allowPolygonOffset);
+		*/
+		virtual bool isDrawable();
+		virtual bool isPlanar();
+
+		virtual ~Object();
+
+	protected:
+		Type type;
+		uint16 objectID;
+		Vector3d origin, size;
+};
+
+/*
+#include "GeometricObject.h"
+#include "Entrance.h"
+#include "Sensor.h"
+#include "Group.h"
+*/
+
+#endif /* defined(__Phantasma__Object__) */


Commit: 56f4fdca104f6bcd8f8c6fd6c86a37f95dc8c4bb
    https://github.com/scummvm/scummvm/commit/56f4fdca104f6bcd8f8c6fd6c86a37f95dc8c4bb
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:33+01:00

Commit Message:
FREESCAPE: added more code from phantasma

Changed paths:
  A engines/freescape/language/instruction.cpp
  A engines/freescape/language/parser.h
    engines/freescape/loaders/16bitBinaryLoader.cpp
    engines/freescape/module.mk


diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
new file mode 100644
index 00000000000..882e7440109
--- /dev/null
+++ b/engines/freescape/language/instruction.cpp
@@ -0,0 +1,80 @@
+//
+//  Instruction.cpp
+//  Phantasma
+//
+//  Created by Thomas Harte on 08/12/2013.
+//  Copyright (c) 2013 Thomas Harte. All rights reserved.
+//
+
+#include "freescape/language/instruction.h"
+
+FCLInstruction::FCLInstruction(Token::Type _type)
+{
+	// TODO: learn modern constructor syntax
+	type = _type;
+}
+
+FCLInstruction::FCLInstruction(const FCLInstruction &source)
+{
+	type = source.type;
+	arguments.source = source.arguments.source;
+	arguments.destination = source.arguments.destination;
+	arguments.option = source.arguments.option;
+	conditional.thenInstructions = source.conditional.thenInstructions;
+	conditional.elseInstructions = source.conditional.elseInstructions;
+}
+
+/*
+	Very routine setters for now; this code does not currently enforce good behaviour.
+	TODO: allow mutation only once; delete supplied objects and raise an error if a
+	second attempt at mutation is made
+*/
+void FCLInstruction::setArguments(Token &source)
+{
+	arguments.source = source;
+}
+
+void FCLInstruction::setArguments(Token &source, Token &destination)
+{
+	arguments.source = source;
+	arguments.destination = destination;
+}
+
+void FCLInstruction::setArguments(Token &source, Token &destination, Token &option)
+{
+	arguments.source = source;
+	arguments.destination = destination;
+	arguments.option = option;
+}
+
+void FCLInstruction::setBranches(FCLInstructionVector thenBranch, FCLInstructionVector elseBranch)
+{
+	conditional.thenInstructions = thenBranch;
+	conditional.elseInstructions = elseBranch;
+}
+
+/*
+	Similarly routine getters...
+*/
+void FCLInstruction::getValue(CGameState &gameState, int32_t &source)
+{
+	source		= arguments.source.getValue(gameState, source);
+}
+
+void FCLInstruction::getValue(CGameState &gameState, int32_t &source, int32_t &destination)
+{
+	source		= arguments.source.getValue(gameState, source);
+	destination	= arguments.destination.getValue(gameState, destination);
+}
+
+void FCLInstruction::getValue(CGameState &gameState, int32_t &source, int32_t &destination, int32_t &option)
+{
+	source		= arguments.source.getValue(gameState, source);
+	destination	= arguments.destination.getValue(gameState, destination);
+	option		= arguments.option.getValue(gameState, option);
+}
+
+Token::Type FCLInstruction::getType()
+{
+	return type;
+}
diff --git a/engines/freescape/language/parser.h b/engines/freescape/language/parser.h
new file mode 100644
index 00000000000..e9eb1a42f45
--- /dev/null
+++ b/engines/freescape/language/parser.h
@@ -0,0 +1,17 @@
+//
+//  Parser.h
+//  Phantasma
+//
+//  Created by Thomas Harte on 08/12/2013.
+//  Copyright (c) 2013 Thomas Harte. All rights reserved.
+//
+
+#ifndef __Phantasma__Parser__
+#define __Phantasma__Parser__
+
+#include "common/str.h"
+#include "freescape/language/instruction.h"
+
+FCLInstructionVector getInstructions(Common::String *sourceCode);
+
+#endif /* defined(__Phantasma__InstructionBuilder__) */
diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
index 1ded294b947..b6bbd89ed9b 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/16bitBinaryLoader.cpp
@@ -19,6 +19,7 @@
 #include "freescape/loaders/16bitBinaryLoader.h"
 #include "freescape/language/16bitDetokeniser.h"
 #include "freescape/language/instruction.h"
+#include "freescape/language/parser.h"
 
 class StreamLoader
 {
@@ -190,7 +191,7 @@ static Object *loadObject(StreamLoader &stream)
 				Common::Array<uint8> *conditionData = stream.nextBytes(byteSizeOfObject);
 
 				Common::String *conditionSource = detokenise16bitCondition(*conditionData);
-				instructions = nullptr; //getInstructions(conditionSource.get());
+				//instructions = getInstructions(conditionSource);
 			}
 			byteSizeOfObject = 0;
 
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index bfc8ee695b0..0c74326a742 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -8,7 +8,8 @@ MODULE_OBJS := \
 	objects/object.o \
 	objects/geometricobject.o \
 	loaders/16bitBinaryLoader.o \
-	language/16bitDetokeniser.o
+	language/16bitDetokeniser.o \
+	language/instruction.o
  
 MODULE_DIRS += \
 	engines/freescape


Commit: 1edba8cfb243a9762f952a4658c4ef408128670c
    https://github.com/scummvm/scummvm/commit/1edba8cfb243a9762f952a4658c4ef408128670c
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:33+01:00

Commit Message:
FREESCAPE: used clang-format to improve code style

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/detection.cpp
    engines/freescape/freescape.cpp
    engines/freescape/game.cpp
    engines/freescape/language/16bitDetokeniser.cpp
    engines/freescape/language/16bitDetokeniser.h
    engines/freescape/language/instruction.cpp
    engines/freescape/language/instruction.h
    engines/freescape/language/token.h
    engines/freescape/loaders/16bitBinaryLoader.cpp
    engines/freescape/loaders/16bitBinaryLoader.h
    engines/freescape/metaengine.cpp
    engines/freescape/objects/geometricobject.cpp
    engines/freescape/objects/geometricobject.h
    engines/freescape/objects/object.cpp
    engines/freescape/objects/object.h


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 1b79c741312..7cb41b7ecc4 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -6,37 +6,33 @@
 //  Copyright (c) 2013 Thomas Harte. All rights reserved.
 //
 
-#include "common/algorithm.h"
 #include "freescape/area.h"
+#include "common/algorithm.h"
 #include "freescape/objects/object.h"
 
-Object *Area::objectWithIDFromMap(ObjectMap *map, uint16 objectID)
-{
-	if(!map) return nullptr;
+Object *Area::objectWithIDFromMap(ObjectMap *map, uint16 objectID) {
+	if (!map)
+		return nullptr;
 	//TODO //if(!map->count(objectID)) return nullptr;
 	return (*map)[objectID];
 }
 
-Object *Area::objectWithID(uint16 objectID)
-{
+Object *Area::objectWithID(uint16 objectID) {
 	return objectWithIDFromMap(objectsByID, objectID);
 }
 
-Object *Area::entranceWithID(uint16 objectID)
-{
+Object *Area::entranceWithID(uint16 objectID) {
 	return objectWithIDFromMap(entrancesByID, objectID);
 }
 
-uint16 Area::getAreaID()
-{
+uint16 Area::getAreaID() {
 	return areaID;
 }
 
 Area::Area(
 	uint16 _areaID,
 	ObjectMap *_objectsByID,
-	ObjectMap *_entrancesByID)
-{
+	ObjectMap *_entrancesByID) {
 	areaID = _areaID;
 	objectsByID = _objectsByID;
 	entrancesByID = _entrancesByID;
@@ -44,10 +40,8 @@ Area::Area(
 	drawElementsBuffer = nullptr;
 
 	// create a list of drawable objects only
-	for(ObjectMap::iterator iterator = objectsByID->begin(); iterator != objectsByID->end(); iterator++)
-	{
-		if(iterator->_value->isDrawable())
-		{
+	for (ObjectMap::iterator iterator = objectsByID->begin(); iterator != objectsByID->end(); iterator++) {
+		if (iterator->_value->isDrawable()) {
 			drawableObjects.push_back(iterator->_value);
 		}
 	}
@@ -55,23 +49,23 @@ Area::Area(
 	// sort so that those that are planar are drawn last
 	struct
 	{
-		bool operator() (Object *object1, Object *object2)
-		{
-			if(!object1->isPlanar() && object2->isPlanar()) return true;
-			if(object1->isPlanar() && !object2->isPlanar()) return false;
+		bool operator()(Object *object1, Object *object2) {
+			if (!object1->isPlanar() && object2->isPlanar())
+				return true;
+			if (object1->isPlanar() && !object2->isPlanar())
+				return false;
 			return object1->getObjectID() < object2->getObjectID();
 		};
 	} compareObjects;
-	
+
 	Common::sort(drawableObjects.begin(), drawableObjects.end(), compareObjects);
 }
 
-Area::~Area()
-{
-	for(ObjectMap::iterator iterator = entrancesByID->begin(); iterator != entrancesByID->end(); iterator++)
+Area::~Area() {
+	for (ObjectMap::iterator iterator = entrancesByID->begin(); iterator != entrancesByID->end(); iterator++)
 		delete iterator->_value;
 
-	for(ObjectMap::iterator iterator = objectsByID->begin(); iterator != objectsByID->end(); iterator++)
+	for (ObjectMap::iterator iterator = objectsByID->begin(); iterator != objectsByID->end(); iterator++)
 		delete iterator->_value;
 
 	delete entrancesByID;
diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index e99614b424d..974c92c1d00 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -3,28 +3,24 @@
 
 namespace Freescape {
 static const PlainGameDescriptor freescapeGames[] = {
-	{ "3dkit", "3D Kit Constructor example game" },
-	{ 0, 0 }
-};
+	{"3dkit", "3D Kit Constructor example game"},
+	{0, 0}};
 
 static const ADGameDescription gameDescriptions[] = {
-	{
-		"3Dkit",
-		0,
-		AD_ENTRY1s("3DKIT.RUN", "f35147729a2f5b6852a504223aeb6a57", 112158),
-		Common::EN_ANY,
-		Common::kPlatformDOS,
-		ADGF_NO_FLAGS,
-		GUIO1(GUIO_NOMIDI)
-	},
-	AD_TABLE_END_MARKER
-};
+	{"3Dkit",
+	 0,
+	 AD_ENTRY1s("3DKIT.RUN", "f35147729a2f5b6852a504223aeb6a57", 112158),
+	 Common::EN_ANY,
+	 Common::kPlatformDOS,
+	 ADGF_NO_FLAGS,
+	 GUIO1(GUIO_NOMIDI)},
+	AD_TABLE_END_MARKER};
 } // End of namespace Freescape
 
 class FreescapeMetaEngineDetection : public AdvancedMetaEngineDetection {
 public:
 	FreescapeMetaEngineDetection() : AdvancedMetaEngineDetection(Freescape::gameDescriptions, sizeof(ADGameDescription), Freescape::freescapeGames) {
-	}	
+	}
 
 	const char *getEngineId() const override {
 		return "freescape";
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 2310243f86e..97349bc59a5 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -1,8 +1,8 @@
 #include "common/scummsys.h"
 
 #include "common/config-manager.h"
-#include "common/debug.h"
 #include "common/debug-channels.h"
+#include "common/debug.h"
 #include "common/error.h"
 #include "common/events.h"
 #include "common/file.h"
@@ -16,9 +16,9 @@
 #include "freescape/loaders/16bitBinaryLoader.h"
 //#include "freescape/loaders/8bitBinaryLoader.h"
 
-#define OFFSET_DARKSIDE       0xc9ce
-#define OFFSET_DRILLER        0xcf3e
-#define OFFSET_TOTALECLIPSE   0xcdb7
+#define OFFSET_DARKSIDE 0xc9ce
+#define OFFSET_DRILLER 0xcf3e
+#define OFFSET_TOTALECLIPSE 0xcdb7
 
 namespace Freescape {
 
@@ -74,13 +74,13 @@ Common::Error FreescapeEngine::run() {
 	//OSystem::kTransactionSizeChangeFailed here
 	//_system->endGFXTransaction();
 
-    Game *_game = load16bitBinary("3DKIT.RUN");
-    Common::File *file = new Common::File();
+	Game *_game = load16bitBinary("3DKIT.RUN");
+	Common::File *file = new Common::File();
 
-    if (!file->open("3DKIT.RUN")) {
-        delete file;
-    	return Common::kNoError;
-    }
+	if (!file->open("3DKIT.RUN")) {
+		delete file;
+		return Common::kNoError;
+	}
 
 	const int32 fileSize = file->size();
 	byte *buf = (byte *)malloc(fileSize);
@@ -88,25 +88,20 @@ Common::Error FreescapeEngine::run() {
 
 	_pixelFormat = g_system->getScreenFormat();
 	// 16 colors palette from ultima
-    static const byte PALETTE[16][3] = {
-                { 0, 0, 0 },{ 0xe0, 0xc0, 0x70 },{ 0xb0, 0x80, 0x40 },{ 0x80, 0x60, 0x10 },
-                { 0x50, 0x30, 0x00 },{ 0x20, 0x80, 0xd0 },{ 0x20, 0x50, 0xb0 },{ 0x20, 0x30, 0x70 },
-                { 0x30, 0x40, 0x30 },{ 0x30, 0x30, 0x30 },{ 0x40, 0x40, 0x40 },{ 0x60, 0x60, 0x60 },
-                { 0x70, 0x70, 0x70 },{ 0x90, 0x90, 0x90 },{ 0xa0, 0xa0, 0xa0 },{ 0xc0, 0xc0, 0xc0 }
-    };
-    g_system->getPaletteManager()->setPalette(&PALETTE[0][0], 0, 16);
+	static const byte PALETTE[16][3] = {
+		{0, 0, 0}, {0xe0, 0xc0, 0x70}, {0xb0, 0x80, 0x40}, {0x80, 0x60, 0x10}, {0x50, 0x30, 0x00}, {0x20, 0x80, 0xd0}, {0x20, 0x50, 0xb0}, {0x20, 0x30, 0x70}, {0x30, 0x40, 0x30}, {0x30, 0x30, 0x30}, {0x40, 0x40, 0x40}, {0x60, 0x60, 0x60}, {0x70, 0x70, 0x70}, {0x90, 0x90, 0x90}, {0xa0, 0xa0, 0xa0}, {0xc0, 0xc0, 0xc0}};
+	g_system->getPaletteManager()->setPalette(&PALETTE[0][0], 0, 16);
 
 	int i = 0;
 	byte *p = buf;
 
-	while(i < fileSize-4) {
-		if(*((uint32*) p) == 0xfa002445) {
+	while (i < fileSize - 4) {
+		if (*((uint32 *)p) == 0xfa002445) {
 			debug("Border found at %x", i);
-			g_system->copyRectToScreen((const void*) p, 320, 0, 0, 320, 200);
+			g_system->copyRectToScreen((const void *)p, 320, 0, 0, 320, 200);
 		}
 		p++;
 		i++;
-
 	}
 
 	// Create debugger console. It requires GFX to be initialized
@@ -126,10 +121,9 @@ Common::Error FreescapeEngine::run() {
 }
 
 bool FreescapeEngine::hasFeature(EngineFeature f) const {
-	return
-		(f == kSupportsReturnToLauncher) ||
-		(f == kSupportsLoadingDuringRuntime) ||
-		(f == kSupportsSavingDuringRuntime);
+	return (f == kSupportsReturnToLauncher) ||
+		   (f == kSupportsLoadingDuringRuntime) ||
+		   (f == kSupportsSavingDuringRuntime);
 }
 
 Common::Error FreescapeEngine::loadGameStream(Common::SeekableReadStream *stream) {
@@ -150,4 +144,4 @@ void FreescapeEngine::syncGameStream(Common::Serializer &s) {
 	s.syncAsUint16LE(dummy);
 }
 
-} // End of namespace Quux
+} // namespace Freescape
diff --git a/engines/freescape/game.cpp b/engines/freescape/game.cpp
index 154779b0b5e..35710a8cab1 100644
--- a/engines/freescape/game.cpp
+++ b/engines/freescape/game.cpp
@@ -11,26 +11,24 @@
 //#include "Matrix.h"
 //#include "VertexBuffer.h"
 
-Game::Game(AreaMap *_areasByAreaID)
-{
+Game::Game(AreaMap *_areasByAreaID) {
 	hasReceivedTime = false;
 	areasByAreaID = _areasByAreaID;
 
 	rotation[0] =
-	rotation[1] =
-	rotation[2] = 0.0f;
+		rotation[1] =
+			rotation[2] = 0.0f;
 
 	position[0] = 1000.0f;
 	position[1] = 300.0f;
 	position[2] = 1000.0f;
 
 	velocity[0] =
-	velocity[1] =
-	velocity[2] = 0.0f;
+		velocity[1] =
+			velocity[2] = 0.0f;
 }
 
-Game::~Game()
-{
+Game::~Game() {
 	delete areasByAreaID;
 }
 /*
diff --git a/engines/freescape/language/16bitDetokeniser.cpp b/engines/freescape/language/16bitDetokeniser.cpp
index c54835c736b..454506891b8 100644
--- a/engines/freescape/language/16bitDetokeniser.cpp
+++ b/engines/freescape/language/16bitDetokeniser.cpp
@@ -8,134 +8,234 @@
 
 #include "16bitDetokeniser.h"
 
-Common::String *detokenise16bitCondition(Common::Array <uint8> &tokenisedCondition)
-{
+Common::String *detokenise16bitCondition(Common::Array<uint8> &tokenisedCondition) {
 	Common::String detokenisedStream;
-	Common::Array <uint8>::size_type bytePointer = 0;
-	Common::Array <uint8>::size_type sizeOfTokenisedContent = tokenisedCondition.size();
+	Common::Array<uint8>::size_type bytePointer = 0;
+	Common::Array<uint8>::size_type sizeOfTokenisedContent = tokenisedCondition.size();
 
-	while(bytePointer < sizeOfTokenisedContent-1)
-	{
+	while (bytePointer < sizeOfTokenisedContent - 1) {
 		// byte 1 = number of arguments, byte 2 = opcode
-		uint8 numberOfArguments	= tokenisedCondition[bytePointer];
-		uint8 opcode			= tokenisedCondition[bytePointer+1];
+		uint8 numberOfArguments = tokenisedCondition[bytePointer];
+		uint8 opcode = tokenisedCondition[bytePointer + 1];
 		bytePointer += 2;
 
 		// make sure we have enough buffer left to read all the arguments
-		if(bytePointer + numberOfArguments*2 > sizeOfTokenisedContent) break;
+		if (bytePointer + numberOfArguments * 2 > sizeOfTokenisedContent)
+			break;
 
 		// write out the operation
-		switch(opcode)
-		{
-			case 0x01:	detokenisedStream += "ACTIVATED? ";		break;
-			case 0x02:	detokenisedStream += "COLLIDED? ";		break;
-			case 0x03:	detokenisedStream += "SHOT? ";			break;
-			case 0x04:	detokenisedStream += "TIMER? ";			break;
+		switch (opcode) {
+		case 0x01:
+			detokenisedStream += "ACTIVATED? ";
+			break;
+		case 0x02:
+			detokenisedStream += "COLLIDED? ";
+			break;
+		case 0x03:
+			detokenisedStream += "SHOT? ";
+			break;
+		case 0x04:
+			detokenisedStream += "TIMER? ";
+			break;
 
-			case 0x10:	detokenisedStream += "SETVAR ";			break;
-			case 0x11:	detokenisedStream += "ADDVAR ";			break;
-			case 0x12:	detokenisedStream += "SUBVAR ";			break;
+		case 0x10:
+			detokenisedStream += "SETVAR ";
+			break;
+		case 0x11:
+			detokenisedStream += "ADDVAR ";
+			break;
+		case 0x12:
+			detokenisedStream += "SUBVAR ";
+			break;
 
-			case 0x13:	detokenisedStream += "ANDV ";			break;
-			case 0x14:	detokenisedStream += "ORV ";			break;
-			case 0x15:	detokenisedStream += "NOTV ";			break;
+		case 0x13:
+			detokenisedStream += "ANDV ";
+			break;
+		case 0x14:
+			detokenisedStream += "ORV ";
+			break;
+		case 0x15:
+			detokenisedStream += "NOTV ";
+			break;
 
-			case 0x16:	detokenisedStream += "VAR=? ";			break;
-			case 0x17:	detokenisedStream += "VAR>? ";			break;
-			case 0x18:	detokenisedStream += "VAR<? ";			break;
+		case 0x16:
+			detokenisedStream += "VAR=? ";
+			break;
+		case 0x17:
+			detokenisedStream += "VAR>? ";
+			break;
+		case 0x18:
+			detokenisedStream += "VAR<? ";
+			break;
 
-			case 0x2f:	detokenisedStream += "DESTROYED? ";		break;
+		case 0x2f:
+			detokenisedStream += "DESTROYED? ";
+			break;
 
-			case 0x30:	detokenisedStream += "INVIS ";			break;
-			case 0x31:	detokenisedStream += "VIS ";			break;
-			case 0x32:	detokenisedStream += "TOGVIS ";			break;
-			case 0x33:	detokenisedStream += "DESTROY ";		break;
+		case 0x30:
+			detokenisedStream += "INVIS ";
+			break;
+		case 0x31:
+			detokenisedStream += "VIS ";
+			break;
+		case 0x32:
+			detokenisedStream += "TOGVIS ";
+			break;
+		case 0x33:
+			detokenisedStream += "DESTROY ";
+			break;
 
-			case 0x34:	detokenisedStream += "INVIS? ";			break;
-			case 0x35:	detokenisedStream += "VIS? ";			break;
+		case 0x34:
+			detokenisedStream += "INVIS? ";
+			break;
+		case 0x35:
+			detokenisedStream += "VIS? ";
+			break;
 
-			case 0x36:	detokenisedStream += "MOVE ";			break;
+		case 0x36:
+			detokenisedStream += "MOVE ";
+			break;
 
-			case 0x37:	detokenisedStream += "GETXPOS ";		break;
-			case 0x38:	detokenisedStream += "GETYPOS ";		break;
-			case 0x39:	detokenisedStream += "GETZPOS ";		break;
+		case 0x37:
+			detokenisedStream += "GETXPOS ";
+			break;
+		case 0x38:
+			detokenisedStream += "GETYPOS ";
+			break;
+		case 0x39:
+			detokenisedStream += "GETZPOS ";
+			break;
 
-			case 0x3a:	detokenisedStream += "MOVETO ";			break;
+		case 0x3a:
+			detokenisedStream += "MOVETO ";
+			break;
 
-			case 0x40:	detokenisedStream += "IF ";				break;
-			case 0x41:	detokenisedStream += "THEN ";			break;
-			case 0x42:	detokenisedStream += "ELSE ";			break;
-			case 0x43:	detokenisedStream += "ENDIF ";			break;
-			case 0x44:	detokenisedStream += "AND ";			break;
-			case 0x45:	detokenisedStream += "OR ";				break;
+		case 0x40:
+			detokenisedStream += "IF ";
+			break;
+		case 0x41:
+			detokenisedStream += "THEN ";
+			break;
+		case 0x42:
+			detokenisedStream += "ELSE ";
+			break;
+		case 0x43:
+			detokenisedStream += "ENDIF ";
+			break;
+		case 0x44:
+			detokenisedStream += "AND ";
+			break;
+		case 0x45:
+			detokenisedStream += "OR ";
+			break;
 
-			case 0x50:	detokenisedStream += "STARTANIM ";		break;
-			case 0x51:	detokenisedStream += "STOPANIM ";		break;
+		case 0x50:
+			detokenisedStream += "STARTANIM ";
+			break;
+		case 0x51:
+			detokenisedStream += "STOPANIM ";
+			break;
 
-			case 0x52:	detokenisedStream += "START ";			break;
-			case 0x53:	detokenisedStream += "RESTART ";		break;
+		case 0x52:
+			detokenisedStream += "START ";
+			break;
+		case 0x53:
+			detokenisedStream += "RESTART ";
+			break;
 
-			case 0x54:	detokenisedStream += "INCLUDE ";		break;
+		case 0x54:
+			detokenisedStream += "INCLUDE ";
+			break;
 
-			case 0x55:	detokenisedStream += "WAITTRIG ";		break;
-			case 0x56:	detokenisedStream += "TRIGANIM ";		break;
-			case 0x57:	detokenisedStream += "REMOVE ";			break;
+		case 0x55:
+			detokenisedStream += "WAITTRIG ";
+			break;
+		case 0x56:
+			detokenisedStream += "TRIGANIM ";
+			break;
+		case 0x57:
+			detokenisedStream += "REMOVE ";
+			break;
 
-			case 0x60:	detokenisedStream += "LOOP ";			break;
-			case 0x61:	detokenisedStream += "AGAIN ";			break;
+		case 0x60:
+			detokenisedStream += "LOOP ";
+			break;
+		case 0x61:
+			detokenisedStream += "AGAIN ";
+			break;
 
-			case 0x70:	detokenisedStream += "SOUND ";			break;
-			case 0x71:	detokenisedStream += "SYNCSND ";		break;
+		case 0x70:
+			detokenisedStream += "SOUND ";
+			break;
+		case 0x71:
+			detokenisedStream += "SYNCSND ";
+			break;
 
-			case 0x80:	detokenisedStream += "WAIT ";			break;
-			case 0x81:	detokenisedStream += "DELAY ";			break;
+		case 0x80:
+			detokenisedStream += "WAIT ";
+			break;
+		case 0x81:
+			detokenisedStream += "DELAY ";
+			break;
 
-			case 0x82:	detokenisedStream += "UPDATEI ";		break;
-			case 0x83:	detokenisedStream += "PRINT ";			break;
-			case 0x84:	detokenisedStream += "REDRAW ";			break;
+		case 0x82:
+			detokenisedStream += "UPDATEI ";
+			break;
+		case 0x83:
+			detokenisedStream += "PRINT ";
+			break;
+		case 0x84:
+			detokenisedStream += "REDRAW ";
+			break;
 
-			case 0x85:	detokenisedStream += "MODE ";			break;
-			case 0x86:	detokenisedStream += "ENDGAME ";		break;
+		case 0x85:
+			detokenisedStream += "MODE ";
+			break;
+		case 0x86:
+			detokenisedStream += "ENDGAME ";
+			break;
 
-			case 0x87:	detokenisedStream += "EXECUTE ";		break;
-			case 0x90:	detokenisedStream += "GOTO ";			break;
+		case 0x87:
+			detokenisedStream += "EXECUTE ";
+			break;
+		case 0x90:
+			detokenisedStream += "GOTO ";
+			break;
 
-			case 0xff:	detokenisedStream += "END ";			break;
+		case 0xff:
+			detokenisedStream += "END ";
+			break;
 
-			default:
-				detokenisedStream += "<UNKNOWN 16 bit: ";
-				detokenisedStream += Common::String::format("%x", (int)opcode);
-				detokenisedStream += " > ";
+		default:
+			detokenisedStream += "<UNKNOWN 16 bit: ";
+			detokenisedStream += Common::String::format("%x", (int)opcode);
+			detokenisedStream += " > ";
 			break;
 		}
 
 		// PRINT is a special case, requiring us to grab a string,
 		// but everything else is uniform
-		if(numberOfArguments)
-		{
+		if (numberOfArguments) {
 			// arguments are enclosed in brackets
 			detokenisedStream += "(";
 
-			if(opcode == 0x83)
-			{
+			if (opcode == 0x83) {
 				// the first argument is a string, which is encoded as
 				// a two-byte string length (in big endian form)
 				uint16 stringLength =
 					(uint16)(
 						(tokenisedCondition[bytePointer] << 8) |
-						tokenisedCondition[bytePointer+1]
-					);
+						tokenisedCondition[bytePointer + 1]);
 				bytePointer += 2;
 				numberOfArguments--;
 
 				detokenisedStream += "\"";
-				for(uint16 stringPosition = 0; stringPosition < stringLength; stringPosition++)
-				{
+				for (uint16 stringPosition = 0; stringPosition < stringLength; stringPosition++) {
 					char nextChar = (char)tokenisedCondition[bytePointer + stringPosition];
 
 					// TODO: spot special characters here
 
-					if(nextChar)
+					if (nextChar)
 						detokenisedStream += nextChar;
 				}
 				detokenisedStream += "\"";
@@ -143,23 +243,25 @@ Common::String *detokenise16bitCondition(Common::Array <uint8> &tokenisedConditi
 
 				// strings are rounded up in length to the end
 				// of this two-byte quantity
-				if(stringLength&1) bytePointer++;
-				numberOfArguments -= (stringLength+1) >> 1;
+				if (stringLength & 1)
+					bytePointer++;
+				numberOfArguments -= (stringLength + 1) >> 1;
 
 				// that should leave an argument, but you can't be too safe
-				if(numberOfArguments) detokenisedStream += ", ";
+				if (numberOfArguments)
+					detokenisedStream += ", ";
 			}
 
-			for(uint8 argumentNumber = 0; argumentNumber < numberOfArguments; argumentNumber++)
-			{
+			for (uint8 argumentNumber = 0; argumentNumber < numberOfArguments; argumentNumber++) {
 				// each argument is encoded in two bytes...
-				uint8 indexHighByte		= tokenisedCondition[bytePointer];
-				uint8 indexLowByte		= tokenisedCondition[bytePointer+1];
+				uint8 indexHighByte = tokenisedCondition[bytePointer];
+				uint8 indexLowByte = tokenisedCondition[bytePointer + 1];
 				bytePointer += 2;
 
 				// if the high bit of the first byte is clear then this
 				// argument is a constant; if it's set then this is a variable
-				if(indexHighByte&0x80) detokenisedStream += "V";
+				if (indexHighByte & 0x80)
+					detokenisedStream += "V";
 				indexHighByte &= 0x7f;
 
 				// the second byte is either the constant or the index of
@@ -167,7 +269,7 @@ Common::String *detokenise16bitCondition(Common::Array <uint8> &tokenisedConditi
 				detokenisedStream += Common::String::format("%d", (int)(indexLowByte | (indexHighByte << 8)));
 
 				// ... and arguments are separated by commas, of course
-				if(argumentNumber+1 < numberOfArguments)
+				if (argumentNumber + 1 < numberOfArguments)
 					detokenisedStream += ", ";
 			}
 
@@ -175,7 +277,7 @@ Common::String *detokenise16bitCondition(Common::Array <uint8> &tokenisedConditi
 			detokenisedStream += ")";
 		}
 
-		detokenisedStream +=  "\n";
+		detokenisedStream += "\n";
 	}
 
 	return (new Common::String(detokenisedStream));
diff --git a/engines/freescape/language/16bitDetokeniser.h b/engines/freescape/language/16bitDetokeniser.h
index 2a79b25bd89..173d5349571 100644
--- a/engines/freescape/language/16bitDetokeniser.h
+++ b/engines/freescape/language/16bitDetokeniser.h
@@ -9,9 +9,9 @@
 #ifndef __Phantasma___6bitDetokeniser__
 #define __Phantasma___6bitDetokeniser__
 
-#include "common/str.h"
 #include "common/array.h"
+#include "common/str.h"
 
-Common::String *detokenise16bitCondition(Common::Array <uint8> &tokenisedCondition);
+Common::String *detokenise16bitCondition(Common::Array<uint8> &tokenisedCondition);
 
 #endif /* defined(__Phantasma___6bitDetokeniser__) */
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index 882e7440109..7c77eed9c3a 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -8,14 +8,12 @@
 
 #include "freescape/language/instruction.h"
 
-FCLInstruction::FCLInstruction(Token::Type _type)
-{
+FCLInstruction::FCLInstruction(Token::Type _type) {
 	// TODO: learn modern constructor syntax
 	type = _type;
 }
 
-FCLInstruction::FCLInstruction(const FCLInstruction &source)
-{
+FCLInstruction::FCLInstruction(const FCLInstruction &source) {
 	type = source.type;
 	arguments.source = source.arguments.source;
 	arguments.destination = source.arguments.destination;
@@ -29,26 +27,22 @@ FCLInstruction::FCLInstruction(const FCLInstruction &source)
 	TODO: allow mutation only once; delete supplied objects and raise an error if a
 	second attempt at mutation is made
 */
-void FCLInstruction::setArguments(Token &source)
-{
+void FCLInstruction::setArguments(Token &source) {
 	arguments.source = source;
 }
 
-void FCLInstruction::setArguments(Token &source, Token &destination)
-{
+void FCLInstruction::setArguments(Token &source, Token &destination) {
 	arguments.source = source;
 	arguments.destination = destination;
 }
 
-void FCLInstruction::setArguments(Token &source, Token &destination, Token &option)
-{
+void FCLInstruction::setArguments(Token &source, Token &destination, Token &option) {
 	arguments.source = source;
 	arguments.destination = destination;
 	arguments.option = option;
 }
 
-void FCLInstruction::setBranches(FCLInstructionVector thenBranch, FCLInstructionVector elseBranch)
-{
+void FCLInstruction::setBranches(FCLInstructionVector thenBranch, FCLInstructionVector elseBranch) {
 	conditional.thenInstructions = thenBranch;
 	conditional.elseInstructions = elseBranch;
 }
@@ -56,25 +50,21 @@ void FCLInstruction::setBranches(FCLInstructionVector thenBranch, FCLInstruction
 /*
 	Similarly routine getters...
 */
-void FCLInstruction::getValue(CGameState &gameState, int32_t &source)
-{
-	source		= arguments.source.getValue(gameState, source);
+void FCLInstruction::getValue(CGameState &gameState, int32_t &source) {
+	source = arguments.source.getValue(gameState, source);
 }
 
-void FCLInstruction::getValue(CGameState &gameState, int32_t &source, int32_t &destination)
-{
-	source		= arguments.source.getValue(gameState, source);
-	destination	= arguments.destination.getValue(gameState, destination);
+void FCLInstruction::getValue(CGameState &gameState, int32_t &source, int32_t &destination) {
+	source = arguments.source.getValue(gameState, source);
+	destination = arguments.destination.getValue(gameState, destination);
 }
 
-void FCLInstruction::getValue(CGameState &gameState, int32_t &source, int32_t &destination, int32_t &option)
-{
-	source		= arguments.source.getValue(gameState, source);
-	destination	= arguments.destination.getValue(gameState, destination);
-	option		= arguments.option.getValue(gameState, option);
+void FCLInstruction::getValue(CGameState &gameState, int32_t &source, int32_t &destination, int32_t &option) {
+	source = arguments.source.getValue(gameState, source);
+	destination = arguments.destination.getValue(gameState, destination);
+	option = arguments.option.getValue(gameState, option);
 }
 
-Token::Type FCLInstruction::getType()
-{
+Token::Type FCLInstruction::getType() {
 	return type;
 }
diff --git a/engines/freescape/language/instruction.h b/engines/freescape/language/instruction.h
index 0c2f4d17607..b5a2ee2fcd7 100644
--- a/engines/freescape/language/instruction.h
+++ b/engines/freescape/language/instruction.h
@@ -9,45 +9,43 @@
 #ifndef __Phantasma__Instruction__
 #define __Phantasma__Instruction__
 
-#include "freescape/language/token.h"
 #include "common/array.h"
+#include "freescape/language/token.h"
 
 class CGameState;
 
 class FCLInstruction;
 typedef Common::Array<FCLInstruction> *FCLInstructionVector;
 
-class FCLInstruction
-{
-	public:
-		FCLInstruction(Token::Type type);
-		FCLInstruction(const FCLInstruction &source);
+class FCLInstruction {
+public:
+	FCLInstruction(Token::Type type);
+	FCLInstruction(const FCLInstruction &source);
 
-		void setArguments(Token &);
-		void setArguments(Token &, Token &);
-		void setArguments(Token &, Token &, Token &);
+	void setArguments(Token &);
+	void setArguments(Token &, Token &);
+	void setArguments(Token &, Token &, Token &);
 
-		Token::Type getType();
+	Token::Type getType();
 
-		void getValue(CGameState &, int32_t &);
-		void getValue(CGameState &, int32_t &, int32_t &);
-		void getValue(CGameState &, int32_t &, int32_t &, int32 &);
+	void getValue(CGameState &, int32_t &);
+	void getValue(CGameState &, int32_t &, int32_t &);
+	void getValue(CGameState &, int32_t &, int32_t &, int32 &);
 
-		void setBranches(FCLInstructionVector thenBranch, FCLInstructionVector elseBranch);
+	void setBranches(FCLInstructionVector thenBranch, FCLInstructionVector elseBranch);
 
-	private:
-		enum Token::Type type;
+private:
+	enum Token::Type type;
 
-		struct
-		{
-			Token source, destination, option;
-		} arguments;
+	struct
+	{
+		Token source, destination, option;
+	} arguments;
 
-		struct
-		{
-			FCLInstructionVector thenInstructions, elseInstructions;
-		} conditional;
+	struct
+	{
+		FCLInstructionVector thenInstructions, elseInstructions;
+	} conditional;
 };
 
-
 #endif /* defined(__Phantasma__Instruction__) */
diff --git a/engines/freescape/language/token.h b/engines/freescape/language/token.h
index 9a0550836b1..0297d52c3b2 100644
--- a/engines/freescape/language/token.h
+++ b/engines/freescape/language/token.h
@@ -13,49 +13,93 @@
 
 #include "freescape/gamestate.h"
 
-struct Token
-{
-	public:
-		enum Type
-		{
-			ACTIVATEDQ, ADDVAR, AGAIN, AND, ANDV,
-			COLLIDEDQ,
-			DELAY, DESTROY, DESTROYEDQ,
-			ELSE, END, ENDGAME, ENDIF, EXECUTE,
-			GOTO,
-			IF, INVIS, INVISQ, INCLUDE,
-			LOOP,
-			MODE, MOVE, MOVETO,
-			NOTV,
-			OR, ORV,
-			GETXPOS, GETYPOS, GETZPOS, 
-			PRINT,
-			RESTART, REDRAW, REMOVE,
-			SOUND, SETVAR, SHOTQ, START, STARTANIM, STOPANIM, SUBVAR, SYNCSND,
-			THEN, TIMERQ, TOGVIS, TRIGANIM,
-			UPDATEI,
-			VAREQ, VARGQ, VARLQ, VISQ, VIS,
-			WAIT, WAITTRIG,
-			COMMA, OPENBRACKET, CLOSEBRACKET, CONSTANT, VARIABLE, STRINGLITERAL,
-			UNKNOWN, ENDOFFILE,
-			SETBIT, CLEARBIT, TOGGLEBIT, SWAPJET, BITNOTEQ, VARNOTEQ
-		};
-
-		int32_t getValue(CGameState &, int32_t suggestedValue = 0);
-		Type getType();
-
-		Token();
-		Token(Type type);
-		Token(Common::String &string);
-		Token(Type type, int32_t value);
-		Token(const Token &other);
-		Token &operator = (const Token &rhs);
-
-	private:
-		Type type;
-
-		int32_t value;
-		Common::String string;
+struct Token {
+public:
+	enum Type {
+		ACTIVATEDQ,
+		ADDVAR,
+		AGAIN,
+		AND,
+		ANDV,
+		COLLIDEDQ,
+		DELAY,
+		DESTROY,
+		DESTROYEDQ,
+		ELSE,
+		END,
+		ENDGAME,
+		ENDIF,
+		EXECUTE,
+		GOTO,
+		IF,
+		INVIS,
+		INVISQ,
+		INCLUDE,
+		LOOP,
+		MODE,
+		MOVE,
+		MOVETO,
+		NOTV,
+		OR,
+		ORV,
+		GETXPOS,
+		GETYPOS,
+		GETZPOS,
+		PRINT,
+		RESTART,
+		REDRAW,
+		REMOVE,
+		SOUND,
+		SETVAR,
+		SHOTQ,
+		START,
+		STARTANIM,
+		STOPANIM,
+		SUBVAR,
+		SYNCSND,
+		THEN,
+		TIMERQ,
+		TOGVIS,
+		TRIGANIM,
+		UPDATEI,
+		VAREQ,
+		VARGQ,
+		VARLQ,
+		VISQ,
+		VIS,
+		WAIT,
+		WAITTRIG,
+		COMMA,
+		OPENBRACKET,
+		CLOSEBRACKET,
+		CONSTANT,
+		VARIABLE,
+		STRINGLITERAL,
+		UNKNOWN,
+		ENDOFFILE,
+		SETBIT,
+		CLEARBIT,
+		TOGGLEBIT,
+		SWAPJET,
+		BITNOTEQ,
+		VARNOTEQ
+	};
+
+	int32_t getValue(CGameState &, int32_t suggestedValue = 0);
+	Type getType();
+
+	Token();
+	Token(Type type);
+	Token(Common::String &string);
+	Token(Type type, int32_t value);
+	Token(const Token &other);
+	Token &operator=(const Token &rhs);
+
+private:
+	Type type;
+
+	int32_t value;
+	Common::String string;
 };
 
 #endif /* defined(__Phantasma__Token__) */
diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
index b6bbd89ed9b..1004e51f74a 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/16bitBinaryLoader.cpp
@@ -6,118 +6,102 @@
 //  Copyright (c) 2013 Thomas Harte. All rights reserved.
 //
 
-
 //#include "freescape/language/parser.h"
 
-#include "common/debug.h"
 #include "common/array.h"
+#include "common/debug.h"
 #include "common/file.h"
 
 #include "freescape/area.h"
-#include "freescape/objects/object.h"
-#include "freescape/objects/geometricobject.h"
-#include "freescape/loaders/16bitBinaryLoader.h"
 #include "freescape/language/16bitDetokeniser.h"
 #include "freescape/language/instruction.h"
 #include "freescape/language/parser.h"
+#include "freescape/loaders/16bitBinaryLoader.h"
+#include "freescape/objects/geometricobject.h"
+#include "freescape/objects/object.h"
 
-class StreamLoader
-{
-	private:
-
-		Common::Array<uint8>::size_type bytePointer;
-		Common::Array<uint8> binary;
-		uint8 readMaskByte1;
-		uint8 readMaskByte2;
-
-	public:
-		StreamLoader(Common::Array <uint8> &_binary)
-		{
-			binary = _binary;
-			bytePointer = 0;
-			readMaskByte1 = 0;
-			readMaskByte2 = 0;
-		}
+class StreamLoader {
+private:
+	Common::Array<uint8>::size_type bytePointer;
+	Common::Array<uint8> binary;
+	uint8 readMaskByte1;
+	uint8 readMaskByte2;
+
+public:
+	StreamLoader(Common::Array<uint8> &_binary) {
+		binary = _binary;
+		bytePointer = 0;
+		readMaskByte1 = 0;
+		readMaskByte2 = 0;
+	}
 
-		uint8 get8()
-		{
-			if(!eof())
-			{
-				uint8 sourceByte = binary[bytePointer];
-				
-				if(bytePointer&1)
-					sourceByte ^= readMaskByte2;
-				else
-					sourceByte ^= readMaskByte1;
-
-				bytePointer++;
-				return sourceByte;
-			} else
-				error("eof");
-
-			return 0;
-		}
+	uint8 get8() {
+		if (!eof()) {
+			uint8 sourceByte = binary[bytePointer];
 
-		uint16 get16()
-		{
-			uint16 result = (uint16)(get8() << 8);
-			result |= get8();
-			return result;
-		}
+			if (bytePointer & 1)
+				sourceByte ^= readMaskByte2;
+			else
+				sourceByte ^= readMaskByte1;
 
-		uint32 get32()
-		{
-			uint32 result = (uint32)(get16() << 16);
-			result |= get16();
-			return result;
-		}
+			bytePointer++;
+			return sourceByte;
+		} else
+			error("eof");
 
-		bool eof()
-		{
-			return bytePointer >= binary.size();
-		}
-		
-		void alignPointer()
-		{
-			if(bytePointer&1) bytePointer++;
-		}
-		
-		void skipBytes(Common::Array<uint8>::size_type numberOfBytes)
-		{
-			bytePointer += numberOfBytes;
-		}
+		return 0;
+	}
 
-		Common::Array<uint8> *nextBytes(Common::Array<uint8>::size_type numberOfBytes)
-		{
-			Common::Array<uint8> *returnBuffer(new Common::Array<uint8>);
-			debug("give me the next %d bytes", numberOfBytes);
+	uint16 get16() {
+		uint16 result = (uint16)(get8() << 8);
+		result |= get8();
+		return result;
+	}
 
-			while(numberOfBytes--)
-				returnBuffer->push_back(get8());
+	uint32 get32() {
+		uint32 result = (uint32)(get16() << 16);
+		result |= get16();
+		return result;
+	}
 
-			return returnBuffer;
-		}
+	bool eof() {
+		return bytePointer >= binary.size();
+	}
 
-		Common::Array<uint8>::size_type getFileOffset()
-		{
-			return bytePointer;
-		}
+	void alignPointer() {
+		if (bytePointer & 1)
+			bytePointer++;
+	}
 
-		void setFileOffset(Common::Array<uint8>::size_type newOffset)
-		{
-			bytePointer = newOffset;
-		}
-		
-		void setReadMask(uint8 byte1, uint8 byte2)
-		{
-			readMaskByte1 = byte1;
-			readMaskByte2 = byte2;
-		}
-};
+	void skipBytes(Common::Array<uint8>::size_type numberOfBytes) {
+		bytePointer += numberOfBytes;
+	}
+
+	Common::Array<uint8> *nextBytes(Common::Array<uint8>::size_type numberOfBytes) {
+		Common::Array<uint8> *returnBuffer(new Common::Array<uint8>);
+		debug("give me the next %d bytes", numberOfBytes);
+
+		while (numberOfBytes--)
+			returnBuffer->push_back(get8());
+
+		return returnBuffer;
+	}
+
+	Common::Array<uint8>::size_type getFileOffset() {
+		return bytePointer;
+	}
 
+	void setFileOffset(Common::Array<uint8>::size_type newOffset) {
+		bytePointer = newOffset;
+	}
+
+	void setReadMask(uint8 byte1, uint8 byte2) {
+		readMaskByte1 = byte1;
+		readMaskByte2 = byte2;
+	}
+};
 
-static Object *loadObject(StreamLoader &stream)
-{
+static Object *loadObject(StreamLoader &stream) {
 	// get object flags and type
 	uint8 objectFlags = stream.get8();
 	Object::Type objectType = (Object::Type)stream.get8();
@@ -138,12 +122,12 @@ static Object *loadObject(StreamLoader &stream)
 
 	// grab location, size
 	Vector3d position, size;
-	position.x		= stream.get16();
-	position.y		= stream.get16();
-	position.z		= stream.get16();
-	size.x			= stream.get16();
-	size.y			= stream.get16();
-	size.z			= stream.get16();
+	position.x = stream.get16();
+	position.y = stream.get16();
+	position.z = stream.get16();
+	size.x = stream.get16();
+	size.y = stream.get16();
+	size.z = stream.get16();
 
 	// object ID
 	uint16 objectID = stream.get16();
@@ -153,64 +137,56 @@ static Object *loadObject(StreamLoader &stream)
 	// length beyond here
 	uint32 byteSizeOfObject = (uint32)(stream.get16() << 1) - 20;
 
-	debug("Object %d ; type %d ; flags %d ; size %d" , objectID , (int)objectType, (int)objectFlags, byteSizeOfObject);
-
-	switch(objectType)
-	{
-		default:
-		{
-			// read the appropriate number of colours
-			int numberOfColours = GeometricObject::numberOfColoursForObjectOfType(objectType);
-			Common::Array<uint8> *colours = new Common::Array<uint8>;
-			for(uint8 colour = 0; colour < numberOfColours; colour++)
-			{
-				colours->push_back(stream.get8());
-				byteSizeOfObject--;
-			}
-
-			// read extra vertices if required...
-			int numberOfOrdinates = GeometricObject::numberOfOrdinatesForType(objectType);
-			debug("number of ordinates %d", numberOfOrdinates);
-			Common::Array<uint16> *ordinates = nullptr;
+	debug("Object %d ; type %d ; flags %d ; size %d", objectID, (int)objectType, (int)objectFlags, byteSizeOfObject);
 
-			if(numberOfOrdinates)
-			{
-				ordinates = new Common::Array<uint16>;
+	switch (objectType) {
+	default: {
+		// read the appropriate number of colours
+		int numberOfColours = GeometricObject::numberOfColoursForObjectOfType(objectType);
+		Common::Array<uint8> *colours = new Common::Array<uint8>;
+		for (uint8 colour = 0; colour < numberOfColours; colour++) {
+			colours->push_back(stream.get8());
+			byteSizeOfObject--;
+		}
 
-				for(int ordinate = 0; ordinate < numberOfOrdinates; ordinate++)
-				{
-					ordinates->push_back(stream.get16());
-					byteSizeOfObject -= 2;
-				}
-			}
+		// read extra vertices if required...
+		int numberOfOrdinates = GeometricObject::numberOfOrdinatesForType(objectType);
+		debug("number of ordinates %d", numberOfOrdinates);
+		Common::Array<uint16> *ordinates = nullptr;
 
-			// grab the object condition, if there is one
-			FCLInstructionVector instructions;
-			if(byteSizeOfObject)
-			{
-				Common::Array<uint8> *conditionData = stream.nextBytes(byteSizeOfObject);
+		if (numberOfOrdinates) {
+			ordinates = new Common::Array<uint16>;
 
-				Common::String *conditionSource = detokenise16bitCondition(*conditionData);
-				//instructions = getInstructions(conditionSource);
+			for (int ordinate = 0; ordinate < numberOfOrdinates; ordinate++) {
+				ordinates->push_back(stream.get16());
+				byteSizeOfObject -= 2;
 			}
-			byteSizeOfObject = 0;
-
-			// create an object
-			return
-				new GeometricObject(
-					objectType,
-					objectID,
-					position,
-					size,
-					colours,
-					ordinates,
-					instructions);
 		}
-		break;
 
-		case Object::Entrance:
-		case Object::Sensor:
-		case Object::Group:
+		// grab the object condition, if there is one
+		FCLInstructionVector instructions;
+		if (byteSizeOfObject) {
+			Common::Array<uint8> *conditionData = stream.nextBytes(byteSizeOfObject);
+
+			Common::String *conditionSource = detokenise16bitCondition(*conditionData);
+			//instructions = getInstructions(conditionSource);
+		}
+		byteSizeOfObject = 0;
+
+		// create an object
+		return new GeometricObject(
+			objectType,
+			objectID,
+			position,
+			size,
+			colours,
+			ordinates,
+			instructions);
+	} break;
+
+	case Object::Entrance:
+	case Object::Sensor:
+	case Object::Group:
 		break;
 	}
 
@@ -223,29 +199,26 @@ static Object *loadObject(StreamLoader &stream)
 	stream.skipBytes(byteSizeOfObject);
 
 	return nullptr;
-	
 }
 
-Area *loadArea(StreamLoader &stream)
-{
+Area *loadArea(StreamLoader &stream) {
 	// the lowest bit of this value seems to indicate
 	// horizon on or off; this is as much as I currently know
-	uint16 skippedValue		= stream.get16();
-	uint16 numberOfObjects	= stream.get16();
-	uint16 areaNumber			= stream.get16();
+	uint16 skippedValue = stream.get16();
+	uint16 numberOfObjects = stream.get16();
+	uint16 areaNumber = stream.get16();
 
 	debug("Area %d", areaNumber);
 	debug("Skipped value %d", skippedValue);
 	debug("Objects: %d", numberOfObjects);
 
 	// I've yet to decipher this fully
-	uint16 horizonColour	= stream.get16();
+	uint16 horizonColour = stream.get16();
 	debug("Horizon colour %x", (int)horizonColour);
 
 	// this is just a complete guess
-	for(int paletteEntry = 0; paletteEntry < 22; paletteEntry++)
-	{
-		uint8 paletteColour		= stream.get8();
+	for (int paletteEntry = 0; paletteEntry < 22; paletteEntry++) {
+		uint8 paletteColour = stream.get8();
 		debug("Palette colour (?) %x", (int)paletteColour);
 	}
 
@@ -257,18 +230,13 @@ Area *loadArea(StreamLoader &stream)
 
 	// get the objects or whatever; entrances use a unique numbering
 	// system and have the high bit of their IDs set in the original file
-	for(uint16 object = 0; object < numberOfObjects; object++)
-	{
+	for (uint16 object = 0; object < numberOfObjects; object++) {
 		Object *newObject = loadObject(stream);
 
-		if(newObject)
-		{
-			if(newObject->getType() == Object::Entrance)
-			{
+		if (newObject) {
+			if (newObject->getType() == Object::Entrance) {
 				(*entrancesByID)[newObject->getObjectID() & 0x7fff] = newObject;
-			}
-			else
-			{
+			} else {
 				(*objectsByID)[newObject->getObjectID()] = newObject;
 			}
 		}
@@ -277,20 +245,19 @@ Area *loadArea(StreamLoader &stream)
 	return (new Area(areaNumber, objectsByID, entrancesByID));
 }
 
-Game *load16bitBinary(Common::String filename)
-{
+Game *load16bitBinary(Common::String filename) {
 	Common::File *file = new Common::File();
 
-    if (!file->open(filename)) {
-        delete file;
-    	return NULL;
-    }
+	if (!file->open(filename)) {
+		delete file;
+		return NULL;
+	}
 
 	const uint32 fileSize = file->size();
 	byte *buf = (byte *)malloc(fileSize);
 	file->read(buf, fileSize);
 
-	Common::Array <uint8> binary;
+	Common::Array<uint8> binary;
 
 	uint32 i = 0;
 	while (i < fileSize) {
@@ -308,25 +275,21 @@ Game *load16bitBinary(Common::String filename)
 	uint16 platformID = streamLoader.get16();
 	debug("%d", platformID);
 
-	if(
-//		(platformID != 0x4120) && (platformID != 0x5043)
-		(platformID == 12428) || (platformID == 51553)
-	)
-	{
+	if (
+		//		(platformID != 0x4120) && (platformID != 0x5043)
+		(platformID == 12428) || (platformID == 51553)) {
 		// TODO: record original platform type, so we can decode the palette
 		// and possibly the border properly
 		//cout << "AMIGA" << endl;
 
 		streamLoader.setReadMask((platformID >> 8) ^ 'A', (platformID & 0xff) ^ 'M');
-	}
-	else
-	{
+	} else {
 		debug("DOS");
 		// find DOS end of file and consume it
-		while(!streamLoader.eof()) {
+		while (!streamLoader.eof()) {
 			uint8 b = streamLoader.get8();
 			if (b == 0x1a)
-			   break;
+				break;
 		}
 		streamLoader.get8();
 
@@ -343,10 +306,10 @@ Game *load16bitBinary(Common::String filename)
 
 		// check that the next two bytes are "PC", then
 		// skip the number that comes after
-		if(streamLoader.get8() != 'C' || streamLoader.get8() != 'P') return nullptr;
+		if (streamLoader.get8() != 'C' || streamLoader.get8() != 'P')
+			return nullptr;
 	}
 
-	
 	// skip an unknown meaning
 	streamLoader.get16();
 
@@ -357,45 +320,44 @@ Game *load16bitBinary(Common::String filename)
 
 	debug("Number of areas: %d", numberOfAreas);
 
-	uint16 windowCentreX	= streamLoader.get16();
-	uint16 windowCentreY	= streamLoader.get16();
-	uint16 windowWidth	= streamLoader.get16();
-	uint16 windowHeight	= streamLoader.get16();
+	uint16 windowCentreX = streamLoader.get16();
+	uint16 windowCentreY = streamLoader.get16();
+	uint16 windowWidth = streamLoader.get16();
+	uint16 windowHeight = streamLoader.get16();
 
-	
 	debug("Window centre: (%d, %d)", windowCentreX, windowCentreY);
-	debug("Window size: (%d, %d)", windowWidth,  windowHeight);
+	debug("Window size: (%d, %d)", windowWidth, windowHeight);
 
-	uint16 scaleX	= streamLoader.get16();
-	uint16 scaleY	= streamLoader.get16();
-	uint16 scaleZ	= streamLoader.get16();
+	uint16 scaleX = streamLoader.get16();
+	uint16 scaleY = streamLoader.get16();
+	uint16 scaleZ = streamLoader.get16();
 
 	debug("Scale %d, %d, %d", scaleX, scaleY, scaleZ);
-	uint16 timerReload	= streamLoader.get16();
+	uint16 timerReload = streamLoader.get16();
 
 	debug("Timer: every %d 50Hz frames", timerReload);
 
-	uint16 maximumActivationDistance	= streamLoader.get16();
-	uint16 maximumFallDistance		= streamLoader.get16();
-	uint16 maximumClimbDistance		= streamLoader.get16();
+	uint16 maximumActivationDistance = streamLoader.get16();
+	uint16 maximumFallDistance = streamLoader.get16();
+	uint16 maximumClimbDistance = streamLoader.get16();
 
 	debug("Maximum activation distance: %d", maximumActivationDistance);
-	debug("Maximum fall distance: %d",  maximumFallDistance);
+	debug("Maximum fall distance: %d", maximumFallDistance);
 	debug("Maximum climb distance: %d", maximumClimbDistance);
 
-	uint16 startArea					= streamLoader.get16();
-	uint16 startEntrance				= streamLoader.get16();
+	uint16 startArea = streamLoader.get16();
+	uint16 startEntrance = streamLoader.get16();
 
 	debug("Start at entrance %d in area %d", startEntrance, startArea);
 
-	uint16 playerHeight				= streamLoader.get16();
-	uint16 playerStep				= streamLoader.get16();
-	uint16 playerAngle				= streamLoader.get16();
+	uint16 playerHeight = streamLoader.get16();
+	uint16 playerStep = streamLoader.get16();
+	uint16 playerAngle = streamLoader.get16();
 
 	debug("Height %d, step %d, angle %d)", playerHeight, playerStep, playerAngle);
 
-	uint16 startVehicle				= streamLoader.get16();
-	uint16 executeGlobalCondition	= streamLoader.get16();
+	uint16 startVehicle = streamLoader.get16();
+	uint16 executeGlobalCondition = streamLoader.get16();
 
 	debug("Start vehicle %d, execute global condition %d", startVehicle, executeGlobalCondition);
 
@@ -441,13 +403,12 @@ Game *load16bitBinary(Common::String filename)
 	// the number of shorts from the 'PC' tag, so multiply by
 	// two for bytes. Each is four bytes
 	uint32 *fileOffsetForArea = new uint32[numberOfAreas];
-	for(uint16 area = 0; area < numberOfAreas; area++)
+	for (uint16 area = 0; area < numberOfAreas; area++)
 		fileOffsetForArea[area] = (uint32)streamLoader.get32() << 1;
 
 	// now come the global conditions
 	uint16 numberOfGlobalConditions = streamLoader.get16();
-	for(uint16 globalCondition = 0; globalCondition < numberOfGlobalConditions; globalCondition++)
-	{
+	for (uint16 globalCondition = 0; globalCondition < numberOfGlobalConditions; globalCondition++) {
 		// 12 bytes for the name of the condition;
 		// we don't care
 		streamLoader.skipBytes(12);
@@ -459,26 +420,23 @@ Game *load16bitBinary(Common::String filename)
 		// get the condition
 		Common::Array<uint8> *conditionData = streamLoader.nextBytes(lengthOfCondition);
 
-		debug("Global condition %d", globalCondition+1);
+		debug("Global condition %d", globalCondition + 1);
 		debug("%s", detokenise16bitCondition(*conditionData)->c_str());
 	}
 
 	// grab the areas
 	AreaMap *areaMap = new AreaMap;
-	for(uint16 area = 0; area < numberOfAreas; area++)
-	{
+	for (uint16 area = 0; area < numberOfAreas; area++) {
 		debug("Area offset %d", fileOffsetForArea[area]);
 
 		streamLoader.setFileOffset(fileOffsetForArea[area] + baseOffset);
 		Area *newArea = loadArea(streamLoader);
-		
-		if(newArea)
-		{
+
+		if (newArea) {
 			(*areaMap)[newArea->getAreaID()] = newArea;
 		}
-
 	}
-	streamLoader.setFileOffset(fileOffsetForArea[numberOfAreas-1] + baseOffset);
+	streamLoader.setFileOffset(fileOffsetForArea[numberOfAreas - 1] + baseOffset);
 
 	delete[] fileOffsetForArea;
 	return new Game(areaMap);
diff --git a/engines/freescape/loaders/16bitBinaryLoader.h b/engines/freescape/loaders/16bitBinaryLoader.h
index 821ee2b799a..8905b1b7a37 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.h
+++ b/engines/freescape/loaders/16bitBinaryLoader.h
@@ -16,7 +16,6 @@
 
 #include "freescape/game.h"
 
-
 using namespace std;
 
 Game *load16bitBinary(Common::String);
diff --git a/engines/freescape/metaengine.cpp b/engines/freescape/metaengine.cpp
index 821b7448c50..9981b9ce560 100644
--- a/engines/freescape/metaengine.cpp
+++ b/engines/freescape/metaengine.cpp
@@ -1,5 +1,5 @@
-#include "freescape/freescape.h"
 #include "engines/advancedDetector.h"
+#include "freescape/freescape.h"
 
 class FreescapeMetaEngine : public AdvancedMetaEngine {
 public:
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index 0fb08675454..0b8d5b50209 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -13,59 +13,61 @@
 #pragma mark -
 #pragma mark Static Getters
 
-int GeometricObject::numberOfColoursForObjectOfType(Type type)
-{
-	switch(type)
-	{
-		default:
-		case Entrance:
-		case Group:
-		case Sensor:			return 0;
-
-		case Line:				return 2;
-
-		case Rectangle:
-		case Triangle:
-		case Quadrilateral:
-		case Pentagon:
-		case Hexagon:			return 2;
-
-		case Cube:
-		case EastPyramid:
-		case WestPyramid:
-		case UpPyramid:
-		case DownPyramid:
-		case NorthPyramid:
-		case SouthPyramid:		return 6;
+int GeometricObject::numberOfColoursForObjectOfType(Type type) {
+	switch (type) {
+	default:
+	case Entrance:
+	case Group:
+	case Sensor:
+		return 0;
+
+	case Line:
+		return 2;
+
+	case Rectangle:
+	case Triangle:
+	case Quadrilateral:
+	case Pentagon:
+	case Hexagon:
+		return 2;
+
+	case Cube:
+	case EastPyramid:
+	case WestPyramid:
+	case UpPyramid:
+	case DownPyramid:
+	case NorthPyramid:
+	case SouthPyramid:
+		return 6;
 	}
 }
 
-int GeometricObject::numberOfOrdinatesForType(Type type)
-{
-	switch(type)
-	{
-		default:
-		case Entrance:
-		case Group:
-		case Rectangle:
-		case Sensor:			return 0;
-
-		case EastPyramid:
-		case WestPyramid:
-		case UpPyramid:
-		case DownPyramid:
-		case NorthPyramid:
-		case SouthPyramid:		return 4;
-
-		case Line:
-		case Triangle:
-		case Quadrilateral:
-		case Pentagon:
-		case Hexagon:			return 3*(2 + type - Line);
+int GeometricObject::numberOfOrdinatesForType(Type type) {
+	switch (type) {
+	default:
+	case Entrance:
+	case Group:
+	case Rectangle:
+	case Sensor:
+		return 0;
+
+	case EastPyramid:
+	case WestPyramid:
+	case UpPyramid:
+	case DownPyramid:
+	case NorthPyramid:
+	case SouthPyramid:
+		return 4;
+
+	case Line:
+	case Triangle:
+	case Quadrilateral:
+	case Pentagon:
+	case Hexagon:
+		return 3 * (2 + type - Line);
 	}
 }
 
-
 #pragma mark -
 #pragma mark Construction/Destruction
 
@@ -76,25 +78,24 @@ GeometricObject::GeometricObject(
 	const Vector3d &_size,
 	Common::Array<uint8> *_colours,
 	Common::Array<uint16> *_ordinates,
-	FCLInstructionVector _condition)
-{
+	FCLInstructionVector _condition) {
 	type = _type;
 	objectID = _objectID;
 	origin = _origin;
 	size = _size;
 
-	if(_colours)	colours		= new Common::Array<uint8>(*_colours);
-	if(_ordinates)	ordinates	= new Common::Array<uint16>(*_ordinates);
+	if (_colours)
+		colours = new Common::Array<uint8>(*_colours);
+	if (_ordinates)
+		ordinates = new Common::Array<uint16>(*_ordinates);
 	condition = _condition;
 }
 
-GeometricObject::~GeometricObject()
-{
+GeometricObject::~GeometricObject() {
 }
 
-bool GeometricObject::isDrawable()								{	return true;	}
-bool GeometricObject::isPlanar()
-{
+bool GeometricObject::isDrawable() { return true; }
+bool GeometricObject::isPlanar() {
 	Type type = this->getType();
 	return (type >= Object::Line) || !size.x || !size.y || !size.z;
 }
diff --git a/engines/freescape/objects/geometricobject.h b/engines/freescape/objects/geometricobject.h
index e9d681297ef..cb2b31e46d4 100644
--- a/engines/freescape/objects/geometricobject.h
+++ b/engines/freescape/objects/geometricobject.h
@@ -10,51 +10,49 @@
 #define __Phantasma__GeometricObject__
 
 #include "common/array.h"
-#include "freescape/objects/object.h"
 #include "freescape/language/instruction.h"
+#include "freescape/objects/object.h"
 
 class BatchDrawer;
-class GeometricObject: public Object
-{
-	public:
-
-		static int numberOfColoursForObjectOfType(Type type);
-		static int numberOfOrdinatesForType(Type type);
+class GeometricObject : public Object {
+public:
+	static int numberOfColoursForObjectOfType(Type type);
+	static int numberOfOrdinatesForType(Type type);
 
-		/*static void setupOpenGL();
+	/*static void setupOpenGL();
 		static void setProjectionMatrix(const GLfloat *projectionMatrix);
 		static void setViewMatrix(const GLfloat *projectionMatrix);
 
 		static VertexBuffer *newVertexBuffer();
 		static DrawElementsBuffer *newDrawElementsBuffer();*/
 
-		GeometricObject(
-			Type type,
-			uint16 objectID,
-			const Vector3d &origin,
-			const Vector3d &size,
-			Common::Array<uint8> *colours,
-			Common::Array<uint16> *ordinates,
-			FCLInstructionVector condition);
-		virtual ~GeometricObject();
-
-		/*void setupOpenGL(VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer);
+	GeometricObject(
+		Type type,
+		uint16 objectID,
+		const Vector3d &origin,
+		const Vector3d &size,
+		Common::Array<uint8> *colours,
+		Common::Array<uint16> *ordinates,
+		FCLInstructionVector condition);
+	virtual ~GeometricObject();
+
+	/*void setupOpenGL(VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer);
 		void draw(VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer, BatchDrawer *areaBatchDrawer, bool allowPolygonOffset);*/
-		bool isDrawable();
-		bool isPlanar();
+	bool isDrawable();
+	bool isPlanar();
 
-	private:
-		/*static GLuint openGLProgram;
+private:
+	/*static GLuint openGLProgram;
 		static GLuint compileShader(const GLchar *source, GLenum shaderType);
 		static GLint viewMatrixUniform, projectionMatrixUniform;*/
 
-		FCLInstructionVector condition;
-		Common::Array<uint8> *colours;
-		Common::Array<uint16> *ordinates;
+	FCLInstructionVector condition;
+	Common::Array<uint8> *colours;
+	Common::Array<uint16> *ordinates;
 
-		size_t drawElementsStartIndex;
-		//GLsizei drawElementsCount;
-		//GLenum drawElementsMode;
+	size_t drawElementsStartIndex;
+	//GLsizei drawElementsCount;
+	//GLenum drawElementsMode;
 };
 
 #endif /* defined(__Phantasma__GeometricObject__) */
diff --git a/engines/freescape/objects/object.cpp b/engines/freescape/objects/object.cpp
index 7ff4dbd63af..b11389a7ab8 100644
--- a/engines/freescape/objects/object.cpp
+++ b/engines/freescape/objects/object.cpp
@@ -8,14 +8,14 @@
 
 #include "freescape/objects/object.h"
 
-Object::Type Object::getType()	{	return type;		}
-uint16 Object::getObjectID()	{	return objectID;	}
+Object::Type Object::getType() { return type; }
+uint16 Object::getObjectID() { return objectID; }
 //Vector3d Object::getOrigin()	{	return origin;		}
 //Vector3d Object::getSize()		{	return size;		}
 
 //void Object::setupOpenGL(VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer)					{}
 //void Object::draw(VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer, BatchDrawer *batchDrawer, bool allowPolygonOffset)	{}
-bool Object::isDrawable()								{	return false;	}
-bool Object::isPlanar()									{	return false;	}
+bool Object::isDrawable() { return false; }
+bool Object::isPlanar() { return false; }
 
-Object::~Object()				{}
+Object::~Object() {}
diff --git a/engines/freescape/objects/object.h b/engines/freescape/objects/object.h
index 1eda9b135d3..934e37ac528 100644
--- a/engines/freescape/objects/object.h
+++ b/engines/freescape/objects/object.h
@@ -14,16 +14,16 @@
 //#include <vector>
 //#include "freescape/language/instruction.h"
 
-typedef struct Vector3d
-{
+typedef struct Vector3d {
 	uint16 x, y, z;
-	uint16 &operator [](int index)
-	{
-		switch(index)
-		{
-			default: return x;
-			case 1: return y;
-			case 2: return z;
+	uint16 &operator[](int index) {
+		switch (index) {
+		default:
+			return x;
+		case 1:
+			return y;
+		case 2:
+			return z;
 		}
 	};
 } Vector3d;
@@ -31,57 +31,55 @@ typedef struct Vector3d
 class VertexBuffer;
 class DrawElementsBuffer;
 class BatchDrawer;
-class Object
-{
-	public:
-		typedef enum
-		{
-			Entrance		= 0,
-			Cube			= 1,
-			Sensor			= 2,
-			Rectangle		= 3,
+class Object {
+public:
+	typedef enum {
+		Entrance = 0,
+		Cube = 1,
+		Sensor = 2,
+		Rectangle = 3,
 
-			EastPyramid		= 4,
-			WestPyramid		= 5,
-			UpPyramid		= 6,
-			DownPyramid		= 7,
-			NorthPyramid	= 8,
-			SouthPyramid	= 9,
+		EastPyramid = 4,
+		WestPyramid = 5,
+		UpPyramid = 6,
+		DownPyramid = 7,
+		NorthPyramid = 8,
+		SouthPyramid = 9,
 
-			Line			= 10,
-			Triangle		= 11,
-			Quadrilateral	= 12,
-			Pentagon		= 13,
-			Hexagon			= 14,
+		Line = 10,
+		Triangle = 11,
+		Quadrilateral = 12,
+		Pentagon = 13,
+		Hexagon = 14,
 
-			Group			= 15
-		} Type;
+		Group = 15
+	} Type;
 
-		Type		getType();
-		uint16	getObjectID();
-		Vector3d	getOrigin();
-		Vector3d	getSize();
+	Type getType();
+	uint16 getObjectID();
+	Vector3d getOrigin();
+	Vector3d getSize();
 
-		/*
+	/*
 		virtual void setupOpenGL(VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer);
 		virtual void draw(VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer, BatchDrawer *batchDrawer, bool allowPolygonOffset);
 		*/
-		virtual bool isDrawable();
-		virtual bool isPlanar();
+	virtual bool isDrawable();
+	virtual bool isPlanar();
 
-		virtual ~Object();
+	virtual ~Object();
 
-	protected:
-		Type type;
-		uint16 objectID;
-		Vector3d origin, size;
+protected:
+	Type type;
+	uint16 objectID;
+	Vector3d origin, size;
 };
 
 /*
-#include "GeometricObject.h"
 #include "Entrance.h"
-#include "Sensor.h"
+#include "GeometricObject.h"
 #include "Group.h"
+#include "Sensor.h"
 */
 
 #endif /* defined(__Phantasma__Object__) */


Commit: 7606960ec8c5a4a944ebd66b9a775960afc2fcc3
    https://github.com/scummvm/scummvm/commit/7606960ec8c5a4a944ebd66b9a775960afc2fcc3
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:34+01:00

Commit Message:
FREESCAPE: refactored old phantasma code

Changed paths:
    engines/freescape/detection.cpp
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/game.cpp
    engines/freescape/game.h
    engines/freescape/loaders/16bitBinaryLoader.cpp
    engines/freescape/loaders/16bitBinaryLoader.h
    engines/freescape/module.mk


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index 974c92c1d00..78694b83e8c 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -3,7 +3,8 @@
 
 namespace Freescape {
 static const PlainGameDescriptor freescapeGames[] = {
-	{"3dkit", "3D Kit Constructor example game"},
+	{"3dkit", "The 3D Kit Game"},
+	{"driller", "Driller"},
 	{0, 0}};
 
 static const ADGameDescription gameDescriptions[] = {
@@ -14,6 +15,14 @@ static const ADGameDescription gameDescriptions[] = {
 	 Common::kPlatformDOS,
 	 ADGF_NO_FLAGS,
 	 GUIO1(GUIO_NOMIDI)},
+
+	{"Driller",
+	 0,
+	 AD_ENTRY1s("DRILLE.EXE", "eb7e9e0acb72e30cf6e9ed20a6480e7a", 51944),
+	 Common::EN_ANY,
+	 Common::kPlatformDOS,
+	 ADGF_NO_FLAGS,
+	 GUIO1(GUIO_NOMIDI)},
 	AD_TABLE_END_MARKER};
 } // End of namespace Freescape
 
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 97349bc59a5..a0de587f676 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -23,21 +23,30 @@
 namespace Freescape {
 
 FreescapeEngine::FreescapeEngine(OSystem *syst)
-	: Engine(syst) {
+	: Engine(syst), _screenW(320), _screenH(200), _border(nullptr) {
 	// Put your engine in a sane state, but do nothing big yet;
 	// in particular, do not load data from files; rather, if you
 	// need to do such things, do them from run().
 
 	// Do not initialize graphics here
 	// Do not initialize audio devices here
+	_hasReceivedTime = false;
 
-	// However this is the place to specify all default directories
-	const Common::FSNode gameDataDir(ConfMan.get("path"));
-	SearchMan.addSubDirectoryMatching(gameDataDir, "sound");
+	_rotation[0] = 0.0f;
+	_rotation[1] = 0.0f;
+	_rotation[2] = 0.0f;
+
+	_position[0] = 1000.0f;
+	_position[1] = 300.0f;
+	_position[2] = 1000.0f;
+
+	_velocity[0] = 0.0f;
+	_velocity[1] = 0.0f;
+	_velocity[2] = 0.0f;
 
 	// Here is the right place to set up the engine specific debug channels
-	DebugMan.addDebugChannel(kQuuxDebugExample, "example", "this is just an example for a engine specific debug channel");
-	DebugMan.addDebugChannel(kQuuxDebugExample2, "example2", "also an example");
+	DebugMan.addDebugChannel(kFreescapeDebug, "example", "this is just an example for a engine specific debug channel");
+	DebugMan.addDebugChannel(kFreescapeDebug2, "example2", "also an example");
 
 	// Don't forget to register your random source
 	_rnd = new Common::RandomSource("freescape");
@@ -50,11 +59,18 @@ FreescapeEngine::~FreescapeEngine() {
 
 	// Dispose your resources here
 	delete _rnd;
+	delete _areasByAreaID;
+	delete _border;
 
 	// Remove all of our debug levels here
 	DebugMan.clearAllDebugChannels();
 }
 
+void FreescapeEngine::drawBorder() {
+	g_system->copyRectToScreen((const void *) _border->data(), _screenW, 0, 0, _screenW, _screenH);
+	g_system->updateScreen();
+}
+
 Common::Error FreescapeEngine::run() {
 	// Initialize graphics using following:
 	initGraphics(320, 200);
@@ -74,42 +90,23 @@ Common::Error FreescapeEngine::run() {
 	//OSystem::kTransactionSizeChangeFailed here
 	//_system->endGFXTransaction();
 
-	Game *_game = load16bitBinary("3DKIT.RUN");
-	Common::File *file = new Common::File();
-
-	if (!file->open("3DKIT.RUN")) {
-		delete file;
-		return Common::kNoError;
-	}
+	Binary binary = load16bitBinary("3DKIT.RUN");
+	debug("%s", _targetName.c_str());
 
-	const int32 fileSize = file->size();
-	byte *buf = (byte *)malloc(fileSize);
-	file->read(buf, fileSize);
+	_areasByAreaID = binary.areasByAreaID;
+	_border = binary.border;
 
-	_pixelFormat = g_system->getScreenFormat();
 	// 16 colors palette from ultima
 	static const byte PALETTE[16][3] = {
 		{0, 0, 0}, {0xe0, 0xc0, 0x70}, {0xb0, 0x80, 0x40}, {0x80, 0x60, 0x10}, {0x50, 0x30, 0x00}, {0x20, 0x80, 0xd0}, {0x20, 0x50, 0xb0}, {0x20, 0x30, 0x70}, {0x30, 0x40, 0x30}, {0x30, 0x30, 0x30}, {0x40, 0x40, 0x40}, {0x60, 0x60, 0x60}, {0x70, 0x70, 0x70}, {0x90, 0x90, 0x90}, {0xa0, 0xa0, 0xa0}, {0xc0, 0xc0, 0xc0}};
 	g_system->getPaletteManager()->setPalette(&PALETTE[0][0], 0, 16);
-
-	int i = 0;
-	byte *p = buf;
-
-	while (i < fileSize - 4) {
-		if (*((uint32 *)p) == 0xfa002445) {
-			debug("Border found at %x", i);
-			g_system->copyRectToScreen((const void *)p, 320, 0, 0, 320, 200);
-		}
-		p++;
-		i++;
-	}
-
+	
 	// Create debugger console. It requires GFX to be initialized
-	Console *console = new Console(this);
-	setDebugger(console);
+	//Console *console = new Console(this);
+	//setDebugger(console);
 
 	debug("FreescapeEngine::init");
-
+	drawBorder();
 	// Simple main event loop
 	Common::Event evt;
 	while (!shouldQuit()) {
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index c52d7d20481..3f0985ccd93 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -8,16 +8,23 @@
 #include "graphics/surface.h"
 #include "graphics/palette.h"
 
+#include "freescape/area.h"
+
 namespace Freescape {
 
+typedef Common::HashMap<uint16, Area*> AreaMap;
+
+typedef struct Binary {
+	AreaMap *areasByAreaID;
+    Common::Array<uint8> *border;
+} Binary;
+
 class Console;
 
 // our engine debug channels
 enum {
-	kQuuxDebugExample = 1 << 0,
-	kQuuxDebugExample2 = 1 << 1
-	// next new channel must be 1 << 2 (4)
-	// the current limitation is 32 debug channels (1 << 31 is the last one)
+	kFreescapeDebug = 1 << 0,
+	kFreescapeDebug2 = 1 << 1
 };
 
 class FreescapeEngine : public Engine {
@@ -25,6 +32,14 @@ private:
 	// We need random numbers
 	Common::RandomSource *_rnd;
 	Graphics::PixelFormat _pixelFormat;
+	int _screenW, _screenH;
+
+	Common::Array<uint8> *_border;
+	uint32 _timeOfLastTick;
+	bool _hasReceivedTime;
+	AreaMap *_areasByAreaID;
+	float _rotation[3], _velocity[3], _position[3];
+
 public:
 	FreescapeEngine(OSystem *syst);
 	~FreescapeEngine();
@@ -32,6 +47,7 @@ public:
 	Graphics::Surface *_compositeSurface;
 
 	Common::Error run() override;
+	void drawBorder();
 	bool hasFeature(EngineFeature f) const override;
 	bool canLoadGameStateCurrently() override { return true; }
 	bool canSaveGameStateCurrently() override { return true; }
diff --git a/engines/freescape/game.cpp b/engines/freescape/game.cpp
index 35710a8cab1..6c92c312542 100644
--- a/engines/freescape/game.cpp
+++ b/engines/freescape/game.cpp
@@ -6,26 +6,18 @@
 //  Copyright (c) 2013 Thomas Harte. All rights reserved.
 //
 
+#include "common/system.h"
+#include "common/debug.h"
+#include "graphics/surface.h"
+#include "graphics/palette.h"
+
 #include "freescape/game.h"
 //#include "GeometricObject.h"
 //#include "Matrix.h"
 //#include "VertexBuffer.h"
 
-Game::Game(AreaMap *_areasByAreaID) {
-	hasReceivedTime = false;
-	areasByAreaID = _areasByAreaID;
-
-	rotation[0] =
-		rotation[1] =
-			rotation[2] = 0.0f;
+Game::Game(Binary binary) {
 
-	position[0] = 1000.0f;
-	position[1] = 300.0f;
-	position[2] = 1000.0f;
-
-	velocity[0] =
-		velocity[1] =
-			velocity[2] = 0.0f;
 }
 
 Game::~Game() {
@@ -40,9 +32,13 @@ void Game::setAspectRatio(float aspectRatio)
 	Matrix projectionMatrix = Matrix::projectionMatrix(60.0f, aspectRatio, 1.0f, 14189.0f);
 	GeometricObject::setProjectionMatrix(projectionMatrix.contents);
 }
+*/
 
 void Game::draw()
 {
+	g_system->copyRectToScreen((const void *) _border->data(), _screenW, 0, 0, _screenW, _screenH);
+	g_system->updateScreen();
+	/*
 	// set the clear colour to salmon; we're not catching floor/ceiling
 	// colours yet
 	glClearColor(1.0f, 0.5f, 0.5f, 1.0f);
@@ -70,8 +66,10 @@ void Game::draw()
 	glEnable(GL_POLYGON_OFFSET_FILL);
 	(*areasByAreaID)[areaNumber]->draw(true, &batchDrawer);
 	batchDrawer.flush();
+	*/
 }
 
+/*
 void Game::setupOpenGL()
 {
 	GeometricObject::setupOpenGL();
diff --git a/engines/freescape/game.h b/engines/freescape/game.h
index 82e8a0ba971..d9c186269ef 100644
--- a/engines/freescape/game.h
+++ b/engines/freescape/game.h
@@ -10,20 +10,24 @@
 #define __Phantasma__Game__
 
 #include "common/hashmap.h"
+#include "common/array.h"
+#include "engines/util.h"
+
 #include "freescape/area.h"
+#include "freescape.h"
+
 //#include "Matrix.h"
 //#include "BatchDrawer.h"
 
-typedef Common::HashMap<uint16, Area*> AreaMap;
 class Game
 {
 	public:
 
-		Game(AreaMap *areasByAreaID);
+		Game(Binary binary);
 		virtual ~Game();
 
-		/*void setAspectRatio(float aspectRatio);
-		void draw();*/
+		//void setAspectRatio(float aspectRatio);
+		void draw();
 		//void advanceToTime(uint32 millisecondsSinceArbitraryMoment);
 
 		//void setupOpenGL();
@@ -32,6 +36,8 @@ class Game
 		//void setMovementVelocity(float x, float y, float z);
 		
 	private:
+		int _screenW, _screenH;
+		Common::Array<uint8> *_border;
 		uint32 timeOfLastTick;
 		bool hasReceivedTime;
 
diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
index 1004e51f74a..772b3b181fb 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/16bitBinaryLoader.cpp
@@ -20,6 +20,7 @@
 #include "freescape/objects/geometricobject.h"
 #include "freescape/objects/object.h"
 
+
 class StreamLoader {
 private:
 	Common::Array<uint8>::size_type bytePointer;
@@ -101,6 +102,8 @@ public:
 	}
 };
 
+namespace Freescape {
+
 static Object *loadObject(StreamLoader &stream) {
 	// get object flags and type
 	uint8 objectFlags = stream.get8();
@@ -245,12 +248,12 @@ Area *loadArea(StreamLoader &stream) {
 	return (new Area(areaNumber, objectsByID, entrancesByID));
 }
 
-Game *load16bitBinary(Common::String filename) {
+Binary load16bitBinary(Common::String filename) {
 	Common::File *file = new Common::File();
 
 	if (!file->open(filename)) {
 		delete file;
-		return NULL;
+		error("NULL");
 	}
 
 	const uint32 fileSize = file->size();
@@ -307,7 +310,7 @@ Game *load16bitBinary(Common::String filename) {
 		// check that the next two bytes are "PC", then
 		// skip the number that comes after
 		if (streamLoader.get8() != 'C' || streamLoader.get8() != 'P')
-			return nullptr;
+			error("invalid header");
 	}
 
 	// skip an unknown meaning
@@ -438,6 +441,21 @@ Game *load16bitBinary(Common::String filename) {
 	}
 	streamLoader.setFileOffset(fileOffsetForArea[numberOfAreas - 1] + baseOffset);
 
+	Common::Array<uint8>::size_type o;
+	Common::Array<uint8> *raw_border = nullptr;
+	while (!streamLoader.eof()) {
+		o = streamLoader.getFileOffset();
+		if (streamLoader.get32() == 0x452400fa) {
+			debug("Border found at %x", o);
+			raw_border = streamLoader.nextBytes(320*200);
+			break;
+		}
+		streamLoader.setFileOffset(o);
+		streamLoader.get8();
+	}
+
 	delete[] fileOffsetForArea;
-	return new Game(areaMap);
+	return Freescape::Binary{areaMap, raw_border};
 }
+
+}
\ No newline at end of file
diff --git a/engines/freescape/loaders/16bitBinaryLoader.h b/engines/freescape/loaders/16bitBinaryLoader.h
index 8905b1b7a37..3bd6c473981 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.h
+++ b/engines/freescape/loaders/16bitBinaryLoader.h
@@ -13,11 +13,12 @@
 //#include <vector>
 //#include <stdint.h>
 #include "common/str.h"
+#include "../freescape.h"
 
-#include "freescape/game.h"
+namespace Freescape {
 
-using namespace std;
+Binary load16bitBinary(Common::String);
 
-Game *load16bitBinary(Common::String);
+}
 
 #endif /* defined(__Phantasma___16bitBinaryLoader__) */
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index 0c74326a742..edc97b70470 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -3,7 +3,6 @@ MODULE := engines/freescape
 MODULE_OBJS := \
 	metaengine.o \
 	freescape.o \
-	game.o \
 	area.o \
 	objects/object.o \
 	objects/geometricobject.o \


Commit: b5df126667afbea821ad5b1621102cb9568e37f8
    https://github.com/scummvm/scummvm/commit/b5df126667afbea821ad5b1621102cb9568e37f8
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:34+01:00

Commit Message:
FREESCAPE: used clang-format to improve code style

Changed paths:
    engines/freescape/area.h
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/game.cpp
    engines/freescape/game.h
    engines/freescape/gamestate.h


diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index c8a971366f3..a77809e759e 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -17,32 +17,31 @@
 typedef Common::HashMap<uint16, Object *> ObjectMap;
 
 class BatchDrawer;
-class Area
-{
-	public:
-		Area(
-			uint16 areaID,
-			ObjectMap *objectsByID,
-			ObjectMap *entrancesByID);
-		virtual ~Area();
-
-		Object *objectWithID(uint16 objectID);
-		Object *entranceWithID(uint16 objectID);
-		uint16 getAreaID();
-
-		//void setupOpenGL();
-		//void draw(bool allowPolygonOffset, BatchDrawer *batchDrawer);
-
-	private:
-		uint16 areaID;
-		ObjectMap *objectsByID;
-		ObjectMap *entrancesByID;
-		Common::Array<Object *> drawableObjects;
-
-		Object *objectWithIDFromMap(ObjectMap *map, uint16 objectID);
-
-		VertexBuffer *vertexBuffer;
-		DrawElementsBuffer *drawElementsBuffer;
+class Area {
+public:
+	Area(
+		uint16 areaID,
+		ObjectMap *objectsByID,
+		ObjectMap *entrancesByID);
+	virtual ~Area();
+
+	Object *objectWithID(uint16 objectID);
+	Object *entranceWithID(uint16 objectID);
+	uint16 getAreaID();
+
+	//void setupOpenGL();
+	//void draw(bool allowPolygonOffset, BatchDrawer *batchDrawer);
+
+private:
+	uint16 areaID;
+	ObjectMap *objectsByID;
+	ObjectMap *entrancesByID;
+	Common::Array<Object *> drawableObjects;
+
+	Object *objectWithIDFromMap(ObjectMap *map, uint16 objectID);
+
+	VertexBuffer *vertexBuffer;
+	DrawElementsBuffer *drawElementsBuffer;
 };
 
 #endif /* defined(__Phantasma__Area__) */
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index a0de587f676..6c23c138493 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -67,7 +67,7 @@ FreescapeEngine::~FreescapeEngine() {
 }
 
 void FreescapeEngine::drawBorder() {
-	g_system->copyRectToScreen((const void *) _border->data(), _screenW, 0, 0, _screenW, _screenH);
+	g_system->copyRectToScreen((const void *)_border->data(), _screenW, 0, 0, _screenW, _screenH);
 	g_system->updateScreen();
 }
 
@@ -100,7 +100,7 @@ Common::Error FreescapeEngine::run() {
 	static const byte PALETTE[16][3] = {
 		{0, 0, 0}, {0xe0, 0xc0, 0x70}, {0xb0, 0x80, 0x40}, {0x80, 0x60, 0x10}, {0x50, 0x30, 0x00}, {0x20, 0x80, 0xd0}, {0x20, 0x50, 0xb0}, {0x20, 0x30, 0x70}, {0x30, 0x40, 0x30}, {0x30, 0x30, 0x30}, {0x40, 0x40, 0x40}, {0x60, 0x60, 0x60}, {0x70, 0x70, 0x70}, {0x90, 0x90, 0x90}, {0xa0, 0xa0, 0xa0}, {0xc0, 0xc0, 0xc0}};
 	g_system->getPaletteManager()->setPalette(&PALETTE[0][0], 0, 16);
-	
+
 	// Create debugger console. It requires GFX to be initialized
 	//Console *console = new Console(this);
 	//setDebugger(console);
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 3f0985ccd93..09f606154ce 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -4,19 +4,19 @@
 #include "common/random.h"
 #include "common/serializer.h"
 #include "engines/engine.h"
-#include "gui/debugger.h"
-#include "graphics/surface.h"
 #include "graphics/palette.h"
+#include "graphics/surface.h"
+#include "gui/debugger.h"
 
 #include "freescape/area.h"
 
 namespace Freescape {
 
-typedef Common::HashMap<uint16, Area*> AreaMap;
+typedef Common::HashMap<uint16, Area *> AreaMap;
 
 typedef struct Binary {
 	AreaMap *areasByAreaID;
-    Common::Array<uint8> *border;
+	Common::Array<uint8> *border;
 } Binary;
 
 class Console;
@@ -65,6 +65,6 @@ public:
 	}
 };
 
-} // End of namespace Quux
+} // namespace Freescape
 
 #endif
diff --git a/engines/freescape/game.cpp b/engines/freescape/game.cpp
index 6c92c312542..9057b0b315c 100644
--- a/engines/freescape/game.cpp
+++ b/engines/freescape/game.cpp
@@ -6,10 +6,10 @@
 //  Copyright (c) 2013 Thomas Harte. All rights reserved.
 //
 
-#include "common/system.h"
 #include "common/debug.h"
-#include "graphics/surface.h"
+#include "common/system.h"
 #include "graphics/palette.h"
+#include "graphics/surface.h"
 
 #include "freescape/game.h"
 //#include "GeometricObject.h"
@@ -17,7 +17,6 @@
 //#include "VertexBuffer.h"
 
 Game::Game(Binary binary) {
-
 }
 
 Game::~Game() {
@@ -34,9 +33,8 @@ void Game::setAspectRatio(float aspectRatio)
 }
 */
 
-void Game::draw()
-{
-	g_system->copyRectToScreen((const void *) _border->data(), _screenW, 0, 0, _screenW, _screenH);
+void Game::draw() {
+	g_system->copyRectToScreen((const void *)_border->data(), _screenW, 0, 0, _screenW, _screenH);
 	g_system->updateScreen();
 	/*
 	// set the clear colour to salmon; we're not catching floor/ceiling
diff --git a/engines/freescape/game.h b/engines/freescape/game.h
index d9c186269ef..3274ca75a46 100644
--- a/engines/freescape/game.h
+++ b/engines/freescape/game.h
@@ -9,45 +9,43 @@
 #ifndef __Phantasma__Game__
 #define __Phantasma__Game__
 
-#include "common/hashmap.h"
 #include "common/array.h"
+#include "common/hashmap.h"
 #include "engines/util.h"
 
-#include "freescape/area.h"
 #include "freescape.h"
+#include "freescape/area.h"
 
 //#include "Matrix.h"
 //#include "BatchDrawer.h"
 
-class Game
-{
-	public:
+class Game {
+public:
+	Game(Binary binary);
+	virtual ~Game();
 
-		Game(Binary binary);
-		virtual ~Game();
+	//void setAspectRatio(float aspectRatio);
+	void draw();
+	//void advanceToTime(uint32 millisecondsSinceArbitraryMoment);
 
-		//void setAspectRatio(float aspectRatio);
-		void draw();
-		//void advanceToTime(uint32 millisecondsSinceArbitraryMoment);
+	//void setupOpenGL();
 
-		//void setupOpenGL();
+	//void rotateView(float x, float y, float z);
+	//void setMovementVelocity(float x, float y, float z);
 
-		//void rotateView(float x, float y, float z);
-		//void setMovementVelocity(float x, float y, float z);
-		
-	private:
-		int _screenW, _screenH;
-		Common::Array<uint8> *_border;
-		uint32 timeOfLastTick;
-		bool hasReceivedTime;
+private:
+	int _screenW, _screenH;
+	Common::Array<uint8> *_border;
+	uint32 timeOfLastTick;
+	bool hasReceivedTime;
 
-		AreaMap *areasByAreaID;
+	AreaMap *areasByAreaID;
 
-		float rotation[3], velocity[3], position[3];
-		//Matrix rotationMatrix;
-		//Matrix translationMatrix;
+	float rotation[3], velocity[3], position[3];
+	//Matrix rotationMatrix;
+	//Matrix translationMatrix;
 
-		//BatchDrawer batchDrawer;*/
+	//BatchDrawer batchDrawer;*/
 };
 
 #endif /* defined(__Phantasma__Game__) */
diff --git a/engines/freescape/gamestate.h b/engines/freescape/gamestate.h
index 6ef51cce549..3d3b36a4335 100644
--- a/engines/freescape/gamestate.h
+++ b/engines/freescape/gamestate.h
@@ -11,11 +11,10 @@
 
 //#include <iostream>
 
-class CGameState
-{
-	public:
-		int32_t getVariable(int32_t variableNumber);
-		bool getBit(int32_t bitNumber);
+class CGameState {
+public:
+	int32_t getVariable(int32_t variableNumber);
+	bool getBit(int32_t bitNumber);
 };
 
 #endif /* defined(__Phantasma__GameState__) */


Commit: 424a2e967c1b49238267c103ff58cc0d97832393
    https://github.com/scummvm/scummvm/commit/424a2e967c1b49238267c103ff58cc0d97832393
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:34+01:00

Commit Message:
FREESCAPE: added first code for 8-bit parsing

Changed paths:
  A engines/freescape/loaders/8bitBinaryLoader.cpp
  A engines/freescape/loaders/8bitBinaryLoader.h
  A engines/freescape/loaders/loader.h
    engines/freescape/freescape.cpp
    engines/freescape/loaders/16bitBinaryLoader.cpp
    engines/freescape/loaders/16bitBinaryLoader.h
    engines/freescape/module.mk


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 6c23c138493..380191e81d1 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -14,10 +14,10 @@
 #include "freescape/freescape.h"
 
 #include "freescape/loaders/16bitBinaryLoader.h"
-//#include "freescape/loaders/8bitBinaryLoader.h"
+#include "freescape/loaders/8bitBinaryLoader.h"
 
 #define OFFSET_DARKSIDE 0xc9ce
-#define OFFSET_DRILLER 0xcf3e
+#define OFFSET_DRILLER 0x8f59
 #define OFFSET_TOTALECLIPSE 0xcdb7
 
 namespace Freescape {
@@ -67,6 +67,8 @@ FreescapeEngine::~FreescapeEngine() {
 }
 
 void FreescapeEngine::drawBorder() {
+	if (_border == nullptr)
+		return;
 	g_system->copyRectToScreen((const void *)_border->data(), _screenW, 0, 0, _screenW, _screenH);
 	g_system->updateScreen();
 }
@@ -90,8 +92,13 @@ Common::Error FreescapeEngine::run() {
 	//OSystem::kTransactionSizeChangeFailed here
 	//_system->endGFXTransaction();
 
-	Binary binary = load16bitBinary("3DKIT.RUN");
-	debug("%s", _targetName.c_str());
+	Binary binary;
+	if (_targetName == "3Dkit")
+		binary = load16bitBinary("3DKIT.RUN");
+	else if (_targetName == "Driller")
+		binary = load8bitBinary("DRILLE.EXE", OFFSET_DRILLER);
+	else
+		error("%s is an invalid game", _targetName.c_str());
 
 	_areasByAreaID = binary.areasByAreaID;
 	_border = binary.border;
diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
index 772b3b181fb..b61c98fe530 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/16bitBinaryLoader.cpp
@@ -13,6 +13,7 @@
 #include "common/file.h"
 
 #include "freescape/area.h"
+#include "freescape/loaders/loader.h"
 #include "freescape/language/16bitDetokeniser.h"
 #include "freescape/language/instruction.h"
 #include "freescape/language/parser.h"
@@ -20,88 +21,6 @@
 #include "freescape/objects/geometricobject.h"
 #include "freescape/objects/object.h"
 
-
-class StreamLoader {
-private:
-	Common::Array<uint8>::size_type bytePointer;
-	Common::Array<uint8> binary;
-	uint8 readMaskByte1;
-	uint8 readMaskByte2;
-
-public:
-	StreamLoader(Common::Array<uint8> &_binary) {
-		binary = _binary;
-		bytePointer = 0;
-		readMaskByte1 = 0;
-		readMaskByte2 = 0;
-	}
-
-	uint8 get8() {
-		if (!eof()) {
-			uint8 sourceByte = binary[bytePointer];
-
-			if (bytePointer & 1)
-				sourceByte ^= readMaskByte2;
-			else
-				sourceByte ^= readMaskByte1;
-
-			bytePointer++;
-			return sourceByte;
-		} else
-			error("eof");
-
-		return 0;
-	}
-
-	uint16 get16() {
-		uint16 result = (uint16)(get8() << 8);
-		result |= get8();
-		return result;
-	}
-
-	uint32 get32() {
-		uint32 result = (uint32)(get16() << 16);
-		result |= get16();
-		return result;
-	}
-
-	bool eof() {
-		return bytePointer >= binary.size();
-	}
-
-	void alignPointer() {
-		if (bytePointer & 1)
-			bytePointer++;
-	}
-
-	void skipBytes(Common::Array<uint8>::size_type numberOfBytes) {
-		bytePointer += numberOfBytes;
-	}
-
-	Common::Array<uint8> *nextBytes(Common::Array<uint8>::size_type numberOfBytes) {
-		Common::Array<uint8> *returnBuffer(new Common::Array<uint8>);
-		debug("give me the next %d bytes", numberOfBytes);
-
-		while (numberOfBytes--)
-			returnBuffer->push_back(get8());
-
-		return returnBuffer;
-	}
-
-	Common::Array<uint8>::size_type getFileOffset() {
-		return bytePointer;
-	}
-
-	void setFileOffset(Common::Array<uint8>::size_type newOffset) {
-		bytePointer = newOffset;
-	}
-
-	void setReadMask(uint8 byte1, uint8 byte2) {
-		readMaskByte1 = byte1;
-		readMaskByte2 = byte2;
-	}
-};
-
 namespace Freescape {
 
 static Object *loadObject(StreamLoader &stream) {
diff --git a/engines/freescape/loaders/16bitBinaryLoader.h b/engines/freescape/loaders/16bitBinaryLoader.h
index 3bd6c473981..1f5b6f48ded 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.h
+++ b/engines/freescape/loaders/16bitBinaryLoader.h
@@ -13,8 +13,10 @@
 //#include <vector>
 //#include <stdint.h>
 #include "common/str.h"
+
 #include "../freescape.h"
 
+
 namespace Freescape {
 
 Binary load16bitBinary(Common::String);
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
new file mode 100644
index 00000000000..122ea2c1de8
--- /dev/null
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -0,0 +1,49 @@
+#include "common/array.h"
+#include "common/debug.h"
+#include "common/file.h"
+
+#include "freescape/area.h"
+#include "freescape/loaders/loader.h"
+//#include "freescape/language/8bitDetokeniser.h"
+#include "freescape/language/instruction.h"
+#include "freescape/language/parser.h"
+#include "freescape/loaders/8bitBinaryLoader.h"
+#include "freescape/objects/geometricobject.h"
+#include "freescape/objects/object.h"
+
+namespace Freescape {
+
+Binary load8bitBinary(Common::String filename, uint offset) {
+	Common::File *file = new Common::File();
+
+	if (!file->open(filename)) {
+		delete file;
+		error("NULL");
+	}
+
+	const uint32 fileSize = file->size();
+	byte *buf = (byte *)malloc(fileSize);
+	file->read(buf, fileSize);
+
+	Common::Array<uint8> binary;
+
+	uint32 i = offset;
+	while (i < fileSize) {
+		binary.push_back(buf[i]);
+		i++;
+	}
+
+	StreamLoader streamLoader(binary);
+	uint8 numberOfAreas = streamLoader.get8();
+	streamLoader.get8(); // meaning unknown
+
+	debug("Number of areas: %d", numberOfAreas);
+	uint8 startArea = streamLoader.get8();
+    debug("Start area: %d", startArea);
+
+
+
+    return Binary{nullptr, nullptr};
+}
+
+}
\ No newline at end of file
diff --git a/engines/freescape/loaders/8bitBinaryLoader.h b/engines/freescape/loaders/8bitBinaryLoader.h
new file mode 100644
index 00000000000..9a1e906cbc1
--- /dev/null
+++ b/engines/freescape/loaders/8bitBinaryLoader.h
@@ -0,0 +1,22 @@
+//
+//  8bitBinaryLoader.h
+//  Phantasma
+//
+//  Created by X.
+//  Copyright (c) X. All rights reserved.
+//
+
+#ifndef __Phantasma___8bitBinaryLoader__
+#define __Phantasma___8bitBinaryLoader__
+
+#include "common/str.h"
+
+#include "../freescape.h"
+
+namespace Freescape {
+
+Binary load8bitBinary(Common::String, uint offset);
+
+}
+
+#endif /* defined(__Phantasma___8bitBinaryLoader__) */
\ No newline at end of file
diff --git a/engines/freescape/loaders/loader.h b/engines/freescape/loaders/loader.h
new file mode 100644
index 00000000000..5801e2724bd
--- /dev/null
+++ b/engines/freescape/loaders/loader.h
@@ -0,0 +1,91 @@
+#ifndef __Phantasma___Loader__
+#define __Phantasma___Loader__
+
+#include "common/array.h"
+
+namespace Freescape {
+
+class StreamLoader {
+private:
+	Common::Array<uint8>::size_type bytePointer;
+	Common::Array<uint8> binary;
+	uint8 readMaskByte1;
+	uint8 readMaskByte2;
+
+public:
+	StreamLoader(Common::Array<uint8> &_binary) {
+		binary = _binary;
+		bytePointer = 0;
+		readMaskByte1 = 0;
+		readMaskByte2 = 0;
+	}
+
+	uint8 get8() {
+		if (!eof()) {
+			uint8 sourceByte = binary[bytePointer];
+
+			if (bytePointer & 1)
+				sourceByte ^= readMaskByte2;
+			else
+				sourceByte ^= readMaskByte1;
+
+			bytePointer++;
+			return sourceByte;
+		} else
+			error("eof");
+
+		return 0;
+	}
+
+	uint16 get16() {
+		uint16 result = (uint16)(get8() << 8);
+		result |= get8();
+		return result;
+	}
+
+	uint32 get32() {
+		uint32 result = (uint32)(get16() << 16);
+		result |= get16();
+		return result;
+	}
+
+	bool eof() {
+		return bytePointer >= binary.size();
+	}
+
+	void alignPointer() {
+		if (bytePointer & 1)
+			bytePointer++;
+	}
+
+	void skipBytes(Common::Array<uint8>::size_type numberOfBytes) {
+		bytePointer += numberOfBytes;
+	}
+
+	Common::Array<uint8> *nextBytes(Common::Array<uint8>::size_type numberOfBytes) {
+		Common::Array<uint8> *returnBuffer(new Common::Array<uint8>);
+		debug("give me the next %d bytes", numberOfBytes);
+
+		while (numberOfBytes--)
+			returnBuffer->push_back(get8());
+
+		return returnBuffer;
+	}
+
+	Common::Array<uint8>::size_type getFileOffset() {
+		return bytePointer;
+	}
+
+	void setFileOffset(Common::Array<uint8>::size_type newOffset) {
+		bytePointer = newOffset;
+	}
+
+	void setReadMask(uint8 byte1, uint8 byte2) {
+		readMaskByte1 = byte1;
+		readMaskByte2 = byte2;
+	}
+};
+
+} // namespace Freescape
+
+#endif
\ No newline at end of file
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index edc97b70470..32e2b9ac08a 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -6,6 +6,7 @@ MODULE_OBJS := \
 	area.o \
 	objects/object.o \
 	objects/geometricobject.o \
+	loaders/8bitBinaryLoader.o \
 	loaders/16bitBinaryLoader.o \
 	language/16bitDetokeniser.o \
 	language/instruction.o


Commit: 9c1391e957c0b0d05ab0309c9322c7419d4d7303
    https://github.com/scummvm/scummvm/commit/9c1391e957c0b0d05ab0309c9322c7419d4d7303
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:34+01:00

Commit Message:
FREESCAPE: used clang-format to improve code style

Changed paths:
    engines/freescape/loaders/16bitBinaryLoader.cpp
    engines/freescape/loaders/16bitBinaryLoader.h
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
index b61c98fe530..45c70ab89be 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/16bitBinaryLoader.cpp
@@ -13,11 +13,11 @@
 #include "common/file.h"
 
 #include "freescape/area.h"
-#include "freescape/loaders/loader.h"
 #include "freescape/language/16bitDetokeniser.h"
 #include "freescape/language/instruction.h"
 #include "freescape/language/parser.h"
 #include "freescape/loaders/16bitBinaryLoader.h"
+#include "freescape/loaders/loader.h"
 #include "freescape/objects/geometricobject.h"
 #include "freescape/objects/object.h"
 
@@ -366,7 +366,7 @@ Binary load16bitBinary(Common::String filename) {
 		o = streamLoader.getFileOffset();
 		if (streamLoader.get32() == 0x452400fa) {
 			debug("Border found at %x", o);
-			raw_border = streamLoader.nextBytes(320*200);
+			raw_border = streamLoader.nextBytes(320 * 200);
 			break;
 		}
 		streamLoader.setFileOffset(o);
@@ -377,4 +377,4 @@ Binary load16bitBinary(Common::String filename) {
 	return Freescape::Binary{areaMap, raw_border};
 }
 
-}
\ No newline at end of file
+} // namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/loaders/16bitBinaryLoader.h b/engines/freescape/loaders/16bitBinaryLoader.h
index 1f5b6f48ded..d7bcc8ab090 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.h
+++ b/engines/freescape/loaders/16bitBinaryLoader.h
@@ -16,7 +16,6 @@
 
 #include "../freescape.h"
 
-
 namespace Freescape {
 
 Binary load16bitBinary(Common::String);
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 122ea2c1de8..021da7de639 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -39,11 +39,9 @@ Binary load8bitBinary(Common::String filename, uint offset) {
 
 	debug("Number of areas: %d", numberOfAreas);
 	uint8 startArea = streamLoader.get8();
-    debug("Start area: %d", startArea);
+	debug("Start area: %d", startArea);
 
-
-
-    return Binary{nullptr, nullptr};
+	return Binary{nullptr, nullptr};
 }
 
-}
\ No newline at end of file
+} // namespace Freescape
\ No newline at end of file


Commit: 5cc47a4077cae0d484eb1e506f5aaef1902523c3
    https://github.com/scummvm/scummvm/commit/5cc47a4077cae0d484eb1e506f5aaef1902523c3
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:34+01:00

Commit Message:
FREESCAPE: added more code for 8-bit parsing

Changed paths:
  A engines/freescape/language/8bitDetokeniser.cpp
  A engines/freescape/language/8bitDetokeniser.h
    engines/freescape/freescape.cpp
    engines/freescape/language/16bitDetokeniser.h
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 380191e81d1..a6db289c1f5 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -17,7 +17,7 @@
 #include "freescape/loaders/8bitBinaryLoader.h"
 
 #define OFFSET_DARKSIDE 0xc9ce
-#define OFFSET_DRILLER 0x8f59
+#define OFFSET_DRILLER 0x9B40
 #define OFFSET_TOTALECLIPSE 0xcdb7
 
 namespace Freescape {
@@ -55,7 +55,7 @@ FreescapeEngine::FreescapeEngine(OSystem *syst)
 }
 
 FreescapeEngine::~FreescapeEngine() {
-	debug("QuuxEngine::~QuuxEngine");
+	debug("FreescapeEngine::~FreescapeEngine");
 
 	// Dispose your resources here
 	delete _rnd;
@@ -75,7 +75,7 @@ void FreescapeEngine::drawBorder() {
 
 Common::Error FreescapeEngine::run() {
 	// Initialize graphics using following:
-	initGraphics(320, 200);
+	initGraphics(_screenW, _screenH);
 
 	// You could use backend transactions directly as an alternative,
 	// but it isn't recommended, until you want to handle the error values
diff --git a/engines/freescape/language/16bitDetokeniser.h b/engines/freescape/language/16bitDetokeniser.h
index 173d5349571..5032f4da853 100644
--- a/engines/freescape/language/16bitDetokeniser.h
+++ b/engines/freescape/language/16bitDetokeniser.h
@@ -6,12 +6,12 @@
 //  Copyright (c) 2013 Thomas Harte. All rights reserved.
 //
 
-#ifndef __Phantasma___6bitDetokeniser__
-#define __Phantasma___6bitDetokeniser__
+#ifndef __Phantasma___16bitDetokeniser__
+#define __Phantasma___16bitDetokeniser__
 
 #include "common/array.h"
 #include "common/str.h"
 
 Common::String *detokenise16bitCondition(Common::Array<uint8> &tokenisedCondition);
 
-#endif /* defined(__Phantasma___6bitDetokeniser__) */
+#endif /* defined(__Phantasma___16bitDetokeniser__) */
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
new file mode 100644
index 00000000000..8a61c923d88
--- /dev/null
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -0,0 +1,185 @@
+//
+//  8bitDetokeniser.cpp
+//  Phantasma
+//
+//  Created by Thomas Harte on 15/12/2013.
+//  Copyright (c) 2013 Thomas Harte. All rights reserved.
+//
+
+/*
+	This has been implemented based on John Elliott's 2001
+	reverse engineering of Driller; see http://www.seasip.demon.co.uk/ZX/Driller/
+*/
+
+#include "8bitDetokeniser.h"
+
+static const int k8bitVariableShield	= 256;
+static const int k8bitVariableEnergy	= 257;
+static const int k8bitVariableScore		= 258;
+
+Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition) {
+	Common::String detokenisedStream;
+	Common::Array<uint8>::size_type bytePointer = 0;
+	Common::Array<uint8>::size_type sizeOfTokenisedContent = tokenisedCondition.size();
+
+	// on the 8bit platforms, all instructions have a conditional flag;
+	// we'll want to convert them into runs of "if shot? then" and "if collided? then",
+	// and we'll want to start that from the top
+	uint8_t conditionalIsShot = 0x1;
+
+	// this lookup table tells us how many argument bytes to read per opcode
+	uint8_t argumentsRequiredByOpcode[32] =
+	{
+		0,	3,	1,	1,	1,	1,	2,	2,
+		2,	1,	1,	2,	1,	1,	2,	1,
+		1,	2,	2,	1,	2,	0,	0,	0,
+		0,	1,	0,	1,	1,	1,	1,	1
+	};
+
+	while(bytePointer < sizeOfTokenisedContent)
+	{
+		// get the conditional type of the next operation
+		uint8_t newConditionalIsShot = tokenisedCondition[bytePointer] & 0x80;
+
+		// if the conditional type has changed then end the old conditional,
+		// if we were in one, and begin a new one
+		if(newConditionalIsShot != conditionalIsShot)
+		{
+			conditionalIsShot = newConditionalIsShot;
+			if(bytePointer) { 
+				detokenisedStream += "ENDIF\n"
+
+			if(conditionalIsShot)
+				detokenisedStream += "IF SHOT? THEN\n";
+			else
+				detokenisedStream += "IF COLLIDED? THEN\n";
+		}
+
+		// get the actual operation
+		uint8_t opcode = tokenisedCondition[bytePointer] & 0x1f;
+		bytePointer++;
+
+		// figure out how many argument bytes we're going to need,
+		// check we have enough bytes left to read
+		uint8_t numberOfArguments = argumentsRequiredByOpcode[opcode];
+		if(bytePointer + numberOfArguments > sizeOfTokenisedContent)
+			break;
+
+		// generate the string
+		switch(opcode)
+		{
+			default:
+				detokenisedStream += "<UNKNOWN 8 bit: "
+				detokenisedStream += Common::String::format("%x", (int)opcode);
+				detokenisedStream += " > ";
+			break;
+
+			case 0: break;			// NOP
+			case 1:					// add three-byte value to score
+			{
+				int32_t additionValue =
+					tokenisedCondition[bytePointer] |
+					(tokenisedCondition[bytePointer+1] << 8) |
+					(tokenisedCondition[bytePointer+2] << 16);
+				detokenisedStream += "ADDVAR";
+				detokenisedStream += Common::String::format("(%d, v%d)", additionValue, k8bitVariableScore);
+				bytePointer += 3;
+				numberOfArguments = 0;
+			}
+			break;
+			case 2:					// add one-byte value to energy
+				detokenisedStream << "ADDVAR (" << (int)tokenisedCondition[bytePointer] << ", v" << k8bitVariableEnergy << ")";
+				bytePointer ++;
+				numberOfArguments = 0;
+			break;
+			case 19:				// add one-byte value to shield
+				detokenisedStream << "ADDVAR (" << (int)tokenisedCondition[bytePointer] << ", v" << k8bitVariableShield << ")";
+				bytePointer ++;
+				numberOfArguments = 0;
+			break;
+
+			case 6:		case 3:		detokenisedStream << "TOGVIS (";		break;	// these all come in unary and binary versions,
+			case 7:		case 4:		detokenisedStream << "VIS (";			break;	// hence each getting two case statement entries
+			case 8:		case 5:		detokenisedStream << "INVIS (";			break;
+
+			case 9:					detokenisedStream << "ADDVAR (1, v";	break;
+			case 10:				detokenisedStream << "SUBVAR (1, v";	break;
+
+			case 11:	// end condition if a variable doesn't have a particular value
+				detokenisedStream	<< "IF VAR!=? (v" << (int)tokenisedCondition[bytePointer] << ", " << (int)tokenisedCondition[bytePointer+1] << ") "
+									<< "THEN END ENDIF";
+				bytePointer += 2;
+				numberOfArguments = 0;
+			break;
+			case 14:	// end condition if a bit doesn't have a particular value
+				detokenisedStream	<< "IF BIT!=? (" << (int)tokenisedCondition[bytePointer] << ", " << (int)tokenisedCondition[bytePointer+1] << ") "
+									<< "THEN END ENDIF";
+				bytePointer += 2;
+				numberOfArguments = 0;
+			break;
+			case 30:	// end condition if an object is invisible
+				detokenisedStream	<< "IF INVIS? (" << (int)tokenisedCondition[bytePointer] << ") "
+									<< "THEN END ENDIF";
+				bytePointer ++;
+				numberOfArguments = 0;
+			break;
+			case 31:	// end condition if an object is visible
+				detokenisedStream	<< "IF VIS? (" << (int)tokenisedCondition[bytePointer] << ") "
+									<< "THEN END ENDIF";
+				bytePointer ++;
+				numberOfArguments = 0;
+			break;
+
+			case 12:				detokenisedStream << "SETBIT (";		break;
+			case 13:				detokenisedStream << "CLRBIT (";		break;
+
+			case 15:				detokenisedStream << "SOUND (";			break;
+			case 17:	case 16:	detokenisedStream << "DESTROY (";		break;
+			case 18:				detokenisedStream << "GOTO (";			break;
+
+			case 21:				detokenisedStream << "SWAPJET";			break;
+			case 26:				detokenisedStream << "REDRAW";			break;
+			case 27:				detokenisedStream << "DELAY (";			break;
+			case 28:				detokenisedStream << "SYNCSND (";		break;
+			case 29:				detokenisedStream << "TOGBIT (";		break;
+
+			case 25:
+			{
+				// this should toggle border colour; it's therefore a no-op
+				bytePointer++;
+				numberOfArguments = 0;
+			}
+			break;
+
+			case 20:
+				detokenisedStream	<< "SETVAR (" << (int)tokenisedCondition[bytePointer] << ", v" << (int)tokenisedCondition[bytePointer+1] << ") ";
+				bytePointer += 2;
+				numberOfArguments = 0;
+			break;
+		}
+
+		// if there are any regular arguments to add, do so
+		if(numberOfArguments)
+		{
+			for(uint8_t argumentNumber = 0; argumentNumber < numberOfArguments; argumentNumber++)
+			{
+				detokenisedStream << (int)tokenisedCondition[bytePointer];
+				bytePointer++;
+
+				if(argumentNumber < numberOfArguments-1)
+					detokenisedStream += ", ";
+			}
+
+			detokenisedStream += ")";
+		}
+
+		// throw in a newline
+		detokenisedStream << endl;
+	}
+
+	shared_ptr<string> outputString(new string);
+	*outputString = detokenisedStream.str();
+
+	return outputString;
+
+}
diff --git a/engines/freescape/language/8bitDetokeniser.h b/engines/freescape/language/8bitDetokeniser.h
new file mode 100644
index 00000000000..f7d2db24b6e
--- /dev/null
+++ b/engines/freescape/language/8bitDetokeniser.h
@@ -0,0 +1,17 @@
+//
+//  8bitDetokeniser.h
+//  Phantasma
+//
+//  Created by Thomas Harte on 15/12/2013.
+//  Copyright (c) 2013 Thomas Harte. All rights reserved.
+//
+
+#ifndef __Phantasma___8bitDetokeniser__
+#define __Phantasma___8bitDetokeniser__
+
+#include "common/array.h"
+#include "common/str.h"
+
+Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition);
+
+#endif /* defined(__Phantasma___8bitDetokeniser__) */
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 021da7de639..4779803a497 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -4,7 +4,7 @@
 
 #include "freescape/area.h"
 #include "freescape/loaders/loader.h"
-//#include "freescape/language/8bitDetokeniser.h"
+#include "freescape/language/8bitDetokeniser.h"
 #include "freescape/language/instruction.h"
 #include "freescape/language/parser.h"
 #include "freescape/loaders/8bitBinaryLoader.h"
@@ -35,11 +35,38 @@ Binary load8bitBinary(Common::String filename, uint offset) {
 
 	StreamLoader streamLoader(binary);
 	uint8 numberOfAreas = streamLoader.get8();
-	streamLoader.get8(); // meaning unknown
+	streamLoader.get16(); // meaning unknown
 
 	debug("Number of areas: %d", numberOfAreas);
 	uint8 startArea = streamLoader.get8();
 	debug("Start area: %d", startArea);
+	uint8 entranceArea = streamLoader.get8();
+	debug("Entrace area: %d", entranceArea);
+	streamLoader.skipBytes(68);
+	uint16 globalByteCodeTable;
+	globalByteCodeTable = streamLoader.get16();
+	debug("GBCT: %d\n", globalByteCodeTable);
+
+	streamLoader.setFileOffset(globalByteCodeTable);
+	//uint8 *ConditionPointer = &Base[GlobalByteCodeTable];
+	uint8 numConditions = streamLoader.get8();
+	debug("%d global conditions", numConditions);
+	while(numConditions--)
+	{
+		// get the length
+		uint32 lengthOfCondition = streamLoader.get8();
+		debug("length of condition: %d", lengthOfCondition);
+		// get the condition
+		Common::Array<uint8> *conditionData = streamLoader.nextBytes(lengthOfCondition);
+
+		//debug("Global condition %d", globalCondition + 1);
+		//debug("%s", detokenise16bitCondition(*conditionData)->c_str());
+		/*CCondition *NewCon = GetConditionZXBinary(&ConditionPointer[1], ConditionPointer[0], true);
+		GlobalArea->AddCondition(NumConditions, NewCon);
+		printf("\t%d bytes\n", *ConditionPointer);
+		ConditionPointer += *ConditionPointer;*/
+	}
+
 
 	return Binary{nullptr, nullptr};
 }


Commit: 8d0b3b3e0414dc3620bc56e1981a980a5acbb588
    https://github.com/scummvm/scummvm/commit/8d0b3b3e0414dc3620bc56e1981a980a5acbb588
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:34+01:00

Commit Message:
FREESCAPE: added more code for 8-bit parsing

Changed paths:
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/module.mk


diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index 8a61c923d88..5df95ca4f4f 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -25,10 +25,10 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 	// on the 8bit platforms, all instructions have a conditional flag;
 	// we'll want to convert them into runs of "if shot? then" and "if collided? then",
 	// and we'll want to start that from the top
-	uint8_t conditionalIsShot = 0x1;
+	uint8 conditionalIsShot = 0x1;
 
 	// this lookup table tells us how many argument bytes to read per opcode
-	uint8_t argumentsRequiredByOpcode[32] =
+	uint8 argumentsRequiredByOpcode[32] =
 	{
 		0,	3,	1,	1,	1,	1,	2,	2,
 		2,	1,	1,	2,	1,	1,	2,	1,
@@ -39,15 +39,15 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 	while(bytePointer < sizeOfTokenisedContent)
 	{
 		// get the conditional type of the next operation
-		uint8_t newConditionalIsShot = tokenisedCondition[bytePointer] & 0x80;
+		uint8 newConditionalIsShot = tokenisedCondition[bytePointer] & 0x80;
 
 		// if the conditional type has changed then end the old conditional,
 		// if we were in one, and begin a new one
 		if(newConditionalIsShot != conditionalIsShot)
 		{
 			conditionalIsShot = newConditionalIsShot;
-			if(bytePointer) { 
-				detokenisedStream += "ENDIF\n"
+			if(bytePointer)
+				detokenisedStream += "ENDIF\n";
 
 			if(conditionalIsShot)
 				detokenisedStream += "IF SHOT? THEN\n";
@@ -56,12 +56,12 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 		}
 
 		// get the actual operation
-		uint8_t opcode = tokenisedCondition[bytePointer] & 0x1f;
+		uint8 opcode = tokenisedCondition[bytePointer] & 0x1f;
 		bytePointer++;
 
 		// figure out how many argument bytes we're going to need,
 		// check we have enough bytes left to read
-		uint8_t numberOfArguments = argumentsRequiredByOpcode[opcode];
+		uint8 numberOfArguments = argumentsRequiredByOpcode[opcode];
 		if(bytePointer + numberOfArguments > sizeOfTokenisedContent)
 			break;
 
@@ -69,7 +69,7 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 		switch(opcode)
 		{
 			default:
-				detokenisedStream += "<UNKNOWN 8 bit: "
+				detokenisedStream += "<UNKNOWN 8 bit: ";
 				detokenisedStream += Common::String::format("%x", (int)opcode);
 				detokenisedStream += " > ";
 			break;
@@ -77,7 +77,7 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			case 0: break;			// NOP
 			case 1:					// add three-byte value to score
 			{
-				int32_t additionValue =
+				int32 additionValue =
 					tokenisedCondition[bytePointer] |
 					(tokenisedCondition[bytePointer+1] << 8) |
 					(tokenisedCondition[bytePointer+2] << 16);
@@ -88,60 +88,66 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			}
 			break;
 			case 2:					// add one-byte value to energy
-				detokenisedStream << "ADDVAR (" << (int)tokenisedCondition[bytePointer] << ", v" << k8bitVariableEnergy << ")";
+				detokenisedStream += "ADDVAR ";
+				detokenisedStream += Common::String::format("(%d, v%d)", (int)tokenisedCondition[bytePointer], k8bitVariableEnergy);
 				bytePointer ++;
 				numberOfArguments = 0;
 			break;
 			case 19:				// add one-byte value to shield
-				detokenisedStream << "ADDVAR (" << (int)tokenisedCondition[bytePointer] << ", v" << k8bitVariableShield << ")";
+				detokenisedStream += "ADDVAR ";
+				detokenisedStream += Common::String::format("(%d, v%d)", (int)tokenisedCondition[bytePointer], k8bitVariableShield);
 				bytePointer ++;
 				numberOfArguments = 0;
 			break;
 
-			case 6:		case 3:		detokenisedStream << "TOGVIS (";		break;	// these all come in unary and binary versions,
-			case 7:		case 4:		detokenisedStream << "VIS (";			break;	// hence each getting two case statement entries
-			case 8:		case 5:		detokenisedStream << "INVIS (";			break;
+			case 6:		case 3:		detokenisedStream += "TOGVIS (";		break;	// these all come in unary and binary versions,
+			case 7:		case 4:		detokenisedStream += "VIS (";			break;	// hence each getting two case statement entries
+			case 8:		case 5:		detokenisedStream += "INVIS (";			break;
 
-			case 9:					detokenisedStream << "ADDVAR (1, v";	break;
-			case 10:				detokenisedStream << "SUBVAR (1, v";	break;
+			case 9:					detokenisedStream += "ADDVAR (1, v";	break;
+			case 10:				detokenisedStream += "SUBVAR (1, v";	break;
 
 			case 11:	// end condition if a variable doesn't have a particular value
-				detokenisedStream	<< "IF VAR!=? (v" << (int)tokenisedCondition[bytePointer] << ", " << (int)tokenisedCondition[bytePointer+1] << ") "
-									<< "THEN END ENDIF";
+				detokenisedStream += "IF VAR!=? ";
+				detokenisedStream += Common::String::format("(v%d, v%d)", (int)tokenisedCondition[bytePointer], (int)tokenisedCondition[bytePointer+1]);
+				detokenisedStream += "THEN END ENDIF";
 				bytePointer += 2;
 				numberOfArguments = 0;
 			break;
 			case 14:	// end condition if a bit doesn't have a particular value
-				detokenisedStream	<< "IF BIT!=? (" << (int)tokenisedCondition[bytePointer] << ", " << (int)tokenisedCondition[bytePointer+1] << ") "
-									<< "THEN END ENDIF";
+				detokenisedStream   += "IF BIT!=? ";
+				detokenisedStream   += Common::String::format("(%d, %d)", (int)tokenisedCondition[bytePointer], (int)tokenisedCondition[bytePointer+1]);
+				detokenisedStream	+= "THEN END ENDIF";
 				bytePointer += 2;
 				numberOfArguments = 0;
 			break;
 			case 30:	// end condition if an object is invisible
-				detokenisedStream	<< "IF INVIS? (" << (int)tokenisedCondition[bytePointer] << ") "
-									<< "THEN END ENDIF";
+				detokenisedStream	+= "IF INVIS? ";
+				detokenisedStream   += Common::String::format("(%d)", (int)tokenisedCondition[bytePointer]);
+				detokenisedStream   += "THEN END ENDIF";
 				bytePointer ++;
 				numberOfArguments = 0;
 			break;
 			case 31:	// end condition if an object is visible
-				detokenisedStream	<< "IF VIS? (" << (int)tokenisedCondition[bytePointer] << ") "
-									<< "THEN END ENDIF";
+				detokenisedStream	+= "IF VIS? ";
+				detokenisedStream   += Common::String::format("(%d)", (int)tokenisedCondition[bytePointer]);
+				detokenisedStream   += "THEN END ENDIF";
 				bytePointer ++;
 				numberOfArguments = 0;
 			break;
 
-			case 12:				detokenisedStream << "SETBIT (";		break;
-			case 13:				detokenisedStream << "CLRBIT (";		break;
+			case 12:				detokenisedStream += "SETBIT (";		break;
+			case 13:				detokenisedStream += "CLRBIT (";		break;
 
-			case 15:				detokenisedStream << "SOUND (";			break;
-			case 17:	case 16:	detokenisedStream << "DESTROY (";		break;
-			case 18:				detokenisedStream << "GOTO (";			break;
+			case 15:				detokenisedStream += "SOUND (";			break;
+			case 17:	case 16:	detokenisedStream += "DESTROY (";		break;
+			case 18:				detokenisedStream += "GOTO (";			break;
 
-			case 21:				detokenisedStream << "SWAPJET";			break;
-			case 26:				detokenisedStream << "REDRAW";			break;
-			case 27:				detokenisedStream << "DELAY (";			break;
-			case 28:				detokenisedStream << "SYNCSND (";		break;
-			case 29:				detokenisedStream << "TOGBIT (";		break;
+			case 21:				detokenisedStream += "SWAPJET";			break;
+			case 26:				detokenisedStream += "REDRAW";			break;
+			case 27:				detokenisedStream += "DELAY (";			break;
+			case 28:				detokenisedStream += "SYNCSND (";		break;
+			case 29:				detokenisedStream += "TOGBIT (";		break;
 
 			case 25:
 			{
@@ -152,7 +158,8 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			break;
 
 			case 20:
-				detokenisedStream	<< "SETVAR (" << (int)tokenisedCondition[bytePointer] << ", v" << (int)tokenisedCondition[bytePointer+1] << ") ";
+				detokenisedStream += "SETVAR ";
+				detokenisedStream += Common::String::format("(%d, v%d)", (int)tokenisedCondition[bytePointer], (int)tokenisedCondition[bytePointer+1]);
 				bytePointer += 2;
 				numberOfArguments = 0;
 			break;
@@ -161,9 +168,9 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 		// if there are any regular arguments to add, do so
 		if(numberOfArguments)
 		{
-			for(uint8_t argumentNumber = 0; argumentNumber < numberOfArguments; argumentNumber++)
+			for(uint8 argumentNumber = 0; argumentNumber < numberOfArguments; argumentNumber++)
 			{
-				detokenisedStream << (int)tokenisedCondition[bytePointer];
+				detokenisedStream += Common::String::format("%d", (int)tokenisedCondition[bytePointer]);
 				bytePointer++;
 
 				if(argumentNumber < numberOfArguments-1)
@@ -174,12 +181,9 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 		}
 
 		// throw in a newline
-		detokenisedStream << endl;
+		detokenisedStream += "\n";
 	}
 
-	shared_ptr<string> outputString(new string);
-	*outputString = detokenisedStream.str();
-
-	return outputString;
+	return (new Common::String(detokenisedStream));
 
 }
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 4779803a497..e85b77e5448 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -59,12 +59,8 @@ Binary load8bitBinary(Common::String filename, uint offset) {
 		// get the condition
 		Common::Array<uint8> *conditionData = streamLoader.nextBytes(lengthOfCondition);
 
-		//debug("Global condition %d", globalCondition + 1);
-		//debug("%s", detokenise16bitCondition(*conditionData)->c_str());
-		/*CCondition *NewCon = GetConditionZXBinary(&ConditionPointer[1], ConditionPointer[0], true);
-		GlobalArea->AddCondition(NumConditions, NewCon);
-		printf("\t%d bytes\n", *ConditionPointer);
-		ConditionPointer += *ConditionPointer;*/
+		//debug("Global condition %d", numCondition + 1);
+		debug("%s", detokenise8bitCondition(*conditionData)->c_str());
 	}
 
 
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index 32e2b9ac08a..c0269d4687c 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -7,6 +7,7 @@ MODULE_OBJS := \
 	objects/object.o \
 	objects/geometricobject.o \
 	loaders/8bitBinaryLoader.o \
+	language/8bitDetokeniser.o \
 	loaders/16bitBinaryLoader.o \
 	language/16bitDetokeniser.o \
 	language/instruction.o


Commit: f4558be547f3c5ec4e864d9503cd4d2cd443bd12
    https://github.com/scummvm/scummvm/commit/f4558be547f3c5ec4e864d9503cd4d2cd443bd12
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:35+01:00

Commit Message:
FREESCAPE: used clang-format to improve code

Changed paths:
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index 5df95ca4f4f..fcb31452e5d 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -13,9 +13,9 @@
 
 #include "8bitDetokeniser.h"
 
-static const int k8bitVariableShield	= 256;
-static const int k8bitVariableEnergy	= 257;
-static const int k8bitVariableScore		= 258;
+static const int k8bitVariableShield = 256;
+static const int k8bitVariableEnergy = 257;
+static const int k8bitVariableScore = 258;
 
 Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition) {
 	Common::String detokenisedStream;
@@ -29,27 +29,24 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 
 	// this lookup table tells us how many argument bytes to read per opcode
 	uint8 argumentsRequiredByOpcode[32] =
-	{
-		0,	3,	1,	1,	1,	1,	2,	2,
-		2,	1,	1,	2,	1,	1,	2,	1,
-		1,	2,	2,	1,	2,	0,	0,	0,
-		0,	1,	0,	1,	1,	1,	1,	1
-	};
-
-	while(bytePointer < sizeOfTokenisedContent)
-	{
+		{
+			0, 3, 1, 1, 1, 1, 2, 2,
+			2, 1, 1, 2, 1, 1, 2, 1,
+			1, 2, 2, 1, 2, 0, 0, 0,
+			0, 1, 0, 1, 1, 1, 1, 1};
+
+	while (bytePointer < sizeOfTokenisedContent) {
 		// get the conditional type of the next operation
 		uint8 newConditionalIsShot = tokenisedCondition[bytePointer] & 0x80;
 
 		// if the conditional type has changed then end the old conditional,
 		// if we were in one, and begin a new one
-		if(newConditionalIsShot != conditionalIsShot)
-		{
+		if (newConditionalIsShot != conditionalIsShot) {
 			conditionalIsShot = newConditionalIsShot;
-			if(bytePointer)
+			if (bytePointer)
 				detokenisedStream += "ENDIF\n";
 
-			if(conditionalIsShot)
+			if (conditionalIsShot)
 				detokenisedStream += "IF SHOT? THEN\n";
 			else
 				detokenisedStream += "IF COLLIDED? THEN\n";
@@ -62,118 +59,147 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 		// figure out how many argument bytes we're going to need,
 		// check we have enough bytes left to read
 		uint8 numberOfArguments = argumentsRequiredByOpcode[opcode];
-		if(bytePointer + numberOfArguments > sizeOfTokenisedContent)
+		if (bytePointer + numberOfArguments > sizeOfTokenisedContent)
 			break;
 
 		// generate the string
-		switch(opcode)
+		switch (opcode) {
+		default:
+			detokenisedStream += "<UNKNOWN 8 bit: ";
+			detokenisedStream += Common::String::format("%x", (int)opcode);
+			detokenisedStream += " > ";
+			break;
+
+		case 0:
+			break; // NOP
+		case 1:    // add three-byte value to score
 		{
-			default:
-				detokenisedStream += "<UNKNOWN 8 bit: ";
-				detokenisedStream += Common::String::format("%x", (int)opcode);
-				detokenisedStream += " > ";
-			break;
-
-			case 0: break;			// NOP
-			case 1:					// add three-byte value to score
-			{
-				int32 additionValue =
-					tokenisedCondition[bytePointer] |
-					(tokenisedCondition[bytePointer+1] << 8) |
-					(tokenisedCondition[bytePointer+2] << 16);
-				detokenisedStream += "ADDVAR";
-				detokenisedStream += Common::String::format("(%d, v%d)", additionValue, k8bitVariableScore);
-				bytePointer += 3;
-				numberOfArguments = 0;
-			}
+			int32 additionValue =
+				tokenisedCondition[bytePointer] |
+				(tokenisedCondition[bytePointer + 1] << 8) |
+				(tokenisedCondition[bytePointer + 2] << 16);
+			detokenisedStream += "ADDVAR";
+			detokenisedStream += Common::String::format("(%d, v%d)", additionValue, k8bitVariableScore);
+			bytePointer += 3;
+			numberOfArguments = 0;
+		} break;
+		case 2: // add one-byte value to energy
+			detokenisedStream += "ADDVAR ";
+			detokenisedStream += Common::String::format("(%d, v%d)", (int)tokenisedCondition[bytePointer], k8bitVariableEnergy);
+			bytePointer++;
+			numberOfArguments = 0;
 			break;
-			case 2:					// add one-byte value to energy
-				detokenisedStream += "ADDVAR ";
-				detokenisedStream += Common::String::format("(%d, v%d)", (int)tokenisedCondition[bytePointer], k8bitVariableEnergy);
-				bytePointer ++;
-				numberOfArguments = 0;
-			break;
-			case 19:				// add one-byte value to shield
-				detokenisedStream += "ADDVAR ";
-				detokenisedStream += Common::String::format("(%d, v%d)", (int)tokenisedCondition[bytePointer], k8bitVariableShield);
-				bytePointer ++;
-				numberOfArguments = 0;
-			break;
-
-			case 6:		case 3:		detokenisedStream += "TOGVIS (";		break;	// these all come in unary and binary versions,
-			case 7:		case 4:		detokenisedStream += "VIS (";			break;	// hence each getting two case statement entries
-			case 8:		case 5:		detokenisedStream += "INVIS (";			break;
-
-			case 9:					detokenisedStream += "ADDVAR (1, v";	break;
-			case 10:				detokenisedStream += "SUBVAR (1, v";	break;
-
-			case 11:	// end condition if a variable doesn't have a particular value
-				detokenisedStream += "IF VAR!=? ";
-				detokenisedStream += Common::String::format("(v%d, v%d)", (int)tokenisedCondition[bytePointer], (int)tokenisedCondition[bytePointer+1]);
-				detokenisedStream += "THEN END ENDIF";
-				bytePointer += 2;
-				numberOfArguments = 0;
-			break;
-			case 14:	// end condition if a bit doesn't have a particular value
-				detokenisedStream   += "IF BIT!=? ";
-				detokenisedStream   += Common::String::format("(%d, %d)", (int)tokenisedCondition[bytePointer], (int)tokenisedCondition[bytePointer+1]);
-				detokenisedStream	+= "THEN END ENDIF";
-				bytePointer += 2;
-				numberOfArguments = 0;
-			break;
-			case 30:	// end condition if an object is invisible
-				detokenisedStream	+= "IF INVIS? ";
-				detokenisedStream   += Common::String::format("(%d)", (int)tokenisedCondition[bytePointer]);
-				detokenisedStream   += "THEN END ENDIF";
-				bytePointer ++;
-				numberOfArguments = 0;
-			break;
-			case 31:	// end condition if an object is visible
-				detokenisedStream	+= "IF VIS? ";
-				detokenisedStream   += Common::String::format("(%d)", (int)tokenisedCondition[bytePointer]);
-				detokenisedStream   += "THEN END ENDIF";
-				bytePointer ++;
-				numberOfArguments = 0;
-			break;
-
-			case 12:				detokenisedStream += "SETBIT (";		break;
-			case 13:				detokenisedStream += "CLRBIT (";		break;
-
-			case 15:				detokenisedStream += "SOUND (";			break;
-			case 17:	case 16:	detokenisedStream += "DESTROY (";		break;
-			case 18:				detokenisedStream += "GOTO (";			break;
-
-			case 21:				detokenisedStream += "SWAPJET";			break;
-			case 26:				detokenisedStream += "REDRAW";			break;
-			case 27:				detokenisedStream += "DELAY (";			break;
-			case 28:				detokenisedStream += "SYNCSND (";		break;
-			case 29:				detokenisedStream += "TOGBIT (";		break;
-
-			case 25:
-			{
-				// this should toggle border colour; it's therefore a no-op
-				bytePointer++;
-				numberOfArguments = 0;
-			}
+		case 19: // add one-byte value to shield
+			detokenisedStream += "ADDVAR ";
+			detokenisedStream += Common::String::format("(%d, v%d)", (int)tokenisedCondition[bytePointer], k8bitVariableShield);
+			bytePointer++;
+			numberOfArguments = 0;
 			break;
 
-			case 20:
-				detokenisedStream += "SETVAR ";
-				detokenisedStream += Common::String::format("(%d, v%d)", (int)tokenisedCondition[bytePointer], (int)tokenisedCondition[bytePointer+1]);
-				bytePointer += 2;
-				numberOfArguments = 0;
+		case 6:
+		case 3:
+			detokenisedStream += "TOGVIS (";
+			break; // these all come in unary and binary versions,
+		case 7:
+		case 4:
+			detokenisedStream += "VIS (";
+			break; // hence each getting two case statement entries
+		case 8:
+		case 5:
+			detokenisedStream += "INVIS (";
+			break;
+
+		case 9:
+			detokenisedStream += "ADDVAR (1, v";
+			break;
+		case 10:
+			detokenisedStream += "SUBVAR (1, v";
+			break;
+
+		case 11: // end condition if a variable doesn't have a particular value
+			detokenisedStream += "IF VAR!=? ";
+			detokenisedStream += Common::String::format("(v%d, v%d)", (int)tokenisedCondition[bytePointer], (int)tokenisedCondition[bytePointer + 1]);
+			detokenisedStream += "THEN END ENDIF";
+			bytePointer += 2;
+			numberOfArguments = 0;
+			break;
+		case 14: // end condition if a bit doesn't have a particular value
+			detokenisedStream += "IF BIT!=? ";
+			detokenisedStream += Common::String::format("(%d, %d)", (int)tokenisedCondition[bytePointer], (int)tokenisedCondition[bytePointer + 1]);
+			detokenisedStream += "THEN END ENDIF";
+			bytePointer += 2;
+			numberOfArguments = 0;
+			break;
+		case 30: // end condition if an object is invisible
+			detokenisedStream += "IF INVIS? ";
+			detokenisedStream += Common::String::format("(%d)", (int)tokenisedCondition[bytePointer]);
+			detokenisedStream += "THEN END ENDIF";
+			bytePointer++;
+			numberOfArguments = 0;
+			break;
+		case 31: // end condition if an object is visible
+			detokenisedStream += "IF VIS? ";
+			detokenisedStream += Common::String::format("(%d)", (int)tokenisedCondition[bytePointer]);
+			detokenisedStream += "THEN END ENDIF";
+			bytePointer++;
+			numberOfArguments = 0;
+			break;
+
+		case 12:
+			detokenisedStream += "SETBIT (";
+			break;
+		case 13:
+			detokenisedStream += "CLRBIT (";
+			break;
+
+		case 15:
+			detokenisedStream += "SOUND (";
+			break;
+		case 17:
+		case 16:
+			detokenisedStream += "DESTROY (";
+			break;
+		case 18:
+			detokenisedStream += "GOTO (";
+			break;
+
+		case 21:
+			detokenisedStream += "SWAPJET";
+			break;
+		case 26:
+			detokenisedStream += "REDRAW";
+			break;
+		case 27:
+			detokenisedStream += "DELAY (";
+			break;
+		case 28:
+			detokenisedStream += "SYNCSND (";
+			break;
+		case 29:
+			detokenisedStream += "TOGBIT (";
+			break;
+
+		case 25: {
+			// this should toggle border colour; it's therefore a no-op
+			bytePointer++;
+			numberOfArguments = 0;
+		} break;
+
+		case 20:
+			detokenisedStream += "SETVAR ";
+			detokenisedStream += Common::String::format("(%d, v%d)", (int)tokenisedCondition[bytePointer], (int)tokenisedCondition[bytePointer + 1]);
+			bytePointer += 2;
+			numberOfArguments = 0;
 			break;
 		}
 
 		// if there are any regular arguments to add, do so
-		if(numberOfArguments)
-		{
-			for(uint8 argumentNumber = 0; argumentNumber < numberOfArguments; argumentNumber++)
-			{
+		if (numberOfArguments) {
+			for (uint8 argumentNumber = 0; argumentNumber < numberOfArguments; argumentNumber++) {
 				detokenisedStream += Common::String::format("%d", (int)tokenisedCondition[bytePointer]);
 				bytePointer++;
 
-				if(argumentNumber < numberOfArguments-1)
+				if (argumentNumber < numberOfArguments - 1)
 					detokenisedStream += ", ";
 			}
 
@@ -185,5 +211,4 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 	}
 
 	return (new Common::String(detokenisedStream));
-
 }
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index e85b77e5448..1606183cb1e 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -3,11 +3,11 @@
 #include "common/file.h"
 
 #include "freescape/area.h"
-#include "freescape/loaders/loader.h"
 #include "freescape/language/8bitDetokeniser.h"
 #include "freescape/language/instruction.h"
 #include "freescape/language/parser.h"
 #include "freescape/loaders/8bitBinaryLoader.h"
+#include "freescape/loaders/loader.h"
 #include "freescape/objects/geometricobject.h"
 #include "freescape/objects/object.h"
 
@@ -51,8 +51,7 @@ Binary load8bitBinary(Common::String filename, uint offset) {
 	//uint8 *ConditionPointer = &Base[GlobalByteCodeTable];
 	uint8 numConditions = streamLoader.get8();
 	debug("%d global conditions", numConditions);
-	while(numConditions--)
-	{
+	while (numConditions--) {
 		// get the length
 		uint32 lengthOfCondition = streamLoader.get8();
 		debug("length of condition: %d", lengthOfCondition);
@@ -63,7 +62,6 @@ Binary load8bitBinary(Common::String filename, uint offset) {
 		debug("%s", detokenise8bitCondition(*conditionData)->c_str());
 	}
 
-
 	return Binary{nullptr, nullptr};
 }
 


Commit: a7c57a39b12b95586f4f744049610380329f38b1
    https://github.com/scummvm/scummvm/commit/a7c57a39b12b95586f4f744049610380329f38b1
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:35+01:00

Commit Message:
FREESCAPE: first attempt to do palette parsing

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/loaders/16bitBinaryLoader.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index a6db289c1f5..b139b4c7575 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -102,11 +102,9 @@ Common::Error FreescapeEngine::run() {
 
 	_areasByAreaID = binary.areasByAreaID;
 	_border = binary.border;
+	_palette = binary.palette;
 
-	// 16 colors palette from ultima
-	static const byte PALETTE[16][3] = {
-		{0, 0, 0}, {0xe0, 0xc0, 0x70}, {0xb0, 0x80, 0x40}, {0x80, 0x60, 0x10}, {0x50, 0x30, 0x00}, {0x20, 0x80, 0xd0}, {0x20, 0x50, 0xb0}, {0x20, 0x30, 0x70}, {0x30, 0x40, 0x30}, {0x30, 0x30, 0x30}, {0x40, 0x40, 0x40}, {0x60, 0x60, 0x60}, {0x70, 0x70, 0x70}, {0x90, 0x90, 0x90}, {0xa0, 0xa0, 0xa0}, {0xc0, 0xc0, 0xc0}};
-	g_system->getPaletteManager()->setPalette(&PALETTE[0][0], 0, 16);
+	g_system->getPaletteManager()->setPalette(_palette->data(), 0, 16);
 
 	// Create debugger console. It requires GFX to be initialized
 	//Console *console = new Console(this);
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 09f606154ce..4ab1a3f39f2 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -17,6 +17,7 @@ typedef Common::HashMap<uint16, Area *> AreaMap;
 typedef struct Binary {
 	AreaMap *areasByAreaID;
 	Common::Array<uint8> *border;
+	Common::Array<uint8> *palette;
 } Binary;
 
 class Console;
@@ -35,6 +36,8 @@ private:
 	int _screenW, _screenH;
 
 	Common::Array<uint8> *_border;
+	Common::Array<uint8> *_palette;
+	
 	uint32 _timeOfLastTick;
 	bool _hasReceivedTime;
 	AreaMap *_areasByAreaID;
diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
index 45c70ab89be..e1446b3a11e 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/16bitBinaryLoader.cpp
@@ -362,11 +362,19 @@ Binary load16bitBinary(Common::String filename) {
 
 	Common::Array<uint8>::size_type o;
 	Common::Array<uint8> *raw_border = nullptr;
+	Common::Array<uint8> *raw_palette = nullptr;
+
 	while (!streamLoader.eof()) {
 		o = streamLoader.getFileOffset();
 		if (streamLoader.get32() == 0x452400fa) {
 			debug("Border found at %x", o);
 			raw_border = streamLoader.nextBytes(320 * 200);
+			raw_palette = new Common::Array<uint8>(); 
+
+			for (i = 0; i < 16*3; i++) {
+				raw_palette->push_back(streamLoader.get8() << 2);
+			}
+			
 			break;
 		}
 		streamLoader.setFileOffset(o);
@@ -374,7 +382,7 @@ Binary load16bitBinary(Common::String filename) {
 	}
 
 	delete[] fileOffsetForArea;
-	return Freescape::Binary{areaMap, raw_border};
+	return Freescape::Binary{areaMap, raw_border, raw_palette};
 }
 
 } // namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 1606183cb1e..19ad33216f2 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -62,7 +62,7 @@ Binary load8bitBinary(Common::String filename, uint offset) {
 		debug("%s", detokenise8bitCondition(*conditionData)->c_str());
 	}
 
-	return Binary{nullptr, nullptr};
+	return Binary{nullptr, nullptr, nullptr};
 }
 
 } // namespace Freescape
\ No newline at end of file


Commit: 085c083d2b29aecf1f1359001db7820bd23d964e
    https://github.com/scummvm/scummvm/commit/085c083d2b29aecf1f1359001db7820bd23d964e
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:35+01:00

Commit Message:
FREESCAPE: initial tinygl support

Changed paths:
  A engines/freescape/gfx.cpp
  A engines/freescape/gfx.h
  A engines/freescape/gfx_tinygl.cpp
  A engines/freescape/gfx_tinygl.h
  A engines/freescape/gfx_tinygl_texture.cpp
  A engines/freescape/gfx_tinygl_texture.h
    engines/freescape/configure.engine
    engines/freescape/detection.cpp
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/module.mk


diff --git a/engines/freescape/configure.engine b/engines/freescape/configure.engine
index 757ed0bc680..5201585bedb 100644
--- a/engines/freescape/configure.engine
+++ b/engines/freescape/configure.engine
@@ -1,3 +1,3 @@
 # This file is included from the main "configure" script
 # add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
-add_engine freescape "Freescape" no
+add_engine freescape "Freescape" no "" "" "highres 16bit"
diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index 78694b83e8c..2d9406ea105 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -5,6 +5,7 @@ namespace Freescape {
 static const PlainGameDescriptor freescapeGames[] = {
 	{"3dkit", "The 3D Kit Game"},
 	{"driller", "Driller"},
+	{"castle", "Castle Master"},
 	{0, 0}};
 
 static const ADGameDescription gameDescriptions[] = {
@@ -23,6 +24,14 @@ static const ADGameDescription gameDescriptions[] = {
 	 Common::kPlatformDOS,
 	 ADGF_NO_FLAGS,
 	 GUIO1(GUIO_NOMIDI)},
+
+	{"Castle",
+	 0,
+	 AD_ENTRY1s("CME.EXE", "99d8b4dbaad1fd73c9afdde550dc5195", 92320),
+	 Common::EN_ANY,
+	 Common::kPlatformDOS,
+	 ADGF_NO_FLAGS,
+	 GUIO1(GUIO_NOMIDI)},
 	AD_TABLE_END_MARKER};
 } // End of namespace Freescape
 
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index b139b4c7575..87e12600d9a 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -11,19 +11,23 @@
 
 #include "engines/util.h"
 
+#include "graphics/renderer.h"
+
 #include "freescape/freescape.h"
+#include "freescape/gfx.h"
 
 #include "freescape/loaders/16bitBinaryLoader.h"
 #include "freescape/loaders/8bitBinaryLoader.h"
 
 #define OFFSET_DARKSIDE 0xc9ce
-#define OFFSET_DRILLER 0x9B40
+#define OFFSET_DRILLER 0x9b40
+#define OFFSET_CASTLE 0x9b40
 #define OFFSET_TOTALECLIPSE 0xcdb7
 
 namespace Freescape {
 
 FreescapeEngine::FreescapeEngine(OSystem *syst)
-	: Engine(syst), _screenW(320), _screenH(200), _border(nullptr) {
+	: Engine(syst), _screenW(320), _screenH(200), _border(nullptr), _gfx(nullptr) {
 	// Put your engine in a sane state, but do nothing big yet;
 	// in particular, do not load data from files; rather, if you
 	// need to do such things, do them from run().
@@ -59,61 +63,63 @@ FreescapeEngine::~FreescapeEngine() {
 
 	// Dispose your resources here
 	delete _rnd;
-	delete _areasByAreaID;
+	//delete _areasByAreaID;
 	delete _border;
+	delete _gfx;
 
 	// Remove all of our debug levels here
 	DebugMan.clearAllDebugChannels();
 }
 
+void FreescapeEngine::convertBorder() {
+	Graphics::PixelFormat srcFormat = Graphics::PixelFormat::createFormatCLUT8();
+	_border = new Graphics::Surface();
+	_border->create(_screenW, _screenH, srcFormat);
+	_border->copyRectToSurface(_rawBorder->data(), _border->w, 0, 0, _border->w, _border->h);
+	_border->convertToInPlace(_pixelFormat, _rawPalette->data());
+}
+
 void FreescapeEngine::drawBorder() {
 	if (_border == nullptr)
 		return;
-	g_system->copyRectToScreen((const void *)_border->data(), _screenW, 0, 0, _screenW, _screenH);
-	g_system->updateScreen();
+
+	Texture *t = _gfx->createTexture(_border);
+	const Common::Rect rect(0, 0, 320, 200);
+
+	_gfx->drawTexturedRect2D(rect, rect, t, 1.0, false);
+	_gfx->flipBuffer();
+	_system->updateScreen();
+	_gfx->freeTexture(t);
 }
 
 Common::Error FreescapeEngine::run() {
-	// Initialize graphics using following:
-	initGraphics(_screenW, _screenH);
-
-	// You could use backend transactions directly as an alternative,
-	// but it isn't recommended, until you want to handle the error values
-	// from OSystem::endGFXTransaction yourself.
-	// This is just an example template:
-	//_system->beginGFXTransaction();
-	//	// This setup the graphics mode according to users seetings
-	//	initCommonGFX(false);
-	//
-	//	// Specify dimensions of game graphics window.
-	//	// In this example: 320x200
-	//	_system->initSize(320, 200);
-	//FIXME: You really want to handle
-	//OSystem::kTransactionSizeChangeFailed here
-	//_system->endGFXTransaction();
-
+	// Initialize graphics:
+	_pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
+	_gfx = Freescape::createRenderer(_system, &_pixelFormat);
+	_gfx->init();
+	_gfx->clear();
+	
 	Binary binary;
 	if (_targetName == "3Dkit")
 		binary = load16bitBinary("3DKIT.RUN");
 	else if (_targetName == "Driller")
 		binary = load8bitBinary("DRILLE.EXE", OFFSET_DRILLER);
+	else if (_targetName == "Castle")
+		binary = load8bitBinary("CME.EXE", OFFSET_CASTLE);
 	else
 		error("%s is an invalid game", _targetName.c_str());
 
 	_areasByAreaID = binary.areasByAreaID;
-	_border = binary.border;
-	_palette = binary.palette;
-
-	g_system->getPaletteManager()->setPalette(_palette->data(), 0, 16);
-
-	// Create debugger console. It requires GFX to be initialized
-	//Console *console = new Console(this);
-	//setDebugger(console);
+	_rawBorder = binary.border;
+	_rawPalette = binary.palette;
+	convertBorder();
 
 	debug("FreescapeEngine::init");
-	drawBorder();
 	// Simple main event loop
 	Common::Event evt;
+
+	drawBorder();
+
 	while (!shouldQuit()) {
 		g_system->getEventManager()->pollEvent(evt);
 		g_system->delayMillis(10);
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 4ab1a3f39f2..c4f916a8fb0 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -9,9 +9,12 @@
 #include "gui/debugger.h"
 
 #include "freescape/area.h"
+#include "freescape/gfx.h"
 
 namespace Freescape {
 
+class Renderer;
+
 typedef Common::HashMap<uint16, Area *> AreaMap;
 
 typedef struct Binary {
@@ -33,10 +36,13 @@ private:
 	// We need random numbers
 	Common::RandomSource *_rnd;
 	Graphics::PixelFormat _pixelFormat;
+	Renderer *_gfx;
 	int _screenW, _screenH;
 
-	Common::Array<uint8> *_border;
-	Common::Array<uint8> *_palette;
+	Common::Array<uint8> *_rawBorder;
+	Graphics::Surface *_border;
+
+	Common::Array<uint8> *_rawPalette;
 	
 	uint32 _timeOfLastTick;
 	bool _hasReceivedTime;
@@ -50,6 +56,7 @@ public:
 	Graphics::Surface *_compositeSurface;
 
 	Common::Error run() override;
+	void convertBorder();
 	void drawBorder();
 	bool hasFeature(EngineFeature f) const override;
 	bool canLoadGameStateCurrently() override { return true; }
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
new file mode 100644
index 00000000000..30bd63438f1
--- /dev/null
+++ b/engines/freescape/gfx.cpp
@@ -0,0 +1,340 @@
+/* ResidualVM - A 3D game interpreter
+ *
+ * ResidualVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the AUTHORS
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "engines/freescape/gfx.h"
+
+#include "engines/util.h"
+
+#include "common/config-manager.h"
+
+#include "graphics/renderer.h"
+#include "graphics/surface.h"
+
+#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS) || defined(USE_GLES2)
+#include "graphics/opengl/context.h"
+#endif
+
+#include "math/glmath.h"
+
+namespace Freescape {
+
+const float Renderer::cubeVertices[] = {
+	// S     T      X      Y      Z
+	0.0f, 1.0f, -320.0f, -320.0f, -320.0f,
+	1.0f, 1.0f,  320.0f, -320.0f, -320.0f,
+	0.0f, 0.0f, -320.0f,  320.0f, -320.0f,
+	1.0f, 0.0f,  320.0f,  320.0f, -320.0f,
+	0.0f, 1.0f,  320.0f, -320.0f, -320.0f,
+	1.0f, 1.0f, -320.0f, -320.0f, -320.0f,
+	0.0f, 0.0f,  320.0f, -320.0f,  320.0f,
+	1.0f, 0.0f, -320.0f, -320.0f,  320.0f,
+	0.0f, 1.0f,  320.0f, -320.0f,  320.0f,
+	1.0f, 1.0f, -320.0f, -320.0f,  320.0f,
+	0.0f, 0.0f,  320.0f,  320.0f,  320.0f,
+	1.0f, 0.0f, -320.0f,  320.0f,  320.0f,
+	0.0f, 1.0f,  320.0f, -320.0f, -320.0f,
+	1.0f, 1.0f,  320.0f, -320.0f,  320.0f,
+	0.0f, 0.0f,  320.0f,  320.0f, -320.0f,
+	1.0f, 0.0f,  320.0f,  320.0f,  320.0f,
+	0.0f, 1.0f, -320.0f, -320.0f,  320.0f,
+	1.0f, 1.0f, -320.0f, -320.0f, -320.0f,
+	0.0f, 0.0f, -320.0f,  320.0f,  320.0f,
+	1.0f, 0.0f, -320.0f,  320.0f, -320.0f,
+	0.0f, 1.0f,  320.0f,  320.0f,  320.0f,
+	1.0f, 1.0f, -320.0f,  320.0f,  320.0f,
+	0.0f, 0.0f,  320.0f,  320.0f, -320.0f,
+	1.0f, 0.0f, -320.0f,  320.0f, -320.0f
+};
+
+Renderer::Renderer(OSystem *system)
+		: _system(system),
+		  _font(nullptr) {
+
+	// Compute the cube faces Axis Aligned Bounding Boxes
+	for (uint i = 0; i < ARRAYSIZE(_cubeFacesAABB); i++) {
+		for (uint j = 0; j < 4; j++) {
+			_cubeFacesAABB[i].expand(Math::Vector3d(cubeVertices[5 * (4 * i + j) + 2], cubeVertices[5 * (4 * i + j) + 3], cubeVertices[5 * (4 * i + j) + 4]));
+		}
+	}
+}
+
+Renderer::~Renderer() {
+}
+
+void Renderer::initFont(const Graphics::Surface *surface) {
+	_font = createTexture(surface);
+}
+
+void Renderer::freeFont() {
+	if (_font) {
+		freeTexture(_font);
+		_font = nullptr;
+	}
+}
+
+Texture *Renderer::copyScreenshotToTexture() {
+	Graphics::Surface *surface = getScreenshot();
+
+	Texture *texture = createTexture(surface);
+
+	surface->free();
+	delete surface;
+
+	return texture;
+}
+
+Common::Rect Renderer::getFontCharacterRect(uint8 character) {
+	uint index = 0;
+
+	if (character == ' ')
+		index = 0;
+	else if (character >= '0' && character <= '9')
+		index = 1 + character - '0';
+	else if (character >= 'A' && character <= 'Z')
+		index = 1 + 10 + character - 'A';
+	else if (character == '|')
+		index = 1 + 10 + 26;
+	else if (character == '/')
+		index = 2 + 10 + 26;
+	else if (character == ':')
+		index = 3 + 10 + 26;
+
+	return Common::Rect(16 * index, 0, 16 * (index + 1), 32);
+}
+
+Common::Rect Renderer::viewport() const {
+	return _screenViewport;
+}
+
+void Renderer::computeScreenViewport() {
+	int32 screenWidth = _system->getWidth();
+	int32 screenHeight = _system->getHeight();
+
+	/*if (ConfMan.getBool("widescreen_mod")) {
+		_screenViewport = Common::Rect(screenWidth, screenHeight);
+	} else {*/
+		// Aspect ratio correction
+		int32 viewportWidth = MIN<int32>(screenWidth, screenHeight * kOriginalWidth / kOriginalHeight);
+		int32 viewportHeight = MIN<int32>(screenHeight, screenWidth * kOriginalHeight / kOriginalWidth);
+		_screenViewport = Common::Rect(viewportWidth, viewportHeight);
+
+		// Pillarboxing
+		_screenViewport.translate((screenWidth - viewportWidth) / 2,
+			(screenHeight - viewportHeight) / 2);
+	//}
+}
+
+Math::Matrix4 Renderer::makeProjectionMatrix(float fov) const {
+	static const float nearClipPlane = 1.0;
+	static const float farClipPlane = 10000.0;
+
+	float aspectRatio = kOriginalWidth / (float) kFrameHeight;
+
+	float xmaxValue = nearClipPlane * tan(fov * M_PI / 360.0);
+	float ymaxValue = xmaxValue / aspectRatio;
+
+	return Math::makeFrustumMatrix(-xmaxValue, xmaxValue, -ymaxValue, ymaxValue, nearClipPlane, farClipPlane);
+}
+
+void Renderer::setupCameraPerspective(float pitch, float heading, float fov) {
+	_projectionMatrix = makeProjectionMatrix(fov);
+	_modelViewMatrix = Math::Matrix4(180.0f - heading, pitch, 0.0f, Math::EO_YXZ);
+
+	Math::Matrix4 proj = _projectionMatrix;
+	Math::Matrix4 model = _modelViewMatrix;
+	proj.transpose();
+	model.transpose();
+
+	_mvpMatrix = proj * model;
+
+	_frustum.setup(_mvpMatrix);
+
+	_mvpMatrix.transpose();
+}
+
+bool Renderer::isCubeFaceVisible(uint face) {
+	assert(face < 6);
+
+	return _frustum.isInside(_cubeFacesAABB[face]);
+}
+
+void Renderer::flipVertical(Graphics::Surface *s) {
+	for (int y = 0; y < s->h / 2; ++y) {
+		// Flip the lines
+		byte *line1P = (byte *)s->getBasePtr(0, y);
+		byte *line2P = (byte *)s->getBasePtr(0, s->h - y - 1);
+
+		for (int x = 0; x < s->pitch; ++x)
+			SWAP(line1P[x], line2P[x]);
+	}
+}
+
+Renderer *createRenderer(OSystem *system, Graphics::PixelFormat *pixelFormat) {
+	Common::String rendererConfig = ConfMan.get("renderer");
+	Graphics::RendererType desiredRendererType = Graphics::kRendererTypeTinyGL; //Graphics::parseRendererTypeCode(rendererConfig);
+	Graphics::RendererType matchingRendererType = Graphics::kRendererTypeTinyGL; //Graphics::getBestMatchingAvailableRendererType(desiredRendererType);
+
+	bool isAccelerated = 0; //matchingRendererType != Graphics::kRendererTypeTinyGL;
+
+	uint width;
+	uint height = Renderer::kOriginalHeight;
+	/*if (ConfMan.getBool("widescreen_mod")) {
+		width = Renderer::kOriginalWidth * Renderer::kOriginalHeight / Renderer::kFrameHeight;
+	} else {*/
+		width = Renderer::kOriginalWidth;
+	//}
+	debug("w: %d, h: %d", width, height);
+	if (isAccelerated) {
+		initGraphics3d(width, height);
+	} else {
+		initGraphics(width, height, pixelFormat);
+	}
+
+/*#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS) || defined(USE_GLES2)
+	bool backendCapableOpenGL = g_system->hasFeature(OSystem::kFeatureOpenGLForGame);
+#endif
+
+#if defined(USE_OPENGL_GAME)
+	// Check the OpenGL context actually supports shaders
+	if (backendCapableOpenGL && matchingRendererType == Graphics::kRendererTypeOpenGLShaders && !OpenGLContext.shadersSupported) {
+		matchingRendererType = Graphics::kRendererTypeOpenGL;
+	}
+#endif*/
+
+	if (matchingRendererType != desiredRendererType && desiredRendererType != Graphics::kRendererTypeDefault) {
+		// Display a warning if unable to use the desired renderer
+		warning("Unable to create a '%s' renderer", rendererConfig.c_str());
+	}
+/*
+#if defined(USE_GLES2) || defined(USE_OPENGL_SHADERS)
+	if (backendCapableOpenGL && matchingRendererType == Graphics::kRendererTypeOpenGLShaders) {
+		return CreateGfxOpenGLShader(system);
+	}
+#endif
+#if defined(USE_OPENGL_GAME) && !defined(USE_GLES2)
+	if (backendCapableOpenGL && matchingRendererType == Graphics::kRendererTypeOpenGL) {
+		return CreateGfxOpenGL(system);
+	}
+#endif*/
+	if (matchingRendererType == Graphics::kRendererTypeTinyGL) {
+		return CreateGfxTinyGL(system);
+	}
+
+	error("Unable to create a '%s' renderer", rendererConfig.c_str());
+}
+
+void Renderer::renderDrawable(Drawable *drawable, Window *window) {
+	if (drawable->isConstrainedToWindow()) {
+		selectTargetWindow(window, drawable->is3D(), drawable->isScaled());
+	} else {
+		selectTargetWindow(nullptr, drawable->is3D(), drawable->isScaled());
+	}
+	drawable->draw();
+}
+
+void Renderer::renderDrawableOverlay(Drawable *drawable, Window *window) {
+	// Overlays are always 2D
+	if (drawable->isConstrainedToWindow()) {
+		selectTargetWindow(window, drawable->is3D(), drawable->isScaled());
+	} else {
+		selectTargetWindow(nullptr, drawable->is3D(), drawable->isScaled());
+	}
+	drawable->drawOverlay();
+}
+
+void Renderer::renderWindow(Window *window) {
+	renderDrawable(window, window);
+}
+
+void Renderer::renderWindowOverlay(Window *window) {
+	renderDrawableOverlay(window, window);
+}
+
+Drawable::Drawable() :
+		_isConstrainedToWindow(true),
+		_is3D(false),
+		_scaled(true) {
+}
+
+Common::Point Window::getCenter() const {
+	Common::Rect frame = getPosition();
+
+	return Common::Point((frame.left + frame.right) / 2, (frame.top + frame.bottom) / 2);
+}
+
+Common::Point Window::screenPosToWindowPos(const Common::Point &screen) const {
+	Common::Rect frame = getPosition();
+
+	return Common::Point(screen.x - frame.left, screen.y - frame.top);
+}
+
+Common::Point Window::scalePoint(const Common::Point &screen) const {
+	Common::Rect viewport = getPosition();
+	Common::Rect originalViewport = getOriginalPosition();
+
+	Common::Point scaledPosition = screen;
+	scaledPosition.x -= viewport.left;
+	scaledPosition.y -= viewport.top;
+	scaledPosition.x = CLIP<int16>(scaledPosition.x, 0, viewport.width());
+	scaledPosition.y = CLIP<int16>(scaledPosition.y, 0, viewport.height());
+
+	if (_scaled) {
+		scaledPosition.x *= originalViewport.width() / (float) viewport.width();
+		scaledPosition.y *= originalViewport.height() / (float) viewport.height();
+	}
+
+	return scaledPosition;
+}
+
+FrameLimiter::FrameLimiter(OSystem *system, const uint framerate) :
+	_system(system),
+	_speedLimitMs(0),
+	_startFrameTime(0) {
+	// The frame limiter is disabled when vsync is enabled.
+	_enabled = !_system->getFeatureState(OSystem::kFeatureVSync) && framerate != 0;
+
+	if (_enabled) {
+		_speedLimitMs = 1000 / CLIP<uint>(framerate, 0, 100);
+	}
+}
+
+void FrameLimiter::startFrame() {
+	_startFrameTime = _system->getMillis();
+}
+
+void FrameLimiter::delayBeforeSwap() {
+	uint endFrameTime = _system->getMillis();
+	uint frameDuration = endFrameTime - _startFrameTime;
+
+	if (_enabled && frameDuration < _speedLimitMs) {
+		_system->delayMillis(_speedLimitMs - frameDuration);
+	}
+}
+
+const Graphics::PixelFormat Texture::getRGBAPixelFormat() {
+#ifdef SCUMM_BIG_ENDIAN
+	return Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
+#else
+	return Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24);
+#endif
+}
+} // End of namespace Myst3
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
new file mode 100644
index 00000000000..d0b1d10bfa1
--- /dev/null
+++ b/engines/freescape/gfx.h
@@ -0,0 +1,227 @@
+/* ResidualVM - A 3D game interpreter
+ *
+ * ResidualVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the AUTHORS
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GFX_H_
+#define GFX_H_
+
+#include "common/rect.h"
+#include "common/system.h"
+
+#include "math/frustum.h"
+#include "math/matrix4.h"
+#include "math/vector3d.h"
+
+namespace Freescape {
+
+class Renderer;
+
+class Drawable {
+public:
+	Drawable();
+	virtual ~Drawable() {}
+
+	virtual void draw() {}
+	virtual void drawOverlay() {}
+
+	/** Should the drawable be drawn inside the active window, or is it allowed to draw on the entire screen? */
+	bool isConstrainedToWindow() const { return _isConstrainedToWindow; }
+
+	/** Whether to setup the renderer state for 2D or 3D when processing the drawable */
+	bool is3D() const { return _is3D; }
+
+	/** Whether to scale the drawable to a size equivalent to the original engine or to draw it at its native size */
+	bool isScaled() const { return _scaled; }
+
+protected:
+	bool _isConstrainedToWindow;
+	bool _is3D;
+	bool _scaled;
+};
+
+/**
+ * Game screen window
+ *
+ * A window represents a game screen pane.
+ * It allows abstracting the rendering position from the behavior.
+ */
+class Window : public Drawable {
+public:
+	/**
+	 * Get the window position in screen coordinates
+	 */
+	virtual Common::Rect getPosition() const = 0;
+
+	/**
+	 * Get the window position in original (640x480) screen coordinates
+	 */
+	virtual Common::Rect getOriginalPosition() const = 0;
+
+	/**
+	 * Get the window center in screen coordinates
+	 */
+	Common::Point getCenter() const;
+
+	/**
+	 * Convert screen coordinates to window coordinates
+	 */
+	Common::Point screenPosToWindowPos(const Common::Point &screen) const;
+
+	/**
+	 * Transform a point from screen coordinates to scaled window coordinates
+	 */
+	Common::Point scalePoint(const Common::Point &screen) const;
+};
+
+class Texture {
+public:
+	uint width;
+	uint height;
+	Graphics::PixelFormat format;
+
+	virtual void update(const Graphics::Surface *surface) = 0;
+	virtual void updatePartial(const Graphics::Surface *surface, const Common::Rect &rect) = 0;
+
+	static const Graphics::PixelFormat getRGBAPixelFormat();
+protected:
+	Texture() {}
+	virtual ~Texture() {}
+};
+
+class Renderer {
+public:
+	Renderer(OSystem *system);
+	virtual ~Renderer();
+
+	virtual void init() = 0;
+	virtual void clear() = 0;
+
+	/**
+	 *  Swap the buffers, making the drawn screen visible
+	 */
+	virtual void flipBuffer() { }
+
+	virtual void initFont(const Graphics::Surface *surface);
+	virtual void freeFont();
+
+	virtual Texture *createTexture(const Graphics::Surface *surface) = 0;
+	virtual void freeTexture(Texture *texture) = 0;
+
+	virtual void drawRect2D(const Common::Rect &rect, uint32 color) = 0;
+	virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture,
+									float transparency = -1.0, bool additiveBlending = false) = 0;
+	virtual void drawTexturedRect3D(const Math::Vector3d &topLeft, const Math::Vector3d &bottomLeft,
+									const Math::Vector3d &topRight, const Math::Vector3d &bottomRight,
+									Texture *texture) = 0;
+
+	virtual void drawCube(Texture **textures) = 0;
+	virtual void draw2DText(const Common::String &text, const Common::Point &position) = 0;
+
+	virtual Graphics::Surface *getScreenshot() = 0;
+	virtual Texture *copyScreenshotToTexture();
+
+	/** Render a Drawable in the specified window */
+	void renderDrawable(Drawable *drawable, Window *window);
+
+	/** Render a Drawable overlay in the specified window */
+	void renderDrawableOverlay(Drawable *drawable, Window *window);
+
+	/** Render the main Drawable of a Window */
+	void renderWindow(Window *window);
+
+	/** Render the main Drawable overlay of a Window */
+	void renderWindowOverlay(Window *window);
+
+	Common::Rect viewport() const;
+
+	/**
+	 * Select the window where to render
+	 *
+	 * This also sets the viewport
+	 */
+	virtual void selectTargetWindow(Window *window, bool is3D, bool scaled) = 0;
+
+	void setupCameraPerspective(float pitch, float heading, float fov);
+
+	bool isCubeFaceVisible(uint face);
+
+	Math::Matrix4 getMvpMatrix() const { return _mvpMatrix; }
+
+	void flipVertical(Graphics::Surface *s);
+
+	static const int kOriginalWidth = 320;
+	static const int kOriginalHeight = 200;
+	static const int kTopBorderHeight = 30;
+	static const int kBottomBorderHeight = 90;
+	static const int kFrameHeight = 360;
+
+	void computeScreenViewport();
+
+protected:
+	OSystem *_system;
+	Texture *_font;
+
+	Common::Rect _screenViewport;
+
+	Math::Matrix4 _projectionMatrix;
+	Math::Matrix4 _modelViewMatrix;
+	Math::Matrix4 _mvpMatrix;
+
+	Math::Frustum _frustum;
+
+	static const float cubeVertices[5 * 6 * 4];
+	Math::AABB _cubeFacesAABB[6];
+
+	Common::Rect getFontCharacterRect(uint8 character);
+
+	Math::Matrix4 makeProjectionMatrix(float fov) const;
+};
+
+/**
+ * A framerate limiter
+ *
+ * Ensures the framerate does not exceed the specified value
+ * by delaying until all of the timeslot allocated to the frame
+ * is consumed.
+ * Allows to curb CPU usage and have a stable framerate.
+ */
+class FrameLimiter {
+public:
+	FrameLimiter(OSystem *system, const uint framerate);
+
+	void startFrame();
+	void delayBeforeSwap();
+private:
+	OSystem *_system;
+
+	bool _enabled;
+	uint _speedLimitMs;
+	uint _startFrameTime;
+};
+
+Renderer *CreateGfxOpenGL(OSystem *system);
+Renderer *CreateGfxOpenGLShader(OSystem *system);
+Renderer *CreateGfxTinyGL(OSystem *system);
+Renderer *createRenderer(OSystem *system, Graphics::PixelFormat *pixelFormat);
+
+} // End of namespace Myst3
+
+#endif // GFX_H_
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
new file mode 100644
index 00000000000..4c3585b7ca8
--- /dev/null
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -0,0 +1,297 @@
+/* ResidualVM - A 3D game interpreter
+ *
+ * ResidualVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the AUTHORS
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/config-manager.h"
+#include "common/rect.h"
+#include "common/textconsole.h"
+
+#include "graphics/colormasks.h"
+#include "graphics/surface.h"
+
+#include "math/vector2d.h"
+#include "math/glmath.h"
+
+#include "engines/freescape/gfx.h"
+#include "engines/freescape/gfx_tinygl.h"
+#include "engines/freescape/gfx_tinygl_texture.h"
+#include "graphics/tinygl/zblit.h"
+
+namespace Freescape {
+
+Renderer *CreateGfxTinyGL(OSystem *system) {
+	return new TinyGLRenderer(system);
+}
+
+TinyGLRenderer::TinyGLRenderer(OSystem *system) :
+		Renderer(system),
+		_fb(NULL) {
+}
+
+TinyGLRenderer::~TinyGLRenderer() {
+}
+
+Texture *TinyGLRenderer::createTexture(const Graphics::Surface *surface) {
+	return new TinyGLTexture(surface);
+}
+
+void TinyGLRenderer::freeTexture(Texture *texture) {
+	TinyGLTexture *glTexture = static_cast<TinyGLTexture *>(texture);
+	delete glTexture;
+}
+
+void TinyGLRenderer::init() {
+	debug("Initializing Software 3D Renderer");
+
+	computeScreenViewport();
+
+	_fb = new TinyGL::FrameBuffer(kOriginalWidth, kOriginalHeight, g_system->getScreenFormat());
+	TinyGL::glInit(_fb, 512);
+	tglEnableDirtyRects(ConfMan.getBool("dirtyrects"));
+
+	tglMatrixMode(TGL_PROJECTION);
+	tglLoadIdentity();
+
+	tglMatrixMode(TGL_MODELVIEW);
+	tglLoadIdentity();
+
+	tglDisable(TGL_LIGHTING);
+	tglEnable(TGL_TEXTURE_2D);
+	tglEnable(TGL_DEPTH_TEST);
+}
+
+void TinyGLRenderer::clear() {
+	tglClear(TGL_COLOR_BUFFER_BIT | TGL_DEPTH_BUFFER_BIT);
+	tglColor3f(1.0f, 1.0f, 1.0f);
+}
+
+void TinyGLRenderer::selectTargetWindow(Window *window, bool is3D, bool scaled) {
+	// NOTE: tinyGL viewport implementation needs to be checked as it doesn't behave the same as openGL
+
+	if (!window) {
+		// No window found ...
+		if (scaled) {
+			// ... in scaled mode draw in the original game screen area
+			Common::Rect vp = viewport();
+			tglViewport(vp.left, vp.top, vp.width(), vp.height());
+			//tglViewport(vp.left, _system->getHeight() - vp.top - vp.height(), vp.width(), vp.height());
+		} else {
+			// ... otherwise, draw on the whole screen
+			tglViewport(0, 0, _system->getWidth(), _system->getHeight());
+		}
+	} else {
+		// Found a window, draw inside it
+		Common::Rect vp = window->getPosition();
+		tglViewport(vp.left, vp.top, vp.width(), vp.height());
+		//tglViewport(vp.left, _system->getHeight() - vp.top - vp.height(), vp.width(), vp.height());
+	}
+
+	if (is3D) {
+		tglMatrixMode(TGL_PROJECTION);
+		tglLoadMatrixf(_projectionMatrix.getData());
+
+		tglMatrixMode(TGL_MODELVIEW);
+		tglLoadMatrixf(_modelViewMatrix.getData());
+	} else {
+		tglMatrixMode(TGL_PROJECTION);
+		tglLoadIdentity();
+
+		if (!window) {
+			if (scaled) {
+				tglOrtho(0.0, kOriginalWidth, kOriginalHeight, 0.0, -1.0, 1.0);
+			} else {
+				tglOrtho(0.0, _system->getWidth(), _system->getHeight(), 0.0, -1.0, 1.0);
+			}
+		} else {
+			if (scaled) {
+				Common::Rect originalRect = window->getOriginalPosition();
+				tglOrtho(0.0, originalRect.width(), originalRect.height(), 0.0, -1.0, 1.0);
+			} else {
+				Common::Rect vp = window->getPosition();
+				tglOrtho(0.0, vp.width(), vp.height(), 0.0, -1.0, 1.0);
+			}
+		}
+
+		tglMatrixMode(TGL_MODELVIEW);
+		tglLoadIdentity();
+	}
+}
+
+void TinyGLRenderer::drawRect2D(const Common::Rect &rect, uint32 color) {
+	uint8 a, r, g, b;
+	Graphics::colorToARGB< Graphics::ColorMasks<8888> >(color, a, r, g, b);
+
+	tglDisable(TGL_TEXTURE_2D);
+	tglColor4f(r / 255.0, g / 255.0, b / 255.0, a / 255.0);
+
+	if (a != 255) {
+		tglEnable(TGL_BLEND);
+		tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE_MINUS_SRC_ALPHA);
+	}
+
+	tglBegin(TGL_TRIANGLE_STRIP);
+		tglVertex3f(rect.left, rect.bottom, 0.0f);
+		tglVertex3f(rect.right, rect.bottom, 0.0f);
+		tglVertex3f(rect.left, rect.top, 0.0f);
+		tglVertex3f(rect.right, rect.top, 0.0f);
+	tglEnd();
+
+	tglDisable(TGL_BLEND);
+}
+
+void TinyGLRenderer::drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect,
+		Texture *texture, float transparency, bool additiveBlending) {
+	const float sLeft = screenRect.left;
+	const float sTop = screenRect.top;
+	const float sWidth = screenRect.width();
+	const float sHeight = screenRect.height();
+
+	if (transparency >= 0.0) {
+		if (additiveBlending) {
+			tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE);
+		} else {
+			tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE_MINUS_SRC_ALPHA);
+		}
+		tglEnable(TGL_BLEND);
+	} else {
+		transparency = 1.0;
+	}
+
+	// HACK: tglBlit is not affected by the viewport, so we offset the draw coordinates here
+	int viewPort[4];
+	tglGetIntegerv(TGL_VIEWPORT, viewPort);
+
+	tglEnable(TGL_TEXTURE_2D);
+	tglDepthMask(TGL_FALSE);
+
+	Graphics::BlitTransform transform(sLeft + viewPort[0], sTop + viewPort[1]);
+	transform.sourceRectangle(textureRect.left, textureRect.top, sWidth, sHeight);
+	transform.tint(transparency);
+	tglBlit(((TinyGLTexture *)texture)->getBlitTexture(), transform);
+
+	tglDisable(TGL_BLEND);
+	tglDepthMask(TGL_TRUE);
+}
+
+void TinyGLRenderer::draw2DText(const Common::String &text, const Common::Point &position) {
+	TinyGLTexture *glFont = static_cast<TinyGLTexture *>(_font);
+
+	// The font only has uppercase letters
+	Common::String textToDraw = text;
+	textToDraw.toUppercase();
+
+	tglEnable(TGL_BLEND);
+	tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE_MINUS_SRC_ALPHA);
+
+	tglEnable(TGL_TEXTURE_2D);
+	tglDepthMask(TGL_FALSE);
+
+	tglColor3f(1.0f, 1.0f, 1.0f);
+	tglBindTexture(TGL_TEXTURE_2D, glFont->id);
+
+	int x = position.x;
+	int y = position.y;
+
+	for (uint i = 0; i < textToDraw.size(); i++) {
+		Common::Rect textureRect = getFontCharacterRect(textToDraw[i]);
+		int w = textureRect.width();
+		int h = textureRect.height();
+
+		Graphics::BlitTransform transform(x, y);
+		transform.sourceRectangle(textureRect.left, textureRect.top, w, h);
+		transform.flip(true, false);
+		Graphics::tglBlit(glFont->getBlitTexture(), transform);
+
+		x += textureRect.width() - 3;
+	}
+
+	tglDisable(TGL_TEXTURE_2D);
+	tglDisable(TGL_BLEND);
+	tglDepthMask(TGL_TRUE);
+}
+
+void TinyGLRenderer::drawFace(uint face, Texture *texture) {
+	TinyGLTexture *glTexture = static_cast<TinyGLTexture *>(texture);
+
+	tglBindTexture(TGL_TEXTURE_2D, glTexture->id);
+	tglBegin(TGL_TRIANGLE_STRIP);
+	for (uint i = 0; i < 4; i++) {
+		tglTexCoord2f(cubeVertices[5 * (4 * face + i) + 0], cubeVertices[5 * (4 * face + i) + 1]);
+		tglVertex3f(cubeVertices[5 * (4 * face + i) + 2], cubeVertices[5 * (4 * face + i) + 3], cubeVertices[5 * (4 * face + i) + 4]);
+	}
+	tglEnd();
+}
+
+void TinyGLRenderer::drawCube(Texture **textures) {
+	tglEnable(TGL_TEXTURE_2D);
+	tglDepthMask(TGL_FALSE);
+
+	for (uint i = 0; i < 6; i++) {
+		drawFace(i, textures[i]);
+	}
+
+	tglDepthMask(TGL_TRUE);
+}
+
+void TinyGLRenderer::drawTexturedRect3D(const Math::Vector3d &topLeft, const Math::Vector3d &bottomLeft,
+		const Math::Vector3d &topRight, const Math::Vector3d &bottomRight, Texture *texture) {
+
+	TinyGLTexture *glTexture = static_cast<TinyGLTexture *>(texture);
+
+	tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE_MINUS_SRC_ALPHA);
+	tglEnable(TGL_BLEND);
+	tglDepthMask(TGL_FALSE);
+
+	tglBindTexture(TGL_TEXTURE_2D, glTexture->id);
+
+	tglBegin(TGL_TRIANGLE_STRIP);
+		tglTexCoord2f(0, 0);
+		tglVertex3f(-topLeft.x(), topLeft.y(), topLeft.z());
+
+		tglTexCoord2f(0, 1);
+		tglVertex3f(-bottomLeft.x(), bottomLeft.y(), bottomLeft.z());
+
+		tglTexCoord2f(1, 0);
+		tglVertex3f(-topRight.x(), topRight.y(), topRight.z());
+
+		tglTexCoord2f(1, 1);
+		tglVertex3f(-bottomRight.x(), bottomRight.y(), bottomRight.z());
+	tglEnd();
+
+	tglDisable(TGL_BLEND);
+	tglDepthMask(TGL_TRUE);
+}
+
+Graphics::Surface *TinyGLRenderer::getScreenshot() {
+	Graphics::Surface *s = new Graphics::Surface();
+	s->create(kOriginalWidth, kOriginalHeight, Texture::getRGBAPixelFormat());
+	Graphics::PixelBuffer buf(s->format, (byte *)s->getPixels());
+	_fb->copyToBuffer(buf);
+	return s;
+}
+
+void TinyGLRenderer::flipBuffer() {
+	TinyGL::tglPresentBuffer();
+	g_system->copyRectToScreen(_fb->getPixelBuffer(), _fb->linesize,
+	                           0, 0, _fb->xsize, _fb->ysize);
+}
+
+} // End of namespace Myst3
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
new file mode 100644
index 00000000000..3a62b089c5b
--- /dev/null
+++ b/engines/freescape/gfx_tinygl.h
@@ -0,0 +1,69 @@
+/* ResidualVM - A 3D game interpreter
+ *
+ * ResidualVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the AUTHORS
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GFX_TINYGL_H_
+#define GFX_TINYGL_H_
+
+#include "common/rect.h"
+#include "common/system.h"
+#include "math/vector3d.h"
+
+#include "engines/freescape/gfx.h"
+#include "graphics/tinygl/zgl.h"
+
+namespace Freescape {
+
+class TinyGLRenderer : public Renderer {
+public:
+	TinyGLRenderer(OSystem *_system);
+	virtual ~TinyGLRenderer();
+
+	virtual void init() override;
+
+	virtual void clear() override;
+	virtual void selectTargetWindow(Window *window, bool is3D, bool scaled) override;
+
+	Texture *createTexture(const Graphics::Surface *surface) override;
+	void freeTexture(Texture *texture) override;
+
+	virtual void drawRect2D(const Common::Rect &rect, uint32 color) override;
+	virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture,
+	                                float transparency = -1.0, bool additiveBlending = false) override;
+	virtual void drawTexturedRect3D(const Math::Vector3d &topLeft, const Math::Vector3d &bottomLeft,
+	                                const Math::Vector3d &topRight, const Math::Vector3d &bottomRight,
+	                                Texture *texture) override;
+
+	virtual void drawCube(Texture **textures) override;
+	virtual void draw2DText(const Common::String &text, const Common::Point &position) override;
+
+	virtual Graphics::Surface *getScreenshot() override;
+
+	virtual void flipBuffer() override;
+private:
+	void drawFace(uint face, Texture *texture);
+
+	TinyGL::FrameBuffer *_fb;
+};
+
+} // End of namespace Myst3
+
+#endif // GFX_H_
diff --git a/engines/freescape/gfx_tinygl_texture.cpp b/engines/freescape/gfx_tinygl_texture.cpp
new file mode 100644
index 00000000000..493bd53d9f4
--- /dev/null
+++ b/engines/freescape/gfx_tinygl_texture.cpp
@@ -0,0 +1,77 @@
+/* ResidualVM - A 3D game interpreter
+ *
+ * ResidualVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the AUTHORS
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "engines/freescape/gfx_tinygl_texture.h"
+#include "graphics/tinygl/zblit.h"
+
+namespace Freescape {
+
+TinyGLTexture::TinyGLTexture(const Graphics::Surface *surface) {
+	width = surface->w;
+	height = surface->h;
+	format = surface->format;
+
+	if (format.bytesPerPixel == 4) {
+		internalFormat = TGL_RGBA;
+		sourceFormat = TGL_UNSIGNED_BYTE;
+	} else if (format.bytesPerPixel == 2) {
+		internalFormat = TGL_RGB;
+		sourceFormat = TGL_UNSIGNED_SHORT_5_6_5;
+	} else
+		error("Unknown pixel format");
+
+	tglGenTextures(1, &id);
+	tglBindTexture(TGL_TEXTURE_2D, id);
+	tglTexImage2D(TGL_TEXTURE_2D, 0, 3, width, height, 0, internalFormat, sourceFormat, 0);
+	tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_MIN_FILTER, TGL_LINEAR);
+	tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_MAG_FILTER, TGL_LINEAR);
+
+	// NOTE: TinyGL doesn't have issues with white lines so doesn't need use TGL_CLAMP_TO_EDGE
+	tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_WRAP_S, TGL_REPEAT);
+	tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_WRAP_T, TGL_REPEAT);
+	_blitImage = Graphics::tglGenBlitImage();
+
+	update(surface);
+}
+
+TinyGLTexture::~TinyGLTexture() {
+	tglDeleteTextures(1, &id);
+	tglDeleteBlitImage(_blitImage);
+}
+
+void TinyGLTexture::update(const Graphics::Surface *surface) {
+	tglBindTexture(TGL_TEXTURE_2D, id);
+	tglTexImage2D(TGL_TEXTURE_2D, 0, 3, width, height, 0,
+			internalFormat, sourceFormat, const_cast<void *>(surface->getPixels())); // TESTME: Not sure if it works.
+	Graphics::tglUploadBlitImage(_blitImage, *surface, 0, false);
+}
+
+void TinyGLTexture::updatePartial(const Graphics::Surface *surface, const Common::Rect &rect) {
+	// FIXME: TinyGL does not support partial texture update
+	update(surface);
+}
+
+Graphics::BlitImage *TinyGLTexture::getBlitTexture() const {
+	return _blitImage;
+}
+
+} // End of namespace Myst3
diff --git a/engines/freescape/gfx_tinygl_texture.h b/engines/freescape/gfx_tinygl_texture.h
new file mode 100644
index 00000000000..78f29e26621
--- /dev/null
+++ b/engines/freescape/gfx_tinygl_texture.h
@@ -0,0 +1,54 @@
+/* ResidualVM - A 3D game interpreter
+ *
+ * ResidualVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the AUTHORS
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GFX_TINYGL_TEXTURE_H
+#define GFX_TINYGL_TEXTURE_H
+
+#include "graphics/surface.h"
+#include "graphics/tinygl/zgl.h"
+#include "common/textconsole.h"
+
+#include "engines/freescape/gfx.h"
+#include "graphics/tinygl/zblit.h"
+
+namespace Freescape {
+
+class TinyGLTexture : public Texture {
+public:
+	TinyGLTexture(const Graphics::Surface *surface);
+	virtual ~TinyGLTexture();
+
+	Graphics::BlitImage *getBlitTexture() const;
+
+	void update(const Graphics::Surface *surface) override;
+	void updatePartial(const Graphics::Surface *surface, const Common::Rect &rect) override;
+
+	TGLuint id;
+	TGLuint internalFormat;
+	TGLuint sourceFormat;
+private:
+	Graphics::BlitImage *_blitImage;
+};
+
+} // End of namespace Myst3
+
+#endif
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index c0269d4687c..edac86f4e98 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -4,6 +4,9 @@ MODULE_OBJS := \
 	metaengine.o \
 	freescape.o \
 	area.o \
+	gfx.o \
+	gfx_tinygl.o \
+	gfx_tinygl_texture.o \
 	objects/object.o \
 	objects/geometricobject.o \
 	loaders/8bitBinaryLoader.o \


Commit: 868d07e2df1f9356eff83fbb23d0fbf2420c7bc4
    https://github.com/scummvm/scummvm/commit/868d07e2df1f9356eff83fbb23d0fbf2420c7bc4
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:35+01:00

Commit Message:
FREESCAPE: start area support and empty draw code

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/loaders/16bitBinaryLoader.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/objects/object.cpp
    engines/freescape/objects/object.h


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 7cb41b7ecc4..919e349a7f8 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -82,12 +82,12 @@ Area::~Area() {
 
 	for(std::vector<Object *>::iterator iterator = drawableObjects.begin(); iterator != drawableObjects.end(); iterator++)
 		(*iterator)->setupOpenGL(vertexBuffer, drawElementsBuffer);
-}
+}*/
 
-void Area::draw(bool allowPolygonOffset, BatchDrawer *batchDrawer)
+void Area::draw(/*bool allowPolygonOffset, BatchDrawer *batchDrawer*/)
 {
-	for(std::vector<Object *>::iterator iterator = drawableObjects.begin(); iterator != drawableObjects.end(); iterator++)
+	for(Common::Array<Object *>::iterator iterator = drawableObjects.begin(); iterator != drawableObjects.end(); iterator++)
 	{
-		(*iterator)->draw(vertexBuffer, drawElementsBuffer, batchDrawer, allowPolygonOffset);
+		(*iterator)->draw(/*vertexBuffer, drawElementsBuffer, batchDrawer, allowPolygonOffset*/);
 	}
-}*/
+}
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index a77809e759e..58a77bf8e21 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -28,9 +28,7 @@ public:
 	Object *objectWithID(uint16 objectID);
 	Object *entranceWithID(uint16 objectID);
 	uint16 getAreaID();
-
-	//void setupOpenGL();
-	//void draw(bool allowPolygonOffset, BatchDrawer *batchDrawer);
+	void draw(/*bool allowPolygonOffset, BatchDrawer *batchDrawer*/);
 
 private:
 	uint16 areaID;
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 87e12600d9a..ed2634ebcc5 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -112,6 +112,7 @@ Common::Error FreescapeEngine::run() {
 	_areasByAreaID = binary.areasByAreaID;
 	_rawBorder = binary.border;
 	_rawPalette = binary.palette;
+	_startArea = binary.startArea;
 	convertBorder();
 
 	debug("FreescapeEngine::init");
@@ -119,6 +120,10 @@ Common::Error FreescapeEngine::run() {
 	Common::Event evt;
 
 	drawBorder();
+	assert(_areasByAreaID->contains(_startArea));
+	Area *area = (*_areasByAreaID)[_startArea];
+	assert(area);
+	area->draw();
 
 	while (!shouldQuit()) {
 		g_system->getEventManager()->pollEvent(evt);
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index c4f916a8fb0..6aa42a94a8d 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -18,6 +18,7 @@ class Renderer;
 typedef Common::HashMap<uint16, Area *> AreaMap;
 
 typedef struct Binary {
+	uint16 startArea; 
 	AreaMap *areasByAreaID;
 	Common::Array<uint8> *border;
 	Common::Array<uint8> *palette;
@@ -46,6 +47,8 @@ private:
 	
 	uint32 _timeOfLastTick;
 	bool _hasReceivedTime;
+
+	uint16 _startArea;
 	AreaMap *_areasByAreaID;
 	float _rotation[3], _velocity[3], _position[3];
 
diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
index e1446b3a11e..78b2ee82e7f 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/16bitBinaryLoader.cpp
@@ -382,7 +382,7 @@ Binary load16bitBinary(Common::String filename) {
 	}
 
 	delete[] fileOffsetForArea;
-	return Freescape::Binary{areaMap, raw_border, raw_palette};
+	return Freescape::Binary{startArea, areaMap, raw_border, raw_palette};
 }
 
 } // namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 19ad33216f2..a284c6b6c7f 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -62,7 +62,7 @@ Binary load8bitBinary(Common::String filename, uint offset) {
 		debug("%s", detokenise8bitCondition(*conditionData)->c_str());
 	}
 
-	return Binary{nullptr, nullptr, nullptr};
+	return Binary{0, nullptr, nullptr, nullptr};
 }
 
 } // namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/objects/object.cpp b/engines/freescape/objects/object.cpp
index b11389a7ab8..a555ea1ff6b 100644
--- a/engines/freescape/objects/object.cpp
+++ b/engines/freescape/objects/object.cpp
@@ -14,7 +14,7 @@ uint16 Object::getObjectID() { return objectID; }
 //Vector3d Object::getSize()		{	return size;		}
 
 //void Object::setupOpenGL(VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer)					{}
-//void Object::draw(VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer, BatchDrawer *batchDrawer, bool allowPolygonOffset)	{}
+void Object::draw(/*VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer, BatchDrawer *batchDrawer, bool allowPolygonOffset*/)	{}
 bool Object::isDrawable() { return false; }
 bool Object::isPlanar() { return false; }
 
diff --git a/engines/freescape/objects/object.h b/engines/freescape/objects/object.h
index 934e37ac528..acf1c529fd4 100644
--- a/engines/freescape/objects/object.h
+++ b/engines/freescape/objects/object.h
@@ -60,10 +60,10 @@ public:
 	Vector3d getOrigin();
 	Vector3d getSize();
 
-	/*
-		virtual void setupOpenGL(VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer);
-		virtual void draw(VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer, BatchDrawer *batchDrawer, bool allowPolygonOffset);
-		*/
+	
+		//virtual void setupOpenGL(VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer);
+	virtual void draw(/*VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer, BatchDrawer *batchDrawer, bool allowPolygonOffset*/);
+	
 	virtual bool isDrawable();
 	virtual bool isPlanar();
 


Commit: 62aa8d4bf568e95ce444ea067a2847d288503077
    https://github.com/scummvm/scummvm/commit/62aa8d4bf568e95ce444ea067a2847d288503077
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:35+01:00

Commit Message:
FREESCAPE: fixes in the main and object class

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/objects/object.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index ed2634ebcc5..78219014f64 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -26,12 +26,15 @@
 
 namespace Freescape {
 
+FreescapeEngine *g_freescape = NULL;
+
 FreescapeEngine::FreescapeEngine(OSystem *syst)
 	: Engine(syst), _screenW(320), _screenH(200), _border(nullptr), _gfx(nullptr) {
 	// Put your engine in a sane state, but do nothing big yet;
 	// in particular, do not load data from files; rather, if you
 	// need to do such things, do them from run().
 
+	g_freescape = this;
 	// Do not initialize graphics here
 	// Do not initialize audio devices here
 	_hasReceivedTime = false;
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 6aa42a94a8d..1870c50e772 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -37,7 +37,6 @@ private:
 	// We need random numbers
 	Common::RandomSource *_rnd;
 	Graphics::PixelFormat _pixelFormat;
-	Renderer *_gfx;
 	int _screenW, _screenH;
 
 	Common::Array<uint8> *_rawBorder;
@@ -56,8 +55,7 @@ public:
 	FreescapeEngine(OSystem *syst);
 	~FreescapeEngine();
 
-	Graphics::Surface *_compositeSurface;
-
+	Renderer *_gfx;
 	Common::Error run() override;
 	void convertBorder();
 	void drawBorder();
@@ -78,6 +76,8 @@ public:
 	}
 };
 
+extern FreescapeEngine *g_freescape;
+
 } // namespace Freescape
 
 #endif
diff --git a/engines/freescape/objects/object.cpp b/engines/freescape/objects/object.cpp
index a555ea1ff6b..f60dc6fda47 100644
--- a/engines/freescape/objects/object.cpp
+++ b/engines/freescape/objects/object.cpp
@@ -7,14 +7,16 @@
 //
 
 #include "freescape/objects/object.h"
-
+#include "freescape/freescape.h"
 Object::Type Object::getType() { return type; }
 uint16 Object::getObjectID() { return objectID; }
 //Vector3d Object::getOrigin()	{	return origin;		}
 //Vector3d Object::getSize()		{	return size;		}
 
 //void Object::setupOpenGL(VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer)					{}
-void Object::draw(/*VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer, BatchDrawer *batchDrawer, bool allowPolygonOffset*/)	{}
+void Object::draw(/*VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer, BatchDrawer *batchDrawer, bool allowPolygonOffset*/) {
+    Freescape::g_freescape->_gfx;
+}
 bool Object::isDrawable() { return false; }
 bool Object::isPlanar() { return false; }
 


Commit: 0cd58b40caedd36039d5eb4a996cca90453c13fa
    https://github.com/scummvm/scummvm/commit/0cd58b40caedd36039d5eb4a996cca90453c13fa
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:35+01:00

Commit Message:
FREESCAPE: fixes in the area and object class

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/freescape.cpp
    engines/freescape/objects/object.cpp
    engines/freescape/objects/object.h


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 919e349a7f8..7a050adbcea 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -84,10 +84,10 @@ Area::~Area() {
 		(*iterator)->setupOpenGL(vertexBuffer, drawElementsBuffer);
 }*/
 
-void Area::draw(/*bool allowPolygonOffset, BatchDrawer *batchDrawer*/)
+void Area::draw(Freescape::Renderer *gfx)
 {
 	for(Common::Array<Object *>::iterator iterator = drawableObjects.begin(); iterator != drawableObjects.end(); iterator++)
 	{
-		(*iterator)->draw(/*vertexBuffer, drawElementsBuffer, batchDrawer, allowPolygonOffset*/);
+		(*iterator)->draw(gfx);
 	}
 }
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index 58a77bf8e21..2111d6c85a8 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -11,6 +11,7 @@
 
 #include "common/hashmap.h"
 #include "freescape/objects/object.h"
+#include "freescape/gfx.h"
 //#include "VertexBuffer.h"
 //#include "DrawElementsBuffer.h"
 
@@ -28,7 +29,7 @@ public:
 	Object *objectWithID(uint16 objectID);
 	Object *entranceWithID(uint16 objectID);
 	uint16 getAreaID();
-	void draw(/*bool allowPolygonOffset, BatchDrawer *batchDrawer*/);
+	void draw(Freescape::Renderer *gfx);
 
 private:
 	uint16 areaID;
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 78219014f64..d8cfd161735 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -126,7 +126,7 @@ Common::Error FreescapeEngine::run() {
 	assert(_areasByAreaID->contains(_startArea));
 	Area *area = (*_areasByAreaID)[_startArea];
 	assert(area);
-	area->draw();
+	area->draw(_gfx);
 
 	while (!shouldQuit()) {
 		g_system->getEventManager()->pollEvent(evt);
diff --git a/engines/freescape/objects/object.cpp b/engines/freescape/objects/object.cpp
index f60dc6fda47..6a8a4883242 100644
--- a/engines/freescape/objects/object.cpp
+++ b/engines/freescape/objects/object.cpp
@@ -8,14 +8,16 @@
 
 #include "freescape/objects/object.h"
 #include "freescape/freescape.h"
+#include "freescape/gfx.h"
+
 Object::Type Object::getType() { return type; }
 uint16 Object::getObjectID() { return objectID; }
 //Vector3d Object::getOrigin()	{	return origin;		}
 //Vector3d Object::getSize()		{	return size;		}
 
 //void Object::setupOpenGL(VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer)					{}
-void Object::draw(/*VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer, BatchDrawer *batchDrawer, bool allowPolygonOffset*/) {
-    Freescape::g_freescape->_gfx;
+void Object::draw(Freescape::Renderer *gfx/*VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer, BatchDrawer *batchDrawer, bool allowPolygonOffset*/) {
+    gfx;
 }
 bool Object::isDrawable() { return false; }
 bool Object::isPlanar() { return false; }
diff --git a/engines/freescape/objects/object.h b/engines/freescape/objects/object.h
index acf1c529fd4..0c4ab260f5f 100644
--- a/engines/freescape/objects/object.h
+++ b/engines/freescape/objects/object.h
@@ -9,6 +9,7 @@
 #ifndef __Phantasma__Object__
 #define __Phantasma__Object__
 
+#include "freescape/gfx.h"
 #include "common/system.h"
 
 //#include <vector>
@@ -62,7 +63,7 @@ public:
 
 	
 		//virtual void setupOpenGL(VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer);
-	virtual void draw(/*VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer, BatchDrawer *batchDrawer, bool allowPolygonOffset*/);
+	virtual void draw(Freescape::Renderer *gfx);
 	
 	virtual bool isDrawable();
 	virtual bool isPlanar();


Commit: 26573ae04869c362be6bf3be62e8c906683f26cc
    https://github.com/scummvm/scummvm/commit/26573ae04869c362be6bf3be62e8c906683f26cc
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:36+01:00

Commit Message:
FREESCAPE: more fixes

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/objects/object.cpp
    engines/freescape/objects/object.h


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 7a050adbcea..1cd00c55b31 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -84,10 +84,8 @@ Area::~Area() {
 		(*iterator)->setupOpenGL(vertexBuffer, drawElementsBuffer);
 }*/
 
-void Area::draw(Freescape::Renderer *gfx)
-{
-	for(Common::Array<Object *>::iterator iterator = drawableObjects.begin(); iterator != drawableObjects.end(); iterator++)
-	{
+void Area::draw(Freescape::Renderer *gfx) {
+	for (Common::Array<Object *>::iterator iterator = drawableObjects.begin(); iterator != drawableObjects.end(); iterator++) {
 		(*iterator)->draw(gfx);
 	}
 }
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index 2111d6c85a8..3e57ec6a5f9 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -10,8 +10,8 @@
 #define __Phantasma__Area__
 
 #include "common/hashmap.h"
-#include "freescape/objects/object.h"
 #include "freescape/gfx.h"
+#include "freescape/objects/object.h"
 //#include "VertexBuffer.h"
 //#include "DrawElementsBuffer.h"
 
diff --git a/engines/freescape/objects/object.cpp b/engines/freescape/objects/object.cpp
index 6a8a4883242..cbad577ca09 100644
--- a/engines/freescape/objects/object.cpp
+++ b/engines/freescape/objects/object.cpp
@@ -16,8 +16,8 @@ uint16 Object::getObjectID() { return objectID; }
 //Vector3d Object::getSize()		{	return size;		}
 
 //void Object::setupOpenGL(VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer)					{}
-void Object::draw(Freescape::Renderer *gfx/*VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer, BatchDrawer *batchDrawer, bool allowPolygonOffset*/) {
-    gfx;
+void Object::draw(Freescape::Renderer *gfx /*VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer, BatchDrawer *batchDrawer, bool allowPolygonOffset*/) {
+	gfx;
 }
 bool Object::isDrawable() { return false; }
 bool Object::isPlanar() { return false; }
diff --git a/engines/freescape/objects/object.h b/engines/freescape/objects/object.h
index 0c4ab260f5f..9337409c41d 100644
--- a/engines/freescape/objects/object.h
+++ b/engines/freescape/objects/object.h
@@ -9,8 +9,8 @@
 #ifndef __Phantasma__Object__
 #define __Phantasma__Object__
 
-#include "freescape/gfx.h"
 #include "common/system.h"
+#include "freescape/gfx.h"
 
 //#include <vector>
 //#include "freescape/language/instruction.h"
@@ -61,10 +61,9 @@ public:
 	Vector3d getOrigin();
 	Vector3d getSize();
 
-	
-		//virtual void setupOpenGL(VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer);
+	//virtual void setupOpenGL(VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer);
 	virtual void draw(Freescape::Renderer *gfx);
-	
+
 	virtual bool isDrawable();
 	virtual bool isPlanar();
 


Commit: 3956250e63b9a75065490bbc0f558e25f7b520d2
    https://github.com/scummvm/scummvm/commit/3956250e63b9a75065490bbc0f558e25f7b520d2
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:36+01:00

Commit Message:
FREESCAPE: initial rendering of sky and ground

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/gfx_tinygl.h
    engines/freescape/loaders/16bitBinaryLoader.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 1cd00c55b31..8c35f7e23f6 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -13,7 +13,8 @@
 Object *Area::objectWithIDFromMap(ObjectMap *map, uint16 objectID) {
 	if (!map)
 		return nullptr;
-	//TODO //if(!map->count(objectID)) return nullptr;
+	if(!map->contains(objectID)) 
+		return nullptr;
 	return (*map)[objectID];
 }
 
@@ -32,7 +33,11 @@ uint16 Area::getAreaID() {
 Area::Area(
 	uint16 _areaID,
 	ObjectMap *_objectsByID,
-	ObjectMap *_entrancesByID) {
+	ObjectMap *_entrancesByID,
+	uint8 _skyColor,
+	uint8 _groundColor) {
+	skyColor = _skyColor;
+	groundColor = _groundColor;
 	areaID = _areaID;
 	objectsByID = _objectsByID;
 	entrancesByID = _entrancesByID;
@@ -85,6 +90,23 @@ Area::~Area() {
 }*/
 
 void Area::draw(Freescape::Renderer *gfx) {
+	debug("w: %d, h: %d", gfx->kOriginalWidth, gfx->kOriginalHeight);
+	Common::Rect sky(-1, 0, 1, 1);
+	uint8 r, g, b;
+	gfx->_palette->getRGBAt(skyColor, r, g, b);
+	//debug("Rendering area %d sky with color %x -> %x %x %x", areaID, skyColor, r, g, b);
+	gfx->drawRect2D(sky, 255, r, g, b);
+
+	Common::Rect ground(-1, -1, 1, 0);
+	gfx->_palette->getRGBAt(groundColor, r, g, b);
+	//debug("Rendering area %d sky with color %x -> %x %x %x", areaID, skyColor, r, g, b);
+	//ground.clip(gfx->_viewToRender);
+	//ground.debugPrint();
+	gfx->drawRect2D(ground, 255, r, g, b);
+
+	gfx->flipBuffer();
+	g_system->updateScreen();
+
 	for (Common::Array<Object *>::iterator iterator = drawableObjects.begin(); iterator != drawableObjects.end(); iterator++) {
 		(*iterator)->draw(gfx);
 	}
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index 3e57ec6a5f9..c431337f6be 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -23,7 +23,9 @@ public:
 	Area(
 		uint16 areaID,
 		ObjectMap *objectsByID,
-		ObjectMap *entrancesByID);
+		ObjectMap *entrancesByID,
+		uint8 skyColor,
+		uint8 groundColor);
 	virtual ~Area();
 
 	Object *objectWithID(uint16 objectID);
@@ -33,6 +35,8 @@ public:
 
 private:
 	uint16 areaID;
+	uint8 skyColor;
+	uint8 groundColor;
 	ObjectMap *objectsByID;
 	ObjectMap *entrancesByID;
 	Common::Array<Object *> drawableObjects;
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index d8cfd161735..1e2d1360bb1 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -75,19 +75,20 @@ FreescapeEngine::~FreescapeEngine() {
 }
 
 void FreescapeEngine::convertBorder() {
-	Graphics::PixelFormat srcFormat = Graphics::PixelFormat::createFormatCLUT8();
-	_border = new Graphics::Surface();
-	_border->create(_screenW, _screenH, srcFormat);
-	_border->copyRectToSurface(_rawBorder->data(), _border->w, 0, 0, _border->w, _border->h);
-	_border->convertToInPlace(_pixelFormat, _rawPalette->data());
+	_borderSurf = new Graphics::Surface();
+	_borderSurf->create(_screenW, _screenH, _originalPixelFormat);
+	_borderSurf->copyRectToSurface(_border->getRawBuffer(), _borderSurf->w, 0, 0, _borderSurf->w, _borderSurf->h);
+	_borderSurf->convertToInPlace(_currentPixelFormat, _palette->getRawBuffer());
 }
 
 void FreescapeEngine::drawBorder() {
 	if (_border == nullptr)
 		return;
 
-	Texture *t = _gfx->createTexture(_border);
+	Texture *t = _gfx->createTexture(_borderSurf);
 	const Common::Rect rect(0, 0, 320, 200);
+	//g_system->copyRectToScreen(_borderSurf->getPixels(), _borderSurf->pitch, 0, 0, _screenW, _screenH);
+
 
 	_gfx->drawTexturedRect2D(rect, rect, t, 1.0, false);
 	_gfx->flipBuffer();
@@ -97,8 +98,12 @@ void FreescapeEngine::drawBorder() {
 
 Common::Error FreescapeEngine::run() {
 	// Initialize graphics:
-	_pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
-	_gfx = Freescape::createRenderer(_system, &_pixelFormat);
+	_currentPixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
+	_originalPixelFormat = Graphics::PixelFormat::createFormatCLUT8();
+	_palettePixelFormat = Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0);
+
+	_gfx = Freescape::createRenderer(_system, &_currentPixelFormat);
+	_gfx->_viewToRender = Common::Rect(64, 60, 575, 260);
 	_gfx->init();
 	_gfx->clear();
 	
@@ -113,20 +118,24 @@ Common::Error FreescapeEngine::run() {
 		error("%s is an invalid game", _targetName.c_str());
 
 	_areasByAreaID = binary.areasByAreaID;
-	_rawBorder = binary.border;
-	_rawPalette = binary.palette;
-	_startArea = binary.startArea;
+	_border = new Graphics::PixelBuffer(_originalPixelFormat, 320*200, DisposeAfterUse::NO);
+	*_border = binary.border->data();
+	_palette = new Graphics::PixelBuffer(_palettePixelFormat, 256, DisposeAfterUse::NO);
+	*_palette = binary.palette->data();
+	//debug("color: %x", binary.palette->data()[0x4c*3]);	
+	_startArea = 1; //binary.startArea;
+	_gfx->_palette = _palette;
 	convertBorder();
 
 	debug("FreescapeEngine::init");
 	// Simple main event loop
 	Common::Event evt;
 
-	drawBorder();
 	assert(_areasByAreaID->contains(_startArea));
 	Area *area = (*_areasByAreaID)[_startArea];
 	assert(area);
 	area->draw(_gfx);
+	//drawBorder();
 
 	while (!shouldQuit()) {
 		g_system->getEventManager()->pollEvent(evt);
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 1870c50e772..dabd149d772 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -6,6 +6,7 @@
 #include "engines/engine.h"
 #include "graphics/palette.h"
 #include "graphics/surface.h"
+#include "graphics/pixelbuffer.h"
 #include "gui/debugger.h"
 
 #include "freescape/area.h"
@@ -36,13 +37,16 @@ class FreescapeEngine : public Engine {
 private:
 	// We need random numbers
 	Common::RandomSource *_rnd;
-	Graphics::PixelFormat _pixelFormat;
+	Graphics::PixelFormat _currentPixelFormat;
+	Graphics::PixelFormat _originalPixelFormat;
+	Graphics::PixelFormat _palettePixelFormat;
 	int _screenW, _screenH;
 
-	Common::Array<uint8> *_rawBorder;
-	Graphics::Surface *_border;
+	Graphics::PixelBuffer *_border;
+	Graphics::PixelBuffer *_palette;
+
+	Graphics::Surface *_borderSurf;
 
-	Common::Array<uint8> *_rawPalette;
 	
 	uint32 _timeOfLastTick;
 	bool _hasReceivedTime;
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index d0b1d10bfa1..42c15500e13 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -125,7 +125,7 @@ public:
 	virtual Texture *createTexture(const Graphics::Surface *surface) = 0;
 	virtual void freeTexture(Texture *texture) = 0;
 
-	virtual void drawRect2D(const Common::Rect &rect, uint32 color) = 0;
+	virtual void drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint8 g, uint8 b) = 0;
 	virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture,
 									float transparency = -1.0, bool additiveBlending = false) = 0;
 	virtual void drawTexturedRect3D(const Math::Vector3d &topLeft, const Math::Vector3d &bottomLeft,
@@ -151,6 +151,8 @@ public:
 	void renderWindowOverlay(Window *window);
 
 	Common::Rect viewport() const;
+	Common::Rect _viewToRender;
+	Graphics::PixelBuffer *_palette = nullptr;
 
 	/**
 	 * Select the window where to render
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 4c3585b7ca8..8b4ba1b1986 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -135,12 +135,9 @@ void TinyGLRenderer::selectTargetWindow(Window *window, bool is3D, bool scaled)
 	}
 }
 
-void TinyGLRenderer::drawRect2D(const Common::Rect &rect, uint32 color) {
-	uint8 a, r, g, b;
-	Graphics::colorToARGB< Graphics::ColorMasks<8888> >(color, a, r, g, b);
-
+void TinyGLRenderer::drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint8 g, uint8 b) {	
 	tglDisable(TGL_TEXTURE_2D);
-	tglColor4f(r / 255.0, g / 255.0, b / 255.0, a / 255.0);
+	tglColor4f(r / 255.0, g / 255.0, b / 255.0, a);
 
 	if (a != 255) {
 		tglEnable(TGL_BLEND);
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index 3a62b089c5b..913936c601f 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -45,7 +45,7 @@ public:
 	Texture *createTexture(const Graphics::Surface *surface) override;
 	void freeTexture(Texture *texture) override;
 
-	virtual void drawRect2D(const Common::Rect &rect, uint32 color) override;
+	virtual void drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint8 g, uint8 b) override;
 	virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture,
 	                                float transparency = -1.0, bool additiveBlending = false) override;
 	virtual void drawTexturedRect3D(const Math::Vector3d &topLeft, const Math::Vector3d &bottomLeft,
diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
index 78b2ee82e7f..a87e3afb747 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/16bitBinaryLoader.cpp
@@ -135,14 +135,33 @@ Area *loadArea(StreamLoader &stream) {
 	debug("Objects: %d", numberOfObjects);
 
 	// I've yet to decipher this fully
-	uint16 horizonColour = stream.get16();
-	debug("Horizon colour %x", (int)horizonColour);
+	stream.get16();
+	stream.get16();
+	stream.get16();
+	
+
+	uint8 skyColor = stream.get8();
+	skyColor = (stream.get8() << 4) | skyColor;
+
+	debug("Sky color %x", skyColor);
+	uint8 groundColor = stream.get8();
+	groundColor = (stream.get8() << 4) | groundColor;
+	debug("Ground color %x", groundColor);
+	stream.skipBytes(14);
 
 	// this is just a complete guess
-	for (int paletteEntry = 0; paletteEntry < 22; paletteEntry++) {
-		uint8 paletteColour = stream.get8();
-		debug("Palette colour (?) %x", (int)paletteColour);
+	/*Common::Array<uint8> palette;
+	uint32 i;
+	for (i = 0; i < 7*3; i++) {
+		uint8 c = stream.get8();
+		palette.push_back(c);
+		debug("color %d", c);
 	}
+	stream.get8(); // ????*/
+	//for (int paletteEntry = 0; paletteEntry < 22; paletteEntry++) {
+	//	uint8 paletteColour = stream.get8() << 2;
+	//	debug("Palette colour (?) %x", paletteColour);
+	//}
 
 	// we'll need to collate all objects and entrances; it's likely a
 	// plain C array would do but maps are safer and the total application
@@ -164,7 +183,7 @@ Area *loadArea(StreamLoader &stream) {
 		}
 	}
 
-	return (new Area(areaNumber, objectsByID, entrancesByID));
+	return (new Area(areaNumber, objectsByID, entrancesByID, skyColor, groundColor));
 }
 
 Binary load16bitBinary(Common::String filename) {
@@ -363,18 +382,20 @@ Binary load16bitBinary(Common::String filename) {
 	Common::Array<uint8>::size_type o;
 	Common::Array<uint8> *raw_border = nullptr;
 	Common::Array<uint8> *raw_palette = nullptr;
-
+	debug("End of areas at %x", streamLoader.getFileOffset());
 	while (!streamLoader.eof()) {
 		o = streamLoader.getFileOffset();
 		if (streamLoader.get32() == 0x452400fa) {
 			debug("Border found at %x", o);
 			raw_border = streamLoader.nextBytes(320 * 200);
 			raw_palette = new Common::Array<uint8>(); 
-
-			for (i = 0; i < 16*3; i++) {
+			debug("Palete follows at %x", streamLoader.getFileOffset());
+			for (i = 0; i < 256*3; i++) {
+				//uint8 c = streamLoader.get8(); 
+				//if (streamLoader.getFileOffset() == 0x170e9 || streamLoader.getFileOffset() == 0x170ea)
+				//	debug("c[%x]: %x -> %x", i/3, c, c << 2);
 				raw_palette->push_back(streamLoader.get8() << 2);
 			}
-			
 			break;
 		}
 		streamLoader.setFileOffset(o);


Commit: 3a9491a2a32d4b53c7cf43be03ad619589ddd88d
    https://github.com/scummvm/scummvm/commit/3a9491a2a32d4b53c7cf43be03ad619589ddd88d
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:36+01:00

Commit Message:
FREESCAPE: fixed rendering sky and ground with border

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/freescape.cpp
    engines/freescape/gfx.cpp
    engines/freescape/gfx.h


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 8c35f7e23f6..03fb926d6a9 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -91,17 +91,15 @@ Area::~Area() {
 
 void Area::draw(Freescape::Renderer *gfx) {
 	debug("w: %d, h: %d", gfx->kOriginalWidth, gfx->kOriginalHeight);
-	Common::Rect sky(-1, 0, 1, 1);
+	Common::Rect view(20, 30, 305, 110);
+	Common::Rect sky(view.left, view.top, view.right, view.bottom-view.height()/2);
 	uint8 r, g, b;
 	gfx->_palette->getRGBAt(skyColor, r, g, b);
-	//debug("Rendering area %d sky with color %x -> %x %x %x", areaID, skyColor, r, g, b);
 	gfx->drawRect2D(sky, 255, r, g, b);
 
-	Common::Rect ground(-1, -1, 1, 0);
+
+	Common::Rect ground(view.left, view.top+view.height()/2, view.right, view.bottom);
 	gfx->_palette->getRGBAt(groundColor, r, g, b);
-	//debug("Rendering area %d sky with color %x -> %x %x %x", areaID, skyColor, r, g, b);
-	//ground.clip(gfx->_viewToRender);
-	//ground.debugPrint();
 	gfx->drawRect2D(ground, 255, r, g, b);
 
 	gfx->flipBuffer();
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 1e2d1360bb1..8c480f7f8ec 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -106,6 +106,7 @@ Common::Error FreescapeEngine::run() {
 	_gfx->_viewToRender = Common::Rect(64, 60, 575, 260);
 	_gfx->init();
 	_gfx->clear();
+	_gfx->selectTargetWindow(nullptr, false, true);
 	
 	Binary binary;
 	if (_targetName == "3Dkit")
@@ -134,8 +135,9 @@ Common::Error FreescapeEngine::run() {
 	assert(_areasByAreaID->contains(_startArea));
 	Area *area = (*_areasByAreaID)[_startArea];
 	assert(area);
+	drawBorder();
 	area->draw(_gfx);
-	//drawBorder();
+	
 
 	while (!shouldQuit()) {
 		g_system->getEventManager()->pollEvent(evt);
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index 30bd63438f1..a6bcf380778 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -128,6 +128,7 @@ Common::Rect Renderer::viewport() const {
 void Renderer::computeScreenViewport() {
 	int32 screenWidth = _system->getWidth();
 	int32 screenHeight = _system->getHeight();
+	//assert(0);
 
 	/*if (ConfMan.getBool("widescreen_mod")) {
 		_screenViewport = Common::Rect(screenWidth, screenHeight);
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 42c15500e13..68d1f664db6 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -171,9 +171,7 @@ public:
 
 	static const int kOriginalWidth = 320;
 	static const int kOriginalHeight = 200;
-	static const int kTopBorderHeight = 30;
-	static const int kBottomBorderHeight = 90;
-	static const int kFrameHeight = 360;
+	static const int kFrameHeight = 200;
 
 	void computeScreenViewport();
 


Commit: a36dc0bd75bb87cba273a66624b071d2a8991d55
    https://github.com/scummvm/scummvm/commit/a36dc0bd75bb87cba273a66624b071d2a8991d55
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:36+01:00

Commit Message:
FREESCAPE: fixes and added one cube example

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/detection.cpp
    engines/freescape/freescape.cpp
    engines/freescape/gfx.cpp
    engines/freescape/gfx.h
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/loaders/loader.h


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 03fb926d6a9..95a88b77152 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -91,7 +91,8 @@ Area::~Area() {
 
 void Area::draw(Freescape::Renderer *gfx) {
 	debug("w: %d, h: %d", gfx->kOriginalWidth, gfx->kOriginalHeight);
-	Common::Rect view(20, 30, 305, 110);
+	//Common::Rect view(20, 30, 305, 110);
+	Common::Rect view = gfx->rviewport();
 	Common::Rect sky(view.left, view.top, view.right, view.bottom-view.height()/2);
 	uint8 r, g, b;
 	gfx->_palette->getRGBAt(skyColor, r, g, b);
diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index 2d9406ea105..95da7198f12 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -4,6 +4,7 @@
 namespace Freescape {
 static const PlainGameDescriptor freescapeGames[] = {
 	{"3dkit", "The 3D Kit Game"},
+	{"3dkitcube", "The 3D Kit Game with only one cube"},
 	{"driller", "Driller"},
 	{"castle", "Castle Master"},
 	{0, 0}};
@@ -17,6 +18,14 @@ static const ADGameDescription gameDescriptions[] = {
 	 ADGF_NO_FLAGS,
 	 GUIO1(GUIO_NOMIDI)},
 
+	{"3Dkitcube",
+	 "One cube",
+	 AD_ENTRY1s("CUBE.RUN", "3b7930be0f646b98885cfb70c26c89a2", 66138),
+	 Common::EN_ANY,
+	 Common::kPlatformDOS,
+	 ADGF_NO_FLAGS,
+	 GUIO1(GUIO_NOMIDI)},
+
 	{"Driller",
 	 0,
 	 AD_ENTRY1s("DRILLE.EXE", "eb7e9e0acb72e30cf6e9ed20a6480e7a", 51944),
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 8c480f7f8ec..74b7636876f 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -103,7 +103,6 @@ Common::Error FreescapeEngine::run() {
 	_palettePixelFormat = Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0);
 
 	_gfx = Freescape::createRenderer(_system, &_currentPixelFormat);
-	_gfx->_viewToRender = Common::Rect(64, 60, 575, 260);
 	_gfx->init();
 	_gfx->clear();
 	_gfx->selectTargetWindow(nullptr, false, true);
@@ -111,6 +110,8 @@ Common::Error FreescapeEngine::run() {
 	Binary binary;
 	if (_targetName == "3Dkit")
 		binary = load16bitBinary("3DKIT.RUN");
+	else if (_targetName == "3Dkitcube")
+		binary = load16bitBinary("CUBE.RUN");
 	else if (_targetName == "Driller")
 		binary = load8bitBinary("DRILLE.EXE", OFFSET_DRILLER);
 	else if (_targetName == "Castle")
@@ -118,27 +119,27 @@ Common::Error FreescapeEngine::run() {
 	else
 		error("%s is an invalid game", _targetName.c_str());
 
-	_areasByAreaID = binary.areasByAreaID;
-	_border = new Graphics::PixelBuffer(_originalPixelFormat, 320*200, DisposeAfterUse::NO);
-	*_border = binary.border->data();
-	_palette = new Graphics::PixelBuffer(_palettePixelFormat, 256, DisposeAfterUse::NO);
-	*_palette = binary.palette->data();
-	//debug("color: %x", binary.palette->data()[0x4c*3]);	
-	_startArea = 1; //binary.startArea;
-	_gfx->_palette = _palette;
-	convertBorder();
-
+	if (binary.areasByAreaID && binary.border && binary.palette) {
+		_areasByAreaID = binary.areasByAreaID;
+		_border = new Graphics::PixelBuffer(_originalPixelFormat, 320*200, DisposeAfterUse::NO);
+		*_border = binary.border->data();
+		_palette = new Graphics::PixelBuffer(_palettePixelFormat, 256, DisposeAfterUse::NO);
+		*_palette = binary.palette->data();
+		//debug("color: %x", binary.palette->data()[0x4c*3]);	
+		_startArea = 1; //binary.startArea;
+		_gfx->_palette = _palette;
+		convertBorder();
+
+		assert(_areasByAreaID->contains(_startArea));
+		Area *area = (*_areasByAreaID)[_startArea];
+		assert(area);
+		drawBorder();
+		area->draw(_gfx);
+	}	
 	debug("FreescapeEngine::init");
 	// Simple main event loop
 	Common::Event evt;
 
-	assert(_areasByAreaID->contains(_startArea));
-	Area *area = (*_areasByAreaID)[_startArea];
-	assert(area);
-	drawBorder();
-	area->draw(_gfx);
-	
-
 	while (!shouldQuit()) {
 		g_system->getEventManager()->pollEvent(evt);
 		g_system->delayMillis(10);
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index a6bcf380778..6b5abb8461f 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -125,9 +125,17 @@ Common::Rect Renderer::viewport() const {
 	return _screenViewport;
 }
 
+Common::Rect Renderer::rviewport() const {
+	return _rscreenViewport;
+}
+
 void Renderer::computeScreenViewport() {
 	int32 screenWidth = _system->getWidth();
 	int32 screenHeight = _system->getHeight();
+	int32 tmargin = 27;
+	int32 vmargin = 40;
+	int32 bmargin = 90;
+
 	//assert(0);
 
 	/*if (ConfMan.getBool("widescreen_mod")) {
@@ -137,6 +145,7 @@ void Renderer::computeScreenViewport() {
 		int32 viewportWidth = MIN<int32>(screenWidth, screenHeight * kOriginalWidth / kOriginalHeight);
 		int32 viewportHeight = MIN<int32>(screenHeight, screenWidth * kOriginalHeight / kOriginalWidth);
 		_screenViewport = Common::Rect(viewportWidth, viewportHeight);
+		_rscreenViewport = Common::Rect(vmargin, tmargin, _screenViewport.right - vmargin, _screenViewport.bottom - bmargin);
 
 		// Pillarboxing
 		_screenViewport.translate((screenWidth - viewportWidth) / 2,
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 68d1f664db6..b004857638a 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -151,7 +151,7 @@ public:
 	void renderWindowOverlay(Window *window);
 
 	Common::Rect viewport() const;
-	Common::Rect _viewToRender;
+	Common::Rect rviewport() const;
 	Graphics::PixelBuffer *_palette = nullptr;
 
 	/**
@@ -180,6 +180,7 @@ protected:
 	Texture *_font;
 
 	Common::Rect _screenViewport;
+	Common::Rect _rscreenViewport;
 
 	Math::Matrix4 _projectionMatrix;
 	Math::Matrix4 _modelViewMatrix;
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index a284c6b6c7f..07a6126b245 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -13,6 +13,86 @@
 
 namespace Freescape {
 
+Area *load8bitArea(StreamLoader &stream) {
+	uint8 skippedValue = stream.get8(); // 0
+	uint8 numberOfObjects = stream.get8(); // 1
+	uint8 areaNumber = stream.get8(); // 2
+
+	debug("Area %d", areaNumber);
+	debug("Objects: %d", numberOfObjects);
+
+	uint16 cPtr = stream.rget16(); // 4
+	uint8 scale = stream.get8(); // 5
+	stream.get16(); // 6-7
+	stream.get16(); // 8-9
+	// Set16PaletteGradient(SpecCols[IPtr[8]&15], SpecCols[IPtr[9]&15]);
+
+	stream.setFileOffset(cPtr);
+	uint8 numConditions = stream.get8();
+	debug("%d area conditions", numConditions);
+	while (numConditions--) {
+		// get the length
+		uint32 lengthOfCondition = stream.get8();
+		debug("length of condition: %d", lengthOfCondition);
+		// get the condition
+		Common::Array<uint8> *conditionData = stream.nextBytes(lengthOfCondition);
+
+		//debug("Global condition %d", numCondition + 1);
+		debug("%s", detokenise8bitCondition(*conditionData)->c_str());
+	}
+
+
+	/*Uint8 *ObjPtr = &IPtr[(Offset == OFFSET_TOTALECLIPSE) ? 15 : 25];
+			while(NumObjects--)
+			{*/
+
+	/*
+	// I've yet to decipher this fully
+	stream.get16();
+	stream.get16();
+	stream.get16();
+	
+
+	uint8 skyColor = stream.get8();
+	skyColor = (stream.get8() << 4) | skyColor;
+
+	debug("Sky color %x", skyColor);
+	uint8 groundColor = stream.get8();
+	groundColor = (stream.get8() << 4) | groundColor;
+	debug("Ground color %x", groundColor);
+	stream.skipBytes(14);
+
+	//for (int paletteEntry = 0; paletteEntry < 22; paletteEntry++) {
+	//	uint8 paletteColour = stream.get8() << 2;
+	//	debug("Palette colour (?) %x", paletteColour);
+	//}
+
+	// we'll need to collate all objects and entrances; it's likely a
+	// plain C array would do but maps are safer and the total application
+	// cost is going to be negligible regardless
+	ObjectMap *objectsByID = new ObjectMap;
+	ObjectMap *entrancesByID = new ObjectMap;
+
+	// get the objects or whatever; entrances use a unique numbering
+	// system and have the high bit of their IDs set in the original file
+	for (uint16 object = 0; object < numberOfObjects; object++) {
+		Object *newObject = loadObject(stream);
+
+		if (newObject) {
+			if (newObject->getType() == Object::Entrance) {
+				(*entrancesByID)[newObject->getObjectID() & 0x7fff] = newObject;
+			} else {
+				(*objectsByID)[newObject->getObjectID()] = newObject;
+			}
+		}
+	}
+
+	return (new Area(areaNumber, objectsByID, entrancesByID, skyColor, groundColor));
+	*/
+	return nullptr;
+}
+
+
 Binary load8bitBinary(Common::String filename, uint offset) {
 	Common::File *file = new Common::File();
 
@@ -62,6 +142,25 @@ Binary load8bitBinary(Common::String filename, uint offset) {
 		debug("%s", detokenise8bitCondition(*conditionData)->c_str());
 	}
 
+	streamLoader.setFileOffset(200);
+	uint16 *fileOffsetForArea = new uint16[numberOfAreas];
+	for (uint16 area = 0; area < numberOfAreas; area++) {
+		fileOffsetForArea[area] = streamLoader.rget16();
+	}
+
+	// grab the areas
+	AreaMap *areaMap = new AreaMap;
+	for (uint16 area = 0; area < numberOfAreas; area++) {
+		debug("Area offset %d", fileOffsetForArea[area]);
+
+		streamLoader.setFileOffset(fileOffsetForArea[area]);
+		Area *newArea = load8bitArea(streamLoader);
+
+		if (newArea) {
+			(*areaMap)[newArea->getAreaID()] = newArea;
+		}
+	}
+
 	return Binary{0, nullptr, nullptr, nullptr};
 }
 
diff --git a/engines/freescape/loaders/loader.h b/engines/freescape/loaders/loader.h
index 5801e2724bd..ec73a524537 100644
--- a/engines/freescape/loaders/loader.h
+++ b/engines/freescape/loaders/loader.h
@@ -43,6 +43,12 @@ public:
 		return result;
 	}
 
+	uint16 rget16() {
+		uint16 result = (uint16)(get8());
+		result |= (get8() << 8);
+		return result;
+	}
+
 	uint32 get32() {
 		uint32 result = (uint32)(get16() << 16);
 		result |= get16();


Commit: c6d703414ab638f45a6090af4e5e92e33055c75e
    https://github.com/scummvm/scummvm/commit/c6d703414ab638f45a6090af4e5e92e33055c75e
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:36+01:00

Commit Message:
FREESCAPE: added more code for rendering areas

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/gfx_tinygl.h
    engines/freescape/loaders/16bitBinaryLoader.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 95a88b77152..241eae5732e 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -103,6 +103,8 @@ void Area::draw(Freescape::Renderer *gfx) {
 	gfx->_palette->getRGBAt(groundColor, r, g, b);
 	gfx->drawRect2D(ground, 255, r, g, b);
 
+	gfx->drawTriange(); // I have no idea why?
+
 	gfx->flipBuffer();
 	g_system->updateScreen();
 
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index b004857638a..103bd2a0716 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -133,6 +133,7 @@ public:
 									Texture *texture) = 0;
 
 	virtual void drawCube(Texture **textures) = 0;
+	virtual void drawTriange() = 0;
 	virtual void draw2DText(const Common::String &text, const Common::Point &position) = 0;
 
 	virtual Graphics::Surface *getScreenshot() = 0;
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 8b4ba1b1986..30469c49763 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -237,6 +237,36 @@ void TinyGLRenderer::drawFace(uint face, Texture *texture) {
 	tglEnd();
 }
 
+void TinyGLRenderer::drawTriange() {
+
+	tglViewport(0, 0, 320, 200);
+	tglEnable(TGL_DEPTH_TEST);
+	// GLfloat  h = (GLfloat) winSizeY / (GLfloat) winSizeX;
+	tglMatrixMode(TGL_PROJECTION);
+	tglLoadIdentity();
+	// glFrustum( -1.0, 1.0, -h, h, 5.0, 60.0 );
+	tglMatrixMode(TGL_MODELVIEW);
+	tglLoadIdentity();
+
+	tglMatrixMode(TGL_MODELVIEW);
+	tglLoadIdentity();
+	tglPushMatrix();
+	tglRotatef(0.01, 0, 0, 1);
+	tglBegin(TGL_TRIANGLES);
+	tglColor3f(0.2, 0.2, 1.0); // BLUE!
+	// glColor3f(1.0, 0.2, 0.2); //RED!
+	tglVertex3f(-0.8, -0.8, 0.2);
+
+	tglColor3f(0.2, 1.0, 0.2); // GREEN!
+	// glColor3f(1.0, 0.2, 0.2); //RED!
+	tglVertex3f(0.8, -0.8, 0.2);
+
+	tglColor3f(1.0, 0.2, 0.2); // RED!
+	tglVertex3f(0, 1.2, 0.2);
+	tglEnd();
+	tglPopMatrix();
+}
+
 void TinyGLRenderer::drawCube(Texture **textures) {
 	tglEnable(TGL_TEXTURE_2D);
 	tglDepthMask(TGL_FALSE);
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index 913936c601f..44f4350e26e 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -53,6 +53,7 @@ public:
 	                                Texture *texture) override;
 
 	virtual void drawCube(Texture **textures) override;
+	virtual void drawTriange() override;
 	virtual void draw2DText(const Common::String &text, const Common::Point &position) override;
 
 	virtual Graphics::Surface *getScreenshot() override;
diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
index a87e3afb747..0bd7812c626 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/16bitBinaryLoader.cpp
@@ -23,7 +23,7 @@
 
 namespace Freescape {
 
-static Object *loadObject(StreamLoader &stream) {
+static Object *load16bitObject(StreamLoader &stream) {
 	// get object flags and type
 	uint8 objectFlags = stream.get8();
 	Object::Type objectType = (Object::Type)stream.get8();
@@ -123,7 +123,7 @@ static Object *loadObject(StreamLoader &stream) {
 	return nullptr;
 }
 
-Area *loadArea(StreamLoader &stream) {
+Area *load16bitArea(StreamLoader &stream) {
 	// the lowest bit of this value seems to indicate
 	// horizon on or off; this is as much as I currently know
 	uint16 skippedValue = stream.get16();
@@ -172,7 +172,7 @@ Area *loadArea(StreamLoader &stream) {
 	// get the objects or whatever; entrances use a unique numbering
 	// system and have the high bit of their IDs set in the original file
 	for (uint16 object = 0; object < numberOfObjects; object++) {
-		Object *newObject = loadObject(stream);
+		Object *newObject = load16bitObject(stream);
 
 		if (newObject) {
 			if (newObject->getType() == Object::Entrance) {
@@ -371,7 +371,7 @@ Binary load16bitBinary(Common::String filename) {
 		debug("Area offset %d", fileOffsetForArea[area]);
 
 		streamLoader.setFileOffset(fileOffsetForArea[area] + baseOffset);
-		Area *newArea = loadArea(streamLoader);
+		Area *newArea = load16bitArea(streamLoader);
 
 		if (newArea) {
 			(*areaMap)[newArea->getAreaID()] = newArea;
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 07a6126b245..d0eecc7aa7a 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -13,6 +13,12 @@
 
 namespace Freescape {
 
+static Object *load8bitObject(StreamLoader &stream) {
+	return nullptr;
+}
+
+
+
 Area *load8bitArea(StreamLoader &stream) {
 	uint8 skippedValue = stream.get8(); // 0
 	uint8 numberOfObjects = stream.get8(); // 1
@@ -27,6 +33,21 @@ Area *load8bitArea(StreamLoader &stream) {
 	stream.get16(); // 8-9
 	// Set16PaletteGradient(SpecCols[IPtr[8]&15], SpecCols[IPtr[9]&15]);
 
+
+	stream.skipBytes(15);
+
+	for (uint8 object = 0; object < numberOfObjects; object++) {
+		Object *newObject = load8bitObject(stream);
+
+		/*if (newObject) {
+			if (newObject->getType() == Object::Entrance) {
+				(*entrancesByID)[newObject->getObjectID() & 0x7fff] = newObject;
+			} else {
+				(*objectsByID)[newObject->getObjectID()] = newObject;
+			}
+		}*/
+	}
+
 	stream.setFileOffset(cPtr);
 	uint8 numConditions = stream.get8();
 	debug("%d area conditions", numConditions);


Commit: 2a150147195b319dbda65a42de8f770d4463dc4e
    https://github.com/scummvm/scummvm/commit/2a150147195b319dbda65a42de8f770d4463dc4e
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:36+01:00

Commit Message:
FREESCAPE: better parsing of Driller and fixes

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/loaders/16bitBinaryLoader.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/loaders/8bitBinaryLoader.h
    engines/freescape/loaders/loader.h


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 241eae5732e..86b2a6a6ef5 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -35,7 +35,9 @@ Area::Area(
 	ObjectMap *_objectsByID,
 	ObjectMap *_entrancesByID,
 	uint8 _skyColor,
-	uint8 _groundColor) {
+	uint8 _groundColor,
+	Common::Array<uint8> *_palette) {
+	raw_palette = _palette;
 	skyColor = _skyColor;
 	groundColor = _groundColor;
 	areaID = _areaID;
@@ -90,20 +92,29 @@ Area::~Area() {
 }*/
 
 void Area::draw(Freescape::Renderer *gfx) {
+	Graphics::PixelBuffer *palette;
+	if (gfx->_palette)
+		palette = gfx->_palette;
+	else if (raw_palette) {
+		palette = new Graphics::PixelBuffer(Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0), 16, DisposeAfterUse::NO); 
+		*palette = raw_palette->data();
+	}
+
+	gfx->selectTargetWindow(nullptr, false, true);
 	debug("w: %d, h: %d", gfx->kOriginalWidth, gfx->kOriginalHeight);
 	//Common::Rect view(20, 30, 305, 110);
 	Common::Rect view = gfx->rviewport();
 	Common::Rect sky(view.left, view.top, view.right, view.bottom-view.height()/2);
 	uint8 r, g, b;
-	gfx->_palette->getRGBAt(skyColor, r, g, b);
+	palette->getRGBAt(skyColor, r, g, b);
 	gfx->drawRect2D(sky, 255, r, g, b);
 
 
 	Common::Rect ground(view.left, view.top+view.height()/2, view.right, view.bottom);
-	gfx->_palette->getRGBAt(groundColor, r, g, b);
+	palette->getRGBAt(groundColor, r, g, b);
 	gfx->drawRect2D(ground, 255, r, g, b);
 
-	gfx->drawTriange(); // I have no idea why?
+	//gfx->drawTriange(); // I have no idea why?
 
 	gfx->flipBuffer();
 	g_system->updateScreen();
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index c431337f6be..85bf96e408d 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -10,6 +10,7 @@
 #define __Phantasma__Area__
 
 #include "common/hashmap.h"
+#include "common/array.h"
 #include "freescape/gfx.h"
 #include "freescape/objects/object.h"
 //#include "VertexBuffer.h"
@@ -25,7 +26,8 @@ public:
 		ObjectMap *objectsByID,
 		ObjectMap *entrancesByID,
 		uint8 skyColor,
-		uint8 groundColor);
+		uint8 groundColor,
+		Common::Array<uint8> *palette = nullptr);
 	virtual ~Area();
 
 	Object *objectWithID(uint16 objectID);
@@ -37,6 +39,7 @@ private:
 	uint16 areaID;
 	uint8 skyColor;
 	uint8 groundColor;
+	Common::Array<uint8> *raw_palette;
 	ObjectMap *objectsByID;
 	ObjectMap *entrancesByID;
 	Common::Array<Object *> drawableObjects;
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 74b7636876f..4865ec6fcac 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -21,7 +21,7 @@
 
 #define OFFSET_DARKSIDE 0xc9ce
 #define OFFSET_DRILLER 0x9b40
-#define OFFSET_CASTLE 0x9b40
+#define OFFSET_CASTLE 0xe472
 #define OFFSET_TOTALECLIPSE 0xcdb7
 
 namespace Freescape {
@@ -75,6 +75,8 @@ FreescapeEngine::~FreescapeEngine() {
 }
 
 void FreescapeEngine::convertBorder() {
+	if (_border == nullptr)
+		return;
 	_borderSurf = new Graphics::Surface();
 	_borderSurf->create(_screenW, _screenH, _originalPixelFormat);
 	_borderSurf->copyRectToSurface(_border->getRawBuffer(), _borderSurf->w, 0, 0, _borderSurf->w, _borderSurf->h);
@@ -105,7 +107,6 @@ Common::Error FreescapeEngine::run() {
 	_gfx = Freescape::createRenderer(_system, &_currentPixelFormat);
 	_gfx->init();
 	_gfx->clear();
-	_gfx->selectTargetWindow(nullptr, false, true);
 	
 	Binary binary;
 	if (_targetName == "3Dkit")
@@ -119,15 +120,22 @@ Common::Error FreescapeEngine::run() {
 	else
 		error("%s is an invalid game", _targetName.c_str());
 
-	if (binary.areasByAreaID && binary.border && binary.palette) {
+	if (binary.areasByAreaID) {
 		_areasByAreaID = binary.areasByAreaID;
-		_border = new Graphics::PixelBuffer(_originalPixelFormat, 320*200, DisposeAfterUse::NO);
-		*_border = binary.border->data();
-		_palette = new Graphics::PixelBuffer(_palettePixelFormat, 256, DisposeAfterUse::NO);
-		*_palette = binary.palette->data();
+		if (binary.border) {
+			_border = new Graphics::PixelBuffer(_originalPixelFormat, 320*200, DisposeAfterUse::NO);
+			*_border = binary.border->data();
+		}
+
+		if (binary.palette) {
+			_palette = new Graphics::PixelBuffer(_palettePixelFormat, 256, DisposeAfterUse::NO);
+			*_palette = binary.palette->data();
+			_gfx->_palette = _palette;
+		}
+
 		//debug("color: %x", binary.palette->data()[0x4c*3]);	
-		_startArea = 1; //binary.startArea;
-		_gfx->_palette = _palette;
+		_startArea = binary.startArea;
+
 		convertBorder();
 
 		assert(_areasByAreaID->contains(_startArea));
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index dabd149d772..3b662a2012f 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -63,6 +63,7 @@ public:
 	Common::Error run() override;
 	void convertBorder();
 	void drawBorder();
+
 	bool hasFeature(EngineFeature f) const override;
 	bool canLoadGameStateCurrently() override { return true; }
 	bool canSaveGameStateCurrently() override { return true; }
diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
index 0bd7812c626..9122bb239a0 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/16bitBinaryLoader.cpp
@@ -59,7 +59,9 @@ static Object *load16bitObject(StreamLoader &stream) {
 	// length beyond here
 	uint32 byteSizeOfObject = (uint32)(stream.get16() << 1) - 20;
 
-	debug("Object %d ; type %d ; flags %d ; size %d", objectID, (int)objectType, (int)objectFlags, byteSizeOfObject);
+	debug("Object %d ; type %d ; flags %d ; size %d", (int)objectID, (int)objectType, (int)objectFlags, byteSizeOfObject);
+	debug("Location: %d, %d, %d", position.x, position.y, position.z);
+	debug("Size: %d, %d, %d", size.x, size.y, size.z);
 
 	switch (objectType) {
 	default: {
@@ -67,7 +69,9 @@ static Object *load16bitObject(StreamLoader &stream) {
 		int numberOfColours = GeometricObject::numberOfColoursForObjectOfType(objectType);
 		Common::Array<uint8> *colours = new Common::Array<uint8>;
 		for (uint8 colour = 0; colour < numberOfColours; colour++) {
-			colours->push_back(stream.get8());
+			uint8 c = stream.get8();
+			debug("face %d color: %d", colour, c);
+			colours->push_back(c);
 			byteSizeOfObject--;
 		}
 
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index d0eecc7aa7a..9332b694383 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -14,41 +14,126 @@
 namespace Freescape {
 
 static Object *load8bitObject(StreamLoader &stream) {
+	
+	Object::Type objectType = (Object::Type)stream.get8();
+	Vector3d position, size;
+
+	position.x = stream.get8();
+	position.y = stream.get8();
+	position.z = stream.get8();
+
+	size.x = stream.get8();
+	size.y = stream.get8();
+	size.z = stream.get8();
+
+	// object ID
+	uint16 objectID = stream.get8();
+	// size of object on disk; we've accounted for 8 bytes
+	// already so we can subtract that to get the remaining
+	// length beyond here
+	uint8 byteSizeOfObject = stream.get8();
+	assert(byteSizeOfObject >= 9);
+	byteSizeOfObject = byteSizeOfObject - 9;
+	debug("Object %d ; type %d ; size %d", objectID, (int)objectType, byteSizeOfObject);
+    debug("pos: %d %d %d", position.x, position.y, position.z);
+	debug("size: %d %d %d", size.x, size.y, size.z);
+	switch (objectType) {
+	default: {
+		// read the appropriate number of colours
+		int numberOfColours = GeometricObject::numberOfColoursForObjectOfType(objectType);
+		Common::Array<uint8> *colours = new Common::Array<uint8>;
+		for (uint8 colour = 0; colour < numberOfColours/2; colour++) {
+			uint8 c = stream.get8();
+			debug("color[%d] = %x", colour, c);
+			colours->push_back(c);
+			byteSizeOfObject--;
+		}
+
+		// grab the object condition, if there is one
+		FCLInstructionVector instructions;
+		if (byteSizeOfObject) {
+			Common::Array<uint8> *conditionData = stream.nextBytes(byteSizeOfObject);
+
+			Common::String *conditionSource = detokenise8bitCondition(*conditionData);
+			//instructions = getInstructions(conditionSource);
+			debug("%s", conditionSource->c_str());
+		}
+
+		// create an object
+		return new GeometricObject(
+			objectType,
+			objectID,
+			position,
+			size,
+			nullptr,
+			0,
+			instructions);
+	} break;
+
+	case Object::Entrance:
+	case Object::Sensor:
+	case Object::Group:
+		break;
+	}
+
+	stream.skipBytes(byteSizeOfObject);
+	//debug("Object %d ; size %d", objectID, byteSizeOfObject);
+	//assert(0);
 	return nullptr;
 }
 
+Common::Array <uint8>*getPaletteGradient(float *c1, float *c2)
+{
+	Common::Array <uint8> *raw_palette = new Common::Array <uint8>();
+	for(int c = 0; c < 16; c++)
+	{
+		float ic = (float)c / 15.0f;
+		ic = sqrt(ic);
+		raw_palette->push_back(255*(ic*c2[0] + (1-ic)*c1[0]));
+		raw_palette->push_back(255*(ic*c2[1] + (1-ic)*c1[1]));
+		raw_palette->push_back(255*(ic*c2[2] + (1-ic)*c1[2]));
+	}
+	return raw_palette;
+}
 
 
 Area *load8bitArea(StreamLoader &stream) {
-	uint8 skippedValue = stream.get8(); // 0
-	uint8 numberOfObjects = stream.get8(); // 1
-	uint8 areaNumber = stream.get8(); // 2
+	uint32 base = stream.getFileOffset();
+	uint8 skippedValue = stream.get8();
+	uint8 numberOfObjects = stream.get8();
+	uint8 areaNumber = stream.get8();
 
-	debug("Area %d", areaNumber);
-	debug("Objects: %d", numberOfObjects);
+	uint16 cPtr = stream.rget16();
+	uint8 scale = stream.get8(); 
+	uint8 ci1 = stream.get8()&15;
+	uint8 ci2 = stream.get8()&15; 
+	uint8 ci3 = stream.get8()&15; 
+	uint8 ci4 = stream.get8()&15; 
 
-	uint16 cPtr = stream.rget16(); // 4
-	uint8 scale = stream.get8(); // 5
-	stream.get16(); // 6-7
-	stream.get16(); // 8-9
-	// Set16PaletteGradient(SpecCols[IPtr[8]&15], SpecCols[IPtr[9]&15]);
+	debug("Colors: %d %d %d %d", ci1, ci2, ci3, ci4);
+	Common::Array <uint8> *raw_palette = getPaletteGradient(specColors[ci3], specColors[ci4]);
 
+	debug("Area %d", areaNumber);
+	debug("Objects: %d", numberOfObjects);
+	debug("Condition Ptr: %x", cPtr);
 
 	stream.skipBytes(15);
+	ObjectMap *objectsByID = new ObjectMap;
+	ObjectMap *entrancesByID = new ObjectMap;
 
 	for (uint8 object = 0; object < numberOfObjects; object++) {
 		Object *newObject = load8bitObject(stream);
 
-		/*if (newObject) {
+		if (newObject) {
 			if (newObject->getType() == Object::Entrance) {
 				(*entrancesByID)[newObject->getObjectID() & 0x7fff] = newObject;
 			} else {
 				(*objectsByID)[newObject->getObjectID()] = newObject;
 			}
-		}*/
+		}
 	}
 
-	stream.setFileOffset(cPtr);
+	stream.setFileOffset(base+cPtr);
 	uint8 numConditions = stream.get8();
 	debug("%d area conditions", numConditions);
 	while (numConditions--) {
@@ -58,59 +143,10 @@ Area *load8bitArea(StreamLoader &stream) {
 		// get the condition
 		Common::Array<uint8> *conditionData = stream.nextBytes(lengthOfCondition);
 
-		//debug("Global condition %d", numCondition + 1);
 		debug("%s", detokenise8bitCondition(*conditionData)->c_str());
 	}
 
-
-	/*Uint8 *ObjPtr = &IPtr[(Offset == OFFSET_TOTALECLIPSE) ? 15 : 25];
-			while(NumObjects--)
-			{*/
-
-	/*
-	// I've yet to decipher this fully
-	stream.get16();
-	stream.get16();
-	stream.get16();
-	
-
-	uint8 skyColor = stream.get8();
-	skyColor = (stream.get8() << 4) | skyColor;
-
-	debug("Sky color %x", skyColor);
-	uint8 groundColor = stream.get8();
-	groundColor = (stream.get8() << 4) | groundColor;
-	debug("Ground color %x", groundColor);
-	stream.skipBytes(14);
-
-	//for (int paletteEntry = 0; paletteEntry < 22; paletteEntry++) {
-	//	uint8 paletteColour = stream.get8() << 2;
-	//	debug("Palette colour (?) %x", paletteColour);
-	//}
-
-	// we'll need to collate all objects and entrances; it's likely a
-	// plain C array would do but maps are safer and the total application
-	// cost is going to be negligible regardless
-	ObjectMap *objectsByID = new ObjectMap;
-	ObjectMap *entrancesByID = new ObjectMap;
-
-	// get the objects or whatever; entrances use a unique numbering
-	// system and have the high bit of their IDs set in the original file
-	for (uint16 object = 0; object < numberOfObjects; object++) {
-		Object *newObject = loadObject(stream);
-
-		if (newObject) {
-			if (newObject->getType() == Object::Entrance) {
-				(*entrancesByID)[newObject->getObjectID() & 0x7fff] = newObject;
-			} else {
-				(*objectsByID)[newObject->getObjectID()] = newObject;
-			}
-		}
-	}
-
-	return (new Area(areaNumber, objectsByID, entrancesByID, skyColor, groundColor));
-	*/
-	return nullptr;
+	return (new Area(areaNumber, objectsByID, entrancesByID, ci1, ci2, raw_palette));
 }
 
 
@@ -160,7 +196,7 @@ Binary load8bitBinary(Common::String filename, uint offset) {
 		Common::Array<uint8> *conditionData = streamLoader.nextBytes(lengthOfCondition);
 
 		//debug("Global condition %d", numCondition + 1);
-		debug("%s", detokenise8bitCondition(*conditionData)->c_str());
+		//debug("%s", detokenise8bitCondition(*conditionData)->c_str());
 	}
 
 	streamLoader.setFileOffset(200);
@@ -182,7 +218,7 @@ Binary load8bitBinary(Common::String filename, uint offset) {
 		}
 	}
 
-	return Binary{0, nullptr, nullptr, nullptr};
+	return Binary{startArea, areaMap, nullptr, nullptr};
 }
 
 } // namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/loaders/8bitBinaryLoader.h b/engines/freescape/loaders/8bitBinaryLoader.h
index 9a1e906cbc1..a97bfe2aca7 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.h
+++ b/engines/freescape/loaders/8bitBinaryLoader.h
@@ -15,6 +15,12 @@
 
 namespace Freescape {
 
+static float specColors[16][3] = {
+    {0, 0, 0}, {0, 0, 0.75}, {0.75, 0, 0}, {0.75, 0, 0.75}, {0, 0.75, 0}, {0, 0.75, 0.75}, {0.75, 0.75, 0}, {0.75, 0.75, 0.75},
+    {0, 0, 0}, {0, 0, 1}, {1, 0, 0}, {1, 0, 1}, {0, 1, 0}, {0, 1, 1}, {1, 1, 0}, {1, 1, 1}
+};
+
+
 Binary load8bitBinary(Common::String, uint offset);
 
 }
diff --git a/engines/freescape/loaders/loader.h b/engines/freescape/loaders/loader.h
index ec73a524537..7dfdcf8e4f8 100644
--- a/engines/freescape/loaders/loader.h
+++ b/engines/freescape/loaders/loader.h
@@ -70,7 +70,7 @@ public:
 
 	Common::Array<uint8> *nextBytes(Common::Array<uint8>::size_type numberOfBytes) {
 		Common::Array<uint8> *returnBuffer(new Common::Array<uint8>);
-		debug("give me the next %d bytes", numberOfBytes);
+		//debug("skiping %d bytes", numberOfBytes);
 
 		while (numberOfBytes--)
 			returnBuffer->push_back(get8());


Commit: e0cbcd074d16d8d11ed9983b369f91e15cfce93f
    https://github.com/scummvm/scummvm/commit/e0cbcd074d16d8d11ed9983b369f91e15cfce93f
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:37+01:00

Commit Message:
FREESCAPE: improve palette handling

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/gfx.cpp
    engines/freescape/gfx.h
    engines/freescape/loaders/16bitBinaryLoader.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 86b2a6a6ef5..3263d7ef4ef 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -96,7 +96,7 @@ void Area::draw(Freescape::Renderer *gfx) {
 	if (gfx->_palette)
 		palette = gfx->_palette;
 	else if (raw_palette) {
-		palette = new Graphics::PixelBuffer(Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0), 16, DisposeAfterUse::NO); 
+		palette = new Graphics::PixelBuffer(gfx->_palettePixelFormat, 16, DisposeAfterUse::NO); 
 		*palette = raw_palette->data();
 	}
 
@@ -107,11 +107,13 @@ void Area::draw(Freescape::Renderer *gfx) {
 	Common::Rect sky(view.left, view.top, view.right, view.bottom-view.height()/2);
 	uint8 r, g, b;
 	palette->getRGBAt(skyColor, r, g, b);
+	debug("color: %d %x%x%x", skyColor, g, b);
 	gfx->drawRect2D(sky, 255, r, g, b);
 
 
 	Common::Rect ground(view.left, view.top+view.height()/2, view.right, view.bottom);
 	palette->getRGBAt(groundColor, r, g, b);
+	debug("color: %d %x%x%x", groundColor, g, b);
 	gfx->drawRect2D(ground, 255, r, g, b);
 
 	//gfx->drawTriange(); // I have no idea why?
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 4865ec6fcac..ec202feec56 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -74,21 +74,12 @@ FreescapeEngine::~FreescapeEngine() {
 	DebugMan.clearAllDebugChannels();
 }
 
-void FreescapeEngine::convertBorder() {
-	if (_border == nullptr)
-		return;
-	_borderSurf = new Graphics::Surface();
-	_borderSurf->create(_screenW, _screenH, _originalPixelFormat);
-	_borderSurf->copyRectToSurface(_border->getRawBuffer(), _borderSurf->w, 0, 0, _borderSurf->w, _borderSurf->h);
-	_borderSurf->convertToInPlace(_currentPixelFormat, _palette->getRawBuffer());
-}
-
 void FreescapeEngine::drawBorder() {
 	if (_border == nullptr)
 		return;
 
-	Texture *t = _gfx->createTexture(_borderSurf);
-	const Common::Rect rect(0, 0, 320, 200);
+	Texture *t = _gfx->createTexture(_border);
+	const Common::Rect rect(0, 0, _screenW, _screenH);
 	//g_system->copyRectToScreen(_borderSurf->getPixels(), _borderSurf->pitch, 0, 0, _screenW, _screenH);
 
 
@@ -100,11 +91,7 @@ void FreescapeEngine::drawBorder() {
 
 Common::Error FreescapeEngine::run() {
 	// Initialize graphics:
-	_currentPixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
-	_originalPixelFormat = Graphics::PixelFormat::createFormatCLUT8();
-	_palettePixelFormat = Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0);
-
-	_gfx = Freescape::createRenderer(_system, &_currentPixelFormat);
+	_gfx = Freescape::createRenderer(_system);
 	_gfx->init();
 	_gfx->clear();
 	
@@ -122,21 +109,27 @@ Common::Error FreescapeEngine::run() {
 
 	if (binary.areasByAreaID) {
 		_areasByAreaID = binary.areasByAreaID;
-		if (binary.border) {
-			_border = new Graphics::PixelBuffer(_originalPixelFormat, 320*200, DisposeAfterUse::NO);
-			*_border = binary.border->data();
-		}
-
 		if (binary.palette) {
-			_palette = new Graphics::PixelBuffer(_palettePixelFormat, 256, DisposeAfterUse::NO);
-			*_palette = binary.palette->data();
-			_gfx->_palette = _palette;
+			uint pSize = 0; 
+			if (binary.bits == 16)
+				pSize = 256;
+			else if (binary.bits == 8)
+				pSize = 16;
+			else
+				error("Invalid number of bits %d", binary.bits);
+
+			Graphics::PixelBuffer *palette = new Graphics::PixelBuffer(_gfx->_palettePixelFormat, pSize, DisposeAfterUse::NO);
+			*palette = binary.palette->data();
+			_gfx->_palette = palette;
 		}
 
-		//debug("color: %x", binary.palette->data()[0x4c*3]);	
-		_startArea = binary.startArea;
+		if (binary.border) {
+			Graphics::PixelBuffer *border = new Graphics::PixelBuffer(_gfx->_originalPixelFormat, 320*200, DisposeAfterUse::NO);
+			*border = binary.border->data();
+			_border = _gfx->convertFromPalette(border);
+		}
 
-		convertBorder();
+		_startArea = 1; //binary.startArea;
 
 		assert(_areasByAreaID->contains(_startArea));
 		Area *area = (*_areasByAreaID)[_startArea];
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 3b662a2012f..dc9d1abc3be 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -19,6 +19,7 @@ class Renderer;
 typedef Common::HashMap<uint16, Area *> AreaMap;
 
 typedef struct Binary {
+	uint8 bits;
 	uint16 startArea; 
 	AreaMap *areasByAreaID;
 	Common::Array<uint8> *border;
@@ -37,16 +38,9 @@ class FreescapeEngine : public Engine {
 private:
 	// We need random numbers
 	Common::RandomSource *_rnd;
-	Graphics::PixelFormat _currentPixelFormat;
-	Graphics::PixelFormat _originalPixelFormat;
-	Graphics::PixelFormat _palettePixelFormat;
 	int _screenW, _screenH;
 
-	Graphics::PixelBuffer *_border;
-	Graphics::PixelBuffer *_palette;
-
-	Graphics::Surface *_borderSurf;
-
+	Graphics::Surface *_border;
 	
 	uint32 _timeOfLastTick;
 	bool _hasReceivedTime;
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index 6b5abb8461f..3967db4a46a 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -69,6 +69,10 @@ Renderer::Renderer(OSystem *system)
 		: _system(system),
 		  _font(nullptr) {
 
+	_currentPixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
+	_originalPixelFormat = Graphics::PixelFormat::createFormatCLUT8();
+	_palettePixelFormat = Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0);
+
 	// Compute the cube faces Axis Aligned Bounding Boxes
 	for (uint i = 0; i < ARRAYSIZE(_cubeFacesAABB); i++) {
 		for (uint j = 0; j < 4; j++) {
@@ -91,6 +95,15 @@ void Renderer::freeFont() {
 	}
 }
 
+Graphics::Surface *Renderer::convertFromPalette(Graphics::PixelBuffer *rawsurf) {
+	Graphics::Surface * surf = new Graphics::Surface();
+	surf->create(kOriginalWidth, kOriginalHeight, _originalPixelFormat);
+	surf->copyRectToSurface(rawsurf->getRawBuffer(), surf->w, 0, 0, surf->w, surf->h);
+	surf->convertToInPlace(_currentPixelFormat, _palette->getRawBuffer());
+	return surf;
+}
+
+
 Texture *Renderer::copyScreenshotToTexture() {
 	Graphics::Surface *surface = getScreenshot();
 
@@ -198,25 +211,21 @@ void Renderer::flipVertical(Graphics::Surface *s) {
 	}
 }
 
-Renderer *createRenderer(OSystem *system, Graphics::PixelFormat *pixelFormat) {
+Renderer *createRenderer(OSystem *system) {
 	Common::String rendererConfig = ConfMan.get("renderer");
+	Graphics::PixelFormat pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
 	Graphics::RendererType desiredRendererType = Graphics::kRendererTypeTinyGL; //Graphics::parseRendererTypeCode(rendererConfig);
 	Graphics::RendererType matchingRendererType = Graphics::kRendererTypeTinyGL; //Graphics::getBestMatchingAvailableRendererType(desiredRendererType);
 
 	bool isAccelerated = 0; //matchingRendererType != Graphics::kRendererTypeTinyGL;
 
-	uint width;
+	uint width = Renderer::kOriginalWidth;
 	uint height = Renderer::kOriginalHeight;
-	/*if (ConfMan.getBool("widescreen_mod")) {
-		width = Renderer::kOriginalWidth * Renderer::kOriginalHeight / Renderer::kFrameHeight;
-	} else {*/
-		width = Renderer::kOriginalWidth;
-	//}
-	debug("w: %d, h: %d", width, height);
+
 	if (isAccelerated) {
 		initGraphics3d(width, height);
 	} else {
-		initGraphics(width, height, pixelFormat);
+		initGraphics(width, height, &pixelFormat);
 	}
 
 /*#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS) || defined(USE_GLES2)
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 103bd2a0716..505e81f7dfa 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -111,6 +111,15 @@ public:
 	Renderer(OSystem *system);
 	virtual ~Renderer();
 
+	Graphics::PixelFormat _currentPixelFormat;
+	Graphics::PixelFormat _originalPixelFormat;
+	Graphics::PixelFormat _palettePixelFormat;
+
+    /**
+	 *   Convert from paletted surface
+     */
+	Graphics::Surface *convertFromPalette(Graphics::PixelBuffer *rawsurf);
+
 	virtual void init() = 0;
 	virtual void clear() = 0;
 
@@ -175,6 +184,7 @@ public:
 	static const int kFrameHeight = 200;
 
 	void computeScreenViewport();
+	
 
 protected:
 	OSystem *_system;
@@ -222,7 +232,7 @@ private:
 Renderer *CreateGfxOpenGL(OSystem *system);
 Renderer *CreateGfxOpenGLShader(OSystem *system);
 Renderer *CreateGfxTinyGL(OSystem *system);
-Renderer *createRenderer(OSystem *system, Graphics::PixelFormat *pixelFormat);
+Renderer *createRenderer(OSystem *system);
 
 } // End of namespace Myst3
 
diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
index 9122bb239a0..f43c9def790 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/16bitBinaryLoader.cpp
@@ -407,7 +407,7 @@ Binary load16bitBinary(Common::String filename) {
 	}
 
 	delete[] fileOffsetForArea;
-	return Freescape::Binary{startArea, areaMap, raw_border, raw_palette};
+	return Binary{16, startArea, areaMap, raw_border, raw_palette};
 }
 
 } // namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 9332b694383..2e91d142a32 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -44,8 +44,10 @@ static Object *load8bitObject(StreamLoader &stream) {
 		Common::Array<uint8> *colours = new Common::Array<uint8>;
 		for (uint8 colour = 0; colour < numberOfColours/2; colour++) {
 			uint8 c = stream.get8();
-			debug("color[%d] = %x", colour, c);
-			colours->push_back(c);
+			colours->push_back(c >> 4);
+			debug("color[%d] = %x", 2*colour, c >> 4);
+			colours->push_back(c & 0xf);
+			debug("color[%d] = %x", 2*colour+1, c & 0xf);
 			byteSizeOfObject--;
 		}
 
@@ -85,13 +87,19 @@ static Object *load8bitObject(StreamLoader &stream) {
 Common::Array <uint8>*getPaletteGradient(float *c1, float *c2)
 {
 	Common::Array <uint8> *raw_palette = new Common::Array <uint8>();
+	uint16 y0, y1, y2;
+	debug("palette:");
 	for(int c = 0; c < 16; c++)
 	{
 		float ic = (float)c / 15.0f;
 		ic = sqrt(ic);
-		raw_palette->push_back(255*(ic*c2[0] + (1-ic)*c1[0]));
-		raw_palette->push_back(255*(ic*c2[1] + (1-ic)*c1[1]));
-		raw_palette->push_back(255*(ic*c2[2] + (1-ic)*c1[2]));
+		y0  = 255*(ic*c2[0] + (1-ic)*c1[0]);
+		y1  = 255*(ic*c2[1] + (1-ic)*c1[1]);
+		y2  = 255*(ic*c2[2] + (1-ic)*c1[2]);
+		debug("%d %d %d", y0, y1, y2);
+		raw_palette->push_back(y2);
+		raw_palette->push_back(y1);
+		raw_palette->push_back(y0);
 	}
 	return raw_palette;
 }
@@ -146,7 +154,7 @@ Area *load8bitArea(StreamLoader &stream) {
 		debug("%s", detokenise8bitCondition(*conditionData)->c_str());
 	}
 
-	return (new Area(areaNumber, objectsByID, entrancesByID, ci1, ci2, raw_palette));
+	return (new Area(areaNumber, objectsByID, entrancesByID, 0, 1, raw_palette));
 }
 
 
@@ -218,7 +226,7 @@ Binary load8bitBinary(Common::String filename, uint offset) {
 		}
 	}
 
-	return Binary{startArea, areaMap, nullptr, nullptr};
+	return Binary{8, startArea, areaMap, nullptr, nullptr};
 }
 
 } // namespace Freescape
\ No newline at end of file


Commit: 6f328337f92bd8919c8f1b345457bc294c7c6e82
    https://github.com/scummvm/scummvm/commit/6f328337f92bd8919c8f1b345457bc294c7c6e82
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:37+01:00

Commit Message:
FREESCAPE: better parsing of 3DK games

Changed paths:
    engines/freescape/loaders/16bitBinaryLoader.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/loaders/8bitBinaryLoader.h
    engines/freescape/loaders/loader.h


diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
index f43c9def790..b50d34d06a9 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/16bitBinaryLoader.cpp
@@ -23,6 +23,11 @@
 
 namespace Freescape {
 
+typedef enum {
+		First = 0x0000,
+		Border = 0x4524,
+} ChunkType;
+
 static Object *load16bitObject(StreamLoader &stream) {
 	// get object flags and type
 	uint8 objectFlags = stream.get8();
@@ -98,6 +103,7 @@ static Object *load16bitObject(StreamLoader &stream) {
 			//instructions = getInstructions(conditionSource);
 		}
 		byteSizeOfObject = 0;
+		debug("End of object at %x", stream.getFileOffset());
 
 		// create an object
 		return new GeometricObject(
@@ -123,10 +129,15 @@ static Object *load16bitObject(StreamLoader &stream) {
 	//for (i = 0; i < byteSizeOfObject/2; i++)
 	//	cout << i << stream.get16() << endl;
 	stream.skipBytes(byteSizeOfObject);
+	debug("End of object at %x", stream.getFileOffset());
 
 	return nullptr;
 }
 
+void load16bitInstrument(StreamLoader &stream) {}
+	
+
+
 Area *load16bitArea(StreamLoader &stream) {
 	// the lowest bit of this value seems to indicate
 	// horizon on or off; this is as much as I currently know
@@ -190,6 +201,8 @@ Area *load16bitArea(StreamLoader &stream) {
 	return (new Area(areaNumber, objectsByID, entrancesByID, skyColor, groundColor));
 }
 
+
+
 Binary load16bitBinary(Common::String filename) {
 	Common::File *file = new Common::File();
 
@@ -261,7 +274,8 @@ Binary load16bitBinary(Common::String filename) {
 	// start grabbing some of the basics...
 
 	uint16 numberOfAreas = streamLoader.get16();
-	streamLoader.get16(); // meaning unknown
+	uint16 sm = streamLoader.get16();
+	debug("Something??: %d", sm); // meaning unknown
 
 	debug("Number of areas: %d", numberOfAreas);
 
@@ -381,29 +395,58 @@ Binary load16bitBinary(Common::String filename) {
 			(*areaMap)[newArea->getAreaID()] = newArea;
 		}
 	}
-	streamLoader.setFileOffset(fileOffsetForArea[numberOfAreas - 1] + baseOffset);
+	load16bitInstrument(streamLoader);
 
 	Common::Array<uint8>::size_type o;
 	Common::Array<uint8> *raw_border = nullptr;
 	Common::Array<uint8> *raw_palette = nullptr;
+	uint16 chunkType = 0;
+	uint16 chunkSize = 0;
+	uint16 colorNumber = 0;
 	debug("End of areas at %x", streamLoader.getFileOffset());
 	while (!streamLoader.eof()) {
 		o = streamLoader.getFileOffset();
-		if (streamLoader.get32() == 0x452400fa) {
-			debug("Border found at %x", o);
-			raw_border = streamLoader.nextBytes(320 * 200);
+		chunkType = streamLoader.get16();
+		if (chunkType == First) {
+			chunkSize = streamLoader.rget16();
+			if (chunkSize != 0xac) {
+				debug("skip %x", chunkType);
+				streamLoader.setFileOffset(o+2);
+			} else {
+				debug("First chunk found at %x with size %x", o, chunkSize);
+				streamLoader.skipBytes(chunkSize-2);
+			}
+		}
+		else if (chunkType == Border) {
+			chunkSize = streamLoader.rget16();
+			debug("Border found at %x with size %x", o, chunkSize);
+
+			if (chunkSize == 320*200 / 4)
+				colorNumber = 4; // CGA
+			else if (chunkSize == 320*200)
+				colorNumber = 256;
+			else
+				error("Unexpected size of image %d", chunkSize);
+
+			raw_border = streamLoader.nextBytes(chunkSize);
 			raw_palette = new Common::Array<uint8>(); 
 			debug("Palete follows at %x", streamLoader.getFileOffset());
-			for (i = 0; i < 256*3; i++) {
-				//uint8 c = streamLoader.get8(); 
-				//if (streamLoader.getFileOffset() == 0x170e9 || streamLoader.getFileOffset() == 0x170ea)
-				//	debug("c[%x]: %x -> %x", i/3, c, c << 2);
+			for (i = 0; i < colorNumber*3; i++)
 				raw_palette->push_back(streamLoader.get8() << 2);
-			}
-			break;
+			
+			debug("Palete finishes at %x", streamLoader.getFileOffset());
+			chunkSize = streamLoader.rget16();
+			debug("Something else of size %x at %x??", chunkSize, streamLoader.getFileOffset());
+			streamLoader.skipBytes(chunkSize);
+		}
+		else {
+			debug("skip %x", chunkType);
+			//chunkSize = streamLoader.rget16();
+			//if (chunkSize > 0 && streamLoader.getFileOffset() + chunkSize-2 == 0x73ea)
+			//	error("Found at %x!", o);
+			//streamLoader.setFileOffset(o+2);
+			//error("Unknown chunk %x find at %x with size %x", chunkType, o, chunkSize);
 		}
-		streamLoader.setFileOffset(o);
-		streamLoader.get8();
 	}
 
 	delete[] fileOffsetForArea;
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 2e91d142a32..b91ce524e85 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -18,9 +18,9 @@ static Object *load8bitObject(StreamLoader &stream) {
 	Object::Type objectType = (Object::Type)stream.get8();
 	Vector3d position, size;
 
-	position.x = stream.get8();
-	position.y = stream.get8();
-	position.z = stream.get8();
+	position.x = stream.get8() * 32;
+	position.y = stream.get8() * 32;
+	position.z = stream.get8() * 32;
 
 	size.x = stream.get8();
 	size.y = stream.get8();
@@ -84,6 +84,26 @@ static Object *load8bitObject(StreamLoader &stream) {
 	return nullptr;
 }
 
+float specColors[16][3] = {
+    {0, 0, 0}, 
+	{0, 0, 0.75}, 
+	{0.75, 0, 0}, 
+	{0.75, 0, 0.75}, 
+	{0, 0.75, 0}, 
+	{0, 0.75, 0.75}, 
+	{0.75, 0.75, 0}, 
+	{0.75, 0.75, 0.75},
+    {0, 0, 0}, 
+	{0, 0, 1}, 
+	{1, 0, 0}, 
+	{1, 0, 1}, 
+	{0, 1, 0}, 
+	{0, 1, 1}, 
+	{1, 1, 0}, 
+	{1, 1, 1}
+};
+
+
 Common::Array <uint8>*getPaletteGradient(float *c1, float *c2)
 {
 	Common::Array <uint8> *raw_palette = new Common::Array <uint8>();
@@ -96,11 +116,12 @@ Common::Array <uint8>*getPaletteGradient(float *c1, float *c2)
 		y0  = 255*(ic*c2[0] + (1-ic)*c1[0]);
 		y1  = 255*(ic*c2[1] + (1-ic)*c1[1]);
 		y2  = 255*(ic*c2[2] + (1-ic)*c1[2]);
-		debug("%d %d %d", y0, y1, y2);
-		raw_palette->push_back(y2);
-		raw_palette->push_back(y1);
+		debug("%x %x %x", y0, y1, y2);
 		raw_palette->push_back(y0);
+		raw_palette->push_back(y1);
+		raw_palette->push_back(y2);
 	}
+	//assert(0);
 	return raw_palette;
 }
 
@@ -119,7 +140,7 @@ Area *load8bitArea(StreamLoader &stream) {
 	uint8 ci4 = stream.get8()&15; 
 
 	debug("Colors: %d %d %d %d", ci1, ci2, ci3, ci4);
-	Common::Array <uint8> *raw_palette = getPaletteGradient(specColors[ci3], specColors[ci4]);
+	Common::Array <uint8> *raw_palette = getPaletteGradient(specColors[ci4], specColors[ci3]);
 
 	debug("Area %d", areaNumber);
 	debug("Objects: %d", numberOfObjects);
diff --git a/engines/freescape/loaders/8bitBinaryLoader.h b/engines/freescape/loaders/8bitBinaryLoader.h
index a97bfe2aca7..9a1e906cbc1 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.h
+++ b/engines/freescape/loaders/8bitBinaryLoader.h
@@ -15,12 +15,6 @@
 
 namespace Freescape {
 
-static float specColors[16][3] = {
-    {0, 0, 0}, {0, 0, 0.75}, {0.75, 0, 0}, {0.75, 0, 0.75}, {0, 0.75, 0}, {0, 0.75, 0.75}, {0.75, 0.75, 0}, {0.75, 0.75, 0.75},
-    {0, 0, 0}, {0, 0, 1}, {1, 0, 0}, {1, 0, 1}, {0, 1, 0}, {0, 1, 1}, {1, 1, 0}, {1, 1, 1}
-};
-
-
 Binary load8bitBinary(Common::String, uint offset);
 
 }
diff --git a/engines/freescape/loaders/loader.h b/engines/freescape/loaders/loader.h
index 7dfdcf8e4f8..24627db1298 100644
--- a/engines/freescape/loaders/loader.h
+++ b/engines/freescape/loaders/loader.h
@@ -66,6 +66,7 @@ public:
 
 	void skipBytes(Common::Array<uint8>::size_type numberOfBytes) {
 		bytePointer += numberOfBytes;
+		assert(bytePointer <= binary.size());
 	}
 
 	Common::Array<uint8> *nextBytes(Common::Array<uint8>::size_type numberOfBytes) {


Commit: 56f692a67cd6e64773ba7b1807351928adfe60b0
    https://github.com/scummvm/scummvm/commit/56f692a67cd6e64773ba7b1807351928adfe60b0
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:37+01:00

Commit Message:
FREESCAPE: some parsing of instruments in 3DK games

Changed paths:
    engines/freescape/loaders/16bitBinaryLoader.cpp


diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
index b50d34d06a9..ca45801f063 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/16bitBinaryLoader.cpp
@@ -134,9 +134,28 @@ static Object *load16bitObject(StreamLoader &stream) {
 	return nullptr;
 }
 
-void load16bitInstrument(StreamLoader &stream) {}
-	
+void load16bitInstrument(StreamLoader &stream) {
+	uint16 zero = stream.get16();
+	assert( zero == 0);
+	uint16 type = stream.get16();
+	uint16 x = stream.get16();
+	uint16 y = stream.get16();
+	uint16 length = stream.get16();
+	uint16 height = stream.get16();
+	stream.get16();
+	stream.get16();
+	uint16 lb = stream.get16();
+	uint16 rt = stream.get16();
+	uint16 v = stream.get16();
+	uint16 fgcolor = stream.get16();
+	uint16 bgcolor = stream.get16();
 
+	stream.get16();
+	stream.get16();
+	stream.get16();
+	stream.get16();
+	debug("type %d ; x %d ; y %d ; length %d ; height %d ; lb %d ; rt %d ; variable: %d", type, x, y, length, height, lb, rt, v);
+}
 
 Area *load16bitArea(StreamLoader &stream) {
 	// the lowest bit of this value seems to indicate
@@ -379,7 +398,7 @@ Binary load16bitBinary(Common::String filename) {
 		// get the condition
 		Common::Array<uint8> *conditionData = streamLoader.nextBytes(lengthOfCondition);
 
-		debug("Global condition %d", globalCondition + 1);
+		debug("Global condition %d at %x", globalCondition + 1, streamLoader.getFileOffset());
 		debug("%s", detokenise16bitCondition(*conditionData)->c_str());
 	}
 
@@ -395,7 +414,7 @@ Binary load16bitBinary(Common::String filename) {
 			(*areaMap)[newArea->getAreaID()] = newArea;
 		}
 	}
-	load16bitInstrument(streamLoader);
+	//load16bitInstrument(streamLoader);
 
 	Common::Array<uint8>::size_type o;
 	Common::Array<uint8> *raw_border = nullptr;
@@ -423,6 +442,8 @@ Binary load16bitBinary(Common::String filename) {
 
 			if (chunkSize == 320*200 / 4)
 				colorNumber = 4; // CGA
+			else if (chunkSize == 320*200 / 2)
+				colorNumber = 16;
 			else if (chunkSize == 320*200)
 				colorNumber = 256;
 			else


Commit: 38f86638809bd725f15fa8f7bb5a54bcde94a295
    https://github.com/scummvm/scummvm/commit/38f86638809bd725f15fa8f7bb5a54bcde94a295
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:37+01:00

Commit Message:
FREESCAPE: entraces support for Driller

Changed paths:
  A engines/freescape/objects/entrance.cpp
  A engines/freescape/objects/entrance.h
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/module.mk
    engines/freescape/objects/geometricobject.cpp
    engines/freescape/objects/geometricobject.h
    engines/freescape/objects/object.h


diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index b91ce524e85..8b4749602f3 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -9,22 +9,23 @@
 #include "freescape/loaders/8bitBinaryLoader.h"
 #include "freescape/loaders/loader.h"
 #include "freescape/objects/geometricobject.h"
+#include "freescape/objects/entrance.h"
 #include "freescape/objects/object.h"
 
 namespace Freescape {
 
 static Object *load8bitObject(StreamLoader &stream) {
 	
-	Object::Type objectType = (Object::Type)stream.get8();
-	Vector3d position, size;
+	Object::Type objectType = (Object::Type)(stream.get8() & 0x1F);
+	Vector3d position, v;
 
 	position.x = stream.get8() * 32;
 	position.y = stream.get8() * 32;
 	position.z = stream.get8() * 32;
 
-	size.x = stream.get8();
-	size.y = stream.get8();
-	size.z = stream.get8();
+	v.x = stream.get8();
+	v.y = stream.get8();
+	v.z = stream.get8();
 
 	// object ID
 	uint16 objectID = stream.get8();
@@ -36,9 +37,9 @@ static Object *load8bitObject(StreamLoader &stream) {
 	byteSizeOfObject = byteSizeOfObject - 9;
 	debug("Object %d ; type %d ; size %d", objectID, (int)objectType, byteSizeOfObject);
     debug("pos: %d %d %d", position.x, position.y, position.z);
-	debug("size: %d %d %d", size.x, size.y, size.z);
 	switch (objectType) {
 	default: {
+		debug("size: %d %d %d", v.x, v.y, v.z);
 		// read the appropriate number of colours
 		int numberOfColours = GeometricObject::numberOfColoursForObjectOfType(objectType);
 		Common::Array<uint8> *colours = new Common::Array<uint8>;
@@ -66,13 +67,22 @@ static Object *load8bitObject(StreamLoader &stream) {
 			objectType,
 			objectID,
 			position,
-			size,
+			v, // size
 			nullptr,
 			0,
 			instructions);
 	} break;
 
-	case Object::Entrance:
+	case Object::Entrance: {
+		debug("rotation: %d %d %d", v.x, v.y, v.z);
+		assert(byteSizeOfObject == 0);
+		// create an entrance
+		return new Entrance(
+			objectID,
+			position,
+			v); // rotation
+	} break;
+
 	case Object::Sensor:
 	case Object::Group:
 		break;
@@ -80,7 +90,6 @@ static Object *load8bitObject(StreamLoader &stream) {
 
 	stream.skipBytes(byteSizeOfObject);
 	//debug("Object %d ; size %d", objectID, byteSizeOfObject);
-	//assert(0);
 	return nullptr;
 }
 
@@ -161,7 +170,7 @@ Area *load8bitArea(StreamLoader &stream) {
 			}
 		}
 	}
-
+	//assert(0);
 	stream.setFileOffset(base+cPtr);
 	uint8 numConditions = stream.get8();
 	debug("%d area conditions", numConditions);
@@ -201,7 +210,8 @@ Binary load8bitBinary(Common::String filename, uint offset) {
 
 	StreamLoader streamLoader(binary);
 	uint8 numberOfAreas = streamLoader.get8();
-	streamLoader.get16(); // meaning unknown
+	uint16 dbSize = streamLoader.rget16();
+	debug("Database ends at %x", dbSize);
 
 	debug("Number of areas: %d", numberOfAreas);
 	uint8 startArea = streamLoader.get8();
@@ -247,6 +257,8 @@ Binary load8bitBinary(Common::String filename, uint offset) {
 		}
 	}
 
+	debug("End of areas at %x", streamLoader.getFileOffset());
+
 	return Binary{8, startArea, areaMap, nullptr, nullptr};
 }
 
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index edac86f4e98..bbb66059b4d 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -8,6 +8,7 @@ MODULE_OBJS := \
 	gfx_tinygl.o \
 	gfx_tinygl_texture.o \
 	objects/object.o \
+	objects/entrance.o \
 	objects/geometricobject.o \
 	loaders/8bitBinaryLoader.o \
 	language/8bitDetokeniser.o \
diff --git a/engines/freescape/objects/entrance.cpp b/engines/freescape/objects/entrance.cpp
new file mode 100644
index 00000000000..d5a6f2c7566
--- /dev/null
+++ b/engines/freescape/objects/entrance.cpp
@@ -0,0 +1,26 @@
+//
+//  Entrance.cpp
+//  Phantasma
+//
+//  Created by Thomas Harte on 25/12/2013.
+//  Copyright (c) 2013 Thomas Harte. All rights reserved.
+//
+
+#include "freescape/objects/entrance.h"
+
+#pragma mark -
+#pragma mark Construction/Destruction
+
+Entrance::Entrance(
+	uint16 _objectID,
+	const Vector3d &_origin,
+	const Vector3d &_rotation) {
+	objectID = _objectID;
+	origin = _origin;
+	rotation = _rotation;
+}
+
+Entrance::~Entrance() {}
+
+bool Entrance::isDrawable() { return false; }
+bool Entrance::isPlanar() { return true; }
\ No newline at end of file
diff --git a/engines/freescape/objects/entrance.h b/engines/freescape/objects/entrance.h
new file mode 100644
index 00000000000..2dc1b420f10
--- /dev/null
+++ b/engines/freescape/objects/entrance.h
@@ -0,0 +1,28 @@
+//
+//  Entrance.h
+//  Phantasma
+//
+//  Created by Thomas Harte on 25/12/2013.
+//  Copyright (c) 2013 Thomas Harte. All rights reserved.
+//
+
+#ifndef __Phantasma__Entrance__
+#define __Phantasma__Entrance__
+
+#include "freescape/objects/object.h"
+
+class Entrance : public Object {
+public:
+
+	Entrance(
+		uint16 objectID,
+		const Vector3d &origin,
+		const Vector3d &rotation);
+	virtual ~Entrance();
+
+	bool isDrawable();
+	bool isPlanar();
+};
+
+
+#endif /* defined(__Phantasma__Entrance__) */
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index 0b8d5b50209..e043f98d4e3 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -7,7 +7,6 @@
 //
 
 #include "common/str.h"
-
 #include "freescape/objects/geometricobject.h"
 
 #pragma mark -
diff --git a/engines/freescape/objects/geometricobject.h b/engines/freescape/objects/geometricobject.h
index cb2b31e46d4..b4d73e4d9ff 100644
--- a/engines/freescape/objects/geometricobject.h
+++ b/engines/freescape/objects/geometricobject.h
@@ -13,7 +13,6 @@
 #include "freescape/language/instruction.h"
 #include "freescape/objects/object.h"
 
-class BatchDrawer;
 class GeometricObject : public Object {
 public:
 	static int numberOfColoursForObjectOfType(Type type);
diff --git a/engines/freescape/objects/object.h b/engines/freescape/objects/object.h
index 9337409c41d..f056f317c9c 100644
--- a/engines/freescape/objects/object.h
+++ b/engines/freescape/objects/object.h
@@ -72,7 +72,7 @@ public:
 protected:
 	Type type;
 	uint16 objectID;
-	Vector3d origin, size;
+	Vector3d origin, size, rotation;
 };
 
 /*


Commit: ad0f96ad11fc0ac8f925f59745f3e842c174d9b3
    https://github.com/scummvm/scummvm/commit/ad0f96ad11fc0ac8f925f59745f3e842c174d9b3
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:37+01:00

Commit Message:
FREESCAPE: better parser for Driller

Changed paths:
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 8b4749602f3..0caf282239e 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -43,6 +43,7 @@ static Object *load8bitObject(StreamLoader &stream) {
 		// read the appropriate number of colours
 		int numberOfColours = GeometricObject::numberOfColoursForObjectOfType(objectType);
 		Common::Array<uint8> *colours = new Common::Array<uint8>;
+		debug("Number of colors", numberOfColours/2);
 		for (uint8 colour = 0; colour < numberOfColours/2; colour++) {
 			uint8 c = stream.get8();
 			colours->push_back(c >> 4);
@@ -52,6 +53,23 @@ static Object *load8bitObject(StreamLoader &stream) {
 			byteSizeOfObject--;
 		}
 
+		// read extra vertices if required...
+		int numberOfOrdinates = GeometricObject::numberOfOrdinatesForType(objectType);
+		debug("number of ordinates %d", numberOfOrdinates);
+		Common::Array<uint16> *ordinates = nullptr;
+
+		if (numberOfOrdinates) {
+			ordinates = new Common::Array<uint16>;
+			uint16 ord = 0;
+
+			for (int ordinate = 0; ordinate < numberOfOrdinates; ordinate++) {
+				ord = stream.get8();
+				debug("ord: %x", ord);
+				ordinates->push_back(ord);
+				byteSizeOfObject--;
+			}
+		}
+
 		// grab the object condition, if there is one
 		FCLInstructionVector instructions;
 		if (byteSizeOfObject) {
@@ -68,8 +86,8 @@ static Object *load8bitObject(StreamLoader &stream) {
 			objectID,
 			position,
 			v, // size
-			nullptr,
-			0,
+			colours,
+			ordinates,
 			instructions);
 	} break;
 
@@ -89,7 +107,6 @@ static Object *load8bitObject(StreamLoader &stream) {
 	}
 
 	stream.skipBytes(byteSizeOfObject);
-	//debug("Object %d ; size %d", objectID, byteSizeOfObject);
 	return nullptr;
 }
 
@@ -130,7 +147,6 @@ Common::Array <uint8>*getPaletteGradient(float *c1, float *c2)
 		raw_palette->push_back(y1);
 		raw_palette->push_back(y2);
 	}
-	//assert(0);
 	return raw_palette;
 }
 
@@ -170,7 +186,6 @@ Area *load8bitArea(StreamLoader &stream) {
 			}
 		}
 	}
-	//assert(0);
 	stream.setFileOffset(base+cPtr);
 	uint8 numConditions = stream.get8();
 	debug("%d area conditions", numConditions);
@@ -218,7 +233,13 @@ Binary load8bitBinary(Common::String filename, uint offset) {
 	debug("Start area: %d", startArea);
 	uint8 entranceArea = streamLoader.get8();
 	debug("Entrace area: %d", entranceArea);
-	streamLoader.skipBytes(68);
+
+	streamLoader.skipBytes(66);
+
+	uint16 globalSomething;
+	globalSomething = streamLoader.get16();
+	debug("Pointer to something: %x\n", globalSomething);
+
 	uint16 globalByteCodeTable;
 	globalByteCodeTable = streamLoader.get16();
 	debug("GBCT: %d\n", globalByteCodeTable);


Commit: fcd721c90a7240c5d3cc77d140e76ed7196060da
    https://github.com/scummvm/scummvm/commit/fcd721c90a7240c5d3cc77d140e76ed7196060da
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:37+01:00

Commit Message:
FREESCAPE: better detection and starting to parse Driller frame image

Changed paths:
    engines/freescape/detection.cpp
    engines/freescape/freescape.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index 95da7198f12..09bddc0f411 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -27,12 +27,12 @@ static const ADGameDescription gameDescriptions[] = {
 	 GUIO1(GUIO_NOMIDI)},
 
 	{"Driller",
-	 0,
-	 AD_ENTRY1s("DRILLE.EXE", "eb7e9e0acb72e30cf6e9ed20a6480e7a", 51944),
+	 "",
+	 AD_ENTRY1s("DRILLER.EXE", "cafc0ea0d3424640a7723af87f8bfc0b", 17427),
 	 Common::EN_ANY,
 	 Common::kPlatformDOS,
 	 ADGF_NO_FLAGS,
-	 GUIO1(GUIO_NOMIDI)},
+	 GUIO3(GUIO_NOMIDI, GUIO_RENDEREGA, GUIO_RENDERCGA)},
 
 	{"Castle",
 	 0,
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index ec202feec56..ac0082ae3cd 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -20,7 +20,8 @@
 #include "freescape/loaders/8bitBinaryLoader.h"
 
 #define OFFSET_DARKSIDE 0xc9ce
-#define OFFSET_DRILLER 0x9b40
+#define OFFSET_DRILLER_EGA 0x9b40
+#define OFFSET_DRILLER_CGA 0x7bb0
 #define OFFSET_CASTLE 0xe472
 #define OFFSET_TOTALECLIPSE 0xcdb7
 
@@ -96,12 +97,25 @@ Common::Error FreescapeEngine::run() {
 	_gfx->clear();
 	
 	Binary binary;
+	Common::String renderMode = "";
+
 	if (_targetName == "3Dkit")
 		binary = load16bitBinary("3DKIT.RUN");
 	else if (_targetName == "3Dkitcube")
 		binary = load16bitBinary("CUBE.RUN");
-	else if (_targetName == "Driller")
-		binary = load8bitBinary("DRILLE.EXE", OFFSET_DRILLER);
+	else if (_targetName == "Driller") {
+		renderMode = "ega";
+		if (!ConfMan.hasKey("render_mode"))
+			renderMode = "ega";
+
+		if (renderMode == "ega")
+			binary = load8bitBinary("DRILLE.EXE", OFFSET_DRILLER_EGA);
+		else if (renderMode == "cga")
+			binary = load8bitBinary("DRILLC.EXE", OFFSET_DRILLER_CGA);
+		else
+			error("Invalid render mode %s for Driller", renderMode.c_str());
+
+	}
 	else if (_targetName == "Castle")
 		binary = load8bitBinary("CME.EXE", OFFSET_CASTLE);
 	else
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 0caf282239e..c6cc5a85b35 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -43,7 +43,7 @@ static Object *load8bitObject(StreamLoader &stream) {
 		// read the appropriate number of colours
 		int numberOfColours = GeometricObject::numberOfColoursForObjectOfType(objectType);
 		Common::Array<uint8> *colours = new Common::Array<uint8>;
-		debug("Number of colors", numberOfColours/2);
+		debug("Number of colors: %d", numberOfColours/2);
 		for (uint8 colour = 0; colour < numberOfColours/2; colour++) {
 			uint8 c = stream.get8();
 			colours->push_back(c >> 4);
@@ -217,13 +217,19 @@ Binary load8bitBinary(Common::String filename, uint offset) {
 
 	Common::Array<uint8> binary;
 
-	uint32 i = offset;
+	uint32 i = 0;
 	while (i < fileSize) {
-		binary.push_back(buf[i]);
+		binary.push_back(buf[i]);		
 		i++;
 	}
 
 	StreamLoader streamLoader(binary);
+	streamLoader.skipBytes(0x210);
+	uint16 frameSize = streamLoader.get16();
+	Common::Array<uint8> *raw_border = streamLoader.nextBytes(frameSize);
+	debug("Found border image of size %x", frameSize);
+
+	streamLoader.setFileOffset(offset);
 	uint8 numberOfAreas = streamLoader.get8();
 	uint16 dbSize = streamLoader.rget16();
 	debug("Database ends at %x", dbSize);
@@ -244,8 +250,7 @@ Binary load8bitBinary(Common::String filename, uint offset) {
 	globalByteCodeTable = streamLoader.get16();
 	debug("GBCT: %d\n", globalByteCodeTable);
 
-	streamLoader.setFileOffset(globalByteCodeTable);
-	//uint8 *ConditionPointer = &Base[GlobalByteCodeTable];
+	streamLoader.setFileOffset(offset + globalByteCodeTable);
 	uint8 numConditions = streamLoader.get8();
 	debug("%d global conditions", numConditions);
 	while (numConditions--) {
@@ -256,10 +261,10 @@ Binary load8bitBinary(Common::String filename, uint offset) {
 		Common::Array<uint8> *conditionData = streamLoader.nextBytes(lengthOfCondition);
 
 		//debug("Global condition %d", numCondition + 1);
-		//debug("%s", detokenise8bitCondition(*conditionData)->c_str());
+		debug("%s", detokenise8bitCondition(*conditionData)->c_str());
 	}
 
-	streamLoader.setFileOffset(200);
+	streamLoader.setFileOffset(offset +200);
 	uint16 *fileOffsetForArea = new uint16[numberOfAreas];
 	for (uint16 area = 0; area < numberOfAreas; area++) {
 		fileOffsetForArea[area] = streamLoader.rget16();
@@ -270,16 +275,13 @@ Binary load8bitBinary(Common::String filename, uint offset) {
 	for (uint16 area = 0; area < numberOfAreas; area++) {
 		debug("Area offset %d", fileOffsetForArea[area]);
 
-		streamLoader.setFileOffset(fileOffsetForArea[area]);
+		streamLoader.setFileOffset(offset + fileOffsetForArea[area]);
 		Area *newArea = load8bitArea(streamLoader);
 
 		if (newArea) {
 			(*areaMap)[newArea->getAreaID()] = newArea;
 		}
 	}
-
-	debug("End of areas at %x", streamLoader.getFileOffset());
-
 	return Binary{8, startArea, areaMap, nullptr, nullptr};
 }
 


Commit: d18ef03d1a84518d650b68cb08433e510ac6f7a8
    https://github.com/scummvm/scummvm/commit/d18ef03d1a84518d650b68cb08433e510ac6f7a8
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:38+01:00

Commit Message:
FREESCAPE: code clean-up

Changed paths:
    engines/freescape/area.h
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/gfx.cpp
    engines/freescape/gfx.h
    engines/freescape/loaders/16bitBinaryLoader.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/loaders/8bitBinaryLoader.h


diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index 85bf96e408d..d98047118f7 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -34,12 +34,12 @@ public:
 	Object *entranceWithID(uint16 objectID);
 	uint16 getAreaID();
 	void draw(Freescape::Renderer *gfx);
+	Common::Array<uint8> *raw_palette;
 
 private:
 	uint16 areaID;
 	uint8 skyColor;
 	uint8 groundColor;
-	Common::Array<uint8> *raw_palette;
 	ObjectMap *objectsByID;
 	ObjectMap *entrancesByID;
 	Common::Array<Object *> drawableObjects;
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index ac0082ae3cd..ddb8fc0ee4c 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -19,11 +19,6 @@
 #include "freescape/loaders/16bitBinaryLoader.h"
 #include "freescape/loaders/8bitBinaryLoader.h"
 
-#define OFFSET_DARKSIDE 0xc9ce
-#define OFFSET_DRILLER_EGA 0x9b40
-#define OFFSET_DRILLER_CGA 0x7bb0
-#define OFFSET_CASTLE 0xe472
-#define OFFSET_TOTALECLIPSE 0xcdb7
 
 namespace Freescape {
 
@@ -81,8 +76,6 @@ void FreescapeEngine::drawBorder() {
 
 	Texture *t = _gfx->createTexture(_border);
 	const Common::Rect rect(0, 0, _screenW, _screenH);
-	//g_system->copyRectToScreen(_borderSurf->getPixels(), _borderSurf->pitch, 0, 0, _screenW, _screenH);
-
 
 	_gfx->drawTexturedRect2D(rect, rect, t, 1.0, false);
 	_gfx->flipBuffer();
@@ -104,35 +97,28 @@ Common::Error FreescapeEngine::run() {
 	else if (_targetName == "3Dkitcube")
 		binary = load16bitBinary("CUBE.RUN");
 	else if (_targetName == "Driller") {
-		renderMode = "ega";
 		if (!ConfMan.hasKey("render_mode"))
 			renderMode = "ega";
+		else
+			renderMode = ConfMan.get("render_mode");
 
+		debug("renderMode: %s", renderMode.c_str());
 		if (renderMode == "ega")
-			binary = load8bitBinary("DRILLE.EXE", OFFSET_DRILLER_EGA);
+			binary = load8bitBinary("DRILLE.EXE");
 		else if (renderMode == "cga")
-			binary = load8bitBinary("DRILLC.EXE", OFFSET_DRILLER_CGA);
+			binary = load8bitBinary("DRILLC.EXE");
 		else
 			error("Invalid render mode %s for Driller", renderMode.c_str());
 
-	}
-	else if (_targetName == "Castle")
-		binary = load8bitBinary("CME.EXE", OFFSET_CASTLE);
+	} else if (_targetName == "Castle")
+		binary = load8bitBinary("CME.EXE");
 	else
 		error("%s is an invalid game", _targetName.c_str());
 
 	if (binary.areasByAreaID) {
 		_areasByAreaID = binary.areasByAreaID;
 		if (binary.palette) {
-			uint pSize = 0; 
-			if (binary.bits == 16)
-				pSize = 256;
-			else if (binary.bits == 8)
-				pSize = 16;
-			else
-				error("Invalid number of bits %d", binary.bits);
-
-			Graphics::PixelBuffer *palette = new Graphics::PixelBuffer(_gfx->_palettePixelFormat, pSize, DisposeAfterUse::NO);
+			Graphics::PixelBuffer *palette = new Graphics::PixelBuffer(_gfx->_palettePixelFormat, binary.ncolors, DisposeAfterUse::NO);
 			*palette = binary.palette->data();
 			_gfx->_palette = palette;
 		}
@@ -148,6 +134,7 @@ Common::Error FreescapeEngine::run() {
 		assert(_areasByAreaID->contains(_startArea));
 		Area *area = (*_areasByAreaID)[_startArea];
 		assert(area);
+		//_gfx->renderPalette(area->raw_palette, binary.ncolors);
 		drawBorder();
 		area->draw(_gfx);
 	}	
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index dc9d1abc3be..7954e14fe18 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -24,6 +24,7 @@ typedef struct Binary {
 	AreaMap *areasByAreaID;
 	Common::Array<uint8> *border;
 	Common::Array<uint8> *palette;
+	uint16 ncolors;
 } Binary;
 
 class Console;
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index 3967db4a46a..b4612e50116 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -104,6 +104,38 @@ Graphics::Surface *Renderer::convertFromPalette(Graphics::PixelBuffer *rawsurf)
 }
 
 
+void Renderer::renderPalette(Common::Array<uint8> *raw_palette, uint16 ncolors) {
+	Graphics::PixelBuffer *palette;
+	if (_palette)
+		palette = _palette;
+	else if (raw_palette) {
+		palette = new Graphics::PixelBuffer(_palettePixelFormat, 16, DisposeAfterUse::NO); 
+		*palette = raw_palette->data();
+	} else 
+		error("No palette to show");
+
+	selectTargetWindow(nullptr, false, true);
+	Common::Rect view = viewport();
+	uint8 r, g, b;
+	uint16 c;
+	uint16 top = view.top;
+	uint16 size = kOriginalHeight/ncolors; 
+	uint16 bottom = size;
+
+	for (c = 0; c < ncolors; c++) {
+		view = Common::Rect(view.left, top, view.right, bottom);
+		palette->getRGBAt(c, r, g, b);
+		debug("color: %d %x %x %x", c, r, g, b);
+		drawRect2D(view, 255, r, g, b);
+		bottom = bottom + size;
+		top = top + size;
+	}
+
+	flipBuffer();
+	g_system->updateScreen();
+
+}
+
 Texture *Renderer::copyScreenshotToTexture() {
 	Graphics::Surface *surface = getScreenshot();
 
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 505e81f7dfa..dd29ab1a395 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -120,6 +120,12 @@ public:
      */
 	Graphics::Surface *convertFromPalette(Graphics::PixelBuffer *rawsurf);
 
+
+    /**
+	 *   Show palette on screen
+     */
+	void renderPalette(Common::Array<uint8> *raw_palette, uint16 ncolors);
+
 	virtual void init() = 0;
 	virtual void clear() = 0;
 
diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
index ca45801f063..2b723b918d1 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/16bitBinaryLoader.cpp
@@ -471,7 +471,7 @@ Binary load16bitBinary(Common::String filename) {
 	}
 
 	delete[] fileOffsetForArea;
-	return Binary{16, startArea, areaMap, raw_border, raw_palette};
+	return Binary{16, startArea, areaMap, raw_border, raw_palette, colorNumber};
 }
 
 } // namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index c6cc5a85b35..d90fd4908da 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -129,20 +129,17 @@ float specColors[16][3] = {
 	{1, 1, 1}
 };
 
-
-Common::Array <uint8>*getPaletteGradient(float *c1, float *c2)
-{
+Common::Array <uint8>*getPaletteGradient(float *c1, float *c2, uint16 ncolors) {
 	Common::Array <uint8> *raw_palette = new Common::Array <uint8>();
 	uint16 y0, y1, y2;
-	debug("palette:");
-	for(int c = 0; c < 16; c++)
+	for(int c = 0; c < ncolors; c++)
 	{
-		float ic = (float)c / 15.0f;
+		float ic = (float)c / float(ncolors-1);
 		ic = sqrt(ic);
 		y0  = 255*(ic*c2[0] + (1-ic)*c1[0]);
 		y1  = 255*(ic*c2[1] + (1-ic)*c1[1]);
 		y2  = 255*(ic*c2[2] + (1-ic)*c1[2]);
-		debug("%x %x %x", y0, y1, y2);
+		//debug("%x %x %x", y0, y1, y2);
 		raw_palette->push_back(y0);
 		raw_palette->push_back(y1);
 		raw_palette->push_back(y2);
@@ -151,7 +148,7 @@ Common::Array <uint8>*getPaletteGradient(float *c1, float *c2)
 }
 
 
-Area *load8bitArea(StreamLoader &stream) {
+Area *load8bitArea(StreamLoader &stream, uint16 ncolors) {
 	uint32 base = stream.getFileOffset();
 	uint8 skippedValue = stream.get8();
 	uint8 numberOfObjects = stream.get8();
@@ -165,7 +162,12 @@ Area *load8bitArea(StreamLoader &stream) {
 	uint8 ci4 = stream.get8()&15; 
 
 	debug("Colors: %d %d %d %d", ci1, ci2, ci3, ci4);
-	Common::Array <uint8> *raw_palette = getPaletteGradient(specColors[ci4], specColors[ci3]);
+
+	float *f1, *f2;
+	f1 = specColors[ci3];
+	f2 = specColors[ci4];
+
+	Common::Array <uint8> *raw_palette = getPaletteGradient(f1, f2, ncolors);
 
 	debug("Area %d", areaNumber);
 	debug("Objects: %d", numberOfObjects);
@@ -202,8 +204,37 @@ Area *load8bitArea(StreamLoader &stream) {
 	return (new Area(areaNumber, objectsByID, entrancesByID, 0, 1, raw_palette));
 }
 
+struct BinaryTable {
+	const char *filename;
+	int ncolors;
+	int offset;
+};
+
+static const BinaryTable binaryTable[] = {
+	{ "DRILLE.EXE",  8,  0x9b40},
+	{ "DRILLC.EXE",  4,  0x7bb0},
+	{ "TOTE.EXE",    8,  0xcdb7},
+    //{ "TOTC.EXE",  8,  ??????},
+	{ nullptr,       0,  0  }
+};
+
+Binary load8bitBinary(Common::String filename) {
+	int offset = 0;
+	int ncolors = 0;
+
+	const BinaryTable *entry = binaryTable;
+	while (entry->filename) {
+		debug(entry->filename);
+		if (filename == entry->filename)
+			break;
+		entry++;
+	}
+	if (!entry->filename)
+		error("Unknown game to load %s", filename.c_str());
+
+	offset = entry->offset;
+	ncolors = entry->ncolors;
 
-Binary load8bitBinary(Common::String filename, uint offset) {
 	Common::File *file = new Common::File();
 
 	if (!file->open(filename)) {
@@ -264,7 +295,7 @@ Binary load8bitBinary(Common::String filename, uint offset) {
 		debug("%s", detokenise8bitCondition(*conditionData)->c_str());
 	}
 
-	streamLoader.setFileOffset(offset +200);
+	streamLoader.setFileOffset(offset + 200);
 	uint16 *fileOffsetForArea = new uint16[numberOfAreas];
 	for (uint16 area = 0; area < numberOfAreas; area++) {
 		fileOffsetForArea[area] = streamLoader.rget16();
@@ -276,13 +307,13 @@ Binary load8bitBinary(Common::String filename, uint offset) {
 		debug("Area offset %d", fileOffsetForArea[area]);
 
 		streamLoader.setFileOffset(offset + fileOffsetForArea[area]);
-		Area *newArea = load8bitArea(streamLoader);
+		Area *newArea = load8bitArea(streamLoader, ncolors);
 
 		if (newArea) {
 			(*areaMap)[newArea->getAreaID()] = newArea;
 		}
 	}
-	return Binary{8, startArea, areaMap, nullptr, nullptr};
+	return Binary{8, startArea, areaMap, nullptr, nullptr, ncolors};
 }
 
 } // namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/loaders/8bitBinaryLoader.h b/engines/freescape/loaders/8bitBinaryLoader.h
index 9a1e906cbc1..0ee1071df35 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.h
+++ b/engines/freescape/loaders/8bitBinaryLoader.h
@@ -15,7 +15,7 @@
 
 namespace Freescape {
 
-Binary load8bitBinary(Common::String, uint offset);
+Binary load8bitBinary(Common::String filename);
 
 }
 


Commit: 1f4ae36d19c2338501850c51acc8cb40eef2b9ce
    https://github.com/scummvm/scummvm/commit/1f4ae36d19c2338501850c51acc8cb40eef2b9ce
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:38+01:00

Commit Message:
FREESCAPE: removed clearAllDebugChannels when rebased with master

Changed paths:
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index ddb8fc0ee4c..cd60fe3d61c 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -67,7 +67,7 @@ FreescapeEngine::~FreescapeEngine() {
 	delete _gfx;
 
 	// Remove all of our debug levels here
-	DebugMan.clearAllDebugChannels();
+	//DebugMan.clearAllDebugChannels();
 }
 
 void FreescapeEngine::drawBorder() {


Commit: 0110695d3166cf6ac491664d8b97fd6c6daf0163
    https://github.com/scummvm/scummvm/commit/0110695d3166cf6ac491664d8b97fd6c6daf0163
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:38+01:00

Commit Message:
FREESCAPE: refactoring to better integrate exe parsing

Changed paths:
    engines/freescape/detection.cpp
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/loaders/16bitBinaryLoader.cpp
    engines/freescape/loaders/16bitBinaryLoader.h
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/loaders/8bitBinaryLoader.h
    engines/freescape/objects/geometricobject.cpp
    engines/freescape/objects/object.h


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index 09bddc0f411..664f2786466 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -4,22 +4,29 @@
 namespace Freescape {
 static const PlainGameDescriptor freescapeGames[] = {
 	{"3dkit", "The 3D Kit Game"},
-	{"3dkitcube", "The 3D Kit Game with only one cube"},
 	{"driller", "Driller"},
 	{"castle", "Castle Master"},
 	{0, 0}};
 
 static const ADGameDescription gameDescriptions[] = {
-	{"3Dkit",
-	 0,
+	{"3dkit",
+	 "Example game",
 	 AD_ENTRY1s("3DKIT.RUN", "f35147729a2f5b6852a504223aeb6a57", 112158),
 	 Common::EN_ANY,
 	 Common::kPlatformDOS,
 	 ADGF_NO_FLAGS,
 	 GUIO1(GUIO_NOMIDI)},
 
-	{"3Dkitcube",
-	 "One cube",
+	{"3dkit",
+	 "Empty scene",
+	 AD_ENTRY1s("EMPTY.RUN", "7e7238e12dd9da4336a77a58d1bcfc0e", 83184),
+	 Common::EN_ANY,
+	 Common::kPlatformDOS,
+	 ADGF_NO_FLAGS,
+	 GUIO1(GUIO_NOMIDI)},
+
+	{"3Dkit",
+	 "One cube in scene",
 	 AD_ENTRY1s("CUBE.RUN", "3b7930be0f646b98885cfb70c26c89a2", 66138),
 	 Common::EN_ANY,
 	 Common::kPlatformDOS,
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index cd60fe3d61c..465c505bcf2 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -83,52 +83,64 @@ void FreescapeEngine::drawBorder() {
 	_gfx->freeTexture(t);
 }
 
-Common::Error FreescapeEngine::run() {
-	// Initialize graphics:
-	_gfx = Freescape::createRenderer(_system);
-	_gfx->init();
-	_gfx->clear();
-	
-	Binary binary;
+void FreescapeEngine::loadAssets() {
 	Common::String renderMode = "";
+	Common::SeekableReadStream *file = nullptr;
+	Common::String path = ConfMan.get("path");
+	Common::FSDirectory gameDir(path);
+
+	if (_targetName.hasSuffix("3dkit")) {
+		Common::ArchiveMemberList files;
+        gameDir.listMatchingMembers(files, "*.RUN");
+
+		if (files.size() == 0) {
+			error("No .RUN was found in %s", path.c_str());
+		} else if (files.size() > 1) {
+			warning("More than one .RUN file found, only the first one will be used!");
+		}
 
-	if (_targetName == "3Dkit")
-		binary = load16bitBinary("3DKIT.RUN");
-	else if (_targetName == "3Dkitcube")
-		binary = load16bitBinary("CUBE.RUN");
-	else if (_targetName == "Driller") {
+		file = files.begin()->get()->createReadStream();
+		load16bitBinary(file);
+	} else if (_targetName == "Driller") {
 		if (!ConfMan.hasKey("render_mode"))
 			renderMode = "ega";
 		else
 			renderMode = ConfMan.get("render_mode");
 
+		Common::File exe;	
 		debug("renderMode: %s", renderMode.c_str());
-		if (renderMode == "ega")
-			binary = load8bitBinary("DRILLE.EXE");
-		else if (renderMode == "cga")
-			binary = load8bitBinary("DRILLC.EXE");
-		else
+		bool success = false;
+		if (renderMode == "ega") {
+			file = gameDir.createReadStreamForMember("DRILLE.EXE");
+
+			if (file == nullptr)
+				error("Failed to open DRILLE.EXE");
+
+			load8bitBinary(file, 0x9b40, 8);
+		} else if (renderMode == "cga") {
+			file = gameDir.createReadStreamForMember("DRILLC.EXE");
+
+			if (file == nullptr)
+				error("Failed to open DRILLC.EXE");
+			load8bitBinary(file, 0x7bb0, 4);
+		} else
 			error("Invalid render mode %s for Driller", renderMode.c_str());
 
-	} else if (_targetName == "Castle")
-		binary = load8bitBinary("CME.EXE");
-	else
-		error("%s is an invalid game", _targetName.c_str());
-
-	if (binary.areasByAreaID) {
-		_areasByAreaID = binary.areasByAreaID;
-		if (binary.palette) {
-			Graphics::PixelBuffer *palette = new Graphics::PixelBuffer(_gfx->_palettePixelFormat, binary.ncolors, DisposeAfterUse::NO);
-			*palette = binary.palette->data();
-			_gfx->_palette = palette;
-		}
+	   } else if (_targetName == "Castle") {
+			error("Unsupported game");
+	   } else
+		error("'%s' is an invalid game", _targetName.c_str());
 
-		if (binary.border) {
-			Graphics::PixelBuffer *border = new Graphics::PixelBuffer(_gfx->_originalPixelFormat, 320*200, DisposeAfterUse::NO);
-			*border = binary.border->data();
-			_border = _gfx->convertFromPalette(border);
-		}
+}
+
+Common::Error FreescapeEngine::run() {
+	// Initialize graphics:
+	_gfx = Freescape::createRenderer(_system);
+	_gfx->init();
+	_gfx->clear();
+	loadAssets();
 
+	if (_areasByAreaID) {
 		_startArea = 1; //binary.startArea;
 
 		assert(_areasByAreaID->contains(_startArea));
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 7954e14fe18..afb97da75b3 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -46,10 +46,6 @@ private:
 	uint32 _timeOfLastTick;
 	bool _hasReceivedTime;
 
-	uint16 _startArea;
-	AreaMap *_areasByAreaID;
-	float _rotation[3], _velocity[3], _position[3];
-
 public:
 	FreescapeEngine(OSystem *syst);
 	~FreescapeEngine();
@@ -59,6 +55,23 @@ public:
 	void convertBorder();
 	void drawBorder();
 
+
+	// Parsing
+	void loadAssets();
+	void load16bitBinary(Common::SeekableReadStream *file);
+	void load8bitBinary(Common::SeekableReadStream *file, int offset, int ncolors);
+
+	uint8 _binaryBits;
+
+	// Areas
+	uint16 _startArea;
+	AreaMap *_areasByAreaID;
+	float _rotation[3], _velocity[3], _position[3];
+
+
+	// Rendering
+	uint8 _colorNumber;
+
 	bool hasFeature(EngineFeature f) const override;
 	bool canLoadGameStateCurrently() override { return true; }
 	bool canSaveGameStateCurrently() override { return true; }
diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
index 2b723b918d1..a8c6a6cc798 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/16bitBinaryLoader.cpp
@@ -49,12 +49,12 @@ static Object *load16bitObject(StreamLoader &stream) {
 
 	// grab location, size
 	Vector3d position, size;
-	position.x = stream.get16();
-	position.y = stream.get16();
-	position.z = stream.get16();
-	size.x = stream.get16();
-	size.y = stream.get16();
-	size.z = stream.get16();
+	position.X = stream.get16();
+	position.Y = stream.get16();
+	position.Z = stream.get16();
+	size.X = stream.get16();
+	size.Y = stream.get16();
+	size.Z = stream.get16();
 
 	// object ID
 	uint16 objectID = stream.get16();
@@ -65,8 +65,8 @@ static Object *load16bitObject(StreamLoader &stream) {
 	uint32 byteSizeOfObject = (uint32)(stream.get16() << 1) - 20;
 
 	debug("Object %d ; type %d ; flags %d ; size %d", (int)objectID, (int)objectType, (int)objectFlags, byteSizeOfObject);
-	debug("Location: %d, %d, %d", position.x, position.y, position.z);
-	debug("Size: %d, %d, %d", size.x, size.y, size.z);
+	debug("Location: %f, %f, %f", position.X, position.Y, position.Z);
+	debug("Size: %f, %f, %f", size.X, size.Y, size.Z);
 
 	switch (objectType) {
 	default: {
@@ -222,14 +222,7 @@ Area *load16bitArea(StreamLoader &stream) {
 
 
 
-Binary load16bitBinary(Common::String filename) {
-	Common::File *file = new Common::File();
-
-	if (!file->open(filename)) {
-		delete file;
-		error("NULL");
-	}
-
+void FreescapeEngine::load16bitBinary(Common::SeekableReadStream *file) {
 	const uint32 fileSize = file->size();
 	byte *buf = (byte *)malloc(fileSize);
 	file->read(buf, fileSize);
@@ -470,8 +463,24 @@ Binary load16bitBinary(Common::String filename) {
 		}
 	}
 
+	if (raw_palette) {
+		Graphics::PixelBuffer *palette = new Graphics::PixelBuffer(_gfx->_palettePixelFormat, colorNumber, DisposeAfterUse::NO);
+		*palette = raw_palette->data();
+		_gfx->_palette = palette;
+	}
+
+	if (raw_border) {
+		Graphics::PixelBuffer *border = new Graphics::PixelBuffer(_gfx->_originalPixelFormat, 320*200, DisposeAfterUse::NO);
+		*border = raw_border->data();
+		_border = _gfx->convertFromPalette(border);
+	}
+
 	delete[] fileOffsetForArea;
-	return Binary{16, startArea, areaMap, raw_border, raw_palette, colorNumber};
+	_startArea = startArea;
+	_colorNumber = colorNumber;
+	_areasByAreaID = areaMap;
+	_binaryBits = 16;
+	//return Binary{16, startArea, areaMap, raw_border, raw_palette, colorNumber};
 }
 
 } // namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/loaders/16bitBinaryLoader.h b/engines/freescape/loaders/16bitBinaryLoader.h
index d7bcc8ab090..ef177632b78 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.h
+++ b/engines/freescape/loaders/16bitBinaryLoader.h
@@ -18,8 +18,6 @@
 
 namespace Freescape {
 
-Binary load16bitBinary(Common::String);
-
 }
 
 #endif /* defined(__Phantasma___16bitBinaryLoader__) */
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index d90fd4908da..67d703ec9d0 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -19,13 +19,13 @@ static Object *load8bitObject(StreamLoader &stream) {
 	Object::Type objectType = (Object::Type)(stream.get8() & 0x1F);
 	Vector3d position, v;
 
-	position.x = stream.get8() * 32;
-	position.y = stream.get8() * 32;
-	position.z = stream.get8() * 32;
+	position.X = stream.get8() * 32;
+	position.Y = stream.get8() * 32;
+	position.Z = stream.get8() * 32;
 
-	v.x = stream.get8();
-	v.y = stream.get8();
-	v.z = stream.get8();
+	v.X = stream.get8();
+	v.Y = stream.get8();
+	v.Z = stream.get8();
 
 	// object ID
 	uint16 objectID = stream.get8();
@@ -36,10 +36,10 @@ static Object *load8bitObject(StreamLoader &stream) {
 	assert(byteSizeOfObject >= 9);
 	byteSizeOfObject = byteSizeOfObject - 9;
 	debug("Object %d ; type %d ; size %d", objectID, (int)objectType, byteSizeOfObject);
-    debug("pos: %d %d %d", position.x, position.y, position.z);
+    debug("pos: %f %f %f", position.X, position.Y, position.Z);
 	switch (objectType) {
 	default: {
-		debug("size: %d %d %d", v.x, v.y, v.z);
+		debug("size: %f %f %f", v.X, v.Y, v.Z);
 		// read the appropriate number of colours
 		int numberOfColours = GeometricObject::numberOfColoursForObjectOfType(objectType);
 		Common::Array<uint8> *colours = new Common::Array<uint8>;
@@ -92,7 +92,7 @@ static Object *load8bitObject(StreamLoader &stream) {
 	} break;
 
 	case Object::Entrance: {
-		debug("rotation: %d %d %d", v.x, v.y, v.z);
+		debug("rotation: %f %f %f", v.X, v.Y, v.Z);
 		assert(byteSizeOfObject == 0);
 		// create an entrance
 		return new Entrance(
@@ -204,44 +204,21 @@ Area *load8bitArea(StreamLoader &stream, uint16 ncolors) {
 	return (new Area(areaNumber, objectsByID, entrancesByID, 0, 1, raw_palette));
 }
 
-struct BinaryTable {
-	const char *filename;
-	int ncolors;
-	int offset;
-};
-
-static const BinaryTable binaryTable[] = {
-	{ "DRILLE.EXE",  8,  0x9b40},
-	{ "DRILLC.EXE",  4,  0x7bb0},
-	{ "TOTE.EXE",    8,  0xcdb7},
-    //{ "TOTC.EXE",  8,  ??????},
-	{ nullptr,       0,  0  }
-};
-
-Binary load8bitBinary(Common::String filename) {
-	int offset = 0;
-	int ncolors = 0;
-
-	const BinaryTable *entry = binaryTable;
-	while (entry->filename) {
-		debug(entry->filename);
-		if (filename == entry->filename)
-			break;
-		entry++;
-	}
-	if (!entry->filename)
-		error("Unknown game to load %s", filename.c_str());
-
-	offset = entry->offset;
-	ncolors = entry->ncolors;
-
-	Common::File *file = new Common::File();
-
-	if (!file->open(filename)) {
-		delete file;
-		error("NULL");
-	}
-
+// struct BinaryTable {
+// 	const char *filename;
+// 	int ncolors;
+// 	int offset;
+// };
+
+// static const BinaryTable binaryTable[] = {
+// 	{ "DRILLE.EXE",  8,  0x9b40},
+// 	{ "DRILLC.EXE",  4,  0x7bb0},
+// 	{ "TOTE.EXE",    8,  0xcdb7},
+//     //{ "TOTC.EXE",  8,  ??????},
+// 	{ nullptr,       0,  0  }
+// };
+
+void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offset, int ncolors) {
 	const uint32 fileSize = file->size();
 	byte *buf = (byte *)malloc(fileSize);
 	file->read(buf, fileSize);
@@ -313,7 +290,10 @@ Binary load8bitBinary(Common::String filename) {
 			(*areaMap)[newArea->getAreaID()] = newArea;
 		}
 	}
-	return Binary{8, startArea, areaMap, nullptr, nullptr, ncolors};
+	_areasByAreaID = areaMap;
+	_startArea = startArea;
+	_colorNumber = ncolor;
+	_binaryBits = 8;
 }
 
 } // namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/loaders/8bitBinaryLoader.h b/engines/freescape/loaders/8bitBinaryLoader.h
index 0ee1071df35..aa4a0524107 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.h
+++ b/engines/freescape/loaders/8bitBinaryLoader.h
@@ -15,7 +15,7 @@
 
 namespace Freescape {
 
-Binary load8bitBinary(Common::String filename);
+//Binary load8bitBinary(Common::String filename);
 
 }
 
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index e043f98d4e3..1c87294c49f 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -96,5 +96,5 @@ GeometricObject::~GeometricObject() {
 bool GeometricObject::isDrawable() { return true; }
 bool GeometricObject::isPlanar() {
 	Type type = this->getType();
-	return (type >= Object::Line) || !size.x || !size.y || !size.z;
+	return (type >= Object::Line) || !size.X || !size.Y || !size.Z;
 }
diff --git a/engines/freescape/objects/object.h b/engines/freescape/objects/object.h
index f056f317c9c..4ca18cc8180 100644
--- a/engines/freescape/objects/object.h
+++ b/engines/freescape/objects/object.h
@@ -10,24 +10,14 @@
 #define __Phantasma__Object__
 
 #include "common/system.h"
+#include "graphics/tinygl/zmath.h"
+
 #include "freescape/gfx.h"
 
 //#include <vector>
 //#include "freescape/language/instruction.h"
 
-typedef struct Vector3d {
-	uint16 x, y, z;
-	uint16 &operator[](int index) {
-		switch (index) {
-		default:
-			return x;
-		case 1:
-			return y;
-		case 2:
-			return z;
-		}
-	};
-} Vector3d;
+typedef TinyGL::Vector3 Vector3d;
 
 class VertexBuffer;
 class DrawElementsBuffer;


Commit: 7ecb3169eea6019740f00e7299c4d37389cee26f
    https://github.com/scummvm/scummvm/commit/7ecb3169eea6019740f00e7299c4d37389cee26f
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:38+01:00

Commit Message:
FREESCAPE: preliminary movement functions and fixes

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 465c505bcf2..7daeafb4639 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -35,17 +35,19 @@ FreescapeEngine::FreescapeEngine(OSystem *syst)
 	// Do not initialize audio devices here
 	_hasReceivedTime = false;
 
-	_rotation[0] = 0.0f;
-	_rotation[1] = 0.0f;
-	_rotation[2] = 0.0f;
+	_rotation.X = 0.f;
+	_rotation.Y = 0.f;
+	_rotation.Z = 0.f;
 
-	_position[0] = 1000.0f;
-	_position[1] = 300.0f;
-	_position[2] = 1000.0f;
+	_position.X = 1000.0f;
+	_position.Y = 0.0f;
+	_position.Z = 1000.0f;
 
-	_velocity[0] = 0.0f;
-	_velocity[1] = 0.0f;
-	_velocity[2] = 0.0f;
+	_velocity.X = 0.0f;
+	_velocity.Y = 0.0f;
+	_velocity.Z = 0.0f;
+
+	_movementSpeed = 4.5f;
 
 	// Here is the right place to set up the engine specific debug channels
 	DebugMan.addDebugChannel(kFreescapeDebug, "example", "this is just an example for a engine specific debug channel");
@@ -152,16 +154,77 @@ Common::Error FreescapeEngine::run() {
 	}	
 	debug("FreescapeEngine::init");
 	// Simple main event loop
-	Common::Event evt;
+	Common::Event event;
+	float lastFrame = 0.f;
 
 	while (!shouldQuit()) {
-		g_system->getEventManager()->pollEvent(evt);
+        float currentFrame = g_system->getMillis();
+        float deltaTime = currentFrame - lastFrame;
+        lastFrame = currentFrame;
+
+		while (g_system->getEventManager()->pollEvent(event)) {
+			Common::Point mousePos = g_system->getEventManager()->getMousePos();
+
+			switch (event.type) {
+			case Common::EVENT_KEYDOWN:
+				if (event.kbd.keycode == Common::KEYCODE_w || event.kbd.keycode == Common::KEYCODE_UP)
+					Move(FORWARD, deltaTime);
+				else if (event.kbd.keycode == Common::KEYCODE_s || event.kbd.keycode == Common::KEYCODE_DOWN)
+					Move(BACKWARD, deltaTime);
+				else if (event.kbd.keycode == Common::KEYCODE_a || event.kbd.keycode == Common::KEYCODE_LEFT)
+					Move(LEFT, deltaTime);
+				else if (event.kbd.keycode == Common::KEYCODE_d || event.kbd.keycode == Common::KEYCODE_RIGHT)
+					Move(RIGHT, deltaTime);
+				
+				debug("player position: %f %f %f", _position.X, _position.Y, _position.Z);
+				break;
+
+			case Common::EVENT_QUIT:
+			case Common::EVENT_RETURN_TO_LAUNCHER:
+				return Common::kNoError;
+				break;
+			
+			default:
+				break;
+
+			}
+		}
+
 		g_system->delayMillis(10);
 	}
 
 	return Common::kNoError;
 }
 
+void FreescapeEngine::Move(CameraMovement direction, float deltaTime) {
+	float velocity = _movementSpeed * deltaTime;
+	switch (direction) {
+	case FORWARD:
+		_rotation.Z = 1.f;
+		_position = _position + _rotation * velocity;
+		_rotation.Z = 0.f;
+		break;
+	case BACKWARD:
+		_rotation.Z = -1.f;
+		_position = _position + _rotation * velocity;
+		_rotation.Z = 0.f;
+		break;
+	case LEFT:
+		_rotation.X = 1.f;
+		_position = _position + _rotation * velocity;
+		_rotation.X = 0.f;
+		break;
+	case RIGHT:
+		_rotation.X = -1.f;
+		_position = _position + _rotation * velocity;
+		_rotation.X = 0.f;
+		break;
+	}
+	// Make sure the user stays at the ground level
+	// this one-liner keeps the user at the ground level (xz plane)
+	_position.Y = 0.0f;
+}
+
 bool FreescapeEngine::hasFeature(EngineFeature f) const {
 	return (f == kSupportsReturnToLauncher) ||
 		   (f == kSupportsLoadingDuringRuntime) ||
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index afb97da75b3..25b6804a938 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -16,6 +16,15 @@ namespace Freescape {
 
 class Renderer;
 
+// from shooter
+// Defines several possible options for camera movement. Used as abstraction to stay away from window-system specific input methods
+enum CameraMovement {
+    FORWARD,
+    BACKWARD,
+    LEFT,
+    RIGHT
+};
+
 typedef Common::HashMap<uint16, Area *> AreaMap;
 
 typedef struct Binary {
@@ -66,7 +75,12 @@ public:
 	// Areas
 	uint16 _startArea;
 	AreaMap *_areasByAreaID;
-	float _rotation[3], _velocity[3], _position[3];
+
+
+	// Movement
+	void Move(CameraMovement direction, float deltaTime);
+	float _movementSpeed;
+	Vector3d _position, _rotation, _velocity;
 
 
 	// Rendering
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 67d703ec9d0..8ce5c05ca08 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -292,7 +292,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	}
 	_areasByAreaID = areaMap;
 	_startArea = startArea;
-	_colorNumber = ncolor;
+	_colorNumber = ncolors;
 	_binaryBits = 8;
 }
 


Commit: 3e6c07f5faf1815ac6fa9af630b699eb64fe90ec
    https://github.com/scummvm/scummvm/commit/3e6c07f5faf1815ac6fa9af630b699eb64fe90ec
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:38+01:00

Commit Message:
FREESCAPE: preliminary rotation/movement code

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 7daeafb4639..e8327e1fc25 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -43,11 +43,14 @@ FreescapeEngine::FreescapeEngine(OSystem *syst)
 	_position.Y = 0.0f;
 	_position.Z = 1000.0f;
 
-	_velocity.X = 0.0f;
-	_velocity.Y = 0.0f;
-	_velocity.Z = 0.0f;
+	_velocity = Vector3d(0.0f, 0.0f, 0.0f);
+	_front = Vector3d(0.0f, 0.0f, 0.0f);
+	_right = Vector3d(0.0f, 0.0f, 0.0f);
 
+	_yaw = 90.0f;
+	_pitch = 0.0f;
 	_movementSpeed = 4.5f;
+	_mouseSensitivity = 0.05f;
 
 	// Here is the right place to set up the engine specific debug channels
 	DebugMan.addDebugChannel(kFreescapeDebug, "example", "this is just an example for a engine specific debug channel");
@@ -155,6 +158,7 @@ Common::Error FreescapeEngine::run() {
 	debug("FreescapeEngine::init");
 	// Simple main event loop
 	Common::Event event;
+	Common::Point lastMousePos(0, 0);
 	float lastFrame = 0.f;
 
 	while (!shouldQuit()) {
@@ -168,13 +172,13 @@ Common::Error FreescapeEngine::run() {
 			switch (event.type) {
 			case Common::EVENT_KEYDOWN:
 				if (event.kbd.keycode == Common::KEYCODE_w || event.kbd.keycode == Common::KEYCODE_UP)
-					Move(FORWARD, deltaTime);
+					move(FORWARD, deltaTime);
 				else if (event.kbd.keycode == Common::KEYCODE_s || event.kbd.keycode == Common::KEYCODE_DOWN)
-					Move(BACKWARD, deltaTime);
+					move(BACKWARD, deltaTime);
 				else if (event.kbd.keycode == Common::KEYCODE_a || event.kbd.keycode == Common::KEYCODE_LEFT)
-					Move(LEFT, deltaTime);
+					move(LEFT, deltaTime);
 				else if (event.kbd.keycode == Common::KEYCODE_d || event.kbd.keycode == Common::KEYCODE_RIGHT)
-					Move(RIGHT, deltaTime);
+					move(RIGHT, deltaTime);
 				
 				debug("player position: %f %f %f", _position.X, _position.Y, _position.Z);
 				break;
@@ -184,6 +188,11 @@ Common::Error FreescapeEngine::run() {
 				return Common::kNoError;
 				break;
 			
+			case Common::EVENT_MOUSEMOVE:
+				rotate(lastMousePos, mousePos);
+				lastMousePos = mousePos;
+				debug("player rotation (front): %f %f %f", _front.X, _front.Y, _front.Z);
+				break;
 			default:
 				break;
 
@@ -196,28 +205,52 @@ Common::Error FreescapeEngine::run() {
 	return Common::kNoError;
 }
 
-void FreescapeEngine::Move(CameraMovement direction, float deltaTime) {
+
+void FreescapeEngine::rotate(Common::Point lastMousePos, Common::Point mousePos) {
+	float xoffset = mousePos.x - lastMousePos.x;
+	float yoffset = mousePos.y - lastMousePos.y;
+
+	xoffset *= _mouseSensitivity;
+	yoffset *= _mouseSensitivity;
+
+	_yaw += xoffset;
+	_pitch += yoffset;
+
+	// Make sure that when pitch is out of bounds, screen doesn't get flipped
+	if (_pitch > 89.0f)
+		_pitch = 89.0f;
+	if (_pitch < -89.0f)
+		_pitch = -89.0f;
+
+	Vector3d v;
+	v.X = cos(_yaw  * M_PI / 180.0) * cos(_pitch  * M_PI / 180.0);
+	v.Y = sin(_pitch * M_PI / 180.0);
+	v.Z = sin(_yaw * M_PI / 180.0) * cos(_pitch * M_PI / 180.0);
+	v.normalize();
+	_front = v;
+
+	// _right = _front x _up;
+	v.X = -_front.Z;
+	v.Y =  0;
+	v.Z = _front.X;
+	v.normalize();
+	_right = v;
+}
+
+void FreescapeEngine::move(CameraMovement direction, float deltaTime) {
 	float velocity = _movementSpeed * deltaTime;
 	switch (direction) {
 	case FORWARD:
-		_rotation.Z = 1.f;
-		_position = _position + _rotation * velocity;
-		_rotation.Z = 0.f;
+		_position = _position + _front * velocity;
 		break;
 	case BACKWARD:
-		_rotation.Z = -1.f;
-		_position = _position + _rotation * velocity;
-		_rotation.Z = 0.f;
-		break;
-	case LEFT:
-		_rotation.X = 1.f;
-		_position = _position + _rotation * velocity;
-		_rotation.X = 0.f;
+		_position = _position - _front * velocity;
 		break;
 	case RIGHT:
-		_rotation.X = -1.f;
-		_position = _position + _rotation * velocity;
-		_rotation.X = 0.f;
+		_position = _position + _right * velocity;
+		break;
+	case LEFT:
+		_position = _position - _right * velocity;
 		break;
 	}
 	// Make sure the user stays at the ground level
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 25b6804a938..8a4ea8d1769 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -78,8 +78,15 @@ public:
 
 
 	// Movement
-	void Move(CameraMovement direction, float deltaTime);
+	void move(CameraMovement direction, float deltaTime);
+	void rotate(Common::Point lastMousePos, Common::Point mousePos);
+	// Eular Angles
+	float _yaw;
+	float _pitch;
+	// Camera options
+	float _mouseSensitivity;
 	float _movementSpeed;
+	Vector3d _front, _right;
 	Vector3d _position, _rotation, _velocity;
 
 


Commit: 9a2479465b11bf954e71397c86e02016a77b01f2
    https://github.com/scummvm/scummvm/commit/9a2479465b11bf954e71397c86e02016a77b01f2
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:38+01:00

Commit Message:
FREESCAPE: removed useless code from the renderer

Changed paths:
    engines/freescape/gfx.cpp
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/gfx_tinygl.h


diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index b4612e50116..1a2ba45ffb7 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -37,33 +37,6 @@
 
 namespace Freescape {
 
-const float Renderer::cubeVertices[] = {
-	// S     T      X      Y      Z
-	0.0f, 1.0f, -320.0f, -320.0f, -320.0f,
-	1.0f, 1.0f,  320.0f, -320.0f, -320.0f,
-	0.0f, 0.0f, -320.0f,  320.0f, -320.0f,
-	1.0f, 0.0f,  320.0f,  320.0f, -320.0f,
-	0.0f, 1.0f,  320.0f, -320.0f, -320.0f,
-	1.0f, 1.0f, -320.0f, -320.0f, -320.0f,
-	0.0f, 0.0f,  320.0f, -320.0f,  320.0f,
-	1.0f, 0.0f, -320.0f, -320.0f,  320.0f,
-	0.0f, 1.0f,  320.0f, -320.0f,  320.0f,
-	1.0f, 1.0f, -320.0f, -320.0f,  320.0f,
-	0.0f, 0.0f,  320.0f,  320.0f,  320.0f,
-	1.0f, 0.0f, -320.0f,  320.0f,  320.0f,
-	0.0f, 1.0f,  320.0f, -320.0f, -320.0f,
-	1.0f, 1.0f,  320.0f, -320.0f,  320.0f,
-	0.0f, 0.0f,  320.0f,  320.0f, -320.0f,
-	1.0f, 0.0f,  320.0f,  320.0f,  320.0f,
-	0.0f, 1.0f, -320.0f, -320.0f,  320.0f,
-	1.0f, 1.0f, -320.0f, -320.0f, -320.0f,
-	0.0f, 0.0f, -320.0f,  320.0f,  320.0f,
-	1.0f, 0.0f, -320.0f,  320.0f, -320.0f,
-	0.0f, 1.0f,  320.0f,  320.0f,  320.0f,
-	1.0f, 1.0f, -320.0f,  320.0f,  320.0f,
-	0.0f, 0.0f,  320.0f,  320.0f, -320.0f,
-	1.0f, 0.0f, -320.0f,  320.0f, -320.0f
-};
 
 Renderer::Renderer(OSystem *system)
 		: _system(system),
@@ -73,16 +46,9 @@ Renderer::Renderer(OSystem *system)
 	_originalPixelFormat = Graphics::PixelFormat::createFormatCLUT8();
 	_palettePixelFormat = Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0);
 
-	// Compute the cube faces Axis Aligned Bounding Boxes
-	for (uint i = 0; i < ARRAYSIZE(_cubeFacesAABB); i++) {
-		for (uint j = 0; j < 4; j++) {
-			_cubeFacesAABB[i].expand(Math::Vector3d(cubeVertices[5 * (4 * i + j) + 2], cubeVertices[5 * (4 * i + j) + 3], cubeVertices[5 * (4 * i + j) + 4]));
-		}
-	}
 }
 
-Renderer::~Renderer() {
-}
+Renderer::~Renderer() {}
 
 void Renderer::initFont(const Graphics::Surface *surface) {
 	_font = createTexture(surface);
@@ -136,17 +102,6 @@ void Renderer::renderPalette(Common::Array<uint8> *raw_palette, uint16 ncolors)
 
 }
 
-Texture *Renderer::copyScreenshotToTexture() {
-	Graphics::Surface *surface = getScreenshot();
-
-	Texture *texture = createTexture(surface);
-
-	surface->free();
-	delete surface;
-
-	return texture;
-}
-
 Common::Rect Renderer::getFontCharacterRect(uint8 character) {
 	uint index = 0;
 
@@ -226,23 +181,6 @@ void Renderer::setupCameraPerspective(float pitch, float heading, float fov) {
 	_mvpMatrix.transpose();
 }
 
-bool Renderer::isCubeFaceVisible(uint face) {
-	assert(face < 6);
-
-	return _frustum.isInside(_cubeFacesAABB[face]);
-}
-
-void Renderer::flipVertical(Graphics::Surface *s) {
-	for (int y = 0; y < s->h / 2; ++y) {
-		// Flip the lines
-		byte *line1P = (byte *)s->getBasePtr(0, y);
-		byte *line2P = (byte *)s->getBasePtr(0, s->h - y - 1);
-
-		for (int x = 0; x < s->pitch; ++x)
-			SWAP(line1P[x], line2P[x]);
-	}
-}
-
 Renderer *createRenderer(OSystem *system) {
 	Common::String rendererConfig = ConfMan.get("renderer");
 	Graphics::PixelFormat pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index dd29ab1a395..99b0e25b939 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -143,16 +143,9 @@ public:
 	virtual void drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint8 g, uint8 b) = 0;
 	virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture,
 									float transparency = -1.0, bool additiveBlending = false) = 0;
-	virtual void drawTexturedRect3D(const Math::Vector3d &topLeft, const Math::Vector3d &bottomLeft,
-									const Math::Vector3d &topRight, const Math::Vector3d &bottomRight,
-									Texture *texture) = 0;
 
-	virtual void drawCube(Texture **textures) = 0;
-	virtual void drawTriange() = 0;
 	virtual void draw2DText(const Common::String &text, const Common::Point &position) = 0;
 
-	virtual Graphics::Surface *getScreenshot() = 0;
-	virtual Texture *copyScreenshotToTexture();
 
 	/** Render a Drawable in the specified window */
 	void renderDrawable(Drawable *drawable, Window *window);
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 30469c49763..752d2d05fae 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -225,96 +225,6 @@ void TinyGLRenderer::draw2DText(const Common::String &text, const Common::Point
 	tglDepthMask(TGL_TRUE);
 }
 
-void TinyGLRenderer::drawFace(uint face, Texture *texture) {
-	TinyGLTexture *glTexture = static_cast<TinyGLTexture *>(texture);
-
-	tglBindTexture(TGL_TEXTURE_2D, glTexture->id);
-	tglBegin(TGL_TRIANGLE_STRIP);
-	for (uint i = 0; i < 4; i++) {
-		tglTexCoord2f(cubeVertices[5 * (4 * face + i) + 0], cubeVertices[5 * (4 * face + i) + 1]);
-		tglVertex3f(cubeVertices[5 * (4 * face + i) + 2], cubeVertices[5 * (4 * face + i) + 3], cubeVertices[5 * (4 * face + i) + 4]);
-	}
-	tglEnd();
-}
-
-void TinyGLRenderer::drawTriange() {
-
-	tglViewport(0, 0, 320, 200);
-	tglEnable(TGL_DEPTH_TEST);
-	// GLfloat  h = (GLfloat) winSizeY / (GLfloat) winSizeX;
-	tglMatrixMode(TGL_PROJECTION);
-	tglLoadIdentity();
-	// glFrustum( -1.0, 1.0, -h, h, 5.0, 60.0 );
-	tglMatrixMode(TGL_MODELVIEW);
-	tglLoadIdentity();
-
-	tglMatrixMode(TGL_MODELVIEW);
-	tglLoadIdentity();
-	tglPushMatrix();
-	tglRotatef(0.01, 0, 0, 1);
-	tglBegin(TGL_TRIANGLES);
-	tglColor3f(0.2, 0.2, 1.0); // BLUE!
-	// glColor3f(1.0, 0.2, 0.2); //RED!
-	tglVertex3f(-0.8, -0.8, 0.2);
-
-	tglColor3f(0.2, 1.0, 0.2); // GREEN!
-	// glColor3f(1.0, 0.2, 0.2); //RED!
-	tglVertex3f(0.8, -0.8, 0.2);
-
-	tglColor3f(1.0, 0.2, 0.2); // RED!
-	tglVertex3f(0, 1.2, 0.2);
-	tglEnd();
-	tglPopMatrix();
-}
-
-void TinyGLRenderer::drawCube(Texture **textures) {
-	tglEnable(TGL_TEXTURE_2D);
-	tglDepthMask(TGL_FALSE);
-
-	for (uint i = 0; i < 6; i++) {
-		drawFace(i, textures[i]);
-	}
-
-	tglDepthMask(TGL_TRUE);
-}
-
-void TinyGLRenderer::drawTexturedRect3D(const Math::Vector3d &topLeft, const Math::Vector3d &bottomLeft,
-		const Math::Vector3d &topRight, const Math::Vector3d &bottomRight, Texture *texture) {
-
-	TinyGLTexture *glTexture = static_cast<TinyGLTexture *>(texture);
-
-	tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE_MINUS_SRC_ALPHA);
-	tglEnable(TGL_BLEND);
-	tglDepthMask(TGL_FALSE);
-
-	tglBindTexture(TGL_TEXTURE_2D, glTexture->id);
-
-	tglBegin(TGL_TRIANGLE_STRIP);
-		tglTexCoord2f(0, 0);
-		tglVertex3f(-topLeft.x(), topLeft.y(), topLeft.z());
-
-		tglTexCoord2f(0, 1);
-		tglVertex3f(-bottomLeft.x(), bottomLeft.y(), bottomLeft.z());
-
-		tglTexCoord2f(1, 0);
-		tglVertex3f(-topRight.x(), topRight.y(), topRight.z());
-
-		tglTexCoord2f(1, 1);
-		tglVertex3f(-bottomRight.x(), bottomRight.y(), bottomRight.z());
-	tglEnd();
-
-	tglDisable(TGL_BLEND);
-	tglDepthMask(TGL_TRUE);
-}
-
-Graphics::Surface *TinyGLRenderer::getScreenshot() {
-	Graphics::Surface *s = new Graphics::Surface();
-	s->create(kOriginalWidth, kOriginalHeight, Texture::getRGBAPixelFormat());
-	Graphics::PixelBuffer buf(s->format, (byte *)s->getPixels());
-	_fb->copyToBuffer(buf);
-	return s;
-}
-
 void TinyGLRenderer::flipBuffer() {
 	TinyGL::tglPresentBuffer();
 	g_system->copyRectToScreen(_fb->getPixelBuffer(), _fb->linesize,
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index 44f4350e26e..7b78cc22e51 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -38,7 +38,6 @@ public:
 	virtual ~TinyGLRenderer();
 
 	virtual void init() override;
-
 	virtual void clear() override;
 	virtual void selectTargetWindow(Window *window, bool is3D, bool scaled) override;
 
@@ -48,16 +47,8 @@ public:
 	virtual void drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint8 g, uint8 b) override;
 	virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture,
 	                                float transparency = -1.0, bool additiveBlending = false) override;
-	virtual void drawTexturedRect3D(const Math::Vector3d &topLeft, const Math::Vector3d &bottomLeft,
-	                                const Math::Vector3d &topRight, const Math::Vector3d &bottomRight,
-	                                Texture *texture) override;
-
-	virtual void drawCube(Texture **textures) override;
-	virtual void drawTriange() override;
 	virtual void draw2DText(const Common::String &text, const Common::Point &position) override;
 
-	virtual Graphics::Surface *getScreenshot() override;
-
 	virtual void flipBuffer() override;
 private:
 	void drawFace(uint face, Texture *texture);


Commit: 364c0f31743c122d14295fd563e64bd0a31ef8a3
    https://github.com/scummvm/scummvm/commit/364c0f31743c122d14295fd563e64bd0a31ef8a3
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:39+01:00

Commit Message:
FREESCAPE: using Math::Vector3d instead of TinyGL::Vector3

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/loaders/16bitBinaryLoader.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/objects/geometricobject.cpp
    engines/freescape/objects/object.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index e8327e1fc25..3a11c3054e4 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -35,14 +35,8 @@ FreescapeEngine::FreescapeEngine(OSystem *syst)
 	// Do not initialize audio devices here
 	_hasReceivedTime = false;
 
-	_rotation.X = 0.f;
-	_rotation.Y = 0.f;
-	_rotation.Z = 0.f;
-
-	_position.X = 1000.0f;
-	_position.Y = 0.0f;
-	_position.Z = 1000.0f;
-
+	_rotation = Vector3d(0.f, 0.f, 0.f);
+	_position = Vector3d(1000.0f, 0.0f, 1000.0f);
 	_velocity = Vector3d(0.0f, 0.0f, 0.0f);
 	_front = Vector3d(0.0f, 0.0f, 0.0f);
 	_right = Vector3d(0.0f, 0.0f, 0.0f);
@@ -180,7 +174,7 @@ Common::Error FreescapeEngine::run() {
 				else if (event.kbd.keycode == Common::KEYCODE_d || event.kbd.keycode == Common::KEYCODE_RIGHT)
 					move(RIGHT, deltaTime);
 				
-				debug("player position: %f %f %f", _position.X, _position.Y, _position.Z);
+				debug("player position: %f %f %f", _position.x(), _position.y(), _position.z());
 				break;
 
 			case Common::EVENT_QUIT:
@@ -191,7 +185,7 @@ Common::Error FreescapeEngine::run() {
 			case Common::EVENT_MOUSEMOVE:
 				rotate(lastMousePos, mousePos);
 				lastMousePos = mousePos;
-				debug("player rotation (front): %f %f %f", _front.X, _front.Y, _front.Z);
+				debug("player rotation (front): %f %f %f", _front.x(), _front.y(), _front.z());
 				break;
 			default:
 				break;
@@ -223,16 +217,16 @@ void FreescapeEngine::rotate(Common::Point lastMousePos, Common::Point mousePos)
 		_pitch = -89.0f;
 
 	Vector3d v;
-	v.X = cos(_yaw  * M_PI / 180.0) * cos(_pitch  * M_PI / 180.0);
-	v.Y = sin(_pitch * M_PI / 180.0);
-	v.Z = sin(_yaw * M_PI / 180.0) * cos(_pitch * M_PI / 180.0);
+	float x = cos(_yaw  * M_PI / 180.0) * cos(_pitch  * M_PI / 180.0);
+	float y = sin(_pitch * M_PI / 180.0);
+	float z = sin(_yaw * M_PI / 180.0) * cos(_pitch * M_PI / 180.0);
+	v.set(x, y, z);
 	v.normalize();
 	_front = v;
 
 	// _right = _front x _up;
-	v.X = -_front.Z;
-	v.Y =  0;
-	v.Z = _front.X;
+	Vector3d up(0, 1, 0); // this should be const
+	v = Math::Vector3d::crossProduct(_front, up);
 	v.normalize();
 	_right = v;
 }
@@ -255,7 +249,7 @@ void FreescapeEngine::move(CameraMovement direction, float deltaTime) {
 	}
 	// Make sure the user stays at the ground level
 	// this one-liner keeps the user at the ground level (xz plane)
-	_position.Y = 0.0f;
+	_position.set(_position.x(), 0, _position.z());
 }
 
 bool FreescapeEngine::hasFeature(EngineFeature f) const {
diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
index a8c6a6cc798..7195bb3704b 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/16bitBinaryLoader.cpp
@@ -49,12 +49,12 @@ static Object *load16bitObject(StreamLoader &stream) {
 
 	// grab location, size
 	Vector3d position, size;
-	position.X = stream.get16();
-	position.Y = stream.get16();
-	position.Z = stream.get16();
-	size.X = stream.get16();
-	size.Y = stream.get16();
-	size.Z = stream.get16();
+	position.x() = stream.get16();
+	position.y() = stream.get16();
+	position.z() = stream.get16();
+	size.x() = stream.get16();
+	size.y() = stream.get16();
+	size.z() = stream.get16();
 
 	// object ID
 	uint16 objectID = stream.get16();
@@ -65,8 +65,8 @@ static Object *load16bitObject(StreamLoader &stream) {
 	uint32 byteSizeOfObject = (uint32)(stream.get16() << 1) - 20;
 
 	debug("Object %d ; type %d ; flags %d ; size %d", (int)objectID, (int)objectType, (int)objectFlags, byteSizeOfObject);
-	debug("Location: %f, %f, %f", position.X, position.Y, position.Z);
-	debug("Size: %f, %f, %f", size.X, size.Y, size.Z);
+	debug("Location: %f, %f, %f", position.x(), position.y(), position.z());
+	debug("Size: %f, %f, %f", size.x(), size.y(), size.z());
 
 	switch (objectType) {
 	default: {
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 8ce5c05ca08..9ab9c5a5961 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -19,13 +19,13 @@ static Object *load8bitObject(StreamLoader &stream) {
 	Object::Type objectType = (Object::Type)(stream.get8() & 0x1F);
 	Vector3d position, v;
 
-	position.X = stream.get8() * 32;
-	position.Y = stream.get8() * 32;
-	position.Z = stream.get8() * 32;
+	position.x() = stream.get8() * 32;
+	position.y() = stream.get8() * 32;
+	position.z() = stream.get8() * 32;
 
-	v.X = stream.get8();
-	v.Y = stream.get8();
-	v.Z = stream.get8();
+	v.x() = stream.get8();
+	v.y() = stream.get8();
+	v.z() = stream.get8();
 
 	// object ID
 	uint16 objectID = stream.get8();
@@ -36,10 +36,10 @@ static Object *load8bitObject(StreamLoader &stream) {
 	assert(byteSizeOfObject >= 9);
 	byteSizeOfObject = byteSizeOfObject - 9;
 	debug("Object %d ; type %d ; size %d", objectID, (int)objectType, byteSizeOfObject);
-    debug("pos: %f %f %f", position.X, position.Y, position.Z);
+    debug("pos: %f %f %f", position.x(), position.y(), position.z());
 	switch (objectType) {
 	default: {
-		debug("size: %f %f %f", v.X, v.Y, v.Z);
+		debug("size: %f %f %f", v.x(), v.y(), v.z());
 		// read the appropriate number of colours
 		int numberOfColours = GeometricObject::numberOfColoursForObjectOfType(objectType);
 		Common::Array<uint8> *colours = new Common::Array<uint8>;
@@ -92,7 +92,7 @@ static Object *load8bitObject(StreamLoader &stream) {
 	} break;
 
 	case Object::Entrance: {
-		debug("rotation: %f %f %f", v.X, v.Y, v.Z);
+		debug("rotation: %f %f %f", v.x(), v.y(), v.z());
 		assert(byteSizeOfObject == 0);
 		// create an entrance
 		return new Entrance(
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index 1c87294c49f..14049c8a803 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -96,5 +96,5 @@ GeometricObject::~GeometricObject() {
 bool GeometricObject::isDrawable() { return true; }
 bool GeometricObject::isPlanar() {
 	Type type = this->getType();
-	return (type >= Object::Line) || !size.X || !size.Y || !size.Z;
+	return (type >= Object::Line) || !size.x() || !size.y() || !size.z();
 }
diff --git a/engines/freescape/objects/object.h b/engines/freescape/objects/object.h
index 4ca18cc8180..125207e0442 100644
--- a/engines/freescape/objects/object.h
+++ b/engines/freescape/objects/object.h
@@ -10,14 +10,12 @@
 #define __Phantasma__Object__
 
 #include "common/system.h"
-#include "graphics/tinygl/zmath.h"
+#include "math/vector3d.h"
 
 #include "freescape/gfx.h"
 
-//#include <vector>
-//#include "freescape/language/instruction.h"
 
-typedef TinyGL::Vector3 Vector3d;
+typedef Math::Vector3d Vector3d;
 
 class VertexBuffer;
 class DrawElementsBuffer;


Commit: 5fa47a018848bb42b68b122c0dd23120d3aa4414
    https://github.com/scummvm/scummvm/commit/5fa47a018848bb42b68b122c0dd23120d3aa4414
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:39+01:00

Commit Message:
FREESCAPE: added some code to determinate how to render a cube

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/freescape.cpp
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/gfx_tinygl.h
    engines/freescape/objects/geometricobject.cpp
    engines/freescape/objects/geometricobject.h


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 3263d7ef4ef..931cc57044d 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -117,11 +117,9 @@ void Area::draw(Freescape::Renderer *gfx) {
 	gfx->drawRect2D(ground, 255, r, g, b);
 
 	//gfx->drawTriange(); // I have no idea why?
-
-	gfx->flipBuffer();
-	g_system->updateScreen();
-
 	for (Common::Array<Object *>::iterator iterator = drawableObjects.begin(); iterator != drawableObjects.end(); iterator++) {
 		(*iterator)->draw(gfx);
 	}
+	gfx->flipBuffer();
+	g_system->updateScreen();
 }
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 3a11c3054e4..ab0a184339e 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -88,7 +88,7 @@ void FreescapeEngine::loadAssets() {
 	Common::String path = ConfMan.get("path");
 	Common::FSDirectory gameDir(path);
 
-	if (_targetName.hasSuffix("3dkit")) {
+	if (_targetName.hasPrefix("3dkit")) {
 		Common::ArchiveMemberList files;
         gameDir.listMatchingMembers(files, "*.RUN");
 
@@ -138,16 +138,15 @@ Common::Error FreescapeEngine::run() {
 	_gfx->init();
 	_gfx->clear();
 	loadAssets();
-
+	Area *area = nullptr;
 	if (_areasByAreaID) {
 		_startArea = 1; //binary.startArea;
 
 		assert(_areasByAreaID->contains(_startArea));
-		Area *area = (*_areasByAreaID)[_startArea];
+		area = (*_areasByAreaID)[_startArea];
 		assert(area);
 		//_gfx->renderPalette(area->raw_palette, binary.ncolors);
 		drawBorder();
-		area->draw(_gfx);
 	}	
 	debug("FreescapeEngine::init");
 	// Simple main event loop
@@ -156,6 +155,7 @@ Common::Error FreescapeEngine::run() {
 	float lastFrame = 0.f;
 
 	while (!shouldQuit()) {
+		area->draw(_gfx);
         float currentFrame = g_system->getMillis();
         float deltaTime = currentFrame - lastFrame;
         lastFrame = currentFrame;
@@ -174,7 +174,7 @@ Common::Error FreescapeEngine::run() {
 				else if (event.kbd.keycode == Common::KEYCODE_d || event.kbd.keycode == Common::KEYCODE_RIGHT)
 					move(RIGHT, deltaTime);
 				
-				debug("player position: %f %f %f", _position.x(), _position.y(), _position.z());
+				//debug("player position: %f %f %f", _position.x(), _position.y(), _position.z());
 				break;
 
 			case Common::EVENT_QUIT:
@@ -185,7 +185,7 @@ Common::Error FreescapeEngine::run() {
 			case Common::EVENT_MOUSEMOVE:
 				rotate(lastMousePos, mousePos);
 				lastMousePos = mousePos;
-				debug("player rotation (front): %f %f %f", _front.x(), _front.y(), _front.z());
+				//debug("player rotation (front): %f %f %f", _front.x(), _front.y(), _front.z());
 				break;
 			default:
 				break;
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 99b0e25b939..d0dc7902231 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -146,6 +146,8 @@ public:
 
 	virtual void draw2DText(const Common::String &text, const Common::Point &position) = 0;
 
+	virtual void renderCube(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) = 0;
+	virtual void drawFace(const Math::Vector3d &position, float xs, float ys, float zs, uint8 color) = 0;
 
 	/** Render a Drawable in the specified window */
 	void renderDrawable(Drawable *drawable, Window *window);
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 752d2d05fae..39d952b4d7c 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -137,7 +137,7 @@ void TinyGLRenderer::selectTargetWindow(Window *window, bool is3D, bool scaled)
 
 void TinyGLRenderer::drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint8 g, uint8 b) {	
 	tglDisable(TGL_TEXTURE_2D);
-	tglColor4f(r / 255.0, g / 255.0, b / 255.0, a);
+	tglColor3ub(r, g, b);
 
 	if (a != 255) {
 		tglEnable(TGL_BLEND);
@@ -225,6 +225,35 @@ void TinyGLRenderer::draw2DText(const Common::String &text, const Common::Point
 	tglDepthMask(TGL_TRUE);
 }
 
+void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector3d &size, Common::Array<uint8> *colours) {
+	debug("Rendering cube at %f, %f, %f", origin.x(), origin.y(), origin.z());
+	debug("with size %f, %f, %f", size.x(), size.y(), size.z());
+	drawFace(origin, size.x(), size.y(), 0, (*colours)[0]);
+}
+
+void TinyGLRenderer::drawFace(const Math::Vector3d &origin, float xs, float ys, float zs, uint8 color) {
+	debug("Face at %f, %f, %f", origin.x(), origin.y(), origin.z());
+	debug("with size %f, %f, %f", xs, ys, zs);
+	assert(_palette);
+	uint8 r, g, b;
+	_palette->getRGBAt(color, r, g, b);
+	debug("with colour %d (%d, %d, %d)", color, r, g, b);
+	tglBegin(TGL_TRIANGLES);
+	tglColor3ub(r, g, b);
+
+	// First triangle
+	tglVertex3f(origin.x(), origin.y(), origin.z());
+	tglVertex3f(origin.x() + xs, origin.y(), origin.z());
+	tglVertex3f(origin.x() + xs, origin.y() - ys, origin.z());
+
+	// Second triangle
+	tglVertex3f(origin.x(), origin.y(), origin.z());
+	tglVertex3f(origin.x(), origin.y() - ys, origin.z());
+	tglVertex3f(origin.x() + xs, origin.y() - ys, origin.z());
+
+	tglEnd();
+}
+
 void TinyGLRenderer::flipBuffer() {
 	TinyGL::tglPresentBuffer();
 	g_system->copyRectToScreen(_fb->getPixelBuffer(), _fb->linesize,
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index 7b78cc22e51..c979c080f82 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -48,11 +48,12 @@ public:
 	virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture,
 	                                float transparency = -1.0, bool additiveBlending = false) override;
 	virtual void draw2DText(const Common::String &text, const Common::Point &position) override;
+	virtual void renderCube(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) override;
 
 	virtual void flipBuffer() override;
-private:
-	void drawFace(uint face, Texture *texture);
+	virtual void drawFace(const Math::Vector3d &position, float xs, float ys, float zs, uint8 color) override;
 
+private:
 	TinyGL::FrameBuffer *_fb;
 };
 
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index 14049c8a803..9956aeb4178 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -98,3 +98,10 @@ bool GeometricObject::isPlanar() {
 	Type type = this->getType();
 	return (type >= Object::Line) || !size.x() || !size.y() || !size.z();
 }
+
+void GeometricObject::draw(Freescape::Renderer *gfx) {
+	if (this->getType() == Cube) {
+		gfx->renderCube(origin, size, colours);
+	}
+		
+};
\ No newline at end of file
diff --git a/engines/freescape/objects/geometricobject.h b/engines/freescape/objects/geometricobject.h
index b4d73e4d9ff..0ab60a6b498 100644
--- a/engines/freescape/objects/geometricobject.h
+++ b/engines/freescape/objects/geometricobject.h
@@ -35,8 +35,8 @@ public:
 		FCLInstructionVector condition);
 	virtual ~GeometricObject();
 
-	/*void setupOpenGL(VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer);
-		void draw(VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer, BatchDrawer *areaBatchDrawer, bool allowPolygonOffset);*/
+	/*void setupOpenGL(VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer);*/
+	void draw(Freescape::Renderer *gfx) override;
 	bool isDrawable();
 	bool isPlanar();
 


Commit: 8bdfd73559cb9a014e07d4dd2b92fb4f7a78da79
    https://github.com/scummvm/scummvm/commit/8bdfd73559cb9a014e07d4dd2b92fb4f7a78da79
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:39+01:00

Commit Message:
FREESCAPE: refactoring detection code and first attempt to render cubes

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/detection.cpp
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/gfx.cpp
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/gfx_tinygl.h


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 931cc57044d..0e20280f8ce 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -92,34 +92,30 @@ Area::~Area() {
 }*/
 
 void Area::draw(Freescape::Renderer *gfx) {
-	Graphics::PixelBuffer *palette;
-	if (gfx->_palette)
-		palette = gfx->_palette;
-	else if (raw_palette) {
-		palette = new Graphics::PixelBuffer(gfx->_palettePixelFormat, 16, DisposeAfterUse::NO); 
-		*palette = raw_palette->data();
-	}
+	// Graphics::PixelBuffer *palette;
+	// if (gfx->_palette)
+	// 	palette = gfx->_palette;
+	// else if (raw_palette) {
+	// 	palette = new Graphics::PixelBuffer(gfx->_palettePixelFormat, 16, DisposeAfterUse::NO); 
+	// 	*palette = raw_palette->data();
+	// }
+
+	//gfx->selectTargetWindow(nullptr, false, true);
+	// debug("w: %d, h: %d", gfx->kOriginalWidth, gfx->kOriginalHeight);
+	// //Common::Rect view(20, 30, 305, 110);
+	// Common::Rect view = gfx->rviewport();
+	// Common::Rect sky(view.left, view.top, view.right, view.bottom-view.height()/2);
+	//debug("color: %d %x%x%x", skyColor, g, b);
+	gfx->drawSky(skyColor);
 
-	gfx->selectTargetWindow(nullptr, false, true);
-	debug("w: %d, h: %d", gfx->kOriginalWidth, gfx->kOriginalHeight);
-	//Common::Rect view(20, 30, 305, 110);
-	Common::Rect view = gfx->rviewport();
-	Common::Rect sky(view.left, view.top, view.right, view.bottom-view.height()/2);
-	uint8 r, g, b;
-	palette->getRGBAt(skyColor, r, g, b);
-	debug("color: %d %x%x%x", skyColor, g, b);
-	gfx->drawRect2D(sky, 255, r, g, b);
 
+	// Common::Rect ground(view.left, view.top+view.height()/2, view.right, view.bottom);
+	// palette->getRGBAt(groundColor, r, g, b);
+	// debug("color: %d %x%x%x", groundColor, g, b);
+	// gfx->drawRect2D(ground, 255, r, g, b);
 
-	Common::Rect ground(view.left, view.top+view.height()/2, view.right, view.bottom);
-	palette->getRGBAt(groundColor, r, g, b);
-	debug("color: %d %x%x%x", groundColor, g, b);
-	gfx->drawRect2D(ground, 255, r, g, b);
 
-	//gfx->drawTriange(); // I have no idea why?
 	for (Common::Array<Object *>::iterator iterator = drawableObjects.begin(); iterator != drawableObjects.end(); iterator++) {
 		(*iterator)->draw(gfx);
 	}
-	gfx->flipBuffer();
-	g_system->updateScreen();
 }
diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index 664f2786466..0057cccaf9d 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -25,7 +25,7 @@ static const ADGameDescription gameDescriptions[] = {
 	 ADGF_NO_FLAGS,
 	 GUIO1(GUIO_NOMIDI)},
 
-	{"3Dkit",
+	{"3dkit",
 	 "One cube in scene",
 	 AD_ENTRY1s("CUBE.RUN", "3b7930be0f646b98885cfb70c26c89a2", 66138),
 	 Common::EN_ANY,
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index ab0a184339e..742ec4194cf 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -36,10 +36,10 @@ FreescapeEngine::FreescapeEngine(OSystem *syst)
 	_hasReceivedTime = false;
 
 	_rotation = Vector3d(0.f, 0.f, 0.f);
-	_position = Vector3d(1000.0f, 0.0f, 1000.0f);
+	_position = Vector3d(4000.f, 30.f, 4000.f);
 	_velocity = Vector3d(0.0f, 0.0f, 0.0f);
-	_front = Vector3d(0.0f, 0.0f, 0.0f);
-	_right = Vector3d(0.0f, 0.0f, 0.0f);
+	_cameraFront = Vector3d(0.0f, 0.0f, 0.0f);
+	_cameraRight = Vector3d(0.0f, 0.0f, 0.0f);
 
 	_yaw = 90.0f;
 	_pitch = 0.0f;
@@ -146,15 +146,32 @@ Common::Error FreescapeEngine::run() {
 		area = (*_areasByAreaID)[_startArea];
 		assert(area);
 		//_gfx->renderPalette(area->raw_palette, binary.ncolors);
-		drawBorder();
+		//drawBorder();
 	}	
 	debug("FreescapeEngine::init");
 	// Simple main event loop
 	Common::Event event;
 	Common::Point lastMousePos(0, 0);
 	float lastFrame = 0.f;
+	float nearClipPlane = 1.f;
+	float farClipPlane;
+
+	if (_binaryBits == 16) {
+		// create a projection matrix; the 16-bit kit permits the range 0-8192 to
+		// be used along all three axes and from that comes the far plane distance
+		// of 14189.
+		farClipPlane = 14189.0f;
+	} else {
+		error("Unknown farClipPlane");
+	}
+
+	g_system->lockMouse(true);
 
 	while (!shouldQuit()) {
+		_gfx->updateProjectionMatrix(40.0, nearClipPlane, farClipPlane);
+		_gfx->positionCamera(_position, _position + _cameraFront);
+		//_gfx->selectTargetWindow(nullptr, true, false);
+		//_gfx->updateMatrices();
 		area->draw(_gfx);
         float currentFrame = g_system->getMillis();
         float deltaTime = currentFrame - lastFrame;
@@ -193,6 +210,8 @@ Common::Error FreescapeEngine::run() {
 			}
 		}
 
+		_gfx->flipBuffer();
+		g_system->updateScreen();
 		g_system->delayMillis(10);
 	}
 
@@ -211,10 +230,10 @@ void FreescapeEngine::rotate(Common::Point lastMousePos, Common::Point mousePos)
 	_pitch += yoffset;
 
 	// Make sure that when pitch is out of bounds, screen doesn't get flipped
-	if (_pitch > 89.0f)
-		_pitch = 89.0f;
-	if (_pitch < -89.0f)
-		_pitch = -89.0f;
+	if (_pitch > 180.0f)
+		_pitch = 180.0f;
+	if (_pitch < -180.0f)
+		_pitch = -180.0f;
 
 	Vector3d v;
 	float x = cos(_yaw  * M_PI / 180.0) * cos(_pitch  * M_PI / 180.0);
@@ -222,34 +241,34 @@ void FreescapeEngine::rotate(Common::Point lastMousePos, Common::Point mousePos)
 	float z = sin(_yaw * M_PI / 180.0) * cos(_pitch * M_PI / 180.0);
 	v.set(x, y, z);
 	v.normalize();
-	_front = v;
+	_cameraFront = v;
 
-	// _right = _front x _up;
+	// // _right = _front x _up;
 	Vector3d up(0, 1, 0); // this should be const
-	v = Math::Vector3d::crossProduct(_front, up);
+	v = Math::Vector3d::crossProduct(_cameraFront, up);
 	v.normalize();
-	_right = v;
+	_cameraRight = v;
 }
 
 void FreescapeEngine::move(CameraMovement direction, float deltaTime) {
 	float velocity = _movementSpeed * deltaTime;
 	switch (direction) {
 	case FORWARD:
-		_position = _position + _front * velocity;
+		_position = _position + _cameraFront * velocity;
 		break;
 	case BACKWARD:
-		_position = _position - _front * velocity;
+		_position = _position - _cameraFront * velocity;
 		break;
 	case RIGHT:
-		_position = _position + _right * velocity;
+		_position = _position + _cameraRight * velocity;
 		break;
 	case LEFT:
-		_position = _position - _right * velocity;
+		_position = _position - _cameraRight * velocity;
 		break;
 	}
 	// Make sure the user stays at the ground level
 	// this one-liner keeps the user at the ground level (xz plane)
-	_position.set(_position.x(), 0, _position.z());
+	_position.set(_position.x(), 60., _position.z());
 }
 
 bool FreescapeEngine::hasFeature(EngineFeature f) const {
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 8a4ea8d1769..4f1fe5e1046 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -86,7 +86,8 @@ public:
 	// Camera options
 	float _mouseSensitivity;
 	float _movementSpeed;
-	Vector3d _front, _right;
+	Vector3d _cameraFront, _cameraUp, _cameraRight;
+	// Spacial attributes
 	Vector3d _position, _rotation, _velocity;
 
 
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index 1a2ba45ffb7..ab79b61045b 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -69,39 +69,6 @@ Graphics::Surface *Renderer::convertFromPalette(Graphics::PixelBuffer *rawsurf)
 	return surf;
 }
 
-
-void Renderer::renderPalette(Common::Array<uint8> *raw_palette, uint16 ncolors) {
-	Graphics::PixelBuffer *palette;
-	if (_palette)
-		palette = _palette;
-	else if (raw_palette) {
-		palette = new Graphics::PixelBuffer(_palettePixelFormat, 16, DisposeAfterUse::NO); 
-		*palette = raw_palette->data();
-	} else 
-		error("No palette to show");
-
-	selectTargetWindow(nullptr, false, true);
-	Common::Rect view = viewport();
-	uint8 r, g, b;
-	uint16 c;
-	uint16 top = view.top;
-	uint16 size = kOriginalHeight/ncolors; 
-	uint16 bottom = size;
-
-	for (c = 0; c < ncolors; c++) {
-		view = Common::Rect(view.left, top, view.right, bottom);
-		palette->getRGBAt(c, r, g, b);
-		debug("color: %d %x %x %x", c, r, g, b);
-		drawRect2D(view, 255, r, g, b);
-		bottom = bottom + size;
-		top = top + size;
-	}
-
-	flipBuffer();
-	g_system->updateScreen();
-
-}
-
 Common::Rect Renderer::getFontCharacterRect(uint8 character) {
 	uint index = 0;
 
@@ -153,34 +120,6 @@ void Renderer::computeScreenViewport() {
 	//}
 }
 
-Math::Matrix4 Renderer::makeProjectionMatrix(float fov) const {
-	static const float nearClipPlane = 1.0;
-	static const float farClipPlane = 10000.0;
-
-	float aspectRatio = kOriginalWidth / (float) kFrameHeight;
-
-	float xmaxValue = nearClipPlane * tan(fov * M_PI / 360.0);
-	float ymaxValue = xmaxValue / aspectRatio;
-
-	return Math::makeFrustumMatrix(-xmaxValue, xmaxValue, -ymaxValue, ymaxValue, nearClipPlane, farClipPlane);
-}
-
-void Renderer::setupCameraPerspective(float pitch, float heading, float fov) {
-	_projectionMatrix = makeProjectionMatrix(fov);
-	_modelViewMatrix = Math::Matrix4(180.0f - heading, pitch, 0.0f, Math::EO_YXZ);
-
-	Math::Matrix4 proj = _projectionMatrix;
-	Math::Matrix4 model = _modelViewMatrix;
-	proj.transpose();
-	model.transpose();
-
-	_mvpMatrix = proj * model;
-
-	_frustum.setup(_mvpMatrix);
-
-	_mvpMatrix.transpose();
-}
-
 Renderer *createRenderer(OSystem *system) {
 	Common::String rendererConfig = ConfMan.get("renderer");
 	Graphics::PixelFormat pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
@@ -232,22 +171,22 @@ Renderer *createRenderer(OSystem *system) {
 }
 
 void Renderer::renderDrawable(Drawable *drawable, Window *window) {
-	if (drawable->isConstrainedToWindow()) {
-		selectTargetWindow(window, drawable->is3D(), drawable->isScaled());
-	} else {
-		selectTargetWindow(nullptr, drawable->is3D(), drawable->isScaled());
-	}
-	drawable->draw();
+	// if (drawable->isConstrainedToWindow()) {
+	// 	selectTargetWindow(window, drawable->is3D(), drawable->isScaled());
+	// } else {
+	// 	selectTargetWindow(nullptr, drawable->is3D(), drawable->isScaled());
+	// }
+	// drawable->draw();
 }
 
 void Renderer::renderDrawableOverlay(Drawable *drawable, Window *window) {
-	// Overlays are always 2D
-	if (drawable->isConstrainedToWindow()) {
-		selectTargetWindow(window, drawable->is3D(), drawable->isScaled());
-	} else {
-		selectTargetWindow(nullptr, drawable->is3D(), drawable->isScaled());
-	}
-	drawable->drawOverlay();
+	// // Overlays are always 2D
+	// if (drawable->isConstrainedToWindow()) {
+	// 	selectTargetWindow(window, drawable->is3D(), drawable->isScaled());
+	// } else {
+	// 	selectTargetWindow(nullptr, drawable->is3D(), drawable->isScaled());
+	// }
+	// drawable->drawOverlay();
 }
 
 void Renderer::renderWindow(Window *window) {
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index d0dc7902231..cf0999e649e 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -121,11 +121,6 @@ public:
 	Graphics::Surface *convertFromPalette(Graphics::PixelBuffer *rawsurf);
 
 
-    /**
-	 *   Show palette on screen
-     */
-	void renderPalette(Common::Array<uint8> *raw_palette, uint16 ncolors);
-
 	virtual void init() = 0;
 	virtual void clear() = 0;
 
@@ -147,7 +142,7 @@ public:
 	virtual void draw2DText(const Common::String &text, const Common::Point &position) = 0;
 
 	virtual void renderCube(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) = 0;
-	virtual void drawFace(const Math::Vector3d &position, float xs, float ys, float zs, uint8 color) = 0;
+	virtual void drawSky(uint8 color) = 0;
 
 	/** Render a Drawable in the specified window */
 	void renderDrawable(Drawable *drawable, Window *window);
@@ -170,11 +165,9 @@ public:
 	 *
 	 * This also sets the viewport
 	 */
-	virtual void selectTargetWindow(Window *window, bool is3D, bool scaled) = 0;
 
-	void setupCameraPerspective(float pitch, float heading, float fov);
-
-	bool isCubeFaceVisible(uint face);
+	virtual void positionCamera(const Math::Vector3d &pos, const Math::Vector3d &interest) = 0;
+	virtual void updateProjectionMatrix(float fov, float nearClipPlane, float farClipPlane) = 0;
 
 	Math::Matrix4 getMvpMatrix() const { return _mvpMatrix; }
 
@@ -204,8 +197,7 @@ protected:
 	Math::AABB _cubeFacesAABB[6];
 
 	Common::Rect getFontCharacterRect(uint8 character);
-
-	Math::Matrix4 makeProjectionMatrix(float fov) const;
+	Math::Matrix4 makeProjectionMatrix(float fov, float nearClipPlane, float farClipPlane) const;
 };
 
 /**
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 39d952b4d7c..657df950456 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -74,7 +74,7 @@ void TinyGLRenderer::init() {
 	tglLoadIdentity();
 
 	tglDisable(TGL_LIGHTING);
-	tglEnable(TGL_TEXTURE_2D);
+	tglDisable(TGL_TEXTURE_2D);
 	tglEnable(TGL_DEPTH_TEST);
 }
 
@@ -83,58 +83,6 @@ void TinyGLRenderer::clear() {
 	tglColor3f(1.0f, 1.0f, 1.0f);
 }
 
-void TinyGLRenderer::selectTargetWindow(Window *window, bool is3D, bool scaled) {
-	// NOTE: tinyGL viewport implementation needs to be checked as it doesn't behave the same as openGL
-
-	if (!window) {
-		// No window found ...
-		if (scaled) {
-			// ... in scaled mode draw in the original game screen area
-			Common::Rect vp = viewport();
-			tglViewport(vp.left, vp.top, vp.width(), vp.height());
-			//tglViewport(vp.left, _system->getHeight() - vp.top - vp.height(), vp.width(), vp.height());
-		} else {
-			// ... otherwise, draw on the whole screen
-			tglViewport(0, 0, _system->getWidth(), _system->getHeight());
-		}
-	} else {
-		// Found a window, draw inside it
-		Common::Rect vp = window->getPosition();
-		tglViewport(vp.left, vp.top, vp.width(), vp.height());
-		//tglViewport(vp.left, _system->getHeight() - vp.top - vp.height(), vp.width(), vp.height());
-	}
-
-	if (is3D) {
-		tglMatrixMode(TGL_PROJECTION);
-		tglLoadMatrixf(_projectionMatrix.getData());
-
-		tglMatrixMode(TGL_MODELVIEW);
-		tglLoadMatrixf(_modelViewMatrix.getData());
-	} else {
-		tglMatrixMode(TGL_PROJECTION);
-		tglLoadIdentity();
-
-		if (!window) {
-			if (scaled) {
-				tglOrtho(0.0, kOriginalWidth, kOriginalHeight, 0.0, -1.0, 1.0);
-			} else {
-				tglOrtho(0.0, _system->getWidth(), _system->getHeight(), 0.0, -1.0, 1.0);
-			}
-		} else {
-			if (scaled) {
-				Common::Rect originalRect = window->getOriginalPosition();
-				tglOrtho(0.0, originalRect.width(), originalRect.height(), 0.0, -1.0, 1.0);
-			} else {
-				Common::Rect vp = window->getPosition();
-				tglOrtho(0.0, vp.width(), vp.height(), 0.0, -1.0, 1.0);
-			}
-		}
-
-		tglMatrixMode(TGL_MODELVIEW);
-		tglLoadIdentity();
-	}
-}
-
 void TinyGLRenderer::drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint8 g, uint8 b) {	
 	tglDisable(TGL_TEXTURE_2D);
 	tglColor3ub(r, g, b);
@@ -225,35 +173,121 @@ void TinyGLRenderer::draw2DText(const Common::String &text, const Common::Point
 	tglDepthMask(TGL_TRUE);
 }
 
-void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector3d &size, Common::Array<uint8> *colours) {
-	debug("Rendering cube at %f, %f, %f", origin.x(), origin.y(), origin.z());
-	debug("with size %f, %f, %f", size.x(), size.y(), size.z());
-	drawFace(origin, size.x(), size.y(), 0, (*colours)[0]);
+void TinyGLRenderer::updateProjectionMatrix(float fov, float nearClipPlane, float farClipPlane) {
+	tglMatrixMode(TGL_PROJECTION);
+	tglLoadIdentity();
+
+	float aspectRatio = kOriginalWidth / (float) kFrameHeight;
+
+	float xmaxValue = nearClipPlane * tan(fov * M_PI / 360.0);
+	float ymaxValue = xmaxValue / aspectRatio;
+	//debug("max values: %f %f", xmaxValue, ymaxValue);
+
+	tglFrustum(-xmaxValue, xmaxValue, -ymaxValue, ymaxValue, nearClipPlane, farClipPlane);
+	tglMatrixMode(TGL_MODELVIEW);
+	tglLoadIdentity();
 }
 
-void TinyGLRenderer::drawFace(const Math::Vector3d &origin, float xs, float ys, float zs, uint8 color) {
-	debug("Face at %f, %f, %f", origin.x(), origin.y(), origin.z());
-	debug("with size %f, %f, %f", xs, ys, zs);
-	assert(_palette);
+void TinyGLRenderer::positionCamera(const Math::Vector3d &pos, const Math::Vector3d &interest) {
+	Math::Vector3d up_vec(0, 1, 0);
+	Math::Matrix4 lookMatrix = Math::makeLookAtMatrix(pos, interest, up_vec);
+
+	tglMultMatrixf(lookMatrix.getData());
+	tglTranslatef(-pos.x(), -pos.y(), -pos.z());
+}
+
+void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector3d &size, Common::Array<uint8> *colours) {
+	//debug("Rendering cube at %f, %f, %f", origin.x(), origin.y(), origin.z());
+	//debug("with size %f, %f, %f", size.x(), size.y(), size.z());
 	uint8 r, g, b;
-	_palette->getRGBAt(color, r, g, b);
-	debug("with colour %d (%d, %d, %d)", color, r, g, b);
+
+	_palette->getRGBAt((*colours)[0], r, g, b);
+	tglDisable(TGL_TEXTURE_2D);
+	tglColor3ub(r, g, b);
+	// Face 0
+	tglBegin(TGL_TRIANGLES);
+	tglVertex3f(origin.x(),		        origin.y(),				origin.z() + size.z());
+	tglVertex3f(origin.x() + size.x(),	origin.y(),				origin.z() + size.z());
+	tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z() + size.z());
+
+	tglVertex3f(origin.x(),		        origin.y(),				origin.z() + size.z());
+	tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z() + size.z());
+	tglVertex3f(origin.x(),		        origin.y() + size.y(),	origin.z() + size.z());
+	tglEnd();
+
+	// Face 1
+	_palette->getRGBAt((*colours)[1], r, g, b);
+	tglColor3ub(r, g, b);
+
+	tglBegin(TGL_TRIANGLES);
+	tglVertex3f(origin.x(),				origin.y() + size.y(),	origin.z());
+	tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z());
+	tglVertex3f(origin.x() + size.x(),	origin.y(),				origin.z());
+
+	tglVertex3f(origin.x(),				origin.y() + size.y(),	origin.z());
+	tglVertex3f(origin.x() + size.x(),	origin.y(),				origin.z());
+	tglVertex3f(origin.x(),				origin.y(),				origin.z());
+	tglEnd();
+
+	// Face 2
+	_palette->getRGBAt((*colours)[2], r, g, b);
+	tglColor3ub(r, g, b);
+
+	tglBegin(TGL_TRIANGLES);
+	tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z());
+	tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z() + size.z());
+	tglVertex3f(origin.x() + size.x(),	origin.y(),				origin.z() + size.z());
+
+	tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z());
+	tglVertex3f(origin.x() + size.x(),	origin.y(),				origin.z() + size.z());
+	tglVertex3f(origin.x() + size.x(),	origin.y(),				origin.z());
+	tglEnd();
+
+	// Face 3
+	_palette->getRGBAt((*colours)[3], r, g, b);
+	tglColor3ub(r, g, b);
 	tglBegin(TGL_TRIANGLES);
+	tglVertex3f(origin.x(),	origin.y(),				origin.z());
+	tglVertex3f(origin.x(),	origin.y(),				origin.z() + size.z());
+	tglVertex3f(origin.x(),	origin.y() + size.y(),	origin.z() + size.z());
+
+	tglVertex3f(origin.x(),	origin.y(),				origin.z());
+	tglVertex3f(origin.x(),	origin.y() + size.y(),	origin.z() + size.z());
+	tglVertex3f(origin.x(),	origin.y() + size.y(),	origin.z());
+	tglEnd();
+
+	_palette->getRGBAt((*colours)[4], r, g, b);
 	tglColor3ub(r, g, b);
+	tglBegin(TGL_TRIANGLES);
+	tglVertex3f(origin.x() + size.x(),	origin.y(),	origin.z());
+	tglVertex3f(origin.x() + size.x(),	origin.y(),	origin.z() + size.z());
+	tglVertex3f(origin.x(),			origin.y(),		origin.z() + size.z());
 
-	// First triangle
-	tglVertex3f(origin.x(), origin.y(), origin.z());
-	tglVertex3f(origin.x() + xs, origin.y(), origin.z());
-	tglVertex3f(origin.x() + xs, origin.y() - ys, origin.z());
+	tglVertex3f(origin.x() + size.x(),	origin.y(),	origin.z());
+	tglVertex3f(origin.x(),			origin.y(),		origin.z() + size.z());
+	tglVertex3f(origin.x(),			origin.y(),		origin.z());
+	tglEnd();
 
-	// Second triangle
-	tglVertex3f(origin.x(), origin.y(), origin.z());
-	tglVertex3f(origin.x(), origin.y() - ys, origin.z());
-	tglVertex3f(origin.x() + xs, origin.y() - ys, origin.z());
+	_palette->getRGBAt((*colours)[5], r, g, b);
+	tglColor3ub(r, g, b);
+	tglBegin(TGL_TRIANGLES);
+	tglVertex3f(origin.x(),				origin.y() + size.y(),	origin.z());
+	tglVertex3f(origin.x(),				origin.y() + size.y(),	origin.z() + size.z());
+	tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z() + size.z());
 
+	tglVertex3f(origin.x(),				origin.y() + size.y(),	origin.z());
+	tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z() + size.z());
+	tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z());
 	tglEnd();
 }
 
+void TinyGLRenderer::drawSky(uint8 color) {
+	uint8 r, g, b;
+	_palette->getRGBAt(color, r, g, b);
+	tglClearColor(r / 255., g / 255., b / 255., 1.0);
+	tglClear(TGL_COLOR_BUFFER_BIT | TGL_DEPTH_BUFFER_BIT);
+}
+
 void TinyGLRenderer::flipBuffer() {
 	TinyGL::tglPresentBuffer();
 	g_system->copyRectToScreen(_fb->getPixelBuffer(), _fb->linesize,
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index c979c080f82..ed566deae87 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -39,7 +39,8 @@ public:
 
 	virtual void init() override;
 	virtual void clear() override;
-	virtual void selectTargetWindow(Window *window, bool is3D, bool scaled) override;
+	virtual void positionCamera(const Math::Vector3d &pos, const Math::Vector3d &interest) override;
+	virtual void updateProjectionMatrix(float fov, float nearClipPlane, float farClipPlane) override;
 
 	Texture *createTexture(const Graphics::Surface *surface) override;
 	void freeTexture(Texture *texture) override;
@@ -51,7 +52,7 @@ public:
 	virtual void renderCube(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) override;
 
 	virtual void flipBuffer() override;
-	virtual void drawFace(const Math::Vector3d &position, float xs, float ys, float zs, uint8 color) override;
+	virtual void drawSky(uint8 color) override;
 
 private:
 	TinyGL::FrameBuffer *_fb;


Commit: 829afc23255d93d19d963ba13b0e217367377d01
    https://github.com/scummvm/scummvm/commit/829afc23255d93d19d963ba13b0e217367377d01
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:39+01:00

Commit Message:
FREESCAPE: fixes

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/gfx_tinygl.h
    engines/freescape/loaders/16bitBinaryLoader.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/objects/entrance.h
    engines/freescape/objects/geometricobject.cpp
    engines/freescape/objects/geometricobject.h
    engines/freescape/objects/object.cpp
    engines/freescape/objects/object.h


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 0e20280f8ce..57fa2b335b5 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -92,30 +92,8 @@ Area::~Area() {
 }*/
 
 void Area::draw(Freescape::Renderer *gfx) {
-	// Graphics::PixelBuffer *palette;
-	// if (gfx->_palette)
-	// 	palette = gfx->_palette;
-	// else if (raw_palette) {
-	// 	palette = new Graphics::PixelBuffer(gfx->_palettePixelFormat, 16, DisposeAfterUse::NO); 
-	// 	*palette = raw_palette->data();
-	// }
-
-	//gfx->selectTargetWindow(nullptr, false, true);
-	// debug("w: %d, h: %d", gfx->kOriginalWidth, gfx->kOriginalHeight);
-	// //Common::Rect view(20, 30, 305, 110);
-	// Common::Rect view = gfx->rviewport();
-	// Common::Rect sky(view.left, view.top, view.right, view.bottom-view.height()/2);
-	//debug("color: %d %x%x%x", skyColor, g, b);
 	gfx->drawSky(skyColor);
-
-
-	// Common::Rect ground(view.left, view.top+view.height()/2, view.right, view.bottom);
-	// palette->getRGBAt(groundColor, r, g, b);
-	// debug("color: %d %x%x%x", groundColor, g, b);
-	// gfx->drawRect2D(ground, 255, r, g, b);
-
-
-	for (Common::Array<Object *>::iterator iterator = drawableObjects.begin(); iterator != drawableObjects.end(); iterator++) {
-		(*iterator)->draw(gfx);
+	for (Common::Array<Object *>::iterator it = drawableObjects.begin(); it != drawableObjects.end(); it++) {
+		(*it)->draw(gfx);
 	}
 }
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 742ec4194cf..68e1809c780 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -36,15 +36,15 @@ FreescapeEngine::FreescapeEngine(OSystem *syst)
 	_hasReceivedTime = false;
 
 	_rotation = Vector3d(0.f, 0.f, 0.f);
-	_position = Vector3d(4000.f, 30.f, 4000.f);
-	_velocity = Vector3d(0.0f, 0.0f, 0.0f);
-	_cameraFront = Vector3d(0.0f, 0.0f, 0.0f);
-	_cameraRight = Vector3d(0.0f, 0.0f, 0.0f);
+	_position = Vector3d(0.f, 0.f, 0.f);
+	_velocity = Vector3d(0.f, 0.f, 0.f);
+	_cameraFront = Vector3d(0.f, 0.f, 0.f);
+	_cameraRight = Vector3d(0.f, 0.f, 0.f);
 
-	_yaw = 90.0f;
+	_yaw = -90.0f;
 	_pitch = 0.0f;
 	_movementSpeed = 4.5f;
-	_mouseSensitivity = 0.05f;
+	_mouseSensitivity = 0.1f;
 
 	// Here is the right place to set up the engine specific debug channels
 	DebugMan.addDebugChannel(kFreescapeDebug, "example", "this is just an example for a engine specific debug channel");
@@ -139,15 +139,19 @@ Common::Error FreescapeEngine::run() {
 	_gfx->clear();
 	loadAssets();
 	Area *area = nullptr;
+	Entrance *entrance = nullptr;
 	if (_areasByAreaID) {
-		_startArea = 1; //binary.startArea;
-
+		if (_startArea == 14)
+			_startArea = 1;
 		assert(_areasByAreaID->contains(_startArea));
 		area = (*_areasByAreaID)[_startArea];
 		assert(area);
+		entrance = (Entrance*) area->entranceWithID(_startEntrance);
+		assert(entrance);
+		_position = entrance->getOrigin();
 		//_gfx->renderPalette(area->raw_palette, binary.ncolors);
 		//drawBorder();
-	}	
+	}
 	debug("FreescapeEngine::init");
 	// Simple main event loop
 	Common::Event event;
@@ -170,6 +174,7 @@ Common::Error FreescapeEngine::run() {
 	while (!shouldQuit()) {
 		_gfx->updateProjectionMatrix(40.0, nearClipPlane, farClipPlane);
 		_gfx->positionCamera(_position, _position + _cameraFront);
+		_gfx->scale(_scale);
 		//_gfx->selectTargetWindow(nullptr, true, false);
 		//_gfx->updateMatrices();
 		area->draw(_gfx);
@@ -213,6 +218,7 @@ Common::Error FreescapeEngine::run() {
 		_gfx->flipBuffer();
 		g_system->updateScreen();
 		g_system->delayMillis(10);
+		//g_system->warpMouse(_screenH/2, _screenW/2);
 	}
 
 	return Common::kNoError;
@@ -220,6 +226,7 @@ Common::Error FreescapeEngine::run() {
 
 
 void FreescapeEngine::rotate(Common::Point lastMousePos, Common::Point mousePos) {
+	//debug("x: %d, y: %d", mousePos.x, mousePos.y);
 	float xoffset = mousePos.x - lastMousePos.x;
 	float yoffset = mousePos.y - lastMousePos.y;
 
@@ -230,10 +237,10 @@ void FreescapeEngine::rotate(Common::Point lastMousePos, Common::Point mousePos)
 	_pitch += yoffset;
 
 	// Make sure that when pitch is out of bounds, screen doesn't get flipped
-	if (_pitch > 180.0f)
-		_pitch = 180.0f;
-	if (_pitch < -180.0f)
-		_pitch = -180.0f;
+	if (_pitch > 89.0f)
+		_pitch = 89.0f;
+	if (_pitch < -89.0f)
+		_pitch = -89.0f;
 
 	Vector3d v;
 	float x = cos(_yaw  * M_PI / 180.0) * cos(_pitch  * M_PI / 180.0);
@@ -268,7 +275,7 @@ void FreescapeEngine::move(CameraMovement direction, float deltaTime) {
 	}
 	// Make sure the user stays at the ground level
 	// this one-liner keeps the user at the ground level (xz plane)
-	_position.set(_position.x(), 60., _position.z());
+	_position.set(_position.x(), _playerHeight, _position.z());
 }
 
 bool FreescapeEngine::hasFeature(EngineFeature f) const {
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 4f1fe5e1046..9527d878d50 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -10,6 +10,7 @@
 #include "gui/debugger.h"
 
 #include "freescape/area.h"
+#include "freescape/objects/entrance.h"
 #include "freescape/gfx.h"
 
 namespace Freescape {
@@ -69,13 +70,17 @@ public:
 	void loadAssets();
 	void load16bitBinary(Common::SeekableReadStream *file);
 	void load8bitBinary(Common::SeekableReadStream *file, int offset, int ncolors);
-
 	uint8 _binaryBits;
 
+	// Player
+	uint16 _playerHeight;
+
 	// Areas
 	uint16 _startArea;
 	AreaMap *_areasByAreaID;
-
+	Math::Vector3d _scale;
+	// Entrance
+	uint16 _startEntrance;
 
 	// Movement
 	void move(CameraMovement direction, float deltaTime);
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index cf0999e649e..8ba3a0f7e96 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -140,7 +140,7 @@ public:
 									float transparency = -1.0, bool additiveBlending = false) = 0;
 
 	virtual void draw2DText(const Common::String &text, const Common::Point &position) = 0;
-
+	virtual void scale(const Math::Vector3d &scale) = 0;
 	virtual void renderCube(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) = 0;
 	virtual void drawSky(uint8 color) = 0;
 
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 657df950456..b1bc8c783d6 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -173,6 +173,11 @@ void TinyGLRenderer::draw2DText(const Common::String &text, const Common::Point
 	tglDepthMask(TGL_TRUE);
 }
 
+void TinyGLRenderer::scale(const Math::Vector3d &scale) {
+	//tglScalef(-scale.x() / 256.f, scale.y() / 256.f, scale.z() / 256.f);
+}
+
+
 void TinyGLRenderer::updateProjectionMatrix(float fov, float nearClipPlane, float farClipPlane) {
 	tglMatrixMode(TGL_PROJECTION);
 	tglLoadIdentity();
@@ -201,7 +206,7 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 	//debug("with size %f, %f, %f", size.x(), size.y(), size.z());
 	uint8 r, g, b;
 
-	_palette->getRGBAt((*colours)[0], r, g, b);
+	_palette->getRGBAt((*colours)[5], r, g, b);
 	tglDisable(TGL_TEXTURE_2D);
 	tglColor3ub(r, g, b);
 	// Face 0
@@ -216,7 +221,7 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 	tglEnd();
 
 	// Face 1
-	_palette->getRGBAt((*colours)[1], r, g, b);
+	_palette->getRGBAt((*colours)[4], r, g, b);
 	tglColor3ub(r, g, b);
 
 	tglBegin(TGL_TRIANGLES);
@@ -230,7 +235,7 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 	tglEnd();
 
 	// Face 2
-	_palette->getRGBAt((*colours)[2], r, g, b);
+	_palette->getRGBAt((*colours)[0], r, g, b);
 	tglColor3ub(r, g, b);
 
 	tglBegin(TGL_TRIANGLES);
@@ -244,7 +249,7 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 	tglEnd();
 
 	// Face 3
-	_palette->getRGBAt((*colours)[3], r, g, b);
+	_palette->getRGBAt((*colours)[1], r, g, b);
 	tglColor3ub(r, g, b);
 	tglBegin(TGL_TRIANGLES);
 	tglVertex3f(origin.x(),	origin.y(),				origin.z());
@@ -256,7 +261,7 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 	tglVertex3f(origin.x(),	origin.y() + size.y(),	origin.z());
 	tglEnd();
 
-	_palette->getRGBAt((*colours)[4], r, g, b);
+	_palette->getRGBAt((*colours)[2], r, g, b);
 	tglColor3ub(r, g, b);
 	tglBegin(TGL_TRIANGLES);
 	tglVertex3f(origin.x() + size.x(),	origin.y(),	origin.z());
@@ -268,7 +273,7 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 	tglVertex3f(origin.x(),			origin.y(),		origin.z());
 	tglEnd();
 
-	_palette->getRGBAt((*colours)[5], r, g, b);
+	_palette->getRGBAt((*colours)[3], r, g, b);
 	tglColor3ub(r, g, b);
 	tglBegin(TGL_TRIANGLES);
 	tglVertex3f(origin.x(),				origin.y() + size.y(),	origin.z());
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index ed566deae87..710a2dd9a82 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -39,6 +39,7 @@ public:
 
 	virtual void init() override;
 	virtual void clear() override;
+	virtual void scale(const Math::Vector3d &scale) override;
 	virtual void positionCamera(const Math::Vector3d &pos, const Math::Vector3d &interest) override;
 	virtual void updateProjectionMatrix(float fov, float nearClipPlane, float farClipPlane) override;
 
diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
index 7195bb3704b..1fc0948ad8a 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/16bitBinaryLoader.cpp
@@ -28,7 +28,7 @@ typedef enum {
 		Border = 0x4524,
 } ChunkType;
 
-static Object *load16bitObject(StreamLoader &stream) {
+static Object *load16bitObject(StreamLoader &stream, uint8 groundColor) {
 	// get object flags and type
 	uint8 objectFlags = stream.get8();
 	Object::Type objectType = (Object::Type)stream.get8();
@@ -75,6 +75,8 @@ static Object *load16bitObject(StreamLoader &stream) {
 		Common::Array<uint8> *colours = new Common::Array<uint8>;
 		for (uint8 colour = 0; colour < numberOfColours; colour++) {
 			uint8 c = stream.get8();
+			if (objectID == 1)
+				c = groundColor;
 			debug("face %d color: %d", colour, c);
 			colours->push_back(c);
 			byteSizeOfObject--;
@@ -109,6 +111,7 @@ static Object *load16bitObject(StreamLoader &stream) {
 		return new GeometricObject(
 			objectType,
 			objectID,
+			objectFlags,
 			position,
 			size,
 			colours,
@@ -117,6 +120,8 @@ static Object *load16bitObject(StreamLoader &stream) {
 	} break;
 
 	case Object::Entrance:
+		return new Entrance(objectID, position, size); // size will be always 0,0,0?
+		break;
 	case Object::Sensor:
 	case Object::Group:
 		break;
@@ -206,7 +211,7 @@ Area *load16bitArea(StreamLoader &stream) {
 	// get the objects or whatever; entrances use a unique numbering
 	// system and have the high bit of their IDs set in the original file
 	for (uint16 object = 0; object < numberOfObjects; object++) {
-		Object *newObject = load16bitObject(stream);
+		Object *newObject = load16bitObject(stream, groundColor);
 
 		if (newObject) {
 			if (newObject->getType() == Object::Entrance) {
@@ -325,7 +330,7 @@ void FreescapeEngine::load16bitBinary(Common::SeekableReadStream *file) {
 	uint16 playerStep = streamLoader.get16();
 	uint16 playerAngle = streamLoader.get16();
 
-	debug("Height %d, step %d, angle %d)", playerHeight, playerStep, playerAngle);
+	debug("Height %d, step %d, angle %d", playerHeight, playerStep, playerAngle);
 
 	uint16 startVehicle = streamLoader.get16();
 	uint16 executeGlobalCondition = streamLoader.get16();
@@ -406,6 +411,8 @@ void FreescapeEngine::load16bitBinary(Common::SeekableReadStream *file) {
 		if (newArea) {
 			(*areaMap)[newArea->getAreaID()] = newArea;
 		}
+		//if (newArea->getAreaID() == startArea)
+		//	assert(0);
 	}
 	//load16bitInstrument(streamLoader);
 
@@ -476,9 +483,12 @@ void FreescapeEngine::load16bitBinary(Common::SeekableReadStream *file) {
 	}
 
 	delete[] fileOffsetForArea;
+	_playerHeight = playerHeight;
 	_startArea = startArea;
+	_startEntrance = startEntrance;
 	_colorNumber = colorNumber;
 	_areasByAreaID = areaMap;
+	_scale = Math::Vector3d(scaleX, scaleY, scaleZ);
 	_binaryBits = 16;
 	//return Binary{16, startArea, areaMap, raw_border, raw_palette, colorNumber};
 }
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 9ab9c5a5961..d7e8e2d8b67 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -84,6 +84,7 @@ static Object *load8bitObject(StreamLoader &stream) {
 		return new GeometricObject(
 			objectType,
 			objectID,
+			0, // flags
 			position,
 			v, // size
 			colours,
diff --git a/engines/freescape/objects/entrance.h b/engines/freescape/objects/entrance.h
index 2dc1b420f10..6c53246c6da 100644
--- a/engines/freescape/objects/entrance.h
+++ b/engines/freescape/objects/entrance.h
@@ -22,6 +22,8 @@ public:
 
 	bool isDrawable();
 	bool isPlanar();
+	Type getType() override { return Type::Entrance; };
+	void draw(Freescape::Renderer *gfx) override { error("cannot render Entrance"); };
 };
 
 
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index 9956aeb4178..0dd0ee00a90 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -73,12 +73,14 @@ int GeometricObject::numberOfOrdinatesForType(Type type) {
 GeometricObject::GeometricObject(
 	Type _type,
 	uint16 _objectID,
+	uint16 _flags,
 	const Vector3d &_origin,
 	const Vector3d &_size,
 	Common::Array<uint8> *_colours,
 	Common::Array<uint16> *_ordinates,
 	FCLInstructionVector _condition) {
 	type = _type;
+	flags = _flags;
 	objectID = _objectID;
 	origin = _origin;
 	size = _size;
diff --git a/engines/freescape/objects/geometricobject.h b/engines/freescape/objects/geometricobject.h
index 0ab60a6b498..0c33e3e4c74 100644
--- a/engines/freescape/objects/geometricobject.h
+++ b/engines/freescape/objects/geometricobject.h
@@ -28,6 +28,7 @@ public:
 	GeometricObject(
 		Type type,
 		uint16 objectID,
+		uint16 flags,
 		const Vector3d &origin,
 		const Vector3d &size,
 		Common::Array<uint8> *colours,
diff --git a/engines/freescape/objects/object.cpp b/engines/freescape/objects/object.cpp
index cbad577ca09..87d0eb631f7 100644
--- a/engines/freescape/objects/object.cpp
+++ b/engines/freescape/objects/object.cpp
@@ -12,13 +12,13 @@
 
 Object::Type Object::getType() { return type; }
 uint16 Object::getObjectID() { return objectID; }
-//Vector3d Object::getOrigin()	{	return origin;		}
-//Vector3d Object::getSize()		{	return size;		}
+uint16 Object::getObjectFlags() { return flags; }
+Vector3d Object::getOrigin() { return origin; }
+Vector3d Object::getSize() { return size; }
 
-//void Object::setupOpenGL(VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer)					{}
-void Object::draw(Freescape::Renderer *gfx /*VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer, BatchDrawer *batchDrawer, bool allowPolygonOffset*/) {
-	gfx;
-}
+//void Object::draw(Freescape::Renderer *gfx) {
+//	gfx;
+//}
 bool Object::isDrawable() { return false; }
 bool Object::isPlanar() { return false; }
 
diff --git a/engines/freescape/objects/object.h b/engines/freescape/objects/object.h
index 125207e0442..7b528875965 100644
--- a/engines/freescape/objects/object.h
+++ b/engines/freescape/objects/object.h
@@ -44,13 +44,13 @@ public:
 		Group = 15
 	} Type;
 
-	Type getType();
+	virtual Type getType();
 	uint16 getObjectID();
+	uint16 getObjectFlags();
 	Vector3d getOrigin();
 	Vector3d getSize();
 
-	//virtual void setupOpenGL(VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer);
-	virtual void draw(Freescape::Renderer *gfx);
+	virtual void draw(Freescape::Renderer *gfx) = 0;
 
 	virtual bool isDrawable();
 	virtual bool isPlanar();
@@ -58,16 +58,10 @@ public:
 	virtual ~Object();
 
 protected:
+	uint16 flags;
 	Type type;
 	uint16 objectID;
 	Vector3d origin, size, rotation;
 };
 
-/*
-#include "Entrance.h"
-#include "GeometricObject.h"
-#include "Group.h"
-#include "Sensor.h"
-*/
-
 #endif /* defined(__Phantasma__Object__) */


Commit: 359884615b3fa5e1dc61c7aec48c15c53f8e33b7
    https://github.com/scummvm/scummvm/commit/359884615b3fa5e1dc61c7aec48c15c53f8e33b7
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:39+01:00

Commit Message:
FREESCAPE: improved mouse look and some other fixes

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/gfx.cpp
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/gfx_tinygl.h
    engines/freescape/loaders/16bitBinaryLoader.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/objects/geometricobject.cpp
    engines/freescape/objects/geometricobject.h


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 57fa2b335b5..e2aaa0123e4 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -30,21 +30,25 @@ uint16 Area::getAreaID() {
 	return areaID;
 }
 
+uint8 Area::getScale() {
+	return scale;
+}
+
 Area::Area(
 	uint16 _areaID,
 	ObjectMap *_objectsByID,
 	ObjectMap *_entrancesByID,
+	uint8 _scale,
 	uint8 _skyColor,
 	uint8 _groundColor,
-	Common::Array<uint8> *_palette) {
-	raw_palette = _palette;
+	Graphics::PixelBuffer *_palette) {
+	scale = _scale;
+	palette = _palette;
 	skyColor = _skyColor;
 	groundColor = _groundColor;
 	areaID = _areaID;
 	objectsByID = _objectsByID;
 	entrancesByID = _entrancesByID;
-	vertexBuffer = nullptr;
-	drawElementsBuffer = nullptr;
 
 	// create a list of drawable objects only
 	for (ObjectMap::iterator iterator = objectsByID->begin(); iterator != objectsByID->end(); iterator++) {
@@ -79,21 +83,17 @@ Area::~Area() {
 	delete objectsByID;
 }
 
-/*void Area::setupOpenGL()
-{
-	delete vertexBuffer;
-	vertexBuffer = GeometricObject::newVertexBuffer();
-
-	delete drawElementsBuffer;
-	drawElementsBuffer = GeometricObject::newDrawElementsBuffer();
-
-	for(std::vector<Object *>::iterator iterator = drawableObjects.begin(); iterator != drawableObjects.end(); iterator++)
-		(*iterator)->setupOpenGL(vertexBuffer, drawElementsBuffer);
-}*/
 
 void Area::draw(Freescape::Renderer *gfx) {
+	if (palette) {
+		gfx->_palette = palette;
+	}
+	gfx->clear();
 	gfx->drawSky(skyColor);
+	assert(drawableObjects.size() > 0);
 	for (Common::Array<Object *>::iterator it = drawableObjects.begin(); it != drawableObjects.end(); it++) {
-		(*it)->draw(gfx);
+		if ((*it)->getSize() != Math::Vector3d(8192.f, 20.f, 8192.f))
+			(*it)->draw(gfx);
 	}
+	gfx->drawFloor(groundColor);
 }
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index d98047118f7..201dd4f2ce8 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -9,12 +9,11 @@
 #ifndef __Phantasma__Area__
 #define __Phantasma__Area__
 
+#include "math/vector3d.h"
 #include "common/hashmap.h"
 #include "common/array.h"
 #include "freescape/gfx.h"
 #include "freescape/objects/object.h"
-//#include "VertexBuffer.h"
-//#include "DrawElementsBuffer.h"
 
 typedef Common::HashMap<uint16, Object *> ObjectMap;
 
@@ -25,29 +24,28 @@ public:
 		uint16 areaID,
 		ObjectMap *objectsByID,
 		ObjectMap *entrancesByID,
+		uint8 scale,
 		uint8 skyColor,
 		uint8 groundColor,
-		Common::Array<uint8> *palette = nullptr);
+		Graphics::PixelBuffer *palette = nullptr);
 	virtual ~Area();
 
 	Object *objectWithID(uint16 objectID);
 	Object *entranceWithID(uint16 objectID);
 	uint16 getAreaID();
+	uint8 getScale();
 	void draw(Freescape::Renderer *gfx);
-	Common::Array<uint8> *raw_palette;
 
 private:
 	uint16 areaID;
+	uint8 scale;
+	Graphics::PixelBuffer *palette;
 	uint8 skyColor;
 	uint8 groundColor;
 	ObjectMap *objectsByID;
 	ObjectMap *entrancesByID;
 	Common::Array<Object *> drawableObjects;
-
 	Object *objectWithIDFromMap(ObjectMap *map, uint16 objectID);
-
-	VertexBuffer *vertexBuffer;
-	DrawElementsBuffer *drawElementsBuffer;
 };
 
 #endif /* defined(__Phantasma__Area__) */
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 68e1809c780..cb7e24631cd 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -115,7 +115,7 @@ void FreescapeEngine::loadAssets() {
 			if (file == nullptr)
 				error("Failed to open DRILLE.EXE");
 
-			load8bitBinary(file, 0x9b40, 8);
+			load8bitBinary(file, 0x9b40, 16);
 		} else if (renderMode == "cga") {
 			file = gameDir.createReadStreamForMember("DRILLC.EXE");
 
@@ -140,43 +140,40 @@ Common::Error FreescapeEngine::run() {
 	loadAssets();
 	Area *area = nullptr;
 	Entrance *entrance = nullptr;
-	if (_areasByAreaID) {
-		if (_startArea == 14)
-			_startArea = 1;
-		assert(_areasByAreaID->contains(_startArea));
-		area = (*_areasByAreaID)[_startArea];
-		assert(area);
-		entrance = (Entrance*) area->entranceWithID(_startEntrance);
-		assert(entrance);
-		_position = entrance->getOrigin();
-		//_gfx->renderPalette(area->raw_palette, binary.ncolors);
-		//drawBorder();
-	}
+	assert(_areasByAreaID);
+	if (_startArea == 14)
+		_startArea = 1;
+	assert(_areasByAreaID->contains(_startArea));
+	area = (*_areasByAreaID)[_startArea];
+	assert(area);
+	entrance = (Entrance*) area->entranceWithID(_startEntrance);
+	assert(entrance);
+	_position = entrance->getOrigin();
+	uint8 scale = area->getScale();
+	_position.setValue(1, _position.y() + scale * _playerHeight);
 	debug("FreescapeEngine::init");
 	// Simple main event loop
 	Common::Event event;
 	Common::Point lastMousePos(0, 0);
 	float lastFrame = 0.f;
+	// used to create a projection matrix;
 	float nearClipPlane = 1.f;
 	float farClipPlane;
 
 	if (_binaryBits == 16) {
-		// create a projection matrix; the 16-bit kit permits the range 0-8192 to
-		// be used along all three axes and from that comes the far plane distance
-		// of 14189.
-		farClipPlane = 14189.0f;
+		// the 16-bit kit permits the range 0-8192 to be used along all three axes and from that comes the far plane distance of 14189.
+		farClipPlane = 14189.f;
 	} else {
-		error("Unknown farClipPlane");
+		farClipPlane = 1024.f; // wild guess
 	}
 
-	g_system->lockMouse(true);
+	//_gfx->computeScreenViewport();
+	//error("%d %d", _gfx->viewport().width(), _gfx->viewport().height());
+	//g_system->lockMouse(true);
 
 	while (!shouldQuit()) {
 		_gfx->updateProjectionMatrix(40.0, nearClipPlane, farClipPlane);
 		_gfx->positionCamera(_position, _position + _cameraFront);
-		_gfx->scale(_scale);
-		//_gfx->selectTargetWindow(nullptr, true, false);
-		//_gfx->updateMatrices();
 		area->draw(_gfx);
         float currentFrame = g_system->getMillis();
         float deltaTime = currentFrame - lastFrame;
@@ -188,15 +185,13 @@ Common::Error FreescapeEngine::run() {
 			switch (event.type) {
 			case Common::EVENT_KEYDOWN:
 				if (event.kbd.keycode == Common::KEYCODE_w || event.kbd.keycode == Common::KEYCODE_UP)
-					move(FORWARD, deltaTime);
+					move(FORWARD, scale, deltaTime);
 				else if (event.kbd.keycode == Common::KEYCODE_s || event.kbd.keycode == Common::KEYCODE_DOWN)
-					move(BACKWARD, deltaTime);
+					move(BACKWARD, scale, deltaTime);
 				else if (event.kbd.keycode == Common::KEYCODE_a || event.kbd.keycode == Common::KEYCODE_LEFT)
-					move(LEFT, deltaTime);
+					move(LEFT, scale, deltaTime);
 				else if (event.kbd.keycode == Common::KEYCODE_d || event.kbd.keycode == Common::KEYCODE_RIGHT)
-					move(RIGHT, deltaTime);
-				
-				//debug("player position: %f %f %f", _position.x(), _position.y(), _position.z());
+					move(RIGHT, scale, deltaTime);
 				break;
 
 			case Common::EVENT_QUIT:
@@ -207,7 +202,11 @@ Common::Error FreescapeEngine::run() {
 			case Common::EVENT_MOUSEMOVE:
 				rotate(lastMousePos, mousePos);
 				lastMousePos = mousePos;
-				//debug("player rotation (front): %f %f %f", _front.x(), _front.y(), _front.z());
+				if (mousePos.x <= 5 || mousePos.x >= 315) {
+					g_system->warpMouse(_screenW/2, mousePos.y);
+					lastMousePos.x = _screenW/2;
+					lastMousePos.y = mousePos.y;
+				} 
 				break;
 			default:
 				break;
@@ -218,7 +217,6 @@ Common::Error FreescapeEngine::run() {
 		_gfx->flipBuffer();
 		g_system->updateScreen();
 		g_system->delayMillis(10);
-		//g_system->warpMouse(_screenH/2, _screenW/2);
 	}
 
 	return Common::kNoError;
@@ -257,8 +255,9 @@ void FreescapeEngine::rotate(Common::Point lastMousePos, Common::Point mousePos)
 	_cameraRight = v;
 }
 
-void FreescapeEngine::move(CameraMovement direction, float deltaTime) {
+void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTime) {
 	float velocity = _movementSpeed * deltaTime;
+	float positionY = _position.y(); 
 	switch (direction) {
 	case FORWARD:
 		_position = _position + _cameraFront * velocity;
@@ -275,7 +274,7 @@ void FreescapeEngine::move(CameraMovement direction, float deltaTime) {
 	}
 	// Make sure the user stays at the ground level
 	// this one-liner keeps the user at the ground level (xz plane)
-	_position.set(_position.x(), _playerHeight, _position.z());
+	_position.set(_position.x(), positionY, _position.z());
 }
 
 bool FreescapeEngine::hasFeature(EngineFeature f) const {
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 9527d878d50..9c136363051 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -83,7 +83,7 @@ public:
 	uint16 _startEntrance;
 
 	// Movement
-	void move(CameraMovement direction, float deltaTime);
+	void move(CameraMovement direction, uint8 scale, float deltaTime);
 	void rotate(Common::Point lastMousePos, Common::Point mousePos);
 	// Eular Angles
 	float _yaw;
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index ab79b61045b..91aaa9d6398 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -99,9 +99,9 @@ Common::Rect Renderer::rviewport() const {
 void Renderer::computeScreenViewport() {
 	int32 screenWidth = _system->getWidth();
 	int32 screenHeight = _system->getHeight();
-	int32 tmargin = 27;
-	int32 vmargin = 40;
-	int32 bmargin = 90;
+	int32 tmargin = 0; //27;
+	int32 vmargin = 0; //40;
+	int32 bmargin = 0; //90;
 
 	//assert(0);
 
@@ -112,11 +112,11 @@ void Renderer::computeScreenViewport() {
 		int32 viewportWidth = MIN<int32>(screenWidth, screenHeight * kOriginalWidth / kOriginalHeight);
 		int32 viewportHeight = MIN<int32>(screenHeight, screenWidth * kOriginalHeight / kOriginalWidth);
 		_screenViewport = Common::Rect(viewportWidth, viewportHeight);
-		_rscreenViewport = Common::Rect(vmargin, tmargin, _screenViewport.right - vmargin, _screenViewport.bottom - bmargin);
+		//_rscreenViewport = Common::Rect(vmargin, tmargin, _screenViewport.right - vmargin, _screenViewport.bottom - bmargin);
 
 		// Pillarboxing
-		_screenViewport.translate((screenWidth - viewportWidth) / 2,
-			(screenHeight - viewportHeight) / 2);
+		//_screenViewport.translate((screenWidth - viewportWidth) / 2,
+		//	(screenHeight - viewportHeight) / 2);
 	//}
 }
 
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 8ba3a0f7e96..d189467fdf7 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -143,6 +143,7 @@ public:
 	virtual void scale(const Math::Vector3d &scale) = 0;
 	virtual void renderCube(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) = 0;
 	virtual void drawSky(uint8 color) = 0;
+	virtual void drawFloor(uint8 color) = 0;
 
 	/** Render a Drawable in the specified window */
 	void renderDrawable(Drawable *drawable, Window *window);
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index b1bc8c783d6..eda39a7f378 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -195,6 +195,7 @@ void TinyGLRenderer::updateProjectionMatrix(float fov, float nearClipPlane, floa
 
 void TinyGLRenderer::positionCamera(const Math::Vector3d &pos, const Math::Vector3d &interest) {
 	Math::Vector3d up_vec(0, 1, 0);
+
 	Math::Matrix4 lookMatrix = Math::makeLookAtMatrix(pos, interest, up_vec);
 
 	tglMultMatrixf(lookMatrix.getData());
@@ -202,6 +203,10 @@ void TinyGLRenderer::positionCamera(const Math::Vector3d &pos, const Math::Vecto
 }
 
 void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector3d &size, Common::Array<uint8> *colours) {
+	assert(size.x() > 0);
+	assert(size.y() > 0);
+	assert(size.z() > 0);
+
 	//debug("Rendering cube at %f, %f, %f", origin.x(), origin.y(), origin.z());
 	//debug("with size %f, %f, %f", size.x(), size.y(), size.z());
 	uint8 r, g, b;
@@ -293,6 +298,18 @@ void TinyGLRenderer::drawSky(uint8 color) {
 	tglClear(TGL_COLOR_BUFFER_BIT | TGL_DEPTH_BUFFER_BIT);
 }
 
+void TinyGLRenderer::drawFloor(uint8 color) {
+	uint8 r, g, b;
+	_palette->getRGBAt(color, r, g, b);
+	tglColor3ub(r, g, b);
+	tglBegin(TGL_QUADS);
+	tglVertex3f(-100000.f, 0.f, -100000.f);
+	tglVertex3f(100000.f, 0.f, -100000.f);
+	tglVertex3f(100000.f, 0.f, 100000.f);
+	tglVertex3f(-100000.f, 0.f, 100000.f);
+	tglEnd();
+}
+
 void TinyGLRenderer::flipBuffer() {
 	TinyGL::tglPresentBuffer();
 	g_system->copyRectToScreen(_fb->getPixelBuffer(), _fb->linesize,
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index 710a2dd9a82..0b8c5fcf998 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -54,6 +54,7 @@ public:
 
 	virtual void flipBuffer() override;
 	virtual void drawSky(uint8 color) override;
+	virtual void drawFloor(uint8 color) override;
 
 private:
 	TinyGL::FrameBuffer *_fb;
diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
index 1fc0948ad8a..6ea832581b7 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/16bitBinaryLoader.cpp
@@ -28,7 +28,7 @@ typedef enum {
 		Border = 0x4524,
 } ChunkType;
 
-static Object *load16bitObject(StreamLoader &stream, uint8 groundColor) {
+static Object *load16bitObject(StreamLoader &stream) {
 	// get object flags and type
 	uint8 objectFlags = stream.get8();
 	Object::Type objectType = (Object::Type)stream.get8();
@@ -75,8 +75,6 @@ static Object *load16bitObject(StreamLoader &stream, uint8 groundColor) {
 		Common::Array<uint8> *colours = new Common::Array<uint8>;
 		for (uint8 colour = 0; colour < numberOfColours; colour++) {
 			uint8 c = stream.get8();
-			if (objectID == 1)
-				c = groundColor;
 			debug("face %d color: %d", colour, c);
 			colours->push_back(c);
 			byteSizeOfObject--;
@@ -211,7 +209,7 @@ Area *load16bitArea(StreamLoader &stream) {
 	// get the objects or whatever; entrances use a unique numbering
 	// system and have the high bit of their IDs set in the original file
 	for (uint16 object = 0; object < numberOfObjects; object++) {
-		Object *newObject = load16bitObject(stream, groundColor);
+		Object *newObject = load16bitObject(stream);
 
 		if (newObject) {
 			if (newObject->getType() == Object::Entrance) {
@@ -222,11 +220,9 @@ Area *load16bitArea(StreamLoader &stream) {
 		}
 	}
 
-	return (new Area(areaNumber, objectsByID, entrancesByID, skyColor, groundColor));
+	return (new Area(areaNumber, objectsByID, entrancesByID, 1, skyColor, groundColor));
 }
 
-
-
 void FreescapeEngine::load16bitBinary(Common::SeekableReadStream *file) {
 	const uint32 fileSize = file->size();
 	byte *buf = (byte *)malloc(fileSize);
@@ -411,8 +407,6 @@ void FreescapeEngine::load16bitBinary(Common::SeekableReadStream *file) {
 		if (newArea) {
 			(*areaMap)[newArea->getAreaID()] = newArea;
 		}
-		//if (newArea->getAreaID() == startArea)
-		//	assert(0);
 	}
 	//load16bitInstrument(streamLoader);
 
@@ -443,9 +437,9 @@ void FreescapeEngine::load16bitBinary(Common::SeekableReadStream *file) {
 			if (chunkSize == 320*200 / 4)
 				colorNumber = 4; // CGA
 			else if (chunkSize == 320*200 / 2)
-				colorNumber = 16;
+				colorNumber = 16; // EGA
 			else if (chunkSize == 320*200)
-				colorNumber = 256;
+				colorNumber = 256; // VGA
 			else
 				error("Unexpected size of image %d", chunkSize);
 
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index d7e8e2d8b67..0b73aff6d3b 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -130,7 +130,7 @@ float specColors[16][3] = {
 	{1, 1, 1}
 };
 
-Common::Array <uint8>*getPaletteGradient(float *c1, float *c2, uint16 ncolors) {
+Graphics::PixelBuffer *getPaletteGradient(float *c1, float *c2, uint16 ncolors) {
 	Common::Array <uint8> *raw_palette = new Common::Array <uint8>();
 	uint16 y0, y1, y2;
 	for(int c = 0; c < ncolors; c++)
@@ -145,7 +145,12 @@ Common::Array <uint8>*getPaletteGradient(float *c1, float *c2, uint16 ncolors) {
 		raw_palette->push_back(y1);
 		raw_palette->push_back(y2);
 	}
-	return raw_palette;
+	assert(ncolors == 16);
+	assert(raw_palette->size() == ncolors * 3);
+	Graphics::PixelFormat pixelFormat = Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0);
+	Graphics::PixelBuffer *palette = new Graphics::PixelBuffer(pixelFormat, ncolors, DisposeAfterUse::NO); //TODO
+	*palette = raw_palette->data();
+	return palette;
 }
 
 
@@ -156,7 +161,9 @@ Area *load8bitArea(StreamLoader &stream, uint16 ncolors) {
 	uint8 areaNumber = stream.get8();
 
 	uint16 cPtr = stream.rget16();
-	uint8 scale = stream.get8(); 
+	uint8 scale = stream.get8();
+	debug("Scale: %d", scale);
+
 	uint8 ci1 = stream.get8()&15;
 	uint8 ci2 = stream.get8()&15; 
 	uint8 ci3 = stream.get8()&15; 
@@ -168,7 +175,7 @@ Area *load8bitArea(StreamLoader &stream, uint16 ncolors) {
 	f1 = specColors[ci3];
 	f2 = specColors[ci4];
 
-	Common::Array <uint8> *raw_palette = getPaletteGradient(f1, f2, ncolors);
+	Graphics::PixelBuffer *palette = getPaletteGradient(f1, f2, ncolors);
 
 	debug("Area %d", areaNumber);
 	debug("Objects: %d", numberOfObjects);
@@ -202,7 +209,7 @@ Area *load8bitArea(StreamLoader &stream, uint16 ncolors) {
 		debug("%s", detokenise8bitCondition(*conditionData)->c_str());
 	}
 
-	return (new Area(areaNumber, objectsByID, entrancesByID, 0, 1, raw_palette));
+	return (new Area(areaNumber, objectsByID, entrancesByID, scale, 0, 1, palette));
 }
 
 // struct BinaryTable {
@@ -212,10 +219,10 @@ Area *load8bitArea(StreamLoader &stream, uint16 ncolors) {
 // };
 
 // static const BinaryTable binaryTable[] = {
-// 	{ "DRILLE.EXE",  8,  0x9b40},
+// 	{ "DRILLE.EXE",  16,  0x9b40},
 // 	{ "DRILLC.EXE",  4,  0x7bb0},
-// 	{ "TOTE.EXE",    8,  0xcdb7},
-//     //{ "TOTC.EXE",  8,  ??????},
+// 	{ "TOTE.EXE",    16,  0xcdb7},
+//  { "TOTC.EXE",    16,  ??????},
 // 	{ nullptr,       0,  0  }
 // };
 
@@ -246,8 +253,8 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	debug("Number of areas: %d", numberOfAreas);
 	uint8 startArea = streamLoader.get8();
 	debug("Start area: %d", startArea);
-	uint8 entranceArea = streamLoader.get8();
-	debug("Entrace area: %d", entranceArea);
+	uint8 startEntrance = streamLoader.get8();
+	debug("Entrace area: %d", startEntrance);
 
 	streamLoader.skipBytes(66);
 
@@ -293,6 +300,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	}
 	_areasByAreaID = areaMap;
 	_startArea = startArea;
+	_startEntrance = startEntrance;
 	_colorNumber = ncolors;
 	_binaryBits = 8;
 }
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index 0dd0ee00a90..5a0b440baf7 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -103,7 +103,9 @@ bool GeometricObject::isPlanar() {
 
 void GeometricObject::draw(Freescape::Renderer *gfx) {
 	if (this->getType() == Cube) {
+		//debug("Drawing cube!");
 		gfx->renderCube(origin, size, colours);
-	}
+	} //else
+		//debug("Drawing something of type %d", this->getType());
 		
 };
\ No newline at end of file
diff --git a/engines/freescape/objects/geometricobject.h b/engines/freescape/objects/geometricobject.h
index 0c33e3e4c74..4b41213920f 100644
--- a/engines/freescape/objects/geometricobject.h
+++ b/engines/freescape/objects/geometricobject.h
@@ -18,13 +18,6 @@ public:
 	static int numberOfColoursForObjectOfType(Type type);
 	static int numberOfOrdinatesForType(Type type);
 
-	/*static void setupOpenGL();
-		static void setProjectionMatrix(const GLfloat *projectionMatrix);
-		static void setViewMatrix(const GLfloat *projectionMatrix);
-
-		static VertexBuffer *newVertexBuffer();
-		static DrawElementsBuffer *newDrawElementsBuffer();*/
-
 	GeometricObject(
 		Type type,
 		uint16 objectID,
@@ -35,24 +28,17 @@ public:
 		Common::Array<uint16> *ordinates,
 		FCLInstructionVector condition);
 	virtual ~GeometricObject();
-
-	/*void setupOpenGL(VertexBuffer *areaVertexBuffer, DrawElementsBuffer *areaDrawElementsBuffer);*/
 	void draw(Freescape::Renderer *gfx) override;
 	bool isDrawable();
 	bool isPlanar();
 
 private:
-	/*static GLuint openGLProgram;
-		static GLuint compileShader(const GLchar *source, GLenum shaderType);
-		static GLint viewMatrixUniform, projectionMatrixUniform;*/
 
 	FCLInstructionVector condition;
 	Common::Array<uint8> *colours;
 	Common::Array<uint16> *ordinates;
 
 	size_t drawElementsStartIndex;
-	//GLsizei drawElementsCount;
-	//GLenum drawElementsMode;
 };
 
 #endif /* defined(__Phantasma__GeometricObject__) */


Commit: 227b5f535de6b052820fcef0fc986993aee9eed1
    https://github.com/scummvm/scummvm/commit/227b5f535de6b052820fcef0fc986993aee9eed1
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:39+01:00

Commit Message:
FREESCAPE: fixed colors and improved rendering to avoid the mirror effect

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/detection.cpp
    engines/freescape/freescape.cpp
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/loaders/16bitBinaryLoader.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/objects/object.h


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index e2aaa0123e4..da570e10b84 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -85,14 +85,14 @@ Area::~Area() {
 
 
 void Area::draw(Freescape::Renderer *gfx) {
-	if (palette) {
+	if (palette) 
 		gfx->_palette = palette;
-	}
+
 	gfx->clear();
 	gfx->drawSky(skyColor);
 	assert(drawableObjects.size() > 0);
 	for (Common::Array<Object *>::iterator it = drawableObjects.begin(); it != drawableObjects.end(); it++) {
-		if ((*it)->getSize() != Math::Vector3d(8192.f, 20.f, 8192.f))
+		if (!(*it)->isInvisible()) 
 			(*it)->draw(gfx);
 	}
 	gfx->drawFloor(groundColor);
diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index 0057cccaf9d..b4af009ed2e 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -32,6 +32,13 @@ static const ADGameDescription gameDescriptions[] = {
 	 Common::kPlatformDOS,
 	 ADGF_NO_FLAGS,
 	 GUIO1(GUIO_NOMIDI)},
+	{"3dkit",
+	 "Another cube scene",
+	 AD_ENTRY1s("CUBE2.RUN", "c070cdd82148390dd14a0444a7ab4cce", 83210),
+	 Common::EN_ANY,
+	 Common::kPlatformDOS,
+	 ADGF_NO_FLAGS,
+	 GUIO1(GUIO_NOMIDI)},
 
 	{"Driller",
 	 "",
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index cb7e24631cd..e083acb406e 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -45,6 +45,7 @@ FreescapeEngine::FreescapeEngine(OSystem *syst)
 	_pitch = 0.0f;
 	_movementSpeed = 4.5f;
 	_mouseSensitivity = 0.1f;
+	_scale = Math::Vector3d(0, 0, 0);
 
 	// Here is the right place to set up the engine specific debug channels
 	DebugMan.addDebugChannel(kFreescapeDebug, "example", "this is just an example for a engine specific debug channel");
@@ -149,8 +150,14 @@ Common::Error FreescapeEngine::run() {
 	entrance = (Entrance*) area->entranceWithID(_startEntrance);
 	assert(entrance);
 	_position = entrance->getOrigin();
-	uint8 scale = area->getScale();
-	_position.setValue(1, _position.y() + scale * _playerHeight);
+	Math::Vector3d scaleVector;
+	if (_scale == Math::Vector3d(0, 0, 0)) {
+		uint8 scale = area->getScale();
+		scaleVector = Math::Vector3d(scale, scale, scale);
+	} else
+		scaleVector = _scale;
+	debug("scale: %f, %f, %f", scaleVector.x(), scaleVector.y(), scaleVector.z());
+	_position.setValue(1, _position.y() + _playerHeight);
 	debug("FreescapeEngine::init");
 	// Simple main event loop
 	Common::Event event;
@@ -167,13 +174,12 @@ Common::Error FreescapeEngine::run() {
 		farClipPlane = 1024.f; // wild guess
 	}
 
-	//_gfx->computeScreenViewport();
-	//error("%d %d", _gfx->viewport().width(), _gfx->viewport().height());
 	//g_system->lockMouse(true);
 
 	while (!shouldQuit()) {
 		_gfx->updateProjectionMatrix(40.0, nearClipPlane, farClipPlane);
 		_gfx->positionCamera(_position, _position + _cameraFront);
+		_gfx->scale(scaleVector);
 		area->draw(_gfx);
         float currentFrame = g_system->getMillis();
         float deltaTime = currentFrame - lastFrame;
@@ -185,13 +191,13 @@ Common::Error FreescapeEngine::run() {
 			switch (event.type) {
 			case Common::EVENT_KEYDOWN:
 				if (event.kbd.keycode == Common::KEYCODE_w || event.kbd.keycode == Common::KEYCODE_UP)
-					move(FORWARD, scale, deltaTime);
+					move(FORWARD, scaleVector.x(), deltaTime);
 				else if (event.kbd.keycode == Common::KEYCODE_s || event.kbd.keycode == Common::KEYCODE_DOWN)
-					move(BACKWARD, scale, deltaTime);
+					move(BACKWARD, scaleVector.x(), deltaTime);
 				else if (event.kbd.keycode == Common::KEYCODE_a || event.kbd.keycode == Common::KEYCODE_LEFT)
-					move(LEFT, scale, deltaTime);
+					move(LEFT, scaleVector.y(), deltaTime);
 				else if (event.kbd.keycode == Common::KEYCODE_d || event.kbd.keycode == Common::KEYCODE_RIGHT)
-					move(RIGHT, scale, deltaTime);
+					move(RIGHT, scaleVector.y(), deltaTime);
 				break;
 
 			case Common::EVENT_QUIT:
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index eda39a7f378..1c9388d0a97 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -174,7 +174,7 @@ void TinyGLRenderer::draw2DText(const Common::String &text, const Common::Point
 }
 
 void TinyGLRenderer::scale(const Math::Vector3d &scale) {
-	//tglScalef(-scale.x() / 256.f, scale.y() / 256.f, scale.z() / 256.f);
+	tglScalef(-scale.x(), scale.y(), scale.z());
 }
 
 
@@ -197,7 +197,6 @@ void TinyGLRenderer::positionCamera(const Math::Vector3d &pos, const Math::Vecto
 	Math::Vector3d up_vec(0, 1, 0);
 
 	Math::Matrix4 lookMatrix = Math::makeLookAtMatrix(pos, interest, up_vec);
-
 	tglMultMatrixf(lookMatrix.getData());
 	tglTranslatef(-pos.x(), -pos.y(), -pos.z());
 }
@@ -211,84 +210,97 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 	//debug("with size %f, %f, %f", size.x(), size.y(), size.z());
 	uint8 r, g, b;
 
-	_palette->getRGBAt((*colours)[5], r, g, b);
-	tglDisable(TGL_TEXTURE_2D);
-	tglColor3ub(r, g, b);
 	// Face 0
-	tglBegin(TGL_TRIANGLES);
-	tglVertex3f(origin.x(),		        origin.y(),				origin.z() + size.z());
-	tglVertex3f(origin.x() + size.x(),	origin.y(),				origin.z() + size.z());
-	tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z() + size.z());
-
-	tglVertex3f(origin.x(),		        origin.y(),				origin.z() + size.z());
-	tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z() + size.z());
-	tglVertex3f(origin.x(),		        origin.y() + size.y(),	origin.z() + size.z());
-	tglEnd();
+	if ((*colours)[5] > 0) {
+		_palette->getRGBAt((*colours)[5], r, g, b);
+		tglDisable(TGL_TEXTURE_2D);
+		tglColor3ub(r, g, b);
+		// Face 0
+		tglBegin(TGL_TRIANGLES);
+		tglVertex3f(origin.x(),		        origin.y(),				origin.z() + size.z());
+		tglVertex3f(origin.x() + size.x(),	origin.y(),				origin.z() + size.z());
+		tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z() + size.z());
+
+		tglVertex3f(origin.x(),		        origin.y(),				origin.z() + size.z());
+		tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z() + size.z());
+		tglVertex3f(origin.x(),		        origin.y() + size.y(),	origin.z() + size.z());
+		tglEnd();
+	}
 
 	// Face 1
-	_palette->getRGBAt((*colours)[4], r, g, b);
-	tglColor3ub(r, g, b);
-
-	tglBegin(TGL_TRIANGLES);
-	tglVertex3f(origin.x(),				origin.y() + size.y(),	origin.z());
-	tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z());
-	tglVertex3f(origin.x() + size.x(),	origin.y(),				origin.z());
-
-	tglVertex3f(origin.x(),				origin.y() + size.y(),	origin.z());
-	tglVertex3f(origin.x() + size.x(),	origin.y(),				origin.z());
-	tglVertex3f(origin.x(),				origin.y(),				origin.z());
-	tglEnd();
+	if ((*colours)[4] > 0) {
+		_palette->getRGBAt((*colours)[4], r, g, b);
+		tglColor3ub(r, g, b);
+
+		tglBegin(TGL_TRIANGLES);
+		tglVertex3f(origin.x(),				origin.y() + size.y(),	origin.z());
+		tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z());
+		tglVertex3f(origin.x() + size.x(),	origin.y(),				origin.z());
+
+		tglVertex3f(origin.x(),				origin.y() + size.y(),	origin.z());
+		tglVertex3f(origin.x() + size.x(),	origin.y(),				origin.z());
+		tglVertex3f(origin.x(),				origin.y(),				origin.z());
+		tglEnd();
+	}
 
 	// Face 2
-	_palette->getRGBAt((*colours)[0], r, g, b);
-	tglColor3ub(r, g, b);
-
-	tglBegin(TGL_TRIANGLES);
-	tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z());
-	tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z() + size.z());
-	tglVertex3f(origin.x() + size.x(),	origin.y(),				origin.z() + size.z());
-
-	tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z());
-	tglVertex3f(origin.x() + size.x(),	origin.y(),				origin.z() + size.z());
-	tglVertex3f(origin.x() + size.x(),	origin.y(),				origin.z());
-	tglEnd();
+	if ((*colours)[1] > 0) {
+		_palette->getRGBAt((*colours)[1], r, g, b);
+		tglColor3ub(r, g, b);
+
+		tglBegin(TGL_TRIANGLES);
+		tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z());
+		tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z() + size.z());
+		tglVertex3f(origin.x() + size.x(),	origin.y(),				origin.z() + size.z());
+
+		tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z());
+		tglVertex3f(origin.x() + size.x(),	origin.y(),				origin.z() + size.z());
+		tglVertex3f(origin.x() + size.x(),	origin.y(),				origin.z());
+		tglEnd();
+	}
 
 	// Face 3
-	_palette->getRGBAt((*colours)[1], r, g, b);
-	tglColor3ub(r, g, b);
-	tglBegin(TGL_TRIANGLES);
-	tglVertex3f(origin.x(),	origin.y(),				origin.z());
-	tglVertex3f(origin.x(),	origin.y(),				origin.z() + size.z());
-	tglVertex3f(origin.x(),	origin.y() + size.y(),	origin.z() + size.z());
-
-	tglVertex3f(origin.x(),	origin.y(),				origin.z());
-	tglVertex3f(origin.x(),	origin.y() + size.y(),	origin.z() + size.z());
-	tglVertex3f(origin.x(),	origin.y() + size.y(),	origin.z());
-	tglEnd();
+	if ((*colours)[0] > 0) {
+		_palette->getRGBAt((*colours)[0], r, g, b);
+		tglColor3ub(r, g, b);
+		tglBegin(TGL_TRIANGLES);
+		tglVertex3f(origin.x(),	origin.y(),				origin.z());
+		tglVertex3f(origin.x(),	origin.y(),				origin.z() + size.z());
+		tglVertex3f(origin.x(),	origin.y() + size.y(),	origin.z() + size.z());
+
+		tglVertex3f(origin.x(),	origin.y(),				origin.z());
+		tglVertex3f(origin.x(),	origin.y() + size.y(),	origin.z() + size.z());
+		tglVertex3f(origin.x(),	origin.y() + size.y(),	origin.z());
+		tglEnd();
+	}
 
-	_palette->getRGBAt((*colours)[2], r, g, b);
-	tglColor3ub(r, g, b);
-	tglBegin(TGL_TRIANGLES);
-	tglVertex3f(origin.x() + size.x(),	origin.y(),	origin.z());
-	tglVertex3f(origin.x() + size.x(),	origin.y(),	origin.z() + size.z());
-	tglVertex3f(origin.x(),			origin.y(),		origin.z() + size.z());
-
-	tglVertex3f(origin.x() + size.x(),	origin.y(),	origin.z());
-	tglVertex3f(origin.x(),			origin.y(),		origin.z() + size.z());
-	tglVertex3f(origin.x(),			origin.y(),		origin.z());
-	tglEnd();
+	if ((*colours)[2] > 0) {
+		_palette->getRGBAt((*colours)[2], r, g, b);
+		tglColor3ub(r, g, b);
+		tglBegin(TGL_TRIANGLES);
+		tglVertex3f(origin.x() + size.x(),	origin.y(),	origin.z());
+		tglVertex3f(origin.x() + size.x(),	origin.y(),	origin.z() + size.z());
+		tglVertex3f(origin.x(),			origin.y(),		origin.z() + size.z());
+
+		tglVertex3f(origin.x() + size.x(),	origin.y(),	origin.z());
+		tglVertex3f(origin.x(),			origin.y(),		origin.z() + size.z());
+		tglVertex3f(origin.x(),			origin.y(),		origin.z());
+		tglEnd();
+	}
 
-	_palette->getRGBAt((*colours)[3], r, g, b);
-	tglColor3ub(r, g, b);
-	tglBegin(TGL_TRIANGLES);
-	tglVertex3f(origin.x(),				origin.y() + size.y(),	origin.z());
-	tglVertex3f(origin.x(),				origin.y() + size.y(),	origin.z() + size.z());
-	tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z() + size.z());
-
-	tglVertex3f(origin.x(),				origin.y() + size.y(),	origin.z());
-	tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z() + size.z());
-	tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z());
-	tglEnd();
+	if ((*colours)[3] > 0) {
+		_palette->getRGBAt((*colours)[3], r, g, b);
+		tglColor3ub(r, g, b);
+		tglBegin(TGL_TRIANGLES);
+		tglVertex3f(origin.x(),				origin.y() + size.y(),	origin.z());
+		tglVertex3f(origin.x(),				origin.y() + size.y(),	origin.z() + size.z());
+		tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z() + size.z());
+
+		tglVertex3f(origin.x(),				origin.y() + size.y(),	origin.z());
+		tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z() + size.z());
+		tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z());
+		tglEnd();
+	}
 }
 
 void TinyGLRenderer::drawSky(uint8 color) {
diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
index 6ea832581b7..b3f65b8ab67 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/16bitBinaryLoader.cpp
@@ -73,10 +73,17 @@ static Object *load16bitObject(StreamLoader &stream) {
 		// read the appropriate number of colours
 		int numberOfColours = GeometricObject::numberOfColoursForObjectOfType(objectType);
 		Common::Array<uint8> *colours = new Common::Array<uint8>;
-		for (uint8 colour = 0; colour < numberOfColours; colour++) {
-			uint8 c = stream.get8();
-			debug("face %d color: %d", colour, c);
-			colours->push_back(c);
+		for (uint8 colour = 0; colour < numberOfColours/2; colour++) {
+			uint8 c1 = stream.get8();
+			uint8 c2 = stream.get8();
+			debug("data: %x %x", c1, c2);
+			colours->push_back( (c1 & 0x0f) | ((c2 & 0x0f) << 4));
+			debug("color[%d] = %d", 2*colour, (c1 & 0x0f) | ((c2 & 0x0f) << 4));
+
+			colours->push_back(c1 >> 4 | c2 & 0xf0);
+			debug("color[%d] = %d", 2*colour+1, c1 >> 4 | c2 & 0xf0);
+
+			byteSizeOfObject--;
 			byteSizeOfObject--;
 		}
 
@@ -86,6 +93,7 @@ static Object *load16bitObject(StreamLoader &stream) {
 		Common::Array<uint16> *ordinates = nullptr;
 
 		if (numberOfOrdinates) {
+			assert(byteSizeOfObject > 0);
 			ordinates = new Common::Array<uint16>;
 
 			for (int ordinate = 0; ordinate < numberOfOrdinates; ordinate++) {
@@ -96,13 +104,13 @@ static Object *load16bitObject(StreamLoader &stream) {
 
 		// grab the object condition, if there is one
 		FCLInstructionVector instructions;
-		if (byteSizeOfObject) {
+		if (byteSizeOfObject > 0) {
 			Common::Array<uint8> *conditionData = stream.nextBytes(byteSizeOfObject);
 
 			Common::String *conditionSource = detokenise16bitCondition(*conditionData);
 			//instructions = getInstructions(conditionSource);
 		}
-		byteSizeOfObject = 0;
+		//assert(byteSizeOfObject == 0);
 		debug("End of object at %x", stream.getFileOffset());
 
 		// create an object
@@ -482,7 +490,7 @@ void FreescapeEngine::load16bitBinary(Common::SeekableReadStream *file) {
 	_startEntrance = startEntrance;
 	_colorNumber = colorNumber;
 	_areasByAreaID = areaMap;
-	_scale = Math::Vector3d(scaleX, scaleY, scaleZ);
+	_scale = Math::Vector3d(1, 1, 1);
 	_binaryBits = 16;
 	//return Binary{16, startArea, areaMap, raw_border, raw_palette, colorNumber};
 }
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 0b73aff6d3b..26e0f3dd479 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -85,8 +85,8 @@ static Object *load8bitObject(StreamLoader &stream) {
 			objectType,
 			objectID,
 			0, // flags
-			position,
-			v, // size
+			64 * position,
+			64 * v, // size
 			colours,
 			ordinates,
 			instructions);
diff --git a/engines/freescape/objects/object.h b/engines/freescape/objects/object.h
index 7b528875965..1997fe146bb 100644
--- a/engines/freescape/objects/object.h
+++ b/engines/freescape/objects/object.h
@@ -54,6 +54,7 @@ public:
 
 	virtual bool isDrawable();
 	virtual bool isPlanar();
+	bool isInvisible() { return flags & 0x4; }
 
 	virtual ~Object();
 


Commit: 7dfc5e7894708c8bb60e6ba2a7a26fd7340c8c3e
    https://github.com/scummvm/scummvm/commit/7dfc5e7894708c8bb60e6ba2a7a26fd7340c8c3e
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:40+01:00

Commit Message:
FREESCAPE: refactored rendering code and added more games

Changed paths:
    engines/freescape/detection.cpp
    engines/freescape/freescape.cpp
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/loaders/16bitBinaryLoader.cpp
    engines/freescape/objects/entrance.h


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index b4af009ed2e..712bb100729 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -9,6 +9,27 @@ static const PlainGameDescriptor freescapeGames[] = {
 	{0, 0}};
 
 static const ADGameDescription gameDescriptions[] = {
+	{"3dkit",
+	 "Chrismas",
+	 AD_ENTRY1s("CHRISTMA.RUN", "106b8f0dd0384d3138a8f0f62caef392", 69910),
+	 Common::EN_ANY,
+	 Common::kPlatformDOS,
+	 ADGF_NO_FLAGS,
+	 GUIO1(GUIO_NOMIDI)},
+	{"3dkit",
+	 "Maze",
+	 AD_ENTRY1s("DESMAZE.RUN", "5cfab15e53d77029bdb02c87acae3186", 99212),
+	 Common::EN_ANY,
+	 Common::kPlatformDOS,
+	 ADGF_NO_FLAGS,
+	 GUIO1(GUIO_NOMIDI)},
+	{"3dkit",
+	 "Mountain",
+	 AD_ENTRY1s("MOUNTAIN.RUN", "ec3bb57fe23b1a6785e870af1baa74d7", 129106),
+	 Common::EN_ANY,
+	 Common::kPlatformDOS,
+	 ADGF_NO_FLAGS,
+	 GUIO1(GUIO_NOMIDI)},
 	{"3dkit",
 	 "Example game",
 	 AD_ENTRY1s("3DKIT.RUN", "f35147729a2f5b6852a504223aeb6a57", 112158),
@@ -16,7 +37,6 @@ static const ADGameDescription gameDescriptions[] = {
 	 Common::kPlatformDOS,
 	 ADGF_NO_FLAGS,
 	 GUIO1(GUIO_NOMIDI)},
-
 	{"3dkit",
 	 "Empty scene",
 	 AD_ENTRY1s("EMPTY.RUN", "7e7238e12dd9da4336a77a58d1bcfc0e", 83184),
@@ -34,7 +54,7 @@ static const ADGameDescription gameDescriptions[] = {
 	 GUIO1(GUIO_NOMIDI)},
 	{"3dkit",
 	 "Another cube scene",
-	 AD_ENTRY1s("CUBE2.RUN", "c070cdd82148390dd14a0444a7ab4cce", 83210),
+	 AD_ENTRY1s("CUBE2.RUN", "8790effbb162191c1c61ddee0ef0ce8c", 83210),
 	 Common::EN_ANY,
 	 Common::kPlatformDOS,
 	 ADGF_NO_FLAGS,
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index e083acb406e..3fbd2810b76 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -40,9 +40,6 @@ FreescapeEngine::FreescapeEngine(OSystem *syst)
 	_velocity = Vector3d(0.f, 0.f, 0.f);
 	_cameraFront = Vector3d(0.f, 0.f, 0.f);
 	_cameraRight = Vector3d(0.f, 0.f, 0.f);
-
-	_yaw = -90.0f;
-	_pitch = 0.0f;
 	_movementSpeed = 4.5f;
 	_mouseSensitivity = 0.1f;
 	_scale = Math::Vector3d(0, 0, 0);
@@ -158,6 +155,11 @@ Common::Error FreescapeEngine::run() {
 		scaleVector = _scale;
 	debug("scale: %f, %f, %f", scaleVector.x(), scaleVector.y(), scaleVector.z());
 	_position.setValue(1, _position.y() + _playerHeight);
+
+	Math::Vector3d rotation = entrance->getRotation(); 
+	_pitch = rotation.x() - 180.f;
+	_yaw = rotation.y() - 180.f;
+
 	debug("FreescapeEngine::init");
 	// Simple main event loop
 	Common::Event event;
@@ -177,7 +179,7 @@ Common::Error FreescapeEngine::run() {
 	//g_system->lockMouse(true);
 
 	while (!shouldQuit()) {
-		_gfx->updateProjectionMatrix(40.0, nearClipPlane, farClipPlane);
+		_gfx->updateProjectionMatrix(60.0, nearClipPlane, farClipPlane);
 		_gfx->positionCamera(_position, _position + _cameraFront);
 		_gfx->scale(scaleVector);
 		area->draw(_gfx);
@@ -241,10 +243,10 @@ void FreescapeEngine::rotate(Common::Point lastMousePos, Common::Point mousePos)
 	_pitch += yoffset;
 
 	// Make sure that when pitch is out of bounds, screen doesn't get flipped
-	if (_pitch > 89.0f)
-		_pitch = 89.0f;
-	if (_pitch < -89.0f)
-		_pitch = -89.0f;
+	if (_pitch > 180.0f)
+		_pitch = 180.0f;
+	if (_pitch < -180.0f)
+		_pitch = -180.0f;
 
 	Vector3d v;
 	float x = cos(_yaw  * M_PI / 180.0) * cos(_pitch  * M_PI / 180.0);
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 1c9388d0a97..6fc413b0e58 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -174,10 +174,9 @@ void TinyGLRenderer::draw2DText(const Common::String &text, const Common::Point
 }
 
 void TinyGLRenderer::scale(const Math::Vector3d &scale) {
-	tglScalef(-scale.x(), scale.y(), scale.z());
+	tglScalef(-1, 1, 1);
 }
 
-
 void TinyGLRenderer::updateProjectionMatrix(float fov, float nearClipPlane, float farClipPlane) {
 	tglMatrixMode(TGL_PROJECTION);
 	tglLoadIdentity();
@@ -211,43 +210,24 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 	uint8 r, g, b;
 
 	// Face 0
-	if ((*colours)[5] > 0) {
-		_palette->getRGBAt((*colours)[5], r, g, b);
-		tglDisable(TGL_TEXTURE_2D);
+	if ((*colours)[0] > 0) {
+		_palette->getRGBAt((*colours)[0], r, g, b);
 		tglColor3ub(r, g, b);
-		// Face 0
 		tglBegin(TGL_TRIANGLES);
-		tglVertex3f(origin.x(),		        origin.y(),				origin.z() + size.z());
-		tglVertex3f(origin.x() + size.x(),	origin.y(),				origin.z() + size.z());
-		tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z() + size.z());
+		tglVertex3f(origin.x(),	origin.y(),				origin.z());
+		tglVertex3f(origin.x(),	origin.y(),				origin.z() + size.z());
+		tglVertex3f(origin.x(),	origin.y() + size.y(),	origin.z() + size.z());
 
-		tglVertex3f(origin.x(),		        origin.y(),				origin.z() + size.z());
-		tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z() + size.z());
-		tglVertex3f(origin.x(),		        origin.y() + size.y(),	origin.z() + size.z());
+		tglVertex3f(origin.x(),	origin.y(),				origin.z());
+		tglVertex3f(origin.x(),	origin.y() + size.y(),	origin.z() + size.z());
+		tglVertex3f(origin.x(),	origin.y() + size.y(),	origin.z());
 		tglEnd();
 	}
 
 	// Face 1
-	if ((*colours)[4] > 0) {
-		_palette->getRGBAt((*colours)[4], r, g, b);
-		tglColor3ub(r, g, b);
-
-		tglBegin(TGL_TRIANGLES);
-		tglVertex3f(origin.x(),				origin.y() + size.y(),	origin.z());
-		tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z());
-		tglVertex3f(origin.x() + size.x(),	origin.y(),				origin.z());
-
-		tglVertex3f(origin.x(),				origin.y() + size.y(),	origin.z());
-		tglVertex3f(origin.x() + size.x(),	origin.y(),				origin.z());
-		tglVertex3f(origin.x(),				origin.y(),				origin.z());
-		tglEnd();
-	}
-
-	// Face 2
 	if ((*colours)[1] > 0) {
 		_palette->getRGBAt((*colours)[1], r, g, b);
 		tglColor3ub(r, g, b);
-
 		tglBegin(TGL_TRIANGLES);
 		tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z());
 		tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z() + size.z());
@@ -259,21 +239,7 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 		tglEnd();
 	}
 
-	// Face 3
-	if ((*colours)[0] > 0) {
-		_palette->getRGBAt((*colours)[0], r, g, b);
-		tglColor3ub(r, g, b);
-		tglBegin(TGL_TRIANGLES);
-		tglVertex3f(origin.x(),	origin.y(),				origin.z());
-		tglVertex3f(origin.x(),	origin.y(),				origin.z() + size.z());
-		tglVertex3f(origin.x(),	origin.y() + size.y(),	origin.z() + size.z());
-
-		tglVertex3f(origin.x(),	origin.y(),				origin.z());
-		tglVertex3f(origin.x(),	origin.y() + size.y(),	origin.z() + size.z());
-		tglVertex3f(origin.x(),	origin.y() + size.y(),	origin.z());
-		tglEnd();
-	}
-
+	// Face 2
 	if ((*colours)[2] > 0) {
 		_palette->getRGBAt((*colours)[2], r, g, b);
 		tglColor3ub(r, g, b);
@@ -288,6 +254,7 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 		tglEnd();
 	}
 
+	// Face 3
 	if ((*colours)[3] > 0) {
 		_palette->getRGBAt((*colours)[3], r, g, b);
 		tglColor3ub(r, g, b);
@@ -301,6 +268,36 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 		tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z());
 		tglEnd();
 	}
+
+	// Face 1
+	if ((*colours)[4] > 0) {
+		_palette->getRGBAt((*colours)[4], r, g, b);
+		tglColor3ub(r, g, b);
+		tglBegin(TGL_TRIANGLES);
+		tglVertex3f(origin.x(),				origin.y() + size.y(),	origin.z());
+		tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z());
+		tglVertex3f(origin.x() + size.x(),	origin.y(),				origin.z());
+
+		tglVertex3f(origin.x(),				origin.y() + size.y(),	origin.z());
+		tglVertex3f(origin.x() + size.x(),	origin.y(),				origin.z());
+		tglVertex3f(origin.x(),				origin.y(),				origin.z());
+		tglEnd();
+	}
+
+	// Face 0
+	if ((*colours)[5] > 0) {
+		_palette->getRGBAt((*colours)[5], r, g, b);	
+		tglColor3ub(r, g, b);
+		tglBegin(TGL_TRIANGLES);
+		tglVertex3f(origin.x(),		        origin.y(),				origin.z() + size.z());
+		tglVertex3f(origin.x() + size.x(),	origin.y(),				origin.z() + size.z());
+		tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z() + size.z());
+
+		tglVertex3f(origin.x(),		        origin.y(),				origin.z() + size.z());
+		tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z() + size.z());
+		tglVertex3f(origin.x(),		        origin.y() + size.y(),	origin.z() + size.z());
+		tglEnd();
+	}
 }
 
 void TinyGLRenderer::drawSky(uint8 color) {
diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
index b3f65b8ab67..1a03a15ec45 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/16bitBinaryLoader.cpp
@@ -75,16 +75,13 @@ static Object *load16bitObject(StreamLoader &stream) {
 		Common::Array<uint8> *colours = new Common::Array<uint8>;
 		for (uint8 colour = 0; colour < numberOfColours/2; colour++) {
 			uint8 c1 = stream.get8();
+			byteSizeOfObject--;
 			uint8 c2 = stream.get8();
-			debug("data: %x %x", c1, c2);
+			byteSizeOfObject--;
 			colours->push_back( (c1 & 0x0f) | ((c2 & 0x0f) << 4));
 			debug("color[%d] = %d", 2*colour, (c1 & 0x0f) | ((c2 & 0x0f) << 4));
-
 			colours->push_back(c1 >> 4 | c2 & 0xf0);
 			debug("color[%d] = %d", 2*colour+1, c1 >> 4 | c2 & 0xf0);
-
-			byteSizeOfObject--;
-			byteSizeOfObject--;
 		}
 
 		// read extra vertices if required...
@@ -104,13 +101,18 @@ static Object *load16bitObject(StreamLoader &stream) {
 
 		// grab the object condition, if there is one
 		FCLInstructionVector instructions;
-		if (byteSizeOfObject > 0) {
-			Common::Array<uint8> *conditionData = stream.nextBytes(byteSizeOfObject);
-
-			Common::String *conditionSource = detokenise16bitCondition(*conditionData);
-			//instructions = getInstructions(conditionSource);
-		}
-		//assert(byteSizeOfObject == 0);
+		// if (byteSizeOfObject > 0) {
+		// 	uint32 offset = stream.getFileOffset();
+		// 	Common::Array<uint8> *conditionData = stream.nextBytes(byteSizeOfObject);
+		// 	byteSizeOfObject = byteSizeOfObject - (offset - stream.getFileOffset());
+
+		// 	Common::String *conditionSource = detokenise16bitCondition(*conditionData);
+		// 	debug("Condition: %s", conditionSource->c_str());
+		// 	//instructions = getInstructions(conditionSource);
+		// }
+
+		debug("Skipping %d bytes", byteSizeOfObject);
+		stream.skipBytes(byteSizeOfObject);
 		debug("End of object at %x", stream.getFileOffset());
 
 		// create an object
@@ -126,6 +128,9 @@ static Object *load16bitObject(StreamLoader &stream) {
 	} break;
 
 	case Object::Entrance:
+		debug("Skipping %d bytes", byteSizeOfObject);
+		stream.skipBytes(byteSizeOfObject);
+		debug("End of object at %x", stream.getFileOffset());
 		return new Entrance(objectID, position, size); // size will be always 0,0,0?
 		break;
 	case Object::Sensor:
@@ -490,7 +495,7 @@ void FreescapeEngine::load16bitBinary(Common::SeekableReadStream *file) {
 	_startEntrance = startEntrance;
 	_colorNumber = colorNumber;
 	_areasByAreaID = areaMap;
-	_scale = Math::Vector3d(1, 1, 1);
+	_scale = Math::Vector3d(scaleX, scaleY, scaleZ);
 	_binaryBits = 16;
 	//return Binary{16, startArea, areaMap, raw_border, raw_palette, colorNumber};
 }
diff --git a/engines/freescape/objects/entrance.h b/engines/freescape/objects/entrance.h
index 6c53246c6da..8fe86619436 100644
--- a/engines/freescape/objects/entrance.h
+++ b/engines/freescape/objects/entrance.h
@@ -23,6 +23,8 @@ public:
 	bool isDrawable();
 	bool isPlanar();
 	Type getType() override { return Type::Entrance; };
+	Vector3d getRotation() { return rotation; }
+	
 	void draw(Freescape::Renderer *gfx) override { error("cannot render Entrance"); };
 };
 


Commit: 79e2e0b5423ec4c44838fe0bcd9c652ba2b93154
    https://github.com/scummvm/scummvm/commit/79e2e0b5423ec4c44838fe0bcd9c652ba2b93154
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:40+01:00

Commit Message:
FREESCAPE: added more detected games, better parsing and added polygon rendering

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/detection.cpp
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/gfx_tinygl.h
    engines/freescape/language/16bitDetokeniser.cpp
    engines/freescape/loaders/16bitBinaryLoader.cpp
    engines/freescape/objects/geometricobject.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index da570e10b84..25afa54dd05 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -83,6 +83,10 @@ Area::~Area() {
 	delete objectsByID;
 }
 
+void Area::show() {
+	for (ObjectMap::iterator it = objectsByID->begin(); it != objectsByID->end(); it++)
+		debug("objID: %d, type: %d", (*it)._value->getObjectID(), (*it)._value->getType());
+}
 
 void Area::draw(Freescape::Renderer *gfx) {
 	if (palette) 
@@ -95,5 +99,9 @@ void Area::draw(Freescape::Renderer *gfx) {
 		if (!(*it)->isInvisible()) 
 			(*it)->draw(gfx);
 	}
+	for (Common::Array<Object *>::iterator it = drawableObjects.begin(); it != drawableObjects.end(); it++) {
+		if (!(*it)->isInvisible() && (*it)->isPlanar()) 
+			(*it)->draw(gfx);
+	}
 	gfx->drawFloor(groundColor);
 }
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index 201dd4f2ce8..ed97121cf17 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -35,6 +35,7 @@ public:
 	uint16 getAreaID();
 	uint8 getScale();
 	void draw(Freescape::Renderer *gfx);
+	void show();
 
 private:
 	uint16 areaID;
diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index 712bb100729..aeb005d7be2 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -6,60 +6,53 @@ static const PlainGameDescriptor freescapeGames[] = {
 	{"3dkit", "The 3D Kit Game"},
 	{"driller", "Driller"},
 	{"castle", "Castle Master"},
+	{"menace", "Menace of Dr. Spoil Sport"},
 	{0, 0}};
 
 static const ADGameDescription gameDescriptions[] = {
 	{"3dkit",
-	 "Chrismas",
-	 AD_ENTRY1s("CHRISTMA.RUN", "106b8f0dd0384d3138a8f0f62caef392", 69910),
+	 "Simple example",
+	 AD_ENTRY1s("HEX.RUN", "084c0314d0cd8e6d2287f30483a732eb", 83242),
 	 Common::EN_ANY,
 	 Common::kPlatformDOS,
 	 ADGF_NO_FLAGS,
 	 GUIO1(GUIO_NOMIDI)},
-	{"3dkit",
-	 "Maze",
-	 AD_ENTRY1s("DESMAZE.RUN", "5cfab15e53d77029bdb02c87acae3186", 99212),
-	 Common::EN_ANY,
-	 Common::kPlatformDOS,
-	 ADGF_NO_FLAGS,
-	 GUIO1(GUIO_NOMIDI)},
-	{"3dkit",
-	 "Mountain",
-	 AD_ENTRY1s("MOUNTAIN.RUN", "ec3bb57fe23b1a6785e870af1baa74d7", 129106),
+	{"menace",
+	 "",
+	 AD_ENTRY1s("MODSS.RUN", "409ac1100a15447e742ec1415b2741c3", 91176),
 	 Common::EN_ANY,
 	 Common::kPlatformDOS,
 	 ADGF_NO_FLAGS,
 	 GUIO1(GUIO_NOMIDI)},
+
 	{"3dkit",
-	 "Example game",
-	 AD_ENTRY1s("3DKIT.RUN", "f35147729a2f5b6852a504223aeb6a57", 112158),
+	 "Chrismas",
+	 AD_ENTRY1s("CHRISTMA.RUN", "106b8f0dd0384d3138a8f0f62caef392", 69910),
 	 Common::EN_ANY,
 	 Common::kPlatformDOS,
 	 ADGF_NO_FLAGS,
 	 GUIO1(GUIO_NOMIDI)},
 	{"3dkit",
-	 "Empty scene",
-	 AD_ENTRY1s("EMPTY.RUN", "7e7238e12dd9da4336a77a58d1bcfc0e", 83184),
+	 "Maze",
+	 AD_ENTRY1s("DESMAZE.RUN", "5cfab15e53d77029bdb02c87acae3186", 99212),
 	 Common::EN_ANY,
 	 Common::kPlatformDOS,
 	 ADGF_NO_FLAGS,
 	 GUIO1(GUIO_NOMIDI)},
-
 	{"3dkit",
-	 "One cube in scene",
-	 AD_ENTRY1s("CUBE.RUN", "3b7930be0f646b98885cfb70c26c89a2", 66138),
+	 "Mountain",
+	 AD_ENTRY1s("MOUNTAIN.RUN", "ec3bb57fe23b1a6785e870af1baa74d7", 129106),
 	 Common::EN_ANY,
 	 Common::kPlatformDOS,
 	 ADGF_NO_FLAGS,
 	 GUIO1(GUIO_NOMIDI)},
 	{"3dkit",
-	 "Another cube scene",
-	 AD_ENTRY1s("CUBE2.RUN", "8790effbb162191c1c61ddee0ef0ce8c", 83210),
+	 "Example game",
+	 AD_ENTRY1s("3DKIT.RUN", "f35147729a2f5b6852a504223aeb6a57", 112158),
 	 Common::EN_ANY,
 	 Common::kPlatformDOS,
 	 ADGF_NO_FLAGS,
 	 GUIO1(GUIO_NOMIDI)},
-
 	{"Driller",
 	 "",
 	 AD_ENTRY1s("DRILLER.EXE", "cafc0ea0d3424640a7723af87f8bfc0b", 17427),
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 3fbd2810b76..83f436e3f75 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -43,6 +43,7 @@ FreescapeEngine::FreescapeEngine(OSystem *syst)
 	_movementSpeed = 4.5f;
 	_mouseSensitivity = 0.1f;
 	_scale = Math::Vector3d(0, 0, 0);
+	_borderTexture = nullptr;
 
 	// Here is the right place to set up the engine specific debug channels
 	DebugMan.addDebugChannel(kFreescapeDebug, "example", "this is just an example for a engine specific debug channel");
@@ -71,13 +72,14 @@ void FreescapeEngine::drawBorder() {
 	if (_border == nullptr)
 		return;
 
-	Texture *t = _gfx->createTexture(_border);
+	if (!_borderTexture)
+		_borderTexture = _gfx->createTexture(_border);
 	const Common::Rect rect(0, 0, _screenW, _screenH);
 
-	_gfx->drawTexturedRect2D(rect, rect, t, 1.0, false);
-	_gfx->flipBuffer();
-	_system->updateScreen();
-	_gfx->freeTexture(t);
+	_gfx->drawTexturedRect2D(rect, rect, _borderTexture, 1.0, false);
+	// _gfx->flipBuffer();
+	// _system->updateScreen();
+	// _gfx->freeTexture(t);
 }
 
 void FreescapeEngine::loadAssets() {
@@ -86,7 +88,7 @@ void FreescapeEngine::loadAssets() {
 	Common::String path = ConfMan.get("path");
 	Common::FSDirectory gameDir(path);
 
-	if (_targetName.hasPrefix("3dkit")) {
+	if (_targetName.hasPrefix("3dkit") || _targetName == "menace") {
 		Common::ArchiveMemberList files;
         gameDir.listMatchingMembers(files, "*.RUN");
 
@@ -145,6 +147,7 @@ Common::Error FreescapeEngine::run() {
 	area = (*_areasByAreaID)[_startArea];
 	assert(area);
 	entrance = (Entrance*) area->entranceWithID(_startEntrance);
+	area->show();
 	assert(entrance);
 	_position = entrance->getOrigin();
 	Math::Vector3d scaleVector;
@@ -222,6 +225,7 @@ Common::Error FreescapeEngine::run() {
 			}
 		}
 
+		//drawBorder();
 		_gfx->flipBuffer();
 		g_system->updateScreen();
 		g_system->delayMillis(10);
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 9c136363051..d6de611a6ad 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -62,8 +62,11 @@ public:
 
 	Renderer *_gfx;
 	Common::Error run() override;
+
+	// Border
 	void convertBorder();
 	void drawBorder();
+	Texture *_borderTexture;
 
 
 	// Parsing
@@ -95,7 +98,6 @@ public:
 	// Spacial attributes
 	Vector3d _position, _rotation, _velocity;
 
-
 	// Rendering
 	uint8 _colorNumber;
 
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index d189467fdf7..6cc66863089 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -142,6 +142,10 @@ public:
 	virtual void draw2DText(const Common::String &text, const Common::Point &position) = 0;
 	virtual void scale(const Math::Vector3d &scale) = 0;
 	virtual void renderCube(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) = 0;
+	virtual void renderRectangle(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) = 0;
+	virtual void renderPolygon(const Math::Vector3d &origin, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours) = 0;
+	virtual void renderFace(const Common::Array<Math::Vector3d> &vertices) = 0;
+
 	virtual void drawSky(uint8 color) = 0;
 	virtual void drawFloor(uint8 color) = 0;
 
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 6fc413b0e58..d8ceb0d8b60 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -76,6 +76,10 @@ void TinyGLRenderer::init() {
 	tglDisable(TGL_LIGHTING);
 	tglDisable(TGL_TEXTURE_2D);
 	tglEnable(TGL_DEPTH_TEST);
+
+	//tglColorMask(TGL_FALSE, TGL_FALSE, TGL_FALSE, TGL_FALSE);
+	//tglDisable(TGL_POLYGON_OFFSET_FILL);
+
 }
 
 void TinyGLRenderer::clear() {
@@ -200,6 +204,141 @@ void TinyGLRenderer::positionCamera(const Math::Vector3d &pos, const Math::Vecto
 	tglTranslatef(-pos.x(), -pos.y(), -pos.z());
 }
 
+
+void TinyGLRenderer::renderFace(const Common::Array<Math::Vector3d> &vertices) {
+	assert(vertices.size() >= 2);
+	const Math::Vector3d &v0 = vertices[0];
+
+	if (vertices.size() == 2) {
+		const Math::Vector3d &v1 = vertices[1];
+		if (v0 == v1)
+			return;
+		tglBegin(TGL_LINES);
+		tglVertex3f(v0.x(), v0.y(),	v0.z());
+		tglVertex3f(v1.x(), v1.y(),	v1.z());		
+		tglEnd();
+		return;
+	}
+
+	tglBegin(TGL_TRIANGLES);
+	for (int i = 1; i < vertices.size() - 1; i++) {
+		const Math::Vector3d &v1 = vertices[i];
+		const Math::Vector3d &v2 = vertices[i+1];
+		tglVertex3f(v0.x(), v0.y(),	v0.z());
+		tglVertex3f(v1.x(), v1.y(),	v1.z());
+		tglVertex3f(v2.x(), v2.y(),	v2.z()); 
+	}
+	tglEnd();
+}
+
+void TinyGLRenderer::renderPolygon(const Math::Vector3d &origin, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours) {
+	//assert(size.x() == 0 || size.y() == 0 || size.z() == 0);
+	uint8 r, g, b;
+	Common::Array<Math::Vector3d> vertices;
+	// tglEnable(TGL_POLYGON_OFFSET_FILL);
+	// tglEnable(TGL_POLYGON_OFFSET_LINE);
+	// tglEnable(TGL_POLYGON_OFFSET_POINT);
+	tglPolygonOffset(50.f, 50.f);
+	if ((*colours)[0] > 0) {
+		_palette->getRGBAt((*colours)[0], r, g, b);
+		tglColor3ub(r, g, b);
+		for (int i = 0; i < ordinates->size(); i = i + 3) {
+			vertices.push_back(Math::Vector3d(origin.x() + (*ordinates)[i], origin.y() + (*ordinates)[i + 1],	origin.z() + (*ordinates)[i + 2]));
+		}
+		renderFace(vertices);
+	}
+	vertices.clear();
+	if ((*colours)[1] > 0) {
+		_palette->getRGBAt((*colours)[1], r, g, b);
+		tglColor3ub(r, g, b);
+		for (int i = ordinates->size(); i > 0; i = i - 3) {
+			vertices.push_back(Math::Vector3d(origin.x() + (*ordinates)[i-3], origin.y() + (*ordinates)[i-2],	origin.z() + (*ordinates)[i-1]));
+		}
+		renderFace(vertices);
+	}
+	tglPolygonOffset(0, 0);
+	tglDisable(TGL_POLYGON_OFFSET_FILL);
+}
+
+void TinyGLRenderer::renderRectangle(const Math::Vector3d &origin, const Math::Vector3d &size, Common::Array<uint8> *colours) {
+
+	assert(size.x() == 0 || size.y() == 0 || size.z() == 0);
+
+	tglPolygonOffset(50, 50);
+	//debug("origin: %f, %f, %f", origin.x(), origin.y(), origin.z());
+	//debug("size: %f, %f, %f", size.x(), size.y(), size.z());
+	
+	float dx, dy, dz;
+	float offset = 0;
+	uint8 r, g, b;
+	Common::Array<Math::Vector3d> vertices;
+	for (int i = 0; i < 2; i++) { 
+		
+		//debug("rec color: %d", (*colours)[i]);
+		if ((*colours)[i] > 0) {
+			_palette->getRGBAt((*colours)[i], r, g, b);
+			tglColor3ub(r, g, b);
+			vertices.clear();
+			vertices.push_back(Math::Vector3d(origin.x(), origin.y(), origin.z()));
+
+			dx = dy = dz = 0;
+			if (size.x() == 0) {
+				dy = size.y();
+			} else if (size.y() == 0) {
+				dx = size.x();
+			} else if (size.z() == 0) {
+				dx = size.x();
+			}
+
+			vertices.push_back(Math::Vector3d(origin.x() + dx,	origin.y() + dy, origin.z() + dz));
+			vertices.push_back(Math::Vector3d(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z()));
+			renderFace(vertices);
+
+			vertices.clear();
+			vertices.push_back(Math::Vector3d(origin.x(), origin.y(), origin.z()));
+
+			dx = dy = dz = 0;
+			if (size.x() == 0) {
+				dz = size.z();
+			} else if (size.y() == 0) {
+				dz = size.z();
+			} else if (size.z() == 0) {
+				dy = size.y();
+			}
+
+			vertices.push_back(Math::Vector3d(origin.x() + dx,	origin.y() + dy, origin.z() + dz));
+			vertices.push_back(Math::Vector3d(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z()));
+			renderFace(vertices);
+
+			// tglBegin(TGL_TRIANGLES);
+			// tglVertex3f(origin.x(),	origin.y(),	origin.z());
+			// if (size.x() == 0)
+			// 	tglVertex3f(origin.x(),	origin.y() + size.y(), origin.z());
+			// else if (size.y() == 0)
+			// 	tglVertex3f(origin.x() + size.x(),	origin.y(), origin.z());
+			// else 
+			// 	tglVertex3f(origin.x() + size.x(),	origin.y(), origin.z());
+			// tglVertex3f(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z());
+
+			// tglVertex3f(origin.x(),	origin.y(),	origin.z());
+			// if (size.x() == 0)
+			// 	tglVertex3f(origin.x(),	origin.y(), origin.z()  + size.z());
+			// else if (size.y() == 0)
+			// 	tglVertex3f(origin.x() + size.x(),	origin.y(), origin.z() + size.y());
+			// else 
+			// 	tglVertex3f(origin.x(),	origin.y() + size.y(), origin.z());
+			// tglVertex3f(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z());
+			// tglEnd();
+		}
+	}
+
+	tglPolygonOffset(0, 0);
+	//tglDepthMask(TGL_TRUE);
+	//tglColorMask(TGL_FALSE, TGL_FALSE, TGL_FALSE, TGL_FALSE);
+	//tglDisable(TGL_POLYGON_OFFSET_FILL);
+}
+
+
 void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector3d &size, Common::Array<uint8> *colours) {
 	assert(size.x() > 0);
 	assert(size.y() > 0);
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index 0b8c5fcf998..a050ad98fd3 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -50,7 +50,13 @@ public:
 	virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture,
 	                                float transparency = -1.0, bool additiveBlending = false) override;
 	virtual void draw2DText(const Common::String &text, const Common::Point &position) override;
+
 	virtual void renderCube(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) override;
+	virtual void renderRectangle(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) override;
+	virtual void renderPolygon(const Math::Vector3d &origin, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours) override;
+    virtual void renderFace(const Common::Array<Math::Vector3d> &vertices) override;
+
+
 
 	virtual void flipBuffer() override;
 	virtual void drawSky(uint8 color) override;
diff --git a/engines/freescape/language/16bitDetokeniser.cpp b/engines/freescape/language/16bitDetokeniser.cpp
index 454506891b8..f50bb48e768 100644
--- a/engines/freescape/language/16bitDetokeniser.cpp
+++ b/engines/freescape/language/16bitDetokeniser.cpp
@@ -208,6 +208,7 @@ Common::String *detokenise16bitCondition(Common::Array<uint8> &tokenisedConditio
 
 		default:
 			detokenisedStream += "<UNKNOWN 16 bit: ";
+			detokenisedStream += Common::String::format("%x, ", (int)numberOfArguments);
 			detokenisedStream += Common::String::format("%x", (int)opcode);
 			detokenisedStream += " > ";
 			break;
diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
index 1a03a15ec45..a2550d75386 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/16bitBinaryLoader.cpp
@@ -101,15 +101,18 @@ static Object *load16bitObject(StreamLoader &stream) {
 
 		// grab the object condition, if there is one
 		FCLInstructionVector instructions;
-		// if (byteSizeOfObject > 0) {
+		if (byteSizeOfObject > 0) {
 		// 	uint32 offset = stream.getFileOffset();
-		// 	Common::Array<uint8> *conditionData = stream.nextBytes(byteSizeOfObject);
+		    Common::Array<uint8> *conditionData = stream.nextBytes(byteSizeOfObject);
 		// 	byteSizeOfObject = byteSizeOfObject - (offset - stream.getFileOffset());
 
-		// 	Common::String *conditionSource = detokenise16bitCondition(*conditionData);
-		// 	debug("Condition: %s", conditionSource->c_str());
+			Common::String *conditionSource = detokenise16bitCondition(*conditionData);
+		 	debug("Condition: %s", conditionSource->c_str());
+			byteSizeOfObject = 0;
 		// 	//instructions = getInstructions(conditionSource);
-		// }
+		}
+		// if (objectType == 11)
+		// 	error("triangle!");
 
 		debug("Skipping %d bytes", byteSizeOfObject);
 		stream.skipBytes(byteSizeOfObject);
@@ -233,6 +236,28 @@ Area *load16bitArea(StreamLoader &stream) {
 		}
 	}
 
+	uint16 numberOfLocalConditions = stream.get16();
+	debug("Number of conditions: %d", numberOfLocalConditions);
+	for (uint16 localCondition = 0; localCondition < numberOfLocalConditions; localCondition++) {
+		// 12 bytes for the name of the condition;
+		// we don't care
+		stream.skipBytes(12);
+
+		// get the length and the data itself, converting from
+		// shorts to bytes
+		uint32 lengthOfCondition = (uint32)stream.get16() << 1;
+		debug("Length of condition: %d", lengthOfCondition);
+		if (lengthOfCondition == 0) {
+			break;
+		}
+
+		// get the condition
+		Common::Array<uint8> *conditionData = stream.nextBytes(lengthOfCondition);
+
+		debug("Local condition %d at %x", localCondition + 1, stream.getFileOffset());
+		debug("%s", detokenise16bitCondition(*conditionData)->c_str());
+	}
+
 	return (new Area(areaNumber, objectsByID, entrancesByID, 1, skyColor, groundColor));
 }
 
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index 5a0b440baf7..c0349b6cef3 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -102,10 +102,13 @@ bool GeometricObject::isPlanar() {
 }
 
 void GeometricObject::draw(Freescape::Renderer *gfx) {
+	//debug("Drawing %d of type %d", this->getObjectID(), this->getType());
 	if (this->getType() == Cube) {
 		//debug("Drawing cube!");
 		gfx->renderCube(origin, size, colours);
-	} //else
-		//debug("Drawing something of type %d", this->getType());
-		
-};
\ No newline at end of file
+	} else if (this->getType() == Rectangle) {
+		gfx->renderRectangle(origin, size, colours);
+	} else if (this->isPlanar()) {
+		gfx->renderPolygon(origin, ordinates, colours);
+	}
+}
\ No newline at end of file


Commit: a2f764a61d103d00114cce19ac145f9f1a930b71
    https://github.com/scummvm/scummvm/commit/a2f764a61d103d00114cce19ac145f9f1a930b71
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:40+01:00

Commit Message:
FREESCAPE: better polygon rendering and object code refactoring

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/gfx_tinygl.h
    engines/freescape/loaders/16bitBinaryLoader.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/objects/entrance.cpp
    engines/freescape/objects/entrance.h
    engines/freescape/objects/geometricobject.cpp
    engines/freescape/objects/geometricobject.h
    engines/freescape/objects/object.cpp
    engines/freescape/objects/object.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 83f436e3f75..214b3076a3f 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -35,11 +35,11 @@ FreescapeEngine::FreescapeEngine(OSystem *syst)
 	// Do not initialize audio devices here
 	_hasReceivedTime = false;
 
-	_rotation = Vector3d(0.f, 0.f, 0.f);
-	_position = Vector3d(0.f, 0.f, 0.f);
-	_velocity = Vector3d(0.f, 0.f, 0.f);
-	_cameraFront = Vector3d(0.f, 0.f, 0.f);
-	_cameraRight = Vector3d(0.f, 0.f, 0.f);
+	_rotation = Math::Vector3d(0.f, 0.f, 0.f);
+	_position = Math::Vector3d(0.f, 0.f, 0.f);
+	_velocity = Math::Vector3d(0.f, 0.f, 0.f);
+	_cameraFront = Math::Vector3d(0.f, 0.f, 0.f);
+	_cameraRight = Math::Vector3d(0.f, 0.f, 0.f);
 	_movementSpeed = 4.5f;
 	_mouseSensitivity = 0.1f;
 	_scale = Math::Vector3d(0, 0, 0);
@@ -252,7 +252,7 @@ void FreescapeEngine::rotate(Common::Point lastMousePos, Common::Point mousePos)
 	if (_pitch < -180.0f)
 		_pitch = -180.0f;
 
-	Vector3d v;
+	Math::Vector3d v;
 	float x = cos(_yaw  * M_PI / 180.0) * cos(_pitch  * M_PI / 180.0);
 	float y = sin(_pitch * M_PI / 180.0);
 	float z = sin(_yaw * M_PI / 180.0) * cos(_pitch * M_PI / 180.0);
@@ -261,7 +261,7 @@ void FreescapeEngine::rotate(Common::Point lastMousePos, Common::Point mousePos)
 	_cameraFront = v;
 
 	// // _right = _front x _up;
-	Vector3d up(0, 1, 0); // this should be const
+	Math::Vector3d up(0, 1, 0); // this should be const
 	v = Math::Vector3d::crossProduct(_cameraFront, up);
 	v.normalize();
 	_cameraRight = v;
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index d6de611a6ad..96df68569fc 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -94,9 +94,9 @@ public:
 	// Camera options
 	float _mouseSensitivity;
 	float _movementSpeed;
-	Vector3d _cameraFront, _cameraUp, _cameraRight;
+	Math::Vector3d _cameraFront, _cameraUp, _cameraRight;
 	// Spacial attributes
-	Vector3d _position, _rotation, _velocity;
+	Math::Vector3d _position, _rotation, _velocity;
 
 	// Rendering
 	uint8 _colorNumber;
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 6cc66863089..00316882e56 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -143,7 +143,7 @@ public:
 	virtual void scale(const Math::Vector3d &scale) = 0;
 	virtual void renderCube(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) = 0;
 	virtual void renderRectangle(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) = 0;
-	virtual void renderPolygon(const Math::Vector3d &origin, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours) = 0;
+	virtual void renderPolygon(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours) = 0;
 	virtual void renderFace(const Common::Array<Math::Vector3d> &vertices) = 0;
 
 	virtual void drawSky(uint8 color) = 0;
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index d8ceb0d8b60..9d5f22f893c 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -231,9 +231,23 @@ void TinyGLRenderer::renderFace(const Common::Array<Math::Vector3d> &vertices) {
 	tglEnd();
 }
 
-void TinyGLRenderer::renderPolygon(const Math::Vector3d &origin, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours) {
+void TinyGLRenderer::renderPolygon(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours) {
 	//assert(size.x() == 0 || size.y() == 0 || size.z() == 0);
 	uint8 r, g, b;
+	float dx, dy, dz;
+	dx = dy = dz = 0;
+
+	if (size.x() == 0)
+		dx = 2;
+	else if (size.y() == 0)
+		dy = 2;
+	else if (size.z() == 0)
+		dz = 2;
+	else { 
+		if (ordinates->size() != 6)
+			error("Invalid polygon: %f %f %f", size.x(), size.y(), size.z());
+	}
+	
 	Common::Array<Math::Vector3d> vertices;
 	// tglEnable(TGL_POLYGON_OFFSET_FILL);
 	// tglEnable(TGL_POLYGON_OFFSET_LINE);
@@ -243,7 +257,7 @@ void TinyGLRenderer::renderPolygon(const Math::Vector3d &origin, const Common::A
 		_palette->getRGBAt((*colours)[0], r, g, b);
 		tglColor3ub(r, g, b);
 		for (int i = 0; i < ordinates->size(); i = i + 3) {
-			vertices.push_back(Math::Vector3d(origin.x() + (*ordinates)[i], origin.y() + (*ordinates)[i + 1],	origin.z() + (*ordinates)[i + 2]));
+			vertices.push_back(Math::Vector3d(origin.x() + (*ordinates)[i] + dx, origin.y() + (*ordinates)[i + 1] + dy,	origin.z() + (*ordinates)[i + 2] + dz));
 		}
 		renderFace(vertices);
 	}
@@ -252,7 +266,7 @@ void TinyGLRenderer::renderPolygon(const Math::Vector3d &origin, const Common::A
 		_palette->getRGBAt((*colours)[1], r, g, b);
 		tglColor3ub(r, g, b);
 		for (int i = ordinates->size(); i > 0; i = i - 3) {
-			vertices.push_back(Math::Vector3d(origin.x() + (*ordinates)[i-3], origin.y() + (*ordinates)[i-2],	origin.z() + (*ordinates)[i-1]));
+			vertices.push_back(Math::Vector3d(origin.x() + (*ordinates)[i-3] - dx, origin.y() + (*ordinates)[i-2] - dy,	origin.z() + (*ordinates)[i-1] - dz));
 		}
 		renderFace(vertices);
 	}
@@ -264,7 +278,7 @@ void TinyGLRenderer::renderRectangle(const Math::Vector3d &origin, const Math::V
 
 	assert(size.x() == 0 || size.y() == 0 || size.z() == 0);
 
-	tglPolygonOffset(50, 50);
+	tglPolygonOffset(250, 250);
 	//debug("origin: %f, %f, %f", origin.x(), origin.y(), origin.z());
 	//debug("size: %f, %f, %f", size.x(), size.y(), size.z());
 	
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index a050ad98fd3..31ac51d9599 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -53,7 +53,7 @@ public:
 
 	virtual void renderCube(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) override;
 	virtual void renderRectangle(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) override;
-	virtual void renderPolygon(const Math::Vector3d &origin, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours) override;
+	virtual void renderPolygon(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours) override;
     virtual void renderFace(const Common::Array<Math::Vector3d> &vertices) override;
 
 
diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
index a2550d75386..75587f25026 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/16bitBinaryLoader.cpp
@@ -48,7 +48,7 @@ static Object *load16bitObject(StreamLoader &stream) {
 	debug("skippedShort: %d", skippedShort);
 
 	// grab location, size
-	Vector3d position, size;
+	Math::Vector3d position, size;
 	position.x() = stream.get16();
 	position.y() = stream.get16();
 	position.z() = stream.get16();
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 26e0f3dd479..2fe39c12e5f 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -17,7 +17,7 @@ namespace Freescape {
 static Object *load8bitObject(StreamLoader &stream) {
 	
 	Object::Type objectType = (Object::Type)(stream.get8() & 0x1F);
-	Vector3d position, v;
+	Math::Vector3d position, v;
 
 	position.x() = stream.get8() * 32;
 	position.y() = stream.get8() * 32;
diff --git a/engines/freescape/objects/entrance.cpp b/engines/freescape/objects/entrance.cpp
index d5a6f2c7566..9736997f956 100644
--- a/engines/freescape/objects/entrance.cpp
+++ b/engines/freescape/objects/entrance.cpp
@@ -12,12 +12,12 @@
 #pragma mark Construction/Destruction
 
 Entrance::Entrance(
-	uint16 _objectID,
-	const Vector3d &_origin,
-	const Vector3d &_rotation) {
-	objectID = _objectID;
-	origin = _origin;
-	rotation = _rotation;
+	uint16 objectID,
+	const Math::Vector3d &origin,
+	const Math::Vector3d &rotation) {
+	_objectID = objectID;
+	_origin = origin;
+	_rotation = rotation;
 }
 
 Entrance::~Entrance() {}
diff --git a/engines/freescape/objects/entrance.h b/engines/freescape/objects/entrance.h
index 8fe86619436..a696de4d4e0 100644
--- a/engines/freescape/objects/entrance.h
+++ b/engines/freescape/objects/entrance.h
@@ -6,8 +6,8 @@
 //  Copyright (c) 2013 Thomas Harte. All rights reserved.
 //
 
-#ifndef __Phantasma__Entrance__
-#define __Phantasma__Entrance__
+#ifndef FREESCAPE_ENTRANCE_H
+#define FREESCAPE_ENTRANCE_H
 
 #include "freescape/objects/object.h"
 
@@ -16,17 +16,16 @@ public:
 
 	Entrance(
 		uint16 objectID,
-		const Vector3d &origin,
-		const Vector3d &rotation);
+		const Math::Vector3d &origin,
+		const Math::Vector3d &rotation);
 	virtual ~Entrance();
 
 	bool isDrawable();
 	bool isPlanar();
 	Type getType() override { return Type::Entrance; };
-	Vector3d getRotation() { return rotation; }
+	Math::Vector3d getRotation() { return _rotation; }
 	
 	void draw(Freescape::Renderer *gfx) override { error("cannot render Entrance"); };
 };
 
-
-#endif /* defined(__Phantasma__Entrance__) */
+#endif
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index c0349b6cef3..4b39c26e473 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -71,19 +71,19 @@ int GeometricObject::numberOfOrdinatesForType(Type type) {
 #pragma mark Construction/Destruction
 
 GeometricObject::GeometricObject(
-	Type _type,
-	uint16 _objectID,
-	uint16 _flags,
-	const Vector3d &_origin,
-	const Vector3d &_size,
+	Type type,
+	uint16 objectID,
+	uint16 flags,
+	const Math::Vector3d &origin,
+	const Math::Vector3d &size,
 	Common::Array<uint8> *_colours,
 	Common::Array<uint16> *_ordinates,
 	FCLInstructionVector _condition) {
-	type = _type;
-	flags = _flags;
-	objectID = _objectID;
-	origin = _origin;
-	size = _size;
+	_type = type;
+	_flags = flags;
+	_objectID = objectID;
+	_origin = origin;
+	_size = size;
 
 	if (_colours)
 		colours = new Common::Array<uint8>(*_colours);
@@ -98,17 +98,18 @@ GeometricObject::~GeometricObject() {
 bool GeometricObject::isDrawable() { return true; }
 bool GeometricObject::isPlanar() {
 	Type type = this->getType();
-	return (type >= Object::Line) || !size.x() || !size.y() || !size.z();
+	return (type >= Object::Line) || !_size.x() || !_size.y() || !_size.z();
 }
 
 void GeometricObject::draw(Freescape::Renderer *gfx) {
 	//debug("Drawing %d of type %d", this->getObjectID(), this->getType());
 	if (this->getType() == Cube) {
 		//debug("Drawing cube!");
-		gfx->renderCube(origin, size, colours);
+		gfx->renderCube(_origin, _size, colours);
 	} else if (this->getType() == Rectangle) {
-		gfx->renderRectangle(origin, size, colours);
+		gfx->renderRectangle(_origin, _size, colours);
 	} else if (this->isPlanar()) {
-		gfx->renderPolygon(origin, ordinates, colours);
+		//debug("Drawing %d of type %d", this->getObjectID(), this->getType());
+		gfx->renderPolygon(_origin, _size, ordinates, colours);
 	}
 }
\ No newline at end of file
diff --git a/engines/freescape/objects/geometricobject.h b/engines/freescape/objects/geometricobject.h
index 4b41213920f..833e63d9be1 100644
--- a/engines/freescape/objects/geometricobject.h
+++ b/engines/freescape/objects/geometricobject.h
@@ -22,8 +22,8 @@ public:
 		Type type,
 		uint16 objectID,
 		uint16 flags,
-		const Vector3d &origin,
-		const Vector3d &size,
+		const Math::Vector3d &origin,
+		const Math::Vector3d &size,
 		Common::Array<uint8> *colours,
 		Common::Array<uint16> *ordinates,
 		FCLInstructionVector condition);
diff --git a/engines/freescape/objects/object.cpp b/engines/freescape/objects/object.cpp
index 87d0eb631f7..fb6921f86f6 100644
--- a/engines/freescape/objects/object.cpp
+++ b/engines/freescape/objects/object.cpp
@@ -10,11 +10,11 @@
 #include "freescape/freescape.h"
 #include "freescape/gfx.h"
 
-Object::Type Object::getType() { return type; }
-uint16 Object::getObjectID() { return objectID; }
-uint16 Object::getObjectFlags() { return flags; }
-Vector3d Object::getOrigin() { return origin; }
-Vector3d Object::getSize() { return size; }
+Object::Type Object::getType() { return _type; }
+uint16 Object::getObjectID() { return _objectID; }
+uint16 Object::getObjectFlags() { return _flags; }
+Math::Vector3d Object::getOrigin() { return _origin; }
+Math::Vector3d Object::getSize() { return _size; }
 
 //void Object::draw(Freescape::Renderer *gfx) {
 //	gfx;
diff --git a/engines/freescape/objects/object.h b/engines/freescape/objects/object.h
index 1997fe146bb..8c6c5418886 100644
--- a/engines/freescape/objects/object.h
+++ b/engines/freescape/objects/object.h
@@ -6,20 +6,14 @@
 //  Copyright (c) 2013 Thomas Harte. All rights reserved.
 //
 
-#ifndef __Phantasma__Object__
-#define __Phantasma__Object__
+#ifndef FREESCAPE_OBJECT_H
+#define FREESCAPE_OBJECT_H
 
 #include "common/system.h"
 #include "math/vector3d.h"
 
 #include "freescape/gfx.h"
 
-
-typedef Math::Vector3d Vector3d;
-
-class VertexBuffer;
-class DrawElementsBuffer;
-class BatchDrawer;
 class Object {
 public:
 	typedef enum {
@@ -47,22 +41,21 @@ public:
 	virtual Type getType();
 	uint16 getObjectID();
 	uint16 getObjectFlags();
-	Vector3d getOrigin();
-	Vector3d getSize();
+	Math::Vector3d getOrigin();
+	Math::Vector3d getSize();
 
 	virtual void draw(Freescape::Renderer *gfx) = 0;
 
 	virtual bool isDrawable();
 	virtual bool isPlanar();
-	bool isInvisible() { return flags & 0x4; }
+	bool isInvisible() { return _flags & 0x4; }
 
 	virtual ~Object();
 
-protected:
-	uint16 flags;
-	Type type;
-	uint16 objectID;
-	Vector3d origin, size, rotation;
+	uint16 _flags;
+	Type _type;
+	uint16 _objectID;
+	Math::Vector3d _origin, _size, _rotation;
 };
 
-#endif /* defined(__Phantasma__Object__) */
+#endif


Commit: 4594050af586cee8e36f0a45512f78b704f9f4f3
    https://github.com/scummvm/scummvm/commit/4594050af586cee8e36f0a45512f78b704f9f4f3
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:40+01:00

Commit Message:
FREESCAPE: fixes regarding tinygl changes upstream

Changed paths:
    engines/freescape/freescape.h
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/gfx_tinygl.h
    engines/freescape/gfx_tinygl_texture.cpp
    engines/freescape/gfx_tinygl_texture.h


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 96df68569fc..099cf4be4b0 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -6,7 +6,7 @@
 #include "engines/engine.h"
 #include "graphics/palette.h"
 #include "graphics/surface.h"
-#include "graphics/pixelbuffer.h"
+#include "graphics/tinygl/pixelbuffer.h"
 #include "gui/debugger.h"
 
 #include "freescape/area.h"
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 00316882e56..418e9c3c540 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -29,6 +29,7 @@
 #include "math/frustum.h"
 #include "math/matrix4.h"
 #include "math/vector3d.h"
+#include "graphics/tinygl/pixelbuffer.h"
 
 namespace Freescape {
 
@@ -183,7 +184,7 @@ public:
 	static const int kFrameHeight = 200;
 
 	void computeScreenViewport();
-	
+
 
 protected:
 	OSystem *_system;
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 9d5f22f893c..cf0d18601ee 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -33,7 +33,7 @@
 #include "engines/freescape/gfx.h"
 #include "engines/freescape/gfx_tinygl.h"
 #include "engines/freescape/gfx_tinygl_texture.h"
-#include "graphics/tinygl/zblit.h"
+#include "graphics/tinygl/tinygl.h"
 
 namespace Freescape {
 
@@ -41,9 +41,7 @@ Renderer *CreateGfxTinyGL(OSystem *system) {
 	return new TinyGLRenderer(system);
 }
 
-TinyGLRenderer::TinyGLRenderer(OSystem *system) :
-		Renderer(system),
-		_fb(NULL) {
+TinyGLRenderer::TinyGLRenderer(OSystem *system) : Renderer(system) {
 }
 
 TinyGLRenderer::~TinyGLRenderer() {
@@ -63,9 +61,10 @@ void TinyGLRenderer::init() {
 
 	computeScreenViewport();
 
-	_fb = new TinyGL::FrameBuffer(kOriginalWidth, kOriginalHeight, g_system->getScreenFormat());
-	TinyGL::glInit(_fb, 512);
-	tglEnableDirtyRects(ConfMan.getBool("dirtyrects"));
+	//_fb = new TinyGL::FrameBuffer(kOriginalWidth, kOriginalHeight, g_system->getScreenFormat(), true);
+	TinyGL::createContext(kOriginalWidth, kOriginalHeight, g_system->getScreenFormat(), 512, true, ConfMan.getBool("dirtyrects"));
+	//TinyGL::glInit(_fb, 512);
+	//tglEnableDirtyRects(ConfMan.getBool("dirtyrects"));
 
 	tglMatrixMode(TGL_PROJECTION);
 	tglLoadIdentity();
@@ -87,7 +86,7 @@ void TinyGLRenderer::clear() {
 	tglColor3f(1.0f, 1.0f, 1.0f);
 }
 
-void TinyGLRenderer::drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint8 g, uint8 b) {	
+void TinyGLRenderer::drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint8 g, uint8 b) {
 	tglDisable(TGL_TEXTURE_2D);
 	tglColor3ub(r, g, b);
 
@@ -131,7 +130,7 @@ void TinyGLRenderer::drawTexturedRect2D(const Common::Rect &screenRect, const Co
 	tglEnable(TGL_TEXTURE_2D);
 	tglDepthMask(TGL_FALSE);
 
-	Graphics::BlitTransform transform(sLeft + viewPort[0], sTop + viewPort[1]);
+	TinyGL::BlitTransform transform(sLeft + viewPort[0], sTop + viewPort[1]);
 	transform.sourceRectangle(textureRect.left, textureRect.top, sWidth, sHeight);
 	transform.tint(transparency);
 	tglBlit(((TinyGLTexture *)texture)->getBlitTexture(), transform);
@@ -164,10 +163,10 @@ void TinyGLRenderer::draw2DText(const Common::String &text, const Common::Point
 		int w = textureRect.width();
 		int h = textureRect.height();
 
-		Graphics::BlitTransform transform(x, y);
+		TinyGL::BlitTransform transform(x, y);
 		transform.sourceRectangle(textureRect.left, textureRect.top, w, h);
 		transform.flip(true, false);
-		Graphics::tglBlit(glFont->getBlitTexture(), transform);
+		//TinyGL::tglBlit(glFont->getBlitTexture(), transform);
 
 		x += textureRect.width() - 3;
 	}
@@ -215,7 +214,7 @@ void TinyGLRenderer::renderFace(const Common::Array<Math::Vector3d> &vertices) {
 			return;
 		tglBegin(TGL_LINES);
 		tglVertex3f(v0.x(), v0.y(),	v0.z());
-		tglVertex3f(v1.x(), v1.y(),	v1.z());		
+		tglVertex3f(v1.x(), v1.y(),	v1.z());
 		tglEnd();
 		return;
 	}
@@ -226,7 +225,7 @@ void TinyGLRenderer::renderFace(const Common::Array<Math::Vector3d> &vertices) {
 		const Math::Vector3d &v2 = vertices[i+1];
 		tglVertex3f(v0.x(), v0.y(),	v0.z());
 		tglVertex3f(v1.x(), v1.y(),	v1.z());
-		tglVertex3f(v2.x(), v2.y(),	v2.z()); 
+		tglVertex3f(v2.x(), v2.y(),	v2.z());
 	}
 	tglEnd();
 }
@@ -243,16 +242,16 @@ void TinyGLRenderer::renderPolygon(const Math::Vector3d &origin, const Math::Vec
 		dy = 2;
 	else if (size.z() == 0)
 		dz = 2;
-	else { 
+	else {
 		if (ordinates->size() != 6)
 			error("Invalid polygon: %f %f %f", size.x(), size.y(), size.z());
 	}
-	
+
 	Common::Array<Math::Vector3d> vertices;
-	// tglEnable(TGL_POLYGON_OFFSET_FILL);
+	tglEnable(TGL_POLYGON_OFFSET_FILL);
 	// tglEnable(TGL_POLYGON_OFFSET_LINE);
 	// tglEnable(TGL_POLYGON_OFFSET_POINT);
-	tglPolygonOffset(50.f, 50.f);
+	tglPolygonOffset(1.f, 1.f);
 	if ((*colours)[0] > 0) {
 		_palette->getRGBAt((*colours)[0], r, g, b);
 		tglColor3ub(r, g, b);
@@ -281,13 +280,13 @@ void TinyGLRenderer::renderRectangle(const Math::Vector3d &origin, const Math::V
 	tglPolygonOffset(250, 250);
 	//debug("origin: %f, %f, %f", origin.x(), origin.y(), origin.z());
 	//debug("size: %f, %f, %f", size.x(), size.y(), size.z());
-	
+
 	float dx, dy, dz;
 	float offset = 0;
 	uint8 r, g, b;
 	Common::Array<Math::Vector3d> vertices;
-	for (int i = 0; i < 2; i++) { 
-		
+	for (int i = 0; i < 2; i++) {
+
 		//debug("rec color: %d", (*colours)[i]);
 		if ((*colours)[i] > 0) {
 			_palette->getRGBAt((*colours)[i], r, g, b);
@@ -330,7 +329,7 @@ void TinyGLRenderer::renderRectangle(const Math::Vector3d &origin, const Math::V
 			// 	tglVertex3f(origin.x(),	origin.y() + size.y(), origin.z());
 			// else if (size.y() == 0)
 			// 	tglVertex3f(origin.x() + size.x(),	origin.y(), origin.z());
-			// else 
+			// else
 			// 	tglVertex3f(origin.x() + size.x(),	origin.y(), origin.z());
 			// tglVertex3f(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z());
 
@@ -339,7 +338,7 @@ void TinyGLRenderer::renderRectangle(const Math::Vector3d &origin, const Math::V
 			// 	tglVertex3f(origin.x(),	origin.y(), origin.z()  + size.z());
 			// else if (size.y() == 0)
 			// 	tglVertex3f(origin.x() + size.x(),	origin.y(), origin.z() + size.y());
-			// else 
+			// else
 			// 	tglVertex3f(origin.x(),	origin.y() + size.y(), origin.z());
 			// tglVertex3f(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z());
 			// tglEnd();
@@ -439,7 +438,7 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 
 	// Face 0
 	if ((*colours)[5] > 0) {
-		_palette->getRGBAt((*colours)[5], r, g, b);	
+		_palette->getRGBAt((*colours)[5], r, g, b);
 		tglColor3ub(r, g, b);
 		tglBegin(TGL_TRIANGLES);
 		tglVertex3f(origin.x(),		        origin.y(),				origin.z() + size.z());
@@ -473,9 +472,18 @@ void TinyGLRenderer::drawFloor(uint8 color) {
 }
 
 void TinyGLRenderer::flipBuffer() {
-	TinyGL::tglPresentBuffer();
-	g_system->copyRectToScreen(_fb->getPixelBuffer(), _fb->linesize,
-	                           0, 0, _fb->xsize, _fb->ysize);
+	Common::List<Common::Rect> dirtyAreas;
+	TinyGL::presentBuffer(dirtyAreas);
+
+	Graphics::Surface glBuffer;
+	TinyGL::getSurfaceRef(glBuffer);
+
+	if (!dirtyAreas.empty()) {
+		for (Common::List<Common::Rect>::iterator itRect = dirtyAreas.begin(); itRect != dirtyAreas.end(); ++itRect) {
+			g_system->copyRectToScreen(glBuffer.getBasePtr((*itRect).left, (*itRect).top), glBuffer.pitch,
+			                           (*itRect).left, (*itRect).top, (*itRect).width(), (*itRect).height());
+		}
+	}
 }
 
 } // End of namespace Myst3
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index 31ac51d9599..76eebbe758f 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -56,14 +56,9 @@ public:
 	virtual void renderPolygon(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours) override;
     virtual void renderFace(const Common::Array<Math::Vector3d> &vertices) override;
 
-
-
 	virtual void flipBuffer() override;
 	virtual void drawSky(uint8 color) override;
 	virtual void drawFloor(uint8 color) override;
-
-private:
-	TinyGL::FrameBuffer *_fb;
 };
 
 } // End of namespace Myst3
diff --git a/engines/freescape/gfx_tinygl_texture.cpp b/engines/freescape/gfx_tinygl_texture.cpp
index 493bd53d9f4..bdb55c69aca 100644
--- a/engines/freescape/gfx_tinygl_texture.cpp
+++ b/engines/freescape/gfx_tinygl_texture.cpp
@@ -48,7 +48,7 @@ TinyGLTexture::TinyGLTexture(const Graphics::Surface *surface) {
 	// NOTE: TinyGL doesn't have issues with white lines so doesn't need use TGL_CLAMP_TO_EDGE
 	tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_WRAP_S, TGL_REPEAT);
 	tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_WRAP_T, TGL_REPEAT);
-	_blitImage = Graphics::tglGenBlitImage();
+	_blitImage = tglGenBlitImage();
 
 	update(surface);
 }
@@ -62,7 +62,7 @@ void TinyGLTexture::update(const Graphics::Surface *surface) {
 	tglBindTexture(TGL_TEXTURE_2D, id);
 	tglTexImage2D(TGL_TEXTURE_2D, 0, 3, width, height, 0,
 			internalFormat, sourceFormat, const_cast<void *>(surface->getPixels())); // TESTME: Not sure if it works.
-	Graphics::tglUploadBlitImage(_blitImage, *surface, 0, false);
+	tglUploadBlitImage(_blitImage, *surface, 0, false);
 }
 
 void TinyGLTexture::updatePartial(const Graphics::Surface *surface, const Common::Rect &rect) {
@@ -70,7 +70,7 @@ void TinyGLTexture::updatePartial(const Graphics::Surface *surface, const Common
 	update(surface);
 }
 
-Graphics::BlitImage *TinyGLTexture::getBlitTexture() const {
+TinyGL::BlitImage *TinyGLTexture::getBlitTexture() const {
 	return _blitImage;
 }
 
diff --git a/engines/freescape/gfx_tinygl_texture.h b/engines/freescape/gfx_tinygl_texture.h
index 78f29e26621..86815298c8e 100644
--- a/engines/freescape/gfx_tinygl_texture.h
+++ b/engines/freescape/gfx_tinygl_texture.h
@@ -37,7 +37,7 @@ public:
 	TinyGLTexture(const Graphics::Surface *surface);
 	virtual ~TinyGLTexture();
 
-	Graphics::BlitImage *getBlitTexture() const;
+	TinyGL::BlitImage *getBlitTexture() const;
 
 	void update(const Graphics::Surface *surface) override;
 	void updatePartial(const Graphics::Surface *surface, const Common::Rect &rect) override;
@@ -46,7 +46,7 @@ public:
 	TGLuint internalFormat;
 	TGLuint sourceFormat;
 private:
-	Graphics::BlitImage *_blitImage;
+	TinyGL::BlitImage *_blitImage;
 };
 
 } // End of namespace Myst3


Commit: 2045ecfb814f438b876860d88cbc96de3fc339fe
    https://github.com/scummvm/scummvm/commit/2045ecfb814f438b876860d88cbc96de3fc339fe
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:40+01:00

Commit Message:
FREESCAPE: removed some old code and add call to destroyContext

Changed paths:
    engines/freescape/gfx_tinygl.cpp


diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index cf0d18601ee..c13b7a830cd 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -45,6 +45,7 @@ TinyGLRenderer::TinyGLRenderer(OSystem *system) : Renderer(system) {
 }
 
 TinyGLRenderer::~TinyGLRenderer() {
+	TinyGL::destroyContext();
 }
 
 Texture *TinyGLRenderer::createTexture(const Graphics::Surface *surface) {
@@ -61,10 +62,7 @@ void TinyGLRenderer::init() {
 
 	computeScreenViewport();
 
-	//_fb = new TinyGL::FrameBuffer(kOriginalWidth, kOriginalHeight, g_system->getScreenFormat(), true);
 	TinyGL::createContext(kOriginalWidth, kOriginalHeight, g_system->getScreenFormat(), 512, true, ConfMan.getBool("dirtyrects"));
-	//TinyGL::glInit(_fb, 512);
-	//tglEnableDirtyRects(ConfMan.getBool("dirtyrects"));
 
 	tglMatrixMode(TGL_PROJECTION);
 	tglLoadIdentity();


Commit: b8c4488cde4ee51e88125cfeedf53a2defdd0366
    https://github.com/scummvm/scummvm/commit/b8c4488cde4ee51e88125cfeedf53a2defdd0366
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:40+01:00

Commit Message:
FREESCAPE: removed more old code

Changed paths:
    engines/freescape/gfx.cpp
    engines/freescape/gfx.h


diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index 91aaa9d6398..418fab6a487 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -99,9 +99,6 @@ Common::Rect Renderer::rviewport() const {
 void Renderer::computeScreenViewport() {
 	int32 screenWidth = _system->getWidth();
 	int32 screenHeight = _system->getHeight();
-	int32 tmargin = 0; //27;
-	int32 vmargin = 0; //40;
-	int32 bmargin = 0; //90;
 
 	//assert(0);
 
@@ -115,8 +112,7 @@ void Renderer::computeScreenViewport() {
 		//_rscreenViewport = Common::Rect(vmargin, tmargin, _screenViewport.right - vmargin, _screenViewport.bottom - bmargin);
 
 		// Pillarboxing
-		//_screenViewport.translate((screenWidth - viewportWidth) / 2,
-		//	(screenHeight - viewportHeight) / 2);
+		_screenViewport.translate((screenWidth - viewportWidth) / 2, (screenHeight - viewportHeight) / 2);
 	//}
 }
 
@@ -170,69 +166,6 @@ Renderer *createRenderer(OSystem *system) {
 	error("Unable to create a '%s' renderer", rendererConfig.c_str());
 }
 
-void Renderer::renderDrawable(Drawable *drawable, Window *window) {
-	// if (drawable->isConstrainedToWindow()) {
-	// 	selectTargetWindow(window, drawable->is3D(), drawable->isScaled());
-	// } else {
-	// 	selectTargetWindow(nullptr, drawable->is3D(), drawable->isScaled());
-	// }
-	// drawable->draw();
-}
-
-void Renderer::renderDrawableOverlay(Drawable *drawable, Window *window) {
-	// // Overlays are always 2D
-	// if (drawable->isConstrainedToWindow()) {
-	// 	selectTargetWindow(window, drawable->is3D(), drawable->isScaled());
-	// } else {
-	// 	selectTargetWindow(nullptr, drawable->is3D(), drawable->isScaled());
-	// }
-	// drawable->drawOverlay();
-}
-
-void Renderer::renderWindow(Window *window) {
-	renderDrawable(window, window);
-}
-
-void Renderer::renderWindowOverlay(Window *window) {
-	renderDrawableOverlay(window, window);
-}
-
-Drawable::Drawable() :
-		_isConstrainedToWindow(true),
-		_is3D(false),
-		_scaled(true) {
-}
-
-Common::Point Window::getCenter() const {
-	Common::Rect frame = getPosition();
-
-	return Common::Point((frame.left + frame.right) / 2, (frame.top + frame.bottom) / 2);
-}
-
-Common::Point Window::screenPosToWindowPos(const Common::Point &screen) const {
-	Common::Rect frame = getPosition();
-
-	return Common::Point(screen.x - frame.left, screen.y - frame.top);
-}
-
-Common::Point Window::scalePoint(const Common::Point &screen) const {
-	Common::Rect viewport = getPosition();
-	Common::Rect originalViewport = getOriginalPosition();
-
-	Common::Point scaledPosition = screen;
-	scaledPosition.x -= viewport.left;
-	scaledPosition.y -= viewport.top;
-	scaledPosition.x = CLIP<int16>(scaledPosition.x, 0, viewport.width());
-	scaledPosition.y = CLIP<int16>(scaledPosition.y, 0, viewport.height());
-
-	if (_scaled) {
-		scaledPosition.x *= originalViewport.width() / (float) viewport.width();
-		scaledPosition.y *= originalViewport.height() / (float) viewport.height();
-	}
-
-	return scaledPosition;
-}
-
 FrameLimiter::FrameLimiter(OSystem *system, const uint framerate) :
 	_system(system),
 	_speedLimitMs(0),
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 418e9c3c540..8a81808ee86 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -35,63 +35,6 @@ namespace Freescape {
 
 class Renderer;
 
-class Drawable {
-public:
-	Drawable();
-	virtual ~Drawable() {}
-
-	virtual void draw() {}
-	virtual void drawOverlay() {}
-
-	/** Should the drawable be drawn inside the active window, or is it allowed to draw on the entire screen? */
-	bool isConstrainedToWindow() const { return _isConstrainedToWindow; }
-
-	/** Whether to setup the renderer state for 2D or 3D when processing the drawable */
-	bool is3D() const { return _is3D; }
-
-	/** Whether to scale the drawable to a size equivalent to the original engine or to draw it at its native size */
-	bool isScaled() const { return _scaled; }
-
-protected:
-	bool _isConstrainedToWindow;
-	bool _is3D;
-	bool _scaled;
-};
-
-/**
- * Game screen window
- *
- * A window represents a game screen pane.
- * It allows abstracting the rendering position from the behavior.
- */
-class Window : public Drawable {
-public:
-	/**
-	 * Get the window position in screen coordinates
-	 */
-	virtual Common::Rect getPosition() const = 0;
-
-	/**
-	 * Get the window position in original (640x480) screen coordinates
-	 */
-	virtual Common::Rect getOriginalPosition() const = 0;
-
-	/**
-	 * Get the window center in screen coordinates
-	 */
-	Common::Point getCenter() const;
-
-	/**
-	 * Convert screen coordinates to window coordinates
-	 */
-	Common::Point screenPosToWindowPos(const Common::Point &screen) const;
-
-	/**
-	 * Transform a point from screen coordinates to scaled window coordinates
-	 */
-	Common::Point scalePoint(const Common::Point &screen) const;
-};
-
 class Texture {
 public:
 	uint width;
@@ -150,18 +93,6 @@ public:
 	virtual void drawSky(uint8 color) = 0;
 	virtual void drawFloor(uint8 color) = 0;
 
-	/** Render a Drawable in the specified window */
-	void renderDrawable(Drawable *drawable, Window *window);
-
-	/** Render a Drawable overlay in the specified window */
-	void renderDrawableOverlay(Drawable *drawable, Window *window);
-
-	/** Render the main Drawable of a Window */
-	void renderWindow(Window *window);
-
-	/** Render the main Drawable overlay of a Window */
-	void renderWindowOverlay(Window *window);
-
 	Common::Rect viewport() const;
 	Common::Rect rviewport() const;
 	Graphics::PixelBuffer *_palette = nullptr;


Commit: edcfe272ce9f36ba436911fe246316b29be48e93
    https://github.com/scummvm/scummvm/commit/edcfe272ce9f36ba436911fe246316b29be48e93
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:41+01:00

Commit Message:
FREESCAPE: removed more old code

Changed paths:
    engines/freescape/gfx.cpp


diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index 418fab6a487..935aafb5e34 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -100,8 +100,6 @@ void Renderer::computeScreenViewport() {
 	int32 screenWidth = _system->getWidth();
 	int32 screenHeight = _system->getHeight();
 
-	//assert(0);
-
 	/*if (ConfMan.getBool("widescreen_mod")) {
 		_screenViewport = Common::Rect(screenWidth, screenHeight);
 	} else {*/
@@ -166,36 +164,4 @@ Renderer *createRenderer(OSystem *system) {
 	error("Unable to create a '%s' renderer", rendererConfig.c_str());
 }
 
-FrameLimiter::FrameLimiter(OSystem *system, const uint framerate) :
-	_system(system),
-	_speedLimitMs(0),
-	_startFrameTime(0) {
-	// The frame limiter is disabled when vsync is enabled.
-	_enabled = !_system->getFeatureState(OSystem::kFeatureVSync) && framerate != 0;
-
-	if (_enabled) {
-		_speedLimitMs = 1000 / CLIP<uint>(framerate, 0, 100);
-	}
-}
-
-void FrameLimiter::startFrame() {
-	_startFrameTime = _system->getMillis();
-}
-
-void FrameLimiter::delayBeforeSwap() {
-	uint endFrameTime = _system->getMillis();
-	uint frameDuration = endFrameTime - _startFrameTime;
-
-	if (_enabled && frameDuration < _speedLimitMs) {
-		_system->delayMillis(_speedLimitMs - frameDuration);
-	}
-}
-
-const Graphics::PixelFormat Texture::getRGBAPixelFormat() {
-#ifdef SCUMM_BIG_ENDIAN
-	return Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
-#else
-	return Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24);
-#endif
-}
 } // End of namespace Myst3


Commit: 99c19f34416d5d6473aa628332bc1d51a3c7d5e3
    https://github.com/scummvm/scummvm/commit/99c19f34416d5d6473aa628332bc1d51a3c7d5e3
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:41+01:00

Commit Message:
FREESCAPE: refactor drawing code into drawFrame

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 214b3076a3f..9e27153ab0d 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -106,7 +106,7 @@ void FreescapeEngine::loadAssets() {
 		else
 			renderMode = ConfMan.get("render_mode");
 
-		Common::File exe;	
+		Common::File exe;
 		debug("renderMode: %s", renderMode.c_str());
 		bool success = false;
 		if (renderMode == "ega") {
@@ -132,6 +132,13 @@ void FreescapeEngine::loadAssets() {
 
 }
 
+void FreescapeEngine::drawFrame(Math::Vector3d scaleVector, Area *area) {
+	_gfx->updateProjectionMatrix(60.0, _nearClipPlane, _farClipPlane);
+	_gfx->positionCamera(_position, _position + _cameraFront);
+	_gfx->scale(scaleVector);
+	area->draw(_gfx);
+}
+
 Common::Error FreescapeEngine::run() {
 	// Initialize graphics:
 	_gfx = Freescape::createRenderer(_system);
@@ -159,7 +166,7 @@ Common::Error FreescapeEngine::run() {
 	debug("scale: %f, %f, %f", scaleVector.x(), scaleVector.y(), scaleVector.z());
 	_position.setValue(1, _position.y() + _playerHeight);
 
-	Math::Vector3d rotation = entrance->getRotation(); 
+	Math::Vector3d rotation = entrance->getRotation();
 	_pitch = rotation.x() - 180.f;
 	_yaw = rotation.y() - 180.f;
 
@@ -169,23 +176,19 @@ Common::Error FreescapeEngine::run() {
 	Common::Point lastMousePos(0, 0);
 	float lastFrame = 0.f;
 	// used to create a projection matrix;
-	float nearClipPlane = 1.f;
-	float farClipPlane;
+	_nearClipPlane = 1.f;
 
 	if (_binaryBits == 16) {
 		// the 16-bit kit permits the range 0-8192 to be used along all three axes and from that comes the far plane distance of 14189.
-		farClipPlane = 14189.f;
+		_farClipPlane = 14189.f;
 	} else {
-		farClipPlane = 1024.f; // wild guess
+		_farClipPlane = 1024.f; // wild guess
 	}
 
 	//g_system->lockMouse(true);
 
 	while (!shouldQuit()) {
-		_gfx->updateProjectionMatrix(60.0, nearClipPlane, farClipPlane);
-		_gfx->positionCamera(_position, _position + _cameraFront);
-		_gfx->scale(scaleVector);
-		area->draw(_gfx);
+		drawFrame(scaleVector, area);
         float currentFrame = g_system->getMillis();
         float deltaTime = currentFrame - lastFrame;
         lastFrame = currentFrame;
@@ -209,7 +212,7 @@ Common::Error FreescapeEngine::run() {
 			case Common::EVENT_RETURN_TO_LAUNCHER:
 				return Common::kNoError;
 				break;
-			
+
 			case Common::EVENT_MOUSEMOVE:
 				rotate(lastMousePos, mousePos);
 				lastMousePos = mousePos;
@@ -217,7 +220,7 @@ Common::Error FreescapeEngine::run() {
 					g_system->warpMouse(_screenW/2, mousePos.y);
 					lastMousePos.x = _screenW/2;
 					lastMousePos.y = mousePos.y;
-				} 
+				}
 				break;
 			default:
 				break;
@@ -234,7 +237,6 @@ Common::Error FreescapeEngine::run() {
 	return Common::kNoError;
 }
 
-
 void FreescapeEngine::rotate(Common::Point lastMousePos, Common::Point mousePos) {
 	//debug("x: %d, y: %d", mousePos.x, mousePos.y);
 	float xoffset = mousePos.x - lastMousePos.x;
@@ -269,7 +271,7 @@ void FreescapeEngine::rotate(Common::Point lastMousePos, Common::Point mousePos)
 
 void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTime) {
 	float velocity = _movementSpeed * deltaTime;
-	float positionY = _position.y(); 
+	float positionY = _position.y();
 	switch (direction) {
 	case FORWARD:
 		_position = _position + _cameraFront * velocity;
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 099cf4be4b0..8bce6a7af86 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -30,7 +30,7 @@ typedef Common::HashMap<uint16, Area *> AreaMap;
 
 typedef struct Binary {
 	uint8 bits;
-	uint16 startArea; 
+	uint16 startArea;
 	AreaMap *areasByAreaID;
 	Common::Array<uint8> *border;
 	Common::Array<uint8> *palette;
@@ -52,7 +52,7 @@ private:
 	int _screenW, _screenH;
 
 	Graphics::Surface *_border;
-	
+
 	uint32 _timeOfLastTick;
 	bool _hasReceivedTime;
 
@@ -98,8 +98,12 @@ public:
 	// Spacial attributes
 	Math::Vector3d _position, _rotation, _velocity;
 
+
 	// Rendering
+	void drawFrame(Math::Vector3d scaleVector, Area *area);
 	uint8 _colorNumber;
+	float _nearClipPlane;
+	float _farClipPlane;
 
 	bool hasFeature(EngineFeature f) const override;
 	bool canLoadGameStateCurrently() override { return true; }


Commit: 43166fbb39e418ed340f2885327023413bf44e5b
    https://github.com/scummvm/scummvm/commit/43166fbb39e418ed340f2885327023413bf44e5b
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:41+01:00

Commit Message:
FREESCAPE: refactor input into processInput

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 9e27153ab0d..3a9ead37e75 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -132,13 +132,55 @@ void FreescapeEngine::loadAssets() {
 
 }
 
-void FreescapeEngine::drawFrame(Math::Vector3d scaleVector, Area *area) {
+void FreescapeEngine::drawFrame(Area *area) {
 	_gfx->updateProjectionMatrix(60.0, _nearClipPlane, _farClipPlane);
 	_gfx->positionCamera(_position, _position + _cameraFront);
-	_gfx->scale(scaleVector);
+	_gfx->scale(_scaleVector);
 	area->draw(_gfx);
 }
 
+void FreescapeEngine::processInput() {
+	float currentFrame = g_system->getMillis();
+	float deltaTime = currentFrame - _lastFrame;
+	_lastFrame = currentFrame;
+	Common::Event event;
+	while (g_system->getEventManager()->pollEvent(event)) {
+		Common::Point mousePos = g_system->getEventManager()->getMousePos();
+
+		switch (event.type) {
+		case Common::EVENT_KEYDOWN:
+			if (event.kbd.keycode == Common::KEYCODE_w || event.kbd.keycode == Common::KEYCODE_UP)
+				move(FORWARD, _scaleVector.x(), deltaTime);
+			else if (event.kbd.keycode == Common::KEYCODE_s || event.kbd.keycode == Common::KEYCODE_DOWN)
+				move(BACKWARD, _scaleVector.x(), deltaTime);
+			else if (event.kbd.keycode == Common::KEYCODE_a || event.kbd.keycode == Common::KEYCODE_LEFT)
+				move(LEFT, _scaleVector.y(), deltaTime);
+			else if (event.kbd.keycode == Common::KEYCODE_d || event.kbd.keycode == Common::KEYCODE_RIGHT)
+				move(RIGHT, _scaleVector.y(), deltaTime);
+			break;
+
+		case Common::EVENT_QUIT:
+		case Common::EVENT_RETURN_TO_LAUNCHER:
+			return;
+			break;
+
+		case Common::EVENT_MOUSEMOVE:
+			rotate(_lastMousePos, mousePos);
+			_lastMousePos = mousePos;
+			if (mousePos.x <= 5 || mousePos.x >= 315) {
+				g_system->warpMouse(_screenW/2, mousePos.y);
+				_lastMousePos.x = _screenW/2;
+				_lastMousePos.y = mousePos.y;
+			}
+			break;
+		default:
+			break;
+
+		}
+	}
+
+}
+
 Common::Error FreescapeEngine::run() {
 	// Initialize graphics:
 	_gfx = Freescape::createRenderer(_system);
@@ -157,13 +199,12 @@ Common::Error FreescapeEngine::run() {
 	area->show();
 	assert(entrance);
 	_position = entrance->getOrigin();
-	Math::Vector3d scaleVector;
 	if (_scale == Math::Vector3d(0, 0, 0)) {
 		uint8 scale = area->getScale();
-		scaleVector = Math::Vector3d(scale, scale, scale);
+		_scaleVector = Math::Vector3d(scale, scale, scale);
 	} else
-		scaleVector = _scale;
-	debug("scale: %f, %f, %f", scaleVector.x(), scaleVector.y(), scaleVector.z());
+		_scaleVector = _scale;
+	debug("scale: %f, %f, %f", _scaleVector.x(), _scaleVector.y(), _scaleVector.z());
 	_position.setValue(1, _position.y() + _playerHeight);
 
 	Math::Vector3d rotation = entrance->getRotation();
@@ -172,9 +213,8 @@ Common::Error FreescapeEngine::run() {
 
 	debug("FreescapeEngine::init");
 	// Simple main event loop
-	Common::Event event;
-	Common::Point lastMousePos(0, 0);
-	float lastFrame = 0.f;
+	_lastMousePos = Common::Point(0, 0);
+	_lastFrame = 0.f;
 	// used to create a projection matrix;
 	_nearClipPlane = 1.f;
 
@@ -188,45 +228,8 @@ Common::Error FreescapeEngine::run() {
 	//g_system->lockMouse(true);
 
 	while (!shouldQuit()) {
-		drawFrame(scaleVector, area);
-        float currentFrame = g_system->getMillis();
-        float deltaTime = currentFrame - lastFrame;
-        lastFrame = currentFrame;
-
-		while (g_system->getEventManager()->pollEvent(event)) {
-			Common::Point mousePos = g_system->getEventManager()->getMousePos();
-
-			switch (event.type) {
-			case Common::EVENT_KEYDOWN:
-				if (event.kbd.keycode == Common::KEYCODE_w || event.kbd.keycode == Common::KEYCODE_UP)
-					move(FORWARD, scaleVector.x(), deltaTime);
-				else if (event.kbd.keycode == Common::KEYCODE_s || event.kbd.keycode == Common::KEYCODE_DOWN)
-					move(BACKWARD, scaleVector.x(), deltaTime);
-				else if (event.kbd.keycode == Common::KEYCODE_a || event.kbd.keycode == Common::KEYCODE_LEFT)
-					move(LEFT, scaleVector.y(), deltaTime);
-				else if (event.kbd.keycode == Common::KEYCODE_d || event.kbd.keycode == Common::KEYCODE_RIGHT)
-					move(RIGHT, scaleVector.y(), deltaTime);
-				break;
-
-			case Common::EVENT_QUIT:
-			case Common::EVENT_RETURN_TO_LAUNCHER:
-				return Common::kNoError;
-				break;
-
-			case Common::EVENT_MOUSEMOVE:
-				rotate(lastMousePos, mousePos);
-				lastMousePos = mousePos;
-				if (mousePos.x <= 5 || mousePos.x >= 315) {
-					g_system->warpMouse(_screenW/2, mousePos.y);
-					lastMousePos.x = _screenW/2;
-					lastMousePos.y = mousePos.y;
-				}
-				break;
-			default:
-				break;
-
-			}
-		}
+		processInput();
+		drawFrame(area);
 
 		//drawBorder();
 		_gfx->flipBuffer();
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 8bce6a7af86..59405e97957 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -85,9 +85,14 @@ public:
 	// Entrance
 	uint16 _startEntrance;
 
-	// Movement
+	// Input
+	void processInput();
 	void move(CameraMovement direction, uint8 scale, float deltaTime);
 	void rotate(Common::Point lastMousePos, Common::Point mousePos);
+	// Input state
+	float _lastFrame;
+	Common::Point _lastMousePos;
+
 	// Eular Angles
 	float _yaw;
 	float _pitch;
@@ -100,8 +105,9 @@ public:
 
 
 	// Rendering
-	void drawFrame(Math::Vector3d scaleVector, Area *area);
+	void drawFrame(Area *area);
 	uint8 _colorNumber;
+	Math::Vector3d _scaleVector;
 	float _nearClipPlane;
 	float _farClipPlane;
 


Commit: 3255d04c2f7172f5edfdeab9ee10a80383de51df
    https://github.com/scummvm/scummvm/commit/3255d04c2f7172f5edfdeab9ee10a80383de51df
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:41+01:00

Commit Message:
FREESCAPE: initialize _playerHeight when using 8-bit engines

Changed paths:
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 2fe39c12e5f..c4b37690256 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -15,7 +15,7 @@
 namespace Freescape {
 
 static Object *load8bitObject(StreamLoader &stream) {
-	
+
 	Object::Type objectType = (Object::Type)(stream.get8() & 0x1F);
 	Math::Vector3d position, v;
 
@@ -112,21 +112,21 @@ static Object *load8bitObject(StreamLoader &stream) {
 }
 
 float specColors[16][3] = {
-    {0, 0, 0}, 
-	{0, 0, 0.75}, 
-	{0.75, 0, 0}, 
-	{0.75, 0, 0.75}, 
-	{0, 0.75, 0}, 
-	{0, 0.75, 0.75}, 
-	{0.75, 0.75, 0}, 
+    {0, 0, 0},
+	{0, 0, 0.75},
+	{0.75, 0, 0},
+	{0.75, 0, 0.75},
+	{0, 0.75, 0},
+	{0, 0.75, 0.75},
+	{0.75, 0.75, 0},
 	{0.75, 0.75, 0.75},
-    {0, 0, 0}, 
-	{0, 0, 1}, 
-	{1, 0, 0}, 
-	{1, 0, 1}, 
-	{0, 1, 0}, 
-	{0, 1, 1}, 
-	{1, 1, 0}, 
+    {0, 0, 0},
+	{0, 0, 1},
+	{1, 0, 0},
+	{1, 0, 1},
+	{0, 1, 0},
+	{0, 1, 1},
+	{1, 1, 0},
 	{1, 1, 1}
 };
 
@@ -165,9 +165,9 @@ Area *load8bitArea(StreamLoader &stream, uint16 ncolors) {
 	debug("Scale: %d", scale);
 
 	uint8 ci1 = stream.get8()&15;
-	uint8 ci2 = stream.get8()&15; 
-	uint8 ci3 = stream.get8()&15; 
-	uint8 ci4 = stream.get8()&15; 
+	uint8 ci2 = stream.get8()&15;
+	uint8 ci3 = stream.get8()&15;
+	uint8 ci4 = stream.get8()&15;
 
 	debug("Colors: %d %d %d %d", ci1, ci2, ci3, ci4);
 
@@ -235,7 +235,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 
 	uint32 i = 0;
 	while (i < fileSize) {
-		binary.push_back(buf[i]);		
+		binary.push_back(buf[i]);
 		i++;
 	}
 
@@ -298,6 +298,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 			(*areaMap)[newArea->getAreaID()] = newArea;
 		}
 	}
+	_playerHeight = 32;
 	_areasByAreaID = areaMap;
 	_startArea = startArea;
 	_startEntrance = startEntrance;


Commit: e04e631472138dbb60135559b21e949057d81c88
    https://github.com/scummvm/scummvm/commit/e04e631472138dbb60135559b21e949057d81c88
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:41+01:00

Commit Message:
FREESCAPE: removed more old code

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/gfx.cpp
    engines/freescape/gfx.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 3a9ead37e75..4b97fda36d8 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -137,6 +137,8 @@ void FreescapeEngine::drawFrame(Area *area) {
 	_gfx->positionCamera(_position, _position + _cameraFront);
 	_gfx->scale(_scaleVector);
 	area->draw(_gfx);
+	//drawBorder();
+	_gfx->flipBuffer();
 }
 
 void FreescapeEngine::processInput() {
@@ -230,9 +232,6 @@ Common::Error FreescapeEngine::run() {
 	while (!shouldQuit()) {
 		processInput();
 		drawFrame(area);
-
-		//drawBorder();
-		_gfx->flipBuffer();
 		g_system->updateScreen();
 		g_system->delayMillis(10);
 	}
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index 935aafb5e34..b05ac2b829e 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -92,10 +92,6 @@ Common::Rect Renderer::viewport() const {
 	return _screenViewport;
 }
 
-Common::Rect Renderer::rviewport() const {
-	return _rscreenViewport;
-}
-
 void Renderer::computeScreenViewport() {
 	int32 screenWidth = _system->getWidth();
 	int32 screenHeight = _system->getHeight();
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 8a81808ee86..898465c24dd 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -94,7 +94,6 @@ public:
 	virtual void drawFloor(uint8 color) = 0;
 
 	Common::Rect viewport() const;
-	Common::Rect rviewport() const;
 	Graphics::PixelBuffer *_palette = nullptr;
 
 	/**
@@ -120,9 +119,7 @@ public:
 protected:
 	OSystem *_system;
 	Texture *_font;
-
 	Common::Rect _screenViewport;
-	Common::Rect _rscreenViewport;
 
 	Math::Matrix4 _projectionMatrix;
 	Math::Matrix4 _modelViewMatrix;
@@ -130,9 +127,6 @@ protected:
 
 	Math::Frustum _frustum;
 
-	static const float cubeVertices[5 * 6 * 4];
-	Math::AABB _cubeFacesAABB[6];
-
 	Common::Rect getFontCharacterRect(uint8 character);
 	Math::Matrix4 makeProjectionMatrix(float fov, float nearClipPlane, float farClipPlane) const;
 };


Commit: 099bb5eed1eb366910359dd6de17791e86365984
    https://github.com/scummvm/scummvm/commit/099bb5eed1eb366910359dd6de17791e86365984
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:42+01:00

Commit Message:
FREESCAPE: some changes to make the code render some levels of Driller

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/freescape.cpp
    engines/freescape/loaders/16bitBinaryLoader.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 25afa54dd05..96af4f46ff6 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -13,7 +13,7 @@
 Object *Area::objectWithIDFromMap(ObjectMap *map, uint16 objectID) {
 	if (!map)
 		return nullptr;
-	if(!map->contains(objectID)) 
+	if(!map->contains(objectID))
 		return nullptr;
 	return (*map)[objectID];
 }
@@ -89,18 +89,18 @@ void Area::show() {
 }
 
 void Area::draw(Freescape::Renderer *gfx) {
-	if (palette) 
+	if (palette)
 		gfx->_palette = palette;
 
 	gfx->clear();
-	gfx->drawSky(skyColor);
+	//gfx->drawSky(skyColor);
 	assert(drawableObjects.size() > 0);
 	for (Common::Array<Object *>::iterator it = drawableObjects.begin(); it != drawableObjects.end(); it++) {
-		if (!(*it)->isInvisible()) 
+		if (!(*it)->isInvisible() && !(*it)->isPlanar())
 			(*it)->draw(gfx);
 	}
 	for (Common::Array<Object *>::iterator it = drawableObjects.begin(); it != drawableObjects.end(); it++) {
-		if (!(*it)->isInvisible() && (*it)->isPlanar()) 
+		if (!(*it)->isInvisible() && (*it)->isPlanar())
 			(*it)->draw(gfx);
 	}
 	gfx->drawFloor(groundColor);
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 4b97fda36d8..965f1c63062 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -163,6 +163,7 @@ void FreescapeEngine::processInput() {
 
 		case Common::EVENT_QUIT:
 		case Common::EVENT_RETURN_TO_LAUNCHER:
+			quitGame();
 			return;
 			break;
 
@@ -206,7 +207,8 @@ Common::Error FreescapeEngine::run() {
 		_scaleVector = Math::Vector3d(scale, scale, scale);
 	} else
 		_scaleVector = _scale;
-	debug("scale: %f, %f, %f", _scaleVector.x(), _scaleVector.y(), _scaleVector.z());
+	debug("entrace position: %f %f %f", _position.x(), _position.y(), _position.z());
+	debug("player height: %d", _playerHeight);
 	_position.setValue(1, _position.y() + _playerHeight);
 
 	Math::Vector3d rotation = entrance->getRotation();
@@ -224,7 +226,7 @@ Common::Error FreescapeEngine::run() {
 		// the 16-bit kit permits the range 0-8192 to be used along all three axes and from that comes the far plane distance of 14189.
 		_farClipPlane = 14189.f;
 	} else {
-		_farClipPlane = 1024.f; // wild guess
+		_farClipPlane = 4096.f; // wild guess
 	}
 
 	//g_system->lockMouse(true);
diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
index 75587f25026..dc92043bd89 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/16bitBinaryLoader.cpp
@@ -35,7 +35,7 @@ static Object *load16bitObject(StreamLoader &stream) {
 
 	/*
 		Notes to self:
-		
+
 			0 = no flags
 			128 = Movable, Animated
 			134 = Movable, Animated, Default invis, invis
@@ -191,7 +191,7 @@ Area *load16bitArea(StreamLoader &stream) {
 	stream.get16();
 	stream.get16();
 	stream.get16();
-	
+
 
 	uint8 skyColor = stream.get8();
 	skyColor = (stream.get8() << 4) | skyColor;
@@ -379,7 +379,7 @@ void FreescapeEngine::load16bitBinary(Common::SeekableReadStream *file) {
 	// file format, could this be shading information by
 	// analogy with that?
 	/*cout << "global unknown:";
-	int i; 
+	int i;
 	int j;
 	for (i = 0; i < 106/2; i++)
 		cout << streamLoader.get16() << endl;*/
@@ -482,11 +482,11 @@ void FreescapeEngine::load16bitBinary(Common::SeekableReadStream *file) {
 				error("Unexpected size of image %d", chunkSize);
 
 			raw_border = streamLoader.nextBytes(chunkSize);
-			raw_palette = new Common::Array<uint8>(); 
+			raw_palette = new Common::Array<uint8>();
 			debug("Palete follows at %x", streamLoader.getFileOffset());
 			for (i = 0; i < colorNumber*3; i++)
 				raw_palette->push_back(streamLoader.get8() << 2);
-			
+
 			debug("Palete finishes at %x", streamLoader.getFileOffset());
 			chunkSize = streamLoader.rget16();
 			debug("Something else of size %x at %x??", chunkSize, streamLoader.getFileOffset());
@@ -520,7 +520,7 @@ void FreescapeEngine::load16bitBinary(Common::SeekableReadStream *file) {
 	_startEntrance = startEntrance;
 	_colorNumber = colorNumber;
 	_areasByAreaID = areaMap;
-	_scale = Math::Vector3d(scaleX, scaleY, scaleZ);
+	_scale = Math::Vector3d(1, 1, 1);
 	_binaryBits = 16;
 	//return Binary{16, startArea, areaMap, raw_border, raw_palette, colorNumber};
 }
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index c4b37690256..f7046161167 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -19,9 +19,9 @@ static Object *load8bitObject(StreamLoader &stream) {
 	Object::Type objectType = (Object::Type)(stream.get8() & 0x1F);
 	Math::Vector3d position, v;
 
-	position.x() = stream.get8() * 32;
-	position.y() = stream.get8() * 32;
-	position.z() = stream.get8() * 32;
+	position.x() = stream.get8();
+	position.y() = stream.get8();
+	position.z() = stream.get8();
 
 	v.x() = stream.get8();
 	v.y() = stream.get8();
@@ -85,8 +85,8 @@ static Object *load8bitObject(StreamLoader &stream) {
 			objectType,
 			objectID,
 			0, // flags
-			64 * position,
-			64 * v, // size
+			32 * position,
+			32 * v, // size
 			colours,
 			ordinates,
 			instructions);


Commit: 2bccd8c6f54d9291c1594d720e4c39e66f56a276
    https://github.com/scummvm/scummvm/commit/2bccd8c6f54d9291c1594d720e4c39e66f56a276
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:42+01:00

Commit Message:
FREESCAPE: avoid rendering sky and floor in Driller

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/freescape.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 96af4f46ff6..9cdfc1f3a7e 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -93,7 +93,8 @@ void Area::draw(Freescape::Renderer *gfx) {
 		gfx->_palette = palette;
 
 	gfx->clear();
-	//gfx->drawSky(skyColor);
+	if (skyColor != 255)
+		gfx->drawSky(skyColor);
 	assert(drawableObjects.size() > 0);
 	for (Common::Array<Object *>::iterator it = drawableObjects.begin(); it != drawableObjects.end(); it++) {
 		if (!(*it)->isInvisible() && !(*it)->isPlanar())
@@ -103,5 +104,6 @@ void Area::draw(Freescape::Renderer *gfx) {
 		if (!(*it)->isInvisible() && (*it)->isPlanar())
 			(*it)->draw(gfx);
 	}
-	gfx->drawFloor(groundColor);
+	if (groundColor != 255)
+		gfx->drawFloor(groundColor);
 }
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 965f1c63062..79ddb532970 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -293,6 +293,7 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 	// Make sure the user stays at the ground level
 	// this one-liner keeps the user at the ground level (xz plane)
 	_position.set(_position.x(), positionY, _position.z());
+	debug("player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
 }
 
 bool FreescapeEngine::hasFeature(EngineFeature f) const {
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index f7046161167..7aefab5794e 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -98,7 +98,7 @@ static Object *load8bitObject(StreamLoader &stream) {
 		// create an entrance
 		return new Entrance(
 			objectID,
-			position,
+			32 * position,
 			v); // rotation
 	} break;
 
@@ -209,7 +209,7 @@ Area *load8bitArea(StreamLoader &stream, uint16 ncolors) {
 		debug("%s", detokenise8bitCondition(*conditionData)->c_str());
 	}
 
-	return (new Area(areaNumber, objectsByID, entrancesByID, scale, 0, 1, palette));
+	return (new Area(areaNumber, objectsByID, entrancesByID, scale, 255, 255, palette));
 }
 
 // struct BinaryTable {
@@ -298,7 +298,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 			(*areaMap)[newArea->getAreaID()] = newArea;
 		}
 	}
-	_playerHeight = 32;
+	_playerHeight = 64;
 	_areasByAreaID = areaMap;
 	_startArea = startArea;
 	_startEntrance = startEntrance;


Commit: 6eb56f8e5cee110bb76fa41f51225853bd3f013d
    https://github.com/scummvm/scummvm/commit/6eb56f8e5cee110bb76fa41f51225853bd3f013d
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:42+01:00

Commit Message:
FREESCAPE: disable transparent color face in Driller

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/gfx.cpp
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 79ddb532970..aad1b48ea9d 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -223,6 +223,8 @@ Common::Error FreescapeEngine::run() {
 	_nearClipPlane = 1.f;
 
 	if (_binaryBits == 16) {
+		// Do not render face if color is zero
+		_gfx->_keyColor = 0;
 		// the 16-bit kit permits the range 0-8192 to be used along all three axes and from that comes the far plane distance of 14189.
 		_farClipPlane = 14189.f;
 	} else {
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index b05ac2b829e..0252f046600 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -45,7 +45,7 @@ Renderer::Renderer(OSystem *system)
 	_currentPixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
 	_originalPixelFormat = Graphics::PixelFormat::createFormatCLUT8();
 	_palettePixelFormat = Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0);
-
+	_keyColor = -1;
 }
 
 Renderer::~Renderer() {}
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 898465c24dd..095cfefd008 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -95,6 +95,7 @@ public:
 
 	Common::Rect viewport() const;
 	Graphics::PixelBuffer *_palette = nullptr;
+	int _keyColor;
 
 	/**
 	 * Select the window where to render
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index c13b7a830cd..53700f783ac 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -250,7 +250,7 @@ void TinyGLRenderer::renderPolygon(const Math::Vector3d &origin, const Math::Vec
 	// tglEnable(TGL_POLYGON_OFFSET_LINE);
 	// tglEnable(TGL_POLYGON_OFFSET_POINT);
 	tglPolygonOffset(1.f, 1.f);
-	if ((*colours)[0] > 0) {
+	if ((*colours)[0] != _keyColor) {
 		_palette->getRGBAt((*colours)[0], r, g, b);
 		tglColor3ub(r, g, b);
 		for (int i = 0; i < ordinates->size(); i = i + 3) {
@@ -259,7 +259,7 @@ void TinyGLRenderer::renderPolygon(const Math::Vector3d &origin, const Math::Vec
 		renderFace(vertices);
 	}
 	vertices.clear();
-	if ((*colours)[1] > 0) {
+	if ((*colours)[1] != _keyColor) {
 		_palette->getRGBAt((*colours)[1], r, g, b);
 		tglColor3ub(r, g, b);
 		for (int i = ordinates->size(); i > 0; i = i - 3) {
@@ -286,7 +286,7 @@ void TinyGLRenderer::renderRectangle(const Math::Vector3d &origin, const Math::V
 	for (int i = 0; i < 2; i++) {
 
 		//debug("rec color: %d", (*colours)[i]);
-		if ((*colours)[i] > 0) {
+		if ((*colours)[i] != _keyColor) {
 			_palette->getRGBAt((*colours)[i], r, g, b);
 			tglColor3ub(r, g, b);
 			vertices.clear();
@@ -360,7 +360,7 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 	uint8 r, g, b;
 
 	// Face 0
-	if ((*colours)[0] > 0) {
+	if ((*colours)[0] != _keyColor) {
 		_palette->getRGBAt((*colours)[0], r, g, b);
 		tglColor3ub(r, g, b);
 		tglBegin(TGL_TRIANGLES);
@@ -375,7 +375,7 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 	}
 
 	// Face 1
-	if ((*colours)[1] > 0) {
+	if ((*colours)[1] != _keyColor) {
 		_palette->getRGBAt((*colours)[1], r, g, b);
 		tglColor3ub(r, g, b);
 		tglBegin(TGL_TRIANGLES);
@@ -390,7 +390,7 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 	}
 
 	// Face 2
-	if ((*colours)[2] > 0) {
+	if ((*colours)[2] != _keyColor) {
 		_palette->getRGBAt((*colours)[2], r, g, b);
 		tglColor3ub(r, g, b);
 		tglBegin(TGL_TRIANGLES);
@@ -405,7 +405,7 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 	}
 
 	// Face 3
-	if ((*colours)[3] > 0) {
+	if ((*colours)[3] != _keyColor) {
 		_palette->getRGBAt((*colours)[3], r, g, b);
 		tglColor3ub(r, g, b);
 		tglBegin(TGL_TRIANGLES);
@@ -420,7 +420,7 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 	}
 
 	// Face 1
-	if ((*colours)[4] > 0) {
+	if ((*colours)[4] != _keyColor) {
 		_palette->getRGBAt((*colours)[4], r, g, b);
 		tglColor3ub(r, g, b);
 		tglBegin(TGL_TRIANGLES);
@@ -435,7 +435,7 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 	}
 
 	// Face 0
-	if ((*colours)[5] > 0) {
+	if ((*colours)[5] != _keyColor) {
 		_palette->getRGBAt((*colours)[5], r, g, b);
 		tglColor3ub(r, g, b);
 		tglBegin(TGL_TRIANGLES);


Commit: bbf7656f0ac49193608ff5229f68c2225f1add36
    https://github.com/scummvm/scummvm/commit/bbf7656f0ac49193608ff5229f68c2225f1add36
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:42+01:00

Commit Message:
FREESCAPE: corrected some colors in Driller

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index aad1b48ea9d..17215f5c932 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -228,7 +228,7 @@ Common::Error FreescapeEngine::run() {
 		// the 16-bit kit permits the range 0-8192 to be used along all three axes and from that comes the far plane distance of 14189.
 		_farClipPlane = 14189.f;
 	} else {
-		_farClipPlane = 4096.f; // wild guess
+		_farClipPlane = 8192.f;
 	}
 
 	//g_system->lockMouse(true);
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 53700f783ac..809d317eed3 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -275,7 +275,7 @@ void TinyGLRenderer::renderRectangle(const Math::Vector3d &origin, const Math::V
 
 	assert(size.x() == 0 || size.y() == 0 || size.z() == 0);
 
-	tglPolygonOffset(250, 250);
+	tglPolygonOffset(1, 1);
 	//debug("origin: %f, %f, %f", origin.x(), origin.y(), origin.z());
 	//debug("size: %f, %f, %f", size.x(), size.y(), size.z());
 
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 7aefab5794e..93b4d510561 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -153,6 +153,60 @@ Graphics::PixelBuffer *getPaletteGradient(float *c1, float *c2, uint16 ncolors)
 	return palette;
 }
 
+Graphics::PixelBuffer *getPaletteGradient(uint8 c1, uint8 c2, uint16 ncolors) {
+	Common::Array <uint8> *raw_palette = new Common::Array <uint8>();
+	uint16 y0, y1, y2;
+
+	for(int c = 0; c < ncolors; c++)
+	{
+		if (c1 == 4 && c2 == 3 && c == 0) {
+			y0 = 0xff;
+			y1 = 0xff;
+			y2 = 0xff;
+		} else 	if (c1 == 4 && c2 == 3 && c == 1) {
+			y0 = 0x00;
+			y1 = 0x00;
+			y2 = 0x00;
+		} else if (c1 == 4 && c2 == 3 && c == 2) {
+			y0 = 0x00;
+			y1 = 0xaa;
+			y2 = 0xaa;
+		} else if (c1 == 4 && c2 == 3 && c == 3) {
+			y0 = 0xaa;
+			y1 = 0x00;
+			y2 = 0xaa;
+		} else if (c1 == 4 && c2 == 3 && c == 4) {
+			y0 = 0x00;
+			y1 = 0xaa;
+			y2 = 0xaa;
+		} else if (c1 == 4 && c2 == 3 && c == 5) {
+			y0 = 0x55;
+			y1 = 0x55;
+			y2 = 0x55;
+		} else if (c1 == 4 && c2 == 3 && c == 6) {
+			y0 = 0x00;
+			y1 = 0xaa;
+			y2 = 0x00;
+		} else if (c1 == 4 && c2 == 3 && c == 7) {
+			y0 = 0x00;
+			y1 = 0x00;
+			y2 = 0xaa;
+		} else {
+			y0 = 0xaa;
+			y1 = 0x00;
+			y2 = 0x00;
+		}
+		raw_palette->push_back(y0);
+		raw_palette->push_back(y1);
+		raw_palette->push_back(y2);
+	}
+	assert(ncolors == 16);
+	assert(raw_palette->size() == ncolors * 3);
+	Graphics::PixelFormat pixelFormat = Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0);
+	Graphics::PixelBuffer *palette = new Graphics::PixelBuffer(pixelFormat, ncolors, DisposeAfterUse::NO); //TODO
+	*palette = raw_palette->data();
+	return palette;
+}
 
 Area *load8bitArea(StreamLoader &stream, uint16 ncolors) {
 	uint32 base = stream.getFileOffset();
@@ -171,11 +225,11 @@ Area *load8bitArea(StreamLoader &stream, uint16 ncolors) {
 
 	debug("Colors: %d %d %d %d", ci1, ci2, ci3, ci4);
 
-	float *f1, *f2;
-	f1 = specColors[ci3];
-	f2 = specColors[ci4];
+	//float *f1, *f2;
+	//f1 = specColors[ci3];
+	//f2 = specColors[ci4];
 
-	Graphics::PixelBuffer *palette = getPaletteGradient(f1, f2, ncolors);
+	Graphics::PixelBuffer *palette = getPaletteGradient(ci3, ci4, ncolors);
 
 	debug("Area %d", areaNumber);
 	debug("Objects: %d", numberOfObjects);


Commit: a74d18cfb208db7aef3d1c117c156c1c01f1828b
    https://github.com/scummvm/scummvm/commit/a74d18cfb208db7aef3d1c117c156c1c01f1828b
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:42+01:00

Commit Message:
FREESCAPE: corrected some colors in the first level of Driller

Changed paths:
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 93b4d510561..d1bf65c1085 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -46,10 +46,10 @@ static Object *load8bitObject(StreamLoader &stream) {
 		debug("Number of colors: %d", numberOfColours/2);
 		for (uint8 colour = 0; colour < numberOfColours/2; colour++) {
 			uint8 c = stream.get8();
-			colours->push_back(c >> 4);
-			debug("color[%d] = %x", 2*colour, c >> 4);
 			colours->push_back(c & 0xf);
-			debug("color[%d] = %x", 2*colour+1, c & 0xf);
+			debug("color[%d] = %x", 2*colour, c & 0xf);
+			colours->push_back(c >> 4);
+			debug("color[%d] = %x", 2*colour+1, c >> 4);
 			byteSizeOfObject--;
 		}
 
@@ -160,9 +160,9 @@ Graphics::PixelBuffer *getPaletteGradient(uint8 c1, uint8 c2, uint16 ncolors) {
 	for(int c = 0; c < ncolors; c++)
 	{
 		if (c1 == 4 && c2 == 3 && c == 0) {
-			y0 = 0xff;
-			y1 = 0xff;
-			y2 = 0xff;
+			y0 = 0x00;
+			y1 = 0x00;
+			y2 = 0x00;
 		} else 	if (c1 == 4 && c2 == 3 && c == 1) {
 			y0 = 0x00;
 			y1 = 0x00;
@@ -176,25 +176,33 @@ Graphics::PixelBuffer *getPaletteGradient(uint8 c1, uint8 c2, uint16 ncolors) {
 			y1 = 0x00;
 			y2 = 0xaa;
 		} else if (c1 == 4 && c2 == 3 && c == 4) {
-			y0 = 0x00;
-			y1 = 0xaa;
-			y2 = 0xaa;
+			y0 = 0xff;
+			y1 = 0xff;
+			y2 = 0xff;
 		} else if (c1 == 4 && c2 == 3 && c == 5) {
 			y0 = 0x55;
 			y1 = 0x55;
 			y2 = 0x55;
 		} else if (c1 == 4 && c2 == 3 && c == 6) {
-			y0 = 0x00;
-			y1 = 0xaa;
-			y2 = 0x00;
-		} else if (c1 == 4 && c2 == 3 && c == 7) {
 			y0 = 0x00;
 			y1 = 0x00;
 			y2 = 0xaa;
-		} else {
+		} else if (c1 == 4 && c2 == 3 && c == 7) {
+			y0 = 0xaa;
+			y1 = 0x55;
+			y2 = 0x00;
+		} else if (c1 == 4 && c2 == 3 && c == 9) {
 			y0 = 0xaa;
 			y1 = 0x00;
 			y2 = 0x00;
+		} else if (c1 == 4 && c2 == 3 && c == 0xa) {
+			y0 = 0xff;
+			y1 = 0x55;
+			y2 = 0xff;
+		} else { // A different color
+			y0 = 0x12;
+			y1 = 0xf3;
+			y2 = 0x56;
 		}
 		raw_palette->push_back(y0);
 		raw_palette->push_back(y1);


Commit: c3512c30f34c337ee310005bb8158de28b6f945a
    https://github.com/scummvm/scummvm/commit/c3512c30f34c337ee310005bb8158de28b6f945a
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:42+01:00

Commit Message:
FREESCAPE: added most of the Driller EGA palette

Changed paths:
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index d1bf65c1085..f8d90c593a0 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -159,50 +159,40 @@ Graphics::PixelBuffer *getPaletteGradient(uint8 c1, uint8 c2, uint16 ncolors) {
 
 	for(int c = 0; c < ncolors; c++)
 	{
-		if (c1 == 4 && c2 == 3 && c == 0) {
-			y0 = 0x00;
-			y1 = 0x00;
-			y2 = 0x00;
-		} else 	if (c1 == 4 && c2 == 3 && c == 1) {
-			y0 = 0x00;
-			y1 = 0x00;
-			y2 = 0x00;
-		} else if (c1 == 4 && c2 == 3 && c == 2) {
-			y0 = 0x00;
-			y1 = 0xaa;
-			y2 = 0xaa;
-		} else if (c1 == 4 && c2 == 3 && c == 3) {
-			y0 = 0xaa;
-			y1 = 0x00;
-			y2 = 0xaa;
-		} else if (c1 == 4 && c2 == 3 && c == 4) {
-			y0 = 0xff;
-			y1 = 0xff;
-			y2 = 0xff;
-		} else if (c1 == 4 && c2 == 3 && c == 5) {
-			y0 = 0x55;
-			y1 = 0x55;
-			y2 = 0x55;
-		} else if (c1 == 4 && c2 == 3 && c == 6) {
-			y0 = 0x00;
-			y1 = 0x00;
-			y2 = 0xaa;
-		} else if (c1 == 4 && c2 == 3 && c == 7) {
-			y0 = 0xaa;
-			y1 = 0x55;
-			y2 = 0x00;
-		} else if (c1 == 4 && c2 == 3 && c == 9) {
-			y0 = 0xaa;
-			y1 = 0x00;
-			y2 = 0x00;
-		} else if (c1 == 4 && c2 == 3 && c == 0xa) {
-			y0 = 0xff;
-			y1 = 0x55;
-			y2 = 0xff;
-		} else { // A different color
-			y0 = 0x12;
-			y1 = 0xf3;
-			y2 = 0x56;
+		if (true /*c1 == 4 && c2 == 3*/) {
+			switch (c) {
+				case 0:
+				case 1:
+				y0 = 0x00; y1 = 0x00; y2 = 0x00;
+				break;
+				case 2:
+				y0 = 0x00; y1 = 0xaa; y2 = 0xaa;
+				break;
+				case 3:
+				y0 = 0xaa; y1 = 0x00; y2 = 0xaa;
+				break;
+				case 4:
+				y0 = 0xff; y1 = 0xff; y2 = 0xff;
+				break;
+				case 5:
+				y0 = 0x55; y1 = 0x55; y2 = 0x55;
+				break;
+				case 6:
+				y0 = 0x00; y1 = 0x00; y2 = 0xaa;
+				break;
+				case 7:
+				y0 = 0xaa; y1 = 0x55; y2 = 0x00;
+				break;
+				case 9:
+				y0 = 0xaa; y1 = 0x00; y2 = 0x00;
+				break;
+				case 0xa:
+				y0 = 0xff; y1 = 0x55; y2 = 0xff;
+				break;
+				default:
+				y0 = 0x12; y1 = 0xf3; y2 = 0x56;
+				break;
+			}
 		}
 		raw_palette->push_back(y0);
 		raw_palette->push_back(y1);


Commit: 00143272df200f515b1854ca712b02ac613fc0bf
    https://github.com/scummvm/scummvm/commit/00143272df200f515b1854ca712b02ac613fc0bf
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:43+01:00

Commit Message:
FREESCAPE: improved initial position in Driller

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 17215f5c932..209a39e1903 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -209,6 +209,7 @@ Common::Error FreescapeEngine::run() {
 		_scaleVector = _scale;
 	debug("entrace position: %f %f %f", _position.x(), _position.y(), _position.z());
 	debug("player height: %d", _playerHeight);
+	_position.setValue(0, _position.x() - 8192);
 	_position.setValue(1, _position.y() + _playerHeight);
 
 	Math::Vector3d rotation = entrance->getRotation();
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index f8d90c593a0..be71eebb9ad 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -99,7 +99,7 @@ static Object *load8bitObject(StreamLoader &stream) {
 		return new Entrance(
 			objectID,
 			32 * position,
-			v); // rotation
+			5 * v); // rotation
 	} break;
 
 	case Object::Sensor:


Commit: f8dac295ca66ab37bb8f115be28359167d480443
    https://github.com/scummvm/scummvm/commit/f8dac295ca66ab37bb8f115be28359167d480443
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:43+01:00

Commit Message:
FREESCAPE: refactor 8-bit binary loading to use scummvm API

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 209a39e1903..16b985a7585 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -209,7 +209,7 @@ Common::Error FreescapeEngine::run() {
 		_scaleVector = _scale;
 	debug("entrace position: %f %f %f", _position.x(), _position.y(), _position.z());
 	debug("player height: %d", _playerHeight);
-	_position.setValue(0, _position.x() - 8192);
+	_position.setValue(0, _position.x() - 4096);
 	_position.setValue(1, _position.y() + _playerHeight);
 
 	Math::Vector3d rotation = entrance->getRotation();
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index be71eebb9ad..82286aa3118 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -14,25 +14,25 @@
 
 namespace Freescape {
 
-static Object *load8bitObject(StreamLoader &stream) {
+static Object *load8bitObject(Common::SeekableReadStream *file) {
 
-	Object::Type objectType = (Object::Type)(stream.get8() & 0x1F);
+	Object::Type objectType = (Object::Type)(file->readByte() & 0x1F);
 	Math::Vector3d position, v;
 
-	position.x() = stream.get8();
-	position.y() = stream.get8();
-	position.z() = stream.get8();
+	position.x() = file->readByte();
+	position.y() = file->readByte();
+	position.z() = file->readByte();
 
-	v.x() = stream.get8();
-	v.y() = stream.get8();
-	v.z() = stream.get8();
+	v.x() = file->readByte();
+	v.y() = file->readByte();
+	v.z() = file->readByte();
 
 	// object ID
-	uint16 objectID = stream.get8();
+	uint16 objectID = file->readByte();
 	// size of object on disk; we've accounted for 8 bytes
 	// already so we can subtract that to get the remaining
 	// length beyond here
-	uint8 byteSizeOfObject = stream.get8();
+	uint8 byteSizeOfObject = file->readByte();
 	assert(byteSizeOfObject >= 9);
 	byteSizeOfObject = byteSizeOfObject - 9;
 	debug("Object %d ; type %d ; size %d", objectID, (int)objectType, byteSizeOfObject);
@@ -45,7 +45,7 @@ static Object *load8bitObject(StreamLoader &stream) {
 		Common::Array<uint8> *colours = new Common::Array<uint8>;
 		debug("Number of colors: %d", numberOfColours/2);
 		for (uint8 colour = 0; colour < numberOfColours/2; colour++) {
-			uint8 c = stream.get8();
+			uint8 c = file->readByte();
 			colours->push_back(c & 0xf);
 			debug("color[%d] = %x", 2*colour, c & 0xf);
 			colours->push_back(c >> 4);
@@ -63,7 +63,7 @@ static Object *load8bitObject(StreamLoader &stream) {
 			uint16 ord = 0;
 
 			for (int ordinate = 0; ordinate < numberOfOrdinates; ordinate++) {
-				ord = stream.get8();
+				ord = file->readByte();
 				debug("ord: %x", ord);
 				ordinates->push_back(ord);
 				byteSizeOfObject--;
@@ -73,9 +73,10 @@ static Object *load8bitObject(StreamLoader &stream) {
 		// grab the object condition, if there is one
 		FCLInstructionVector instructions;
 		if (byteSizeOfObject) {
-			Common::Array<uint8> *conditionData = stream.nextBytes(byteSizeOfObject);
-
-			Common::String *conditionSource = detokenise8bitCondition(*conditionData);
+			byte *conditionData = (byte*)malloc(byteSizeOfObject);
+			file->read(conditionData, byteSizeOfObject);
+			Common::Array<uint8> conditionArray(conditionData, byteSizeOfObject);
+			Common::String *conditionSource = detokenise8bitCondition(conditionArray);
 			//instructions = getInstructions(conditionSource);
 			debug("%s", conditionSource->c_str());
 		}
@@ -107,7 +108,7 @@ static Object *load8bitObject(StreamLoader &stream) {
 		break;
 	}
 
-	stream.skipBytes(byteSizeOfObject);
+	file->seek(byteSizeOfObject, SEEK_CUR);
 	return nullptr;
 }
 
@@ -206,20 +207,21 @@ Graphics::PixelBuffer *getPaletteGradient(uint8 c1, uint8 c2, uint16 ncolors) {
 	return palette;
 }
 
-Area *load8bitArea(StreamLoader &stream, uint16 ncolors) {
-	uint32 base = stream.getFileOffset();
-	uint8 skippedValue = stream.get8();
-	uint8 numberOfObjects = stream.get8();
-	uint8 areaNumber = stream.get8();
+Area *load8bitArea(Common::SeekableReadStream *file, uint16 ncolors) {
+
+	uint32 base = file->pos();
+	uint8 skippedValue = file->readByte();
+	uint8 numberOfObjects = file->readByte();
+	uint8 areaNumber = file->readByte();
 
-	uint16 cPtr = stream.rget16();
-	uint8 scale = stream.get8();
+	uint16 cPtr = file->readUint16LE();
+	uint8 scale = file->readByte();
 	debug("Scale: %d", scale);
 
-	uint8 ci1 = stream.get8()&15;
-	uint8 ci2 = stream.get8()&15;
-	uint8 ci3 = stream.get8()&15;
-	uint8 ci4 = stream.get8()&15;
+	uint8 ci1 = file->readByte() & 15;
+	uint8 ci2 = file->readByte() & 15;
+	uint8 ci3 = file->readByte() & 15;
+	uint8 ci4 = file->readByte() & 15;
 
 	debug("Colors: %d %d %d %d", ci1, ci2, ci3, ci4);
 
@@ -233,12 +235,11 @@ Area *load8bitArea(StreamLoader &stream, uint16 ncolors) {
 	debug("Objects: %d", numberOfObjects);
 	debug("Condition Ptr: %x", cPtr);
 
-	stream.skipBytes(15);
+	file->seek(15, SEEK_CUR);
 	ObjectMap *objectsByID = new ObjectMap;
 	ObjectMap *entrancesByID = new ObjectMap;
-
 	for (uint8 object = 0; object < numberOfObjects; object++) {
-		Object *newObject = load8bitObject(stream);
+		Object *newObject = load8bitObject(file);
 
 		if (newObject) {
 			if (newObject->getType() == Object::Entrance) {
@@ -248,17 +249,18 @@ Area *load8bitArea(StreamLoader &stream, uint16 ncolors) {
 			}
 		}
 	}
-	stream.setFileOffset(base+cPtr);
-	uint8 numConditions = stream.get8();
+	file->seek(base + cPtr);
+	uint8 numConditions = file->readByte();
 	debug("%d area conditions", numConditions);
 	while (numConditions--) {
 		// get the length
-		uint32 lengthOfCondition = stream.get8();
+		uint32 lengthOfCondition = file->readByte();
 		debug("length of condition: %d", lengthOfCondition);
 		// get the condition
-		Common::Array<uint8> *conditionData = stream.nextBytes(lengthOfCondition);
-
-		debug("%s", detokenise8bitCondition(*conditionData)->c_str());
+		byte *conditionData = (byte*)malloc(lengthOfCondition);
+		file->read(conditionData, lengthOfCondition);
+		Common::Array<uint8> conditionArray(conditionData, lengthOfCondition);
+		debug("%s", detokenise8bitCondition(conditionArray)->c_str());
 	}
 
 	return (new Area(areaNumber, objectsByID, entrancesByID, scale, 255, 255, palette));
@@ -279,63 +281,54 @@ Area *load8bitArea(StreamLoader &stream, uint16 ncolors) {
 // };
 
 void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offset, int ncolors) {
-	const uint32 fileSize = file->size();
-	byte *buf = (byte *)malloc(fileSize);
-	file->read(buf, fileSize);
-
-	Common::Array<uint8> binary;
-
-	uint32 i = 0;
-	while (i < fileSize) {
-		binary.push_back(buf[i]);
-		i++;
-	}
-
-	StreamLoader streamLoader(binary);
-	streamLoader.skipBytes(0x210);
-	uint16 frameSize = streamLoader.get16();
-	Common::Array<uint8> *raw_border = streamLoader.nextBytes(frameSize);
+	//const uint32 fileSize = file->size();
+	file->seek(0x210);
+	uint16 frameSize = file->readUint16BE();
+	//Common::Array<uint8> *raw_border = streamLoader.nextBytes(frameSize);
 	debug("Found border image of size %x", frameSize);
 
-	streamLoader.setFileOffset(offset);
-	uint8 numberOfAreas = streamLoader.get8();
-	uint16 dbSize = streamLoader.rget16();
+	file->seek(offset);
+	uint8 numberOfAreas = file->readByte();
+	uint16 dbSize = file->readUint16LE();
 	debug("Database ends at %x", dbSize);
 
 	debug("Number of areas: %d", numberOfAreas);
-	uint8 startArea = streamLoader.get8();
+
+	uint8 startArea = file->readByte();
 	debug("Start area: %d", startArea);
-	uint8 startEntrance = streamLoader.get8();
+	uint8 startEntrance = file->readByte();
 	debug("Entrace area: %d", startEntrance);
 
-	streamLoader.skipBytes(66);
+	//streamLoader.skipBytes(66);
+	file->seek(66, SEEK_CUR);
 
 	uint16 globalSomething;
-	globalSomething = streamLoader.get16();
+	globalSomething = file->readUint16BE();
 	debug("Pointer to something: %x\n", globalSomething);
 
 	uint16 globalByteCodeTable;
-	globalByteCodeTable = streamLoader.get16();
+	globalByteCodeTable = file->readUint16BE();
 	debug("GBCT: %d\n", globalByteCodeTable);
 
-	streamLoader.setFileOffset(offset + globalByteCodeTable);
-	uint8 numConditions = streamLoader.get8();
+	file->seek(offset + globalByteCodeTable);
+	uint8 numConditions = file->readByte();
 	debug("%d global conditions", numConditions);
 	while (numConditions--) {
 		// get the length
-		uint32 lengthOfCondition = streamLoader.get8();
+		uint32 lengthOfCondition = file->readByte();
 		debug("length of condition: %d", lengthOfCondition);
 		// get the condition
-		Common::Array<uint8> *conditionData = streamLoader.nextBytes(lengthOfCondition);
-
+		byte *conditionData = (byte*)malloc(lengthOfCondition);
+		file->read(conditionData, lengthOfCondition);
+		Common::Array<uint8> conditionArray(conditionData, lengthOfCondition);
 		//debug("Global condition %d", numCondition + 1);
-		debug("%s", detokenise8bitCondition(*conditionData)->c_str());
+		debug("%s", detokenise8bitCondition(conditionArray)->c_str());
 	}
 
-	streamLoader.setFileOffset(offset + 200);
+	file->seek(offset + 200);
 	uint16 *fileOffsetForArea = new uint16[numberOfAreas];
 	for (uint16 area = 0; area < numberOfAreas; area++) {
-		fileOffsetForArea[area] = streamLoader.rget16();
+		fileOffsetForArea[area] = file->readUint16LE();
 	}
 
 	// grab the areas
@@ -343,8 +336,8 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	for (uint16 area = 0; area < numberOfAreas; area++) {
 		debug("Area offset %d", fileOffsetForArea[area]);
 
-		streamLoader.setFileOffset(offset + fileOffsetForArea[area]);
-		Area *newArea = load8bitArea(streamLoader, ncolors);
+		file->seek(offset + fileOffsetForArea[area]);
+		Area *newArea = load8bitArea(file, ncolors);
 
 		if (newArea) {
 			(*areaMap)[newArea->getAreaID()] = newArea;


Commit: 0d3ee5696014d986dcc0df25d139ef9d996f2773
    https://github.com/scummvm/scummvm/commit/0d3ee5696014d986dcc0df25d139ef9d996f2773
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:43+01:00

Commit Message:
FREESCAPE: prototype of shooting code and refactor

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/objects/geometricobject.cpp
    engines/freescape/objects/object.h


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 9cdfc1f3a7e..86b9978834b 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -107,3 +107,13 @@ void Area::draw(Freescape::Renderer *gfx) {
 	if (groundColor != 255)
 		gfx->drawFloor(groundColor);
 }
+
+Object *Area::shootRay(const Math::Ray &ray) {
+	debug("drawable size: %d", drawableObjects.size());
+	for (Common::Array<Object *>::iterator it = drawableObjects.begin(); it != drawableObjects.end(); it++) {
+		if (!(*it)->isInvisible() && (*it)->_boundingBox.isValid() && ray.intersectAABB((*it)->_boundingBox))
+			return (*it);
+	}
+
+	return nullptr;
+}
\ No newline at end of file
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index ed97121cf17..cd5a2751e4f 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -9,9 +9,12 @@
 #ifndef __Phantasma__Area__
 #define __Phantasma__Area__
 
-#include "math/vector3d.h"
 #include "common/hashmap.h"
 #include "common/array.h"
+
+#include "math/vector3d.h"
+#include "math/ray.h"
+
 #include "freescape/gfx.h"
 #include "freescape/objects/object.h"
 
@@ -37,6 +40,8 @@ public:
 	void draw(Freescape::Renderer *gfx);
 	void show();
 
+	Object *shootRay(const Math::Ray &ray);
+
 private:
 	uint16 areaID;
 	uint8 scale;
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 16b985a7585..582dff6bebd 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -6,12 +6,14 @@
 #include "common/error.h"
 #include "common/events.h"
 #include "common/file.h"
+#include "common/math.h"
 #include "common/fs.h"
 #include "common/system.h"
 
 #include "engines/util.h"
 
 #include "graphics/renderer.h"
+#include "math/ray.h"
 
 #include "freescape/freescape.h"
 #include "freescape/gfx.h"
@@ -34,7 +36,7 @@ FreescapeEngine::FreescapeEngine(OSystem *syst)
 	// Do not initialize graphics here
 	// Do not initialize audio devices here
 	_hasReceivedTime = false;
-
+	_currentArea = nullptr;
 	_rotation = Math::Vector3d(0.f, 0.f, 0.f);
 	_position = Math::Vector3d(0.f, 0.f, 0.f);
 	_velocity = Math::Vector3d(0.f, 0.f, 0.f);
@@ -132,11 +134,25 @@ void FreescapeEngine::loadAssets() {
 
 }
 
-void FreescapeEngine::drawFrame(Area *area) {
+// Taken from the Myst 3 codebase, it should be abstracted
+Math::Vector3d FreescapeEngine::directionToVector(float pitch, float heading) {
+	Math::Vector3d v;
+
+	float radHeading = Common::deg2rad(heading);
+	float radPitch = Common::deg2rad(pitch);
+
+	v.setValue(0, cos(radPitch) * cos(radHeading));
+	v.setValue(1, sin(radPitch));
+	v.setValue(2, cos(radPitch) * sin(radHeading));
+
+	return v;
+}
+
+void FreescapeEngine::drawFrame() {
 	_gfx->updateProjectionMatrix(60.0, _nearClipPlane, _farClipPlane);
 	_gfx->positionCamera(_position, _position + _cameraFront);
 	_gfx->scale(_scaleVector);
-	area->draw(_gfx);
+	_currentArea->draw(_gfx);
 	//drawBorder();
 	_gfx->flipBuffer();
 }
@@ -176,6 +192,11 @@ void FreescapeEngine::processInput() {
 				_lastMousePos.y = mousePos.y;
 			}
 			break;
+
+		case Common::EVENT_LBUTTONDOWN:
+			shoot();
+			break;
+
 		default:
 			break;
 
@@ -184,26 +205,38 @@ void FreescapeEngine::processInput() {
 
 }
 
+void FreescapeEngine::shoot() {
+	debug("dir: %f %f", _pitch, 90.0 - _yaw);
+	Math::Vector3d direction = directionToVector(_pitch, 90.0 - _yaw);
+	Math::Ray ray(_position, direction);
+	Object *shooted = _currentArea->shootRay(ray);
+	if (shooted) {
+		Math::Vector3d origin = shooted->getOrigin();
+		debug("shoot to %d at %f %f!", shooted->getObjectID(), origin.x(), origin.z());
+	}
+	//debug("camera front: %f %f %f", _cameraFront.x(), _rotation.y(), _rotation.z());
+}
+
+
 Common::Error FreescapeEngine::run() {
 	// Initialize graphics:
 	_gfx = Freescape::createRenderer(_system);
 	_gfx->init();
 	_gfx->clear();
 	loadAssets();
-	Area *area = nullptr;
 	Entrance *entrance = nullptr;
 	assert(_areasByAreaID);
 	if (_startArea == 14)
 		_startArea = 1;
 	assert(_areasByAreaID->contains(_startArea));
-	area = (*_areasByAreaID)[_startArea];
-	assert(area);
-	entrance = (Entrance*) area->entranceWithID(_startEntrance);
-	area->show();
+	_currentArea = (*_areasByAreaID)[_startArea];
+	assert(_currentArea);
+	entrance = (Entrance*) _currentArea->entranceWithID(_startEntrance);
+	_currentArea->show();
 	assert(entrance);
 	_position = entrance->getOrigin();
 	if (_scale == Math::Vector3d(0, 0, 0)) {
-		uint8 scale = area->getScale();
+		uint8 scale = _currentArea->getScale();
 		_scaleVector = Math::Vector3d(scale, scale, scale);
 	} else
 		_scaleVector = _scale;
@@ -236,7 +269,7 @@ Common::Error FreescapeEngine::run() {
 
 	while (!shouldQuit()) {
 		processInput();
-		drawFrame(area);
+		drawFrame();
 		g_system->updateScreen();
 		g_system->delayMillis(10);
 	}
@@ -261,17 +294,11 @@ void FreescapeEngine::rotate(Common::Point lastMousePos, Common::Point mousePos)
 	if (_pitch < -180.0f)
 		_pitch = -180.0f;
 
-	Math::Vector3d v;
-	float x = cos(_yaw  * M_PI / 180.0) * cos(_pitch  * M_PI / 180.0);
-	float y = sin(_pitch * M_PI / 180.0);
-	float z = sin(_yaw * M_PI / 180.0) * cos(_pitch * M_PI / 180.0);
-	v.set(x, y, z);
-	v.normalize();
-	_cameraFront = v;
+	_cameraFront = directionToVector(_pitch, _yaw);
 
 	// // _right = _front x _up;
 	Math::Vector3d up(0, 1, 0); // this should be const
-	v = Math::Vector3d::crossProduct(_cameraFront, up);
+	Math::Vector3d v = Math::Vector3d::crossProduct(_cameraFront, up);
 	v.normalize();
 	_cameraRight = v;
 }
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 59405e97957..49a4a489322 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -68,7 +68,6 @@ public:
 	void drawBorder();
 	Texture *_borderTexture;
 
-
 	// Parsing
 	void loadAssets();
 	void load16bitBinary(Common::SeekableReadStream *file);
@@ -81,6 +80,7 @@ public:
 	// Areas
 	uint16 _startArea;
 	AreaMap *_areasByAreaID;
+	Area *_currentArea;
 	Math::Vector3d _scale;
 	// Entrance
 	uint16 _startEntrance;
@@ -93,9 +93,14 @@ public:
 	float _lastFrame;
 	Common::Point _lastMousePos;
 
+	// Interaction
+	void shoot();
+
 	// Eular Angles
 	float _yaw;
 	float _pitch;
+	Math::Vector3d directionToVector(float pitch, float heading);
+
 	// Camera options
 	float _mouseSensitivity;
 	float _movementSpeed;
@@ -105,7 +110,7 @@ public:
 
 
 	// Rendering
-	void drawFrame(Area *area);
+	void drawFrame();
 	uint8 _colorNumber;
 	Math::Vector3d _scaleVector;
 	float _nearClipPlane;
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index 4b39c26e473..e866831842e 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -90,6 +90,21 @@ GeometricObject::GeometricObject(
 	if (_ordinates)
 		ordinates = new Common::Array<uint16>(*_ordinates);
 	condition = _condition;
+
+	if (_type == Cube) {
+		Math::Vector3d v;
+		v = origin;
+		_boundingBox.expand(v);
+
+		for (int i = 0; i < 3; i++) {
+			v = origin;
+			v.setValue(i, origin.getValue(i) + size.getValue(i));
+			_boundingBox.expand(v);
+		}
+
+		v = size;
+		_boundingBox.expand(v);
+	}
 }
 
 GeometricObject::~GeometricObject() {
diff --git a/engines/freescape/objects/object.h b/engines/freescape/objects/object.h
index 8c6c5418886..c507ec001c9 100644
--- a/engines/freescape/objects/object.h
+++ b/engines/freescape/objects/object.h
@@ -11,6 +11,7 @@
 
 #include "common/system.h"
 #include "math/vector3d.h"
+#include "math/aabb.h"
 
 #include "freescape/gfx.h"
 
@@ -56,6 +57,7 @@ public:
 	Type _type;
 	uint16 _objectID;
 	Math::Vector3d _origin, _size, _rotation;
+	Math::AABB _boundingBox;
 };
 
 #endif


Commit: 786f70782e06aae6f0f6e0e3760db437e724b12a
    https://github.com/scummvm/scummvm/commit/786f70782e06aae6f0f6e0e3760db437e724b12a
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:43+01:00

Commit Message:
FREESCAPE: improved handling of mouse rotation and bounding boxes

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/objects/geometricobject.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 582dff6bebd..64e16c18916 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -186,10 +186,14 @@ void FreescapeEngine::processInput() {
 		case Common::EVENT_MOUSEMOVE:
 			rotate(_lastMousePos, mousePos);
 			_lastMousePos = mousePos;
-			if (mousePos.x <= 5 || mousePos.x >= 315) {
+			if (mousePos.x <= 5 || mousePos.x >= _screenW - 5) {
 				g_system->warpMouse(_screenW/2, mousePos.y);
 				_lastMousePos.x = _screenW/2;
 				_lastMousePos.y = mousePos.y;
+			} else if (mousePos.y <= 5 || mousePos.y >= _screenH - 5) {
+				g_system->warpMouse(mousePos.x, _screenH/2);
+				_lastMousePos.x = mousePos.x;
+				_lastMousePos.y = _screenH/2;
 			}
 			break;
 
@@ -206,8 +210,7 @@ void FreescapeEngine::processInput() {
 }
 
 void FreescapeEngine::shoot() {
-	debug("dir: %f %f", _pitch, 90.0 - _yaw);
-	Math::Vector3d direction = directionToVector(_pitch, 90.0 - _yaw);
+	Math::Vector3d direction = directionToVector(_pitch, 90.f - _yaw);
 	Math::Ray ray(_position, direction);
 	Object *shooted = _currentArea->shootRay(ray);
 	if (shooted) {
@@ -265,8 +268,6 @@ Common::Error FreescapeEngine::run() {
 		_farClipPlane = 8192.f;
 	}
 
-	//g_system->lockMouse(true);
-
 	while (!shouldQuit()) {
 		processInput();
 		drawFrame();
@@ -289,10 +290,10 @@ void FreescapeEngine::rotate(Common::Point lastMousePos, Common::Point mousePos)
 	_pitch += yoffset;
 
 	// Make sure that when pitch is out of bounds, screen doesn't get flipped
-	if (_pitch > 180.0f)
-		_pitch = 180.0f;
-	if (_pitch < -180.0f)
-		_pitch = -180.0f;
+	if (_pitch > 360.0f)
+		_pitch -= 360.0f;
+	if (_pitch < 0.0f)
+		_pitch += 360.0f;
 
 	_cameraFront = directionToVector(_pitch, _yaw);
 
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index e866831842e..85c823553e9 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -92,18 +92,23 @@ GeometricObject::GeometricObject(
 	condition = _condition;
 
 	if (_type == Cube) {
-		Math::Vector3d v;
-		v = origin;
-		_boundingBox.expand(v);
+		Math::Vector3d torigin = origin;
+		torigin.setValue(0, origin.x() - 4096);
 
+		_boundingBox.expand(torigin);
 		for (int i = 0; i < 3; i++) {
-			v = origin;
-			v.setValue(i, origin.getValue(i) + size.getValue(i));
+			Math::Vector3d v = torigin;
+			v.setValue(i, v.getValue(i) + size.getValue(i));
 			_boundingBox.expand(v);
 		}
 
-		v = size;
-		_boundingBox.expand(v);
+		for (int i = 0; i < 3; i++) {
+			Math::Vector3d v = torigin + size;
+			v.setValue(i, v.getValue(i) - size.getValue(i));
+			_boundingBox.expand(v);
+		}
+		_boundingBox.expand(torigin + size);
+		assert(_boundingBox.isValid());
 	}
 }
 


Commit: dcc631ff3d613b7fb09364f4bd27a8fdaebfb5d2
    https://github.com/scummvm/scummvm/commit/dcc631ff3d613b7fb09364f4bd27a8fdaebfb5d2
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:43+01:00

Commit Message:
FREESCAPE: improved validation of polygon when rendering

Changed paths:
    engines/freescape/gfx_tinygl.cpp


diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 809d317eed3..81fe72d13ad 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -241,10 +241,14 @@ void TinyGLRenderer::renderPolygon(const Math::Vector3d &origin, const Math::Vec
 	else if (size.z() == 0)
 		dz = 2;
 	else {
-		if (ordinates->size() != 6)
+		if (ordinates->size() != 6) {
 			error("Invalid polygon: %f %f %f", size.x(), size.y(), size.z());
+		}
 	}
 
+	if (ordinates->size() % 3 > 0)
+		error("Invalid polygon using %d ordinates", ordinates->size());
+
 	Common::Array<Math::Vector3d> vertices;
 	tglEnable(TGL_POLYGON_OFFSET_FILL);
 	// tglEnable(TGL_POLYGON_OFFSET_LINE);


Commit: 7e8653487dd8497c320d123767e682d45cdf4be9
    https://github.com/scummvm/scummvm/commit/7e8653487dd8497c320d123767e682d45cdf4be9
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:44+01:00

Commit Message:
FREESCAPE: some changes to allow to parse and render castle master levels

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/objects/geometricobject.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 64e16c18916..ab5a7a8fcd3 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -128,7 +128,14 @@ void FreescapeEngine::loadAssets() {
 			error("Invalid render mode %s for Driller", renderMode.c_str());
 
 	   } else if (_targetName == "Castle") {
-			error("Unsupported game");
+			file = gameDir.createReadStreamForMember("castle.sna");
+
+			if (file == nullptr)
+				error("Failed to open castle.sna");
+			// Courtyard -> 0x93c1
+			// Beds -> 0x867d
+			// All? -> 0x845d or 0x80ed?
+			load8bitBinary(file, 0x93c1, 16);
 	   } else
 		error("'%s' is an invalid game", _targetName.c_str());
 
@@ -236,8 +243,13 @@ Common::Error FreescapeEngine::run() {
 	assert(_currentArea);
 	entrance = (Entrance*) _currentArea->entranceWithID(_startEntrance);
 	_currentArea->show();
-	assert(entrance);
-	_position = entrance->getOrigin();
+	Math::Vector3d rotation;
+
+	if (entrance) {
+		_position = entrance->getOrigin();
+		rotation = entrance->getRotation();
+	}
+	//assert(entrance);
 	if (_scale == Math::Vector3d(0, 0, 0)) {
 		uint8 scale = _currentArea->getScale();
 		_scaleVector = Math::Vector3d(scale, scale, scale);
@@ -248,7 +260,6 @@ Common::Error FreescapeEngine::run() {
 	_position.setValue(0, _position.x() - 4096);
 	_position.setValue(1, _position.y() + _playerHeight);
 
-	Math::Vector3d rotation = entrance->getRotation();
 	_pitch = rotation.x() - 180.f;
 	_yaw = rotation.y() - 180.f;
 
@@ -267,7 +278,7 @@ Common::Error FreescapeEngine::run() {
 	} else {
 		_farClipPlane = 8192.f;
 	}
-
+	debug("Starting area %d", _currentArea->getAreaID());
 	while (!shouldQuit()) {
 		processInput();
 		drawFrame();
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 81fe72d13ad..27f14b0997e 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -241,7 +241,8 @@ void TinyGLRenderer::renderPolygon(const Math::Vector3d &origin, const Math::Vec
 	else if (size.z() == 0)
 		dz = 2;
 	else {
-		if (ordinates->size() != 6) {
+		if (ordinates->size() % 3 > 0) {
+			//return;
 			error("Invalid polygon: %f %f %f", size.x(), size.y(), size.z());
 		}
 	}
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 82286aa3118..a3341a3aeef 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -16,7 +16,10 @@ namespace Freescape {
 
 static Object *load8bitObject(Common::SeekableReadStream *file) {
 
-	Object::Type objectType = (Object::Type)(file->readByte() & 0x1F);
+	byte rawType = file->readByte();
+	debug("Raw object type: %d", rawType);
+	Object::Type objectType = (Object::Type)(rawType & 0x1F);
+
 	Math::Vector3d position, v;
 
 	position.x() = file->readByte();
@@ -33,6 +36,13 @@ static Object *load8bitObject(Common::SeekableReadStream *file) {
 	// already so we can subtract that to get the remaining
 	// length beyond here
 	uint8 byteSizeOfObject = file->readByte();
+	debug("Raw object %d ; type %d ; size %d", objectID, (int)objectType, byteSizeOfObject);
+	if (byteSizeOfObject < 9) {
+		error("Not enough bytes %d to read object %d with type %d", byteSizeOfObject, objectID, objectType);
+		//file->seek(byteSizeOfObject, SEEK_CUR);
+		//return nullptr;
+	}
+
 	assert(byteSizeOfObject >= 9);
 	byteSizeOfObject = byteSizeOfObject - 9;
 	debug("Object %d ; type %d ; size %d", objectID, (int)objectType, byteSizeOfObject);
@@ -61,7 +71,11 @@ static Object *load8bitObject(Common::SeekableReadStream *file) {
 		if (numberOfOrdinates) {
 			ordinates = new Common::Array<uint16>;
 			uint16 ord = 0;
-
+			if (byteSizeOfObject < numberOfOrdinates) {
+				error("Not enough bytes to read all the ordinates");
+				//file->seek(byteSizeOfObject, SEEK_CUR);
+				//return nullptr;
+			}
 			for (int ordinate = 0; ordinate < numberOfOrdinates; ordinate++) {
 				ord = file->readByte();
 				debug("ord: %x", ord);
@@ -78,7 +92,7 @@ static Object *load8bitObject(Common::SeekableReadStream *file) {
 			Common::Array<uint8> conditionArray(conditionData, byteSizeOfObject);
 			Common::String *conditionSource = detokenise8bitCondition(conditionArray);
 			//instructions = getInstructions(conditionSource);
-			debug("%s", conditionSource->c_str());
+			//debug("%s", conditionSource->c_str());
 		}
 
 		// create an object
@@ -92,9 +106,13 @@ static Object *load8bitObject(Common::SeekableReadStream *file) {
 			ordinates,
 			instructions);
 	} break;
-
 	case Object::Entrance: {
 		debug("rotation: %f %f %f", v.x(), v.y(), v.z());
+		if (byteSizeOfObject > 0) {
+			error("Extra bytes in entrance");
+			//file->seek(byteSizeOfObject, SEEK_CUR);
+			//return nullptr;
+		}
 		assert(byteSizeOfObject == 0);
 		// create an entrance
 		return new Entrance(
@@ -199,7 +217,7 @@ Graphics::PixelBuffer *getPaletteGradient(uint8 c1, uint8 c2, uint16 ncolors) {
 		raw_palette->push_back(y1);
 		raw_palette->push_back(y2);
 	}
-	assert(ncolors == 16);
+	//assert(ncolors == 16);
 	assert(raw_palette->size() == ncolors * 3);
 	Graphics::PixelFormat pixelFormat = Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0);
 	Graphics::PixelBuffer *palette = new Graphics::PixelBuffer(pixelFormat, ncolors, DisposeAfterUse::NO); //TODO
@@ -210,6 +228,7 @@ Graphics::PixelBuffer *getPaletteGradient(uint8 c1, uint8 c2, uint16 ncolors) {
 Area *load8bitArea(Common::SeekableReadStream *file, uint16 ncolors) {
 
 	uint32 base = file->pos();
+	debug("Area base: %x", base);
 	uint8 skippedValue = file->readByte();
 	uint8 numberOfObjects = file->readByte();
 	uint8 areaNumber = file->readByte();
@@ -232,16 +251,22 @@ Area *load8bitArea(Common::SeekableReadStream *file, uint16 ncolors) {
 	Graphics::PixelBuffer *palette = getPaletteGradient(ci3, ci4, ncolors);
 
 	debug("Area %d", areaNumber);
-	debug("Objects: %d", numberOfObjects);
+	debug("Skipped: %d Objects: %d", skippedValue, numberOfObjects);
 	debug("Condition Ptr: %x", cPtr);
+	debug("Pos before first object: %lx", file->pos());
 
 	file->seek(15, SEEK_CUR);
+	//file->seek(4, SEEK_CUR);
+
 	ObjectMap *objectsByID = new ObjectMap;
 	ObjectMap *entrancesByID = new ObjectMap;
 	for (uint8 object = 0; object < numberOfObjects; object++) {
+		debug("Reading object: %d", object);
 		Object *newObject = load8bitObject(file);
 
 		if (newObject) {
+			//if (newObject->getObjectID() == 255) // TODO: fix me?
+			//	break;
 			if (newObject->getType() == Object::Entrance) {
 				(*entrancesByID)[newObject->getObjectID() & 0x7fff] = newObject;
 			} else {
@@ -260,7 +285,7 @@ Area *load8bitArea(Common::SeekableReadStream *file, uint16 ncolors) {
 		byte *conditionData = (byte*)malloc(lengthOfCondition);
 		file->read(conditionData, lengthOfCondition);
 		Common::Array<uint8> conditionArray(conditionData, lengthOfCondition);
-		debug("%s", detokenise8bitCondition(conditionArray)->c_str());
+		//debug("%s", detokenise8bitCondition(conditionArray)->c_str());
 	}
 
 	return (new Area(areaNumber, objectsByID, entrancesByID, scale, 255, 255, palette));
@@ -322,30 +347,40 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 		file->read(conditionData, lengthOfCondition);
 		Common::Array<uint8> conditionArray(conditionData, lengthOfCondition);
 		//debug("Global condition %d", numCondition + 1);
-		debug("%s", detokenise8bitCondition(conditionArray)->c_str());
+		//debug("%s", detokenise8bitCondition(conditionArray)->c_str());
 	}
 
 	file->seek(offset + 200);
+	debug("areas index at: %lx", file->pos());
 	uint16 *fileOffsetForArea = new uint16[numberOfAreas];
 	for (uint16 area = 0; area < numberOfAreas; area++) {
 		fileOffsetForArea[area] = file->readUint16LE();
+		debug("offset: %x", fileOffsetForArea[area]);
 	}
 
 	// grab the areas
 	AreaMap *areaMap = new AreaMap;
+	Area *newArea = nullptr;
 	for (uint16 area = 0; area < numberOfAreas; area++) {
 		debug("Area offset %d", fileOffsetForArea[area]);
 
 		file->seek(offset + fileOffsetForArea[area]);
-		Area *newArea = load8bitArea(file, ncolors);
+		newArea = load8bitArea(file, ncolors);
 
 		if (newArea) {
-			(*areaMap)[newArea->getAreaID()] = newArea;
-		}
+			if (!areaMap->contains(newArea->getAreaID()))
+				(*areaMap)[newArea->getAreaID()] = newArea;
+			else
+				error("WARNING: area ID repeated: %d", newArea->getAreaID());
+		} else
+			error("Invalid area?");
 	}
 	_playerHeight = 64;
 	_areasByAreaID = areaMap;
-	_startArea = startArea;
+	if (!areaMap->contains(startArea))
+		_startArea = newArea->getAreaID();
+	else
+		_startArea = startArea;
 	_startEntrance = startEntrance;
 	_colorNumber = ncolors;
 	_binaryBits = 8;
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index 85c823553e9..ac52c2759d4 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -128,7 +128,7 @@ void GeometricObject::draw(Freescape::Renderer *gfx) {
 		gfx->renderCube(_origin, _size, colours);
 	} else if (this->getType() == Rectangle) {
 		gfx->renderRectangle(_origin, _size, colours);
-	} else if (this->isPlanar()) {
+	} else if (this->isPlanar() && _type <= 14) {
 		//debug("Drawing %d of type %d", this->getObjectID(), this->getType());
 		gfx->renderPolygon(_origin, _size, ordinates, colours);
 	}


Commit: 92ca9ab6a4d3f16810fe62649beb85160c50d972
    https://github.com/scummvm/scummvm/commit/92ca9ab6a4d3f16810fe62649beb85160c50d972
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:44+01:00

Commit Message:
FREESCAPE: improved detection of castle

Changed paths:
    engines/freescape/detection.cpp
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/loaders/8bitBinaryLoader.h


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index aeb005d7be2..43b7f0a6754 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -5,7 +5,7 @@ namespace Freescape {
 static const PlainGameDescriptor freescapeGames[] = {
 	{"3dkit", "The 3D Kit Game"},
 	{"driller", "Driller"},
-	{"castle", "Castle Master"},
+	{"castlemaster", "Castle Master"},
 	{"menace", "Menace of Dr. Spoil Sport"},
 	{0, 0}};
 
@@ -53,16 +53,16 @@ static const ADGameDescription gameDescriptions[] = {
 	 Common::kPlatformDOS,
 	 ADGF_NO_FLAGS,
 	 GUIO1(GUIO_NOMIDI)},
-	{"Driller",
-	 "",
+	{"driller",
+	 "Driller",
 	 AD_ENTRY1s("DRILLER.EXE", "cafc0ea0d3424640a7723af87f8bfc0b", 17427),
 	 Common::EN_ANY,
 	 Common::kPlatformDOS,
 	 ADGF_NO_FLAGS,
 	 GUIO3(GUIO_NOMIDI, GUIO_RENDEREGA, GUIO_RENDERCGA)},
 
-	{"Castle",
-	 0,
+	{"castlemaster",
+	 "Castle Master",
 	 AD_ENTRY1s("CME.EXE", "99d8b4dbaad1fd73c9afdde550dc5195", 92320),
 	 Common::EN_ANY,
 	 Common::kPlatformDOS,
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index ab5a7a8fcd3..5692599aae2 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -102,7 +102,7 @@ void FreescapeEngine::loadAssets() {
 
 		file = files.begin()->get()->createReadStream();
 		load16bitBinary(file);
-	} else if (_targetName == "Driller") {
+	} else if (_targetName == "driller") {
 		if (!ConfMan.hasKey("render_mode"))
 			renderMode = "ega";
 		else
@@ -127,15 +127,15 @@ void FreescapeEngine::loadAssets() {
 		} else
 			error("Invalid render mode %s for Driller", renderMode.c_str());
 
-	   } else if (_targetName == "Castle") {
+	   } else if (_targetName == "castlemaster") {
 			file = gameDir.createReadStreamForMember("castle.sna");
 
 			if (file == nullptr)
 				error("Failed to open castle.sna");
-			// Courtyard -> 0x93c1
+			// Courtyard -> 0x93c1 -> 0x8cbc,3
 			// Beds -> 0x867d
 			// All? -> 0x845d or 0x80ed?
-			load8bitBinary(file, 0x93c1, 16);
+			load8bitBinary(file, 0x659c, 16);
 	   } else
 		error("'%s' is an invalid game", _targetName.c_str());
 
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 49a4a489322..aa8a98fcaa6 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -69,11 +69,15 @@ public:
 	Texture *_borderTexture;
 
 	// Parsing
+	uint8 _binaryBits;
 	void loadAssets();
 	void load16bitBinary(Common::SeekableReadStream *file);
-	void load8bitBinary(Common::SeekableReadStream *file, int offset, int ncolors);
-	uint8 _binaryBits;
 
+
+	// 8-bits
+	void load8bitBinary(Common::SeekableReadStream *file, int offset, int ncolors);
+	Area *load8bitArea(Common::SeekableReadStream *file, uint16 ncolors);
+	Object *load8bitObject(Common::SeekableReadStream *file);
 	// Player
 	uint16 _playerHeight;
 
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index a3341a3aeef..01def41870c 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -14,7 +14,7 @@
 
 namespace Freescape {
 
-static Object *load8bitObject(Common::SeekableReadStream *file) {
+Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 
 	byte rawType = file->readByte();
 	debug("Raw object type: %d", rawType);
@@ -225,7 +225,7 @@ Graphics::PixelBuffer *getPaletteGradient(uint8 c1, uint8 c2, uint16 ncolors) {
 	return palette;
 }
 
-Area *load8bitArea(Common::SeekableReadStream *file, uint16 ncolors) {
+Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 ncolors) {
 
 	uint32 base = file->pos();
 	debug("Area base: %x", base);
@@ -233,30 +233,27 @@ Area *load8bitArea(Common::SeekableReadStream *file, uint16 ncolors) {
 	uint8 numberOfObjects = file->readByte();
 	uint8 areaNumber = file->readByte();
 
-	uint16 cPtr = file->readUint16LE();
+	uint16 cPtr = 0;
+	if (_targetName != "castlemaster")
+		cPtr = file->readUint16LE();
 	uint8 scale = file->readByte();
 	debug("Scale: %d", scale);
 
-	uint8 ci1 = file->readByte() & 15;
-	uint8 ci2 = file->readByte() & 15;
-	uint8 ci3 = file->readByte() & 15;
-	uint8 ci4 = file->readByte() & 15;
+	uint8 ci1 = file->readByte(); //& 15;
+	uint8 ci2 = file->readByte(); //& 15;
+	uint8 ci3 = file->readByte(); //& 15;
+	uint8 ci4 = file->readByte(); //& 15;
 
 	debug("Colors: %d %d %d %d", ci1, ci2, ci3, ci4);
-
-	//float *f1, *f2;
-	//f1 = specColors[ci3];
-	//f2 = specColors[ci4];
-
-	Graphics::PixelBuffer *palette = getPaletteGradient(ci3, ci4, ncolors);
+	Graphics::PixelBuffer *palette = getPaletteGradient(1, 1, ncolors);
 
 	debug("Area %d", areaNumber);
 	debug("Skipped: %d Objects: %d", skippedValue, numberOfObjects);
-	debug("Condition Ptr: %x", cPtr);
+	//debug("Condition Ptr: %x", cPtr);
 	debug("Pos before first object: %lx", file->pos());
 
-	file->seek(15, SEEK_CUR);
-	//file->seek(4, SEEK_CUR);
+	if (_targetName != "castlemaster")
+		file->seek(15, SEEK_CUR);
 
 	ObjectMap *objectsByID = new ObjectMap;
 	ObjectMap *entrancesByID = new ObjectMap;
@@ -274,7 +271,7 @@ Area *load8bitArea(Common::SeekableReadStream *file, uint16 ncolors) {
 			}
 		}
 	}
-	file->seek(base + cPtr);
+	/*file->seek(base + cPtr);
 	uint8 numConditions = file->readByte();
 	debug("%d area conditions", numConditions);
 	while (numConditions--) {
@@ -286,7 +283,7 @@ Area *load8bitArea(Common::SeekableReadStream *file, uint16 ncolors) {
 		file->read(conditionData, lengthOfCondition);
 		Common::Array<uint8> conditionArray(conditionData, lengthOfCondition);
 		//debug("%s", detokenise8bitCondition(conditionArray)->c_str());
-	}
+	}*/
 
 	return (new Area(areaNumber, objectsByID, entrancesByID, scale, 255, 255, palette));
 }
@@ -314,6 +311,8 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 
 	file->seek(offset);
 	uint8 numberOfAreas = file->readByte();
+	//if (numberOfAreas < 10) // TODO: just for testing
+	//	numberOfAreas = 10;
 	uint16 dbSize = file->readUint16LE();
 	debug("Database ends at %x", dbSize);
 
@@ -371,9 +370,11 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 			if (!areaMap->contains(newArea->getAreaID()))
 				(*areaMap)[newArea->getAreaID()] = newArea;
 			else
-				error("WARNING: area ID repeated: %d", newArea->getAreaID());
+				debug("WARNING: area ID repeated: %d", newArea->getAreaID());
 		} else
 			error("Invalid area?");
+		if (_targetName == "castlemaster")
+			break;
 	}
 	_playerHeight = 64;
 	_areasByAreaID = areaMap;
diff --git a/engines/freescape/loaders/8bitBinaryLoader.h b/engines/freescape/loaders/8bitBinaryLoader.h
index aa4a0524107..18a78b94f75 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.h
+++ b/engines/freescape/loaders/8bitBinaryLoader.h
@@ -13,10 +13,4 @@
 
 #include "../freescape.h"
 
-namespace Freescape {
-
-//Binary load8bitBinary(Common::String filename);
-
-}
-
-#endif /* defined(__Phantasma___8bitBinaryLoader__) */
\ No newline at end of file
+#endif
\ No newline at end of file


Commit: c6af73a7b216b3a414afec17dc68514413c70b1d
    https://github.com/scummvm/scummvm/commit/c6af73a7b216b3a414afec17dc68514413c70b1d
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:44+01:00

Commit Message:
FREESCAPE: added basic detection of space station oblivion

Changed paths:
    engines/freescape/detection.cpp
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index 43b7f0a6754..51054d82430 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -5,6 +5,7 @@ namespace Freescape {
 static const PlainGameDescriptor freescapeGames[] = {
 	{"3dkit", "The 3D Kit Game"},
 	{"driller", "Driller"},
+	{"spacestationoblivion", "Space Station Oblivion"},
 	{"castlemaster", "Castle Master"},
 	{"menace", "Menace of Dr. Spoil Sport"},
 	{0, 0}};
@@ -60,7 +61,13 @@ static const ADGameDescription gameDescriptions[] = {
 	 Common::kPlatformDOS,
 	 ADGF_NO_FLAGS,
 	 GUIO3(GUIO_NOMIDI, GUIO_RENDEREGA, GUIO_RENDERCGA)},
-
+	{"spacestationoblivion",
+	 "Space Station Oblivion",
+	 AD_ENTRY1s("OBLIVION.EXE", "80783622013750d7c88fd1d35dde919a", 6765),
+	 Common::EN_ANY,
+	 Common::kPlatformDOS,
+	 ADGF_NO_FLAGS,
+	 GUIO3(GUIO_NOMIDI, GUIO_RENDEREGA, GUIO_RENDERCGA)},
 	{"castlemaster",
 	 "Castle Master",
 	 AD_ENTRY1s("CME.EXE", "99d8b4dbaad1fd73c9afdde550dc5195", 92320),
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 5692599aae2..1e24a85d5be 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -102,7 +102,7 @@ void FreescapeEngine::loadAssets() {
 
 		file = files.begin()->get()->createReadStream();
 		load16bitBinary(file);
-	} else if (_targetName == "driller") {
+	} else if (_targetName == "driller" || _targetName == "spacestationoblivion") {
 		if (!ConfMan.hasKey("render_mode"))
 			renderMode = "ega";
 		else


Commit: 6a9b2a8b032d6845cfc4c26bb7c81b7c8260d52c
    https://github.com/scummvm/scummvm/commit/6a9b2a8b032d6845cfc4c26bb7c81b7c8260d52c
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:44+01:00

Commit Message:
FREESCAPE: fixed mirrored rendering and basic ray collision

Changed paths:
    engines/freescape/detection.cpp
    engines/freescape/freescape.cpp
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/loaders/16bitBinaryLoader.cpp
    engines/freescape/objects/geometricobject.cpp


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index 51054d82430..5085cbc590c 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -18,6 +18,13 @@ static const ADGameDescription gameDescriptions[] = {
 	 Common::kPlatformDOS,
 	 ADGF_NO_FLAGS,
 	 GUIO1(GUIO_NOMIDI)},
+	{"3dkit",
+	 "Simple example (cube)",
+	 AD_ENTRY1s("CUBE.RUN", "3b7930be0f646b98885cfb70c26c89a2", 66138),
+	 Common::EN_ANY,
+	 Common::kPlatformDOS,
+	 ADGF_NO_FLAGS,
+	 GUIO1(GUIO_NOMIDI)},
 	{"menace",
 	 "",
 	 AD_ENTRY1s("MODSS.RUN", "409ac1100a15447e742ec1415b2741c3", 91176),
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 1e24a85d5be..72287d4863b 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -217,7 +217,7 @@ void FreescapeEngine::processInput() {
 }
 
 void FreescapeEngine::shoot() {
-	Math::Vector3d direction = directionToVector(_pitch, 90.f - _yaw);
+	Math::Vector3d direction = directionToVector(_pitch, _yaw);
 	Math::Ray ray(_position, direction);
 	Object *shooted = _currentArea->shootRay(ray);
 	if (shooted) {
@@ -257,7 +257,6 @@ Common::Error FreescapeEngine::run() {
 		_scaleVector = _scale;
 	debug("entrace position: %f %f %f", _position.x(), _position.y(), _position.z());
 	debug("player height: %d", _playerHeight);
-	_position.setValue(0, _position.x() - 4096);
 	_position.setValue(1, _position.y() + _playerHeight);
 
 	_pitch = rotation.x() - 180.f;
@@ -297,7 +296,7 @@ void FreescapeEngine::rotate(Common::Point lastMousePos, Common::Point mousePos)
 	xoffset *= _mouseSensitivity;
 	yoffset *= _mouseSensitivity;
 
-	_yaw += xoffset;
+	_yaw -= xoffset;
 	_pitch += yoffset;
 
 	// Make sure that when pitch is out of bounds, screen doesn't get flipped
@@ -326,10 +325,10 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 		_position = _position - _cameraFront * velocity;
 		break;
 	case RIGHT:
-		_position = _position + _cameraRight * velocity;
+		_position = _position - _cameraRight * velocity;
 		break;
 	case LEFT:
-		_position = _position - _cameraRight * velocity;
+		_position = _position + _cameraRight * velocity;
 		break;
 	}
 	// Make sure the user stays at the ground level
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 27f14b0997e..7c6f1c72226 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -175,7 +175,7 @@ void TinyGLRenderer::draw2DText(const Common::String &text, const Common::Point
 }
 
 void TinyGLRenderer::scale(const Math::Vector3d &scale) {
-	tglScalef(-1, 1, 1);
+	tglScalef(1, 1, 1);
 }
 
 void TinyGLRenderer::updateProjectionMatrix(float fov, float nearClipPlane, float farClipPlane) {
@@ -188,7 +188,7 @@ void TinyGLRenderer::updateProjectionMatrix(float fov, float nearClipPlane, floa
 	float ymaxValue = xmaxValue / aspectRatio;
 	//debug("max values: %f %f", xmaxValue, ymaxValue);
 
-	tglFrustum(-xmaxValue, xmaxValue, -ymaxValue, ymaxValue, nearClipPlane, farClipPlane);
+	tglFrustum(xmaxValue, -xmaxValue, -ymaxValue, ymaxValue, nearClipPlane, farClipPlane);
 	tglMatrixMode(TGL_MODELVIEW);
 	tglLoadIdentity();
 }
diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
index dc92043bd89..a19fe14365b 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/16bitBinaryLoader.cpp
@@ -111,8 +111,6 @@ static Object *load16bitObject(StreamLoader &stream) {
 			byteSizeOfObject = 0;
 		// 	//instructions = getInstructions(conditionSource);
 		}
-		// if (objectType == 11)
-		// 	error("triangle!");
 
 		debug("Skipping %d bytes", byteSizeOfObject);
 		stream.skipBytes(byteSizeOfObject);
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index ac52c2759d4..c9ea157368f 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -93,7 +93,6 @@ GeometricObject::GeometricObject(
 
 	if (_type == Cube) {
 		Math::Vector3d torigin = origin;
-		torigin.setValue(0, origin.x() - 4096);
 
 		_boundingBox.expand(torigin);
 		for (int i = 0; i < 3; i++) {
@@ -124,7 +123,6 @@ bool GeometricObject::isPlanar() {
 void GeometricObject::draw(Freescape::Renderer *gfx) {
 	//debug("Drawing %d of type %d", this->getObjectID(), this->getType());
 	if (this->getType() == Cube) {
-		//debug("Drawing cube!");
 		gfx->renderCube(_origin, _size, colours);
 	} else if (this->getType() == Rectangle) {
 		gfx->renderRectangle(_origin, _size, colours);


Commit: 420f2346d85889e2db2f14e8966c206ab7b71b4c
    https://github.com/scummvm/scummvm/commit/420f2346d85889e2db2f14e8966c206ab7b71b4c
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:44+01:00

Commit Message:
FREESCAPE: proof of concept of collision with geometric objects

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/loaders/16bitBinaryLoader.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/objects/geometricobject.cpp
    engines/freescape/objects/geometricobject.h


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 86b9978834b..84b8c8873f8 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -7,6 +7,7 @@
 //
 
 #include "freescape/area.h"
+#include "freescape/objects/geometricobject.h"
 #include "common/algorithm.h"
 #include "freescape/objects/object.h"
 
@@ -109,11 +110,22 @@ void Area::draw(Freescape::Renderer *gfx) {
 }
 
 Object *Area::shootRay(const Math::Ray &ray) {
-	debug("drawable size: %d", drawableObjects.size());
 	for (Common::Array<Object *>::iterator it = drawableObjects.begin(); it != drawableObjects.end(); it++) {
 		if (!(*it)->isInvisible() && (*it)->_boundingBox.isValid() && ray.intersectAABB((*it)->_boundingBox))
 			return (*it);
 	}
+	return nullptr;
+}
 
+Object *Area::checkCollisions(const Math::AABB &boundingBox) {
+	for (Common::Array<Object *>::iterator it = drawableObjects.begin(); it != drawableObjects.end(); it++) {
+		if ((*it)->isDrawable()) {
+			GeometricObject *obj = (GeometricObject*) (*it);
+			if (obj->collides(boundingBox))
+				return (*it);
+		}
+	}
 	return nullptr;
+
+
 }
\ No newline at end of file
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index cd5a2751e4f..f8739af6ac4 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -41,6 +41,8 @@ public:
 	void show();
 
 	Object *shootRay(const Math::Ray &ray);
+	Object *checkCollisions(const Math::AABB &boundingBox);
+
 
 private:
 	uint16 areaID;
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 72287d4863b..d627ef309bf 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -335,8 +335,23 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 	// this one-liner keeps the user at the ground level (xz plane)
 	_position.set(_position.x(), positionY, _position.z());
 	debug("player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
+	checkCollisions();
 }
 
+void FreescapeEngine::checkCollisions() {
+
+	Math::Vector3d v1(_position.x() - _playerWidth / 2, _playerHeight / 2                , _position.z() - _playerDepth / 2);
+	Math::Vector3d v2(_position.x() + _playerWidth / 2, _position.y() + _playerHeight / 2, _position.z() + _playerDepth / 2);
+
+	const Math::AABB boundingBox(v1, v2);
+	Object *obj = _currentArea->checkCollisions(boundingBox);
+
+	if (obj != nullptr)
+		error("Collided with object of size %f %f %f", obj->getSize().x(), obj->getSize().y(), obj->getSize().z());
+}
+
+
+
 bool FreescapeEngine::hasFeature(EngineFeature f) const {
 	return (f == kSupportsReturnToLauncher) ||
 		   (f == kSupportsLoadingDuringRuntime) ||
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index aa8a98fcaa6..6954b2a1841 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -73,13 +73,10 @@ public:
 	void loadAssets();
 	void load16bitBinary(Common::SeekableReadStream *file);
 
-
 	// 8-bits
 	void load8bitBinary(Common::SeekableReadStream *file, int offset, int ncolors);
 	Area *load8bitArea(Common::SeekableReadStream *file, uint16 ncolors);
 	Object *load8bitObject(Common::SeekableReadStream *file);
-	// Player
-	uint16 _playerHeight;
 
 	// Areas
 	uint16 _startArea;
@@ -111,7 +108,12 @@ public:
 	Math::Vector3d _cameraFront, _cameraUp, _cameraRight;
 	// Spacial attributes
 	Math::Vector3d _position, _rotation, _velocity;
+	uint16 _playerHeight;
+	uint16 _playerWidth;
+	uint16 _playerDepth;
 
+	// Effects
+	void checkCollisions();
 
 	// Rendering
 	void drawFrame();
diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
index a19fe14365b..23e48dfb0be 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/16bitBinaryLoader.cpp
@@ -514,6 +514,9 @@ void FreescapeEngine::load16bitBinary(Common::SeekableReadStream *file) {
 
 	delete[] fileOffsetForArea;
 	_playerHeight = playerHeight;
+	_playerWidth = 32;
+	_playerDepth = 32;
+
 	_startArea = startArea;
 	_startEntrance = startEntrance;
 	_colorNumber = colorNumber;
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 01def41870c..b3dfef497f1 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -377,6 +377,9 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 			break;
 	}
 	_playerHeight = 64;
+	_playerWidth = 32;
+	_playerDepth = 32;
+
 	_areasByAreaID = areaMap;
 	if (!areaMap->contains(startArea))
 		_startArea = newArea->getAreaID();
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index c9ea157368f..3ce4fbe4202 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -90,24 +90,39 @@ GeometricObject::GeometricObject(
 	if (_ordinates)
 		ordinates = new Common::Array<uint16>(*_ordinates);
 	condition = _condition;
+	createBoundingBox();
+}
 
-	if (_type == Cube) {
-		Math::Vector3d torigin = origin;
-
-		_boundingBox.expand(torigin);
+void GeometricObject::createBoundingBox() {
+	switch (_type) {
+	default:
+	break;
+	case Cube:
+		_boundingBox.expand(_origin);
 		for (int i = 0; i < 3; i++) {
-			Math::Vector3d v = torigin;
-			v.setValue(i, v.getValue(i) + size.getValue(i));
+			Math::Vector3d v = _origin;
+			v.setValue(i, v.getValue(i) + _size.getValue(i));
 			_boundingBox.expand(v);
 		}
 
 		for (int i = 0; i < 3; i++) {
-			Math::Vector3d v = torigin + size;
-			v.setValue(i, v.getValue(i) - size.getValue(i));
+			Math::Vector3d v = _origin + _size;
+			v.setValue(i, v.getValue(i) - _size.getValue(i));
 			_boundingBox.expand(v);
 		}
-		_boundingBox.expand(torigin + size);
+		_boundingBox.expand(_origin + _size);
 		assert(_boundingBox.isValid());
+		break;
+	case Rectangle:
+		_boundingBox.expand(_origin);
+
+		Math::Vector3d v = _origin + _size;
+		for (int i = 0; i < 3; i++) {
+			if (_size.getValue(i) == 0)
+				v.setValue(i, v.getValue(i) + 10);
+		}
+		_boundingBox.expand(v);
+		break;
 	}
 }
 
@@ -120,6 +135,18 @@ bool GeometricObject::isPlanar() {
 	return (type >= Object::Line) || !_size.x() || !_size.y() || !_size.z();
 }
 
+bool GeometricObject::collides(const Math::AABB &boundingBox) {
+	if (!_boundingBox.isValid() || !boundingBox.isValid())
+		return false;
+
+	return(	_boundingBox.getMax().x() > boundingBox.getMin().x() &&
+			_boundingBox.getMin().x() < boundingBox.getMax().x() &&
+			_boundingBox.getMax().y() > boundingBox.getMin().y() &&
+			_boundingBox.getMin().y() < boundingBox.getMax().y() &&
+			_boundingBox.getMax().z() > boundingBox.getMin().z() &&
+			_boundingBox.getMin().z() < boundingBox.getMax().z());
+}
+
 void GeometricObject::draw(Freescape::Renderer *gfx) {
 	//debug("Drawing %d of type %d", this->getObjectID(), this->getType());
 	if (this->getType() == Cube) {
diff --git a/engines/freescape/objects/geometricobject.h b/engines/freescape/objects/geometricobject.h
index 833e63d9be1..fcb56b3ee03 100644
--- a/engines/freescape/objects/geometricobject.h
+++ b/engines/freescape/objects/geometricobject.h
@@ -28,6 +28,8 @@ public:
 		Common::Array<uint16> *ordinates,
 		FCLInstructionVector condition);
 	virtual ~GeometricObject();
+	void createBoundingBox();
+	bool collides(const Math::AABB &boundingBox);
 	void draw(Freescape::Renderer *gfx) override;
 	bool isDrawable();
 	bool isPlanar();


Commit: 18c4de3eb077b6723bf1c11fa7d3437d885457eb
    https://github.com/scummvm/scummvm/commit/18c4de3eb077b6723bf1c11fa7d3437d885457eb
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:44+01:00

Commit Message:
FREESCAPE: removed game.cpp and game.h files

Changed paths:
  R engines/freescape/game.cpp
  R engines/freescape/game.h


diff --git a/engines/freescape/game.cpp b/engines/freescape/game.cpp
deleted file mode 100644
index 9057b0b315c..00000000000
--- a/engines/freescape/game.cpp
+++ /dev/null
@@ -1,134 +0,0 @@
-//
-//  Game.cpp
-//  Phantasma
-//
-//  Created by Thomas Harte on 17/12/2013.
-//  Copyright (c) 2013 Thomas Harte. All rights reserved.
-//
-
-#include "common/debug.h"
-#include "common/system.h"
-#include "graphics/palette.h"
-#include "graphics/surface.h"
-
-#include "freescape/game.h"
-//#include "GeometricObject.h"
-//#include "Matrix.h"
-//#include "VertexBuffer.h"
-
-Game::Game(Binary binary) {
-}
-
-Game::~Game() {
-	delete areasByAreaID;
-}
-/*
-void Game::setAspectRatio(float aspectRatio)
-{
-	// create a projection matrix; the 16-bit kit permits the range 0-8192 to
-	// be used along all three axes and from that comes the far plane distance
-	// of 14189.
-	Matrix projectionMatrix = Matrix::projectionMatrix(60.0f, aspectRatio, 1.0f, 14189.0f);
-	GeometricObject::setProjectionMatrix(projectionMatrix.contents);
-}
-*/
-
-void Game::draw() {
-	g_system->copyRectToScreen((const void *)_border->data(), _screenW, 0, 0, _screenW, _screenH);
-	g_system->updateScreen();
-	/*
-	// set the clear colour to salmon; we're not catching floor/ceiling
-	// colours yet
-	glClearColor(1.0f, 0.5f, 0.5f, 1.0f);
-
-	// clear depth and colour
-	glDepthMask(GL_TRUE);
-	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
-	// establish the view matrix
-	GeometricObject::setViewMatrix((rotationMatrix * translationMatrix).contents);
-
-	// 4 is the rocket
-	const uint16_t areaNumber = 1;
-
-	// draw once to populate the z buffer without a polygon offset applied
-	glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
-	glDisable(GL_POLYGON_OFFSET_FILL);
-	(*areasByAreaID)[areaNumber]->draw(false, &batchDrawer);
-	batchDrawer.flush();
-
-	// draw with a polygon offset, allowing only reading from the depth buffer —
-	// the overall objective here is to allow arbitrary coplanar rendering
-	glDepthMask(GL_FALSE);
-	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-	glEnable(GL_POLYGON_OFFSET_FILL);
-	(*areasByAreaID)[areaNumber]->draw(true, &batchDrawer);
-	batchDrawer.flush();
-	*/
-}
-
-/*
-void Game::setupOpenGL()
-{
-	GeometricObject::setupOpenGL();
-
-	glEnable(GL_DEPTH_TEST);
-	glDepthFunc(GL_LEQUAL);
-	glLineWidth(4.0f);
-
-	for(AreaMap::iterator iterator = areasByAreaID->begin(); iterator != areasByAreaID->end(); iterator++)
-		iterator->second->setupOpenGL();
-}
-
-void Game::advanceToTime(uint32 millisecondsSinceArbitraryMoment)
-{
-	if(!hasReceivedTime)
-	{
-		timeOfLastTick = millisecondsSinceArbitraryMoment;
-		hasReceivedTime = true;
-		return;
-	}
-
-	// so how many milliseconds is that since we last paid attention?
-	uint32 timeDifference = millisecondsSinceArbitraryMoment - timeOfLastTick;
-
-	// TODO: player movement updates out here
-	float velocityMultiplier = (float)timeDifference;
-//	position[0] -= velocityMultiplier * (velocity[0] * rotationMatrix.contents[0] + velocity[2] * rotationMatrix.contents[2]);
-//	position[1] -= velocityMultiplier * velocity[1];
-//	position[2] -= velocityMultiplier * (velocity[0] * rotationMatrix.contents[8] + velocity[2] * rotationMatrix.contents[10]);
-
-	position[0] -= velocityMultiplier * (velocity[0] * rotationMatrix.contents[0] + velocity[1] * rotationMatrix.contents[1] + velocity[2] * rotationMatrix.contents[2]);
-	position[1] -= velocityMultiplier * (velocity[0] * rotationMatrix.contents[4] + velocity[1] * rotationMatrix.contents[5] + velocity[2] * rotationMatrix.contents[6]);
-	position[2] -= velocityMultiplier * (velocity[0] * rotationMatrix.contents[8] + velocity[1] * rotationMatrix.contents[9] + velocity[2] * rotationMatrix.contents[10]);
-
-	translationMatrix = Matrix::translationMatrix(-position[0], -position[1], -position[2]);
-
-	// we'll advance at 50hz, which makes for some easy integer arithmetic here
-	while(timeDifference > 20)
-	{
-		timeOfLastTick += 20;
-		timeDifference -= 20;
-
-		// TODO: in-game timed events here
-	}
-}*/
-
-/*void Game::rotateView(float x, float y, float z)
-{
-	rotation[0] -= x;
-	rotation[1] -= y;
-	rotation[2] -= z;
-
-	Matrix xRotationMatrix = Matrix::rotationMatrix(rotation[0], 1.0f, 0.0f, 0.0f);
-	Matrix yRotationMatrix = Matrix::rotationMatrix(rotation[1], 0.0f, 1.0f, 0.0f);
-	Matrix zRotationMatrix = Matrix::rotationMatrix(rotation[2], 0.0f, 0.0f, 1.0f);
-	rotationMatrix = zRotationMatrix * xRotationMatrix * yRotationMatrix;
-}*/
-
-/*void Game::setMovementVelocity(float x, float y, float z)
-{
-	velocity[0] = x;
-	velocity[1] = y;
-	velocity[2] = z;
-}*/
diff --git a/engines/freescape/game.h b/engines/freescape/game.h
deleted file mode 100644
index 3274ca75a46..00000000000
--- a/engines/freescape/game.h
+++ /dev/null
@@ -1,51 +0,0 @@
-//
-//  Game.h
-//  Phantasma
-//
-//  Created by Thomas Harte on 17/12/2013.
-//  Copyright (c) 2013 Thomas Harte. All rights reserved.
-//
-
-#ifndef __Phantasma__Game__
-#define __Phantasma__Game__
-
-#include "common/array.h"
-#include "common/hashmap.h"
-#include "engines/util.h"
-
-#include "freescape.h"
-#include "freescape/area.h"
-
-//#include "Matrix.h"
-//#include "BatchDrawer.h"
-
-class Game {
-public:
-	Game(Binary binary);
-	virtual ~Game();
-
-	//void setAspectRatio(float aspectRatio);
-	void draw();
-	//void advanceToTime(uint32 millisecondsSinceArbitraryMoment);
-
-	//void setupOpenGL();
-
-	//void rotateView(float x, float y, float z);
-	//void setMovementVelocity(float x, float y, float z);
-
-private:
-	int _screenW, _screenH;
-	Common::Array<uint8> *_border;
-	uint32 timeOfLastTick;
-	bool hasReceivedTime;
-
-	AreaMap *areasByAreaID;
-
-	float rotation[3], velocity[3], position[3];
-	//Matrix rotationMatrix;
-	//Matrix translationMatrix;
-
-	//BatchDrawer batchDrawer;*/
-};
-
-#endif /* defined(__Phantasma__Game__) */


Commit: 24fa074f15457a5d53618dcf4ea7e5b9c391cfb1
    https://github.com/scummvm/scummvm/commit/24fa074f15457a5d53618dcf4ea7e5b9c391cfb1
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:45+01:00

Commit Message:
FREESCAPE: improved detection tables for several games

Changed paths:
    engines/freescape/detection.cpp


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index 5085cbc590c..0f018dca4a4 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -63,21 +63,41 @@ static const ADGameDescription gameDescriptions[] = {
 	 GUIO1(GUIO_NOMIDI)},
 	{"driller",
 	 "Driller",
-	 AD_ENTRY1s("DRILLER.EXE", "cafc0ea0d3424640a7723af87f8bfc0b", 17427),
+	 {
+		{"DRILLER.EXE", 0, "cafc0ea0d3424640a7723af87f8bfc0b", 17427},
+		{"DRILLC.EXE", 0, "908dd1f8732ebcbaece7d8f0cffd8830", 43864},
+		{"DRILLT.EXE", 0, "afce0e5e0ad8c508e0c31c3e0b18b9a5", 51096},
+		{"DRILLE.EXE", 0, "eb7e9e0acb72e30cf6e9ed20a6480e7a", 51944},
+		{"DRILLH.EXE", 0, "033d2d45390886d0bff78cf53e83b6ed", 47496},
+		AD_LISTEND
+	 },
 	 Common::EN_ANY,
 	 Common::kPlatformDOS,
 	 ADGF_NO_FLAGS,
 	 GUIO3(GUIO_NOMIDI, GUIO_RENDEREGA, GUIO_RENDERCGA)},
 	{"spacestationoblivion",
 	 "Space Station Oblivion",
-	 AD_ENTRY1s("OBLIVION.EXE", "80783622013750d7c88fd1d35dde919a", 6765),
+	 {
+		{"OBLIVION.EXE", 0, "80783622013750d7c88fd1d35dde919a", 6765},
+		{"DRILLC.EXE", 0, "56394eae69f535cbddaa463888086ac6", 43864},
+		{"DRILLE.EXE", 0, "30edf6be0037b2b0e8c6957df62c2a02", 51944},
+		{"DRILLH.EXE", 0, "7f764048050e7a1b1f33aa466230edeb", 47496},
+		AD_LISTEND
+	 },
 	 Common::EN_ANY,
 	 Common::kPlatformDOS,
 	 ADGF_NO_FLAGS,
 	 GUIO3(GUIO_NOMIDI, GUIO_RENDEREGA, GUIO_RENDERCGA)},
 	{"castlemaster",
 	 "Castle Master",
-	 AD_ENTRY1s("CME.EXE", "99d8b4dbaad1fd73c9afdde550dc5195", 92320),
+	 {
+		{"CASTLE.EXE", 0, "f1a141df0e47860246716db20d2ba061", 2806},
+		{"CMC.EXE", 0, "03af2b79b1aad690684cf89025c5f425", 60240},
+		{"CMT.EXE", 0, "a603d3f96e981ab0014b7b1a5a2dc28c", 81840},
+		{"CME.EXE", 0, "99d8b4dbaad1fd73c9afdde550dc5195", 92320},
+		{"CMH.EXE", 0, "1f3b67e649e718e239ebfd7c56e96d47", 63040},
+		AD_LISTEND
+	 },
 	 Common::EN_ANY,
 	 Common::kPlatformDOS,
 	 ADGF_NO_FLAGS,


Commit: 6f500da3f8f74930cf24b17f859f539468f79aed
    https://github.com/scummvm/scummvm/commit/6f500da3f8f74930cf24b17f859f539468f79aed
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:45+01:00

Commit Message:
FREESCAPE: removed StreamLoader and replaced with scummvm API in the 16bit binary loader

Changed paths:
  R engines/freescape/loaders/loader.h
    engines/freescape/freescape.cpp
    engines/freescape/loaders/16bitBinaryLoader.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index d627ef309bf..55e57357a8a 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -227,7 +227,6 @@ void FreescapeEngine::shoot() {
 	//debug("camera front: %f %f %f", _cameraFront.x(), _rotation.y(), _rotation.z());
 }
 
-
 Common::Error FreescapeEngine::run() {
 	// Initialize graphics:
 	_gfx = Freescape::createRenderer(_system);
@@ -347,11 +346,9 @@ void FreescapeEngine::checkCollisions() {
 	Object *obj = _currentArea->checkCollisions(boundingBox);
 
 	if (obj != nullptr)
-		error("Collided with object of size %f %f %f", obj->getSize().x(), obj->getSize().y(), obj->getSize().z());
+		debug("Collided with object of size %f %f %f", obj->getSize().x(), obj->getSize().y(), obj->getSize().z());
 }
 
-
-
 bool FreescapeEngine::hasFeature(EngineFeature f) const {
 	return (f == kSupportsReturnToLauncher) ||
 		   (f == kSupportsLoadingDuringRuntime) ||
diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
index 23e48dfb0be..82179f6e5d1 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/16bitBinaryLoader.cpp
@@ -17,7 +17,6 @@
 #include "freescape/language/instruction.h"
 #include "freescape/language/parser.h"
 #include "freescape/loaders/16bitBinaryLoader.h"
-#include "freescape/loaders/loader.h"
 #include "freescape/objects/geometricobject.h"
 #include "freescape/objects/object.h"
 
@@ -28,10 +27,10 @@ typedef enum {
 		Border = 0x4524,
 } ChunkType;
 
-static Object *load16bitObject(StreamLoader &stream) {
+static Object *load16bitObject(Common::SeekableReadStream *file) {
 	// get object flags and type
-	uint8 objectFlags = stream.get8();
-	Object::Type objectType = (Object::Type)stream.get8();
+	uint8 objectFlags = file->readByte();
+	Object::Type objectType = (Object::Type)file->readByte();
 
 	/*
 		Notes to self:
@@ -44,25 +43,25 @@ static Object *load16bitObject(StreamLoader &stream) {
 	*/
 
 	// get unknown value
-	uint16 skippedShort = stream.get16();
+	uint16 skippedShort = file->readUint16BE();
 	debug("skippedShort: %d", skippedShort);
 
 	// grab location, size
 	Math::Vector3d position, size;
-	position.x() = stream.get16();
-	position.y() = stream.get16();
-	position.z() = stream.get16();
-	size.x() = stream.get16();
-	size.y() = stream.get16();
-	size.z() = stream.get16();
+	position.x() = file->readUint16BE();
+	position.y() = file->readUint16BE();
+	position.z() = file->readUint16BE();
+	size.x() = file->readUint16BE();
+	size.y() = file->readUint16BE();
+	size.z() = file->readUint16BE();
 
 	// object ID
-	uint16 objectID = stream.get16();
+	uint16 objectID = file->readUint16BE();
 
 	// size of object on disk; we've accounted for 20 bytes
 	// already so we can subtract that to get the remaining
 	// length beyond here
-	uint32 byteSizeOfObject = (uint32)(stream.get16() << 1) - 20;
+	uint32 byteSizeOfObject = (uint32)(file->readUint16BE() << 1) - 20;
 
 	debug("Object %d ; type %d ; flags %d ; size %d", (int)objectID, (int)objectType, (int)objectFlags, byteSizeOfObject);
 	debug("Location: %f, %f, %f", position.x(), position.y(), position.z());
@@ -74,9 +73,9 @@ static Object *load16bitObject(StreamLoader &stream) {
 		int numberOfColours = GeometricObject::numberOfColoursForObjectOfType(objectType);
 		Common::Array<uint8> *colours = new Common::Array<uint8>;
 		for (uint8 colour = 0; colour < numberOfColours/2; colour++) {
-			uint8 c1 = stream.get8();
+			uint8 c1 = file->readByte();
 			byteSizeOfObject--;
-			uint8 c2 = stream.get8();
+			uint8 c2 = file->readByte();
 			byteSizeOfObject--;
 			colours->push_back( (c1 & 0x0f) | ((c2 & 0x0f) << 4));
 			debug("color[%d] = %d", 2*colour, (c1 & 0x0f) | ((c2 & 0x0f) << 4));
@@ -94,7 +93,7 @@ static Object *load16bitObject(StreamLoader &stream) {
 			ordinates = new Common::Array<uint16>;
 
 			for (int ordinate = 0; ordinate < numberOfOrdinates; ordinate++) {
-				ordinates->push_back(stream.get16());
+				ordinates->push_back(file->readUint16BE());
 				byteSizeOfObject -= 2;
 			}
 		}
@@ -102,19 +101,19 @@ static Object *load16bitObject(StreamLoader &stream) {
 		// grab the object condition, if there is one
 		FCLInstructionVector instructions;
 		if (byteSizeOfObject > 0) {
-		// 	uint32 offset = stream.getFileOffset();
-		    Common::Array<uint8> *conditionData = stream.nextBytes(byteSizeOfObject);
-		// 	byteSizeOfObject = byteSizeOfObject - (offset - stream.getFileOffset());
-
-			Common::String *conditionSource = detokenise16bitCondition(*conditionData);
+			// get the condition
+			byte *conditionData = (byte*)malloc(byteSizeOfObject);
+			file->read(conditionData, byteSizeOfObject);
+			Common::Array<uint8> conditionArray(conditionData, byteSizeOfObject);
+			Common::String *conditionSource = detokenise16bitCondition(conditionArray);
 		 	debug("Condition: %s", conditionSource->c_str());
 			byteSizeOfObject = 0;
 		// 	//instructions = getInstructions(conditionSource);
 		}
 
 		debug("Skipping %d bytes", byteSizeOfObject);
-		stream.skipBytes(byteSizeOfObject);
-		debug("End of object at %x", stream.getFileOffset());
+		file->seek(byteSizeOfObject, SEEK_CUR);
+		debug("End of object at %lx", file->pos());
 
 		// create an object
 		return new GeometricObject(
@@ -130,8 +129,8 @@ static Object *load16bitObject(StreamLoader &stream) {
 
 	case Object::Entrance:
 		debug("Skipping %d bytes", byteSizeOfObject);
-		stream.skipBytes(byteSizeOfObject);
-		debug("End of object at %x", stream.getFileOffset());
+		file->seek(byteSizeOfObject, SEEK_CUR);
+		debug("End of object at %lx", file->pos());
 		return new Entrance(objectID, position, size); // size will be always 0,0,0?
 		break;
 	case Object::Sensor:
@@ -145,13 +144,13 @@ static Object *load16bitObject(StreamLoader &stream) {
 	//int j = 0;
 	//for (i = 0; i < byteSizeOfObject/2; i++)
 	//	cout << i << stream.get16() << endl;
-	stream.skipBytes(byteSizeOfObject);
-	debug("End of object at %x", stream.getFileOffset());
+	file->seek(byteSizeOfObject, SEEK_CUR);
+	debug("End of object at %lx", file->pos());
 
 	return nullptr;
 }
 
-void load16bitInstrument(StreamLoader &stream) {
+/*void load16bitInstrument(StreamLoader &stream) {
 	uint16 zero = stream.get16();
 	assert( zero == 0);
 	uint16 type = stream.get16();
@@ -172,33 +171,32 @@ void load16bitInstrument(StreamLoader &stream) {
 	stream.get16();
 	stream.get16();
 	debug("type %d ; x %d ; y %d ; length %d ; height %d ; lb %d ; rt %d ; variable: %d", type, x, y, length, height, lb, rt, v);
-}
+}*/
 
-Area *load16bitArea(StreamLoader &stream) {
+Area *load16bitArea(Common::SeekableReadStream *file) {
 	// the lowest bit of this value seems to indicate
 	// horizon on or off; this is as much as I currently know
-	uint16 skippedValue = stream.get16();
-	uint16 numberOfObjects = stream.get16();
-	uint16 areaNumber = stream.get16();
+	uint16 skippedValue = file->readUint16BE();
+	uint16 numberOfObjects = file->readUint16BE();
+	uint16 areaNumber = file->readUint16BE();
 
 	debug("Area %d", areaNumber);
 	debug("Skipped value %d", skippedValue);
 	debug("Objects: %d", numberOfObjects);
 
 	// I've yet to decipher this fully
-	stream.get16();
-	stream.get16();
-	stream.get16();
-
+	file->readUint16BE();
+	file->readUint16BE();
+	file->readUint16BE();
 
-	uint8 skyColor = stream.get8();
-	skyColor = (stream.get8() << 4) | skyColor;
+	uint8 skyColor = file->readByte();
+	skyColor = (file->readByte() << 4) | skyColor;
 
 	debug("Sky color %x", skyColor);
-	uint8 groundColor = stream.get8();
-	groundColor = (stream.get8() << 4) | groundColor;
+	uint8 groundColor = file->readByte();
+	groundColor = (file->readByte() << 4) | groundColor;
 	debug("Ground color %x", groundColor);
-	stream.skipBytes(14);
+	file->seek(14, SEEK_CUR);
 
 	// this is just a complete guess
 	/*Common::Array<uint8> palette;
@@ -223,7 +221,7 @@ Area *load16bitArea(StreamLoader &stream) {
 	// get the objects or whatever; entrances use a unique numbering
 	// system and have the high bit of their IDs set in the original file
 	for (uint16 object = 0; object < numberOfObjects; object++) {
-		Object *newObject = load16bitObject(stream);
+		Object *newObject = load16bitObject(file);
 
 		if (newObject) {
 			if (newObject->getType() == Object::Entrance) {
@@ -234,52 +232,41 @@ Area *load16bitArea(StreamLoader &stream) {
 		}
 	}
 
-	uint16 numberOfLocalConditions = stream.get16();
+	uint16 numberOfLocalConditions = file->readUint16BE();
 	debug("Number of conditions: %d", numberOfLocalConditions);
 	for (uint16 localCondition = 0; localCondition < numberOfLocalConditions; localCondition++) {
 		// 12 bytes for the name of the condition;
 		// we don't care
-		stream.skipBytes(12);
+		file->seek(12, SEEK_CUR);
 
 		// get the length and the data itself, converting from
 		// shorts to bytes
-		uint32 lengthOfCondition = (uint32)stream.get16() << 1;
+		uint32 lengthOfCondition = (uint32)file->readUint16BE() << 1;
+
 		debug("Length of condition: %d", lengthOfCondition);
 		if (lengthOfCondition == 0) {
 			break;
 		}
 
 		// get the condition
-		Common::Array<uint8> *conditionData = stream.nextBytes(lengthOfCondition);
+		byte *conditionData = (byte*)malloc(lengthOfCondition);
+		file->read(conditionData, lengthOfCondition);
+		Common::Array<uint8> conditionArray(conditionData, lengthOfCondition);
 
-		debug("Local condition %d at %x", localCondition + 1, stream.getFileOffset());
-		debug("%s", detokenise16bitCondition(*conditionData)->c_str());
+		debug("Local condition %d at %lx", localCondition + 1, file->pos());
+		debug("%s", detokenise16bitCondition(conditionArray)->c_str());
 	}
 
 	return (new Area(areaNumber, objectsByID, entrancesByID, 1, skyColor, groundColor));
 }
 
 void FreescapeEngine::load16bitBinary(Common::SeekableReadStream *file) {
-	const uint32 fileSize = file->size();
-	byte *buf = (byte *)malloc(fileSize);
-	file->read(buf, fileSize);
-
-	Common::Array<uint8> binary;
-
-	uint32 i = 0;
-	while (i < fileSize) {
-		binary.push_back(buf[i]);
-		i++;
-	}
-
-	StreamLoader streamLoader(binary);
-
 	Common::Array<uint8>::size_type baseOffset = 0;
 
 	// check whether this looks like an Amiga game; if so it'll start with AM
 	// XOR'd with the repeating byte pattern 0x71, 0xc1 or with the pattern
 	// 0x88 0x2c if it's on the ST (though the signature will still be AM)
-	uint16 platformID = streamLoader.get16();
+	uint16 platformID = file->readUint16BE();
 	debug("%d", platformID);
 
 	if (
@@ -287,88 +274,89 @@ void FreescapeEngine::load16bitBinary(Common::SeekableReadStream *file) {
 		(platformID == 12428) || (platformID == 51553)) {
 		// TODO: record original platform type, so we can decode the palette
 		// and possibly the border properly
+		debug("Loading an Amiga game");
 		//cout << "AMIGA" << endl;
 
-		streamLoader.setReadMask((platformID >> 8) ^ 'A', (platformID & 0xff) ^ 'M');
+		// TODO
+		//streamLoader.setReadMask((platformID >> 8) ^ 'A', (platformID & 0xff) ^ 'M');
 	} else {
-		debug("DOS");
+		debug("Loading a DOS game");
 		// find DOS end of file and consume it
-		while (!streamLoader.eof()) {
-			uint8 b = streamLoader.get8();
+		while (!file->eos()) {
+			uint8 b = file->readByte();
 			if (b == 0x1a)
 				break;
 		}
-		streamLoader.get8();
+		file->readByte();
 
 		// advance to the next two-byte boundary if necessary
-		streamLoader.alignPointer();
+		if (file->pos() % 2 > 0)
+			file->readByte();
 
 		// skip bytes with meaning unknown
-		streamLoader.get16();
+		file->readUint16BE();
 
 		// this brings us to the beginning of the embedded
 		// .KIT file, so we'll grab the base offset for
 		// finding areas later
-		baseOffset = streamLoader.getFileOffset();
+		baseOffset = file->pos(); //streamLoader.getFileOffset();
 
 		// check that the next two bytes are "PC", then
 		// skip the number that comes after
-		if (streamLoader.get8() != 'C' || streamLoader.get8() != 'P')
+		if (file->readByte() != 'C' || file->readByte() != 'P')
 			error("invalid header");
 	}
 
 	// skip an unknown meaning
-	streamLoader.get16();
+	file->readUint16BE();
 
 	// start grabbing some of the basics...
 
-	uint16 numberOfAreas = streamLoader.get16();
-	uint16 sm = streamLoader.get16();
+	uint16 numberOfAreas = file->readUint16BE();
+	uint16 sm = file->readUint16BE();
 	debug("Something??: %d", sm); // meaning unknown
-
 	debug("Number of areas: %d", numberOfAreas);
 
-	uint16 windowCentreX = streamLoader.get16();
-	uint16 windowCentreY = streamLoader.get16();
-	uint16 windowWidth = streamLoader.get16();
-	uint16 windowHeight = streamLoader.get16();
+	uint16 windowCentreX = file->readUint16BE();
+	uint16 windowCentreY = file->readUint16BE();
+	uint16 windowWidth = file->readUint16BE();
+	uint16 windowHeight = file->readUint16BE();
 
 	debug("Window centre: (%d, %d)", windowCentreX, windowCentreY);
 	debug("Window size: (%d, %d)", windowWidth, windowHeight);
 
-	uint16 scaleX = streamLoader.get16();
-	uint16 scaleY = streamLoader.get16();
-	uint16 scaleZ = streamLoader.get16();
+	uint16 scaleX = file->readUint16BE();
+	uint16 scaleY = file->readUint16BE();
+	uint16 scaleZ = file->readUint16BE();
 
 	debug("Scale %d, %d, %d", scaleX, scaleY, scaleZ);
-	uint16 timerReload = streamLoader.get16();
+	uint16 timerReload = file->readUint16BE();
 
 	debug("Timer: every %d 50Hz frames", timerReload);
 
-	uint16 maximumActivationDistance = streamLoader.get16();
-	uint16 maximumFallDistance = streamLoader.get16();
-	uint16 maximumClimbDistance = streamLoader.get16();
+	uint16 maximumActivationDistance = file->readUint16BE();
+	uint16 maximumFallDistance = file->readUint16BE();
+	uint16 maximumClimbDistance = file->readUint16BE();
 
 	debug("Maximum activation distance: %d", maximumActivationDistance);
 	debug("Maximum fall distance: %d", maximumFallDistance);
 	debug("Maximum climb distance: %d", maximumClimbDistance);
 
-	uint16 startArea = streamLoader.get16();
-	uint16 startEntrance = streamLoader.get16();
+	uint16 startArea = file->readUint16BE();
+	uint16 startEntrance = file->readUint16BE();
 
 	debug("Start at entrance %d in area %d", startEntrance, startArea);
 
-	uint16 playerHeight = streamLoader.get16();
-	uint16 playerStep = streamLoader.get16();
-	uint16 playerAngle = streamLoader.get16();
+	uint16 playerHeight = file->readUint16BE();
+	uint16 playerStep = file->readUint16BE();
+	uint16 playerAngle = file->readUint16BE();
 
 	debug("Height %d, step %d, angle %d", playerHeight, playerStep, playerAngle);
 
-	uint16 startVehicle = streamLoader.get16();
-	uint16 executeGlobalCondition = streamLoader.get16();
+	uint16 startVehicle = file->readUint16BE();
+	uint16 executeGlobalCondition = file->readUint16BE();
 
 	debug("Start vehicle %d, execute global condition %d", startVehicle, executeGlobalCondition);
-
 	// I haven't figured out what the next 106
 	// bytes mean, so we'll skip them — global objects
 	// maybe? Likely not 106 bytes in every file.
@@ -382,7 +370,7 @@ void FreescapeEngine::load16bitBinary(Common::SeekableReadStream *file) {
 	for (i = 0; i < 106/2; i++)
 		cout << streamLoader.get16() << endl;*/
 
-	streamLoader.skipBytes(106);
+	file->seek(106, SEEK_CUR);
 
 	// at this point I should properly load the border/key/mouse
 	// bindings, but I'm not worried about it for now.
@@ -405,31 +393,33 @@ void FreescapeEngine::load16bitBinary(Common::SeekableReadStream *file) {
 	//for (i = 0; i < 350/2; i++)
 	//	cout << streamLoader.get16() << endl;
 
-	streamLoader.skipBytes(350);
+	file->seek(350, SEEK_CUR);
 
 	// there are then file pointers for every area — these are
 	// the number of shorts from the 'PC' tag, so multiply by
 	// two for bytes. Each is four bytes
 	uint32 *fileOffsetForArea = new uint32[numberOfAreas];
 	for (uint16 area = 0; area < numberOfAreas; area++)
-		fileOffsetForArea[area] = (uint32)streamLoader.get32() << 1;
+		fileOffsetForArea[area] = file->readUint32BE() << 1;
 
 	// now come the global conditions
-	uint16 numberOfGlobalConditions = streamLoader.get16();
+	uint16 numberOfGlobalConditions = file->readUint16BE();
 	for (uint16 globalCondition = 0; globalCondition < numberOfGlobalConditions; globalCondition++) {
 		// 12 bytes for the name of the condition;
 		// we don't care
-		streamLoader.skipBytes(12);
+		file->seek(12, SEEK_CUR);
 
 		// get the length and the data itself, converting from
 		// shorts to bytes
-		uint32 lengthOfCondition = (uint32)streamLoader.get16() << 1;
+		uint32 lengthOfCondition = (uint32)file->readUint16BE() << 1;
 
 		// get the condition
-		Common::Array<uint8> *conditionData = streamLoader.nextBytes(lengthOfCondition);
+		byte *conditionData = (byte*)malloc(lengthOfCondition);
+		file->read(conditionData, lengthOfCondition);
+		Common::Array<uint8> conditionArray(conditionData, lengthOfCondition);
 
-		debug("Global condition %d at %x", globalCondition + 1, streamLoader.getFileOffset());
-		debug("%s", detokenise16bitCondition(*conditionData)->c_str());
+		debug("Global condition %d at %lx", globalCondition + 1, file->pos());
+		debug("%s", detokenise16bitCondition(conditionArray)->c_str());
 	}
 
 	// grab the areas
@@ -437,13 +427,14 @@ void FreescapeEngine::load16bitBinary(Common::SeekableReadStream *file) {
 	for (uint16 area = 0; area < numberOfAreas; area++) {
 		debug("Area offset %d", fileOffsetForArea[area]);
 
-		streamLoader.setFileOffset(fileOffsetForArea[area] + baseOffset);
-		Area *newArea = load16bitArea(streamLoader);
+		file->seek(fileOffsetForArea[area] + baseOffset);
+		Area *newArea = load16bitArea(file);
 
 		if (newArea) {
 			(*areaMap)[newArea->getAreaID()] = newArea;
 		}
 	}
+	// TODO
 	//load16bitInstrument(streamLoader);
 
 	Common::Array<uint8>::size_type o;
@@ -452,22 +443,22 @@ void FreescapeEngine::load16bitBinary(Common::SeekableReadStream *file) {
 	uint16 chunkType = 0;
 	uint16 chunkSize = 0;
 	uint16 colorNumber = 0;
-	debug("End of areas at %x", streamLoader.getFileOffset());
-	while (!streamLoader.eof()) {
-		o = streamLoader.getFileOffset();
-		chunkType = streamLoader.get16();
+	debug("End of areas at %lx", file->pos());
+	while (!file->eos()) {
+		o = file->pos();
+		chunkType = file->readUint16BE();
 		if (chunkType == First) {
-			chunkSize = streamLoader.rget16();
+			chunkSize = file->readUint16LE();
 			if (chunkSize != 0xac) {
 				debug("skip %x", chunkType);
-				streamLoader.setFileOffset(o+2);
+				file->seek(o+2);
 			} else {
 				debug("First chunk found at %x with size %x", o, chunkSize);
-				streamLoader.skipBytes(chunkSize-2);
+				file->seek(chunkSize-2, SEEK_CUR);
 			}
 		}
 		else if (chunkType == Border) {
-			chunkSize = streamLoader.rget16();
+			chunkSize = file->readUint16LE();
 			debug("Border found at %x with size %x", o, chunkSize);
 
 			if (chunkSize == 320*200 / 4)
@@ -479,16 +470,19 @@ void FreescapeEngine::load16bitBinary(Common::SeekableReadStream *file) {
 			else
 				error("Unexpected size of image %d", chunkSize);
 
-			raw_border = streamLoader.nextBytes(chunkSize);
+			byte *borderData = (byte*)malloc(chunkSize);
+			file->read(borderData, chunkSize);
+			raw_border = new Common::Array<uint8>(borderData, chunkSize);
+
 			raw_palette = new Common::Array<uint8>();
-			debug("Palete follows at %x", streamLoader.getFileOffset());
-			for (i = 0; i < colorNumber*3; i++)
-				raw_palette->push_back(streamLoader.get8() << 2);
-
-			debug("Palete finishes at %x", streamLoader.getFileOffset());
-			chunkSize = streamLoader.rget16();
-			debug("Something else of size %x at %x??", chunkSize, streamLoader.getFileOffset());
-			streamLoader.skipBytes(chunkSize);
+			debug("Palete follows at %lx", file->pos());
+			for (int i = 0; i < colorNumber*3; i++)
+				raw_palette->push_back(file->readByte() << 2);
+
+			debug("Palete finishes at %lx", file->pos());
+			chunkSize = file->readUint16LE();
+			debug("Something else of size %x at %lx??", chunkSize, file->pos());
+			file->seek(chunkSize, SEEK_CUR);
 		}
 		else {
 			debug("skip %x", chunkType);
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index b3dfef497f1..f2a7bd4f954 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -7,7 +7,6 @@
 #include "freescape/language/instruction.h"
 #include "freescape/language/parser.h"
 #include "freescape/loaders/8bitBinaryLoader.h"
-#include "freescape/loaders/loader.h"
 #include "freescape/objects/geometricobject.h"
 #include "freescape/objects/entrance.h"
 #include "freescape/objects/object.h"
diff --git a/engines/freescape/loaders/loader.h b/engines/freescape/loaders/loader.h
deleted file mode 100644
index 24627db1298..00000000000
--- a/engines/freescape/loaders/loader.h
+++ /dev/null
@@ -1,98 +0,0 @@
-#ifndef __Phantasma___Loader__
-#define __Phantasma___Loader__
-
-#include "common/array.h"
-
-namespace Freescape {
-
-class StreamLoader {
-private:
-	Common::Array<uint8>::size_type bytePointer;
-	Common::Array<uint8> binary;
-	uint8 readMaskByte1;
-	uint8 readMaskByte2;
-
-public:
-	StreamLoader(Common::Array<uint8> &_binary) {
-		binary = _binary;
-		bytePointer = 0;
-		readMaskByte1 = 0;
-		readMaskByte2 = 0;
-	}
-
-	uint8 get8() {
-		if (!eof()) {
-			uint8 sourceByte = binary[bytePointer];
-
-			if (bytePointer & 1)
-				sourceByte ^= readMaskByte2;
-			else
-				sourceByte ^= readMaskByte1;
-
-			bytePointer++;
-			return sourceByte;
-		} else
-			error("eof");
-
-		return 0;
-	}
-
-	uint16 get16() {
-		uint16 result = (uint16)(get8() << 8);
-		result |= get8();
-		return result;
-	}
-
-	uint16 rget16() {
-		uint16 result = (uint16)(get8());
-		result |= (get8() << 8);
-		return result;
-	}
-
-	uint32 get32() {
-		uint32 result = (uint32)(get16() << 16);
-		result |= get16();
-		return result;
-	}
-
-	bool eof() {
-		return bytePointer >= binary.size();
-	}
-
-	void alignPointer() {
-		if (bytePointer & 1)
-			bytePointer++;
-	}
-
-	void skipBytes(Common::Array<uint8>::size_type numberOfBytes) {
-		bytePointer += numberOfBytes;
-		assert(bytePointer <= binary.size());
-	}
-
-	Common::Array<uint8> *nextBytes(Common::Array<uint8>::size_type numberOfBytes) {
-		Common::Array<uint8> *returnBuffer(new Common::Array<uint8>);
-		//debug("skiping %d bytes", numberOfBytes);
-
-		while (numberOfBytes--)
-			returnBuffer->push_back(get8());
-
-		return returnBuffer;
-	}
-
-	Common::Array<uint8>::size_type getFileOffset() {
-		return bytePointer;
-	}
-
-	void setFileOffset(Common::Array<uint8>::size_type newOffset) {
-		bytePointer = newOffset;
-	}
-
-	void setReadMask(uint8 byte1, uint8 byte2) {
-		readMaskByte1 = byte1;
-		readMaskByte2 = byte2;
-	}
-};
-
-} // namespace Freescape
-
-#endif
\ No newline at end of file


Commit: d3f29493e87e52835ab5cdbca025f57c09156547
    https://github.com/scummvm/scummvm/commit/d3f29493e87e52835ab5cdbca025f57c09156547
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:45+01:00

Commit Message:
FREESCAPE: fixed rendering of planar objects and enforced more constrains on 8-bits binary loading

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/freescape.cpp
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 84b8c8873f8..73f2497ed81 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -98,13 +98,14 @@ void Area::draw(Freescape::Renderer *gfx) {
 		gfx->drawSky(skyColor);
 	assert(drawableObjects.size() > 0);
 	for (Common::Array<Object *>::iterator it = drawableObjects.begin(); it != drawableObjects.end(); it++) {
-		if (!(*it)->isInvisible() && !(*it)->isPlanar())
+		if (!(*it)->isInvisible()) {
 			(*it)->draw(gfx);
+		}
 	}
-	for (Common::Array<Object *>::iterator it = drawableObjects.begin(); it != drawableObjects.end(); it++) {
+	/*for (Common::Array<Object *>::iterator it = drawableObjects.begin(); it != drawableObjects.end(); it++) {
 		if (!(*it)->isInvisible() && (*it)->isPlanar())
 			(*it)->draw(gfx);
-	}
+	}*/
 	if (groundColor != 255)
 		gfx->drawFloor(groundColor);
 }
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 55e57357a8a..f211d127532 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -135,7 +135,7 @@ void FreescapeEngine::loadAssets() {
 			// Courtyard -> 0x93c1 -> 0x8cbc,3
 			// Beds -> 0x867d
 			// All? -> 0x845d or 0x80ed?
-			load8bitBinary(file, 0x659c, 16);
+			load8bitBinary(file, 0x8cbc, 16);
 	   } else
 		error("'%s' is an invalid game", _targetName.c_str());
 
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 7c6f1c72226..84dbfd57d6a 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -252,9 +252,7 @@ void TinyGLRenderer::renderPolygon(const Math::Vector3d &origin, const Math::Vec
 
 	Common::Array<Math::Vector3d> vertices;
 	tglEnable(TGL_POLYGON_OFFSET_FILL);
-	// tglEnable(TGL_POLYGON_OFFSET_LINE);
-	// tglEnable(TGL_POLYGON_OFFSET_POINT);
-	tglPolygonOffset(1.f, 1.f);
+	tglPolygonOffset(-2.0f, 1.f);
 	if ((*colours)[0] != _keyColor) {
 		_palette->getRGBAt((*colours)[0], r, g, b);
 		tglColor3ub(r, g, b);
@@ -279,8 +277,8 @@ void TinyGLRenderer::renderPolygon(const Math::Vector3d &origin, const Math::Vec
 void TinyGLRenderer::renderRectangle(const Math::Vector3d &origin, const Math::Vector3d &size, Common::Array<uint8> *colours) {
 
 	assert(size.x() == 0 || size.y() == 0 || size.z() == 0);
-
-	tglPolygonOffset(1, 1);
+	tglEnable(TGL_POLYGON_OFFSET_FILL);
+	tglPolygonOffset(-2.0f, 1.0f);
 	//debug("origin: %f, %f, %f", origin.x(), origin.y(), origin.z());
 	//debug("size: %f, %f, %f", size.x(), size.y(), size.z());
 
@@ -349,9 +347,7 @@ void TinyGLRenderer::renderRectangle(const Math::Vector3d &origin, const Math::V
 	}
 
 	tglPolygonOffset(0, 0);
-	//tglDepthMask(TGL_TRUE);
-	//tglColorMask(TGL_FALSE, TGL_FALSE, TGL_FALSE, TGL_FALSE);
-	//tglDisable(TGL_POLYGON_OFFSET_FILL);
+	tglDisable(TGL_POLYGON_OFFSET_FILL);
 }
 
 
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index f2a7bd4f954..a80826afdba 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -93,6 +93,7 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 			//instructions = getInstructions(conditionSource);
 			//debug("%s", conditionSource->c_str());
 		}
+		debug("End of object at %lx", file->pos());
 
 		// create an object
 		return new GeometricObject(
@@ -113,6 +114,7 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 			//return nullptr;
 		}
 		assert(byteSizeOfObject == 0);
+		debug("End of object at %lx", file->pos());
 		// create an entrance
 		return new Entrance(
 			objectID,
@@ -266,6 +268,7 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 			if (newObject->getType() == Object::Entrance) {
 				(*entrancesByID)[newObject->getObjectID() & 0x7fff] = newObject;
 			} else {
+				assert(!(objectsByID->contains(newObject->getObjectID())));
 				(*objectsByID)[newObject->getObjectID()] = newObject;
 			}
 		}


Commit: 45b2731a2f580e20503c2cd01ce8697c0fc3d796
    https://github.com/scummvm/scummvm/commit/45b2731a2f580e20503c2cd01ce8697c0fc3d796
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:45+01:00

Commit Message:
FREESCAPE: initial implementation of pyramid rendering

Changed paths:
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/gfx_tinygl.h
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/module.mk
    engines/freescape/objects/geometricobject.cpp
    engines/freescape/objects/geometricobject.h


diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 095cfefd008..d6d11d9664c 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -68,6 +68,15 @@ public:
 	virtual void init() = 0;
 	virtual void clear() = 0;
 
+	typedef enum {
+		EastPyramid = 4,
+		WestPyramid = 5,
+		UpPyramid = 6,
+		DownPyramid = 7,
+		NorthPyramid = 8,
+		SouthPyramid = 9,
+	} PyramidType;
+
 	/**
 	 *  Swap the buffers, making the drawn screen visible
 	 */
@@ -88,6 +97,7 @@ public:
 	virtual void renderCube(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) = 0;
 	virtual void renderRectangle(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) = 0;
 	virtual void renderPolygon(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours) = 0;
+	virtual void renderPyramid(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours, int type) = 0;
 	virtual void renderFace(const Common::Array<Math::Vector3d> &vertices) = 0;
 
 	virtual void drawSky(uint8 color) = 0;
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 84dbfd57d6a..e982fb1d757 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -350,6 +350,126 @@ void TinyGLRenderer::renderRectangle(const Math::Vector3d &origin, const Math::V
 	tglDisable(TGL_POLYGON_OFFSET_FILL);
 }
 
+void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours, int type) {
+	Math::Vector3d vertices[8] = {
+		origin,		origin,		origin,		origin,
+		origin,		origin,		origin,		origin,
+	};
+	PyramidType pyramidType = (PyramidType)type;
+	switch(pyramidType) {
+		default: break;
+		case EastPyramid:
+			vertices[0] += Math::Vector3d(0, 0, size.z());
+			vertices[1] += Math::Vector3d(0, size.y(), size.z());
+			vertices[2] += Math::Vector3d(0, size.y(), 0);
+
+			vertices[4] += Math::Vector3d(size.x(), (*ordinates)[0], (*ordinates)[3]);
+			vertices[5] += Math::Vector3d(size.x(), (*ordinates)[2], (*ordinates)[3]);
+			vertices[6] += Math::Vector3d(size.x(), (*ordinates)[2], (*ordinates)[1]);
+			vertices[7] += Math::Vector3d(size.x(), (*ordinates)[0], (*ordinates)[1]);
+			break;
+		case WestPyramid:
+
+			vertices[0] += Math::Vector3d(size.x(), 0, 0);
+			vertices[1] += Math::Vector3d(size.x(), size.y(), 0);
+			vertices[2] += Math::Vector3d(size.x(), size.y(), size.z());
+			vertices[3] += Math::Vector3d(size.x(), 0, size.z());
+
+			vertices[4] += Math::Vector3d(0, (*ordinates)[0], (*ordinates)[1]);
+			vertices[5] += Math::Vector3d(0, (*ordinates)[2], (*ordinates)[1]);
+			vertices[6] += Math::Vector3d(0, (*ordinates)[2], (*ordinates)[3]);
+			vertices[7] += Math::Vector3d(0, (*ordinates)[0], (*ordinates)[3]);
+			break;
+
+		case UpPyramid:
+			vertices[1] += Math::Vector3d(size.x(), 0, 0);
+			vertices[2] += Math::Vector3d(size.x(), 0, size.z());
+			vertices[3] += Math::Vector3d(0, 0, size.z());
+
+			vertices[4] += Math::Vector3d((*ordinates)[0], size.y(), (*ordinates)[1]);
+			vertices[5] += Math::Vector3d((*ordinates)[2], size.y(), (*ordinates)[1]);
+			vertices[6] += Math::Vector3d((*ordinates)[2], size.y(), (*ordinates)[3]);
+			vertices[7] += Math::Vector3d((*ordinates)[0], size.y(), (*ordinates)[3]);
+			break;
+
+		case DownPyramid:
+
+			vertices[0] += Math::Vector3d(size.x(), size.y(), 0);
+			vertices[1] += Math::Vector3d(0, size.y(), 0);
+			vertices[2] += Math::Vector3d(0, size.y(), size.z());
+			vertices[3] += Math::Vector3d(size.x(), size.y(), size.z());
+
+			vertices[4] += Math::Vector3d((*ordinates)[2], 0, (*ordinates)[1]);
+			vertices[5] += Math::Vector3d((*ordinates)[0], 0, (*ordinates)[1]);
+			vertices[6] += Math::Vector3d((*ordinates)[0], 0, (*ordinates)[3]);
+			vertices[7] += Math::Vector3d((*ordinates)[2], 0, (*ordinates)[3]);
+			break;
+
+		case NorthPyramid:
+			vertices[0] += Math::Vector3d(0, size.y(), 0);
+			vertices[1] += Math::Vector3d(size.x(), size.y(), 0);
+			vertices[2] += Math::Vector3d(size.x(), 0, 0);
+
+			vertices[4] += Math::Vector3d((*ordinates)[0], (*ordinates)[3], size.z());
+			vertices[5] += Math::Vector3d((*ordinates)[2], (*ordinates)[3], size.z());
+			vertices[6] += Math::Vector3d((*ordinates)[2], (*ordinates)[1], size.z());
+			vertices[7] += Math::Vector3d((*ordinates)[0], (*ordinates)[1], size.z());
+			break;
+		case SouthPyramid:
+			vertices[0] += Math::Vector3d(0, 0, size.z());
+			vertices[1] += Math::Vector3d(size.x(), 0, size.z());
+			vertices[2] += Math::Vector3d(size.x(), size.y(), size.z());
+
+			vertices[3] += Math::Vector3d(0, size.y(), size.z());
+			vertices[4] += Math::Vector3d((*ordinates)[0], (*ordinates)[1], 0);
+			vertices[5] += Math::Vector3d((*ordinates)[2], (*ordinates)[1], 0);
+			vertices[6] += Math::Vector3d((*ordinates)[2], (*ordinates)[3], 0);
+			vertices[7] += Math::Vector3d((*ordinates)[0], (*ordinates)[3], 0);
+			break;
+	}
+
+	Common::Array<Math::Vector3d> face;
+	face.push_back(vertices[5]);
+	face.push_back(vertices[6]);
+	face.push_back(vertices[2]);
+	face.push_back(vertices[1]);
+	renderFace(face);
+	face.clear();
+
+	face.push_back(vertices[7]);
+	face.push_back(vertices[4]);
+	face.push_back(vertices[0]);
+	face.push_back(vertices[3]);
+	renderFace(face);
+	face.clear();
+
+	face.push_back(vertices[4]);
+	face.push_back(vertices[5]);
+	face.push_back(vertices[1]);
+	face.push_back(vertices[0]);
+	renderFace(face);
+	face.clear();
+
+	face.push_back(vertices[6]);
+	face.push_back(vertices[7]);
+	face.push_back(vertices[3]);
+	face.push_back(vertices[2]);
+	renderFace(face);
+	face.clear();
+
+	face.push_back(vertices[0]);
+	face.push_back(vertices[1]);
+	face.push_back(vertices[2]);
+	face.push_back(vertices[3]);
+	renderFace(face);
+	face.clear();
+
+	face.push_back(vertices[7]);
+	face.push_back(vertices[6]);
+	face.push_back(vertices[5]);
+	face.push_back(vertices[4]);
+	renderFace(face);
+}
 
 void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector3d &size, Common::Array<uint8> *colours) {
 	assert(size.x() > 0);
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index 76eebbe758f..74ed9633e30 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -54,6 +54,8 @@ public:
 	virtual void renderCube(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) override;
 	virtual void renderRectangle(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) override;
 	virtual void renderPolygon(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours) override;
+	virtual void renderPyramid(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours, int type);
+
     virtual void renderFace(const Common::Array<Math::Vector3d> &vertices) override;
 
 	virtual void flipBuffer() override;
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index a80826afdba..8bae3431e7e 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -358,6 +358,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 		fileOffsetForArea[area] = file->readUint16LE();
 		debug("offset: %x", fileOffsetForArea[area]);
 	}
+	//fileOffsetForArea[0] = 0x89a6 - offset; // For testing
 
 	// grab the areas
 	AreaMap *areaMap = new AreaMap;
@@ -386,7 +387,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	if (!areaMap->contains(startArea))
 		_startArea = newArea->getAreaID();
 	else
-		_startArea = startArea;
+		_startArea = startArea + 1;
 	_startEntrance = startEntrance;
 	_colorNumber = ncolors;
 	_binaryBits = 8;
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index bbb66059b4d..27e8c9d1f66 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -1,5 +1,5 @@
 MODULE := engines/freescape
- 
+
 MODULE_OBJS := \
 	metaengine.o \
 	freescape.o \
@@ -15,17 +15,17 @@ MODULE_OBJS := \
 	loaders/16bitBinaryLoader.o \
 	language/16bitDetokeniser.o \
 	language/instruction.o
- 
+
 MODULE_DIRS += \
 	engines/freescape
 
- 
+
 # This module can be built as a plugin
 ifeq ($(ENABLE_FREESCAPE), DYNAMIC_PLUGIN)
 PLUGIN := 1
 endif
- 
-# Include common rules 
+
+# Include common rules
 include $(srcdir)/rules.mk
 
 # Detection objects
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index 3ce4fbe4202..71f452188b4 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -67,6 +67,21 @@ int GeometricObject::numberOfOrdinatesForType(Type type) {
 	}
 }
 
+bool GeometricObject::isPyramid(Type type) {
+	switch (type) {
+	default:
+		return false;
+
+	case EastPyramid:
+	case WestPyramid:
+	case UpPyramid:
+	case DownPyramid:
+	case NorthPyramid:
+	case SouthPyramid:
+		return true;
+	}
+}
+
 #pragma mark -
 #pragma mark Construction/Destruction
 
@@ -153,6 +168,8 @@ void GeometricObject::draw(Freescape::Renderer *gfx) {
 		gfx->renderCube(_origin, _size, colours);
 	} else if (this->getType() == Rectangle) {
 		gfx->renderRectangle(_origin, _size, colours);
+	} else if (isPyramid(this->getType())) {
+		gfx->renderPyramid(_origin, _size, ordinates, colours, this->getType());
 	} else if (this->isPlanar() && _type <= 14) {
 		//debug("Drawing %d of type %d", this->getObjectID(), this->getType());
 		gfx->renderPolygon(_origin, _size, ordinates, colours);
diff --git a/engines/freescape/objects/geometricobject.h b/engines/freescape/objects/geometricobject.h
index fcb56b3ee03..1beb8e69505 100644
--- a/engines/freescape/objects/geometricobject.h
+++ b/engines/freescape/objects/geometricobject.h
@@ -17,6 +17,7 @@ class GeometricObject : public Object {
 public:
 	static int numberOfColoursForObjectOfType(Type type);
 	static int numberOfOrdinatesForType(Type type);
+	static bool isPyramid(Type type);
 
 	GeometricObject(
 		Type type,


Commit: 213698c53d44bb4f845c24cc8f68f5a7fc654bfa
    https://github.com/scummvm/scummvm/commit/213698c53d44bb4f845c24cc8f68f5a7fc654bfa
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:45+01:00

Commit Message:
FREESCAPE: more code to help debuging and testing

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 73f2497ed81..c396b00d528 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -87,6 +87,9 @@ Area::~Area() {
 void Area::show() {
 	for (ObjectMap::iterator it = objectsByID->begin(); it != objectsByID->end(); it++)
 		debug("objID: %d, type: %d", (*it)._value->getObjectID(), (*it)._value->getType());
+
+	for (ObjectMap::iterator it = entrancesByID->begin(); it != entrancesByID->end(); it++)
+		debug("objID: %d, type: %d (entrance)", (*it)._value->getObjectID(), (*it)._value->getType());
 }
 
 void Area::draw(Freescape::Renderer *gfx) {
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 8bae3431e7e..455fe032344 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -234,18 +234,26 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	uint8 numberOfObjects = file->readByte();
 	uint8 areaNumber = file->readByte();
 
-	uint16 cPtr = 0;
-	if (_targetName != "castlemaster")
-		cPtr = file->readUint16LE();
+	uint16 cPtr = file->readUint16LE();
+	debug("Condition pointer: %x", cPtr);
 	uint8 scale = file->readByte();
 	debug("Scale: %d", scale);
 
-	uint8 ci1 = file->readByte(); //& 15;
-	uint8 ci2 = file->readByte(); //& 15;
-	uint8 ci3 = file->readByte(); //& 15;
-	uint8 ci4 = file->readByte(); //& 15;
-
-	debug("Colors: %d %d %d %d", ci1, ci2, ci3, ci4);
+	uint8 ci1 = 0;
+	uint8 ci2 = 0;
+	uint8 ci3 = 0;
+	uint8 ci4 = 0;
+	if (_targetName != "castlemaster") {
+		ci1 = file->readByte() & 15;
+		ci2 = file->readByte() & 15;
+		ci3 = file->readByte() & 15;
+		ci4 = file->readByte() & 15;
+		debug("Colors: %d %d %d %d", ci1, ci2, ci3, ci4);
+	} else {
+		ci3 = file->readByte();
+		ci4 = file->readByte();
+		debug("Colors: %d %d", ci3, ci4);
+	}
 	Graphics::PixelBuffer *palette = getPaletteGradient(1, 1, ncolors);
 
 	debug("Area %d", areaNumber);
@@ -268,12 +276,16 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 			if (newObject->getType() == Object::Entrance) {
 				(*entrancesByID)[newObject->getObjectID() & 0x7fff] = newObject;
 			} else {
-				assert(!(objectsByID->contains(newObject->getObjectID())));
+				if (objectsByID->contains(newObject->getObjectID()))
+					debug("WARNING: replacing object id %d", newObject->getObjectID());
 				(*objectsByID)[newObject->getObjectID()] = newObject;
 			}
 		}
 	}
-	/*file->seek(base + cPtr);
+	long int endLastObject = file->pos();
+	debug("Last position %lx", endLastObject);
+	assert(endLastObject <= base + cPtr);
+	file->seek(base + cPtr);
 	uint8 numConditions = file->readByte();
 	debug("%d area conditions", numConditions);
 	while (numConditions--) {
@@ -284,8 +296,8 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 		byte *conditionData = (byte*)malloc(lengthOfCondition);
 		file->read(conditionData, lengthOfCondition);
 		Common::Array<uint8> conditionArray(conditionData, lengthOfCondition);
-		//debug("%s", detokenise8bitCondition(conditionArray)->c_str());
-	}*/
+		debug("%s", detokenise8bitCondition(conditionArray)->c_str());
+	}
 
 	return (new Area(areaNumber, objectsByID, entrancesByID, scale, 255, 255, palette));
 }
@@ -313,8 +325,8 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 
 	file->seek(offset);
 	uint8 numberOfAreas = file->readByte();
-	//if (numberOfAreas < 10) // TODO: just for testing
-	//	numberOfAreas = 10;
+	if (numberOfAreas < 2) // TODO: just for testing
+		numberOfAreas = 20;
 	uint16 dbSize = file->readUint16LE();
 	debug("Database ends at %x", dbSize);
 
@@ -358,7 +370,13 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 		fileOffsetForArea[area] = file->readUint16LE();
 		debug("offset: %x", fileOffsetForArea[area]);
 	}
-	//fileOffsetForArea[0] = 0x89a6 - offset; // For testing
+	//fileOffsetForArea[0] = 0x9e75 - offset - 8 - 12; // Table?
+	//fileOffsetForArea[0] = 0x9571 - offset;
+	//fileOffsetForArea[0] = 0xaba5 - offset - 8 - 16; // ???
+
+	//fileOffsetForArea[0] = 0x959b - offset - 16; // Church? (22 elements)
+	//fileOffsetForArea[0] = 0x94b7 - offset; // For testing
+	//fileOffsetForArea[0] = 0x97cb - offset; // For testing
 
 	// grab the areas
 	AreaMap *areaMap = new AreaMap;
@@ -387,7 +405,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	if (!areaMap->contains(startArea))
 		_startArea = newArea->getAreaID();
 	else
-		_startArea = startArea + 1;
+		_startArea = startArea;
 	_startEntrance = startEntrance;
 	_colorNumber = ncolors;
 	_binaryBits = 8;


Commit: 6df44a7391c5945946f812e2fa9ece95ef6d4c58
    https://github.com/scummvm/scummvm/commit/6df44a7391c5945946f812e2fa9ece95ef6d4c58
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:45+01:00

Commit Message:
FREESCAPE: detection of total eclipse and more debugging code

Changed paths:
    engines/freescape/detection.cpp
    engines/freescape/freescape.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index 0f018dca4a4..a86a69f4d76 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -6,6 +6,7 @@ static const PlainGameDescriptor freescapeGames[] = {
 	{"3dkit", "The 3D Kit Game"},
 	{"driller", "Driller"},
 	{"spacestationoblivion", "Space Station Oblivion"},
+	{"totaleclipse", "Total Eclipse"},
 	{"castlemaster", "Castle Master"},
 	{"menace", "Menace of Dr. Spoil Sport"},
 	{0, 0}};
@@ -75,6 +76,20 @@ static const ADGameDescription gameDescriptions[] = {
 	 Common::kPlatformDOS,
 	 ADGF_NO_FLAGS,
 	 GUIO3(GUIO_NOMIDI, GUIO_RENDEREGA, GUIO_RENDERCGA)},
+	{"totaleclipse",
+	 "Total Eclipse",
+	 {
+		{"TOTAL.EXE", 0, "959703c1cd37b0d9744c492240a8178b", 13327},
+		{"TOTEH.EXE", 0, "c68d59874ab2a93cc9cc1b1d3aed8f17", 60628},
+		{"TOTEC.EXE", 0, "6c058c48255945a12479c8420321db75", 56900},
+		{"TOTET.EXE", 0, "2bc2b0892ca91a77c58e9bedabf45afe", 63732},
+		{"TOTEE.EXE", 0, "2ba865d2bdcda0c934baec7b31fb4ab2", 64196},
+		AD_LISTEND
+	 },
+	 Common::EN_ANY,
+	 Common::kPlatformDOS,
+	 ADGF_NO_FLAGS,
+	 GUIO3(GUIO_NOMIDI, GUIO_RENDEREGA, GUIO_RENDERCGA)},
 	{"spacestationoblivion",
 	 "Space Station Oblivion",
 	 {
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index f211d127532..2e84442a3d9 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -127,6 +127,30 @@ void FreescapeEngine::loadAssets() {
 		} else
 			error("Invalid render mode %s for Driller", renderMode.c_str());
 
+	} else if (_targetName == "totaleclipse") {
+		if (!ConfMan.hasKey("render_mode"))
+			renderMode = "ega";
+		else
+			renderMode = ConfMan.get("render_mode");
+
+		Common::File exe;
+		debug("renderMode: %s", renderMode.c_str());
+		bool success = false;
+		if (renderMode == "ega") {
+			file = gameDir.createReadStreamForMember("TOTEE.EXE");
+
+			if (file == nullptr)
+				error("Failed to open TOTEE.EXE");
+
+			load8bitBinary(file, 0xcdb7, 16);
+		} else if (renderMode == "cga") {
+			file = gameDir.createReadStreamForMember("TOTEC.EXE");
+
+			if (file == nullptr)
+				error("Failed to open TOTEC.EXE");
+			load8bitBinary(file, 0x7bb0, 4); // TODO
+		} else
+			error("Invalid render mode %s for Total Eclipse", renderMode.c_str());
 	   } else if (_targetName == "castlemaster") {
 			file = gameDir.createReadStreamForMember("castle.sna");
 
@@ -135,7 +159,7 @@ void FreescapeEngine::loadAssets() {
 			// Courtyard -> 0x93c1 -> 0x8cbc,3
 			// Beds -> 0x867d
 			// All? -> 0x845d or 0x80ed?
-			load8bitBinary(file, 0x8cbc, 16);
+			load8bitBinary(file, 0x1000, 16);
 	   } else
 		error("'%s' is an invalid game", _targetName.c_str());
 
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 455fe032344..b59bd6f5329 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -277,7 +277,7 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 				(*entrancesByID)[newObject->getObjectID() & 0x7fff] = newObject;
 			} else {
 				if (objectsByID->contains(newObject->getObjectID()))
-					debug("WARNING: replacing object id %d", newObject->getObjectID());
+					error("WARNING: replacing object id %d", newObject->getObjectID());
 				(*objectsByID)[newObject->getObjectID()] = newObject;
 			}
 		}
@@ -376,7 +376,9 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 
 	//fileOffsetForArea[0] = 0x959b - offset - 16; // Church? (22 elements)
 	//fileOffsetForArea[0] = 0x94b7 - offset; // For testing
-	//fileOffsetForArea[0] = 0x97cb - offset; // For testing
+	//fileOffsetForArea[0] = 0x97cb - offset; // Courtyard
+	//fileOffsetForArea[0] = 0x92cc - offset ; // Pool?
+	//fileOffsetForArea[0] = 0x866b - offset - 8; // Pool?
 
 	// grab the areas
 	AreaMap *areaMap = new AreaMap;


Commit: 8830dce83ae9536cb5d8cb111587ed5ed87f072c
    https://github.com/scummvm/scummvm/commit/8830dce83ae9536cb5d8cb111587ed5ed87f072c
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:46+01:00

Commit Message:
FREESCAPE: show code to execute when colliding

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/language/8bitDetokeniser.h
    engines/freescape/language/token.h
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/objects/geometricobject.cpp
    engines/freescape/objects/geometricobject.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 2e84442a3d9..f2d9928b53b 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -17,6 +17,7 @@
 
 #include "freescape/freescape.h"
 #include "freescape/gfx.h"
+#include "freescape/objects/geometricobject.h"
 
 #include "freescape/loaders/16bitBinaryLoader.h"
 #include "freescape/loaders/8bitBinaryLoader.h"
@@ -369,8 +370,12 @@ void FreescapeEngine::checkCollisions() {
 	const Math::AABB boundingBox(v1, v2);
 	Object *obj = _currentArea->checkCollisions(boundingBox);
 
-	if (obj != nullptr)
+	if (obj != nullptr) {
 		debug("Collided with object of size %f %f %f", obj->getSize().x(), obj->getSize().y(), obj->getSize().z());
+		GeometricObject *gobj = (GeometricObject*) obj;
+		if (gobj->conditionSource != nullptr)
+			debug("Must use collision = true when executing: %s", gobj->conditionSource->c_str());
+	}
 }
 
 bool FreescapeEngine::hasFeature(EngineFeature f) const {
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index fcb31452e5d..1382f7895a9 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -17,7 +17,7 @@ static const int k8bitVariableShield = 256;
 static const int k8bitVariableEnergy = 257;
 static const int k8bitVariableScore = 258;
 
-Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition) {
+Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition, FCLInstructionVector *instructions) {
 	Common::String detokenisedStream;
 	Common::Array<uint8>::size_type bytePointer = 0;
 	Common::Array<uint8>::size_type sizeOfTokenisedContent = tokenisedCondition.size();
@@ -68,6 +68,8 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			detokenisedStream += "<UNKNOWN 8 bit: ";
 			detokenisedStream += Common::String::format("%x", (int)opcode);
 			detokenisedStream += " > ";
+			if (opcode != 0x18)
+				error("Unknown FCL instruction: 0x%x", (int)opcode);
 			break;
 
 		case 0:
diff --git a/engines/freescape/language/8bitDetokeniser.h b/engines/freescape/language/8bitDetokeniser.h
index f7d2db24b6e..75b92112294 100644
--- a/engines/freescape/language/8bitDetokeniser.h
+++ b/engines/freescape/language/8bitDetokeniser.h
@@ -12,6 +12,8 @@
 #include "common/array.h"
 #include "common/str.h"
 
-Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition);
+#include "freescape/language/instruction.h"
+
+Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition, FCLInstructionVector *instructions);
 
 #endif /* defined(__Phantasma___8bitDetokeniser__) */
diff --git a/engines/freescape/language/token.h b/engines/freescape/language/token.h
index 0297d52c3b2..457cc11e4ae 100644
--- a/engines/freescape/language/token.h
+++ b/engines/freescape/language/token.h
@@ -88,17 +88,23 @@ public:
 	int32_t getValue(CGameState &, int32_t suggestedValue = 0);
 	Type getType();
 
-	Token();
-	Token(Type type);
-	Token(Common::String &string);
-	Token(Type type, int32_t value);
-	Token(const Token &other);
-	Token &operator=(const Token &rhs);
+	Token() {
+		type = UNKNOWN;
+		value = 0;
+	}
+	Token(Type _type) {
+		type = _type;
+		value = 0;
+	}
+	//Token(Common::String &string);
+	//Token(Type type, int32_t value);
+	//Token(const Token &other);
+	//Token &operator=(const Token &rhs);
 
 private:
 	Type type;
 
-	int32_t value;
+	int32 value;
 	Common::String string;
 };
 
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index b59bd6f5329..0ea642ff211 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -85,11 +85,12 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 
 		// grab the object condition, if there is one
 		FCLInstructionVector instructions;
+		Common::String *conditionSource = nullptr;
 		if (byteSizeOfObject) {
 			byte *conditionData = (byte*)malloc(byteSizeOfObject);
 			file->read(conditionData, byteSizeOfObject);
 			Common::Array<uint8> conditionArray(conditionData, byteSizeOfObject);
-			Common::String *conditionSource = detokenise8bitCondition(conditionArray);
+			conditionSource = detokenise8bitCondition(conditionArray, nullptr);
 			//instructions = getInstructions(conditionSource);
 			//debug("%s", conditionSource->c_str());
 		}
@@ -104,7 +105,8 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 			32 * v, // size
 			colours,
 			ordinates,
-			instructions);
+			instructions,
+			conditionSource);
 	} break;
 	case Object::Entrance: {
 		debug("rotation: %f %f %f", v.x(), v.y(), v.z());
@@ -296,7 +298,7 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 		byte *conditionData = (byte*)malloc(lengthOfCondition);
 		file->read(conditionData, lengthOfCondition);
 		Common::Array<uint8> conditionArray(conditionData, lengthOfCondition);
-		debug("%s", detokenise8bitCondition(conditionArray)->c_str());
+		debug("%s", detokenise8bitCondition(conditionArray, nullptr)->c_str(), nullptr);
 	}
 
 	return (new Area(areaNumber, objectsByID, entrancesByID, scale, 255, 255, palette));
@@ -359,8 +361,9 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 		byte *conditionData = (byte*)malloc(lengthOfCondition);
 		file->read(conditionData, lengthOfCondition);
 		Common::Array<uint8> conditionArray(conditionData, lengthOfCondition);
-		//debug("Global condition %d", numCondition + 1);
-		//debug("%s", detokenise8bitCondition(conditionArray)->c_str());
+		//debug("Global condition %d", numConditions + 1);
+		Common::String *conditions = detokenise8bitCondition(conditionArray, nullptr);
+		//debug("%s", conditions->c_str());
 	}
 
 	file->seek(offset + 200);
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index 71f452188b4..1ba20b12d94 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -93,7 +93,8 @@ GeometricObject::GeometricObject(
 	const Math::Vector3d &size,
 	Common::Array<uint8> *_colours,
 	Common::Array<uint16> *_ordinates,
-	FCLInstructionVector _condition) {
+	FCLInstructionVector _conditionInstructions,
+	Common::String *_conditionSource) {
 	_type = type;
 	_flags = flags;
 	_objectID = objectID;
@@ -104,7 +105,8 @@ GeometricObject::GeometricObject(
 		colours = new Common::Array<uint8>(*_colours);
 	if (_ordinates)
 		ordinates = new Common::Array<uint16>(*_ordinates);
-	condition = _condition;
+	condition = _conditionInstructions;
+	conditionSource = _conditionSource;
 	createBoundingBox();
 }
 
diff --git a/engines/freescape/objects/geometricobject.h b/engines/freescape/objects/geometricobject.h
index 1beb8e69505..4ad48349399 100644
--- a/engines/freescape/objects/geometricobject.h
+++ b/engines/freescape/objects/geometricobject.h
@@ -27,7 +27,8 @@ public:
 		const Math::Vector3d &size,
 		Common::Array<uint8> *colours,
 		Common::Array<uint16> *ordinates,
-		FCLInstructionVector condition);
+		FCLInstructionVector conditionInstructions,
+		Common::String *conditionSource = nullptr);
 	virtual ~GeometricObject();
 	void createBoundingBox();
 	bool collides(const Math::AABB &boundingBox);
@@ -35,6 +36,8 @@ public:
 	bool isDrawable();
 	bool isPlanar();
 
+	Common::String *conditionSource;
+
 private:
 
 	FCLInstructionVector condition;


Commit: 9fb29ea4ca0e7b7cbc0f8b5f014ba3c6e28fbe98
    https://github.com/scummvm/scummvm/commit/9fb29ea4ca0e7b7cbc0f8b5f014ba3c6e28fbe98
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:46+01:00

Commit Message:
FREESCAPE: proof of concept of fcl execution

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/language/8bitDetokeniser.h
    engines/freescape/language/instruction.cpp
    engines/freescape/language/instruction.h
    engines/freescape/language/token.h
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/objects/geometricobject.h


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index c396b00d528..ac28c906695 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -27,6 +27,10 @@ Object *Area::entranceWithID(uint16 objectID) {
 	return objectWithIDFromMap(entrancesByID, objectID);
 }
 
+Object *Area::firstEntrance() {
+	return entrancesByID->begin()->_value;
+}
+
 uint16 Area::getAreaID() {
 	return areaID;
 }
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index f8739af6ac4..f417bc2d3e9 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -20,7 +20,6 @@
 
 typedef Common::HashMap<uint16, Object *> ObjectMap;
 
-class BatchDrawer;
 class Area {
 public:
 	Area(
@@ -35,6 +34,7 @@ public:
 
 	Object *objectWithID(uint16 objectID);
 	Object *entranceWithID(uint16 objectID);
+	Object *firstEntrance();
 	uint16 getAreaID();
 	uint8 getScale();
 	void draw(Freescape::Renderer *gfx);
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index f2d9928b53b..c7bdb34c06a 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -18,6 +18,7 @@
 #include "freescape/freescape.h"
 #include "freescape/gfx.h"
 #include "freescape/objects/geometricobject.h"
+#include "freescape/language/token.h"
 
 #include "freescape/loaders/16bitBinaryLoader.h"
 #include "freescape/loaders/8bitBinaryLoader.h"
@@ -260,8 +261,8 @@ Common::Error FreescapeEngine::run() {
 	loadAssets();
 	Entrance *entrance = nullptr;
 	assert(_areasByAreaID);
-	if (_startArea == 14)
-		_startArea = 1;
+	//if (_startArea == 14)
+	//	_startArea = 1;
 	assert(_areasByAreaID->contains(_startArea));
 	_currentArea = (*_areasByAreaID)[_startArea];
 	assert(_currentArea);
@@ -371,13 +372,50 @@ void FreescapeEngine::checkCollisions() {
 	Object *obj = _currentArea->checkCollisions(boundingBox);
 
 	if (obj != nullptr) {
-		debug("Collided with object of size %f %f %f", obj->getSize().x(), obj->getSize().y(), obj->getSize().z());
+		debug("Collided with object id %d of size %f %f %f", obj->getObjectID(), obj->getSize().x(), obj->getSize().y(), obj->getSize().z());
 		GeometricObject *gobj = (GeometricObject*) obj;
-		if (gobj->conditionSource != nullptr)
+		if (gobj->conditionSource != nullptr) {
 			debug("Must use collision = true when executing: %s", gobj->conditionSource->c_str());
+			executeCode(gobj->condition);
+		}
 	}
 }
 
+void FreescapeEngine::executeCode(FCLInstructionVector &code) {
+	int ip = 0;
+	int codeSize = code.size();
+	while (ip <= codeSize - 1) {
+		FCLInstruction &instruction = code[ip];
+		debug("Executing ip: %d in code with size: %d", ip, codeSize);
+		switch (instruction.getType()) {
+			default:
+			break;
+			case Token::COLLIDEDQ:
+			executeCode(*instruction.thenInstructions);
+			break;
+			case Token::GOTO:
+			executeGoto(instruction);
+			break;
+		}
+		ip++;
+	}
+	return;
+}
+
+void FreescapeEngine::executeGoto(FCLInstruction &instruction) {
+	int areaID = instruction.source;
+	int entranceID = instruction.destination;
+	assert(_areasByAreaID->contains(areaID));
+	_currentArea = (*_areasByAreaID)[areaID];
+
+	Entrance *entrance = (Entrance*) _currentArea->entranceWithID(entranceID);
+	if (!entrance)
+		entrance = (Entrance*) _currentArea->firstEntrance();
+
+
+	_position = entrance->getOrigin();
+}
+
 bool FreescapeEngine::hasFeature(EngineFeature f) const {
 	return (f == kSupportsReturnToLauncher) ||
 		   (f == kSupportsLoadingDuringRuntime) ||
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 6954b2a1841..03c6d286e80 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -11,6 +11,7 @@
 
 #include "freescape/area.h"
 #include "freescape/objects/entrance.h"
+#include "freescape/language/instruction.h"
 #include "freescape/gfx.h"
 
 namespace Freescape {
@@ -114,6 +115,11 @@ public:
 
 	// Effects
 	void checkCollisions();
+	void executeCode(FCLInstructionVector &code);
+
+	// Instructions
+	void executeGoto(FCLInstruction &instruction);
+	void executeIfThenElse(FCLInstruction &instruction);
 
 	// Rendering
 	void drawFrame();
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index e982fb1d757..a8f26513e99 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -472,9 +472,9 @@ void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vec
 }
 
 void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector3d &size, Common::Array<uint8> *colours) {
-	assert(size.x() > 0);
+	/*assert(size.x() > 0);
 	assert(size.y() > 0);
-	assert(size.z() > 0);
+	assert(size.z() > 0);*/
 
 	//debug("Rendering cube at %f, %f, %f", origin.x(), origin.y(), origin.z());
 	//debug("with size %f, %f, %f", size.x(), size.y(), size.z());
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index 1382f7895a9..fa0214325f5 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -12,12 +12,13 @@
 */
 
 #include "8bitDetokeniser.h"
+#include "token.h"
 
 static const int k8bitVariableShield = 256;
 static const int k8bitVariableEnergy = 257;
 static const int k8bitVariableScore = 258;
 
-Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition, FCLInstructionVector *instructions) {
+Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition, FCLInstructionVector &instructions) {
 	Common::String detokenisedStream;
 	Common::Array<uint8>::size_type bytePointer = 0;
 	Common::Array<uint8>::size_type sizeOfTokenisedContent = tokenisedCondition.size();
@@ -26,6 +27,8 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 	// we'll want to convert them into runs of "if shot? then" and "if collided? then",
 	// and we'll want to start that from the top
 	uint8 conditionalIsShot = 0x1;
+	FCLInstructionVector *conditionalInstructions = new FCLInstructionVector();
+	FCLInstruction currentInstruction;
 
 	// this lookup table tells us how many argument bytes to read per opcode
 	uint8 argumentsRequiredByOpcode[32] =
@@ -42,6 +45,15 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 		// if the conditional type has changed then end the old conditional,
 		// if we were in one, and begin a new one
 		if (newConditionalIsShot != conditionalIsShot) {
+			FCLInstruction branch;
+			if (conditionalIsShot)
+				branch = FCLInstruction(Token::SHOTQ);
+			else
+				branch = FCLInstruction(Token::COLLIDEDQ);
+
+			branch.setBranches(conditionalInstructions, nullptr);
+			instructions.push_back(branch);
+
 			conditionalIsShot = newConditionalIsShot;
 			if (bytePointer)
 				detokenisedStream += "ENDIF\n";
@@ -50,6 +62,9 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 				detokenisedStream += "IF SHOT? THEN\n";
 			else
 				detokenisedStream += "IF COLLIDED? THEN\n";
+
+			// Allocate the next vector of instructions
+			conditionalInstructions = new FCLInstructionVector();
 		}
 
 		// get the actual operation
@@ -163,6 +178,7 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			break;
 		case 18:
 			detokenisedStream += "GOTO (";
+			currentInstruction = FCLInstruction(Token::GOTO);
 			break;
 
 		case 21:
@@ -198,6 +214,13 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 		// if there are any regular arguments to add, do so
 		if (numberOfArguments) {
 			for (uint8 argumentNumber = 0; argumentNumber < numberOfArguments; argumentNumber++) {
+				if (argumentNumber == 0)
+					currentInstruction.setSource(tokenisedCondition[bytePointer]);
+				else if (argumentNumber == 1)
+					currentInstruction.setDestination(tokenisedCondition[bytePointer]);
+				else
+					error("Unexpected number of arguments!");
+
 				detokenisedStream += Common::String::format("%d", (int)tokenisedCondition[bytePointer]);
 				bytePointer++;
 
@@ -206,11 +229,27 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			}
 
 			detokenisedStream += ")";
+			conditionalInstructions->push_back(currentInstruction);
+			currentInstruction = FCLInstruction(Token::UNKNOWN);
 		}
 
 		// throw in a newline
 		detokenisedStream += "\n";
 	}
 
+	//if (!conditionalInstructions)
+	//	conditionalInstructions = new FCLInstructionVector();
+
+	//conditionalInstructions->push_back(currentInstruction);
+
+	FCLInstruction branch;
+	if (conditionalIsShot)
+		branch = FCLInstruction(Token::SHOTQ);
+	else
+		branch = FCLInstruction(Token::COLLIDEDQ);
+
+	branch.setBranches(conditionalInstructions, nullptr);
+	instructions.push_back(branch);
+
 	return (new Common::String(detokenisedStream));
 }
diff --git a/engines/freescape/language/8bitDetokeniser.h b/engines/freescape/language/8bitDetokeniser.h
index 75b92112294..9162090710f 100644
--- a/engines/freescape/language/8bitDetokeniser.h
+++ b/engines/freescape/language/8bitDetokeniser.h
@@ -14,6 +14,6 @@
 
 #include "freescape/language/instruction.h"
 
-Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition, FCLInstructionVector *instructions);
+Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition, FCLInstructionVector &instructions);
 
 #endif /* defined(__Phantasma___8bitDetokeniser__) */
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index 7c77eed9c3a..a5fa1826358 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -11,46 +11,47 @@
 FCLInstruction::FCLInstruction(Token::Type _type) {
 	// TODO: learn modern constructor syntax
 	type = _type;
+	thenInstructions = nullptr;
+	elseInstructions = nullptr;
 }
 
-FCLInstruction::FCLInstruction(const FCLInstruction &source) {
+FCLInstruction::FCLInstruction() {
+	type = Token::UNKNOWN;
+	thenInstructions = nullptr;
+	elseInstructions = nullptr;
+}
+
+/*FCLInstruction::FCLInstruction(const FCLInstruction &source) {
 	type = source.type;
 	arguments.source = source.arguments.source;
 	arguments.destination = source.arguments.destination;
 	arguments.option = source.arguments.option;
 	conditional.thenInstructions = source.conditional.thenInstructions;
 	conditional.elseInstructions = source.conditional.elseInstructions;
-}
+}*/
 
 /*
 	Very routine setters for now; this code does not currently enforce good behaviour.
 	TODO: allow mutation only once; delete supplied objects and raise an error if a
 	second attempt at mutation is made
 */
-void FCLInstruction::setArguments(Token &source) {
-	arguments.source = source;
+void FCLInstruction::setSource(int32 _source) {
+	source = _source;
 }
 
-void FCLInstruction::setArguments(Token &source, Token &destination) {
-	arguments.source = source;
-	arguments.destination = destination;
+void FCLInstruction::setDestination(int32 _destination) {
+	destination = _destination;
 }
 
-void FCLInstruction::setArguments(Token &source, Token &destination, Token &option) {
-	arguments.source = source;
-	arguments.destination = destination;
-	arguments.option = option;
-}
-
-void FCLInstruction::setBranches(FCLInstructionVector thenBranch, FCLInstructionVector elseBranch) {
-	conditional.thenInstructions = thenBranch;
-	conditional.elseInstructions = elseBranch;
+void FCLInstruction::setBranches(FCLInstructionVector *thenBranch, FCLInstructionVector *elseBranch) {
+	thenInstructions = thenBranch;
+	elseInstructions = elseBranch;
 }
 
 /*
 	Similarly routine getters...
 */
-void FCLInstruction::getValue(CGameState &gameState, int32_t &source) {
+/*void FCLInstruction::getValue(CGameState &gameState, int32_t &source) {
 	source = arguments.source.getValue(gameState, source);
 }
 
@@ -63,7 +64,7 @@ void FCLInstruction::getValue(CGameState &gameState, int32_t &source, int32_t &d
 	source = arguments.source.getValue(gameState, source);
 	destination = arguments.destination.getValue(gameState, destination);
 	option = arguments.option.getValue(gameState, option);
-}
+}*/
 
 Token::Type FCLInstruction::getType() {
 	return type;
diff --git a/engines/freescape/language/instruction.h b/engines/freescape/language/instruction.h
index b5a2ee2fcd7..ffe7685e1b1 100644
--- a/engines/freescape/language/instruction.h
+++ b/engines/freescape/language/instruction.h
@@ -15,37 +15,25 @@
 class CGameState;
 
 class FCLInstruction;
-typedef Common::Array<FCLInstruction> *FCLInstructionVector;
+typedef Common::Array<FCLInstruction> FCLInstructionVector;
 
 class FCLInstruction {
 public:
+	FCLInstruction();
 	FCLInstruction(Token::Type type);
-	FCLInstruction(const FCLInstruction &source);
-
-	void setArguments(Token &);
-	void setArguments(Token &, Token &);
-	void setArguments(Token &, Token &, Token &);
+	void setSource(int32 _source);
+	void setDestination(int32 _destination);
 
 	Token::Type getType();
+	void setBranches(FCLInstructionVector *thenBranch, FCLInstructionVector *elseBranch);
 
-	void getValue(CGameState &, int32_t &);
-	void getValue(CGameState &, int32_t &, int32_t &);
-	void getValue(CGameState &, int32_t &, int32_t &, int32 &);
-
-	void setBranches(FCLInstructionVector thenBranch, FCLInstructionVector elseBranch);
+	int32 source;
+	int32 destination;
 
+	FCLInstructionVector *thenInstructions;
+	FCLInstructionVector *elseInstructions;
 private:
 	enum Token::Type type;
-
-	struct
-	{
-		Token source, destination, option;
-	} arguments;
-
-	struct
-	{
-		FCLInstructionVector thenInstructions, elseInstructions;
-	} conditional;
 };
 
 #endif /* defined(__Phantasma__Instruction__) */
diff --git a/engines/freescape/language/token.h b/engines/freescape/language/token.h
index 457cc11e4ae..0a9d34424c5 100644
--- a/engines/freescape/language/token.h
+++ b/engines/freescape/language/token.h
@@ -85,7 +85,7 @@ public:
 		VARNOTEQ
 	};
 
-	int32_t getValue(CGameState &, int32_t suggestedValue = 0);
+	int32_t getValue(CGameState &, int32 suggestedValue = 0);
 	Type getType();
 
 	Token() {
@@ -96,6 +96,7 @@ public:
 		type = _type;
 		value = 0;
 	}
+
 	//Token(Common::String &string);
 	//Token(Type type, int32_t value);
 	//Token(const Token &other);
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 0ea642ff211..a8a206471e0 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -90,7 +90,7 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 			byte *conditionData = (byte*)malloc(byteSizeOfObject);
 			file->read(conditionData, byteSizeOfObject);
 			Common::Array<uint8> conditionArray(conditionData, byteSizeOfObject);
-			conditionSource = detokenise8bitCondition(conditionArray, nullptr);
+			conditionSource = detokenise8bitCondition(conditionArray, instructions);
 			//instructions = getInstructions(conditionSource);
 			//debug("%s", conditionSource->c_str());
 		}
@@ -291,6 +291,7 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	uint8 numConditions = file->readByte();
 	debug("%d area conditions", numConditions);
 	while (numConditions--) {
+		FCLInstructionVector instructions;
 		// get the length
 		uint32 lengthOfCondition = file->readByte();
 		debug("length of condition: %d", lengthOfCondition);
@@ -298,7 +299,7 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 		byte *conditionData = (byte*)malloc(lengthOfCondition);
 		file->read(conditionData, lengthOfCondition);
 		Common::Array<uint8> conditionArray(conditionData, lengthOfCondition);
-		debug("%s", detokenise8bitCondition(conditionArray, nullptr)->c_str(), nullptr);
+		debug("%s", detokenise8bitCondition(conditionArray, instructions)->c_str(), nullptr);
 	}
 
 	return (new Area(areaNumber, objectsByID, entrancesByID, scale, 255, 255, palette));
@@ -354,6 +355,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	uint8 numConditions = file->readByte();
 	debug("%d global conditions", numConditions);
 	while (numConditions--) {
+		FCLInstructionVector instructions;
 		// get the length
 		uint32 lengthOfCondition = file->readByte();
 		debug("length of condition: %d", lengthOfCondition);
@@ -362,7 +364,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 		file->read(conditionData, lengthOfCondition);
 		Common::Array<uint8> conditionArray(conditionData, lengthOfCondition);
 		//debug("Global condition %d", numConditions + 1);
-		Common::String *conditions = detokenise8bitCondition(conditionArray, nullptr);
+		Common::String *conditions = detokenise8bitCondition(conditionArray, instructions);
 		//debug("%s", conditions->c_str());
 	}
 
diff --git a/engines/freescape/objects/geometricobject.h b/engines/freescape/objects/geometricobject.h
index 4ad48349399..eca6509c072 100644
--- a/engines/freescape/objects/geometricobject.h
+++ b/engines/freescape/objects/geometricobject.h
@@ -37,14 +37,11 @@ public:
 	bool isPlanar();
 
 	Common::String *conditionSource;
+	FCLInstructionVector condition;
 
 private:
-
-	FCLInstructionVector condition;
 	Common::Array<uint8> *colours;
 	Common::Array<uint16> *ordinates;
-
-	size_t drawElementsStartIndex;
 };
 
 #endif /* defined(__Phantasma__GeometricObject__) */


Commit: e65c905eff3a6f26652acea386fd669e5e15fd1b
    https://github.com/scummvm/scummvm/commit/e65c905eff3a6f26652acea386fd669e5e15fd1b
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:46+01:00

Commit Message:
FREESCAPE: refactor area changing code

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index c7bdb34c06a..bdaadc9fe7e 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -259,34 +259,7 @@ Common::Error FreescapeEngine::run() {
 	_gfx->init();
 	_gfx->clear();
 	loadAssets();
-	Entrance *entrance = nullptr;
-	assert(_areasByAreaID);
-	//if (_startArea == 14)
-	//	_startArea = 1;
-	assert(_areasByAreaID->contains(_startArea));
-	_currentArea = (*_areasByAreaID)[_startArea];
-	assert(_currentArea);
-	entrance = (Entrance*) _currentArea->entranceWithID(_startEntrance);
-	_currentArea->show();
-	Math::Vector3d rotation;
-
-	if (entrance) {
-		_position = entrance->getOrigin();
-		rotation = entrance->getRotation();
-	}
-	//assert(entrance);
-	if (_scale == Math::Vector3d(0, 0, 0)) {
-		uint8 scale = _currentArea->getScale();
-		_scaleVector = Math::Vector3d(scale, scale, scale);
-	} else
-		_scaleVector = _scale;
-	debug("entrace position: %f %f %f", _position.x(), _position.y(), _position.z());
-	debug("player height: %d", _playerHeight);
-	_position.setValue(1, _position.y() + _playerHeight);
-
-	_pitch = rotation.x() - 180.f;
-	_yaw = rotation.y() - 180.f;
-
+	gotoArea(_startArea, _startEntrance);
 	debug("FreescapeEngine::init");
 	// Simple main event loop
 	_lastMousePos = Common::Point(0, 0);
@@ -381,6 +354,29 @@ void FreescapeEngine::checkCollisions() {
 	}
 }
 
+void FreescapeEngine::gotoArea(uint16 areaID, uint16 entranceID) {
+	debug("go to area: %d, entrance: %d", areaID, entranceID);
+
+	assert(_areasByAreaID->contains(areaID));
+	_currentArea = (*_areasByAreaID)[areaID];
+
+	Entrance *entrance = (Entrance*) _currentArea->entranceWithID(entranceID);
+	if (!entrance)
+		entrance = (Entrance*) _currentArea->firstEntrance();
+
+	_position = entrance->getOrigin();
+	_rotation = entrance->getRotation();
+	int scale = _currentArea->getScale();
+	assert(scale > 0);
+
+	debug("entrace position: %f %f %f", _position.x(), _position.y(), _position.z());
+	debug("player height: %d", scale * _playerHeight);
+	_position.setValue(1, _position.y() + scale * _playerHeight);
+
+	_pitch = _rotation.x() - 180.f;
+	_yaw = _rotation.y() - 180.f;
+}
+
 void FreescapeEngine::executeCode(FCLInstructionVector &code) {
 	int ip = 0;
 	int codeSize = code.size();
@@ -403,17 +399,9 @@ void FreescapeEngine::executeCode(FCLInstructionVector &code) {
 }
 
 void FreescapeEngine::executeGoto(FCLInstruction &instruction) {
-	int areaID = instruction.source;
-	int entranceID = instruction.destination;
-	assert(_areasByAreaID->contains(areaID));
-	_currentArea = (*_areasByAreaID)[areaID];
-
-	Entrance *entrance = (Entrance*) _currentArea->entranceWithID(entranceID);
-	if (!entrance)
-		entrance = (Entrance*) _currentArea->firstEntrance();
-
-
-	_position = entrance->getOrigin();
+	uint16 areaID = instruction.source;
+	uint16 entranceID = instruction.destination;
+	gotoArea(areaID, entranceID);
 }
 
 bool FreescapeEngine::hasFeature(EngineFeature f) const {
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 03c6d286e80..2367e1f9462 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -84,6 +84,8 @@ public:
 	AreaMap *_areasByAreaID;
 	Area *_currentArea;
 	Math::Vector3d _scale;
+
+	void gotoArea(uint16 areaID, uint16 entranceID);
 	// Entrance
 	uint16 _startEntrance;
 


Commit: 263d710d6426d82e4274a981ae95c800a6bbbe47
    https://github.com/scummvm/scummvm/commit/263d710d6426d82e4274a981ae95c800a6bbbe47
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:46+01:00

Commit Message:
FREESCAPE: improved detection code to perform an inverse search on the drawable objects

Changed paths:
    engines/freescape/area.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index ac28c906695..5cd0b3fb109 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -126,14 +126,12 @@ Object *Area::shootRay(const Math::Ray &ray) {
 }
 
 Object *Area::checkCollisions(const Math::AABB &boundingBox) {
-	for (Common::Array<Object *>::iterator it = drawableObjects.begin(); it != drawableObjects.end(); it++) {
-		if ((*it)->isDrawable()) {
-			GeometricObject *obj = (GeometricObject*) (*it);
+	for (int i = drawableObjects.size() - 1; i >= 0; i--) {
+		if (drawableObjects[i]->isDrawable()) {
+			GeometricObject *obj = (GeometricObject*) drawableObjects[i];
 			if (obj->collides(boundingBox))
-				return (*it);
+				return drawableObjects[i];
 		}
 	}
 	return nullptr;
-
-
 }
\ No newline at end of file


Commit: ab4030ecb029b591dd545c8b4842527e17c31813
    https://github.com/scummvm/scummvm/commit/ab4030ecb029b591dd545c8b4842527e17c31813
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:46+01:00

Commit Message:
FREESCAPE: implemented invis opcode and improved collision detection when shooting

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/objects/object.h


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 5cd0b3fb109..a186383f230 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -118,9 +118,9 @@ void Area::draw(Freescape::Renderer *gfx) {
 }
 
 Object *Area::shootRay(const Math::Ray &ray) {
-	for (Common::Array<Object *>::iterator it = drawableObjects.begin(); it != drawableObjects.end(); it++) {
-		if (!(*it)->isInvisible() && (*it)->_boundingBox.isValid() && ray.intersectAABB((*it)->_boundingBox))
-			return (*it);
+	for (int i = drawableObjects.size() - 1; i >= 0; i--) {
+		if (!drawableObjects[i]->isInvisible() && drawableObjects[i]->_boundingBox.isValid() && ray.intersectAABB(drawableObjects[i]->_boundingBox))
+			return drawableObjects[i];
 	}
 	return nullptr;
 }
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index bdaadc9fe7e..91ce37bbe8e 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -245,10 +245,13 @@ void FreescapeEngine::processInput() {
 void FreescapeEngine::shoot() {
 	Math::Vector3d direction = directionToVector(_pitch, _yaw);
 	Math::Ray ray(_position, direction);
-	Object *shooted = _currentArea->shootRay(ray);
-	if (shooted) {
-		Math::Vector3d origin = shooted->getOrigin();
-		debug("shoot to %d at %f %f!", shooted->getObjectID(), origin.x(), origin.z());
+	Object *shot = _currentArea->shootRay(ray);
+	if (shot) {
+		GeometricObject *gobj = (GeometricObject*) shot;
+		if (gobj->conditionSource != nullptr) {
+			debug("Must use shot = true when executing: %s", gobj->conditionSource->c_str());
+			executeCode(gobj->condition, true, false);
+		}
 	}
 	//debug("camera front: %f %f %f", _cameraFront.x(), _rotation.y(), _rotation.z());
 }
@@ -349,7 +352,7 @@ void FreescapeEngine::checkCollisions() {
 		GeometricObject *gobj = (GeometricObject*) obj;
 		if (gobj->conditionSource != nullptr) {
 			debug("Must use collision = true when executing: %s", gobj->conditionSource->c_str());
-			executeCode(gobj->condition);
+			executeCode(gobj->condition, false, true);
 		}
 	}
 }
@@ -377,7 +380,8 @@ void FreescapeEngine::gotoArea(uint16 areaID, uint16 entranceID) {
 	_yaw = _rotation.y() - 180.f;
 }
 
-void FreescapeEngine::executeCode(FCLInstructionVector &code) {
+void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool collided) {
+	assert(!(shot && collided));
 	int ip = 0;
 	int codeSize = code.size();
 	while (ip <= codeSize - 1) {
@@ -387,17 +391,37 @@ void FreescapeEngine::executeCode(FCLInstructionVector &code) {
 			default:
 			break;
 			case Token::COLLIDEDQ:
-			executeCode(*instruction.thenInstructions);
+			if (collided)
+				executeCode(*instruction.thenInstructions, shot, collided);
+			// else branch is always empty
+			assert(instruction.elseInstructions == nullptr);
+			break;
+			case Token::SHOTQ:
+			if (shot)
+				executeCode(*instruction.thenInstructions, shot, collided);
+			// else branch is always empty
+			assert(instruction.elseInstructions == nullptr);
 			break;
 			case Token::GOTO:
 			executeGoto(instruction);
 			break;
+			case Token::INVIS:
+			executeMakeInvisible(instruction);
+			break;
+
 		}
 		ip++;
 	}
 	return;
 }
 
+void FreescapeEngine::executeMakeInvisible(FCLInstruction &instruction) {
+	uint16 objectID = instruction.source;
+	debug("Making obj %d invisible!", objectID);
+	Object *obj = _currentArea->objectWithID(objectID);
+	obj->makeInvisible();
+}
+
 void FreescapeEngine::executeGoto(FCLInstruction &instruction) {
 	uint16 areaID = instruction.source;
 	uint16 entranceID = instruction.destination;
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 2367e1f9462..489810749ee 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -117,11 +117,13 @@ public:
 
 	// Effects
 	void checkCollisions();
-	void executeCode(FCLInstructionVector &code);
+	void executeCode(FCLInstructionVector &code, bool shot, bool collided);
 
 	// Instructions
 	void executeGoto(FCLInstruction &instruction);
 	void executeIfThenElse(FCLInstruction &instruction);
+	void executeMakeInvisible(FCLInstruction &instruction);
+
 
 	// Rendering
 	void drawFrame();
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index fa0214325f5..7c0a016aba7 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -124,6 +124,7 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 		case 8:
 		case 5:
 			detokenisedStream += "INVIS (";
+			currentInstruction = FCLInstruction(Token::INVIS);
 			break;
 
 		case 9:
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index a8a206471e0..793d3016526 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -15,9 +15,9 @@ namespace Freescape {
 
 Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 
-	byte rawType = file->readByte();
-	debug("Raw object type: %d", rawType);
-	Object::Type objectType = (Object::Type)(rawType & 0x1F);
+	byte rawFlagsAndType = file->readByte();
+	debug("Raw object data flags and type: %d", rawFlagsAndType);
+	Object::Type objectType = (Object::Type)(rawFlagsAndType & 0x1F);
 
 	Math::Vector3d position, v;
 
@@ -100,7 +100,7 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 		return new GeometricObject(
 			objectType,
 			objectID,
-			0, // flags
+			rawFlagsAndType, // flags
 			32 * position,
 			32 * v, // size
 			colours,
diff --git a/engines/freescape/objects/object.h b/engines/freescape/objects/object.h
index c507ec001c9..9123ee00076 100644
--- a/engines/freescape/objects/object.h
+++ b/engines/freescape/objects/object.h
@@ -49,7 +49,8 @@ public:
 
 	virtual bool isDrawable();
 	virtual bool isPlanar();
-	bool isInvisible() { return _flags & 0x4; }
+	bool isInvisible() { return _flags & 0x80; }
+	void makeInvisible() { _flags = _flags | 0x80; }
 
 	virtual ~Object();
 


Commit: 5a1026d54a3bfdd4ebd101a89749eac98a57b7f0
    https://github.com/scummvm/scummvm/commit/5a1026d54a3bfdd4ebd101a89749eac98a57b7f0
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:46+01:00

Commit Message:
FREESCAPE: fixed ordinate scales for 8-bit binaries

Changed paths:
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 793d3016526..d0f5ae5771f 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -78,7 +78,7 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 			for (int ordinate = 0; ordinate < numberOfOrdinates; ordinate++) {
 				ord = file->readByte();
 				debug("ord: %x", ord);
-				ordinates->push_back(ord);
+				ordinates->push_back(32 * ord);
 				byteSizeOfObject--;
 			}
 		}


Commit: 3d63dc44b718f8ad9dfb785d0d72872074e9921a
    https://github.com/scummvm/scummvm/commit/3d63dc44b718f8ad9dfb785d0d72872074e9921a
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:47+01:00

Commit Message:
FREESCAPE: improved detection collision considering distance to object

Changed paths:
    engines/freescape/area.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index a186383f230..2314333dab3 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -118,11 +118,17 @@ void Area::draw(Freescape::Renderer *gfx) {
 }
 
 Object *Area::shootRay(const Math::Ray &ray) {
+	float distance = 16 * 8192; // TODO: check if this is max distance
+	Object *collided = nullptr;
 	for (int i = drawableObjects.size() - 1; i >= 0; i--) {
-		if (!drawableObjects[i]->isInvisible() && drawableObjects[i]->_boundingBox.isValid() && ray.intersectAABB(drawableObjects[i]->_boundingBox))
-			return drawableObjects[i];
+		if (!drawableObjects[i]->isInvisible() && drawableObjects[i]->_boundingBox.isValid() && ray.intersectAABB(drawableObjects[i]->_boundingBox)) {
+			if (ray.getOrigin().getDistanceTo(drawableObjects[i]->getOrigin()) < distance ) {
+				collided = drawableObjects[i];
+				distance = ray.getOrigin().getDistanceTo(collided->getOrigin());
+			}
+		}
 	}
-	return nullptr;
+	return collided;
 }
 
 Object *Area::checkCollisions(const Math::AABB &boundingBox) {


Commit: 93de5a6d60655753e5d481c43c17da283d3b05a9
    https://github.com/scummvm/scummvm/commit/93de5a6d60655753e5d481c43c17da283d3b05a9
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:47+01:00

Commit Message:
FREESCAPE: avoid collisions with invisible objects

Changed paths:
    engines/freescape/objects/geometricobject.cpp


diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index 1ba20b12d94..a7abc4b0243 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -153,7 +153,7 @@ bool GeometricObject::isPlanar() {
 }
 
 bool GeometricObject::collides(const Math::AABB &boundingBox) {
-	if (!_boundingBox.isValid() || !boundingBox.isValid())
+	if (isInvisible() || !_boundingBox.isValid() || !boundingBox.isValid())
 		return false;
 
 	return(	_boundingBox.getMax().x() > boundingBox.getMin().x() &&


Commit: a684bc9506b6bb3e65a79a604460b69401d15376
    https://github.com/scummvm/scummvm/commit/a684bc9506b6bb3e65a79a604460b69401d15376
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:47+01:00

Commit Message:
FREESCAPE: added basic VIS implementation

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/objects/object.cpp
    engines/freescape/objects/object.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 91ce37bbe8e..3960c1c43fc 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -408,6 +408,9 @@ void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool co
 			case Token::INVIS:
 			executeMakeInvisible(instruction);
 			break;
+			case Token::VIS:
+			executeMakeVisible(instruction);
+			break;
 
 		}
 		ip++;
@@ -422,6 +425,13 @@ void FreescapeEngine::executeMakeInvisible(FCLInstruction &instruction) {
 	obj->makeInvisible();
 }
 
+void FreescapeEngine::executeMakeVisible(FCLInstruction &instruction) {
+	uint16 objectID = instruction.source;
+	debug("Making obj %d visible!", objectID);
+	Object *obj = _currentArea->objectWithID(objectID);
+	obj->makeVisible();
+}
+
 void FreescapeEngine::executeGoto(FCLInstruction &instruction) {
 	uint16 areaID = instruction.source;
 	uint16 entranceID = instruction.destination;
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 489810749ee..2dd17276c35 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -123,7 +123,7 @@ public:
 	void executeGoto(FCLInstruction &instruction);
 	void executeIfThenElse(FCLInstruction &instruction);
 	void executeMakeInvisible(FCLInstruction &instruction);
-
+	void executeMakeVisible(FCLInstruction &instruction);
 
 	// Rendering
 	void drawFrame();
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index 7c0a016aba7..20781f82cc0 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -120,6 +120,7 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 		case 7:
 		case 4:
 			detokenisedStream += "VIS (";
+			currentInstruction = FCLInstruction(Token::VIS);
 			break; // hence each getting two case statement entries
 		case 8:
 		case 5:
diff --git a/engines/freescape/objects/object.cpp b/engines/freescape/objects/object.cpp
index fb6921f86f6..3c9ecac1d0e 100644
--- a/engines/freescape/objects/object.cpp
+++ b/engines/freescape/objects/object.cpp
@@ -16,10 +16,11 @@ uint16 Object::getObjectFlags() { return _flags; }
 Math::Vector3d Object::getOrigin() { return _origin; }
 Math::Vector3d Object::getSize() { return _size; }
 
-//void Object::draw(Freescape::Renderer *gfx) {
-//	gfx;
-//}
 bool Object::isDrawable() { return false; }
 bool Object::isPlanar() { return false; }
 
+bool Object::isInvisible() { return _flags & 0x80; }
+void Object::makeInvisible() { _flags = _flags | 0x80; }
+void Object::makeVisible() { _flags = _flags & ~0x80; }
+
 Object::~Object() {}
diff --git a/engines/freescape/objects/object.h b/engines/freescape/objects/object.h
index 9123ee00076..032b715f573 100644
--- a/engines/freescape/objects/object.h
+++ b/engines/freescape/objects/object.h
@@ -49,8 +49,9 @@ public:
 
 	virtual bool isDrawable();
 	virtual bool isPlanar();
-	bool isInvisible() { return _flags & 0x80; }
-	void makeInvisible() { _flags = _flags | 0x80; }
+	bool isInvisible();
+	void makeInvisible();
+	void makeVisible();
 
 	virtual ~Object();
 


Commit: 8442d007e79cd5ed7006abd044cf740ff8a9dea5
    https://github.com/scummvm/scummvm/commit/8442d007e79cd5ed7006abd044cf740ff8a9dea5
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:47+01:00

Commit Message:
FREESCAPE: added basic TOGVIS implementation

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/objects/object.cpp
    engines/freescape/objects/object.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 3960c1c43fc..b241d02faa0 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -405,6 +405,9 @@ void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool co
 			case Token::GOTO:
 			executeGoto(instruction);
 			break;
+			case Token::TOGVIS:
+			executeToggleVisibility(instruction);
+			break;
 			case Token::INVIS:
 			executeMakeInvisible(instruction);
 			break;
@@ -432,6 +435,13 @@ void FreescapeEngine::executeMakeVisible(FCLInstruction &instruction) {
 	obj->makeVisible();
 }
 
+void FreescapeEngine::executeToggleVisibility(FCLInstruction &instruction) {
+	uint16 objectID = instruction.source;
+	debug("Toggling obj %d visibility!", objectID);
+	Object *obj = _currentArea->objectWithID(objectID);
+	obj->toggleVisibility();
+}
+
 void FreescapeEngine::executeGoto(FCLInstruction &instruction) {
 	uint16 areaID = instruction.source;
 	uint16 entranceID = instruction.destination;
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 2dd17276c35..18bb84a8474 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -124,6 +124,7 @@ public:
 	void executeIfThenElse(FCLInstruction &instruction);
 	void executeMakeInvisible(FCLInstruction &instruction);
 	void executeMakeVisible(FCLInstruction &instruction);
+	void executeToggleVisibility(FCLInstruction &instruction);
 
 	// Rendering
 	void drawFrame();
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index 20781f82cc0..f612dec169e 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -116,6 +116,7 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 		case 6:
 		case 3:
 			detokenisedStream += "TOGVIS (";
+			currentInstruction = FCLInstruction(Token::TOGVIS);
 			break; // these all come in unary and binary versions,
 		case 7:
 		case 4:
diff --git a/engines/freescape/objects/object.cpp b/engines/freescape/objects/object.cpp
index 3c9ecac1d0e..db6d90ce4e8 100644
--- a/engines/freescape/objects/object.cpp
+++ b/engines/freescape/objects/object.cpp
@@ -22,5 +22,6 @@ bool Object::isPlanar() { return false; }
 bool Object::isInvisible() { return _flags & 0x80; }
 void Object::makeInvisible() { _flags = _flags | 0x80; }
 void Object::makeVisible() { _flags = _flags & ~0x80; }
+void Object::toggleVisibility() { _flags = _flags ^ 0x80; }
 
 Object::~Object() {}
diff --git a/engines/freescape/objects/object.h b/engines/freescape/objects/object.h
index 032b715f573..6391b53cd28 100644
--- a/engines/freescape/objects/object.h
+++ b/engines/freescape/objects/object.h
@@ -52,6 +52,7 @@ public:
 	bool isInvisible();
 	void makeInvisible();
 	void makeVisible();
+	void toggleVisibility();
 
 	virtual ~Object();
 


Commit: 773fffc048869d39c98bf4f522ec41303023ec52
    https://github.com/scummvm/scummvm/commit/773fffc048869d39c98bf4f522ec41303023ec52
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:47+01:00

Commit Message:
FREESCAPE: added basic crossair implementation

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/gfx_tinygl.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index b241d02faa0..138e32bf7c0 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -186,6 +186,7 @@ void FreescapeEngine::drawFrame() {
 	_gfx->positionCamera(_position, _position + _cameraFront);
 	_gfx->scale(_scaleVector);
 	_currentArea->draw(_gfx);
+	_gfx->renderCrossair(0);
 	//drawBorder();
 	_gfx->flipBuffer();
 }
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index d6d11d9664c..44511419602 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -94,6 +94,8 @@ public:
 
 	virtual void draw2DText(const Common::String &text, const Common::Point &position) = 0;
 	virtual void scale(const Math::Vector3d &scale) = 0;
+
+	virtual void renderCrossair(byte color) = 0;
 	virtual void renderCube(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) = 0;
 	virtual void renderRectangle(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) = 0;
 	virtual void renderPolygon(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours) = 0;
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index a8f26513e99..db975683398 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -201,6 +201,31 @@ void TinyGLRenderer::positionCamera(const Math::Vector3d &pos, const Math::Vecto
 	tglTranslatef(-pos.x(), -pos.y(), -pos.z());
 }
 
+void TinyGLRenderer::renderCrossair(byte color) {
+	uint8 r, g, b;
+	_palette->getRGBAt(color, r, g, b);
+
+	tglMatrixMode(TGL_PROJECTION);
+	tglLoadIdentity();
+	tglOrtho(0, kOriginalWidth, kOriginalHeight, 0, 0, 1);
+	tglMatrixMode(TGL_MODELVIEW);
+	tglLoadIdentity();
+
+	tglDisable(TGL_DEPTH_TEST);
+	tglDepthMask(TGL_FALSE);
+
+	tglColor3ub(r, g, b);
+
+	tglBegin(TGL_LINES);
+	tglVertex2f(kOriginalWidth / 2 - 2, kOriginalHeight / 2);
+	tglVertex2f(kOriginalWidth / 2 + 3, kOriginalHeight / 2);
+
+	tglVertex2f(kOriginalWidth / 2, kOriginalHeight / 2 - 2);
+	tglVertex2f(kOriginalWidth / 2, kOriginalHeight / 2 + 3);
+	tglEnd();
+
+	tglDepthMask(TGL_TRUE);
+	tglEnable(TGL_DEPTH_TEST);}
 
 void TinyGLRenderer::renderFace(const Common::Array<Math::Vector3d> &vertices) {
 	assert(vertices.size() >= 2);
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index 74ed9633e30..436e9448ce1 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -51,6 +51,7 @@ public:
 	                                float transparency = -1.0, bool additiveBlending = false) override;
 	virtual void draw2DText(const Common::String &text, const Common::Point &position) override;
 
+	virtual void renderCrossair(byte color) override;
 	virtual void renderCube(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) override;
 	virtual void renderRectangle(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) override;
 	virtual void renderPolygon(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours) override;


Commit: f3779e290135573dfa71e2145d2a6018a9209111
    https://github.com/scummvm/scummvm/commit/f3779e290135573dfa71e2145d2a6018a9209111
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:47+01:00

Commit Message:
FREESCAPE: avoid collisions with invisible objects

Changed paths:
    engines/freescape/area.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 2314333dab3..724e004bddd 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -133,7 +133,7 @@ Object *Area::shootRay(const Math::Ray &ray) {
 
 Object *Area::checkCollisions(const Math::AABB &boundingBox) {
 	for (int i = drawableObjects.size() - 1; i >= 0; i--) {
-		if (drawableObjects[i]->isDrawable()) {
+		if (drawableObjects[i]->isDrawable() && !drawableObjects[i]->isInvisible()) {
 			GeometricObject *obj = (GeometricObject*) drawableObjects[i];
 			if (obj->collides(boundingBox))
 				return drawableObjects[i];


Commit: 7d8c52d02e3a9c32f07afc35037c00d08ea1505c
    https://github.com/scummvm/scummvm/commit/7d8c52d02e3a9c32f07afc35037c00d08ea1505c
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:48+01:00

Commit Message:
FREESCAPE: render basic shoot line

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/gfx_tinygl.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 138e32bf7c0..1e7b20c228d 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -188,7 +188,6 @@ void FreescapeEngine::drawFrame() {
 	_currentArea->draw(_gfx);
 	_gfx->renderCrossair(0);
 	//drawBorder();
-	_gfx->flipBuffer();
 }
 
 void FreescapeEngine::processInput() {
@@ -244,6 +243,7 @@ void FreescapeEngine::processInput() {
 }
 
 void FreescapeEngine::shoot() {
+	_gfx->renderShoot(0);
 	Math::Vector3d direction = directionToVector(_pitch, _yaw);
 	Math::Ray ray(_position, direction);
 	Object *shot = _currentArea->shootRay(ray);
@@ -281,8 +281,9 @@ Common::Error FreescapeEngine::run() {
 	}
 	debug("Starting area %d", _currentArea->getAreaID());
 	while (!shouldQuit()) {
-		processInput();
 		drawFrame();
+		processInput();
+		_gfx->flipBuffer();
 		g_system->updateScreen();
 		g_system->delayMillis(10);
 	}
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 44511419602..f779f14485f 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -96,6 +96,7 @@ public:
 	virtual void scale(const Math::Vector3d &scale) = 0;
 
 	virtual void renderCrossair(byte color) = 0;
+	virtual void renderShoot(byte color) = 0;
 	virtual void renderCube(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) = 0;
 	virtual void renderRectangle(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) = 0;
 	virtual void renderPolygon(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours) = 0;
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index db975683398..b26ca2d99d5 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -225,7 +225,42 @@ void TinyGLRenderer::renderCrossair(byte color) {
 	tglEnd();
 
 	tglDepthMask(TGL_TRUE);
-	tglEnable(TGL_DEPTH_TEST);}
+	tglEnable(TGL_DEPTH_TEST);
+}
+
+void TinyGLRenderer::renderShoot(byte color) {
+	uint8 r, g, b;
+	_palette->getRGBAt(color, r, g, b);
+
+	tglMatrixMode(TGL_PROJECTION);
+	tglLoadIdentity();
+	tglOrtho(0, kOriginalWidth, kOriginalHeight, 0, 0, 1);
+	tglMatrixMode(TGL_MODELVIEW);
+	tglLoadIdentity();
+
+	tglDisable(TGL_DEPTH_TEST);
+	tglDepthMask(TGL_FALSE);
+
+	tglColor3ub(r, g, b);
+
+	tglBegin(TGL_LINES);
+	tglVertex2f(0, kOriginalHeight - 2);
+	tglVertex2f(kOriginalWidth / 2, kOriginalHeight / 2);
+
+	tglVertex2f(0, kOriginalHeight);
+	tglVertex2f(kOriginalWidth / 2, kOriginalHeight / 2);
+
+	tglVertex2f(kOriginalWidth, kOriginalHeight - 2);
+	tglVertex2f(kOriginalWidth / 2, kOriginalHeight / 2);
+
+	tglVertex2f(kOriginalWidth, kOriginalHeight);
+	tglVertex2f(kOriginalWidth / 2, kOriginalHeight / 2);
+
+	tglEnd();
+
+	tglEnable(TGL_DEPTH_TEST);
+	tglDepthMask(TGL_TRUE);
+}
 
 void TinyGLRenderer::renderFace(const Common::Array<Math::Vector3d> &vertices) {
 	assert(vertices.size() >= 2);
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index 436e9448ce1..7bc02bace23 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -52,6 +52,7 @@ public:
 	virtual void draw2DText(const Common::String &text, const Common::Point &position) override;
 
 	virtual void renderCrossair(byte color) override;
+	virtual void renderShoot(byte color) override;
 	virtual void renderCube(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) override;
 	virtual void renderRectangle(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) override;
 	virtual void renderPolygon(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours) override;


Commit: e9dffc6ef9815b95d0e595a31b94b99f87f2fdd4
    https://github.com/scummvm/scummvm/commit/e9dffc6ef9815b95d0e595a31b94b99f87f2fdd4
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:48+01:00

Commit Message:
FREESCAPE: improved header, namespaces and removed useless files

Changed paths:
  R engines/freescape/language/parser.h
  R engines/freescape/loaders/16bitBinaryLoader.h
  R engines/freescape/loaders/8bitBinaryLoader.h
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/freescape.cpp
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/gfx_tinygl.h
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/language/8bitDetokeniser.h
    engines/freescape/language/instruction.cpp
    engines/freescape/language/instruction.h
    engines/freescape/language/token.h
    engines/freescape/loaders/16bitBinaryLoader.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/objects/entrance.cpp
    engines/freescape/objects/entrance.h
    engines/freescape/objects/geometricobject.cpp
    engines/freescape/objects/geometricobject.h
    engines/freescape/objects/object.cpp
    engines/freescape/objects/object.h


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 724e004bddd..b087e2b0109 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -11,6 +11,8 @@
 #include "common/algorithm.h"
 #include "freescape/objects/object.h"
 
+namespace Freescape {
+
 Object *Area::objectWithIDFromMap(ObjectMap *map, uint16 objectID) {
 	if (!map)
 		return nullptr;
@@ -140,4 +142,6 @@ Object *Area::checkCollisions(const Math::AABB &boundingBox) {
 		}
 	}
 	return nullptr;
-}
\ No newline at end of file
+}
+
+} // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index f417bc2d3e9..0674c079b5e 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -6,8 +6,8 @@
 //  Copyright (c) 2013 Thomas Harte. All rights reserved.
 //
 
-#ifndef __Phantasma__Area__
-#define __Phantasma__Area__
+#ifndef FREESCAPE_AREA_H
+#define FREESCAPE_AREA_H
 
 #include "common/hashmap.h"
 #include "common/array.h"
@@ -18,6 +18,8 @@
 #include "freescape/gfx.h"
 #include "freescape/objects/object.h"
 
+namespace Freescape {
+
 typedef Common::HashMap<uint16, Object *> ObjectMap;
 
 class Area {
@@ -37,7 +39,7 @@ public:
 	Object *firstEntrance();
 	uint16 getAreaID();
 	uint8 getScale();
-	void draw(Freescape::Renderer *gfx);
+	void draw(Renderer *gfx);
 	void show();
 
 	Object *shootRay(const Math::Ray &ray);
@@ -56,4 +58,6 @@ private:
 	Object *objectWithIDFromMap(ObjectMap *map, uint16 objectID);
 };
 
-#endif /* defined(__Phantasma__Area__) */
+} // End of namespace Freescape
+
+#endif
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 1e7b20c228d..d14f78e48ba 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -20,9 +20,6 @@
 #include "freescape/objects/geometricobject.h"
 #include "freescape/language/token.h"
 
-#include "freescape/loaders/16bitBinaryLoader.h"
-#include "freescape/loaders/8bitBinaryLoader.h"
-
 
 namespace Freescape {
 
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index f779f14485f..af8ccca5232 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -20,8 +20,8 @@
  *
  */
 
-#ifndef GFX_H_
-#define GFX_H_
+#ifndef FREESCAPE_GFX_H
+#define FREESCAPE_GFX_H
 
 #include "common/rect.h"
 #include "common/system.h"
@@ -172,6 +172,6 @@ Renderer *CreateGfxOpenGLShader(OSystem *system);
 Renderer *CreateGfxTinyGL(OSystem *system);
 Renderer *createRenderer(OSystem *system);
 
-} // End of namespace Myst3
+} // End of namespace Freescape
 
 #endif // GFX_H_
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index b26ca2d99d5..18477b7f436 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -665,4 +665,4 @@ void TinyGLRenderer::flipBuffer() {
 	}
 }
 
-} // End of namespace Myst3
+} // End of namespace Freescape
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index 7bc02bace23..f3d6c81396e 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -20,8 +20,8 @@
  *
  */
 
-#ifndef GFX_TINYGL_H_
-#define GFX_TINYGL_H_
+#ifndef FREESCAPE_GFX_TINYGL_H_
+#define FREESCAPE_GFX_TINYGL_H_
 
 #include "common/rect.h"
 #include "common/system.h"
@@ -65,6 +65,6 @@ public:
 	virtual void drawFloor(uint8 color) override;
 };
 
-} // End of namespace Myst3
+} // End of namespace Freescape
 
 #endif // GFX_H_
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index f612dec169e..c2f9fc1b1c3 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -14,6 +14,8 @@
 #include "8bitDetokeniser.h"
 #include "token.h"
 
+namespace Freescape {
+
 static const int k8bitVariableShield = 256;
 static const int k8bitVariableEnergy = 257;
 static const int k8bitVariableScore = 258;
@@ -256,3 +258,5 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 
 	return (new Common::String(detokenisedStream));
 }
+
+} // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/language/8bitDetokeniser.h b/engines/freescape/language/8bitDetokeniser.h
index 9162090710f..08b058594f2 100644
--- a/engines/freescape/language/8bitDetokeniser.h
+++ b/engines/freescape/language/8bitDetokeniser.h
@@ -6,14 +6,18 @@
 //  Copyright (c) 2013 Thomas Harte. All rights reserved.
 //
 
-#ifndef __Phantasma___8bitDetokeniser__
-#define __Phantasma___8bitDetokeniser__
+#ifndef FREESCAPE_8BITDETOKENIZER_H
+#define FREESCAPE_8BITDETOKENIZER_H
 
 #include "common/array.h"
 #include "common/str.h"
 
 #include "freescape/language/instruction.h"
 
+namespace Freescape {
+
 Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition, FCLInstructionVector &instructions);
 
+} // End of namespace Freescape
+
 #endif /* defined(__Phantasma___8bitDetokeniser__) */
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index a5fa1826358..f58b184cd38 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -8,6 +8,8 @@
 
 #include "freescape/language/instruction.h"
 
+namespace Freescape {
+
 FCLInstruction::FCLInstruction(Token::Type _type) {
 	// TODO: learn modern constructor syntax
 	type = _type;
@@ -69,3 +71,5 @@ void FCLInstruction::getValue(CGameState &gameState, int32_t &source, int32_t &d
 Token::Type FCLInstruction::getType() {
 	return type;
 }
+
+} // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/language/instruction.h b/engines/freescape/language/instruction.h
index ffe7685e1b1..be78e090304 100644
--- a/engines/freescape/language/instruction.h
+++ b/engines/freescape/language/instruction.h
@@ -6,13 +6,13 @@
 //  Copyright (c) 2013 Thomas Harte. All rights reserved.
 //
 
-#ifndef __Phantasma__Instruction__
-#define __Phantasma__Instruction__
+#ifndef FREESCAPE_INSTRUCTION_H
+#define FREESCAPE_INSTRUCTION_H
 
 #include "common/array.h"
 #include "freescape/language/token.h"
 
-class CGameState;
+namespace Freescape {
 
 class FCLInstruction;
 typedef Common::Array<FCLInstruction> FCLInstructionVector;
@@ -36,4 +36,6 @@ private:
 	enum Token::Type type;
 };
 
-#endif /* defined(__Phantasma__Instruction__) */
+} // End of namespace Freescape
+
+#endif
diff --git a/engines/freescape/language/parser.h b/engines/freescape/language/parser.h
deleted file mode 100644
index e9eb1a42f45..00000000000
--- a/engines/freescape/language/parser.h
+++ /dev/null
@@ -1,17 +0,0 @@
-//
-//  Parser.h
-//  Phantasma
-//
-//  Created by Thomas Harte on 08/12/2013.
-//  Copyright (c) 2013 Thomas Harte. All rights reserved.
-//
-
-#ifndef __Phantasma__Parser__
-#define __Phantasma__Parser__
-
-#include "common/str.h"
-#include "freescape/language/instruction.h"
-
-FCLInstructionVector getInstructions(Common::String *sourceCode);
-
-#endif /* defined(__Phantasma__InstructionBuilder__) */
diff --git a/engines/freescape/language/token.h b/engines/freescape/language/token.h
index 0a9d34424c5..7060693483f 100644
--- a/engines/freescape/language/token.h
+++ b/engines/freescape/language/token.h
@@ -6,13 +6,15 @@
 //  Copyright (c) 2013 Thomas Harte. All rights reserved.
 //
 
-#ifndef __Phantasma__Token__
-#define __Phantasma__Token__
+#ifndef FREESCAPE_TOKEN_H
+#define FREESCAPE_TOKEN_H
 
 #include "common/str.h"
 
 #include "freescape/gamestate.h"
 
+namespace Freescape {
+
 struct Token {
 public:
 	enum Type {
@@ -109,4 +111,6 @@ private:
 	Common::String string;
 };
 
+} // End of namespace Freescape
+
 #endif /* defined(__Phantasma__Token__) */
diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
index 82179f6e5d1..f57769f1d67 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/16bitBinaryLoader.cpp
@@ -12,11 +12,10 @@
 #include "common/debug.h"
 #include "common/file.h"
 
+#include "freescape/freescape.h"
 #include "freescape/area.h"
 #include "freescape/language/16bitDetokeniser.h"
 #include "freescape/language/instruction.h"
-#include "freescape/language/parser.h"
-#include "freescape/loaders/16bitBinaryLoader.h"
 #include "freescape/objects/geometricobject.h"
 #include "freescape/objects/object.h"
 
diff --git a/engines/freescape/loaders/16bitBinaryLoader.h b/engines/freescape/loaders/16bitBinaryLoader.h
deleted file mode 100644
index ef177632b78..00000000000
--- a/engines/freescape/loaders/16bitBinaryLoader.h
+++ /dev/null
@@ -1,23 +0,0 @@
-//
-//  16bitBinaryLoader.h
-//  Phantasma
-//
-//  Created by Thomas Harte on 17/12/2013.
-//  Copyright (c) 2013 Thomas Harte. All rights reserved.
-//
-
-#ifndef __Phantasma___16bitBinaryLoader__
-#define __Phantasma___16bitBinaryLoader__
-
-//#include <iostream>
-//#include <vector>
-//#include <stdint.h>
-#include "common/str.h"
-
-#include "../freescape.h"
-
-namespace Freescape {
-
-}
-
-#endif /* defined(__Phantasma___16bitBinaryLoader__) */
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index d0f5ae5771f..b1c4695b481 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -2,11 +2,10 @@
 #include "common/debug.h"
 #include "common/file.h"
 
+#include "freescape/freescape.h"
 #include "freescape/area.h"
 #include "freescape/language/8bitDetokeniser.h"
 #include "freescape/language/instruction.h"
-#include "freescape/language/parser.h"
-#include "freescape/loaders/8bitBinaryLoader.h"
 #include "freescape/objects/geometricobject.h"
 #include "freescape/objects/entrance.h"
 #include "freescape/objects/object.h"
diff --git a/engines/freescape/loaders/8bitBinaryLoader.h b/engines/freescape/loaders/8bitBinaryLoader.h
deleted file mode 100644
index 18a78b94f75..00000000000
--- a/engines/freescape/loaders/8bitBinaryLoader.h
+++ /dev/null
@@ -1,16 +0,0 @@
-//
-//  8bitBinaryLoader.h
-//  Phantasma
-//
-//  Created by X.
-//  Copyright (c) X. All rights reserved.
-//
-
-#ifndef __Phantasma___8bitBinaryLoader__
-#define __Phantasma___8bitBinaryLoader__
-
-#include "common/str.h"
-
-#include "../freescape.h"
-
-#endif
\ No newline at end of file
diff --git a/engines/freescape/objects/entrance.cpp b/engines/freescape/objects/entrance.cpp
index 9736997f956..2eb680e18f3 100644
--- a/engines/freescape/objects/entrance.cpp
+++ b/engines/freescape/objects/entrance.cpp
@@ -11,6 +11,8 @@
 #pragma mark -
 #pragma mark Construction/Destruction
 
+namespace Freescape {
+
 Entrance::Entrance(
 	uint16 objectID,
 	const Math::Vector3d &origin,
@@ -23,4 +25,6 @@ Entrance::Entrance(
 Entrance::~Entrance() {}
 
 bool Entrance::isDrawable() { return false; }
-bool Entrance::isPlanar() { return true; }
\ No newline at end of file
+bool Entrance::isPlanar() { return true; }
+
+} // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/objects/entrance.h b/engines/freescape/objects/entrance.h
index a696de4d4e0..2891184d564 100644
--- a/engines/freescape/objects/entrance.h
+++ b/engines/freescape/objects/entrance.h
@@ -11,6 +11,8 @@
 
 #include "freescape/objects/object.h"
 
+namespace Freescape {
+
 class Entrance : public Object {
 public:
 
@@ -24,8 +26,10 @@ public:
 	bool isPlanar();
 	Type getType() override { return Type::Entrance; };
 	Math::Vector3d getRotation() { return _rotation; }
-	
+
 	void draw(Freescape::Renderer *gfx) override { error("cannot render Entrance"); };
 };
 
+} // End of namespace Freescape
+
 #endif
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index a7abc4b0243..65822826c2f 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -12,6 +12,8 @@
 #pragma mark -
 #pragma mark Static Getters
 
+namespace Freescape {
+
 int GeometricObject::numberOfColoursForObjectOfType(Type type) {
 	switch (type) {
 	default:
@@ -176,4 +178,6 @@ void GeometricObject::draw(Freescape::Renderer *gfx) {
 		//debug("Drawing %d of type %d", this->getObjectID(), this->getType());
 		gfx->renderPolygon(_origin, _size, ordinates, colours);
 	}
-}
\ No newline at end of file
+}
+
+} // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/objects/geometricobject.h b/engines/freescape/objects/geometricobject.h
index eca6509c072..b979c86fcc8 100644
--- a/engines/freescape/objects/geometricobject.h
+++ b/engines/freescape/objects/geometricobject.h
@@ -6,13 +6,15 @@
 //  Copyright (c) 2013 Thomas Harte. All rights reserved.
 //
 
-#ifndef __Phantasma__GeometricObject__
-#define __Phantasma__GeometricObject__
+#ifndef FREESCAPE_GEOMETRICOBJECT_H
+#define FREESCAPE_GEOMETRICOBJECT_H
 
 #include "common/array.h"
 #include "freescape/language/instruction.h"
 #include "freescape/objects/object.h"
 
+namespace Freescape {
+
 class GeometricObject : public Object {
 public:
 	static int numberOfColoursForObjectOfType(Type type);
@@ -44,4 +46,6 @@ private:
 	Common::Array<uint16> *ordinates;
 };
 
-#endif /* defined(__Phantasma__GeometricObject__) */
+} // End of namespace Freescape
+
+#endif
diff --git a/engines/freescape/objects/object.cpp b/engines/freescape/objects/object.cpp
index db6d90ce4e8..29beda51198 100644
--- a/engines/freescape/objects/object.cpp
+++ b/engines/freescape/objects/object.cpp
@@ -10,6 +10,8 @@
 #include "freescape/freescape.h"
 #include "freescape/gfx.h"
 
+namespace Freescape {
+
 Object::Type Object::getType() { return _type; }
 uint16 Object::getObjectID() { return _objectID; }
 uint16 Object::getObjectFlags() { return _flags; }
@@ -25,3 +27,5 @@ void Object::makeVisible() { _flags = _flags & ~0x80; }
 void Object::toggleVisibility() { _flags = _flags ^ 0x80; }
 
 Object::~Object() {}
+
+} // End of namespace Freescape
diff --git a/engines/freescape/objects/object.h b/engines/freescape/objects/object.h
index 6391b53cd28..391c1df633d 100644
--- a/engines/freescape/objects/object.h
+++ b/engines/freescape/objects/object.h
@@ -15,6 +15,8 @@
 
 #include "freescape/gfx.h"
 
+namespace Freescape {
+
 class Object {
 public:
 	typedef enum {
@@ -63,4 +65,6 @@ public:
 	Math::AABB _boundingBox;
 };
 
+} // End of namespace Freescape
+
 #endif


Commit: 364740551414745e1f5eee07a055915b06d9086b
    https://github.com/scummvm/scummvm/commit/364740551414745e1f5eee07a055915b06d9086b
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:48+01:00

Commit Message:
FREESCAPE: more debugging code

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index d14f78e48ba..3ef87325e70 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -205,6 +205,10 @@ void FreescapeEngine::processInput() {
 				move(LEFT, _scaleVector.y(), deltaTime);
 			else if (event.kbd.keycode == Common::KEYCODE_d || event.kbd.keycode == Common::KEYCODE_RIGHT)
 				move(RIGHT, _scaleVector.y(), deltaTime);
+			else if (event.kbd.keycode == Common::KEYCODE_f)
+				_position.setValue(1, _position.y() + 12);
+			else if (event.kbd.keycode == Common::KEYCODE_v)
+				_position.setValue(1, _position.y() - 12);
 			break;
 
 		case Common::EVENT_QUIT:
@@ -361,6 +365,7 @@ void FreescapeEngine::gotoArea(uint16 areaID, uint16 entranceID) {
 
 	assert(_areasByAreaID->contains(areaID));
 	_currentArea = (*_areasByAreaID)[areaID];
+	_currentArea->show();
 
 	Entrance *entrance = (Entrance*) _currentArea->entranceWithID(entranceID);
 	if (!entrance)
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index c2f9fc1b1c3..ced552ac177 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -214,6 +214,18 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			bytePointer += 2;
 			numberOfArguments = 0;
 			break;
+
+		case 23:
+			detokenisedStream += "UNKNOWN(23)(..) ";
+			bytePointer += 2;
+			numberOfArguments = 0;
+			break;
+
+		case 22:
+			detokenisedStream += "UNKNOWN(22)(..) ";
+			bytePointer += 2;
+			numberOfArguments = 0;
+			break;
 		}
 
 		// if there are any regular arguments to add, do so
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index b1c4695b481..f359feb0e28 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -275,6 +275,9 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 			//if (newObject->getObjectID() == 255) // TODO: fix me?
 			//	break;
 			if (newObject->getType() == Object::Entrance) {
+				if (entrancesByID->contains(newObject->getObjectID() & 0x7fff))
+					error("WARNING: replacing object id %d (%d)", newObject->getObjectID(), newObject->getObjectID() & 0x7fff);
+
 				(*entrancesByID)[newObject->getObjectID() & 0x7fff] = newObject;
 			} else {
 				if (objectsByID->contains(newObject->getObjectID()))
@@ -288,7 +291,7 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	assert(endLastObject <= base + cPtr);
 	file->seek(base + cPtr);
 	uint8 numConditions = file->readByte();
-	debug("%d area conditions", numConditions);
+	debug("%d area conditions at %x", numConditions, base + cPtr);
 	while (numConditions--) {
 		FCLInstructionVector instructions;
 		// get the length
@@ -298,7 +301,7 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 		byte *conditionData = (byte*)malloc(lengthOfCondition);
 		file->read(conditionData, lengthOfCondition);
 		Common::Array<uint8> conditionArray(conditionData, lengthOfCondition);
-		debug("%s", detokenise8bitCondition(conditionArray, instructions)->c_str(), nullptr);
+		debug("%s", detokenise8bitCondition(conditionArray, instructions)->c_str());
 	}
 
 	return (new Area(areaNumber, objectsByID, entrancesByID, scale, 255, 255, palette));
@@ -377,12 +380,19 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	//fileOffsetForArea[0] = 0x9e75 - offset - 8 - 12; // Table?
 	//fileOffsetForArea[0] = 0x9571 - offset;
 	//fileOffsetForArea[0] = 0xaba5 - offset - 8 - 16; // ???
+	//fileOffsetForArea[0] = 0x87c7 - offset - 8; // ???
+	//fileOffsetForArea[0] = 0x9304 - offset - 8 - 12 - 12 - 12; // ???
+	//fileOffsetForArea[0] = 0x92cc - offset; // Pool, 20
+	//fileOffsetForArea[0] = 0x9f40 - offset - 8;
+	//fileOffsetForArea[0] = 0x9f35 - offset; // Another Church, 12
+	//fileOffsetForArea[0] = 0xa06e - offset - 8; // Cornisa? 37
 
 	//fileOffsetForArea[0] = 0x959b - offset - 16; // Church? (22 elements)
 	//fileOffsetForArea[0] = 0x94b7 - offset; // For testing
 	//fileOffsetForArea[0] = 0x97cb - offset; // Courtyard
 	//fileOffsetForArea[0] = 0x92cc - offset ; // Pool?
-	//fileOffsetForArea[0] = 0x866b - offset - 8; // Pool?
+	//fileOffsetForArea[0] = 0x8e0a - offset - 8; // Pool?
+	//fileOffsetForArea[0] = 0x92d8 - offset; // ??
 
 	// grab the areas
 	AreaMap *areaMap = new AreaMap;


Commit: b479b395ecbcd1197cf148121f2280e9afd30981
    https://github.com/scummvm/scummvm/commit/b479b395ecbcd1197cf148121f2280e9afd30981
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:48+01:00

Commit Message:
FREESCAPE: implemented bounding box for pyramids

Changed paths:
    engines/freescape/objects/entrance.cpp
    engines/freescape/objects/geometricobject.cpp
    engines/freescape/objects/object.cpp
    engines/freescape/objects/object.h


diff --git a/engines/freescape/objects/entrance.cpp b/engines/freescape/objects/entrance.cpp
index 2eb680e18f3..dbbbb7a591e 100644
--- a/engines/freescape/objects/entrance.cpp
+++ b/engines/freescape/objects/entrance.cpp
@@ -15,10 +15,10 @@ namespace Freescape {
 
 Entrance::Entrance(
 	uint16 objectID,
-	const Math::Vector3d &origin,
+	const Math::Vector3d &_origin,
 	const Math::Vector3d &rotation) {
 	_objectID = objectID;
-	_origin = origin;
+	origin = _origin;
 	_rotation = rotation;
 }
 
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index 65822826c2f..18ce6a343a2 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -91,8 +91,8 @@ GeometricObject::GeometricObject(
 	Type type,
 	uint16 objectID,
 	uint16 flags,
-	const Math::Vector3d &origin,
-	const Math::Vector3d &size,
+	const Math::Vector3d &_origin,
+	const Math::Vector3d &_size,
 	Common::Array<uint8> *_colours,
 	Common::Array<uint16> *_ordinates,
 	FCLInstructionVector _conditionInstructions,
@@ -100,8 +100,8 @@ GeometricObject::GeometricObject(
 	_type = type;
 	_flags = flags;
 	_objectID = objectID;
-	_origin = origin;
-	_size = size;
+	origin = _origin;
+	size = _size;
 
 	if (_colours)
 		colours = new Common::Array<uint8>(*_colours);
@@ -113,35 +113,99 @@ GeometricObject::GeometricObject(
 }
 
 void GeometricObject::createBoundingBox() {
+	Math::Vector3d v;
 	switch (_type) {
 	default:
 	break;
 	case Cube:
-		_boundingBox.expand(_origin);
+		_boundingBox.expand(origin);
 		for (int i = 0; i < 3; i++) {
-			Math::Vector3d v = _origin;
-			v.setValue(i, v.getValue(i) + _size.getValue(i));
+			v = origin;
+			v.setValue(i, v.getValue(i) + size.getValue(i));
 			_boundingBox.expand(v);
 		}
 
 		for (int i = 0; i < 3; i++) {
-			Math::Vector3d v = _origin + _size;
-			v.setValue(i, v.getValue(i) - _size.getValue(i));
+			v = origin + size;
+			v.setValue(i, v.getValue(i) - size.getValue(i));
 			_boundingBox.expand(v);
 		}
-		_boundingBox.expand(_origin + _size);
+		_boundingBox.expand(origin + size);
 		assert(_boundingBox.isValid());
 		break;
 	case Rectangle:
-		_boundingBox.expand(_origin);
+		_boundingBox.expand(origin);
 
-		Math::Vector3d v = _origin + _size;
+		v = origin + size;
 		for (int i = 0; i < 3; i++) {
-			if (_size.getValue(i) == 0)
+			if (size.getValue(i) == 0)
 				v.setValue(i, v.getValue(i) + 10);
 		}
 		_boundingBox.expand(v);
 		break;
+	case EastPyramid:
+		_boundingBox.expand(origin + Math::Vector3d(0, 0, size.z()));
+		_boundingBox.expand(origin + Math::Vector3d(0, size.y(), size.z()));
+		_boundingBox.expand(origin + Math::Vector3d(0, size.y(), 0));
+
+		_boundingBox.expand(origin + Math::Vector3d(size.x(), (*ordinates)[0], (*ordinates)[3]));
+		_boundingBox.expand(origin + Math::Vector3d(size.x(), (*ordinates)[2], (*ordinates)[3]));
+		_boundingBox.expand(origin + Math::Vector3d(size.x(), (*ordinates)[2], (*ordinates)[1]));
+		_boundingBox.expand(origin + Math::Vector3d(size.x(), (*ordinates)[0], (*ordinates)[1]));
+		break;
+	case WestPyramid:
+		_boundingBox.expand(origin + Math::Vector3d(size.x(), 0, 0));
+		_boundingBox.expand(origin + Math::Vector3d(size.x(), size.y(), 0));
+		_boundingBox.expand(origin + Math::Vector3d(size.x(), size.y(), size.z()));
+		_boundingBox.expand(origin + Math::Vector3d(size.x(), 0, size.z()));
+
+		_boundingBox.expand(origin + Math::Vector3d(0, (*ordinates)[0], (*ordinates)[1]));
+		_boundingBox.expand(origin + Math::Vector3d(0, (*ordinates)[2], (*ordinates)[1]));
+		_boundingBox.expand(origin + Math::Vector3d(0, (*ordinates)[2], (*ordinates)[3]));
+		_boundingBox.expand(origin + Math::Vector3d(0, (*ordinates)[0], (*ordinates)[3]));
+		break;
+	case UpPyramid:
+		_boundingBox.expand(origin + Math::Vector3d(size.x(), 0, 0));
+		_boundingBox.expand(origin + Math::Vector3d(size.x(), 0, size.z()));
+		_boundingBox.expand(origin + Math::Vector3d(0, 0, size.z()));
+
+		_boundingBox.expand(origin + Math::Vector3d((*ordinates)[0], size.y(), (*ordinates)[1]));
+		_boundingBox.expand(origin + Math::Vector3d((*ordinates)[2], size.y(), (*ordinates)[1]));
+		_boundingBox.expand(origin + Math::Vector3d((*ordinates)[2], size.y(), (*ordinates)[3]));
+		_boundingBox.expand(origin + Math::Vector3d((*ordinates)[0], size.y(), (*ordinates)[3]));
+		break;
+	case DownPyramid:
+		_boundingBox.expand(origin + Math::Vector3d(size.x(), size.y(), 0));
+		_boundingBox.expand(origin + Math::Vector3d(0, size.y(), 0));
+		_boundingBox.expand(origin + Math::Vector3d(0, size.y(), size.z()));
+		_boundingBox.expand(origin + Math::Vector3d(size.x(), size.y(), size.z()));
+
+		_boundingBox.expand(origin + Math::Vector3d((*ordinates)[2], 0, (*ordinates)[1]));
+		_boundingBox.expand(origin + Math::Vector3d((*ordinates)[0], 0, (*ordinates)[1]));
+		_boundingBox.expand(origin + Math::Vector3d((*ordinates)[0], 0, (*ordinates)[3]));
+		_boundingBox.expand(origin + Math::Vector3d((*ordinates)[2], 0, (*ordinates)[3]));
+		break;
+	case NorthPyramid:
+		_boundingBox.expand(origin + Math::Vector3d(0, size.y(), 0));
+		_boundingBox.expand(origin + Math::Vector3d(size.x(), size.y(), 0));
+		_boundingBox.expand(origin + Math::Vector3d(size.x(), 0, 0));
+
+		_boundingBox.expand(origin + Math::Vector3d((*ordinates)[0], (*ordinates)[3], size.z()));
+		_boundingBox.expand(origin + Math::Vector3d((*ordinates)[2], (*ordinates)[3], size.z()));
+		_boundingBox.expand(origin + Math::Vector3d((*ordinates)[2], (*ordinates)[1], size.z()));
+		_boundingBox.expand(origin + Math::Vector3d((*ordinates)[0], (*ordinates)[1], size.z()));
+		break;
+	case SouthPyramid:
+		_boundingBox.expand(origin + Math::Vector3d(0, 0, size.z()));
+		_boundingBox.expand(origin + Math::Vector3d(size.x(), 0, size.z()));
+		_boundingBox.expand(origin + Math::Vector3d(size.x(), size.y(), size.z()));
+
+		_boundingBox.expand(origin + Math::Vector3d(0, size.y(), size.z()));
+		_boundingBox.expand(origin + Math::Vector3d((*ordinates)[0], (*ordinates)[1], 0));
+		_boundingBox.expand(origin + Math::Vector3d((*ordinates)[2], (*ordinates)[1], 0));
+		_boundingBox.expand(origin + Math::Vector3d((*ordinates)[2], (*ordinates)[3], 0));
+		_boundingBox.expand(origin + Math::Vector3d((*ordinates)[0], (*ordinates)[3], 0));
+		break;
 	}
 }
 
@@ -151,7 +215,7 @@ GeometricObject::~GeometricObject() {
 bool GeometricObject::isDrawable() { return true; }
 bool GeometricObject::isPlanar() {
 	Type type = this->getType();
-	return (type >= Object::Line) || !_size.x() || !_size.y() || !_size.z();
+	return (type >= Object::Line) || !size.x() || !size.y() || !size.z();
 }
 
 bool GeometricObject::collides(const Math::AABB &boundingBox) {
@@ -169,14 +233,14 @@ bool GeometricObject::collides(const Math::AABB &boundingBox) {
 void GeometricObject::draw(Freescape::Renderer *gfx) {
 	//debug("Drawing %d of type %d", this->getObjectID(), this->getType());
 	if (this->getType() == Cube) {
-		gfx->renderCube(_origin, _size, colours);
+		gfx->renderCube(origin, size, colours);
 	} else if (this->getType() == Rectangle) {
-		gfx->renderRectangle(_origin, _size, colours);
+		gfx->renderRectangle(origin, size, colours);
 	} else if (isPyramid(this->getType())) {
-		gfx->renderPyramid(_origin, _size, ordinates, colours, this->getType());
+		gfx->renderPyramid(origin, size, ordinates, colours, this->getType());
 	} else if (this->isPlanar() && _type <= 14) {
 		//debug("Drawing %d of type %d", this->getObjectID(), this->getType());
-		gfx->renderPolygon(_origin, _size, ordinates, colours);
+		gfx->renderPolygon(origin, size, ordinates, colours);
 	}
 }
 
diff --git a/engines/freescape/objects/object.cpp b/engines/freescape/objects/object.cpp
index 29beda51198..99fc3aff246 100644
--- a/engines/freescape/objects/object.cpp
+++ b/engines/freescape/objects/object.cpp
@@ -15,8 +15,8 @@ namespace Freescape {
 Object::Type Object::getType() { return _type; }
 uint16 Object::getObjectID() { return _objectID; }
 uint16 Object::getObjectFlags() { return _flags; }
-Math::Vector3d Object::getOrigin() { return _origin; }
-Math::Vector3d Object::getSize() { return _size; }
+Math::Vector3d Object::getOrigin() { return origin; }
+Math::Vector3d Object::getSize() { return size; }
 
 bool Object::isDrawable() { return false; }
 bool Object::isPlanar() { return false; }
diff --git a/engines/freescape/objects/object.h b/engines/freescape/objects/object.h
index 391c1df633d..30c0be69680 100644
--- a/engines/freescape/objects/object.h
+++ b/engines/freescape/objects/object.h
@@ -61,7 +61,7 @@ public:
 	uint16 _flags;
 	Type _type;
 	uint16 _objectID;
-	Math::Vector3d _origin, _size, _rotation;
+	Math::Vector3d origin, size, _rotation;
 	Math::AABB _boundingBox;
 };
 


Commit: 66c4c8c70b84292db10dd1344f274bb7d676d40b
    https://github.com/scummvm/scummvm/commit/66c4c8c70b84292db10dd1344f274bb7d676d40b
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:48+01:00

Commit Message:
FREESCAPE: basic implementation of solid objects using current collision checking

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 3ef87325e70..5ff47cb7237 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -319,6 +319,9 @@ void FreescapeEngine::rotate(Common::Point lastMousePos, Common::Point mousePos)
 }
 
 void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTime) {
+	Math::Vector3d previousPosition = _position;
+	int previousAreaID = _currentArea->getAreaID();
+
 	float velocity = _movementSpeed * deltaTime;
 	float positionY = _position.y();
 	switch (direction) {
@@ -338,11 +341,13 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 	// Make sure the user stays at the ground level
 	// this one-liner keeps the user at the ground level (xz plane)
 	_position.set(_position.x(), positionY, _position.z());
+	bool collided = checkCollisions();
+	if (collided && previousAreaID == _currentArea->getAreaID())
+		_position = previousPosition;
 	debug("player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
-	checkCollisions();
 }
 
-void FreescapeEngine::checkCollisions() {
+bool FreescapeEngine::checkCollisions() {
 
 	Math::Vector3d v1(_position.x() - _playerWidth / 2, _playerHeight / 2                , _position.z() - _playerDepth / 2);
 	Math::Vector3d v2(_position.x() + _playerWidth / 2, _position.y() + _playerHeight / 2, _position.z() + _playerDepth / 2);
@@ -357,7 +362,9 @@ void FreescapeEngine::checkCollisions() {
 			debug("Must use collision = true when executing: %s", gobj->conditionSource->c_str());
 			executeCode(gobj->condition, false, true);
 		}
+		return true;
 	}
+	return false;
 }
 
 void FreescapeEngine::gotoArea(uint16 areaID, uint16 entranceID) {
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 18bb84a8474..cc3db82da01 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -116,7 +116,7 @@ public:
 	uint16 _playerDepth;
 
 	// Effects
-	void checkCollisions();
+	bool checkCollisions();
 	void executeCode(FCLInstructionVector &code, bool shot, bool collided);
 
 	// Instructions


Commit: 239aa6a49db7dd355844aeae4ea44188f424c482
    https://github.com/scummvm/scummvm/commit/239aa6a49db7dd355844aeae4ea44188f424c482
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:48+01:00

Commit Message:
FREESCAPE: coloring pyramid implementation and refactoring of palette code

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/gfx_tinygl.h
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 5ff47cb7237..2cd608981ea 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -43,7 +43,6 @@ FreescapeEngine::FreescapeEngine(OSystem *syst)
 	_cameraRight = Math::Vector3d(0.f, 0.f, 0.f);
 	_movementSpeed = 4.5f;
 	_mouseSensitivity = 0.1f;
-	_scale = Math::Vector3d(0, 0, 0);
 	_borderTexture = nullptr;
 
 	// Here is the right place to set up the engine specific debug channels
@@ -181,7 +180,6 @@ Math::Vector3d FreescapeEngine::directionToVector(float pitch, float heading) {
 void FreescapeEngine::drawFrame() {
 	_gfx->updateProjectionMatrix(60.0, _nearClipPlane, _farClipPlane);
 	_gfx->positionCamera(_position, _position + _cameraFront);
-	_gfx->scale(_scaleVector);
 	_currentArea->draw(_gfx);
 	_gfx->renderCrossair(0);
 	//drawBorder();
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index af8ccca5232..6b6058f2a95 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -93,7 +93,6 @@ public:
 									float transparency = -1.0, bool additiveBlending = false) = 0;
 
 	virtual void draw2DText(const Common::String &text, const Common::Point &position) = 0;
-	virtual void scale(const Math::Vector3d &scale) = 0;
 
 	virtual void renderCrossair(byte color) = 0;
 	virtual void renderShoot(byte color) = 0;
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 18477b7f436..00a484b7711 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -174,10 +174,6 @@ void TinyGLRenderer::draw2DText(const Common::String &text, const Common::Point
 	tglDepthMask(TGL_TRUE);
 }
 
-void TinyGLRenderer::scale(const Math::Vector3d &scale) {
-	tglScalef(1, 1, 1);
-}
-
 void TinyGLRenderer::updateProjectionMatrix(float fov, float nearClipPlane, float farClipPlane) {
 	tglMatrixMode(TGL_PROJECTION);
 	tglLoadIdentity();
@@ -489,6 +485,10 @@ void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vec
 	}
 
 	Common::Array<Math::Vector3d> face;
+	uint8 r, g, b;
+	_palette->getRGBAt((*colours)[1], r, g, b);
+	tglColor3ub(r, g, b);
+
 	face.push_back(vertices[5]);
 	face.push_back(vertices[6]);
 	face.push_back(vertices[2]);
@@ -496,6 +496,9 @@ void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vec
 	renderFace(face);
 	face.clear();
 
+	_palette->getRGBAt((*colours)[0], r, g, b);
+	tglColor3ub(r, g, b);
+
 	face.push_back(vertices[7]);
 	face.push_back(vertices[4]);
 	face.push_back(vertices[0]);
@@ -503,6 +506,9 @@ void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vec
 	renderFace(face);
 	face.clear();
 
+	_palette->getRGBAt((*colours)[3], r, g, b);
+	tglColor3ub(r, g, b);
+
 	face.push_back(vertices[4]);
 	face.push_back(vertices[5]);
 	face.push_back(vertices[1]);
@@ -510,6 +516,9 @@ void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vec
 	renderFace(face);
 	face.clear();
 
+	_palette->getRGBAt((*colours)[2], r, g, b);
+	tglColor3ub(r, g, b);
+
 	face.push_back(vertices[6]);
 	face.push_back(vertices[7]);
 	face.push_back(vertices[3]);
@@ -517,6 +526,9 @@ void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vec
 	renderFace(face);
 	face.clear();
 
+	_palette->getRGBAt((*colours)[5], r, g, b);
+	tglColor3ub(r, g, b);
+
 	face.push_back(vertices[0]);
 	face.push_back(vertices[1]);
 	face.push_back(vertices[2]);
@@ -524,6 +536,9 @@ void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vec
 	renderFace(face);
 	face.clear();
 
+	_palette->getRGBAt((*colours)[4], r, g, b);
+	tglColor3ub(r, g, b);
+
 	face.push_back(vertices[7]);
 	face.push_back(vertices[6]);
 	face.push_back(vertices[5]);
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index f3d6c81396e..db983aacd7e 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -39,7 +39,6 @@ public:
 
 	virtual void init() override;
 	virtual void clear() override;
-	virtual void scale(const Math::Vector3d &scale) override;
 	virtual void positionCamera(const Math::Vector3d &pos, const Math::Vector3d &interest) override;
 	virtual void updateProjectionMatrix(float fov, float nearClipPlane, float farClipPlane) override;
 
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index f359feb0e28..c93041788ab 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -151,7 +151,7 @@ float specColors[16][3] = {
 	{1, 1, 1}
 };
 
-Graphics::PixelBuffer *getPaletteGradient(float *c1, float *c2, uint16 ncolors) {
+/*Graphics::PixelBuffer *getPaletteGradient(float *c1, float *c2, uint16 ncolors) {
 	Common::Array <uint8> *raw_palette = new Common::Array <uint8>();
 	uint16 y0, y1, y2;
 	for(int c = 0; c < ncolors; c++)
@@ -172,58 +172,35 @@ Graphics::PixelBuffer *getPaletteGradient(float *c1, float *c2, uint16 ncolors)
 	Graphics::PixelBuffer *palette = new Graphics::PixelBuffer(pixelFormat, ncolors, DisposeAfterUse::NO); //TODO
 	*palette = raw_palette->data();
 	return palette;
-}
-
-Graphics::PixelBuffer *getPaletteGradient(uint8 c1, uint8 c2, uint16 ncolors) {
-	Common::Array <uint8> *raw_palette = new Common::Array <uint8>();
-	uint16 y0, y1, y2;
+}*/
+
+byte drillerEGA[16][3] = {
+	{0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00},
+	{0x00, 0xaa, 0xaa},
+	{0xaa, 0x00, 0xaa},
+	{0xff, 0xff, 0xff},
+	{0x55, 0x55, 0x55},
+	{0x00, 0x00, 0xaa},
+	{0xaa, 0x55, 0x00},
+	{0x12, 0xf3, 0x56},
+	{0xaa, 0x00, 0x00},
+	{0xff, 0x55, 0xff},
+	{0x12, 0xf3, 0x56},
+	{0x12, 0xf3, 0x56},
+	{0x12, 0xf3, 0x56},
+	{0x12, 0xf3, 0x56},
+	{0x12, 0xf3, 0x56}
+};
 
-	for(int c = 0; c < ncolors; c++)
-	{
-		if (true /*c1 == 4 && c2 == 3*/) {
-			switch (c) {
-				case 0:
-				case 1:
-				y0 = 0x00; y1 = 0x00; y2 = 0x00;
-				break;
-				case 2:
-				y0 = 0x00; y1 = 0xaa; y2 = 0xaa;
-				break;
-				case 3:
-				y0 = 0xaa; y1 = 0x00; y2 = 0xaa;
-				break;
-				case 4:
-				y0 = 0xff; y1 = 0xff; y2 = 0xff;
-				break;
-				case 5:
-				y0 = 0x55; y1 = 0x55; y2 = 0x55;
-				break;
-				case 6:
-				y0 = 0x00; y1 = 0x00; y2 = 0xaa;
-				break;
-				case 7:
-				y0 = 0xaa; y1 = 0x55; y2 = 0x00;
-				break;
-				case 9:
-				y0 = 0xaa; y1 = 0x00; y2 = 0x00;
-				break;
-				case 0xa:
-				y0 = 0xff; y1 = 0x55; y2 = 0xff;
-				break;
-				default:
-				y0 = 0x12; y1 = 0xf3; y2 = 0x56;
-				break;
-			}
-		}
-		raw_palette->push_back(y0);
-		raw_palette->push_back(y1);
-		raw_palette->push_back(y2);
-	}
-	//assert(ncolors == 16);
-	assert(raw_palette->size() == ncolors * 3);
+Graphics::PixelBuffer *getPaletteGradient(uint8 areaNumber, uint8 c1, uint8 c2, uint16 ncolors) {
 	Graphics::PixelFormat pixelFormat = Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0);
-	Graphics::PixelBuffer *palette = new Graphics::PixelBuffer(pixelFormat, ncolors, DisposeAfterUse::NO); //TODO
-	*palette = raw_palette->data();
+	Graphics::PixelBuffer *palette = nullptr;
+	switch (areaNumber) {
+		default:
+		palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&drillerEGA);
+		break;
+	}
 	return palette;
 }
 
@@ -255,7 +232,7 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 		ci4 = file->readByte();
 		debug("Colors: %d %d", ci3, ci4);
 	}
-	Graphics::PixelBuffer *palette = getPaletteGradient(1, 1, ncolors);
+	Graphics::PixelBuffer *palette = getPaletteGradient(areaNumber, 1, 1, ncolors);
 
 	debug("Area %d", areaNumber);
 	debug("Skipped: %d Objects: %d", skippedValue, numberOfObjects);


Commit: 4283f9b4e6e1febeee1102872d2e9bc084897b14
    https://github.com/scummvm/scummvm/commit/4283f9b4e6e1febeee1102872d2e9bc084897b14
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:49+01:00

Commit Message:
FREESCAPE: added one cga palette and refactored palette code

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 2cd608981ea..023e20bd60d 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -35,6 +35,11 @@ FreescapeEngine::FreescapeEngine(OSystem *syst)
 	// Do not initialize graphics here
 	// Do not initialize audio devices here
 	_hasReceivedTime = false;
+	if (!ConfMan.hasKey("render_mode"))
+		_renderMode = "ega";
+	else
+		_renderMode = ConfMan.get("render_mode");
+
 	_currentArea = nullptr;
 	_rotation = Math::Vector3d(0.f, 0.f, 0.f);
 	_position = Math::Vector3d(0.f, 0.f, 0.f);
@@ -83,7 +88,6 @@ void FreescapeEngine::drawBorder() {
 }
 
 void FreescapeEngine::loadAssets() {
-	Common::String renderMode = "";
 	Common::SeekableReadStream *file = nullptr;
 	Common::String path = ConfMan.get("path");
 	Common::FSDirectory gameDir(path);
@@ -100,55 +104,43 @@ void FreescapeEngine::loadAssets() {
 
 		file = files.begin()->get()->createReadStream();
 		load16bitBinary(file);
-	} else if (_targetName == "driller" || _targetName == "spacestationoblivion") {
-		if (!ConfMan.hasKey("render_mode"))
-			renderMode = "ega";
-		else
-			renderMode = ConfMan.get("render_mode");
-
+	} else if (_targetName.hasPrefix("driller") || _targetName.hasPrefix("spacestationoblivion")) {
 		Common::File exe;
-		debug("renderMode: %s", renderMode.c_str());
 		bool success = false;
-		if (renderMode == "ega") {
+		if (_renderMode == "ega") {
 			file = gameDir.createReadStreamForMember("DRILLE.EXE");
 
 			if (file == nullptr)
 				error("Failed to open DRILLE.EXE");
 
 			load8bitBinary(file, 0x9b40, 16);
-		} else if (renderMode == "cga") {
+		} else if (_renderMode == "cga") {
 			file = gameDir.createReadStreamForMember("DRILLC.EXE");
 
 			if (file == nullptr)
 				error("Failed to open DRILLC.EXE");
 			load8bitBinary(file, 0x7bb0, 4);
 		} else
-			error("Invalid render mode %s for Driller", renderMode.c_str());
+			error("Invalid render mode %s for Driller", _renderMode.c_str());
 
 	} else if (_targetName == "totaleclipse") {
-		if (!ConfMan.hasKey("render_mode"))
-			renderMode = "ega";
-		else
-			renderMode = ConfMan.get("render_mode");
-
 		Common::File exe;
-		debug("renderMode: %s", renderMode.c_str());
 		bool success = false;
-		if (renderMode == "ega") {
+		if (_renderMode == "ega") {
 			file = gameDir.createReadStreamForMember("TOTEE.EXE");
 
 			if (file == nullptr)
 				error("Failed to open TOTEE.EXE");
 
 			load8bitBinary(file, 0xcdb7, 16);
-		} else if (renderMode == "cga") {
+		} else if (_renderMode == "cga") {
 			file = gameDir.createReadStreamForMember("TOTEC.EXE");
 
 			if (file == nullptr)
 				error("Failed to open TOTEC.EXE");
 			load8bitBinary(file, 0x7bb0, 4); // TODO
 		} else
-			error("Invalid render mode %s for Total Eclipse", renderMode.c_str());
+			error("Invalid render mode %s for Total Eclipse", _renderMode.c_str());
 	   } else if (_targetName == "castlemaster") {
 			file = gameDir.createReadStreamForMember("castle.sna");
 
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index cc3db82da01..9dd4fb1aa3d 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -127,6 +127,8 @@ public:
 	void executeToggleVisibility(FCLInstruction &instruction);
 
 	// Rendering
+	Common::String _renderMode;
+	Graphics::PixelBuffer *getPalette(uint8 areaNumber, uint8 c1, uint8 c2, uint8 c3, uint8 c4, uint16 ncolors);
 	void drawFrame();
 	uint8 _colorNumber;
 	Math::Vector3d _scaleVector;
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index c93041788ab..82ed8edf206 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -52,12 +52,22 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 		int numberOfColours = GeometricObject::numberOfColoursForObjectOfType(objectType);
 		Common::Array<uint8> *colours = new Common::Array<uint8>;
 		debug("Number of colors: %d", numberOfColours/2);
+		uint8 entry;
 		for (uint8 colour = 0; colour < numberOfColours/2; colour++) {
-			uint8 c = file->readByte();
-			colours->push_back(c & 0xf);
-			debug("color[%d] = %x", 2*colour, c & 0xf);
-			colours->push_back(c >> 4);
-			debug("color[%d] = %x", 2*colour+1, c >> 4);
+			uint8 data = file->readByte();
+			entry = data & 0xf;
+			if (_renderMode == "cga")
+				entry = entry % 4; // TODO: use dithering
+
+			colours->push_back(entry);
+			debug("color[%d] = %x", 2*colour, entry);
+
+			entry = data >> 4;
+			if (_renderMode == "cga")
+				entry = entry % 4; // TODO: use dithering
+
+			colours->push_back(entry);
+			debug("color[%d] = %x", 2*colour+1, entry);
 			byteSizeOfObject--;
 		}
 
@@ -132,48 +142,6 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 	return nullptr;
 }
 
-float specColors[16][3] = {
-    {0, 0, 0},
-	{0, 0, 0.75},
-	{0.75, 0, 0},
-	{0.75, 0, 0.75},
-	{0, 0.75, 0},
-	{0, 0.75, 0.75},
-	{0.75, 0.75, 0},
-	{0.75, 0.75, 0.75},
-    {0, 0, 0},
-	{0, 0, 1},
-	{1, 0, 0},
-	{1, 0, 1},
-	{0, 1, 0},
-	{0, 1, 1},
-	{1, 1, 0},
-	{1, 1, 1}
-};
-
-/*Graphics::PixelBuffer *getPaletteGradient(float *c1, float *c2, uint16 ncolors) {
-	Common::Array <uint8> *raw_palette = new Common::Array <uint8>();
-	uint16 y0, y1, y2;
-	for(int c = 0; c < ncolors; c++)
-	{
-		float ic = (float)c / float(ncolors-1);
-		ic = sqrt(ic);
-		y0  = 255*(ic*c2[0] + (1-ic)*c1[0]);
-		y1  = 255*(ic*c2[1] + (1-ic)*c1[1]);
-		y2  = 255*(ic*c2[2] + (1-ic)*c1[2]);
-		//debug("%x %x %x", y0, y1, y2);
-		raw_palette->push_back(y0);
-		raw_palette->push_back(y1);
-		raw_palette->push_back(y2);
-	}
-	assert(ncolors == 16);
-	assert(raw_palette->size() == ncolors * 3);
-	Graphics::PixelFormat pixelFormat = Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0);
-	Graphics::PixelBuffer *palette = new Graphics::PixelBuffer(pixelFormat, ncolors, DisposeAfterUse::NO); //TODO
-	*palette = raw_palette->data();
-	return palette;
-}*/
-
 byte drillerEGA[16][3] = {
 	{0x00, 0x00, 0x00},
 	{0x00, 0x00, 0x00},
@@ -193,13 +161,21 @@ byte drillerEGA[16][3] = {
 	{0x12, 0xf3, 0x56}
 };
 
-Graphics::PixelBuffer *getPaletteGradient(uint8 areaNumber, uint8 c1, uint8 c2, uint16 ncolors) {
-	Graphics::PixelFormat pixelFormat = Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0);
+byte drillerCGA[4][3] = {
+	{0x00, 0x00, 0x00},
+	{0xff, 0xff, 0xff},
+	{0xa8, 0x00, 0xa8},
+	{0x00, 0xa8, 0xa8},
+};
+
+Graphics::PixelBuffer *FreescapeEngine::getPalette(uint8 areaNumber, uint8 c1, uint8 c2, uint8 c3, uint8 c4, uint16 ncolors) {
+	Graphics::PixelFormat pixelFormat = Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, ncolors, 0);
 	Graphics::PixelBuffer *palette = nullptr;
-	switch (areaNumber) {
-		default:
-		palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&drillerEGA);
-		break;
+	if (_targetName.hasPrefix("driller")) {
+		if (_renderMode == "ega")
+			palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&drillerEGA);
+		else if (_renderMode == "cga")
+			palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&drillerCGA);
 	}
 	return palette;
 }
@@ -232,7 +208,7 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 		ci4 = file->readByte();
 		debug("Colors: %d %d", ci3, ci4);
 	}
-	Graphics::PixelBuffer *palette = getPaletteGradient(areaNumber, 1, 1, ncolors);
+	Graphics::PixelBuffer *palette = getPalette(areaNumber, ci1, ci2, ci3, ci4, ncolors);
 
 	debug("Area %d", areaNumber);
 	debug("Skipped: %d Objects: %d", skippedValue, numberOfObjects);


Commit: 1a3e7af413d3eaaaa7781bb4f8edf783d94041fa
    https://github.com/scummvm/scummvm/commit/1a3e7af413d3eaaaa7781bb4f8edf783d94041fa
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:49+01:00

Commit Message:
FREESCAPE: fixed position rendering of polygons

Changed paths:
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/objects/geometricobject.cpp
    engines/freescape/objects/geometricobject.h


diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 00a484b7711..0a45134db63 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -290,18 +290,18 @@ void TinyGLRenderer::renderPolygon(const Math::Vector3d &origin, const Math::Vec
 	float dx, dy, dz;
 	dx = dy = dz = 0;
 
-	if (size.x() == 0)
+	/*if (size.x() == 0)
 		dx = 2;
 	else if (size.y() == 0)
 		dy = 2;
 	else if (size.z() == 0)
 		dz = 2;
-	else {
+	else {*/
 		if (ordinates->size() % 3 > 0) {
 			//return;
 			error("Invalid polygon: %f %f %f", size.x(), size.y(), size.z());
 		}
-	}
+	//}
 
 	if (ordinates->size() % 3 > 0)
 		error("Invalid polygon using %d ordinates", ordinates->size());
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 82ed8edf206..dc9f9f8d38c 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -105,12 +105,15 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 		}
 		debug("End of object at %lx", file->pos());
 
+		if (!GeometricObject::isPolygon(objectType))
+			position = 32 * position;
+
 		// create an object
 		return new GeometricObject(
 			objectType,
 			objectID,
 			rawFlagsAndType, // flags
-			32 * position,
+			position,
 			32 * v, // size
 			colours,
 			ordinates,
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index 18ce6a343a2..874e547e206 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -82,6 +82,21 @@ bool GeometricObject::isPyramid(Type type) {
 	case SouthPyramid:
 		return true;
 	}
+
+}
+
+bool GeometricObject::isPolygon(Type type) {
+	switch (type) {
+	default:
+		return false;
+
+	case Line:
+	case Triangle:
+	case Quadrilateral:
+	case Pentagon:
+	case Hexagon:
+		return true;
+	}
 }
 
 #pragma mark -
diff --git a/engines/freescape/objects/geometricobject.h b/engines/freescape/objects/geometricobject.h
index b979c86fcc8..2c688ad6a48 100644
--- a/engines/freescape/objects/geometricobject.h
+++ b/engines/freescape/objects/geometricobject.h
@@ -20,6 +20,7 @@ public:
 	static int numberOfColoursForObjectOfType(Type type);
 	static int numberOfOrdinatesForType(Type type);
 	static bool isPyramid(Type type);
+	static bool isPolygon(Type type);
 
 	GeometricObject(
 		Type type,


Commit: cc1bfdf84e85ec139c1a812c1a1c4136e99da572
    https://github.com/scummvm/scummvm/commit/cc1bfdf84e85ec139c1a812c1a1c4136e99da572
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:49+01:00

Commit Message:
FREESCAPE: implemented the DESTROY instruction

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/objects/geometricobject.cpp
    engines/freescape/objects/object.cpp
    engines/freescape/objects/object.h


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index b087e2b0109..fcad3074579 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -107,7 +107,7 @@ void Area::draw(Freescape::Renderer *gfx) {
 		gfx->drawSky(skyColor);
 	assert(drawableObjects.size() > 0);
 	for (Common::Array<Object *>::iterator it = drawableObjects.begin(); it != drawableObjects.end(); it++) {
-		if (!(*it)->isInvisible()) {
+		if (!(*it)->isDestroyed() && !(*it)->isInvisible()) {
 			(*it)->draw(gfx);
 		}
 	}
@@ -123,7 +123,7 @@ Object *Area::shootRay(const Math::Ray &ray) {
 	float distance = 16 * 8192; // TODO: check if this is max distance
 	Object *collided = nullptr;
 	for (int i = drawableObjects.size() - 1; i >= 0; i--) {
-		if (!drawableObjects[i]->isInvisible() && drawableObjects[i]->_boundingBox.isValid() && ray.intersectAABB(drawableObjects[i]->_boundingBox)) {
+		if (!drawableObjects[i]->isDestroyed() && !drawableObjects[i]->isInvisible() && drawableObjects[i]->_boundingBox.isValid() && ray.intersectAABB(drawableObjects[i]->_boundingBox)) {
 			if (ray.getOrigin().getDistanceTo(drawableObjects[i]->getOrigin()) < distance ) {
 				collided = drawableObjects[i];
 				distance = ray.getOrigin().getDistanceTo(collided->getOrigin());
@@ -135,7 +135,7 @@ Object *Area::shootRay(const Math::Ray &ray) {
 
 Object *Area::checkCollisions(const Math::AABB &boundingBox) {
 	for (int i = drawableObjects.size() - 1; i >= 0; i--) {
-		if (drawableObjects[i]->isDrawable() && !drawableObjects[i]->isInvisible()) {
+		if (drawableObjects[i]->isDrawable() && !drawableObjects[i]->isDestroyed() && !drawableObjects[i]->isInvisible()) {
 			GeometricObject *obj = (GeometricObject*) drawableObjects[i];
 			if (obj->collides(boundingBox))
 				return drawableObjects[i];
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 023e20bd60d..59f0f7e45b4 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -415,13 +415,23 @@ void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool co
 			case Token::VIS:
 			executeMakeVisible(instruction);
 			break;
-
+			case Token::DESTROY:
+			executeDestroy(instruction);
+			break;
 		}
 		ip++;
 	}
 	return;
 }
 
+void FreescapeEngine::executeDestroy(FCLInstruction &instruction) {
+	uint16 objectID = instruction.source;
+	debug("Destroying obj %d!", objectID);
+	Object *obj = _currentArea->objectWithID(objectID);
+	assert(!obj->isDestroyed());
+	obj->destroy();
+}
+
 void FreescapeEngine::executeMakeInvisible(FCLInstruction &instruction) {
 	uint16 objectID = instruction.source;
 	debug("Making obj %d invisible!", objectID);
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 9dd4fb1aa3d..54ae70a87d1 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -125,6 +125,7 @@ public:
 	void executeMakeInvisible(FCLInstruction &instruction);
 	void executeMakeVisible(FCLInstruction &instruction);
 	void executeToggleVisibility(FCLInstruction &instruction);
+	void executeDestroy(FCLInstruction &instruction);
 
 	// Rendering
 	Common::String _renderMode;
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index ced552ac177..229b615b7ae 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -180,6 +180,7 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 		case 17:
 		case 16:
 			detokenisedStream += "DESTROY (";
+			currentInstruction = FCLInstruction(Token::DESTROY);
 			break;
 		case 18:
 			detokenisedStream += "GOTO (";
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index 874e547e206..3a2d82d104e 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -234,7 +234,7 @@ bool GeometricObject::isPlanar() {
 }
 
 bool GeometricObject::collides(const Math::AABB &boundingBox) {
-	if (isInvisible() || !_boundingBox.isValid() || !boundingBox.isValid())
+	if (isDestroyed() || isInvisible() || !_boundingBox.isValid() || !boundingBox.isValid())
 		return false;
 
 	return(	_boundingBox.getMax().x() > boundingBox.getMin().x() &&
diff --git a/engines/freescape/objects/object.cpp b/engines/freescape/objects/object.cpp
index 99fc3aff246..d7efa610442 100644
--- a/engines/freescape/objects/object.cpp
+++ b/engines/freescape/objects/object.cpp
@@ -24,6 +24,8 @@ bool Object::isPlanar() { return false; }
 bool Object::isInvisible() { return _flags & 0x80; }
 void Object::makeInvisible() { _flags = _flags | 0x80; }
 void Object::makeVisible() { _flags = _flags & ~0x80; }
+bool Object::isDestroyed() { return _flags & 0x20; }
+void Object::destroy() { _flags = _flags | 0x20; }
 void Object::toggleVisibility() { _flags = _flags ^ 0x80; }
 
 Object::~Object() {}
diff --git a/engines/freescape/objects/object.h b/engines/freescape/objects/object.h
index 30c0be69680..a272b04a00c 100644
--- a/engines/freescape/objects/object.h
+++ b/engines/freescape/objects/object.h
@@ -55,6 +55,8 @@ public:
 	void makeInvisible();
 	void makeVisible();
 	void toggleVisibility();
+	bool isDestroyed();
+	void destroy();
 
 	virtual ~Object();
 


Commit: 03291ca0b082343ac383de04fe5e108cb5b46804
    https://github.com/scummvm/scummvm/commit/03291ca0b082343ac383de04fe5e108cb5b46804
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:49+01:00

Commit Message:
FREESCAPE: basic support for border rendering in driller

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/gfx_tinygl.h
    engines/freescape/gfx_tinygl_texture.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 59f0f7e45b4..e121282a5ab 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -80,11 +80,7 @@ void FreescapeEngine::drawBorder() {
 	if (!_borderTexture)
 		_borderTexture = _gfx->createTexture(_border);
 	const Common::Rect rect(0, 0, _screenW, _screenH);
-
-	_gfx->drawTexturedRect2D(rect, rect, _borderTexture, 1.0, false);
-	// _gfx->flipBuffer();
-	// _system->updateScreen();
-	// _gfx->freeTexture(t);
+	_gfx->drawTexturedRect2D(rect, rect, _borderTexture);
 }
 
 void FreescapeEngine::loadAssets() {
@@ -149,7 +145,7 @@ void FreescapeEngine::loadAssets() {
 			// Courtyard -> 0x93c1 -> 0x8cbc,3
 			// Beds -> 0x867d
 			// All? -> 0x845d or 0x80ed?
-			load8bitBinary(file, 0x1000, 16);
+			load8bitBinary(file, 0x8465, 16);
 	   } else
 		error("'%s' is an invalid game", _targetName.c_str());
 
@@ -174,7 +170,7 @@ void FreescapeEngine::drawFrame() {
 	_gfx->positionCamera(_position, _position + _cameraFront);
 	_currentArea->draw(_gfx);
 	_gfx->renderCrossair(0);
-	//drawBorder();
+	drawBorder();
 }
 
 void FreescapeEngine::processInput() {
@@ -270,6 +266,17 @@ Common::Error FreescapeEngine::run() {
 	} else {
 		_farClipPlane = 8192.f;
 	}
+
+	drawBorder();
+	_gfx->flipBuffer();
+	g_system->updateScreen();
+	g_system->delayMillis(1000);
+
+	_borderTexture = nullptr;
+
+	Common::Rect viewArea(40, 16, 279, 116);
+	_border->fillRect(viewArea, 0xA0A0A0FF);
+
 	debug("Starting area %d", _currentArea->getAreaID());
 	while (!shouldQuit()) {
 		drawFrame();
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 6b6058f2a95..c85b03c2c03 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -89,8 +89,7 @@ public:
 	virtual void freeTexture(Texture *texture) = 0;
 
 	virtual void drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint8 g, uint8 b) = 0;
-	virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture,
-									float transparency = -1.0, bool additiveBlending = false) = 0;
+	virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture) = 0;
 
 	virtual void draw2DText(const Common::String &text, const Common::Point &position) = 0;
 
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 0a45134db63..cc0f3240766 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -103,38 +103,19 @@ void TinyGLRenderer::drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint
 	tglDisable(TGL_BLEND);
 }
 
-void TinyGLRenderer::drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect,
-		Texture *texture, float transparency, bool additiveBlending) {
+void TinyGLRenderer::drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture) {
 	const float sLeft = screenRect.left;
 	const float sTop = screenRect.top;
 	const float sWidth = screenRect.width();
 	const float sHeight = screenRect.height();
 
-	if (transparency >= 0.0) {
-		if (additiveBlending) {
-			tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE);
-		} else {
-			tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE_MINUS_SRC_ALPHA);
-		}
-		tglEnable(TGL_BLEND);
-	} else {
-		transparency = 1.0;
-	}
-
 	// HACK: tglBlit is not affected by the viewport, so we offset the draw coordinates here
 	int viewPort[4];
 	tglGetIntegerv(TGL_VIEWPORT, viewPort);
 
-	tglEnable(TGL_TEXTURE_2D);
-	tglDepthMask(TGL_FALSE);
-
 	TinyGL::BlitTransform transform(sLeft + viewPort[0], sTop + viewPort[1]);
 	transform.sourceRectangle(textureRect.left, textureRect.top, sWidth, sHeight);
-	transform.tint(transparency);
 	tglBlit(((TinyGLTexture *)texture)->getBlitTexture(), transform);
-
-	tglDisable(TGL_BLEND);
-	tglDepthMask(TGL_TRUE);
 }
 
 void TinyGLRenderer::draw2DText(const Common::String &text, const Common::Point &position) {
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index db983aacd7e..9c1e976b981 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -46,8 +46,7 @@ public:
 	void freeTexture(Texture *texture) override;
 
 	virtual void drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint8 g, uint8 b) override;
-	virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture,
-	                                float transparency = -1.0, bool additiveBlending = false) override;
+	virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture) override;
 	virtual void draw2DText(const Common::String &text, const Common::Point &position) override;
 
 	virtual void renderCrossair(byte color) override;
diff --git a/engines/freescape/gfx_tinygl_texture.cpp b/engines/freescape/gfx_tinygl_texture.cpp
index bdb55c69aca..de4fab0695a 100644
--- a/engines/freescape/gfx_tinygl_texture.cpp
+++ b/engines/freescape/gfx_tinygl_texture.cpp
@@ -30,24 +30,6 @@ TinyGLTexture::TinyGLTexture(const Graphics::Surface *surface) {
 	height = surface->h;
 	format = surface->format;
 
-	if (format.bytesPerPixel == 4) {
-		internalFormat = TGL_RGBA;
-		sourceFormat = TGL_UNSIGNED_BYTE;
-	} else if (format.bytesPerPixel == 2) {
-		internalFormat = TGL_RGB;
-		sourceFormat = TGL_UNSIGNED_SHORT_5_6_5;
-	} else
-		error("Unknown pixel format");
-
-	tglGenTextures(1, &id);
-	tglBindTexture(TGL_TEXTURE_2D, id);
-	tglTexImage2D(TGL_TEXTURE_2D, 0, 3, width, height, 0, internalFormat, sourceFormat, 0);
-	tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_MIN_FILTER, TGL_LINEAR);
-	tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_MAG_FILTER, TGL_LINEAR);
-
-	// NOTE: TinyGL doesn't have issues with white lines so doesn't need use TGL_CLAMP_TO_EDGE
-	tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_WRAP_S, TGL_REPEAT);
-	tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_WRAP_T, TGL_REPEAT);
 	_blitImage = tglGenBlitImage();
 
 	update(surface);
@@ -59,10 +41,7 @@ TinyGLTexture::~TinyGLTexture() {
 }
 
 void TinyGLTexture::update(const Graphics::Surface *surface) {
-	tglBindTexture(TGL_TEXTURE_2D, id);
-	tglTexImage2D(TGL_TEXTURE_2D, 0, 3, width, height, 0,
-			internalFormat, sourceFormat, const_cast<void *>(surface->getPixels())); // TESTME: Not sure if it works.
-	tglUploadBlitImage(_blitImage, *surface, 0, false);
+	tglUploadBlitImage(_blitImage, *surface, 0xA0A0A0FF, true);
 }
 
 void TinyGLTexture::updatePartial(const Graphics::Surface *surface, const Common::Rect &rect) {
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index dc9f9f8d38c..1963a43ba43 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -1,6 +1,7 @@
 #include "common/array.h"
 #include "common/debug.h"
 #include "common/file.h"
+#include "image/bmp.h"
 
 #include "freescape/freescape.h"
 #include "freescape/area.h"
@@ -278,11 +279,14 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 // };
 
 void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offset, int ncolors) {
-	//const uint32 fileSize = file->size();
-	file->seek(0x210);
-	uint16 frameSize = file->readUint16BE();
-	//Common::Array<uint8> *raw_border = streamLoader.nextBytes(frameSize);
-	debug("Found border image of size %x", frameSize);
+	Image::BitmapDecoder decoder;
+	Common::File borderFile;
+
+	if (_renderMode == "ega" && borderFile.open("ega.bmp")) {
+		decoder.loadStream(borderFile);
+		_border = new Graphics::Surface();
+		_border->copyFrom(*decoder.getSurface());
+	}
 
 	file->seek(offset);
 	uint8 numberOfAreas = file->readByte();


Commit: 3e5f02f34676377940eb63c73d38663c29d55334
    https://github.com/scummvm/scummvm/commit/3e5f02f34676377940eb63c73d38663c29d55334
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:49+01:00

Commit Message:
FREESCAPE: avoid crashing when there is no border file and added support for cga border

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index e121282a5ab..d38937b8bdd 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -74,7 +74,7 @@ FreescapeEngine::~FreescapeEngine() {
 }
 
 void FreescapeEngine::drawBorder() {
-	if (_border == nullptr)
+	if (!_border)
 		return;
 
 	if (!_borderTexture)
@@ -267,15 +267,16 @@ Common::Error FreescapeEngine::run() {
 		_farClipPlane = 8192.f;
 	}
 
-	drawBorder();
-	_gfx->flipBuffer();
-	g_system->updateScreen();
-	g_system->delayMillis(1000);
-
-	_borderTexture = nullptr;
+	if (_border) {
+		drawBorder();
+		_gfx->flipBuffer();
+		g_system->updateScreen();
+		g_system->delayMillis(1000);
 
-	Common::Rect viewArea(40, 16, 279, 116);
-	_border->fillRect(viewArea, 0xA0A0A0FF);
+		_borderTexture = nullptr;
+		Common::Rect viewArea(40, 16, 279, 116);
+		_border->fillRect(viewArea, 0xA0A0A0FF);
+	}
 
 	debug("Starting area %d", _currentArea->getAreaID());
 	while (!shouldQuit()) {
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 1963a43ba43..5485d7ef20b 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -282,7 +282,8 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	Image::BitmapDecoder decoder;
 	Common::File borderFile;
 
-	if (_renderMode == "ega" && borderFile.open("ega.bmp")) {
+	if ((_renderMode == "ega" && borderFile.open("ega.bmp")) ||
+	    (_renderMode == "cga" && borderFile.open("cga.bmp"))) {
 		decoder.loadStream(borderFile);
 		_border = new Graphics::Surface();
 		_border->copyFrom(*decoder.getSurface());


Commit: 18feecbb69a0d0d6b1a20fa23a415b98aad5c1ea
    https://github.com/scummvm/scummvm/commit/18feecbb69a0d0d6b1a20fa23a415b98aad5c1ea
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:49+01:00

Commit Message:
FREESCAPE: initial implementation of variable increment and game state in Driller

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/language/8bitDetokeniser.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index d38937b8bdd..504c670a224 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -19,7 +19,7 @@
 #include "freescape/gfx.h"
 #include "freescape/objects/geometricobject.h"
 #include "freescape/language/token.h"
-
+#include "freescape/language/8bitDetokeniser.h"
 
 namespace Freescape {
 
@@ -245,8 +245,10 @@ void FreescapeEngine::shoot() {
 }
 
 Common::Error FreescapeEngine::run() {
-	// Initialize graphics:
-	_gfx = Freescape::createRenderer(_system);
+	initGameState();
+
+	// Initialize graphics
+	_gfx = createRenderer(_system);
 	_gfx->init();
 	_gfx->clear();
 	loadAssets();
@@ -290,6 +292,15 @@ Common::Error FreescapeEngine::run() {
 	return Common::kNoError;
 }
 
+void FreescapeEngine::initGameState() {
+	/*for (int16 i = 0; i < 256; i++) {
+		_gameState[i] = 0;
+	}*/
+
+	_gameState[k8bitVariableEnergy] = 100;
+	_gameState[k8bitVariableShield] = 100;
+}
+
 void FreescapeEngine::rotate(Common::Point lastMousePos, Common::Point mousePos) {
 	//debug("x: %d, y: %d", mousePos.x, mousePos.y);
 	float xoffset = mousePos.x - lastMousePos.x;
@@ -411,6 +422,9 @@ void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool co
 			// else branch is always empty
 			assert(instruction.elseInstructions == nullptr);
 			break;
+			case Token::ADDVAR:
+			executeIncrementVariable(instruction);
+			break;
 			case Token::GOTO:
 			executeGoto(instruction);
 			break;
@@ -432,6 +446,16 @@ void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool co
 	return;
 }
 
+void FreescapeEngine::executeIncrementVariable(FCLInstruction &instruction) {
+	uint16 variable = instruction.source;
+	uint16 increment = instruction.destination;
+	_gameState[variable] = _gameState[variable] + increment;
+	if (variable == k8bitVariableScore) {
+		debug("Score incremented by %d up to %d", increment, _gameState[variable]);
+	} else
+		debug("Variable %d by %d incremented up to %d!", variable, increment, _gameState[variable]);
+}
+
 void FreescapeEngine::executeDestroy(FCLInstruction &instruction) {
 	uint16 objectID = instruction.source;
 	debug("Destroying obj %d!", objectID);
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 54ae70a87d1..5c6cc803903 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -120,6 +120,7 @@ public:
 	void executeCode(FCLInstructionVector &code, bool shot, bool collided);
 
 	// Instructions
+	void executeIncrementVariable(FCLInstruction &instruction);
 	void executeGoto(FCLInstruction &instruction);
 	void executeIfThenElse(FCLInstruction &instruction);
 	void executeMakeInvisible(FCLInstruction &instruction);
@@ -136,6 +137,10 @@ public:
 	float _nearClipPlane;
 	float _farClipPlane;
 
+	// Game state
+	void initGameState();
+	Common::HashMap<uint16, int32> _gameState;
+
 	bool hasFeature(EngineFeature f) const override;
 	bool canLoadGameStateCurrently() override { return true; }
 	bool canSaveGameStateCurrently() override { return true; }
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index 229b615b7ae..c4b3a538564 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -16,10 +16,6 @@
 
 namespace Freescape {
 
-static const int k8bitVariableShield = 256;
-static const int k8bitVariableEnergy = 257;
-static const int k8bitVariableScore = 258;
-
 Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition, FCLInstructionVector &instructions) {
 	Common::String detokenisedStream;
 	Common::Array<uint8>::size_type bytePointer = 0;
@@ -99,18 +95,33 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 				(tokenisedCondition[bytePointer + 2] << 16);
 			detokenisedStream += "ADDVAR";
 			detokenisedStream += Common::String::format("(%d, v%d)", additionValue, k8bitVariableScore);
+			currentInstruction = FCLInstruction(Token::ADDVAR);
+			currentInstruction.setSource(k8bitVariableScore);
+			currentInstruction.setDestination(additionValue);
+			conditionalInstructions->push_back(currentInstruction);
+			currentInstruction = FCLInstruction(Token::UNKNOWN);
 			bytePointer += 3;
 			numberOfArguments = 0;
 		} break;
 		case 2: // add one-byte value to energy
 			detokenisedStream += "ADDVAR ";
 			detokenisedStream += Common::String::format("(%d, v%d)", (int)tokenisedCondition[bytePointer], k8bitVariableEnergy);
+			currentInstruction = FCLInstruction(Token::ADDVAR);
+			currentInstruction.setSource(k8bitVariableEnergy);
+			currentInstruction.setDestination(tokenisedCondition[bytePointer]);
+			conditionalInstructions->push_back(currentInstruction);
+			currentInstruction = FCLInstruction(Token::UNKNOWN);
 			bytePointer++;
 			numberOfArguments = 0;
 			break;
 		case 19: // add one-byte value to shield
 			detokenisedStream += "ADDVAR ";
 			detokenisedStream += Common::String::format("(%d, v%d)", (int)tokenisedCondition[bytePointer], k8bitVariableShield);
+			currentInstruction = FCLInstruction(Token::ADDVAR);
+			currentInstruction.setSource(k8bitVariableShield);
+			currentInstruction.setDestination(tokenisedCondition[bytePointer]);
+			conditionalInstructions->push_back(currentInstruction);
+			currentInstruction = FCLInstruction(Token::UNKNOWN);
 			bytePointer++;
 			numberOfArguments = 0;
 			break;
@@ -133,6 +144,11 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 
 		case 9:
 			detokenisedStream += "ADDVAR (1, v";
+			currentInstruction = FCLInstruction(Token::ADDVAR);
+			currentInstruction.setSource(tokenisedCondition[bytePointer]);
+			currentInstruction.setDestination(1);
+			conditionalInstructions->push_back(currentInstruction);
+			currentInstruction = FCLInstruction(Token::UNKNOWN);
 			break;
 		case 10:
 			detokenisedStream += "SUBVAR (1, v";
diff --git a/engines/freescape/language/8bitDetokeniser.h b/engines/freescape/language/8bitDetokeniser.h
index 08b058594f2..9490cff52cc 100644
--- a/engines/freescape/language/8bitDetokeniser.h
+++ b/engines/freescape/language/8bitDetokeniser.h
@@ -16,6 +16,12 @@
 
 namespace Freescape {
 
+enum {
+	k8bitVariableShield = 256,
+	k8bitVariableEnergy = 257,
+	k8bitVariableScore = 258
+};
+
 Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition, FCLInstructionVector &instructions);
 
 } // End of namespace Freescape


Commit: ee973d346f8281d6c7b97b632c38f89ec5079f83
    https://github.com/scummvm/scummvm/commit/ee973d346f8281d6c7b97b632c38f89ec5079f83
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:50+01:00

Commit Message:
FREESCAPE: initial implementation of variable decrement and fix in global condition parsing Driller

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 504c670a224..b1de6345c8a 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -425,6 +425,9 @@ void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool co
 			case Token::ADDVAR:
 			executeIncrementVariable(instruction);
 			break;
+			case Token::SUBVAR:
+			executeDecrementVariable(instruction);
+			break;
 			case Token::GOTO:
 			executeGoto(instruction);
 			break;
@@ -456,6 +459,16 @@ void FreescapeEngine::executeIncrementVariable(FCLInstruction &instruction) {
 		debug("Variable %d by %d incremented up to %d!", variable, increment, _gameState[variable]);
 }
 
+void FreescapeEngine::executeDecrementVariable(FCLInstruction &instruction) {
+	uint16 variable = instruction.source;
+	uint16 decrement = instruction.destination;
+	_gameState[variable] = _gameState[variable] - decrement;
+	if (variable == k8bitVariableEnergy) {
+		debug("Energy decrement by %d up to %d", decrement, _gameState[variable]);
+	} else
+		debug("Variable %d by %d incremented up to %d!", variable, decrement, _gameState[variable]);
+}
+
 void FreescapeEngine::executeDestroy(FCLInstruction &instruction) {
 	uint16 objectID = instruction.source;
 	debug("Destroying obj %d!", objectID);
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 5c6cc803903..54763a87259 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -121,6 +121,7 @@ public:
 
 	// Instructions
 	void executeIncrementVariable(FCLInstruction &instruction);
+	void executeDecrementVariable(FCLInstruction &instruction);
 	void executeGoto(FCLInstruction &instruction);
 	void executeIfThenElse(FCLInstruction &instruction);
 	void executeMakeInvisible(FCLInstruction &instruction);
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index c4b3a538564..46e400934c7 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -152,6 +152,12 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			break;
 		case 10:
 			detokenisedStream += "SUBVAR (1, v";
+			currentInstruction = FCLInstruction(Token::SUBVAR);
+			currentInstruction.setSource(tokenisedCondition[bytePointer]);
+			currentInstruction.setDestination(1);
+			conditionalInstructions->push_back(currentInstruction);
+			currentInstruction = FCLInstruction(Token::UNKNOWN);
+			break;
 			break;
 
 		case 11: // end condition if a variable doesn't have a particular value
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 5485d7ef20b..cea2b175d76 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -248,7 +248,7 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	assert(endLastObject <= base + cPtr);
 	file->seek(base + cPtr);
 	uint8 numConditions = file->readByte();
-	debug("%d area conditions at %x", numConditions, base + cPtr);
+	debug("%d area conditions at %x of area %d", numConditions, base + cPtr, areaNumber);
 	while (numConditions--) {
 		FCLInstructionVector instructions;
 		// get the length
@@ -303,15 +303,16 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	uint8 startEntrance = file->readByte();
 	debug("Entrace area: %d", startEntrance);
 
-	//streamLoader.skipBytes(66);
-	file->seek(66, SEEK_CUR);
+	file->seek(0x42, SEEK_CUR);
 
 	uint16 globalSomething;
 	globalSomething = file->readUint16BE();
 	debug("Pointer to something: %x\n", globalSomething);
 
+	file->seek(offset + 0x48);
+
 	uint16 globalByteCodeTable;
-	globalByteCodeTable = file->readUint16BE();
+	globalByteCodeTable = file->readUint16LE();
 	debug("GBCT: %d\n", globalByteCodeTable);
 
 	file->seek(offset + globalByteCodeTable);
@@ -328,7 +329,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 		Common::Array<uint8> conditionArray(conditionData, lengthOfCondition);
 		//debug("Global condition %d", numConditions + 1);
 		Common::String *conditions = detokenise8bitCondition(conditionArray, instructions);
-		//debug("%s", conditions->c_str());
+		debug("%s", conditions->c_str());
 	}
 
 	file->seek(offset + 200);


Commit: 6d6d104115cfb8a3b4aa22364ffc390485170388
    https://github.com/scummvm/scummvm/commit/6d6d104115cfb8a3b4aa22364ffc390485170388
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:50+01:00

Commit Message:
FREESCAPE: initial implementation of end if not equal instruction

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/language/8bitDetokeniser.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index b1de6345c8a..dbefe3f4493 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -422,6 +422,10 @@ void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool co
 			// else branch is always empty
 			assert(instruction.elseInstructions == nullptr);
 			break;
+			case Token::VARNOTEQ:
+			if (executeEndIfNotEqual(instruction))
+				ip = codeSize;
+			break;
 			case Token::ADDVAR:
 			executeIncrementVariable(instruction);
 			break;
@@ -449,6 +453,13 @@ void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool co
 	return;
 }
 
+bool FreescapeEngine::executeEndIfNotEqual(FCLInstruction &instruction) {
+	uint16 variable1 = instruction.source;
+	uint16 variable2 = instruction.destination;
+	debug("End condition if variable %d is not equal to variable %d!", variable1, variable2);
+	return (_gameState[variable1] != _gameState[variable2]);
+}
+
 void FreescapeEngine::executeIncrementVariable(FCLInstruction &instruction) {
 	uint16 variable = instruction.source;
 	uint16 increment = instruction.destination;
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 54763a87259..09127d2064b 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -128,6 +128,8 @@ public:
 	void executeMakeVisible(FCLInstruction &instruction);
 	void executeToggleVisibility(FCLInstruction &instruction);
 	void executeDestroy(FCLInstruction &instruction);
+	bool executeEndIfNotEqual(FCLInstruction &instruction);
+
 
 	// Rendering
 	Common::String _renderMode;
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index 46e400934c7..0a1f1f49295 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -164,6 +164,11 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			detokenisedStream += "IF VAR!=? ";
 			detokenisedStream += Common::String::format("(v%d, v%d)", (int)tokenisedCondition[bytePointer], (int)tokenisedCondition[bytePointer + 1]);
 			detokenisedStream += "THEN END ENDIF";
+			currentInstruction = FCLInstruction(Token::VARNOTEQ);
+			currentInstruction.setSource(tokenisedCondition[bytePointer]);
+			currentInstruction.setDestination(tokenisedCondition[bytePointer + 1]);
+			conditionalInstructions->push_back(currentInstruction);
+			currentInstruction = FCLInstruction(Token::UNKNOWN);
 			bytePointer += 2;
 			numberOfArguments = 0;
 			break;


Commit: 93129f9c769d6c8af206190b384d888c29feece3
    https://github.com/scummvm/scummvm/commit/93129f9c769d6c8af206190b384d888c29feece3
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:50+01:00

Commit Message:
FREESCAPE: initial implementations of redraw and delay instructions

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/language/8bitDetokeniser.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index dbefe3f4493..c7b9c2f9941 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -447,12 +447,29 @@ void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool co
 			case Token::DESTROY:
 			executeDestroy(instruction);
 			break;
+			case Token::REDRAW:
+			executeRedraw(instruction);
+			break;
+			case Token::DELAY:
+			executeDelay(instruction);
+			break;
 		}
 		ip++;
 	}
 	return;
 }
 
+void FreescapeEngine::executeRedraw(FCLInstruction &instruction) {
+	debug("Redrawing screen");
+	drawFrame();
+}
+
+void FreescapeEngine::executeDelay(FCLInstruction &instruction) {
+	uint16 delay = instruction.source;
+	debug("Delaying %d * 1/50 seconds", delay);
+	g_system->delayMillis(20 * delay);
+}
+
 bool FreescapeEngine::executeEndIfNotEqual(FCLInstruction &instruction) {
 	uint16 variable1 = instruction.source;
 	uint16 variable2 = instruction.destination;
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 09127d2064b..31791addfcf 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -128,6 +128,8 @@ public:
 	void executeMakeVisible(FCLInstruction &instruction);
 	void executeToggleVisibility(FCLInstruction &instruction);
 	void executeDestroy(FCLInstruction &instruction);
+	void executeRedraw(FCLInstruction &instruction);
+	void executeDelay(FCLInstruction &instruction);
 	bool executeEndIfNotEqual(FCLInstruction &instruction);
 
 
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index 0a1f1f49295..fd64c4c8175 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -219,9 +219,13 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			break;
 		case 26:
 			detokenisedStream += "REDRAW";
+			currentInstruction = FCLInstruction(Token::REDRAW);
+			conditionalInstructions->push_back(currentInstruction);
+			currentInstruction = FCLInstruction(Token::UNKNOWN);
 			break;
 		case 27:
 			detokenisedStream += "DELAY (";
+			currentInstruction = FCLInstruction(Token::DELAY);
 			break;
 		case 28:
 			detokenisedStream += "SYNCSND (";


Commit: e87876e400cd44f674528072a3e7bb40e370496c
    https://github.com/scummvm/scummvm/commit/e87876e400cd44f674528072a3e7bb40e370496c
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:50+01:00

Commit Message:
FREESCAPE: refactored instruction code

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/language/instruction.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index c7b9c2f9941..fd667c1b6cc 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -400,138 +400,6 @@ void FreescapeEngine::gotoArea(uint16 areaID, uint16 entranceID) {
 	_yaw = _rotation.y() - 180.f;
 }
 
-void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool collided) {
-	assert(!(shot && collided));
-	int ip = 0;
-	int codeSize = code.size();
-	while (ip <= codeSize - 1) {
-		FCLInstruction &instruction = code[ip];
-		debug("Executing ip: %d in code with size: %d", ip, codeSize);
-		switch (instruction.getType()) {
-			default:
-			break;
-			case Token::COLLIDEDQ:
-			if (collided)
-				executeCode(*instruction.thenInstructions, shot, collided);
-			// else branch is always empty
-			assert(instruction.elseInstructions == nullptr);
-			break;
-			case Token::SHOTQ:
-			if (shot)
-				executeCode(*instruction.thenInstructions, shot, collided);
-			// else branch is always empty
-			assert(instruction.elseInstructions == nullptr);
-			break;
-			case Token::VARNOTEQ:
-			if (executeEndIfNotEqual(instruction))
-				ip = codeSize;
-			break;
-			case Token::ADDVAR:
-			executeIncrementVariable(instruction);
-			break;
-			case Token::SUBVAR:
-			executeDecrementVariable(instruction);
-			break;
-			case Token::GOTO:
-			executeGoto(instruction);
-			break;
-			case Token::TOGVIS:
-			executeToggleVisibility(instruction);
-			break;
-			case Token::INVIS:
-			executeMakeInvisible(instruction);
-			break;
-			case Token::VIS:
-			executeMakeVisible(instruction);
-			break;
-			case Token::DESTROY:
-			executeDestroy(instruction);
-			break;
-			case Token::REDRAW:
-			executeRedraw(instruction);
-			break;
-			case Token::DELAY:
-			executeDelay(instruction);
-			break;
-		}
-		ip++;
-	}
-	return;
-}
-
-void FreescapeEngine::executeRedraw(FCLInstruction &instruction) {
-	debug("Redrawing screen");
-	drawFrame();
-}
-
-void FreescapeEngine::executeDelay(FCLInstruction &instruction) {
-	uint16 delay = instruction.source;
-	debug("Delaying %d * 1/50 seconds", delay);
-	g_system->delayMillis(20 * delay);
-}
-
-bool FreescapeEngine::executeEndIfNotEqual(FCLInstruction &instruction) {
-	uint16 variable1 = instruction.source;
-	uint16 variable2 = instruction.destination;
-	debug("End condition if variable %d is not equal to variable %d!", variable1, variable2);
-	return (_gameState[variable1] != _gameState[variable2]);
-}
-
-void FreescapeEngine::executeIncrementVariable(FCLInstruction &instruction) {
-	uint16 variable = instruction.source;
-	uint16 increment = instruction.destination;
-	_gameState[variable] = _gameState[variable] + increment;
-	if (variable == k8bitVariableScore) {
-		debug("Score incremented by %d up to %d", increment, _gameState[variable]);
-	} else
-		debug("Variable %d by %d incremented up to %d!", variable, increment, _gameState[variable]);
-}
-
-void FreescapeEngine::executeDecrementVariable(FCLInstruction &instruction) {
-	uint16 variable = instruction.source;
-	uint16 decrement = instruction.destination;
-	_gameState[variable] = _gameState[variable] - decrement;
-	if (variable == k8bitVariableEnergy) {
-		debug("Energy decrement by %d up to %d", decrement, _gameState[variable]);
-	} else
-		debug("Variable %d by %d incremented up to %d!", variable, decrement, _gameState[variable]);
-}
-
-void FreescapeEngine::executeDestroy(FCLInstruction &instruction) {
-	uint16 objectID = instruction.source;
-	debug("Destroying obj %d!", objectID);
-	Object *obj = _currentArea->objectWithID(objectID);
-	assert(!obj->isDestroyed());
-	obj->destroy();
-}
-
-void FreescapeEngine::executeMakeInvisible(FCLInstruction &instruction) {
-	uint16 objectID = instruction.source;
-	debug("Making obj %d invisible!", objectID);
-	Object *obj = _currentArea->objectWithID(objectID);
-	obj->makeInvisible();
-}
-
-void FreescapeEngine::executeMakeVisible(FCLInstruction &instruction) {
-	uint16 objectID = instruction.source;
-	debug("Making obj %d visible!", objectID);
-	Object *obj = _currentArea->objectWithID(objectID);
-	obj->makeVisible();
-}
-
-void FreescapeEngine::executeToggleVisibility(FCLInstruction &instruction) {
-	uint16 objectID = instruction.source;
-	debug("Toggling obj %d visibility!", objectID);
-	Object *obj = _currentArea->objectWithID(objectID);
-	obj->toggleVisibility();
-}
-
-void FreescapeEngine::executeGoto(FCLInstruction &instruction) {
-	uint16 areaID = instruction.source;
-	uint16 entranceID = instruction.destination;
-	gotoArea(areaID, entranceID);
-}
-
 bool FreescapeEngine::hasFeature(EngineFeature f) const {
 	return (f == kSupportsReturnToLauncher) ||
 		   (f == kSupportsLoadingDuringRuntime) ||
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index f58b184cd38..0de7b3b0b3c 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -7,6 +7,8 @@
 //
 
 #include "freescape/language/instruction.h"
+#include "freescape/language/8bitDetokeniser.h"
+#include "freescape/freescape.h"
 
 namespace Freescape {
 
@@ -23,20 +25,6 @@ FCLInstruction::FCLInstruction() {
 	elseInstructions = nullptr;
 }
 
-/*FCLInstruction::FCLInstruction(const FCLInstruction &source) {
-	type = source.type;
-	arguments.source = source.arguments.source;
-	arguments.destination = source.arguments.destination;
-	arguments.option = source.arguments.option;
-	conditional.thenInstructions = source.conditional.thenInstructions;
-	conditional.elseInstructions = source.conditional.elseInstructions;
-}*/
-
-/*
-	Very routine setters for now; this code does not currently enforce good behaviour.
-	TODO: allow mutation only once; delete supplied objects and raise an error if a
-	second attempt at mutation is made
-*/
 void FCLInstruction::setSource(int32 _source) {
 	source = _source;
 }
@@ -50,26 +38,142 @@ void FCLInstruction::setBranches(FCLInstructionVector *thenBranch, FCLInstructio
 	elseInstructions = elseBranch;
 }
 
-/*
-	Similarly routine getters...
-*/
-/*void FCLInstruction::getValue(CGameState &gameState, int32_t &source) {
-	source = arguments.source.getValue(gameState, source);
+Token::Type FCLInstruction::getType() {
+	return type;
 }
 
-void FCLInstruction::getValue(CGameState &gameState, int32_t &source, int32_t &destination) {
-	source = arguments.source.getValue(gameState, source);
-	destination = arguments.destination.getValue(gameState, destination);
+void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool collided) {
+	assert(!(shot && collided));
+	int ip = 0;
+	int codeSize = code.size();
+	while (ip <= codeSize - 1) {
+		FCLInstruction &instruction = code[ip];
+		debug("Executing ip: %d in code with size: %d", ip, codeSize);
+		switch (instruction.getType()) {
+			default:
+			break;
+			case Token::COLLIDEDQ:
+			if (collided)
+				executeCode(*instruction.thenInstructions, shot, collided);
+			// else branch is always empty
+			assert(instruction.elseInstructions == nullptr);
+			break;
+			case Token::SHOTQ:
+			if (shot)
+				executeCode(*instruction.thenInstructions, shot, collided);
+			// else branch is always empty
+			assert(instruction.elseInstructions == nullptr);
+			break;
+			case Token::VARNOTEQ:
+			if (executeEndIfNotEqual(instruction))
+				ip = codeSize;
+			break;
+			case Token::ADDVAR:
+			executeIncrementVariable(instruction);
+			break;
+			case Token::SUBVAR:
+			executeDecrementVariable(instruction);
+			break;
+			case Token::GOTO:
+			executeGoto(instruction);
+			break;
+			case Token::TOGVIS:
+			executeToggleVisibility(instruction);
+			break;
+			case Token::INVIS:
+			executeMakeInvisible(instruction);
+			break;
+			case Token::VIS:
+			executeMakeVisible(instruction);
+			break;
+			case Token::DESTROY:
+			executeDestroy(instruction);
+			break;
+			case Token::REDRAW:
+			executeRedraw(instruction);
+			break;
+			case Token::DELAY:
+			executeDelay(instruction);
+			break;
+		}
+		ip++;
+	}
+	return;
 }
 
-void FCLInstruction::getValue(CGameState &gameState, int32_t &source, int32_t &destination, int32_t &option) {
-	source = arguments.source.getValue(gameState, source);
-	destination = arguments.destination.getValue(gameState, destination);
-	option = arguments.option.getValue(gameState, option);
-}*/
 
-Token::Type FCLInstruction::getType() {
-	return type;
+void FreescapeEngine::executeRedraw(FCLInstruction &instruction) {
+	debug("Redrawing screen");
+	drawFrame();
+}
+
+void FreescapeEngine::executeDelay(FCLInstruction &instruction) {
+	uint16 delay = instruction.source;
+	debug("Delaying %d * 1/50 seconds", delay);
+	g_system->delayMillis(20 * delay);
+}
+
+bool FreescapeEngine::executeEndIfNotEqual(FCLInstruction &instruction) {
+	uint16 variable1 = instruction.source;
+	uint16 variable2 = instruction.destination;
+	debug("End condition if variable %d is not equal to variable %d!", variable1, variable2);
+	return (_gameState[variable1] != _gameState[variable2]);
+}
+
+void FreescapeEngine::executeIncrementVariable(FCLInstruction &instruction) {
+	uint16 variable = instruction.source;
+	uint16 increment = instruction.destination;
+	_gameState[variable] = _gameState[variable] + increment;
+	if (variable == k8bitVariableScore) {
+		debug("Score incremented by %d up to %d", increment, _gameState[variable]);
+	} else
+		debug("Variable %d by %d incremented up to %d!", variable, increment, _gameState[variable]);
+}
+
+void FreescapeEngine::executeDecrementVariable(FCLInstruction &instruction) {
+	uint16 variable = instruction.source;
+	uint16 decrement = instruction.destination;
+	_gameState[variable] = _gameState[variable] - decrement;
+	if (variable == k8bitVariableEnergy) {
+		debug("Energy decrement by %d up to %d", decrement, _gameState[variable]);
+	} else
+		debug("Variable %d by %d incremented up to %d!", variable, decrement, _gameState[variable]);
 }
 
+void FreescapeEngine::executeDestroy(FCLInstruction &instruction) {
+	uint16 objectID = instruction.source;
+	debug("Destroying obj %d!", objectID);
+	Object *obj = _currentArea->objectWithID(objectID);
+	assert(!obj->isDestroyed());
+	obj->destroy();
+}
+
+void FreescapeEngine::executeMakeInvisible(FCLInstruction &instruction) {
+	uint16 objectID = instruction.source;
+	debug("Making obj %d invisible!", objectID);
+	Object *obj = _currentArea->objectWithID(objectID);
+	obj->makeInvisible();
+}
+
+void FreescapeEngine::executeMakeVisible(FCLInstruction &instruction) {
+	uint16 objectID = instruction.source;
+	debug("Making obj %d visible!", objectID);
+	Object *obj = _currentArea->objectWithID(objectID);
+	obj->makeVisible();
+}
+
+void FreescapeEngine::executeToggleVisibility(FCLInstruction &instruction) {
+	uint16 objectID = instruction.source;
+	debug("Toggling obj %d visibility!", objectID);
+	Object *obj = _currentArea->objectWithID(objectID);
+	obj->toggleVisibility();
+}
+
+void FreescapeEngine::executeGoto(FCLInstruction &instruction) {
+	uint16 areaID = instruction.source;
+	uint16 entranceID = instruction.destination;
+	gotoArea(areaID, entranceID);
+}
+
+
 } // End of namespace Freescape
\ No newline at end of file


Commit: 5cd4f59dcbd213898e548a46621c5d2526b7da71
    https://github.com/scummvm/scummvm/commit/5cd4f59dcbd213898e548a46621c5d2526b7da71
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:50+01:00

Commit Message:
FREESCAPE: improved 8bit instruction parsing

Changed paths:
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index fd64c4c8175..768409784b1 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -10,7 +10,7 @@
 	This has been implemented based on John Elliott's 2001
 	reverse engineering of Driller; see http://www.seasip.demon.co.uk/ZX/Driller/
 */
-
+#include "common/debug.h"
 #include "8bitDetokeniser.h"
 #include "token.h"
 
@@ -29,12 +29,12 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 	FCLInstruction currentInstruction;
 
 	// this lookup table tells us how many argument bytes to read per opcode
-	uint8 argumentsRequiredByOpcode[32] =
+	uint8 argumentsRequiredByOpcode[33] =
 		{
 			0, 3, 1, 1, 1, 1, 2, 2,
 			2, 1, 1, 2, 1, 1, 2, 1,
 			1, 2, 2, 1, 2, 0, 0, 0,
-			0, 1, 0, 1, 1, 1, 1, 1};
+			1, 1, 0, 1, 1, 1, 1, 1, 2};
 
 	while (bytePointer < sizeOfTokenisedContent) {
 		// get the conditional type of the next operation
@@ -66,7 +66,7 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 		}
 
 		// get the actual operation
-		uint8 opcode = tokenisedCondition[bytePointer] & 0x1f;
+		uint16 opcode = tokenisedCondition[bytePointer] & 0x7f;
 		bytePointer++;
 
 		// figure out how many argument bytes we're going to need,
@@ -194,6 +194,14 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			numberOfArguments = 0;
 			break;
 
+		case 32: // end condition if an object is visible in another area
+			detokenisedStream += "IF RVIS? ";
+			detokenisedStream += Common::String::format("(%d), (%d)", (int)tokenisedCondition[bytePointer], (int)tokenisedCondition[bytePointer + 1]);
+			detokenisedStream += "THEN END ENDIF";
+			bytePointer += 2;
+			numberOfArguments = 0;
+			break;
+
 		case 12:
 			detokenisedStream += "SETBIT (";
 			break;
@@ -234,11 +242,10 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			detokenisedStream += "TOGBIT (";
 			break;
 
-		case 25: {
-			// this should toggle border colour; it's therefore a no-op
-			bytePointer++;
-			numberOfArguments = 0;
-		} break;
+		case 25:
+			// this should toggle border colour or the room palette
+			detokenisedStream += "SPFX (";
+		break;
 
 		case 20:
 			detokenisedStream += "SETVAR ";
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index cea2b175d76..a3aba008b47 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -322,7 +322,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 		FCLInstructionVector instructions;
 		// get the length
 		uint32 lengthOfCondition = file->readByte();
-		debug("length of condition: %d", lengthOfCondition);
+		debug("length of condition: %d at %lx", lengthOfCondition, file->pos());
 		// get the condition
 		byte *conditionData = (byte*)malloc(lengthOfCondition);
 		file->read(conditionData, lengthOfCondition);
@@ -331,7 +331,6 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 		Common::String *conditions = detokenise8bitCondition(conditionArray, instructions);
 		debug("%s", conditions->c_str());
 	}
-
 	file->seek(offset + 200);
 	debug("areas index at: %lx", file->pos());
 	uint16 *fileOffsetForArea = new uint16[numberOfAreas];


Commit: 91ba5e177ed6c85fc3de5459d2725c9604d918d2
    https://github.com/scummvm/scummvm/commit/91ba5e177ed6c85fc3de5459d2725c9604d918d2
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:50+01:00

Commit Message:
FREESCAPE: improved 8bit instruction parsing and line rendering

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/objects/geometricobject.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index fcad3074579..65c11a32219 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -111,10 +111,6 @@ void Area::draw(Freescape::Renderer *gfx) {
 			(*it)->draw(gfx);
 		}
 	}
-	/*for (Common::Array<Object *>::iterator it = drawableObjects.begin(); it != drawableObjects.end(); it++) {
-		if (!(*it)->isInvisible() && (*it)->isPlanar())
-			(*it)->draw(gfx);
-	}*/
 	if (groundColor != 255)
 		gfx->drawFloor(groundColor);
 }
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index cc0f3240766..adaa6ac3e6e 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -290,23 +290,41 @@ void TinyGLRenderer::renderPolygon(const Math::Vector3d &origin, const Math::Vec
 	Common::Array<Math::Vector3d> vertices;
 	tglEnable(TGL_POLYGON_OFFSET_FILL);
 	tglPolygonOffset(-2.0f, 1.f);
-	if ((*colours)[0] != _keyColor) {
+
+	if (ordinates->size() == 6) { // Line
 		_palette->getRGBAt((*colours)[0], r, g, b);
 		tglColor3ub(r, g, b);
-		for (int i = 0; i < ordinates->size(); i = i + 3) {
-			vertices.push_back(Math::Vector3d(origin.x() + (*ordinates)[i] + dx, origin.y() + (*ordinates)[i + 1] + dy,	origin.z() + (*ordinates)[i + 2] + dz));
-		}
+		for (int i = 0; i < ordinates->size(); i = i + 3)
+			vertices.push_back(Math::Vector3d((*ordinates)[i], (*ordinates)[i + 1],	(*ordinates)[i + 2]));
 		renderFace(vertices);
-	}
-	vertices.clear();
-	if ((*colours)[1] != _keyColor) {
+
+		vertices.clear();
 		_palette->getRGBAt((*colours)[1], r, g, b);
 		tglColor3ub(r, g, b);
-		for (int i = ordinates->size(); i > 0; i = i - 3) {
-			vertices.push_back(Math::Vector3d(origin.x() + (*ordinates)[i-3] - dx, origin.y() + (*ordinates)[i-2] - dy,	origin.z() + (*ordinates)[i-1] - dz));
-		}
+		for (int i = ordinates->size(); i > 0; i = i - 3)
+			vertices.push_back(Math::Vector3d((*ordinates)[i-3], (*ordinates)[i-2],	(*ordinates)[i-1]));
 		renderFace(vertices);
+
+	} else {
+		if ((*colours)[0] != _keyColor) {
+			_palette->getRGBAt((*colours)[0], r, g, b);
+			tglColor3ub(r, g, b);
+			for (int i = 0; i < ordinates->size(); i = i + 3) {
+				vertices.push_back(Math::Vector3d(origin.x() + (*ordinates)[i] + dx, origin.y() + (*ordinates)[i + 1] + dy,	origin.z() + (*ordinates)[i + 2] + dz));
+			}
+			renderFace(vertices);
+		}
+		vertices.clear();
+		if ((*colours)[1] != _keyColor) {
+			_palette->getRGBAt((*colours)[1], r, g, b);
+			tglColor3ub(r, g, b);
+			for (int i = ordinates->size(); i > 0; i = i - 3) {
+				vertices.push_back(Math::Vector3d(origin.x() + (*ordinates)[i-3] - dx, origin.y() + (*ordinates)[i-2] - dy,	origin.z() + (*ordinates)[i-1] - dz));
+			}
+			renderFace(vertices);
+		}
 	}
+
 	tglPolygonOffset(0, 0);
 	tglDisable(TGL_POLYGON_OFFSET_FILL);
 }
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index 768409784b1..42fdf9485f2 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -71,6 +71,11 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 
 		// figure out how many argument bytes we're going to need,
 		// check we have enough bytes left to read
+		if (opcode > 32) {
+			debug("ERROR: failed to read opcode: %x", opcode);
+			break;
+		}
+
 		uint8 numberOfArguments = argumentsRequiredByOpcode[opcode];
 		if (bytePointer + numberOfArguments > sizeOfTokenisedContent)
 			break;
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index a3aba008b47..3c56af929d4 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -180,7 +180,9 @@ Graphics::PixelBuffer *FreescapeEngine::getPalette(uint8 areaNumber, uint8 c1, u
 			palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&drillerEGA);
 		else if (_renderMode == "cga")
 			palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&drillerCGA);
-	}
+	} else
+		palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&drillerEGA);
+
 	return palette;
 }
 
@@ -245,7 +247,7 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	}
 	long int endLastObject = file->pos();
 	debug("Last position %lx", endLastObject);
-	assert(endLastObject <= base + cPtr);
+	assert(endLastObject == base + cPtr);
 	file->seek(base + cPtr);
 	uint8 numConditions = file->readByte();
 	debug("%d area conditions at %x of area %d", numConditions, base + cPtr, areaNumber);
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index 3a2d82d104e..a55d3ee0c57 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -254,6 +254,9 @@ void GeometricObject::draw(Freescape::Renderer *gfx) {
 	} else if (isPyramid(this->getType())) {
 		gfx->renderPyramid(origin, size, ordinates, colours, this->getType());
 	} else if (this->isPlanar() && _type <= 14) {
+		if (this->getType() == Triangle)
+			assert(ordinates->size() == 9);
+
 		//debug("Drawing %d of type %d", this->getObjectID(), this->getType());
 		gfx->renderPolygon(origin, size, ordinates, colours);
 	}


Commit: a6fcc20d45f2fda547800715079c5a2ba9530276
    https://github.com/scummvm/scummvm/commit/a6fcc20d45f2fda547800715079c5a2ba9530276
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:51+01:00

Commit Message:
FREESCAPE: mapped more castle master areas

Changed paths:
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 3c56af929d4..282b5d41744 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -124,9 +124,10 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 	case Object::Entrance: {
 		debug("rotation: %f %f %f", v.x(), v.y(), v.z());
 		if (byteSizeOfObject > 0) {
-			error("Extra bytes in entrance");
-			//file->seek(byteSizeOfObject, SEEK_CUR);
-			//return nullptr;
+			// TODO: there is something here
+			debug("Warning: extra %d bytes in entrance", byteSizeOfObject);
+			file->seek(byteSizeOfObject, SEEK_CUR);
+			byteSizeOfObject = 0;
 		}
 		assert(byteSizeOfObject == 0);
 		debug("End of object at %lx", file->pos());
@@ -262,7 +263,7 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 		Common::Array<uint8> conditionArray(conditionData, lengthOfCondition);
 		debug("%s", detokenise8bitCondition(conditionArray, instructions)->c_str());
 	}
-
+	debug("End of area at %lx", file->pos());
 	return (new Area(areaNumber, objectsByID, entrancesByID, scale, 255, 255, palette));
 }
 
@@ -344,18 +345,31 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	//fileOffsetForArea[0] = 0x9571 - offset;
 	//fileOffsetForArea[0] = 0xaba5 - offset - 8 - 16; // ???
 	//fileOffsetForArea[0] = 0x87c7 - offset - 8; // ???
-	//fileOffsetForArea[0] = 0x9304 - offset - 8 - 12 - 12 - 12; // ???
-	//fileOffsetForArea[0] = 0x92cc - offset; // Pool, 20
 	//fileOffsetForArea[0] = 0x9f40 - offset - 8;
 	//fileOffsetForArea[0] = 0x9f35 - offset; // Another Church, 12
 	//fileOffsetForArea[0] = 0xa06e - offset - 8; // Cornisa? 37
 
-	//fileOffsetForArea[0] = 0x959b - offset - 16; // Church? (22 elements)
-	//fileOffsetForArea[0] = 0x94b7 - offset; // For testing
-	//fileOffsetForArea[0] = 0x97cb - offset; // Courtyard
-	//fileOffsetForArea[0] = 0x92cc - offset ; // Pool?
+	// Complete Areas:
+	//fileOffsetForArea[0] = 0x87bf - offset; // Beds?
+	//fileOffsetForArea[0] = 0x8ccc - offset; // Wizard hut
+	//fileOffsetForArea[0] = 0x8dac - offset; // Horse
+	//fileOffsetForArea[0] = 0x8e78 - offset; // Corridor
+	//fileOffsetForArea[0] = 0x8f3a - offset; // chimney
+	//fileOffsetForArea[0] = 0x904e - offset; // master bed?
+	//fileOffsetForArea[0] = 0x90e1 - offset; // Dragon?
+	//fileOffsetForArea[0] = 0x9238 - offset; // ????
+	//fileOffsetForArea[0] = 0x92a7 - offset; // Pool
+	//fileOffsetForArea[0] = 0x93e3 - offset; // Doors
+	//fileOffsetForArea[0] = 0x94e5 - offset; // More doors
+	//fileOffsetForArea[0] = 0x9580 - offset; // Church? !!!
+	//fileOffsetForArea[0] = 0x96c8 - offset; // Another area !!!
+	//fileOffsetForArea[0] = 0x974a - offset; // Another area !!!
+	//fileOffsetForArea[0] = 0x97cb - offset; // Courtyard !!!
+	//fileOffsetForArea[0] = 0x9a5c - offset; // Stable !!!
+	//fileOffsetForArea[0] = 0x9b4b - offset; // Another area !!!
+
+
 	//fileOffsetForArea[0] = 0x8e0a - offset - 8; // Pool?
-	//fileOffsetForArea[0] = 0x92d8 - offset; // ??
 
 	// grab the areas
 	AreaMap *areaMap = new AreaMap;


Commit: 6cb783daa089981cbfae5a16b2c500af7e6132fa
    https://github.com/scummvm/scummvm/commit/6cb783daa089981cbfae5a16b2c500af7e6132fa
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:51+01:00

Commit Message:
FREESCAPE: improved player collisions and added basic detection of darkside

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/detection.cpp
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 65c11a32219..84c1f97706f 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -130,14 +130,19 @@ Object *Area::shootRay(const Math::Ray &ray) {
 }
 
 Object *Area::checkCollisions(const Math::AABB &boundingBox) {
+	float size = 16 * 8192; // TODO: check if this is max size
+	Object *collided = nullptr;
 	for (int i = drawableObjects.size() - 1; i >= 0; i--) {
 		if (drawableObjects[i]->isDrawable() && !drawableObjects[i]->isDestroyed() && !drawableObjects[i]->isInvisible()) {
 			GeometricObject *obj = (GeometricObject*) drawableObjects[i];
-			if (obj->collides(boundingBox))
-				return drawableObjects[i];
+			float objSize = obj->getSize().length();
+			if (obj->collides(boundingBox) && size > objSize) {
+				collided = obj;
+				size = objSize;
+			}
 		}
 	}
-	return nullptr;
+	return collided;
 }
 
 } // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index a86a69f4d76..a049f90c55a 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -6,6 +6,7 @@ static const PlainGameDescriptor freescapeGames[] = {
 	{"3dkit", "The 3D Kit Game"},
 	{"driller", "Driller"},
 	{"spacestationoblivion", "Space Station Oblivion"},
+	{"darkside", "Dark Side"},
 	{"totaleclipse", "Total Eclipse"},
 	{"castlemaster", "Castle Master"},
 	{"menace", "Menace of Dr. Spoil Sport"},
@@ -76,6 +77,19 @@ static const ADGameDescription gameDescriptions[] = {
 	 Common::kPlatformDOS,
 	 ADGF_NO_FLAGS,
 	 GUIO3(GUIO_NOMIDI, GUIO_RENDEREGA, GUIO_RENDERCGA)},
+	{"darkside",
+	 "Dark Side",
+	 {
+		{"DARKSIDE.EXE", 0, "c6c0d0186ec45e6cecd72bf5550c7f98", 1600},
+		{"DSIDEC.EXE", 0, "31e6c169d9270b6de8c1c2e746ac238e", 49504},
+		{"DSIDEH.EXE", 0, "5e18e0746647bd04f43b9db24b6a036d", 53232},
+		{"DSIDEE.EXE", 0, "524281f7d2dc49e0a41fcb1d38ee2559", 56800},
+		AD_LISTEND
+	 },
+	 Common::EN_ANY,
+	 Common::kPlatformDOS,
+	 ADGF_NO_FLAGS,
+	 GUIO3(GUIO_NOMIDI, GUIO_RENDEREGA, GUIO_RENDERCGA)},
 	{"totaleclipse",
 	 "Total Eclipse",
 	 {
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index fd667c1b6cc..1d60b897d66 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -46,7 +46,7 @@ FreescapeEngine::FreescapeEngine(OSystem *syst)
 	_velocity = Math::Vector3d(0.f, 0.f, 0.f);
 	_cameraFront = Math::Vector3d(0.f, 0.f, 0.f);
 	_cameraRight = Math::Vector3d(0.f, 0.f, 0.f);
-	_movementSpeed = 4.5f;
+	_movementSpeed = 2.5f;
 	_mouseSensitivity = 0.1f;
 	_borderTexture = nullptr;
 
@@ -119,6 +119,25 @@ void FreescapeEngine::loadAssets() {
 		} else
 			error("Invalid render mode %s for Driller", _renderMode.c_str());
 
+	} else if (_targetName.hasPrefix("darkside")) {
+		Common::File exe;
+		bool success = false;
+		if (_renderMode == "ega") {
+			file = gameDir.createReadStreamForMember("DSIDEE.EXE");
+
+			if (file == nullptr)
+				error("Failed to open DSIDEE.EXE");
+
+			load8bitBinary(file, 0x9b40, 16);
+		} else if (_renderMode == "cga") {
+			file = gameDir.createReadStreamForMember("DSIDEC.EXE");
+
+			if (file == nullptr)
+				error("Failed to open DSIDE.EXE");
+			load8bitBinary(file, 0x7bb0, 4);
+		} else
+			error("Invalid render mode %s for Driller", _renderMode.c_str());
+
 	} else if (_targetName == "totaleclipse") {
 		Common::File exe;
 		bool success = false;
@@ -128,7 +147,7 @@ void FreescapeEngine::loadAssets() {
 			if (file == nullptr)
 				error("Failed to open TOTEE.EXE");
 
-			load8bitBinary(file, 0xcdb7, 16);
+			load8bitBinary(file, 0x9b40, 16);
 		} else if (_renderMode == "cga") {
 			file = gameDir.createReadStreamForMember("TOTEC.EXE");
 
@@ -380,6 +399,7 @@ void FreescapeEngine::gotoArea(uint16 areaID, uint16 entranceID) {
 	debug("go to area: %d, entrance: %d", areaID, entranceID);
 
 	assert(_areasByAreaID->contains(areaID));
+	assert(entranceID > 0);
 	_currentArea = (*_areasByAreaID)[areaID];
 	_currentArea->show();
 


Commit: 2b35817292b45141e2173478879bf867dabdf266
    https://github.com/scummvm/scummvm/commit/2b35817292b45141e2173478879bf867dabdf266
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:51+01:00

Commit Message:
FREESCAPE: implemented bit instructions

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/language/instruction.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 1d60b897d66..b05d235dff6 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -312,9 +312,10 @@ Common::Error FreescapeEngine::run() {
 }
 
 void FreescapeEngine::initGameState() {
-	/*for (int16 i = 0; i < 256; i++) {
-		_gameState[i] = 0;
-	}*/
+	_areaBits.resize(33);
+	for (int16 i = 0; i <= 32; i++) {
+		_areaBits[i] = false;
+	}
 
 	_gameState[k8bitVariableEnergy] = 100;
 	_gameState[k8bitVariableShield] = 100;
@@ -418,6 +419,10 @@ void FreescapeEngine::gotoArea(uint16 areaID, uint16 entranceID) {
 
 	_pitch = _rotation.x() - 180.f;
 	_yaw = _rotation.y() - 180.f;
+
+	for (int16 i = 0; i <= 32; i++) {
+		_areaBits[i] = false;
+	}
 }
 
 bool FreescapeEngine::hasFeature(EngineFeature f) const {
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 31791addfcf..d37d61b86fb 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -131,6 +131,10 @@ public:
 	void executeRedraw(FCLInstruction &instruction);
 	void executeDelay(FCLInstruction &instruction);
 	bool executeEndIfNotEqual(FCLInstruction &instruction);
+	void executeSetBit(FCLInstruction &instruction);
+	void executeClearBit(FCLInstruction &instruction);
+	void executeToggleBit(FCLInstruction &instruction);
+	bool executeEndIfBitNotEqual(FCLInstruction &instruction);
 
 
 	// Rendering
@@ -145,6 +149,7 @@ public:
 	// Game state
 	void initGameState();
 	Common::HashMap<uint16, int32> _gameState;
+	Common::Array<bool> _areaBits;
 
 	bool hasFeature(EngineFeature f) const override;
 	bool canLoadGameStateCurrently() override { return true; }
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index 42fdf9485f2..6f6efc28d43 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -181,6 +181,11 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			detokenisedStream += "IF BIT!=? ";
 			detokenisedStream += Common::String::format("(%d, %d)", (int)tokenisedCondition[bytePointer], (int)tokenisedCondition[bytePointer + 1]);
 			detokenisedStream += "THEN END ENDIF";
+			currentInstruction = FCLInstruction(Token::BITNOTEQ);
+			currentInstruction.setSource(tokenisedCondition[bytePointer]);
+			currentInstruction.setDestination(tokenisedCondition[bytePointer + 1]);
+			conditionalInstructions->push_back(currentInstruction);
+			currentInstruction = FCLInstruction(Token::UNKNOWN);
 			bytePointer += 2;
 			numberOfArguments = 0;
 			break;
@@ -209,9 +214,11 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 
 		case 12:
 			detokenisedStream += "SETBIT (";
+			currentInstruction = FCLInstruction(Token::SETBIT);
 			break;
 		case 13:
 			detokenisedStream += "CLRBIT (";
+			currentInstruction = FCLInstruction(Token::CLEARBIT);
 			break;
 
 		case 15:
@@ -244,7 +251,8 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			detokenisedStream += "SYNCSND (";
 			break;
 		case 29:
-			detokenisedStream += "TOGBIT (";
+			detokenisedStream += "TOGGLEBIT (";
+			currentInstruction = FCLInstruction(Token::TOGGLEBIT);
 			break;
 
 		case 25:
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index 0de7b3b0b3c..9242034cacf 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -95,6 +95,16 @@ void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool co
 			case Token::DELAY:
 			executeDelay(instruction);
 			break;
+			case Token::SETBIT:
+			executeSetBit(instruction);
+			break;
+			case Token::CLEARBIT:
+			executeClearBit(instruction);
+			break;
+			case Token::BITNOTEQ:
+			if (executeEndIfBitNotEqual(instruction))
+				ip = codeSize;
+			break;
 		}
 		ip++;
 	}
@@ -175,5 +185,29 @@ void FreescapeEngine::executeGoto(FCLInstruction &instruction) {
 	gotoArea(areaID, entranceID);
 }
 
+void FreescapeEngine::executeSetBit(FCLInstruction &instruction) {
+	uint16 index = instruction.source;
+	_areaBits[index] = true;
+	debug("Setting bit %d", index);
+}
+
+void FreescapeEngine::executeClearBit(FCLInstruction &instruction) {
+	uint16 index = instruction.source;
+	_areaBits[index] = false;
+	debug("Clearing bit %d", index);
+}
+
+void FreescapeEngine::executeToggleBit(FCLInstruction &instruction) {
+	uint16 index = instruction.source;
+	_areaBits[index] = ~_areaBits[index];
+	debug("Toggling bit %d", index);
+}
+
+bool FreescapeEngine::executeEndIfBitNotEqual(FCLInstruction &instruction) {
+	uint16 index = instruction.source;
+	uint16 value = instruction.destination;
+	debug("End condition if bit %d is not equal to %d!", index, value);
+	return (_areaBits[index] != value);
+}
 
 } // End of namespace Freescape
\ No newline at end of file


Commit: 6840ce7ba27fa4838c27fa94067f4666079781a3
    https://github.com/scummvm/scummvm/commit/6840ce7ba27fa4838c27fa94067f4666079781a3
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:51+01:00

Commit Message:
FREESCAPE: basic implementation of step up/down

Changed paths:
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index b05d235dff6..169a71a6224 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -367,19 +367,38 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 		_position = _position + _cameraRight * velocity;
 		break;
 	}
-	// Make sure the user stays at the ground level
-	// this one-liner keeps the user at the ground level (xz plane)
-	_position.set(_position.x(), positionY, _position.z());
+	// Is threre some floor under the player?
+	_position.set(_position.x(), positionY - 16, _position.z());
 	bool collided = checkCollisions();
-	if (collided && previousAreaID == _currentArea->getAreaID())
-		_position = previousPosition;
-	debug("player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
+
+	if (!collided) {  // Player is falling, let's try to step down
+		_position.set(_position.x(), positionY - 16 - 64, _position.z());
+		collided = checkCollisions();
+		assert(collided);
+
+		// restore position
+		_position.set(_position.x(), positionY - 64, _position.z());
+	} else {
+		// restore position
+		_position.set(_position.x(), positionY, _position.z());
+
+		collided = checkCollisions();
+		if (collided && previousAreaID == _currentArea->getAreaID()) {
+			// We found a collisions, let's try to step up
+			_position.set(_position.x(), positionY + 64, _position.z());
+			collided = checkCollisions();
+			if (collided)
+				_position = previousPosition;
+		}
+	}
+
+	debug("new player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
 }
 
 bool FreescapeEngine::checkCollisions() {
 
-	Math::Vector3d v1(_position.x() - _playerWidth / 2, _playerHeight / 2                , _position.z() - _playerDepth / 2);
-	Math::Vector3d v2(_position.x() + _playerWidth / 2, _position.y() + _playerHeight / 2, _position.z() + _playerDepth / 2);
+	Math::Vector3d v1(_position.x() - _playerWidth / 2, _position.y() - _playerHeight     , _position.z() - _playerDepth / 2);
+	Math::Vector3d v2(_position.x() + _playerWidth / 2, _position.y(), _position.z() + _playerDepth / 2);
 
 	const Math::AABB boundingBox(v1, v2);
 	Object *obj = _currentArea->checkCollisions(boundingBox);


Commit: da75afe5444a87e02e8c5fa5232219c0e321ae1f
    https://github.com/scummvm/scummvm/commit/da75afe5444a87e02e8c5fa5232219c0e321ae1f
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:51+01:00

Commit Message:
FREESCAPE: initial parsing of Total Eclipse

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/freescape.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 84c1f97706f..682ce1daad8 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -77,6 +77,23 @@ Area::Area(
 	} compareObjects;
 
 	Common::sort(drawableObjects.begin(), drawableObjects.end(), compareObjects);
+	/*FCLInstructionVector empty;
+
+	Common::Array<uint8> *floorColors = new Common::Array<uint8>;
+	for (int i = 0; i < 6; i++)
+		floorColors->push_back(0);
+
+	GeometricObject *floor = new GeometricObject(
+		(Object::Type) 1,
+		200,
+		0, // flags
+		Math::Vector3d(0, -1, 0), // Position
+		Math::Vector3d(8128, 1, 8128), // size
+		floorColors,
+		nullptr,
+		empty
+	);
+	drawableObjects.push_back(floor);*/
 }
 
 Area::~Area() {
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 169a71a6224..bf124c732a0 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -147,7 +147,7 @@ void FreescapeEngine::loadAssets() {
 			if (file == nullptr)
 				error("Failed to open TOTEE.EXE");
 
-			load8bitBinary(file, 0x9b40, 16);
+			load8bitBinary(file, 0x3ce0, 16);
 		} else if (_renderMode == "cga") {
 			file = gameDir.createReadStreamForMember("TOTEC.EXE");
 
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 282b5d41744..c382073d514 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -173,6 +173,25 @@ byte drillerCGA[4][3] = {
 	{0x00, 0xa8, 0xa8},
 };
 
+byte eclipseEGA[16][3] = {
+	{0xfc, 0xfc, 0x54},
+	{0x54, 0xfc, 0xfc},
+	{0x00, 0xaa, 0xaa},
+	{0xaa, 0x00, 0xaa},
+	{0xff, 0xff, 0xff},
+	{0x00, 0x00, 0xA8},
+	{0x00, 0x00, 0xaa},
+	{0xaa, 0x55, 0x00},
+	{0x12, 0xf3, 0x56},
+	{0xaa, 0x00, 0x00},
+	{0xff, 0x55, 0xff},
+	{0xa8, 0x54, 0x00},
+	{0x12, 0xf3, 0x56},
+	{0x54, 0x54, 0x54},
+	{0x54, 0x54, 0x54},
+	{0x12, 0xf3, 0x56}
+};
+
 Graphics::PixelBuffer *FreescapeEngine::getPalette(uint8 areaNumber, uint8 c1, uint8 c2, uint8 c3, uint8 c4, uint16 ncolors) {
 	Graphics::PixelFormat pixelFormat = Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, ncolors, 0);
 	Graphics::PixelBuffer *palette = nullptr;
@@ -181,6 +200,8 @@ Graphics::PixelBuffer *FreescapeEngine::getPalette(uint8 areaNumber, uint8 c1, u
 			palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&drillerEGA);
 		else if (_renderMode == "cga")
 			palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&drillerCGA);
+	} else if (_targetName.hasPrefix("totaleclipse")) {
+		palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&eclipseEGA);
 	} else
 		palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&drillerEGA);
 
@@ -222,7 +243,9 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	//debug("Condition Ptr: %x", cPtr);
 	debug("Pos before first object: %lx", file->pos());
 
-	if (_targetName != "castlemaster")
+	if (_targetName == "totaleclipse")
+		file->seek(5, SEEK_CUR);
+	else if (_targetName != "castlemaster")
 		file->seek(15, SEEK_CUR);
 
 	ObjectMap *objectsByID = new ObjectMap;


Commit: fc07a47c61cb94ee50c44b4518414f210771cdfe
    https://github.com/scummvm/scummvm/commit/fc07a47c61cb94ee50c44b4518414f210771cdfe
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:51+01:00

Commit Message:
FREESCAPE: initial parsing of Dark Side and some rendering fixes for eclipse

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/freescape.cpp
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 682ce1daad8..84c1f97706f 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -77,23 +77,6 @@ Area::Area(
 	} compareObjects;
 
 	Common::sort(drawableObjects.begin(), drawableObjects.end(), compareObjects);
-	/*FCLInstructionVector empty;
-
-	Common::Array<uint8> *floorColors = new Common::Array<uint8>;
-	for (int i = 0; i < 6; i++)
-		floorColors->push_back(0);
-
-	GeometricObject *floor = new GeometricObject(
-		(Object::Type) 1,
-		200,
-		0, // flags
-		Math::Vector3d(0, -1, 0), // Position
-		Math::Vector3d(8128, 1, 8128), // size
-		floorColors,
-		nullptr,
-		empty
-	);
-	drawableObjects.push_back(floor);*/
 }
 
 Area::~Area() {
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index bf124c732a0..60e94ddb765 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -128,7 +128,7 @@ void FreescapeEngine::loadAssets() {
 			if (file == nullptr)
 				error("Failed to open DSIDEE.EXE");
 
-			load8bitBinary(file, 0x9b40, 16);
+			load8bitBinary(file, 0xa280, 16);
 		} else if (_renderMode == "cga") {
 			file = gameDir.createReadStreamForMember("DSIDEC.EXE");
 
@@ -371,7 +371,7 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 	_position.set(_position.x(), positionY - 16, _position.z());
 	bool collided = checkCollisions();
 
-	if (!collided) {  // Player is falling, let's try to step down
+	if (!collided && _targetName == "driller") {  // Player is falling, let's try to step down
 		_position.set(_position.x(), positionY - 16 - 64, _position.z());
 		collided = checkCollisions();
 		assert(collided);
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index adaa6ac3e6e..1cd702f8d0e 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -378,26 +378,6 @@ void TinyGLRenderer::renderRectangle(const Math::Vector3d &origin, const Math::V
 			vertices.push_back(Math::Vector3d(origin.x() + dx,	origin.y() + dy, origin.z() + dz));
 			vertices.push_back(Math::Vector3d(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z()));
 			renderFace(vertices);
-
-			// tglBegin(TGL_TRIANGLES);
-			// tglVertex3f(origin.x(),	origin.y(),	origin.z());
-			// if (size.x() == 0)
-			// 	tglVertex3f(origin.x(),	origin.y() + size.y(), origin.z());
-			// else if (size.y() == 0)
-			// 	tglVertex3f(origin.x() + size.x(),	origin.y(), origin.z());
-			// else
-			// 	tglVertex3f(origin.x() + size.x(),	origin.y(), origin.z());
-			// tglVertex3f(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z());
-
-			// tglVertex3f(origin.x(),	origin.y(),	origin.z());
-			// if (size.x() == 0)
-			// 	tglVertex3f(origin.x(),	origin.y(), origin.z()  + size.z());
-			// else if (size.y() == 0)
-			// 	tglVertex3f(origin.x() + size.x(),	origin.y(), origin.z() + size.y());
-			// else
-			// 	tglVertex3f(origin.x(),	origin.y() + size.y(), origin.z());
-			// tglVertex3f(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z());
-			// tglEnd();
 		}
 	}
 
@@ -485,7 +465,7 @@ void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vec
 
 	Common::Array<Math::Vector3d> face;
 	uint8 r, g, b;
-	_palette->getRGBAt((*colours)[1], r, g, b);
+	_palette->getRGBAt((*colours)[0], r, g, b);
 	tglColor3ub(r, g, b);
 
 	face.push_back(vertices[5]);
@@ -495,7 +475,7 @@ void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vec
 	renderFace(face);
 	face.clear();
 
-	_palette->getRGBAt((*colours)[0], r, g, b);
+	_palette->getRGBAt((*colours)[1], r, g, b);
 	tglColor3ub(r, g, b);
 
 	face.push_back(vertices[7]);
@@ -505,7 +485,7 @@ void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vec
 	renderFace(face);
 	face.clear();
 
-	_palette->getRGBAt((*colours)[3], r, g, b);
+	_palette->getRGBAt((*colours)[2], r, g, b);
 	tglColor3ub(r, g, b);
 
 	face.push_back(vertices[4]);
@@ -515,7 +495,7 @@ void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vec
 	renderFace(face);
 	face.clear();
 
-	_palette->getRGBAt((*colours)[2], r, g, b);
+	_palette->getRGBAt((*colours)[3], r, g, b);
 	tglColor3ub(r, g, b);
 
 	face.push_back(vertices[6]);
@@ -525,7 +505,7 @@ void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vec
 	renderFace(face);
 	face.clear();
 
-	_palette->getRGBAt((*colours)[5], r, g, b);
+	_palette->getRGBAt((*colours)[4], r, g, b);
 	tglColor3ub(r, g, b);
 
 	face.push_back(vertices[0]);
@@ -535,7 +515,7 @@ void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vec
 	renderFace(face);
 	face.clear();
 
-	_palette->getRGBAt((*colours)[4], r, g, b);
+	_palette->getRGBAt((*colours)[5], r, g, b);
 	tglColor3ub(r, g, b);
 
 	face.push_back(vertices[7]);
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index c382073d514..4066c791384 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -175,20 +175,20 @@ byte drillerCGA[4][3] = {
 
 byte eclipseEGA[16][3] = {
 	{0xfc, 0xfc, 0x54},
+	{0x00, 0x00, 0x00},
 	{0x54, 0xfc, 0xfc},
-	{0x00, 0xaa, 0xaa},
 	{0xaa, 0x00, 0xaa},
-	{0xff, 0xff, 0xff},
+	{0x54, 0xfc, 0xfc},
 	{0x00, 0x00, 0xA8},
 	{0x00, 0x00, 0xaa},
 	{0xaa, 0x55, 0x00},
 	{0x12, 0xf3, 0x56},
 	{0xaa, 0x00, 0x00},
 	{0xff, 0x55, 0xff},
-	{0xa8, 0x54, 0x00},
+	{0xa8, 0x00, 0x00},
 	{0x12, 0xf3, 0x56},
 	{0x54, 0x54, 0x54},
-	{0x54, 0x54, 0x54},
+	{0xa8, 0x54, 0x00},
 	{0x12, 0xf3, 0x56}
 };
 
@@ -223,29 +223,31 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 
 	uint8 ci1 = 0;
 	uint8 ci2 = 0;
-	uint8 ci3 = 0;
-	uint8 ci4 = 0;
+	uint8 skyColor = 255;
+	uint8 groundColor = 255;
 	if (_targetName != "castlemaster") {
 		ci1 = file->readByte() & 15;
 		ci2 = file->readByte() & 15;
-		ci3 = file->readByte() & 15;
-		ci4 = file->readByte() & 15;
-		debug("Colors: %d %d %d %d", ci1, ci2, ci3, ci4);
+		skyColor = file->readByte() & 15;
+		groundColor = file->readByte() & 15;
+		skyColor = 2;
+		groundColor = 0;
+		debug("Colors: %d %d %d %d", ci1, ci2, skyColor, groundColor);
 	} else {
-		ci3 = file->readByte();
-		ci4 = file->readByte();
-		debug("Colors: %d %d", ci3, ci4);
+		skyColor = file->readByte();
+		groundColor = file->readByte();
+		debug("Colors: %d %d", skyColor, groundColor);
 	}
-	Graphics::PixelBuffer *palette = getPalette(areaNumber, ci1, ci2, ci3, ci4, ncolors);
+	Graphics::PixelBuffer *palette = getPalette(areaNumber, ci1, ci2, skyColor, groundColor, ncolors);
 
 	debug("Area %d", areaNumber);
 	debug("Skipped: %d Objects: %d", skippedValue, numberOfObjects);
 	//debug("Condition Ptr: %x", cPtr);
 	debug("Pos before first object: %lx", file->pos());
 
-	if (_targetName == "totaleclipse")
+	if (_targetName == "totaleclipse") {
 		file->seek(5, SEEK_CUR);
-	else if (_targetName != "castlemaster")
+	} else if (_targetName != "castlemaster")
 		file->seek(15, SEEK_CUR);
 
 	ObjectMap *objectsByID = new ObjectMap;
@@ -287,23 +289,9 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 		debug("%s", detokenise8bitCondition(conditionArray, instructions)->c_str());
 	}
 	debug("End of area at %lx", file->pos());
-	return (new Area(areaNumber, objectsByID, entrancesByID, scale, 255, 255, palette));
+	return (new Area(areaNumber, objectsByID, entrancesByID, scale, skyColor, groundColor, palette));
 }
 
-// struct BinaryTable {
-// 	const char *filename;
-// 	int ncolors;
-// 	int offset;
-// };
-
-// static const BinaryTable binaryTable[] = {
-// 	{ "DRILLE.EXE",  16,  0x9b40},
-// 	{ "DRILLC.EXE",  4,  0x7bb0},
-// 	{ "TOTE.EXE",    16,  0xcdb7},
-//  { "TOTC.EXE",    16,  ??????},
-// 	{ nullptr,       0,  0  }
-// };
-
 void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offset, int ncolors) {
 	Image::BitmapDecoder decoder;
 	Common::File borderFile;


Commit: a76317afb4e87bb040948610ce72eb265b9c1b32
    https://github.com/scummvm/scummvm/commit/a76317afb4e87bb040948610ce72eb265b9c1b32
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:52+01:00

Commit Message:
FREESCAPE: added more Castle Master releases and some fixes

Changed paths:
    engines/freescape/detection.cpp
    engines/freescape/freescape.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index a049f90c55a..8df2eae9b70 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -131,6 +131,34 @@ static const ADGameDescription gameDescriptions[] = {
 	 Common::kPlatformDOS,
 	 ADGF_NO_FLAGS,
 	 GUIO1(GUIO_NOMIDI)},
+	{"castlemaster",
+	 "Castle Master/VirtualWords",
+	 {
+		{"CASTLE.EXE", 0, "f1a141df0e47860246716db20d2ba061", 2806},
+		{"CMC.EXE", 0, "7b9275df446f82fdd0c377f6ec2db546", 57168},
+		{"CMT.EXE", 0, "5814e68a175f74ebce0773a73e7488c7", 78768},
+		{"CME.EXE", 0, "d563ae1475752e6a9a81b1350abebef3", 89248},
+		{"CMH.EXE", 0, "26337adc7861300e5395e992e42b6329", 59968},
+		AD_LISTEND
+	 },
+	 Common::EN_ANY,
+	 Common::kPlatformDOS,
+	 ADGF_NO_FLAGS,
+	 GUIO1(GUIO_NOMIDI)},
+	{"castlemaster",
+	 "Castle Master",
+	 {
+		{"CASTLE.EXE", 0, "42a7d46b418d68e75e31c1cb9d89af14", 2678},
+		{"CMC.EXE", 0, "9015c244dc8a97fe55df7b235b31e00c", 57168},
+		{"CMT.EXE", 0, "5814e68a175f74ebce0773a73e7488c7", 78768},
+		{"CME.EXE", 0, "d563ae1475752e6a9a81b1350abebef3", 89248},
+		{"CMH.EXE", 0, "cc68c42d254b3aa0f208cd08731c6805", 59968},
+		AD_LISTEND
+	 },
+	 Common::ES_ESP,
+	 Common::kPlatformDOS,
+	 ADGF_NO_FLAGS,
+	 GUIO1(GUIO_NOMIDI)},
 	AD_TABLE_END_MARKER};
 } // End of namespace Freescape
 
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 60e94ddb765..0781d10a207 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -156,7 +156,7 @@ void FreescapeEngine::loadAssets() {
 			load8bitBinary(file, 0x7bb0, 4); // TODO
 		} else
 			error("Invalid render mode %s for Total Eclipse", _renderMode.c_str());
-	   } else if (_targetName == "castlemaster") {
+	   } else if (_targetName.hasPrefix("castlemaster")) {
 			file = gameDir.createReadStreamForMember("castle.sna");
 
 			if (file == nullptr)
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 4066c791384..f8281184c4d 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -230,12 +230,10 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 		ci2 = file->readByte() & 15;
 		skyColor = file->readByte() & 15;
 		groundColor = file->readByte() & 15;
-		skyColor = 2;
-		groundColor = 0;
 		debug("Colors: %d %d %d %d", ci1, ci2, skyColor, groundColor);
 	} else {
-		skyColor = file->readByte();
-		groundColor = file->readByte();
+		skyColor = file->readByte() & 15;
+		groundColor = file->readByte() & 15;
 		debug("Colors: %d %d", skyColor, groundColor);
 	}
 	Graphics::PixelBuffer *palette = getPalette(areaNumber, ci1, ci2, skyColor, groundColor, ncolors);
@@ -353,9 +351,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 		debug("offset: %x", fileOffsetForArea[area]);
 	}
 	//fileOffsetForArea[0] = 0x9e75 - offset - 8 - 12; // Table?
-	//fileOffsetForArea[0] = 0x9571 - offset;
 	//fileOffsetForArea[0] = 0xaba5 - offset - 8 - 16; // ???
-	//fileOffsetForArea[0] = 0x87c7 - offset - 8; // ???
 	//fileOffsetForArea[0] = 0x9f40 - offset - 8;
 	//fileOffsetForArea[0] = 0x9f35 - offset; // Another Church, 12
 	//fileOffsetForArea[0] = 0xa06e - offset - 8; // Cornisa? 37
@@ -379,8 +375,25 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	//fileOffsetForArea[0] = 0x9a5c - offset; // Stable !!!
 	//fileOffsetForArea[0] = 0x9b4b - offset; // Another area !!!
 
-
-	//fileOffsetForArea[0] = 0x8e0a - offset - 8; // Pool?
+	/*fileOffsetForArea[0] = 0x9d1a - offset; // Soccer field
+	fileOffsetForArea[0] = 0x9e43 - offset; // Workshop?
+	fileOffsetForArea[0] = 0x9f22 - offset; // Church
+	fileOffsetForArea[0] = 0x9fcd - offset; // ???
+
+	fileOffsetForArea[0] = 0xa03c - offset; // Tower
+	fileOffsetForArea[0] = 0xa25e - offset; // Room?
+
+	fileOffsetForArea[0] = 0xa30f - offset; // ???
+	fileOffsetForArea[0] = 0xa394 - offset; // ???
+	fileOffsetForArea[0] = 0xa3f8 - offset;
+	fileOffsetForArea[0] = 0xa48c - offset;
+	fileOffsetForArea[0] = 0xa4fa - offset;
+	fileOffsetForArea[0] = 0xa593 - offset;
+	fileOffsetForArea[0] = 0xa5ef - offset;
+	fileOffsetForArea[0] = 0xa64a - offset;
+	fileOffsetForArea[0] = 0xa695 - offset;
+	fileOffsetForArea[0] = 0xa71d - offset;*/
+	//fileOffsetForArea[0] = 0xa77e - offset; <- fails
 
 	// grab the areas
 	AreaMap *areaMap = new AreaMap;


Commit: 26d1918b73482bec547a51166e11b115aa5413d7
    https://github.com/scummvm/scummvm/commit/26d1918b73482bec547a51166e11b115aa5413d7
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:52+01:00

Commit Message:
FREESCAPE: load all the Castle Master data from amstrad

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 0781d10a207..f68376bc087 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -161,10 +161,7 @@ void FreescapeEngine::loadAssets() {
 
 			if (file == nullptr)
 				error("Failed to open castle.sna");
-			// Courtyard -> 0x93c1 -> 0x8cbc,3
-			// Beds -> 0x867d
-			// All? -> 0x845d or 0x80ed?
-			load8bitBinary(file, 0x8465, 16);
+			load8bitBinary(file, 0x84da, 16);
 	   } else
 		error("'%s' is an invalid game", _targetName.c_str());
 
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index f8281184c4d..432f2710a3f 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -303,8 +303,6 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 
 	file->seek(offset);
 	uint8 numberOfAreas = file->readByte();
-	if (numberOfAreas < 2) // TODO: just for testing
-		numberOfAreas = 20;
 	uint16 dbSize = file->readUint16LE();
 	debug("Database ends at %x", dbSize);
 
@@ -343,57 +341,18 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 		Common::String *conditions = detokenise8bitCondition(conditionArray, instructions);
 		debug("%s", conditions->c_str());
 	}
-	file->seek(offset + 200);
+
+	if (_targetName != "castlemaster")
+		file->seek(offset + 0xc8);
+	else
+		file->seek(offset + 0x4f);
+
 	debug("areas index at: %lx", file->pos());
 	uint16 *fileOffsetForArea = new uint16[numberOfAreas];
 	for (uint16 area = 0; area < numberOfAreas; area++) {
 		fileOffsetForArea[area] = file->readUint16LE();
 		debug("offset: %x", fileOffsetForArea[area]);
 	}
-	//fileOffsetForArea[0] = 0x9e75 - offset - 8 - 12; // Table?
-	//fileOffsetForArea[0] = 0xaba5 - offset - 8 - 16; // ???
-	//fileOffsetForArea[0] = 0x9f40 - offset - 8;
-	//fileOffsetForArea[0] = 0x9f35 - offset; // Another Church, 12
-	//fileOffsetForArea[0] = 0xa06e - offset - 8; // Cornisa? 37
-
-	// Complete Areas:
-	//fileOffsetForArea[0] = 0x87bf - offset; // Beds?
-	//fileOffsetForArea[0] = 0x8ccc - offset; // Wizard hut
-	//fileOffsetForArea[0] = 0x8dac - offset; // Horse
-	//fileOffsetForArea[0] = 0x8e78 - offset; // Corridor
-	//fileOffsetForArea[0] = 0x8f3a - offset; // chimney
-	//fileOffsetForArea[0] = 0x904e - offset; // master bed?
-	//fileOffsetForArea[0] = 0x90e1 - offset; // Dragon?
-	//fileOffsetForArea[0] = 0x9238 - offset; // ????
-	//fileOffsetForArea[0] = 0x92a7 - offset; // Pool
-	//fileOffsetForArea[0] = 0x93e3 - offset; // Doors
-	//fileOffsetForArea[0] = 0x94e5 - offset; // More doors
-	//fileOffsetForArea[0] = 0x9580 - offset; // Church? !!!
-	//fileOffsetForArea[0] = 0x96c8 - offset; // Another area !!!
-	//fileOffsetForArea[0] = 0x974a - offset; // Another area !!!
-	//fileOffsetForArea[0] = 0x97cb - offset; // Courtyard !!!
-	//fileOffsetForArea[0] = 0x9a5c - offset; // Stable !!!
-	//fileOffsetForArea[0] = 0x9b4b - offset; // Another area !!!
-
-	/*fileOffsetForArea[0] = 0x9d1a - offset; // Soccer field
-	fileOffsetForArea[0] = 0x9e43 - offset; // Workshop?
-	fileOffsetForArea[0] = 0x9f22 - offset; // Church
-	fileOffsetForArea[0] = 0x9fcd - offset; // ???
-
-	fileOffsetForArea[0] = 0xa03c - offset; // Tower
-	fileOffsetForArea[0] = 0xa25e - offset; // Room?
-
-	fileOffsetForArea[0] = 0xa30f - offset; // ???
-	fileOffsetForArea[0] = 0xa394 - offset; // ???
-	fileOffsetForArea[0] = 0xa3f8 - offset;
-	fileOffsetForArea[0] = 0xa48c - offset;
-	fileOffsetForArea[0] = 0xa4fa - offset;
-	fileOffsetForArea[0] = 0xa593 - offset;
-	fileOffsetForArea[0] = 0xa5ef - offset;
-	fileOffsetForArea[0] = 0xa64a - offset;
-	fileOffsetForArea[0] = 0xa695 - offset;
-	fileOffsetForArea[0] = 0xa71d - offset;*/
-	//fileOffsetForArea[0] = 0xa77e - offset; <- fails
 
 	// grab the areas
 	AreaMap *areaMap = new AreaMap;
@@ -411,8 +370,6 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 				debug("WARNING: area ID repeated: %d", newArea->getAreaID());
 		} else
 			error("Invalid area?");
-		if (_targetName == "castlemaster")
-			break;
 	}
 	_playerHeight = 64;
 	_playerWidth = 32;


Commit: 327cff4fea80ff73bfc6056b645bb9e5b7e1cad3
    https://github.com/scummvm/scummvm/commit/327cff4fea80ff73bfc6056b645bb9e5b7e1cad3
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:52+01:00

Commit Message:
FREESCAPE: fixed for castle in cpc amstrad

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index f68376bc087..549b54dabe6 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -157,11 +157,12 @@ void FreescapeEngine::loadAssets() {
 		} else
 			error("Invalid render mode %s for Total Eclipse", _renderMode.c_str());
 	   } else if (_targetName.hasPrefix("castlemaster")) {
+			_renderMode = "cga";
 			file = gameDir.createReadStreamForMember("castle.sna");
 
 			if (file == nullptr)
 				error("Failed to open castle.sna");
-			load8bitBinary(file, 0x84da, 16);
+			load8bitBinary(file, 0x84da, 4);
 	   } else
 		error("'%s' is an invalid game", _targetName.c_str());
 
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index 6f6efc28d43..4938d15e3ea 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -29,12 +29,12 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 	FCLInstruction currentInstruction;
 
 	// this lookup table tells us how many argument bytes to read per opcode
-	uint8 argumentsRequiredByOpcode[33] =
+	uint8 argumentsRequiredByOpcode[35] =
 		{
 			0, 3, 1, 1, 1, 1, 2, 2,
 			2, 1, 1, 2, 1, 1, 2, 1,
 			1, 2, 2, 1, 2, 0, 0, 0,
-			1, 1, 0, 1, 1, 1, 1, 1, 2};
+			1, 1, 0, 1, 1, 1, 1, 1, 2, 0, 1};
 
 	while (bytePointer < sizeOfTokenisedContent) {
 		// get the conditional type of the next operation
@@ -71,7 +71,7 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 
 		// figure out how many argument bytes we're going to need,
 		// check we have enough bytes left to read
-		if (opcode > 32) {
+		if (opcode > 34) {
 			debug("ERROR: failed to read opcode: %x", opcode);
 			break;
 		}
@@ -212,6 +212,10 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			numberOfArguments = 0;
 			break;
 
+		case 34: // show a message on screen
+			detokenisedStream += "MESSAGE (";
+			break;
+
 		case 12:
 			detokenisedStream += "SETBIT (";
 			currentInstruction = FCLInstruction(Token::SETBIT);
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 432f2710a3f..f7e54f57da2 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -102,7 +102,7 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 			Common::Array<uint8> conditionArray(conditionData, byteSizeOfObject);
 			conditionSource = detokenise8bitCondition(conditionArray, instructions);
 			//instructions = getInstructions(conditionSource);
-			//debug("%s", conditionSource->c_str());
+			debug("%s", conditionSource->c_str());
 		}
 		debug("End of object at %lx", file->pos());
 
@@ -173,6 +173,13 @@ byte drillerCGA[4][3] = {
 	{0x00, 0xa8, 0xa8},
 };
 
+byte castleCGA[4][3] = {
+	{0x83, 0x85, 0x83},
+	{0x00, 0x00, 0x00},
+	{0x00, 0x85, 0x00},
+	{0xff, 0xfb, 0xff},
+};
+
 byte eclipseEGA[16][3] = {
 	{0xfc, 0xfc, 0x54},
 	{0x00, 0x00, 0x00},
@@ -193,18 +200,24 @@ byte eclipseEGA[16][3] = {
 };
 
 Graphics::PixelBuffer *FreescapeEngine::getPalette(uint8 areaNumber, uint8 c1, uint8 c2, uint8 c3, uint8 c4, uint16 ncolors) {
-	Graphics::PixelFormat pixelFormat = Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, ncolors, 0);
+	Graphics::PixelFormat pixelFormat = Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0);
 	Graphics::PixelBuffer *palette = nullptr;
 	if (_targetName.hasPrefix("driller")) {
 		if (_renderMode == "ega")
 			palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&drillerEGA);
 		else if (_renderMode == "cga")
 			palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&drillerCGA);
+	} else if (_targetName.hasPrefix("castlemaster")) {
+		if (_renderMode == "ega")
+			palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&drillerEGA); // TODO
+		else if (_renderMode == "cga")
+			palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&castleCGA);
 	} else if (_targetName.hasPrefix("totaleclipse")) {
 		palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&eclipseEGA);
 	} else
 		palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&drillerEGA);
 
+	assert(palette);
 	return palette;
 }
 
@@ -236,6 +249,12 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 		groundColor = file->readByte() & 15;
 		debug("Colors: %d %d", skyColor, groundColor);
 	}
+
+	if (_renderMode == "cga") {
+		skyColor = skyColor % 4;
+		groundColor = groundColor % 4;
+	}
+
 	Graphics::PixelBuffer *palette = getPalette(areaNumber, ci1, ci2, skyColor, groundColor, ncolors);
 
 	debug("Area %d", areaNumber);


Commit: 87ff5766e3fa9267e42c7b8ef95c25cbeab8fb44
    https://github.com/scummvm/scummvm/commit/87ff5766e3fa9267e42c7b8ef95c25cbeab8fb44
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:52+01:00

Commit Message:
FREESCAPE: improved collision detection code considering area scale

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/language/instruction.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 549b54dabe6..b9683de1ce7 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -346,6 +346,7 @@ void FreescapeEngine::rotate(Common::Point lastMousePos, Common::Point mousePos)
 }
 
 void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTime) {
+	debug("old player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
 	Math::Vector3d previousPosition = _position;
 	int previousAreaID = _currentArea->getAreaID();
 
@@ -365,38 +366,50 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 		_position = _position + _cameraRight * velocity;
 		break;
 	}
+	int areaScale = _currentArea->getScale();
 	// Is threre some floor under the player?
-	_position.set(_position.x(), positionY - 16, _position.z());
-	bool collided = checkCollisions();
+	_position.set(_position.x(), positionY - 16 * areaScale, _position.z());
+	bool collided = checkCollisions(false);
 
 	if (!collided && _targetName == "driller") {  // Player is falling, let's try to step down
-		_position.set(_position.x(), positionY - 16 - 64, _position.z());
-		collided = checkCollisions();
+		debug("steping down from position: %f, %f, %f", _position.x(), _position.y(), _position.z());
+
+		_position.set(_position.x(), positionY - 16 * areaScale - 64 * areaScale, _position.z());
+
+		collided = checkCollisions(false);
+		if (!collided)
+			debug("falling from position: %f, %f, %f", _position.x(), _position.y(), _position.z());
 		assert(collided);
 
 		// restore position
-		_position.set(_position.x(), positionY - 64, _position.z());
+		_position.set(_position.x(), positionY - 64 * areaScale, _position.z());
+
+		checkCollisions(true);
+		/*if (collided && previousAreaID == _currentArea->getAreaID()) {
+			_position = previousPosition;
+		}*/
 	} else {
 		// restore position
 		_position.set(_position.x(), positionY, _position.z());
 
-		collided = checkCollisions();
+		collided = checkCollisions(true);
 		if (collided && previousAreaID == _currentArea->getAreaID()) {
+			debug("steping down from position: %f, %f, %f", _position.x(), _position.y(), _position.z());
 			// We found a collisions, let's try to step up
-			_position.set(_position.x(), positionY + 64, _position.z());
-			collided = checkCollisions();
+			_position.set(_position.x(), positionY + 64 * areaScale, _position.z());
+			collided = checkCollisions(false);
 			if (collided)
 				_position = previousPosition;
 		}
 	}
-
 	debug("new player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
 }
 
-bool FreescapeEngine::checkCollisions() {
+bool FreescapeEngine::checkCollisions(bool executeConditions) {
+	int areaScale = _currentArea->getScale();
 
-	Math::Vector3d v1(_position.x() - _playerWidth / 2, _position.y() - _playerHeight     , _position.z() - _playerDepth / 2);
-	Math::Vector3d v2(_position.x() + _playerWidth / 2, _position.y(), _position.z() + _playerDepth / 2);
+	Math::Vector3d v1(_position.x() - _playerWidth / 2, _position.y() - areaScale * _playerHeight , _position.z() - _playerDepth / 2);
+	Math::Vector3d v2(_position.x() + _playerWidth / 2, _position.y()                             , _position.z() + _playerDepth / 2);
 
 	const Math::AABB boundingBox(v1, v2);
 	Object *obj = _currentArea->checkCollisions(boundingBox);
@@ -404,7 +417,7 @@ bool FreescapeEngine::checkCollisions() {
 	if (obj != nullptr) {
 		debug("Collided with object id %d of size %f %f %f", obj->getObjectID(), obj->getSize().x(), obj->getSize().y(), obj->getSize().z());
 		GeometricObject *gobj = (GeometricObject*) obj;
-		if (gobj->conditionSource != nullptr) {
+		if (gobj->conditionSource != nullptr && executeConditions) {
 			debug("Must use collision = true when executing: %s", gobj->conditionSource->c_str());
 			executeCode(gobj->condition, false, true);
 		}
@@ -440,6 +453,7 @@ void FreescapeEngine::gotoArea(uint16 areaID, uint16 entranceID) {
 	for (int16 i = 0; i <= 32; i++) {
 		_areaBits[i] = false;
 	}
+	debug("starting player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
 }
 
 bool FreescapeEngine::hasFeature(EngineFeature f) const {
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index d37d61b86fb..d829802ccba 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -116,7 +116,7 @@ public:
 	uint16 _playerDepth;
 
 	// Effects
-	bool checkCollisions();
+	bool checkCollisions(bool executeConditions);
 	void executeCode(FCLInstructionVector &code, bool shot, bool collided);
 
 	// Instructions
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index 9242034cacf..75b61ccbed9 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -199,7 +199,7 @@ void FreescapeEngine::executeClearBit(FCLInstruction &instruction) {
 
 void FreescapeEngine::executeToggleBit(FCLInstruction &instruction) {
 	uint16 index = instruction.source;
-	_areaBits[index] = ~_areaBits[index];
+	_areaBits[index] = !_areaBits[index];
 	debug("Toggling bit %d", index);
 }
 


Commit: ee5d57849f0d481919ef34163b62ecc35577ee62
    https://github.com/scummvm/scummvm/commit/ee5d57849f0d481919ef34163b62ecc35577ee62
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:52+01:00

Commit Message:
FREESCAPE: planar rendering fixes

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/gfx_tinygl.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 84c1f97706f..5dcecd5b01c 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -69,10 +69,10 @@ Area::Area(
 	{
 		bool operator()(Object *object1, Object *object2) {
 			if (!object1->isPlanar() && object2->isPlanar())
-				return true;
-			if (object1->isPlanar() && !object2->isPlanar())
 				return false;
-			return object1->getObjectID() < object2->getObjectID();
+			if (object1->isPlanar() && !object2->isPlanar())
+				return true;
+			return object1->getObjectID() > object2->getObjectID();
 		};
 	} compareObjects;
 
@@ -118,9 +118,9 @@ void Area::draw(Freescape::Renderer *gfx) {
 Object *Area::shootRay(const Math::Ray &ray) {
 	float distance = 16 * 8192; // TODO: check if this is max distance
 	Object *collided = nullptr;
-	for (int i = drawableObjects.size() - 1; i >= 0; i--) {
+	for (int i = 0; i < drawableObjects.size(); i++) {
 		if (!drawableObjects[i]->isDestroyed() && !drawableObjects[i]->isInvisible() && drawableObjects[i]->_boundingBox.isValid() && ray.intersectAABB(drawableObjects[i]->_boundingBox)) {
-			if (ray.getOrigin().getDistanceTo(drawableObjects[i]->getOrigin()) < distance ) {
+			if (ray.getOrigin().getDistanceTo(drawableObjects[i]->getOrigin()) <= distance ) {
 				collided = drawableObjects[i];
 				distance = ray.getOrigin().getDistanceTo(collided->getOrigin());
 			}
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 1cd702f8d0e..50c7d3dbd24 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -268,24 +268,8 @@ void TinyGLRenderer::renderFace(const Common::Array<Math::Vector3d> &vertices) {
 void TinyGLRenderer::renderPolygon(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours) {
 	//assert(size.x() == 0 || size.y() == 0 || size.z() == 0);
 	uint8 r, g, b;
-	float dx, dy, dz;
-	dx = dy = dz = 0;
-
-	/*if (size.x() == 0)
-		dx = 2;
-	else if (size.y() == 0)
-		dy = 2;
-	else if (size.z() == 0)
-		dz = 2;
-	else {*/
-		if (ordinates->size() % 3 > 0) {
-			//return;
-			error("Invalid polygon: %f %f %f", size.x(), size.y(), size.z());
-		}
-	//}
-
-	if (ordinates->size() % 3 > 0)
-		error("Invalid polygon using %d ordinates", ordinates->size());
+	if (ordinates->size() % 3 > 0 && ordinates->size() > 0)
+		error("Invalid polygon with size %f %f %f and ordinates %d", size.x(), size.y(), size.z(), ordinates->size());
 
 	Common::Array<Math::Vector3d> vertices;
 	tglEnable(TGL_POLYGON_OFFSET_FILL);
@@ -310,7 +294,7 @@ void TinyGLRenderer::renderPolygon(const Math::Vector3d &origin, const Math::Vec
 			_palette->getRGBAt((*colours)[0], r, g, b);
 			tglColor3ub(r, g, b);
 			for (int i = 0; i < ordinates->size(); i = i + 3) {
-				vertices.push_back(Math::Vector3d(origin.x() + (*ordinates)[i] + dx, origin.y() + (*ordinates)[i + 1] + dy,	origin.z() + (*ordinates)[i + 2] + dz));
+				vertices.push_back(Math::Vector3d(/*origin.x() +*/ (*ordinates)[i], /*origin.y() +*/ (*ordinates)[i + 1],	/*origin.z() +*/ (*ordinates)[i + 2]));
 			}
 			renderFace(vertices);
 		}
@@ -319,7 +303,7 @@ void TinyGLRenderer::renderPolygon(const Math::Vector3d &origin, const Math::Vec
 			_palette->getRGBAt((*colours)[1], r, g, b);
 			tglColor3ub(r, g, b);
 			for (int i = ordinates->size(); i > 0; i = i - 3) {
-				vertices.push_back(Math::Vector3d(origin.x() + (*ordinates)[i-3] - dx, origin.y() + (*ordinates)[i-2] - dy,	origin.z() + (*ordinates)[i-1] - dz));
+				vertices.push_back(Math::Vector3d(/*origin.x() +*/ (*ordinates)[i-3], /*origin.y() +*/ (*ordinates)[i-2],	/*origin.z() +*/ (*ordinates)[i-1]));
 			}
 			renderFace(vertices);
 		}
@@ -334,11 +318,8 @@ void TinyGLRenderer::renderRectangle(const Math::Vector3d &origin, const Math::V
 	assert(size.x() == 0 || size.y() == 0 || size.z() == 0);
 	tglEnable(TGL_POLYGON_OFFSET_FILL);
 	tglPolygonOffset(-2.0f, 1.0f);
-	//debug("origin: %f, %f, %f", origin.x(), origin.y(), origin.z());
-	//debug("size: %f, %f, %f", size.x(), size.y(), size.z());
 
 	float dx, dy, dz;
-	float offset = 0;
 	uint8 r, g, b;
 	Common::Array<Math::Vector3d> vertices;
 	for (int i = 0; i < 2; i++) {


Commit: 19fcfae60953e0d822b0005e7ab71d4711a8e4ca
    https://github.com/scummvm/scummvm/commit/19fcfae60953e0d822b0005e7ab71d4711a8e4ca
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:52+01:00

Commit Message:
FREESCAPE: simplified and improved ray collision code

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/objects/geometricobject.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 5dcecd5b01c..5aa5e8452bf 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -116,15 +116,10 @@ void Area::draw(Freescape::Renderer *gfx) {
 }
 
 Object *Area::shootRay(const Math::Ray &ray) {
-	float distance = 16 * 8192; // TODO: check if this is max distance
 	Object *collided = nullptr;
-	for (int i = 0; i < drawableObjects.size(); i++) {
-		if (!drawableObjects[i]->isDestroyed() && !drawableObjects[i]->isInvisible() && drawableObjects[i]->_boundingBox.isValid() && ray.intersectAABB(drawableObjects[i]->_boundingBox)) {
-			if (ray.getOrigin().getDistanceTo(drawableObjects[i]->getOrigin()) <= distance ) {
-				collided = drawableObjects[i];
-				distance = ray.getOrigin().getDistanceTo(collided->getOrigin());
-			}
-		}
+	for (int i = drawableObjects.size() - 1; i >= 0; i--) {
+		if (!drawableObjects[i]->isDestroyed() && !drawableObjects[i]->isInvisible() && drawableObjects[i]->_boundingBox.isValid() && ray.intersectAABB(drawableObjects[i]->_boundingBox))
+			collided = drawableObjects[i];
 	}
 	return collided;
 }
@@ -132,8 +127,8 @@ Object *Area::shootRay(const Math::Ray &ray) {
 Object *Area::checkCollisions(const Math::AABB &boundingBox) {
 	float size = 16 * 8192; // TODO: check if this is max size
 	Object *collided = nullptr;
-	for (int i = drawableObjects.size() - 1; i >= 0; i--) {
-		if (drawableObjects[i]->isDrawable() && !drawableObjects[i]->isDestroyed() && !drawableObjects[i]->isInvisible()) {
+	for (int i = 0; i < int(drawableObjects.size()); i++) {
+		if (!drawableObjects[i]->isDestroyed() && !drawableObjects[i]->isInvisible()) {
 			GeometricObject *obj = (GeometricObject*) drawableObjects[i];
 			float objSize = obj->getSize().length();
 			if (obj->collides(boundingBox) && size > objSize) {
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 50c7d3dbd24..7f08e1fe947 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -294,7 +294,7 @@ void TinyGLRenderer::renderPolygon(const Math::Vector3d &origin, const Math::Vec
 			_palette->getRGBAt((*colours)[0], r, g, b);
 			tglColor3ub(r, g, b);
 			for (int i = 0; i < ordinates->size(); i = i + 3) {
-				vertices.push_back(Math::Vector3d(/*origin.x() +*/ (*ordinates)[i], /*origin.y() +*/ (*ordinates)[i + 1],	/*origin.z() +*/ (*ordinates)[i + 2]));
+				vertices.push_back(Math::Vector3d((*ordinates)[i], (*ordinates)[i + 1], (*ordinates)[i + 2]));
 			}
 			renderFace(vertices);
 		}
@@ -303,7 +303,7 @@ void TinyGLRenderer::renderPolygon(const Math::Vector3d &origin, const Math::Vec
 			_palette->getRGBAt((*colours)[1], r, g, b);
 			tglColor3ub(r, g, b);
 			for (int i = ordinates->size(); i > 0; i = i - 3) {
-				vertices.push_back(Math::Vector3d(/*origin.x() +*/ (*ordinates)[i-3], /*origin.y() +*/ (*ordinates)[i-2],	/*origin.z() +*/ (*ordinates)[i-1]));
+				vertices.push_back(Math::Vector3d((*ordinates)[i-3], (*ordinates)[i-2], (*ordinates)[i-1]));
 			}
 			renderFace(vertices);
 		}
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index a55d3ee0c57..7ade654faf2 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -150,14 +150,18 @@ void GeometricObject::createBoundingBox() {
 		break;
 	case Rectangle:
 		_boundingBox.expand(origin);
-
-		v = origin + size;
-		for (int i = 0; i < 3; i++) {
-			if (size.getValue(i) == 0)
-				v.setValue(i, v.getValue(i) + 10);
+		_boundingBox.expand(origin + size);
+		break;
+	case Line:
+	case Triangle:
+	case Quadrilateral:
+	case Pentagon:
+	case Hexagon:
+		for (int i = 0; i < int(ordinates->size()); i = i + 3) {
+			_boundingBox.expand(Math::Vector3d((*ordinates)[i], (*ordinates)[i + 1], (*ordinates)[i + 2]));
 		}
-		_boundingBox.expand(v);
 		break;
+
 	case EastPyramid:
 		_boundingBox.expand(origin + Math::Vector3d(0, 0, size.z()));
 		_boundingBox.expand(origin + Math::Vector3d(0, size.y(), size.z()));


Commit: 22c722d02c80dbfcee49b7793f315fe80c2ae437
    https://github.com/scummvm/scummvm/commit/22c722d02c80dbfcee49b7793f315fe80c2ae437
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:53+01:00

Commit Message:
FREESCAPE: first implementation of area conditions when shooting

Changed paths:
    engines/freescape/area.h
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/language/instruction.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index 0674c079b5e..9f1add1c0cb 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -17,6 +17,7 @@
 
 #include "freescape/gfx.h"
 #include "freescape/objects/object.h"
+#include "freescape/language/instruction.h"
 
 namespace Freescape {
 
@@ -45,6 +46,8 @@ public:
 	Object *shootRay(const Math::Ray &ray);
 	Object *checkCollisions(const Math::AABB &boundingBox);
 
+	Common::Array<Common::String*> conditionSources;
+	Common::Array<FCLInstructionVector> conditions;
 
 private:
 	uint16 areaID;
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index b9683de1ce7..5f9d88890be 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -243,7 +243,6 @@ void FreescapeEngine::processInput() {
 
 		}
 	}
-
 }
 
 void FreescapeEngine::shoot() {
@@ -258,6 +257,12 @@ void FreescapeEngine::shoot() {
 			executeCode(gobj->condition, true, false);
 		}
 	}
+
+	for (int i = 0; i < int(_currentArea->conditionSources.size()); i++) {
+		debug("Must use shot = true executing: %s", _currentArea->conditionSources[i]->c_str());
+		executeCode(_currentArea->conditions[i], true, false);
+	}
+
 	//debug("camera front: %f %f %f", _cameraFront.x(), _rotation.y(), _rotation.z());
 }
 
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index d829802ccba..eb191f91d4d 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -135,6 +135,7 @@ public:
 	void executeClearBit(FCLInstruction &instruction);
 	void executeToggleBit(FCLInstruction &instruction);
 	bool executeEndIfBitNotEqual(FCLInstruction &instruction);
+	bool executeEndIfVisibilityIsNotEqual(FCLInstruction &instruction);
 
 
 	// Rendering
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index 4938d15e3ea..55d50d43a66 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -140,11 +140,15 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 		case 4:
 			detokenisedStream += "VIS (";
 			currentInstruction = FCLInstruction(Token::VIS);
+			currentInstruction.source = 0;
+			currentInstruction.destination = 0;
 			break; // hence each getting two case statement entries
 		case 8:
 		case 5:
 			detokenisedStream += "INVIS (";
 			currentInstruction = FCLInstruction(Token::INVIS);
+			currentInstruction.source = 0;
+			currentInstruction.destination = 0;
 			break;
 
 		case 9:
@@ -193,6 +197,11 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			detokenisedStream += "IF INVIS? ";
 			detokenisedStream += Common::String::format("(%d)", (int)tokenisedCondition[bytePointer]);
 			detokenisedStream += "THEN END ENDIF";
+			currentInstruction = FCLInstruction(Token::INVISQ);
+			currentInstruction.setSource(tokenisedCondition[bytePointer]);
+			currentInstruction.setDestination(true); // visible
+			conditionalInstructions->push_back(currentInstruction);
+			currentInstruction = FCLInstruction(Token::UNKNOWN);
 			bytePointer++;
 			numberOfArguments = 0;
 			break;
@@ -200,6 +209,11 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			detokenisedStream += "IF VIS? ";
 			detokenisedStream += Common::String::format("(%d)", (int)tokenisedCondition[bytePointer]);
 			detokenisedStream += "THEN END ENDIF";
+			currentInstruction = FCLInstruction(Token::INVISQ);
+			currentInstruction.setSource(tokenisedCondition[bytePointer]);
+			currentInstruction.setDestination(false); // visible
+			conditionalInstructions->push_back(currentInstruction);
+			currentInstruction = FCLInstruction(Token::UNKNOWN);
 			bytePointer++;
 			numberOfArguments = 0;
 			break;
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index 75b61ccbed9..06bff8c7d40 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -105,6 +105,10 @@ void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool co
 			if (executeEndIfBitNotEqual(instruction))
 				ip = codeSize;
 			break;
+			case Token::INVISQ:
+			if (executeEndIfVisibilityIsNotEqual(instruction))
+				ip = codeSize;
+			break;
 		}
 		ip++;
 	}
@@ -123,6 +127,15 @@ void FreescapeEngine::executeDelay(FCLInstruction &instruction) {
 	g_system->delayMillis(20 * delay);
 }
 
+bool FreescapeEngine::executeEndIfVisibilityIsNotEqual(FCLInstruction &instruction) {
+	uint16 objectID = instruction.source;
+	uint16 value = instruction.destination;
+	debug("End condition if visibility of obj with id %d is %d!", objectID, value);
+	Object *obj = _currentArea->objectWithID(objectID);
+	assert(obj);
+	return (obj->isInvisible() == value);
+}
+
 bool FreescapeEngine::executeEndIfNotEqual(FCLInstruction &instruction) {
 	uint16 variable1 = instruction.source;
 	uint16 variable2 = instruction.destination;
@@ -159,16 +172,34 @@ void FreescapeEngine::executeDestroy(FCLInstruction &instruction) {
 }
 
 void FreescapeEngine::executeMakeInvisible(FCLInstruction &instruction) {
-	uint16 objectID = instruction.source;
-	debug("Making obj %d invisible!", objectID);
-	Object *obj = _currentArea->objectWithID(objectID);
+	uint16 objectID = 0;
+	uint16 areaID = _currentArea->getAreaID();
+
+	if (instruction.destination > 0) {
+		objectID = instruction.destination;
+		areaID = instruction.source;
+	} else {
+		objectID = instruction.source;
+	}
+
+	debug("Making obj %d invisible in area %d!", objectID, areaID);
+	Object *obj = (*_areasByAreaID)[areaID]->objectWithID(objectID);
 	obj->makeInvisible();
 }
 
 void FreescapeEngine::executeMakeVisible(FCLInstruction &instruction) {
-	uint16 objectID = instruction.source;
-	debug("Making obj %d visible!", objectID);
-	Object *obj = _currentArea->objectWithID(objectID);
+	uint16 objectID = 0;
+	uint16 areaID = _currentArea->getAreaID();
+
+	if (instruction.destination > 0) {
+		objectID = instruction.destination;
+		areaID = instruction.source;
+	} else {
+		objectID = instruction.source;
+	}
+
+	debug("Making obj %d visible in area %d!", objectID, areaID);
+	Object *obj = (*_areasByAreaID)[areaID]->objectWithID(objectID);
 	obj->makeVisible();
 }
 
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index f7e54f57da2..edd47e8a36c 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -294,6 +294,9 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	file->seek(base + cPtr);
 	uint8 numConditions = file->readByte();
 	debug("%d area conditions at %x of area %d", numConditions, base + cPtr, areaNumber);
+
+	Area *area = new Area(areaNumber, objectsByID, entrancesByID, scale, skyColor, groundColor, palette);
+
 	while (numConditions--) {
 		FCLInstructionVector instructions;
 		// get the length
@@ -303,10 +306,13 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 		byte *conditionData = (byte*)malloc(lengthOfCondition);
 		file->read(conditionData, lengthOfCondition);
 		Common::Array<uint8> conditionArray(conditionData, lengthOfCondition);
-		debug("%s", detokenise8bitCondition(conditionArray, instructions)->c_str());
+		Common::String *conditionSource = detokenise8bitCondition(conditionArray, instructions);
+		area->conditions.push_back(instructions);
+		area->conditionSources.push_back(conditionSource);
+		debug("%s", conditionSource->c_str());
 	}
 	debug("End of area at %lx", file->pos());
-	return (new Area(areaNumber, objectsByID, entrancesByID, scale, skyColor, groundColor, palette));
+	return area;
 }
 
 void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offset, int ncolors) {


Commit: 7993864cc0528a1349f643001e55845877c7b279
    https://github.com/scummvm/scummvm/commit/7993864cc0528a1349f643001e55845877c7b279
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:53+01:00

Commit Message:
FREESCAPE: improved ray hit detection and finished implementation of toggle visibility opcode

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/language/instruction.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 5aa5e8452bf..e3075952398 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -116,10 +116,18 @@ void Area::draw(Freescape::Renderer *gfx) {
 }
 
 Object *Area::shootRay(const Math::Ray &ray) {
+	float size = 16 * 8192; // TODO: check if this is max size
 	Object *collided = nullptr;
-	for (int i = drawableObjects.size() - 1; i >= 0; i--) {
-		if (!drawableObjects[i]->isDestroyed() && !drawableObjects[i]->isInvisible() && drawableObjects[i]->_boundingBox.isValid() && ray.intersectAABB(drawableObjects[i]->_boundingBox))
+	for (int i = 0; i < drawableObjects.size(); i++) {
+		float objSize = drawableObjects[i]->getSize().length();
+		if (!drawableObjects[i]->isDestroyed() && !drawableObjects[i]->isInvisible()
+		  && drawableObjects[i]->_boundingBox.isValid()
+		  && ray.intersectAABB(drawableObjects[i]->_boundingBox)
+		  && size >= objSize) {
+			debug("shot obj id: %d", drawableObjects[i]->getObjectID());
 			collided = drawableObjects[i];
+			size = objSize;
+		}
 	}
 	return collided;
 }
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index 55d50d43a66..c39d41540c6 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -135,6 +135,8 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 		case 3:
 			detokenisedStream += "TOGVIS (";
 			currentInstruction = FCLInstruction(Token::TOGVIS);
+			currentInstruction.source = 0;
+			currentInstruction.destination = 0;
 			break; // these all come in unary and binary versions,
 		case 7:
 		case 4:
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index 06bff8c7d40..836014c3a79 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -204,9 +204,18 @@ void FreescapeEngine::executeMakeVisible(FCLInstruction &instruction) {
 }
 
 void FreescapeEngine::executeToggleVisibility(FCLInstruction &instruction) {
-	uint16 objectID = instruction.source;
-	debug("Toggling obj %d visibility!", objectID);
-	Object *obj = _currentArea->objectWithID(objectID);
+	uint16 objectID = 0;
+	uint16 areaID = _currentArea->getAreaID();
+
+	if (instruction.destination > 0) {
+		objectID = instruction.destination;
+		areaID = instruction.source;
+	} else {
+		objectID = instruction.source;
+	}
+
+	debug("Toggling obj %d visibility in area %d!", objectID, areaID);
+	Object *obj = (*_areasByAreaID)[areaID]->objectWithID(objectID);
 	obj->toggleVisibility();
 }
 


Commit: 1085cf6b507743c53c97fe3c056c2cb9d9fe3f96
    https://github.com/scummvm/scummvm/commit/1085cf6b507743c53c97fe3c056c2cb9d9fe3f96
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:53+01:00

Commit Message:
FREESCAPE: corrected end if not equal opcode

Changed paths:
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/language/instruction.cpp


diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index c39d41540c6..3131f92ecff 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -173,7 +173,7 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 
 		case 11: // end condition if a variable doesn't have a particular value
 			detokenisedStream += "IF VAR!=? ";
-			detokenisedStream += Common::String::format("(v%d, v%d)", (int)tokenisedCondition[bytePointer], (int)tokenisedCondition[bytePointer + 1]);
+			detokenisedStream += Common::String::format("(v%d, %d)", (int)tokenisedCondition[bytePointer], (int)tokenisedCondition[bytePointer + 1]);
 			detokenisedStream += "THEN END ENDIF";
 			currentInstruction = FCLInstruction(Token::VARNOTEQ);
 			currentInstruction.setSource(tokenisedCondition[bytePointer]);
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index 836014c3a79..024c2b9a1fa 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -137,10 +137,10 @@ bool FreescapeEngine::executeEndIfVisibilityIsNotEqual(FCLInstruction &instructi
 }
 
 bool FreescapeEngine::executeEndIfNotEqual(FCLInstruction &instruction) {
-	uint16 variable1 = instruction.source;
-	uint16 variable2 = instruction.destination;
-	debug("End condition if variable %d is not equal to variable %d!", variable1, variable2);
-	return (_gameState[variable1] != _gameState[variable2]);
+	uint16 variable = instruction.source;
+	uint16 value = instruction.destination;
+	debug("End condition if variable %d is not equal to %d!", variable, value);
+	return (_gameState[variable] != value);
 }
 
 void FreescapeEngine::executeIncrementVariable(FCLInstruction &instruction) {


Commit: 580e9b1854853394602769d647ef8d98cdd2f909
    https://github.com/scummvm/scummvm/commit/580e9b1854853394602769d647ef8d98cdd2f909
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:53+01:00

Commit Message:
FREESCAPE: allow users to fit in small areas reducing its width

Changed paths:
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index edd47e8a36c..c83275016fd 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -397,7 +397,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 			error("Invalid area?");
 	}
 	_playerHeight = 64;
-	_playerWidth = 32;
+	_playerWidth = 12;
 	_playerDepth = 32;
 
 	_areasByAreaID = areaMap;


Commit: af059a695e480786f18b6cf8f62914cb7cbadb65
    https://github.com/scummvm/scummvm/commit/af059a695e480786f18b6cf8f62914cb7cbadb65
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:53+01:00

Commit Message:
FREESCAPE: basic sound implementation and adding floor to castle master levels

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/language/instruction.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index e3075952398..e133a4fd386 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -148,4 +148,22 @@ Object *Area::checkCollisions(const Math::AABB &boundingBox) {
 	return collided;
 }
 
+void Area::addFloor() {
+	FCLInstructionVector empty;
+	Common::Array<uint8> *gColors = new Common::Array<uint8>;
+	for (int i = 0; i < 6; i++)
+		gColors->push_back(groundColor);
+	GeometricObject *floor = new GeometricObject(
+		Object::Type::Cube,
+		200,
+		0, // flags
+		Math::Vector3d(0, -64, 0), // Position
+		Math::Vector3d(8128, 64, 8128), // size
+		gColors,
+		nullptr,
+		empty
+	);
+	drawableObjects.push_back(floor);
+}
+
 } // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index 9f1add1c0cb..e8aea215c4e 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -45,6 +45,7 @@ public:
 
 	Object *shootRay(const Math::Ray &ray);
 	Object *checkCollisions(const Math::AABB &boundingBox);
+	void addFloor();
 
 	Common::Array<Common::String*> conditionSources;
 	Common::Array<FCLInstructionVector> conditions;
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 5f9d88890be..a4c74cbc4a1 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -405,7 +405,14 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 			collided = checkCollisions(false);
 			if (collided)
 				_position = previousPosition;
+		} else {
+			_position.set(_position.x(), positionY - 16 * areaScale, _position.z());
+			collided = checkCollisions(true);
+			assert(collided); // This should not fail
+			// restore position
+			_position.set(_position.x(), positionY, _position.z());
 		}
+
 	}
 	debug("new player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
 }
@@ -467,6 +474,13 @@ bool FreescapeEngine::hasFeature(EngineFeature f) const {
 		   (f == kSupportsSavingDuringRuntime);
 }
 
+void FreescapeEngine::playSound(int index) {
+	debug("Playing sound %d", index);
+	_speaker.setVolume(Audio::Mixer::kMaxChannelVolume);
+	_speaker.play(Audio::PCSpeaker::kWaveFormSine, 2000, 100);
+	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_speakerHandle, &_speaker);
+}
+
 Common::Error FreescapeEngine::loadGameStream(Common::SeekableReadStream *stream) {
 	Common::Serializer s(stream, nullptr);
 	syncGameStream(s);
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index eb191f91d4d..4bff2b2e24c 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -9,6 +9,9 @@
 #include "graphics/tinygl/pixelbuffer.h"
 #include "gui/debugger.h"
 
+#include "audio/mixer.h"
+#include "audio/softsynth/pcspk.h"
+
 #include "freescape/area.h"
 #include "freescape/objects/entrance.h"
 #include "freescape/language/instruction.h"
@@ -129,6 +132,7 @@ public:
 	void executeToggleVisibility(FCLInstruction &instruction);
 	void executeDestroy(FCLInstruction &instruction);
 	void executeRedraw(FCLInstruction &instruction);
+	void executeSound(FCLInstruction &instruction);
 	void executeDelay(FCLInstruction &instruction);
 	bool executeEndIfNotEqual(FCLInstruction &instruction);
 	void executeSetBit(FCLInstruction &instruction);
@@ -137,6 +141,10 @@ public:
 	bool executeEndIfBitNotEqual(FCLInstruction &instruction);
 	bool executeEndIfVisibilityIsNotEqual(FCLInstruction &instruction);
 
+	// Souund
+	Audio::SoundHandle _speakerHandle;
+	Audio::PCSpeaker _speaker;
+	void playSound(int index);
 
 	// Rendering
 	Common::String _renderMode;
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index 3131f92ecff..8029ea06618 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -243,6 +243,7 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 
 		case 15:
 			detokenisedStream += "SOUND (";
+			currentInstruction = FCLInstruction(Token::SOUND);
 			break;
 		case 17:
 		case 16:
@@ -269,6 +270,7 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			break;
 		case 28:
 			detokenisedStream += "SYNCSND (";
+			currentInstruction = FCLInstruction(Token::SOUND);
 			break;
 		case 29:
 			detokenisedStream += "TOGGLEBIT (";
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index 024c2b9a1fa..faf7267a6bc 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -95,6 +95,9 @@ void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool co
 			case Token::DELAY:
 			executeDelay(instruction);
 			break;
+			case Token::SOUND:
+			executeSound(instruction);
+			break;
 			case Token::SETBIT:
 			executeSetBit(instruction);
 			break;
@@ -121,6 +124,11 @@ void FreescapeEngine::executeRedraw(FCLInstruction &instruction) {
 	drawFrame();
 }
 
+void FreescapeEngine::executeSound(FCLInstruction &instruction) {
+	uint16 index = instruction.source;
+	playSound(index);
+}
+
 void FreescapeEngine::executeDelay(FCLInstruction &instruction) {
 	uint16 delay = instruction.source;
 	debug("Delaying %d * 1/50 seconds", delay);
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index c83275016fd..70bdef30984 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -311,6 +311,10 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 		area->conditionSources.push_back(conditionSource);
 		debug("%s", conditionSource->c_str());
 	}
+
+	if (_targetName.hasPrefix("castlemaster"))
+		area->addFloor();
+
 	debug("End of area at %lx", file->pos());
 	return area;
 }


Commit: 359bd5c95037c29f42102dad9bf91c9732534f5b
    https://github.com/scummvm/scummvm/commit/359bd5c95037c29f42102dad9bf91c9732534f5b
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:53+01:00

Commit Message:
FREESCAPE: minor changes in collision detections

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index e133a4fd386..f5b821ce670 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -133,7 +133,7 @@ Object *Area::shootRay(const Math::Ray &ray) {
 }
 
 Object *Area::checkCollisions(const Math::AABB &boundingBox) {
-	float size = 16 * 8192; // TODO: check if this is max size
+	float size = 3 * 8192 * 8192; // TODO: check if this is max size
 	Object *collided = nullptr;
 	for (int i = 0; i < int(drawableObjects.size()); i++) {
 		if (!drawableObjects[i]->isDestroyed() && !drawableObjects[i]->isInvisible()) {
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index a4c74cbc4a1..290cf7069ad 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -46,7 +46,7 @@ FreescapeEngine::FreescapeEngine(OSystem *syst)
 	_velocity = Math::Vector3d(0.f, 0.f, 0.f);
 	_cameraFront = Math::Vector3d(0.f, 0.f, 0.f);
 	_cameraRight = Math::Vector3d(0.f, 0.f, 0.f);
-	_movementSpeed = 2.5f;
+	_movementSpeed = 1.0f;
 	_mouseSensitivity = 0.1f;
 	_borderTexture = nullptr;
 
@@ -399,7 +399,7 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 
 		collided = checkCollisions(true);
 		if (collided && previousAreaID == _currentArea->getAreaID()) {
-			debug("steping down from position: %f, %f, %f", _position.x(), _position.y(), _position.z());
+			debug("steping up from position: %f, %f, %f", _position.x(), _position.y(), _position.z());
 			// We found a collisions, let's try to step up
 			_position.set(_position.x(), positionY + 64 * areaScale, _position.z());
 			collided = checkCollisions(false);


Commit: c821a6164c38ed5814bea9470e8dc82ac7059cb3
    https://github.com/scummvm/scummvm/commit/c821a6164c38ed5814bea9470e8dc82ac7059cb3
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:54+01:00

Commit Message:
FREESCAPE: removed unusued variables

Changed paths:
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 290cf7069ad..430ea871a4f 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -102,7 +102,6 @@ void FreescapeEngine::loadAssets() {
 		load16bitBinary(file);
 	} else if (_targetName.hasPrefix("driller") || _targetName.hasPrefix("spacestationoblivion")) {
 		Common::File exe;
-		bool success = false;
 		if (_renderMode == "ega") {
 			file = gameDir.createReadStreamForMember("DRILLE.EXE");
 
@@ -121,7 +120,6 @@ void FreescapeEngine::loadAssets() {
 
 	} else if (_targetName.hasPrefix("darkside")) {
 		Common::File exe;
-		bool success = false;
 		if (_renderMode == "ega") {
 			file = gameDir.createReadStreamForMember("DSIDEE.EXE");
 
@@ -140,7 +138,6 @@ void FreescapeEngine::loadAssets() {
 
 	} else if (_targetName == "totaleclipse") {
 		Common::File exe;
-		bool success = false;
 		if (_renderMode == "ega") {
 			file = gameDir.createReadStreamForMember("TOTEE.EXE");
 


Commit: 59328b71147dbbce9553a76836468728ec38de5a
    https://github.com/scummvm/scummvm/commit/59328b71147dbbce9553a76836468728ec38de5a
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:54+01:00

Commit Message:
FREESCAPE: reworked collision detection code

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 430ea871a4f..9835979d962 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -46,7 +46,7 @@ FreescapeEngine::FreescapeEngine(OSystem *syst)
 	_velocity = Math::Vector3d(0.f, 0.f, 0.f);
 	_cameraFront = Math::Vector3d(0.f, 0.f, 0.f);
 	_cameraRight = Math::Vector3d(0.f, 0.f, 0.f);
-	_movementSpeed = 1.0f;
+	_movementSpeed = 1.5f;
 	_mouseSensitivity = 0.1f;
 	_borderTexture = nullptr;
 
@@ -369,51 +369,80 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 		break;
 	}
 	int areaScale = _currentArea->getScale();
-	// Is threre some floor under the player?
-	_position.set(_position.x(), positionY - 16 * areaScale, _position.z());
+	// restore y coordinate
+	_position.set(_position.x(), positionY, _position.z());
 	bool collided = checkCollisions(false);
 
-	if (!collided && _targetName == "driller") {  // Player is falling, let's try to step down
-		debug("steping down from position: %f, %f, %f", _position.x(), _position.y(), _position.z());
-
-		_position.set(_position.x(), positionY - 16 * areaScale - 64 * areaScale, _position.z());
+	if (!collided) {
+		bool hasFloor = checkFloor(_position);
+		if (!hasFloor) {
+			int fallen;
+			for (fallen = 1; fallen < 65 + 1; fallen++) {
+				_position.set(_position.x(), positionY - fallen * areaScale, _position.z());
+				if (tryStepDown(_position))
+					break;
+			}
+			fallen++;
+			fallen++;
+			if (fallen >= 67) {
+				_position = previousPosition; //error("NASTY FALL!");
+				return;
+			}
+			_position.set(_position.x(), positionY - fallen * areaScale, _position.z());
+		}
+		checkCollisions(true); // run the effects
+	} else {
+		checkCollisions(true); // run the effects
+		if (_currentArea->getAreaID() == previousAreaID) {
+			bool stepUp = tryStepUp(_position);
+			if (stepUp) {
+				checkCollisions(true); // run the effects (again)
+			} else {
+				_position = previousPosition;
+			}
+		}
+	}
+	debug("new player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
+}
 
-		collided = checkCollisions(false);
-		if (!collided)
-			debug("falling from position: %f, %f, %f", _position.x(), _position.y(), _position.z());
-		assert(collided);
+bool FreescapeEngine::checkFloor(Math::Vector3d currentPosition) {
+	int areaScale = _currentArea->getScale();
+	bool collided = checkCollisions(false);
+	assert(!collided);
 
-		// restore position
-		_position.set(_position.x(), positionY - 64 * areaScale, _position.z());
+	_position.set(_position.x(), _position.y() - 2 * areaScale, _position.z());
+	collided = checkCollisions(false);
+	_position = currentPosition;
+	return collided;
+}
 
-		checkCollisions(true);
-		/*if (collided && previousAreaID == _currentArea->getAreaID()) {
-			_position = previousPosition;
-		}*/
+bool FreescapeEngine::tryStepUp(Math::Vector3d currentPosition) {
+	debug("Try to step up!");
+	int areaScale = _currentArea->getScale();
+	_position.set(_position.x(), _position.y() + 64 * areaScale, _position.z());
+	bool collided = checkCollisions(false);
+	if (collided) {
+		_position = currentPosition;
+		return false;
 	} else {
-		// restore position
-		_position.set(_position.x(), positionY, _position.z());
-
-		collided = checkCollisions(true);
-		if (collided && previousAreaID == _currentArea->getAreaID()) {
-			debug("steping up from position: %f, %f, %f", _position.x(), _position.y(), _position.z());
-			// We found a collisions, let's try to step up
-			_position.set(_position.x(), positionY + 64 * areaScale, _position.z());
-			collided = checkCollisions(false);
-			if (collided)
-				_position = previousPosition;
-		} else {
-			_position.set(_position.x(), positionY - 16 * areaScale, _position.z());
-			collided = checkCollisions(true);
-			assert(collided); // This should not fail
-			// restore position
-			_position.set(_position.x(), positionY, _position.z());
-		}
+		// Try to step down
+		return true;
+	}
+}
 
+bool FreescapeEngine::tryStepDown(Math::Vector3d currentPosition) {
+	debug("Try to step down!");
+	int areaScale = _currentArea->getScale();
+	_position.set(_position.x(), _position.y() - areaScale, _position.z());
+	if (checkFloor(_position)) {
+		return true;
+	} else {
+		_position = currentPosition;
+		return false;
 	}
-	debug("new player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
 }
 
+
 bool FreescapeEngine::checkCollisions(bool executeConditions) {
 	int areaScale = _currentArea->getScale();
 
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 4bff2b2e24c..fa2c4ed5d6b 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -95,6 +95,10 @@ public:
 	// Input
 	void processInput();
 	void move(CameraMovement direction, uint8 scale, float deltaTime);
+	bool checkFloor(Math::Vector3d currentPosition);
+	bool tryStepUp(Math::Vector3d currentPosition);
+	bool tryStepDown(Math::Vector3d currentPosition);
+
 	void rotate(Common::Point lastMousePos, Common::Point mousePos);
 	// Input state
 	float _lastFrame;


Commit: d140a9fd2ff8b74adb3299596466051e9700f1a2
    https://github.com/scummvm/scummvm/commit/d140a9fd2ff8b74adb3299596466051e9700f1a2
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:54+01:00

Commit Message:
FREESCAPE: basic castle EGA palette

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 9835979d962..50f14be20cf 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -154,12 +154,12 @@ void FreescapeEngine::loadAssets() {
 		} else
 			error("Invalid render mode %s for Total Eclipse", _renderMode.c_str());
 	   } else if (_targetName.hasPrefix("castlemaster")) {
-			_renderMode = "cga";
+			_renderMode = "ega";
 			file = gameDir.createReadStreamForMember("castle.sna");
 
 			if (file == nullptr)
 				error("Failed to open castle.sna");
-			load8bitBinary(file, 0x84da, 4);
+			load8bitBinary(file, 0x84da, 16);
 	   } else
 		error("'%s' is an invalid game", _targetName.c_str());
 
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 70bdef30984..3578ddaac7d 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -180,6 +180,25 @@ byte castleCGA[4][3] = {
 	{0xff, 0xfb, 0xff},
 };
 
+byte castleEGA[16][3] = {
+	{0x00, 0x00, 0x00},
+	{0x00, 0xaa, 0x00},
+	{0x00, 0xaa, 0xaa},
+	{0x00, 0xaa, 0xaa},
+	{0xaa, 0xaa, 0xaa},
+	{0x55, 0x55, 0x55},
+	{0x00, 0x00, 0x00},
+	{0xaa, 0x55, 0x00},
+	{0x12, 0xf3, 0x56},
+	{0xaa, 0x00, 0x00},
+	{0xff, 0x55, 0xff},
+	{0xaa, 0x55, 0x00},
+	{0xaa, 0x55, 0x00},
+	{0xaa, 0x55, 0x00},
+	{0x12, 0xf3, 0x56},
+	{0x12, 0xf3, 0x56}
+};
+
 byte eclipseEGA[16][3] = {
 	{0xfc, 0xfc, 0x54},
 	{0x00, 0x00, 0x00},
@@ -209,7 +228,7 @@ Graphics::PixelBuffer *FreescapeEngine::getPalette(uint8 areaNumber, uint8 c1, u
 			palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&drillerCGA);
 	} else if (_targetName.hasPrefix("castlemaster")) {
 		if (_renderMode == "ega")
-			palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&drillerEGA); // TODO
+			palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&castleEGA); // TODO
 		else if (_renderMode == "cga")
 			palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&castleCGA);
 	} else if (_targetName.hasPrefix("totaleclipse")) {


Commit: ea663d580a76a6ae368887d50db9c6a14ee0a21c
    https://github.com/scummvm/scummvm/commit/ea663d580a76a6ae368887d50db9c6a14ee0a21c
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:54+01:00

Commit Message:
FREESCAPE: sensor objects are created

Changed paths:
  A engines/freescape/objects/sensor.cpp
  A engines/freescape/objects/sensor.h
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/module.mk


diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 3578ddaac7d..b65609d83d0 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -5,11 +5,14 @@
 
 #include "freescape/freescape.h"
 #include "freescape/area.h"
+
 #include "freescape/language/8bitDetokeniser.h"
 #include "freescape/language/instruction.h"
+
+#include "freescape/objects/object.h"
 #include "freescape/objects/geometricobject.h"
 #include "freescape/objects/entrance.h"
-#include "freescape/objects/object.h"
+#include "freescape/objects/sensor.h"
 
 namespace Freescape {
 
@@ -138,8 +141,25 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 			5 * v); // rotation
 	} break;
 
-	case Object::Sensor:
+	case Object::Sensor: {
+		debug("rotation: %f %f %f", v.x(), v.y(), v.z());
+		if (byteSizeOfObject > 0) {
+			// TODO: there is something here
+			debug("Warning: extra %d bytes in sensor", byteSizeOfObject);
+			file->seek(byteSizeOfObject, SEEK_CUR);
+			byteSizeOfObject = 0;
+		}
+		assert(byteSizeOfObject == 0);
+		debug("End of object at %lx", file->pos());
+		// create an entrance
+		return new Sensor(
+			objectID,
+			32 * position,
+			5 * v); // rotation
+	} break;
+
 	case Object::Group:
+		error("Object of type 'group'");
 		break;
 	}
 
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index 27e8c9d1f66..46ee645baec 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -10,6 +10,7 @@ MODULE_OBJS := \
 	objects/object.o \
 	objects/entrance.o \
 	objects/geometricobject.o \
+	objects/sensor.o \
 	loaders/8bitBinaryLoader.o \
 	language/8bitDetokeniser.o \
 	loaders/16bitBinaryLoader.o \
diff --git a/engines/freescape/objects/sensor.cpp b/engines/freescape/objects/sensor.cpp
new file mode 100644
index 00000000000..9052649d714
--- /dev/null
+++ b/engines/freescape/objects/sensor.cpp
@@ -0,0 +1,19 @@
+#include "freescape/objects/sensor.h"
+
+namespace Freescape {
+
+Sensor::Sensor(
+	uint16 objectID,
+	const Math::Vector3d &_origin,
+	const Math::Vector3d &rotation) {
+	_objectID = objectID;
+	origin = _origin;
+	_rotation = rotation;
+}
+
+Sensor::~Sensor() {}
+
+bool Sensor::isDrawable() { return false; }
+bool Sensor::isPlanar() { return true; }
+
+} // End of namespace Freescape
diff --git a/engines/freescape/objects/sensor.h b/engines/freescape/objects/sensor.h
new file mode 100644
index 00000000000..a56c86b34e3
--- /dev/null
+++ b/engines/freescape/objects/sensor.h
@@ -0,0 +1,27 @@
+#ifndef FREESCAPE_SENSOR_H
+#define FREESCAPE_SENSOR_H
+
+#include "freescape/objects/object.h"
+
+namespace Freescape {
+
+class Sensor : public Object {
+public:
+
+	Sensor(
+		uint16 objectID,
+		const Math::Vector3d &origin,
+		const Math::Vector3d &rotation);
+	virtual ~Sensor();
+
+	bool isDrawable();
+	bool isPlanar();
+	Type getType() override { return Type::Sensor; };
+	Math::Vector3d getRotation() { return _rotation; }
+
+	void draw(Freescape::Renderer *gfx) override { error("cannot render sensor"); };
+};
+
+} // End of namespace Freescape
+
+#endif


Commit: 39fc195dc97560a76885a414dfc0cfb3efc88468
    https://github.com/scummvm/scummvm/commit/39fc195dc97560a76885a414dfc0cfb3efc88468
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:54+01:00

Commit Message:
FREESCAPE: improved collision detection when running effects

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index f5b821ce670..96f8fe8198f 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -118,7 +118,7 @@ void Area::draw(Freescape::Renderer *gfx) {
 Object *Area::shootRay(const Math::Ray &ray) {
 	float size = 16 * 8192; // TODO: check if this is max size
 	Object *collided = nullptr;
-	for (int i = 0; i < drawableObjects.size(); i++) {
+	for (int i = 0; i < int(drawableObjects.size()); i++) {
 		float objSize = drawableObjects[i]->getSize().length();
 		if (!drawableObjects[i]->isDestroyed() && !drawableObjects[i]->isInvisible()
 		  && drawableObjects[i]->_boundingBox.isValid()
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 50f14be20cf..7e504ff87c3 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -390,12 +390,15 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 			}
 			_position.set(_position.x(), positionY - fallen * areaScale, _position.z());
 		}
+		debug("Runing effects:");
 		checkCollisions(true); // run the effects
 	} else {
+		debug("Runing effects:");
 		checkCollisions(true); // run the effects
 		if (_currentArea->getAreaID() == previousAreaID) {
 			bool stepUp = tryStepUp(_position);
 			if (stepUp) {
+				debug("Runing effects:");
 				checkCollisions(true); // run the effects (again)
 			} else {
 				_position = previousPosition;
@@ -446,8 +449,16 @@ bool FreescapeEngine::tryStepDown(Math::Vector3d currentPosition) {
 bool FreescapeEngine::checkCollisions(bool executeConditions) {
 	int areaScale = _currentArea->getScale();
 
-	Math::Vector3d v1(_position.x() - _playerWidth / 2, _position.y() - areaScale * _playerHeight , _position.z() - _playerDepth / 2);
-	Math::Vector3d v2(_position.x() + _playerWidth / 2, _position.y()                             , _position.z() + _playerDepth / 2);
+	Math::Vector3d v1;
+	Math::Vector3d v2;
+
+	if (executeConditions) {
+		v1 = Math::Vector3d(_position.x() -  areaScale * 3 * _playerWidth / 4, _position.y() - (areaScale + 1) * _playerHeight , _position.z() - areaScale * 3 * _playerDepth / 4);
+		v2 = Math::Vector3d(_position.x() +  areaScale * 3 * _playerWidth / 4, _position.y()                             , _position.z() + areaScale * 3 * _playerDepth / 4);
+	} else {
+		v1 = Math::Vector3d(_position.x() - areaScale * _playerWidth / 2, _position.y() - areaScale * _playerHeight , _position.z() - areaScale * _playerDepth / 2);
+		v2 = Math::Vector3d(_position.x() + areaScale * _playerWidth / 2, _position.y()                             , _position.z() + areaScale * _playerDepth / 2);
+	}
 
 	const Math::AABB boundingBox(v1, v2);
 	Object *obj = _currentArea->checkCollisions(boundingBox);


Commit: f161f75250e7790db8d2b2ff4037138e5ad28951
    https://github.com/scummvm/scummvm/commit/f161f75250e7790db8d2b2ff4037138e5ad28951
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:54+01:00

Commit Message:
FREESCAPE: improved fcl parsing and load some global objects in driller

Changed paths:
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index 8029ea06618..4b7b38c6ea2 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -34,7 +34,7 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			0, 3, 1, 1, 1, 1, 2, 2,
 			2, 1, 1, 2, 1, 1, 2, 1,
 			1, 2, 2, 1, 2, 0, 0, 0,
-			1, 1, 0, 1, 1, 1, 1, 1, 2, 0, 1};
+			1, 1, 0, 1, 1, 1, 1, 1, 2, 2, 1};
 
 	while (bytePointer < sizeOfTokenisedContent) {
 		// get the conditional type of the next operation
@@ -228,6 +228,14 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			numberOfArguments = 0;
 			break;
 
+		case 33: // end condition if an object is invisible in another area
+			detokenisedStream += "IF RINVIS? ";
+			detokenisedStream += Common::String::format("(%d), (%d)", (int)tokenisedCondition[bytePointer], (int)tokenisedCondition[bytePointer + 1]);
+			detokenisedStream += "THEN END ENDIF";
+			bytePointer += 2;
+			numberOfArguments = 0;
+			break;
+
 		case 34: // show a message on screen
 			detokenisedStream += "MESSAGE (";
 			break;
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index b65609d83d0..a3621cc2e41 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -351,7 +351,7 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 		debug("%s", conditionSource->c_str());
 	}
 
-	if (_targetName.hasPrefix("castlemaster"))
+	if (_targetName.hasPrefix("castlemaster") || _targetName.hasPrefix("totaleclipse"))
 		area->addFloor();
 
 	debug("End of area at %lx", file->pos());
@@ -381,13 +381,17 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	uint8 startEntrance = file->readByte();
 	debug("Entrace area: %d", startEntrance);
 
-	file->seek(0x42, SEEK_CUR);
+	file->seek(0x46, SEEK_CUR);
 
 	uint16 globalSomething;
-	globalSomething = file->readUint16BE();
+	globalSomething = file->readUint16LE();
 	debug("Pointer to something: %x\n", globalSomething);
 
-	file->seek(offset + 0x48);
+	if (_targetName.hasPrefix("driller")) {
+		file->seek(0x3b42);
+		for (int i = 0; i < 8; i++)
+			load8bitObject(file);
+	}
 
 	uint16 globalByteCodeTable;
 	globalByteCodeTable = file->readUint16LE();


Commit: 0206ca09984ba26af2c445654338986a1a13b46f
    https://github.com/scummvm/scummvm/commit/0206ca09984ba26af2c445654338986a1a13b46f
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:55+01:00

Commit Message:
FREESCAPE: improved rendering in eclipse

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/freescape.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/objects/geometricobject.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 96f8fe8198f..f3bb8cacf98 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -105,14 +105,16 @@ void Area::draw(Freescape::Renderer *gfx) {
 	gfx->clear();
 	if (skyColor != 255)
 		gfx->drawSky(skyColor);
+
+	if (groundColor != 255)
+		gfx->drawFloor(groundColor);
+
 	assert(drawableObjects.size() > 0);
 	for (Common::Array<Object *>::iterator it = drawableObjects.begin(); it != drawableObjects.end(); it++) {
 		if (!(*it)->isDestroyed() && !(*it)->isInvisible()) {
 			(*it)->draw(gfx);
 		}
 	}
-	if (groundColor != 255)
-		gfx->drawFloor(groundColor);
 }
 
 Object *Area::shootRay(const Math::Ray &ray) {
@@ -153,6 +155,7 @@ void Area::addFloor() {
 	Common::Array<uint8> *gColors = new Common::Array<uint8>;
 	for (int i = 0; i < 6; i++)
 		gColors->push_back(groundColor);
+
 	GeometricObject *floor = new GeometricObject(
 		Object::Type::Cube,
 		200,
@@ -163,7 +166,7 @@ void Area::addFloor() {
 		nullptr,
 		empty
 	);
-	drawableObjects.push_back(floor);
+	drawableObjects.insert_at(0, floor);
 }
 
 } // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 7e504ff87c3..812e9e640de 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -249,6 +249,7 @@ void FreescapeEngine::shoot() {
 	Object *shot = _currentArea->shootRay(ray);
 	if (shot) {
 		GeometricObject *gobj = (GeometricObject*) shot;
+		debug("Shot object %d with flags %x", gobj->getObjectID(), gobj->getObjectFlags());
 		if (gobj->conditionSource != nullptr) {
 			debug("Must use shot = true when executing: %s", gobj->conditionSource->c_str());
 			executeCode(gobj->condition, true, false);
@@ -286,6 +287,8 @@ Common::Error FreescapeEngine::run() {
 		_farClipPlane = 14189.f;
 	} else {
 		_farClipPlane = 8192.f;
+		if (!_targetName.hasPrefix("driller"))
+			_gfx->_keyColor = 0;
 	}
 
 	if (_border) {
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index a3621cc2e41..9576e33acf6 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -278,10 +278,10 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	uint8 skyColor = 255;
 	uint8 groundColor = 255;
 	if (_targetName != "castlemaster") {
+		groundColor = file->readByte() & 15;
+		skyColor = file->readByte() & 15;
 		ci1 = file->readByte() & 15;
 		ci2 = file->readByte() & 15;
-		skyColor = file->readByte() & 15;
-		groundColor = file->readByte() & 15;
 		debug("Colors: %d %d %d %d", ci1, ci2, skyColor, groundColor);
 	} else {
 		skyColor = file->readByte() & 15;
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index 7ade654faf2..590c468f70b 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -114,6 +114,9 @@ GeometricObject::GeometricObject(
 	Common::String *_conditionSource) {
 	_type = type;
 	_flags = flags;
+	if (flags & 0x40)
+		makeInvisible();
+
 	_objectID = objectID;
 	origin = _origin;
 	size = _size;


Commit: 0a684948453bef730218bb98f61cf2c8c0b013fb
    https://github.com/scummvm/scummvm/commit/0a684948453bef730218bb98f61cf2c8c0b013fb
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:55+01:00

Commit Message:
FREESCAPE: improved rendering in castle

Changed paths:
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 9576e33acf6..ee71fc220b9 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -202,12 +202,12 @@ byte castleCGA[4][3] = {
 
 byte castleEGA[16][3] = {
 	{0x00, 0x00, 0x00},
-	{0x00, 0xaa, 0x00},
+	{0x00, 0x00, 0x00},
 	{0x00, 0xaa, 0xaa},
 	{0x00, 0xaa, 0xaa},
 	{0xaa, 0xaa, 0xaa},
 	{0x55, 0x55, 0x55},
-	{0x00, 0x00, 0x00},
+	{0x00, 0xaa, 0x00},
 	{0xaa, 0x55, 0x00},
 	{0x12, 0xf3, 0x56},
 	{0xaa, 0x00, 0x00},
@@ -284,8 +284,8 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 		ci2 = file->readByte() & 15;
 		debug("Colors: %d %d %d %d", ci1, ci2, skyColor, groundColor);
 	} else {
-		skyColor = file->readByte() & 15;
 		groundColor = file->readByte() & 15;
+		skyColor = file->readByte() & 15;
 		debug("Colors: %d %d", skyColor, groundColor);
 	}
 


Commit: 10b26d1afc31dbe8a13493ee3b5b6f87c6e09797
    https://github.com/scummvm/scummvm/commit/10b26d1afc31dbe8a13493ee3b5b6f87c6e09797
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:55+01:00

Commit Message:
FREESCAPE: refactor some code for eclipse

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/freescape.cpp
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index f3bb8cacf98..af4774a6b3f 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -150,23 +150,89 @@ Object *Area::checkCollisions(const Math::AABB &boundingBox) {
 	return collided;
 }
 
-void Area::addFloor() {
+void Area::addStructure() {
+
+	Object *data = (*entrancesByID)[255];
+
+	if (data == nullptr)
+		return;
+
 	FCLInstructionVector empty;
 	Common::Array<uint8> *gColors = new Common::Array<uint8>;
 	for (int i = 0; i < 6; i++)
-		gColors->push_back(groundColor);
+		gColors->push_back(0xd);
+
+	int id = 200;
+	GeometricObject *gobj = nullptr;
+
+	// Floor
+	gobj = new GeometricObject(
+		Object::Type::Cube,
+		id,
+		0, // flags
+		Math::Vector3d(0, 1, 0), // Position
+		Math::Vector3d(128 * 32, 1, 135 * 32), // size
+		gColors,
+		nullptr,
+		empty
+	);
+	(*objectsByID)[id] = (Object*) gobj;
+	drawableObjects.insert_at(0, gobj);
+
+	gColors = new Common::Array<uint8>;
+	for (int i = 0; i < 6; i++)
+		gColors->push_back(0x0);
+
+	// East Wall
+	id++;
+	gobj = new GeometricObject(
+		Object::Type::Cube,
+		id,
+		0, // flags
+		//Math::Vector3d(-64 + 22*32, 0, 0), // Position
+		Math::Vector3d(22*32, 0, 0), // Position
+
+		Math::Vector3d(1, 8128, 8128), // size
+		gColors,
+		nullptr,
+		empty
+	);
+	(*objectsByID)[id] = (Object*) gobj;
+	drawableObjects.insert_at(0, gobj);
+
+	// West Wall
+	id++;
+	gobj = new GeometricObject(
+		Object::Type::Cube,
+		id,
+		0, // flags
+		Math::Vector3d(2*22*32, 0, 0), // Position
+		Math::Vector3d(1, 8128, 8128), // size
+		gColors,
+		nullptr,
+		empty
+	);
+	(*objectsByID)[id] = (Object*) gobj;
+	drawableObjects.insert_at(0, gobj);
+
+	gColors = new Common::Array<uint8>;
+	for (int i = 0; i < 6; i++)
+		gColors->push_back(0xe);
 
-	GeometricObject *floor = new GeometricObject(
+	// North Wall
+	id++;
+	gobj = new GeometricObject(
 		Object::Type::Cube,
-		200,
+		id,
 		0, // flags
-		Math::Vector3d(0, -64, 0), // Position
-		Math::Vector3d(8128, 64, 8128), // size
+		Math::Vector3d(0, 0, 2080), // Position
+		Math::Vector3d(8128, 8128, 1), // size
 		gColors,
 		nullptr,
 		empty
 	);
-	drawableObjects.insert_at(0, floor);
+	(*objectsByID)[id] = (Object*) gobj;
+	drawableObjects.insert_at(0, gobj);
 }
 
 } // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index e8aea215c4e..950722166af 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -45,7 +45,7 @@ public:
 
 	Object *shootRay(const Math::Ray &ray);
 	Object *checkCollisions(const Math::AABB &boundingBox);
-	void addFloor();
+	void addStructure();
 
 	Common::Array<Common::String*> conditionSources;
 	Common::Array<FCLInstructionVector> conditions;
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 812e9e640de..c5fc013e2fd 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -209,6 +209,8 @@ void FreescapeEngine::processInput() {
 				_position.setValue(1, _position.y() + 12);
 			else if (event.kbd.keycode == Common::KEYCODE_v)
 				_position.setValue(1, _position.y() - 12);
+			else if (event.kbd.keycode == Common::KEYCODE_n)
+				gotoArea(_currentArea->getAreaID() + 1, 0);
 			break;
 
 		case Common::EVENT_QUIT:
@@ -374,6 +376,7 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 	int areaScale = _currentArea->getScale();
 	// restore y coordinate
 	_position.set(_position.x(), positionY, _position.z());
+
 	bool collided = checkCollisions(false);
 
 	if (!collided) {
@@ -482,7 +485,7 @@ void FreescapeEngine::gotoArea(uint16 areaID, uint16 entranceID) {
 	debug("go to area: %d, entrance: %d", areaID, entranceID);
 
 	assert(_areasByAreaID->contains(areaID));
-	assert(entranceID > 0);
+	//assert(entranceID > 0);
 	_currentArea = (*_areasByAreaID)[areaID];
 	_currentArea->show();
 
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 7f08e1fe947..09523a8161d 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -446,64 +446,76 @@ void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vec
 
 	Common::Array<Math::Vector3d> face;
 	uint8 r, g, b;
-	_palette->getRGBAt((*colours)[0], r, g, b);
-	tglColor3ub(r, g, b);
+	if ((*colours)[0] != _keyColor) {
+		_palette->getRGBAt((*colours)[0], r, g, b);
+		tglColor3ub(r, g, b);
 
-	face.push_back(vertices[5]);
-	face.push_back(vertices[6]);
-	face.push_back(vertices[2]);
-	face.push_back(vertices[1]);
-	renderFace(face);
-	face.clear();
+		face.push_back(vertices[5]);
+		face.push_back(vertices[6]);
+		face.push_back(vertices[2]);
+		face.push_back(vertices[1]);
+		renderFace(face);
+		face.clear();
+	}
 
-	_palette->getRGBAt((*colours)[1], r, g, b);
-	tglColor3ub(r, g, b);
+	if ((*colours)[1] != _keyColor) {
+		_palette->getRGBAt((*colours)[1], r, g, b);
+		tglColor3ub(r, g, b);
 
-	face.push_back(vertices[7]);
-	face.push_back(vertices[4]);
-	face.push_back(vertices[0]);
-	face.push_back(vertices[3]);
-	renderFace(face);
-	face.clear();
+		face.push_back(vertices[7]);
+		face.push_back(vertices[4]);
+		face.push_back(vertices[0]);
+		face.push_back(vertices[3]);
+		renderFace(face);
+		face.clear();
+	}
 
-	_palette->getRGBAt((*colours)[2], r, g, b);
-	tglColor3ub(r, g, b);
+	if ((*colours)[2] != _keyColor) {
+		_palette->getRGBAt((*colours)[2], r, g, b);
+		tglColor3ub(r, g, b);
 
-	face.push_back(vertices[4]);
-	face.push_back(vertices[5]);
-	face.push_back(vertices[1]);
-	face.push_back(vertices[0]);
-	renderFace(face);
-	face.clear();
+		face.push_back(vertices[4]);
+		face.push_back(vertices[5]);
+		face.push_back(vertices[1]);
+		face.push_back(vertices[0]);
+		renderFace(face);
+		face.clear();
+	}
 
-	_palette->getRGBAt((*colours)[3], r, g, b);
-	tglColor3ub(r, g, b);
+	if ((*colours)[3] != _keyColor) {
+		_palette->getRGBAt((*colours)[3], r, g, b);
+		tglColor3ub(r, g, b);
 
-	face.push_back(vertices[6]);
-	face.push_back(vertices[7]);
-	face.push_back(vertices[3]);
-	face.push_back(vertices[2]);
-	renderFace(face);
-	face.clear();
+		face.push_back(vertices[6]);
+		face.push_back(vertices[7]);
+		face.push_back(vertices[3]);
+		face.push_back(vertices[2]);
+		renderFace(face);
+		face.clear();
+	}
 
-	_palette->getRGBAt((*colours)[4], r, g, b);
-	tglColor3ub(r, g, b);
+	if ((*colours)[4] != _keyColor) {
+		_palette->getRGBAt((*colours)[4], r, g, b);
+		tglColor3ub(r, g, b);
 
-	face.push_back(vertices[0]);
-	face.push_back(vertices[1]);
-	face.push_back(vertices[2]);
-	face.push_back(vertices[3]);
-	renderFace(face);
-	face.clear();
+		face.push_back(vertices[0]);
+		face.push_back(vertices[1]);
+		face.push_back(vertices[2]);
+		face.push_back(vertices[3]);
+		renderFace(face);
+		face.clear();
+	}
 
-	_palette->getRGBAt((*colours)[5], r, g, b);
-	tglColor3ub(r, g, b);
+	if ((*colours)[5] != _keyColor) {
+		_palette->getRGBAt((*colours)[5], r, g, b);
+		tglColor3ub(r, g, b);
 
-	face.push_back(vertices[7]);
-	face.push_back(vertices[6]);
-	face.push_back(vertices[5]);
-	face.push_back(vertices[4]);
-	renderFace(face);
+		face.push_back(vertices[7]);
+		face.push_back(vertices[6]);
+		face.push_back(vertices[5]);
+		face.push_back(vertices[4]);
+		renderFace(face);
+	}
 }
 
 void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector3d &size, Common::Array<uint8> *colours) {
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index ee71fc220b9..713a218d90e 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -129,7 +129,10 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 		if (byteSizeOfObject > 0) {
 			// TODO: there is something here
 			debug("Warning: extra %d bytes in entrance", byteSizeOfObject);
-			file->seek(byteSizeOfObject, SEEK_CUR);
+			//file->seek(byteSizeOfObject, SEEK_CUR);
+			while (byteSizeOfObject--) {
+				debug("b: %x", file->readByte());
+			}
 			byteSizeOfObject = 0;
 		}
 		assert(byteSizeOfObject == 0);
@@ -227,7 +230,7 @@ byte eclipseEGA[16][3] = {
 	{0x54, 0xfc, 0xfc},
 	{0x00, 0x00, 0xA8},
 	{0x00, 0x00, 0xaa},
-	{0xaa, 0x55, 0x00},
+	{0xaa, 0x00, 0xaa},
 	{0x12, 0xf3, 0x56},
 	{0xaa, 0x00, 0x00},
 	{0xff, 0x55, 0xff},
@@ -280,8 +283,8 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	if (_targetName != "castlemaster") {
 		groundColor = file->readByte() & 15;
 		skyColor = file->readByte() & 15;
-		ci1 = file->readByte() & 15;
-		ci2 = file->readByte() & 15;
+		ci1 = file->readByte();
+		ci2 = file->readByte();
 		debug("Colors: %d %d %d %d", ci1, ci2, skyColor, groundColor);
 	} else {
 		groundColor = file->readByte() & 15;
@@ -300,9 +303,12 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	debug("Skipped: %d Objects: %d", skippedValue, numberOfObjects);
 	//debug("Condition Ptr: %x", cPtr);
 	debug("Pos before first object: %lx", file->pos());
-
 	if (_targetName == "totaleclipse") {
-		file->seek(5, SEEK_CUR);
+		debug("b: %x", file->readByte());
+		debug("b: %x", file->readByte());
+		debug("b: %x", file->readByte());
+		debug("b: %x", file->readByte());
+		debug("b: %x", file->readByte());
 	} else if (_targetName != "castlemaster")
 		file->seek(15, SEEK_CUR);
 
@@ -313,8 +319,6 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 		Object *newObject = load8bitObject(file);
 
 		if (newObject) {
-			//if (newObject->getObjectID() == 255) // TODO: fix me?
-			//	break;
 			if (newObject->getType() == Object::Entrance) {
 				if (entrancesByID->contains(newObject->getObjectID() & 0x7fff))
 					error("WARNING: replacing object id %d (%d)", newObject->getObjectID(), newObject->getObjectID() & 0x7fff);
@@ -325,7 +329,8 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 					error("WARNING: replacing object id %d", newObject->getObjectID());
 				(*objectsByID)[newObject->getObjectID()] = newObject;
 			}
-		}
+		} else
+			error("Failed to read an object!");
 	}
 	long int endLastObject = file->pos();
 	debug("Last position %lx", endLastObject);
@@ -352,7 +357,7 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	}
 
 	if (_targetName.hasPrefix("castlemaster") || _targetName.hasPrefix("totaleclipse"))
-		area->addFloor();
+		area->addStructure();
 
 	debug("End of area at %lx", file->pos());
 	return area;


Commit: c9effe93123ca1c495ca076d70b4299505106dfe
    https://github.com/scummvm/scummvm/commit/c9effe93123ca1c495ca076d70b4299505106dfe
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:55+01:00

Commit Message:
FREESCAPE: start in area 1 when using 3dck games

Changed paths:
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index c5fc013e2fd..a59d509b8bc 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -274,7 +274,6 @@ Common::Error FreescapeEngine::run() {
 	_gfx->init();
 	_gfx->clear();
 	loadAssets();
-	gotoArea(_startArea, _startEntrance);
 	debug("FreescapeEngine::init");
 	// Simple main event loop
 	_lastMousePos = Common::Point(0, 0);
@@ -287,6 +286,7 @@ Common::Error FreescapeEngine::run() {
 		_gfx->_keyColor = 0;
 		// the 16-bit kit permits the range 0-8192 to be used along all three axes and from that comes the far plane distance of 14189.
 		_farClipPlane = 14189.f;
+		_startArea = 1;
 	} else {
 		_farClipPlane = 8192.f;
 		if (!_targetName.hasPrefix("driller"))
@@ -304,6 +304,7 @@ Common::Error FreescapeEngine::run() {
 		_border->fillRect(viewArea, 0xA0A0A0FF);
 	}
 
+	gotoArea(_startArea, _startEntrance);
 	debug("Starting area %d", _currentArea->getAreaID());
 	while (!shouldQuit()) {
 		drawFrame();


Commit: c4e0484271c8cbba97f552fe80905d0ea236dcda
    https://github.com/scummvm/scummvm/commit/c4e0484271c8cbba97f552fe80905d0ea236dcda
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:55+01:00

Commit Message:
FREESCAPE: fixed parsing of global bytecode table

Changed paths:
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 713a218d90e..c2f106f8820 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -386,18 +386,12 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	uint8 startEntrance = file->readByte();
 	debug("Entrace area: %d", startEntrance);
 
-	file->seek(0x46, SEEK_CUR);
+	file->seek(offset + 0x46); // 0x46
 
 	uint16 globalSomething;
 	globalSomething = file->readUint16LE();
 	debug("Pointer to something: %x\n", globalSomething);
 
-	if (_targetName.hasPrefix("driller")) {
-		file->seek(0x3b42);
-		for (int i = 0; i < 8; i++)
-			load8bitObject(file);
-	}
-
 	uint16 globalByteCodeTable;
 	globalByteCodeTable = file->readUint16LE();
 	debug("GBCT: %d\n", globalByteCodeTable);
@@ -419,6 +413,12 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 		debug("%s", conditions->c_str());
 	}
 
+	if (_targetName.hasPrefix("driller")) {
+		file->seek(0x3b42);
+		for (int i = 0; i < 8; i++)
+			load8bitObject(file);
+	}
+
 	if (_targetName != "castlemaster")
 		file->seek(offset + 0xc8);
 	else


Commit: eedc9f213b1260e87562c8dfa30ba7b874ec4030
    https://github.com/scummvm/scummvm/commit/eedc9f213b1260e87562c8dfa30ba7b874ec4030
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:55+01:00

Commit Message:
FREESCAPE: refactored bit operations and removed unused code

Changed paths:
  R engines/freescape/gamestate.h
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/language/instruction.cpp
    engines/freescape/language/token.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index a59d509b8bc..aaca820f169 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -318,13 +318,8 @@ Common::Error FreescapeEngine::run() {
 }
 
 void FreescapeEngine::initGameState() {
-	_areaBits.resize(33);
-	for (int16 i = 0; i <= 32; i++) {
-		_areaBits[i] = false;
-	}
-
-	_gameState[k8bitVariableEnergy] = 100;
-	_gameState[k8bitVariableShield] = 100;
+	_gameStateVars[k8bitVariableEnergy] = 100;
+	_gameStateVars[k8bitVariableShield] = 100;
 }
 
 void FreescapeEngine::rotate(Common::Point lastMousePos, Common::Point mousePos) {
@@ -484,6 +479,8 @@ bool FreescapeEngine::checkCollisions(bool executeConditions) {
 
 void FreescapeEngine::gotoArea(uint16 areaID, uint16 entranceID) {
 	debug("go to area: %d, entrance: %d", areaID, entranceID);
+	if (!_gameStateBits.contains(areaID))
+		_gameStateBits[areaID] = 0;
 
 	assert(_areasByAreaID->contains(areaID));
 	//assert(entranceID > 0);
@@ -505,10 +502,6 @@ void FreescapeEngine::gotoArea(uint16 areaID, uint16 entranceID) {
 
 	_pitch = _rotation.x() - 180.f;
 	_yaw = _rotation.y() - 180.f;
-
-	for (int16 i = 0; i <= 32; i++) {
-		_areaBits[i] = false;
-	}
 	debug("starting player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
 }
 
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index fa2c4ed5d6b..fd2c0cc1511 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -161,8 +161,8 @@ public:
 
 	// Game state
 	void initGameState();
-	Common::HashMap<uint16, int32> _gameState;
-	Common::Array<bool> _areaBits;
+	Common::HashMap<uint16, int32> _gameStateVars;
+	Common::HashMap<uint16, uint32> _gameStateBits;
 
 	bool hasFeature(EngineFeature f) const override;
 	bool canLoadGameStateCurrently() override { return true; }
diff --git a/engines/freescape/gamestate.h b/engines/freescape/gamestate.h
deleted file mode 100644
index 3d3b36a4335..00000000000
--- a/engines/freescape/gamestate.h
+++ /dev/null
@@ -1,20 +0,0 @@
-//
-//  GameState.h
-//  Phantasma
-//
-//  Created by Thomas Harte on 08/12/2013.
-//  Copyright (c) 2013 Thomas Harte. All rights reserved.
-//
-
-#ifndef __Phantasma__GameState__
-#define __Phantasma__GameState__
-
-//#include <iostream>
-
-class CGameState {
-public:
-	int32_t getVariable(int32_t variableNumber);
-	bool getBit(int32_t bitNumber);
-};
-
-#endif /* defined(__Phantasma__GameState__) */
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index faf7267a6bc..a83bd434f22 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -148,27 +148,27 @@ bool FreescapeEngine::executeEndIfNotEqual(FCLInstruction &instruction) {
 	uint16 variable = instruction.source;
 	uint16 value = instruction.destination;
 	debug("End condition if variable %d is not equal to %d!", variable, value);
-	return (_gameState[variable] != value);
+	return (_gameStateVars[variable] != value);
 }
 
 void FreescapeEngine::executeIncrementVariable(FCLInstruction &instruction) {
 	uint16 variable = instruction.source;
 	uint16 increment = instruction.destination;
-	_gameState[variable] = _gameState[variable] + increment;
+	_gameStateVars[variable] = _gameStateVars[variable] + increment;
 	if (variable == k8bitVariableScore) {
-		debug("Score incremented by %d up to %d", increment, _gameState[variable]);
+		debug("Score incremented by %d up to %d", increment, _gameStateVars[variable]);
 	} else
-		debug("Variable %d by %d incremented up to %d!", variable, increment, _gameState[variable]);
+		debug("Variable %d by %d incremented up to %d!", variable, increment, _gameStateVars[variable]);
 }
 
 void FreescapeEngine::executeDecrementVariable(FCLInstruction &instruction) {
 	uint16 variable = instruction.source;
 	uint16 decrement = instruction.destination;
-	_gameState[variable] = _gameState[variable] - decrement;
+	_gameStateVars[variable] = _gameStateVars[variable] - decrement;
 	if (variable == k8bitVariableEnergy) {
-		debug("Energy decrement by %d up to %d", decrement, _gameState[variable]);
+		debug("Energy decrement by %d up to %d", decrement, _gameStateVars[variable]);
 	} else
-		debug("Variable %d by %d incremented up to %d!", variable, decrement, _gameState[variable]);
+		debug("Variable %d by %d incremented up to %d!", variable, decrement, _gameStateVars[variable]);
 }
 
 void FreescapeEngine::executeDestroy(FCLInstruction &instruction) {
@@ -234,28 +234,32 @@ void FreescapeEngine::executeGoto(FCLInstruction &instruction) {
 }
 
 void FreescapeEngine::executeSetBit(FCLInstruction &instruction) {
-	uint16 index = instruction.source;
-	_areaBits[index] = true;
+	uint16 index = instruction.source - 1; // Starts in 1
+	assert(index < 32);
+	_gameStateBits[_currentArea->getAreaID()] |= (1 << index);
 	debug("Setting bit %d", index);
+	//debug("v: %d", (_gameStateBits[_currentArea->getAreaID()] & (1 << index)));
 }
 
 void FreescapeEngine::executeClearBit(FCLInstruction &instruction) {
-	uint16 index = instruction.source;
-	_areaBits[index] = false;
+	uint16 index = instruction.source - 1; // Starts in 1
+	assert(index < 32);
+	_gameStateBits[_currentArea->getAreaID()] &= ~(1 << index);
 	debug("Clearing bit %d", index);
 }
 
 void FreescapeEngine::executeToggleBit(FCLInstruction &instruction) {
-	uint16 index = instruction.source;
-	_areaBits[index] = !_areaBits[index];
+	uint16 index = instruction.source - 1; // Starts in 1
+	_gameStateBits[_currentArea->getAreaID()] ^= (1 << index);
 	debug("Toggling bit %d", index);
 }
 
 bool FreescapeEngine::executeEndIfBitNotEqual(FCLInstruction &instruction) {
-	uint16 index = instruction.source;
+	uint16 index = instruction.source - 1; // Starts in 1
 	uint16 value = instruction.destination;
+	assert(index < 32);
 	debug("End condition if bit %d is not equal to %d!", index, value);
-	return (_areaBits[index] != value);
+	return (((_gameStateBits[_currentArea->getAreaID()] >> index) & 1) != value);
 }
 
 } // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/language/token.h b/engines/freescape/language/token.h
index 7060693483f..a995a51a122 100644
--- a/engines/freescape/language/token.h
+++ b/engines/freescape/language/token.h
@@ -11,8 +11,6 @@
 
 #include "common/str.h"
 
-#include "freescape/gamestate.h"
-
 namespace Freescape {
 
 struct Token {
@@ -87,7 +85,6 @@ public:
 		VARNOTEQ
 	};
 
-	int32_t getValue(CGameState &, int32 suggestedValue = 0);
 	Type getType();
 
 	Token() {


Commit: 2500e5859733501794591061d73bdad68f8b23d6
    https://github.com/scummvm/scummvm/commit/2500e5859733501794591061d73bdad68f8b23d6
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:56+01:00

Commit Message:
FREESCAPE: fixed entrance angle when changing areas

Changed paths:
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index aaca820f169..07ef55f7f70 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -323,6 +323,8 @@ void FreescapeEngine::initGameState() {
 }
 
 void FreescapeEngine::rotate(Common::Point lastMousePos, Common::Point mousePos) {
+	if (lastMousePos == Common::Point(0, 0))
+		return;
 	//debug("x: %d, y: %d", mousePos.x, mousePos.y);
 	float xoffset = mousePos.x - lastMousePos.x;
 	float yoffset = mousePos.y - lastMousePos.y;
@@ -492,16 +494,18 @@ void FreescapeEngine::gotoArea(uint16 areaID, uint16 entranceID) {
 		entrance = (Entrance*) _currentArea->firstEntrance();
 
 	_position = entrance->getOrigin();
-	_rotation = entrance->getRotation();
+	if (_rotation == Math::Vector3d(0, 0, 0)) {
+		_rotation = entrance->getRotation();
+		debug("yaw: %f, pitch: %f", _rotation.x(), _rotation.y());
+		_pitch = _rotation.x();
+		_yaw = _rotation.y() - 260;
+	}
 	int scale = _currentArea->getScale();
 	assert(scale > 0);
 
 	debug("entrace position: %f %f %f", _position.x(), _position.y(), _position.z());
 	debug("player height: %d", scale * _playerHeight);
 	_position.setValue(1, _position.y() + scale * _playerHeight);
-
-	_pitch = _rotation.x() - 180.f;
-	_yaw = _rotation.y() - 180.f;
 	debug("starting player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
 }
 


Commit: 5d2b569d12ca83c9c2f43cf8065612484ba478ca
    https://github.com/scummvm/scummvm/commit/5d2b569d12ca83c9c2f43cf8065612484ba478ca
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:56+01:00

Commit Message:
FREESCAPE: correct viewport for driller

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/gfx.cpp
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/gfx_tinygl.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 07ef55f7f70..523cecbf33b 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -77,10 +77,14 @@ void FreescapeEngine::drawBorder() {
 	if (!_border)
 		return;
 
+	const Common::Rect fullscreenViewArea(0, 0, _screenW, _screenH);
+	_gfx->setViewport(fullscreenViewArea);
+
 	if (!_borderTexture)
 		_borderTexture = _gfx->createTexture(_border);
-	const Common::Rect rect(0, 0, _screenW, _screenH);
-	_gfx->drawTexturedRect2D(rect, rect, _borderTexture);
+	_gfx->drawTexturedRect2D(fullscreenViewArea, fullscreenViewArea, _borderTexture);
+	Common::Rect drillerViewArea(40, 16, 279, 116);
+	_gfx->setViewport(drillerViewArea);
 }
 
 void FreescapeEngine::loadAssets() {
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index 0252f046600..1983008568b 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -95,19 +95,7 @@ Common::Rect Renderer::viewport() const {
 void Renderer::computeScreenViewport() {
 	int32 screenWidth = _system->getWidth();
 	int32 screenHeight = _system->getHeight();
-
-	/*if (ConfMan.getBool("widescreen_mod")) {
-		_screenViewport = Common::Rect(screenWidth, screenHeight);
-	} else {*/
-		// Aspect ratio correction
-		int32 viewportWidth = MIN<int32>(screenWidth, screenHeight * kOriginalWidth / kOriginalHeight);
-		int32 viewportHeight = MIN<int32>(screenHeight, screenWidth * kOriginalHeight / kOriginalWidth);
-		_screenViewport = Common::Rect(viewportWidth, viewportHeight);
-		//_rscreenViewport = Common::Rect(vmargin, tmargin, _screenViewport.right - vmargin, _screenViewport.bottom - bmargin);
-
-		// Pillarboxing
-		_screenViewport.translate((screenWidth - viewportWidth) / 2, (screenHeight - viewportHeight) / 2);
-	//}
+	_screenViewport = Common::Rect(screenWidth, screenHeight);
 }
 
 Renderer *createRenderer(OSystem *system) {
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index c85b03c2c03..a9979bfc6b6 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -67,6 +67,7 @@ public:
 
 	virtual void init() = 0;
 	virtual void clear() = 0;
+	virtual void setViewport(const Common::Rect &rect) = 0;
 
 	typedef enum {
 		EastPyramid = 4,
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 09523a8161d..f2415d46189 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -79,6 +79,11 @@ void TinyGLRenderer::init() {
 
 }
 
+void TinyGLRenderer::setViewport(const Common::Rect &rect) {
+	tglViewport(rect.left, g_system->getHeight() - rect.bottom, rect.width(), rect.height());
+}
+
+
 void TinyGLRenderer::clear() {
 	tglClear(TGL_COLOR_BUFFER_BIT | TGL_DEPTH_BUFFER_BIT);
 	tglColor3f(1.0f, 1.0f, 1.0f);
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index 9c1e976b981..974c4aaf0ae 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -39,6 +39,7 @@ public:
 
 	virtual void init() override;
 	virtual void clear() override;
+	virtual void setViewport(const Common::Rect &rect) override;
 	virtual void positionCamera(const Math::Vector3d &pos, const Math::Vector3d &interest) override;
 	virtual void updateProjectionMatrix(float fov, float nearClipPlane, float farClipPlane) override;
 


Commit: 78b2ea28cf0148c9aca38cb634324516604c32a5
    https://github.com/scummvm/scummvm/commit/78b2ea28cf0148c9aca38cb634324516604c32a5
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:56+01:00

Commit Message:
FREESCAPE: fixed code style

Changed paths:
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 523cecbf33b..3302afa2877 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -227,13 +227,13 @@ void FreescapeEngine::processInput() {
 			rotate(_lastMousePos, mousePos);
 			_lastMousePos = mousePos;
 			if (mousePos.x <= 5 || mousePos.x >= _screenW - 5) {
-				g_system->warpMouse(_screenW/2, mousePos.y);
-				_lastMousePos.x = _screenW/2;
+				g_system->warpMouse(_screenW / 2, mousePos.y);
+				_lastMousePos.x = _screenW / 2;
 				_lastMousePos.y = mousePos.y;
 			} else if (mousePos.y <= 5 || mousePos.y >= _screenH - 5) {
-				g_system->warpMouse(mousePos.x, _screenH/2);
+				g_system->warpMouse(mousePos.x, _screenH / 2);
 				_lastMousePos.x = mousePos.x;
-				_lastMousePos.y = _screenH/2;
+				_lastMousePos.y = _screenH / 2;
 			}
 			break;
 


Commit: 1f55d4b03decab831c08a97f105bb22bb503f87d
    https://github.com/scummvm/scummvm/commit/1f55d4b03decab831c08a97f105bb22bb503f87d
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:56+01:00

Commit Message:
FREESCAPE: added fly mode and improved entrance handling

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 3302afa2877..b5a305ebe67 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -43,11 +43,13 @@ FreescapeEngine::FreescapeEngine(OSystem *syst)
 	_currentArea = nullptr;
 	_rotation = Math::Vector3d(0.f, 0.f, 0.f);
 	_position = Math::Vector3d(0.f, 0.f, 0.f);
+	_lastPosition = Math::Vector3d(0.f, 0.f, 0.f);
 	_velocity = Math::Vector3d(0.f, 0.f, 0.f);
 	_cameraFront = Math::Vector3d(0.f, 0.f, 0.f);
 	_cameraRight = Math::Vector3d(0.f, 0.f, 0.f);
 	_movementSpeed = 1.5f;
 	_mouseSensitivity = 0.1f;
+	_flyMode = false;
 	_borderTexture = nullptr;
 
 	// Here is the right place to set up the engine specific debug channels
@@ -356,7 +358,6 @@ void FreescapeEngine::rotate(Common::Point lastMousePos, Common::Point mousePos)
 
 void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTime) {
 	debug("old player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
-	Math::Vector3d previousPosition = _position;
 	int previousAreaID = _currentArea->getAreaID();
 
 	float velocity = _movementSpeed * deltaTime;
@@ -377,13 +378,14 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 	}
 	int areaScale = _currentArea->getScale();
 	// restore y coordinate
-	_position.set(_position.x(), positionY, _position.z());
+	if (!_flyMode)
+		_position.set(_position.x(), positionY, _position.z());
 
 	bool collided = checkCollisions(false);
 
 	if (!collided) {
 		bool hasFloor = checkFloor(_position);
-		if (!hasFloor) {
+		if (!hasFloor  && !_flyMode) {
 			int fallen;
 			for (fallen = 1; fallen < 65 + 1; fallen++) {
 				_position.set(_position.x(), positionY - fallen * areaScale, _position.z());
@@ -393,7 +395,7 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 			fallen++;
 			fallen++;
 			if (fallen >= 67) {
-				_position = previousPosition; //error("NASTY FALL!");
+				_position = _lastPosition; //error("NASTY FALL!");
 				return;
 			}
 			_position.set(_position.x(), positionY - fallen * areaScale, _position.z());
@@ -403,16 +405,19 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 	} else {
 		debug("Runing effects:");
 		checkCollisions(true); // run the effects
-		if (_currentArea->getAreaID() == previousAreaID) {
+		if (_flyMode)
+			_position = _lastPosition;
+		else if (_currentArea->getAreaID() == previousAreaID) {
 			bool stepUp = tryStepUp(_position);
 			if (stepUp) {
 				debug("Runing effects:");
 				checkCollisions(true); // run the effects (again)
 			} else {
-				_position = previousPosition;
+				_position = _lastPosition;
 			}
 		}
 	}
+	_lastPosition = _position;
 	debug("new player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
 }
 
@@ -489,27 +494,40 @@ void FreescapeEngine::gotoArea(uint16 areaID, uint16 entranceID) {
 		_gameStateBits[areaID] = 0;
 
 	assert(_areasByAreaID->contains(areaID));
-	//assert(entranceID > 0);
 	_currentArea = (*_areasByAreaID)[areaID];
 	_currentArea->show();
 
-	Entrance *entrance = (Entrance*) _currentArea->entranceWithID(entranceID);
-	if (!entrance)
+	int scale = _currentArea->getScale();
+	assert(scale > 0);
+
+	Entrance *entrance = nullptr;
+	if (entranceID > 0) {
+		entrance = (Entrance*) _currentArea->entranceWithID(entranceID);
+		assert(entrance);
+
+		_position = entrance->getOrigin();
+		if (_rotation == Math::Vector3d(0, 0, 0)) {
+			_rotation = entrance->getRotation();
+			debug("yaw: %f, pitch: %f", _rotation.x(), _rotation.y());
+			_pitch = _rotation.x();
+			_yaw = _rotation.y() - 260;
+		}
+		debug("entrace position: %f %f %f", _position.x(), _position.y(), _position.z());
+		debug("player height: %d", scale * _playerHeight);
+		_position.setValue(1, _position.y() + scale * _playerHeight);
+	} else {
+		Math::Vector3d diff = _lastPosition - _position;
+		debug("%f %f %f", diff.x(), diff.y(), diff.z());
+		// diff should be used to determinate which entrance to use
 		entrance = (Entrance*) _currentArea->firstEntrance();
+		assert(entrance);
+		if (abs(diff.x()) < abs(diff.z()))
+			_position.setValue(2, entrance->getOrigin().z());
+		else
+			_position.setValue(0, entrance->getOrigin().x());
 
-	_position = entrance->getOrigin();
-	if (_rotation == Math::Vector3d(0, 0, 0)) {
-		_rotation = entrance->getRotation();
-		debug("yaw: %f, pitch: %f", _rotation.x(), _rotation.y());
-		_pitch = _rotation.x();
-		_yaw = _rotation.y() - 260;
 	}
-	int scale = _currentArea->getScale();
-	assert(scale > 0);
 
-	debug("entrace position: %f %f %f", _position.x(), _position.y(), _position.z());
-	debug("player height: %d", scale * _playerHeight);
-	_position.setValue(1, _position.y() + scale * _playerHeight);
 	debug("starting player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
 }
 
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index fd2c0cc1511..7ca9afdd6c4 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -93,6 +93,7 @@ public:
 	uint16 _startEntrance;
 
 	// Input
+	bool _flyMode;
 	void processInput();
 	void move(CameraMovement direction, uint8 scale, float deltaTime);
 	bool checkFloor(Math::Vector3d currentPosition);
@@ -118,6 +119,7 @@ public:
 	Math::Vector3d _cameraFront, _cameraUp, _cameraRight;
 	// Spacial attributes
 	Math::Vector3d _position, _rotation, _velocity;
+	Math::Vector3d _lastPosition;
 	uint16 _playerHeight;
 	uint16 _playerWidth;
 	uint16 _playerDepth;


Commit: 30351a2c67ab985dc81b16c69176ae89aaebcb84
    https://github.com/scummvm/scummvm/commit/30351a2c67ab985dc81b16c69176ae89aaebcb84
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:56+01:00

Commit Message:
FREESCAPE: basic implementation of swapjet opcode

Changed paths:
    engines/freescape/freescape.h
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/language/instruction.cpp


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 7ca9afdd6c4..69a8668a20a 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -146,8 +146,9 @@ public:
 	void executeToggleBit(FCLInstruction &instruction);
 	bool executeEndIfBitNotEqual(FCLInstruction &instruction);
 	bool executeEndIfVisibilityIsNotEqual(FCLInstruction &instruction);
+	void executeSwapJet(FCLInstruction &instruction);
 
-	// Souund
+	// Sound
 	Audio::SoundHandle _speakerHandle;
 	Audio::PCSpeaker _speaker;
 	void playSound(int index);
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index 4b7b38c6ea2..8d3d95c9c53 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -265,6 +265,11 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 
 		case 21:
 			detokenisedStream += "SWAPJET";
+			currentInstruction = FCLInstruction(Token::SWAPJET);
+			conditionalInstructions->push_back(currentInstruction);
+			currentInstruction = FCLInstruction(Token::UNKNOWN);
+			bytePointer++;
+			numberOfArguments = 0;
 			break;
 		case 26:
 			detokenisedStream += "REDRAW";
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index a83bd434f22..bf8843970d1 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -68,6 +68,9 @@ void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool co
 			if (executeEndIfNotEqual(instruction))
 				ip = codeSize;
 			break;
+			case Token::SWAPJET:
+			executeSwapJet(instruction);
+			break;
 			case Token::ADDVAR:
 			executeIncrementVariable(instruction);
 			break;
@@ -262,4 +265,13 @@ bool FreescapeEngine::executeEndIfBitNotEqual(FCLInstruction &instruction) {
 	return (((_gameStateBits[_currentArea->getAreaID()] >> index) & 1) != value);
 }
 
+void FreescapeEngine::executeSwapJet(FCLInstruction &instruction) {
+	_flyMode = !_flyMode;
+	if (_flyMode)
+		debug("Swaping to ship mode");
+	else
+		debug("Swaping to tank mode");
+	// TODO: implement the rest of the changes (e.g. border)
+}
+
 } // End of namespace Freescape
\ No newline at end of file


Commit: 78eeb68cc5148acd23a6785adfafae9829fc1d44
    https://github.com/scummvm/scummvm/commit/78eeb68cc5148acd23a6785adfafae9829fc1d44
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:56+01:00

Commit Message:
FREESCAPE: added basic debug levels

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/language/instruction.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index b5a305ebe67..4dac11e8d77 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -52,27 +52,19 @@ FreescapeEngine::FreescapeEngine(OSystem *syst)
 	_flyMode = false;
 	_borderTexture = nullptr;
 
-	// Here is the right place to set up the engine specific debug channels
-	DebugMan.addDebugChannel(kFreescapeDebug, "example", "this is just an example for a engine specific debug channel");
-	DebugMan.addDebugChannel(kFreescapeDebug2, "example2", "also an example");
+	DebugMan.addDebugChannel(kFreescapeDebugMove, "move", "");
+	DebugMan.addDebugChannel(kFreescapeDebugParser, "parser", "");
+	DebugMan.addDebugChannel(kFreescapeDebugCode, "code", "");
 
-	// Don't forget to register your random source
 	_rnd = new Common::RandomSource("freescape");
-
-	debug("FreescapeEngine::FreescapeEngine");
 }
 
 FreescapeEngine::~FreescapeEngine() {
-	debug("FreescapeEngine::~FreescapeEngine");
-
 	// Dispose your resources here
 	delete _rnd;
 	//delete _areasByAreaID;
 	delete _border;
 	delete _gfx;
-
-	// Remove all of our debug levels here
-	//DebugMan.clearAllDebugChannels();
 }
 
 void FreescapeEngine::drawBorder() {
@@ -101,7 +93,7 @@ void FreescapeEngine::loadAssets() {
 		if (files.size() == 0) {
 			error("No .RUN was found in %s", path.c_str());
 		} else if (files.size() > 1) {
-			warning("More than one .RUN file found, only the first one will be used!");
+			debugC(1, kFreescapeDebugParser, "More than one .RUN file found, only the first one will be used!");
 		}
 
 		file = files.begin()->get()->createReadStream();
@@ -140,7 +132,7 @@ void FreescapeEngine::loadAssets() {
 				error("Failed to open DSIDE.EXE");
 			load8bitBinary(file, 0x7bb0, 4);
 		} else
-			error("Invalid render mode %s for Driller", _renderMode.c_str());
+			error("Invalid render mode %s for Dark Side", _renderMode.c_str());
 
 	} else if (_targetName == "totaleclipse") {
 		Common::File exe;
@@ -280,7 +272,6 @@ Common::Error FreescapeEngine::run() {
 	_gfx->init();
 	_gfx->clear();
 	loadAssets();
-	debug("FreescapeEngine::init");
 	// Simple main event loop
 	_lastMousePos = Common::Point(0, 0);
 	_lastFrame = 0.f;
@@ -311,7 +302,7 @@ Common::Error FreescapeEngine::run() {
 	}
 
 	gotoArea(_startArea, _startEntrance);
-	debug("Starting area %d", _currentArea->getAreaID());
+	debugC(1, kFreescapeDebugMove, "Starting area %d", _currentArea->getAreaID());
 	while (!shouldQuit()) {
 		drawFrame();
 		processInput();
@@ -357,7 +348,7 @@ void FreescapeEngine::rotate(Common::Point lastMousePos, Common::Point mousePos)
 }
 
 void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTime) {
-	debug("old player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
+	debugC(1, kFreescapeDebugMove, "old player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
 	int previousAreaID = _currentArea->getAreaID();
 
 	float velocity = _movementSpeed * deltaTime;
@@ -400,17 +391,17 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 			}
 			_position.set(_position.x(), positionY - fallen * areaScale, _position.z());
 		}
-		debug("Runing effects:");
+		debugC(1, kFreescapeDebugCode, "Runing effects:");
 		checkCollisions(true); // run the effects
 	} else {
-		debug("Runing effects:");
+		debugC(1, kFreescapeDebugCode, "Runing effects:");
 		checkCollisions(true); // run the effects
 		if (_flyMode)
 			_position = _lastPosition;
 		else if (_currentArea->getAreaID() == previousAreaID) {
 			bool stepUp = tryStepUp(_position);
 			if (stepUp) {
-				debug("Runing effects:");
+				debugC(1, kFreescapeDebugCode, "Runing effects:");
 				checkCollisions(true); // run the effects (again)
 			} else {
 				_position = _lastPosition;
@@ -418,10 +409,11 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 		}
 	}
 	_lastPosition = _position;
-	debug("new player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
+	debugC(1, kFreescapeDebugMove, "new player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
 }
 
 bool FreescapeEngine::checkFloor(Math::Vector3d currentPosition) {
+	debugC(1, kFreescapeDebugMove, "Checking floor under the player");
 	int areaScale = _currentArea->getScale();
 	bool collided = checkCollisions(false);
 	assert(!collided);
@@ -433,7 +425,7 @@ bool FreescapeEngine::checkFloor(Math::Vector3d currentPosition) {
 }
 
 bool FreescapeEngine::tryStepUp(Math::Vector3d currentPosition) {
-	debug("Try to step up!");
+	debugC(1, kFreescapeDebugMove, "Try to step up!");
 	int areaScale = _currentArea->getScale();
 	_position.set(_position.x(), _position.y() + 64 * areaScale, _position.z());
 	bool collided = checkCollisions(false);
@@ -447,7 +439,7 @@ bool FreescapeEngine::tryStepUp(Math::Vector3d currentPosition) {
 }
 
 bool FreescapeEngine::tryStepDown(Math::Vector3d currentPosition) {
-	debug("Try to step down!");
+	debugC(1, kFreescapeDebugMove, "Try to step down!");
 	int areaScale = _currentArea->getScale();
 	_position.set(_position.x(), _position.y() - areaScale, _position.z());
 	if (checkFloor(_position)) {
@@ -477,7 +469,7 @@ bool FreescapeEngine::checkCollisions(bool executeConditions) {
 	Object *obj = _currentArea->checkCollisions(boundingBox);
 
 	if (obj != nullptr) {
-		debug("Collided with object id %d of size %f %f %f", obj->getObjectID(), obj->getSize().x(), obj->getSize().y(), obj->getSize().z());
+		debugC(1, kFreescapeDebugMove, "Collided with object id %d of size %f %f %f", obj->getObjectID(), obj->getSize().x(), obj->getSize().y(), obj->getSize().z());
 		GeometricObject *gobj = (GeometricObject*) obj;
 		if (gobj->conditionSource != nullptr && executeConditions) {
 			debug("Must use collision = true when executing: %s", gobj->conditionSource->c_str());
@@ -489,7 +481,7 @@ bool FreescapeEngine::checkCollisions(bool executeConditions) {
 }
 
 void FreescapeEngine::gotoArea(uint16 areaID, uint16 entranceID) {
-	debug("go to area: %d, entrance: %d", areaID, entranceID);
+	debugC(1, kFreescapeDebugMove, "Jumping to area: %d, entrance: %d", areaID, entranceID);
 	if (!_gameStateBits.contains(areaID))
 		_gameStateBits[areaID] = 0;
 
@@ -508,12 +500,11 @@ void FreescapeEngine::gotoArea(uint16 areaID, uint16 entranceID) {
 		_position = entrance->getOrigin();
 		if (_rotation == Math::Vector3d(0, 0, 0)) {
 			_rotation = entrance->getRotation();
-			debug("yaw: %f, pitch: %f", _rotation.x(), _rotation.y());
 			_pitch = _rotation.x();
 			_yaw = _rotation.y() - 260;
 		}
-		debug("entrace position: %f %f %f", _position.x(), _position.y(), _position.z());
-		debug("player height: %d", scale * _playerHeight);
+		debugC(1, kFreescapeDebugMove, "entrace position: %f %f %f", _position.x(), _position.y(), _position.z());
+		debugC(1, kFreescapeDebugMove, "player height: %d", scale * _playerHeight);
 		_position.setValue(1, _position.y() + scale * _playerHeight);
 	} else {
 		Math::Vector3d diff = _lastPosition - _position;
@@ -528,7 +519,7 @@ void FreescapeEngine::gotoArea(uint16 areaID, uint16 entranceID) {
 
 	}
 
-	debug("starting player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
+	debugC(1, kFreescapeDebugMove, "starting player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
 }
 
 bool FreescapeEngine::hasFeature(EngineFeature f) const {
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 69a8668a20a..01bbbee00ad 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -43,10 +43,10 @@ typedef struct Binary {
 
 class Console;
 
-// our engine debug channels
 enum {
-	kFreescapeDebug = 1 << 0,
-	kFreescapeDebug2 = 1 << 1
+	kFreescapeDebugMove = 1 << 0,
+	kFreescapeDebugParser = 1 << 1,
+	kFreescapeDebugCode = 1 << 2
 };
 
 class FreescapeEngine : public Engine {
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index bf8843970d1..e356c9be6d1 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -48,7 +48,7 @@ void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool co
 	int codeSize = code.size();
 	while (ip <= codeSize - 1) {
 		FCLInstruction &instruction = code[ip];
-		debug("Executing ip: %d in code with size: %d", ip, codeSize);
+		debugC(1, kFreescapeDebugCode, "Executing ip: %d in code with size: %d", ip, codeSize);
 		switch (instruction.getType()) {
 			default:
 			break;
@@ -123,25 +123,26 @@ void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool co
 
 
 void FreescapeEngine::executeRedraw(FCLInstruction &instruction) {
-	debug("Redrawing screen");
+	debugC(1, kFreescapeDebugCode, "Redrawing screen");
 	drawFrame();
 }
 
 void FreescapeEngine::executeSound(FCLInstruction &instruction) {
 	uint16 index = instruction.source;
+	debugC(1, kFreescapeDebugCode, "Playing sound %d", index);
 	playSound(index);
 }
 
 void FreescapeEngine::executeDelay(FCLInstruction &instruction) {
 	uint16 delay = instruction.source;
-	debug("Delaying %d * 1/50 seconds", delay);
+	debugC(1, kFreescapeDebugCode, "Delaying %d * 1/50 seconds", delay);
 	g_system->delayMillis(20 * delay);
 }
 
 bool FreescapeEngine::executeEndIfVisibilityIsNotEqual(FCLInstruction &instruction) {
 	uint16 objectID = instruction.source;
 	uint16 value = instruction.destination;
-	debug("End condition if visibility of obj with id %d is %d!", objectID, value);
+	debugC(1, kFreescapeDebugCode, "End condition if visibility of obj with id %d is %d!", objectID, value);
 	Object *obj = _currentArea->objectWithID(objectID);
 	assert(obj);
 	return (obj->isInvisible() == value);
@@ -150,7 +151,7 @@ bool FreescapeEngine::executeEndIfVisibilityIsNotEqual(FCLInstruction &instructi
 bool FreescapeEngine::executeEndIfNotEqual(FCLInstruction &instruction) {
 	uint16 variable = instruction.source;
 	uint16 value = instruction.destination;
-	debug("End condition if variable %d is not equal to %d!", variable, value);
+	debugC(1, kFreescapeDebugCode, "End condition if variable %d is not equal to %d!", variable, value);
 	return (_gameStateVars[variable] != value);
 }
 
@@ -159,9 +160,9 @@ void FreescapeEngine::executeIncrementVariable(FCLInstruction &instruction) {
 	uint16 increment = instruction.destination;
 	_gameStateVars[variable] = _gameStateVars[variable] + increment;
 	if (variable == k8bitVariableScore) {
-		debug("Score incremented by %d up to %d", increment, _gameStateVars[variable]);
+		debugC(1, kFreescapeDebugCode, "Score incremented by %d up to %d", increment, _gameStateVars[variable]);
 	} else
-		debug("Variable %d by %d incremented up to %d!", variable, increment, _gameStateVars[variable]);
+		debugC(1, kFreescapeDebugCode, "Variable %d by %d incremented up to %d!", variable, increment, _gameStateVars[variable]);
 }
 
 void FreescapeEngine::executeDecrementVariable(FCLInstruction &instruction) {
@@ -169,14 +170,14 @@ void FreescapeEngine::executeDecrementVariable(FCLInstruction &instruction) {
 	uint16 decrement = instruction.destination;
 	_gameStateVars[variable] = _gameStateVars[variable] - decrement;
 	if (variable == k8bitVariableEnergy) {
-		debug("Energy decrement by %d up to %d", decrement, _gameStateVars[variable]);
+		debugC(1, kFreescapeDebugCode, "Energy decrement by %d up to %d", decrement, _gameStateVars[variable]);
 	} else
-		debug("Variable %d by %d incremented up to %d!", variable, decrement, _gameStateVars[variable]);
+		debugC(1, kFreescapeDebugCode, "Variable %d by %d incremented up to %d!", variable, decrement, _gameStateVars[variable]);
 }
 
 void FreescapeEngine::executeDestroy(FCLInstruction &instruction) {
 	uint16 objectID = instruction.source;
-	debug("Destroying obj %d!", objectID);
+	debugC(1, kFreescapeDebugCode, "Destroying obj %d!", objectID);
 	Object *obj = _currentArea->objectWithID(objectID);
 	assert(!obj->isDestroyed());
 	obj->destroy();
@@ -193,7 +194,7 @@ void FreescapeEngine::executeMakeInvisible(FCLInstruction &instruction) {
 		objectID = instruction.source;
 	}
 
-	debug("Making obj %d invisible in area %d!", objectID, areaID);
+	debugC(1, kFreescapeDebugCode, "Making obj %d invisible in area %d!", objectID, areaID);
 	Object *obj = (*_areasByAreaID)[areaID]->objectWithID(objectID);
 	obj->makeInvisible();
 }
@@ -209,7 +210,7 @@ void FreescapeEngine::executeMakeVisible(FCLInstruction &instruction) {
 		objectID = instruction.source;
 	}
 
-	debug("Making obj %d visible in area %d!", objectID, areaID);
+	debugC(1, kFreescapeDebugCode, "Making obj %d visible in area %d!", objectID, areaID);
 	Object *obj = (*_areasByAreaID)[areaID]->objectWithID(objectID);
 	obj->makeVisible();
 }
@@ -225,7 +226,7 @@ void FreescapeEngine::executeToggleVisibility(FCLInstruction &instruction) {
 		objectID = instruction.source;
 	}
 
-	debug("Toggling obj %d visibility in area %d!", objectID, areaID);
+	debugC(1, kFreescapeDebugCode, "Toggling obj %d visibility in area %d!", objectID, areaID);
 	Object *obj = (*_areasByAreaID)[areaID]->objectWithID(objectID);
 	obj->toggleVisibility();
 }
@@ -240,7 +241,7 @@ void FreescapeEngine::executeSetBit(FCLInstruction &instruction) {
 	uint16 index = instruction.source - 1; // Starts in 1
 	assert(index < 32);
 	_gameStateBits[_currentArea->getAreaID()] |= (1 << index);
-	debug("Setting bit %d", index);
+	debugC(1, kFreescapeDebugCode, "Setting bit %d", index);
 	//debug("v: %d", (_gameStateBits[_currentArea->getAreaID()] & (1 << index)));
 }
 
@@ -248,29 +249,29 @@ void FreescapeEngine::executeClearBit(FCLInstruction &instruction) {
 	uint16 index = instruction.source - 1; // Starts in 1
 	assert(index < 32);
 	_gameStateBits[_currentArea->getAreaID()] &= ~(1 << index);
-	debug("Clearing bit %d", index);
+	debugC(1, kFreescapeDebugCode, "Clearing bit %d", index);
 }
 
 void FreescapeEngine::executeToggleBit(FCLInstruction &instruction) {
 	uint16 index = instruction.source - 1; // Starts in 1
 	_gameStateBits[_currentArea->getAreaID()] ^= (1 << index);
-	debug("Toggling bit %d", index);
+	debugC(1, kFreescapeDebugCode, "Toggling bit %d", index);
 }
 
 bool FreescapeEngine::executeEndIfBitNotEqual(FCLInstruction &instruction) {
 	uint16 index = instruction.source - 1; // Starts in 1
 	uint16 value = instruction.destination;
 	assert(index < 32);
-	debug("End condition if bit %d is not equal to %d!", index, value);
+	debugC(1, kFreescapeDebugCode, "End condition if bit %d is not equal to %d!", index, value);
 	return (((_gameStateBits[_currentArea->getAreaID()] >> index) & 1) != value);
 }
 
 void FreescapeEngine::executeSwapJet(FCLInstruction &instruction) {
 	_flyMode = !_flyMode;
 	if (_flyMode)
-		debug("Swaping to ship mode");
+		debugC(1, kFreescapeDebugCode, "Swaping to ship mode");
 	else
-		debug("Swaping to tank mode");
+		debugC(1, kFreescapeDebugCode, "Swaping to tank mode");
 	// TODO: implement the rest of the changes (e.g. border)
 }
 
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index c2f106f8820..3cb128ffb9d 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -19,7 +19,7 @@ namespace Freescape {
 Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 
 	byte rawFlagsAndType = file->readByte();
-	debug("Raw object data flags and type: %d", rawFlagsAndType);
+	debugC(1, kFreescapeDebugParser, "Raw object data flags and type: %d", rawFlagsAndType);
 	Object::Type objectType = (Object::Type)(rawFlagsAndType & 0x1F);
 
 	Math::Vector3d position, v;
@@ -38,7 +38,7 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 	// already so we can subtract that to get the remaining
 	// length beyond here
 	uint8 byteSizeOfObject = file->readByte();
-	debug("Raw object %d ; type %d ; size %d", objectID, (int)objectType, byteSizeOfObject);
+	debugC(1, kFreescapeDebugParser, "Raw object %d ; type %d ; size %d", objectID, (int)objectType, byteSizeOfObject);
 	if (byteSizeOfObject < 9) {
 		error("Not enough bytes %d to read object %d with type %d", byteSizeOfObject, objectID, objectType);
 		//file->seek(byteSizeOfObject, SEEK_CUR);
@@ -47,15 +47,15 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 
 	assert(byteSizeOfObject >= 9);
 	byteSizeOfObject = byteSizeOfObject - 9;
-	debug("Object %d ; type %d ; size %d", objectID, (int)objectType, byteSizeOfObject);
-    debug("pos: %f %f %f", position.x(), position.y(), position.z());
+	debugC(1, kFreescapeDebugParser, "Object %d ; type %d ; size %d", objectID, (int)objectType, byteSizeOfObject);
+    debugC(1, kFreescapeDebugParser, "pos: %f %f %f", position.x(), position.y(), position.z());
 	switch (objectType) {
 	default: {
-		debug("size: %f %f %f", v.x(), v.y(), v.z());
+		debugC(1, kFreescapeDebugParser, "size: %f %f %f", v.x(), v.y(), v.z());
 		// read the appropriate number of colours
 		int numberOfColours = GeometricObject::numberOfColoursForObjectOfType(objectType);
 		Common::Array<uint8> *colours = new Common::Array<uint8>;
-		debug("Number of colors: %d", numberOfColours/2);
+		debugC(1, kFreescapeDebugParser, "Number of colors: %d", numberOfColours/2);
 		uint8 entry;
 		for (uint8 colour = 0; colour < numberOfColours/2; colour++) {
 			uint8 data = file->readByte();
@@ -64,20 +64,20 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 				entry = entry % 4; // TODO: use dithering
 
 			colours->push_back(entry);
-			debug("color[%d] = %x", 2*colour, entry);
+			debugC(1, kFreescapeDebugParser, "color[%d] = %x", 2*colour, entry);
 
 			entry = data >> 4;
 			if (_renderMode == "cga")
 				entry = entry % 4; // TODO: use dithering
 
 			colours->push_back(entry);
-			debug("color[%d] = %x", 2*colour+1, entry);
+			debugC(1, kFreescapeDebugParser, "color[%d] = %x", 2*colour+1, entry);
 			byteSizeOfObject--;
 		}
 
 		// read extra vertices if required...
 		int numberOfOrdinates = GeometricObject::numberOfOrdinatesForType(objectType);
-		debug("number of ordinates %d", numberOfOrdinates);
+		debugC(1, kFreescapeDebugParser, "number of ordinates %d", numberOfOrdinates);
 		Common::Array<uint16> *ordinates = nullptr;
 
 		if (numberOfOrdinates) {
@@ -90,7 +90,7 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 			}
 			for (int ordinate = 0; ordinate < numberOfOrdinates; ordinate++) {
 				ord = file->readByte();
-				debug("ord: %x", ord);
+				debugC(1, kFreescapeDebugParser, "ord: %x", ord);
 				ordinates->push_back(32 * ord);
 				byteSizeOfObject--;
 			}
@@ -105,9 +105,9 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 			Common::Array<uint8> conditionArray(conditionData, byteSizeOfObject);
 			conditionSource = detokenise8bitCondition(conditionArray, instructions);
 			//instructions = getInstructions(conditionSource);
-			debug("%s", conditionSource->c_str());
+			debugC(1, kFreescapeDebugParser, "%s", conditionSource->c_str());
 		}
-		debug("End of object at %lx", file->pos());
+		debugC(1, kFreescapeDebugParser, "End of object at %lx", file->pos());
 
 		if (!GeometricObject::isPolygon(objectType))
 			position = 32 * position;
@@ -125,18 +125,18 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 			conditionSource);
 	} break;
 	case Object::Entrance: {
-		debug("rotation: %f %f %f", v.x(), v.y(), v.z());
+		debugC(1, kFreescapeDebugParser, "rotation: %f %f %f", v.x(), v.y(), v.z());
 		if (byteSizeOfObject > 0) {
 			// TODO: there is something here
-			debug("Warning: extra %d bytes in entrance", byteSizeOfObject);
+			debugC(1, kFreescapeDebugParser, "Warning: extra %d bytes in entrance", byteSizeOfObject);
 			//file->seek(byteSizeOfObject, SEEK_CUR);
 			while (byteSizeOfObject--) {
-				debug("b: %x", file->readByte());
+				debugC(1, kFreescapeDebugParser, "b: %x", file->readByte());
 			}
 			byteSizeOfObject = 0;
 		}
 		assert(byteSizeOfObject == 0);
-		debug("End of object at %lx", file->pos());
+		debugC(1, kFreescapeDebugParser, "End of object at %lx", file->pos());
 		// create an entrance
 		return new Entrance(
 			objectID,
@@ -145,15 +145,15 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 	} break;
 
 	case Object::Sensor: {
-		debug("rotation: %f %f %f", v.x(), v.y(), v.z());
+		debugC(1, kFreescapeDebugParser, "rotation: %f %f %f", v.x(), v.y(), v.z());
 		if (byteSizeOfObject > 0) {
 			// TODO: there is something here
-			debug("Warning: extra %d bytes in sensor", byteSizeOfObject);
+			debugC(1, kFreescapeDebugParser, "Warning: extra %d bytes in sensor", byteSizeOfObject);
 			file->seek(byteSizeOfObject, SEEK_CUR);
 			byteSizeOfObject = 0;
 		}
 		assert(byteSizeOfObject == 0);
-		debug("End of object at %lx", file->pos());
+		debugC(1, kFreescapeDebugParser, "End of object at %lx", file->pos());
 		// create an entrance
 		return new Sensor(
 			objectID,
@@ -266,15 +266,15 @@ Graphics::PixelBuffer *FreescapeEngine::getPalette(uint8 areaNumber, uint8 c1, u
 Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 ncolors) {
 
 	uint32 base = file->pos();
-	debug("Area base: %x", base);
+	debugC(1, kFreescapeDebugParser, "Area base: %x", base);
 	uint8 skippedValue = file->readByte();
 	uint8 numberOfObjects = file->readByte();
 	uint8 areaNumber = file->readByte();
 
 	uint16 cPtr = file->readUint16LE();
-	debug("Condition pointer: %x", cPtr);
+	debugC(1, kFreescapeDebugParser, "Condition pointer: %x", cPtr);
 	uint8 scale = file->readByte();
-	debug("Scale: %d", scale);
+	debugC(1, kFreescapeDebugParser, "Scale: %d", scale);
 
 	uint8 ci1 = 0;
 	uint8 ci2 = 0;
@@ -285,11 +285,11 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 		skyColor = file->readByte() & 15;
 		ci1 = file->readByte();
 		ci2 = file->readByte();
-		debug("Colors: %d %d %d %d", ci1, ci2, skyColor, groundColor);
+		debugC(1, kFreescapeDebugParser, "Colors: %d %d %d %d", ci1, ci2, skyColor, groundColor);
 	} else {
 		groundColor = file->readByte() & 15;
 		skyColor = file->readByte() & 15;
-		debug("Colors: %d %d", skyColor, groundColor);
+		debugC(1, kFreescapeDebugParser, "Colors: %d %d", skyColor, groundColor);
 	}
 
 	if (_renderMode == "cga") {
@@ -299,23 +299,23 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 
 	Graphics::PixelBuffer *palette = getPalette(areaNumber, ci1, ci2, skyColor, groundColor, ncolors);
 
-	debug("Area %d", areaNumber);
-	debug("Skipped: %d Objects: %d", skippedValue, numberOfObjects);
+	debugC(1, kFreescapeDebugParser, "Area %d", areaNumber);
+	debugC(1, kFreescapeDebugParser, "Skipped: %d Objects: %d", skippedValue, numberOfObjects);
 	//debug("Condition Ptr: %x", cPtr);
-	debug("Pos before first object: %lx", file->pos());
+	debugC(1, kFreescapeDebugParser, "Pos before first object: %lx", file->pos());
 	if (_targetName == "totaleclipse") {
-		debug("b: %x", file->readByte());
-		debug("b: %x", file->readByte());
-		debug("b: %x", file->readByte());
-		debug("b: %x", file->readByte());
-		debug("b: %x", file->readByte());
+		debugC(1, kFreescapeDebugParser, "b: %x", file->readByte());
+		debugC(1, kFreescapeDebugParser, "b: %x", file->readByte());
+		debugC(1, kFreescapeDebugParser, "b: %x", file->readByte());
+		debugC(1, kFreescapeDebugParser, "b: %x", file->readByte());
+		debugC(1, kFreescapeDebugParser, "b: %x", file->readByte());
 	} else if (_targetName != "castlemaster")
 		file->seek(15, SEEK_CUR);
 
 	ObjectMap *objectsByID = new ObjectMap;
 	ObjectMap *entrancesByID = new ObjectMap;
 	for (uint8 object = 0; object < numberOfObjects; object++) {
-		debug("Reading object: %d", object);
+		debugC(1, kFreescapeDebugParser, "Reading object: %d", object);
 		Object *newObject = load8bitObject(file);
 
 		if (newObject) {
@@ -333,11 +333,11 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 			error("Failed to read an object!");
 	}
 	long int endLastObject = file->pos();
-	debug("Last position %lx", endLastObject);
+	debugC(1, kFreescapeDebugParser, "Last position %lx", endLastObject);
 	assert(endLastObject == base + cPtr);
 	file->seek(base + cPtr);
 	uint8 numConditions = file->readByte();
-	debug("%d area conditions at %x of area %d", numConditions, base + cPtr, areaNumber);
+	debugC(1, kFreescapeDebugParser, "%d area conditions at %x of area %d", numConditions, base + cPtr, areaNumber);
 
 	Area *area = new Area(areaNumber, objectsByID, entrancesByID, scale, skyColor, groundColor, palette);
 
@@ -345,7 +345,7 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 		FCLInstructionVector instructions;
 		// get the length
 		uint32 lengthOfCondition = file->readByte();
-		debug("length of condition: %d", lengthOfCondition);
+		debugC(1, kFreescapeDebugParser, "length of condition: %d", lengthOfCondition);
 		// get the condition
 		byte *conditionData = (byte*)malloc(lengthOfCondition);
 		file->read(conditionData, lengthOfCondition);
@@ -353,13 +353,13 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 		Common::String *conditionSource = detokenise8bitCondition(conditionArray, instructions);
 		area->conditions.push_back(instructions);
 		area->conditionSources.push_back(conditionSource);
-		debug("%s", conditionSource->c_str());
+		debugC(1, kFreescapeDebugParser, "%s", conditionSource->c_str());
 	}
 
 	if (_targetName.hasPrefix("castlemaster") || _targetName.hasPrefix("totaleclipse"))
 		area->addStructure();
 
-	debug("End of area at %lx", file->pos());
+	debugC(1, kFreescapeDebugParser, "End of area at %lx", file->pos());
 	return area;
 }
 
@@ -377,40 +377,39 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	file->seek(offset);
 	uint8 numberOfAreas = file->readByte();
 	uint16 dbSize = file->readUint16LE();
-	debug("Database ends at %x", dbSize);
-
-	debug("Number of areas: %d", numberOfAreas);
+	debugC(1, kFreescapeDebugParser, "Number of areas: %d", numberOfAreas);
+	debugC(1, kFreescapeDebugParser, "Database ends at %x", dbSize);
 
 	uint8 startArea = file->readByte();
-	debug("Start area: %d", startArea);
+	debugC(1, kFreescapeDebugParser, "Start area: %d", startArea);
 	uint8 startEntrance = file->readByte();
-	debug("Entrace area: %d", startEntrance);
+	debugC(1, kFreescapeDebugParser, "Entrace area: %d", startEntrance);
 
 	file->seek(offset + 0x46); // 0x46
 
 	uint16 globalSomething;
 	globalSomething = file->readUint16LE();
-	debug("Pointer to something: %x\n", globalSomething);
+	debugC(1, kFreescapeDebugParser, "Pointer to something: %x\n", globalSomething);
 
 	uint16 globalByteCodeTable;
 	globalByteCodeTable = file->readUint16LE();
-	debug("GBCT: %d\n", globalByteCodeTable);
+	debugC(1, kFreescapeDebugParser, "GBCT: %d\n", globalByteCodeTable);
 
 	file->seek(offset + globalByteCodeTable);
 	uint8 numConditions = file->readByte();
-	debug("%d global conditions", numConditions);
+	debugC(1, kFreescapeDebugParser, "%d global conditions", numConditions);
 	while (numConditions--) {
 		FCLInstructionVector instructions;
 		// get the length
 		uint32 lengthOfCondition = file->readByte();
-		debug("length of condition: %d at %lx", lengthOfCondition, file->pos());
+		debugC(1, kFreescapeDebugParser, "length of condition: %d at %lx", lengthOfCondition, file->pos());
 		// get the condition
 		byte *conditionData = (byte*)malloc(lengthOfCondition);
 		file->read(conditionData, lengthOfCondition);
 		Common::Array<uint8> conditionArray(conditionData, lengthOfCondition);
 		//debug("Global condition %d", numConditions + 1);
 		Common::String *conditions = detokenise8bitCondition(conditionArray, instructions);
-		debug("%s", conditions->c_str());
+		debugC(1, kFreescapeDebugParser, "%s", conditions->c_str());
 	}
 
 	if (_targetName.hasPrefix("driller")) {
@@ -424,18 +423,18 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	else
 		file->seek(offset + 0x4f);
 
-	debug("areas index at: %lx", file->pos());
+	debugC(1, kFreescapeDebugParser, "areas index at: %lx", file->pos());
 	uint16 *fileOffsetForArea = new uint16[numberOfAreas];
 	for (uint16 area = 0; area < numberOfAreas; area++) {
 		fileOffsetForArea[area] = file->readUint16LE();
-		debug("offset: %x", fileOffsetForArea[area]);
+		debugC(1, kFreescapeDebugParser, "offset: %x", fileOffsetForArea[area]);
 	}
 
 	// grab the areas
 	AreaMap *areaMap = new AreaMap;
 	Area *newArea = nullptr;
 	for (uint16 area = 0; area < numberOfAreas; area++) {
-		debug("Area offset %d", fileOffsetForArea[area]);
+		debugC(1, kFreescapeDebugParser, "Area offset %d", fileOffsetForArea[area]);
 
 		file->seek(offset + fileOffsetForArea[area]);
 		newArea = load8bitArea(file, ncolors);
@@ -444,7 +443,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 			if (!areaMap->contains(newArea->getAreaID()))
 				(*areaMap)[newArea->getAreaID()] = newArea;
 			else
-				debug("WARNING: area ID repeated: %d", newArea->getAreaID());
+				debugC(1, kFreescapeDebugParser, "WARNING: area ID repeated: %d", newArea->getAreaID());
 		} else
 			error("Invalid area?");
 	}


Commit: b62fcf64ac0cd87389319e272302486362400db8
    https://github.com/scummvm/scummvm/commit/b62fcf64ac0cd87389319e272302486362400db8
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:57+01:00

Commit Message:
FREESCAPE: correctly registred debug levels

Changed paths:
    engines/freescape/detection.cpp
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index 8df2eae9b70..4b15a5333e4 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -1,6 +1,8 @@
 #include "base/plugins.h"
 #include "engines/advancedDetector.h"
 
+#include "freescape/freescape.h"
+
 namespace Freescape {
 static const PlainGameDescriptor freescapeGames[] = {
 	{"3dkit", "The 3D Kit Game"},
@@ -162,6 +164,13 @@ static const ADGameDescription gameDescriptions[] = {
 	AD_TABLE_END_MARKER};
 } // End of namespace Freescape
 
+static const DebugChannelDef debugFlagList[] = {
+	{Freescape::kFreescapeDebugMove, "move", ""},
+	{Freescape::kFreescapeDebugParser, "parser", ""},
+	{Freescape::kFreescapeDebugCode, "code", ""},
+	DEBUG_CHANNEL_END
+};
+
 class FreescapeMetaEngineDetection : public AdvancedMetaEngineDetection {
 public:
 	FreescapeMetaEngineDetection() : AdvancedMetaEngineDetection(Freescape::gameDescriptions, sizeof(ADGameDescription), Freescape::freescapeGames) {
@@ -178,6 +187,10 @@ public:
 	const char *getOriginalCopyright() const override {
 		return "Copyright (C) Incentive Software";
 	}
+
+	const DebugChannelDef *getDebugChannels() const override {
+		return debugFlagList;
+	}
 };
 
 REGISTER_PLUGIN_STATIC(FREESCAPE_DETECTION, PLUGIN_TYPE_ENGINE_DETECTION, FreescapeMetaEngineDetection);
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 4dac11e8d77..a84e64cd988 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -52,10 +52,6 @@ FreescapeEngine::FreescapeEngine(OSystem *syst)
 	_flyMode = false;
 	_borderTexture = nullptr;
 
-	DebugMan.addDebugChannel(kFreescapeDebugMove, "move", "");
-	DebugMan.addDebugChannel(kFreescapeDebugParser, "parser", "");
-	DebugMan.addDebugChannel(kFreescapeDebugCode, "code", "");
-
 	_rnd = new Common::RandomSource("freescape");
 }
 


Commit: 4806895eea3a56dbb8bf20fc8853389a4d07a564
    https://github.com/scummvm/scummvm/commit/4806895eea3a56dbb8bf20fc8853389a4d07a564
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:57+01:00

Commit Message:
FREESCAPE: basic save/load implementation without level state

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index a84e64cd988..8498f07561a 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -205,6 +205,8 @@ void FreescapeEngine::processInput() {
 				_position.setValue(1, _position.y() - 12);
 			else if (event.kbd.keycode == Common::KEYCODE_n)
 				gotoArea(_currentArea->getAreaID() + 1, 0);
+			else if (event.kbd.keycode == Common::KEYCODE_ESCAPE)
+				openMainMenuDialog();
 			break;
 
 		case Common::EVENT_QUIT:
@@ -297,7 +299,12 @@ Common::Error FreescapeEngine::run() {
 		_border->fillRect(viewArea, 0xA0A0A0FF);
 	}
 
-	gotoArea(_startArea, _startEntrance);
+	int saveSlot = ConfMan.getInt("save_slot");
+	if (saveSlot >= 0) { // load the savegame
+		loadGameState(saveSlot);
+	} else
+		gotoArea(_startArea, _startEntrance);
+
 	debugC(1, kFreescapeDebugMove, "Starting area %d", _currentArea->getAreaID());
 	while (!shouldQuit()) {
 		drawFrame();
@@ -476,7 +483,7 @@ bool FreescapeEngine::checkCollisions(bool executeConditions) {
 	return false;
 }
 
-void FreescapeEngine::gotoArea(uint16 areaID, uint16 entranceID) {
+void FreescapeEngine::gotoArea(uint16 areaID, int entranceID) {
 	debugC(1, kFreescapeDebugMove, "Jumping to area: %d, entrance: %d", areaID, entranceID);
 	if (!_gameStateBits.contains(areaID))
 		_gameStateBits[areaID] = 0;
@@ -502,7 +509,7 @@ void FreescapeEngine::gotoArea(uint16 areaID, uint16 entranceID) {
 		debugC(1, kFreescapeDebugMove, "entrace position: %f %f %f", _position.x(), _position.y(), _position.z());
 		debugC(1, kFreescapeDebugMove, "player height: %d", scale * _playerHeight);
 		_position.setValue(1, _position.y() + scale * _playerHeight);
-	} else {
+	} else if (entranceID == 0) {
 		Math::Vector3d diff = _lastPosition - _position;
 		debug("%f %f %f", diff.x(), diff.y(), diff.z());
 		// diff should be used to determinate which entrance to use
@@ -532,21 +539,38 @@ void FreescapeEngine::playSound(int index) {
 }
 
 Common::Error FreescapeEngine::loadGameStream(Common::SeekableReadStream *stream) {
-	Common::Serializer s(stream, nullptr);
-	syncGameStream(s);
+
+	uint16 areaID = stream->readUint16LE();
+	for (int i = 0; i < 3; i++)
+		_position.setValue(i, stream->readFloatLE());
+
+	for (int i = 0; i < 3; i++)
+		_rotation.setValue(i, stream->readFloatLE());
+
+	_yaw = stream->readFloatLE();
+	_pitch = stream->readFloatLE();
+
+	if (!_currentArea || _currentArea->getAreaID() != areaID)
+		gotoArea(areaID, -1); // Do not change position nor rotation
 	return Common::kNoError;
 }
 
 Common::Error FreescapeEngine::saveGameStream(Common::WriteStream *stream, bool isAutosave) {
-	Common::Serializer s(nullptr, stream);
-	syncGameStream(s);
-	return Common::kNoError;
-}
+	if (isAutosave)
+		return Common::kNoError;
+
+	stream->writeUint16LE(_currentArea->getAreaID());
+
+	for (int i = 0; i < 3; i++)
+		stream->writeFloatLE(_position.getValue(i));
 
-void FreescapeEngine::syncGameStream(Common::Serializer &s) {
-	// Use methods of Serializer to save/load fields
-	int dummy = 0;
-	s.syncAsUint16LE(dummy);
+	for (int i = 0; i < 3; i++)
+		stream->writeFloatLE(_rotation.getValue(i));
+
+	stream->writeFloatLE(_yaw);
+	stream->writeFloatLE(_pitch);
+
+	return Common::kNoError;
 }
 
 } // namespace Freescape
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 01bbbee00ad..e85556854f1 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -88,7 +88,7 @@ public:
 	Area *_currentArea;
 	Math::Vector3d _scale;
 
-	void gotoArea(uint16 areaID, uint16 entranceID);
+	void gotoArea(uint16 areaID, int entranceID);
 	// Entrance
 	uint16 _startEntrance;
 
@@ -169,10 +169,10 @@ public:
 
 	bool hasFeature(EngineFeature f) const override;
 	bool canLoadGameStateCurrently() override { return true; }
+	bool canSaveAutosaveCurrently() override { return false; }
 	bool canSaveGameStateCurrently() override { return true; }
 	Common::Error loadGameStream(Common::SeekableReadStream *stream) override;
 	Common::Error saveGameStream(Common::WriteStream *stream, bool isAutosave = false) override;
-	void syncGameStream(Common::Serializer &s);
 };
 
 // Example console class


Commit: 291c5465cfff6ee60a5180577aec0dca68cb15bf
    https://github.com/scummvm/scummvm/commit/291c5465cfff6ee60a5180577aec0dca68cb15bf
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:57+01:00

Commit Message:
FREESCAPE: initial implementation of loading of level state

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/language/8bitDetokeniser.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 8498f07561a..e5052d15a49 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -263,13 +263,14 @@ void FreescapeEngine::shoot() {
 }
 
 Common::Error FreescapeEngine::run() {
-	initGameState();
-
 	// Initialize graphics
 	_gfx = createRenderer(_system);
 	_gfx->init();
 	_gfx->clear();
+
+	// Load game data and init game state
 	loadAssets();
+	initGameState();
 	// Simple main event loop
 	_lastMousePos = Common::Point(0, 0);
 	_lastFrame = 0.f;
@@ -318,6 +319,12 @@ Common::Error FreescapeEngine::run() {
 }
 
 void FreescapeEngine::initGameState() {
+	for (int i = 0; i < k8bitMaxVariable; i++) // TODO: check maximum variable
+		_gameStateVars[i] = 0;
+
+	for (AreaMap::iterator it = _areasByAreaID->begin(); it != _areasByAreaID->end(); ++it)
+		_gameStateBits[it->_key] = 0;
+
 	_gameStateVars[k8bitVariableEnergy] = 100;
 	_gameStateVars[k8bitVariableShield] = 100;
 }
@@ -550,6 +557,17 @@ Common::Error FreescapeEngine::loadGameStream(Common::SeekableReadStream *stream
 	_yaw = stream->readFloatLE();
 	_pitch = stream->readFloatLE();
 
+	// Level state
+	for (int i = 0; i < _gameStateVars.size(); i++) {
+		uint16 key = stream->readUint16LE();
+		_gameStateVars[key] = stream->readUint32LE();
+	}
+
+	for (int i = 0; i < _gameStateBits.size(); i++) {
+		uint16 key = stream->readUint16LE();
+		_gameStateBits[key] = stream->readUint32LE();
+	}
+
 	if (!_currentArea || _currentArea->getAreaID() != areaID)
 		gotoArea(areaID, -1); // Do not change position nor rotation
 	return Common::kNoError;
@@ -570,6 +588,17 @@ Common::Error FreescapeEngine::saveGameStream(Common::WriteStream *stream, bool
 	stream->writeFloatLE(_yaw);
 	stream->writeFloatLE(_pitch);
 
+	// Level state
+	for (StateVars::iterator it = _gameStateVars.begin(); it != _gameStateVars.end(); ++it) {
+		stream->writeUint16LE(it->_key);
+		stream->writeUint32LE(it->_value);
+	}
+
+	for (StateBits::iterator it = _gameStateBits.begin(); it != _gameStateBits.end(); ++it) {
+		stream->writeUint16LE(it->_key);
+		stream->writeUint32LE(it->_value);
+	}
+
 	return Common::kNoError;
 }
 
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index e85556854f1..a4c0421af01 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -21,8 +21,6 @@ namespace Freescape {
 
 class Renderer;
 
-// from shooter
-// Defines several possible options for camera movement. Used as abstraction to stay away from window-system specific input methods
 enum CameraMovement {
     FORWARD,
     BACKWARD,
@@ -31,17 +29,8 @@ enum CameraMovement {
 };
 
 typedef Common::HashMap<uint16, Area *> AreaMap;
-
-typedef struct Binary {
-	uint8 bits;
-	uint16 startArea;
-	AreaMap *areasByAreaID;
-	Common::Array<uint8> *border;
-	Common::Array<uint8> *palette;
-	uint16 ncolors;
-} Binary;
-
-class Console;
+typedef Common::HashMap<uint16, int32> StateVars;
+typedef Common::HashMap<uint16, uint32> StateBits;
 
 enum {
 	kFreescapeDebugMove = 1 << 0,
@@ -164,8 +153,8 @@ public:
 
 	// Game state
 	void initGameState();
-	Common::HashMap<uint16, int32> _gameStateVars;
-	Common::HashMap<uint16, uint32> _gameStateBits;
+	StateVars _gameStateVars;
+	StateBits _gameStateBits;
 
 	bool hasFeature(EngineFeature f) const override;
 	bool canLoadGameStateCurrently() override { return true; }
diff --git a/engines/freescape/language/8bitDetokeniser.h b/engines/freescape/language/8bitDetokeniser.h
index 9490cff52cc..a110d3fad63 100644
--- a/engines/freescape/language/8bitDetokeniser.h
+++ b/engines/freescape/language/8bitDetokeniser.h
@@ -17,11 +17,13 @@
 namespace Freescape {
 
 enum {
-	k8bitVariableShield = 256,
-	k8bitVariableEnergy = 257,
-	k8bitVariableScore = 258
+	k8bitVariableShield = 63,
+	k8bitVariableEnergy = 62,
+	k8bitVariableScore = 61
 };
 
+static uint8 k8bitMaxVariable = 64;
+
 Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition, FCLInstructionVector &instructions);
 
 } // End of namespace Freescape


Commit: 11b6700f87c8a4a5c573644a6d0d7da4d632adca
    https://github.com/scummvm/scummvm/commit/11b6700f87c8a4a5c573644a6d0d7da4d632adca
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:57+01:00

Commit Message:
FREESCAPE: removed use of pointer and renamed area map

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/language/instruction.cpp
    engines/freescape/loaders/16bitBinaryLoader.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index e5052d15a49..cd6c54e7533 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -322,7 +322,7 @@ void FreescapeEngine::initGameState() {
 	for (int i = 0; i < k8bitMaxVariable; i++) // TODO: check maximum variable
 		_gameStateVars[i] = 0;
 
-	for (AreaMap::iterator it = _areasByAreaID->begin(); it != _areasByAreaID->end(); ++it)
+	for (AreaMap::iterator it = _areaMap.begin(); it != _areaMap.end(); ++it)
 		_gameStateBits[it->_key] = 0;
 
 	_gameStateVars[k8bitVariableEnergy] = 100;
@@ -495,8 +495,8 @@ void FreescapeEngine::gotoArea(uint16 areaID, int entranceID) {
 	if (!_gameStateBits.contains(areaID))
 		_gameStateBits[areaID] = 0;
 
-	assert(_areasByAreaID->contains(areaID));
-	_currentArea = (*_areasByAreaID)[areaID];
+	assert(_areaMap.contains(areaID));
+	_currentArea = _areaMap[areaID];
 	_currentArea->show();
 
 	int scale = _currentArea->getScale();
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index a4c0421af01..6a5117ebc5c 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -73,7 +73,7 @@ public:
 
 	// Areas
 	uint16 _startArea;
-	AreaMap *_areasByAreaID;
+	AreaMap _areaMap;
 	Area *_currentArea;
 	Math::Vector3d _scale;
 
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index e356c9be6d1..b0a3407bf3e 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -195,7 +195,7 @@ void FreescapeEngine::executeMakeInvisible(FCLInstruction &instruction) {
 	}
 
 	debugC(1, kFreescapeDebugCode, "Making obj %d invisible in area %d!", objectID, areaID);
-	Object *obj = (*_areasByAreaID)[areaID]->objectWithID(objectID);
+	Object *obj = _areaMap[areaID]->objectWithID(objectID);
 	obj->makeInvisible();
 }
 
@@ -211,7 +211,7 @@ void FreescapeEngine::executeMakeVisible(FCLInstruction &instruction) {
 	}
 
 	debugC(1, kFreescapeDebugCode, "Making obj %d visible in area %d!", objectID, areaID);
-	Object *obj = (*_areasByAreaID)[areaID]->objectWithID(objectID);
+	Object *obj = _areaMap[areaID]->objectWithID(objectID);
 	obj->makeVisible();
 }
 
@@ -227,7 +227,7 @@ void FreescapeEngine::executeToggleVisibility(FCLInstruction &instruction) {
 	}
 
 	debugC(1, kFreescapeDebugCode, "Toggling obj %d visibility in area %d!", objectID, areaID);
-	Object *obj = (*_areasByAreaID)[areaID]->objectWithID(objectID);
+	Object *obj = _areaMap[areaID]->objectWithID(objectID);
 	obj->toggleVisibility();
 }
 
diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
index f57769f1d67..c9694921102 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/16bitBinaryLoader.cpp
@@ -422,7 +422,6 @@ void FreescapeEngine::load16bitBinary(Common::SeekableReadStream *file) {
 	}
 
 	// grab the areas
-	AreaMap *areaMap = new AreaMap;
 	for (uint16 area = 0; area < numberOfAreas; area++) {
 		debug("Area offset %d", fileOffsetForArea[area]);
 
@@ -430,7 +429,7 @@ void FreescapeEngine::load16bitBinary(Common::SeekableReadStream *file) {
 		Area *newArea = load16bitArea(file);
 
 		if (newArea) {
-			(*areaMap)[newArea->getAreaID()] = newArea;
+			_areaMap[newArea->getAreaID()] = newArea;
 		}
 	}
 	// TODO
@@ -513,10 +512,8 @@ void FreescapeEngine::load16bitBinary(Common::SeekableReadStream *file) {
 	_startArea = startArea;
 	_startEntrance = startEntrance;
 	_colorNumber = colorNumber;
-	_areasByAreaID = areaMap;
 	_scale = Math::Vector3d(1, 1, 1);
 	_binaryBits = 16;
-	//return Binary{16, startArea, areaMap, raw_border, raw_palette, colorNumber};
 }
 
 } // namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 3cb128ffb9d..7eadf18cb83 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -431,7 +431,6 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	}
 
 	// grab the areas
-	AreaMap *areaMap = new AreaMap;
 	Area *newArea = nullptr;
 	for (uint16 area = 0; area < numberOfAreas; area++) {
 		debugC(1, kFreescapeDebugParser, "Area offset %d", fileOffsetForArea[area]);
@@ -440,8 +439,8 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 		newArea = load8bitArea(file, ncolors);
 
 		if (newArea) {
-			if (!areaMap->contains(newArea->getAreaID()))
-				(*areaMap)[newArea->getAreaID()] = newArea;
+			if (!_areaMap.contains(newArea->getAreaID()))
+				_areaMap[newArea->getAreaID()] = newArea;
 			else
 				debugC(1, kFreescapeDebugParser, "WARNING: area ID repeated: %d", newArea->getAreaID());
 		} else
@@ -451,8 +450,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	_playerWidth = 12;
 	_playerDepth = 32;
 
-	_areasByAreaID = areaMap;
-	if (!areaMap->contains(startArea))
+	if (_areaMap.contains(startArea))
 		_startArea = newArea->getAreaID();
 	else
 		_startArea = startArea;


Commit: 13631f3770e52334a07717e5982a35ec5308bde3
    https://github.com/scummvm/scummvm/commit/13631f3770e52334a07717e5982a35ec5308bde3
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:57+01:00

Commit Message:
FREESCAPE: save and restore level flags

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/freescape.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/objects/object.cpp
    engines/freescape/objects/object.h


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index af4774a6b3f..02d6d3715ef 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -98,6 +98,25 @@ void Area::show() {
 		debug("objID: %d, type: %d (entrance)", (*it)._value->getObjectID(), (*it)._value->getType());
 }
 
+void Area::loadObjectFlags(Common::SeekableReadStream *stream) {
+	for (int i = 0; i < int(objectsByID->size()); i++) {
+		uint16 key = stream->readUint32LE();
+		assert(objectsByID->contains(key));
+		Object *obj = (*objectsByID)[key];
+		obj->setObjectFlags(stream->readUint32LE());
+	}
+}
+
+void Area::saveObjectFlags(Common::WriteStream *stream) {
+	int dirtyFlags = 0;
+	//stream->writeUint32LE(objectsByID->size());
+
+	for (ObjectMap::iterator iterator = objectsByID->begin(); iterator != objectsByID->end(); iterator++) {
+		stream->writeUint32LE(iterator->_key);
+		stream->writeUint32LE(iterator->_value->getObjectFlags());
+	}
+}
+
 void Area::draw(Freescape::Renderer *gfx) {
 	if (palette)
 		gfx->_palette = palette;
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index 950722166af..81288613eb9 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -50,6 +50,10 @@ public:
 	Common::Array<Common::String*> conditionSources;
 	Common::Array<FCLInstructionVector> conditions;
 
+	// Serialization
+	void saveObjectFlags(Common::WriteStream *stream);
+	void loadObjectFlags(Common::SeekableReadStream *stream);
+
 private:
 	uint16 areaID;
 	uint8 scale;
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index cd6c54e7533..4758d74ba9f 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -299,7 +299,7 @@ Common::Error FreescapeEngine::run() {
 		Common::Rect viewArea(40, 16, 279, 116);
 		_border->fillRect(viewArea, 0xA0A0A0FF);
 	}
-
+	assert(_startArea == 1);
 	int saveSlot = ConfMan.getInt("save_slot");
 	if (saveSlot >= 0) { // load the savegame
 		loadGameState(saveSlot);
@@ -558,16 +558,23 @@ Common::Error FreescapeEngine::loadGameStream(Common::SeekableReadStream *stream
 	_pitch = stream->readFloatLE();
 
 	// Level state
-	for (int i = 0; i < _gameStateVars.size(); i++) {
+	for (int i = 0; i < int(_gameStateVars.size()); i++) {
 		uint16 key = stream->readUint16LE();
 		_gameStateVars[key] = stream->readUint32LE();
 	}
 
-	for (int i = 0; i < _gameStateBits.size(); i++) {
+	for (int i = 0; i < int(_gameStateBits.size()); i++) {
 		uint16 key = stream->readUint16LE();
 		_gameStateBits[key] = stream->readUint32LE();
 	}
 
+	for (int i = 0; i < int(_areaMap.size()); i++) {
+		uint16 key = stream->readUint16LE();
+		assert(_areaMap.contains(key));
+		Area *area = _areaMap[key];
+		area->loadObjectFlags(stream);
+	}
+
 	if (!_currentArea || _currentArea->getAreaID() != areaID)
 		gotoArea(areaID, -1); // Do not change position nor rotation
 	return Common::kNoError;
@@ -599,6 +606,11 @@ Common::Error FreescapeEngine::saveGameStream(Common::WriteStream *stream, bool
 		stream->writeUint32LE(it->_value);
 	}
 
+	for (AreaMap::iterator it = _areaMap.begin(); it != _areaMap.end(); ++it) {
+		stream->writeUint16LE(it->_key);
+		it->_value->saveObjectFlags(stream);
+	}
+
 	return Common::kNoError;
 }
 
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 7eadf18cb83..4487d8685d5 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -450,7 +450,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	_playerWidth = 12;
 	_playerDepth = 32;
 
-	if (_areaMap.contains(startArea))
+	if (!_areaMap.contains(startArea))
 		_startArea = newArea->getAreaID();
 	else
 		_startArea = startArea;
diff --git a/engines/freescape/objects/object.cpp b/engines/freescape/objects/object.cpp
index d7efa610442..bfbbf4f7bc6 100644
--- a/engines/freescape/objects/object.cpp
+++ b/engines/freescape/objects/object.cpp
@@ -15,6 +15,7 @@ namespace Freescape {
 Object::Type Object::getType() { return _type; }
 uint16 Object::getObjectID() { return _objectID; }
 uint16 Object::getObjectFlags() { return _flags; }
+void Object::setObjectFlags(uint32 flags) { _flags = flags; }
 Math::Vector3d Object::getOrigin() { return origin; }
 Math::Vector3d Object::getSize() { return size; }
 
diff --git a/engines/freescape/objects/object.h b/engines/freescape/objects/object.h
index a272b04a00c..242b0adfab0 100644
--- a/engines/freescape/objects/object.h
+++ b/engines/freescape/objects/object.h
@@ -44,6 +44,7 @@ public:
 	virtual Type getType();
 	uint16 getObjectID();
 	uint16 getObjectFlags();
+	void setObjectFlags(uint32 flags);
 	Math::Vector3d getOrigin();
 	Math::Vector3d getSize();
 


Commit: 91c0529a851b6ca68cecbb1842418110627a61e1
    https://github.com/scummvm/scummvm/commit/91c0529a851b6ca68cecbb1842418110627a61e1
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:57+01:00

Commit Message:
FREESCAPE: improved check collision detection

Changed paths:
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 4758d74ba9f..1908d536db8 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -468,8 +468,8 @@ bool FreescapeEngine::checkCollisions(bool executeConditions) {
 	Math::Vector3d v2;
 
 	if (executeConditions) {
-		v1 = Math::Vector3d(_position.x() -  areaScale * 3 * _playerWidth / 4, _position.y() - (areaScale + 1) * _playerHeight , _position.z() - areaScale * 3 * _playerDepth / 4);
-		v2 = Math::Vector3d(_position.x() +  areaScale * 3 * _playerWidth / 4, _position.y()                             , _position.z() + areaScale * 3 * _playerDepth / 4);
+		v1 = Math::Vector3d(_position.x() -  areaScale * 3 * _playerWidth / 5, _position.y() - (areaScale + 1) * _playerHeight , _position.z() - areaScale * 3 * _playerDepth / 5);
+		v2 = Math::Vector3d(_position.x() +  areaScale * 3 * _playerWidth / 5, _position.y()                                   , _position.z() + areaScale * 3 * _playerDepth / 5);
 	} else {
 		v1 = Math::Vector3d(_position.x() - areaScale * _playerWidth / 2, _position.y() - areaScale * _playerHeight , _position.z() - areaScale * _playerDepth / 2);
 		v2 = Math::Vector3d(_position.x() + areaScale * _playerWidth / 2, _position.y()                             , _position.z() + areaScale * _playerDepth / 2);


Commit: 1984138437444f270c9868d19dec9a8d38dad2b3
    https://github.com/scummvm/scummvm/commit/1984138437444f270c9868d19dec9a8d38dad2b3
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:58+01:00

Commit Message:
FREESCAPE: correctly allocate an speaker audio object for each sound

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 1908d536db8..5079015973e 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -539,10 +539,11 @@ bool FreescapeEngine::hasFeature(EngineFeature f) const {
 }
 
 void FreescapeEngine::playSound(int index) {
+	_mixer->stopAll();
 	debug("Playing sound %d", index);
-	_speaker.setVolume(Audio::Mixer::kMaxChannelVolume);
-	_speaker.play(Audio::PCSpeaker::kWaveFormSine, 2000, 100);
-	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_speakerHandle, &_speaker);
+	Audio::PCSpeaker *speaker = new Audio::PCSpeaker();
+	speaker->play(Audio::PCSpeaker::kWaveFormSine, 2000, 100);
+	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_speakerHandle, speaker);
 }
 
 Common::Error FreescapeEngine::loadGameStream(Common::SeekableReadStream *stream) {
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 6a5117ebc5c..451c60af09f 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -139,7 +139,6 @@ public:
 
 	// Sound
 	Audio::SoundHandle _speakerHandle;
-	Audio::PCSpeaker _speaker;
 	void playSound(int index);
 
 	// Rendering


Commit: 9d566d20d8a0cdcc82e2044209b75e2b8f915825
    https://github.com/scummvm/scummvm/commit/9d566d20d8a0cdcc82e2044209b75e2b8f915825
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:58+01:00

Commit Message:
FREESCAPE: save and restore vehicle information

Changed paths:
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 5079015973e..72e2ad447a6 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -576,6 +576,7 @@ Common::Error FreescapeEngine::loadGameStream(Common::SeekableReadStream *stream
 		area->loadObjectFlags(stream);
 	}
 
+	_flyMode = stream->readByte();
 	if (!_currentArea || _currentArea->getAreaID() != areaID)
 		gotoArea(areaID, -1); // Do not change position nor rotation
 	return Common::kNoError;
@@ -612,6 +613,7 @@ Common::Error FreescapeEngine::saveGameStream(Common::WriteStream *stream, bool
 		it->_value->saveObjectFlags(stream);
 	}
 
+	stream->writeByte(_flyMode);
 	return Common::kNoError;
 }
 


Commit: 7dcd4b2be64beb2e66dae96b70a047082c8ad1f0
    https://github.com/scummvm/scummvm/commit/7dcd4b2be64beb2e66dae96b70a047082c8ad1f0
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:58+01:00

Commit Message:
FREESCAPE: execute room/global conditions

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 72e2ad447a6..86661759d50 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -481,10 +481,25 @@ bool FreescapeEngine::checkCollisions(bool executeConditions) {
 	if (obj != nullptr) {
 		debugC(1, kFreescapeDebugMove, "Collided with object id %d of size %f %f %f", obj->getObjectID(), obj->getSize().x(), obj->getSize().y(), obj->getSize().z());
 		GeometricObject *gobj = (GeometricObject*) obj;
-		if (gobj->conditionSource != nullptr && executeConditions) {
-			debug("Must use collision = true when executing: %s", gobj->conditionSource->c_str());
+		if (!executeConditions) // Avoid executing code
+			return true;
+
+		if (gobj->conditionSource != nullptr) {
+			debugC(1, kFreescapeDebugCode, "Executing with collision flag: %s", gobj->conditionSource->c_str());
 			executeCode(gobj->condition, false, true);
 		}
+
+		debugC(1, kFreescapeDebugCode, "Executing room conditions");
+		for (int i = 0; i < int(_currentArea->conditions.size()); i++) {
+			debugC(1, kFreescapeDebugCode, "Executing with collision flag: %s", _currentArea->conditionSources[i]->c_str());
+			executeCode(_currentArea->conditions[i], true, false);
+		}
+
+		debugC(1, kFreescapeDebugCode, "Executing global conditions (%d)", _conditions.size());
+		for (int i = 0; i < int(_conditions.size()); i++) {
+			//debugC(1, kFreescapeDebugCode, "Executing with collision flag: %s", _conditionSources[i]->c_str());
+			executeCode(_conditions[i], false, true);
+		}
 		return true;
 	}
 	return false;
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 451c60af09f..208ebdc51a5 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -114,6 +114,9 @@ public:
 	uint16 _playerDepth;
 
 	// Effects
+	Common::Array<Common::String*> _conditionSources;
+	Common::Array<FCLInstructionVector> _conditions;
+
 	bool checkCollisions(bool executeConditions);
 	void executeCode(FCLInstructionVector &code, bool shot, bool collided);
 
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 4487d8685d5..27ee48e9cc7 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -408,8 +408,10 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 		file->read(conditionData, lengthOfCondition);
 		Common::Array<uint8> conditionArray(conditionData, lengthOfCondition);
 		//debug("Global condition %d", numConditions + 1);
-		Common::String *conditions = detokenise8bitCondition(conditionArray, instructions);
-		debugC(1, kFreescapeDebugParser, "%s", conditions->c_str());
+		Common::String *conditionSource = detokenise8bitCondition(conditionArray, instructions);
+		_conditions.push_back(instructions);
+		_conditionSources.push_back(conditionSource);
+		debugC(1, kFreescapeDebugParser, "%s", conditionSource->c_str());
 	}
 
 	if (_targetName.hasPrefix("driller")) {


Commit: 0864babe560c83ce84d0c892d26a96844b03205d
    https://github.com/scummvm/scummvm/commit/0864babe560c83ce84d0c892d26a96844b03205d
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:58+01:00

Commit Message:
FREESCAPE: refector code that executes object/room/global conditions

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/language/instruction.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 86661759d50..5b8f169e977 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -248,18 +248,12 @@ void FreescapeEngine::shoot() {
 	if (shot) {
 		GeometricObject *gobj = (GeometricObject*) shot;
 		debug("Shot object %d with flags %x", gobj->getObjectID(), gobj->getObjectFlags());
-		if (gobj->conditionSource != nullptr) {
+
+		if (gobj->conditionSource != nullptr)
 			debug("Must use shot = true when executing: %s", gobj->conditionSource->c_str());
-			executeCode(gobj->condition, true, false);
-		}
-	}
 
-	for (int i = 0; i < int(_currentArea->conditionSources.size()); i++) {
-		debug("Must use shot = true executing: %s", _currentArea->conditionSources[i]->c_str());
-		executeCode(_currentArea->conditions[i], true, false);
+		executeConditions(gobj, true, false);
 	}
-
-	//debug("camera front: %f %f %f", _cameraFront.x(), _rotation.y(), _rotation.z());
 }
 
 Common::Error FreescapeEngine::run() {
@@ -461,13 +455,13 @@ bool FreescapeEngine::tryStepDown(Math::Vector3d currentPosition) {
 }
 
 
-bool FreescapeEngine::checkCollisions(bool executeConditions) {
+bool FreescapeEngine::checkCollisions(bool executeCode) {
 	int areaScale = _currentArea->getScale();
 
 	Math::Vector3d v1;
 	Math::Vector3d v2;
 
-	if (executeConditions) {
+	if (executeCode) {
 		v1 = Math::Vector3d(_position.x() -  areaScale * 3 * _playerWidth / 5, _position.y() - (areaScale + 1) * _playerHeight , _position.z() - areaScale * 3 * _playerDepth / 5);
 		v2 = Math::Vector3d(_position.x() +  areaScale * 3 * _playerWidth / 5, _position.y()                                   , _position.z() + areaScale * 3 * _playerDepth / 5);
 	} else {
@@ -481,25 +475,10 @@ bool FreescapeEngine::checkCollisions(bool executeConditions) {
 	if (obj != nullptr) {
 		debugC(1, kFreescapeDebugMove, "Collided with object id %d of size %f %f %f", obj->getObjectID(), obj->getSize().x(), obj->getSize().y(), obj->getSize().z());
 		GeometricObject *gobj = (GeometricObject*) obj;
-		if (!executeConditions) // Avoid executing code
+		if (!executeCode) // Avoid executing code
 			return true;
 
-		if (gobj->conditionSource != nullptr) {
-			debugC(1, kFreescapeDebugCode, "Executing with collision flag: %s", gobj->conditionSource->c_str());
-			executeCode(gobj->condition, false, true);
-		}
-
-		debugC(1, kFreescapeDebugCode, "Executing room conditions");
-		for (int i = 0; i < int(_currentArea->conditions.size()); i++) {
-			debugC(1, kFreescapeDebugCode, "Executing with collision flag: %s", _currentArea->conditionSources[i]->c_str());
-			executeCode(_currentArea->conditions[i], true, false);
-		}
-
-		debugC(1, kFreescapeDebugCode, "Executing global conditions (%d)", _conditions.size());
-		for (int i = 0; i < int(_conditions.size()); i++) {
-			//debugC(1, kFreescapeDebugCode, "Executing with collision flag: %s", _conditionSources[i]->c_str());
-			executeCode(_conditions[i], false, true);
-		}
+		executeConditions(gobj, false, true);
 		return true;
 	}
 	return false;
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 208ebdc51a5..fa8394722eb 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -13,6 +13,7 @@
 #include "audio/softsynth/pcspk.h"
 
 #include "freescape/area.h"
+#include "freescape/objects/geometricobject.h"
 #include "freescape/objects/entrance.h"
 #include "freescape/language/instruction.h"
 #include "freescape/gfx.h"
@@ -117,7 +118,8 @@ public:
 	Common::Array<Common::String*> _conditionSources;
 	Common::Array<FCLInstructionVector> _conditions;
 
-	bool checkCollisions(bool executeConditions);
+	bool checkCollisions(bool executeCode);
+	void executeConditions(GeometricObject *obj, bool shot, bool collided);
 	void executeCode(FCLInstructionVector &code, bool shot, bool collided);
 
 	// Instructions
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index b0a3407bf3e..ea7d74a3cbd 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -42,6 +42,25 @@ Token::Type FCLInstruction::getType() {
 	return type;
 }
 
+void FreescapeEngine::executeConditions(GeometricObject *obj, bool shot, bool collided) {
+	if (obj->conditionSource != nullptr) {
+		debugC(1, kFreescapeDebugCode, "Executing with collision flag: %s", obj->conditionSource->c_str());
+		executeCode(obj->condition, shot, collided);
+	}
+
+	debugC(1, kFreescapeDebugCode, "Executing room conditions");
+	for (int i = 0; i < int(_currentArea->conditions.size()); i++) {
+		debugC(1, kFreescapeDebugCode, "Executing with collision flag: %s", _currentArea->conditionSources[i]->c_str());
+		executeCode(_currentArea->conditions[i], shot, collided);
+	}
+
+	debugC(1, kFreescapeDebugCode, "Executing global conditions (%d)", _conditions.size());
+	for (int i = 0; i < int(_conditions.size()); i++) {
+		//debugC(1, kFreescapeDebugCode, "Executing with collision flag: %s", _conditionSources[i]->c_str());
+		executeCode(_conditions[i], shot, collided);
+	}
+}
+
 void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool collided) {
 	assert(!(shot && collided));
 	int ip = 0;


Commit: 32cba2439735e8b300cc4262d8c59a1482b1f981
    https://github.com/scummvm/scummvm/commit/32cba2439735e8b300cc4262d8c59a1482b1f981
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:58+01:00

Commit Message:
FREESCAPE: better transition between levels

Changed paths:
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 5b8f169e977..14193f3d488 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -400,15 +400,17 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 	} else {
 		debugC(1, kFreescapeDebugCode, "Runing effects:");
 		checkCollisions(true); // run the effects
-		if (_flyMode)
-			_position = _lastPosition;
-		else if (_currentArea->getAreaID() == previousAreaID) {
-			bool stepUp = tryStepUp(_position);
-			if (stepUp) {
-				debugC(1, kFreescapeDebugCode, "Runing effects:");
-				checkCollisions(true); // run the effects (again)
-			} else {
+		if (_currentArea->getAreaID() == previousAreaID) {
+			if (_flyMode)
 				_position = _lastPosition;
+			else {
+				bool stepUp = tryStepUp(_position);
+				if (stepUp) {
+					debugC(1, kFreescapeDebugCode, "Runing effects:");
+					checkCollisions(true); // run the effects (again)
+				} else {
+					_position = _lastPosition;
+				}
 			}
 		}
 	}
@@ -512,15 +514,23 @@ void FreescapeEngine::gotoArea(uint16 areaID, int entranceID) {
 		_position.setValue(1, _position.y() + scale * _playerHeight);
 	} else if (entranceID == 0) {
 		Math::Vector3d diff = _lastPosition - _position;
-		debug("%f %f %f", diff.x(), diff.y(), diff.z());
+		debug("dif: %f %f %f", diff.x(), diff.y(), diff.z());
 		// diff should be used to determinate which entrance to use
-		entrance = (Entrance*) _currentArea->firstEntrance();
-		assert(entrance);
-		if (abs(diff.x()) < abs(diff.z()))
-			_position.setValue(2, entrance->getOrigin().z());
-		else
-			_position.setValue(0, entrance->getOrigin().x());
-
+		int newPos = -1;
+		if (abs(diff.x()) < abs(diff.z())) {
+			if (diff.z() > 0)
+				newPos = 4000;
+			else
+				newPos = 100;
+			_position.setValue(2, newPos);
+		} else {
+			if (diff.x() > 0)
+				newPos = 4000;
+			else
+				newPos = 100;
+			_position.setValue(0, newPos);
+		}
+		assert(newPos != -1);
 	}
 
 	debugC(1, kFreescapeDebugMove, "starting player position: %f, %f, %f", _position.x(), _position.y(), _position.z());


Commit: 67249c9c85e960c64ae535988eb18ed629947919
    https://github.com/scummvm/scummvm/commit/67249c9c85e960c64ae535988eb18ed629947919
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:58+01:00

Commit Message:
FREESCAPE: implemented additional opcode for driller

Changed paths:
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/language/instruction.cpp
    engines/freescape/language/instruction.h


diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index 8d3d95c9c53..ab98111c11e 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -224,6 +224,10 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			detokenisedStream += "IF RVIS? ";
 			detokenisedStream += Common::String::format("(%d), (%d)", (int)tokenisedCondition[bytePointer], (int)tokenisedCondition[bytePointer + 1]);
 			detokenisedStream += "THEN END ENDIF";
+			currentInstruction = FCLInstruction(Token::INVISQ);
+			currentInstruction.setSource(tokenisedCondition[bytePointer]);
+			currentInstruction.setAdditional(tokenisedCondition[bytePointer + 1]);
+			currentInstruction.setDestination(false); // visible
 			bytePointer += 2;
 			numberOfArguments = 0;
 			break;
@@ -232,6 +236,10 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			detokenisedStream += "IF RINVIS? ";
 			detokenisedStream += Common::String::format("(%d), (%d)", (int)tokenisedCondition[bytePointer], (int)tokenisedCondition[bytePointer + 1]);
 			detokenisedStream += "THEN END ENDIF";
+			currentInstruction = FCLInstruction(Token::INVISQ);
+			currentInstruction.setSource(tokenisedCondition[bytePointer]);
+			currentInstruction.setAdditional(tokenisedCondition[bytePointer + 1]);
+			currentInstruction.setDestination(true); // invisible
 			bytePointer += 2;
 			numberOfArguments = 0;
 			break;
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index ea7d74a3cbd..3674130c1a5 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -13,6 +13,9 @@
 namespace Freescape {
 
 FCLInstruction::FCLInstruction(Token::Type _type) {
+	source = 0;
+	destination = 0;
+	additional = 0;
 	// TODO: learn modern constructor syntax
 	type = _type;
 	thenInstructions = nullptr;
@@ -20,6 +23,9 @@ FCLInstruction::FCLInstruction(Token::Type _type) {
 }
 
 FCLInstruction::FCLInstruction() {
+	source = 0;
+	destination = 0;
+	additional = 0;
 	type = Token::UNKNOWN;
 	thenInstructions = nullptr;
 	elseInstructions = nullptr;
@@ -29,6 +35,10 @@ void FCLInstruction::setSource(int32 _source) {
 	source = _source;
 }
 
+void FCLInstruction::setAdditional(int32 _additional) {
+	additional = _additional;
+}
+
 void FCLInstruction::setDestination(int32 _destination) {
 	destination = _destination;
 }
@@ -159,11 +169,22 @@ void FreescapeEngine::executeDelay(FCLInstruction &instruction) {
 }
 
 bool FreescapeEngine::executeEndIfVisibilityIsNotEqual(FCLInstruction &instruction) {
-	uint16 objectID = instruction.source;
+	uint16 source = instruction.source;
+	uint16 additional = instruction.additional;
 	uint16 value = instruction.destination;
-	debugC(1, kFreescapeDebugCode, "End condition if visibility of obj with id %d is %d!", objectID, value);
-	Object *obj = _currentArea->objectWithID(objectID);
-	assert(obj);
+
+	Object *obj = nullptr;
+	if (additional == 0) {
+		obj = _currentArea->objectWithID(source);
+		assert(obj);
+		debugC(1, kFreescapeDebugCode, "End condition if visibility of obj with id %d is %d!", source, value);
+	} else {
+		assert(_areaMap.contains(source));
+		obj = _areaMap[source]->objectWithID(additional);
+		assert(obj);
+		debugC(1, kFreescapeDebugCode, "End condition if visibility of obj with id %d in area %d is %d!", additional, source, value);
+	}
+
 	return (obj->isInvisible() == value);
 }
 
@@ -247,7 +268,11 @@ void FreescapeEngine::executeToggleVisibility(FCLInstruction &instruction) {
 
 	debugC(1, kFreescapeDebugCode, "Toggling obj %d visibility in area %d!", objectID, areaID);
 	Object *obj = _areaMap[areaID]->objectWithID(objectID);
-	obj->toggleVisibility();
+	if (obj)
+		obj->toggleVisibility();
+	else
+		debugC(1, kFreescapeDebugCode, "WARNING!: obj %d does not exists in area %d!", objectID, areaID);
+
 }
 
 void FreescapeEngine::executeGoto(FCLInstruction &instruction) {
diff --git a/engines/freescape/language/instruction.h b/engines/freescape/language/instruction.h
index be78e090304..873c8f18c3b 100644
--- a/engines/freescape/language/instruction.h
+++ b/engines/freescape/language/instruction.h
@@ -22,12 +22,14 @@ public:
 	FCLInstruction();
 	FCLInstruction(Token::Type type);
 	void setSource(int32 _source);
+	void setAdditional(int32 _additional);
 	void setDestination(int32 _destination);
 
 	Token::Type getType();
 	void setBranches(FCLInstructionVector *thenBranch, FCLInstructionVector *elseBranch);
 
 	int32 source;
+	int32 additional;
 	int32 destination;
 
 	FCLInstructionVector *thenInstructions;


Commit: 999c7785b668765e864e1a3bec5f9eeab61b0627
    https://github.com/scummvm/scummvm/commit/999c7785b668765e864e1a3bec5f9eeab61b0627
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:59+01:00

Commit Message:
FREESCAPE: removed useless assert

Changed paths:
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 14193f3d488..0b2ac75ec81 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -293,7 +293,6 @@ Common::Error FreescapeEngine::run() {
 		Common::Rect viewArea(40, 16, 279, 116);
 		_border->fillRect(viewArea, 0xA0A0A0FF);
 	}
-	assert(_startArea == 1);
 	int saveSlot = ConfMan.getInt("save_slot");
 	if (saveSlot >= 0) { // load the savegame
 		loadGameState(saveSlot);


Commit: 095709ac45a51e9ff1f081592384e7be23911398
    https://github.com/scummvm/scummvm/commit/095709ac45a51e9ff1f081592384e7be23911398
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:59+01:00

Commit Message:
FREESCAPE: added basic implementation of room structure for eclipse and castle

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/freescape.h
    engines/freescape/language/instruction.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/objects/entrance.cpp
    engines/freescape/objects/entrance.h


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 02d6d3715ef..65a2790bcc8 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -8,6 +8,7 @@
 
 #include "freescape/area.h"
 #include "freescape/objects/geometricobject.h"
+#include "freescape/objects/entrance.h"
 #include "common/algorithm.h"
 #include "freescape/objects/object.h"
 
@@ -169,89 +170,46 @@ Object *Area::checkCollisions(const Math::AABB &boundingBox) {
 	return collided;
 }
 
-void Area::addStructure() {
-
-	Object *data = (*entrancesByID)[255];
-
-	if (data == nullptr)
+void Area::addStructure(Area *structure) {
+	Object *obj = nullptr;
+	if (!structure || !entrancesByID->contains(255)) {
+		int id = 254;
+		Common::Array<uint8> *gColors = new Common::Array<uint8>;
+		for (int i = 0; i < 6; i++)
+			gColors->push_back(0);
+
+		obj = (Object*) new GeometricObject(
+			Object::Type::Cube,
+			id,
+			0, // flags
+			Math::Vector3d(0, -1, 0), // Position
+			Math::Vector3d(4128, 1, 4128), // size
+			gColors,
+			nullptr,
+			FCLInstructionVector()
+		);
+		(*objectsByID)[id] = obj;
+		drawableObjects.insert_at(0, obj);
 		return;
-
-	FCLInstructionVector empty;
-	Common::Array<uint8> *gColors = new Common::Array<uint8>;
-	for (int i = 0; i < 6; i++)
-		gColors->push_back(0xd);
-
-	int id = 200;
-	GeometricObject *gobj = nullptr;
-
-	// Floor
-	gobj = new GeometricObject(
-		Object::Type::Cube,
-		id,
-		0, // flags
-		Math::Vector3d(0, 1, 0), // Position
-		Math::Vector3d(128 * 32, 1, 135 * 32), // size
-		gColors,
-		nullptr,
-		empty
-	);
-	(*objectsByID)[id] = (Object*) gobj;
-	drawableObjects.insert_at(0, gobj);
-
-	gColors = new Common::Array<uint8>;
-	for (int i = 0; i < 6; i++)
-		gColors->push_back(0x0);
-
-	// East Wall
-	id++;
-	gobj = new GeometricObject(
-		Object::Type::Cube,
-		id,
-		0, // flags
-		//Math::Vector3d(-64 + 22*32, 0, 0), // Position
-		Math::Vector3d(22*32, 0, 0), // Position
-
-		Math::Vector3d(1, 8128, 8128), // size
-		gColors,
-		nullptr,
-		empty
-	);
-	(*objectsByID)[id] = (Object*) gobj;
-	drawableObjects.insert_at(0, gobj);
-
-	// West Wall
-	id++;
-	gobj = new GeometricObject(
-		Object::Type::Cube,
-		id,
-		0, // flags
-		Math::Vector3d(2*22*32, 0, 0), // Position
-		Math::Vector3d(1, 8128, 8128), // size
-		gColors,
-		nullptr,
-		empty
-	);
-	(*objectsByID)[id] = (Object*) gobj;
-	drawableObjects.insert_at(0, gobj);
-
-	gColors = new Common::Array<uint8>;
-	for (int i = 0; i < 6; i++)
-		gColors->push_back(0xe);
-
-	// North Wall
-	id++;
-	gobj = new GeometricObject(
-		Object::Type::Cube,
-		id,
-		0, // flags
-		Math::Vector3d(0, 0, 2080), // Position
-		Math::Vector3d(8128, 8128, 1), // size
-		gColors,
-		nullptr,
-		empty
-	);
-	(*objectsByID)[id] = (Object*) gobj;
-	drawableObjects.insert_at(0, gobj);
+	}
+	RoomStructure *rs = (RoomStructure*) (*entrancesByID)[255];
+
+	for (int i = 0; i < int(rs->structure.size()); i++) {
+		int16 id = rs->structure[i];
+		if (id == 0)
+			continue;
+
+		debug("Adding object %d to room structure", id);
+		obj = structure->objectWithID(id);
+		if (!obj) {
+			assert(structure->entranceWithID(id));
+			(*entrancesByID)[id] = structure->entranceWithID(id);
+		} else {
+			(*objectsByID)[id] = structure->objectWithID(id);
+			if (obj->isDrawable())
+				drawableObjects.insert_at(0, obj);
+		}
+	}
 }
 
 } // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index 81288613eb9..f835bbca8bf 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -45,7 +45,7 @@ public:
 
 	Object *shootRay(const Math::Ray &ray);
 	Object *checkCollisions(const Math::AABB &boundingBox);
-	void addStructure();
+	void addStructure(Area *structure);
 
 	Common::Array<Common::String*> conditionSources;
 	Common::Array<FCLInstructionVector> conditions;
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index fa8394722eb..1193a15db8e 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -29,7 +29,7 @@ enum CameraMovement {
     RIGHT
 };
 
-typedef Common::HashMap<uint16, Area *> AreaMap;
+typedef Common::HashMap<uint16, Area*> AreaMap;
 typedef Common::HashMap<uint16, int32> StateVars;
 typedef Common::HashMap<uint16, uint32> StateBits;
 
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index 3674130c1a5..521f0b7b15f 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -58,6 +58,9 @@ void FreescapeEngine::executeConditions(GeometricObject *obj, bool shot, bool co
 		executeCode(obj->condition, shot, collided);
 	}
 
+	if (!_targetName.hasPrefix("driller"))
+		return;
+
 	debugC(1, kFreescapeDebugCode, "Executing room conditions");
 	for (int i = 0; i < int(_currentArea->conditions.size()); i++) {
 		debugC(1, kFreescapeDebugCode, "Executing with collision flag: %s", _currentArea->conditionSources[i]->c_str());
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 27ee48e9cc7..9182d33b659 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -41,12 +41,27 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 	debugC(1, kFreescapeDebugParser, "Raw object %d ; type %d ; size %d", objectID, (int)objectType, byteSizeOfObject);
 	if (byteSizeOfObject < 9) {
 		error("Not enough bytes %d to read object %d with type %d", byteSizeOfObject, objectID, objectType);
-		//file->seek(byteSizeOfObject, SEEK_CUR);
-		//return nullptr;
 	}
 
 	assert(byteSizeOfObject >= 9);
 	byteSizeOfObject = byteSizeOfObject - 9;
+	if (objectID == 255) {
+		debug("Found the room structure (objectID: 255 with size %d)", byteSizeOfObject + 6);
+		byte *structureData = (byte*)malloc(byteSizeOfObject + 6);
+		structureData[0] = int(position.x());
+		structureData[1] = int(position.y());
+		structureData[2] = int(position.z());
+
+		structureData[3] = int(v.x());
+		structureData[4] = int(v.y());
+		structureData[5] = int(v.z());
+
+		if (byteSizeOfObject > 0)
+			file->read(structureData+6, byteSizeOfObject);
+		Common::Array<uint8> structureArray(structureData, byteSizeOfObject + 6);
+		return new RoomStructure(structureArray);
+	}
+
 	debugC(1, kFreescapeDebugParser, "Object %d ; type %d ; size %d", objectID, (int)objectType, byteSizeOfObject);
     debugC(1, kFreescapeDebugParser, "pos: %f %f %f", position.x(), position.y(), position.z());
 	switch (objectType) {
@@ -356,8 +371,10 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 		debugC(1, kFreescapeDebugParser, "%s", conditionSource->c_str());
 	}
 
-	if (_targetName.hasPrefix("castlemaster") || _targetName.hasPrefix("totaleclipse"))
-		area->addStructure();
+	if (_areaMap.contains(255))
+		area->addStructure(_areaMap[255]);
+	else if (_targetName.hasPrefix("castle") || _targetName.hasPrefix("totaleclipse"))
+		area->addStructure(nullptr);
 
 	debugC(1, kFreescapeDebugParser, "End of area at %lx", file->pos());
 	return area;
diff --git a/engines/freescape/objects/entrance.cpp b/engines/freescape/objects/entrance.cpp
index dbbbb7a591e..306d77b1990 100644
--- a/engines/freescape/objects/entrance.cpp
+++ b/engines/freescape/objects/entrance.cpp
@@ -13,6 +13,11 @@
 
 namespace Freescape {
 
+RoomStructure::RoomStructure(const Common::Array<byte> _structure) {
+	_objectID = 255;
+	structure = _structure;
+}
+
 Entrance::Entrance(
 	uint16 objectID,
 	const Math::Vector3d &_origin,
diff --git a/engines/freescape/objects/entrance.h b/engines/freescape/objects/entrance.h
index 2891184d564..3fa99e73e31 100644
--- a/engines/freescape/objects/entrance.h
+++ b/engines/freescape/objects/entrance.h
@@ -13,6 +13,14 @@
 
 namespace Freescape {
 
+class RoomStructure : public Object {
+public:
+	Common::Array<byte> structure;
+	RoomStructure(const Common::Array<byte> _structure);
+	Type getType() override { return Type::Entrance; };
+	void draw(Freescape::Renderer *gfx) override { error("cannot render RoomStructure"); };
+};
+
 class Entrance : public Object {
 public:
 


Commit: 16fcdfb27e1108a259699a670ca2576389c6ab08
    https://github.com/scummvm/scummvm/commit/16fcdfb27e1108a259699a670ca2576389c6ab08
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:59+01:00

Commit Message:
FREESCAPE: implement some area flags

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/loaders/16bitBinaryLoader.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 65a2790bcc8..07169d845ab 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -38,12 +38,17 @@ uint16 Area::getAreaID() {
 	return areaID;
 }
 
+uint16 Area::getAreaFlags() {
+	return areaFlags;
+}
+
 uint8 Area::getScale() {
 	return scale;
 }
 
 Area::Area(
 	uint16 _areaID,
+	uint16 _areaFlags,
 	ObjectMap *_objectsByID,
 	ObjectMap *_entrancesByID,
 	uint8 _scale,
@@ -55,6 +60,7 @@ Area::Area(
 	skyColor = _skyColor;
 	groundColor = _groundColor;
 	areaID = _areaID;
+	areaFlags = _areaFlags;
 	objectsByID = _objectsByID;
 	entrancesByID = _entrancesByID;
 
@@ -122,13 +128,18 @@ void Area::draw(Freescape::Renderer *gfx) {
 	if (palette)
 		gfx->_palette = palette;
 
-	gfx->clear();
-	if (skyColor != 255)
-		gfx->drawSky(skyColor);
+	if (areaFlags & 0x80)
+		gfx->_keyColor = 0;
+	else
+		gfx->_keyColor = 255;
 
-	if (groundColor != 255)
+	gfx->clear();
+	if (areaFlags & 0x01)
 		gfx->drawFloor(groundColor);
 
+	if (areaFlags & 0x02)
+		gfx->drawSky(skyColor);
+
 	assert(drawableObjects.size() > 0);
 	for (Common::Array<Object *>::iterator it = drawableObjects.begin(); it != drawableObjects.end(); it++) {
 		if (!(*it)->isDestroyed() && !(*it)->isInvisible()) {
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index f835bbca8bf..4740ba59764 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -27,6 +27,7 @@ class Area {
 public:
 	Area(
 		uint16 areaID,
+		uint16 areaFlags,
 		ObjectMap *objectsByID,
 		ObjectMap *entrancesByID,
 		uint8 scale,
@@ -39,6 +40,7 @@ public:
 	Object *entranceWithID(uint16 objectID);
 	Object *firstEntrance();
 	uint16 getAreaID();
+	uint16 getAreaFlags();
 	uint8 getScale();
 	void draw(Renderer *gfx);
 	void show();
@@ -56,6 +58,7 @@ public:
 
 private:
 	uint16 areaID;
+	uint16 areaFlags;
 	uint8 scale;
 	Graphics::PixelBuffer *palette;
 	uint8 skyColor;
diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
index c9694921102..07b111c49a3 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/16bitBinaryLoader.cpp
@@ -175,12 +175,12 @@ static Object *load16bitObject(Common::SeekableReadStream *file) {
 Area *load16bitArea(Common::SeekableReadStream *file) {
 	// the lowest bit of this value seems to indicate
 	// horizon on or off; this is as much as I currently know
-	uint16 skippedValue = file->readUint16BE();
+	uint16 areaFlags = file->readUint16BE();
 	uint16 numberOfObjects = file->readUint16BE();
 	uint16 areaNumber = file->readUint16BE();
 
 	debug("Area %d", areaNumber);
-	debug("Skipped value %d", skippedValue);
+	debug("Area flags %d", areaFlags);
 	debug("Objects: %d", numberOfObjects);
 
 	// I've yet to decipher this fully
@@ -256,7 +256,7 @@ Area *load16bitArea(Common::SeekableReadStream *file) {
 		debug("%s", detokenise16bitCondition(conditionArray)->c_str());
 	}
 
-	return (new Area(areaNumber, objectsByID, entrancesByID, 1, skyColor, groundColor));
+	return (new Area(areaNumber, areaFlags, objectsByID, entrancesByID, 1, skyColor, groundColor));
 }
 
 void FreescapeEngine::load16bitBinary(Common::SeekableReadStream *file) {
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 9182d33b659..c7f869d6bbc 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -282,7 +282,7 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 
 	uint32 base = file->pos();
 	debugC(1, kFreescapeDebugParser, "Area base: %x", base);
-	uint8 skippedValue = file->readByte();
+	uint8 areaFlags = file->readByte();
 	uint8 numberOfObjects = file->readByte();
 	uint8 areaNumber = file->readByte();
 
@@ -315,7 +315,7 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	Graphics::PixelBuffer *palette = getPalette(areaNumber, ci1, ci2, skyColor, groundColor, ncolors);
 
 	debugC(1, kFreescapeDebugParser, "Area %d", areaNumber);
-	debugC(1, kFreescapeDebugParser, "Skipped: %d Objects: %d", skippedValue, numberOfObjects);
+	debugC(1, kFreescapeDebugParser, "Flags: %d Objects: %d", areaFlags, numberOfObjects);
 	//debug("Condition Ptr: %x", cPtr);
 	debugC(1, kFreescapeDebugParser, "Pos before first object: %lx", file->pos());
 	if (_targetName == "totaleclipse") {
@@ -354,7 +354,7 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	uint8 numConditions = file->readByte();
 	debugC(1, kFreescapeDebugParser, "%d area conditions at %x of area %d", numConditions, base + cPtr, areaNumber);
 
-	Area *area = new Area(areaNumber, objectsByID, entrancesByID, scale, skyColor, groundColor, palette);
+	Area *area = new Area(areaNumber, areaFlags, objectsByID, entrancesByID, scale, skyColor, groundColor, palette);
 
 	while (numConditions--) {
 		FCLInstructionVector instructions;


Commit: a8ad0f7b9366777d37c8c281c4ea3a1741e43ae6
    https://github.com/scummvm/scummvm/commit/a8ad0f7b9366777d37c8c281c4ea3a1741e43ae6
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:59+01:00

Commit Message:
FREESCAPE: move palettes to another file

Changed paths:
  A engines/freescape/palettes.cpp
    engines/freescape/freescape.h
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/module.mk


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 1193a15db8e..3393dfcdb5c 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -39,6 +39,13 @@ enum {
 	kFreescapeDebugCode = 1 << 2
 };
 
+extern byte drillerEGA[16][3];
+extern byte drillerCGA[4][3];
+extern byte castleCGA[4][3];
+extern byte castleEGA[16][3];
+extern byte eclipseEGA[16][3];
+
+
 class FreescapeEngine : public Engine {
 private:
 	// We need random numbers
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index c7f869d6bbc..1d73cf3949f 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -144,7 +144,6 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 		if (byteSizeOfObject > 0) {
 			// TODO: there is something here
 			debugC(1, kFreescapeDebugParser, "Warning: extra %d bytes in entrance", byteSizeOfObject);
-			//file->seek(byteSizeOfObject, SEEK_CUR);
 			while (byteSizeOfObject--) {
 				debugC(1, kFreescapeDebugParser, "b: %x", file->readByte());
 			}
@@ -185,77 +184,6 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 	return nullptr;
 }
 
-byte drillerEGA[16][3] = {
-	{0x00, 0x00, 0x00},
-	{0x00, 0x00, 0x00},
-	{0x00, 0xaa, 0xaa},
-	{0xaa, 0x00, 0xaa},
-	{0xff, 0xff, 0xff},
-	{0x55, 0x55, 0x55},
-	{0x00, 0x00, 0xaa},
-	{0xaa, 0x55, 0x00},
-	{0x12, 0xf3, 0x56},
-	{0xaa, 0x00, 0x00},
-	{0xff, 0x55, 0xff},
-	{0x12, 0xf3, 0x56},
-	{0x12, 0xf3, 0x56},
-	{0x12, 0xf3, 0x56},
-	{0x12, 0xf3, 0x56},
-	{0x12, 0xf3, 0x56}
-};
-
-byte drillerCGA[4][3] = {
-	{0x00, 0x00, 0x00},
-	{0xff, 0xff, 0xff},
-	{0xa8, 0x00, 0xa8},
-	{0x00, 0xa8, 0xa8},
-};
-
-byte castleCGA[4][3] = {
-	{0x83, 0x85, 0x83},
-	{0x00, 0x00, 0x00},
-	{0x00, 0x85, 0x00},
-	{0xff, 0xfb, 0xff},
-};
-
-byte castleEGA[16][3] = {
-	{0x00, 0x00, 0x00},
-	{0x00, 0x00, 0x00},
-	{0x00, 0xaa, 0xaa},
-	{0x00, 0xaa, 0xaa},
-	{0xaa, 0xaa, 0xaa},
-	{0x55, 0x55, 0x55},
-	{0x00, 0xaa, 0x00},
-	{0xaa, 0x55, 0x00},
-	{0x12, 0xf3, 0x56},
-	{0xaa, 0x00, 0x00},
-	{0xff, 0x55, 0xff},
-	{0xaa, 0x55, 0x00},
-	{0xaa, 0x55, 0x00},
-	{0xaa, 0x55, 0x00},
-	{0x12, 0xf3, 0x56},
-	{0x12, 0xf3, 0x56}
-};
-
-byte eclipseEGA[16][3] = {
-	{0xfc, 0xfc, 0x54},
-	{0x00, 0x00, 0x00},
-	{0x54, 0xfc, 0xfc},
-	{0xaa, 0x00, 0xaa},
-	{0x54, 0xfc, 0xfc},
-	{0x00, 0x00, 0xA8},
-	{0x00, 0x00, 0xaa},
-	{0xaa, 0x00, 0xaa},
-	{0x12, 0xf3, 0x56},
-	{0xaa, 0x00, 0x00},
-	{0xff, 0x55, 0xff},
-	{0xa8, 0x00, 0x00},
-	{0x12, 0xf3, 0x56},
-	{0x54, 0x54, 0x54},
-	{0xa8, 0x54, 0x00},
-	{0x12, 0xf3, 0x56}
-};
-
 Graphics::PixelBuffer *FreescapeEngine::getPalette(uint8 areaNumber, uint8 c1, uint8 c2, uint8 c3, uint8 c4, uint16 ncolors) {
 	Graphics::PixelFormat pixelFormat = Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0);
 	Graphics::PixelBuffer *palette = nullptr;
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index 46ee645baec..0c479c5a9f0 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -15,7 +15,8 @@ MODULE_OBJS := \
 	language/8bitDetokeniser.o \
 	loaders/16bitBinaryLoader.o \
 	language/16bitDetokeniser.o \
-	language/instruction.o
+	language/instruction.o \
+	palettes.o
 
 MODULE_DIRS += \
 	engines/freescape
diff --git a/engines/freescape/palettes.cpp b/engines/freescape/palettes.cpp
new file mode 100644
index 00000000000..9ce35a37a6f
--- /dev/null
+++ b/engines/freescape/palettes.cpp
@@ -0,0 +1,76 @@
+#include "common/file.h"
+
+namespace Freescape {
+
+byte drillerEGA[16][3] = {
+	{0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00},
+	{0x00, 0xaa, 0xaa},
+	{0xaa, 0x00, 0xaa},
+	{0xff, 0xff, 0xff},
+	{0x55, 0x55, 0x55},
+	{0x00, 0x00, 0xaa},
+	{0xaa, 0x55, 0x00},
+	{0x12, 0xf3, 0x56},
+	{0xaa, 0x00, 0x00},
+	{0xff, 0x55, 0xff},
+	{0x12, 0xf3, 0x56},
+	{0x12, 0xf3, 0x56},
+	{0x12, 0xf3, 0x56},
+	{0x12, 0xf3, 0x56},
+	{0x12, 0xf3, 0x56}
+};
+
+byte drillerCGA[4][3] = {
+	{0x00, 0x00, 0x00},
+	{0xff, 0xff, 0xff},
+	{0xa8, 0x00, 0xa8},
+	{0x00, 0xa8, 0xa8},
+};
+
+byte castleCGA[4][3] = {
+	{0x83, 0x85, 0x83},
+	{0x00, 0x00, 0x00},
+	{0x00, 0x85, 0x00},
+	{0xff, 0xfb, 0xff},
+};
+
+byte castleEGA[16][3] = {
+	{0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00},
+	{0x00, 0xaa, 0xaa},
+	{0x00, 0xaa, 0xaa},
+	{0xaa, 0xaa, 0xaa},
+	{0x55, 0x55, 0x55},
+	{0x00, 0xaa, 0x00},
+	{0xaa, 0x55, 0x00},
+	{0x12, 0xf3, 0x56},
+	{0xaa, 0x00, 0x00},
+	{0xff, 0x55, 0xff},
+	{0xaa, 0x55, 0x00},
+	{0xaa, 0x55, 0x00},
+	{0xaa, 0x55, 0x00},
+	{0x12, 0xf3, 0x56},
+	{0x12, 0xf3, 0x56}
+};
+
+byte eclipseEGA[16][3] = {
+	{0xfc, 0xfc, 0x54},
+	{0x00, 0x00, 0x00},
+	{0x54, 0xfc, 0xfc},
+	{0xaa, 0x00, 0xaa},
+	{0x54, 0xfc, 0xfc},
+	{0x00, 0x00, 0xA8},
+	{0x00, 0x00, 0xaa},
+	{0xaa, 0x00, 0xaa},
+	{0x12, 0xf3, 0x56},
+	{0xaa, 0x00, 0x00},
+	{0xff, 0x55, 0xff},
+	{0xa8, 0x00, 0x00},
+	{0x12, 0xf3, 0x56},
+	{0x54, 0x54, 0x54},
+	{0xa8, 0x54, 0x00},
+	{0x12, 0xf3, 0x56}
+};
+
+}
\ No newline at end of file


Commit: 2bf32efe8268cd964d6d4e5562f0015f6d95c77f
    https://github.com/scummvm/scummvm/commit/2bf32efe8268cd964d6d4e5562f0015f6d95c77f
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:59+01:00

Commit Message:
FREESCAPE: refactored palette code

Changed paths:
    engines/freescape/freescape.h
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/palettes.cpp


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 3393dfcdb5c..1193a15db8e 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -39,13 +39,6 @@ enum {
 	kFreescapeDebugCode = 1 << 2
 };
 
-extern byte drillerEGA[16][3];
-extern byte drillerCGA[4][3];
-extern byte castleCGA[4][3];
-extern byte castleEGA[16][3];
-extern byte eclipseEGA[16][3];
-
-
 class FreescapeEngine : public Engine {
 private:
 	// We need random numbers
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 1d73cf3949f..80c943a5abf 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -184,28 +184,6 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 	return nullptr;
 }
 
-Graphics::PixelBuffer *FreescapeEngine::getPalette(uint8 areaNumber, uint8 c1, uint8 c2, uint8 c3, uint8 c4, uint16 ncolors) {
-	Graphics::PixelFormat pixelFormat = Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0);
-	Graphics::PixelBuffer *palette = nullptr;
-	if (_targetName.hasPrefix("driller")) {
-		if (_renderMode == "ega")
-			palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&drillerEGA);
-		else if (_renderMode == "cga")
-			palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&drillerCGA);
-	} else if (_targetName.hasPrefix("castlemaster")) {
-		if (_renderMode == "ega")
-			palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&castleEGA); // TODO
-		else if (_renderMode == "cga")
-			palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&castleCGA);
-	} else if (_targetName.hasPrefix("totaleclipse")) {
-		palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&eclipseEGA);
-	} else
-		palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&drillerEGA);
-
-	assert(palette);
-	return palette;
-}
-
 Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 ncolors) {
 
 	uint32 base = file->pos();
diff --git a/engines/freescape/palettes.cpp b/engines/freescape/palettes.cpp
index 9ce35a37a6f..04a0c56b7cb 100644
--- a/engines/freescape/palettes.cpp
+++ b/engines/freescape/palettes.cpp
@@ -1,4 +1,4 @@
-#include "common/file.h"
+#include "freescape/freescape.h"
 
 namespace Freescape {
 
@@ -73,4 +73,26 @@ byte eclipseEGA[16][3] = {
 	{0x12, 0xf3, 0x56}
 };
 
+Graphics::PixelBuffer *FreescapeEngine::getPalette(uint8 areaNumber, uint8 c1, uint8 c2, uint8 c3, uint8 c4, uint16 ncolors) {
+	Graphics::PixelFormat pixelFormat = Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0);
+	Graphics::PixelBuffer *palette = nullptr;
+	if (_targetName.hasPrefix("driller")) {
+		if (_renderMode == "ega")
+			palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&drillerEGA);
+		else if (_renderMode == "cga")
+			palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&drillerCGA);
+	} else if (_targetName.hasPrefix("castlemaster")) {
+		if (_renderMode == "ega")
+			palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&castleEGA); // TODO
+		else if (_renderMode == "cga")
+			palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&castleCGA);
+	} else if (_targetName.hasPrefix("totaleclipse")) {
+		palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&eclipseEGA);
+	} else
+		palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&drillerEGA);
+
+	assert(palette);
+	return palette;
+}
+
 }
\ No newline at end of file


Commit: 191a7ce2cb1179551b8060ae75bb6b8bd48057d1
    https://github.com/scummvm/scummvm/commit/191a7ce2cb1179551b8060ae75bb6b8bd48057d1
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T21:59:59+01:00

Commit Message:
FREESCAPE: improved palette for total eclipse and added some fixes

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/objects/geometricobject.cpp
    engines/freescape/palettes.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 07169d845ab..8f388723393 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -76,9 +76,9 @@ Area::Area(
 	{
 		bool operator()(Object *object1, Object *object2) {
 			if (!object1->isPlanar() && object2->isPlanar())
-				return false;
-			if (object1->isPlanar() && !object2->isPlanar())
 				return true;
+			if (object1->isPlanar() && !object2->isPlanar())
+				return false;
 			return object1->getObjectID() > object2->getObjectID();
 		};
 	} compareObjects;
@@ -128,18 +128,19 @@ void Area::draw(Freescape::Renderer *gfx) {
 	if (palette)
 		gfx->_palette = palette;
 
+	gfx->clear();
+
+	if (areaFlags & 0x02 || areaFlags & 0x20)
+		gfx->drawSky(skyColor);
+
+	if (areaFlags & 0x01 || areaFlags & 0x40)
+		gfx->drawFloor(groundColor);
+
 	if (areaFlags & 0x80)
 		gfx->_keyColor = 0;
 	else
 		gfx->_keyColor = 255;
 
-	gfx->clear();
-	if (areaFlags & 0x01)
-		gfx->drawFloor(groundColor);
-
-	if (areaFlags & 0x02)
-		gfx->drawSky(skyColor);
-
 	assert(drawableObjects.size() > 0);
 	for (Common::Array<Object *>::iterator it = drawableObjects.begin(); it != drawableObjects.end(); it++) {
 		if (!(*it)->isDestroyed() && !(*it)->isInvisible()) {
@@ -187,7 +188,7 @@ void Area::addStructure(Area *structure) {
 		int id = 254;
 		Common::Array<uint8> *gColors = new Common::Array<uint8>;
 		for (int i = 0; i < 6; i++)
-			gColors->push_back(0);
+			gColors->push_back(groundColor);
 
 		obj = (Object*) new GeometricObject(
 			Object::Type::Cube,
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index 590c468f70b..bbe8f91bf02 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -237,7 +237,7 @@ GeometricObject::~GeometricObject() {
 bool GeometricObject::isDrawable() { return true; }
 bool GeometricObject::isPlanar() {
 	Type type = this->getType();
-	return (type >= Object::Line) || !size.x() || !size.y() || !size.z();
+	return (type >= Object::Line) || type == Object::Rectangle || !size.x() || !size.y() || !size.z();
 }
 
 bool GeometricObject::collides(const Math::AABB &boundingBox) {
diff --git a/engines/freescape/palettes.cpp b/engines/freescape/palettes.cpp
index 04a0c56b7cb..7a151f29820 100644
--- a/engines/freescape/palettes.cpp
+++ b/engines/freescape/palettes.cpp
@@ -58,19 +58,19 @@ byte eclipseEGA[16][3] = {
 	{0xfc, 0xfc, 0x54},
 	{0x00, 0x00, 0x00},
 	{0x54, 0xfc, 0xfc},
-	{0xaa, 0x00, 0xaa},
-	{0x54, 0xfc, 0xfc},
+	{0x00, 0xaa, 0xaa},
+	{0x00, 0xaa, 0x00},
 	{0x00, 0x00, 0xA8},
-	{0x00, 0x00, 0xaa},
+	{0xff, 0x00, 0xaa},
 	{0xaa, 0x00, 0xaa},
 	{0x12, 0xf3, 0x56},
-	{0xaa, 0x00, 0x00},
-	{0xff, 0x55, 0xff},
+	{0x55, 0x55, 0xff},
+	{0x55, 0xff, 0x55},
 	{0xa8, 0x00, 0x00},
-	{0x12, 0xf3, 0x56},
+	{0xff, 0x55, 0x55},
 	{0x54, 0x54, 0x54},
 	{0xa8, 0x54, 0x00},
-	{0x12, 0xf3, 0x56}
+	{0xff, 0xff, 0x55}
 };
 
 Graphics::PixelBuffer *FreescapeEngine::getPalette(uint8 areaNumber, uint8 c1, uint8 c2, uint8 c3, uint8 c4, uint16 ncolors) {


Commit: b863506abcaad655306d3aeee7ecd064ad09e016
    https://github.com/scummvm/scummvm/commit/b863506abcaad655306d3aeee7ecd064ad09e016
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:00+01:00

Commit Message:
FREESCAPE: if an object is destroyed, restore it while loading

Changed paths:
    engines/freescape/objects/geometricobject.cpp


diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index bbe8f91bf02..1e0ace83863 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -114,8 +114,9 @@ GeometricObject::GeometricObject(
 	Common::String *_conditionSource) {
 	_type = type;
 	_flags = flags;
-	if (flags & 0x40)
-		makeInvisible();
+
+	if (isDestroyed()) // If the object is destroyed, restore it
+		_flags = _flags & ~0x20;
 
 	_objectID = objectID;
 	origin = _origin;


Commit: b7ba3d2049ee9d8abaed85474fa66ee04c82db7f
    https://github.com/scummvm/scummvm/commit/b7ba3d2049ee9d8abaed85474fa66ee04c82db7f
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:00+01:00

Commit Message:
FREESCAPE: implement border and view port for driller and eclipse

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 0b2ac75ec81..e8c317520d3 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -51,6 +51,7 @@ FreescapeEngine::FreescapeEngine(OSystem *syst)
 	_mouseSensitivity = 0.1f;
 	_flyMode = false;
 	_borderTexture = nullptr;
+	_viewArea = Common::Rect(0, 0, _screenW, _screenH);
 
 	_rnd = new Common::RandomSource("freescape");
 }
@@ -73,8 +74,7 @@ void FreescapeEngine::drawBorder() {
 	if (!_borderTexture)
 		_borderTexture = _gfx->createTexture(_border);
 	_gfx->drawTexturedRect2D(fullscreenViewArea, fullscreenViewArea, _borderTexture);
-	Common::Rect drillerViewArea(40, 16, 279, 116);
-	_gfx->setViewport(drillerViewArea);
+	_gfx->setViewport(_viewArea);
 }
 
 void FreescapeEngine::loadAssets() {
@@ -290,8 +290,14 @@ Common::Error FreescapeEngine::run() {
 		g_system->delayMillis(1000);
 
 		_borderTexture = nullptr;
-		Common::Rect viewArea(40, 16, 279, 116);
-		_border->fillRect(viewArea, 0xA0A0A0FF);
+		if (_targetName.hasPrefix("driller"))
+			_viewArea = Common::Rect(40, 16, 279, 116);
+		else if (_targetName.hasPrefix("totaleclipse"))
+			_viewArea = Common::Rect(40, 32, 280, 132);
+		else
+			error("Invalid target!");
+
+		_border->fillRect(_viewArea, 0xA0A0A0FF);
 	}
 	int saveSlot = ConfMan.getInt("save_slot");
 	if (saveSlot >= 0) { // load the savegame
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 1193a15db8e..31ce7c4d5ce 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -58,6 +58,7 @@ public:
 	Common::Error run() override;
 
 	// Border
+	Common::Rect _viewArea;
 	void convertBorder();
 	void drawBorder();
 	Texture *_borderTexture;


Commit: 6d41bc9829b2a2a1c05196c7aba642562b8995d3
    https://github.com/scummvm/scummvm/commit/6d41bc9829b2a2a1c05196c7aba642562b8995d3
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:00+01:00

Commit Message:
FREESCAPE: improved destroy opcode implementation

Changed paths:
    engines/freescape/language/instruction.cpp


diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index 521f0b7b15f..0480c1150ab 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -219,10 +219,20 @@ void FreescapeEngine::executeDecrementVariable(FCLInstruction &instruction) {
 }
 
 void FreescapeEngine::executeDestroy(FCLInstruction &instruction) {
-	uint16 objectID = instruction.source;
-	debugC(1, kFreescapeDebugCode, "Destroying obj %d!", objectID);
-	Object *obj = _currentArea->objectWithID(objectID);
-	assert(!obj->isDestroyed());
+	uint16 objectID = 0;
+	uint16 areaID = _currentArea->getAreaID();
+
+	if (instruction.destination > 0) {
+		objectID = instruction.destination;
+		areaID = instruction.source;
+	} else {
+		objectID = instruction.source;
+	}
+
+	debugC(1, kFreescapeDebugCode, "Destroying obj %d in area %d!", objectID, areaID);
+	assert(_areaMap.contains(areaID));
+	Object *obj = _areaMap[areaID]->objectWithID(objectID);
+	assert(!(obj->isDestroyed()));
 	obj->destroy();
 }
 


Commit: 9cd387cff9058c63e1ab30a1680c3d2afa88f64b
    https://github.com/scummvm/scummvm/commit/9cd387cff9058c63e1ab30a1680c3d2afa88f64b
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:00+01:00

Commit Message:
FREESCAPE: improved player size for driller and eclipse

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index e8c317520d3..aacb36284f3 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -464,17 +464,8 @@ bool FreescapeEngine::tryStepDown(Math::Vector3d currentPosition) {
 
 bool FreescapeEngine::checkCollisions(bool executeCode) {
 	int areaScale = _currentArea->getScale();
-
-	Math::Vector3d v1;
-	Math::Vector3d v2;
-
-	if (executeCode) {
-		v1 = Math::Vector3d(_position.x() -  areaScale * 3 * _playerWidth / 5, _position.y() - (areaScale + 1) * _playerHeight , _position.z() - areaScale * 3 * _playerDepth / 5);
-		v2 = Math::Vector3d(_position.x() +  areaScale * 3 * _playerWidth / 5, _position.y()                                   , _position.z() + areaScale * 3 * _playerDepth / 5);
-	} else {
-		v1 = Math::Vector3d(_position.x() - areaScale * _playerWidth / 2, _position.y() - areaScale * _playerHeight , _position.z() - areaScale * _playerDepth / 2);
-		v2 = Math::Vector3d(_position.x() + areaScale * _playerWidth / 2, _position.y()                             , _position.z() + areaScale * _playerDepth / 2);
-	}
+	Math::Vector3d v1(_position.x() - areaScale * _playerWidth / 2, _position.y() - areaScale * _playerHeight , _position.z() - areaScale * _playerDepth / 2);
+	Math::Vector3d v2(_position.x() + areaScale * _playerWidth / 2, _position.y()                             , _position.z() + areaScale * _playerDepth / 2);
 
 	const Math::AABB boundingBox(v1, v2);
 	Object *obj = _currentArea->checkCollisions(boundingBox);
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 80c943a5abf..76d13b6da9d 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -371,9 +371,15 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 		} else
 			error("Invalid area?");
 	}
-	_playerHeight = 64;
-	_playerWidth = 12;
-	_playerDepth = 32;
+	if (_targetName.hasPrefix("totaleclipse")) {
+		_playerHeight = 48;
+		_playerWidth = 8;
+		_playerDepth = 8;
+	} else {
+		_playerHeight = 64;
+		_playerWidth = 12;
+		_playerDepth = 32;
+	}
 
 	if (!_areaMap.contains(startArea))
 		_startArea = newArea->getAreaID();


Commit: 453e7132006d89bf8a2083d5abc11d6f8d5068d7
    https://github.com/scummvm/scummvm/commit/453e7132006d89bf8a2083d5abc11d6f8d5068d7
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:00+01:00

Commit Message:
FREESCAPE: improved game selection

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/language/instruction.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/palettes.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index aacb36284f3..41bc5174074 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -94,7 +94,7 @@ void FreescapeEngine::loadAssets() {
 
 		file = files.begin()->get()->createReadStream();
 		load16bitBinary(file);
-	} else if (_targetName.hasPrefix("driller") || _targetName.hasPrefix("spacestationoblivion")) {
+	} else if (isDriller()) {
 		Common::File exe;
 		if (_renderMode == "ega") {
 			file = gameDir.createReadStreamForMember("DRILLE.EXE");
@@ -112,7 +112,7 @@ void FreescapeEngine::loadAssets() {
 		} else
 			error("Invalid render mode %s for Driller", _renderMode.c_str());
 
-	} else if (_targetName.hasPrefix("darkside")) {
+	} else if (isDark()) {
 		Common::File exe;
 		if (_renderMode == "ega") {
 			file = gameDir.createReadStreamForMember("DSIDEE.EXE");
@@ -130,7 +130,7 @@ void FreescapeEngine::loadAssets() {
 		} else
 			error("Invalid render mode %s for Dark Side", _renderMode.c_str());
 
-	} else if (_targetName == "totaleclipse") {
+	} else if (isEclipse()) {
 		Common::File exe;
 		if (_renderMode == "ega") {
 			file = gameDir.createReadStreamForMember("TOTEE.EXE");
@@ -147,7 +147,7 @@ void FreescapeEngine::loadAssets() {
 			load8bitBinary(file, 0x7bb0, 4); // TODO
 		} else
 			error("Invalid render mode %s for Total Eclipse", _renderMode.c_str());
-	   } else if (_targetName.hasPrefix("castlemaster")) {
+	   } else if (isCastle()) {
 			_renderMode = "ega";
 			file = gameDir.createReadStreamForMember("castle.sna");
 
@@ -279,8 +279,6 @@ Common::Error FreescapeEngine::run() {
 		_startArea = 1;
 	} else {
 		_farClipPlane = 8192.f;
-		if (!_targetName.hasPrefix("driller"))
-			_gfx->_keyColor = 0;
 	}
 
 	if (_border) {
@@ -290,9 +288,9 @@ Common::Error FreescapeEngine::run() {
 		g_system->delayMillis(1000);
 
 		_borderTexture = nullptr;
-		if (_targetName.hasPrefix("driller"))
+		if (isDriller())
 			_viewArea = Common::Rect(40, 16, 279, 116);
-		else if (_targetName.hasPrefix("totaleclipse"))
+		else if (isEclipse())
 			_viewArea = Common::Rect(40, 32, 280, 132);
 		else
 			error("Invalid target!");
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 31ce7c4d5ce..8da30df4d75 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -54,6 +54,12 @@ public:
 	FreescapeEngine(OSystem *syst);
 	~FreescapeEngine();
 
+	// Game selection
+	bool isDriller() { return _targetName.hasPrefix("driller") || _targetName.hasPrefix("spacestationoblivion"); }
+	bool isDark() { return _targetName.hasPrefix("darkside"); }
+	bool isEclipse() { return _targetName.hasPrefix("totaleclipse"); }
+	bool isCastle() { return _targetName.hasPrefix("castle"); }
+
 	Renderer *_gfx;
 	Common::Error run() override;
 
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index 0480c1150ab..acc221c1c89 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -58,7 +58,7 @@ void FreescapeEngine::executeConditions(GeometricObject *obj, bool shot, bool co
 		executeCode(obj->condition, shot, collided);
 	}
 
-	if (!_targetName.hasPrefix("driller"))
+	if (!isDriller())
 		return;
 
 	debugC(1, kFreescapeDebugCode, "Executing room conditions");
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 76d13b6da9d..6a70ce5d8f7 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -201,7 +201,7 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	uint8 ci2 = 0;
 	uint8 skyColor = 255;
 	uint8 groundColor = 255;
-	if (_targetName != "castlemaster") {
+	if (!isCastle()) {
 		groundColor = file->readByte() & 15;
 		skyColor = file->readByte() & 15;
 		ci1 = file->readByte();
@@ -224,13 +224,13 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	debugC(1, kFreescapeDebugParser, "Flags: %d Objects: %d", areaFlags, numberOfObjects);
 	//debug("Condition Ptr: %x", cPtr);
 	debugC(1, kFreescapeDebugParser, "Pos before first object: %lx", file->pos());
-	if (_targetName == "totaleclipse") {
+	if (isEclipse()) {
 		debugC(1, kFreescapeDebugParser, "b: %x", file->readByte());
 		debugC(1, kFreescapeDebugParser, "b: %x", file->readByte());
 		debugC(1, kFreescapeDebugParser, "b: %x", file->readByte());
 		debugC(1, kFreescapeDebugParser, "b: %x", file->readByte());
 		debugC(1, kFreescapeDebugParser, "b: %x", file->readByte());
-	} else if (_targetName != "castlemaster")
+	} else if (!isCastle())
 		file->seek(15, SEEK_CUR);
 
 	ObjectMap *objectsByID = new ObjectMap;
@@ -279,7 +279,7 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 
 	if (_areaMap.contains(255))
 		area->addStructure(_areaMap[255]);
-	else if (_targetName.hasPrefix("castle") || _targetName.hasPrefix("totaleclipse"))
+	else if (isCastle() || isEclipse())
 		area->addStructure(nullptr);
 
 	debugC(1, kFreescapeDebugParser, "End of area at %lx", file->pos());
@@ -337,13 +337,13 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 		debugC(1, kFreescapeDebugParser, "%s", conditionSource->c_str());
 	}
 
-	if (_targetName.hasPrefix("driller")) {
+	if (isDriller()) {
 		file->seek(0x3b42);
 		for (int i = 0; i < 8; i++)
 			load8bitObject(file);
 	}
 
-	if (_targetName != "castlemaster")
+	if (!isCastle())
 		file->seek(offset + 0xc8);
 	else
 		file->seek(offset + 0x4f);
@@ -371,7 +371,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 		} else
 			error("Invalid area?");
 	}
-	if (_targetName.hasPrefix("totaleclipse")) {
+	if (isEclipse()) {
 		_playerHeight = 48;
 		_playerWidth = 8;
 		_playerDepth = 8;
diff --git a/engines/freescape/palettes.cpp b/engines/freescape/palettes.cpp
index 7a151f29820..315bde02773 100644
--- a/engines/freescape/palettes.cpp
+++ b/engines/freescape/palettes.cpp
@@ -76,17 +76,17 @@ byte eclipseEGA[16][3] = {
 Graphics::PixelBuffer *FreescapeEngine::getPalette(uint8 areaNumber, uint8 c1, uint8 c2, uint8 c3, uint8 c4, uint16 ncolors) {
 	Graphics::PixelFormat pixelFormat = Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0);
 	Graphics::PixelBuffer *palette = nullptr;
-	if (_targetName.hasPrefix("driller")) {
+	if (isDriller()) {
 		if (_renderMode == "ega")
 			palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&drillerEGA);
 		else if (_renderMode == "cga")
 			palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&drillerCGA);
-	} else if (_targetName.hasPrefix("castlemaster")) {
+	} else if (isCastle()) {
 		if (_renderMode == "ega")
 			palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&castleEGA); // TODO
 		else if (_renderMode == "cga")
 			palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&castleCGA);
-	} else if (_targetName.hasPrefix("totaleclipse")) {
+	} else if (isEclipse()) {
 		palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&eclipseEGA);
 	} else
 		palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&drillerEGA);


Commit: 78d247ea71827acc99446532744a3d2924bba7ab
    https://github.com/scummvm/scummvm/commit/78d247ea71827acc99446532744a3d2924bba7ab
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:01+01:00

Commit Message:
FREESCAPE: read gas pockets and allow driller deployment

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/objects/object.cpp
    engines/freescape/objects/object.h


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 8f388723393..e952a165e2b 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -84,6 +84,10 @@ Area::Area(
 	} compareObjects;
 
 	Common::sort(drawableObjects.begin(), drawableObjects.end(), compareObjects);
+
+	gasPocketX = 0;
+	gasPocketY = 0;
+	gasPocketRadius = 0;
 }
 
 Area::~Area() {
@@ -182,6 +186,55 @@ Object *Area::checkCollisions(const Math::AABB &boundingBox) {
 	return collided;
 }
 
+void Area::addDrill(Area *structure, const Math::Vector3d position) {
+	//int drillObjectIDs[8] = {255, 254, 253, 252, 251, 250, 248, 247};
+	Object *obj = nullptr;
+	Math::Vector3d offset = position;
+	offset.setValue(1, 1);
+
+	int16 id;
+
+	id = 255;
+	debug("Adding object %d to room structure", id);
+	obj = structure->objectWithID(id);
+	obj->setOrigin(offset);
+	offset.setValue(1, offset.y() + obj->getSize().y());
+	assert(obj);
+	(*objectsByID)[id] = obj;
+	obj->makeVisible();
+	drawableObjects.insert_at(0, obj);
+
+	id = 254;
+	debug("Adding object %d to room structure", id);
+	obj = structure->objectWithID(id);
+	obj->setOrigin(offset);
+	offset.setValue(1, offset.y() + obj->getSize().y());
+	assert(obj);
+	(*objectsByID)[id] = obj;
+	obj->makeVisible();
+	drawableObjects.insert_at(0, obj);
+
+	id = 253;
+	debug("Adding object %d to room structure", id);
+	obj = structure->objectWithID(id);
+	obj->setOrigin(offset);
+	offset.setValue(1, offset.y() + obj->getSize().y());
+	assert(obj);
+	(*objectsByID)[id] = obj;
+	obj->makeVisible();
+	drawableObjects.insert_at(0, obj);
+
+	id = 252;
+	debug("Adding object %d to room structure", id);
+	obj = structure->objectWithID(id);
+	obj->setOrigin(offset);
+	offset.setValue(1, offset.y() + obj->getSize().y());
+	assert(obj);
+	(*objectsByID)[id] = obj;
+	obj->makeVisible();
+	drawableObjects.insert_at(0, obj);
+}
+
 void Area::addStructure(Area *structure) {
 	Object *obj = nullptr;
 	if (!structure || !entrancesByID->contains(255)) {
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index 4740ba59764..c8a42999863 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -48,6 +48,7 @@ public:
 	Object *shootRay(const Math::Ray &ray);
 	Object *checkCollisions(const Math::AABB &boundingBox);
 	void addStructure(Area *structure);
+	void addDrill(Area *structure, const Math::Vector3d position);
 
 	Common::Array<Common::String*> conditionSources;
 	Common::Array<FCLInstructionVector> conditions;
@@ -56,6 +57,11 @@ public:
 	void saveObjectFlags(Common::WriteStream *stream);
 	void loadObjectFlags(Common::SeekableReadStream *stream);
 
+	// Driller specific fields
+	uint8 gasPocketX;
+	uint8 gasPocketY;
+	uint8 gasPocketRadius;
+
 private:
 	uint16 areaID;
 	uint16 areaFlags;
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 41bc5174074..2a1bfbe528c 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -205,6 +205,8 @@ void FreescapeEngine::processInput() {
 				_position.setValue(1, _position.y() - 12);
 			else if (event.kbd.keycode == Common::KEYCODE_n)
 				gotoArea(_currentArea->getAreaID() + 1, 0);
+			else if (event.kbd.keycode == Common::KEYCODE_m)
+				_currentArea->addDrill(globalObjectsArea, _position);
 			else if (event.kbd.keycode == Common::KEYCODE_ESCAPE)
 				openMainMenuDialog();
 			break;
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 8da30df4d75..a21490df547 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -75,6 +75,8 @@ public:
 	void load16bitBinary(Common::SeekableReadStream *file);
 
 	// 8-bits
+	//ObjectMap globalObjectsByID;
+	Area *globalObjectsArea;
 	void load8bitBinary(Common::SeekableReadStream *file, int offset, int ncolors);
 	Area *load8bitArea(Common::SeekableReadStream *file, uint16 ncolors);
 	Object *load8bitObject(Common::SeekableReadStream *file);
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 6a70ce5d8f7..cdeeb8d8fd5 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -45,7 +45,7 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 
 	assert(byteSizeOfObject >= 9);
 	byteSizeOfObject = byteSizeOfObject - 9;
-	if (objectID == 255) {
+	if (objectID == 255 && objectType == Object::Type::Entrance) {
 		debug("Found the room structure (objectID: 255 with size %d)", byteSizeOfObject + 6);
 		byte *structureData = (byte*)malloc(byteSizeOfObject + 6);
 		structureData[0] = int(position.x());
@@ -224,12 +224,23 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	debugC(1, kFreescapeDebugParser, "Flags: %d Objects: %d", areaFlags, numberOfObjects);
 	//debug("Condition Ptr: %x", cPtr);
 	debugC(1, kFreescapeDebugParser, "Pos before first object: %lx", file->pos());
+
+	uint8 gasPocketX = 0;
+	uint8 gasPocketY = 0;
+	uint8 gasPocketRadius = 0;
+
 	if (isEclipse()) {
 		debugC(1, kFreescapeDebugParser, "b: %x", file->readByte());
 		debugC(1, kFreescapeDebugParser, "b: %x", file->readByte());
 		debugC(1, kFreescapeDebugParser, "b: %x", file->readByte());
 		debugC(1, kFreescapeDebugParser, "b: %x", file->readByte());
 		debugC(1, kFreescapeDebugParser, "b: %x", file->readByte());
+	} else if (isDriller()) {
+		gasPocketX = file->readByte();
+		gasPocketY = file->readByte();
+		gasPocketRadius = file->readByte();
+		debugC(1, kFreescapeDebugParser, "Gas pocket at (%d, %d) with radius %d", gasPocketX, gasPocketY, gasPocketRadius);
+		file->seek(12, SEEK_CUR);
 	} else if (!isCastle())
 		file->seek(15, SEEK_CUR);
 
@@ -261,6 +272,9 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	debugC(1, kFreescapeDebugParser, "%d area conditions at %x of area %d", numConditions, base + cPtr, areaNumber);
 
 	Area *area = new Area(areaNumber, areaFlags, objectsByID, entrancesByID, scale, skyColor, groundColor, palette);
+	area->gasPocketX = gasPocketX;
+	area->gasPocketY = gasPocketY;
+	area->gasPocketRadius = gasPocketRadius;
 
 	while (numConditions--) {
 		FCLInstructionVector instructions;
@@ -338,9 +352,17 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	}
 
 	if (isDriller()) {
+		ObjectMap *globalObjectsByID = new ObjectMap;
 		file->seek(0x3b42);
-		for (int i = 0; i < 8; i++)
-			load8bitObject(file);
+		for (int i = 0; i < 8; i++) {
+			Object *gobj = load8bitObject(file);
+			assert(gobj);
+			assert(!globalObjectsByID->contains(gobj->getObjectID()));
+			debugC(1, kFreescapeDebugParser, "Adding global object: %d", gobj->getObjectID());
+			(*globalObjectsByID)[gobj->getObjectID()] = gobj;
+		}
+
+		globalObjectsArea = new Area(255, 0, globalObjectsByID, nullptr, 1, 255, 255, nullptr);
 	}
 
 	if (!isCastle())
diff --git a/engines/freescape/objects/object.cpp b/engines/freescape/objects/object.cpp
index bfbbf4f7bc6..83a5b4493bf 100644
--- a/engines/freescape/objects/object.cpp
+++ b/engines/freescape/objects/object.cpp
@@ -17,6 +17,7 @@ uint16 Object::getObjectID() { return _objectID; }
 uint16 Object::getObjectFlags() { return _flags; }
 void Object::setObjectFlags(uint32 flags) { _flags = flags; }
 Math::Vector3d Object::getOrigin() { return origin; }
+void Object::setOrigin(Math::Vector3d _origin) { origin = _origin; };
 Math::Vector3d Object::getSize() { return size; }
 
 bool Object::isDrawable() { return false; }
diff --git a/engines/freescape/objects/object.h b/engines/freescape/objects/object.h
index 242b0adfab0..00619237517 100644
--- a/engines/freescape/objects/object.h
+++ b/engines/freescape/objects/object.h
@@ -46,6 +46,7 @@ public:
 	uint16 getObjectFlags();
 	void setObjectFlags(uint32 flags);
 	Math::Vector3d getOrigin();
+	void setOrigin(Math::Vector3d origin);
 	Math::Vector3d getSize();
 
 	virtual void draw(Freescape::Renderer *gfx) = 0;


Commit: 96ab09bcedf76c4cf2d9a4f5600b1d9502e6f394
    https://github.com/scummvm/scummvm/commit/96ab09bcedf76c4cf2d9a4f5600b1d9502e6f394
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:01+01:00

Commit Message:
FREESCAPE: parse area names for driller and dark

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index e952a165e2b..1c09b43f0c0 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -102,6 +102,7 @@ Area::~Area() {
 }
 
 void Area::show() {
+	debug("Area name: %s", name.c_str());
 	for (ObjectMap::iterator it = objectsByID->begin(); it != objectsByID->end(); it++)
 		debug("objID: %d, type: %d", (*it)._value->getObjectID(), (*it)._value->getType());
 
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index c8a42999863..ddb597d8c2c 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -36,6 +36,7 @@ public:
 		Graphics::PixelBuffer *palette = nullptr);
 	virtual ~Area();
 
+	Common::String name;
 	Object *objectWithID(uint16 objectID);
 	Object *entranceWithID(uint16 objectID);
 	Object *firstEntrance();
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index cdeeb8d8fd5..3458ed22858 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -186,6 +186,7 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 
 Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 ncolors) {
 
+	Common::String name;
 	uint32 base = file->pos();
 	debugC(1, kFreescapeDebugParser, "Area base: %x", base);
 	uint8 areaFlags = file->readByte();
@@ -235,12 +236,17 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 		debugC(1, kFreescapeDebugParser, "b: %x", file->readByte());
 		debugC(1, kFreescapeDebugParser, "b: %x", file->readByte());
 		debugC(1, kFreescapeDebugParser, "b: %x", file->readByte());
-	} else if (isDriller()) {
+	} else if (isDriller() || isDark()) {
 		gasPocketX = file->readByte();
 		gasPocketY = file->readByte();
 		gasPocketRadius = file->readByte();
 		debugC(1, kFreescapeDebugParser, "Gas pocket at (%d, %d) with radius %d", gasPocketX, gasPocketY, gasPocketRadius);
-		file->seek(12, SEEK_CUR);
+		int i = 0;
+		while (i < 12) {
+			name = name + char(file->readByte());
+			i++;
+		}
+		debugC(1, kFreescapeDebugParser, "Area name: %s", name.c_str());
 	} else if (!isCastle())
 		file->seek(15, SEEK_CUR);
 
@@ -272,6 +278,7 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	debugC(1, kFreescapeDebugParser, "%d area conditions at %x of area %d", numConditions, base + cPtr, areaNumber);
 
 	Area *area = new Area(areaNumber, areaFlags, objectsByID, entrancesByID, scale, skyColor, groundColor, palette);
+	area->name = name;
 	area->gasPocketX = gasPocketX;
 	area->gasPocketY = gasPocketY;
 	area->gasPocketRadius = gasPocketRadius;


Commit: f118754db99e71789c8dea08f2da06de1fb83c47
    https://github.com/scummvm/scummvm/commit/f118754db99e71789c8dea08f2da06de1fb83c47
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:01+01:00

Commit Message:
FREESCAPE: parse area names for eclipse

Changed paths:
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 3458ed22858..e0951fd8803 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -184,6 +184,18 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 	return nullptr;
 }
 
+static const char *eclipseRoomName[] = {
+	"* SAHARA",
+	"HORAKHTY",
+	"NEPHTHYS",
+	"KHEPRESH",
+	" RAMESES",
+	"PHARAOHS",
+	" SHABAKA",
+	"ILLUSION",
+	"????????"
+};
+
 Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 ncolors) {
 
 	Common::String name;
@@ -231,11 +243,15 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	uint8 gasPocketRadius = 0;
 
 	if (isEclipse()) {
-		debugC(1, kFreescapeDebugParser, "b: %x", file->readByte());
-		debugC(1, kFreescapeDebugParser, "b: %x", file->readByte());
-		debugC(1, kFreescapeDebugParser, "b: %x", file->readByte());
-		debugC(1, kFreescapeDebugParser, "b: %x", file->readByte());
-		debugC(1, kFreescapeDebugParser, "b: %x", file->readByte());
+		byte idx = file->readByte();
+		name = idx < 8 ? eclipseRoomName[idx] : eclipseRoomName[8];
+		name = name + "-" + char(file->readByte()) + " ";
+
+		int i = 0;
+		while (i < 3) {
+			name = name + char(file->readByte());
+			i++;
+		}
 	} else if (isDriller() || isDark()) {
 		gasPocketX = file->readByte();
 		gasPocketY = file->readByte();


Commit: 4aa4667a34a27f4f7e4ed50b51990d062be806d0
    https://github.com/scummvm/scummvm/commit/4aa4667a34a27f4f7e4ed50b51990d062be806d0
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:01+01:00

Commit Message:
FREESCAPE: only allow to add drill in driller

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 2a1bfbe528c..e16f91e8cb5 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -205,9 +205,13 @@ void FreescapeEngine::processInput() {
 				_position.setValue(1, _position.y() - 12);
 			else if (event.kbd.keycode == Common::KEYCODE_n)
 				gotoArea(_currentArea->getAreaID() + 1, 0);
-			else if (event.kbd.keycode == Common::KEYCODE_m)
-				_currentArea->addDrill(globalObjectsArea, _position);
-			else if (event.kbd.keycode == Common::KEYCODE_ESCAPE)
+			else if (event.kbd.keycode == Common::KEYCODE_m) {
+				if (isDriller()) {
+					// TODO: check if there is space for the drill
+					_currentArea->addDrill(globalObjectsArea, _position + _cameraFront * 128);
+					// TODO check the result of the drilling
+				}
+			} else if (event.kbd.keycode == Common::KEYCODE_ESCAPE)
 				openMainMenuDialog();
 			break;
 
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index a21490df547..f2e1b2b5174 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -115,7 +115,7 @@ public:
 	// Camera options
 	float _mouseSensitivity;
 	float _movementSpeed;
-	Math::Vector3d _cameraFront, _cameraUp, _cameraRight;
+	Math::Vector3d _cameraFront, _cameraRight;
 	// Spacial attributes
 	Math::Vector3d _position, _rotation, _velocity;
 	Math::Vector3d _lastPosition;


Commit: ab155f3c097e5e81f3b8ac145a7c3e90d71967b4
    https://github.com/scummvm/scummvm/commit/ab155f3c097e5e81f3b8ac145a7c3e90d71967b4
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:01+01:00

Commit Message:
FREESCAPE: removed old code

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index e16f91e8cb5..d7394e7965b 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -27,14 +27,7 @@ FreescapeEngine *g_freescape = NULL;
 
 FreescapeEngine::FreescapeEngine(OSystem *syst)
 	: Engine(syst), _screenW(320), _screenH(200), _border(nullptr), _gfx(nullptr) {
-	// Put your engine in a sane state, but do nothing big yet;
-	// in particular, do not load data from files; rather, if you
-	// need to do such things, do them from run().
-
 	g_freescape = this;
-	// Do not initialize graphics here
-	// Do not initialize audio devices here
-	_hasReceivedTime = false;
 	if (!ConfMan.hasKey("render_mode"))
 		_renderMode = "ega";
 	else
@@ -57,9 +50,7 @@ FreescapeEngine::FreescapeEngine(OSystem *syst)
 }
 
 FreescapeEngine::~FreescapeEngine() {
-	// Dispose your resources here
 	delete _rnd;
-	//delete _areasByAreaID;
 	delete _border;
 	delete _gfx;
 }
@@ -291,7 +282,8 @@ Common::Error FreescapeEngine::run() {
 		drawBorder();
 		_gfx->flipBuffer();
 		g_system->updateScreen();
-		g_system->delayMillis(1000);
+		if (isDriller())
+			g_system->delayMillis(1000);
 
 		_borderTexture = nullptr;
 		if (isDriller())
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index f2e1b2b5174..03a50cdf4f0 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -43,12 +43,6 @@ class FreescapeEngine : public Engine {
 private:
 	// We need random numbers
 	Common::RandomSource *_rnd;
-	int _screenW, _screenH;
-
-	Graphics::Surface *_border;
-
-	uint32 _timeOfLastTick;
-	bool _hasReceivedTime;
 
 public:
 	FreescapeEngine(OSystem *syst);
@@ -60,7 +54,6 @@ public:
 	bool isEclipse() { return _targetName.hasPrefix("totaleclipse"); }
 	bool isCastle() { return _targetName.hasPrefix("castle"); }
 
-	Renderer *_gfx;
 	Common::Error run() override;
 
 	// Border
@@ -107,7 +100,7 @@ public:
 	// Interaction
 	void shoot();
 
-	// Eular Angles
+	// Euler Angles
 	float _yaw;
 	float _pitch;
 	Math::Vector3d directionToVector(float pitch, float heading);
@@ -156,6 +149,8 @@ public:
 	void playSound(int index);
 
 	// Rendering
+	int _screenW, _screenH;
+	Renderer *_gfx;
 	Common::String _renderMode;
 	Graphics::PixelBuffer *getPalette(uint8 areaNumber, uint8 c1, uint8 c2, uint8 c3, uint8 c4, uint16 ncolors);
 	void drawFrame();
@@ -163,6 +158,7 @@ public:
 	Math::Vector3d _scaleVector;
 	float _nearClipPlane;
 	float _farClipPlane;
+	Graphics::Surface *_border;
 
 	// Game state
 	void initGameState();


Commit: 347f1a857c66011c21f2bac1013f5f8e4dfdcee8
    https://github.com/scummvm/scummvm/commit/347f1a857c66011c21f2bac1013f5f8e4dfdcee8
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:01+01:00

Commit Message:
FREESCAPE: removed old code

Changed paths:
    engines/freescape/gfx.cpp
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/gfx_tinygl.h


diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index 1983008568b..30a8488362b 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -20,27 +20,23 @@
  *
  */
 
-#include "engines/freescape/gfx.h"
-
-#include "engines/util.h"
 
 #include "common/config-manager.h"
-
 #include "graphics/renderer.h"
 #include "graphics/surface.h"
-
 #if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS) || defined(USE_GLES2)
 #include "graphics/opengl/context.h"
 #endif
 
 #include "math/glmath.h"
 
-namespace Freescape {
+#include "engines/freescape/gfx.h"
+#include "engines/util.h"
 
+namespace Freescape {
 
 Renderer::Renderer(OSystem *system)
-		: _system(system),
-		  _font(nullptr) {
+		: _system(system) {
 
 	_currentPixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
 	_originalPixelFormat = Graphics::PixelFormat::createFormatCLUT8();
@@ -50,17 +46,6 @@ Renderer::Renderer(OSystem *system)
 
 Renderer::~Renderer() {}
 
-void Renderer::initFont(const Graphics::Surface *surface) {
-	_font = createTexture(surface);
-}
-
-void Renderer::freeFont() {
-	if (_font) {
-		freeTexture(_font);
-		_font = nullptr;
-	}
-}
-
 Graphics::Surface *Renderer::convertFromPalette(Graphics::PixelBuffer *rawsurf) {
 	Graphics::Surface * surf = new Graphics::Surface();
 	surf->create(kOriginalWidth, kOriginalHeight, _originalPixelFormat);
@@ -148,4 +133,4 @@ Renderer *createRenderer(OSystem *system) {
 	error("Unable to create a '%s' renderer", rendererConfig.c_str());
 }
 
-} // End of namespace Myst3
+} // End of namespace Freescape
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index a9979bfc6b6..adcd2881813 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -83,17 +83,12 @@ public:
 	 */
 	virtual void flipBuffer() { }
 
-	virtual void initFont(const Graphics::Surface *surface);
-	virtual void freeFont();
-
 	virtual Texture *createTexture(const Graphics::Surface *surface) = 0;
 	virtual void freeTexture(Texture *texture) = 0;
 
 	virtual void drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint8 g, uint8 b) = 0;
 	virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture) = 0;
 
-	virtual void draw2DText(const Common::String &text, const Common::Point &position) = 0;
-
 	virtual void renderCrossair(byte color) = 0;
 	virtual void renderShoot(byte color) = 0;
 	virtual void renderCube(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) = 0;
@@ -131,7 +126,6 @@ public:
 
 protected:
 	OSystem *_system;
-	Texture *_font;
 	Common::Rect _screenViewport;
 
 	Math::Matrix4 _projectionMatrix;
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index f2415d46189..29bb4dabbdd 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -123,43 +123,6 @@ void TinyGLRenderer::drawTexturedRect2D(const Common::Rect &screenRect, const Co
 	tglBlit(((TinyGLTexture *)texture)->getBlitTexture(), transform);
 }
 
-void TinyGLRenderer::draw2DText(const Common::String &text, const Common::Point &position) {
-	TinyGLTexture *glFont = static_cast<TinyGLTexture *>(_font);
-
-	// The font only has uppercase letters
-	Common::String textToDraw = text;
-	textToDraw.toUppercase();
-
-	tglEnable(TGL_BLEND);
-	tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE_MINUS_SRC_ALPHA);
-
-	tglEnable(TGL_TEXTURE_2D);
-	tglDepthMask(TGL_FALSE);
-
-	tglColor3f(1.0f, 1.0f, 1.0f);
-	tglBindTexture(TGL_TEXTURE_2D, glFont->id);
-
-	int x = position.x;
-	int y = position.y;
-
-	for (uint i = 0; i < textToDraw.size(); i++) {
-		Common::Rect textureRect = getFontCharacterRect(textToDraw[i]);
-		int w = textureRect.width();
-		int h = textureRect.height();
-
-		TinyGL::BlitTransform transform(x, y);
-		transform.sourceRectangle(textureRect.left, textureRect.top, w, h);
-		transform.flip(true, false);
-		//TinyGL::tglBlit(glFont->getBlitTexture(), transform);
-
-		x += textureRect.width() - 3;
-	}
-
-	tglDisable(TGL_TEXTURE_2D);
-	tglDisable(TGL_BLEND);
-	tglDepthMask(TGL_TRUE);
-}
-
 void TinyGLRenderer::updateProjectionMatrix(float fov, float nearClipPlane, float farClipPlane) {
 	tglMatrixMode(TGL_PROJECTION);
 	tglLoadIdentity();
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index 974c4aaf0ae..5fb2cb14fa6 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -48,7 +48,6 @@ public:
 
 	virtual void drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint8 g, uint8 b) override;
 	virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture) override;
-	virtual void draw2DText(const Common::String &text, const Common::Point &position) override;
 
 	virtual void renderCrossair(byte color) override;
 	virtual void renderShoot(byte color) override;


Commit: 44de3eebd3e4b655718b8d644f703c17df2bca47
    https://github.com/scummvm/scummvm/commit/44de3eebd3e4b655718b8d644f703c17df2bca47
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:02+01:00

Commit Message:
FREESCAPE: removed more old code

Changed paths:
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/gfx_tinygl.h


diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index adcd2881813..bbb68198c66 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -85,8 +85,6 @@ public:
 
 	virtual Texture *createTexture(const Graphics::Surface *surface) = 0;
 	virtual void freeTexture(Texture *texture) = 0;
-
-	virtual void drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint8 g, uint8 b) = 0;
 	virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture) = 0;
 
 	virtual void renderCrossair(byte color) = 0;
@@ -123,7 +121,6 @@ public:
 
 	void computeScreenViewport();
 
-
 protected:
 	OSystem *_system;
 	Common::Rect _screenViewport;
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 29bb4dabbdd..34a489f05ee 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -73,41 +73,17 @@ void TinyGLRenderer::init() {
 	tglDisable(TGL_LIGHTING);
 	tglDisable(TGL_TEXTURE_2D);
 	tglEnable(TGL_DEPTH_TEST);
-
-	//tglColorMask(TGL_FALSE, TGL_FALSE, TGL_FALSE, TGL_FALSE);
-	//tglDisable(TGL_POLYGON_OFFSET_FILL);
-
 }
 
 void TinyGLRenderer::setViewport(const Common::Rect &rect) {
 	tglViewport(rect.left, g_system->getHeight() - rect.bottom, rect.width(), rect.height());
 }
 
-
 void TinyGLRenderer::clear() {
 	tglClear(TGL_COLOR_BUFFER_BIT | TGL_DEPTH_BUFFER_BIT);
 	tglColor3f(1.0f, 1.0f, 1.0f);
 }
 
-void TinyGLRenderer::drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint8 g, uint8 b) {
-	tglDisable(TGL_TEXTURE_2D);
-	tglColor3ub(r, g, b);
-
-	if (a != 255) {
-		tglEnable(TGL_BLEND);
-		tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE_MINUS_SRC_ALPHA);
-	}
-
-	tglBegin(TGL_TRIANGLE_STRIP);
-		tglVertex3f(rect.left, rect.bottom, 0.0f);
-		tglVertex3f(rect.right, rect.bottom, 0.0f);
-		tglVertex3f(rect.left, rect.top, 0.0f);
-		tglVertex3f(rect.right, rect.top, 0.0f);
-	tglEnd();
-
-	tglDisable(TGL_BLEND);
-}
-
 void TinyGLRenderer::drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture) {
 	const float sLeft = screenRect.left;
 	const float sTop = screenRect.top;
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index 5fb2cb14fa6..4e9d5aba4ba 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -46,7 +46,6 @@ public:
 	Texture *createTexture(const Graphics::Surface *surface) override;
 	void freeTexture(Texture *texture) override;
 
-	virtual void drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint8 g, uint8 b) override;
 	virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture) override;
 
 	virtual void renderCrossair(byte color) override;


Commit: 62eeb5121f6dcd931160020bc7f855f3f4b3bd3e
    https://github.com/scummvm/scummvm/commit/62eeb5121f6dcd931160020bc7f855f3f4b3bd3e
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:02+01:00

Commit Message:
FREESCAPE: removed more old code

Changed paths:
    engines/freescape/gfx_tinygl.h
    engines/freescape/gfx_tinygl_texture.cpp
    engines/freescape/gfx_tinygl_texture.h


diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index 4e9d5aba4ba..c84be819b23 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -45,7 +45,6 @@ public:
 
 	Texture *createTexture(const Graphics::Surface *surface) override;
 	void freeTexture(Texture *texture) override;
-
 	virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture) override;
 
 	virtual void renderCrossair(byte color) override;
@@ -54,7 +53,6 @@ public:
 	virtual void renderRectangle(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) override;
 	virtual void renderPolygon(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours) override;
 	virtual void renderPyramid(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours, int type);
-
     virtual void renderFace(const Common::Array<Math::Vector3d> &vertices) override;
 
 	virtual void flipBuffer() override;
diff --git a/engines/freescape/gfx_tinygl_texture.cpp b/engines/freescape/gfx_tinygl_texture.cpp
index de4fab0695a..40d9b761f94 100644
--- a/engines/freescape/gfx_tinygl_texture.cpp
+++ b/engines/freescape/gfx_tinygl_texture.cpp
@@ -53,4 +53,4 @@ TinyGL::BlitImage *TinyGLTexture::getBlitTexture() const {
 	return _blitImage;
 }
 
-} // End of namespace Myst3
+} // End of namespace Freescape
diff --git a/engines/freescape/gfx_tinygl_texture.h b/engines/freescape/gfx_tinygl_texture.h
index 86815298c8e..d9a209f0d8c 100644
--- a/engines/freescape/gfx_tinygl_texture.h
+++ b/engines/freescape/gfx_tinygl_texture.h
@@ -49,6 +49,6 @@ private:
 	TinyGL::BlitImage *_blitImage;
 };
 
-} // End of namespace Myst3
+} // End of namespace Freescape
 
 #endif


Commit: 71257b980b90461041049c73051c6ba0d07c5a0e
    https://github.com/scummvm/scummvm/commit/71257b980b90461041049c73051c6ba0d07c5a0e
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:02+01:00

Commit Message:
FREESCAPE: make sure line bounding boxes are valid

Changed paths:
    engines/freescape/objects/geometricobject.cpp


diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index 1e0ace83863..6e4fee529bc 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -157,6 +157,27 @@ void GeometricObject::createBoundingBox() {
 		_boundingBox.expand(origin + size);
 		break;
 	case Line:
+		for (int i = 0; i < int(ordinates->size()); i = i + 3) {
+			_boundingBox.expand(Math::Vector3d((*ordinates)[i], (*ordinates)[i + 1], (*ordinates)[i + 2]));
+		}
+		int dx, dy, dz;
+		dx = dy = dz = 0;
+		if (size.x() == 0 && size.y() == 0) {
+			dx = 2;
+			dy = 2;
+		} else if (size.x() == 0 && size.z() == 0) {
+			dx = 2;
+			dz = 2;
+		} else if (size.y() == 0 && size.z() == 0) {
+			dy = 2;
+			dz = 2;
+		}
+
+		for (int i = 0; i < int(ordinates->size()); i = i + 3) {
+			_boundingBox.expand(Math::Vector3d((*ordinates)[i] + dx, (*ordinates)[i + 1] + dy, (*ordinates)[i + 2] + dz));
+		}
+
+		break;
 	case Triangle:
 	case Quadrilateral:
 	case Pentagon:


Commit: 90c3ff28a6d142452c846d1a6dbd54a7273f0ee9
    https://github.com/scummvm/scummvm/commit/90c3ff28a6d142452c846d1a6dbd54a7273f0ee9
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:02+01:00

Commit Message:
FREESCAPE: corrected IFINVISQ opcode implementation

Changed paths:
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/language/instruction.cpp


diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index ab98111c11e..9f97713513f 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -228,6 +228,8 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			currentInstruction.setSource(tokenisedCondition[bytePointer]);
 			currentInstruction.setAdditional(tokenisedCondition[bytePointer + 1]);
 			currentInstruction.setDestination(false); // visible
+			conditionalInstructions->push_back(currentInstruction);
+			currentInstruction = FCLInstruction(Token::UNKNOWN);
 			bytePointer += 2;
 			numberOfArguments = 0;
 			break;
@@ -240,6 +242,8 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			currentInstruction.setSource(tokenisedCondition[bytePointer]);
 			currentInstruction.setAdditional(tokenisedCondition[bytePointer + 1]);
 			currentInstruction.setDestination(true); // invisible
+			conditionalInstructions->push_back(currentInstruction);
+			currentInstruction = FCLInstruction(Token::UNKNOWN);
 			bytePointer += 2;
 			numberOfArguments = 0;
 			break;
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index acc221c1c89..4f992cbb044 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -63,13 +63,13 @@ void FreescapeEngine::executeConditions(GeometricObject *obj, bool shot, bool co
 
 	debugC(1, kFreescapeDebugCode, "Executing room conditions");
 	for (int i = 0; i < int(_currentArea->conditions.size()); i++) {
-		debugC(1, kFreescapeDebugCode, "Executing with collision flag: %s", _currentArea->conditionSources[i]->c_str());
+		debugC(1, kFreescapeDebugCode, "%s", _currentArea->conditionSources[i]->c_str());
 		executeCode(_currentArea->conditions[i], shot, collided);
 	}
 
 	debugC(1, kFreescapeDebugCode, "Executing global conditions (%d)", _conditions.size());
 	for (int i = 0; i < int(_conditions.size()); i++) {
-		//debugC(1, kFreescapeDebugCode, "Executing with collision flag: %s", _conditionSources[i]->c_str());
+		debugC(1, kFreescapeDebugCode, "%s", _conditionSources[i]->c_str());
 		executeCode(_conditions[i], shot, collided);
 	}
 }
@@ -188,7 +188,7 @@ bool FreescapeEngine::executeEndIfVisibilityIsNotEqual(FCLInstruction &instructi
 		debugC(1, kFreescapeDebugCode, "End condition if visibility of obj with id %d in area %d is %d!", additional, source, value);
 	}
 
-	return (obj->isInvisible() == value);
+	return (obj->isInvisible() != value);
 }
 
 bool FreescapeEngine::executeEndIfNotEqual(FCLInstruction &instruction) {


Commit: f668a6e6a10951c9282b1bc9689be5bf08e0e608
    https://github.com/scummvm/scummvm/commit/f668a6e6a10951c9282b1bc9689be5bf08e0e608
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:02+01:00

Commit Message:
FREESCAPE: improved detection of castle

Changed paths:
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index d7394e7965b..df912aacf17 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -140,11 +140,11 @@ void FreescapeEngine::loadAssets() {
 			error("Invalid render mode %s for Total Eclipse", _renderMode.c_str());
 	   } else if (isCastle()) {
 			_renderMode = "ega";
-			file = gameDir.createReadStreamForMember("castle.sna");
+			file = gameDir.createReadStreamForMember("cm.bin");
 
 			if (file == nullptr)
-				error("Failed to open castle.sna");
-			load8bitBinary(file, 0x84da, 16);
+				error("Failed to open cm.bin");
+			load8bitBinary(file, 0x791a, 16);
 	   } else
 		error("'%s' is an invalid game", _targetName.c_str());
 


Commit: 1758d54909d5189b5549ab4afdde527c3878c533
    https://github.com/scummvm/scummvm/commit/1758d54909d5189b5549ab4afdde527c3878c533
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:02+01:00

Commit Message:
FREESCAPE: loading of castle from dos release

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index df912aacf17..dbd3a1f81fc 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -9,6 +9,7 @@
 #include "common/math.h"
 #include "common/fs.h"
 #include "common/system.h"
+#include "common/memstream.h"
 
 #include "engines/util.h"
 
@@ -140,11 +141,26 @@ void FreescapeEngine::loadAssets() {
 			error("Invalid render mode %s for Total Eclipse", _renderMode.c_str());
 	   } else if (isCastle()) {
 			_renderMode = "ega";
-			file = gameDir.createReadStreamForMember("cm.bin");
 
-			if (file == nullptr)
-				error("Failed to open cm.bin");
-			load8bitBinary(file, 0x791a, 16);
+			file = gameDir.createReadStreamForMember("CMEDF");
+			int size = file->size();
+			byte *encryptedBuffer = (byte*) malloc(size);
+			file->read(encryptedBuffer, size);
+
+			int seed = 24;
+			for (int i = 0; i < size; i++) {
+				encryptedBuffer[i] ^= seed;
+				seed = (seed + 1) & 0xff;
+			}
+
+			file = new Common::MemoryReadStream(encryptedBuffer, size);
+			load8bitBinary(file, 0, 16);
+
+			// CPC
+			//file = gameDir.createReadStreamForMember("cm.bin");
+			//if (file == nullptr)
+			//	error("Failed to open cm.bin");
+			//load8bitBinary(file, 0x791a, 16);
 	   } else
 		error("'%s' is an invalid game", _targetName.c_str());
 
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index e0951fd8803..6ee6a2c1890 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -176,7 +176,12 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 	} break;
 
 	case Object::Group:
-		error("Object of type 'group'");
+		debug("Object of type 'group'");
+		file->seek(byteSizeOfObject, SEEK_CUR);
+		return new Sensor(
+			objectID,
+			position,
+			v);
 		break;
 	}
 
@@ -214,17 +219,16 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	uint8 ci2 = 0;
 	uint8 skyColor = 255;
 	uint8 groundColor = 255;
-	if (!isCastle()) {
-		groundColor = file->readByte() & 15;
-		skyColor = file->readByte() & 15;
-		ci1 = file->readByte();
-		ci2 = file->readByte();
-		debugC(1, kFreescapeDebugParser, "Colors: %d %d %d %d", ci1, ci2, skyColor, groundColor);
-	} else {
-		groundColor = file->readByte() & 15;
-		skyColor = file->readByte() & 15;
-		debugC(1, kFreescapeDebugParser, "Colors: %d %d", skyColor, groundColor);
-	}
+
+	groundColor = file->readByte() & 15;
+	skyColor = file->readByte() & 15;
+	ci1 = file->readByte();
+	ci2 = file->readByte();
+	debugC(1, kFreescapeDebugParser, "Colors: %d %d %d %d", ci1, ci2, skyColor, groundColor);
+	// CPC
+	//groundColor = file->readByte() & 15;
+	//skyColor = file->readByte() & 15;
+	//debugC(1, kFreescapeDebugParser, "Colors: %d %d", skyColor, groundColor);
 
 	if (_renderMode == "cga") {
 		skyColor = skyColor % 4;
@@ -238,6 +242,9 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	//debug("Condition Ptr: %x", cPtr);
 	debugC(1, kFreescapeDebugParser, "Pos before first object: %lx", file->pos());
 
+	if (areaNumber == 192)
+		return nullptr;
+
 	uint8 gasPocketX = 0;
 	uint8 gasPocketY = 0;
 	uint8 gasPocketRadius = 0;
@@ -263,12 +270,12 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 			i++;
 		}
 		debugC(1, kFreescapeDebugParser, "Area name: %s", name.c_str());
-	} else if (!isCastle())
-		file->seek(15, SEEK_CUR);
+	} else if (isCastle())
+		file->seek(5, SEEK_CUR);
 
 	ObjectMap *objectsByID = new ObjectMap;
 	ObjectMap *entrancesByID = new ObjectMap;
-	for (uint8 object = 0; object < numberOfObjects; object++) {
+	for (uint8 object = 0; object < numberOfObjects && areaNumber != 192; object++) {
 		debugC(1, kFreescapeDebugParser, "Reading object: %d", object);
 		Object *newObject = load8bitObject(file);
 
@@ -288,7 +295,7 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	}
 	long int endLastObject = file->pos();
 	debugC(1, kFreescapeDebugParser, "Last position %lx", endLastObject);
-	assert(endLastObject == base + cPtr);
+	assert(endLastObject == base + cPtr || areaNumber == 192);
 	file->seek(base + cPtr);
 	uint8 numConditions = file->readByte();
 	debugC(1, kFreescapeDebugParser, "%d area conditions at %x of area %d", numConditions, base + cPtr, areaNumber);
@@ -388,10 +395,8 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 		globalObjectsArea = new Area(255, 0, globalObjectsByID, nullptr, 1, 255, 255, nullptr);
 	}
 
-	if (!isCastle())
-		file->seek(offset + 0xc8);
-	else
-		file->seek(offset + 0x4f);
+	file->seek(offset + 0xc8);
+	//file->seek(offset + 0x4f); //CPC
 
 	debugC(1, kFreescapeDebugParser, "areas index at: %lx", file->pos());
 	uint16 *fileOffsetForArea = new uint16[numberOfAreas];
@@ -413,10 +418,12 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 				_areaMap[newArea->getAreaID()] = newArea;
 			else
 				debugC(1, kFreescapeDebugParser, "WARNING: area ID repeated: %d", newArea->getAreaID());
-		} else
-			error("Invalid area?");
+		} else {
+			debug("Invalid area %d?", area);
+			break;
+		}
 	}
-	if (isEclipse()) {
+	if (isEclipse() || isCastle()) {
 		_playerHeight = 48;
 		_playerWidth = 8;
 		_playerDepth = 8;


Commit: c90d2620ba8115883769f0d95c1535f1eefca24f
    https://github.com/scummvm/scummvm/commit/c90d2620ba8115883769f0d95c1535f1eefca24f
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:03+01:00

Commit Message:
FREESCAPE: parse more fcd opcodes

Changed paths:
    engines/freescape/language/8bitDetokeniser.cpp


diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index 9f97713513f..edfb14bd29d 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -29,12 +29,14 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 	FCLInstruction currentInstruction;
 
 	// this lookup table tells us how many argument bytes to read per opcode
-	uint8 argumentsRequiredByOpcode[35] =
-		{
-			0, 3, 1, 1, 1, 1, 2, 2,
-			2, 1, 1, 2, 1, 1, 2, 1,
-			1, 2, 2, 1, 2, 0, 0, 0,
-			1, 1, 0, 1, 1, 1, 1, 1, 2, 2, 1};
+	uint8 argumentsRequiredByOpcode[49] =
+		{ 0, 3, 1, 1, 1, 1, 2, 2,
+		  2, 1, 1, 2, 1, 1, 2, 1,
+		  1, 2, 2, 1, 2, 0, 0, 0,
+		  1, 1, 0, 1, 1, 1, 1, 1,
+		  2, 2, 1, 1, 0, 0, 0, 0,
+		  0, 0, 0, 0, 0, 0, 2, 2,
+		  1};
 
 	while (bytePointer < sizeOfTokenisedContent) {
 		// get the conditional type of the next operation
@@ -71,8 +73,10 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 
 		// figure out how many argument bytes we're going to need,
 		// check we have enough bytes left to read
-		if (opcode > 34) {
-			debug("ERROR: failed to read opcode: %x", opcode);
+		if (opcode > 48) {
+			debug("%s", detokenisedStream.c_str());
+			if (opcode != 0x29 && opcode < 0x4f && opcode > 0x5f)
+				error("ERROR: failed to read opcode: %x", opcode);
 			break;
 		}
 
@@ -86,8 +90,6 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			detokenisedStream += "<UNKNOWN 8 bit: ";
 			detokenisedStream += Common::String::format("%x", (int)opcode);
 			detokenisedStream += " > ";
-			if (opcode != 0x18)
-				error("Unknown FCL instruction: 0x%x", (int)opcode);
 			break;
 
 		case 0:
@@ -314,17 +316,43 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			numberOfArguments = 0;
 			break;
 
-		case 23:
-			detokenisedStream += "UNKNOWN(23)(..) ";
+		case 35:
+			detokenisedStream += "SCREEN ";
+			//detokenisedStream += Common::String::format("(%d)", (int)tokenisedCondition[bytePointer]);
+			//bytePointer += 1;
+			//numberOfArguments = 0;
+			break;
+
+		case 44:
+			detokenisedStream += "ELSE ";
+			//numberOfArguments = 0;
+			break;
+
+		case 45:
+			detokenisedStream += "ENDIF ";
+			//numberOfArguments = 0;
+			break;
+
+		case 46:
+			detokenisedStream += "IFGTE ";
+			detokenisedStream += Common::String::format("(v%d, %d)", (int)tokenisedCondition[bytePointer], (int)tokenisedCondition[bytePointer + 1]);
 			bytePointer += 2;
 			numberOfArguments = 0;
 			break;
 
-		case 22:
-			detokenisedStream += "UNKNOWN(22)(..) ";
+		case 47:
+			detokenisedStream += "IFLTE ";
+			detokenisedStream += Common::String::format("(v%d, %d)", (int)tokenisedCondition[bytePointer], (int)tokenisedCondition[bytePointer + 1]);
 			bytePointer += 2;
 			numberOfArguments = 0;
 			break;
+
+		case 48:
+			detokenisedStream += "EXECUTE ";
+			//detokenisedStream += Common::String::format("(%d)", (int)tokenisedCondition[bytePointer]);
+			//bytePointer += 1;
+			//numberOfArguments = 0;
+			break;
 		}
 
 		// if there are any regular arguments to add, do so


Commit: 98352edc3b1f8934b8d15a34b454ddc86d7f22c0
    https://github.com/scummvm/scummvm/commit/98352edc3b1f8934b8d15a34b454ddc86d7f22c0
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:03+01:00

Commit Message:
FREESCAPE: improved parsing of fcd opcodes

Changed paths:
    engines/freescape/language/8bitDetokeniser.cpp


diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index edfb14bd29d..f09067f77df 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -68,14 +68,14 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 		}
 
 		// get the actual operation
-		uint16 opcode = tokenisedCondition[bytePointer] & 0x7f;
+		uint16 opcode = tokenisedCondition[bytePointer] & 0x3f;
 		bytePointer++;
 
 		// figure out how many argument bytes we're going to need,
 		// check we have enough bytes left to read
 		if (opcode > 48) {
 			debug("%s", detokenisedStream.c_str());
-			if (opcode != 0x29 && opcode < 0x4f && opcode > 0x5f)
+			if (opcode != 0x3f)
 				error("ERROR: failed to read opcode: %x", opcode);
 			break;
 		}
@@ -318,19 +318,14 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 
 		case 35:
 			detokenisedStream += "SCREEN ";
-			//detokenisedStream += Common::String::format("(%d)", (int)tokenisedCondition[bytePointer]);
-			//bytePointer += 1;
-			//numberOfArguments = 0;
 			break;
 
 		case 44:
 			detokenisedStream += "ELSE ";
-			//numberOfArguments = 0;
 			break;
 
 		case 45:
 			detokenisedStream += "ENDIF ";
-			//numberOfArguments = 0;
 			break;
 
 		case 46:
@@ -349,9 +344,6 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 
 		case 48:
 			detokenisedStream += "EXECUTE ";
-			//detokenisedStream += Common::String::format("(%d)", (int)tokenisedCondition[bytePointer]);
-			//bytePointer += 1;
-			//numberOfArguments = 0;
 			break;
 		}
 


Commit: 8cf72c7e5cacc41189fe65d38ae0492f30f2ea7e
    https://github.com/scummvm/scummvm/commit/8cf72c7e5cacc41189fe65d38ae0492f30f2ea7e
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:03+01:00

Commit Message:
FREESCAPE: correctly parse sky and ground color

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/palettes.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 1c09b43f0c0..293cdf2060c 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -134,16 +134,10 @@ void Area::draw(Freescape::Renderer *gfx) {
 		gfx->_palette = palette;
 
 	gfx->clear();
-
-	if (areaFlags & 0x02 || areaFlags & 0x20)
-		gfx->drawSky(skyColor);
-
-	if (areaFlags & 0x01 || areaFlags & 0x40)
-		gfx->drawFloor(groundColor);
-
-	if (areaFlags & 0x80)
+	if (skyColor != 255) {
 		gfx->_keyColor = 0;
-	else
+		gfx->drawSky(skyColor);
+	} else
 		gfx->_keyColor = 255;
 
 	assert(drawableObjects.size() > 0);
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 6ee6a2c1890..264c281129b 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -217,11 +217,16 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 
 	uint8 ci1 = 0;
 	uint8 ci2 = 0;
-	uint8 skyColor = 255;
-	uint8 groundColor = 255;
+	uint8 skyColor = areaFlags & 15;
+	uint8 groundColor = areaFlags >> 4;
 
-	groundColor = file->readByte() & 15;
-	skyColor = file->readByte() & 15;
+	if (groundColor == 0)
+		groundColor = 255;
+	if (skyColor == 0)
+		skyColor = 255;
+
+	file->readByte() & 15;
+	file->readByte() & 15;
 	ci1 = file->readByte();
 	ci2 = file->readByte();
 	debugC(1, kFreescapeDebugParser, "Colors: %d %d %d %d", ci1, ci2, skyColor, groundColor);
diff --git a/engines/freescape/palettes.cpp b/engines/freescape/palettes.cpp
index 315bde02773..99b163c6096 100644
--- a/engines/freescape/palettes.cpp
+++ b/engines/freescape/palettes.cpp
@@ -42,16 +42,16 @@ byte castleEGA[16][3] = {
 	{0x00, 0xaa, 0xaa},
 	{0xaa, 0xaa, 0xaa},
 	{0x55, 0x55, 0x55},
+	{0xaa, 0x00, 0x00},
 	{0x00, 0xaa, 0x00},
-	{0xaa, 0x55, 0x00},
 	{0x12, 0xf3, 0x56},
 	{0xaa, 0x00, 0x00},
 	{0xff, 0x55, 0xff},
 	{0xaa, 0x55, 0x00},
 	{0xaa, 0x55, 0x00},
 	{0xaa, 0x55, 0x00},
-	{0x12, 0xf3, 0x56},
-	{0x12, 0xf3, 0x56}
+	{0x00, 0x00, 0xaa},
+	{0xaa, 0x55, 0x00}
 };
 
 byte eclipseEGA[16][3] = {
@@ -63,14 +63,14 @@ byte eclipseEGA[16][3] = {
 	{0x00, 0x00, 0xA8},
 	{0xff, 0x00, 0xaa},
 	{0xaa, 0x00, 0xaa},
-	{0x12, 0xf3, 0x56},
+	{0x55, 0xff, 0xff},
 	{0x55, 0x55, 0xff},
 	{0x55, 0xff, 0x55},
 	{0xa8, 0x00, 0x00},
 	{0xff, 0x55, 0x55},
 	{0x54, 0x54, 0x54},
 	{0xa8, 0x54, 0x00},
-	{0xff, 0xff, 0x55}
+	{0xfc, 0xfc, 0x54}
 };
 
 Graphics::PixelBuffer *FreescapeEngine::getPalette(uint8 areaNumber, uint8 c1, uint8 c2, uint8 c3, uint8 c4, uint16 ncolors) {


Commit: 45ba823fc9301a8758402f4bed932385b195d9ce
    https://github.com/scummvm/scummvm/commit/45ba823fc9301a8758402f4bed932385b195d9ce
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:03+01:00

Commit Message:
FREESCAPE: correctly set keys for driller and implement basic adding/removing of drill

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/freescape.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 293cdf2060c..e74a4e262b2 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -202,8 +202,8 @@ void Area::addDrill(Area *structure, const Math::Vector3d position) {
 	id = 254;
 	debug("Adding object %d to room structure", id);
 	obj = structure->objectWithID(id);
-	obj->setOrigin(offset);
 	offset.setValue(1, offset.y() + obj->getSize().y());
+	obj->setOrigin(offset);
 	assert(obj);
 	(*objectsByID)[id] = obj;
 	obj->makeVisible();
@@ -230,6 +230,18 @@ void Area::addDrill(Area *structure, const Math::Vector3d position) {
 	drawableObjects.insert_at(0, obj);
 }
 
+void Area::removeDrill() {
+	for (int16 id = 252; id < 256; id++) {
+		objectsByID->erase(id);
+		assert(drawableObjects[0]->getObjectID() == id);
+		drawableObjects.remove_at(0);
+	}
+}
+
+bool Area::drillDeployed() {
+	return (objectWithID(252) != nullptr);
+}
+
 void Area::addStructure(Area *structure) {
 	Object *obj = nullptr;
 	if (!structure || !entrancesByID->contains(255)) {
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index ddb597d8c2c..7555b3d24a3 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -49,7 +49,6 @@ public:
 	Object *shootRay(const Math::Ray &ray);
 	Object *checkCollisions(const Math::AABB &boundingBox);
 	void addStructure(Area *structure);
-	void addDrill(Area *structure, const Math::Vector3d position);
 
 	Common::Array<Common::String*> conditionSources;
 	Common::Array<FCLInstructionVector> conditions;
@@ -58,10 +57,15 @@ public:
 	void saveObjectFlags(Common::WriteStream *stream);
 	void loadObjectFlags(Common::SeekableReadStream *stream);
 
-	// Driller specific fields
-	uint8 gasPocketX;
-	uint8 gasPocketY;
-	uint8 gasPocketRadius;
+	// Driller specific
+	void addDrill(Area *structure, const Math::Vector3d position);
+	void removeDrill();
+
+	bool drillDeployed();
+
+	uint32 gasPocketX;
+	uint32 gasPocketY;
+	uint32 gasPocketRadius;
 
 private:
 	uint16 areaID;
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index dbd3a1f81fc..eef3ff13601 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -198,25 +198,39 @@ void FreescapeEngine::processInput() {
 
 		switch (event.type) {
 		case Common::EVENT_KEYDOWN:
-			if (event.kbd.keycode == Common::KEYCODE_w || event.kbd.keycode == Common::KEYCODE_UP)
+			if (event.kbd.keycode == Common::KEYCODE_o || event.kbd.keycode == Common::KEYCODE_UP)
 				move(FORWARD, _scaleVector.x(), deltaTime);
-			else if (event.kbd.keycode == Common::KEYCODE_s || event.kbd.keycode == Common::KEYCODE_DOWN)
+			else if (event.kbd.keycode == Common::KEYCODE_k || event.kbd.keycode == Common::KEYCODE_DOWN)
 				move(BACKWARD, _scaleVector.x(), deltaTime);
-			else if (event.kbd.keycode == Common::KEYCODE_a || event.kbd.keycode == Common::KEYCODE_LEFT)
+			else if (event.kbd.keycode == Common::KEYCODE_q || event.kbd.keycode == Common::KEYCODE_LEFT)
 				move(LEFT, _scaleVector.y(), deltaTime);
-			else if (event.kbd.keycode == Common::KEYCODE_d || event.kbd.keycode == Common::KEYCODE_RIGHT)
+			else if (event.kbd.keycode == Common::KEYCODE_w || event.kbd.keycode == Common::KEYCODE_RIGHT)
 				move(RIGHT, _scaleVector.y(), deltaTime);
+			else if (event.kbd.keycode == Common::KEYCODE_KP5 || event.kbd.keycode == Common::KEYCODE_KP0)
+				shoot();
 			else if (event.kbd.keycode == Common::KEYCODE_f)
 				_position.setValue(1, _position.y() + 12);
 			else if (event.kbd.keycode == Common::KEYCODE_v)
 				_position.setValue(1, _position.y() - 12);
 			else if (event.kbd.keycode == Common::KEYCODE_n)
 				gotoArea(_currentArea->getAreaID() + 1, 0);
-			else if (event.kbd.keycode == Common::KEYCODE_m) {
-				if (isDriller()) {
+			else if (event.kbd.keycode == Common::KEYCODE_d) {
+				if (isDriller() && !_currentArea->drillDeployed()) {
 					// TODO: check if there is space for the drill
-					_currentArea->addDrill(globalObjectsArea, _position + _cameraFront * 128);
+					// TODO: check if there is enough energy
+					Math::Vector3d drillPosition = _position + _cameraFront * 128;
+					drillPosition.setValue(1, 1);
+					const Math::Vector3d gasPocket(_currentArea->gasPocketX, 1, _currentArea->gasPocketY);
+					_currentArea->addDrill(globalObjectsArea, drillPosition);
+					float distance = (gasPocket - drillPosition).length();
+					debug("length to gas pocket: %f with radius %d", distance, _currentArea->gasPocketRadius);
 					// TODO check the result of the drilling
+					// TODO: reduce energy
+				}
+			} else if (event.kbd.keycode == Common::KEYCODE_c) {
+				// TODO: check if there is enough energy
+				if (isDriller() && _currentArea->drillDeployed()) {
+					_currentArea->removeDrill();
 				}
 			} else if (event.kbd.keycode == Common::KEYCODE_ESCAPE)
 				openMainMenuDialog();
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 264c281129b..b21b3de5d67 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -307,8 +307,8 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 
 	Area *area = new Area(areaNumber, areaFlags, objectsByID, entrancesByID, scale, skyColor, groundColor, palette);
 	area->name = name;
-	area->gasPocketX = gasPocketX;
-	area->gasPocketY = gasPocketY;
+	area->gasPocketX = 32 * gasPocketX;
+	area->gasPocketY = 32 * gasPocketY;
 	area->gasPocketRadius = gasPocketRadius;
 
 	while (numConditions--) {


Commit: a6532770de7f603055d18b2cbd759a17196862ce
    https://github.com/scummvm/scummvm/commit/a6532770de7f603055d18b2cbd759a17196862ce
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:03+01:00

Commit Message:
FREESCAPE: only allow to drill when radious is positive

Changed paths:
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index eef3ff13601..e237f8e2395 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -215,12 +215,15 @@ void FreescapeEngine::processInput() {
 			else if (event.kbd.keycode == Common::KEYCODE_n)
 				gotoArea(_currentArea->getAreaID() + 1, 0);
 			else if (event.kbd.keycode == Common::KEYCODE_d) {
-				if (isDriller() && !_currentArea->drillDeployed()) {
+				uint32 gasPocketX = _currentArea->gasPocketX;
+				uint32 gasPocketY = _currentArea->gasPocketX;
+				uint32 gasPocketRadius = _currentArea->gasPocketRadius;
+				if (isDriller() && gasPocketRadius > 0 && !_currentArea->drillDeployed()) {
 					// TODO: check if there is space for the drill
 					// TODO: check if there is enough energy
 					Math::Vector3d drillPosition = _position + _cameraFront * 128;
 					drillPosition.setValue(1, 1);
-					const Math::Vector3d gasPocket(_currentArea->gasPocketX, 1, _currentArea->gasPocketY);
+					const Math::Vector3d gasPocket(gasPocketX, 1, gasPocketY);
 					_currentArea->addDrill(globalObjectsArea, drillPosition);
 					float distance = (gasPocket - drillPosition).length();
 					debug("length to gas pocket: %f with radius %d", distance, _currentArea->gasPocketRadius);


Commit: 82ac1f6f41b106a4e3194869a4a7043babfa6424
    https://github.com/scummvm/scummvm/commit/82ac1f6f41b106a4e3194869a4a7043babfa6424
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:03+01:00

Commit Message:
FREESCAPE: increase variable 32 when drilling

Changed paths:
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index e237f8e2395..637e388eeae 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -219,6 +219,7 @@ void FreescapeEngine::processInput() {
 				uint32 gasPocketY = _currentArea->gasPocketX;
 				uint32 gasPocketRadius = _currentArea->gasPocketRadius;
 				if (isDriller() && gasPocketRadius > 0 && !_currentArea->drillDeployed()) {
+					_gameStateVars[32]++;
 					// TODO: check if there is space for the drill
 					// TODO: check if there is enough energy
 					Math::Vector3d drillPosition = _position + _cameraFront * 128;
@@ -233,6 +234,7 @@ void FreescapeEngine::processInput() {
 			} else if (event.kbd.keycode == Common::KEYCODE_c) {
 				// TODO: check if there is enough energy
 				if (isDriller() && _currentArea->drillDeployed()) {
+					_gameStateVars[32]--;
 					_currentArea->removeDrill();
 				}
 			} else if (event.kbd.keycode == Common::KEYCODE_ESCAPE)


Commit: 59146c166764bbdd553bdeda6a0f8cfaffad6fed
    https://github.com/scummvm/scummvm/commit/59146c166764bbdd553bdeda6a0f8cfaffad6fed
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:04+01:00

Commit Message:
FREESCAPE: added detection of another release of castle

Changed paths:
    engines/freescape/detection.cpp


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index 4b15a5333e4..c2f61de85c4 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -147,6 +147,20 @@ static const ADGameDescription gameDescriptions[] = {
 	 Common::kPlatformDOS,
 	 ADGF_NO_FLAGS,
 	 GUIO1(GUIO_NOMIDI)},
+	{"castlemaster",
+	 "Castle Master/DomarkPCCollection",
+	 {
+		{"X.EXE", 0, "d51d7db1e06814cbf763c43f411df616", 2157},
+		{"CMC.EXE", 0, "7b9275df446f82fdd0c377f6ec2db546", 57168},
+		{"CMT.EXE", 0, "78002e4b6c14e0a7924317d27e868985", 40685},
+		{"CME.EXE", 0, "494268dea6d8580a7f27afb2a8157cc0", 46557},
+		{"CMH.EXE", 0, "03b6f4c5b8931259e42e229de06ac5fc", 35645},
+		AD_LISTEND
+	 },
+	 Common::EN_ANY,
+	 Common::kPlatformDOS,
+	 ADGF_NO_FLAGS,
+	 GUIO1(GUIO_NOMIDI)},
 	{"castlemaster",
 	 "Castle Master",
 	 {


Commit: 2bbb638f37dd6b8c18ff8392908083a0bd4fe68d
    https://github.com/scummvm/scummvm/commit/2bbb638f37dd6b8c18ff8392908083a0bd4fe68d
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:04+01:00

Commit Message:
FREESCAPE: allow save and load drill position

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/freescape.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index e74a4e262b2..272e7bc856c 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -84,9 +84,6 @@ Area::Area(
 	} compareObjects;
 
 	Common::sort(drawableObjects.begin(), drawableObjects.end(), compareObjects);
-
-	gasPocketX = 0;
-	gasPocketY = 0;
 	gasPocketRadius = 0;
 }
 
@@ -111,6 +108,10 @@ void Area::show() {
 }
 
 void Area::loadObjectFlags(Common::SeekableReadStream *stream) {
+	drillPosition.setValue(0, stream->readFloatLE());
+	drillPosition.setValue(1, stream->readFloatLE());
+	drillPosition.setValue(2, stream->readFloatLE());
+
 	for (int i = 0; i < int(objectsByID->size()); i++) {
 		uint16 key = stream->readUint32LE();
 		assert(objectsByID->contains(key));
@@ -121,6 +122,10 @@ void Area::loadObjectFlags(Common::SeekableReadStream *stream) {
 
 void Area::saveObjectFlags(Common::WriteStream *stream) {
 	int dirtyFlags = 0;
+	stream->writeFloatLE(drillPosition.x());
+	stream->writeFloatLE(drillPosition.y());
+	stream->writeFloatLE(drillPosition.z());
+
 	//stream->writeUint32LE(objectsByID->size());
 
 	for (ObjectMap::iterator iterator = objectsByID->begin(); iterator != objectsByID->end(); iterator++) {
@@ -183,6 +188,7 @@ Object *Area::checkCollisions(const Math::AABB &boundingBox) {
 
 void Area::addDrill(Area *structure, const Math::Vector3d position) {
 	//int drillObjectIDs[8] = {255, 254, 253, 252, 251, 250, 248, 247};
+	drillPosition = position;
 	Object *obj = nullptr;
 	Math::Vector3d offset = position;
 	offset.setValue(1, 1);
@@ -195,7 +201,6 @@ void Area::addDrill(Area *structure, const Math::Vector3d position) {
 	obj->setOrigin(offset);
 	offset.setValue(1, offset.y() + obj->getSize().y());
 	assert(obj);
-	(*objectsByID)[id] = obj;
 	obj->makeVisible();
 	drawableObjects.insert_at(0, obj);
 
@@ -205,7 +210,6 @@ void Area::addDrill(Area *structure, const Math::Vector3d position) {
 	offset.setValue(1, offset.y() + obj->getSize().y());
 	obj->setOrigin(offset);
 	assert(obj);
-	(*objectsByID)[id] = obj;
 	obj->makeVisible();
 	drawableObjects.insert_at(0, obj);
 
@@ -215,7 +219,6 @@ void Area::addDrill(Area *structure, const Math::Vector3d position) {
 	obj->setOrigin(offset);
 	offset.setValue(1, offset.y() + obj->getSize().y());
 	assert(obj);
-	(*objectsByID)[id] = obj;
 	obj->makeVisible();
 	drawableObjects.insert_at(0, obj);
 
@@ -225,12 +228,12 @@ void Area::addDrill(Area *structure, const Math::Vector3d position) {
 	obj->setOrigin(offset);
 	offset.setValue(1, offset.y() + obj->getSize().y());
 	assert(obj);
-	(*objectsByID)[id] = obj;
 	obj->makeVisible();
 	drawableObjects.insert_at(0, obj);
 }
 
 void Area::removeDrill() {
+	drillPosition = Math::Vector3d();
 	for (int16 id = 252; id < 256; id++) {
 		objectsByID->erase(id);
 		assert(drawableObjects[0]->getObjectID() == id);
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index 7555b3d24a3..d4e06fb0017 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -62,9 +62,8 @@ public:
 	void removeDrill();
 
 	bool drillDeployed();
-
-	uint32 gasPocketX;
-	uint32 gasPocketY;
+	Math::Vector3d drillPosition;
+	Common::Point gasPocketPosition;
 	uint32 gasPocketRadius;
 
 private:
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 637e388eeae..d0d3b441332 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -215,8 +215,7 @@ void FreescapeEngine::processInput() {
 			else if (event.kbd.keycode == Common::KEYCODE_n)
 				gotoArea(_currentArea->getAreaID() + 1, 0);
 			else if (event.kbd.keycode == Common::KEYCODE_d) {
-				uint32 gasPocketX = _currentArea->gasPocketX;
-				uint32 gasPocketY = _currentArea->gasPocketX;
+				Common::Point gasPocket = _currentArea->gasPocketPosition;
 				uint32 gasPocketRadius = _currentArea->gasPocketRadius;
 				if (isDriller() && gasPocketRadius > 0 && !_currentArea->drillDeployed()) {
 					_gameStateVars[32]++;
@@ -224,10 +223,11 @@ void FreescapeEngine::processInput() {
 					// TODO: check if there is enough energy
 					Math::Vector3d drillPosition = _position + _cameraFront * 128;
 					drillPosition.setValue(1, 1);
-					const Math::Vector3d gasPocket(gasPocketX, 1, gasPocketY);
+					debugC(1, kFreescapeDebugMove, "Trying to adding drill at %f %f %f", drillPosition.x(), drillPosition.y(), drillPosition.z());
+					const Math::Vector3d gasPocket3D(gasPocket.x, 1, gasPocket.y);
 					_currentArea->addDrill(globalObjectsArea, drillPosition);
-					float distance = (gasPocket - drillPosition).length();
-					debug("length to gas pocket: %f with radius %d", distance, _currentArea->gasPocketRadius);
+					float distance = (gasPocket3D - drillPosition).length();
+					debugC(1, kFreescapeDebugMove, "length to gas pocket: %f with radius %d", distance, _currentArea->gasPocketRadius);
 					// TODO check the result of the drilling
 					// TODO: reduce energy
 				}
@@ -605,6 +605,9 @@ Common::Error FreescapeEngine::loadGameStream(Common::SeekableReadStream *stream
 		assert(_areaMap.contains(key));
 		Area *area = _areaMap[key];
 		area->loadObjectFlags(stream);
+		// Add drill, if available
+		if (area->drillPosition != Math::Vector3d())
+			area->addDrill(globalObjectsArea, area->drillPosition);
 	}
 
 	_flyMode = stream->readByte();
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index b21b3de5d67..3bb6b39aa0c 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -307,8 +307,7 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 
 	Area *area = new Area(areaNumber, areaFlags, objectsByID, entrancesByID, scale, skyColor, groundColor, palette);
 	area->name = name;
-	area->gasPocketX = 32 * gasPocketX;
-	area->gasPocketY = 32 * gasPocketY;
+	area->gasPocketPosition = Common::Point(32 * gasPocketX, 32 * gasPocketY);
 	area->gasPocketRadius = gasPocketRadius;
 
 	while (numConditions--) {


Commit: 907dae22be94aa77a59522e262d4a001bebd4241
    https://github.com/scummvm/scummvm/commit/907dae22be94aa77a59522e262d4a001bebd4241
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:04+01:00

Commit Message:
FREESCAPE: add drill at the correct y position

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 272e7bc856c..0b15e4fe7ef 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -191,7 +191,6 @@ void Area::addDrill(Area *structure, const Math::Vector3d position) {
 	drillPosition = position;
 	Object *obj = nullptr;
 	Math::Vector3d offset = position;
-	offset.setValue(1, 1);
 
 	int16 id;
 
@@ -242,7 +241,7 @@ void Area::removeDrill() {
 }
 
 bool Area::drillDeployed() {
-	return (objectWithID(252) != nullptr);
+	return (drawableObjects[0]->getObjectID() == 252);
 }
 
 void Area::addStructure(Area *structure) {
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index d0d3b441332..9f1578879ea 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -222,7 +222,7 @@ void FreescapeEngine::processInput() {
 					// TODO: check if there is space for the drill
 					// TODO: check if there is enough energy
 					Math::Vector3d drillPosition = _position + _cameraFront * 128;
-					drillPosition.setValue(1, 1);
+					drillPosition.setValue(1, _position.y() - _playerHeight * _currentArea->getScale());
 					debugC(1, kFreescapeDebugMove, "Trying to adding drill at %f %f %f", drillPosition.x(), drillPosition.y(), drillPosition.z());
 					const Math::Vector3d gasPocket3D(gasPocket.x, 1, gasPocket.y);
 					_currentArea->addDrill(globalObjectsArea, drillPosition);


Commit: 22395f03003671362faa9c4b657c61d994b862ad
    https://github.com/scummvm/scummvm/commit/22395f03003671362faa9c4b657c61d994b862ad
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:04+01:00

Commit Message:
FREESCAPE: added new licenses and cleaned up includes

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/detection.cpp
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/gfx.cpp
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/gfx_tinygl.h
    engines/freescape/gfx_tinygl_texture.cpp
    engines/freescape/gfx_tinygl_texture.h
    engines/freescape/language/16bitDetokeniser.cpp
    engines/freescape/language/16bitDetokeniser.h
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/language/8bitDetokeniser.h
    engines/freescape/language/instruction.cpp
    engines/freescape/language/instruction.h
    engines/freescape/language/token.h
    engines/freescape/loaders/16bitBinaryLoader.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/metaengine.cpp
    engines/freescape/objects/entrance.cpp
    engines/freescape/objects/entrance.h
    engines/freescape/objects/geometricobject.cpp
    engines/freescape/objects/geometricobject.h
    engines/freescape/objects/object.cpp
    engines/freescape/objects/object.h
    engines/freescape/objects/sensor.cpp
    engines/freescape/objects/sensor.h
    engines/freescape/palettes.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 0b15e4fe7ef..ff4643bcf89 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -1,16 +1,30 @@
-//
-//  Area.cpp
-//  Phantasma
-//
-//  Created by Thomas Harte on 25/12/2013.
-//  Copyright (c) 2013 Thomas Harte. All rights reserved.
-//
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+// Based on Phantasma code by Thomas Harte (2013)
 
 #include "freescape/area.h"
 #include "freescape/objects/geometricobject.h"
 #include "freescape/objects/entrance.h"
 #include "common/algorithm.h"
-#include "freescape/objects/object.h"
 
 namespace Freescape {
 
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index d4e06fb0017..0886195e245 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -1,21 +1,32 @@
-//
-//  Area.h
-//  Phantasma
-//
-//  Created by Thomas Harte on 25/12/2013.
-//  Copyright (c) 2013 Thomas Harte. All rights reserved.
-//
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+// Based on Phantasma code by Thomas Harte (2013)
 
 #ifndef FREESCAPE_AREA_H
 #define FREESCAPE_AREA_H
 
-#include "common/hashmap.h"
-#include "common/array.h"
-
 #include "math/vector3d.h"
 #include "math/ray.h"
 
-#include "freescape/gfx.h"
 #include "freescape/objects/object.h"
 #include "freescape/language/instruction.h"
 
diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index c2f61de85c4..faf5988c552 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -1,3 +1,24 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
 #include "base/plugins.h"
 #include "engines/advancedDetector.h"
 
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 9f1578879ea..8cbd1715914 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -1,25 +1,31 @@
-#include "common/scummsys.h"
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
 
 #include "common/config-manager.h"
-#include "common/debug-channels.h"
-#include "common/debug.h"
-#include "common/error.h"
 #include "common/events.h"
 #include "common/file.h"
 #include "common/math.h"
-#include "common/fs.h"
-#include "common/system.h"
 #include "common/memstream.h"
 
-#include "engines/util.h"
-
-#include "graphics/renderer.h"
-#include "math/ray.h"
-
 #include "freescape/freescape.h"
-#include "freescape/gfx.h"
-#include "freescape/objects/geometricobject.h"
-#include "freescape/language/token.h"
 #include "freescape/language/8bitDetokeniser.h"
 
 namespace Freescape {
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 03a50cdf4f0..3c8177f58e9 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -1,13 +1,32 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
 #ifndef FREESCAPE_H
 #define FREESCAPE_H
 
 #include "common/random.h"
-#include "common/serializer.h"
 #include "engines/engine.h"
 #include "graphics/palette.h"
 #include "graphics/surface.h"
 #include "graphics/tinygl/pixelbuffer.h"
-#include "gui/debugger.h"
 
 #include "audio/mixer.h"
 #include "audio/softsynth/pcspk.h"
@@ -15,7 +34,6 @@
 #include "freescape/area.h"
 #include "freescape/objects/geometricobject.h"
 #include "freescape/objects/entrance.h"
-#include "freescape/language/instruction.h"
 #include "freescape/gfx.h"
 
 namespace Freescape {
@@ -173,15 +191,6 @@ public:
 	Common::Error saveGameStream(Common::WriteStream *stream, bool isAutosave = false) override;
 };
 
-// Example console class
-class Console : public GUI::Debugger {
-public:
-	Console(FreescapeEngine *vm) {
-	}
-	virtual ~Console(void) {
-	}
-};
-
 extern FreescapeEngine *g_freescape;
 
 } // namespace Freescape
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index 30a8488362b..5d2daa7f139 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -1,13 +1,13 @@
-/* ResidualVM - A 3D game interpreter
+/* ScummVM - Graphic Adventure Engine
  *
- * ResidualVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the AUTHORS
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
  * file distributed with this source distribution.
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,12 +15,10 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
-
 #include "common/config-manager.h"
 #include "graphics/renderer.h"
 #include "graphics/surface.h"
@@ -29,9 +27,9 @@
 #endif
 
 #include "math/glmath.h"
+#include "engines/util.h"
 
 #include "engines/freescape/gfx.h"
-#include "engines/util.h"
 
 namespace Freescape {
 
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index bbb68198c66..bc1c3f518f6 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -1,13 +1,13 @@
-/* ResidualVM - A 3D game interpreter
+/* ScummVM - Graphic Adventure Engine
  *
- * ResidualVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the AUTHORS
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
  * file distributed with this source distribution.
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 34a489f05ee..2960af3f255 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -1,13 +1,13 @@
-/* ResidualVM - A 3D game interpreter
+/* ScummVM - Graphic Adventure Engine
  *
- * ResidualVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the AUTHORS
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
  * file distributed with this source distribution.
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,25 +15,19 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
+// Based on Phantasma code by Thomas Harte (2013)
+
 #include "common/config-manager.h"
 #include "common/rect.h"
-#include "common/textconsole.h"
-
-#include "graphics/colormasks.h"
-#include "graphics/surface.h"
-
-#include "math/vector2d.h"
 #include "math/glmath.h"
+#include "graphics/tinygl/tinygl.h"
 
-#include "engines/freescape/gfx.h"
 #include "engines/freescape/gfx_tinygl.h"
 #include "engines/freescape/gfx_tinygl_texture.h"
-#include "graphics/tinygl/tinygl.h"
 
 namespace Freescape {
 
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index c84be819b23..049f0f9cf84 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -1,13 +1,13 @@
-/* ResidualVM - A 3D game interpreter
+/* ScummVM - Graphic Adventure Engine
  *
- * ResidualVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the AUTHORS
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
  * file distributed with this source distribution.
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
@@ -24,11 +23,9 @@
 #define FREESCAPE_GFX_TINYGL_H_
 
 #include "common/rect.h"
-#include "common/system.h"
 #include "math/vector3d.h"
 
 #include "engines/freescape/gfx.h"
-#include "graphics/tinygl/zgl.h"
 
 namespace Freescape {
 
@@ -62,4 +59,4 @@ public:
 
 } // End of namespace Freescape
 
-#endif // GFX_H_
+#endif
diff --git a/engines/freescape/gfx_tinygl_texture.cpp b/engines/freescape/gfx_tinygl_texture.cpp
index 40d9b761f94..a73baffa172 100644
--- a/engines/freescape/gfx_tinygl_texture.cpp
+++ b/engines/freescape/gfx_tinygl_texture.cpp
@@ -1,13 +1,13 @@
-/* ResidualVM - A 3D game interpreter
+/* ScummVM - Graphic Adventure Engine
  *
- * ResidualVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the AUTHORS
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
  * file distributed with this source distribution.
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
diff --git a/engines/freescape/gfx_tinygl_texture.h b/engines/freescape/gfx_tinygl_texture.h
index d9a209f0d8c..79272e61ea9 100644
--- a/engines/freescape/gfx_tinygl_texture.h
+++ b/engines/freescape/gfx_tinygl_texture.h
@@ -1,13 +1,13 @@
-/* ResidualVM - A 3D game interpreter
+/* ScummVM - Graphic Adventure Engine
  *
- * ResidualVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the AUTHORS
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
  * file distributed with this source distribution.
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
@@ -25,7 +24,6 @@
 
 #include "graphics/surface.h"
 #include "graphics/tinygl/zgl.h"
-#include "common/textconsole.h"
 
 #include "engines/freescape/gfx.h"
 #include "graphics/tinygl/zblit.h"
diff --git a/engines/freescape/language/16bitDetokeniser.cpp b/engines/freescape/language/16bitDetokeniser.cpp
index f50bb48e768..13b8265a659 100644
--- a/engines/freescape/language/16bitDetokeniser.cpp
+++ b/engines/freescape/language/16bitDetokeniser.cpp
@@ -1,10 +1,25 @@
-//
-//  16bitDetokeniser.cpp
-//  Phantasma
-//
-//  Created by Thomas Harte on 15/12/2013.
-//  Copyright (c) 2013 Thomas Harte. All rights reserved.
-//
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+// Based on Phantasma code by Thomas Harte (2013)
 
 #include "16bitDetokeniser.h"
 
diff --git a/engines/freescape/language/16bitDetokeniser.h b/engines/freescape/language/16bitDetokeniser.h
index 5032f4da853..668ddf45f4c 100644
--- a/engines/freescape/language/16bitDetokeniser.h
+++ b/engines/freescape/language/16bitDetokeniser.h
@@ -1,17 +1,31 @@
-//
-//  16bitDetokeniser.h
-//  Phantasma
-//
-//  Created by Thomas Harte on 15/12/2013.
-//  Copyright (c) 2013 Thomas Harte. All rights reserved.
-//
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
 
-#ifndef __Phantasma___16bitDetokeniser__
-#define __Phantasma___16bitDetokeniser__
+// Based on Phantasma code by Thomas Harte (2013)
+
+#ifndef FREESCAPE_16BITDETOKENIZER_H
+#define FREESCAPE_16BITDETOKENIZER_H
 
 #include "common/array.h"
-#include "common/str.h"
 
 Common::String *detokenise16bitCondition(Common::Array<uint8> &tokenisedCondition);
 
-#endif /* defined(__Phantasma___16bitDetokeniser__) */
+#endif
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index f09067f77df..3e046ee0726 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -1,18 +1,29 @@
-//
-//  8bitDetokeniser.cpp
-//  Phantasma
-//
-//  Created by Thomas Harte on 15/12/2013.
-//  Copyright (c) 2013 Thomas Harte. All rights reserved.
-//
-
-/*
-	This has been implemented based on John Elliott's 2001
-	reverse engineering of Driller; see http://www.seasip.demon.co.uk/ZX/Driller/
-*/
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+// Based on Phantasma code by Thomas Harte (2013), which was implemented based on
+// John Elliott's 2001 reverse engineering of Driller; see http://www.seasip.demon.co.uk/ZX/Driller/
+
 #include "common/debug.h"
 #include "8bitDetokeniser.h"
-#include "token.h"
 
 namespace Freescape {
 
diff --git a/engines/freescape/language/8bitDetokeniser.h b/engines/freescape/language/8bitDetokeniser.h
index a110d3fad63..1d554be0411 100644
--- a/engines/freescape/language/8bitDetokeniser.h
+++ b/engines/freescape/language/8bitDetokeniser.h
@@ -1,17 +1,29 @@
-//
-//  8bitDetokeniser.h
-//  Phantasma
-//
-//  Created by Thomas Harte on 15/12/2013.
-//  Copyright (c) 2013 Thomas Harte. All rights reserved.
-//
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+// Based on Phantasma code by Thomas Harte (2013)
 
 #ifndef FREESCAPE_8BITDETOKENIZER_H
 #define FREESCAPE_8BITDETOKENIZER_H
 
-#include "common/array.h"
-#include "common/str.h"
-
 #include "freescape/language/instruction.h"
 
 namespace Freescape {
@@ -23,9 +35,8 @@ enum {
 };
 
 static uint8 k8bitMaxVariable = 64;
-
 Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition, FCLInstructionVector &instructions);
 
 } // End of namespace Freescape
 
-#endif /* defined(__Phantasma___8bitDetokeniser__) */
+#endif
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index 4f992cbb044..5dcea924ae1 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -1,12 +1,26 @@
-//
-//  Instruction.cpp
-//  Phantasma
-//
-//  Created by Thomas Harte on 08/12/2013.
-//  Copyright (c) 2013 Thomas Harte. All rights reserved.
-//
-
-#include "freescape/language/instruction.h"
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+// Based on Phantasma code by Thomas Harte (2013)
+
 #include "freescape/language/8bitDetokeniser.h"
 #include "freescape/freescape.h"
 
diff --git a/engines/freescape/language/instruction.h b/engines/freescape/language/instruction.h
index 873c8f18c3b..88fe5508203 100644
--- a/engines/freescape/language/instruction.h
+++ b/engines/freescape/language/instruction.h
@@ -1,10 +1,25 @@
-//
-//  Instruction.h
-//  Phantasma
-//
-//  Created by Thomas Harte on 08/12/2013.
-//  Copyright (c) 2013 Thomas Harte. All rights reserved.
-//
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+// Based on Phantasma code by Thomas Harte (2013)
 
 #ifndef FREESCAPE_INSTRUCTION_H
 #define FREESCAPE_INSTRUCTION_H
diff --git a/engines/freescape/language/token.h b/engines/freescape/language/token.h
index a995a51a122..2186ed33ef0 100644
--- a/engines/freescape/language/token.h
+++ b/engines/freescape/language/token.h
@@ -1,10 +1,25 @@
-//
-//  Token.h
-//  Phantasma
-//
-//  Created by Thomas Harte on 08/12/2013.
-//  Copyright (c) 2013 Thomas Harte. All rights reserved.
-//
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+// Based on Phantasma code by Thomas Harte (2013)
 
 #ifndef FREESCAPE_TOKEN_H
 #define FREESCAPE_TOKEN_H
@@ -96,14 +111,8 @@ public:
 		value = 0;
 	}
 
-	//Token(Common::String &string);
-	//Token(Type type, int32_t value);
-	//Token(const Token &other);
-	//Token &operator=(const Token &rhs);
-
 private:
 	Type type;
-
 	int32 value;
 	Common::String string;
 };
diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
index 07b111c49a3..1cd01a97329 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/16bitBinaryLoader.cpp
@@ -1,23 +1,28 @@
-//
-//  16bitBinaryLoader.cpp
-//  Phantasma
-//
-//  Created by Thomas Harte on 17/12/2013.
-//  Copyright (c) 2013 Thomas Harte. All rights reserved.
-//
-
-//#include "freescape/language/parser.h"
-
-#include "common/array.h"
-#include "common/debug.h"
-#include "common/file.h"
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+// Based on Phantasma code by Thomas Harte (2013)
 
 #include "freescape/freescape.h"
-#include "freescape/area.h"
 #include "freescape/language/16bitDetokeniser.h"
-#include "freescape/language/instruction.h"
-#include "freescape/objects/geometricobject.h"
-#include "freescape/objects/object.h"
 
 namespace Freescape {
 
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 3bb6b39aa0c..6b5c3ac2c66 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -1,17 +1,31 @@
-#include "common/array.h"
-#include "common/debug.h"
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+// Based on Phantasma code by Thomas Harte (2013)
+
 #include "common/file.h"
 #include "image/bmp.h"
 
 #include "freescape/freescape.h"
-#include "freescape/area.h"
-
 #include "freescape/language/8bitDetokeniser.h"
-#include "freescape/language/instruction.h"
-
-#include "freescape/objects/object.h"
-#include "freescape/objects/geometricobject.h"
-#include "freescape/objects/entrance.h"
 #include "freescape/objects/sensor.h"
 
 namespace Freescape {
diff --git a/engines/freescape/metaengine.cpp b/engines/freescape/metaengine.cpp
index 9981b9ce560..6d183c8762b 100644
--- a/engines/freescape/metaengine.cpp
+++ b/engines/freescape/metaengine.cpp
@@ -1,3 +1,24 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
 #include "engines/advancedDetector.h"
 #include "freescape/freescape.h"
 
diff --git a/engines/freescape/objects/entrance.cpp b/engines/freescape/objects/entrance.cpp
index 306d77b1990..032d35a2f03 100644
--- a/engines/freescape/objects/entrance.cpp
+++ b/engines/freescape/objects/entrance.cpp
@@ -1,16 +1,28 @@
-//
-//  Entrance.cpp
-//  Phantasma
-//
-//  Created by Thomas Harte on 25/12/2013.
-//  Copyright (c) 2013 Thomas Harte. All rights reserved.
-//
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+// Based on Phantasma code by Thomas Harte (2013)
 
 #include "freescape/objects/entrance.h"
 
-#pragma mark -
-#pragma mark Construction/Destruction
-
 namespace Freescape {
 
 RoomStructure::RoomStructure(const Common::Array<byte> _structure) {
diff --git a/engines/freescape/objects/entrance.h b/engines/freescape/objects/entrance.h
index 3fa99e73e31..ab6c8af1ac4 100644
--- a/engines/freescape/objects/entrance.h
+++ b/engines/freescape/objects/entrance.h
@@ -1,10 +1,25 @@
-//
-//  Entrance.h
-//  Phantasma
-//
-//  Created by Thomas Harte on 25/12/2013.
-//  Copyright (c) 2013 Thomas Harte. All rights reserved.
-//
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+// Based on Phantasma code by Thomas Harte (2013)
 
 #ifndef FREESCAPE_ENTRANCE_H
 #define FREESCAPE_ENTRANCE_H
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index 6e4fee529bc..7f0d8cc9246 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -1,16 +1,27 @@
-//
-//  GeometricObject.cpp
-//  Phantasma
-//
-//  Created by Thomas Harte on 25/12/2013.
-//  Copyright (c) 2013 Thomas Harte. All rights reserved.
-//
-
-#include "common/str.h"
-#include "freescape/objects/geometricobject.h"
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+// Based on Phantasma code by Thomas Harte (2013)
 
-#pragma mark -
-#pragma mark Static Getters
+#include "freescape/objects/geometricobject.h"
 
 namespace Freescape {
 
diff --git a/engines/freescape/objects/geometricobject.h b/engines/freescape/objects/geometricobject.h
index 2c688ad6a48..fcee884cb52 100644
--- a/engines/freescape/objects/geometricobject.h
+++ b/engines/freescape/objects/geometricobject.h
@@ -1,15 +1,29 @@
-//
-//  GeometricObject.h
-//  Phantasma
-//
-//  Created by Thomas Harte on 25/12/2013.
-//  Copyright (c) 2013 Thomas Harte. All rights reserved.
-//
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+// Based on Phantasma code by Thomas Harte (2013)
 
 #ifndef FREESCAPE_GEOMETRICOBJECT_H
 #define FREESCAPE_GEOMETRICOBJECT_H
 
-#include "common/array.h"
 #include "freescape/language/instruction.h"
 #include "freescape/objects/object.h"
 
diff --git a/engines/freescape/objects/object.cpp b/engines/freescape/objects/object.cpp
index 83a5b4493bf..964fdcbdd2a 100644
--- a/engines/freescape/objects/object.cpp
+++ b/engines/freescape/objects/object.cpp
@@ -1,14 +1,27 @@
-//
-//  Object.cpp
-//  Phantasma
-//
-//  Created by Thomas Harte on 18/12/2013.
-//  Copyright (c) 2013 Thomas Harte. All rights reserved.
-//
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+// Based on Phantasma code by Thomas Harte (2013)
 
 #include "freescape/objects/object.h"
-#include "freescape/freescape.h"
-#include "freescape/gfx.h"
 
 namespace Freescape {
 
diff --git a/engines/freescape/objects/object.h b/engines/freescape/objects/object.h
index 00619237517..7ebc3fe714c 100644
--- a/engines/freescape/objects/object.h
+++ b/engines/freescape/objects/object.h
@@ -1,15 +1,29 @@
-//
-//  Object.h
-//  Phantasma
-//
-//  Created by Thomas Harte on 18/12/2013.
-//  Copyright (c) 2013 Thomas Harte. All rights reserved.
-//
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+// Based on Phantasma code by Thomas Harte (2013)
 
 #ifndef FREESCAPE_OBJECT_H
 #define FREESCAPE_OBJECT_H
 
-#include "common/system.h"
 #include "math/vector3d.h"
 #include "math/aabb.h"
 
diff --git a/engines/freescape/objects/sensor.cpp b/engines/freescape/objects/sensor.cpp
index 9052649d714..0bc86bf29f4 100644
--- a/engines/freescape/objects/sensor.cpp
+++ b/engines/freescape/objects/sensor.cpp
@@ -1,3 +1,26 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+// Based on Phantasma code by Thomas Harte (2013)
+
 #include "freescape/objects/sensor.h"
 
 namespace Freescape {
diff --git a/engines/freescape/objects/sensor.h b/engines/freescape/objects/sensor.h
index a56c86b34e3..2f9dd1bf86f 100644
--- a/engines/freescape/objects/sensor.h
+++ b/engines/freescape/objects/sensor.h
@@ -1,3 +1,26 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+// Based on Phantasma code by Thomas Harte (2013)
+
 #ifndef FREESCAPE_SENSOR_H
 #define FREESCAPE_SENSOR_H
 
diff --git a/engines/freescape/palettes.cpp b/engines/freescape/palettes.cpp
index 99b163c6096..a38ef6763d3 100644
--- a/engines/freescape/palettes.cpp
+++ b/engines/freescape/palettes.cpp
@@ -1,3 +1,24 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
 #include "freescape/freescape.h"
 
 namespace Freescape {
@@ -95,4 +116,4 @@ Graphics::PixelBuffer *FreescapeEngine::getPalette(uint8 areaNumber, uint8 c1, u
 	return palette;
 }
 
-}
\ No newline at end of file
+} // End of namespace Freescape
\ No newline at end of file


Commit: 5115cc1f68c59af76b80edaf06045d6f6d846c4a
    https://github.com/scummvm/scummvm/commit/5115cc1f68c59af76b80edaf06045d6f6d846c4a
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:04+01:00

Commit Message:
FREESCAPE: allow to rise or lower player height in driller

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 8cbd1715914..68d648ef0b2 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -50,6 +50,7 @@ FreescapeEngine::FreescapeEngine(OSystem *syst)
 	_movementSpeed = 1.5f;
 	_mouseSensitivity = 0.1f;
 	_flyMode = false;
+	_playerHeightNumber = 1;
 	_borderTexture = nullptr;
 	_viewArea = Common::Rect(0, 0, _screenW, _screenH);
 
@@ -214,10 +215,10 @@ void FreescapeEngine::processInput() {
 				move(RIGHT, _scaleVector.y(), deltaTime);
 			else if (event.kbd.keycode == Common::KEYCODE_KP5 || event.kbd.keycode == Common::KEYCODE_KP0)
 				shoot();
+			else if (event.kbd.keycode == Common::KEYCODE_r)
+				rise();
 			else if (event.kbd.keycode == Common::KEYCODE_f)
-				_position.setValue(1, _position.y() + 12);
-			else if (event.kbd.keycode == Common::KEYCODE_v)
-				_position.setValue(1, _position.y() - 12);
+				lower();
 			else if (event.kbd.keycode == Common::KEYCODE_n)
 				gotoArea(_currentArea->getAreaID() + 1, 0);
 			else if (event.kbd.keycode == Common::KEYCODE_d) {
@@ -393,6 +394,67 @@ void FreescapeEngine::rotate(Common::Point lastMousePos, Common::Point mousePos)
 	_cameraRight = v;
 }
 
+void FreescapeEngine::changePlayerHeight(int delta) {
+	int scale = _currentArea->getScale();
+	_position.setValue(1, _position.y() - scale * _playerHeight);
+	_playerHeight = _playerHeight + delta;
+	_position.setValue(1, _position.y() + scale * _playerHeight);
+}
+
+void FreescapeEngine::rise() {
+	int previousAreaID = _currentArea->getAreaID();
+	int scale = _currentArea->getScale();
+
+	if (_flyMode) {
+		_position.setValue(1, _position.y() + scale * 32);
+	} else {
+		if (_playerHeightNumber == 10) // TODO
+			return;
+
+		_playerHeightNumber++;
+		changePlayerHeight(16);
+	}
+
+	bool collided = checkCollisions(true);
+	if (collided) {
+		if (_currentArea->getAreaID() == previousAreaID) {
+			if (_flyMode)
+				_position = _lastPosition;
+			else {
+				changePlayerHeight(-16);
+			}
+		}
+	}
+
+	_lastPosition = _position;
+	debugC(1, kFreescapeDebugMove, "new player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
+}
+
+void FreescapeEngine::lower() {
+	int previousAreaID = _currentArea->getAreaID();
+	int scale = _currentArea->getScale();
+
+	if (_flyMode) {
+		_position.setValue(1, _position.y() - scale * 32);
+		bool collided = checkCollisions(true);
+		if (collided) {
+			if (_currentArea->getAreaID() == previousAreaID) {
+				_position = _lastPosition;
+			}
+		}
+	} else {
+		if (_playerHeightNumber == 0)
+			return;
+
+		_playerHeightNumber--;
+		changePlayerHeight(-16);
+	}
+
+	_lastPosition = _position;
+	debugC(1, kFreescapeDebugMove, "new player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
+}
+
+
 void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTime) {
 	debugC(1, kFreescapeDebugMove, "old player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
 	int previousAreaID = _currentArea->getAreaID();
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 3c8177f58e9..1a4fed2224e 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -106,6 +106,9 @@ public:
 	bool _flyMode;
 	void processInput();
 	void move(CameraMovement direction, uint8 scale, float deltaTime);
+	void changePlayerHeight(int delta);
+	void rise();
+	void lower();
 	bool checkFloor(Math::Vector3d currentPosition);
 	bool tryStepUp(Math::Vector3d currentPosition);
 	bool tryStepDown(Math::Vector3d currentPosition);
@@ -130,6 +133,7 @@ public:
 	// Spacial attributes
 	Math::Vector3d _position, _rotation, _velocity;
 	Math::Vector3d _lastPosition;
+	int _playerHeightNumber;
 	uint16 _playerHeight;
 	uint16 _playerWidth;
 	uint16 _playerDepth;


Commit: a42b93078effd86c33e5d9091df375c4e8e6e5fa
    https://github.com/scummvm/scummvm/commit/a42b93078effd86c33e5d9091df375c4e8e6e5fa
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:04+01:00

Commit Message:
FREESCAPE: fix mouselook in fullscreen

Changed paths:
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 68d648ef0b2..66a6f8ada76 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -24,6 +24,7 @@
 #include "common/file.h"
 #include "common/math.h"
 #include "common/memstream.h"
+#include "graphics/cursorman.h"
 
 #include "freescape/freescape.h"
 #include "freescape/language/8bitDetokeniser.h"
@@ -35,7 +36,7 @@ FreescapeEngine *g_freescape = NULL;
 FreescapeEngine::FreescapeEngine(OSystem *syst)
 	: Engine(syst), _screenW(320), _screenH(200), _border(nullptr), _gfx(nullptr) {
 	g_freescape = this;
-	if (!ConfMan.hasKey("render_mode"))
+	if (!ConfMan.hasKey("render_mode") || ConfMan.get("render_mode").empty())
 		_renderMode = "ega";
 	else
 		_renderMode = ConfMan.get("render_mode");
@@ -48,7 +49,7 @@ FreescapeEngine::FreescapeEngine(OSystem *syst)
 	_cameraFront = Math::Vector3d(0.f, 0.f, 0.f);
 	_cameraRight = Math::Vector3d(0.f, 0.f, 0.f);
 	_movementSpeed = 1.5f;
-	_mouseSensitivity = 0.1f;
+	_mouseSensitivity = 0.25f;
 	_flyMode = false;
 	_playerHeightNumber = 1;
 	_borderTexture = nullptr;
@@ -255,17 +256,31 @@ void FreescapeEngine::processInput() {
 			break;
 
 		case Common::EVENT_MOUSEMOVE:
-			rotate(_lastMousePos, mousePos);
-			_lastMousePos = mousePos;
 			if (mousePos.x <= 5 || mousePos.x >= _screenW - 5) {
 				g_system->warpMouse(_screenW / 2, mousePos.y);
+
 				_lastMousePos.x = _screenW / 2;
 				_lastMousePos.y = mousePos.y;
+				if (mousePos.x <= 5)
+					mousePos.x = _lastMousePos.x + 3;
+				else
+					mousePos.x = _lastMousePos.x - 3;
+
+				mousePos.y = _lastMousePos.y;
+
 			} else if (mousePos.y <= 5 || mousePos.y >= _screenH - 5) {
 				g_system->warpMouse(mousePos.x, _screenH / 2);
 				_lastMousePos.x = mousePos.x;
 				_lastMousePos.y = _screenH / 2;
+				if (mousePos.y <= 5)
+					mousePos.y = _lastMousePos.y + 3;
+				else
+					mousePos.y = _lastMousePos.y - 3;
+
+				mousePos.x = _lastMousePos.x;
 			}
+			rotate(_lastMousePos, mousePos);
+			_lastMousePos = mousePos;
 			break;
 
 		case Common::EVENT_LBUTTONDOWN:
@@ -344,6 +359,7 @@ Common::Error FreescapeEngine::run() {
 		gotoArea(_startArea, _startEntrance);
 
 	debugC(1, kFreescapeDebugMove, "Starting area %d", _currentArea->getAreaID());
+	_system->lockMouse(true);
 	while (!shouldQuit()) {
 		drawFrame();
 		processInput();


Commit: 6e04dc224e393e6b47323bb3cebd0170c3d7c8ac
    https://github.com/scummvm/scummvm/commit/6e04dc224e393e6b47323bb3cebd0170c3d7c8ac
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:05+01:00

Commit Message:
FREESCAPE: correctly render up-pyramids

Changed paths:
    engines/freescape/gfx_tinygl.cpp


diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 2960af3f255..0bdfed6840a 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -387,11 +387,11 @@ void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vec
 	if ((*colours)[0] != _keyColor) {
 		_palette->getRGBAt((*colours)[0], r, g, b);
 		tglColor3ub(r, g, b);
-
-		face.push_back(vertices[5]);
 		face.push_back(vertices[6]);
+		face.push_back(vertices[7]);
+		face.push_back(vertices[3]);
 		face.push_back(vertices[2]);
-		face.push_back(vertices[1]);
+
 		renderFace(face);
 		face.clear();
 	}
@@ -424,10 +424,10 @@ void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vec
 		_palette->getRGBAt((*colours)[3], r, g, b);
 		tglColor3ub(r, g, b);
 
+		face.push_back(vertices[5]);
 		face.push_back(vertices[6]);
-		face.push_back(vertices[7]);
-		face.push_back(vertices[3]);
 		face.push_back(vertices[2]);
+		face.push_back(vertices[1]);
 		renderFace(face);
 		face.clear();
 	}


Commit: a06b72736ea4ad59c6a2e493713924b03d5be452
    https://github.com/scummvm/scummvm/commit/a06b72736ea4ad59c6a2e493713924b03d5be452
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:05+01:00

Commit Message:
FREESCAPE: correctly initialize flags for sensors/entrance

Changed paths:
    engines/freescape/objects/entrance.cpp
    engines/freescape/objects/sensor.cpp


diff --git a/engines/freescape/objects/entrance.cpp b/engines/freescape/objects/entrance.cpp
index 032d35a2f03..a13b648bcf5 100644
--- a/engines/freescape/objects/entrance.cpp
+++ b/engines/freescape/objects/entrance.cpp
@@ -37,6 +37,7 @@ Entrance::Entrance(
 	_objectID = objectID;
 	origin = _origin;
 	_rotation = rotation;
+	_flags = 0;
 }
 
 Entrance::~Entrance() {}
diff --git a/engines/freescape/objects/sensor.cpp b/engines/freescape/objects/sensor.cpp
index 0bc86bf29f4..2901ec0c337 100644
--- a/engines/freescape/objects/sensor.cpp
+++ b/engines/freescape/objects/sensor.cpp
@@ -32,6 +32,7 @@ Sensor::Sensor(
 	_objectID = objectID;
 	origin = _origin;
 	_rotation = rotation;
+	_flags = 0;
 }
 
 Sensor::~Sensor() {}


Commit: da79f0f68595be3023bddac261f24656b887ca06
    https://github.com/scummvm/scummvm/commit/da79f0f68595be3023bddac261f24656b887ca06
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:05+01:00

Commit Message:
FREESCAPE: add room structure after all the areas are parsed

Changed paths:
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 6b5c3ac2c66..c05be003eeb 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -339,11 +339,6 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 		debugC(1, kFreescapeDebugParser, "%s", conditionSource->c_str());
 	}
 
-	if (_areaMap.contains(255))
-		area->addStructure(_areaMap[255]);
-	else if (isCastle() || isEclipse())
-		area->addStructure(nullptr);
-
 	debugC(1, kFreescapeDebugParser, "End of area at %lx", file->pos());
 	return area;
 }
@@ -441,6 +436,12 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 			break;
 		}
 	}
+
+	if (_areaMap.contains(255)) {
+		for (AreaMap::iterator iterator = _areaMap.begin(); iterator != _areaMap.end(); iterator++)
+			iterator->_value->addStructure(_areaMap[255]);
+	}
+
 	if (isEclipse() || isCastle()) {
 		_playerHeight = 48;
 		_playerWidth = 8;


Commit: 43e4a62dea80d742bc97c1c3d113ab42c4246226
    https://github.com/scummvm/scummvm/commit/43e4a62dea80d742bc97c1c3d113ab42c4246226
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:05+01:00

Commit Message:
FREESCAPE: skip intro screen when loading

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index ff4643bcf89..7f885c9c273 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -44,10 +44,6 @@ Object *Area::entranceWithID(uint16 objectID) {
 	return objectWithIDFromMap(entrancesByID, objectID);
 }
 
-Object *Area::firstEntrance() {
-	return entrancesByID->begin()->_value;
-}
-
 uint16 Area::getAreaID() {
 	return areaID;
 }
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index 0886195e245..91673c4b6df 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -50,7 +50,6 @@ public:
 	Common::String name;
 	Object *objectWithID(uint16 objectID);
 	Object *entranceWithID(uint16 objectID);
-	Object *firstEntrance();
 	uint16 getAreaID();
 	uint16 getAreaFlags();
 	uint8 getScale();
@@ -71,7 +70,6 @@ public:
 	// Driller specific
 	void addDrill(Area *structure, const Math::Vector3d position);
 	void removeDrill();
-
 	bool drillDeployed();
 	Math::Vector3d drillPosition;
 	Common::Point gasPocketPosition;
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 66a6f8ada76..e8eff85fe05 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -334,13 +334,16 @@ Common::Error FreescapeEngine::run() {
 	} else {
 		_farClipPlane = 8192.f;
 	}
+	int saveSlot = ConfMan.getInt("save_slot");
 
 	if (_border) {
-		drawBorder();
-		_gfx->flipBuffer();
-		g_system->updateScreen();
-		if (isDriller())
-			g_system->delayMillis(1000);
+		if (saveSlot == -1) {
+			drawBorder();
+			_gfx->flipBuffer();
+			g_system->updateScreen();
+			if (isDriller())
+				g_system->delayMillis(1000);
+		}
 
 		_borderTexture = nullptr;
 		if (isDriller())
@@ -352,7 +355,6 @@ Common::Error FreescapeEngine::run() {
 
 		_border->fillRect(_viewArea, 0xA0A0A0FF);
 	}
-	int saveSlot = ConfMan.getInt("save_slot");
 	if (saveSlot >= 0) { // load the savegame
 		loadGameState(saveSlot);
 	} else


Commit: d4e26ef512b6b0f0b003d644accd73f3a79306be
    https://github.com/scummvm/scummvm/commit/d4e26ef512b6b0f0b003d644accd73f3a79306be
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:05+01:00

Commit Message:
FREESCAPE: fixed most of the c++ compiler warnings

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/loaders/16bitBinaryLoader.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 7f885c9c273..4bfe380730e 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -131,7 +131,6 @@ void Area::loadObjectFlags(Common::SeekableReadStream *stream) {
 }
 
 void Area::saveObjectFlags(Common::WriteStream *stream) {
-	int dirtyFlags = 0;
 	stream->writeFloatLE(drillPosition.x());
 	stream->writeFloatLE(drillPosition.y());
 	stream->writeFloatLE(drillPosition.z());
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 0bdfed6840a..17681fadf1d 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -193,7 +193,7 @@ void TinyGLRenderer::renderFace(const Common::Array<Math::Vector3d> &vertices) {
 	}
 
 	tglBegin(TGL_TRIANGLES);
-	for (int i = 1; i < vertices.size() - 1; i++) {
+	for (int i = 1; i < int(vertices.size()) - 1; i++) {
 		const Math::Vector3d &v1 = vertices[i];
 		const Math::Vector3d &v2 = vertices[i+1];
 		tglVertex3f(v0.x(), v0.y(),	v0.z());
@@ -216,7 +216,7 @@ void TinyGLRenderer::renderPolygon(const Math::Vector3d &origin, const Math::Vec
 	if (ordinates->size() == 6) { // Line
 		_palette->getRGBAt((*colours)[0], r, g, b);
 		tglColor3ub(r, g, b);
-		for (int i = 0; i < ordinates->size(); i = i + 3)
+		for (int i = 0; i < int(ordinates->size()); i = i + 3)
 			vertices.push_back(Math::Vector3d((*ordinates)[i], (*ordinates)[i + 1],	(*ordinates)[i + 2]));
 		renderFace(vertices);
 
@@ -231,7 +231,7 @@ void TinyGLRenderer::renderPolygon(const Math::Vector3d &origin, const Math::Vec
 		if ((*colours)[0] != _keyColor) {
 			_palette->getRGBAt((*colours)[0], r, g, b);
 			tglColor3ub(r, g, b);
-			for (int i = 0; i < ordinates->size(); i = i + 3) {
+			for (int i = 0; i < int(ordinates->size()); i = i + 3) {
 				vertices.push_back(Math::Vector3d((*ordinates)[i], (*ordinates)[i + 1], (*ordinates)[i + 2]));
 			}
 			renderFace(vertices);
diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
index 1cd01a97329..ac01b6e57ec 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/16bitBinaryLoader.cpp
@@ -81,10 +81,10 @@ static Object *load16bitObject(Common::SeekableReadStream *file) {
 			byteSizeOfObject--;
 			uint8 c2 = file->readByte();
 			byteSizeOfObject--;
-			colours->push_back( (c1 & 0x0f) | ((c2 & 0x0f) << 4));
+			colours->push_back((c1 & 0x0f) | ((c2 & 0x0f) << 4));
 			debug("color[%d] = %d", 2*colour, (c1 & 0x0f) | ((c2 & 0x0f) << 4));
-			colours->push_back(c1 >> 4 | c2 & 0xf0);
-			debug("color[%d] = %d", 2*colour+1, c1 >> 4 | c2 & 0xf0);
+			colours->push_back((c1 >> 4) | (c2 & 0xf0));
+			debug("color[%d] = %d", 2*colour+1, (c1 >> 4) | (c2 & 0xf0));
 		}
 
 		// read extra vertices if required...
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index c05be003eeb..fa11947276b 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -231,6 +231,8 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 
 	uint8 ci1 = 0;
 	uint8 ci2 = 0;
+	uint8 ci3 = 0;
+	uint8 ci4 = 0;
 	uint8 skyColor = areaFlags & 15;
 	uint8 groundColor = areaFlags >> 4;
 
@@ -239,11 +241,11 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	if (skyColor == 0)
 		skyColor = 255;
 
-	file->readByte() & 15;
-	file->readByte() & 15;
-	ci1 = file->readByte();
-	ci2 = file->readByte();
-	debugC(1, kFreescapeDebugParser, "Colors: %d %d %d %d", ci1, ci2, skyColor, groundColor);
+	ci1 = file->readByte() & 15;
+	ci2 = file->readByte() & 15;
+	ci3 = file->readByte();
+	ci4 = file->readByte();
+	debugC(1, kFreescapeDebugParser, "Colors: %d %d %d %d %d %d", ci1, ci2, ci3, ci4, skyColor, groundColor);
 	// CPC
 	//groundColor = file->readByte() & 15;
 	//skyColor = file->readByte() & 15;


Commit: d27837140ddbf53f0fb951ff0a07bef87fc269e3
    https://github.com/scummvm/scummvm/commit/d27837140ddbf53f0fb951ff0a07bef87fc269e3
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:05+01:00

Commit Message:
FREESCAPE: handle some of the special eclipse entrances

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index e8eff85fe05..f629442f827 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -33,6 +33,32 @@ namespace Freescape {
 
 FreescapeEngine *g_freescape = NULL;
 
+static const entrancesTableEntry rawEntranceTable[] = {
+	{183, {36, 137, 13}}, // Correct?
+	{184, {36, 137, 13}}, // TODO
+	{185, {36, 137, 13}}, // TODO
+	{186, {36, 137, 13}}, // TODO
+	{187, {36, 137, 13}}, // TODO
+	{188, {36, 137, 13}}, // TODO
+	{190, {36, 137, 13}}, // TODO
+	{191, {36, 137, 13}}, // TODO
+	{192, {36, 137, 13}}, // TODO
+	{193, {36, 137, 13}}, // TODO
+	{194, {36, 137, 13}}, // TODO
+	{195, {36, 137, 13}}, // TODO
+	{196, {36, 137, 13}}, // TODO
+	{197, {203, 0, 31}},  // TODO
+	{198, {36, 137, 13}}, // TODO
+	{199, {36, 137, 13}}, // TODO
+	{200, {36, 137, 13}}, // TODO
+	{201, {36, 137, 13}}, // TODO
+	{202, {360, 0, 373}}, // TODO
+	{203, {207, 0, 384}},
+	{204, {207, 0, 372}},
+	{206, {36, 137, 13}}, // TODO
+	{0, {0, 0, 0}},        // NULL
+};
+
 FreescapeEngine::FreescapeEngine(OSystem *syst)
 	: Engine(syst), _screenW(320), _screenH(200), _border(nullptr), _gfx(nullptr) {
 	g_freescape = this;
@@ -55,6 +81,13 @@ FreescapeEngine::FreescapeEngine(OSystem *syst)
 	_borderTexture = nullptr;
 	_viewArea = Common::Rect(0, 0, _screenW, _screenH);
 
+	// Total Eclipse specific
+	const entrancesTableEntry *entry = rawEntranceTable;
+	while (entry->id) {
+		_entranceTable[entry->id] = entry;
+		entry++;
+	}
+
 	_rnd = new Common::RandomSource("freescape");
 }
 
@@ -536,8 +569,11 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 			}
 		}
 	}
+	areaScale = _currentArea->getScale();
+
 	_lastPosition = _position;
 	debugC(1, kFreescapeDebugMove, "new player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
+	debugC(1, kFreescapeDebugMove, "player height: %f", _position.y() - areaScale * _playerHeight);
 }
 
 bool FreescapeEngine::checkFloor(Math::Vector3d currentPosition) {
@@ -614,9 +650,14 @@ void FreescapeEngine::gotoArea(uint16 areaID, int entranceID) {
 	Entrance *entrance = nullptr;
 	if (entranceID > 0) {
 		entrance = (Entrance*) _currentArea->entranceWithID(entranceID);
-		assert(entrance);
 
-		_position = entrance->getOrigin();
+		if (!entrance) {
+			assert(_entranceTable.contains(entranceID));
+			const entrancesTableEntry *entry = _entranceTable[entranceID];
+			_position = scale * Math::Vector3d(entry->position[0], entry->position[1], entry->position[2]);
+		} else
+			_position = entrance->getOrigin();
+
 		if (_rotation == Math::Vector3d(0, 0, 0)) {
 			_rotation = entrance->getRotation();
 			_pitch = _rotation.x();
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 1a4fed2224e..efad40233e5 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -57,6 +57,11 @@ enum {
 	kFreescapeDebugCode = 1 << 2
 };
 
+struct entrancesTableEntry {
+	int id;
+	int position[3];
+};
+
 class FreescapeEngine : public Engine {
 private:
 	// We need random numbers
@@ -101,6 +106,7 @@ public:
 	void gotoArea(uint16 areaID, int entranceID);
 	// Entrance
 	uint16 _startEntrance;
+	Common::HashMap<int, const struct entrancesTableEntry*> _entranceTable;
 
 	// Input
 	bool _flyMode;


Commit: a0b69a148efc035d50b6cf89cc8f78b57ee226c3
    https://github.com/scummvm/scummvm/commit/a0b69a148efc035d50b6cf89cc8f78b57ee226c3
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:06+01:00

Commit Message:
FREESCAPE: implemented shield and energy UI in driller

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/gfx_tinygl.h
    engines/freescape/language/8bitDetokeniser.h
    engines/freescape/language/instruction.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index f629442f827..626136d8ff2 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -79,7 +79,8 @@ FreescapeEngine::FreescapeEngine(OSystem *syst)
 	_flyMode = false;
 	_playerHeightNumber = 1;
 	_borderTexture = nullptr;
-	_viewArea = Common::Rect(0, 0, _screenW, _screenH);
+	_fullscreenViewArea = Common::Rect(0, 0, _screenW, _screenH);
+	_viewArea = _fullscreenViewArea;
 
 	// Total Eclipse specific
 	const entrancesTableEntry *entry = rawEntranceTable;
@@ -101,12 +102,10 @@ void FreescapeEngine::drawBorder() {
 	if (!_border)
 		return;
 
-	const Common::Rect fullscreenViewArea(0, 0, _screenW, _screenH);
-	_gfx->setViewport(fullscreenViewArea);
-
+	_gfx->setViewport(_fullscreenViewArea);
 	if (!_borderTexture)
 		_borderTexture = _gfx->createTexture(_border);
-	_gfx->drawTexturedRect2D(fullscreenViewArea, fullscreenViewArea, _borderTexture);
+	_gfx->drawTexturedRect2D(_fullscreenViewArea, _fullscreenViewArea, _borderTexture);
 	_gfx->setViewport(_viewArea);
 }
 
@@ -221,12 +220,42 @@ Math::Vector3d FreescapeEngine::directionToVector(float pitch, float heading) {
 	return v;
 }
 
+void FreescapeEngine::drawUI() {
+	_gfx->setViewport(_fullscreenViewArea);
+
+	if (isDriller()) {
+		int energy = _gameStateVars[k8bitVariableEnergy];
+		int shield = _gameStateVars[k8bitVariableShield];
+		if (_renderMode == "ega" && _border) {
+			//Common::Rect black(20, 177, 87, 191);
+			//_gfx->drawRect2D(black, 255, 0, 0, 0);
+
+			if (energy >= 0) {
+				Common::Rect black(20, 186, 87 - energy, 191);
+				_gfx->drawRect2D(black, 255, 0, 0, 0);
+				Common::Rect energyBar(87 - energy, 186, 87, 191);
+				_gfx->drawRect2D(energyBar, 255, 0xfc, 0xfc, 0x54);
+			}
+
+			if (shield >= 0) {
+				Common::Rect black(20, 178, 87 - shield, 183);
+				_gfx->drawRect2D(black, 255, 0, 0, 0);
+
+				Common::Rect shieldBar(87 - shield, 178, 87, 183);
+				_gfx->drawRect2D(shieldBar, 255, 0xfc, 0xfc, 0x54);
+			}
+		}
+	}
+}
+
+
 void FreescapeEngine::drawFrame() {
 	_gfx->updateProjectionMatrix(60.0, _nearClipPlane, _farClipPlane);
 	_gfx->positionCamera(_position, _position + _cameraFront);
 	_currentArea->draw(_gfx);
 	_gfx->renderCrossair(0);
 	drawBorder();
+	drawUI();
 }
 
 void FreescapeEngine::processInput() {
@@ -413,8 +442,8 @@ void FreescapeEngine::initGameState() {
 	for (AreaMap::iterator it = _areaMap.begin(); it != _areaMap.end(); ++it)
 		_gameStateBits[it->_key] = 0;
 
-	_gameStateVars[k8bitVariableEnergy] = 100;
-	_gameStateVars[k8bitVariableShield] = 100;
+	_gameStateVars[k8bitVariableEnergy] = 43;
+	_gameStateVars[k8bitVariableShield] = 48;
 }
 
 void FreescapeEngine::rotate(Common::Point lastMousePos, Common::Point mousePos) {
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index efad40233e5..3a02a5f1a97 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -79,10 +79,13 @@ public:
 
 	Common::Error run() override;
 
-	// Border
+	// UI
 	Common::Rect _viewArea;
+	Common::Rect _fullscreenViewArea;
+
 	void convertBorder();
 	void drawBorder();
+	void drawUI();
 	Texture *_borderTexture;
 
 	// Parsing
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index bc1c3f518f6..05aa2063af4 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -85,6 +85,7 @@ public:
 	virtual Texture *createTexture(const Graphics::Surface *surface) = 0;
 	virtual void freeTexture(Texture *texture) = 0;
 	virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture) = 0;
+	virtual void drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint8 g, uint8 b) = 0;
 
 	virtual void renderCrossair(byte color) = 0;
 	virtual void renderShoot(byte color) = 0;
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 17681fadf1d..f93a31e73af 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -116,6 +116,25 @@ void TinyGLRenderer::positionCamera(const Math::Vector3d &pos, const Math::Vecto
 	tglTranslatef(-pos.x(), -pos.y(), -pos.z());
 }
 
+void TinyGLRenderer::drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint8 g, uint8 b) {
+	tglDisable(TGL_TEXTURE_2D);
+	tglColor4ub(r, g, b, a);
+
+	if (a != 255) {
+		tglEnable(TGL_BLEND);
+		tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE_MINUS_SRC_ALPHA);
+	}
+
+	tglBegin(TGL_TRIANGLE_STRIP);
+		tglVertex3f(rect.left, rect.bottom, 0.0f);
+		tglVertex3f(rect.right, rect.bottom, 0.0f);
+		tglVertex3f(rect.left, rect.top, 0.0f);
+		tglVertex3f(rect.right, rect.top, 0.0f);
+	tglEnd();
+
+	tglDisable(TGL_BLEND);
+}
+
 void TinyGLRenderer::renderCrossair(byte color) {
 	uint8 r, g, b;
 	_palette->getRGBAt(color, r, g, b);
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index 049f0f9cf84..bcc1bb0ba7d 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -43,6 +43,7 @@ public:
 	Texture *createTexture(const Graphics::Surface *surface) override;
 	void freeTexture(Texture *texture) override;
 	virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture) override;
+	virtual void drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint8 g, uint8 b);
 
 	virtual void renderCrossair(byte color) override;
 	virtual void renderShoot(byte color) override;
diff --git a/engines/freescape/language/8bitDetokeniser.h b/engines/freescape/language/8bitDetokeniser.h
index 1d554be0411..218b835d88d 100644
--- a/engines/freescape/language/8bitDetokeniser.h
+++ b/engines/freescape/language/8bitDetokeniser.h
@@ -34,7 +34,12 @@ enum {
 	k8bitVariableScore = 61
 };
 
+
 static uint8 k8bitMaxVariable = 64;
+static uint8 k8bitMaxShield = 64;
+static uint8 k8bitMaxEnergy = 64;
+
+
 Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition, FCLInstructionVector &instructions);
 
 } // End of namespace Freescape
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index 5dcea924ae1..0d6eba8e826 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -216,10 +216,24 @@ void FreescapeEngine::executeIncrementVariable(FCLInstruction &instruction) {
 	uint16 variable = instruction.source;
 	uint16 increment = instruction.destination;
 	_gameStateVars[variable] = _gameStateVars[variable] + increment;
-	if (variable == k8bitVariableScore) {
+	switch (variable) {
+	case k8bitVariableScore:
 		debugC(1, kFreescapeDebugCode, "Score incremented by %d up to %d", increment, _gameStateVars[variable]);
-	} else
+	break;
+	case k8bitVariableEnergy:
+		if (_gameStateVars[variable] >= k8bitMaxEnergy)
+			_gameStateVars[variable] = k8bitMaxEnergy;
+		debugC(1, kFreescapeDebugCode, "Energy incremented by %d up to %d", increment, _gameStateVars[variable]);
+	break;
+	case k8bitVariableShield:
+		if (_gameStateVars[variable] >= k8bitMaxShield)
+			_gameStateVars[variable] = k8bitMaxShield;
+		debugC(1, kFreescapeDebugCode, "Shield incremented by %d up to %d", increment, _gameStateVars[variable]);
+	break;
+	default:
 		debugC(1, kFreescapeDebugCode, "Variable %d by %d incremented up to %d!", variable, increment, _gameStateVars[variable]);
+	break;
+	}
 }
 
 void FreescapeEngine::executeDecrementVariable(FCLInstruction &instruction) {


Commit: 4c7d22874b04aac4b7533e25ca95bbb1d0a65fec
    https://github.com/scummvm/scummvm/commit/4c7d22874b04aac4b7533e25ca95bbb1d0a65fec
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:06+01:00

Commit Message:
FREESCAPE: check if is energy is enough to deploy/return drill

Changed paths:
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 626136d8ff2..32497e08186 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -288,9 +288,14 @@ void FreescapeEngine::processInput() {
 				Common::Point gasPocket = _currentArea->gasPocketPosition;
 				uint32 gasPocketRadius = _currentArea->gasPocketRadius;
 				if (isDriller() && gasPocketRadius > 0 && !_currentArea->drillDeployed()) {
+					if (_gameStateVars[k8bitVariableEnergy] < 5) {
+						// Show "no enough energy" message
+						continue;
+					}
+
+					_gameStateVars[k8bitVariableEnergy] = _gameStateVars[k8bitVariableEnergy] - 5;
 					_gameStateVars[32]++;
 					// TODO: check if there is space for the drill
-					// TODO: check if there is enough energy
 					Math::Vector3d drillPosition = _position + _cameraFront * 128;
 					drillPosition.setValue(1, _position.y() - _playerHeight * _currentArea->getScale());
 					debugC(1, kFreescapeDebugMove, "Trying to adding drill at %f %f %f", drillPosition.x(), drillPosition.y(), drillPosition.z());
@@ -302,8 +307,14 @@ void FreescapeEngine::processInput() {
 					// TODO: reduce energy
 				}
 			} else if (event.kbd.keycode == Common::KEYCODE_c) {
-				// TODO: check if there is enough energy
+
 				if (isDriller() && _currentArea->drillDeployed()) {
+					if (_gameStateVars[k8bitVariableEnergy] < 5) {
+						// Show "no enough energy" message
+						continue;
+					}
+
+					_gameStateVars[k8bitVariableEnergy] = _gameStateVars[k8bitVariableEnergy] - 5;
 					_gameStateVars[32]--;
 					_currentArea->removeDrill();
 				}


Commit: 72331e5e36e68bb828490143aeb546b439c4a43e
    https://github.com/scummvm/scummvm/commit/72331e5e36e68bb828490143aeb546b439c4a43e
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:06+01:00

Commit Message:
FREESCAPE: improved ui given the current viewport

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/gfx_tinygl.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 32497e08186..74a953a127c 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -221,6 +221,7 @@ Math::Vector3d FreescapeEngine::directionToVector(float pitch, float heading) {
 }
 
 void FreescapeEngine::drawUI() {
+	_gfx->renderCrossair(0);
 	_gfx->setViewport(_fullscreenViewArea);
 
 	if (isDriller()) {
@@ -246,6 +247,7 @@ void FreescapeEngine::drawUI() {
 			}
 		}
 	}
+	_gfx->setViewport(_viewArea);
 }
 
 
@@ -253,7 +255,6 @@ void FreescapeEngine::drawFrame() {
 	_gfx->updateProjectionMatrix(60.0, _nearClipPlane, _farClipPlane);
 	_gfx->positionCamera(_position, _position + _cameraFront);
 	_currentArea->draw(_gfx);
-	_gfx->renderCrossair(0);
 	drawBorder();
 	drawUI();
 }
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index f93a31e73af..a76bff5f29c 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -150,12 +150,15 @@ void TinyGLRenderer::renderCrossair(byte color) {
 
 	tglColor3ub(r, g, b);
 
+	int viewPort[4];
+	tglGetIntegerv(TGL_VIEWPORT, viewPort);
+
 	tglBegin(TGL_LINES);
-	tglVertex2f(kOriginalWidth / 2 - 2, kOriginalHeight / 2);
-	tglVertex2f(kOriginalWidth / 2 + 3, kOriginalHeight / 2);
+	tglVertex2f(viewPort[0] + viewPort[2] / 2 - 2, (viewPort[1] + viewPort[3]) / 2);
+	tglVertex2f(viewPort[0] + viewPort[2] / 2 + 3, (viewPort[1] + viewPort[3]) / 2);
 
-	tglVertex2f(kOriginalWidth / 2, kOriginalHeight / 2 - 2);
-	tglVertex2f(kOriginalWidth / 2, kOriginalHeight / 2 + 3);
+	tglVertex2f(viewPort[0] + viewPort[2] / 2, (viewPort[1] + viewPort[3]) / 2 - 2);
+	tglVertex2f(viewPort[0] + viewPort[2] / 2, (viewPort[1] + viewPort[3]) / 2 + 3);
 	tglEnd();
 
 	tglDepthMask(TGL_TRUE);
@@ -177,18 +180,21 @@ void TinyGLRenderer::renderShoot(byte color) {
 
 	tglColor3ub(r, g, b);
 
+	int viewPort[4];
+	tglGetIntegerv(TGL_VIEWPORT, viewPort);
+
 	tglBegin(TGL_LINES);
-	tglVertex2f(0, kOriginalHeight - 2);
-	tglVertex2f(kOriginalWidth / 2, kOriginalHeight / 2);
+	tglVertex2f(0, viewPort[1] + viewPort[3] - 2);
+	tglVertex2f(viewPort[0] + viewPort[2] / 2, (viewPort[1] + viewPort[3]) / 2);
 
-	tglVertex2f(0, kOriginalHeight);
-	tglVertex2f(kOriginalWidth / 2, kOriginalHeight / 2);
+	tglVertex2f(0, viewPort[1] + viewPort[3]);
+	tglVertex2f(viewPort[0] + viewPort[2] / 2, (viewPort[1] + viewPort[3]) / 2);
 
-	tglVertex2f(kOriginalWidth, kOriginalHeight - 2);
-	tglVertex2f(kOriginalWidth / 2, kOriginalHeight / 2);
+	tglVertex2f(viewPort[0] + viewPort[2], viewPort[1] + viewPort[3] - 2);
+	tglVertex2f(viewPort[0] + viewPort[2] / 2, (viewPort[1] + viewPort[3]) / 2);
 
-	tglVertex2f(kOriginalWidth, kOriginalHeight);
-	tglVertex2f(kOriginalWidth / 2, kOriginalHeight / 2);
+	tglVertex2f(viewPort[0] + viewPort[2], viewPort[1] + viewPort[3]);
+	tglVertex2f(viewPort[0] + viewPort[2] / 2, (viewPort[1] + viewPort[3]) / 2);
 
 	tglEnd();
 


Commit: 1f212caa9266591245b15dcbe7bcacaf7a1a350f
    https://github.com/scummvm/scummvm/commit/1f212caa9266591245b15dcbe7bcacaf7a1a350f
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:06+01:00

Commit Message:
FREESCAPE: improved ui given the current viewport

Changed paths:
    engines/freescape/gfx_tinygl.cpp


diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index a76bff5f29c..d8bc7a76432 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -184,10 +184,10 @@ void TinyGLRenderer::renderShoot(byte color) {
 	tglGetIntegerv(TGL_VIEWPORT, viewPort);
 
 	tglBegin(TGL_LINES);
-	tglVertex2f(0, viewPort[1] + viewPort[3] - 2);
+	tglVertex2f(viewPort[0], viewPort[1] + viewPort[3] - 2);
 	tglVertex2f(viewPort[0] + viewPort[2] / 2, (viewPort[1] + viewPort[3]) / 2);
 
-	tglVertex2f(0, viewPort[1] + viewPort[3]);
+	tglVertex2f(viewPort[0], viewPort[1] + viewPort[3]);
 	tglVertex2f(viewPort[0] + viewPort[2] / 2, (viewPort[1] + viewPort[3]) / 2);
 
 	tglVertex2f(viewPort[0] + viewPort[2], viewPort[1] + viewPort[3] - 2);


Commit: c89a48d32757fad9c0f5aadba319d894ef543d97
    https://github.com/scummvm/scummvm/commit/c89a48d32757fad9c0f5aadba319d894ef543d97
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:06+01:00

Commit Message:
FREESCAPE: splited driller into a separated class

Changed paths:
  A engines/freescape/games/driller.cpp
    engines/freescape/freescape.h
    engines/freescape/metaengine.cpp
    engines/freescape/module.mk


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 3a02a5f1a97..96bb83f3879 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -204,6 +204,11 @@ public:
 	Common::Error saveGameStream(Common::WriteStream *stream, bool isAutosave = false) override;
 };
 
+class DrillerEngine : public FreescapeEngine {
+public:
+	DrillerEngine(OSystem *syst);
+};
+
 extern FreescapeEngine *g_freescape;
 
 } // namespace Freescape
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
new file mode 100644
index 00000000000..960e0462557
--- /dev/null
+++ b/engines/freescape/games/driller.cpp
@@ -0,0 +1,28 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "freescape/freescape.h"
+
+namespace Freescape {
+
+DrillerEngine::DrillerEngine(OSystem *syst) : FreescapeEngine(syst) {}
+
+}
\ No newline at end of file
diff --git a/engines/freescape/metaengine.cpp b/engines/freescape/metaengine.cpp
index 6d183c8762b..c53cf25bede 100644
--- a/engines/freescape/metaengine.cpp
+++ b/engines/freescape/metaengine.cpp
@@ -32,7 +32,11 @@ public:
 };
 
 Common::Error FreescapeMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
-	*engine = new Freescape::FreescapeEngine(syst);
+	if (Common::String(desc->gameId) == "driller" || Common::String(desc->gameId) == "spacestationoblivion") {
+		*engine = (Engine *)new Freescape::DrillerEngine(syst);
+	} else
+		*engine = new Freescape::FreescapeEngine(syst);
+
 	return Common::kNoError;
 }
 
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index 0c479c5a9f0..9987d96c1ca 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -4,6 +4,7 @@ MODULE_OBJS := \
 	metaengine.o \
 	freescape.o \
 	area.o \
+	games/driller.o \
 	gfx.o \
 	gfx_tinygl.o \
 	gfx_tinygl_texture.o \


Commit: d7adf4a6201ccca12675433e985972d24111328f
    https://github.com/scummvm/scummvm/commit/d7adf4a6201ccca12675433e985972d24111328f
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:06+01:00

Commit Message:
FREESCAPE: splited eclipse into a separated class

Changed paths:
  A engines/freescape/games/eclipse.cpp
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/driller.cpp
    engines/freescape/metaengine.cpp
    engines/freescape/module.mk


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 74a953a127c..69f393ebafb 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -33,32 +33,6 @@ namespace Freescape {
 
 FreescapeEngine *g_freescape = NULL;
 
-static const entrancesTableEntry rawEntranceTable[] = {
-	{183, {36, 137, 13}}, // Correct?
-	{184, {36, 137, 13}}, // TODO
-	{185, {36, 137, 13}}, // TODO
-	{186, {36, 137, 13}}, // TODO
-	{187, {36, 137, 13}}, // TODO
-	{188, {36, 137, 13}}, // TODO
-	{190, {36, 137, 13}}, // TODO
-	{191, {36, 137, 13}}, // TODO
-	{192, {36, 137, 13}}, // TODO
-	{193, {36, 137, 13}}, // TODO
-	{194, {36, 137, 13}}, // TODO
-	{195, {36, 137, 13}}, // TODO
-	{196, {36, 137, 13}}, // TODO
-	{197, {203, 0, 31}},  // TODO
-	{198, {36, 137, 13}}, // TODO
-	{199, {36, 137, 13}}, // TODO
-	{200, {36, 137, 13}}, // TODO
-	{201, {36, 137, 13}}, // TODO
-	{202, {360, 0, 373}}, // TODO
-	{203, {207, 0, 384}},
-	{204, {207, 0, 372}},
-	{206, {36, 137, 13}}, // TODO
-	{0, {0, 0, 0}},        // NULL
-};
-
 FreescapeEngine::FreescapeEngine(OSystem *syst)
 	: Engine(syst), _screenW(320), _screenH(200), _border(nullptr), _gfx(nullptr) {
 	g_freescape = this;
@@ -81,14 +55,6 @@ FreescapeEngine::FreescapeEngine(OSystem *syst)
 	_borderTexture = nullptr;
 	_fullscreenViewArea = Common::Rect(0, 0, _screenW, _screenH);
 	_viewArea = _fullscreenViewArea;
-
-	// Total Eclipse specific
-	const entrancesTableEntry *entry = rawEntranceTable;
-	while (entry->id) {
-		_entranceTable[entry->id] = entry;
-		entry++;
-	}
-
 	_rnd = new Common::RandomSource("freescape");
 }
 
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 96bb83f3879..3151f746cd9 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -209,6 +209,11 @@ public:
 	DrillerEngine(OSystem *syst);
 };
 
+class EclipseEngine : public FreescapeEngine {
+public:
+	EclipseEngine(OSystem *syst);
+};
+
 extern FreescapeEngine *g_freescape;
 
 } // namespace Freescape
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 960e0462557..04925c29cbe 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -25,4 +25,4 @@ namespace Freescape {
 
 DrillerEngine::DrillerEngine(OSystem *syst) : FreescapeEngine(syst) {}
 
-}
\ No newline at end of file
+} // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
new file mode 100644
index 00000000000..4df3e02f0db
--- /dev/null
+++ b/engines/freescape/games/eclipse.cpp
@@ -0,0 +1,60 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "freescape/freescape.h"
+
+namespace Freescape {
+
+static const entrancesTableEntry rawEntranceTable[] = {
+	{183, {36, 137, 13}}, // Correct?
+	{184, {36, 137, 13}}, // TODO
+	{185, {36, 137, 13}}, // TODO
+	{186, {36, 137, 13}}, // TODO
+	{187, {36, 137, 13}}, // TODO
+	{188, {36, 137, 13}}, // TODO
+	{190, {36, 137, 13}}, // TODO
+	{191, {36, 137, 13}}, // TODO
+	{192, {36, 137, 13}}, // TODO
+	{193, {36, 137, 13}}, // TODO
+	{194, {36, 137, 13}}, // TODO
+	{195, {36, 137, 13}}, // TODO
+	{196, {36, 137, 13}}, // TODO
+	{197, {203, 0, 31}},  // TODO
+	{198, {36, 137, 13}}, // TODO
+	{199, {36, 137, 13}}, // TODO
+	{200, {36, 137, 13}}, // TODO
+	{201, {36, 137, 13}}, // TODO
+	{202, {360, 0, 373}}, // TODO
+	{203, {207, 0, 384}},
+	{204, {207, 0, 372}},
+	{206, {36, 137, 13}}, // TODO
+	{0, {0, 0, 0}},        // NULL
+};
+
+EclipseEngine::EclipseEngine(OSystem *syst) : FreescapeEngine(syst) {
+	const entrancesTableEntry *entry = rawEntranceTable;
+	while (entry->id) {
+		_entranceTable[entry->id] = entry;
+		entry++;
+	}
+}
+
+} // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/metaengine.cpp b/engines/freescape/metaengine.cpp
index c53cf25bede..b69cad4c02f 100644
--- a/engines/freescape/metaengine.cpp
+++ b/engines/freescape/metaengine.cpp
@@ -34,6 +34,8 @@ public:
 Common::Error FreescapeMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
 	if (Common::String(desc->gameId) == "driller" || Common::String(desc->gameId) == "spacestationoblivion") {
 		*engine = (Engine *)new Freescape::DrillerEngine(syst);
+	} else 	if (Common::String(desc->gameId) == "totaleclipse") {
+		*engine = (Engine *)new Freescape::EclipseEngine(syst);
 	} else
 		*engine = new Freescape::FreescapeEngine(syst);
 
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index 9987d96c1ca..cf664406b71 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -5,6 +5,7 @@ MODULE_OBJS := \
 	freescape.o \
 	area.o \
 	games/driller.o \
+	games/eclipse.o \
 	gfx.o \
 	gfx_tinygl.o \
 	gfx_tinygl_texture.o \


Commit: 78e61e69853f1f1b2ce3cbdb5332be32940e01f0
    https://github.com/scummvm/scummvm/commit/78e61e69853f1f1b2ce3cbdb5332be32940e01f0
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:07+01:00

Commit Message:
FREESCAPE: load assets code for driller and eclipse in different files

Changed paths:
    engines/freescape/freescape.h
    engines/freescape/games/driller.cpp
    engines/freescape/games/eclipse.cpp


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 3151f746cd9..e5d4f896069 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -90,7 +90,7 @@ public:
 
 	// Parsing
 	uint8 _binaryBits;
-	void loadAssets();
+	virtual void loadAssets();
 	void load16bitBinary(Common::SeekableReadStream *file);
 
 	// 8-bits
@@ -207,11 +207,15 @@ public:
 class DrillerEngine : public FreescapeEngine {
 public:
 	DrillerEngine(OSystem *syst);
+
+	void loadAssets() override;
 };
 
 class EclipseEngine : public FreescapeEngine {
 public:
 	EclipseEngine(OSystem *syst);
+
+	void loadAssets() override;
 };
 
 extern FreescapeEngine *g_freescape;
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 04925c29cbe..cd88764e9ae 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -19,10 +19,36 @@
  *
  */
 
+#include "common/config-manager.h"
+#include "common/file.h"
+
 #include "freescape/freescape.h"
 
 namespace Freescape {
 
 DrillerEngine::DrillerEngine(OSystem *syst) : FreescapeEngine(syst) {}
 
+void DrillerEngine::loadAssets() {
+	Common::SeekableReadStream *file = nullptr;
+	Common::String path = ConfMan.get("path");
+	Common::FSDirectory gameDir(path);
+
+	Common::File exe;
+	if (_renderMode == "ega") {
+		file = gameDir.createReadStreamForMember("DRILLE.EXE");
+
+		if (file == nullptr)
+		    error("Failed to open DRILLE.EXE");
+
+		load8bitBinary(file, 0x9b40, 16);
+    } else if (_renderMode == "cga") {
+		file = gameDir.createReadStreamForMember("DRILLC.EXE");
+
+		if (file == nullptr)
+            error("Failed to open DRILLC.EXE");
+        load8bitBinary(file, 0x7bb0, 4);
+    } else
+        error("Invalid render mode %s for Driller", _renderMode.c_str());
+}
+
 } // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index 4df3e02f0db..0f9887edac0 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -19,6 +19,9 @@
  *
  */
 
+#include "common/config-manager.h"
+#include "common/file.h"
+
 #include "freescape/freescape.h"
 
 namespace Freescape {
@@ -57,4 +60,29 @@ EclipseEngine::EclipseEngine(OSystem *syst) : FreescapeEngine(syst) {
 	}
 }
 
+void EclipseEngine::loadAssets() {
+	Common::SeekableReadStream *file = nullptr;
+	Common::String path = ConfMan.get("path");
+	Common::FSDirectory gameDir(path);
+
+    Common::File exe;
+    if (_renderMode == "ega") {
+        file = gameDir.createReadStreamForMember("TOTEE.EXE");
+
+        if (file == nullptr)
+            error("Failed to open TOTEE.EXE");
+
+        load8bitBinary(file, 0x3ce0, 16);
+    } else if (_renderMode == "cga") {
+        file = gameDir.createReadStreamForMember("TOTEC.EXE");
+
+        if (file == nullptr)
+            error("Failed to open TOTEC.EXE");
+        load8bitBinary(file, 0x7bb0, 4); // TODO
+    } else
+        error("Invalid render mode %s for Total Eclipse", _renderMode.c_str());
+
+}
+
+
 } // End of namespace Freescape
\ No newline at end of file


Commit: 174a773802fa0caf0cda447f6ea7326fa17ef8f6
    https://github.com/scummvm/scummvm/commit/174a773802fa0caf0cda447f6ea7326fa17ef8f6
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:07+01:00

Commit Message:
FREESCAPE: splited castle into a separated class

Changed paths:
  A engines/freescape/games/castle.cpp
    engines/freescape/freescape.h
    engines/freescape/metaengine.cpp
    engines/freescape/module.mk


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index e5d4f896069..a90b1dbdb57 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -218,6 +218,13 @@ public:
 	void loadAssets() override;
 };
 
+class CastleEngine : public FreescapeEngine {
+public:
+	CastleEngine(OSystem *syst);
+
+	void loadAssets() override;
+};
+
 extern FreescapeEngine *g_freescape;
 
 } // namespace Freescape
diff --git a/engines/freescape/games/castle.cpp b/engines/freescape/games/castle.cpp
new file mode 100644
index 00000000000..0fa4888397d
--- /dev/null
+++ b/engines/freescape/games/castle.cpp
@@ -0,0 +1,60 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "common/config-manager.h"
+#include "common/file.h"
+#include "common/memstream.h"
+
+#include "freescape/freescape.h"
+
+namespace Freescape {
+
+CastleEngine::CastleEngine(OSystem *syst) : FreescapeEngine(syst) {}
+
+void CastleEngine::loadAssets() {
+	Common::SeekableReadStream *file = nullptr;
+	Common::String path = ConfMan.get("path");
+	Common::FSDirectory gameDir(path);
+
+    _renderMode = "ega";
+
+    file = gameDir.createReadStreamForMember("CMEDF");
+    int size = file->size();
+    byte *encryptedBuffer = (byte*) malloc(size);
+    file->read(encryptedBuffer, size);
+
+    int seed = 24;
+    for (int i = 0; i < size; i++) {
+        encryptedBuffer[i] ^= seed;
+        seed = (seed + 1) & 0xff;
+    }
+
+    file = new Common::MemoryReadStream(encryptedBuffer, size);
+    load8bitBinary(file, 0, 16);
+
+    // CPC
+    //file = gameDir.createReadStreamForMember("cm.bin");
+    //if (file == nullptr)
+    //	error("Failed to open cm.bin");
+    //load8bitBinary(file, 0x791a, 16);
+}
+
+} // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/metaengine.cpp b/engines/freescape/metaengine.cpp
index b69cad4c02f..81edaa44ade 100644
--- a/engines/freescape/metaengine.cpp
+++ b/engines/freescape/metaengine.cpp
@@ -36,6 +36,8 @@ Common::Error FreescapeMetaEngine::createInstance(OSystem *syst, Engine **engine
 		*engine = (Engine *)new Freescape::DrillerEngine(syst);
 	} else 	if (Common::String(desc->gameId) == "totaleclipse") {
 		*engine = (Engine *)new Freescape::EclipseEngine(syst);
+	} else 	if (Common::String(desc->gameId) == "castlemaster") {
+		*engine = (Engine *)new Freescape::CastleEngine(syst);
 	} else
 		*engine = new Freescape::FreescapeEngine(syst);
 
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index cf664406b71..2fb9dafce89 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -4,6 +4,7 @@ MODULE_OBJS := \
 	metaengine.o \
 	freescape.o \
 	area.o \
+	games/castle.o \
 	games/driller.o \
 	games/eclipse.o \
 	gfx.o \


Commit: 59882c743446f6fb06922b341e109353e1cd3fea
    https://github.com/scummvm/scummvm/commit/59882c743446f6fb06922b341e109353e1cd3fea
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:07+01:00

Commit Message:
FREESCAPE: splited dark into a separated class

Changed paths:
  A engines/freescape/games/dark.cpp
    engines/freescape/freescape.h
    engines/freescape/module.mk


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index a90b1dbdb57..7a1e39c322f 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -211,6 +211,13 @@ public:
 	void loadAssets() override;
 };
 
+class DarkEngine : public FreescapeEngine {
+public:
+	DarkEngine(OSystem *syst);
+
+	void loadAssets() override;
+};
+
 class EclipseEngine : public FreescapeEngine {
 public:
 	EclipseEngine(OSystem *syst);
diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
new file mode 100644
index 00000000000..e267ed06050
--- /dev/null
+++ b/engines/freescape/games/dark.cpp
@@ -0,0 +1,54 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "common/config-manager.h"
+#include "common/file.h"
+
+#include "freescape/freescape.h"
+
+namespace Freescape {
+
+DarkEngine::DarkEngine(OSystem *syst) : FreescapeEngine(syst) {}
+
+void DarkEngine::loadAssets() {
+	Common::SeekableReadStream *file = nullptr;
+	Common::String path = ConfMan.get("path");
+	Common::FSDirectory gameDir(path);
+
+    Common::File exe;
+    if (_renderMode == "ega") {
+        file = gameDir.createReadStreamForMember("DSIDEE.EXE");
+
+        if (file == nullptr)
+            error("Failed to open DSIDEE.EXE");
+
+        load8bitBinary(file, 0xa280, 16);
+    } else if (_renderMode == "cga") {
+        file = gameDir.createReadStreamForMember("DSIDEC.EXE");
+
+        if (file == nullptr)
+            error("Failed to open DSIDE.EXE");
+        load8bitBinary(file, 0x7bb0, 4); // TODO
+    } else
+        error("Invalid render mode %s for Dark Side", _renderMode.c_str());
+}
+
+} // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index 2fb9dafce89..bce5fb4a234 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -5,6 +5,7 @@ MODULE_OBJS := \
 	freescape.o \
 	area.o \
 	games/castle.o \
+	games/dark.o \
 	games/driller.o \
 	games/eclipse.o \
 	gfx.o \


Commit: b86e4ccbd6c7df5cea9023e9cdfb830d4faec93f
    https://github.com/scummvm/scummvm/commit/b86e4ccbd6c7df5cea9023e9cdfb830d4faec93f
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:07+01:00

Commit Message:
FREESCAPE: removed specific code from common class

Changed paths:
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 69f393ebafb..eaa21335439 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -23,7 +23,6 @@
 #include "common/events.h"
 #include "common/file.h"
 #include "common/math.h"
-#include "common/memstream.h"
 #include "graphics/cursorman.h"
 
 #include "freescape/freescape.h"
@@ -92,82 +91,7 @@ void FreescapeEngine::loadAssets() {
 
 		file = files.begin()->get()->createReadStream();
 		load16bitBinary(file);
-	} else if (isDriller()) {
-		Common::File exe;
-		if (_renderMode == "ega") {
-			file = gameDir.createReadStreamForMember("DRILLE.EXE");
-
-			if (file == nullptr)
-				error("Failed to open DRILLE.EXE");
-
-			load8bitBinary(file, 0x9b40, 16);
-		} else if (_renderMode == "cga") {
-			file = gameDir.createReadStreamForMember("DRILLC.EXE");
-
-			if (file == nullptr)
-				error("Failed to open DRILLC.EXE");
-			load8bitBinary(file, 0x7bb0, 4);
-		} else
-			error("Invalid render mode %s for Driller", _renderMode.c_str());
-
-	} else if (isDark()) {
-		Common::File exe;
-		if (_renderMode == "ega") {
-			file = gameDir.createReadStreamForMember("DSIDEE.EXE");
-
-			if (file == nullptr)
-				error("Failed to open DSIDEE.EXE");
-
-			load8bitBinary(file, 0xa280, 16);
-		} else if (_renderMode == "cga") {
-			file = gameDir.createReadStreamForMember("DSIDEC.EXE");
-
-			if (file == nullptr)
-				error("Failed to open DSIDE.EXE");
-			load8bitBinary(file, 0x7bb0, 4);
-		} else
-			error("Invalid render mode %s for Dark Side", _renderMode.c_str());
-
-	} else if (isEclipse()) {
-		Common::File exe;
-		if (_renderMode == "ega") {
-			file = gameDir.createReadStreamForMember("TOTEE.EXE");
-
-			if (file == nullptr)
-				error("Failed to open TOTEE.EXE");
-
-			load8bitBinary(file, 0x3ce0, 16);
-		} else if (_renderMode == "cga") {
-			file = gameDir.createReadStreamForMember("TOTEC.EXE");
-
-			if (file == nullptr)
-				error("Failed to open TOTEC.EXE");
-			load8bitBinary(file, 0x7bb0, 4); // TODO
-		} else
-			error("Invalid render mode %s for Total Eclipse", _renderMode.c_str());
-	   } else if (isCastle()) {
-			_renderMode = "ega";
-
-			file = gameDir.createReadStreamForMember("CMEDF");
-			int size = file->size();
-			byte *encryptedBuffer = (byte*) malloc(size);
-			file->read(encryptedBuffer, size);
-
-			int seed = 24;
-			for (int i = 0; i < size; i++) {
-				encryptedBuffer[i] ^= seed;
-				seed = (seed + 1) & 0xff;
-			}
-
-			file = new Common::MemoryReadStream(encryptedBuffer, size);
-			load8bitBinary(file, 0, 16);
-
-			// CPC
-			//file = gameDir.createReadStreamForMember("cm.bin");
-			//if (file == nullptr)
-			//	error("Failed to open cm.bin");
-			//load8bitBinary(file, 0x791a, 16);
-	   } else
+	} else
 		error("'%s' is an invalid game", _targetName.c_str());
 
 }


Commit: 9a7692c97bff445d620040586769749f4d045696
    https://github.com/scummvm/scummvm/commit/9a7692c97bff445d620040586769749f4d045696
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:07+01:00

Commit Message:
FREESCAPE: splited dark into a separated class

Changed paths:
    engines/freescape/metaengine.cpp


diff --git a/engines/freescape/metaengine.cpp b/engines/freescape/metaengine.cpp
index 81edaa44ade..a40067a8abb 100644
--- a/engines/freescape/metaengine.cpp
+++ b/engines/freescape/metaengine.cpp
@@ -34,6 +34,8 @@ public:
 Common::Error FreescapeMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
 	if (Common::String(desc->gameId) == "driller" || Common::String(desc->gameId) == "spacestationoblivion") {
 		*engine = (Engine *)new Freescape::DrillerEngine(syst);
+	} else 	if (Common::String(desc->gameId) == "darkside") {
+		*engine = (Engine *)new Freescape::DarkEngine(syst);
 	} else 	if (Common::String(desc->gameId) == "totaleclipse") {
 		*engine = (Engine *)new Freescape::EclipseEngine(syst);
 	} else 	if (Common::String(desc->gameId) == "castlemaster") {


Commit: 95b3be0ad60c0a093fbf5a6ff914e8075024fae7
    https://github.com/scummvm/scummvm/commit/95b3be0ad60c0a093fbf5a6ff914e8075024fae7
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:07+01:00

Commit Message:
FREESCAPE: moved ui code from driller into a separated class

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/driller.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index eaa21335439..3f4da5fcba4 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -112,31 +112,6 @@ Math::Vector3d FreescapeEngine::directionToVector(float pitch, float heading) {
 
 void FreescapeEngine::drawUI() {
 	_gfx->renderCrossair(0);
-	_gfx->setViewport(_fullscreenViewArea);
-
-	if (isDriller()) {
-		int energy = _gameStateVars[k8bitVariableEnergy];
-		int shield = _gameStateVars[k8bitVariableShield];
-		if (_renderMode == "ega" && _border) {
-			//Common::Rect black(20, 177, 87, 191);
-			//_gfx->drawRect2D(black, 255, 0, 0, 0);
-
-			if (energy >= 0) {
-				Common::Rect black(20, 186, 87 - energy, 191);
-				_gfx->drawRect2D(black, 255, 0, 0, 0);
-				Common::Rect energyBar(87 - energy, 186, 87, 191);
-				_gfx->drawRect2D(energyBar, 255, 0xfc, 0xfc, 0x54);
-			}
-
-			if (shield >= 0) {
-				Common::Rect black(20, 178, 87 - shield, 183);
-				_gfx->drawRect2D(black, 255, 0, 0, 0);
-
-				Common::Rect shieldBar(87 - shield, 178, 87, 183);
-				_gfx->drawRect2D(shieldBar, 255, 0xfc, 0xfc, 0x54);
-			}
-		}
-	}
 	_gfx->setViewport(_viewArea);
 }
 
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 7a1e39c322f..5556ed52c9e 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -85,7 +85,7 @@ public:
 
 	void convertBorder();
 	void drawBorder();
-	void drawUI();
+	virtual void drawUI();
 	Texture *_borderTexture;
 
 	// Parsing
@@ -209,6 +209,7 @@ public:
 	DrillerEngine(OSystem *syst);
 
 	void loadAssets() override;
+	void drawUI() override;
 };
 
 class DarkEngine : public FreescapeEngine {
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index cd88764e9ae..9845bcde69e 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -23,6 +23,7 @@
 #include "common/file.h"
 
 #include "freescape/freescape.h"
+#include "freescape/language/8bitDetokeniser.h"
 
 namespace Freescape {
 
@@ -38,17 +39,46 @@ void DrillerEngine::loadAssets() {
 		file = gameDir.createReadStreamForMember("DRILLE.EXE");
 
 		if (file == nullptr)
-		    error("Failed to open DRILLE.EXE");
+			error("Failed to open DRILLE.EXE");
 
 		load8bitBinary(file, 0x9b40, 16);
-    } else if (_renderMode == "cga") {
+	} else if (_renderMode == "cga") {
 		file = gameDir.createReadStreamForMember("DRILLC.EXE");
 
 		if (file == nullptr)
-            error("Failed to open DRILLC.EXE");
-        load8bitBinary(file, 0x7bb0, 4);
-    } else
-        error("Invalid render mode %s for Driller", _renderMode.c_str());
+			error("Failed to open DRILLC.EXE");
+		load8bitBinary(file, 0x7bb0, 4);
+	} else
+		error("Invalid render mode %s for Driller", _renderMode.c_str());
 }
 
+void DrillerEngine::drawUI() {
+	_gfx->renderCrossair(0);
+	_gfx->setViewport(_fullscreenViewArea);
+
+	int energy = _gameStateVars[k8bitVariableEnergy];
+	int shield = _gameStateVars[k8bitVariableShield];
+	if (_renderMode == "ega" && _border) {
+		//Common::Rect black(20, 177, 87, 191);
+		//_gfx->drawRect2D(black, 255, 0, 0, 0);
+
+		if (energy >= 0) {
+			Common::Rect black(20, 186, 87 - energy, 191);
+			_gfx->drawRect2D(black, 255, 0, 0, 0);
+			Common::Rect energyBar(87 - energy, 186, 87, 191);
+			_gfx->drawRect2D(energyBar, 255, 0xfc, 0xfc, 0x54);
+		}
+
+		if (shield >= 0) {
+			Common::Rect black(20, 178, 87 - shield, 183);
+			_gfx->drawRect2D(black, 255, 0, 0, 0);
+
+			Common::Rect shieldBar(87 - shield, 178, 87, 183);
+			_gfx->drawRect2D(shieldBar, 255, 0xfc, 0xfc, 0x54);
+		}
+	}
+	_gfx->setViewport(_viewArea);
+}
+
+
 } // End of namespace Freescape
\ No newline at end of file


Commit: be64f76e9ecff374b3754459557de8703d05cbda
    https://github.com/scummvm/scummvm/commit/be64f76e9ecff374b3754459557de8703d05cbda
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:08+01:00

Commit Message:
FREESCAPE: moved key processing code from driller into a separated class

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/driller.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 3f4da5fcba4..ac0f5257539 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -124,6 +124,8 @@ void FreescapeEngine::drawFrame() {
 	drawUI();
 }
 
+void FreescapeEngine::pressedKey(const int keycode) {}
+
 void FreescapeEngine::processInput() {
 	float currentFrame = g_system->getMillis();
 	float deltaTime = currentFrame - _lastFrame;
@@ -150,42 +152,10 @@ void FreescapeEngine::processInput() {
 				lower();
 			else if (event.kbd.keycode == Common::KEYCODE_n)
 				gotoArea(_currentArea->getAreaID() + 1, 0);
-			else if (event.kbd.keycode == Common::KEYCODE_d) {
-				Common::Point gasPocket = _currentArea->gasPocketPosition;
-				uint32 gasPocketRadius = _currentArea->gasPocketRadius;
-				if (isDriller() && gasPocketRadius > 0 && !_currentArea->drillDeployed()) {
-					if (_gameStateVars[k8bitVariableEnergy] < 5) {
-						// Show "no enough energy" message
-						continue;
-					}
-
-					_gameStateVars[k8bitVariableEnergy] = _gameStateVars[k8bitVariableEnergy] - 5;
-					_gameStateVars[32]++;
-					// TODO: check if there is space for the drill
-					Math::Vector3d drillPosition = _position + _cameraFront * 128;
-					drillPosition.setValue(1, _position.y() - _playerHeight * _currentArea->getScale());
-					debugC(1, kFreescapeDebugMove, "Trying to adding drill at %f %f %f", drillPosition.x(), drillPosition.y(), drillPosition.z());
-					const Math::Vector3d gasPocket3D(gasPocket.x, 1, gasPocket.y);
-					_currentArea->addDrill(globalObjectsArea, drillPosition);
-					float distance = (gasPocket3D - drillPosition).length();
-					debugC(1, kFreescapeDebugMove, "length to gas pocket: %f with radius %d", distance, _currentArea->gasPocketRadius);
-					// TODO check the result of the drilling
-					// TODO: reduce energy
-				}
-			} else if (event.kbd.keycode == Common::KEYCODE_c) {
-
-				if (isDriller() && _currentArea->drillDeployed()) {
-					if (_gameStateVars[k8bitVariableEnergy] < 5) {
-						// Show "no enough energy" message
-						continue;
-					}
-
-					_gameStateVars[k8bitVariableEnergy] = _gameStateVars[k8bitVariableEnergy] - 5;
-					_gameStateVars[32]--;
-					_currentArea->removeDrill();
-				}
-			} else if (event.kbd.keycode == Common::KEYCODE_ESCAPE)
+			else if (event.kbd.keycode == Common::KEYCODE_ESCAPE)
 				openMainMenuDialog();
+			else
+				pressedKey(event.kbd.keycode);
 			break;
 
 		case Common::EVENT_QUIT:
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 5556ed52c9e..b50e8c6c0fe 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -114,6 +114,7 @@ public:
 	// Input
 	bool _flyMode;
 	void processInput();
+	virtual void pressedKey(const int keycode);
 	void move(CameraMovement direction, uint8 scale, float deltaTime);
 	void changePlayerHeight(int delta);
 	void rise();
@@ -210,6 +211,8 @@ public:
 
 	void loadAssets() override;
 	void drawUI() override;
+
+	void pressedKey(const int keycode) override;
 };
 
 class DarkEngine : public FreescapeEngine {
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 9845bcde69e..f00b6f27e7a 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -20,6 +20,7 @@
  */
 
 #include "common/config-manager.h"
+#include "common/events.h"
 #include "common/file.h"
 
 #include "freescape/freescape.h"
@@ -80,5 +81,41 @@ void DrillerEngine::drawUI() {
 	_gfx->setViewport(_viewArea);
 }
 
+void DrillerEngine::pressedKey(const int keycode) {
+	if (keycode == Common::KEYCODE_d) {
+		Common::Point gasPocket = _currentArea->gasPocketPosition;
+		uint32 gasPocketRadius = _currentArea->gasPocketRadius;
+		if (gasPocketRadius > 0 && !_currentArea->drillDeployed()) {
+			if (_gameStateVars[k8bitVariableEnergy] < 5) {
+				// Show "no enough energy" message
+				return;
+			}
+
+			_gameStateVars[k8bitVariableEnergy] = _gameStateVars[k8bitVariableEnergy] - 5;
+			_gameStateVars[32]++;
+			// TODO: check if there is space for the drill
+			Math::Vector3d drillPosition = _position + _cameraFront * 128;
+			drillPosition.setValue(1, _position.y() - _playerHeight * _currentArea->getScale());
+			debugC(1, kFreescapeDebugMove, "Trying to adding drill at %f %f %f", drillPosition.x(), drillPosition.y(), drillPosition.z());
+			const Math::Vector3d gasPocket3D(gasPocket.x, 1, gasPocket.y);
+			_currentArea->addDrill(globalObjectsArea, drillPosition);
+			float distance = (gasPocket3D - drillPosition).length();
+			debugC(1, kFreescapeDebugMove, "length to gas pocket: %f with radius %d", distance, _currentArea->gasPocketRadius);
+			// TODO check the result of the drilling
+			// TODO: reduce energy
+		}
+	} else if (keycode == Common::KEYCODE_c) {
+		if (_currentArea->drillDeployed()) {
+			if (_gameStateVars[k8bitVariableEnergy] < 5) {
+				// Show "no enough energy" message
+				return;
+			}
+
+			_gameStateVars[k8bitVariableEnergy] = _gameStateVars[k8bitVariableEnergy] - 5;
+			_gameStateVars[32]--;
+			_currentArea->removeDrill();
+		}
+	}
+}
 
 } // End of namespace Freescape
\ No newline at end of file


Commit: c567f890b5caddb73f9a0282e2a745301100b889
    https://github.com/scummvm/scummvm/commit/c567f890b5caddb73f9a0282e2a745301100b889
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:08+01:00

Commit Message:
FREESCAPE: moved game init code from driller into a separated class

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/driller.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index ac0f5257539..f0c71682aed 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -288,9 +288,6 @@ void FreescapeEngine::initGameState() {
 
 	for (AreaMap::iterator it = _areaMap.begin(); it != _areaMap.end(); ++it)
 		_gameStateBits[it->_key] = 0;
-
-	_gameStateVars[k8bitVariableEnergy] = 43;
-	_gameStateVars[k8bitVariableShield] = 48;
 }
 
 void FreescapeEngine::rotate(Common::Point lastMousePos, Common::Point mousePos) {
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index b50e8c6c0fe..9a4985ec6f6 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -193,7 +193,7 @@ public:
 	Graphics::Surface *_border;
 
 	// Game state
-	void initGameState();
+	virtual void initGameState();
 	StateVars _gameStateVars;
 	StateBits _gameStateBits;
 
@@ -209,6 +209,7 @@ class DrillerEngine : public FreescapeEngine {
 public:
 	DrillerEngine(OSystem *syst);
 
+	void initGameState() override;
 	void loadAssets() override;
 	void drawUI() override;
 
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index f00b6f27e7a..1a9cbbaaca3 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -118,4 +118,15 @@ void DrillerEngine::pressedKey(const int keycode) {
 	}
 }
 
+void DrillerEngine::initGameState() {
+	for (int i = 0; i < k8bitMaxVariable; i++) // TODO: check maximum variable
+		_gameStateVars[i] = 0;
+
+	for (AreaMap::iterator it = _areaMap.begin(); it != _areaMap.end(); ++it)
+		_gameStateBits[it->_key] = 0;
+
+	_gameStateVars[k8bitVariableEnergy] = 43;
+	_gameStateVars[k8bitVariableShield] = 48;
+}
+
 } // End of namespace Freescape
\ No newline at end of file


Commit: 3f4c5c92e94548779e7b086e79b051a3ea01c50d
    https://github.com/scummvm/scummvm/commit/3f4c5c92e94548779e7b086e79b051a3ea01c50d
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:08+01:00

Commit Message:
FREESCAPE: moved palettes.cpp into the games directory

Changed paths:
  A engines/freescape/games/palettes.cpp
  R engines/freescape/palettes.cpp
    engines/freescape/module.mk


diff --git a/engines/freescape/palettes.cpp b/engines/freescape/games/palettes.cpp
similarity index 100%
rename from engines/freescape/palettes.cpp
rename to engines/freescape/games/palettes.cpp
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index bce5fb4a234..730cf49627b 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -8,6 +8,7 @@ MODULE_OBJS := \
 	games/dark.o \
 	games/driller.o \
 	games/eclipse.o \
+	games/palettes.o \
 	gfx.o \
 	gfx_tinygl.o \
 	gfx_tinygl_texture.o \
@@ -20,7 +21,7 @@ MODULE_OBJS := \
 	loaders/16bitBinaryLoader.o \
 	language/16bitDetokeniser.o \
 	language/instruction.o \
-	palettes.o
+
 
 MODULE_DIRS += \
 	engines/freescape


Commit: 0050f7a5b76355f2953e77873e3534f8bfa05794
    https://github.com/scummvm/scummvm/commit/0050f7a5b76355f2953e77873e3534f8bfa05794
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:08+01:00

Commit Message:
FREESCAPE: moved more specific code into the game classess

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/games/castle.cpp
    engines/freescape/games/dark.cpp
    engines/freescape/games/driller.cpp
    engines/freescape/games/eclipse.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index f0c71682aed..6962255f1dc 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -255,13 +255,6 @@ Common::Error FreescapeEngine::run() {
 		}
 
 		_borderTexture = nullptr;
-		if (isDriller())
-			_viewArea = Common::Rect(40, 16, 279, 116);
-		else if (isEclipse())
-			_viewArea = Common::Rect(40, 32, 280, 132);
-		else
-			error("Invalid target!");
-
 		_border->fillRect(_viewArea, 0xA0A0A0FF);
 	}
 	if (saveSlot >= 0) { // load the savegame
diff --git a/engines/freescape/games/castle.cpp b/engines/freescape/games/castle.cpp
index 0fa4888397d..6dd62ff6b90 100644
--- a/engines/freescape/games/castle.cpp
+++ b/engines/freescape/games/castle.cpp
@@ -27,34 +27,38 @@
 
 namespace Freescape {
 
-CastleEngine::CastleEngine(OSystem *syst) : FreescapeEngine(syst) {}
+CastleEngine::CastleEngine(OSystem *syst) : FreescapeEngine(syst) {
+	_playerHeight = 48;
+	_playerWidth = 8;
+	_playerDepth = 8;
+}
 
 void CastleEngine::loadAssets() {
 	Common::SeekableReadStream *file = nullptr;
 	Common::String path = ConfMan.get("path");
 	Common::FSDirectory gameDir(path);
 
-    _renderMode = "ega";
+	_renderMode = "ega";
 
-    file = gameDir.createReadStreamForMember("CMEDF");
-    int size = file->size();
-    byte *encryptedBuffer = (byte*) malloc(size);
-    file->read(encryptedBuffer, size);
+	file = gameDir.createReadStreamForMember("CMEDF");
+	int size = file->size();
+	byte *encryptedBuffer = (byte*) malloc(size);
+	file->read(encryptedBuffer, size);
 
-    int seed = 24;
-    for (int i = 0; i < size; i++) {
-        encryptedBuffer[i] ^= seed;
-        seed = (seed + 1) & 0xff;
+	int seed = 24;
+	for (int i = 0; i < size; i++) {
+		encryptedBuffer[i] ^= seed;
+		seed = (seed + 1) & 0xff;
     }
 
-    file = new Common::MemoryReadStream(encryptedBuffer, size);
-    load8bitBinary(file, 0, 16);
+	file = new Common::MemoryReadStream(encryptedBuffer, size);
+	load8bitBinary(file, 0, 16);
 
-    // CPC
-    //file = gameDir.createReadStreamForMember("cm.bin");
-    //if (file == nullptr)
-    //	error("Failed to open cm.bin");
-    //load8bitBinary(file, 0x791a, 16);
+	// CPC
+	//file = gameDir.createReadStreamForMember("cm.bin");
+	//if (file == nullptr)
+	//	error("Failed to open cm.bin");
+	//load8bitBinary(file, 0x791a, 16);
 }
 
 } // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index e267ed06050..d0e65c04d4b 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -26,7 +26,11 @@
 
 namespace Freescape {
 
-DarkEngine::DarkEngine(OSystem *syst) : FreescapeEngine(syst) {}
+DarkEngine::DarkEngine(OSystem *syst) : FreescapeEngine(syst) {
+	_playerHeight = 64;
+	_playerWidth = 12;
+	_playerDepth = 32;
+}
 
 void DarkEngine::loadAssets() {
 	Common::SeekableReadStream *file = nullptr;
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 1a9cbbaaca3..cf02ad2c8cb 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -28,7 +28,12 @@
 
 namespace Freescape {
 
-DrillerEngine::DrillerEngine(OSystem *syst) : FreescapeEngine(syst) {}
+DrillerEngine::DrillerEngine(OSystem *syst) : FreescapeEngine(syst) {
+	_viewArea = Common::Rect(40, 16, 279, 116);
+	_playerHeight = 64;
+	_playerWidth = 12;
+	_playerDepth = 32;
+}
 
 void DrillerEngine::loadAssets() {
 	Common::SeekableReadStream *file = nullptr;
diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index 0f9887edac0..5f08fe833cd 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -53,6 +53,11 @@ static const entrancesTableEntry rawEntranceTable[] = {
 };
 
 EclipseEngine::EclipseEngine(OSystem *syst) : FreescapeEngine(syst) {
+	_viewArea = Common::Rect(40, 32, 280, 132);
+	_playerHeight = 48;
+	_playerWidth = 8;
+	_playerDepth = 8;
+
 	const entrancesTableEntry *entry = rawEntranceTable;
 	while (entry->id) {
 		_entranceTable[entry->id] = entry;
@@ -65,22 +70,22 @@ void EclipseEngine::loadAssets() {
 	Common::String path = ConfMan.get("path");
 	Common::FSDirectory gameDir(path);
 
-    Common::File exe;
-    if (_renderMode == "ega") {
-        file = gameDir.createReadStreamForMember("TOTEE.EXE");
+	Common::File exe;
+	if (_renderMode == "ega") {
+		file = gameDir.createReadStreamForMember("TOTEE.EXE");
 
-        if (file == nullptr)
-            error("Failed to open TOTEE.EXE");
+		if (file == nullptr)
+			error("Failed to open TOTEE.EXE");
 
-        load8bitBinary(file, 0x3ce0, 16);
-    } else if (_renderMode == "cga") {
-        file = gameDir.createReadStreamForMember("TOTEC.EXE");
+		load8bitBinary(file, 0x3ce0, 16);
+	} else if (_renderMode == "cga") {
+		file = gameDir.createReadStreamForMember("TOTEC.EXE");
 
-        if (file == nullptr)
-            error("Failed to open TOTEC.EXE");
-        load8bitBinary(file, 0x7bb0, 4); // TODO
-    } else
-        error("Invalid render mode %s for Total Eclipse", _renderMode.c_str());
+		if (file == nullptr)
+			error("Failed to open TOTEC.EXE");
+		load8bitBinary(file, 0x7bb0, 4); // TODO
+	} else
+		error("Invalid render mode %s for Total Eclipse", _renderMode.c_str());
 
 }
 
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index fa11947276b..2e796cc43c8 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -444,16 +444,6 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 			iterator->_value->addStructure(_areaMap[255]);
 	}
 
-	if (isEclipse() || isCastle()) {
-		_playerHeight = 48;
-		_playerWidth = 8;
-		_playerDepth = 8;
-	} else {
-		_playerHeight = 64;
-		_playerWidth = 12;
-		_playerDepth = 32;
-	}
-
 	if (!_areaMap.contains(startArea))
 		_startArea = newArea->getAreaID();
 	else


Commit: c2869480bc6967d8f39fdba0933170540c928f09
    https://github.com/scummvm/scummvm/commit/c2869480bc6967d8f39fdba0933170540c928f09
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:08+01:00

Commit Message:
FREESCAPE: load an object from the global area if it is not available in the current one

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/language/instruction.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 4bfe380730e..0d3fe4f3493 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -253,9 +253,22 @@ bool Area::drillDeployed() {
 	return (drawableObjects[0]->getObjectID() == 252);
 }
 
-void Area::addStructure(Area *structure) {
+void Area::addObjectFromArea(int16 id, Area *global) {
+	debug("Adding object %d to room structure", id);
+	Object *obj = global->objectWithID(id);
+	if (!obj) {
+		assert(global->entranceWithID(id));
+		(*entrancesByID)[id] = global->entranceWithID(id);
+	} else {
+		(*objectsByID)[id] = global->objectWithID(id);
+		if (obj->isDrawable())
+			drawableObjects.insert_at(0, obj);
+	}
+}
+
+void Area::addStructure(Area *global) {
 	Object *obj = nullptr;
-	if (!structure || !entrancesByID->contains(255)) {
+	if (!global || !entrancesByID->contains(255)) {
 		int id = 254;
 		Common::Array<uint8> *gColors = new Common::Array<uint8>;
 		for (int i = 0; i < 6; i++)
@@ -282,16 +295,7 @@ void Area::addStructure(Area *structure) {
 		if (id == 0)
 			continue;
 
-		debug("Adding object %d to room structure", id);
-		obj = structure->objectWithID(id);
-		if (!obj) {
-			assert(structure->entranceWithID(id));
-			(*entrancesByID)[id] = structure->entranceWithID(id);
-		} else {
-			(*objectsByID)[id] = structure->objectWithID(id);
-			if (obj->isDrawable())
-				drawableObjects.insert_at(0, obj);
-		}
+		addObjectFromArea(id, global);
 	}
 }
 
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index 91673c4b6df..86dabcd9d16 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -58,7 +58,8 @@ public:
 
 	Object *shootRay(const Math::Ray &ray);
 	Object *checkCollisions(const Math::AABB &boundingBox);
-	void addStructure(Area *structure);
+	void addObjectFromArea(int16 id, Area *global);
+	void addStructure(Area *global);
 
 	Common::Array<Common::String*> conditionSources;
 	Common::Array<FCLInstructionVector> conditions;
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index 3e046ee0726..dab839b427b 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -328,7 +328,7 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			break;
 
 		case 35:
-			detokenisedStream += "SCREEN ";
+			detokenisedStream += "SCREEN (";
 			break;
 
 		case 44:
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index 0d6eba8e826..69e9f552795 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -311,8 +311,14 @@ void FreescapeEngine::executeToggleVisibility(FCLInstruction &instruction) {
 	Object *obj = _areaMap[areaID]->objectWithID(objectID);
 	if (obj)
 		obj->toggleVisibility();
-	else
-		debugC(1, kFreescapeDebugCode, "WARNING!: obj %d does not exists in area %d!", objectID, areaID);
+	else {
+		obj = _areaMap[255]->objectWithID(objectID);
+		if (!obj)
+			error("ERROR!: obj %d does not exists in area %d nor in the global one!", objectID, areaID);
+
+		// If an object is not in the area, it is considered to be invisible
+		_currentArea->addObjectFromArea(objectID, _areaMap[255]);
+	}
 
 }
 


Commit: dd5866e769bc09ee2f2ff6305dd02478c6860fb6
    https://github.com/scummvm/scummvm/commit/dd5866e769bc09ee2f2ff6305dd02478c6860fb6
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:08+01:00

Commit Message:
FREESCAPE: load an object from the global area if it is not available in the current one

Changed paths:
    engines/freescape/language/instruction.cpp


diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index 69e9f552795..7b1661daffa 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -318,6 +318,8 @@ void FreescapeEngine::executeToggleVisibility(FCLInstruction &instruction) {
 
 		// If an object is not in the area, it is considered to be invisible
 		_currentArea->addObjectFromArea(objectID, _areaMap[255]);
+		obj = _areaMap[areaID]->objectWithID(objectID);
+		obj->makeVisible();
 	}
 
 }


Commit: 40cca49db24efa7725731c52ab26bc4576c1f758
    https://github.com/scummvm/scummvm/commit/40cca49db24efa7725731c52ab26bc4576c1f758
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:09+01:00

Commit Message:
FREESCAPE: use area scale when stepping foward

Changed paths:
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 6962255f1dc..a182869bf46 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -375,8 +375,9 @@ void FreescapeEngine::lower() {
 void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTime) {
 	debugC(1, kFreescapeDebugMove, "old player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
 	int previousAreaID = _currentArea->getAreaID();
+	int areaScale = _currentArea->getScale();
 
-	float velocity = _movementSpeed * deltaTime;
+	float velocity = _movementSpeed * deltaTime * areaScale;
 	float positionY = _position.y();
 	switch (direction) {
 	case FORWARD:
@@ -392,7 +393,6 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 		_position = _position + _cameraRight * velocity;
 		break;
 	}
-	int areaScale = _currentArea->getScale();
 	// restore y coordinate
 	if (!_flyMode)
 		_position.set(_position.x(), positionY, _position.z());


Commit: 64c2933027c8ecbff12965da82bf9ecdc885ac3c
    https://github.com/scummvm/scummvm/commit/64c2933027c8ecbff12965da82bf9ecdc885ac3c
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:09+01:00

Commit Message:
FREESCAPE: show NOPs in bytecode

Changed paths:
    engines/freescape/language/8bitDetokeniser.cpp


diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index dab839b427b..847a9c4e624 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -104,6 +104,7 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			break;
 
 		case 0:
+			detokenisedStream += "NOP ";
 			break; // NOP
 		case 1:    // add three-byte value to score
 		{


Commit: ff32048a024ee42ea9653654a23a3a5429ea6de9
    https://github.com/scummvm/scummvm/commit/ff32048a024ee42ea9653654a23a3a5429ea6de9
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:09+01:00

Commit Message:
FREESCAPE: improved how drill is positioned by the player

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/games/driller.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 0d3fe4f3493..887551721bd 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -195,7 +195,7 @@ Object *Area::checkCollisions(const Math::AABB &boundingBox) {
 	return collided;
 }
 
-void Area::addDrill(Area *structure, const Math::Vector3d position) {
+void Area::addDrill(Area *global, const Math::Vector3d position) {
 	//int drillObjectIDs[8] = {255, 254, 253, 252, 251, 250, 248, 247};
 	drillPosition = position;
 	Object *obj = nullptr;
@@ -205,16 +205,18 @@ void Area::addDrill(Area *structure, const Math::Vector3d position) {
 
 	id = 255;
 	debug("Adding object %d to room structure", id);
-	obj = structure->objectWithID(id);
+	obj = global->objectWithID(id);
 	obj->setOrigin(offset);
 	offset.setValue(1, offset.y() + obj->getSize().y());
+
+	//offset.setValue(1, offset.y() + obj->getSize().y());
 	assert(obj);
 	obj->makeVisible();
 	drawableObjects.insert_at(0, obj);
 
 	id = 254;
 	debug("Adding object %d to room structure", id);
-	obj = structure->objectWithID(id);
+	obj = global->objectWithID(id);
 	offset.setValue(1, offset.y() + obj->getSize().y());
 	obj->setOrigin(offset);
 	assert(obj);
@@ -223,7 +225,7 @@ void Area::addDrill(Area *structure, const Math::Vector3d position) {
 
 	id = 253;
 	debug("Adding object %d to room structure", id);
-	obj = structure->objectWithID(id);
+	obj = global->objectWithID(id);
 	obj->setOrigin(offset);
 	offset.setValue(1, offset.y() + obj->getSize().y());
 	assert(obj);
@@ -232,7 +234,7 @@ void Area::addDrill(Area *structure, const Math::Vector3d position) {
 
 	id = 252;
 	debug("Adding object %d to room structure", id);
-	obj = structure->objectWithID(id);
+	obj = global->objectWithID(id);
 	obj->setOrigin(offset);
 	offset.setValue(1, offset.y() + obj->getSize().y());
 	assert(obj);
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index cf02ad2c8cb..08df09d6770 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -99,9 +99,14 @@ void DrillerEngine::pressedKey(const int keycode) {
 			_gameStateVars[k8bitVariableEnergy] = _gameStateVars[k8bitVariableEnergy] - 5;
 			_gameStateVars[32]++;
 			// TODO: check if there is space for the drill
-			Math::Vector3d drillPosition = _position + _cameraFront * 128;
+			Math::Vector3d drillPosition = _cameraFront;
+			drillPosition =  _position + 256 * drillPosition;
+
+			debugC(1, kFreescapeDebugMove, "Current position at %f %f %f", _position.x(), _position.y(), _position.z());
 			drillPosition.setValue(1, _position.y() - _playerHeight * _currentArea->getScale());
 			debugC(1, kFreescapeDebugMove, "Trying to adding drill at %f %f %f", drillPosition.x(), drillPosition.y(), drillPosition.z());
+			debugC(1, kFreescapeDebugMove, "with pitch: %f and yaw %f", _pitch, _yaw);
+
 			const Math::Vector3d gasPocket3D(gasPocket.x, 1, gasPocket.y);
 			_currentArea->addDrill(globalObjectsArea, drillPosition);
 			float distance = (gasPocket3D - drillPosition).length();


Commit: d6041b940c423afd6ee582c4eaf7905294c970ed
    https://github.com/scummvm/scummvm/commit/d6041b940c423afd6ee582c4eaf7905294c970ed
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:09+01:00

Commit Message:
FREESCAPE: refactored code that adds the drill

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/driller.cpp
    engines/freescape/objects/geometricobject.cpp
    engines/freescape/objects/geometricobject.h


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 887551721bd..74c44fea065 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -122,7 +122,9 @@ void Area::loadObjectFlags(Common::SeekableReadStream *stream) {
 	drillPosition.setValue(1, stream->readFloatLE());
 	drillPosition.setValue(2, stream->readFloatLE());
 
-	for (int i = 0; i < int(objectsByID->size()); i++) {
+	int objectsByIDSize = stream->readUint32LE();
+
+	for (int i = 0; i < objectsByIDSize; i++) {
 		uint16 key = stream->readUint32LE();
 		assert(objectsByID->contains(key));
 		Object *obj = (*objectsByID)[key];
@@ -135,7 +137,7 @@ void Area::saveObjectFlags(Common::WriteStream *stream) {
 	stream->writeFloatLE(drillPosition.y());
 	stream->writeFloatLE(drillPosition.z());
 
-	//stream->writeUint32LE(objectsByID->size());
+	stream->writeUint32LE(objectsByID->size());
 
 	for (ObjectMap::iterator iterator = objectsByID->begin(); iterator != objectsByID->end(); iterator++) {
 		stream->writeUint32LE(iterator->_key);
@@ -195,53 +197,6 @@ Object *Area::checkCollisions(const Math::AABB &boundingBox) {
 	return collided;
 }
 
-void Area::addDrill(Area *global, const Math::Vector3d position) {
-	//int drillObjectIDs[8] = {255, 254, 253, 252, 251, 250, 248, 247};
-	drillPosition = position;
-	Object *obj = nullptr;
-	Math::Vector3d offset = position;
-
-	int16 id;
-
-	id = 255;
-	debug("Adding object %d to room structure", id);
-	obj = global->objectWithID(id);
-	obj->setOrigin(offset);
-	offset.setValue(1, offset.y() + obj->getSize().y());
-
-	//offset.setValue(1, offset.y() + obj->getSize().y());
-	assert(obj);
-	obj->makeVisible();
-	drawableObjects.insert_at(0, obj);
-
-	id = 254;
-	debug("Adding object %d to room structure", id);
-	obj = global->objectWithID(id);
-	offset.setValue(1, offset.y() + obj->getSize().y());
-	obj->setOrigin(offset);
-	assert(obj);
-	obj->makeVisible();
-	drawableObjects.insert_at(0, obj);
-
-	id = 253;
-	debug("Adding object %d to room structure", id);
-	obj = global->objectWithID(id);
-	obj->setOrigin(offset);
-	offset.setValue(1, offset.y() + obj->getSize().y());
-	assert(obj);
-	obj->makeVisible();
-	drawableObjects.insert_at(0, obj);
-
-	id = 252;
-	debug("Adding object %d to room structure", id);
-	obj = global->objectWithID(id);
-	obj->setOrigin(offset);
-	offset.setValue(1, offset.y() + obj->getSize().y());
-	assert(obj);
-	obj->makeVisible();
-	drawableObjects.insert_at(0, obj);
-}
-
 void Area::removeDrill() {
 	drillPosition = Math::Vector3d();
 	for (int16 id = 252; id < 256; id++) {
@@ -255,6 +210,15 @@ bool Area::drillDeployed() {
 	return (drawableObjects[0]->getObjectID() == 252);
 }
 
+void Area::addObject(Object *obj) {
+	assert(obj);
+	int id = obj->getObjectID();
+	debug("Adding object %d to room %d", id, areaID);
+	(*objectsByID)[id] = obj;
+	if (obj->isDrawable())
+		drawableObjects.insert_at(0, obj);
+}
+
 void Area::addObjectFromArea(int16 id, Area *global) {
 	debug("Adding object %d to room structure", id);
 	Object *obj = global->objectWithID(id);
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index 86dabcd9d16..6548d02479c 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -59,6 +59,7 @@ public:
 	Object *shootRay(const Math::Ray &ray);
 	Object *checkCollisions(const Math::AABB &boundingBox);
 	void addObjectFromArea(int16 id, Area *global);
+	void addObject(Object *obj);
 	void addStructure(Area *global);
 
 	Common::Array<Common::String*> conditionSources;
@@ -69,7 +70,6 @@ public:
 	void loadObjectFlags(Common::SeekableReadStream *stream);
 
 	// Driller specific
-	void addDrill(Area *structure, const Math::Vector3d position);
 	void removeDrill();
 	bool drillDeployed();
 	Math::Vector3d drillPosition;
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index a182869bf46..41a25e8df9e 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -599,8 +599,8 @@ Common::Error FreescapeEngine::loadGameStream(Common::SeekableReadStream *stream
 		Area *area = _areaMap[key];
 		area->loadObjectFlags(stream);
 		// Add drill, if available
-		if (area->drillPosition != Math::Vector3d())
-			area->addDrill(globalObjectsArea, area->drillPosition);
+		//if (area->drillPosition != Math::Vector3d())
+		//	area->addDrill(globalObjectsArea, area->drillPosition);
 	}
 
 	_flyMode = stream->readByte();
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 9a4985ec6f6..ca1e03f7088 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -214,6 +214,9 @@ public:
 	void drawUI() override;
 
 	void pressedKey(const int keycode) override;
+
+	private:
+	void addDrill(const Math::Vector3d position);
 };
 
 class DarkEngine : public FreescapeEngine {
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 08df09d6770..b73a75c5fc3 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -108,7 +108,7 @@ void DrillerEngine::pressedKey(const int keycode) {
 			debugC(1, kFreescapeDebugMove, "with pitch: %f and yaw %f", _pitch, _yaw);
 
 			const Math::Vector3d gasPocket3D(gasPocket.x, 1, gasPocket.y);
-			_currentArea->addDrill(globalObjectsArea, drillPosition);
+			addDrill(drillPosition);
 			float distance = (gasPocket3D - drillPosition).length();
 			debugC(1, kFreescapeDebugMove, "length to gas pocket: %f with radius %d", distance, _currentArea->gasPocketRadius);
 			// TODO check the result of the drilling
@@ -128,6 +128,57 @@ void DrillerEngine::pressedKey(const int keycode) {
 	}
 }
 
+void DrillerEngine::addDrill(const Math::Vector3d position) {
+	//int drillObjectIDs[8] = {255, 254, 253, 252, 251, 250, 248, 247};
+	GeometricObject *obj = nullptr;
+	Math::Vector3d offset = position;
+
+	int16 id;
+
+	id = 255;
+	debug("Adding object %d to room structure", id);
+	obj = (GeometricObject*) globalObjectsArea->objectWithID(id);
+	assert(obj);
+	obj = obj->duplicate();
+	obj->setOrigin(offset);
+	offset.setValue(1, offset.y() + obj->getSize().y());
+
+	//offset.setValue(1, offset.y() + obj->getSize().y());
+	obj->makeVisible();
+	_currentArea->addObject(obj);
+
+	id = 254;
+	debug("Adding object %d to room structure", id);
+	obj = (GeometricObject*) globalObjectsArea->objectWithID(id);
+	assert(obj);
+	obj = obj->duplicate();
+	offset.setValue(1, offset.y() + obj->getSize().y());
+	obj->setOrigin(offset);
+	obj->makeVisible();
+	_currentArea->addObject(obj);
+
+	id = 253;
+	debug("Adding object %d to room structure", id);
+	obj = (GeometricObject*) globalObjectsArea->objectWithID(id);
+	assert(obj);
+	obj = obj->duplicate();
+	obj->setOrigin(offset);
+	offset.setValue(1, offset.y() + obj->getSize().y());
+	obj->makeVisible();
+	_currentArea->addObject(obj);
+
+	id = 252;
+	debug("Adding object %d to room structure", id);
+	obj = (GeometricObject*) globalObjectsArea->objectWithID(id);
+	assert(obj);
+	obj = obj->duplicate();
+	obj->setOrigin(offset);
+	offset.setValue(1, offset.y() + obj->getSize().y());
+	assert(obj);
+	obj->makeVisible();
+	_currentArea->addObject(obj);
+}
+
 void DrillerEngine::initGameState() {
 	for (int i = 0; i < k8bitMaxVariable; i++) // TODO: check maximum variable
 		_gameStateVars[i] = 0;
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index 7f0d8cc9246..11e83197a1b 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -110,9 +110,6 @@ bool GeometricObject::isPolygon(Type type) {
 	}
 }
 
-#pragma mark -
-#pragma mark Construction/Destruction
-
 GeometricObject::GeometricObject(
 	Type type,
 	uint16 objectID,
@@ -133,8 +130,13 @@ GeometricObject::GeometricObject(
 	origin = _origin;
 	size = _size;
 
+	colours = nullptr;
+
 	if (_colours)
 		colours = new Common::Array<uint8>(*_colours);
+
+	ordinates = nullptr;
+
 	if (_ordinates)
 		ordinates = new Common::Array<uint16>(*_ordinates);
 	condition = _conditionInstructions;
@@ -142,6 +144,19 @@ GeometricObject::GeometricObject(
 	createBoundingBox();
 }
 
+GeometricObject *GeometricObject::duplicate() {
+	return new GeometricObject(
+		_type,
+		_objectID,
+		_flags,
+		origin,
+		size,
+		colours,
+		ordinates,
+		condition,
+		conditionSource);
+}
+
 void GeometricObject::createBoundingBox() {
 	Math::Vector3d v;
 	switch (_type) {
diff --git a/engines/freescape/objects/geometricobject.h b/engines/freescape/objects/geometricobject.h
index fcee884cb52..3ec764a5b95 100644
--- a/engines/freescape/objects/geometricobject.h
+++ b/engines/freescape/objects/geometricobject.h
@@ -47,6 +47,8 @@ public:
 		FCLInstructionVector conditionInstructions,
 		Common::String *conditionSource = nullptr);
 	virtual ~GeometricObject();
+
+	GeometricObject *duplicate();
 	void createBoundingBox();
 	bool collides(const Math::AABB &boundingBox);
 	void draw(Freescape::Renderer *gfx) override;


Commit: 6f9c009115b0976121cf898c31b343d4070a78d9
    https://github.com/scummvm/scummvm/commit/6f9c009115b0976121cf898c31b343d4070a78d9
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:09+01:00

Commit Message:
FREESCAPE: renamed object fields

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/objects/entrance.cpp
    engines/freescape/objects/entrance.h
    engines/freescape/objects/geometricobject.cpp
    engines/freescape/objects/object.cpp
    engines/freescape/objects/object.h
    engines/freescape/objects/sensor.cpp
    engines/freescape/objects/sensor.h


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 74c44fea065..b7f0071e963 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -170,8 +170,8 @@ Object *Area::shootRay(const Math::Ray &ray) {
 	for (int i = 0; i < int(drawableObjects.size()); i++) {
 		float objSize = drawableObjects[i]->getSize().length();
 		if (!drawableObjects[i]->isDestroyed() && !drawableObjects[i]->isInvisible()
-		  && drawableObjects[i]->_boundingBox.isValid()
-		  && ray.intersectAABB(drawableObjects[i]->_boundingBox)
+		  && drawableObjects[i]->boundingBox.isValid()
+		  && ray.intersectAABB(drawableObjects[i]->boundingBox)
 		  && size >= objSize) {
 			debug("shot obj id: %d", drawableObjects[i]->getObjectID());
 			collided = drawableObjects[i];
diff --git a/engines/freescape/objects/entrance.cpp b/engines/freescape/objects/entrance.cpp
index a13b648bcf5..abbeecdd351 100644
--- a/engines/freescape/objects/entrance.cpp
+++ b/engines/freescape/objects/entrance.cpp
@@ -26,18 +26,18 @@
 namespace Freescape {
 
 RoomStructure::RoomStructure(const Common::Array<byte> _structure) {
-	_objectID = 255;
+	objectID = 255;
 	structure = _structure;
 }
 
 Entrance::Entrance(
-	uint16 objectID,
+	uint16 _objectID,
 	const Math::Vector3d &_origin,
-	const Math::Vector3d &rotation) {
-	_objectID = objectID;
+	const Math::Vector3d &_rotation) {
+	objectID = _objectID;
 	origin = _origin;
-	_rotation = rotation;
-	_flags = 0;
+	rotation = _rotation;
+	flags = 0;
 }
 
 Entrance::~Entrance() {}
diff --git a/engines/freescape/objects/entrance.h b/engines/freescape/objects/entrance.h
index ab6c8af1ac4..a541040e4da 100644
--- a/engines/freescape/objects/entrance.h
+++ b/engines/freescape/objects/entrance.h
@@ -48,7 +48,7 @@ public:
 	bool isDrawable();
 	bool isPlanar();
 	Type getType() override { return Type::Entrance; };
-	Math::Vector3d getRotation() { return _rotation; }
+	Math::Vector3d getRotation() { return rotation; }
 
 	void draw(Freescape::Renderer *gfx) override { error("cannot render Entrance"); };
 };
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index 11e83197a1b..35bfd717ec8 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -111,22 +111,22 @@ bool GeometricObject::isPolygon(Type type) {
 }
 
 GeometricObject::GeometricObject(
-	Type type,
-	uint16 objectID,
-	uint16 flags,
+	Type _type,
+	uint16 _objectID,
+	uint16 _flags,
 	const Math::Vector3d &_origin,
 	const Math::Vector3d &_size,
 	Common::Array<uint8> *_colours,
 	Common::Array<uint16> *_ordinates,
 	FCLInstructionVector _conditionInstructions,
 	Common::String *_conditionSource) {
-	_type = type;
-	_flags = flags;
+	type = _type;
+	flags = _flags;
 
 	if (isDestroyed()) // If the object is destroyed, restore it
-		_flags = _flags & ~0x20;
+		flags = flags & ~0x20;
 
-	_objectID = objectID;
+	objectID = _objectID;
 	origin = _origin;
 	size = _size;
 
@@ -146,9 +146,9 @@ GeometricObject::GeometricObject(
 
 GeometricObject *GeometricObject::duplicate() {
 	return new GeometricObject(
-		_type,
-		_objectID,
-		_flags,
+		type,
+		objectID,
+		flags,
 		origin,
 		size,
 		colours,
@@ -159,32 +159,32 @@ GeometricObject *GeometricObject::duplicate() {
 
 void GeometricObject::createBoundingBox() {
 	Math::Vector3d v;
-	switch (_type) {
+	switch (type) {
 	default:
 	break;
 	case Cube:
-		_boundingBox.expand(origin);
+		boundingBox.expand(origin);
 		for (int i = 0; i < 3; i++) {
 			v = origin;
 			v.setValue(i, v.getValue(i) + size.getValue(i));
-			_boundingBox.expand(v);
+			boundingBox.expand(v);
 		}
 
 		for (int i = 0; i < 3; i++) {
 			v = origin + size;
 			v.setValue(i, v.getValue(i) - size.getValue(i));
-			_boundingBox.expand(v);
+			boundingBox.expand(v);
 		}
-		_boundingBox.expand(origin + size);
-		assert(_boundingBox.isValid());
+		boundingBox.expand(origin + size);
+		assert(boundingBox.isValid());
 		break;
 	case Rectangle:
-		_boundingBox.expand(origin);
-		_boundingBox.expand(origin + size);
+		boundingBox.expand(origin);
+		boundingBox.expand(origin + size);
 		break;
 	case Line:
 		for (int i = 0; i < int(ordinates->size()); i = i + 3) {
-			_boundingBox.expand(Math::Vector3d((*ordinates)[i], (*ordinates)[i + 1], (*ordinates)[i + 2]));
+			boundingBox.expand(Math::Vector3d((*ordinates)[i], (*ordinates)[i + 1], (*ordinates)[i + 2]));
 		}
 		int dx, dy, dz;
 		dx = dy = dz = 0;
@@ -200,7 +200,7 @@ void GeometricObject::createBoundingBox() {
 		}
 
 		for (int i = 0; i < int(ordinates->size()); i = i + 3) {
-			_boundingBox.expand(Math::Vector3d((*ordinates)[i] + dx, (*ordinates)[i + 1] + dy, (*ordinates)[i + 2] + dz));
+			boundingBox.expand(Math::Vector3d((*ordinates)[i] + dx, (*ordinates)[i + 1] + dy, (*ordinates)[i + 2] + dz));
 		}
 
 		break;
@@ -209,72 +209,72 @@ void GeometricObject::createBoundingBox() {
 	case Pentagon:
 	case Hexagon:
 		for (int i = 0; i < int(ordinates->size()); i = i + 3) {
-			_boundingBox.expand(Math::Vector3d((*ordinates)[i], (*ordinates)[i + 1], (*ordinates)[i + 2]));
+			boundingBox.expand(Math::Vector3d((*ordinates)[i], (*ordinates)[i + 1], (*ordinates)[i + 2]));
 		}
 		break;
 
 	case EastPyramid:
-		_boundingBox.expand(origin + Math::Vector3d(0, 0, size.z()));
-		_boundingBox.expand(origin + Math::Vector3d(0, size.y(), size.z()));
-		_boundingBox.expand(origin + Math::Vector3d(0, size.y(), 0));
-
-		_boundingBox.expand(origin + Math::Vector3d(size.x(), (*ordinates)[0], (*ordinates)[3]));
-		_boundingBox.expand(origin + Math::Vector3d(size.x(), (*ordinates)[2], (*ordinates)[3]));
-		_boundingBox.expand(origin + Math::Vector3d(size.x(), (*ordinates)[2], (*ordinates)[1]));
-		_boundingBox.expand(origin + Math::Vector3d(size.x(), (*ordinates)[0], (*ordinates)[1]));
+		boundingBox.expand(origin + Math::Vector3d(0, 0, size.z()));
+		boundingBox.expand(origin + Math::Vector3d(0, size.y(), size.z()));
+		boundingBox.expand(origin + Math::Vector3d(0, size.y(), 0));
+
+		boundingBox.expand(origin + Math::Vector3d(size.x(), (*ordinates)[0], (*ordinates)[3]));
+		boundingBox.expand(origin + Math::Vector3d(size.x(), (*ordinates)[2], (*ordinates)[3]));
+		boundingBox.expand(origin + Math::Vector3d(size.x(), (*ordinates)[2], (*ordinates)[1]));
+		boundingBox.expand(origin + Math::Vector3d(size.x(), (*ordinates)[0], (*ordinates)[1]));
 		break;
 	case WestPyramid:
-		_boundingBox.expand(origin + Math::Vector3d(size.x(), 0, 0));
-		_boundingBox.expand(origin + Math::Vector3d(size.x(), size.y(), 0));
-		_boundingBox.expand(origin + Math::Vector3d(size.x(), size.y(), size.z()));
-		_boundingBox.expand(origin + Math::Vector3d(size.x(), 0, size.z()));
-
-		_boundingBox.expand(origin + Math::Vector3d(0, (*ordinates)[0], (*ordinates)[1]));
-		_boundingBox.expand(origin + Math::Vector3d(0, (*ordinates)[2], (*ordinates)[1]));
-		_boundingBox.expand(origin + Math::Vector3d(0, (*ordinates)[2], (*ordinates)[3]));
-		_boundingBox.expand(origin + Math::Vector3d(0, (*ordinates)[0], (*ordinates)[3]));
+		boundingBox.expand(origin + Math::Vector3d(size.x(), 0, 0));
+		boundingBox.expand(origin + Math::Vector3d(size.x(), size.y(), 0));
+		boundingBox.expand(origin + Math::Vector3d(size.x(), size.y(), size.z()));
+		boundingBox.expand(origin + Math::Vector3d(size.x(), 0, size.z()));
+
+		boundingBox.expand(origin + Math::Vector3d(0, (*ordinates)[0], (*ordinates)[1]));
+		boundingBox.expand(origin + Math::Vector3d(0, (*ordinates)[2], (*ordinates)[1]));
+		boundingBox.expand(origin + Math::Vector3d(0, (*ordinates)[2], (*ordinates)[3]));
+		boundingBox.expand(origin + Math::Vector3d(0, (*ordinates)[0], (*ordinates)[3]));
 		break;
 	case UpPyramid:
-		_boundingBox.expand(origin + Math::Vector3d(size.x(), 0, 0));
-		_boundingBox.expand(origin + Math::Vector3d(size.x(), 0, size.z()));
-		_boundingBox.expand(origin + Math::Vector3d(0, 0, size.z()));
-
-		_boundingBox.expand(origin + Math::Vector3d((*ordinates)[0], size.y(), (*ordinates)[1]));
-		_boundingBox.expand(origin + Math::Vector3d((*ordinates)[2], size.y(), (*ordinates)[1]));
-		_boundingBox.expand(origin + Math::Vector3d((*ordinates)[2], size.y(), (*ordinates)[3]));
-		_boundingBox.expand(origin + Math::Vector3d((*ordinates)[0], size.y(), (*ordinates)[3]));
+		boundingBox.expand(origin + Math::Vector3d(size.x(), 0, 0));
+		boundingBox.expand(origin + Math::Vector3d(size.x(), 0, size.z()));
+		boundingBox.expand(origin + Math::Vector3d(0, 0, size.z()));
+
+		boundingBox.expand(origin + Math::Vector3d((*ordinates)[0], size.y(), (*ordinates)[1]));
+		boundingBox.expand(origin + Math::Vector3d((*ordinates)[2], size.y(), (*ordinates)[1]));
+		boundingBox.expand(origin + Math::Vector3d((*ordinates)[2], size.y(), (*ordinates)[3]));
+		boundingBox.expand(origin + Math::Vector3d((*ordinates)[0], size.y(), (*ordinates)[3]));
 		break;
 	case DownPyramid:
-		_boundingBox.expand(origin + Math::Vector3d(size.x(), size.y(), 0));
-		_boundingBox.expand(origin + Math::Vector3d(0, size.y(), 0));
-		_boundingBox.expand(origin + Math::Vector3d(0, size.y(), size.z()));
-		_boundingBox.expand(origin + Math::Vector3d(size.x(), size.y(), size.z()));
-
-		_boundingBox.expand(origin + Math::Vector3d((*ordinates)[2], 0, (*ordinates)[1]));
-		_boundingBox.expand(origin + Math::Vector3d((*ordinates)[0], 0, (*ordinates)[1]));
-		_boundingBox.expand(origin + Math::Vector3d((*ordinates)[0], 0, (*ordinates)[3]));
-		_boundingBox.expand(origin + Math::Vector3d((*ordinates)[2], 0, (*ordinates)[3]));
+		boundingBox.expand(origin + Math::Vector3d(size.x(), size.y(), 0));
+		boundingBox.expand(origin + Math::Vector3d(0, size.y(), 0));
+		boundingBox.expand(origin + Math::Vector3d(0, size.y(), size.z()));
+		boundingBox.expand(origin + Math::Vector3d(size.x(), size.y(), size.z()));
+
+		boundingBox.expand(origin + Math::Vector3d((*ordinates)[2], 0, (*ordinates)[1]));
+		boundingBox.expand(origin + Math::Vector3d((*ordinates)[0], 0, (*ordinates)[1]));
+		boundingBox.expand(origin + Math::Vector3d((*ordinates)[0], 0, (*ordinates)[3]));
+		boundingBox.expand(origin + Math::Vector3d((*ordinates)[2], 0, (*ordinates)[3]));
 		break;
 	case NorthPyramid:
-		_boundingBox.expand(origin + Math::Vector3d(0, size.y(), 0));
-		_boundingBox.expand(origin + Math::Vector3d(size.x(), size.y(), 0));
-		_boundingBox.expand(origin + Math::Vector3d(size.x(), 0, 0));
-
-		_boundingBox.expand(origin + Math::Vector3d((*ordinates)[0], (*ordinates)[3], size.z()));
-		_boundingBox.expand(origin + Math::Vector3d((*ordinates)[2], (*ordinates)[3], size.z()));
-		_boundingBox.expand(origin + Math::Vector3d((*ordinates)[2], (*ordinates)[1], size.z()));
-		_boundingBox.expand(origin + Math::Vector3d((*ordinates)[0], (*ordinates)[1], size.z()));
+		boundingBox.expand(origin + Math::Vector3d(0, size.y(), 0));
+		boundingBox.expand(origin + Math::Vector3d(size.x(), size.y(), 0));
+		boundingBox.expand(origin + Math::Vector3d(size.x(), 0, 0));
+
+		boundingBox.expand(origin + Math::Vector3d((*ordinates)[0], (*ordinates)[3], size.z()));
+		boundingBox.expand(origin + Math::Vector3d((*ordinates)[2], (*ordinates)[3], size.z()));
+		boundingBox.expand(origin + Math::Vector3d((*ordinates)[2], (*ordinates)[1], size.z()));
+		boundingBox.expand(origin + Math::Vector3d((*ordinates)[0], (*ordinates)[1], size.z()));
 		break;
 	case SouthPyramid:
-		_boundingBox.expand(origin + Math::Vector3d(0, 0, size.z()));
-		_boundingBox.expand(origin + Math::Vector3d(size.x(), 0, size.z()));
-		_boundingBox.expand(origin + Math::Vector3d(size.x(), size.y(), size.z()));
-
-		_boundingBox.expand(origin + Math::Vector3d(0, size.y(), size.z()));
-		_boundingBox.expand(origin + Math::Vector3d((*ordinates)[0], (*ordinates)[1], 0));
-		_boundingBox.expand(origin + Math::Vector3d((*ordinates)[2], (*ordinates)[1], 0));
-		_boundingBox.expand(origin + Math::Vector3d((*ordinates)[2], (*ordinates)[3], 0));
-		_boundingBox.expand(origin + Math::Vector3d((*ordinates)[0], (*ordinates)[3], 0));
+		boundingBox.expand(origin + Math::Vector3d(0, 0, size.z()));
+		boundingBox.expand(origin + Math::Vector3d(size.x(), 0, size.z()));
+		boundingBox.expand(origin + Math::Vector3d(size.x(), size.y(), size.z()));
+
+		boundingBox.expand(origin + Math::Vector3d(0, size.y(), size.z()));
+		boundingBox.expand(origin + Math::Vector3d((*ordinates)[0], (*ordinates)[1], 0));
+		boundingBox.expand(origin + Math::Vector3d((*ordinates)[2], (*ordinates)[1], 0));
+		boundingBox.expand(origin + Math::Vector3d((*ordinates)[2], (*ordinates)[3], 0));
+		boundingBox.expand(origin + Math::Vector3d((*ordinates)[0], (*ordinates)[3], 0));
 		break;
 	}
 }
@@ -288,16 +288,16 @@ bool GeometricObject::isPlanar() {
 	return (type >= Object::Line) || type == Object::Rectangle || !size.x() || !size.y() || !size.z();
 }
 
-bool GeometricObject::collides(const Math::AABB &boundingBox) {
-	if (isDestroyed() || isInvisible() || !_boundingBox.isValid() || !boundingBox.isValid())
+bool GeometricObject::collides(const Math::AABB &_boundingBox) {
+	if (isDestroyed() || isInvisible() || !boundingBox.isValid() || !_boundingBox.isValid())
 		return false;
 
-	return(	_boundingBox.getMax().x() > boundingBox.getMin().x() &&
-			_boundingBox.getMin().x() < boundingBox.getMax().x() &&
-			_boundingBox.getMax().y() > boundingBox.getMin().y() &&
-			_boundingBox.getMin().y() < boundingBox.getMax().y() &&
-			_boundingBox.getMax().z() > boundingBox.getMin().z() &&
-			_boundingBox.getMin().z() < boundingBox.getMax().z());
+	return(	boundingBox.getMax().x() > _boundingBox.getMin().x() &&
+			boundingBox.getMin().x() < _boundingBox.getMax().x() &&
+			boundingBox.getMax().y() > _boundingBox.getMin().y() &&
+			boundingBox.getMin().y() < _boundingBox.getMax().y() &&
+			boundingBox.getMax().z() > _boundingBox.getMin().z() &&
+			boundingBox.getMin().z() < _boundingBox.getMax().z());
 }
 
 void GeometricObject::draw(Freescape::Renderer *gfx) {
@@ -308,7 +308,7 @@ void GeometricObject::draw(Freescape::Renderer *gfx) {
 		gfx->renderRectangle(origin, size, colours);
 	} else if (isPyramid(this->getType())) {
 		gfx->renderPyramid(origin, size, ordinates, colours, this->getType());
-	} else if (this->isPlanar() && _type <= 14) {
+	} else if (this->isPlanar() && type <= 14) {
 		if (this->getType() == Triangle)
 			assert(ordinates->size() == 9);
 
diff --git a/engines/freescape/objects/object.cpp b/engines/freescape/objects/object.cpp
index 964fdcbdd2a..51b672daec1 100644
--- a/engines/freescape/objects/object.cpp
+++ b/engines/freescape/objects/object.cpp
@@ -25,23 +25,23 @@
 
 namespace Freescape {
 
-Object::Type Object::getType() { return _type; }
-uint16 Object::getObjectID() { return _objectID; }
-uint16 Object::getObjectFlags() { return _flags; }
-void Object::setObjectFlags(uint32 flags) { _flags = flags; }
+Object::Type Object::getType() { return type; }
+uint16 Object::getObjectID() { return objectID; }
+uint16 Object::getObjectFlags() { return flags; }
+void Object::setObjectFlags(uint32 _flags) { flags = _flags; }
 Math::Vector3d Object::getOrigin() { return origin; }
-void Object::setOrigin(Math::Vector3d _origin) { origin = _origin; };
+void Object::setOrigin(Math::Vector3d _origin) { origin = origin; };
 Math::Vector3d Object::getSize() { return size; }
 
 bool Object::isDrawable() { return false; }
 bool Object::isPlanar() { return false; }
 
-bool Object::isInvisible() { return _flags & 0x80; }
-void Object::makeInvisible() { _flags = _flags | 0x80; }
-void Object::makeVisible() { _flags = _flags & ~0x80; }
-bool Object::isDestroyed() { return _flags & 0x20; }
-void Object::destroy() { _flags = _flags | 0x20; }
-void Object::toggleVisibility() { _flags = _flags ^ 0x80; }
+bool Object::isInvisible() { return flags & 0x80; }
+void Object::makeInvisible() { flags = flags | 0x80; }
+void Object::makeVisible() { flags = flags & ~0x80; }
+bool Object::isDestroyed() { return flags & 0x20; }
+void Object::destroy() { flags = flags | 0x20; }
+void Object::toggleVisibility() { flags = flags ^ 0x80; }
 
 Object::~Object() {}
 
diff --git a/engines/freescape/objects/object.h b/engines/freescape/objects/object.h
index 7ebc3fe714c..01df4ebe20d 100644
--- a/engines/freescape/objects/object.h
+++ b/engines/freescape/objects/object.h
@@ -76,11 +76,11 @@ public:
 
 	virtual ~Object();
 
-	uint16 _flags;
-	Type _type;
-	uint16 _objectID;
-	Math::Vector3d origin, size, _rotation;
-	Math::AABB _boundingBox;
+	uint16 flags;
+	Type type;
+	uint16 objectID;
+	Math::Vector3d origin, size, rotation;
+	Math::AABB boundingBox;
 };
 
 } // End of namespace Freescape
diff --git a/engines/freescape/objects/sensor.cpp b/engines/freescape/objects/sensor.cpp
index 2901ec0c337..0262fb3db9e 100644
--- a/engines/freescape/objects/sensor.cpp
+++ b/engines/freescape/objects/sensor.cpp
@@ -26,13 +26,13 @@
 namespace Freescape {
 
 Sensor::Sensor(
-	uint16 objectID,
+	uint16 _objectID,
 	const Math::Vector3d &_origin,
-	const Math::Vector3d &rotation) {
-	_objectID = objectID;
+	const Math::Vector3d &_rotation) {
+	objectID = _objectID;
 	origin = _origin;
-	_rotation = rotation;
-	_flags = 0;
+	rotation = _rotation;
+	flags = 0;
 }
 
 Sensor::~Sensor() {}
diff --git a/engines/freescape/objects/sensor.h b/engines/freescape/objects/sensor.h
index 2f9dd1bf86f..65d59406a8b 100644
--- a/engines/freescape/objects/sensor.h
+++ b/engines/freescape/objects/sensor.h
@@ -40,7 +40,7 @@ public:
 	bool isDrawable();
 	bool isPlanar();
 	Type getType() override { return Type::Sensor; };
-	Math::Vector3d getRotation() { return _rotation; }
+	Math::Vector3d getRotation() { return rotation; }
 
 	void draw(Freescape::Renderer *gfx) override { error("cannot render sensor"); };
 };


Commit: ecc422537a460fb0ee1d24add1f49b85d4f80ef3
    https://github.com/scummvm/scummvm/commit/ecc422537a460fb0ee1d24add1f49b85d4f80ef3
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:10+01:00

Commit Message:
FREESCAPE: renamed object fields

Changed paths:
    engines/freescape/objects/object.cpp


diff --git a/engines/freescape/objects/object.cpp b/engines/freescape/objects/object.cpp
index 51b672daec1..b57a815ff89 100644
--- a/engines/freescape/objects/object.cpp
+++ b/engines/freescape/objects/object.cpp
@@ -30,7 +30,7 @@ uint16 Object::getObjectID() { return objectID; }
 uint16 Object::getObjectFlags() { return flags; }
 void Object::setObjectFlags(uint32 _flags) { flags = _flags; }
 Math::Vector3d Object::getOrigin() { return origin; }
-void Object::setOrigin(Math::Vector3d _origin) { origin = origin; };
+void Object::setOrigin(Math::Vector3d _origin) { origin = _origin; };
 Math::Vector3d Object::getSize() { return size; }
 
 bool Object::isDrawable() { return false; }


Commit: ac8d79f1c4582ed82ac1d022ec71e2c6d6ecbf92
    https://github.com/scummvm/scummvm/commit/ac8d79f1c4582ed82ac1d022ec71e2c6d6ecbf92
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:10+01:00

Commit Message:
FREESCAPE: partially aligned dril elements

Changed paths:
    engines/freescape/games/driller.cpp


diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index b73a75c5fc3..2bce7c3e179 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -131,49 +131,68 @@ void DrillerEngine::pressedKey(const int keycode) {
 void DrillerEngine::addDrill(const Math::Vector3d position) {
 	//int drillObjectIDs[8] = {255, 254, 253, 252, 251, 250, 248, 247};
 	GeometricObject *obj = nullptr;
-	Math::Vector3d offset = position;
+	Math::Vector3d origin = position;
 
 	int16 id;
+	int heightLastObject;
 
 	id = 255;
 	debug("Adding object %d to room structure", id);
 	obj = (GeometricObject*) globalObjectsArea->objectWithID(id);
 	assert(obj);
 	obj = obj->duplicate();
-	obj->setOrigin(offset);
-	offset.setValue(1, offset.y() + obj->getSize().y());
-
+	obj->setOrigin(origin);
 	//offset.setValue(1, offset.y() + obj->getSize().y());
 	obj->makeVisible();
 	_currentArea->addObject(obj);
 
+	heightLastObject = obj->getSize().y();
+
 	id = 254;
 	debug("Adding object %d to room structure", id);
 	obj = (GeometricObject*) globalObjectsArea->objectWithID(id);
 	assert(obj);
+	// Set position for object
+	origin.setValue(0, origin.x() - obj->getSize().x() / 5);
+	origin.setValue(1, origin.y() + heightLastObject);
+	origin.setValue(2, origin.z() - obj->getSize().z() / 5);
+
 	obj = obj->duplicate();
-	offset.setValue(1, offset.y() + obj->getSize().y());
-	obj->setOrigin(offset);
+	obj->setOrigin(origin);
 	obj->makeVisible();
 	_currentArea->addObject(obj);
 
+	// Undo offset
+	origin.setValue(0, origin.x() + obj->getSize().x() / 5);
+	heightLastObject = obj->getSize().y();
+	origin.setValue(2, origin.z() + obj->getSize().z() / 5);
+
 	id = 253;
 	debug("Adding object %d to room structure", id);
 	obj = (GeometricObject*) globalObjectsArea->objectWithID(id);
 	assert(obj);
 	obj = obj->duplicate();
-	obj->setOrigin(offset);
-	offset.setValue(1, offset.y() + obj->getSize().y());
+
+	origin.setValue(0, origin.x() + obj->getSize().x() / 5);
+	origin.setValue(1, origin.y() + heightLastObject);
+	origin.setValue(2, origin.z() + obj->getSize().z() / 5);
+
+	obj->setOrigin(origin);
 	obj->makeVisible();
 	_currentArea->addObject(obj);
 
+	// Undo offset
+	//origin.setValue(0, origin.x() - obj->getSize().x() / 5);
+	heightLastObject = obj->getSize().y();
+	//origin.setValue(2, origin.z() - obj->getSize().z() / 5);
+
 	id = 252;
 	debug("Adding object %d to room structure", id);
 	obj = (GeometricObject*) globalObjectsArea->objectWithID(id);
 	assert(obj);
 	obj = obj->duplicate();
-	obj->setOrigin(offset);
-	offset.setValue(1, offset.y() + obj->getSize().y());
+	origin.setValue(1, origin.y() + heightLastObject);
+	obj->setOrigin(origin);
 	assert(obj);
 	obj->makeVisible();
 	_currentArea->addObject(obj);


Commit: 0ed1d908341011e1bc93b0588e3da9540d3611b5
    https://github.com/scummvm/scummvm/commit/0ed1d908341011e1bc93b0588e3da9540d3611b5
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:10+01:00

Commit Message:
FREESCAPE: correctly save and restore global objects

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/driller.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index b7f0071e963..b1153785d60 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -117,7 +117,7 @@ void Area::show() {
 		debug("objID: %d, type: %d (entrance)", (*it)._value->getObjectID(), (*it)._value->getType());
 }
 
-void Area::loadObjectFlags(Common::SeekableReadStream *stream) {
+void Area::loadObjects(Common::SeekableReadStream *stream, Area *global) {
 	drillPosition.setValue(0, stream->readFloatLE());
 	drillPosition.setValue(1, stream->readFloatLE());
 	drillPosition.setValue(2, stream->readFloatLE());
@@ -126,13 +126,25 @@ void Area::loadObjectFlags(Common::SeekableReadStream *stream) {
 
 	for (int i = 0; i < objectsByIDSize; i++) {
 		uint16 key = stream->readUint32LE();
-		assert(objectsByID->contains(key));
-		Object *obj = (*objectsByID)[key];
-		obj->setObjectFlags(stream->readUint32LE());
+		uint32 flags = stream->readUint32LE();
+		float x = stream->readFloatLE();
+		float y = stream->readFloatLE();
+		float z = stream->readFloatLE();
+		Object *obj = nullptr;
+		if (objectsByID->contains(key)) {
+			obj = (*objectsByID)[key];
+		} else {
+			obj = global->objectWithID(key);
+			assert(obj);
+			obj = (Object*) ((GeometricObject*) obj)->duplicate();
+			addObject(obj);
+		}
+		obj->setObjectFlags(flags);
+		obj->setOrigin(Math::Vector3d(x, y, z));
 	}
 }
 
-void Area::saveObjectFlags(Common::WriteStream *stream) {
+void Area::saveObjects(Common::WriteStream *stream) {
 	stream->writeFloatLE(drillPosition.x());
 	stream->writeFloatLE(drillPosition.y());
 	stream->writeFloatLE(drillPosition.z());
@@ -140,8 +152,12 @@ void Area::saveObjectFlags(Common::WriteStream *stream) {
 	stream->writeUint32LE(objectsByID->size());
 
 	for (ObjectMap::iterator iterator = objectsByID->begin(); iterator != objectsByID->end(); iterator++) {
+		Object *obj = iterator->_value;
 		stream->writeUint32LE(iterator->_key);
-		stream->writeUint32LE(iterator->_value->getObjectFlags());
+		stream->writeUint32LE(obj->getObjectFlags());
+		stream->writeFloatLE(obj->getOrigin().x());
+		stream->writeFloatLE(obj->getOrigin().y());
+		stream->writeFloatLE(obj->getOrigin().z());
 	}
 }
 
@@ -214,6 +230,7 @@ void Area::addObject(Object *obj) {
 	assert(obj);
 	int id = obj->getObjectID();
 	debug("Adding object %d to room %d", id, areaID);
+	assert(!objectsByID->contains(id));
 	(*objectsByID)[id] = obj;
 	if (obj->isDrawable())
 		drawableObjects.insert_at(0, obj);
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index 6548d02479c..a9dcd2cf0e0 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -66,8 +66,8 @@ public:
 	Common::Array<FCLInstructionVector> conditions;
 
 	// Serialization
-	void saveObjectFlags(Common::WriteStream *stream);
-	void loadObjectFlags(Common::SeekableReadStream *stream);
+	void saveObjects(Common::WriteStream *stream);
+	void loadObjects(Common::SeekableReadStream *stream, Area *global);
 
 	// Driller specific
 	void removeDrill();
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 41a25e8df9e..e73dc223c22 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -597,10 +597,7 @@ Common::Error FreescapeEngine::loadGameStream(Common::SeekableReadStream *stream
 		uint16 key = stream->readUint16LE();
 		assert(_areaMap.contains(key));
 		Area *area = _areaMap[key];
-		area->loadObjectFlags(stream);
-		// Add drill, if available
-		//if (area->drillPosition != Math::Vector3d())
-		//	area->addDrill(globalObjectsArea, area->drillPosition);
+		area->loadObjects(stream, _areaMap[255]);
 	}
 
 	_flyMode = stream->readByte();
@@ -637,7 +634,7 @@ Common::Error FreescapeEngine::saveGameStream(Common::WriteStream *stream, bool
 
 	for (AreaMap::iterator it = _areaMap.begin(); it != _areaMap.end(); ++it) {
 		stream->writeUint16LE(it->_key);
-		it->_value->saveObjectFlags(stream);
+		it->_value->saveObjects(stream);
 	}
 
 	stream->writeByte(_flyMode);
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index ca1e03f7088..819bc477393 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -95,7 +95,6 @@ public:
 
 	// 8-bits
 	//ObjectMap globalObjectsByID;
-	Area *globalObjectsArea;
 	void load8bitBinary(Common::SeekableReadStream *file, int offset, int ncolors);
 	Area *load8bitArea(Common::SeekableReadStream *file, uint16 ncolors);
 	Object *load8bitObject(Common::SeekableReadStream *file);
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 2bce7c3e179..f0cbeadd2be 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -138,7 +138,7 @@ void DrillerEngine::addDrill(const Math::Vector3d position) {
 
 	id = 255;
 	debug("Adding object %d to room structure", id);
-	obj = (GeometricObject*) globalObjectsArea->objectWithID(id);
+	obj = (GeometricObject*) _areaMap[255]->objectWithID(id);
 	assert(obj);
 	obj = obj->duplicate();
 	obj->setOrigin(origin);
@@ -150,7 +150,7 @@ void DrillerEngine::addDrill(const Math::Vector3d position) {
 
 	id = 254;
 	debug("Adding object %d to room structure", id);
-	obj = (GeometricObject*) globalObjectsArea->objectWithID(id);
+	obj = (GeometricObject*) _areaMap[255]->objectWithID(id);
 	assert(obj);
 	// Set position for object
 	origin.setValue(0, origin.x() - obj->getSize().x() / 5);
@@ -169,7 +169,7 @@ void DrillerEngine::addDrill(const Math::Vector3d position) {
 
 	id = 253;
 	debug("Adding object %d to room structure", id);
-	obj = (GeometricObject*) globalObjectsArea->objectWithID(id);
+	obj = (GeometricObject*) _areaMap[255]->objectWithID(id);
 	assert(obj);
 	obj = obj->duplicate();
 
@@ -188,7 +188,7 @@ void DrillerEngine::addDrill(const Math::Vector3d position) {
 
 	id = 252;
 	debug("Adding object %d to room structure", id);
-	obj = (GeometricObject*) globalObjectsArea->objectWithID(id);
+	obj = (GeometricObject*) _areaMap[255]->objectWithID(id);
 	assert(obj);
 	obj = obj->duplicate();
 	origin.setValue(1, origin.y() + heightLastObject);
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 2e796cc43c8..079168ee765 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -407,7 +407,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 			(*globalObjectsByID)[gobj->getObjectID()] = gobj;
 		}
 
-		globalObjectsArea = new Area(255, 0, globalObjectsByID, nullptr, 1, 255, 255, nullptr);
+		_areaMap[255] = new Area(255, 0, globalObjectsByID, nullptr, 1, 255, 255, nullptr);
 	}
 
 	file->seek(offset + 0xc8);
@@ -439,7 +439,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 		}
 	}
 
-	if (_areaMap.contains(255)) {
+	if (!isDriller() && !isDark() && _areaMap.contains(255)) {
 		for (AreaMap::iterator iterator = _areaMap.begin(); iterator != _areaMap.end(); iterator++)
 			iterator->_value->addStructure(_areaMap[255]);
 	}


Commit: de8fa81bcf235548da7c241b6e018b255ea2ac88
    https://github.com/scummvm/scummvm/commit/de8fa81bcf235548da7c241b6e018b255ea2ac88
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:10+01:00

Commit Message:
FREESCAPE: use deg2rad in updateProjectionMatrix

Changed paths:
    engines/freescape/gfx_tinygl.cpp


diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index d8bc7a76432..ba6d11a4457 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -24,6 +24,7 @@
 #include "common/config-manager.h"
 #include "common/rect.h"
 #include "math/glmath.h"
+#include "common/math.h"
 #include "graphics/tinygl/tinygl.h"
 
 #include "engines/freescape/gfx_tinygl.h"
@@ -99,7 +100,7 @@ void TinyGLRenderer::updateProjectionMatrix(float fov, float nearClipPlane, floa
 
 	float aspectRatio = kOriginalWidth / (float) kFrameHeight;
 
-	float xmaxValue = nearClipPlane * tan(fov * M_PI / 360.0);
+	float xmaxValue = nearClipPlane * tan(Common::deg2rad(fov) / 2);
 	float ymaxValue = xmaxValue / aspectRatio;
 	//debug("max values: %f %f", xmaxValue, ymaxValue);
 


Commit: 1bebf5b578f7a0f57e4890f1d2ee69b6660aa5e7
    https://github.com/scummvm/scummvm/commit/1bebf5b578f7a0f57e4890f1d2ee69b6660aa5e7
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:10+01:00

Commit Message:
FREESCAPE: added some code to end the game is shield is zero

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/language/instruction.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index e73dc223c22..03de1d7a329 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -264,17 +264,32 @@ Common::Error FreescapeEngine::run() {
 
 	debugC(1, kFreescapeDebugMove, "Starting area %d", _currentArea->getAreaID());
 	_system->lockMouse(true);
-	while (!shouldQuit()) {
+	bool endGame = false;
+	while (!shouldQuit() && !endGame) {
 		drawFrame();
 		processInput();
 		_gfx->flipBuffer();
 		g_system->updateScreen();
 		g_system->delayMillis(10);
+		endGame = checkIfGameEnded();
 	}
 
 	return Common::kNoError;
 }
 
+bool FreescapeEngine::checkIfGameEnded() {
+	if (_gameStateVars[k8bitVariableShield] == 0) {
+		_flyMode = true;
+		gotoArea(127, 0);
+		drawFrame();
+		_gfx->flipBuffer();
+		g_system->updateScreen();
+		g_system->delayMillis(5000);
+		return true;
+	}
+	return false;
+}
+
 void FreescapeEngine::initGameState() {
 	for (int i = 0; i < k8bitMaxVariable; i++) // TODO: check maximum variable
 		_gameStateVars[i] = 0;
@@ -514,7 +529,7 @@ void FreescapeEngine::gotoArea(uint16 areaID, int entranceID) {
 	assert(scale > 0);
 
 	Entrance *entrance = nullptr;
-	if (entranceID > 0) {
+	if (entranceID > 0 || areaID == 127) {
 		entrance = (Entrance*) _currentArea->entranceWithID(entranceID);
 
 		if (!entrance) {
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 819bc477393..01871f20335 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -195,6 +195,7 @@ public:
 	virtual void initGameState();
 	StateVars _gameStateVars;
 	StateBits _gameStateBits;
+	bool checkIfGameEnded();
 
 	bool hasFeature(EngineFeature f) const override;
 	bool canLoadGameStateCurrently() override { return true; }
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index 847a9c4e624..ed19c77205f 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -124,10 +124,10 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 		} break;
 		case 2: // add one-byte value to energy
 			detokenisedStream += "ADDVAR ";
-			detokenisedStream += Common::String::format("(%d, v%d)", (int)tokenisedCondition[bytePointer], k8bitVariableEnergy);
+			detokenisedStream += Common::String::format("(%d, v%d)", (int8)tokenisedCondition[bytePointer], k8bitVariableEnergy);
 			currentInstruction = FCLInstruction(Token::ADDVAR);
 			currentInstruction.setSource(k8bitVariableEnergy);
-			currentInstruction.setDestination(tokenisedCondition[bytePointer]);
+			currentInstruction.setDestination((int8)tokenisedCondition[bytePointer]);
 			conditionalInstructions->push_back(currentInstruction);
 			currentInstruction = FCLInstruction(Token::UNKNOWN);
 			bytePointer++;
@@ -135,10 +135,10 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			break;
 		case 19: // add one-byte value to shield
 			detokenisedStream += "ADDVAR ";
-			detokenisedStream += Common::String::format("(%d, v%d)", (int)tokenisedCondition[bytePointer], k8bitVariableShield);
+			detokenisedStream += Common::String::format("(%d, v%d)", (int8)tokenisedCondition[bytePointer], k8bitVariableShield);
 			currentInstruction = FCLInstruction(Token::ADDVAR);
 			currentInstruction.setSource(k8bitVariableShield);
-			currentInstruction.setDestination(tokenisedCondition[bytePointer]);
+			currentInstruction.setDestination((int8) tokenisedCondition[bytePointer]);
 			conditionalInstructions->push_back(currentInstruction);
 			currentInstruction = FCLInstruction(Token::UNKNOWN);
 			bytePointer++;
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index 7b1661daffa..5bf16e8cad6 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -213,21 +213,26 @@ bool FreescapeEngine::executeEndIfNotEqual(FCLInstruction &instruction) {
 }
 
 void FreescapeEngine::executeIncrementVariable(FCLInstruction &instruction) {
-	uint16 variable = instruction.source;
-	uint16 increment = instruction.destination;
+	int32 variable = instruction.source;
+	int32 increment = instruction.destination;
 	_gameStateVars[variable] = _gameStateVars[variable] + increment;
 	switch (variable) {
 	case k8bitVariableScore:
 		debugC(1, kFreescapeDebugCode, "Score incremented by %d up to %d", increment, _gameStateVars[variable]);
 	break;
 	case k8bitVariableEnergy:
-		if (_gameStateVars[variable] >= k8bitMaxEnergy)
+		if (_gameStateVars[variable] > k8bitMaxEnergy)
 			_gameStateVars[variable] = k8bitMaxEnergy;
+		else if (_gameStateVars[variable] < 0)
+			_gameStateVars[variable] = 0;
 		debugC(1, kFreescapeDebugCode, "Energy incremented by %d up to %d", increment, _gameStateVars[variable]);
 	break;
 	case k8bitVariableShield:
-		if (_gameStateVars[variable] >= k8bitMaxShield)
+		if (_gameStateVars[variable] > k8bitMaxShield)
 			_gameStateVars[variable] = k8bitMaxShield;
+		else if (_gameStateVars[variable] < 0)
+			_gameStateVars[variable] = 0;
+
 		debugC(1, kFreescapeDebugCode, "Shield incremented by %d up to %d", increment, _gameStateVars[variable]);
 	break;
 	default:


Commit: 5365e9bcd68fbf8578b0d9348af60d414ce7c084
    https://github.com/scummvm/scummvm/commit/5365e9bcd68fbf8578b0d9348af60d414ce7c084
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:10+01:00

Commit Message:
FREESCAPE: font loading in driller

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/driller.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 03de1d7a329..ab3a7f07cfe 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -577,6 +577,20 @@ bool FreescapeEngine::hasFeature(EngineFeature f) const {
 		   (f == kSupportsSavingDuringRuntime);
 }
 
+void FreescapeEngine::drawStringInSurface(const Common::String &str, int x, int y, uint32 color, Graphics::Surface *surface) {
+	for (uint32 c = 0; c < str.size(); c++) {
+		for (int j = 0; j < 6; j++) {
+			for (int i = 0; i < 8; i++) {
+				if (_font.get(48*(str[c] - 32) + 1 + j*8 + i))
+					surface->setPixel(x + 8 - i + 8*c, y + j, color);
+				else
+					surface->setPixel(x + 8 - i + 8*c, y + j, 0x000000FF);  // black
+
+			}
+		}
+	}
+}
+
 void FreescapeEngine::playSound(int index) {
 	_mixer->stopAll();
 	debug("Playing sound %d", index);
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 01871f20335..a35fec1ae07 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -22,6 +22,7 @@
 #ifndef FREESCAPE_H
 #define FREESCAPE_H
 
+#include "common/bitarray.h"
 #include "common/random.h"
 #include "engines/engine.h"
 #include "graphics/palette.h"
@@ -191,6 +192,12 @@ public:
 	float _farClipPlane;
 	Graphics::Surface *_border;
 
+	// Fonts
+	Common::BitArray _font;
+	void loadFonts(Common::SeekableReadStream *file, int offset);
+	void drawStringInSurface(const Common::String &str, int x, int y, uint32 color, Graphics::Surface *surface);
+
+
 	// Game state
 	virtual void initGameState();
 	StateVars _gameStateVars;
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index f0cbeadd2be..0390813b9ad 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -62,6 +62,19 @@ void DrillerEngine::drawUI() {
 	_gfx->renderCrossair(0);
 	_gfx->setViewport(_fullscreenViewArea);
 
+	Graphics::Surface *surface = new Graphics::Surface();
+	surface->create(_screenW, _screenH, _gfx->_currentPixelFormat);
+	surface->fillRect(_fullscreenViewArea, 0xA0A0A0FF);
+
+	uint32 yellow = 0xFFFF55FF;
+	drawStringInSurface("   SCUMMVM   ", 197, 177, yellow, surface);
+	drawStringInSurface("    ROCKS    ", 197, 185, yellow, surface);
+
+	Texture *texture = _gfx->createTexture(surface);
+	_gfx->drawTexturedRect2D(_fullscreenViewArea, _fullscreenViewArea, texture);
+	surface->free();
+	delete surface;
+
 	int energy = _gameStateVars[k8bitVariableEnergy];
 	int shield = _gameStateVars[k8bitVariableShield];
 	if (_renderMode == "ega" && _border) {
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 079168ee765..ded678105c4 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -397,6 +397,8 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	}
 
 	if (isDriller()) {
+		loadFonts(file, 0x99dd);
+
 		ObjectMap *globalObjectsByID = new ObjectMap;
 		file->seek(0x3b42);
 		for (int i = 0; i < 8; i++) {
@@ -453,4 +455,14 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	_binaryBits = 8;
 }
 
+void FreescapeEngine::loadFonts(Common::SeekableReadStream *file, int offset) {
+	file->seek(offset);
+	int charNumber = 59;
+	byte *font = (byte *)malloc(6 * charNumber);
+	file->read(font, 6 * charNumber);
+
+	_font.set_size(48 * charNumber);
+	_font.set_bits((byte *)font);
+}
+
 } // namespace Freescape
\ No newline at end of file


Commit: 39d068e8ced048de7871621a8205db000bdba082
    https://github.com/scummvm/scummvm/commit/39d068e8ced048de7871621a8205db000bdba082
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:11+01:00

Commit Message:
FREESCAPE: message loading and rendering in driller

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/driller.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index ab3a7f07cfe..73ed24973cd 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -525,6 +525,14 @@ void FreescapeEngine::gotoArea(uint16 areaID, int entranceID) {
 	_currentArea = _areaMap[areaID];
 	_currentArea->show();
 
+	_currentAreaMessages.clear();
+	if (!_messagesList.empty())
+		_currentAreaMessages.push_back(_messagesList[1]);
+	else
+		_currentAreaMessages.push_back("");
+
+	_currentAreaMessages.push_back(_currentArea->name);
+
 	int scale = _currentArea->getScale();
 	assert(scale > 0);
 
@@ -578,10 +586,12 @@ bool FreescapeEngine::hasFeature(EngineFeature f) const {
 }
 
 void FreescapeEngine::drawStringInSurface(const Common::String &str, int x, int y, uint32 color, Graphics::Surface *surface) {
-	for (uint32 c = 0; c < str.size(); c++) {
+	Common::String ustr = str;
+	ustr.toUppercase();
+	for (uint32 c = 0; c < ustr.size(); c++) {
 		for (int j = 0; j < 6; j++) {
 			for (int i = 0; i < 8; i++) {
-				if (_font.get(48*(str[c] - 32) + 1 + j*8 + i))
+				if (_font.get(48*(ustr[c] - 32) + 1 + j*8 + i))
 					surface->setPixel(x + 8 - i + 8*c, y + j, color);
 				else
 					surface->setPixel(x + 8 - i + 8*c, y + j, 0x000000FF);  // black
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index a35fec1ae07..65ac462d344 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -192,9 +192,13 @@ public:
 	float _farClipPlane;
 	Graphics::Surface *_border;
 
-	// Fonts
-	Common::BitArray _font;
+	// Text messages and Fonts
+	Common::StringArray _messagesList;
+	void loadMessages(Common::SeekableReadStream *file, int offset, int number);
 	void loadFonts(Common::SeekableReadStream *file, int offset);
+	Common::StringArray _currentAreaMessages;
+	Common::StringArray _currentEphymeralMessages;
+	Common::BitArray _font;
 	void drawStringInSurface(const Common::String &str, int x, int y, uint32 color, Graphics::Surface *surface);
 
 
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 0390813b9ad..b01bea700da 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -60,20 +60,24 @@ void DrillerEngine::loadAssets() {
 
 void DrillerEngine::drawUI() {
 	_gfx->renderCrossair(0);
-	_gfx->setViewport(_fullscreenViewArea);
 
-	Graphics::Surface *surface = new Graphics::Surface();
-	surface->create(_screenW, _screenH, _gfx->_currentPixelFormat);
-	surface->fillRect(_fullscreenViewArea, 0xA0A0A0FF);
+	if (_currentAreaMessages.size() == 2) {
+		_gfx->setViewport(_fullscreenViewArea);
 
-	uint32 yellow = 0xFFFF55FF;
-	drawStringInSurface("   SCUMMVM   ", 197, 177, yellow, surface);
-	drawStringInSurface("    ROCKS    ", 197, 185, yellow, surface);
+		Graphics::Surface *surface = new Graphics::Surface();
+		surface->create(_screenW, _screenH, _gfx->_currentPixelFormat);
+		surface->fillRect(_fullscreenViewArea, 0xA0A0A0FF);
 
-	Texture *texture = _gfx->createTexture(surface);
-	_gfx->drawTexturedRect2D(_fullscreenViewArea, _fullscreenViewArea, texture);
-	surface->free();
-	delete surface;
+		uint32 yellow = 0xFFFF55FF;
+
+		drawStringInSurface(_currentAreaMessages[0], 197, 177, yellow, surface);
+		drawStringInSurface(_currentAreaMessages[1], 197, 185, yellow, surface);
+
+		Texture *texture = _gfx->createTexture(surface);
+		_gfx->drawTexturedRect2D(_fullscreenViewArea, _fullscreenViewArea, texture);
+		surface->free();
+		delete surface;
+	}
 
 	int energy = _gameStateVars[k8bitVariableEnergy];
 	int shield = _gameStateVars[k8bitVariableShield];
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index ded678105c4..4e6dd4af587 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -396,7 +396,10 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 		debugC(1, kFreescapeDebugParser, "%s", conditionSource->c_str());
 	}
 
-	if (isDriller()) {
+	if (isEclipse()) {
+		loadFonts(file, 0xd403);
+	} else if (isDriller()) {
+		loadMessages(file, 0x4135, 20);
 		loadFonts(file, 0x99dd);
 
 		ObjectMap *globalObjectsByID = new ObjectMap;
@@ -457,7 +460,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 
 void FreescapeEngine::loadFonts(Common::SeekableReadStream *file, int offset) {
 	file->seek(offset);
-	int charNumber = 59;
+	int charNumber = 60;
 	byte *font = (byte *)malloc(6 * charNumber);
 	file->read(font, 6 * charNumber);
 
@@ -465,4 +468,19 @@ void FreescapeEngine::loadFonts(Common::SeekableReadStream *file, int offset) {
 	_font.set_bits((byte *)font);
 }
 
+void FreescapeEngine::loadMessages(Common::SeekableReadStream *file, int offset, int number) {
+	file->seek(offset);
+	int messageSize = 14;
+	byte *buffer = (byte *)malloc(messageSize + 1);
+	buffer[14] = NULL;
+
+	for (int i = 0; i < number; i++) {
+		file->read(buffer, messageSize);
+		Common::String message = (const char*) buffer;
+		_messagesList.push_back(message);
+		debug("%s", _messagesList[i].c_str());
+	}
+}
+
+
 } // namespace Freescape
\ No newline at end of file


Commit: e4e06ab94876e3d6b769bd20934500c2a25e3beb
    https://github.com/scummvm/scummvm/commit/e4e06ab94876e3d6b769bd20934500c2a25e3beb
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:11+01:00

Commit Message:
FREESCAPE: refactored checkIfGameEnded for driller

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/driller.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 73ed24973cd..14c1980d192 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -278,16 +278,7 @@ Common::Error FreescapeEngine::run() {
 }
 
 bool FreescapeEngine::checkIfGameEnded() {
-	if (_gameStateVars[k8bitVariableShield] == 0) {
-		_flyMode = true;
-		gotoArea(127, 0);
-		drawFrame();
-		_gfx->flipBuffer();
-		g_system->updateScreen();
-		g_system->delayMillis(5000);
-		return true;
-	}
-	return false;
+	return false; // TODO
 }
 
 void FreescapeEngine::initGameState() {
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 65ac462d344..b3c877338cb 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -206,7 +206,7 @@ public:
 	virtual void initGameState();
 	StateVars _gameStateVars;
 	StateBits _gameStateBits;
-	bool checkIfGameEnded();
+	virtual bool checkIfGameEnded();
 
 	bool hasFeature(EngineFeature f) const override;
 	bool canLoadGameStateCurrently() override { return true; }
@@ -221,6 +221,8 @@ public:
 	DrillerEngine(OSystem *syst);
 
 	void initGameState() override;
+	bool checkIfGameEnded() override;
+
 	void loadAssets() override;
 	void drawUI() override;
 
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index b01bea700da..94947f81ef0 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -226,4 +226,17 @@ void DrillerEngine::initGameState() {
 	_gameStateVars[k8bitVariableShield] = 48;
 }
 
+bool DrillerEngine::checkIfGameEnded() {
+	if (_gameStateVars[k8bitVariableShield] == 0) {
+		_flyMode = true;
+		gotoArea(127, 0);
+		drawFrame();
+		_gfx->flipBuffer();
+		g_system->updateScreen();
+		g_system->delayMillis(5000);
+		return true;
+	}
+	return false;
+}
+
 } // End of namespace Freescape
\ No newline at end of file


Commit: 855fe6dec8c15692b21557316fc6dc60da4cc8e1
    https://github.com/scummvm/scummvm/commit/855fe6dec8c15692b21557316fc6dc60da4cc8e1
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:11+01:00

Commit Message:
FREESCAPE: basic font rendering for eclipse

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/driller.cpp
    engines/freescape/games/eclipse.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 14c1980d192..49a56f46427 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -576,16 +576,16 @@ bool FreescapeEngine::hasFeature(EngineFeature f) const {
 		   (f == kSupportsSavingDuringRuntime);
 }
 
-void FreescapeEngine::drawStringInSurface(const Common::String &str, int x, int y, uint32 color, Graphics::Surface *surface) {
+void FreescapeEngine::drawStringInSurface(const Common::String &str, int x, int y, uint32 fontColor, uint32 backColor, Graphics::Surface *surface) {
 	Common::String ustr = str;
 	ustr.toUppercase();
 	for (uint32 c = 0; c < ustr.size(); c++) {
 		for (int j = 0; j < 6; j++) {
 			for (int i = 0; i < 8; i++) {
 				if (_font.get(48*(ustr[c] - 32) + 1 + j*8 + i))
-					surface->setPixel(x + 8 - i + 8*c, y + j, color);
+					surface->setPixel(x + 8 - i + 8*c, y + j, fontColor);
 				else
-					surface->setPixel(x + 8 - i + 8*c, y + j, 0x000000FF);  // black
+					surface->setPixel(x + 8 - i + 8*c, y + j, backColor);
 
 			}
 		}
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index b3c877338cb..510c8a07962 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -199,7 +199,7 @@ public:
 	Common::StringArray _currentAreaMessages;
 	Common::StringArray _currentEphymeralMessages;
 	Common::BitArray _font;
-	void drawStringInSurface(const Common::String &str, int x, int y, uint32 color, Graphics::Surface *surface);
+	void drawStringInSurface(const Common::String &str, int x, int y, uint32 fontColor, uint32 backColor, Graphics::Surface *surface);
 
 
 	// Game state
@@ -244,6 +244,8 @@ public:
 	EclipseEngine(OSystem *syst);
 
 	void loadAssets() override;
+
+	void drawUI() override;
 };
 
 class CastleEngine : public FreescapeEngine {
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 94947f81ef0..fa1e9fd95a0 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -69,9 +69,10 @@ void DrillerEngine::drawUI() {
 		surface->fillRect(_fullscreenViewArea, 0xA0A0A0FF);
 
 		uint32 yellow = 0xFFFF55FF;
+		uint32 black = 0x000000FF;
 
-		drawStringInSurface(_currentAreaMessages[0], 197, 177, yellow, surface);
-		drawStringInSurface(_currentAreaMessages[1], 197, 185, yellow, surface);
+		drawStringInSurface(_currentAreaMessages[0], 197, 177, yellow, black, surface);
+		drawStringInSurface(_currentAreaMessages[1], 197, 185, yellow, black, surface);
 
 		Texture *texture = _gfx->createTexture(surface);
 		_gfx->drawTexturedRect2D(_fullscreenViewArea, _fullscreenViewArea, texture);
diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index 5f08fe833cd..7e01851f406 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -89,5 +89,29 @@ void EclipseEngine::loadAssets() {
 
 }
 
+void EclipseEngine::drawUI() {
+	_gfx->renderCrossair(0);
+
+	if (_currentAreaMessages.size() == 2) {
+		_gfx->setViewport(_fullscreenViewArea);
+
+		Graphics::Surface *surface = new Graphics::Surface();
+		surface->create(_screenW, _screenH, _gfx->_currentPixelFormat);
+		surface->fillRect(_fullscreenViewArea, 0xA0A0A0FF);
+
+		uint32 yellow = 0xFFFF55FF;
+		uint32 black = 0x000000FF;
+
+		drawStringInSurface(_currentAreaMessages[1], 102, 135, black, yellow, surface);
+
+		Texture *texture = _gfx->createTexture(surface);
+		_gfx->drawTexturedRect2D(_fullscreenViewArea, _fullscreenViewArea, texture);
+		surface->free();
+		delete surface;
+	}
+
+	_gfx->setViewport(_viewArea);
+}
+
 
 } // End of namespace Freescape
\ No newline at end of file


Commit: 2d637044e9169bc645d6fcc238eeb25ec81b2a78
    https://github.com/scummvm/scummvm/commit/2d637044e9169bc645d6fcc238eeb25ec81b2a78
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:11+01:00

Commit Message:
FREESCAPE: show score for driller and eclipse

Changed paths:
    engines/freescape/games/driller.cpp
    engines/freescape/games/eclipse.cpp


diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index fa1e9fd95a0..4ecec6d34da 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -68,11 +68,14 @@ void DrillerEngine::drawUI() {
 		surface->create(_screenW, _screenH, _gfx->_currentPixelFormat);
 		surface->fillRect(_fullscreenViewArea, 0xA0A0A0FF);
 
+		int score = _gameStateVars[k8bitVariableScore];
+
 		uint32 yellow = 0xFFFF55FF;
 		uint32 black = 0x000000FF;
 
 		drawStringInSurface(_currentAreaMessages[0], 197, 177, yellow, black, surface);
 		drawStringInSurface(_currentAreaMessages[1], 197, 185, yellow, black, surface);
+		drawStringInSurface(Common::String::format("%07d", score), 240, 129, yellow, black, surface);
 
 		Texture *texture = _gfx->createTexture(surface);
 		_gfx->drawTexturedRect2D(_fullscreenViewArea, _fullscreenViewArea, texture);
diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index 7e01851f406..3edca3fa0f2 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -23,6 +23,7 @@
 #include "common/file.h"
 
 #include "freescape/freescape.h"
+#include "freescape/language/8bitDetokeniser.h"
 
 namespace Freescape {
 
@@ -99,10 +100,13 @@ void EclipseEngine::drawUI() {
 		surface->create(_screenW, _screenH, _gfx->_currentPixelFormat);
 		surface->fillRect(_fullscreenViewArea, 0xA0A0A0FF);
 
+		int score = _gameStateVars[k8bitVariableScore];
 		uint32 yellow = 0xFFFF55FF;
 		uint32 black = 0x000000FF;
+		uint32 white = 0xFFFFFFFF;
 
 		drawStringInSurface(_currentAreaMessages[1], 102, 135, black, yellow, surface);
+		drawStringInSurface(Common::String::format("%07d", score), 136, 6, black, white, surface);
 
 		Texture *texture = _gfx->createTexture(surface);
 		_gfx->drawTexturedRect2D(_fullscreenViewArea, _fullscreenViewArea, texture);


Commit: b9ebb7970b3a612b9a6ec9457678dbb6f5e500f4
    https://github.com/scummvm/scummvm/commit/b9ebb7970b3a612b9a6ec9457678dbb6f5e500f4
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:11+01:00

Commit Message:
FREESCAPE: show position in driller ui

Changed paths:
    engines/freescape/games/driller.cpp


diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 4ecec6d34da..5e7fab3bdd4 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -75,6 +75,11 @@ void DrillerEngine::drawUI() {
 
 		drawStringInSurface(_currentAreaMessages[0], 197, 177, yellow, black, surface);
 		drawStringInSurface(_currentAreaMessages[1], 197, 185, yellow, black, surface);
+		drawStringInSurface(Common::String::format("%04d", 2 * int(_position.x())), 150, 145, yellow, black, surface);
+		drawStringInSurface(Common::String::format("%04d", 2 * int(_position.z())), 150, 153, yellow, black, surface);
+		drawStringInSurface(Common::String::format("%04d", 2 * int(_position.y())), 150, 161, yellow, black, surface);
+
+
 		drawStringInSurface(Common::String::format("%07d", score), 240, 129, yellow, black, surface);
 
 		Texture *texture = _gfx->createTexture(surface);


Commit: ad6cbcca05b680e6af2234075e70d26b63af390a
    https://github.com/scummvm/scummvm/commit/ad6cbcca05b680e6af2234075e70d26b63af390a
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:11+01:00

Commit Message:
FREESCAPE: specialized gotoArea function for driller and eclipse

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/driller.cpp
    engines/freescape/games/eclipse.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 49a56f46427..f7d0149cd7a 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -531,12 +531,8 @@ void FreescapeEngine::gotoArea(uint16 areaID, int entranceID) {
 	if (entranceID > 0 || areaID == 127) {
 		entrance = (Entrance*) _currentArea->entranceWithID(entranceID);
 
-		if (!entrance) {
-			assert(_entranceTable.contains(entranceID));
-			const entrancesTableEntry *entry = _entranceTable[entranceID];
-			_position = scale * Math::Vector3d(entry->position[0], entry->position[1], entry->position[2]);
-		} else
-			_position = entrance->getOrigin();
+		assert(entrance);
+		_position = entrance->getOrigin();
 
 		if (_rotation == Math::Vector3d(0, 0, 0)) {
 			_rotation = entrance->getRotation();
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 510c8a07962..4abbebde7ac 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -106,7 +106,7 @@ public:
 	Area *_currentArea;
 	Math::Vector3d _scale;
 
-	void gotoArea(uint16 areaID, int entranceID);
+	virtual void gotoArea(uint16 areaID, int entranceID);
 	// Entrance
 	uint16 _startEntrance;
 	Common::HashMap<int, const struct entrancesTableEntry*> _entranceTable;
@@ -223,6 +223,8 @@ public:
 	void initGameState() override;
 	bool checkIfGameEnded() override;
 
+	void gotoArea(uint16 areaID, int entranceID) override;
+
 	void loadAssets() override;
 	void drawUI() override;
 
@@ -245,6 +247,8 @@ public:
 
 	void loadAssets() override;
 
+	void gotoArea(uint16 areaID, int entranceID) override;
+
 	void drawUI() override;
 };
 
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 5e7fab3bdd4..18e93e6c9b6 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -35,6 +35,66 @@ DrillerEngine::DrillerEngine(OSystem *syst) : FreescapeEngine(syst) {
 	_playerDepth = 32;
 }
 
+void DrillerEngine::gotoArea(uint16 areaID, int entranceID) {
+	debugC(1, kFreescapeDebugMove, "Jumping to area: %d, entrance: %d", areaID, entranceID);
+	if (!_gameStateBits.contains(areaID))
+		_gameStateBits[areaID] = 0;
+
+	assert(_areaMap.contains(areaID));
+	_currentArea = _areaMap[areaID];
+	_currentArea->show();
+
+	_currentAreaMessages.clear();
+	if (_currentArea->gasPocketRadius > 0)
+		_currentAreaMessages.push_back(_messagesList[1]);
+	else
+		_currentAreaMessages.push_back(_messagesList[2]);
+
+	_currentAreaMessages.push_back(_currentArea->name);
+
+	int scale = _currentArea->getScale();
+	assert(scale > 0);
+
+	Entrance *entrance = nullptr;
+	if (entranceID > 0 || areaID == 127) {
+		entrance = (Entrance*) _currentArea->entranceWithID(entranceID);
+		assert(entrance);
+
+		_position = entrance->getOrigin();
+
+		if (_rotation == Math::Vector3d(0, 0, 0)) {
+			_rotation = entrance->getRotation();
+			_pitch = _rotation.x();
+			_yaw = _rotation.y() - 260;
+		}
+		debugC(1, kFreescapeDebugMove, "entrace position: %f %f %f", _position.x(), _position.y(), _position.z());
+		debugC(1, kFreescapeDebugMove, "player height: %d", scale * _playerHeight);
+		_position.setValue(1, _position.y() + scale * _playerHeight);
+	} else if (entranceID == 0) {
+		Math::Vector3d diff = _lastPosition - _position;
+		debug("dif: %f %f %f", diff.x(), diff.y(), diff.z());
+		// diff should be used to determinate which entrance to use
+		int newPos = -1;
+		if (abs(diff.x()) < abs(diff.z())) {
+			if (diff.z() > 0)
+				newPos = 4000;
+			else
+				newPos = 100;
+			_position.setValue(2, newPos);
+		} else {
+			if (diff.x() > 0)
+				newPos = 4000;
+			else
+				newPos = 100;
+			_position.setValue(0, newPos);
+		}
+		assert(newPos != -1);
+	}
+
+	debugC(1, kFreescapeDebugMove, "starting player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
+}
+
+
 void DrillerEngine::loadAssets() {
 	Common::SeekableReadStream *file = nullptr;
 	Common::String path = ConfMan.get("path");
@@ -73,8 +133,8 @@ void DrillerEngine::drawUI() {
 		uint32 yellow = 0xFFFF55FF;
 		uint32 black = 0x000000FF;
 
-		drawStringInSurface(_currentAreaMessages[0], 197, 177, yellow, black, surface);
-		drawStringInSurface(_currentAreaMessages[1], 197, 185, yellow, black, surface);
+		drawStringInSurface(_currentAreaMessages[0], 196, 177, yellow, black, surface);
+		drawStringInSurface(_currentAreaMessages[1], 196, 185, yellow, black, surface);
 		drawStringInSurface(Common::String::format("%04d", 2 * int(_position.x())), 150, 145, yellow, black, surface);
 		drawStringInSurface(Common::String::format("%04d", 2 * int(_position.z())), 150, 153, yellow, black, surface);
 		drawStringInSurface(Common::String::format("%04d", 2 * int(_position.y())), 150, 161, yellow, black, surface);
diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index 3edca3fa0f2..ee2d6b4b5bb 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -90,29 +90,66 @@ void EclipseEngine::loadAssets() {
 
 }
 
-void EclipseEngine::drawUI() {
-	_gfx->renderCrossair(0);
+void EclipseEngine::gotoArea(uint16 areaID, int entranceID) {
+	debugC(1, kFreescapeDebugMove, "Jumping to area: %d, entrance: %d", areaID, entranceID);
+	if (!_gameStateBits.contains(areaID))
+		_gameStateBits[areaID] = 0;
 
-	if (_currentAreaMessages.size() == 2) {
-		_gfx->setViewport(_fullscreenViewArea);
+	assert(_areaMap.contains(areaID));
+	_currentArea = _areaMap[areaID];
+	_currentArea->show();
 
-		Graphics::Surface *surface = new Graphics::Surface();
-		surface->create(_screenW, _screenH, _gfx->_currentPixelFormat);
-		surface->fillRect(_fullscreenViewArea, 0xA0A0A0FF);
+	_currentAreaMessages.clear();
+	_currentAreaMessages.push_back(_currentArea->name);
 
-		int score = _gameStateVars[k8bitVariableScore];
-		uint32 yellow = 0xFFFF55FF;
-		uint32 black = 0x000000FF;
-		uint32 white = 0xFFFFFFFF;
+	int scale = _currentArea->getScale();
+	assert(scale > 0);
 
-		drawStringInSurface(_currentAreaMessages[1], 102, 135, black, yellow, surface);
-		drawStringInSurface(Common::String::format("%07d", score), 136, 6, black, white, surface);
+	Entrance *entrance = nullptr;
+	assert(entranceID > 0);
 
-		Texture *texture = _gfx->createTexture(surface);
-		_gfx->drawTexturedRect2D(_fullscreenViewArea, _fullscreenViewArea, texture);
-		surface->free();
-		delete surface;
+	entrance = (Entrance*) _currentArea->entranceWithID(entranceID);
+
+	if (!entrance) {
+		assert(_entranceTable.contains(entranceID));
+		const entrancesTableEntry *entry = _entranceTable[entranceID];
+		_position = scale * Math::Vector3d(entry->position[0], entry->position[1], entry->position[2]);
+	} else
+		_position = entrance->getOrigin();
+
+	if (_rotation == Math::Vector3d(0, 0, 0)) {
+		_rotation = entrance->getRotation();
+		_pitch = _rotation.x();
+		_yaw = _rotation.y() - 260;
 	}
+	debugC(1, kFreescapeDebugMove, "entrace position: %f %f %f", _position.x(), _position.y(), _position.z());
+	debugC(1, kFreescapeDebugMove, "player height: %d", scale * _playerHeight);
+	_position.setValue(1, _position.y() + scale * _playerHeight);
+	debugC(1, kFreescapeDebugMove, "starting player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
+}
+
+
+void EclipseEngine::drawUI() {
+	_gfx->renderCrossair(0);
+	_gfx->setViewport(_fullscreenViewArea);
+
+	Graphics::Surface *surface = new Graphics::Surface();
+	surface->create(_screenW, _screenH, _gfx->_currentPixelFormat);
+	surface->fillRect(_fullscreenViewArea, 0xA0A0A0FF);
+
+	int score = _gameStateVars[k8bitVariableScore];
+	uint32 yellow = 0xFFFF55FF;
+	uint32 black = 0x000000FF;
+	uint32 white = 0xFFFFFFFF;
+
+	if (!_currentAreaMessages.empty())
+		drawStringInSurface(_currentAreaMessages[0], 102, 135, black, yellow, surface);
+	drawStringInSurface(Common::String::format("%07d", score), 136, 6, black, white, surface);
+
+	Texture *texture = _gfx->createTexture(surface);
+	_gfx->drawTexturedRect2D(_fullscreenViewArea, _fullscreenViewArea, texture);
+	surface->free();
+	delete surface;
 
 	_gfx->setViewport(_viewArea);
 }


Commit: 9e1afc82d08f4df0ece11a75ced0fca9d0b87758
    https://github.com/scummvm/scummvm/commit/9e1afc82d08f4df0ece11a75ced0fca9d0b87758
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:12+01:00

Commit Message:
FREESCAPE: print text instruction for eclipse

Changed paths:
    engines/freescape/freescape.h
    engines/freescape/games/eclipse.cpp
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/language/instruction.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 4abbebde7ac..ee317130afb 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -175,6 +175,7 @@ public:
 	bool executeEndIfBitNotEqual(FCLInstruction &instruction);
 	bool executeEndIfVisibilityIsNotEqual(FCLInstruction &instruction);
 	void executeSwapJet(FCLInstruction &instruction);
+	void executePrint(FCLInstruction &instruction);
 
 	// Sound
 	Audio::SoundHandle _speakerHandle;
@@ -194,7 +195,7 @@ public:
 
 	// Text messages and Fonts
 	Common::StringArray _messagesList;
-	void loadMessages(Common::SeekableReadStream *file, int offset, int number);
+	void loadMessages(Common::SeekableReadStream *file, int offset, int size, int number);
 	void loadFonts(Common::SeekableReadStream *file, int offset);
 	Common::StringArray _currentAreaMessages;
 	Common::StringArray _currentEphymeralMessages;
diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index ee2d6b4b5bb..bad6d21c559 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -53,6 +53,28 @@ static const entrancesTableEntry rawEntranceTable[] = {
 	{0, {0, 0, 0}},        // NULL
 };
 
+static const char* rawMessagesTable[] = {
+	"HEART  FAILURE",
+	"SUN ECLIPSED",
+	"CRUSHED TO DEATH",
+	"FATAL FALL",
+	"CURSE OVERCOME",
+	"TOTAL ECLIPSE",
+	"TOO HOT TO REST!",
+	"RESTING...",
+	" ANKH FOUND ",
+	"WAY  BLOCKED",
+	"5 ANKHS REQUIRED",
+	"$2M REWARD",
+	"MAKE THE MATCH",
+	"TOUCH TO COLLECT",
+	"NO ENTRY",
+	"REMOVE LID",
+	"POISON AIR",
+	"MATCH MADE",
+	NULL
+};
+
 EclipseEngine::EclipseEngine(OSystem *syst) : FreescapeEngine(syst) {
 	_viewArea = Common::Rect(40, 32, 280, 132);
 	_playerHeight = 48;
@@ -64,6 +86,14 @@ EclipseEngine::EclipseEngine(OSystem *syst) : FreescapeEngine(syst) {
 		_entranceTable[entry->id] = entry;
 		entry++;
 	}
+
+	const char **messagePtr = rawMessagesTable;
+	while (*messagePtr) {
+		Common::String message(*messagePtr);
+		_messagesList.push_back(message);
+		debug("%s", message.c_str());
+		messagePtr++;
+	}
 }
 
 void EclipseEngine::loadAssets() {
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index ed19c77205f..a216b6add56 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -263,7 +263,8 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			break;
 
 		case 34: // show a message on screen
-			detokenisedStream += "MESSAGE (";
+			detokenisedStream += "PRINT (";
+			currentInstruction = FCLInstruction(Token::PRINT);
 			break;
 
 		case 12:
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index 5bf16e8cad6..aa05b2f4fdb 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -153,6 +153,9 @@ void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool co
 			case Token::CLEARBIT:
 			executeClearBit(instruction);
 			break;
+			case Token::PRINT:
+			executePrint(instruction);
+			break;
 			case Token::BITNOTEQ:
 			if (executeEndIfBitNotEqual(instruction))
 				ip = codeSize;
@@ -185,6 +188,13 @@ void FreescapeEngine::executeDelay(FCLInstruction &instruction) {
 	g_system->delayMillis(20 * delay);
 }
 
+void FreescapeEngine::executePrint(FCLInstruction &instruction) {
+	uint16 index = instruction.source - 1;
+	debugC(1, kFreescapeDebugCode, "Printing message %d", index);
+	_currentAreaMessages.clear();
+	_currentAreaMessages.push_back(_messagesList[index]);
+}
+
 bool FreescapeEngine::executeEndIfVisibilityIsNotEqual(FCLInstruction &instruction) {
 	uint16 source = instruction.source;
 	uint16 additional = instruction.additional;
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 4e6dd4af587..91f57147184 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -398,8 +398,9 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 
 	if (isEclipse()) {
 		loadFonts(file, 0xd403);
+		//loadMessages(file, 0x7110, 17, 20);
 	} else if (isDriller()) {
-		loadMessages(file, 0x4135, 20);
+		loadMessages(file, 0x4135, 14, 20);
 		loadFonts(file, 0x99dd);
 
 		ObjectMap *globalObjectsByID = new ObjectMap;
@@ -468,14 +469,13 @@ void FreescapeEngine::loadFonts(Common::SeekableReadStream *file, int offset) {
 	_font.set_bits((byte *)font);
 }
 
-void FreescapeEngine::loadMessages(Common::SeekableReadStream *file, int offset, int number) {
+void FreescapeEngine::loadMessages(Common::SeekableReadStream *file, int offset, int size, int number) {
 	file->seek(offset);
-	int messageSize = 14;
-	byte *buffer = (byte *)malloc(messageSize + 1);
-	buffer[14] = NULL;
+	byte *buffer = (byte *)malloc(size + 1);
+	buffer[size] = NULL;
 
 	for (int i = 0; i < number; i++) {
-		file->read(buffer, messageSize);
+		file->read(buffer, size);
 		Common::String message = (const char*) buffer;
 		_messagesList.push_back(message);
 		debug("%s", _messagesList[i].c_str());


Commit: f66b8b90c71d546387f9e0fdde887f67ccdc4f4c
    https://github.com/scummvm/scummvm/commit/f66b8b90c71d546387f9e0fdde887f67ccdc4f4c
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:12+01:00

Commit Message:
FREESCAPE: added freescape.dat to dists

Changed paths:
  A dists/engine-data/freescape.dat
    Makefile.common
    dists/irix/scummvm.idb
    dists/scummvm.rc
    dists/win32/migration.txt


diff --git a/Makefile.common b/Makefile.common
index ae638f61a5a..c8ad209e463 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -461,6 +461,9 @@ endif
 ifdef ENABLE_XEEN
 DIST_FILES_ENGINEDATA+=xeen.ccs
 endif
+ifdef ENABLE_FREESCAPE
+DIST_FILES_ENGINEDATA+=freescape.dat
+endif
 ifdef USE_FREETYPE2
 DIST_FILES_ENGINEDATA+=fonts.dat
 endif
diff --git a/dists/engine-data/freescape.dat b/dists/engine-data/freescape.dat
new file mode 100644
index 00000000000..6cd1b5013b1
Binary files /dev/null and b/dists/engine-data/freescape.dat differ
diff --git a/dists/irix/scummvm.idb b/dists/irix/scummvm.idb
index e4aab46ef8f..86800452485 100644
--- a/dists/irix/scummvm.idb
+++ b/dists/irix/scummvm.idb
@@ -37,6 +37,7 @@ f 0644 root sys usr/ScummVM/share/scummvm/titanic.dat titanic.dat scummvm.sw.eoe
 f 0644 root sys usr/ScummVM/share/scummvm/tony.dat tony.dat scummvm.sw.eoe
 f 0644 root sys usr/ScummVM/share/scummvm/toon.dat toon.dat scummvm.sw.eoe
 f 0644 root sys usr/ScummVM/share/scummvm/ultima.dat ultima.dat scummvm.sw.eoe
+f 0644 root sys usr/ScummVM/share/scummvm/freescape.dat freescape.dat scummvm.sw.eoe
 f 0644 root sys usr/ScummVM/share/scummvm/wintermute.zip wintermute.zip scummvm.sw.eoe
 f 0644 root sys usr/ScummVM/share/scummvm/xeen.ccs xeen.ccs scummvm.sw.eoe
 f 0644 root sys usr/ScummVM/share/scummvm/pred.dic pred.dic scummvm.sw.eoe
diff --git a/dists/scummvm.rc b/dists/scummvm.rc
index 693eb788281..50c879a0537 100644
--- a/dists/scummvm.rc
+++ b/dists/scummvm.rc
@@ -30,6 +30,9 @@ encoding.dat           FILE    "dists/engine-data/encoding.dat"
 
 // Engine or feature specific resources
 #ifdef BUILTIN_RESOURCES
+#if PLUGIN_ENABLED_STATIC(FREESCAPE)
+freescape.dat              FILE    "dists/engine-data/freescape.dat"
+#endif
 #if PLUGIN_ENABLED_STATIC(GRIM)
 grim-patch.lab         FILE    "dists/engine-data/grim-patch.lab"
 monkey4-patch.m4b      FILE    "dists/engine-data/monkey4-patch.m4b"
diff --git a/dists/win32/migration.txt b/dists/win32/migration.txt
index 852b95321e5..00fe4d99a16 100644
--- a/dists/win32/migration.txt
+++ b/dists/win32/migration.txt
@@ -11,6 +11,7 @@ COPYING.GLAD
 COPYING.txt
 COPYRIGHT.txt
 drascula.dat
+freescape.dat
 hadesch_translations.dat
 hugo.dat
 kyra.dat


Commit: 09885b6a052da6781653b7c1213de9060c7e4b5d
    https://github.com/scummvm/scummvm/commit/09885b6a052da6781653b7c1213de9060c7e4b5d
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:12+01:00

Commit Message:
FREESCAPE: load border bmps from data bundle

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index f7d0149cd7a..d592d405c3f 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -23,6 +23,7 @@
 #include "common/events.h"
 #include "common/file.h"
 #include "common/math.h"
+#include "common/unzip.h"
 #include "graphics/cursorman.h"
 
 #include "freescape/freescape.h"
@@ -226,6 +227,8 @@ Common::Error FreescapeEngine::run() {
 	_gfx->clear();
 
 	// Load game data and init game state
+	loadDataBundle();
+	loadBorder();
 	loadAssets();
 	initGameState();
 	// Simple main event loop
@@ -667,4 +670,11 @@ Common::Error FreescapeEngine::saveGameStream(Common::WriteStream *stream, bool
 	return Common::kNoError;
 }
 
+void FreescapeEngine::loadDataBundle() {
+	_dataBundle = Common::makeZipArchive(FREESCAPE_DATA_BUNDLE);
+	if (!_dataBundle) {
+			error("ENGINE: Couldn't load data bundle '%s'.", FREESCAPE_DATA_BUNDLE.c_str());
+	}
+}
+
 } // namespace Freescape
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index ee317130afb..6c8b556cf93 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -41,6 +41,8 @@ namespace Freescape {
 
 class Renderer;
 
+#define FREESCAPE_DATA_BUNDLE Common::String("freescape.dat")
+
 enum CameraMovement {
     FORWARD,
     BACKWARD,
@@ -89,13 +91,17 @@ public:
 	virtual void drawUI();
 	Texture *_borderTexture;
 
-	// Parsing
+	// Parsing assets
 	uint8 _binaryBits;
 	virtual void loadAssets();
+	Common::Archive *_dataBundle;
+	void loadDataBundle();
+	void loadBorder();
+
+	// 16-bit
 	void load16bitBinary(Common::SeekableReadStream *file);
 
-	// 8-bits
-	//ObjectMap globalObjectsByID;
+	// 8-bit
 	void load8bitBinary(Common::SeekableReadStream *file, int offset, int ncolors);
 	Area *load8bitArea(Common::SeekableReadStream *file, uint16 ncolors);
 	Object *load8bitObject(Common::SeekableReadStream *file);
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 91f57147184..505a6a9cd80 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -346,16 +346,6 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 }
 
 void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offset, int ncolors) {
-	Image::BitmapDecoder decoder;
-	Common::File borderFile;
-
-	if ((_renderMode == "ega" && borderFile.open("ega.bmp")) ||
-	    (_renderMode == "cga" && borderFile.open("cga.bmp"))) {
-		decoder.loadStream(borderFile);
-		_border = new Graphics::Surface();
-		_border->copyFrom(*decoder.getSurface());
-	}
-
 	file->seek(offset);
 	uint8 numberOfAreas = file->readByte();
 	uint16 dbSize = file->readUint16LE();
@@ -459,6 +449,19 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	_binaryBits = 8;
 }
 
+void FreescapeEngine::loadBorder() {
+	Image::BitmapDecoder decoder;
+	Common::String borderFilename = _targetName + "_" + _renderMode + ".bmp";
+
+	if (_dataBundle->hasFile(borderFilename)) {
+		Common::SeekableReadStream *borderFile = _dataBundle->createReadStreamForMember(borderFilename);
+		decoder.loadStream(*borderFile);
+		_border = new Graphics::Surface();
+		_border->copyFrom(*decoder.getSurface());
+	} else
+		debugC(1, kFreescapeDebugParser, "Missing border file '%s' in data bundle", borderFilename.c_str());
+}
+
 void FreescapeEngine::loadFonts(Common::SeekableReadStream *file, int offset) {
 	file->seek(offset);
 	int charNumber = 60;


Commit: 59a033a97481533409eb375c1a1da875d9bc65cc
    https://github.com/scummvm/scummvm/commit/59a033a97481533409eb375c1a1da875d9bc65cc
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:12+01:00

Commit Message:
FREESCAPE: initial prove and jet energy/shield in driller

Changed paths:
    engines/freescape/freescape.h
    engines/freescape/games/driller.cpp


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 6c8b556cf93..c00787f9938 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -227,6 +227,12 @@ class DrillerEngine : public FreescapeEngine {
 public:
 	DrillerEngine(OSystem *syst);
 
+	uint32 _initialJetEnergy;
+	uint32 _initialJetShield;
+
+	uint32 _initialProveEnergy;
+	uint32 _initialProveShield;
+
 	void initGameState() override;
 	bool checkIfGameEnded() override;
 
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 18e93e6c9b6..5086612e5c4 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -33,6 +33,11 @@ DrillerEngine::DrillerEngine(OSystem *syst) : FreescapeEngine(syst) {
 	_playerHeight = 64;
 	_playerWidth = 12;
 	_playerDepth = 32;
+
+	_initialProveEnergy = 48;
+	_initialProveShield = 50;
+	_initialJetEnergy = 29;
+	_initialJetShield = 34;
 }
 
 void DrillerEngine::gotoArea(uint16 areaID, int entranceID) {
@@ -291,8 +296,8 @@ void DrillerEngine::initGameState() {
 	for (AreaMap::iterator it = _areaMap.begin(); it != _areaMap.end(); ++it)
 		_gameStateBits[it->_key] = 0;
 
-	_gameStateVars[k8bitVariableEnergy] = 43;
-	_gameStateVars[k8bitVariableShield] = 48;
+	_gameStateVars[k8bitVariableEnergy] = _initialProveEnergy;
+	_gameStateVars[k8bitVariableShield] = _initialProveShield;
 }
 
 bool DrillerEngine::checkIfGameEnded() {


Commit: a2dce1f7bf8cc4dfc1089bfaedae6d004a2e3fbc
    https://github.com/scummvm/scummvm/commit/a2dce1f7bf8cc4dfc1089bfaedae6d004a2e3fbc
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:12+01:00

Commit Message:
FREESCAPE: improved handling of the palette used for the ega games

Changed paths:
    engines/freescape/freescape.h
    engines/freescape/games/palettes.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index c00787f9938..4766a1392ca 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -192,6 +192,8 @@ public:
 	Renderer *_gfx;
 	Common::String _renderMode;
 	Graphics::PixelBuffer *getPalette(uint8 areaNumber, uint8 c1, uint8 c2, uint8 c3, uint8 c4, uint16 ncolors);
+	Common::Array<byte*> _colorMap;
+	uint8 findColor(uint8 index);
 	void drawFrame();
 	uint8 _colorNumber;
 	Math::Vector3d _scaleVector;
diff --git a/engines/freescape/games/palettes.cpp b/engines/freescape/games/palettes.cpp
index a38ef6763d3..42cdf77f161 100644
--- a/engines/freescape/games/palettes.cpp
+++ b/engines/freescape/games/palettes.cpp
@@ -23,94 +23,39 @@
 
 namespace Freescape {
 
-byte drillerEGA[16][3] = {
-	{0x00, 0x00, 0x00},
+byte dos_EGA_palette[16][3] = {
 	{0x00, 0x00, 0x00},
+	{0x00, 0x00, 0xaa},
+	{0x00, 0xaa, 0x00},
 	{0x00, 0xaa, 0xaa},
+	{0xaa, 0x00, 0x00},
 	{0xaa, 0x00, 0xaa},
-	{0xff, 0xff, 0xff},
-	{0x55, 0x55, 0x55},
-	{0x00, 0x00, 0xaa},
 	{0xaa, 0x55, 0x00},
-	{0x12, 0xf3, 0x56},
-	{0xaa, 0x00, 0x00},
+	{0xaa, 0xaa, 0xaa},
+	{0x55, 0x55, 0x55},
+	{0x55, 0x55, 0xff},
+	{0x55, 0xff, 0x55},
+	{0x55, 0xff, 0xff},
+	{0xff, 0x55, 0x55},
 	{0xff, 0x55, 0xff},
-	{0x12, 0xf3, 0x56},
-	{0x12, 0xf3, 0x56},
-	{0x12, 0xf3, 0x56},
-	{0x12, 0xf3, 0x56},
-	{0x12, 0xf3, 0x56}
+	{0xff, 0xff, 0x55},
+	{0xff, 0xff, 0xff}
 };
 
-byte drillerCGA[4][3] = {
+byte dos_CGA_palette[4][3] = {
 	{0x00, 0x00, 0x00},
 	{0xff, 0xff, 0xff},
 	{0xa8, 0x00, 0xa8},
 	{0x00, 0xa8, 0xa8},
 };
 
-byte castleCGA[4][3] = {
-	{0x83, 0x85, 0x83},
-	{0x00, 0x00, 0x00},
-	{0x00, 0x85, 0x00},
-	{0xff, 0xfb, 0xff},
-};
-
-byte castleEGA[16][3] = {
-	{0x00, 0x00, 0x00},
-	{0x00, 0x00, 0x00},
-	{0x00, 0xaa, 0xaa},
-	{0x00, 0xaa, 0xaa},
-	{0xaa, 0xaa, 0xaa},
-	{0x55, 0x55, 0x55},
-	{0xaa, 0x00, 0x00},
-	{0x00, 0xaa, 0x00},
-	{0x12, 0xf3, 0x56},
-	{0xaa, 0x00, 0x00},
-	{0xff, 0x55, 0xff},
-	{0xaa, 0x55, 0x00},
-	{0xaa, 0x55, 0x00},
-	{0xaa, 0x55, 0x00},
-	{0x00, 0x00, 0xaa},
-	{0xaa, 0x55, 0x00}
-};
-
-byte eclipseEGA[16][3] = {
-	{0xfc, 0xfc, 0x54},
-	{0x00, 0x00, 0x00},
-	{0x54, 0xfc, 0xfc},
-	{0x00, 0xaa, 0xaa},
-	{0x00, 0xaa, 0x00},
-	{0x00, 0x00, 0xA8},
-	{0xff, 0x00, 0xaa},
-	{0xaa, 0x00, 0xaa},
-	{0x55, 0xff, 0xff},
-	{0x55, 0x55, 0xff},
-	{0x55, 0xff, 0x55},
-	{0xa8, 0x00, 0x00},
-	{0xff, 0x55, 0x55},
-	{0x54, 0x54, 0x54},
-	{0xa8, 0x54, 0x00},
-	{0xfc, 0xfc, 0x54}
-};
-
 Graphics::PixelBuffer *FreescapeEngine::getPalette(uint8 areaNumber, uint8 c1, uint8 c2, uint8 c3, uint8 c4, uint16 ncolors) {
 	Graphics::PixelFormat pixelFormat = Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0);
 	Graphics::PixelBuffer *palette = nullptr;
-	if (isDriller()) {
-		if (_renderMode == "ega")
-			palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&drillerEGA);
-		else if (_renderMode == "cga")
-			palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&drillerCGA);
-	} else if (isCastle()) {
-		if (_renderMode == "ega")
-			palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&castleEGA); // TODO
-		else if (_renderMode == "cga")
-			palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&castleCGA);
-	} else if (isEclipse()) {
-		palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&eclipseEGA);
-	} else
-		palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&drillerEGA);
+	if (_renderMode == "ega")
+		palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&dos_EGA_palette);
+	else if (_renderMode == "cga")
+		palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&dos_CGA_palette);
 
 	assert(palette);
 	return palette;
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 505a6a9cd80..82c4bd4f636 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -92,14 +92,14 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 			if (_renderMode == "cga")
 				entry = entry % 4; // TODO: use dithering
 
-			colours->push_back(entry);
+			colours->push_back(findColor(entry));
 			debugC(1, kFreescapeDebugParser, "color[%d] = %x", 2*colour, entry);
 
 			entry = data >> 4;
 			if (_renderMode == "cga")
 				entry = entry % 4; // TODO: use dithering
 
-			colours->push_back(entry);
+			colours->push_back(findColor(entry));
 			debugC(1, kFreescapeDebugParser, "color[%d] = %x", 2*colour+1, entry);
 			byteSizeOfObject--;
 		}
@@ -215,6 +215,28 @@ static const char *eclipseRoomName[] = {
 	"????????"
 };
 
+uint8 FreescapeEngine::findColor(uint8 index) {
+
+	if (index == 255 || index == 0)
+		return index;
+
+	byte *entry = _colorMap[index-1];
+	uint8 color = 0;
+	uint8 acc = 1;
+	for (int i = 0; i < 4; i++) {
+		byte b = *entry;
+		assert(b == 0 || b == 0xff);
+
+		if (b == 0xff)
+			color = color + acc;
+
+		acc = acc << 1;
+		entry++;
+	}
+	assert(color < 16);
+	return color;
+}
+
 Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 ncolors) {
 
 	Common::String name;
@@ -321,7 +343,7 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	uint8 numConditions = file->readByte();
 	debugC(1, kFreescapeDebugParser, "%d area conditions at %x of area %d", numConditions, base + cPtr, areaNumber);
 
-	Area *area = new Area(areaNumber, areaFlags, objectsByID, entrancesByID, scale, skyColor, groundColor, palette);
+	Area *area = new Area(areaNumber, areaFlags, objectsByID, entrancesByID, scale, findColor(skyColor), findColor(groundColor), palette);
 	area->name = name;
 	area->gasPocketPosition = Common::Point(32 * gasPocketX, 32 * gasPocketY);
 	area->gasPocketRadius = gasPocketRadius;
@@ -357,6 +379,32 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	uint8 startEntrance = file->readByte();
 	debugC(1, kFreescapeDebugParser, "Entrace area: %d", startEntrance);
 
+	file->seek(offset + 0xa);
+	debugC(1, kFreescapeDebugParser, "Color map:");
+
+	uint8 data;
+	for (int i = 0; i < 15; i++) {
+		byte *entry = (byte*) malloc(4 * sizeof(byte));;
+		data = file->readByte();
+		*entry = data;
+		entry++;
+		debugC(1, kFreescapeDebugParser, "%x", data);
+		data = file->readByte();
+		*entry = data;
+		entry++;
+		debugC(1, kFreescapeDebugParser, "%x", data);
+		data = file->readByte();
+		*entry = data;
+		entry++;
+		debugC(1, kFreescapeDebugParser, "%x", data);
+		data = file->readByte();
+		*entry = data;
+		debugC(1, kFreescapeDebugParser, "%x", data);
+		debugC(1, kFreescapeDebugParser, "---");
+		_colorMap.push_back(entry - 3);
+	}
+	//assert(0);
+
 	file->seek(offset + 0x46); // 0x46
 
 	uint16 globalSomething;


Commit: 3aceefa5afb10cc3a1d51dc48508d6f396dff26d
    https://github.com/scummvm/scummvm/commit/3aceefa5afb10cc3a1d51dc48508d6f396dff26d
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:12+01:00

Commit Message:
FREESCAPE: renamed and moved findColor

Changed paths:
    engines/freescape/freescape.h
    engines/freescape/games/palettes.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 4766a1392ca..46a255e0751 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -193,7 +193,7 @@ public:
 	Common::String _renderMode;
 	Graphics::PixelBuffer *getPalette(uint8 areaNumber, uint8 c1, uint8 c2, uint8 c3, uint8 c4, uint16 ncolors);
 	Common::Array<byte*> _colorMap;
-	uint8 findColor(uint8 index);
+	uint8 remapColor(uint8 index);
 	void drawFrame();
 	uint8 _colorNumber;
 	Math::Vector3d _scaleVector;
diff --git a/engines/freescape/games/palettes.cpp b/engines/freescape/games/palettes.cpp
index 42cdf77f161..15b1fa087a0 100644
--- a/engines/freescape/games/palettes.cpp
+++ b/engines/freescape/games/palettes.cpp
@@ -61,4 +61,28 @@ Graphics::PixelBuffer *FreescapeEngine::getPalette(uint8 areaNumber, uint8 c1, u
 	return palette;
 }
 
+
+uint8 FreescapeEngine::remapColor(uint8 index) {
+
+	if (index == 255 || index == 0)
+		return index;
+
+	byte *entry = _colorMap[index-1];
+	uint8 color = 0;
+	uint8 acc = 1;
+	for (int i = 0; i < 4; i++) {
+		byte b = *entry;
+		assert(b == 0 || b == 0xff);
+
+		if (b == 0xff)
+			color = color + acc;
+
+		acc = acc << 1;
+		entry++;
+	}
+	assert(color < 16);
+	return color;
+}
+
+
 } // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 82c4bd4f636..53600e2981d 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -92,14 +92,14 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 			if (_renderMode == "cga")
 				entry = entry % 4; // TODO: use dithering
 
-			colours->push_back(findColor(entry));
+			colours->push_back(remapColor(entry));
 			debugC(1, kFreescapeDebugParser, "color[%d] = %x", 2*colour, entry);
 
 			entry = data >> 4;
 			if (_renderMode == "cga")
 				entry = entry % 4; // TODO: use dithering
 
-			colours->push_back(findColor(entry));
+			colours->push_back(remapColor(entry));
 			debugC(1, kFreescapeDebugParser, "color[%d] = %x", 2*colour+1, entry);
 			byteSizeOfObject--;
 		}
@@ -215,28 +215,6 @@ static const char *eclipseRoomName[] = {
 	"????????"
 };
 
-uint8 FreescapeEngine::findColor(uint8 index) {
-
-	if (index == 255 || index == 0)
-		return index;
-
-	byte *entry = _colorMap[index-1];
-	uint8 color = 0;
-	uint8 acc = 1;
-	for (int i = 0; i < 4; i++) {
-		byte b = *entry;
-		assert(b == 0 || b == 0xff);
-
-		if (b == 0xff)
-			color = color + acc;
-
-		acc = acc << 1;
-		entry++;
-	}
-	assert(color < 16);
-	return color;
-}
-
 Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 ncolors) {
 
 	Common::String name;
@@ -343,7 +321,7 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	uint8 numConditions = file->readByte();
 	debugC(1, kFreescapeDebugParser, "%d area conditions at %x of area %d", numConditions, base + cPtr, areaNumber);
 
-	Area *area = new Area(areaNumber, areaFlags, objectsByID, entrancesByID, scale, findColor(skyColor), findColor(groundColor), palette);
+	Area *area = new Area(areaNumber, areaFlags, objectsByID, entrancesByID, scale, remapColor(skyColor), remapColor(groundColor), palette);
 	area->name = name;
 	area->gasPocketPosition = Common::Point(32 * gasPocketX, 32 * gasPocketY);
 	area->gasPocketRadius = gasPocketRadius;


Commit: 50e1e7e3f4e32a016e521b4483cac6443509b849
    https://github.com/scummvm/scummvm/commit/50e1e7e3f4e32a016e521b4483cac6443509b849
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:13+01:00

Commit Message:
FREESCAPE: refactored area constructor

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/loaders/16bitBinaryLoader.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index b1153785d60..e2c029a7b9d 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -56,24 +56,18 @@ uint8 Area::getScale() {
 	return scale;
 }
 
-Area::Area(
-	uint16 _areaID,
-	uint16 _areaFlags,
-	ObjectMap *_objectsByID,
-	ObjectMap *_entrancesByID,
-	uint8 _scale,
-	uint8 _skyColor,
-	uint8 _groundColor,
-	Graphics::PixelBuffer *_palette) {
-	scale = _scale;
-	palette = _palette;
-	skyColor = _skyColor;
-	groundColor = _groundColor;
+Area::Area(uint16 _areaID, uint16 _areaFlags, ObjectMap *_objectsByID, ObjectMap *_entrancesByID) {
 	areaID = _areaID;
 	areaFlags = _areaFlags;
 	objectsByID = _objectsByID;
 	entrancesByID = _entrancesByID;
 
+	scale = 0;
+	palette = 0;
+	skyColor = 255;
+	groundColor = 255;
+	gasPocketRadius = 0;
+
 	// create a list of drawable objects only
 	for (ObjectMap::iterator iterator = objectsByID->begin(); iterator != objectsByID->end(); iterator++) {
 		if (iterator->_value->isDrawable()) {
@@ -94,7 +88,6 @@ Area::Area(
 	} compareObjects;
 
 	Common::sort(drawableObjects.begin(), drawableObjects.end(), compareObjects);
-	gasPocketRadius = 0;
 }
 
 Area::~Area() {
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index a9dcd2cf0e0..ff9b7c5e617 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -36,15 +36,7 @@ typedef Common::HashMap<uint16, Object *> ObjectMap;
 
 class Area {
 public:
-	Area(
-		uint16 areaID,
-		uint16 areaFlags,
-		ObjectMap *objectsByID,
-		ObjectMap *entrancesByID,
-		uint8 scale,
-		uint8 skyColor,
-		uint8 groundColor,
-		Graphics::PixelBuffer *palette = nullptr);
+	Area(uint16 areaID, uint16 areaFlags, ObjectMap *objectsByID, ObjectMap *entrancesByID);
 	virtual ~Area();
 
 	Common::String name;
@@ -76,13 +68,14 @@ public:
 	Common::Point gasPocketPosition;
 	uint32 gasPocketRadius;
 
-private:
-	uint16 areaID;
-	uint16 areaFlags;
 	uint8 scale;
 	Graphics::PixelBuffer *palette;
 	uint8 skyColor;
 	uint8 groundColor;
+
+private:
+	uint16 areaID;
+	uint16 areaFlags;
 	ObjectMap *objectsByID;
 	ObjectMap *entrancesByID;
 	Common::Array<Object *> drawableObjects;
diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
index ac01b6e57ec..8c3a9befb02 100644
--- a/engines/freescape/loaders/16bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/16bitBinaryLoader.cpp
@@ -261,7 +261,12 @@ Area *load16bitArea(Common::SeekableReadStream *file) {
 		debug("%s", detokenise16bitCondition(conditionArray)->c_str());
 	}
 
-	return (new Area(areaNumber, areaFlags, objectsByID, entrancesByID, 1, skyColor, groundColor));
+	Area *area = new Area(areaNumber, areaFlags, objectsByID, entrancesByID);
+	area->scale = 1;
+	area->skyColor = skyColor;
+	area->groundColor = groundColor;
+
+	return area;
 }
 
 void FreescapeEngine::load16bitBinary(Common::SeekableReadStream *file) {
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 53600e2981d..5069ec7ea4f 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -321,8 +321,14 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	uint8 numConditions = file->readByte();
 	debugC(1, kFreescapeDebugParser, "%d area conditions at %x of area %d", numConditions, base + cPtr, areaNumber);
 
-	Area *area = new Area(areaNumber, areaFlags, objectsByID, entrancesByID, scale, remapColor(skyColor), remapColor(groundColor), palette);
+	Area *area = new Area(areaNumber, areaFlags, objectsByID, entrancesByID);
 	area->name = name;
+	area->scale = scale;
+	area->skyColor = remapColor(skyColor);
+	area->groundColor = remapColor(groundColor);
+	area->palette = palette;
+
+	// Driller specific
 	area->gasPocketPosition = Common::Point(32 * gasPocketX, 32 * gasPocketY);
 	area->gasPocketRadius = gasPocketRadius;
 
@@ -429,7 +435,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 			(*globalObjectsByID)[gobj->getObjectID()] = gobj;
 		}
 
-		_areaMap[255] = new Area(255, 0, globalObjectsByID, nullptr, 1, 255, 255, nullptr);
+		_areaMap[255] = new Area(255, 0, globalObjectsByID, nullptr);
 	}
 
 	file->seek(offset + 0xc8);


Commit: 3588fe7e8a2ed90013a1f3214dab83c3b6c11a5c
    https://github.com/scummvm/scummvm/commit/3588fe7e8a2ed90013a1f3214dab83c3b6c11a5c
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:13+01:00

Commit Message:
FREESCAPE: removed getFontCharacterRect function

Changed paths:
    engines/freescape/gfx.cpp
    engines/freescape/gfx.h


diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index 5d2daa7f139..5297d969d51 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -52,25 +52,6 @@ Graphics::Surface *Renderer::convertFromPalette(Graphics::PixelBuffer *rawsurf)
 	return surf;
 }
 
-Common::Rect Renderer::getFontCharacterRect(uint8 character) {
-	uint index = 0;
-
-	if (character == ' ')
-		index = 0;
-	else if (character >= '0' && character <= '9')
-		index = 1 + character - '0';
-	else if (character >= 'A' && character <= 'Z')
-		index = 1 + 10 + character - 'A';
-	else if (character == '|')
-		index = 1 + 10 + 26;
-	else if (character == '/')
-		index = 2 + 10 + 26;
-	else if (character == ':')
-		index = 3 + 10 + 26;
-
-	return Common::Rect(16 * index, 0, 16 * (index + 1), 32);
-}
-
 Common::Rect Renderer::viewport() const {
 	return _screenViewport;
 }
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 05aa2063af4..ddb8676d50e 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -131,7 +131,6 @@ protected:
 
 	Math::Frustum _frustum;
 
-	Common::Rect getFontCharacterRect(uint8 character);
 	Math::Matrix4 makeProjectionMatrix(float fov, float nearClipPlane, float farClipPlane) const;
 };
 


Commit: 6eeb8a371df0109ae944cbea23e66f3d384e0e06
    https://github.com/scummvm/scummvm/commit/6eeb8a371df0109ae944cbea23e66f3d384e0e06
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:13+01:00

Commit Message:
FREESCAPE: initial refact of palette and color map code

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/palettes.cpp
    engines/freescape/gfx.cpp
    engines/freescape/gfx.h
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index e2c029a7b9d..5af219ee316 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -155,9 +155,6 @@ void Area::saveObjects(Common::WriteStream *stream) {
 }
 
 void Area::draw(Freescape::Renderer *gfx) {
-	if (palette)
-		gfx->_palette = palette;
-
 	gfx->clear();
 	if (skyColor != 255) {
 		gfx->_keyColor = 0;
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index d592d405c3f..8c594d4d72c 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -231,6 +231,8 @@ Common::Error FreescapeEngine::run() {
 	loadBorder();
 	loadAssets();
 	initGameState();
+	loadColorPalette();
+
 	// Simple main event loop
 	_lastMousePos = Common::Point(0, 0);
 	_lastFrame = 0.f;
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 46a255e0751..49879beb00a 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -51,6 +51,7 @@ enum CameraMovement {
 };
 
 typedef Common::HashMap<uint16, Area*> AreaMap;
+typedef Common::Array<byte*> ColorMap;
 typedef Common::HashMap<uint16, int32> StateVars;
 typedef Common::HashMap<uint16, uint32> StateBits;
 
@@ -97,6 +98,7 @@ public:
 	Common::Archive *_dataBundle;
 	void loadDataBundle();
 	void loadBorder();
+	void loadColorPalette();
 
 	// 16-bit
 	void load16bitBinary(Common::SeekableReadStream *file);
@@ -192,7 +194,7 @@ public:
 	Renderer *_gfx;
 	Common::String _renderMode;
 	Graphics::PixelBuffer *getPalette(uint8 areaNumber, uint8 c1, uint8 c2, uint8 c3, uint8 c4, uint16 ncolors);
-	Common::Array<byte*> _colorMap;
+	ColorMap _colorMap;
 	uint8 remapColor(uint8 index);
 	void drawFrame();
 	uint8 _colorNumber;
diff --git a/engines/freescape/games/palettes.cpp b/engines/freescape/games/palettes.cpp
index 15b1fa087a0..4ba787e6820 100644
--- a/engines/freescape/games/palettes.cpp
+++ b/engines/freescape/games/palettes.cpp
@@ -49,19 +49,18 @@ byte dos_CGA_palette[4][3] = {
 	{0x00, 0xa8, 0xa8},
 };
 
-Graphics::PixelBuffer *FreescapeEngine::getPalette(uint8 areaNumber, uint8 c1, uint8 c2, uint8 c3, uint8 c4, uint16 ncolors) {
-	Graphics::PixelFormat pixelFormat = Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0);
+
+void FreescapeEngine::loadColorPalette() {
 	Graphics::PixelBuffer *palette = nullptr;
 	if (_renderMode == "ega")
-		palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&dos_EGA_palette);
+		palette = new Graphics::PixelBuffer(_gfx->_palettePixelFormat, (byte*)&dos_EGA_palette);
 	else if (_renderMode == "cga")
-		palette = new Graphics::PixelBuffer(pixelFormat, (byte*)&dos_CGA_palette);
+		palette = new Graphics::PixelBuffer(_gfx->_palettePixelFormat, (byte*)&dos_CGA_palette);
 
-	assert(palette);
-	return palette;
+	_gfx->_palette = palette;
+	_gfx->_colorMap = &_colorMap;
 }
 
-
 uint8 FreescapeEngine::remapColor(uint8 index) {
 
 	if (index == 255 || index == 0)
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index 5297d969d51..87158b1ae02 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -40,6 +40,8 @@ Renderer::Renderer(OSystem *system)
 	_originalPixelFormat = Graphics::PixelFormat::createFormatCLUT8();
 	_palettePixelFormat = Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0);
 	_keyColor = -1;
+	_palette = nullptr;
+	_colorMap = nullptr;
 }
 
 Renderer::~Renderer() {}
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index ddb8676d50e..1c235f69dbf 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -32,6 +32,8 @@
 
 namespace Freescape {
 
+typedef Common::Array<byte*> ColorMap;
+
 class Renderer;
 
 class Texture {
@@ -99,7 +101,8 @@ public:
 	virtual void drawFloor(uint8 color) = 0;
 
 	Common::Rect viewport() const;
-	Graphics::PixelBuffer *_palette = nullptr;
+	Graphics::PixelBuffer *_palette;
+	ColorMap *_colorMap;
 	int _keyColor;
 
 	/**
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 5069ec7ea4f..91eb970590e 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -256,7 +256,7 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 		groundColor = groundColor % 4;
 	}
 
-	Graphics::PixelBuffer *palette = getPalette(areaNumber, ci1, ci2, skyColor, groundColor, ncolors);
+	//Graphics::PixelBuffer *palette = getPalette(areaNumber, ci1, ci2, skyColor, groundColor, ncolors);
 
 	debugC(1, kFreescapeDebugParser, "Area %d", areaNumber);
 	debugC(1, kFreescapeDebugParser, "Flags: %d Objects: %d", areaFlags, numberOfObjects);
@@ -326,7 +326,6 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	area->scale = scale;
 	area->skyColor = remapColor(skyColor);
 	area->groundColor = remapColor(groundColor);
-	area->palette = palette;
 
 	// Driller specific
 	area->gasPocketPosition = Common::Point(32 * gasPocketX, 32 * gasPocketY);


Commit: 4c2293f25d42185896e47b91d1c202280329f9c5
    https://github.com/scummvm/scummvm/commit/4c2293f25d42185896e47b91d1c202280329f9c5
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:13+01:00

Commit Message:
FREESCAPE: initial implementation of freescape sounds using pc speaker

Changed paths:
  A engines/freescape/sound.cpp
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/module.mk


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 8c594d4d72c..bcbea2e6668 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -205,6 +205,7 @@ void FreescapeEngine::processInput() {
 }
 
 void FreescapeEngine::shoot() {
+	playSound(0);
 	_gfx->renderShoot(0);
 	Math::Vector3d direction = directionToVector(_pitch, _yaw);
 	Math::Ray ray(_position, direction);
@@ -426,6 +427,7 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 				return;
 			}
 			_position.set(_position.x(), positionY - fallen * areaScale, _position.z());
+			playSound(2);
 		}
 		debugC(1, kFreescapeDebugCode, "Runing effects:");
 		checkCollisions(true); // run the effects
@@ -438,6 +440,7 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 			else {
 				bool stepUp = tryStepUp(_position);
 				if (stepUp) {
+					playSound(1);
 					debugC(1, kFreescapeDebugCode, "Runing effects:");
 					checkCollisions(true); // run the effects (again)
 				} else {
@@ -593,13 +596,6 @@ void FreescapeEngine::drawStringInSurface(const Common::String &str, int x, int
 	}
 }
 
-void FreescapeEngine::playSound(int index) {
-	_mixer->stopAll();
-	debug("Playing sound %d", index);
-	Audio::PCSpeaker *speaker = new Audio::PCSpeaker();
-	speaker->play(Audio::PCSpeaker::kWaveFormSine, 2000, 100);
-	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_speakerHandle, speaker);
-}
 
 Common::Error FreescapeEngine::loadGameStream(Common::SeekableReadStream *stream) {
 
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 49879beb00a..0166595554b 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -188,6 +188,8 @@ public:
 	// Sound
 	Audio::SoundHandle _speakerHandle;
 	void playSound(int index);
+	void playSoundConst(double hzFreq, int duration);
+	void playSoundSweepIncWL(double hzFreq1, double hzFreq2, double wlStepPerMS, int resolution);
 
 	// Rendering
 	int _screenW, _screenH;
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index 730cf49627b..59391fff6a2 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -21,6 +21,7 @@ MODULE_OBJS := \
 	loaders/16bitBinaryLoader.o \
 	language/16bitDetokeniser.o \
 	language/instruction.o \
+	sound.o
 
 
 MODULE_DIRS += \
diff --git a/engines/freescape/sound.cpp b/engines/freescape/sound.cpp
new file mode 100644
index 00000000000..1af3280691b
--- /dev/null
+++ b/engines/freescape/sound.cpp
@@ -0,0 +1,108 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "freescape/freescape.h"
+
+namespace Freescape {
+
+// If step rate for playSoundSweepIncWL calls needs adjusting,
+// can tweak wlStepPerMS parameter by the factor below.
+const double kFreescapeSweepTuneFactor = 1.0;
+
+void FreescapeEngine::playSound(int index) {
+	_mixer->stopAll();
+	debug("Playing sound %d", index);
+	switch (index) {
+		case 0:
+			playSoundSweepIncWL(1500, 700, 5.46 * kFreescapeSweepTuneFactor, 1);
+		break;
+		case 1: // StairUp
+			playSoundConst(220, 50);
+			playSoundConst(340, 50);
+		break;
+		case 2: // StairDown
+			playSoundConst(220, 50);
+			playSoundConst(185, 50);
+		break;
+		default:
+		break;
+	}
+}
+
+void FreescapeEngine::playSoundConst(double hzFreq, int duration) {
+	Audio::PCSpeaker *speaker = new Audio::PCSpeaker();
+	speaker->setVolume(50);
+	speaker->play(Audio::PCSpeaker::kWaveFormSquare, hzFreq, duration);
+	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_speakerHandle, speaker);
+	_system->delayMillis(duration);
+	_mixer->stopHandle(_speakerHandle);
+}
+
+
+void FreescapeEngine::playSoundSweepIncWL(double hzFreq1, double hzFreq2, double wlStepPerMS, int resolution) {
+	// Play a PC speaker sweep between sound frequencies, using constant wavelength increment.
+
+	// The wavelength step-per-milliseconds value, or wlStepPerMS, describes how
+	// many PIT counter increments occur per millisecond.  This unusual metric is actually
+	// quite efficient when programming an 8086 without floating-point hardware, because
+	// the increment between counters sent to hardware can be a constant integer.
+
+	// The msResolution describes the time resolution used between frequency change events.
+	// If this is only 1 ms, frequency changes very rapidly (every millisecond).
+	// If less resolute, like 100 ms, frequency jumps less often, giving a more "racheted" sweep.
+
+	// The PIT hardware calculates frequencies as 1193180.0 / freq.
+	// Because the hardware only takes 16-bit integers as input, this can expect
+	// to cover nearly all audible frequencies with decent tonal accuracy.
+
+	// Frequencies that sweep using this algorithm will appear to advance slowly
+	// at lower frequencies and quickly at higher frequencies.
+
+	// The exact progression works like this:
+
+	// FreqNext = 1 / (1 / FreqOrig + wlStep / MagicNumber)
+
+	// ...where FreqOrig is the original frequency, FreqNext is the stepped-to frequency,
+	// wlStep is the PIT counter step value, and MagicNumber is 1193180.0.
+
+	// Option:  can round wlStep to integer to make more 16-bit-counter authentic.
+	double wlStep = wlStepPerMS * (double)resolution;
+
+	// Option:  can round inv1 and inv2 to integer to make more 16-bit-counter authentic.
+	double inv1 = 1193180.0 / hzFreq1;
+	double inv2 = 1193180.0 / hzFreq2;
+
+	// Set step to correct direction
+	if (inv1 < inv2 && wlStep < 0)
+		wlStep = -wlStep;
+	if (inv1 > inv2 && wlStep > 0)
+		wlStep = -wlStep;
+
+	// Loop over frequency range
+	int hzCounts = (int)((inv2 - inv1) / wlStep);
+	while (hzCounts-- >= 0) {
+		playSoundConst((1193180.0 / inv1), resolution);
+		inv1 += wlStep;
+	}
+	_mixer->stopHandle(_speakerHandle);
+}
+
+}
\ No newline at end of file


Commit: 75c4e8fdfc08c3b233b7199f389143024e7a84e5
    https://github.com/scummvm/scummvm/commit/75c4e8fdfc08c3b233b7199f389143024e7a84e5
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:13+01:00

Commit Message:
FREESCAPE: initial implementation of freescape sounds using prerecorded wavs

Changed paths:
    dists/engine-data/freescape.dat
    engines/freescape/detection.cpp
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/sound.cpp


diff --git a/dists/engine-data/freescape.dat b/dists/engine-data/freescape.dat
index 6cd1b5013b1..ffb60be86af 100644
Binary files a/dists/engine-data/freescape.dat and b/dists/engine-data/freescape.dat differ
diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index faf5988c552..26a427dd36d 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -21,10 +21,14 @@
 
 #include "base/plugins.h"
 #include "engines/advancedDetector.h"
+#include "common/translation.h"
 
 #include "freescape/freescape.h"
 
+#define GAMEOPTION_PRERECORDED_SOUNDS   GUIO_GAMEOPTIONS1
+
 namespace Freescape {
+
 static const PlainGameDescriptor freescapeGames[] = {
 	{"3dkit", "The 3D Kit Game"},
 	{"driller", "Driller"},
@@ -206,9 +210,25 @@ static const DebugChannelDef debugFlagList[] = {
 	DEBUG_CHANNEL_END
 };
 
+static const ADExtraGuiOptionsMap optionsList[] = {
+	{
+		GAMEOPTION_PRERECORDED_SOUNDS,
+		{
+			_s("Prerecorded sounds"),
+			_s("Use high-quality pre-recorded sounds instead of pc speaker emulation."),
+			"prerecorded_sounds",
+			true,
+			0,
+			0
+		}
+	},
+	AD_EXTRA_GUI_OPTIONS_TERMINATOR
+};
+
 class FreescapeMetaEngineDetection : public AdvancedMetaEngineDetection {
 public:
-	FreescapeMetaEngineDetection() : AdvancedMetaEngineDetection(Freescape::gameDescriptions, sizeof(ADGameDescription), Freescape::freescapeGames) {
+	FreescapeMetaEngineDetection() : AdvancedMetaEngineDetection(Freescape::gameDescriptions, sizeof(ADGameDescription), Freescape::freescapeGames, optionsList) {
+		_guiOptions = GUIO2(GUIO_NOMIDI, GAMEOPTION_PRERECORDED_SOUNDS);
 	}
 
 	const char *getEngineId() const override {
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index bcbea2e6668..c19ad9acf02 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -41,6 +41,9 @@ FreescapeEngine::FreescapeEngine(OSystem *syst)
 	else
 		_renderMode = ConfMan.get("render_mode");
 
+	if (!Common::parseBool(ConfMan.get("prerecorded_sounds"), _usePrerecordedSounds))
+		error("Failed to parse bool from prerecorded_sounds option");
+
 	_currentArea = nullptr;
 	_rotation = Math::Vector3d(0.f, 0.f, 0.f);
 	_position = Math::Vector3d(0.f, 0.f, 0.f);
@@ -205,7 +208,7 @@ void FreescapeEngine::processInput() {
 }
 
 void FreescapeEngine::shoot() {
-	playSound(0);
+	playSound(1);
 	_gfx->renderShoot(0);
 	Math::Vector3d direction = directionToVector(_pitch, _yaw);
 	Math::Ray ray(_position, direction);
@@ -427,7 +430,7 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 				return;
 			}
 			_position.set(_position.x(), positionY - fallen * areaScale, _position.z());
-			playSound(2);
+			playSound(3);
 		}
 		debugC(1, kFreescapeDebugCode, "Runing effects:");
 		checkCollisions(true); // run the effects
@@ -440,10 +443,11 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 			else {
 				bool stepUp = tryStepUp(_position);
 				if (stepUp) {
-					playSound(1);
+					playSound(4);
 					debugC(1, kFreescapeDebugCode, "Runing effects:");
 					checkCollisions(true); // run the effects (again)
 				} else {
+					playSound(2);
 					_position = _lastPosition;
 				}
 			}
@@ -516,6 +520,7 @@ bool FreescapeEngine::checkCollisions(bool executeCode) {
 }
 
 void FreescapeEngine::gotoArea(uint16 areaID, int entranceID) {
+	playSound(5);
 	debugC(1, kFreescapeDebugMove, "Jumping to area: %d, entrance: %d", areaID, entranceID);
 	if (!_gameStateBits.contains(areaID))
 		_gameStateBits[areaID] = 0;
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 0166595554b..3475c27d4d5 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -30,6 +30,7 @@
 #include "graphics/tinygl/pixelbuffer.h"
 
 #include "audio/mixer.h"
+#include "audio/decoders/wave.h"
 #include "audio/softsynth/pcspk.h"
 
 #include "freescape/area.h"
@@ -186,8 +187,10 @@ public:
 	void executePrint(FCLInstruction &instruction);
 
 	// Sound
-	Audio::SoundHandle _speakerHandle;
+	Audio::SoundHandle _handle;
+	bool _usePrerecordedSounds;
 	void playSound(int index);
+	void playWav(const Common::String filename);
 	void playSoundConst(double hzFreq, int duration);
 	void playSoundSweepIncWL(double hzFreq1, double hzFreq2, double wlStepPerMS, int resolution);
 
diff --git a/engines/freescape/sound.cpp b/engines/freescape/sound.cpp
index 1af3280691b..d11a5221a19 100644
--- a/engines/freescape/sound.cpp
+++ b/engines/freescape/sound.cpp
@@ -28,32 +28,206 @@ namespace Freescape {
 const double kFreescapeSweepTuneFactor = 1.0;
 
 void FreescapeEngine::playSound(int index) {
-	_mixer->stopAll();
+	if (!_mixer->isSoundHandleActive(_handle))
+		_mixer->stopHandle(_handle);
+
+	assert(_usePrerecordedSounds);
 	debug("Playing sound %d", index);
 	switch (index) {
-		case 0:
-			playSoundSweepIncWL(1500, 700, 5.46 * kFreescapeSweepTuneFactor, 1);
+		case 1: // Done
+			if (_usePrerecordedSounds) {
+				playWav("fsDOS_laserFire.wav");
+				//_system->delayMillis(50);
+			} else
+				playSoundSweepIncWL(1500, 700, 5.46 * kFreescapeSweepTuneFactor, 1);
+		break;
+		case 2: // Done
+			if (_usePrerecordedSounds) {
+				playWav("fsDOS_WallBump.wav");
+				//_system->delayMillis(50);
+			} else {
+				playSoundConst(82, 60);
+			}
+		break;
+		case 3:
+			if (_usePrerecordedSounds) {
+				playWav("fsDOS_stairDown.wav");
+				//_system->delayMillis(50);
+			} else {
+				playSoundConst(220, 50);
+				playSoundConst(185, 50);
+			}
+		break;
+		case 4:
+			if (_usePrerecordedSounds) {
+				playWav("fsDOS_stairUp.wav");
+				//_system->delayMillis(50);
+			} else {
+				playSoundConst(220, 50);
+				playSoundConst(340, 50);
+			}
+		break;
+		case 5:
+			if (_usePrerecordedSounds) {
+				playWav("fsDOS_roomChange.wav");
+				//_system->delayMillis(50);
+			} else {
+				playSoundConst(82, 60);
+			}
 		break;
-		case 1: // StairUp
-			playSoundConst(220, 50);
-			playSoundConst(340, 50);
+		case 6:
+			if (_usePrerecordedSounds) {
+				playWav("fsDOS_configMenu.wav");
+				//_system->delayMillis(50);
+			} else {
+				playSoundConst(82, 60);
+			}
 		break;
-		case 2: // StairDown
-			playSoundConst(220, 50);
-			playSoundConst(185, 50);
+		case 7:
+			if (_usePrerecordedSounds) {
+				playWav("fsDOS_bigHit.wav");
+				//_system->delayMillis(50);
+			} else {
+				playSoundConst(82, 60);
+			}
+		break;
+		case 8:
+			if (_usePrerecordedSounds) {
+				playWav("fsDOS_teleportActivated.wav");
+				//_system->delayMillis(50);
+			} else {
+				playSoundConst(82, 60);
+			}
+		break;
+
+		case 9:
+			if (_usePrerecordedSounds) {
+				playWav("fsDOS_powerUp.wav");
+				//_system->delayMillis(50);
+			} else {
+				playSoundConst(82, 60);
+			}
+		break;
+
+		case 10:
+			if (_usePrerecordedSounds) {
+				playWav("fsDOS_energyDrain.wav");
+				//_system->delayMillis(50);
+			} else {
+				playSoundConst(82, 60);
+			}
+		break;
+
+		case 11: // ???
+			if (_usePrerecordedSounds) {
+				playWav("???.wav");
+				//_system->delayMillis(50);
+			} else {
+				playSoundConst(82, 60);
+			}
+		break;
+
+		case 12:
+			if (_usePrerecordedSounds) {
+				playWav("fsDOS_switchOff.wav");
+				//_system->delayMillis(50);
+			} else {
+				playSoundConst(82, 60);
+			}
+		break;
+
+		case 13: // Seems to be repeated?
+			if (_usePrerecordedSounds) {
+				playWav("fsDOS_laserHit.wav");
+				//_system->delayMillis(50);
+			} else {
+				playSoundConst(82, 60);
+			}
+		break;
+
+		case 14:
+			if (_usePrerecordedSounds) {
+				playWav("fsDOS_tankFall.wav");
+				//_system->delayMillis(50);
+			} else {
+				playSoundConst(82, 60);
+			}
+		break;
+
+		case 15:
+			if (_usePrerecordedSounds) {
+				playWav("fsDOS_successJingle.wav");
+				//_system->delayMillis(50);
+			} else {
+				playSoundConst(82, 60);
+			}
+		break;
+
+		case 16: // Silence?
+			if (_usePrerecordedSounds) {
+				//playWav("???.wav");
+				//_system->delayMillis(50);
+			} else {
+				playSoundConst(82, 60);
+			}
+		break;
+
+		case 17:
+			if (_usePrerecordedSounds) {
+				playWav("fsDOS_badJingle.wav");
+				//_system->delayMillis(50);
+			} else {
+				playSoundConst(82, 60);
+			}
+		break;
+
+		case 18: // Silence?
+			if (_usePrerecordedSounds) {
+				//playWav("???.wav");
+				//_system->delayMillis(50);
+			} else {
+				playSoundConst(82, 60);
+			}
+		break;
+
+		case 19:
+			if (_usePrerecordedSounds) {
+				playWav("???.wav");
+				//_system->delayMillis(50);
+			} else {
+				playSoundConst(82, 60);
+			}
+		break;
+
+		case 20:
+			if (_usePrerecordedSounds) {
+				playWav("fsDOS_bigHit.wav");
+				//_system->delayMillis(50);
+			} else {
+				playSoundConst(82, 60);
+			}
 		break;
 		default:
+		error("Unexpected sound %d", index);
 		break;
 	}
 }
 
+void FreescapeEngine::playWav(const Common::String filename) {
+	Common::SeekableReadStream *s = _dataBundle->createReadStreamForMember(filename);
+	assert(s);
+	Audio::AudioStream *stream = Audio::makeWAVStream(s, DisposeAfterUse::YES);
+	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_handle, stream);
+}
+
+
 void FreescapeEngine::playSoundConst(double hzFreq, int duration) {
 	Audio::PCSpeaker *speaker = new Audio::PCSpeaker();
 	speaker->setVolume(50);
 	speaker->play(Audio::PCSpeaker::kWaveFormSquare, hzFreq, duration);
-	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_speakerHandle, speaker);
+	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_handle, speaker);
 	_system->delayMillis(duration);
-	_mixer->stopHandle(_speakerHandle);
+	_mixer->stopHandle(_handle);
 }
 
 
@@ -102,7 +276,7 @@ void FreescapeEngine::playSoundSweepIncWL(double hzFreq1, double hzFreq2, double
 		playSoundConst((1193180.0 / inv1), resolution);
 		inv1 += wlStep;
 	}
-	_mixer->stopHandle(_speakerHandle);
+	_mixer->stopHandle(_handle);
 }
 
 }
\ No newline at end of file


Commit: 96b54016e912d0ed86f8de1cf3cb33fd6784ea45
    https://github.com/scummvm/scummvm/commit/96b54016e912d0ed86f8de1cf3cb33fd6784ea45
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:13+01:00

Commit Message:
FREESCAPE: improved rendering of ui

Changed paths:
    engines/freescape/gfx_tinygl.cpp


diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index ba6d11a4457..ac23ecceca9 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -151,15 +151,12 @@ void TinyGLRenderer::renderCrossair(byte color) {
 
 	tglColor3ub(r, g, b);
 
-	int viewPort[4];
-	tglGetIntegerv(TGL_VIEWPORT, viewPort);
-
 	tglBegin(TGL_LINES);
-	tglVertex2f(viewPort[0] + viewPort[2] / 2 - 2, (viewPort[1] + viewPort[3]) / 2);
-	tglVertex2f(viewPort[0] + viewPort[2] / 2 + 3, (viewPort[1] + viewPort[3]) / 2);
+	tglVertex2f(kOriginalWidth / 2 - 1, kOriginalHeight / 2);
+	tglVertex2f(kOriginalWidth / 2 + 3, kOriginalHeight / 2);
 
-	tglVertex2f(viewPort[0] + viewPort[2] / 2, (viewPort[1] + viewPort[3]) / 2 - 2);
-	tglVertex2f(viewPort[0] + viewPort[2] / 2, (viewPort[1] + viewPort[3]) / 2 + 3);
+	tglVertex2f(kOriginalWidth / 2, kOriginalHeight / 2 - 3);
+	tglVertex2f(kOriginalWidth / 2, kOriginalHeight / 2 + 3);
 	tglEnd();
 
 	tglDepthMask(TGL_TRUE);
@@ -185,17 +182,17 @@ void TinyGLRenderer::renderShoot(byte color) {
 	tglGetIntegerv(TGL_VIEWPORT, viewPort);
 
 	tglBegin(TGL_LINES);
-	tglVertex2f(viewPort[0], viewPort[1] + viewPort[3] - 2);
-	tglVertex2f(viewPort[0] + viewPort[2] / 2, (viewPort[1] + viewPort[3]) / 2);
+	tglVertex2f(0, kOriginalHeight - 2);
+	tglVertex2f(kOriginalWidth / 2, kOriginalHeight / 2);
 
-	tglVertex2f(viewPort[0], viewPort[1] + viewPort[3]);
-	tglVertex2f(viewPort[0] + viewPort[2] / 2, (viewPort[1] + viewPort[3]) / 2);
+	tglVertex2f(0, kOriginalHeight - 2);
+	tglVertex2f(kOriginalWidth / 2, kOriginalHeight / 2);
 
-	tglVertex2f(viewPort[0] + viewPort[2], viewPort[1] + viewPort[3] - 2);
-	tglVertex2f(viewPort[0] + viewPort[2] / 2, (viewPort[1] + viewPort[3]) / 2);
+	tglVertex2f(kOriginalWidth, kOriginalHeight - 2);
+	tglVertex2f(kOriginalWidth / 2, kOriginalHeight / 2);
 
-	tglVertex2f(viewPort[0] + viewPort[2], viewPort[1] + viewPort[3]);
-	tglVertex2f(viewPort[0] + viewPort[2] / 2, (viewPort[1] + viewPort[3]) / 2);
+	tglVertex2f(kOriginalWidth, kOriginalHeight);
+	tglVertex2f(kOriginalWidth / 2, kOriginalHeight / 2);
 
 	tglEnd();
 


Commit: 4801685bb088c9a3867c384402e3ae59a1bd92fc
    https://github.com/scummvm/scummvm/commit/4801685bb088c9a3867c384402e3ae59a1bd92fc
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:14+01:00

Commit Message:
FREESCAPE: avoid crashing with unknown sounds

Changed paths:
    engines/freescape/sound.cpp


diff --git a/engines/freescape/sound.cpp b/engines/freescape/sound.cpp
index d11a5221a19..53604c4f92a 100644
--- a/engines/freescape/sound.cpp
+++ b/engines/freescape/sound.cpp
@@ -120,7 +120,7 @@ void FreescapeEngine::playSound(int index) {
 
 		case 11: // ???
 			if (_usePrerecordedSounds) {
-				playWav("???.wav");
+				//playWav("???.wav");
 				//_system->delayMillis(50);
 			} else {
 				playSoundConst(82, 60);
@@ -192,7 +192,7 @@ void FreescapeEngine::playSound(int index) {
 
 		case 19:
 			if (_usePrerecordedSounds) {
-				playWav("???.wav");
+				//playWav("???.wav");
 				//_system->delayMillis(50);
 			} else {
 				playSoundConst(82, 60);


Commit: fd03e9e127973c75a9bda34f0e102e2ef95243fa
    https://github.com/scummvm/scummvm/commit/fd03e9e127973c75a9bda34f0e102e2ef95243fa
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:14+01:00

Commit Message:
FREESCAPE: fixed in handling certain opcodes

Changed paths:
    engines/freescape/freescape.h
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/language/instruction.cpp


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 3475c27d4d5..9b998d8b66c 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -182,7 +182,7 @@ public:
 	void executeClearBit(FCLInstruction &instruction);
 	void executeToggleBit(FCLInstruction &instruction);
 	bool executeEndIfBitNotEqual(FCLInstruction &instruction);
-	bool executeEndIfVisibilityIsNotEqual(FCLInstruction &instruction);
+	bool executeEndIfVisibilityIsEqual(FCLInstruction &instruction);
 	void executeSwapJet(FCLInstruction &instruction);
 	void executePrint(FCLInstruction &instruction);
 
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index a216b6add56..1fdcbe2a048 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -215,7 +215,7 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			detokenisedStream += "THEN END ENDIF";
 			currentInstruction = FCLInstruction(Token::INVISQ);
 			currentInstruction.setSource(tokenisedCondition[bytePointer]);
-			currentInstruction.setDestination(true); // visible
+			currentInstruction.setDestination(true); // invisible
 			conditionalInstructions->push_back(currentInstruction);
 			currentInstruction = FCLInstruction(Token::UNKNOWN);
 			bytePointer++;
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index aa05b2f4fdb..0664372a9ab 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -161,7 +161,7 @@ void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool co
 				ip = codeSize;
 			break;
 			case Token::INVISQ:
-			if (executeEndIfVisibilityIsNotEqual(instruction))
+			if (executeEndIfVisibilityIsEqual(instruction))
 				ip = codeSize;
 			break;
 		}
@@ -195,7 +195,7 @@ void FreescapeEngine::executePrint(FCLInstruction &instruction) {
 	_currentAreaMessages.push_back(_messagesList[index]);
 }
 
-bool FreescapeEngine::executeEndIfVisibilityIsNotEqual(FCLInstruction &instruction) {
+bool FreescapeEngine::executeEndIfVisibilityIsEqual(FCLInstruction &instruction) {
 	uint16 source = instruction.source;
 	uint16 additional = instruction.additional;
 	uint16 value = instruction.destination;
@@ -212,7 +212,7 @@ bool FreescapeEngine::executeEndIfVisibilityIsNotEqual(FCLInstruction &instructi
 		debugC(1, kFreescapeDebugCode, "End condition if visibility of obj with id %d in area %d is %d!", additional, source, value);
 	}
 
-	return (obj->isInvisible() != value);
+	return (obj->isInvisible() == value);
 }
 
 bool FreescapeEngine::executeEndIfNotEqual(FCLInstruction &instruction) {
@@ -275,7 +275,9 @@ void FreescapeEngine::executeDestroy(FCLInstruction &instruction) {
 	debugC(1, kFreescapeDebugCode, "Destroying obj %d in area %d!", objectID, areaID);
 	assert(_areaMap.contains(areaID));
 	Object *obj = _areaMap[areaID]->objectWithID(objectID);
-	assert(!(obj->isDestroyed()));
+	if (obj->isDestroyed())
+		debugC(1, kFreescapeDebugCode, "WARNING: Destroying obj %d in area %d already destroyed!", objectID, areaID);
+
 	obj->destroy();
 }
 


Commit: 5bba4ab46b87785c33a5ee290a9f2fbfdf9fc22e
    https://github.com/scummvm/scummvm/commit/5bba4ab46b87785c33a5ee290a9f2fbfdf9fc22e
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:14+01:00

Commit Message:
FREESCAPE: moved color remapping inside gfx

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/games/palettes.cpp
    engines/freescape/gfx.cpp
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index c19ad9acf02..223d7bea430 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -250,6 +250,7 @@ Common::Error FreescapeEngine::run() {
 		_farClipPlane = 14189.f;
 		_startArea = 1;
 	} else {
+		_gfx->_missingColor = 0;
 		_farClipPlane = 8192.f;
 	}
 	int saveSlot = ConfMan.getInt("save_slot");
diff --git a/engines/freescape/games/palettes.cpp b/engines/freescape/games/palettes.cpp
index 4ba787e6820..d26632355d2 100644
--- a/engines/freescape/games/palettes.cpp
+++ b/engines/freescape/games/palettes.cpp
@@ -62,25 +62,7 @@ void FreescapeEngine::loadColorPalette() {
 }
 
 uint8 FreescapeEngine::remapColor(uint8 index) {
-
-	if (index == 255 || index == 0)
-		return index;
-
-	byte *entry = _colorMap[index-1];
-	uint8 color = 0;
-	uint8 acc = 1;
-	for (int i = 0; i < 4; i++) {
-		byte b = *entry;
-		assert(b == 0 || b == 0xff);
-
-		if (b == 0xff)
-			color = color + acc;
-
-		acc = acc << 1;
-		entry++;
-	}
-	assert(color < 16);
-	return color;
+	return index;
 }
 
 
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index 87158b1ae02..e11eee369a9 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -40,6 +40,7 @@ Renderer::Renderer(OSystem *system)
 	_originalPixelFormat = Graphics::PixelFormat::createFormatCLUT8();
 	_palettePixelFormat = Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0);
 	_keyColor = -1;
+	_missingColor = -1;
 	_palette = nullptr;
 	_colorMap = nullptr;
 }
@@ -54,6 +55,36 @@ Graphics::Surface *Renderer::convertFromPalette(Graphics::PixelBuffer *rawsurf)
 	return surf;
 }
 
+bool Renderer::getRGBAt(uint8 index, uint8 &r, uint8 &g, uint8 &b) {
+
+	if (index == _keyColor)
+		return false;
+
+	if (index == 0) {
+		_palette->getRGBAt(_missingColor, r, g, b);
+		return true;
+	}
+
+	//assert(index-1 < _colorMap->size());
+	byte *entry = (*_colorMap)[index-1];
+	uint8 color = 0;
+	uint8 acc = 1;
+	for (int i = 0; i < 4; i++) {
+		byte be = *entry;
+		assert(be == 0 || be == 0xff);
+
+		if (be == 0xff)
+			color = color + acc;
+
+		acc = acc << 1;
+		entry++;
+	}
+	assert(color < 16);
+	_palette->getRGBAt(color, r, g, b);
+	return true;
+}
+
+
 Common::Rect Renderer::viewport() const {
 	return _screenViewport;
 }
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 1c235f69dbf..952d9c91a7c 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -101,9 +101,13 @@ public:
 	virtual void drawFloor(uint8 color) = 0;
 
 	Common::Rect viewport() const;
+
+	// palette
+	bool getRGBAt(uint8 index, uint8 &r, uint8 &g, uint8 &b);
 	Graphics::PixelBuffer *_palette;
 	ColorMap *_colorMap;
 	int _keyColor;
+	int _missingColor;
 
 	/**
 	 * Select the window where to render
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index ac23ecceca9..c81b0d194fa 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -138,7 +138,7 @@ void TinyGLRenderer::drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint
 
 void TinyGLRenderer::renderCrossair(byte color) {
 	uint8 r, g, b;
-	_palette->getRGBAt(color, r, g, b);
+	_palette->getRGBAt(color, r, g, b); // TODO: should use opposite color
 
 	tglMatrixMode(TGL_PROJECTION);
 	tglLoadIdentity();
@@ -165,7 +165,7 @@ void TinyGLRenderer::renderCrossair(byte color) {
 
 void TinyGLRenderer::renderShoot(byte color) {
 	uint8 r, g, b;
-	_palette->getRGBAt(color, r, g, b);
+	_palette->getRGBAt(color, r, g, b); // TODO: should use opposite color
 
 	tglMatrixMode(TGL_PROJECTION);
 	tglLoadIdentity();
@@ -237,22 +237,21 @@ void TinyGLRenderer::renderPolygon(const Math::Vector3d &origin, const Math::Vec
 	tglPolygonOffset(-2.0f, 1.f);
 
 	if (ordinates->size() == 6) { // Line
-		_palette->getRGBAt((*colours)[0], r, g, b);
+		assert(getRGBAt((*colours)[0], r, g, b)); // It will never return false?
 		tglColor3ub(r, g, b);
 		for (int i = 0; i < int(ordinates->size()); i = i + 3)
 			vertices.push_back(Math::Vector3d((*ordinates)[i], (*ordinates)[i + 1],	(*ordinates)[i + 2]));
 		renderFace(vertices);
 
 		vertices.clear();
-		_palette->getRGBAt((*colours)[1], r, g, b);
+		assert(getRGBAt((*colours)[1], r, g, b)); // It will never return false?
 		tglColor3ub(r, g, b);
 		for (int i = ordinates->size(); i > 0; i = i - 3)
 			vertices.push_back(Math::Vector3d((*ordinates)[i-3], (*ordinates)[i-2],	(*ordinates)[i-1]));
 		renderFace(vertices);
 
 	} else {
-		if ((*colours)[0] != _keyColor) {
-			_palette->getRGBAt((*colours)[0], r, g, b);
+		if (getRGBAt((*colours)[0], r, g, b)) {
 			tglColor3ub(r, g, b);
 			for (int i = 0; i < int(ordinates->size()); i = i + 3) {
 				vertices.push_back(Math::Vector3d((*ordinates)[i], (*ordinates)[i + 1], (*ordinates)[i + 2]));
@@ -260,8 +259,7 @@ void TinyGLRenderer::renderPolygon(const Math::Vector3d &origin, const Math::Vec
 			renderFace(vertices);
 		}
 		vertices.clear();
-		if ((*colours)[1] != _keyColor) {
-			_palette->getRGBAt((*colours)[1], r, g, b);
+		if (getRGBAt((*colours)[1], r, g, b)) {
 			tglColor3ub(r, g, b);
 			for (int i = ordinates->size(); i > 0; i = i - 3) {
 				vertices.push_back(Math::Vector3d((*ordinates)[i-3], (*ordinates)[i-2], (*ordinates)[i-1]));
@@ -286,8 +284,7 @@ void TinyGLRenderer::renderRectangle(const Math::Vector3d &origin, const Math::V
 	for (int i = 0; i < 2; i++) {
 
 		//debug("rec color: %d", (*colours)[i]);
-		if ((*colours)[i] != _keyColor) {
-			_palette->getRGBAt((*colours)[i], r, g, b);
+		if (getRGBAt((*colours)[i], r, g, b)) {
 			tglColor3ub(r, g, b);
 			vertices.clear();
 			vertices.push_back(Math::Vector3d(origin.x(), origin.y(), origin.z()));
@@ -407,8 +404,7 @@ void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vec
 
 	Common::Array<Math::Vector3d> face;
 	uint8 r, g, b;
-	if ((*colours)[0] != _keyColor) {
-		_palette->getRGBAt((*colours)[0], r, g, b);
+	if (getRGBAt((*colours)[0], r, g, b)) {
 		tglColor3ub(r, g, b);
 		face.push_back(vertices[6]);
 		face.push_back(vertices[7]);
@@ -419,8 +415,7 @@ void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vec
 		face.clear();
 	}
 
-	if ((*colours)[1] != _keyColor) {
-		_palette->getRGBAt((*colours)[1], r, g, b);
+	if (getRGBAt((*colours)[1], r, g, b)) {
 		tglColor3ub(r, g, b);
 
 		face.push_back(vertices[7]);
@@ -431,8 +426,7 @@ void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vec
 		face.clear();
 	}
 
-	if ((*colours)[2] != _keyColor) {
-		_palette->getRGBAt((*colours)[2], r, g, b);
+	if (getRGBAt((*colours)[2], r, g, b)) {
 		tglColor3ub(r, g, b);
 
 		face.push_back(vertices[4]);
@@ -443,8 +437,7 @@ void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vec
 		face.clear();
 	}
 
-	if ((*colours)[3] != _keyColor) {
-		_palette->getRGBAt((*colours)[3], r, g, b);
+	if (getRGBAt((*colours)[3], r, g, b)) {
 		tglColor3ub(r, g, b);
 
 		face.push_back(vertices[5]);
@@ -455,8 +448,7 @@ void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vec
 		face.clear();
 	}
 
-	if ((*colours)[4] != _keyColor) {
-		_palette->getRGBAt((*colours)[4], r, g, b);
+	if (getRGBAt((*colours)[4], r, g, b)) {
 		tglColor3ub(r, g, b);
 
 		face.push_back(vertices[0]);
@@ -467,8 +459,7 @@ void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vec
 		face.clear();
 	}
 
-	if ((*colours)[5] != _keyColor) {
-		_palette->getRGBAt((*colours)[5], r, g, b);
+	if (getRGBAt((*colours)[5], r, g, b)) {
 		tglColor3ub(r, g, b);
 
 		face.push_back(vertices[7]);
@@ -489,8 +480,7 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 	uint8 r, g, b;
 
 	// Face 0
-	if ((*colours)[0] != _keyColor) {
-		_palette->getRGBAt((*colours)[0], r, g, b);
+	if (getRGBAt((*colours)[0], r, g, b)) {
 		tglColor3ub(r, g, b);
 		tglBegin(TGL_TRIANGLES);
 		tglVertex3f(origin.x(),	origin.y(),				origin.z());
@@ -504,8 +494,7 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 	}
 
 	// Face 1
-	if ((*colours)[1] != _keyColor) {
-		_palette->getRGBAt((*colours)[1], r, g, b);
+	if (getRGBAt((*colours)[1], r, g, b)) {
 		tglColor3ub(r, g, b);
 		tglBegin(TGL_TRIANGLES);
 		tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z());
@@ -519,8 +508,7 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 	}
 
 	// Face 2
-	if ((*colours)[2] != _keyColor) {
-		_palette->getRGBAt((*colours)[2], r, g, b);
+	if (getRGBAt((*colours)[2], r, g, b)) {
 		tglColor3ub(r, g, b);
 		tglBegin(TGL_TRIANGLES);
 		tglVertex3f(origin.x() + size.x(),	origin.y(),	origin.z());
@@ -534,8 +522,7 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 	}
 
 	// Face 3
-	if ((*colours)[3] != _keyColor) {
-		_palette->getRGBAt((*colours)[3], r, g, b);
+	if (getRGBAt((*colours)[3], r, g, b)) {
 		tglColor3ub(r, g, b);
 		tglBegin(TGL_TRIANGLES);
 		tglVertex3f(origin.x(),				origin.y() + size.y(),	origin.z());
@@ -549,8 +536,7 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 	}
 
 	// Face 1
-	if ((*colours)[4] != _keyColor) {
-		_palette->getRGBAt((*colours)[4], r, g, b);
+	if (getRGBAt((*colours)[4], r, g, b)) {
 		tglColor3ub(r, g, b);
 		tglBegin(TGL_TRIANGLES);
 		tglVertex3f(origin.x(),				origin.y() + size.y(),	origin.z());
@@ -564,8 +550,7 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 	}
 
 	// Face 0
-	if ((*colours)[5] != _keyColor) {
-		_palette->getRGBAt((*colours)[5], r, g, b);
+	if (getRGBAt((*colours)[5], r, g, b)) {
 		tglColor3ub(r, g, b);
 		tglBegin(TGL_TRIANGLES);
 		tglVertex3f(origin.x(),		        origin.y(),				origin.z() + size.z());
@@ -581,14 +566,14 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 
 void TinyGLRenderer::drawSky(uint8 color) {
 	uint8 r, g, b;
-	_palette->getRGBAt(color, r, g, b);
+	assert(getRGBAt(color, r, g, b)); // TODO: move check inside this function
 	tglClearColor(r / 255., g / 255., b / 255., 1.0);
 	tglClear(TGL_COLOR_BUFFER_BIT | TGL_DEPTH_BUFFER_BIT);
 }
 
 void TinyGLRenderer::drawFloor(uint8 color) {
 	uint8 r, g, b;
-	_palette->getRGBAt(color, r, g, b);
+	assert(getRGBAt(color, r, g, b)); // TODO: move check inside this function
 	tglColor3ub(r, g, b);
 	tglBegin(TGL_QUADS);
 	tglVertex3f(-100000.f, 0.f, -100000.f);


Commit: ff9b0835931d46d50ac9ba5e7394d6ea6f2cae72
    https://github.com/scummvm/scummvm/commit/ff9b0835931d46d50ac9ba5e7394d6ea6f2cae72
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:14+01:00

Commit Message:
FREESCAPE: improved pyramid rendering

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/games/castle.cpp
    engines/freescape/games/dark.cpp
    engines/freescape/games/driller.cpp
    engines/freescape/games/eclipse.cpp
    engines/freescape/gfx_tinygl.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 223d7bea430..c19ad9acf02 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -250,7 +250,6 @@ Common::Error FreescapeEngine::run() {
 		_farClipPlane = 14189.f;
 		_startArea = 1;
 	} else {
-		_gfx->_missingColor = 0;
 		_farClipPlane = 8192.f;
 	}
 	int saveSlot = ConfMan.getInt("save_slot");
diff --git a/engines/freescape/games/castle.cpp b/engines/freescape/games/castle.cpp
index 6dd62ff6b90..7c05161c070 100644
--- a/engines/freescape/games/castle.cpp
+++ b/engines/freescape/games/castle.cpp
@@ -39,6 +39,7 @@ void CastleEngine::loadAssets() {
 	Common::FSDirectory gameDir(path);
 
 	_renderMode = "ega";
+	_gfx->_missingColor = 0;
 
 	file = gameDir.createReadStreamForMember("CMEDF");
 	int size = file->size();
diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index d0e65c04d4b..36e46c98d46 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -45,6 +45,7 @@ void DarkEngine::loadAssets() {
             error("Failed to open DSIDEE.EXE");
 
         load8bitBinary(file, 0xa280, 16);
+		_gfx->_missingColor = 0;
     } else if (_renderMode == "cga") {
         file = gameDir.createReadStreamForMember("DSIDEC.EXE");
 
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 5086612e5c4..647d9053be1 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -113,6 +113,7 @@ void DrillerEngine::loadAssets() {
 			error("Failed to open DRILLE.EXE");
 
 		load8bitBinary(file, 0x9b40, 16);
+		_gfx->_missingColor = 0;
 	} else if (_renderMode == "cga") {
 		file = gameDir.createReadStreamForMember("DRILLC.EXE");
 
diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index bad6d21c559..ba7dfb094ab 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -109,6 +109,7 @@ void EclipseEngine::loadAssets() {
 			error("Failed to open TOTEE.EXE");
 
 		load8bitBinary(file, 0x3ce0, 16);
+		_gfx->_missingColor = 0;
 	} else if (_renderMode == "cga") {
 		file = gameDir.createReadStreamForMember("TOTEC.EXE");
 
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index c81b0d194fa..7021dd1ba30 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -417,11 +417,11 @@ void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vec
 
 	if (getRGBAt((*colours)[1], r, g, b)) {
 		tglColor3ub(r, g, b);
+		face.push_back(vertices[5]);
+		face.push_back(vertices[6]);
+		face.push_back(vertices[2]);
+		face.push_back(vertices[1]);
 
-		face.push_back(vertices[7]);
-		face.push_back(vertices[4]);
-		face.push_back(vertices[0]);
-		face.push_back(vertices[3]);
 		renderFace(face);
 		face.clear();
 	}
@@ -439,11 +439,11 @@ void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vec
 
 	if (getRGBAt((*colours)[3], r, g, b)) {
 		tglColor3ub(r, g, b);
+		face.push_back(vertices[7]);
+		face.push_back(vertices[4]);
+		face.push_back(vertices[0]);
+		face.push_back(vertices[3]);
 
-		face.push_back(vertices[5]);
-		face.push_back(vertices[6]);
-		face.push_back(vertices[2]);
-		face.push_back(vertices[1]);
 		renderFace(face);
 		face.clear();
 	}


Commit: a3c3bb2a6531f44541f314c9c971f10fdeaee790
    https://github.com/scummvm/scummvm/commit/a3c3bb2a6531f44541f314c9c971f10fdeaee790
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:14+01:00

Commit Message:
FREESCAPE: improved pyramid rendering

Changed paths:
    engines/freescape/gfx_tinygl.cpp


diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 7021dd1ba30..b0c4bfdcf11 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -406,10 +406,10 @@ void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vec
 	uint8 r, g, b;
 	if (getRGBAt((*colours)[0], r, g, b)) {
 		tglColor3ub(r, g, b);
-		face.push_back(vertices[6]);
-		face.push_back(vertices[7]);
-		face.push_back(vertices[3]);
-		face.push_back(vertices[2]);
+		face.push_back(vertices[4]);
+		face.push_back(vertices[5]);
+		face.push_back(vertices[1]);
+		face.push_back(vertices[0]);
 
 		renderFace(face);
 		face.clear();
@@ -429,10 +429,10 @@ void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vec
 	if (getRGBAt((*colours)[2], r, g, b)) {
 		tglColor3ub(r, g, b);
 
-		face.push_back(vertices[4]);
-		face.push_back(vertices[5]);
-		face.push_back(vertices[1]);
-		face.push_back(vertices[0]);
+		face.push_back(vertices[6]);
+		face.push_back(vertices[7]);
+		face.push_back(vertices[3]);
+		face.push_back(vertices[2]);
 		renderFace(face);
 		face.clear();
 	}


Commit: 2e414c507121edab7d15665a4b144c5453bf51a6
    https://github.com/scummvm/scummvm/commit/2e414c507121edab7d15665a4b144c5453bf51a6
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:14+01:00

Commit Message:
FREESCAPE: removed _missingColor variable from gfx class

Changed paths:
    engines/freescape/games/castle.cpp
    engines/freescape/games/dark.cpp
    engines/freescape/games/driller.cpp
    engines/freescape/games/eclipse.cpp
    engines/freescape/gfx.cpp
    engines/freescape/gfx.h


diff --git a/engines/freescape/games/castle.cpp b/engines/freescape/games/castle.cpp
index 7c05161c070..6dd62ff6b90 100644
--- a/engines/freescape/games/castle.cpp
+++ b/engines/freescape/games/castle.cpp
@@ -39,7 +39,6 @@ void CastleEngine::loadAssets() {
 	Common::FSDirectory gameDir(path);
 
 	_renderMode = "ega";
-	_gfx->_missingColor = 0;
 
 	file = gameDir.createReadStreamForMember("CMEDF");
 	int size = file->size();
diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index 36e46c98d46..d0e65c04d4b 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -45,7 +45,6 @@ void DarkEngine::loadAssets() {
             error("Failed to open DSIDEE.EXE");
 
         load8bitBinary(file, 0xa280, 16);
-		_gfx->_missingColor = 0;
     } else if (_renderMode == "cga") {
         file = gameDir.createReadStreamForMember("DSIDEC.EXE");
 
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 647d9053be1..5086612e5c4 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -113,7 +113,6 @@ void DrillerEngine::loadAssets() {
 			error("Failed to open DRILLE.EXE");
 
 		load8bitBinary(file, 0x9b40, 16);
-		_gfx->_missingColor = 0;
 	} else if (_renderMode == "cga") {
 		file = gameDir.createReadStreamForMember("DRILLC.EXE");
 
diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index ba7dfb094ab..bad6d21c559 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -109,7 +109,6 @@ void EclipseEngine::loadAssets() {
 			error("Failed to open TOTEE.EXE");
 
 		load8bitBinary(file, 0x3ce0, 16);
-		_gfx->_missingColor = 0;
 	} else if (_renderMode == "cga") {
 		file = gameDir.createReadStreamForMember("TOTEC.EXE");
 
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index e11eee369a9..3a51f21729f 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -40,7 +40,6 @@ Renderer::Renderer(OSystem *system)
 	_originalPixelFormat = Graphics::PixelFormat::createFormatCLUT8();
 	_palettePixelFormat = Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0);
 	_keyColor = -1;
-	_missingColor = -1;
 	_palette = nullptr;
 	_colorMap = nullptr;
 }
@@ -61,7 +60,7 @@ bool Renderer::getRGBAt(uint8 index, uint8 &r, uint8 &g, uint8 &b) {
 		return false;
 
 	if (index == 0) {
-		_palette->getRGBAt(_missingColor, r, g, b);
+		_palette->getRGBAt(0, r, g, b);
 		return true;
 	}
 
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 952d9c91a7c..197d613ee45 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -107,7 +107,6 @@ public:
 	Graphics::PixelBuffer *_palette;
 	ColorMap *_colorMap;
 	int _keyColor;
-	int _missingColor;
 
 	/**
 	 * Select the window where to render


Commit: 4e5aca393e2d14a8dda999f8f65719a26fcaf16b
    https://github.com/scummvm/scummvm/commit/4e5aca393e2d14a8dda999f8f65719a26fcaf16b
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:15+01:00

Commit Message:
FREESCAPE: correclty load area in eclipse

Changed paths:
    engines/freescape/games/eclipse.cpp


diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index bad6d21c559..3c0921d1283 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -136,6 +136,9 @@ void EclipseEngine::gotoArea(uint16 areaID, int entranceID) {
 	assert(scale > 0);
 
 	Entrance *entrance = nullptr;
+	if (entranceID == -1)
+		return;
+
 	assert(entranceID > 0);
 
 	entrance = (Entrance*) _currentArea->entranceWithID(entranceID);


Commit: 7d08f4249bf9480659e089149aca8b66fac17615
    https://github.com/scummvm/scummvm/commit/7d08f4249bf9480659e089149aca8b66fac17615
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:15+01:00

Commit Message:
FREESCAPE: force a screen update when executing a redraw opcode

Changed paths:
    engines/freescape/language/instruction.cpp


diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index 0664372a9ab..209c149f6ff 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -174,6 +174,9 @@ void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool co
 void FreescapeEngine::executeRedraw(FCLInstruction &instruction) {
 	debugC(1, kFreescapeDebugCode, "Redrawing screen");
 	drawFrame();
+	_gfx->flipBuffer();
+	g_system->updateScreen();
+	g_system->delayMillis(10);
 }
 
 void FreescapeEngine::executeSound(FCLInstruction &instruction) {


Commit: 085af6ef83d507e41cfdba0e963307bc1f7c3ea6
    https://github.com/scummvm/scummvm/commit/085af6ef83d507e41cfdba0e963307bc1f7c3ea6
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:15+01:00

Commit Message:
FREESCAPE: inverted ifrvis and ifrinvis opcodes

Changed paths:
    engines/freescape/language/8bitDetokeniser.cpp


diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index 1fdcbe2a048..f3d4adeb8bd 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -235,13 +235,13 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			break;
 
 		case 32: // end condition if an object is visible in another area
-			detokenisedStream += "IF RVIS? ";
-			detokenisedStream += Common::String::format("(%d), (%d)", (int)tokenisedCondition[bytePointer], (int)tokenisedCondition[bytePointer + 1]);
+			detokenisedStream += "IF RINVIS? ";
+			detokenisedStream += Common::String::format("(%d, %d)", (int)tokenisedCondition[bytePointer], (int)tokenisedCondition[bytePointer + 1]);
 			detokenisedStream += "THEN END ENDIF";
 			currentInstruction = FCLInstruction(Token::INVISQ);
 			currentInstruction.setSource(tokenisedCondition[bytePointer]);
 			currentInstruction.setAdditional(tokenisedCondition[bytePointer + 1]);
-			currentInstruction.setDestination(false); // visible
+			currentInstruction.setDestination(true); // invisible
 			conditionalInstructions->push_back(currentInstruction);
 			currentInstruction = FCLInstruction(Token::UNKNOWN);
 			bytePointer += 2;
@@ -249,13 +249,13 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			break;
 
 		case 33: // end condition if an object is invisible in another area
-			detokenisedStream += "IF RINVIS? ";
-			detokenisedStream += Common::String::format("(%d), (%d)", (int)tokenisedCondition[bytePointer], (int)tokenisedCondition[bytePointer + 1]);
+			detokenisedStream += "IF RVIS? ";
+			detokenisedStream += Common::String::format("(%d, %d)", (int)tokenisedCondition[bytePointer], (int)tokenisedCondition[bytePointer + 1]);
 			detokenisedStream += "THEN END ENDIF";
 			currentInstruction = FCLInstruction(Token::INVISQ);
 			currentInstruction.setSource(tokenisedCondition[bytePointer]);
 			currentInstruction.setAdditional(tokenisedCondition[bytePointer + 1]);
-			currentInstruction.setDestination(true); // invisible
+			currentInstruction.setDestination(false); // visible
 			conditionalInstructions->push_back(currentInstruction);
 			currentInstruction = FCLInstruction(Token::UNKNOWN);
 			bytePointer += 2;


Commit: f1cecfabc86b973ef792fbb34c81fbfdaf82c2f6
    https://github.com/scummvm/scummvm/commit/f1cecfabc86b973ef792fbb34c81fbfdaf82c2f6
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:15+01:00

Commit Message:
FREESCAPE: relocated movement functions into a separated file

Changed paths:
  A engines/freescape/movement.cpp
    engines/freescape/freescape.cpp
    engines/freescape/games/driller.cpp
    engines/freescape/games/eclipse.cpp
    engines/freescape/module.mk


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index c19ad9acf02..d7c911f1c67 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -326,258 +326,6 @@ void FreescapeEngine::rotate(Common::Point lastMousePos, Common::Point mousePos)
 	_cameraRight = v;
 }
 
-void FreescapeEngine::changePlayerHeight(int delta) {
-	int scale = _currentArea->getScale();
-	_position.setValue(1, _position.y() - scale * _playerHeight);
-	_playerHeight = _playerHeight + delta;
-	_position.setValue(1, _position.y() + scale * _playerHeight);
-}
-
-void FreescapeEngine::rise() {
-	int previousAreaID = _currentArea->getAreaID();
-	int scale = _currentArea->getScale();
-
-	if (_flyMode) {
-		_position.setValue(1, _position.y() + scale * 32);
-	} else {
-		if (_playerHeightNumber == 10) // TODO
-			return;
-
-		_playerHeightNumber++;
-		changePlayerHeight(16);
-	}
-
-	bool collided = checkCollisions(true);
-	if (collided) {
-		if (_currentArea->getAreaID() == previousAreaID) {
-			if (_flyMode)
-				_position = _lastPosition;
-			else {
-				changePlayerHeight(-16);
-			}
-		}
-	}
-
-	_lastPosition = _position;
-	debugC(1, kFreescapeDebugMove, "new player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
-}
-
-void FreescapeEngine::lower() {
-	int previousAreaID = _currentArea->getAreaID();
-	int scale = _currentArea->getScale();
-
-	if (_flyMode) {
-		_position.setValue(1, _position.y() - scale * 32);
-		bool collided = checkCollisions(true);
-		if (collided) {
-			if (_currentArea->getAreaID() == previousAreaID) {
-				_position = _lastPosition;
-			}
-		}
-	} else {
-		if (_playerHeightNumber == 0)
-			return;
-
-		_playerHeightNumber--;
-		changePlayerHeight(-16);
-	}
-
-	_lastPosition = _position;
-	debugC(1, kFreescapeDebugMove, "new player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
-}
-
-
-void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTime) {
-	debugC(1, kFreescapeDebugMove, "old player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
-	int previousAreaID = _currentArea->getAreaID();
-	int areaScale = _currentArea->getScale();
-
-	float velocity = _movementSpeed * deltaTime * areaScale;
-	float positionY = _position.y();
-	switch (direction) {
-	case FORWARD:
-		_position = _position + _cameraFront * velocity;
-		break;
-	case BACKWARD:
-		_position = _position - _cameraFront * velocity;
-		break;
-	case RIGHT:
-		_position = _position - _cameraRight * velocity;
-		break;
-	case LEFT:
-		_position = _position + _cameraRight * velocity;
-		break;
-	}
-	// restore y coordinate
-	if (!_flyMode)
-		_position.set(_position.x(), positionY, _position.z());
-
-	bool collided = checkCollisions(false);
-
-	if (!collided) {
-		bool hasFloor = checkFloor(_position);
-		if (!hasFloor  && !_flyMode) {
-			int fallen;
-			for (fallen = 1; fallen < 65 + 1; fallen++) {
-				_position.set(_position.x(), positionY - fallen * areaScale, _position.z());
-				if (tryStepDown(_position))
-					break;
-			}
-			fallen++;
-			fallen++;
-			if (fallen >= 67) {
-				_position = _lastPosition; //error("NASTY FALL!");
-				return;
-			}
-			_position.set(_position.x(), positionY - fallen * areaScale, _position.z());
-			playSound(3);
-		}
-		debugC(1, kFreescapeDebugCode, "Runing effects:");
-		checkCollisions(true); // run the effects
-	} else {
-		debugC(1, kFreescapeDebugCode, "Runing effects:");
-		checkCollisions(true); // run the effects
-		if (_currentArea->getAreaID() == previousAreaID) {
-			if (_flyMode)
-				_position = _lastPosition;
-			else {
-				bool stepUp = tryStepUp(_position);
-				if (stepUp) {
-					playSound(4);
-					debugC(1, kFreescapeDebugCode, "Runing effects:");
-					checkCollisions(true); // run the effects (again)
-				} else {
-					playSound(2);
-					_position = _lastPosition;
-				}
-			}
-		}
-	}
-	areaScale = _currentArea->getScale();
-
-	_lastPosition = _position;
-	debugC(1, kFreescapeDebugMove, "new player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
-	debugC(1, kFreescapeDebugMove, "player height: %f", _position.y() - areaScale * _playerHeight);
-}
-
-bool FreescapeEngine::checkFloor(Math::Vector3d currentPosition) {
-	debugC(1, kFreescapeDebugMove, "Checking floor under the player");
-	int areaScale = _currentArea->getScale();
-	bool collided = checkCollisions(false);
-	assert(!collided);
-
-	_position.set(_position.x(), _position.y() - 2 * areaScale, _position.z());
-	collided = checkCollisions(false);
-	_position = currentPosition;
-	return collided;
-}
-
-bool FreescapeEngine::tryStepUp(Math::Vector3d currentPosition) {
-	debugC(1, kFreescapeDebugMove, "Try to step up!");
-	int areaScale = _currentArea->getScale();
-	_position.set(_position.x(), _position.y() + 64 * areaScale, _position.z());
-	bool collided = checkCollisions(false);
-	if (collided) {
-		_position = currentPosition;
-		return false;
-	} else {
-		// Try to step down
-		return true;
-	}
-}
-
-bool FreescapeEngine::tryStepDown(Math::Vector3d currentPosition) {
-	debugC(1, kFreescapeDebugMove, "Try to step down!");
-	int areaScale = _currentArea->getScale();
-	_position.set(_position.x(), _position.y() - areaScale, _position.z());
-	if (checkFloor(_position)) {
-		return true;
-	} else {
-		_position = currentPosition;
-		return false;
-	}
-}
-
-
-bool FreescapeEngine::checkCollisions(bool executeCode) {
-	int areaScale = _currentArea->getScale();
-	Math::Vector3d v1(_position.x() - areaScale * _playerWidth / 2, _position.y() - areaScale * _playerHeight , _position.z() - areaScale * _playerDepth / 2);
-	Math::Vector3d v2(_position.x() + areaScale * _playerWidth / 2, _position.y()                             , _position.z() + areaScale * _playerDepth / 2);
-
-	const Math::AABB boundingBox(v1, v2);
-	Object *obj = _currentArea->checkCollisions(boundingBox);
-
-	if (obj != nullptr) {
-		debugC(1, kFreescapeDebugMove, "Collided with object id %d of size %f %f %f", obj->getObjectID(), obj->getSize().x(), obj->getSize().y(), obj->getSize().z());
-		GeometricObject *gobj = (GeometricObject*) obj;
-		if (!executeCode) // Avoid executing code
-			return true;
-
-		executeConditions(gobj, false, true);
-		return true;
-	}
-	return false;
-}
-
-void FreescapeEngine::gotoArea(uint16 areaID, int entranceID) {
-	playSound(5);
-	debugC(1, kFreescapeDebugMove, "Jumping to area: %d, entrance: %d", areaID, entranceID);
-	if (!_gameStateBits.contains(areaID))
-		_gameStateBits[areaID] = 0;
-
-	assert(_areaMap.contains(areaID));
-	_currentArea = _areaMap[areaID];
-	_currentArea->show();
-
-	_currentAreaMessages.clear();
-	if (!_messagesList.empty())
-		_currentAreaMessages.push_back(_messagesList[1]);
-	else
-		_currentAreaMessages.push_back("");
-
-	_currentAreaMessages.push_back(_currentArea->name);
-
-	int scale = _currentArea->getScale();
-	assert(scale > 0);
-
-	Entrance *entrance = nullptr;
-	if (entranceID > 0 || areaID == 127) {
-		entrance = (Entrance*) _currentArea->entranceWithID(entranceID);
-
-		assert(entrance);
-		_position = entrance->getOrigin();
-
-		if (_rotation == Math::Vector3d(0, 0, 0)) {
-			_rotation = entrance->getRotation();
-			_pitch = _rotation.x();
-			_yaw = _rotation.y() - 260;
-		}
-		debugC(1, kFreescapeDebugMove, "entrace position: %f %f %f", _position.x(), _position.y(), _position.z());
-		debugC(1, kFreescapeDebugMove, "player height: %d", scale * _playerHeight);
-		_position.setValue(1, _position.y() + scale * _playerHeight);
-	} else if (entranceID == 0) {
-		Math::Vector3d diff = _lastPosition - _position;
-		debug("dif: %f %f %f", diff.x(), diff.y(), diff.z());
-		// diff should be used to determinate which entrance to use
-		int newPos = -1;
-		if (abs(diff.x()) < abs(diff.z())) {
-			if (diff.z() > 0)
-				newPos = 4000;
-			else
-				newPos = 100;
-			_position.setValue(2, newPos);
-		} else {
-			if (diff.x() > 0)
-				newPos = 4000;
-			else
-				newPos = 100;
-			_position.setValue(0, newPos);
-		}
-		assert(newPos != -1);
-	}
-
-	debugC(1, kFreescapeDebugMove, "starting player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
-}
 
 bool FreescapeEngine::hasFeature(EngineFeature f) const {
 	return (f == kSupportsReturnToLauncher) ||
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 5086612e5c4..ac88304ee38 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -97,6 +97,7 @@ void DrillerEngine::gotoArea(uint16 areaID, int entranceID) {
 	}
 
 	debugC(1, kFreescapeDebugMove, "starting player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
+	playSound(5);
 }
 
 
diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index 3c0921d1283..e54803ca40a 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -159,6 +159,7 @@ void EclipseEngine::gotoArea(uint16 areaID, int entranceID) {
 	debugC(1, kFreescapeDebugMove, "player height: %d", scale * _playerHeight);
 	_position.setValue(1, _position.y() + scale * _playerHeight);
 	debugC(1, kFreescapeDebugMove, "starting player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
+	playSound(5);
 }
 
 
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index 59391fff6a2..bc2da1c8082 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -21,6 +21,7 @@ MODULE_OBJS := \
 	loaders/16bitBinaryLoader.o \
 	language/16bitDetokeniser.o \
 	language/instruction.o \
+	movement.o \
 	sound.o
 
 
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
new file mode 100644
index 00000000000..62470aed59c
--- /dev/null
+++ b/engines/freescape/movement.cpp
@@ -0,0 +1,279 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "freescape/freescape.h"
+
+namespace Freescape {
+
+void FreescapeEngine::gotoArea(uint16 areaID, int entranceID) {
+	debugC(1, kFreescapeDebugMove, "Jumping to area: %d, entrance: %d", areaID, entranceID);
+	if (!_gameStateBits.contains(areaID))
+		_gameStateBits[areaID] = 0;
+
+	assert(_areaMap.contains(areaID));
+	_currentArea = _areaMap[areaID];
+	_currentArea->show();
+
+	_currentAreaMessages.clear();
+	if (!_messagesList.empty())
+		_currentAreaMessages.push_back(_messagesList[1]);
+	else
+		_currentAreaMessages.push_back("");
+
+	_currentAreaMessages.push_back(_currentArea->name);
+
+	int scale = _currentArea->getScale();
+	assert(scale > 0);
+
+	Entrance *entrance = nullptr;
+	if (entranceID > 0 || areaID == 127) {
+		entrance = (Entrance*) _currentArea->entranceWithID(entranceID);
+
+		assert(entrance);
+		_position = entrance->getOrigin();
+
+		if (_rotation == Math::Vector3d(0, 0, 0)) {
+			_rotation = entrance->getRotation();
+			_pitch = _rotation.x();
+			_yaw = _rotation.y() - 260;
+		}
+		debugC(1, kFreescapeDebugMove, "entrace position: %f %f %f", _position.x(), _position.y(), _position.z());
+		debugC(1, kFreescapeDebugMove, "player height: %d", scale * _playerHeight);
+		_position.setValue(1, _position.y() + scale * _playerHeight);
+	} else if (entranceID == 0) {
+		Math::Vector3d diff = _lastPosition - _position;
+		debug("dif: %f %f %f", diff.x(), diff.y(), diff.z());
+		// diff should be used to determinate which entrance to use
+		int newPos = -1;
+		if (abs(diff.x()) < abs(diff.z())) {
+			if (diff.z() > 0)
+				newPos = 4000;
+			else
+				newPos = 100;
+			_position.setValue(2, newPos);
+		} else {
+			if (diff.x() > 0)
+				newPos = 4000;
+			else
+				newPos = 100;
+			_position.setValue(0, newPos);
+		}
+		assert(newPos != -1);
+	}
+
+	debugC(1, kFreescapeDebugMove, "starting player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
+	playSound(5);
+}
+
+void FreescapeEngine::changePlayerHeight(int delta) {
+	int scale = _currentArea->getScale();
+	_position.setValue(1, _position.y() - scale * _playerHeight);
+	_playerHeight = _playerHeight + delta;
+	_position.setValue(1, _position.y() + scale * _playerHeight);
+}
+
+void FreescapeEngine::rise() {
+	int previousAreaID = _currentArea->getAreaID();
+	int scale = _currentArea->getScale();
+
+	if (_flyMode) {
+		_position.setValue(1, _position.y() + scale * 32);
+	} else {
+		if (_playerHeightNumber == 10) // TODO
+			return;
+
+		_playerHeightNumber++;
+		changePlayerHeight(16);
+	}
+
+	bool collided = checkCollisions(true);
+	if (collided) {
+		if (_currentArea->getAreaID() == previousAreaID) {
+			if (_flyMode)
+				_position = _lastPosition;
+			else {
+				changePlayerHeight(-16);
+			}
+		}
+	}
+
+	_lastPosition = _position;
+	debugC(1, kFreescapeDebugMove, "new player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
+}
+
+void FreescapeEngine::lower() {
+	int previousAreaID = _currentArea->getAreaID();
+	int scale = _currentArea->getScale();
+
+	if (_flyMode) {
+		_position.setValue(1, _position.y() - scale * 32);
+		bool collided = checkCollisions(true);
+		if (collided) {
+			if (_currentArea->getAreaID() == previousAreaID) {
+				_position = _lastPosition;
+			}
+		}
+	} else {
+		if (_playerHeightNumber == 0)
+			return;
+
+		_playerHeightNumber--;
+		changePlayerHeight(-16);
+	}
+
+	_lastPosition = _position;
+	debugC(1, kFreescapeDebugMove, "new player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
+}
+
+
+void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTime) {
+	debugC(1, kFreescapeDebugMove, "old player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
+	int previousAreaID = _currentArea->getAreaID();
+	int areaScale = _currentArea->getScale();
+
+	float velocity = _movementSpeed * deltaTime * areaScale;
+	float positionY = _position.y();
+	switch (direction) {
+	case FORWARD:
+		_position = _position + _cameraFront * velocity;
+		break;
+	case BACKWARD:
+		_position = _position - _cameraFront * velocity;
+		break;
+	case RIGHT:
+		_position = _position - _cameraRight * velocity;
+		break;
+	case LEFT:
+		_position = _position + _cameraRight * velocity;
+		break;
+	}
+	// restore y coordinate
+	if (!_flyMode)
+		_position.set(_position.x(), positionY, _position.z());
+
+	bool collided = checkCollisions(false);
+
+	if (!collided) {
+		bool hasFloor = checkFloor(_position);
+		if (!hasFloor  && !_flyMode) {
+			int fallen;
+			for (fallen = 1; fallen < 65 + 1; fallen++) {
+				_position.set(_position.x(), positionY - fallen * areaScale, _position.z());
+				if (tryStepDown(_position))
+					break;
+			}
+			fallen++;
+			fallen++;
+			if (fallen >= 67) {
+				_position = _lastPosition; //error("NASTY FALL!");
+				return;
+			}
+			_position.set(_position.x(), positionY - fallen * areaScale, _position.z());
+			playSound(3);
+		}
+		debugC(1, kFreescapeDebugCode, "Runing effects:");
+		checkCollisions(true); // run the effects
+	} else {
+		debugC(1, kFreescapeDebugCode, "Runing effects:");
+		checkCollisions(true); // run the effects
+		if (_currentArea->getAreaID() == previousAreaID) {
+			if (_flyMode)
+				_position = _lastPosition;
+			else {
+				bool stepUp = tryStepUp(_position);
+				if (stepUp) {
+					playSound(4);
+					debugC(1, kFreescapeDebugCode, "Runing effects:");
+					checkCollisions(true); // run the effects (again)
+				} else {
+					playSound(2);
+					_position = _lastPosition;
+				}
+			}
+		}
+	}
+	areaScale = _currentArea->getScale();
+
+	_lastPosition = _position;
+	debugC(1, kFreescapeDebugMove, "new player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
+	debugC(1, kFreescapeDebugMove, "player height: %f", _position.y() - areaScale * _playerHeight);
+}
+
+bool FreescapeEngine::checkFloor(Math::Vector3d currentPosition) {
+	debugC(1, kFreescapeDebugMove, "Checking floor under the player");
+	int areaScale = _currentArea->getScale();
+	bool collided = checkCollisions(false);
+	assert(!collided);
+
+	_position.set(_position.x(), _position.y() - 2 * areaScale, _position.z());
+	collided = checkCollisions(false);
+	_position = currentPosition;
+	return collided;
+}
+
+bool FreescapeEngine::tryStepUp(Math::Vector3d currentPosition) {
+	debugC(1, kFreescapeDebugMove, "Try to step up!");
+	int areaScale = _currentArea->getScale();
+	_position.set(_position.x(), _position.y() + 64 * areaScale, _position.z());
+	bool collided = checkCollisions(false);
+	if (collided) {
+		_position = currentPosition;
+		return false;
+	} else {
+		// Try to step down
+		return true;
+	}
+}
+
+bool FreescapeEngine::tryStepDown(Math::Vector3d currentPosition) {
+	debugC(1, kFreescapeDebugMove, "Try to step down!");
+	int areaScale = _currentArea->getScale();
+	_position.set(_position.x(), _position.y() - areaScale, _position.z());
+	if (checkFloor(_position)) {
+		return true;
+	} else {
+		_position = currentPosition;
+		return false;
+	}
+}
+
+
+bool FreescapeEngine::checkCollisions(bool executeCode) {
+	int areaScale = _currentArea->getScale();
+	Math::Vector3d v1(_position.x() - areaScale * _playerWidth / 2, _position.y() - areaScale * _playerHeight , _position.z() - areaScale * _playerDepth / 2);
+	Math::Vector3d v2(_position.x() + areaScale * _playerWidth / 2, _position.y()                             , _position.z() + areaScale * _playerDepth / 2);
+
+	const Math::AABB boundingBox(v1, v2);
+	Object *obj = _currentArea->checkCollisions(boundingBox);
+
+	if (obj != nullptr) {
+		debugC(1, kFreescapeDebugMove, "Collided with object id %d of size %f %f %f", obj->getObjectID(), obj->getSize().x(), obj->getSize().y(), obj->getSize().z());
+		GeometricObject *gobj = (GeometricObject*) obj;
+		if (!executeCode) // Avoid executing code
+			return true;
+
+		executeConditions(gobj, false, true);
+		return true;
+	}
+	return false;
+}
+
+} // End of namespace
\ No newline at end of file


Commit: 9e68f6fe1f66f08327f321163274825b413272cf
    https://github.com/scummvm/scummvm/commit/9e68f6fe1f66f08327f321163274825b413272cf
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:15+01:00

Commit Message:
FREESCAPE: improved detection collision in driller

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/movement.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index d7c911f1c67..144a63d5393 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -110,6 +110,7 @@ Math::Vector3d FreescapeEngine::directionToVector(float pitch, float heading) {
 	v.setValue(0, cos(radPitch) * cos(radHeading));
 	v.setValue(1, sin(radPitch));
 	v.setValue(2, cos(radPitch) * sin(radHeading));
+	v.normalize();
 
 	return v;
 }
@@ -132,7 +133,7 @@ void FreescapeEngine::pressedKey(const int keycode) {}
 
 void FreescapeEngine::processInput() {
 	float currentFrame = g_system->getMillis();
-	float deltaTime = currentFrame - _lastFrame;
+	float deltaTime = 20.0;
 	_lastFrame = currentFrame;
 	Common::Event event;
 	while (g_system->getEventManager()->pollEvent(event)) {
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index 62470aed59c..9102d1dddb4 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -192,7 +192,8 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 		debugC(1, kFreescapeDebugCode, "Runing effects:");
 		checkCollisions(true); // run the effects
 	} else {
-		debugC(1, kFreescapeDebugCode, "Runing effects:");
+		debugC(1, kFreescapeDebugCode, "Runing effects: at: %f, %f, %f", _position.x(), _position.y(), _position.z());
+
 		checkCollisions(true); // run the effects
 		if (_currentArea->getAreaID() == previousAreaID) {
 			if (_flyMode)
@@ -258,8 +259,8 @@ bool FreescapeEngine::tryStepDown(Math::Vector3d currentPosition) {
 
 bool FreescapeEngine::checkCollisions(bool executeCode) {
 	int areaScale = _currentArea->getScale();
-	Math::Vector3d v1(_position.x() - areaScale * _playerWidth / 2, _position.y() - areaScale * _playerHeight , _position.z() - areaScale * _playerDepth / 2);
-	Math::Vector3d v2(_position.x() + areaScale * _playerWidth / 2, _position.y()                             , _position.z() + areaScale * _playerDepth / 2);
+	Math::Vector3d v1(_position.x() - areaScale * 0.75 * _playerWidth, _position.y() - areaScale * _playerHeight , _position.z() - areaScale * 0.75 * _playerDepth);
+	Math::Vector3d v2(_position.x() + areaScale * 0.75 * _playerWidth, _position.y()                             , _position.z() + areaScale * 0.75 * _playerDepth);
 
 	const Math::AABB boundingBox(v1, v2);
 	Object *obj = _currentArea->checkCollisions(boundingBox);


Commit: 0f8a55e256b6848922d8dc697ecfc7c886b857b7
    https://github.com/scummvm/scummvm/commit/0f8a55e256b6848922d8dc697ecfc7c886b857b7
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:15+01:00

Commit Message:
FREESCAPE: added missing space when printing bytecode

Changed paths:
    engines/freescape/language/8bitDetokeniser.cpp


diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index f3d4adeb8bd..409f3ea9bbe 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -188,7 +188,7 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 		case 11: // end condition if a variable doesn't have a particular value
 			detokenisedStream += "IF VAR!=? ";
 			detokenisedStream += Common::String::format("(v%d, %d)", (int)tokenisedCondition[bytePointer], (int)tokenisedCondition[bytePointer + 1]);
-			detokenisedStream += "THEN END ENDIF";
+			detokenisedStream += " THEN END ENDIF";
 			currentInstruction = FCLInstruction(Token::VARNOTEQ);
 			currentInstruction.setSource(tokenisedCondition[bytePointer]);
 			currentInstruction.setDestination(tokenisedCondition[bytePointer + 1]);
@@ -200,7 +200,7 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 		case 14: // end condition if a bit doesn't have a particular value
 			detokenisedStream += "IF BIT!=? ";
 			detokenisedStream += Common::String::format("(%d, %d)", (int)tokenisedCondition[bytePointer], (int)tokenisedCondition[bytePointer + 1]);
-			detokenisedStream += "THEN END ENDIF";
+			detokenisedStream += " THEN END ENDIF";
 			currentInstruction = FCLInstruction(Token::BITNOTEQ);
 			currentInstruction.setSource(tokenisedCondition[bytePointer]);
 			currentInstruction.setDestination(tokenisedCondition[bytePointer + 1]);
@@ -212,7 +212,7 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 		case 30: // end condition if an object is invisible
 			detokenisedStream += "IF INVIS? ";
 			detokenisedStream += Common::String::format("(%d)", (int)tokenisedCondition[bytePointer]);
-			detokenisedStream += "THEN END ENDIF";
+			detokenisedStream += " THEN END ENDIF";
 			currentInstruction = FCLInstruction(Token::INVISQ);
 			currentInstruction.setSource(tokenisedCondition[bytePointer]);
 			currentInstruction.setDestination(true); // invisible
@@ -224,7 +224,7 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 		case 31: // end condition if an object is visible
 			detokenisedStream += "IF VIS? ";
 			detokenisedStream += Common::String::format("(%d)", (int)tokenisedCondition[bytePointer]);
-			detokenisedStream += "THEN END ENDIF";
+			detokenisedStream += " THEN END ENDIF";
 			currentInstruction = FCLInstruction(Token::INVISQ);
 			currentInstruction.setSource(tokenisedCondition[bytePointer]);
 			currentInstruction.setDestination(false); // visible
@@ -237,7 +237,7 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 		case 32: // end condition if an object is visible in another area
 			detokenisedStream += "IF RINVIS? ";
 			detokenisedStream += Common::String::format("(%d, %d)", (int)tokenisedCondition[bytePointer], (int)tokenisedCondition[bytePointer + 1]);
-			detokenisedStream += "THEN END ENDIF";
+			detokenisedStream += " THEN END ENDIF";
 			currentInstruction = FCLInstruction(Token::INVISQ);
 			currentInstruction.setSource(tokenisedCondition[bytePointer]);
 			currentInstruction.setAdditional(tokenisedCondition[bytePointer + 1]);
@@ -251,7 +251,7 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 		case 33: // end condition if an object is invisible in another area
 			detokenisedStream += "IF RVIS? ";
 			detokenisedStream += Common::String::format("(%d, %d)", (int)tokenisedCondition[bytePointer], (int)tokenisedCondition[bytePointer + 1]);
-			detokenisedStream += "THEN END ENDIF";
+			detokenisedStream += " THEN END ENDIF";
 			currentInstruction = FCLInstruction(Token::INVISQ);
 			currentInstruction.setSource(tokenisedCondition[bytePointer]);
 			currentInstruction.setAdditional(tokenisedCondition[bytePointer + 1]);


Commit: f5b7b34e91796c640ef14dac5846005993b1ec2a
    https://github.com/scummvm/scummvm/commit/f5b7b34e91796c640ef14dac5846005993b1ec2a
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:16+01:00

Commit Message:
FREESCAPE: added more code to replicate sounds

Changed paths:
    engines/freescape/freescape.h
    engines/freescape/sound.cpp


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 9b998d8b66c..3077d2db20f 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -193,6 +193,7 @@ public:
 	void playWav(const Common::String filename);
 	void playSoundConst(double hzFreq, int duration);
 	void playSoundSweepIncWL(double hzFreq1, double hzFreq2, double wlStepPerMS, int resolution);
+	void playTeleporter(int totalIters);
 
 	// Rendering
 	int _screenW, _screenH;
diff --git a/engines/freescape/sound.cpp b/engines/freescape/sound.cpp
index 53604c4f92a..700e682536c 100644
--- a/engines/freescape/sound.cpp
+++ b/engines/freescape/sound.cpp
@@ -31,10 +31,9 @@ void FreescapeEngine::playSound(int index) {
 	if (!_mixer->isSoundHandleActive(_handle))
 		_mixer->stopHandle(_handle);
 
-	assert(_usePrerecordedSounds);
 	debug("Playing sound %d", index);
 	switch (index) {
-		case 1: // Done
+		case 1:
 			if (_usePrerecordedSounds) {
 				playWav("fsDOS_laserFire.wav");
 				//_system->delayMillis(50);
@@ -72,7 +71,7 @@ void FreescapeEngine::playSound(int index) {
 				playWav("fsDOS_roomChange.wav");
 				//_system->delayMillis(50);
 			} else {
-				playSoundConst(82, 60);
+				playSoundSweepIncWL(262, 100, 65.52 * kFreescapeSweepTuneFactor, 1);
 			}
 		break;
 		case 6:
@@ -80,7 +79,7 @@ void FreescapeEngine::playSound(int index) {
 				playWav("fsDOS_configMenu.wav");
 				//_system->delayMillis(50);
 			} else {
-				playSoundConst(82, 60);
+				playSoundConst(830, 60);
 			}
 		break;
 		case 7:
@@ -88,15 +87,15 @@ void FreescapeEngine::playSound(int index) {
 				playWav("fsDOS_bigHit.wav");
 				//_system->delayMillis(50);
 			} else {
-				playSoundConst(82, 60);
+				playSoundSweepIncWL(3000, 155, 7.28 * kFreescapeSweepTuneFactor, 1);
 			}
 		break;
 		case 8:
 			if (_usePrerecordedSounds) {
-				playWav("fsDOS_teleportActivated.wav");
+				playWav("fsDOS_teleporterActivated.wav");
 				//_system->delayMillis(50);
 			} else {
-				playSoundConst(82, 60);
+				playTeleporter(22);
 			}
 		break;
 
@@ -105,7 +104,7 @@ void FreescapeEngine::playSound(int index) {
 				playWav("fsDOS_powerUp.wav");
 				//_system->delayMillis(50);
 			} else {
-				playSoundConst(82, 60);
+				playSoundSweepIncWL(280, 5000, 9.1 * kFreescapeSweepTuneFactor, 1);
 			}
 		break;
 
@@ -114,16 +113,17 @@ void FreescapeEngine::playSound(int index) {
 				playWav("fsDOS_energyDrain.wav");
 				//_system->delayMillis(50);
 			} else {
-				playSoundConst(82, 60);
+				playSoundSweepIncWL(240, 255, 1.82 * kFreescapeSweepTuneFactor, 1);
 			}
 		break;
 
 		case 11: // ???
+			debug("Playing unknown sound");
 			if (_usePrerecordedSounds) {
 				//playWav("???.wav");
 				//_system->delayMillis(50);
 			} else {
-				playSoundConst(82, 60);
+				//playSoundConst(82, 60);
 			}
 		break;
 
@@ -132,7 +132,7 @@ void FreescapeEngine::playSound(int index) {
 				playWav("fsDOS_switchOff.wav");
 				//_system->delayMillis(50);
 			} else {
-				playSoundConst(82, 60);
+				playSoundSweepIncWL(555, 440, 1.82 * kFreescapeSweepTuneFactor, 1);
 			}
 		break;
 
@@ -141,7 +141,7 @@ void FreescapeEngine::playSound(int index) {
 				playWav("fsDOS_laserHit.wav");
 				//_system->delayMillis(50);
 			} else {
-				playSoundConst(82, 60);
+				playSoundSweepIncWL(3000, 420, 14.56 * kFreescapeSweepTuneFactor, 1);
 			}
 		break;
 
@@ -150,7 +150,7 @@ void FreescapeEngine::playSound(int index) {
 				playWav("fsDOS_tankFall.wav");
 				//_system->delayMillis(50);
 			} else {
-				playSoundConst(82, 60);
+				playSoundSweepIncWL(785, 310, 1.82 * kFreescapeSweepTuneFactor, 1);
 			}
 		break;
 
@@ -159,7 +159,9 @@ void FreescapeEngine::playSound(int index) {
 				playWav("fsDOS_successJingle.wav");
 				//_system->delayMillis(50);
 			} else {
-				playSoundConst(82, 60);
+				playSoundConst(587.330, 250);
+				playSoundConst(740, 175);
+				playSoundConst(880, 450);
 			}
 		break;
 
@@ -168,7 +170,7 @@ void FreescapeEngine::playSound(int index) {
 				//playWav("???.wav");
 				//_system->delayMillis(50);
 			} else {
-				playSoundConst(82, 60);
+				//playSoundConst(82, 60);
 			}
 		break;
 
@@ -177,7 +179,8 @@ void FreescapeEngine::playSound(int index) {
 				playWav("fsDOS_badJingle.wav");
 				//_system->delayMillis(50);
 			} else {
-				playSoundConst(82, 60);
+				playSoundConst(65, 150);
+				playSoundConst(44, 400);
 			}
 		break;
 
@@ -186,16 +189,17 @@ void FreescapeEngine::playSound(int index) {
 				//playWav("???.wav");
 				//_system->delayMillis(50);
 			} else {
-				playSoundConst(82, 60);
+				//playSoundConst(82, 60);
 			}
 		break;
 
 		case 19:
+			debug("Playing unknown sound");
 			if (_usePrerecordedSounds) {
 				//playWav("???.wav");
 				//_system->delayMillis(50);
 			} else {
-				playSoundConst(82, 60);
+				//playSoundConst(82, 60);
 			}
 		break;
 
@@ -204,7 +208,7 @@ void FreescapeEngine::playSound(int index) {
 				playWav("fsDOS_bigHit.wav");
 				//_system->delayMillis(50);
 			} else {
-				playSoundConst(82, 60);
+				playSoundSweepIncWL(3000, 155, 7.28 * kFreescapeSweepTuneFactor, 1);
 			}
 		break;
 		default:
@@ -279,4 +283,40 @@ void FreescapeEngine::playSoundSweepIncWL(double hzFreq1, double hzFreq2, double
 	_mixer->stopHandle(_handle);
 }
 
+void FreescapeEngine::playTeleporter(int totalIters) {
+	// Play FreeScape DOS teleporter-like effect, which is ascending arpeggio.
+	// Length of effect is variable; provide total number of iterations.
+
+	// The general pattern is two iterations upward, one iteration downward.
+	// This means one "ascension cycle" lasts three iterations.
+	// The result is a simulated echo (a better analogy would be a piano's
+	// damper pedal) with gradual ascending frequency.
+
+	// The frequency changes using the same wavelength-shift strategy that is
+	// found in playSoundSweepIncWL.
+
+	int i;
+	double fBase = 1193180.0 / 244.607;
+	double fInc = -600.0;
+	int stepCycle = 1;
+
+	// Loop over iterations
+	for (i = 0; i < totalIters; i++) {
+		playSoundConst(1193180.0 / fBase, 21);
+
+		if (stepCycle <= 1)
+		{
+			// Ascending first two portions of cycle
+			fBase += fInc;
+			stepCycle++;
+		}
+		else
+		{
+			// Descending final portion of cycle
+			fBase -= fInc;
+			stepCycle = 0;
+		}
+	}
+}
+
 }
\ No newline at end of file


Commit: e35d0aec9e33fce3f0d8a52e953fda99d88ed769
    https://github.com/scummvm/scummvm/commit/e35d0aec9e33fce3f0d8a52e953fda99d88ed769
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:16+01:00

Commit Message:
FREESCAPE: avoid crashing when an object is not found in the current/global area

Changed paths:
    engines/freescape/language/instruction.cpp


diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index 209c149f6ff..20346b5ff88 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -333,9 +333,11 @@ void FreescapeEngine::executeToggleVisibility(FCLInstruction &instruction) {
 		obj->toggleVisibility();
 	else {
 		obj = _areaMap[255]->objectWithID(objectID);
-		if (!obj)
-			error("ERROR!: obj %d does not exists in area %d nor in the global one!", objectID, areaID);
-
+		if (!obj) {
+			// This happens in Driller, the ketar hangar
+			warning("ERROR!: obj %d does not exists in area %d nor in the global one!", objectID, areaID);
+			return;
+		}
 		// If an object is not in the area, it is considered to be invisible
 		_currentArea->addObjectFromArea(objectID, _areaMap[255]);
 		obj = _areaMap[areaID]->objectWithID(objectID);


Commit: 3d08b94f57e99dbb923a60ea55bd358183a76bb9
    https://github.com/scummvm/scummvm/commit/3d08b94f57e99dbb923a60ea55bd358183a76bb9
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:16+01:00

Commit Message:
FREESCAPE: refactor area/global condition execution

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/language/instruction.cpp
    engines/freescape/movement.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 144a63d5393..07a28fbcd4e 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -221,8 +221,9 @@ void FreescapeEngine::shoot() {
 		if (gobj->conditionSource != nullptr)
 			debug("Must use shot = true when executing: %s", gobj->conditionSource->c_str());
 
-		executeConditions(gobj, true, false);
+		executeObjectConditions(gobj, true, false);
 	}
+	executeLocalGlobalConditions(true, false); // Only execute "on shot" room/global conditions
 }
 
 Common::Error FreescapeEngine::run() {
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 3077d2db20f..df2f553882b 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -162,7 +162,8 @@ public:
 	Common::Array<FCLInstructionVector> _conditions;
 
 	bool checkCollisions(bool executeCode);
-	void executeConditions(GeometricObject *obj, bool shot, bool collided);
+	void executeObjectConditions(GeometricObject *obj, bool shot, bool collided);
+	void executeLocalGlobalConditions(bool shot, bool collided);
 	void executeCode(FCLInstructionVector &code, bool shot, bool collided);
 
 	// Instructions
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index 20346b5ff88..5f097b7ceea 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -66,14 +66,15 @@ Token::Type FCLInstruction::getType() {
 	return type;
 }
 
-void FreescapeEngine::executeConditions(GeometricObject *obj, bool shot, bool collided) {
+void FreescapeEngine::executeObjectConditions(GeometricObject *obj, bool shot, bool collided) {
+	assert(obj != nullptr);
 	if (obj->conditionSource != nullptr) {
 		debugC(1, kFreescapeDebugCode, "Executing with collision flag: %s", obj->conditionSource->c_str());
 		executeCode(obj->condition, shot, collided);
 	}
+}
 
-	if (!isDriller())
-		return;
+void FreescapeEngine::executeLocalGlobalConditions(bool shot, bool collided) {
 
 	debugC(1, kFreescapeDebugCode, "Executing room conditions");
 	for (int i = 0; i < int(_currentArea->conditions.size()); i++) {
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index 9102d1dddb4..eacd7f24619 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -216,6 +216,7 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 	_lastPosition = _position;
 	debugC(1, kFreescapeDebugMove, "new player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
 	debugC(1, kFreescapeDebugMove, "player height: %f", _position.y() - areaScale * _playerHeight);
+	executeLocalGlobalConditions(false, true); // Only execute "on collision" room/global conditions
 }
 
 bool FreescapeEngine::checkFloor(Math::Vector3d currentPosition) {
@@ -271,7 +272,7 @@ bool FreescapeEngine::checkCollisions(bool executeCode) {
 		if (!executeCode) // Avoid executing code
 			return true;
 
-		executeConditions(gobj, false, true);
+		executeObjectConditions(gobj, false, true);
 		return true;
 	}
 	return false;


Commit: d15ed5bd0c3b313eb2f52005621b3bbd4474d907
    https://github.com/scummvm/scummvm/commit/d15ed5bd0c3b313eb2f52005621b3bbd4474d907
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:16+01:00

Commit Message:
FREESCAPE: added border for dark in ega mode

Changed paths:
    dists/engine-data/freescape.dat
    engines/freescape/games/dark.cpp


diff --git a/dists/engine-data/freescape.dat b/dists/engine-data/freescape.dat
index ffb60be86af..1d571c56ec4 100644
Binary files a/dists/engine-data/freescape.dat and b/dists/engine-data/freescape.dat differ
diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index d0e65c04d4b..d7947466948 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -27,6 +27,7 @@
 namespace Freescape {
 
 DarkEngine::DarkEngine(OSystem *syst) : FreescapeEngine(syst) {
+	_viewArea = Common::Rect(40, 24, 279, 124);
 	_playerHeight = 64;
 	_playerWidth = 12;
 	_playerDepth = 32;
@@ -37,22 +38,22 @@ void DarkEngine::loadAssets() {
 	Common::String path = ConfMan.get("path");
 	Common::FSDirectory gameDir(path);
 
-    Common::File exe;
-    if (_renderMode == "ega") {
-        file = gameDir.createReadStreamForMember("DSIDEE.EXE");
+	Common::File exe;
+	if (_renderMode == "ega") {
+		file = gameDir.createReadStreamForMember("DSIDEE.EXE");
 
-        if (file == nullptr)
-            error("Failed to open DSIDEE.EXE");
+		if (file == nullptr)
+			error("Failed to open DSIDEE.EXE");
 
-        load8bitBinary(file, 0xa280, 16);
-    } else if (_renderMode == "cga") {
-        file = gameDir.createReadStreamForMember("DSIDEC.EXE");
+		load8bitBinary(file, 0xa280, 16);
+	} else if (_renderMode == "cga") {
+		file = gameDir.createReadStreamForMember("DSIDEC.EXE");
 
-        if (file == nullptr)
-            error("Failed to open DSIDE.EXE");
-        load8bitBinary(file, 0x7bb0, 4); // TODO
-    } else
-        error("Invalid render mode %s for Dark Side", _renderMode.c_str());
+		if (file == nullptr)
+			error("Failed to open DSIDEC.EXE");
+		load8bitBinary(file, 0x7bb0, 4); // TODO
+	} else
+		error("Invalid render mode %s for Dark Side", _renderMode.c_str());
 }
 
 } // End of namespace Freescape
\ No newline at end of file


Commit: d8f1c3d0cba3e4c60bade147057c8e0ba825bda8
    https://github.com/scummvm/scummvm/commit/d8f1c3d0cba3e4c60bade147057c8e0ba825bda8
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:16+01:00

Commit Message:
FREESCAPE: basic ui for dark in ega mode

Changed paths:
    engines/freescape/freescape.h
    engines/freescape/games/dark.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index df2f553882b..ad1ad70daa0 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -263,6 +263,8 @@ public:
 	DarkEngine(OSystem *syst);
 
 	void loadAssets() override;
+	void gotoArea(uint16 areaID, int entranceID) override;
+	void drawUI() override;
 };
 
 class EclipseEngine : public FreescapeEngine {
diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index d7947466948..bee5fcb7284 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -23,6 +23,7 @@
 #include "common/file.h"
 
 #include "freescape/freescape.h"
+#include "freescape/language/8bitDetokeniser.h"
 
 namespace Freescape {
 
@@ -56,4 +57,93 @@ void DarkEngine::loadAssets() {
 		error("Invalid render mode %s for Dark Side", _renderMode.c_str());
 }
 
+void DarkEngine::gotoArea(uint16 areaID, int entranceID) {
+	debugC(1, kFreescapeDebugMove, "Jumping to area: %d, entrance: %d", areaID, entranceID);
+	if (!_gameStateBits.contains(areaID))
+		_gameStateBits[areaID] = 0;
+
+	assert(_areaMap.contains(areaID));
+	_currentArea = _areaMap[areaID];
+	_currentArea->show();
+
+	_currentAreaMessages.clear();
+	_currentAreaMessages.push_back(_currentArea->name);
+
+	int scale = _currentArea->getScale();
+	assert(scale > 0);
+
+	Entrance *entrance = nullptr;
+	if (entranceID > 0 || areaID == 127) {
+		entrance = (Entrance*) _currentArea->entranceWithID(entranceID);
+		assert(entrance);
+
+		_position = entrance->getOrigin();
+
+		if (_rotation == Math::Vector3d(0, 0, 0)) {
+			_rotation = entrance->getRotation();
+			_pitch = _rotation.x();
+			_yaw = _rotation.y() - 260;
+		}
+		debugC(1, kFreescapeDebugMove, "entrace position: %f %f %f", _position.x(), _position.y(), _position.z());
+		debugC(1, kFreescapeDebugMove, "player height: %d", scale * _playerHeight);
+		_position.setValue(1, _position.y() + scale * _playerHeight);
+	} else if (entranceID == 0) {
+		Math::Vector3d diff = _lastPosition - _position;
+		debug("dif: %f %f %f", diff.x(), diff.y(), diff.z());
+		// diff should be used to determinate which entrance to use
+		int newPos = -1;
+		if (abs(diff.x()) < abs(diff.z())) {
+			if (diff.z() > 0)
+				newPos = 4000;
+			else
+				newPos = 100;
+			_position.setValue(2, newPos);
+		} else {
+			if (diff.x() > 0)
+				newPos = 4000;
+			else
+				newPos = 100;
+			_position.setValue(0, newPos);
+		}
+		assert(newPos != -1);
+	}
+
+	debugC(1, kFreescapeDebugMove, "starting player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
+	playSound(5);
+}
+
+
+void DarkEngine::drawUI() {
+	_gfx->renderCrossair(0);
+
+	if (_currentAreaMessages.size() == 1) {
+		_gfx->setViewport(_fullscreenViewArea);
+
+		Graphics::Surface *surface = new Graphics::Surface();
+		surface->create(_screenW, _screenH, _gfx->_currentPixelFormat);
+		surface->fillRect(_fullscreenViewArea, 0xA0A0A0FF);
+
+		int score = _gameStateVars[k8bitVariableScore];
+
+		uint32 yellow = 0xFFFF55FF;
+		uint32 black = 0x000000FF;
+
+		drawStringInSurface(_currentAreaMessages[0], 112, 177, yellow, black, surface);
+		drawStringInSurface(Common::String::format("%04d", 2 * int(_position.x())), 201, 137, yellow, black, surface);
+		drawStringInSurface(Common::String::format("%04d", 2 * int(_position.z())), 201, 145, yellow, black, surface);
+		drawStringInSurface(Common::String::format("%04d", 2 * int(_position.y())), 201, 153, yellow, black, surface);
+
+
+		drawStringInSurface(Common::String::format("%07d", score), 95, 8, yellow, black, surface);
+
+		Texture *texture = _gfx->createTexture(surface);
+		_gfx->drawTexturedRect2D(_fullscreenViewArea, _fullscreenViewArea, texture);
+		surface->free();
+		delete surface;
+	}
+
+	_gfx->setViewport(_viewArea);
+}
+
+
 } // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 91eb970590e..4475dd3b4a5 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -281,9 +281,15 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 			i++;
 		}
 	} else if (isDriller() || isDark()) {
-		gasPocketX = file->readByte();
-		gasPocketY = file->readByte();
-		gasPocketRadius = file->readByte();
+		if (isDriller()) {
+			gasPocketX = file->readByte();
+			gasPocketY = file->readByte();
+			gasPocketRadius = file->readByte();
+		} else {
+			name = name + char(file->readByte());
+			name = name + char(file->readByte());
+			name = name + char(file->readByte());
+		}
 		debugC(1, kFreescapeDebugParser, "Gas pocket at (%d, %d) with radius %d", gasPocketX, gasPocketY, gasPocketRadius);
 		int i = 0;
 		while (i < 12) {
@@ -435,6 +441,9 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 		}
 
 		_areaMap[255] = new Area(255, 0, globalObjectsByID, nullptr);
+	} else if (isDark()) {
+		//loadMessages(file, 0x4135, 14, 20);
+		loadFonts(file, 0xa113);
 	}
 
 	file->seek(offset + 0xc8);


Commit: 03f0298e99d34eddd1c1a1638ce81866c437972a
    https://github.com/scummvm/scummvm/commit/03f0298e99d34eddd1c1a1638ce81866c437972a
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:16+01:00

Commit Message:
FREESCAPE: improved handling of rise/fall for all the games

Changed paths:
    engines/freescape/freescape.h
    engines/freescape/games/castle.cpp
    engines/freescape/games/dark.cpp
    engines/freescape/games/driller.cpp
    engines/freescape/games/eclipse.cpp
    engines/freescape/movement.cpp


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index ad1ad70daa0..68ae2f4760a 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -153,6 +153,7 @@ public:
 	Math::Vector3d _position, _rotation, _velocity;
 	Math::Vector3d _lastPosition;
 	int _playerHeightNumber;
+	Common::Array<int> _playerHeights;
 	uint16 _playerHeight;
 	uint16 _playerWidth;
 	uint16 _playerDepth;
diff --git a/engines/freescape/games/castle.cpp b/engines/freescape/games/castle.cpp
index 6dd62ff6b90..9e94c5fdad9 100644
--- a/engines/freescape/games/castle.cpp
+++ b/engines/freescape/games/castle.cpp
@@ -28,7 +28,11 @@
 namespace Freescape {
 
 CastleEngine::CastleEngine(OSystem *syst) : FreescapeEngine(syst) {
-	_playerHeight = 48;
+	_playerHeightNumber = 1;
+	_playerHeights.push_back(16);
+	_playerHeights.push_back(48);
+	_playerHeight = _playerHeights[_playerHeightNumber];
+
 	_playerWidth = 8;
 	_playerDepth = 8;
 }
diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index bee5fcb7284..4c48f419ad0 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -29,6 +29,11 @@ namespace Freescape {
 
 DarkEngine::DarkEngine(OSystem *syst) : FreescapeEngine(syst) {
 	_viewArea = Common::Rect(40, 24, 279, 124);
+	_playerHeightNumber = 1;
+	_playerHeights.push_back(16);
+	_playerHeights.push_back(48);
+
+	_playerHeight = _playerHeights[_playerHeightNumber];
 	_playerHeight = 64;
 	_playerWidth = 12;
 	_playerDepth = 32;
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index ac88304ee38..d53b6a3e323 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -30,7 +30,13 @@ namespace Freescape {
 
 DrillerEngine::DrillerEngine(OSystem *syst) : FreescapeEngine(syst) {
 	_viewArea = Common::Rect(40, 16, 279, 116);
-	_playerHeight = 64;
+	_playerHeightNumber = 1;
+	_playerHeights.push_back(16);
+	_playerHeights.push_back(48);
+	_playerHeights.push_back(80);
+	_playerHeights.push_back(112);
+
+	_playerHeight = _playerHeights[_playerHeightNumber];
 	_playerWidth = 12;
 	_playerDepth = 32;
 
diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index e54803ca40a..f26f7892acc 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -77,7 +77,11 @@ static const char* rawMessagesTable[] = {
 
 EclipseEngine::EclipseEngine(OSystem *syst) : FreescapeEngine(syst) {
 	_viewArea = Common::Rect(40, 32, 280, 132);
-	_playerHeight = 48;
+	_playerHeightNumber = 1;
+	_playerHeights.push_back(16);
+	_playerHeights.push_back(48);
+	_playerHeight = _playerHeights[_playerHeightNumber];
+
 	_playerWidth = 8;
 	_playerDepth = 8;
 
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index eacd7f24619..c9e72ea70c1 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -83,25 +83,26 @@ void FreescapeEngine::gotoArea(uint16 areaID, int entranceID) {
 	playSound(5);
 }
 
-void FreescapeEngine::changePlayerHeight(int delta) {
+void FreescapeEngine::changePlayerHeight(int index) {
 	int scale = _currentArea->getScale();
 	_position.setValue(1, _position.y() - scale * _playerHeight);
-	_playerHeight = _playerHeight + delta;
+	_playerHeight = _playerHeights[index];
 	_position.setValue(1, _position.y() + scale * _playerHeight);
 }
 
 void FreescapeEngine::rise() {
+	debugC(1, kFreescapeDebugMove, "playerHeightNumber: %d", _playerHeightNumber);
 	int previousAreaID = _currentArea->getAreaID();
 	int scale = _currentArea->getScale();
 
 	if (_flyMode) {
 		_position.setValue(1, _position.y() + scale * 32);
 	} else {
-		if (_playerHeightNumber == 10) // TODO
+		if (_playerHeightNumber == int(_playerHeights.size()) - 1)
 			return;
 
 		_playerHeightNumber++;
-		changePlayerHeight(16);
+		changePlayerHeight(_playerHeightNumber);
 	}
 
 	bool collided = checkCollisions(true);
@@ -110,7 +111,8 @@ void FreescapeEngine::rise() {
 			if (_flyMode)
 				_position = _lastPosition;
 			else {
-				changePlayerHeight(-16);
+				_playerHeightNumber--;
+				changePlayerHeight(_playerHeightNumber);
 			}
 		}
 	}
@@ -120,6 +122,7 @@ void FreescapeEngine::rise() {
 }
 
 void FreescapeEngine::lower() {
+	debugC(1, kFreescapeDebugMove, "playerHeightNumber: %d", _playerHeightNumber);
 	int previousAreaID = _currentArea->getAreaID();
 	int scale = _currentArea->getScale();
 
@@ -136,7 +139,7 @@ void FreescapeEngine::lower() {
 			return;
 
 		_playerHeightNumber--;
-		changePlayerHeight(-16);
+		changePlayerHeight(_playerHeightNumber);
 	}
 
 	_lastPosition = _position;


Commit: 1a02e483ac9ce66ec6db43bbe73049f6fdd93293
    https://github.com/scummvm/scummvm/commit/1a02e483ac9ce66ec6db43bbe73049f6fdd93293
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:17+01:00

Commit Message:
FREESCAPE: show height level in the driller ui

Changed paths:
    engines/freescape/games/driller.cpp


diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index d53b6a3e323..2f1427ce5bf 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -150,6 +150,7 @@ void DrillerEngine::drawUI() {
 		drawStringInSurface(Common::String::format("%04d", 2 * int(_position.x())), 150, 145, yellow, black, surface);
 		drawStringInSurface(Common::String::format("%04d", 2 * int(_position.z())), 150, 153, yellow, black, surface);
 		drawStringInSurface(Common::String::format("%04d", 2 * int(_position.y())), 150, 161, yellow, black, surface);
+		drawStringInSurface(Common::String::format("%d", _playerHeightNumber), 57, 161, yellow, black, surface);
 
 
 		drawStringInSurface(Common::String::format("%07d", score), 240, 129, yellow, black, surface);


Commit: 60ad427d29581d62848a765581a0ef322361ea2f
    https://github.com/scummvm/scummvm/commit/60ad427d29581d62848a765581a0ef322361ea2f
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:17+01:00

Commit Message:
FREESCAPE: palette fixes for rendering sky

Changed paths:
    engines/freescape/freescape.h
    engines/freescape/games/palettes.cpp
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 68ae2f4760a..5c7d99df72a 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -203,7 +203,6 @@ public:
 	Common::String _renderMode;
 	Graphics::PixelBuffer *getPalette(uint8 areaNumber, uint8 c1, uint8 c2, uint8 c3, uint8 c4, uint16 ncolors);
 	ColorMap _colorMap;
-	uint8 remapColor(uint8 index);
 	void drawFrame();
 	uint8 _colorNumber;
 	Math::Vector3d _scaleVector;
diff --git a/engines/freescape/games/palettes.cpp b/engines/freescape/games/palettes.cpp
index d26632355d2..566ff4641f9 100644
--- a/engines/freescape/games/palettes.cpp
+++ b/engines/freescape/games/palettes.cpp
@@ -61,9 +61,4 @@ void FreescapeEngine::loadColorPalette() {
 	_gfx->_colorMap = &_colorMap;
 }
 
-uint8 FreescapeEngine::remapColor(uint8 index) {
-	return index;
-}
-
-
 } // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index b0c4bfdcf11..23c48306de6 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -569,6 +569,7 @@ void TinyGLRenderer::drawSky(uint8 color) {
 	assert(getRGBAt(color, r, g, b)); // TODO: move check inside this function
 	tglClearColor(r / 255., g / 255., b / 255., 1.0);
 	tglClear(TGL_COLOR_BUFFER_BIT | TGL_DEPTH_BUFFER_BIT);
+	tglClearColor(0, 0, 0, 1.0);
 }
 
 void TinyGLRenderer::drawFloor(uint8 color) {
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 4475dd3b4a5..831c693a79b 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -92,14 +92,14 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 			if (_renderMode == "cga")
 				entry = entry % 4; // TODO: use dithering
 
-			colours->push_back(remapColor(entry));
+			colours->push_back(entry);
 			debugC(1, kFreescapeDebugParser, "color[%d] = %x", 2*colour, entry);
 
 			entry = data >> 4;
 			if (_renderMode == "cga")
 				entry = entry % 4; // TODO: use dithering
 
-			colours->push_back(remapColor(entry));
+			colours->push_back(entry);
 			debugC(1, kFreescapeDebugParser, "color[%d] = %x", 2*colour+1, entry);
 			byteSizeOfObject--;
 		}
@@ -330,8 +330,8 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	Area *area = new Area(areaNumber, areaFlags, objectsByID, entrancesByID);
 	area->name = name;
 	area->scale = scale;
-	area->skyColor = remapColor(skyColor);
-	area->groundColor = remapColor(groundColor);
+	area->skyColor = skyColor;
+	area->groundColor = groundColor;
 
 	// Driller specific
 	area->gasPocketPosition = Common::Point(32 * gasPocketX, 32 * gasPocketY);


Commit: 0388784ae81e7a1c97904ff41ddb106f04e54275
    https://github.com/scummvm/scummvm/commit/0388784ae81e7a1c97904ff41ddb106f04e54275
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:17+01:00

Commit Message:
FREESCAPE: added special case to convert rectangles that are really lines

Changed paths:
    engines/freescape/objects/geometricobject.cpp


diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index 35bfd717ec8..d613bbb50dd 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -141,6 +141,25 @@ GeometricObject::GeometricObject(
 		ordinates = new Common::Array<uint16>(*_ordinates);
 	condition = _conditionInstructions;
 	conditionSource = _conditionSource;
+
+	if (type == Type::Rectangle) {
+		if ((size.x() == 0 && size.y() == 0) ||
+			(size.y() == 0 && size.z() == 0) ||
+			(size.x() == 0 && size.z() == 0)) {
+
+			type = Type::Line;
+			assert(!ordinates);
+			ordinates = new Common::Array<uint16>();
+			ordinates->push_back(origin.x());
+			ordinates->push_back(origin.y());
+			ordinates->push_back(origin.z());
+
+			ordinates->push_back(origin.x() + size.x());
+			ordinates->push_back(origin.y() + size.y());
+			ordinates->push_back(origin.z() + size.z());
+		   }
+	}
+
 	createBoundingBox();
 }
 


Commit: 8777a3c9db7ec52b5a2dcebb753b837aa7b69fb0
    https://github.com/scummvm/scummvm/commit/8777a3c9db7ec52b5a2dcebb753b837aa7b69fb0
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:17+01:00

Commit Message:
FREESCAPE: refactor sky drawing for each game

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/games/dark.cpp
    engines/freescape/games/driller.cpp
    engines/freescape/games/eclipse.cpp
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/gfx_tinygl.h


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 5af219ee316..0e374d204b8 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -156,12 +156,6 @@ void Area::saveObjects(Common::WriteStream *stream) {
 
 void Area::draw(Freescape::Renderer *gfx) {
 	gfx->clear();
-	if (skyColor != 255) {
-		gfx->_keyColor = 0;
-		gfx->drawSky(skyColor);
-	} else
-		gfx->_keyColor = 255;
-
 	assert(drawableObjects.size() > 0);
 	for (Common::Array<Object *>::iterator it = drawableObjects.begin(); it != drawableObjects.end(); it++) {
 		if (!(*it)->isDestroyed() && !(*it)->isInvisible()) {
diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index 4c48f419ad0..e115dd94622 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -115,6 +115,11 @@ void DarkEngine::gotoArea(uint16 areaID, int entranceID) {
 
 	debugC(1, kFreescapeDebugMove, "starting player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
 	playSound(5);
+	// Ignore sky/ground fields
+	if (_currentArea->getAreaFlags() == 1)
+		_gfx->_keyColor = 0;
+	else
+		_gfx->_keyColor = 255;
 }
 
 
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 2f1427ce5bf..7f70a4bc84f 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -104,6 +104,11 @@ void DrillerEngine::gotoArea(uint16 areaID, int entranceID) {
 
 	debugC(1, kFreescapeDebugMove, "starting player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
 	playSound(5);
+	// Ignore sky/ground fields
+	if (_currentArea->getAreaFlags() == 1)
+		_gfx->_keyColor = 0;
+	else
+		_gfx->_keyColor = 255;
 }
 
 
diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index f26f7892acc..0f6bb1e83fc 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -164,6 +164,12 @@ void EclipseEngine::gotoArea(uint16 areaID, int entranceID) {
 	_position.setValue(1, _position.y() + scale * _playerHeight);
 	debugC(1, kFreescapeDebugMove, "starting player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
 	playSound(5);
+
+	if (_currentArea->skyColor > 0) {
+		_gfx->_keyColor = 0;
+		_gfx->setSkyColor(_currentArea->skyColor);
+	} else
+		_gfx->_keyColor = 255;
 }
 
 
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 197d613ee45..ee76d8e81ee 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -97,7 +97,7 @@ public:
 	virtual void renderPyramid(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours, int type) = 0;
 	virtual void renderFace(const Common::Array<Math::Vector3d> &vertices) = 0;
 
-	virtual void drawSky(uint8 color) = 0;
+	virtual void setSkyColor(uint8 color) = 0;
 	virtual void drawFloor(uint8 color) = 0;
 
 	Common::Rect viewport() const;
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 23c48306de6..27d085da1f7 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -564,12 +564,11 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 	}
 }
 
-void TinyGLRenderer::drawSky(uint8 color) {
+void TinyGLRenderer::setSkyColor(uint8 color) {
 	uint8 r, g, b;
 	assert(getRGBAt(color, r, g, b)); // TODO: move check inside this function
 	tglClearColor(r / 255., g / 255., b / 255., 1.0);
 	tglClear(TGL_COLOR_BUFFER_BIT | TGL_DEPTH_BUFFER_BIT);
-	tglClearColor(0, 0, 0, 1.0);
 }
 
 void TinyGLRenderer::drawFloor(uint8 color) {
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index bcc1bb0ba7d..8cc2aa88f12 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -54,7 +54,7 @@ public:
     virtual void renderFace(const Common::Array<Math::Vector3d> &vertices) override;
 
 	virtual void flipBuffer() override;
-	virtual void drawSky(uint8 color) override;
+	virtual void setSkyColor(uint8 color) override;
 	virtual void drawFloor(uint8 color) override;
 };
 


Commit: 560a3e85a45ea3a64914c903191f8617bd649cf9
    https://github.com/scummvm/scummvm/commit/560a3e85a45ea3a64914c903191f8617bd649cf9
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:17+01:00

Commit Message:
FREESCAPE: specialized gotoArea function for castle

Changed paths:
    engines/freescape/freescape.h
    engines/freescape/games/castle.cpp
    engines/freescape/movement.cpp


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 5c7d99df72a..b02b4e5d685 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -283,6 +283,8 @@ public:
 	CastleEngine(OSystem *syst);
 
 	void loadAssets() override;
+
+	void gotoArea(uint16 areaID, int entranceID) override;
 };
 
 extern FreescapeEngine *g_freescape;
diff --git a/engines/freescape/games/castle.cpp b/engines/freescape/games/castle.cpp
index 9e94c5fdad9..7874da2954f 100644
--- a/engines/freescape/games/castle.cpp
+++ b/engines/freescape/games/castle.cpp
@@ -65,4 +65,44 @@ void CastleEngine::loadAssets() {
 	//load8bitBinary(file, 0x791a, 16);
 }
 
+void CastleEngine::gotoArea(uint16 areaID, int entranceID) {
+	debugC(1, kFreescapeDebugMove, "Jumping to area: %d, entrance: %d", areaID, entranceID);
+	if (!_gameStateBits.contains(areaID))
+		_gameStateBits[areaID] = 0;
+
+	assert(_areaMap.contains(areaID));
+	_currentArea = _areaMap[areaID];
+	_currentArea->show();
+
+	int scale = _currentArea->getScale();
+	assert(scale > 0);
+
+	Entrance *entrance = nullptr;
+	if (entranceID > 0) {
+		entrance = (Entrance*) _currentArea->entranceWithID(entranceID);
+
+		assert(entrance);
+		_position = entrance->getOrigin();
+
+		if (_rotation == Math::Vector3d(0, 0, 0)) {
+			_rotation = entrance->getRotation();
+			_pitch = _rotation.x();
+			_yaw = _rotation.y() - 260;
+		}
+		debugC(1, kFreescapeDebugMove, "entrace position: %f %f %f", _position.x(), _position.y(), _position.z());
+		debugC(1, kFreescapeDebugMove, "player height: %d", scale * _playerHeight);
+		_position.setValue(1, _position.y() + scale * _playerHeight);
+	}
+
+	debugC(1, kFreescapeDebugMove, "starting player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
+	playSound(5);
+
+	if (_currentArea->skyColor > 0) {
+		_gfx->_keyColor = 0;
+		_gfx->setSkyColor(_currentArea->skyColor);
+	} else
+		_gfx->_keyColor = 255;
+}
+
+
 } // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index c9e72ea70c1..8225c3df47f 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -24,63 +24,7 @@
 namespace Freescape {
 
 void FreescapeEngine::gotoArea(uint16 areaID, int entranceID) {
-	debugC(1, kFreescapeDebugMove, "Jumping to area: %d, entrance: %d", areaID, entranceID);
-	if (!_gameStateBits.contains(areaID))
-		_gameStateBits[areaID] = 0;
-
-	assert(_areaMap.contains(areaID));
-	_currentArea = _areaMap[areaID];
-	_currentArea->show();
-
-	_currentAreaMessages.clear();
-	if (!_messagesList.empty())
-		_currentAreaMessages.push_back(_messagesList[1]);
-	else
-		_currentAreaMessages.push_back("");
-
-	_currentAreaMessages.push_back(_currentArea->name);
-
-	int scale = _currentArea->getScale();
-	assert(scale > 0);
-
-	Entrance *entrance = nullptr;
-	if (entranceID > 0 || areaID == 127) {
-		entrance = (Entrance*) _currentArea->entranceWithID(entranceID);
-
-		assert(entrance);
-		_position = entrance->getOrigin();
-
-		if (_rotation == Math::Vector3d(0, 0, 0)) {
-			_rotation = entrance->getRotation();
-			_pitch = _rotation.x();
-			_yaw = _rotation.y() - 260;
-		}
-		debugC(1, kFreescapeDebugMove, "entrace position: %f %f %f", _position.x(), _position.y(), _position.z());
-		debugC(1, kFreescapeDebugMove, "player height: %d", scale * _playerHeight);
-		_position.setValue(1, _position.y() + scale * _playerHeight);
-	} else if (entranceID == 0) {
-		Math::Vector3d diff = _lastPosition - _position;
-		debug("dif: %f %f %f", diff.x(), diff.y(), diff.z());
-		// diff should be used to determinate which entrance to use
-		int newPos = -1;
-		if (abs(diff.x()) < abs(diff.z())) {
-			if (diff.z() > 0)
-				newPos = 4000;
-			else
-				newPos = 100;
-			_position.setValue(2, newPos);
-		} else {
-			if (diff.x() > 0)
-				newPos = 4000;
-			else
-				newPos = 100;
-			_position.setValue(0, newPos);
-		}
-		assert(newPos != -1);
-	}
-
-	debugC(1, kFreescapeDebugMove, "starting player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
-	playSound(5);
+	error("Function \"%s\" not implemented", __FUNCTION__);
 }
 
 void FreescapeEngine::changePlayerHeight(int index) {


Commit: 9cf282a51463486ed39e0e2c32a68ca5605ab4dd
    https://github.com/scummvm/scummvm/commit/9cf282a51463486ed39e0e2c32a68ca5605ab4dd
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:17+01:00

Commit Message:
FREESCAPE: fixes in the position

Changed paths:
    engines/freescape/movement.cpp


diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index 8225c3df47f..bfbf126ba9d 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -112,10 +112,18 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 		_position = _position + _cameraRight * velocity;
 		break;
 	}
+
 	// restore y coordinate
 	if (!_flyMode)
 		_position.set(_position.x(), positionY, _position.z());
 
+	for (int i = 0; i < 3; i++) {
+		if (_position.getValue(i) < 0)
+			_position.setValue(i, 0);
+		else if (_position.getValue(i) > 8128)
+			_position.setValue(i, 8128);
+	}
+
 	bool collided = checkCollisions(false);
 
 	if (!collided) {
@@ -208,7 +216,7 @@ bool FreescapeEngine::tryStepDown(Math::Vector3d currentPosition) {
 bool FreescapeEngine::checkCollisions(bool executeCode) {
 	int areaScale = _currentArea->getScale();
 	Math::Vector3d v1(_position.x() - areaScale * 0.75 * _playerWidth, _position.y() - areaScale * _playerHeight , _position.z() - areaScale * 0.75 * _playerDepth);
-	Math::Vector3d v2(_position.x() + areaScale * 0.75 * _playerWidth, _position.y()                             , _position.z() + areaScale * 0.75 * _playerDepth);
+	Math::Vector3d v2(_position.x() + areaScale * 0.75 * _playerWidth, _position.y() + areaScale                 , _position.z() + areaScale * 0.75 * _playerDepth);
 
 	const Math::AABB boundingBox(v1, v2);
 	Object *obj = _currentArea->checkCollisions(boundingBox);


Commit: e108873791b12da996a8b6bb1f462d6d27e39b02
    https://github.com/scummvm/scummvm/commit/e108873791b12da996a8b6bb1f462d6d27e39b02
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:18+01:00

Commit Message:
FREESCAPE: adjusted collision detection using last position

Changed paths:
    engines/freescape/games/castle.cpp
    engines/freescape/games/dark.cpp
    engines/freescape/games/driller.cpp
    engines/freescape/games/eclipse.cpp
    engines/freescape/movement.cpp


diff --git a/engines/freescape/games/castle.cpp b/engines/freescape/games/castle.cpp
index 7874da2954f..7f18eb8d55c 100644
--- a/engines/freescape/games/castle.cpp
+++ b/engines/freescape/games/castle.cpp
@@ -96,8 +96,9 @@ void CastleEngine::gotoArea(uint16 areaID, int entranceID) {
 
 	debugC(1, kFreescapeDebugMove, "starting player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
 	playSound(5);
+	_lastPosition = _position;
 
-	if (_currentArea->skyColor > 0) {
+	if (_currentArea->skyColor > 0 && _currentArea->skyColor != 255) {
 		_gfx->_keyColor = 0;
 		_gfx->setSkyColor(_currentArea->skyColor);
 	} else
diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index e115dd94622..a6fd9f92b6d 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -115,6 +115,8 @@ void DarkEngine::gotoArea(uint16 areaID, int entranceID) {
 
 	debugC(1, kFreescapeDebugMove, "starting player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
 	playSound(5);
+	_lastPosition = _position;
+
 	// Ignore sky/ground fields
 	if (_currentArea->getAreaFlags() == 1)
 		_gfx->_keyColor = 0;
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 7f70a4bc84f..4eaf8a296d8 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -101,6 +101,7 @@ void DrillerEngine::gotoArea(uint16 areaID, int entranceID) {
 		}
 		assert(newPos != -1);
 	}
+	_lastPosition = _position;
 
 	debugC(1, kFreescapeDebugMove, "starting player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
 	playSound(5);
diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index 0f6bb1e83fc..405d1b71938 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -165,7 +165,9 @@ void EclipseEngine::gotoArea(uint16 areaID, int entranceID) {
 	debugC(1, kFreescapeDebugMove, "starting player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
 	playSound(5);
 
-	if (_currentArea->skyColor > 0) {
+	_lastPosition = _position;
+
+	if (_currentArea->skyColor > 0 && _currentArea->skyColor != 255) {
 		_gfx->_keyColor = 0;
 		_gfx->setSkyColor(_currentArea->skyColor);
 	} else
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index bfbf126ba9d..9dcd5481f5e 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -215,10 +215,13 @@ bool FreescapeEngine::tryStepDown(Math::Vector3d currentPosition) {
 
 bool FreescapeEngine::checkCollisions(bool executeCode) {
 	int areaScale = _currentArea->getScale();
-	Math::Vector3d v1(_position.x() - areaScale * 0.75 * _playerWidth, _position.y() - areaScale * _playerHeight , _position.z() - areaScale * 0.75 * _playerDepth);
-	Math::Vector3d v2(_position.x() + areaScale * 0.75 * _playerWidth, _position.y() + areaScale                 , _position.z() + areaScale * 0.75 * _playerDepth);
+	Math::AABB boundingBox(_lastPosition, _lastPosition);
 
-	const Math::AABB boundingBox(v1, v2);
+	Math::Vector3d v1(_position.x() - areaScale, _position.y() - areaScale * _playerHeight , _position.z() - areaScale);
+	Math::Vector3d v2(_position.x() + areaScale, _position.y() + areaScale                 , _position.z() + areaScale);
+
+	boundingBox.expand(v1);
+	boundingBox.expand(v2);
 	Object *obj = _currentArea->checkCollisions(boundingBox);
 
 	if (obj != nullptr) {


Commit: de83f3a1e89cc97e5c37943725eee3f5f70586fe
    https://github.com/scummvm/scummvm/commit/de83f3a1e89cc97e5c37943725eee3f5f70586fe
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:18+01:00

Commit Message:
FREESCAPE: no drilling in fly mode

Changed paths:
    engines/freescape/games/driller.cpp


diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 4eaf8a296d8..178995d21c9 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -195,7 +195,7 @@ void DrillerEngine::pressedKey(const int keycode) {
 	if (keycode == Common::KEYCODE_d) {
 		Common::Point gasPocket = _currentArea->gasPocketPosition;
 		uint32 gasPocketRadius = _currentArea->gasPocketRadius;
-		if (gasPocketRadius > 0 && !_currentArea->drillDeployed()) {
+		if (gasPocketRadius > 0 && !_currentArea->drillDeployed() && !_flyMode) {
 			if (_gameStateVars[k8bitVariableEnergy] < 5) {
 				// Show "no enough energy" message
 				return;
@@ -220,7 +220,7 @@ void DrillerEngine::pressedKey(const int keycode) {
 			// TODO: reduce energy
 		}
 	} else if (keycode == Common::KEYCODE_c) {
-		if (_currentArea->drillDeployed()) {
+		if (_currentArea->drillDeployed() && !_flyMode) {
 			if (_gameStateVars[k8bitVariableEnergy] < 5) {
 				// Show "no enough energy" message
 				return;


Commit: ec7375cb5ead87a2d268e6c52ef8a9fcc045be10
    https://github.com/scummvm/scummvm/commit/ec7375cb5ead87a2d268e6c52ef8a9fcc045be10
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:18+01:00

Commit Message:
FREESCAPE: show proper messages related with drilling in driller

Changed paths:
    engines/freescape/games/driller.cpp


diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 178995d21c9..928a14769d7 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -195,41 +195,65 @@ void DrillerEngine::pressedKey(const int keycode) {
 	if (keycode == Common::KEYCODE_d) {
 		Common::Point gasPocket = _currentArea->gasPocketPosition;
 		uint32 gasPocketRadius = _currentArea->gasPocketRadius;
-		if (gasPocketRadius > 0 && !_currentArea->drillDeployed() && !_flyMode) {
-			if (_gameStateVars[k8bitVariableEnergy] < 5) {
-				// Show "no enough energy" message
-				return;
-			}
-
-			_gameStateVars[k8bitVariableEnergy] = _gameStateVars[k8bitVariableEnergy] - 5;
-			_gameStateVars[32]++;
-			// TODO: check if there is space for the drill
-			Math::Vector3d drillPosition = _cameraFront;
-			drillPosition =  _position + 256 * drillPosition;
-
-			debugC(1, kFreescapeDebugMove, "Current position at %f %f %f", _position.x(), _position.y(), _position.z());
-			drillPosition.setValue(1, _position.y() - _playerHeight * _currentArea->getScale());
-			debugC(1, kFreescapeDebugMove, "Trying to adding drill at %f %f %f", drillPosition.x(), drillPosition.y(), drillPosition.z());
-			debugC(1, kFreescapeDebugMove, "with pitch: %f and yaw %f", _pitch, _yaw);
-
-			const Math::Vector3d gasPocket3D(gasPocket.x, 1, gasPocket.y);
-			addDrill(drillPosition);
-			float distance = (gasPocket3D - drillPosition).length();
-			debugC(1, kFreescapeDebugMove, "length to gas pocket: %f with radius %d", distance, _currentArea->gasPocketRadius);
-			// TODO check the result of the drilling
-			// TODO: reduce energy
+		if (gasPocketRadius == 0)
+			return;
+
+		if (_flyMode) {
+			_currentAreaMessages[0] = _messagesList[8];
+			return;
+		}
+
+		if (_currentArea->drillDeployed()) {
+			_currentAreaMessages[0] = _messagesList[12];
+			return;
+		}
+
+		if (_gameStateVars[k8bitVariableEnergy] < 5) {
+			_currentAreaMessages[0] = _messagesList[7];
+			return;
 		}
+
+		_gameStateVars[k8bitVariableEnergy] = _gameStateVars[k8bitVariableEnergy] - 5;
+		_gameStateVars[32]++;
+		// TODO: check if there is space for the drill
+		Math::Vector3d drillPosition = _cameraFront;
+		drillPosition =  _position + 256 * drillPosition;
+
+		debugC(1, kFreescapeDebugMove, "Current position at %f %f %f", _position.x(), _position.y(), _position.z());
+		drillPosition.setValue(1, _position.y() - _playerHeight * _currentArea->getScale());
+		debugC(1, kFreescapeDebugMove, "Trying to adding drill at %f %f %f", drillPosition.x(), drillPosition.y(), drillPosition.z());
+		debugC(1, kFreescapeDebugMove, "with pitch: %f and yaw %f", _pitch, _yaw);
+
+		const Math::Vector3d gasPocket3D(gasPocket.x, 1, gasPocket.y);
+		addDrill(drillPosition);
+		float distance = (gasPocket3D - drillPosition).length();
+		debugC(1, kFreescapeDebugMove, "length to gas pocket: %f with radius %d", distance, _currentArea->gasPocketRadius);
+		// TODO: show the result of the drilling
+		_currentAreaMessages[0] = _messagesList[3];
+
 	} else if (keycode == Common::KEYCODE_c) {
-		if (_currentArea->drillDeployed() && !_flyMode) {
-			if (_gameStateVars[k8bitVariableEnergy] < 5) {
-				// Show "no enough energy" message
-				return;
-			}
-
-			_gameStateVars[k8bitVariableEnergy] = _gameStateVars[k8bitVariableEnergy] - 5;
-			_gameStateVars[32]--;
-			_currentArea->removeDrill();
+		uint32 gasPocketRadius = _currentArea->gasPocketRadius;
+		if (gasPocketRadius == 0)
+			return;
+
+		if (_flyMode) {
+			_currentAreaMessages[0] = _messagesList[8];
+			return;
+		}
+
+		if (!_currentArea->drillDeployed()) {
+			_currentAreaMessages[0] = _messagesList[13];
+			return;
+		}
+
+		if (_gameStateVars[k8bitVariableEnergy] < 5) {
+			_currentAreaMessages[0] = _messagesList[7];
+			return;
 		}
+
+		_gameStateVars[k8bitVariableEnergy] = _gameStateVars[k8bitVariableEnergy] - 5;
+		_gameStateVars[32]--;
+		_currentArea->removeDrill();
 	}
 }
 


Commit: 756c4d3b03792cb8c82de05d647a5bba6a59b123
    https://github.com/scummvm/scummvm/commit/756c4d3b03792cb8c82de05d647a5bba6a59b123
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:18+01:00

Commit Message:
FREESCAPE: moved some driller specific code outside the area class

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/freescape.h
    engines/freescape/games/driller.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 0e374d204b8..ce32e8686fa 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -197,19 +197,6 @@ Object *Area::checkCollisions(const Math::AABB &boundingBox) {
 	return collided;
 }
 
-void Area::removeDrill() {
-	drillPosition = Math::Vector3d();
-	for (int16 id = 252; id < 256; id++) {
-		objectsByID->erase(id);
-		assert(drawableObjects[0]->getObjectID() == id);
-		drawableObjects.remove_at(0);
-	}
-}
-
-bool Area::drillDeployed() {
-	return (drawableObjects[0]->getObjectID() == 252);
-}
-
 void Area::addObject(Object *obj) {
 	assert(obj);
 	int id = obj->getObjectID();
@@ -220,6 +207,17 @@ void Area::addObject(Object *obj) {
 		drawableObjects.insert_at(0, obj);
 }
 
+void Area::removeObject(int16 id) {
+	assert(objectsByID->contains(id));
+	for (int i = 0; i < int(drawableObjects.size()); i++) {
+		if (drawableObjects[i]->getObjectID() == id) {
+			drawableObjects.remove_at(i);
+			break;
+		}
+	}
+	objectsByID->erase(id);
+}
+
 void Area::addObjectFromArea(int16 id, Area *global) {
 	debug("Adding object %d to room structure", id);
 	Object *obj = global->objectWithID(id);
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index ff9b7c5e617..09b73ab6b11 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -53,6 +53,7 @@ public:
 	void addObjectFromArea(int16 id, Area *global);
 	void addObject(Object *obj);
 	void addStructure(Area *global);
+	void removeObject(int16 id);
 
 	Common::Array<Common::String*> conditionSources;
 	Common::Array<FCLInstructionVector> conditions;
@@ -63,7 +64,6 @@ public:
 
 	// Driller specific
 	void removeDrill();
-	bool drillDeployed();
 	Math::Vector3d drillPosition;
 	Common::Point gasPocketPosition;
 	uint32 gasPocketRadius;
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index b02b4e5d685..5d95855284b 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -255,7 +255,9 @@ public:
 	void pressedKey(const int keycode) override;
 
 	private:
+	bool drillDeployed();
 	void addDrill(const Math::Vector3d position);
+	void removeDrill();
 };
 
 class DarkEngine : public FreescapeEngine {
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 928a14769d7..3867640f037 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -203,7 +203,7 @@ void DrillerEngine::pressedKey(const int keycode) {
 			return;
 		}
 
-		if (_currentArea->drillDeployed()) {
+		if (drillDeployed()) {
 			_currentAreaMessages[0] = _messagesList[12];
 			return;
 		}
@@ -241,7 +241,7 @@ void DrillerEngine::pressedKey(const int keycode) {
 			return;
 		}
 
-		if (!_currentArea->drillDeployed()) {
+		if (!drillDeployed()) {
 			_currentAreaMessages[0] = _messagesList[13];
 			return;
 		}
@@ -253,10 +253,14 @@ void DrillerEngine::pressedKey(const int keycode) {
 
 		_gameStateVars[k8bitVariableEnergy] = _gameStateVars[k8bitVariableEnergy] - 5;
 		_gameStateVars[32]--;
-		_currentArea->removeDrill();
+		removeDrill();
 	}
 }
 
+bool DrillerEngine::drillDeployed() {
+	return (_currentArea->objectWithID(252) != nullptr);
+}
+
 void DrillerEngine::addDrill(const Math::Vector3d position) {
 	//int drillObjectIDs[8] = {255, 254, 253, 252, 251, 250, 248, 247};
 	GeometricObject *obj = nullptr;
@@ -327,6 +331,12 @@ void DrillerEngine::addDrill(const Math::Vector3d position) {
 	_currentArea->addObject(obj);
 }
 
+void DrillerEngine::removeDrill() {
+	for (int16 id = 252; id < 256; id++) {
+		_currentArea->removeObject(id);
+	}
+}
+
 void DrillerEngine::initGameState() {
 	for (int i = 0; i < k8bitMaxVariable; i++) // TODO: check maximum variable
 		_gameStateVars[i] = 0;


Commit: 4e2dbd51f30d2db664964cef35460acc7cf9573c
    https://github.com/scummvm/scummvm/commit/4e2dbd51f30d2db664964cef35460acc7cf9573c
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:18+01:00

Commit Message:
FREESCAPE: fixed initial rotation when traversing entrances

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/castle.cpp
    engines/freescape/games/dark.cpp
    engines/freescape/games/driller.cpp
    engines/freescape/games/eclipse.cpp
    engines/freescape/movement.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 07a28fbcd4e..d7f0de967bb 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -319,6 +319,11 @@ void FreescapeEngine::rotate(Common::Point lastMousePos, Common::Point mousePos)
 	if (_pitch < 0.0f)
 		_pitch += 360.0f;
 
+	if (_yaw > 360.0f)
+		_yaw -= 360.0f;
+	if (_yaw < 0.0f)
+		_yaw += 360.0f;
+
 	_cameraFront = directionToVector(_pitch, _yaw);
 
 	// // _right = _front x _up;
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 5d95855284b..1acacdf4570 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -143,6 +143,7 @@ public:
 	// Euler Angles
 	float _yaw;
 	float _pitch;
+	void traverseEntrance(uint16 entranceID);
 	Math::Vector3d directionToVector(float pitch, float heading);
 
 	// Camera options
diff --git a/engines/freescape/games/castle.cpp b/engines/freescape/games/castle.cpp
index 7f18eb8d55c..b408343be12 100644
--- a/engines/freescape/games/castle.cpp
+++ b/engines/freescape/games/castle.cpp
@@ -74,27 +74,9 @@ void CastleEngine::gotoArea(uint16 areaID, int entranceID) {
 	_currentArea = _areaMap[areaID];
 	_currentArea->show();
 
-	int scale = _currentArea->getScale();
-	assert(scale > 0);
-
-	Entrance *entrance = nullptr;
-	if (entranceID > 0) {
-		entrance = (Entrance*) _currentArea->entranceWithID(entranceID);
-
-		assert(entrance);
-		_position = entrance->getOrigin();
-
-		if (_rotation == Math::Vector3d(0, 0, 0)) {
-			_rotation = entrance->getRotation();
-			_pitch = _rotation.x();
-			_yaw = _rotation.y() - 260;
-		}
-		debugC(1, kFreescapeDebugMove, "entrace position: %f %f %f", _position.x(), _position.y(), _position.z());
-		debugC(1, kFreescapeDebugMove, "player height: %d", scale * _playerHeight);
-		_position.setValue(1, _position.y() + scale * _playerHeight);
-	}
-
-	debugC(1, kFreescapeDebugMove, "starting player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
+	if (entranceID > 0)
+		traverseEntrance(entranceID);
+
 	playSound(5);
 	_lastPosition = _position;
 
diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index a6fd9f92b6d..3acb88d371f 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -79,19 +79,7 @@ void DarkEngine::gotoArea(uint16 areaID, int entranceID) {
 
 	Entrance *entrance = nullptr;
 	if (entranceID > 0 || areaID == 127) {
-		entrance = (Entrance*) _currentArea->entranceWithID(entranceID);
-		assert(entrance);
-
-		_position = entrance->getOrigin();
-
-		if (_rotation == Math::Vector3d(0, 0, 0)) {
-			_rotation = entrance->getRotation();
-			_pitch = _rotation.x();
-			_yaw = _rotation.y() - 260;
-		}
-		debugC(1, kFreescapeDebugMove, "entrace position: %f %f %f", _position.x(), _position.y(), _position.z());
-		debugC(1, kFreescapeDebugMove, "player height: %d", scale * _playerHeight);
-		_position.setValue(1, _position.y() + scale * _playerHeight);
+		traverseEntrance(entranceID);
 	} else if (entranceID == 0) {
 		Math::Vector3d diff = _lastPosition - _position;
 		debug("dif: %f %f %f", diff.x(), diff.y(), diff.z());
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 3867640f037..a996e815c6c 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -63,24 +63,8 @@ void DrillerEngine::gotoArea(uint16 areaID, int entranceID) {
 
 	_currentAreaMessages.push_back(_currentArea->name);
 
-	int scale = _currentArea->getScale();
-	assert(scale > 0);
-
-	Entrance *entrance = nullptr;
 	if (entranceID > 0 || areaID == 127) {
-		entrance = (Entrance*) _currentArea->entranceWithID(entranceID);
-		assert(entrance);
-
-		_position = entrance->getOrigin();
-
-		if (_rotation == Math::Vector3d(0, 0, 0)) {
-			_rotation = entrance->getRotation();
-			_pitch = _rotation.x();
-			_yaw = _rotation.y() - 260;
-		}
-		debugC(1, kFreescapeDebugMove, "entrace position: %f %f %f", _position.x(), _position.y(), _position.z());
-		debugC(1, kFreescapeDebugMove, "player height: %d", scale * _playerHeight);
-		_position.setValue(1, _position.y() + scale * _playerHeight);
+		traverseEntrance(entranceID);
 	} else if (entranceID == 0) {
 		Math::Vector3d diff = _lastPosition - _position;
 		debug("dif: %f %f %f", diff.x(), diff.y(), diff.z());
diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index 405d1b71938..803059d911f 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -152,18 +152,7 @@ void EclipseEngine::gotoArea(uint16 areaID, int entranceID) {
 		const entrancesTableEntry *entry = _entranceTable[entranceID];
 		_position = scale * Math::Vector3d(entry->position[0], entry->position[1], entry->position[2]);
 	} else
-		_position = entrance->getOrigin();
-
-	if (_rotation == Math::Vector3d(0, 0, 0)) {
-		_rotation = entrance->getRotation();
-		_pitch = _rotation.x();
-		_yaw = _rotation.y() - 260;
-	}
-	debugC(1, kFreescapeDebugMove, "entrace position: %f %f %f", _position.x(), _position.y(), _position.z());
-	debugC(1, kFreescapeDebugMove, "player height: %d", scale * _playerHeight);
-	_position.setValue(1, _position.y() + scale * _playerHeight);
-	debugC(1, kFreescapeDebugMove, "starting player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
-	playSound(5);
+		traverseEntrance(entranceID);
 
 	_lastPosition = _position;
 
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index 9dcd5481f5e..3c1892a01b9 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -27,6 +27,27 @@ void FreescapeEngine::gotoArea(uint16 areaID, int entranceID) {
 	error("Function \"%s\" not implemented", __FUNCTION__);
 }
 
+void FreescapeEngine::traverseEntrance(uint16 entranceID) {
+	Entrance *entrance = (Entrance*) _currentArea->entranceWithID(entranceID);
+	assert(entrance);
+
+	int scale = _currentArea->getScale();
+	assert(scale > 0);
+
+	Math::Vector3d diff = _lastPosition - _position;
+	Math::Vector3d rotation = entrance->getRotation();
+	_position = entrance->getOrigin();
+	_pitch = rotation.x();
+	if (abs(diff.x()) > abs(diff.z()) && _lastPosition != Math::Vector3d(0, 0, 0)) {
+		_yaw = rotation.y() - 90;
+	} else {
+		_yaw = rotation.y() + 90;
+	}
+	debugC(1, kFreescapeDebugMove, "entrace position: %f %f %f", _position.x(), _position.y(), _position.z());
+	debugC(1, kFreescapeDebugMove, "player height: %d", scale * _playerHeight);
+	_position.setValue(1, _position.y() + scale * _playerHeight);
+}
+
 void FreescapeEngine::changePlayerHeight(int index) {
 	int scale = _currentArea->getScale();
 	_position.setValue(1, _position.y() - scale * _playerHeight);


Commit: b30eb9e04c928f7c16ec363850fa4fa2620ca399
    https://github.com/scummvm/scummvm/commit/b30eb9e04c928f7c16ec363850fa4fa2620ca399
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:18+01:00

Commit Message:
FREESCAPE: removed driller specific code from area class

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index ce32e8686fa..e34af9009b4 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -111,10 +111,6 @@ void Area::show() {
 }
 
 void Area::loadObjects(Common::SeekableReadStream *stream, Area *global) {
-	drillPosition.setValue(0, stream->readFloatLE());
-	drillPosition.setValue(1, stream->readFloatLE());
-	drillPosition.setValue(2, stream->readFloatLE());
-
 	int objectsByIDSize = stream->readUint32LE();
 
 	for (int i = 0; i < objectsByIDSize; i++) {
@@ -138,10 +134,6 @@ void Area::loadObjects(Common::SeekableReadStream *stream, Area *global) {
 }
 
 void Area::saveObjects(Common::WriteStream *stream) {
-	stream->writeFloatLE(drillPosition.x());
-	stream->writeFloatLE(drillPosition.y());
-	stream->writeFloatLE(drillPosition.z());
-
 	stream->writeUint32LE(objectsByID->size());
 
 	for (ObjectMap::iterator iterator = objectsByID->begin(); iterator != objectsByID->end(); iterator++) {
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index 09b73ab6b11..d82d3f57a27 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -63,8 +63,6 @@ public:
 	void loadObjects(Common::SeekableReadStream *stream, Area *global);
 
 	// Driller specific
-	void removeDrill();
-	Math::Vector3d drillPosition;
 	Common::Point gasPocketPosition;
 	uint32 gasPocketRadius;
 


Commit: d7c076fb53396826b06fc59a343480a3185d2a73
    https://github.com/scummvm/scummvm/commit/d7c076fb53396826b06fc59a343480a3185d2a73
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:19+01:00

Commit Message:
FREESCAPE: recompute bounding box when an object is moved

Changed paths:
    engines/freescape/objects/geometricobject.cpp
    engines/freescape/objects/geometricobject.h
    engines/freescape/objects/object.h


diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index d613bbb50dd..a0a45c276e5 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -160,9 +160,14 @@ GeometricObject::GeometricObject(
 		   }
 	}
 
-	createBoundingBox();
+	computeBoundingBox();
 }
 
+void GeometricObject::setOrigin(Math::Vector3d _origin) {
+	origin = _origin;
+	computeBoundingBox();
+};
+
 GeometricObject *GeometricObject::duplicate() {
 	return new GeometricObject(
 		type,
@@ -176,7 +181,8 @@ GeometricObject *GeometricObject::duplicate() {
 		conditionSource);
 }
 
-void GeometricObject::createBoundingBox() {
+void GeometricObject::computeBoundingBox() {
+	boundingBox = Math::AABB();
 	Math::Vector3d v;
 	switch (type) {
 	default:
diff --git a/engines/freescape/objects/geometricobject.h b/engines/freescape/objects/geometricobject.h
index 3ec764a5b95..5e081f0cbef 100644
--- a/engines/freescape/objects/geometricobject.h
+++ b/engines/freescape/objects/geometricobject.h
@@ -47,9 +47,10 @@ public:
 		FCLInstructionVector conditionInstructions,
 		Common::String *conditionSource = nullptr);
 	virtual ~GeometricObject();
+	void setOrigin(Math::Vector3d origin) override;
 
 	GeometricObject *duplicate();
-	void createBoundingBox();
+	void computeBoundingBox();
 	bool collides(const Math::AABB &boundingBox);
 	void draw(Freescape::Renderer *gfx) override;
 	bool isDrawable();
diff --git a/engines/freescape/objects/object.h b/engines/freescape/objects/object.h
index 01df4ebe20d..bee8474e05a 100644
--- a/engines/freescape/objects/object.h
+++ b/engines/freescape/objects/object.h
@@ -60,7 +60,7 @@ public:
 	uint16 getObjectFlags();
 	void setObjectFlags(uint32 flags);
 	Math::Vector3d getOrigin();
-	void setOrigin(Math::Vector3d origin);
+	virtual void setOrigin(Math::Vector3d origin);
 	Math::Vector3d getSize();
 
 	virtual void draw(Freescape::Renderer *gfx) = 0;


Commit: 6a9afc56fefe33cdc538c5ee4cacf1da3e2287a0
    https://github.com/scummvm/scummvm/commit/6a9afc56fefe33cdc538c5ee4cacf1da3e2287a0
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:19+01:00

Commit Message:
FREESCAPE: avoid crashing with an unknown sound

Changed paths:
    engines/freescape/detection.cpp
    engines/freescape/freescape.h
    engines/freescape/sound.cpp


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index 26a427dd36d..1252d35ee49 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -207,6 +207,7 @@ static const DebugChannelDef debugFlagList[] = {
 	{Freescape::kFreescapeDebugMove, "move", ""},
 	{Freescape::kFreescapeDebugParser, "parser", ""},
 	{Freescape::kFreescapeDebugCode, "code", ""},
+	{Freescape::kFreescapeDebugMedia, "media", ""},
 	DEBUG_CHANNEL_END
 };
 
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 1acacdf4570..77f634ba0e7 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -59,7 +59,8 @@ typedef Common::HashMap<uint16, uint32> StateBits;
 enum {
 	kFreescapeDebugMove = 1 << 0,
 	kFreescapeDebugParser = 1 << 1,
-	kFreescapeDebugCode = 1 << 2
+	kFreescapeDebugCode = 1 << 2,
+	kFreescapeDebugMedia = 1 << 4,
 };
 
 struct entrancesTableEntry {
diff --git a/engines/freescape/sound.cpp b/engines/freescape/sound.cpp
index 700e682536c..ca3bfadfa87 100644
--- a/engines/freescape/sound.cpp
+++ b/engines/freescape/sound.cpp
@@ -31,7 +31,7 @@ void FreescapeEngine::playSound(int index) {
 	if (!_mixer->isSoundHandleActive(_handle))
 		_mixer->stopHandle(_handle);
 
-	debug("Playing sound %d", index);
+	debugC(1, kFreescapeDebugMedia, "Playing sound %d", index);
 	switch (index) {
 		case 1:
 			if (_usePrerecordedSounds) {
@@ -212,7 +212,7 @@ void FreescapeEngine::playSound(int index) {
 			}
 		break;
 		default:
-		error("Unexpected sound %d", index);
+		debugC(1, kFreescapeDebugMedia, "Unexpected sound %d", index);
 		break;
 	}
 }


Commit: 77f21d24e18b9119df0bf0c0dae12cfb81d0ac45
    https://github.com/scummvm/scummvm/commit/77f21d24e18b9119df0bf0c0dae12cfb81d0ac45
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:19+01:00

Commit Message:
FREESCAPE: added no clip cheat using N key

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/movement.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index d7f0de967bb..36b9179c5fa 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -54,6 +54,7 @@ FreescapeEngine::FreescapeEngine(OSystem *syst)
 	_movementSpeed = 1.5f;
 	_mouseSensitivity = 0.25f;
 	_flyMode = false;
+	_noClipMode = false;
 	_playerHeightNumber = 1;
 	_borderTexture = nullptr;
 	_fullscreenViewArea = Common::Rect(0, 0, _screenW, _screenH);
@@ -155,9 +156,10 @@ void FreescapeEngine::processInput() {
 				rise();
 			else if (event.kbd.keycode == Common::KEYCODE_f)
 				lower();
-			else if (event.kbd.keycode == Common::KEYCODE_n)
-				gotoArea(_currentArea->getAreaID() + 1, 0);
-			else if (event.kbd.keycode == Common::KEYCODE_ESCAPE)
+			else if (event.kbd.keycode == Common::KEYCODE_n) {
+				_noClipMode = !_noClipMode;
+				_flyMode = _noClipMode;
+			} else if (event.kbd.keycode == Common::KEYCODE_ESCAPE)
 				openMainMenuDialog();
 			else
 				pressedKey(event.kbd.keycode);
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 77f634ba0e7..88eb3a77492 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -123,6 +123,7 @@ public:
 
 	// Input
 	bool _flyMode;
+	bool _noClipMode;
 	void processInput();
 	virtual void pressedKey(const int keycode);
 	void move(CameraMovement direction, uint8 scale, float deltaTime);
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index 3c1892a01b9..d83815a4655 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -235,6 +235,8 @@ bool FreescapeEngine::tryStepDown(Math::Vector3d currentPosition) {
 
 
 bool FreescapeEngine::checkCollisions(bool executeCode) {
+	if (_noClipMode)
+		return false;
 	int areaScale = _currentArea->getScale();
 	Math::AABB boundingBox(_lastPosition, _lastPosition);
 


Commit: 698b7ea4a00f207d3a6d70e81910c3f3e4abf806
    https://github.com/scummvm/scummvm/commit/698b7ea4a00f207d3a6d70e81910c3f3e4abf806
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:19+01:00

Commit Message:
FREESCAPE: entrance fixes for eclipse

Changed paths:
    engines/freescape/games/eclipse.cpp


diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index 803059d911f..b9c55a6ba23 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -30,26 +30,26 @@ namespace Freescape {
 static const entrancesTableEntry rawEntranceTable[] = {
 	{183, {36, 137, 13}}, // Correct?
 	{184, {36, 137, 13}}, // TODO
-	{185, {36, 137, 13}}, // TODO
-	{186, {36, 137, 13}}, // TODO
+	{185, {204, 68, 66}},
+	{186, {204, 88, 66}},
 	{187, {36, 137, 13}}, // TODO
-	{188, {36, 137, 13}}, // TODO
+	{188, {352, 105, 204}},
 	{190, {36, 137, 13}}, // TODO
-	{191, {36, 137, 13}}, // TODO
+	{191, {49, 7, 23}}, // TODO
 	{192, {36, 137, 13}}, // TODO
 	{193, {36, 137, 13}}, // TODO
 	{194, {36, 137, 13}}, // TODO
 	{195, {36, 137, 13}}, // TODO
-	{196, {36, 137, 13}}, // TODO
+	{196, {36, 137, 13}}, // <-
 	{197, {203, 0, 31}},  // TODO
 	{198, {36, 137, 13}}, // TODO
 	{199, {36, 137, 13}}, // TODO
 	{200, {36, 137, 13}}, // TODO
 	{201, {36, 137, 13}}, // TODO
-	{202, {360, 0, 373}}, // TODO
-	{203, {207, 0, 384}},
-	{204, {207, 0, 372}},
-	{206, {36, 137, 13}}, // TODO
+	{202, {360, 25, 373}},
+	{203, {207, 25, 384}},
+	{204, {33, 48, 366}},
+	{206, {25, 8, 200}},
 	{0, {0, 0, 0}},        // NULL
 };
 
@@ -151,6 +151,9 @@ void EclipseEngine::gotoArea(uint16 areaID, int entranceID) {
 		assert(_entranceTable.contains(entranceID));
 		const entrancesTableEntry *entry = _entranceTable[entranceID];
 		_position = scale * Math::Vector3d(entry->position[0], entry->position[1], entry->position[2]);
+		_position.setValue(1, _position.y() + scale * _playerHeight);
+		debugC(1, kFreescapeDebugMove, "entrace position: %f %f %f", _position.x(), _position.y(), _position.z());
+		debugC(1, kFreescapeDebugMove, "player height: %d", scale * _playerHeight);
 	} else
 		traverseEntrance(entranceID);
 


Commit: fdd5e1f0fed2173465f23088ff35e0cbe74dae87
    https://github.com/scummvm/scummvm/commit/fdd5e1f0fed2173465f23088ff35e0cbe74dae87
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:19+01:00

Commit Message:
FREESCAPE: replace some debug by debugC calls

Changed paths:
    engines/freescape/games/dark.cpp
    engines/freescape/games/driller.cpp
    engines/freescape/games/eclipse.cpp
    engines/freescape/sound.cpp


diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index 3acb88d371f..78996f092d7 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -82,7 +82,7 @@ void DarkEngine::gotoArea(uint16 areaID, int entranceID) {
 		traverseEntrance(entranceID);
 	} else if (entranceID == 0) {
 		Math::Vector3d diff = _lastPosition - _position;
-		debug("dif: %f %f %f", diff.x(), diff.y(), diff.z());
+		//debug("dif: %f %f %f", diff.x(), diff.y(), diff.z());
 		// diff should be used to determinate which entrance to use
 		int newPos = -1;
 		if (abs(diff.x()) < abs(diff.z())) {
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index a996e815c6c..023bd0c7782 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -67,7 +67,7 @@ void DrillerEngine::gotoArea(uint16 areaID, int entranceID) {
 		traverseEntrance(entranceID);
 	} else if (entranceID == 0) {
 		Math::Vector3d diff = _lastPosition - _position;
-		debug("dif: %f %f %f", diff.x(), diff.y(), diff.z());
+		//debug("dif: %f %f %f", diff.x(), diff.y(), diff.z());
 		// diff should be used to determinate which entrance to use
 		int newPos = -1;
 		if (abs(diff.x()) < abs(diff.z())) {
@@ -254,7 +254,7 @@ void DrillerEngine::addDrill(const Math::Vector3d position) {
 	int heightLastObject;
 
 	id = 255;
-	debug("Adding object %d to room structure", id);
+	debugC(1, kFreescapeDebugParser, "Adding object %d to room structure", id);
 	obj = (GeometricObject*) _areaMap[255]->objectWithID(id);
 	assert(obj);
 	obj = obj->duplicate();
@@ -266,7 +266,7 @@ void DrillerEngine::addDrill(const Math::Vector3d position) {
 	heightLastObject = obj->getSize().y();
 
 	id = 254;
-	debug("Adding object %d to room structure", id);
+	debugC(1, kFreescapeDebugParser, "Adding object %d to room structure", id);
 	obj = (GeometricObject*) _areaMap[255]->objectWithID(id);
 	assert(obj);
 	// Set position for object
@@ -285,7 +285,7 @@ void DrillerEngine::addDrill(const Math::Vector3d position) {
 	origin.setValue(2, origin.z() + obj->getSize().z() / 5);
 
 	id = 253;
-	debug("Adding object %d to room structure", id);
+	debugC(1, kFreescapeDebugParser, "Adding object %d to room structure", id);
 	obj = (GeometricObject*) _areaMap[255]->objectWithID(id);
 	assert(obj);
 	obj = obj->duplicate();
@@ -304,7 +304,7 @@ void DrillerEngine::addDrill(const Math::Vector3d position) {
 	//origin.setValue(2, origin.z() - obj->getSize().z() / 5);
 
 	id = 252;
-	debug("Adding object %d to room structure", id);
+	debugC(1, kFreescapeDebugParser, "Adding object %d to room structure", id);
 	obj = (GeometricObject*) _areaMap[255]->objectWithID(id);
 	assert(obj);
 	obj = obj->duplicate();
diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index b9c55a6ba23..b24bb9573db 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -92,10 +92,11 @@ EclipseEngine::EclipseEngine(OSystem *syst) : FreescapeEngine(syst) {
 	}
 
 	const char **messagePtr = rawMessagesTable;
+	debugC(1, kFreescapeDebugParser, "String table:");
 	while (*messagePtr) {
 		Common::String message(*messagePtr);
 		_messagesList.push_back(message);
-		debug("%s", message.c_str());
+		debugC(1, kFreescapeDebugParser, "%s", message.c_str());
 		messagePtr++;
 	}
 }
diff --git a/engines/freescape/sound.cpp b/engines/freescape/sound.cpp
index ca3bfadfa87..2c8b0a65232 100644
--- a/engines/freescape/sound.cpp
+++ b/engines/freescape/sound.cpp
@@ -118,7 +118,7 @@ void FreescapeEngine::playSound(int index) {
 		break;
 
 		case 11: // ???
-			debug("Playing unknown sound");
+			debugC(1, kFreescapeDebugMedia, "Playing unknown sound");
 			if (_usePrerecordedSounds) {
 				//playWav("???.wav");
 				//_system->delayMillis(50);
@@ -194,7 +194,7 @@ void FreescapeEngine::playSound(int index) {
 		break;
 
 		case 19:
-			debug("Playing unknown sound");
+			debugC(1, kFreescapeDebugMedia, "Playing unknown sound");
 			if (_usePrerecordedSounds) {
 				//playWav("???.wav");
 				//_system->delayMillis(50);


Commit: 37aa8924aa752039c3d8cf60f9c1dfa3151754d7
    https://github.com/scummvm/scummvm/commit/37aa8924aa752039c3d8cf60f9c1dfa3151754d7
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:19+01:00

Commit Message:
FREESCAPE: replace some debug by debugC calls

Changed paths:
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 27d085da1f7..043e26bb607 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -53,7 +53,7 @@ void TinyGLRenderer::freeTexture(Texture *texture) {
 }
 
 void TinyGLRenderer::init() {
-	debug("Initializing Software 3D Renderer");
+	//debug("Initializing Software 3D Renderer");
 
 	computeScreenViewport();
 
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 831c693a79b..9ce3ef6062f 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -60,7 +60,7 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 	assert(byteSizeOfObject >= 9);
 	byteSizeOfObject = byteSizeOfObject - 9;
 	if (objectID == 255 && objectType == Object::Type::Entrance) {
-		debug("Found the room structure (objectID: 255 with size %d)", byteSizeOfObject + 6);
+		debugC(1, kFreescapeDebugParser, "Found the room structure (objectID: 255 with size %d)", byteSizeOfObject + 6);
 		byte *structureData = (byte*)malloc(byteSizeOfObject + 6);
 		structureData[0] = int(position.x());
 		structureData[1] = int(position.y());
@@ -190,7 +190,7 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 	} break;
 
 	case Object::Group:
-		debug("Object of type 'group'");
+		debugC(1, kFreescapeDebugParser, "Object of type 'group'");
 		file->seek(byteSizeOfObject, SEEK_CUR);
 		return new Sensor(
 			objectID,
@@ -470,7 +470,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 			else
 				debugC(1, kFreescapeDebugParser, "WARNING: area ID repeated: %d", newArea->getAreaID());
 		} else {
-			debug("Invalid area %d?", area);
+			debugC(1, kFreescapeDebugParser, "Invalid area %d?", area);
 			break;
 		}
 	}
@@ -516,12 +516,13 @@ void FreescapeEngine::loadMessages(Common::SeekableReadStream *file, int offset,
 	file->seek(offset);
 	byte *buffer = (byte *)malloc(size + 1);
 	buffer[size] = NULL;
+	debugC(1, kFreescapeDebugParser, "String table:");
 
 	for (int i = 0; i < number; i++) {
 		file->read(buffer, size);
 		Common::String message = (const char*) buffer;
 		_messagesList.push_back(message);
-		debug("%s", _messagesList[i].c_str());
+		debugC(1, kFreescapeDebugParser, "%s", _messagesList[i].c_str());
 	}
 }
 


Commit: 003cb43efd9ba0168d78c58099da01d25c117619
    https://github.com/scummvm/scummvm/commit/003cb43efd9ba0168d78c58099da01d25c117619
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:20+01:00

Commit Message:
FREESCAPE: fixed compiler warnings

Changed paths:
    engines/freescape/games/dark.cpp
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/language/8bitDetokeniser.h
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/objects/geometricobject.cpp


diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index 78996f092d7..2298c6a8ba2 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -77,7 +77,6 @@ void DarkEngine::gotoArea(uint16 areaID, int entranceID) {
 	int scale = _currentArea->getScale();
 	assert(scale > 0);
 
-	Entrance *entrance = nullptr;
 	if (entranceID > 0 || areaID == 127) {
 		traverseEntrance(entranceID);
 	} else if (entranceID == 0) {
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index 409f3ea9bbe..5b2a10134b5 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -27,6 +27,10 @@
 
 namespace Freescape {
 
+uint8 k8bitMaxVariable = 64;
+uint8 k8bitMaxShield = 64;
+uint8 k8bitMaxEnergy = 64;
+
 Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition, FCLInstructionVector &instructions) {
 	Common::String detokenisedStream;
 	Common::Array<uint8>::size_type bytePointer = 0;
diff --git a/engines/freescape/language/8bitDetokeniser.h b/engines/freescape/language/8bitDetokeniser.h
index 218b835d88d..80de0ae31df 100644
--- a/engines/freescape/language/8bitDetokeniser.h
+++ b/engines/freescape/language/8bitDetokeniser.h
@@ -34,11 +34,9 @@ enum {
 	k8bitVariableScore = 61
 };
 
-
-static uint8 k8bitMaxVariable = 64;
-static uint8 k8bitMaxShield = 64;
-static uint8 k8bitMaxEnergy = 64;
-
+extern uint8 k8bitMaxVariable;
+extern uint8 k8bitMaxShield;
+extern uint8 k8bitMaxEnergy;
 
 Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition, FCLInstructionVector &instructions);
 
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 9ce3ef6062f..cb50fa29bfa 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -515,7 +515,7 @@ void FreescapeEngine::loadFonts(Common::SeekableReadStream *file, int offset) {
 void FreescapeEngine::loadMessages(Common::SeekableReadStream *file, int offset, int size, int number) {
 	file->seek(offset);
 	byte *buffer = (byte *)malloc(size + 1);
-	buffer[size] = NULL;
+	buffer[size] = 0;
 	debugC(1, kFreescapeDebugParser, "String table:");
 
 	for (int i = 0; i < number; i++) {
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index a0a45c276e5..f4558a9f6ea 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -309,8 +309,8 @@ GeometricObject::~GeometricObject() {
 
 bool GeometricObject::isDrawable() { return true; }
 bool GeometricObject::isPlanar() {
-	Type type = this->getType();
-	return (type >= Object::Line) || type == Object::Rectangle || !size.x() || !size.y() || !size.z();
+	Type t = this->getType();
+	return (t >= Object::Line) || t == Object::Rectangle || !size.x() || !size.y() || !size.z();
 }
 
 bool GeometricObject::collides(const Math::AABB &_boundingBox) {


Commit: 4aec147f9741201b0eff1231c079a096b7b85515
    https://github.com/scummvm/scummvm/commit/4aec147f9741201b0eff1231c079a096b7b85515
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:20+01:00

Commit Message:
FREESCAPE: improved handling of sync/async sounds

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/castle.cpp
    engines/freescape/games/dark.cpp
    engines/freescape/games/driller.cpp
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/language/instruction.cpp
    engines/freescape/movement.cpp
    engines/freescape/sound.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 36b9179c5fa..e08c51f5848 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -211,7 +211,8 @@ void FreescapeEngine::processInput() {
 }
 
 void FreescapeEngine::shoot() {
-	playSound(1);
+	playSound(1, true);
+	_mixer->stopAll();
 	_gfx->renderShoot(0);
 	Math::Vector3d direction = directionToVector(_pitch, _yaw);
 	Math::Ray ray(_position, direction);
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 88eb3a77492..e3261868fc2 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -194,11 +194,11 @@ public:
 	// Sound
 	Audio::SoundHandle _handle;
 	bool _usePrerecordedSounds;
-	void playSound(int index);
+	void playSound(int index, bool sync);
 	void playWav(const Common::String filename);
-	void playSoundConst(double hzFreq, int duration);
-	void playSoundSweepIncWL(double hzFreq1, double hzFreq2, double wlStepPerMS, int resolution);
-	void playTeleporter(int totalIters);
+	void playSoundConst(double hzFreq, int duration, bool sync);
+	void playSoundSweepIncWL(double hzFreq1, double hzFreq2, double wlStepPerMS, int resolution, bool sync);
+	void playTeleporter(int totalIters, bool sync);
 
 	// Rendering
 	int _screenW, _screenH;
diff --git a/engines/freescape/games/castle.cpp b/engines/freescape/games/castle.cpp
index b408343be12..5f12c5e39bb 100644
--- a/engines/freescape/games/castle.cpp
+++ b/engines/freescape/games/castle.cpp
@@ -77,7 +77,7 @@ void CastleEngine::gotoArea(uint16 areaID, int entranceID) {
 	if (entranceID > 0)
 		traverseEntrance(entranceID);
 
-	playSound(5);
+	playSound(5, false);
 	_lastPosition = _position;
 
 	if (_currentArea->skyColor > 0 && _currentArea->skyColor != 255) {
diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index 2298c6a8ba2..3ab9fc6f390 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -101,7 +101,7 @@ void DarkEngine::gotoArea(uint16 areaID, int entranceID) {
 	}
 
 	debugC(1, kFreescapeDebugMove, "starting player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
-	playSound(5);
+	playSound(5, false);
 	_lastPosition = _position;
 
 	// Ignore sky/ground fields
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 023bd0c7782..29fbcfce26c 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -88,7 +88,7 @@ void DrillerEngine::gotoArea(uint16 areaID, int entranceID) {
 	_lastPosition = _position;
 
 	debugC(1, kFreescapeDebugMove, "starting player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
-	playSound(5);
+	playSound(5, false);
 	// Ignore sky/ground fields
 	if (_currentArea->getAreaFlags() == 1)
 		_gfx->_keyColor = 0;
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index 5b2a10134b5..1627c19678d 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -283,6 +283,7 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 		case 15:
 			detokenisedStream += "SOUND (";
 			currentInstruction = FCLInstruction(Token::SOUND);
+			currentInstruction.setAdditional(false);
 			break;
 		case 17:
 		case 16:
@@ -315,6 +316,7 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 		case 28:
 			detokenisedStream += "SYNCSND (";
 			currentInstruction = FCLInstruction(Token::SOUND);
+			currentInstruction.setAdditional(true);
 			break;
 		case 29:
 			detokenisedStream += "TOGGLEBIT (";
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index 5f097b7ceea..793444b25d0 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -182,8 +182,9 @@ void FreescapeEngine::executeRedraw(FCLInstruction &instruction) {
 
 void FreescapeEngine::executeSound(FCLInstruction &instruction) {
 	uint16 index = instruction.source;
+	bool sync = instruction.additional;
 	debugC(1, kFreescapeDebugCode, "Playing sound %d", index);
-	playSound(index);
+	playSound(index, sync);
 }
 
 void FreescapeEngine::executeDelay(FCLInstruction &instruction) {
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index d83815a4655..9875c800b3e 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -163,7 +163,7 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 				return;
 			}
 			_position.set(_position.x(), positionY - fallen * areaScale, _position.z());
-			playSound(3);
+			playSound(3, true);
 		}
 		debugC(1, kFreescapeDebugCode, "Runing effects:");
 		checkCollisions(true); // run the effects
@@ -177,11 +177,11 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 			else {
 				bool stepUp = tryStepUp(_position);
 				if (stepUp) {
-					playSound(4);
+					playSound(4, true);
 					debugC(1, kFreescapeDebugCode, "Runing effects:");
 					checkCollisions(true); // run the effects (again)
 				} else {
-					playSound(2);
+					playSound(2, true);
 					_position = _lastPosition;
 				}
 			}
diff --git a/engines/freescape/sound.cpp b/engines/freescape/sound.cpp
index 2c8b0a65232..5725aec93a3 100644
--- a/engines/freescape/sound.cpp
+++ b/engines/freescape/sound.cpp
@@ -25,27 +25,27 @@ namespace Freescape {
 
 // If step rate for playSoundSweepIncWL calls needs adjusting,
 // can tweak wlStepPerMS parameter by the factor below.
-const double kFreescapeSweepTuneFactor = 1.0;
+const double kFreescapeSweepTuneFactor = 10.0;
 
-void FreescapeEngine::playSound(int index) {
-	if (!_mixer->isSoundHandleActive(_handle))
-		_mixer->stopHandle(_handle);
+void FreescapeEngine::playSound(int index, bool sync) {
+	//if (!_mixer->isSoundHandleActive(_handle))
+	//	_mixer->stopHandle(_handle);
 
-	debugC(1, kFreescapeDebugMedia, "Playing sound %d", index);
+	debugC(1, kFreescapeDebugMedia, "Playing sound %d with sync: %d", index, sync);
 	switch (index) {
 		case 1:
 			if (_usePrerecordedSounds) {
 				playWav("fsDOS_laserFire.wav");
 				//_system->delayMillis(50);
 			} else
-				playSoundSweepIncWL(1500, 700, 5.46 * kFreescapeSweepTuneFactor, 1);
+				playSoundSweepIncWL(1500, 700, 5.46 * kFreescapeSweepTuneFactor, 1, sync);
 		break;
 		case 2: // Done
 			if (_usePrerecordedSounds) {
 				playWav("fsDOS_WallBump.wav");
 				//_system->delayMillis(50);
 			} else {
-				playSoundConst(82, 60);
+				playSoundConst(82, 60, sync);
 			}
 		break;
 		case 3:
@@ -53,8 +53,8 @@ void FreescapeEngine::playSound(int index) {
 				playWav("fsDOS_stairDown.wav");
 				//_system->delayMillis(50);
 			} else {
-				playSoundConst(220, 50);
-				playSoundConst(185, 50);
+				playSoundConst(220, 50, sync);
+				playSoundConst(185, 50, sync);
 			}
 		break;
 		case 4:
@@ -62,8 +62,8 @@ void FreescapeEngine::playSound(int index) {
 				playWav("fsDOS_stairUp.wav");
 				//_system->delayMillis(50);
 			} else {
-				playSoundConst(220, 50);
-				playSoundConst(340, 50);
+				playSoundConst(220, 50, sync);
+				playSoundConst(340, 50, sync);
 			}
 		break;
 		case 5:
@@ -71,7 +71,7 @@ void FreescapeEngine::playSound(int index) {
 				playWav("fsDOS_roomChange.wav");
 				//_system->delayMillis(50);
 			} else {
-				playSoundSweepIncWL(262, 100, 65.52 * kFreescapeSweepTuneFactor, 1);
+				playSoundSweepIncWL(262, 100, 65.52 * kFreescapeSweepTuneFactor, 1, sync);
 			}
 		break;
 		case 6:
@@ -79,7 +79,7 @@ void FreescapeEngine::playSound(int index) {
 				playWav("fsDOS_configMenu.wav");
 				//_system->delayMillis(50);
 			} else {
-				playSoundConst(830, 60);
+				playSoundConst(830, 60, sync);
 			}
 		break;
 		case 7:
@@ -87,7 +87,7 @@ void FreescapeEngine::playSound(int index) {
 				playWav("fsDOS_bigHit.wav");
 				//_system->delayMillis(50);
 			} else {
-				playSoundSweepIncWL(3000, 155, 7.28 * kFreescapeSweepTuneFactor, 1);
+				playSoundSweepIncWL(3000, 155, 7.28 * kFreescapeSweepTuneFactor, 1, sync);
 			}
 		break;
 		case 8:
@@ -95,7 +95,7 @@ void FreescapeEngine::playSound(int index) {
 				playWav("fsDOS_teleporterActivated.wav");
 				//_system->delayMillis(50);
 			} else {
-				playTeleporter(22);
+				playTeleporter(22, sync);
 			}
 		break;
 
@@ -104,7 +104,7 @@ void FreescapeEngine::playSound(int index) {
 				playWav("fsDOS_powerUp.wav");
 				//_system->delayMillis(50);
 			} else {
-				playSoundSweepIncWL(280, 5000, 9.1 * kFreescapeSweepTuneFactor, 1);
+				playSoundSweepIncWL(280, 5000, 9.1 * kFreescapeSweepTuneFactor, 1, sync);
 			}
 		break;
 
@@ -113,17 +113,16 @@ void FreescapeEngine::playSound(int index) {
 				playWav("fsDOS_energyDrain.wav");
 				//_system->delayMillis(50);
 			} else {
-				playSoundSweepIncWL(240, 255, 1.82 * kFreescapeSweepTuneFactor, 1);
+				playSoundSweepIncWL(240, 255, 1.82 * kFreescapeSweepTuneFactor, 1, sync);
 			}
 		break;
 
 		case 11: // ???
 			debugC(1, kFreescapeDebugMedia, "Playing unknown sound");
 			if (_usePrerecordedSounds) {
-				//playWav("???.wav");
-				//_system->delayMillis(50);
+				// TODO
 			} else {
-				//playSoundConst(82, 60);
+				// TODO
 			}
 		break;
 
@@ -132,7 +131,7 @@ void FreescapeEngine::playSound(int index) {
 				playWav("fsDOS_switchOff.wav");
 				//_system->delayMillis(50);
 			} else {
-				playSoundSweepIncWL(555, 440, 1.82 * kFreescapeSweepTuneFactor, 1);
+				playSoundSweepIncWL(555, 440, 1.82 * kFreescapeSweepTuneFactor, 1, sync);
 			}
 		break;
 
@@ -141,7 +140,7 @@ void FreescapeEngine::playSound(int index) {
 				playWav("fsDOS_laserHit.wav");
 				//_system->delayMillis(50);
 			} else {
-				playSoundSweepIncWL(3000, 420, 14.56 * kFreescapeSweepTuneFactor, 1);
+				playSoundSweepIncWL(3000, 420, 14.56 * kFreescapeSweepTuneFactor, 1, sync);
 			}
 		break;
 
@@ -150,7 +149,7 @@ void FreescapeEngine::playSound(int index) {
 				playWav("fsDOS_tankFall.wav");
 				//_system->delayMillis(50);
 			} else {
-				playSoundSweepIncWL(785, 310, 1.82 * kFreescapeSweepTuneFactor, 1);
+				playSoundSweepIncWL(785, 310, 1.82 * kFreescapeSweepTuneFactor, 1, sync);
 			}
 		break;
 
@@ -159,18 +158,17 @@ void FreescapeEngine::playSound(int index) {
 				playWav("fsDOS_successJingle.wav");
 				//_system->delayMillis(50);
 			} else {
-				playSoundConst(587.330, 250);
-				playSoundConst(740, 175);
-				playSoundConst(880, 450);
+				playSoundConst(587.330, 250, sync);
+				playSoundConst(740, 175, sync);
+				playSoundConst(880, 450, sync);
 			}
 		break;
 
 		case 16: // Silence?
 			if (_usePrerecordedSounds) {
-				//playWav("???.wav");
-				//_system->delayMillis(50);
+				// TODO
 			} else {
-				//playSoundConst(82, 60);
+				// TODO
 			}
 		break;
 
@@ -179,27 +177,25 @@ void FreescapeEngine::playSound(int index) {
 				playWav("fsDOS_badJingle.wav");
 				//_system->delayMillis(50);
 			} else {
-				playSoundConst(65, 150);
-				playSoundConst(44, 400);
+				playSoundConst(65, 150, sync);
+				playSoundConst(44, 400, sync);
 			}
 		break;
 
 		case 18: // Silence?
 			if (_usePrerecordedSounds) {
-				//playWav("???.wav");
-				//_system->delayMillis(50);
+				// TODO
 			} else {
-				//playSoundConst(82, 60);
+				// TODO
 			}
 		break;
 
 		case 19:
 			debugC(1, kFreescapeDebugMedia, "Playing unknown sound");
 			if (_usePrerecordedSounds) {
-				//playWav("???.wav");
-				//_system->delayMillis(50);
+				// TODO
 			} else {
-				//playSoundConst(82, 60);
+				// TODO
 			}
 		break;
 
@@ -208,7 +204,7 @@ void FreescapeEngine::playSound(int index) {
 				playWav("fsDOS_bigHit.wav");
 				//_system->delayMillis(50);
 			} else {
-				playSoundSweepIncWL(3000, 155, 7.28 * kFreescapeSweepTuneFactor, 1);
+				playSoundSweepIncWL(3000, 155, 7.28 * kFreescapeSweepTuneFactor, 1, sync);
 			}
 		break;
 		default:
@@ -225,17 +221,18 @@ void FreescapeEngine::playWav(const Common::String filename) {
 }
 
 
-void FreescapeEngine::playSoundConst(double hzFreq, int duration) {
+void FreescapeEngine::playSoundConst(double hzFreq, int duration, bool sync) {
 	Audio::PCSpeaker *speaker = new Audio::PCSpeaker();
 	speaker->setVolume(50);
 	speaker->play(Audio::PCSpeaker::kWaveFormSquare, hzFreq, duration);
 	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_handle, speaker);
-	_system->delayMillis(duration);
-	_mixer->stopHandle(_handle);
+	if (sync) {
+		_system->delayMillis(duration);
+	}
 }
 
 
-void FreescapeEngine::playSoundSweepIncWL(double hzFreq1, double hzFreq2, double wlStepPerMS, int resolution) {
+void FreescapeEngine::playSoundSweepIncWL(double hzFreq1, double hzFreq2, double wlStepPerMS, int resolution, bool sync) {
 	// Play a PC speaker sweep between sound frequencies, using constant wavelength increment.
 
 	// The wavelength step-per-milliseconds value, or wlStepPerMS, describes how
@@ -277,13 +274,13 @@ void FreescapeEngine::playSoundSweepIncWL(double hzFreq1, double hzFreq2, double
 	// Loop over frequency range
 	int hzCounts = (int)((inv2 - inv1) / wlStep);
 	while (hzCounts-- >= 0) {
-		playSoundConst((1193180.0 / inv1), resolution);
+		playSoundConst((1193180.0 / inv1), resolution, sync);
 		inv1 += wlStep;
 	}
 	_mixer->stopHandle(_handle);
 }
 
-void FreescapeEngine::playTeleporter(int totalIters) {
+void FreescapeEngine::playTeleporter(int totalIters, bool sync) {
 	// Play FreeScape DOS teleporter-like effect, which is ascending arpeggio.
 	// Length of effect is variable; provide total number of iterations.
 
@@ -302,7 +299,7 @@ void FreescapeEngine::playTeleporter(int totalIters) {
 
 	// Loop over iterations
 	for (i = 0; i < totalIters; i++) {
-		playSoundConst(1193180.0 / fBase, 21);
+		playSoundConst(1193180.0 / fBase, 21, sync);
 
 		if (stepCycle <= 1)
 		{


Commit: 2e5163608863e07230d2292db525c5a50131652b
    https://github.com/scummvm/scummvm/commit/2e5163608863e07230d2292db525c5a50131652b
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:20+01:00

Commit Message:
FREESCAPE: refactored and added some code to parse data from the amiga releases

Changed paths:
    engines/freescape/detection.cpp
    engines/freescape/freescape.h
    engines/freescape/games/driller.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index 1252d35ee49..bfbae955ef9 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -104,6 +104,26 @@ static const ADGameDescription gameDescriptions[] = {
 	 Common::kPlatformDOS,
 	 ADGF_NO_FLAGS,
 	 GUIO3(GUIO_NOMIDI, GUIO_RENDEREGA, GUIO_RENDERCGA)},
+	{"driller",
+	 "Driller",
+	 {
+		{"driller", 0, "13dab2e10d8e8b9a364c94a660e0d42a", 282384},
+		AD_LISTEND
+	 },
+	 Common::EN_ANY,
+	 Common::kPlatformAmiga,
+	 ADGF_NO_FLAGS,
+	 GUIO1(GUIO_NOMIDI)},
+	{"driller",
+	 "Rolling Demo",
+	 {
+		{"amiga.demo", 0, "0b056286d2d91f302499c97aca235462", 24220},
+		AD_LISTEND
+	 },
+	 Common::EN_ANY,
+	 Common::kPlatformAmiga,
+	 ADGF_NO_FLAGS | ADGF_DEMO,
+	 GUIO1(GUIO_NOMIDI)},
 	{"darkside",
 	 "Dark Side",
 	 {
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index e3261868fc2..8a914cd3f01 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -82,6 +82,7 @@ public:
 	bool isDark() { return _targetName.hasPrefix("darkside"); }
 	bool isEclipse() { return _targetName.hasPrefix("totaleclipse"); }
 	bool isCastle() { return _targetName.hasPrefix("castle"); }
+	bool isAmiga() { return _targetName.hasSuffix("-amiga"); }
 
 	Common::Error run() override;
 
@@ -102,6 +103,7 @@ public:
 	void loadBorder();
 	void loadColorPalette();
 
+	uint16 readField(Common::SeekableReadStream *file, int nbits);
 	// 16-bit
 	void load16bitBinary(Common::SeekableReadStream *file);
 
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 29fbcfce26c..e1f048957a9 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -103,7 +103,14 @@ void DrillerEngine::loadAssets() {
 	Common::FSDirectory gameDir(path);
 
 	Common::File exe;
-	if (_renderMode == "ega") {
+	if (isAmiga()) {
+		file = gameDir.createReadStreamForMember("driller");
+
+		if (file == nullptr)
+			error("Failed to open 'driller' executable for Amiga");
+
+		load8bitBinary(file, 0xbd90, 16);
+	} else if (_renderMode == "ega") {
 		file = gameDir.createReadStreamForMember("DRILLE.EXE");
 
 		if (file == nullptr)
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index cb50fa29bfa..3e42d8e9eac 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -30,28 +30,45 @@
 
 namespace Freescape {
 
+uint16 FreescapeEngine::readField(Common::SeekableReadStream *file, int bits) {
+	uint16 value;
+	assert(bits == 8 || bits == 16);
+	if (isAmiga()) {
+		value = file->readUint16BE();
+		if (bits == 8)
+			assert(value < 256);
+	} else {
+		if (bits == 8)
+			value = file->readByte();
+		else
+			value = file->readUint16LE();
+	}
+
+	return value;
+}
+
 Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 
-	byte rawFlagsAndType = file->readByte();
+	byte rawFlagsAndType = readField(file, 8);
 	debugC(1, kFreescapeDebugParser, "Raw object data flags and type: %d", rawFlagsAndType);
 	Object::Type objectType = (Object::Type)(rawFlagsAndType & 0x1F);
 
 	Math::Vector3d position, v;
 
-	position.x() = file->readByte();
-	position.y() = file->readByte();
-	position.z() = file->readByte();
+	position.x() = readField(file, 8);
+	position.y() = readField(file, 8);
+	position.z() = readField(file, 8);
 
-	v.x() = file->readByte();
-	v.y() = file->readByte();
-	v.z() = file->readByte();
+	v.x() = readField(file, 8);
+	v.y() = readField(file, 8);
+	v.z() = readField(file, 8);
 
 	// object ID
-	uint16 objectID = file->readByte();
+	uint16 objectID = readField(file, 8);
 	// size of object on disk; we've accounted for 8 bytes
 	// already so we can subtract that to get the remaining
 	// length beyond here
-	uint8 byteSizeOfObject = file->readByte();
+	uint8 byteSizeOfObject = readField(file, 8);
 	debugC(1, kFreescapeDebugParser, "Raw object %d ; type %d ; size %d", objectID, (int)objectType, byteSizeOfObject);
 	if (byteSizeOfObject < 9) {
 		error("Not enough bytes %d to read object %d with type %d", byteSizeOfObject, objectID, objectType);
@@ -87,7 +104,7 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 		debugC(1, kFreescapeDebugParser, "Number of colors: %d", numberOfColours/2);
 		uint8 entry;
 		for (uint8 colour = 0; colour < numberOfColours/2; colour++) {
-			uint8 data = file->readByte();
+			uint8 data = readField(file, 8);
 			entry = data & 0xf;
 			if (_renderMode == "cga")
 				entry = entry % 4; // TODO: use dithering
@@ -118,7 +135,7 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 				//return nullptr;
 			}
 			for (int ordinate = 0; ordinate < numberOfOrdinates; ordinate++) {
-				ord = file->readByte();
+				ord = readField(file, 8);
 				debugC(1, kFreescapeDebugParser, "ord: %x", ord);
 				ordinates->push_back(32 * ord);
 				byteSizeOfObject--;
@@ -358,14 +375,18 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 
 void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offset, int ncolors) {
 	file->seek(offset);
-	uint8 numberOfAreas = file->readByte();
-	uint16 dbSize = file->readUint16LE();
+	uint8 numberOfAreas = readField(file, 8);
+	uint16 dbSize = 0;
 	debugC(1, kFreescapeDebugParser, "Number of areas: %d", numberOfAreas);
-	debugC(1, kFreescapeDebugParser, "Database ends at %x", dbSize);
 
-	uint8 startArea = file->readByte();
+	if (!isAmiga()) {
+		dbSize = readField(file, 16);
+		debugC(1, kFreescapeDebugParser, "Database ends at %x", dbSize);
+	}
+
+	uint8 startArea = readField(file, 8);
 	debugC(1, kFreescapeDebugParser, "Start area: %d", startArea);
-	uint8 startEntrance = file->readByte();
+	uint8 startEntrance = readField(file, 8);
 	debugC(1, kFreescapeDebugParser, "Entrace area: %d", startEntrance);
 
 	file->seek(offset + 0xa);
@@ -397,11 +418,11 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	file->seek(offset + 0x46); // 0x46
 
 	uint16 globalSomething;
-	globalSomething = file->readUint16LE();
+	globalSomething = readField(file, 16);
 	debugC(1, kFreescapeDebugParser, "Pointer to something: %x\n", globalSomething);
 
 	uint16 globalByteCodeTable;
-	globalByteCodeTable = file->readUint16LE();
+	globalByteCodeTable = readField(file, 16);
 	debugC(1, kFreescapeDebugParser, "GBCT: %d\n", globalByteCodeTable);
 
 	file->seek(offset + globalByteCodeTable);


Commit: 9ba81add8cc179b17374683db783be3c6e87dca3
    https://github.com/scummvm/scummvm/commit/9ba81add8cc179b17374683db783be3c6e87dca3
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:20+01:00

Commit Message:
FREESCAPE: refactored and added some code to parse data from the amiga releases

Changed paths:
    engines/freescape/freescape.h
    engines/freescape/games/driller.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 8a914cd3f01..e59e16a7af3 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -104,6 +104,7 @@ public:
 	void loadColorPalette();
 
 	uint16 readField(Common::SeekableReadStream *file, int nbits);
+	Common::Array<uint8> readArray(Common::SeekableReadStream *file, int size);
 	// 16-bit
 	void load16bitBinary(Common::SeekableReadStream *file);
 
@@ -260,6 +261,7 @@ public:
 	void pressedKey(const int keycode) override;
 
 	private:
+	void loadGlobalObjects(Common::SeekableReadStream *file, int offset);
 	bool drillDeployed();
 	void addDrill(const Math::Vector3d position);
 	void removeDrill();
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index e1f048957a9..55fd10554fe 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -96,6 +96,20 @@ void DrillerEngine::gotoArea(uint16 areaID, int entranceID) {
 		_gfx->_keyColor = 255;
 }
 
+void DrillerEngine::loadGlobalObjects(Common::SeekableReadStream *file, int offset) {
+	assert(!_areaMap.contains(255));
+	ObjectMap *globalObjectsByID = new ObjectMap;
+	file->seek(offset);
+	for (int i = 0; i < 8; i++) {
+		Object *gobj = load8bitObject(file);
+		assert(gobj);
+		assert(!globalObjectsByID->contains(gobj->getObjectID()));
+		debugC(1, kFreescapeDebugParser, "Adding global object: %d", gobj->getObjectID());
+		(*globalObjectsByID)[gobj->getObjectID()] = gobj;
+	}
+
+	_areaMap[255] = new Area(255, 0, globalObjectsByID, nullptr);
+}
 
 void DrillerEngine::loadAssets() {
 	Common::SeekableReadStream *file = nullptr;
@@ -109,13 +123,22 @@ void DrillerEngine::loadAssets() {
 		if (file == nullptr)
 			error("Failed to open 'driller' executable for Amiga");
 
-		load8bitBinary(file, 0xbd90, 16);
+		loadGlobalObjects(file, 0xbd62);
+		/*file->seek(0x29efe);
+		load8bitArea(file, 16);
+		file->seek(0x2a450);
+		load8bitArea(file, 16);*/
+
+		load8bitBinary(file, 0x29c16, 16);
 	} else if (_renderMode == "ega") {
 		file = gameDir.createReadStreamForMember("DRILLE.EXE");
 
 		if (file == nullptr)
 			error("Failed to open DRILLE.EXE");
 
+		loadMessages(file, 0x4135, 14, 20);
+		loadFonts(file, 0x99dd);
+		loadGlobalObjects(file, 0x3b42);
 		load8bitBinary(file, 0x9b40, 16);
 	} else if (_renderMode == "cga") {
 		file = gameDir.createReadStreamForMember("DRILLC.EXE");
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 3e42d8e9eac..4967fc00922 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -32,11 +32,18 @@ namespace Freescape {
 
 uint16 FreescapeEngine::readField(Common::SeekableReadStream *file, int bits) {
 	uint16 value;
-	assert(bits == 8 || bits == 16);
+	assert(bits == 8 || bits == 16 || bits == 32);
 	if (isAmiga()) {
-		value = file->readUint16BE();
-		if (bits == 8)
-			assert(value < 256);
+		if (bits == 32)
+			value = file->readUint32BE();
+		else {
+			value = file->readUint16BE();
+			if (bits == 8) {
+				if (value >= 256)
+					warning("failed to read byte with value 0x%x", value);
+				value = value & 0xff;
+			}
+		}
 	} else {
 		if (bits == 8)
 			value = file->readByte();
@@ -47,6 +54,15 @@ uint16 FreescapeEngine::readField(Common::SeekableReadStream *file, int bits) {
 	return value;
 }
 
+Common::Array<uint8> FreescapeEngine::readArray(Common::SeekableReadStream *file, int size) {
+	byte *data = (byte*)malloc(size);
+	for (int i = 0; i < size; i++) {
+		data[i] = readField(file, 8);
+	}
+	Common::Array<uint8> array(data, size);
+	return array;
+}
+
 Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 
 	byte rawFlagsAndType = readField(file, 8);
@@ -146,9 +162,7 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 		FCLInstructionVector instructions;
 		Common::String *conditionSource = nullptr;
 		if (byteSizeOfObject) {
-			byte *conditionData = (byte*)malloc(byteSizeOfObject);
-			file->read(conditionData, byteSizeOfObject);
-			Common::Array<uint8> conditionArray(conditionData, byteSizeOfObject);
+			Common::Array<uint8> conditionArray = readArray(file, byteSizeOfObject);
 			conditionSource = detokenise8bitCondition(conditionArray, instructions);
 			//instructions = getInstructions(conditionSource);
 			debugC(1, kFreescapeDebugParser, "%s", conditionSource->c_str());
@@ -237,13 +251,13 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	Common::String name;
 	uint32 base = file->pos();
 	debugC(1, kFreescapeDebugParser, "Area base: %x", base);
-	uint8 areaFlags = file->readByte();
-	uint8 numberOfObjects = file->readByte();
-	uint8 areaNumber = file->readByte();
+	uint8 areaFlags = readField(file, 8);
+	uint8 numberOfObjects = readField(file, 8);
+	uint8 areaNumber = readField(file, 8);
 
-	uint16 cPtr = file->readUint16LE();
+	uint32 cPtr = readField(file, 32);
 	debugC(1, kFreescapeDebugParser, "Condition pointer: %x", cPtr);
-	uint8 scale = file->readByte();
+	uint8 scale = readField(file, 8);
 	debugC(1, kFreescapeDebugParser, "Scale: %d", scale);
 
 	uint8 ci1 = 0;
@@ -258,10 +272,10 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	if (skyColor == 0)
 		skyColor = 255;
 
-	ci1 = file->readByte() & 15;
-	ci2 = file->readByte() & 15;
-	ci3 = file->readByte();
-	ci4 = file->readByte();
+	ci1 = readField(file, 8) & 15;
+	ci2 = readField(file, 8) & 15;
+	ci3 = readField(file, 8);
+	ci4 = readField(file, 8);
 	debugC(1, kFreescapeDebugParser, "Colors: %d %d %d %d %d %d", ci1, ci2, ci3, ci4, skyColor, groundColor);
 	// CPC
 	//groundColor = file->readByte() & 15;
@@ -299,18 +313,18 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 		}
 	} else if (isDriller() || isDark()) {
 		if (isDriller()) {
-			gasPocketX = file->readByte();
-			gasPocketY = file->readByte();
-			gasPocketRadius = file->readByte();
+			gasPocketX = readField(file, 8);
+			gasPocketY = readField(file, 8);
+			gasPocketRadius = readField(file, 8);
 		} else {
-			name = name + char(file->readByte());
-			name = name + char(file->readByte());
-			name = name + char(file->readByte());
+			name = name + char(readField(file, 8));
+			name = name + char(readField(file, 8));
+			name = name + char(readField(file, 8));
 		}
 		debugC(1, kFreescapeDebugParser, "Gas pocket at (%d, %d) with radius %d", gasPocketX, gasPocketY, gasPocketRadius);
 		int i = 0;
 		while (i < 12) {
-			name = name + char(file->readByte());
+			name = name + char(readField(file, 8));
 			i++;
 		}
 		debugC(1, kFreescapeDebugParser, "Area name: %s", name.c_str());
@@ -339,9 +353,11 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	}
 	long int endLastObject = file->pos();
 	debugC(1, kFreescapeDebugParser, "Last position %lx", endLastObject);
-	assert(endLastObject == base + cPtr || areaNumber == 192);
-	file->seek(base + cPtr);
-	uint8 numConditions = file->readByte();
+	if (!isAmiga()) {
+		assert(endLastObject == base + cPtr || areaNumber == 192);
+		file->seek(base + cPtr);
+	}
+	uint8 numConditions = readField(file, 8);
 	debugC(1, kFreescapeDebugParser, "%d area conditions at %x of area %d", numConditions, base + cPtr, areaNumber);
 
 	Area *area = new Area(areaNumber, areaFlags, objectsByID, entrancesByID);
@@ -357,12 +373,10 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	while (numConditions--) {
 		FCLInstructionVector instructions;
 		// get the length
-		uint32 lengthOfCondition = file->readByte();
+		uint32 lengthOfCondition = readField(file, 8);
 		debugC(1, kFreescapeDebugParser, "length of condition: %d", lengthOfCondition);
 		// get the condition
-		byte *conditionData = (byte*)malloc(lengthOfCondition);
-		file->read(conditionData, lengthOfCondition);
-		Common::Array<uint8> conditionArray(conditionData, lengthOfCondition);
+		Common::Array<uint8> conditionArray = readArray(file, lengthOfCondition);
 		Common::String *conditionSource = detokenise8bitCondition(conditionArray, instructions);
 		area->conditions.push_back(instructions);
 		area->conditionSources.push_back(conditionSource);
@@ -382,7 +396,8 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	if (!isAmiga()) {
 		dbSize = readField(file, 16);
 		debugC(1, kFreescapeDebugParser, "Database ends at %x", dbSize);
-	}
+	} else
+		dbSize = readField(file, 32);
 
 	uint8 startArea = readField(file, 8);
 	debugC(1, kFreescapeDebugParser, "Start area: %d", startArea);
@@ -413,7 +428,6 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 		debugC(1, kFreescapeDebugParser, "---");
 		_colorMap.push_back(entry - 3);
 	}
-	//assert(0);
 
 	file->seek(offset + 0x46); // 0x46
 
@@ -447,21 +461,6 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	if (isEclipse()) {
 		loadFonts(file, 0xd403);
 		//loadMessages(file, 0x7110, 17, 20);
-	} else if (isDriller()) {
-		loadMessages(file, 0x4135, 14, 20);
-		loadFonts(file, 0x99dd);
-
-		ObjectMap *globalObjectsByID = new ObjectMap;
-		file->seek(0x3b42);
-		for (int i = 0; i < 8; i++) {
-			Object *gobj = load8bitObject(file);
-			assert(gobj);
-			assert(!globalObjectsByID->contains(gobj->getObjectID()));
-			debugC(1, kFreescapeDebugParser, "Adding global object: %d", gobj->getObjectID());
-			(*globalObjectsByID)[gobj->getObjectID()] = gobj;
-		}
-
-		_areaMap[255] = new Area(255, 0, globalObjectsByID, nullptr);
 	} else if (isDark()) {
 		//loadMessages(file, 0x4135, 14, 20);
 		loadFonts(file, 0xa113);
@@ -473,7 +472,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	debugC(1, kFreescapeDebugParser, "areas index at: %lx", file->pos());
 	uint16 *fileOffsetForArea = new uint16[numberOfAreas];
 	for (uint16 area = 0; area < numberOfAreas; area++) {
-		fileOffsetForArea[area] = file->readUint16LE();
+		fileOffsetForArea[area] = readField(file, 16);
 		debugC(1, kFreescapeDebugParser, "offset: %x", fileOffsetForArea[area]);
 	}
 


Commit: 6e109d6b949337c95b2595bc48959143f5a23aef
    https://github.com/scummvm/scummvm/commit/6e109d6b949337c95b2595bc48959143f5a23aef
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:20+01:00

Commit Message:
FREESCAPE: refactored some game-specific code

Changed paths:
    engines/freescape/games/dark.cpp
    engines/freescape/games/eclipse.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index 3ab9fc6f390..ee9bb6ae9c2 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -51,6 +51,7 @@ void DarkEngine::loadAssets() {
 		if (file == nullptr)
 			error("Failed to open DSIDEE.EXE");
 
+		loadFonts(file, 0xa113);
 		load8bitBinary(file, 0xa280, 16);
 	} else if (_renderMode == "cga") {
 		file = gameDir.createReadStreamForMember("DSIDEC.EXE");
diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index b24bb9573db..d3428d1863c 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -113,6 +113,7 @@ void EclipseEngine::loadAssets() {
 		if (file == nullptr)
 			error("Failed to open TOTEE.EXE");
 
+		loadFonts(file, 0xd403);
 		load8bitBinary(file, 0x3ce0, 16);
 	} else if (_renderMode == "cga") {
 		file = gameDir.createReadStreamForMember("TOTEC.EXE");
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 4967fc00922..c7d3a1e2b6e 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -458,14 +458,6 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 		debugC(1, kFreescapeDebugParser, "%s", conditionSource->c_str());
 	}
 
-	if (isEclipse()) {
-		loadFonts(file, 0xd403);
-		//loadMessages(file, 0x7110, 17, 20);
-	} else if (isDark()) {
-		//loadMessages(file, 0x4135, 14, 20);
-		loadFonts(file, 0xa113);
-	}
-
 	file->seek(offset + 0xc8);
 	//file->seek(offset + 0x4f); //CPC
 


Commit: c47aaa866a7caf2eb5d35b280d9581a76231864c
    https://github.com/scummvm/scummvm/commit/c47aaa866a7caf2eb5d35b280d9581a76231864c
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:20+01:00

Commit Message:
FREESCAPE: refactored some game-specific code

Changed paths:
    engines/freescape/games/castle.cpp
    engines/freescape/games/eclipse.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/games/castle.cpp b/engines/freescape/games/castle.cpp
index 5f12c5e39bb..f428a8d00bb 100644
--- a/engines/freescape/games/castle.cpp
+++ b/engines/freescape/games/castle.cpp
@@ -57,6 +57,8 @@ void CastleEngine::loadAssets() {
 
 	file = new Common::MemoryReadStream(encryptedBuffer, size);
 	load8bitBinary(file, 0, 16);
+	for (AreaMap::iterator iterator = _areaMap.begin(); iterator != _areaMap.end(); iterator++)
+		iterator->_value->addStructure(_areaMap[255]);
 
 	// CPC
 	//file = gameDir.createReadStreamForMember("cm.bin");
diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index d3428d1863c..ebffe453bbb 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -115,6 +115,9 @@ void EclipseEngine::loadAssets() {
 
 		loadFonts(file, 0xd403);
 		load8bitBinary(file, 0x3ce0, 16);
+		for (AreaMap::iterator iterator = _areaMap.begin(); iterator != _areaMap.end(); iterator++)
+			iterator->_value->addStructure(_areaMap[255]);
+
 	} else if (_renderMode == "cga") {
 		file = gameDir.createReadStreamForMember("TOTEC.EXE");
 
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index c7d3a1e2b6e..a751f57ee86 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -487,11 +487,6 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 		}
 	}
 
-	if (!isDriller() && !isDark() && _areaMap.contains(255)) {
-		for (AreaMap::iterator iterator = _areaMap.begin(); iterator != _areaMap.end(); iterator++)
-			iterator->_value->addStructure(_areaMap[255]);
-	}
-
 	if (!_areaMap.contains(startArea))
 		_startArea = newArea->getAreaID();
 	else


Commit: 9846e162f959ee3b6dc97a736184f39dc12989eb
    https://github.com/scummvm/scummvm/commit/9846e162f959ee3b6dc97a736184f39dc12989eb
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:21+01:00

Commit Message:
FREESCAPE: disable execution of local/global condition for castle

Changed paths:
    engines/freescape/language/instruction.cpp


diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index 793444b25d0..115efc9975a 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -75,7 +75,8 @@ void FreescapeEngine::executeObjectConditions(GeometricObject *obj, bool shot, b
 }
 
 void FreescapeEngine::executeLocalGlobalConditions(bool shot, bool collided) {
-
+	if (isCastle())
+		return;
 	debugC(1, kFreescapeDebugCode, "Executing room conditions");
 	for (int i = 0; i < int(_currentArea->conditions.size()); i++) {
 		debugC(1, kFreescapeDebugCode, "%s", _currentArea->conditionSources[i]->c_str());


Commit: 96fbece4eab70cad3dff8166ca0e59f0826c3def
    https://github.com/scummvm/scummvm/commit/96fbece4eab70cad3dff8166ca0e59f0826c3def
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:21+01:00

Commit Message:
FREESCAPE: refactored asset loading code for castle

Changed paths:
    engines/freescape/freescape.h
    engines/freescape/games/castle.cpp
    engines/freescape/games/driller.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index e59e16a7af3..9a8d25dac7c 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -218,7 +218,9 @@ public:
 
 	// Text messages and Fonts
 	Common::StringArray _messagesList;
-	void loadMessages(Common::SeekableReadStream *file, int offset, int size, int number);
+	void loadMessagesFixedSize(Common::SeekableReadStream *file, int offset, int size, int number);
+	void loadMessagesVariableSize(Common::SeekableReadStream *file, int offset, int number);
+
 	void loadFonts(Common::SeekableReadStream *file, int offset);
 	Common::StringArray _currentAreaMessages;
 	Common::StringArray _currentEphymeralMessages;
@@ -294,6 +296,9 @@ public:
 	void loadAssets() override;
 
 	void gotoArea(uint16 areaID, int entranceID) override;
+
+private:
+	Common::SeekableReadStream *decryptFile(const Common::String filename);
 };
 
 extern FreescapeEngine *g_freescape;
diff --git a/engines/freescape/games/castle.cpp b/engines/freescape/games/castle.cpp
index f428a8d00bb..46c2f790bb2 100644
--- a/engines/freescape/games/castle.cpp
+++ b/engines/freescape/games/castle.cpp
@@ -37,14 +37,11 @@ CastleEngine::CastleEngine(OSystem *syst) : FreescapeEngine(syst) {
 	_playerDepth = 8;
 }
 
-void CastleEngine::loadAssets() {
-	Common::SeekableReadStream *file = nullptr;
+Common::SeekableReadStream *CastleEngine::decryptFile(const Common::String filename) {
 	Common::String path = ConfMan.get("path");
 	Common::FSDirectory gameDir(path);
 
-	_renderMode = "ega";
-
-	file = gameDir.createReadStreamForMember("CMEDF");
+	Common::SeekableReadStream *file = gameDir.createReadStreamForMember(filename);
 	int size = file->size();
 	byte *encryptedBuffer = (byte*) malloc(size);
 	file->read(encryptedBuffer, size);
@@ -55,7 +52,19 @@ void CastleEngine::loadAssets() {
 		seed = (seed + 1) & 0xff;
     }
 
-	file = new Common::MemoryReadStream(encryptedBuffer, size);
+	return (new Common::MemoryReadStream(encryptedBuffer, size));
+}
+
+
+void CastleEngine::loadAssets() {
+	Common::SeekableReadStream *file = nullptr;
+	_renderMode = "ega";
+
+	file = decryptFile("CMLE");
+	loadMessagesVariableSize(file, 0, 172);
+	delete file;
+
+	file = decryptFile("CMEDF");
 	load8bitBinary(file, 0, 16);
 	for (AreaMap::iterator iterator = _areaMap.begin(); iterator != _areaMap.end(); iterator++)
 		iterator->_value->addStructure(_areaMap[255]);
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 55fd10554fe..f7b778c2146 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -136,7 +136,7 @@ void DrillerEngine::loadAssets() {
 		if (file == nullptr)
 			error("Failed to open DRILLE.EXE");
 
-		loadMessages(file, 0x4135, 14, 20);
+		loadMessagesFixedSize(file, 0x4135, 14, 20);
 		loadFonts(file, 0x99dd);
 		loadGlobalObjects(file, 0x3b42);
 		load8bitBinary(file, 0x9b40, 16);
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index a751f57ee86..815f2684436 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -519,7 +519,7 @@ void FreescapeEngine::loadFonts(Common::SeekableReadStream *file, int offset) {
 	_font.set_bits((byte *)font);
 }
 
-void FreescapeEngine::loadMessages(Common::SeekableReadStream *file, int offset, int size, int number) {
+void FreescapeEngine::loadMessagesFixedSize(Common::SeekableReadStream *file, int offset, int size, int number) {
 	file->seek(offset);
 	byte *buffer = (byte *)malloc(size + 1);
 	buffer[size] = 0;
@@ -533,5 +533,22 @@ void FreescapeEngine::loadMessages(Common::SeekableReadStream *file, int offset,
 	}
 }
 
+void FreescapeEngine::loadMessagesVariableSize(Common::SeekableReadStream *file, int offset, int number) {
+	file->seek(offset);
+	debugC(1, kFreescapeDebugParser, "String table:");
+
+	for (int i = 0; i < number; i++) {
+		Common::String message = "";
+		while (true) {
+			byte c = file->readByte();
+			if (c <= 1)
+				break;
+			message = message + c;
+		}
+
+		_messagesList.push_back(message);
+		debugC(1, kFreescapeDebugParser, "%s", _messagesList[i].c_str());
+	}
+}
 
 } // namespace Freescape
\ No newline at end of file


Commit: 5333d4ee8f2cf76a5baee7c152e759f6fbd642e2
    https://github.com/scummvm/scummvm/commit/5333d4ee8f2cf76a5baee7c152e759f6fbd642e2
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:21+01:00

Commit Message:
FREESCAPE: fixed texture memory leak

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/dark.cpp
    engines/freescape/games/driller.cpp
    engines/freescape/games/eclipse.cpp
    engines/freescape/gfx.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index e08c51f5848..e5049e91580 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -57,6 +57,8 @@ FreescapeEngine::FreescapeEngine(OSystem *syst)
 	_noClipMode = false;
 	_playerHeightNumber = 1;
 	_borderTexture = nullptr;
+	_uiTexture = nullptr;
+
 	_fullscreenViewArea = Common::Rect(0, 0, _screenW, _screenH);
 	_viewArea = _fullscreenViewArea;
 	_rnd = new Common::RandomSource("freescape");
@@ -65,6 +67,9 @@ FreescapeEngine::FreescapeEngine(OSystem *syst)
 FreescapeEngine::~FreescapeEngine() {
 	delete _rnd;
 	delete _border;
+	delete _borderTexture;
+	delete _uiTexture;
+
 	delete _gfx;
 }
 
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 9a8d25dac7c..65bef0c3db5 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -94,6 +94,7 @@ public:
 	void drawBorder();
 	virtual void drawUI();
 	Texture *_borderTexture;
+	Texture *_uiTexture;
 
 	// Parsing assets
 	uint8 _binaryBits;
diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index ee9bb6ae9c2..95128a3ed57 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -136,8 +136,12 @@ void DarkEngine::drawUI() {
 
 		drawStringInSurface(Common::String::format("%07d", score), 95, 8, yellow, black, surface);
 
-		Texture *texture = _gfx->createTexture(surface);
-		_gfx->drawTexturedRect2D(_fullscreenViewArea, _fullscreenViewArea, texture);
+		if (!_uiTexture)
+			_uiTexture = _gfx->createTexture(surface);
+		else
+			_uiTexture->update(surface);
+
+		_gfx->drawTexturedRect2D(_fullscreenViewArea, _fullscreenViewArea, _uiTexture);
 		surface->free();
 		delete surface;
 	}
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index f7b778c2146..b59b27966c2 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -175,8 +175,12 @@ void DrillerEngine::drawUI() {
 
 		drawStringInSurface(Common::String::format("%07d", score), 240, 129, yellow, black, surface);
 
-		Texture *texture = _gfx->createTexture(surface);
-		_gfx->drawTexturedRect2D(_fullscreenViewArea, _fullscreenViewArea, texture);
+		if (!_uiTexture)
+			_uiTexture = _gfx->createTexture(surface);
+		else
+			_uiTexture->update(surface);
+
+		_gfx->drawTexturedRect2D(_fullscreenViewArea, _fullscreenViewArea, _uiTexture);
 		surface->free();
 		delete surface;
 	}
diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index ebffe453bbb..c2eed343c50 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -189,8 +189,13 @@ void EclipseEngine::drawUI() {
 		drawStringInSurface(_currentAreaMessages[0], 102, 135, black, yellow, surface);
 	drawStringInSurface(Common::String::format("%07d", score), 136, 6, black, white, surface);
 
-	Texture *texture = _gfx->createTexture(surface);
-	_gfx->drawTexturedRect2D(_fullscreenViewArea, _fullscreenViewArea, texture);
+	if (!_uiTexture)
+		_uiTexture = _gfx->createTexture(surface);
+	else
+		_uiTexture->update(surface);
+
+	_gfx->drawTexturedRect2D(_fullscreenViewArea, _fullscreenViewArea, _uiTexture);
+
 	surface->free();
 	delete surface;
 
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index ee76d8e81ee..7727e61f1e8 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -38,6 +38,9 @@ class Renderer;
 
 class Texture {
 public:
+	Texture() {};
+	virtual ~Texture() {};
+
 	uint width;
 	uint height;
 	Graphics::PixelFormat format;
@@ -46,9 +49,6 @@ public:
 	virtual void updatePartial(const Graphics::Surface *surface, const Common::Rect &rect) = 0;
 
 	static const Graphics::PixelFormat getRGBAPixelFormat();
-protected:
-	Texture() {}
-	virtual ~Texture() {}
 };
 
 class Renderer {


Commit: 9db5a84d4d8143c210600b7bef0ff0845793e5d7
    https://github.com/scummvm/scummvm/commit/9db5a84d4d8143c210600b7bef0ff0845793e5d7
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:21+01:00

Commit Message:
FREESCAPE: implemented isDemo

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/castle.cpp
    engines/freescape/games/dark.cpp
    engines/freescape/games/driller.cpp
    engines/freescape/games/eclipse.cpp
    engines/freescape/metaengine.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index e5049e91580..751eafe7ae4 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -33,8 +33,8 @@ namespace Freescape {
 
 FreescapeEngine *g_freescape = NULL;
 
-FreescapeEngine::FreescapeEngine(OSystem *syst)
-	: Engine(syst), _screenW(320), _screenH(200), _border(nullptr), _gfx(nullptr) {
+FreescapeEngine::FreescapeEngine(OSystem *syst, const ADGameDescription *gd)
+	: Engine(syst), _gameDescription(gd), _screenW(320), _screenH(200), _border(nullptr), _gfx(nullptr) {
 	g_freescape = this;
 	if (!ConfMan.hasKey("render_mode") || ConfMan.get("render_mode").empty())
 		_renderMode = "ega";
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 65bef0c3db5..951e8f49bf4 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -25,6 +25,7 @@
 #include "common/bitarray.h"
 #include "common/random.h"
 #include "engines/engine.h"
+#include "engines/advancedDetector.h"
 #include "graphics/palette.h"
 #include "graphics/surface.h"
 #include "graphics/tinygl/pixelbuffer.h"
@@ -74,9 +75,12 @@ private:
 	Common::RandomSource *_rnd;
 
 public:
-	FreescapeEngine(OSystem *syst);
+	FreescapeEngine(OSystem *syst, const ADGameDescription *gd);
 	~FreescapeEngine();
 
+	const ADGameDescription *_gameDescription;
+	bool isDemo() const;
+
 	// Game selection
 	bool isDriller() { return _targetName.hasPrefix("driller") || _targetName.hasPrefix("spacestationoblivion"); }
 	bool isDark() { return _targetName.hasPrefix("darkside"); }
@@ -245,7 +249,7 @@ public:
 
 class DrillerEngine : public FreescapeEngine {
 public:
-	DrillerEngine(OSystem *syst);
+	DrillerEngine(OSystem *syst, const ADGameDescription *gd);
 
 	uint32 _initialJetEnergy;
 	uint32 _initialJetShield;
@@ -263,16 +267,19 @@ public:
 
 	void pressedKey(const int keycode) override;
 
-	private:
+private:
 	void loadGlobalObjects(Common::SeekableReadStream *file, int offset);
 	bool drillDeployed();
 	void addDrill(const Math::Vector3d position);
 	void removeDrill();
+
+	void loadAssetsDemo();
+	void loadAssetsFullGame();
 };
 
 class DarkEngine : public FreescapeEngine {
 public:
-	DarkEngine(OSystem *syst);
+	DarkEngine(OSystem *syst, const ADGameDescription *gd);
 
 	void loadAssets() override;
 	void gotoArea(uint16 areaID, int entranceID) override;
@@ -281,7 +288,7 @@ public:
 
 class EclipseEngine : public FreescapeEngine {
 public:
-	EclipseEngine(OSystem *syst);
+	EclipseEngine(OSystem *syst, const ADGameDescription *gd);
 
 	void loadAssets() override;
 
@@ -292,7 +299,7 @@ public:
 
 class CastleEngine : public FreescapeEngine {
 public:
-	CastleEngine(OSystem *syst);
+	CastleEngine(OSystem *syst, const ADGameDescription *gd);
 
 	void loadAssets() override;
 
diff --git a/engines/freescape/games/castle.cpp b/engines/freescape/games/castle.cpp
index 46c2f790bb2..e4024bf3d5f 100644
--- a/engines/freescape/games/castle.cpp
+++ b/engines/freescape/games/castle.cpp
@@ -27,7 +27,7 @@
 
 namespace Freescape {
 
-CastleEngine::CastleEngine(OSystem *syst) : FreescapeEngine(syst) {
+CastleEngine::CastleEngine(OSystem *syst, const ADGameDescription *gd) : FreescapeEngine(syst, gd) {
 	_playerHeightNumber = 1;
 	_playerHeights.push_back(16);
 	_playerHeights.push_back(48);
diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index 95128a3ed57..a4ca5bb11d9 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -27,7 +27,7 @@
 
 namespace Freescape {
 
-DarkEngine::DarkEngine(OSystem *syst) : FreescapeEngine(syst) {
+DarkEngine::DarkEngine(OSystem *syst, const ADGameDescription *gd) : FreescapeEngine(syst, gd) {
 	_viewArea = Common::Rect(40, 24, 279, 124);
 	_playerHeightNumber = 1;
 	_playerHeights.push_back(16);
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index b59b27966c2..b5dddcf5abd 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -28,7 +28,7 @@
 
 namespace Freescape {
 
-DrillerEngine::DrillerEngine(OSystem *syst) : FreescapeEngine(syst) {
+DrillerEngine::DrillerEngine(OSystem *syst, const ADGameDescription *gd) : FreescapeEngine(syst, gd) {
 	_viewArea = Common::Rect(40, 16, 279, 116);
 	_playerHeightNumber = 1;
 	_playerHeights.push_back(16);
@@ -112,6 +112,37 @@ void DrillerEngine::loadGlobalObjects(Common::SeekableReadStream *file, int offs
 }
 
 void DrillerEngine::loadAssets() {
+	if (isDemo())
+		loadAssetsDemo();
+	else
+		loadAssetsFullGame();
+}
+
+void DrillerEngine::loadAssetsDemo() {
+	Common::SeekableReadStream *file = nullptr;
+	Common::String path = ConfMan.get("path");
+	Common::FSDirectory gameDir(path);
+
+	Common::File exe;
+	if (isAmiga()) {
+		file = gameDir.createReadStreamForMember("amiga.demo");
+
+		if (file == nullptr)
+			error("Failed to open 'amiga.demo' file");
+
+		//loadGlobalObjects(file, 0xbd62);
+		/*file->seek(0x29efe);
+		load8bitArea(file, 16);
+		file->seek(0x2a450);
+		load8bitArea(file, 16);*/
+
+		load8bitBinary(file, 0, 16);
+	} else
+		error("Unsupported demo for Driller");
+}
+
+
+void DrillerEngine::loadAssetsFullGame() {
 	Common::SeekableReadStream *file = nullptr;
 	Common::String path = ConfMan.get("path");
 	Common::FSDirectory gameDir(path);
diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index c2eed343c50..c969932ba63 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -75,7 +75,7 @@ static const char* rawMessagesTable[] = {
 	NULL
 };
 
-EclipseEngine::EclipseEngine(OSystem *syst) : FreescapeEngine(syst) {
+EclipseEngine::EclipseEngine(OSystem *syst, const ADGameDescription *gd) : FreescapeEngine(syst, gd) {
 	_viewArea = Common::Rect(40, 32, 280, 132);
 	_playerHeightNumber = 1;
 	_playerHeights.push_back(16);
diff --git a/engines/freescape/metaengine.cpp b/engines/freescape/metaengine.cpp
index a40067a8abb..a8bdb92ac98 100644
--- a/engines/freescape/metaengine.cpp
+++ b/engines/freescape/metaengine.cpp
@@ -28,24 +28,32 @@ public:
 		return "freescape";
 	}
 
-	Common::Error createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override;
+	Common::Error createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const override;
 };
 
-Common::Error FreescapeMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
-	if (Common::String(desc->gameId) == "driller" || Common::String(desc->gameId) == "spacestationoblivion") {
-		*engine = (Engine *)new Freescape::DrillerEngine(syst);
-	} else 	if (Common::String(desc->gameId) == "darkside") {
-		*engine = (Engine *)new Freescape::DarkEngine(syst);
-	} else 	if (Common::String(desc->gameId) == "totaleclipse") {
-		*engine = (Engine *)new Freescape::EclipseEngine(syst);
-	} else 	if (Common::String(desc->gameId) == "castlemaster") {
-		*engine = (Engine *)new Freescape::CastleEngine(syst);
+Common::Error FreescapeMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const {
+	if (Common::String(gd->gameId) == "driller" || Common::String(gd->gameId) == "spacestationoblivion") {
+		*engine = (Engine *)new Freescape::DrillerEngine(syst, gd);
+	} else 	if (Common::String(gd->gameId) == "darkside") {
+		*engine = (Engine *)new Freescape::DarkEngine(syst, gd);
+	} else 	if (Common::String(gd->gameId) == "totaleclipse") {
+		*engine = (Engine *)new Freescape::EclipseEngine(syst, gd);
+	} else 	if (Common::String(gd->gameId) == "castlemaster") {
+		*engine = (Engine *)new Freescape::CastleEngine(syst, gd);
 	} else
-		*engine = new Freescape::FreescapeEngine(syst);
+		*engine = new Freescape::FreescapeEngine(syst, gd);
 
 	return Common::kNoError;
 }
 
+namespace Freescape {
+
+bool FreescapeEngine::isDemo() const {
+	return (bool)(_gameDescription->flags & ADGF_DEMO);
+}
+
+} // End of namespace freescape
+
 #if PLUGIN_ENABLED_DYNAMIC(FREESCAPE)
 REGISTER_PLUGIN_DYNAMIC(FREESCAPE, PLUGIN_TYPE_ENGINE, FreescapeMetaEngine);
 #else


Commit: bccbaee3b74bb4a57b741fa3a4bc34cf2e25a4cb
    https://github.com/scummvm/scummvm/commit/bccbaee3b74bb4a57b741fa3a4bc34cf2e25a4cb
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:21+01:00

Commit Message:
FREESCAPE: allow to load driller data from amiga

Changed paths:
    engines/freescape/games/driller.cpp
    engines/freescape/gfx.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index b5dddcf5abd..22ba900149d 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -56,12 +56,14 @@ void DrillerEngine::gotoArea(uint16 areaID, int entranceID) {
 	_currentArea->show();
 
 	_currentAreaMessages.clear();
-	if (_currentArea->gasPocketRadius > 0)
-		_currentAreaMessages.push_back(_messagesList[1]);
-	else
-		_currentAreaMessages.push_back(_messagesList[2]);
+	if (_messagesList.size() > 2) {
+		if (_currentArea->gasPocketRadius > 0)
+			_currentAreaMessages.push_back(_messagesList[1]);
+		else
+			_currentAreaMessages.push_back(_messagesList[2]);
 
-	_currentAreaMessages.push_back(_currentArea->name);
+		_currentAreaMessages.push_back(_currentArea->name);
+	}
 
 	if (entranceID > 0 || areaID == 127) {
 		traverseEntrance(entranceID);
@@ -155,9 +157,11 @@ void DrillerEngine::loadAssetsFullGame() {
 			error("Failed to open 'driller' executable for Amiga");
 
 		loadGlobalObjects(file, 0xbd62);
-		/*file->seek(0x29efe);
-		load8bitArea(file, 16);
-		file->seek(0x2a450);
+		// Font data: 0x8940
+		//file->seek(0x29efe);
+		//load8bitArea(file, 16);
+		//assert(0);
+		/*file->seek(0x2a450);
 		load8bitArea(file, 16);*/
 
 		load8bitBinary(file, 0x29c16, 16);
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index 3a51f21729f..4b29d7370bc 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -70,7 +70,11 @@ bool Renderer::getRGBAt(uint8 index, uint8 &r, uint8 &g, uint8 &b) {
 	uint8 acc = 1;
 	for (int i = 0; i < 4; i++) {
 		byte be = *entry;
-		assert(be == 0 || be == 0xff);
+		if (be != 0 && be != 0xff) {
+			// TODO: fix colors for non-DOS releases
+			_palette->getRGBAt(index, r, g, b);
+			return true;
+		}
 
 		if (be == 0xff)
 			color = color + acc;
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 815f2684436..deb58fddc35 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -32,15 +32,19 @@ namespace Freescape {
 
 uint16 FreescapeEngine::readField(Common::SeekableReadStream *file, int bits) {
 	uint16 value;
-	assert(bits == 8 || bits == 16 || bits == 32);
+	assert(bits == 8 || bits == 16);
 	if (isAmiga()) {
-		if (bits == 32)
-			value = file->readUint32BE();
-		else {
+		if (bits == 16) {
+			uint16 lo = file->readUint16BE();
+			assert(lo < 256);
+			uint16 hi = file->readUint16BE();
+			assert(hi < 256);
+			value = 256 * hi + lo;
+		} else {
+			assert(bits == 8);
 			value = file->readUint16BE();
-			if (bits == 8) {
-				if (value >= 256)
-					warning("failed to read byte with value 0x%x", value);
+			if (value >= 256) {
+				warning("failed to read byte with value 0x%x", value);
 				value = value & 0xff;
 			}
 		}
@@ -190,7 +194,7 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 			// TODO: there is something here
 			debugC(1, kFreescapeDebugParser, "Warning: extra %d bytes in entrance", byteSizeOfObject);
 			while (byteSizeOfObject--) {
-				debugC(1, kFreescapeDebugParser, "b: %x", file->readByte());
+				debugC(1, kFreescapeDebugParser, "b: %x", readField(file, 8));
 			}
 			byteSizeOfObject = 0;
 		}
@@ -208,7 +212,8 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 		if (byteSizeOfObject > 0) {
 			// TODO: there is something here
 			debugC(1, kFreescapeDebugParser, "Warning: extra %d bytes in sensor", byteSizeOfObject);
-			file->seek(byteSizeOfObject, SEEK_CUR);
+			for (int i = 0; i < byteSizeOfObject; i++)
+				readField(file, 8);
 			byteSizeOfObject = 0;
 		}
 		assert(byteSizeOfObject == 0);
@@ -255,7 +260,7 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	uint8 numberOfObjects = readField(file, 8);
 	uint8 areaNumber = readField(file, 8);
 
-	uint32 cPtr = readField(file, 32);
+	uint16 cPtr = readField(file, 16);
 	debugC(1, kFreescapeDebugParser, "Condition pointer: %x", cPtr);
 	uint8 scale = readField(file, 8);
 	debugC(1, kFreescapeDebugParser, "Scale: %d", scale);
@@ -390,23 +395,22 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offset, int ncolors) {
 	file->seek(offset);
 	uint8 numberOfAreas = readField(file, 8);
-	uint16 dbSize = 0;
 	debugC(1, kFreescapeDebugParser, "Number of areas: %d", numberOfAreas);
 
-	if (!isAmiga()) {
-		dbSize = readField(file, 16);
-		debugC(1, kFreescapeDebugParser, "Database ends at %x", dbSize);
-	} else
-		dbSize = readField(file, 32);
+	uint32 dbSize = readField(file, 16);
+	debugC(1, kFreescapeDebugParser, "Database ends at %x", dbSize);
 
 	uint8 startArea = readField(file, 8);
 	debugC(1, kFreescapeDebugParser, "Start area: %d", startArea);
 	uint8 startEntrance = readField(file, 8);
 	debugC(1, kFreescapeDebugParser, "Entrace area: %d", startEntrance);
 
-	file->seek(offset + 0xa);
-	debugC(1, kFreescapeDebugParser, "Color map:");
+	if (isAmiga())
+		file->seek(offset + 0x16);
+	else
+		file->seek(offset + 0xa);
 
+	debugC(1, kFreescapeDebugParser, "Color map:");
 	uint8 data;
 	for (int i = 0; i < 15; i++) {
 		byte *entry = (byte*) malloc(4 * sizeof(byte));;
@@ -429,7 +433,10 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 		_colorMap.push_back(entry - 3);
 	}
 
-	file->seek(offset + 0x46); // 0x46
+	if (isAmiga())
+		file->seek(offset + 0x8a);
+	else
+		file->seek(offset + 0x46); // 0x46
 
 	uint16 globalSomething;
 	globalSomething = readField(file, 16);
@@ -437,20 +444,18 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 
 	uint16 globalByteCodeTable;
 	globalByteCodeTable = readField(file, 16);
-	debugC(1, kFreescapeDebugParser, "GBCT: %d\n", globalByteCodeTable);
+	debugC(1, kFreescapeDebugParser, "GBCT: %x\n", globalByteCodeTable);
 
 	file->seek(offset + globalByteCodeTable);
-	uint8 numConditions = file->readByte();
+	uint8 numConditions = readField(file, 8);
 	debugC(1, kFreescapeDebugParser, "%d global conditions", numConditions);
 	while (numConditions--) {
 		FCLInstructionVector instructions;
 		// get the length
-		uint32 lengthOfCondition = file->readByte();
+		uint32 lengthOfCondition = readField(file, 8);
 		debugC(1, kFreescapeDebugParser, "length of condition: %d at %lx", lengthOfCondition, file->pos());
 		// get the condition
-		byte *conditionData = (byte*)malloc(lengthOfCondition);
-		file->read(conditionData, lengthOfCondition);
-		Common::Array<uint8> conditionArray(conditionData, lengthOfCondition);
+		Common::Array<uint8> conditionArray = readArray(file, lengthOfCondition);
 		//debug("Global condition %d", numConditions + 1);
 		Common::String *conditionSource = detokenise8bitCondition(conditionArray, instructions);
 		_conditions.push_back(instructions);
@@ -458,13 +463,18 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 		debugC(1, kFreescapeDebugParser, "%s", conditionSource->c_str());
 	}
 
-	file->seek(offset + 0xc8);
+	if (isAmiga())
+		file->seek(offset + 0x190);
+	else
+		file->seek(offset + 0xc8);
 	//file->seek(offset + 0x4f); //CPC
 
 	debugC(1, kFreescapeDebugParser, "areas index at: %lx", file->pos());
 	uint16 *fileOffsetForArea = new uint16[numberOfAreas];
 	for (uint16 area = 0; area < numberOfAreas; area++) {
 		fileOffsetForArea[area] = readField(file, 16);
+		if (isAmiga())
+			fileOffsetForArea[area] = 2 * fileOffsetForArea[area];
 		debugC(1, kFreescapeDebugParser, "offset: %x", fileOffsetForArea[area]);
 	}
 


Commit: 09cfcf38865b88165f59d34d3db5be354b6defde
    https://github.com/scummvm/scummvm/commit/09cfcf38865b88165f59d34d3db5be354b6defde
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:21+01:00

Commit Message:
FREESCAPE: simplify loading of driller data in amiga

Changed paths:
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index deb58fddc35..85d72d4b5f0 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -40,6 +40,7 @@ uint16 FreescapeEngine::readField(Common::SeekableReadStream *file, int bits) {
 			uint16 hi = file->readUint16BE();
 			assert(hi < 256);
 			value = 256 * hi + lo;
+			value = 2 * value; // Unclear why, but this reads a pointer
 		} else {
 			assert(bits == 8);
 			value = file->readUint16BE();
@@ -358,10 +359,8 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	}
 	long int endLastObject = file->pos();
 	debugC(1, kFreescapeDebugParser, "Last position %lx", endLastObject);
-	if (!isAmiga()) {
-		assert(endLastObject == base + cPtr || areaNumber == 192);
-		file->seek(base + cPtr);
-	}
+	assert(endLastObject == base + cPtr || areaNumber == 192);
+	file->seek(base + cPtr);
 	uint8 numConditions = readField(file, 8);
 	debugC(1, kFreescapeDebugParser, "%d area conditions at %x of area %d", numConditions, base + cPtr, areaNumber);
 
@@ -449,7 +448,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	file->seek(offset + globalByteCodeTable);
 	uint8 numConditions = readField(file, 8);
 	debugC(1, kFreescapeDebugParser, "%d global conditions", numConditions);
-	while (numConditions--) {
+	while (!isAmiga() && numConditions--) { // TODO: read global conditions in Amiga
 		FCLInstructionVector instructions;
 		// get the length
 		uint32 lengthOfCondition = readField(file, 8);
@@ -473,8 +472,6 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	uint16 *fileOffsetForArea = new uint16[numberOfAreas];
 	for (uint16 area = 0; area < numberOfAreas; area++) {
 		fileOffsetForArea[area] = readField(file, 16);
-		if (isAmiga())
-			fileOffsetForArea[area] = 2 * fileOffsetForArea[area];
 		debugC(1, kFreescapeDebugParser, "offset: %x", fileOffsetForArea[area]);
 	}
 


Commit: 99d9c5f86d8623540ea8fdac5c9922c9245d80f9
    https://github.com/scummvm/scummvm/commit/99d9c5f86d8623540ea8fdac5c9922c9245d80f9
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:22+01:00

Commit Message:
FREESCAPE: improved detection of driller data from amiga

Changed paths:
    engines/freescape/detection.cpp
    engines/freescape/games/driller.cpp


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index bfbae955ef9..fd7c4fec751 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -108,6 +108,7 @@ static const ADGameDescription gameDescriptions[] = {
 	 "Driller",
 	 {
 		{"driller", 0, "13dab2e10d8e8b9a364c94a660e0d42a", 282384},
+		{"title.seq", 0, "4dd1b3b45110b24e8240a6132241c973", 185296},
 		AD_LISTEND
 	 },
 	 Common::EN_ANY,
@@ -117,7 +118,9 @@ static const ADGameDescription gameDescriptions[] = {
 	{"driller",
 	 "Rolling Demo",
 	 {
-		{"amiga.demo", 0, "0b056286d2d91f302499c97aca235462", 24220},
+		{"driller", 0, "f0d0e9447830e329e110e384371955fd", 162880},
+		{"data", 0, "0b056286d2d91f302499c97aca235462", 24220},
+		{"demo.cmd", 0, "7b90427c5c3c4bbb42d14076af994d50", 4096},
 		AD_LISTEND
 	 },
 	 Common::EN_ANY,
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 22ba900149d..0bd083b610f 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -127,10 +127,10 @@ void DrillerEngine::loadAssetsDemo() {
 
 	Common::File exe;
 	if (isAmiga()) {
-		file = gameDir.createReadStreamForMember("amiga.demo");
+		file = gameDir.createReadStreamForMember("data");
 
 		if (file == nullptr)
-			error("Failed to open 'amiga.demo' file");
+			error("Failed to open 'data' file");
 
 		//loadGlobalObjects(file, 0xbd62);
 		/*file->seek(0x29efe);
@@ -138,7 +138,7 @@ void DrillerEngine::loadAssetsDemo() {
 		file->seek(0x2a450);
 		load8bitArea(file, 16);*/
 
-		load8bitBinary(file, 0, 16);
+		load8bitBinary(file, 0x442, 16);
 	} else
 		error("Unsupported demo for Driller");
 }


Commit: 8a73bb978ec06135a61a95befd9b924adc61c7d8
    https://github.com/scummvm/scummvm/commit/8a73bb978ec06135a61a95befd9b924adc61c7d8
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:22+01:00

Commit Message:
FREESCAPE: avoid crashing if fonts are not loaded

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/driller.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 751eafe7ae4..dddf9774c35 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -58,6 +58,7 @@ FreescapeEngine::FreescapeEngine(OSystem *syst, const ADGameDescription *gd)
 	_playerHeightNumber = 1;
 	_borderTexture = nullptr;
 	_uiTexture = nullptr;
+	_fontLoaded = false;
 
 	_fullscreenViewArea = Common::Rect(0, 0, _screenW, _screenH);
 	_viewArea = _fullscreenViewArea;
@@ -349,6 +350,8 @@ bool FreescapeEngine::hasFeature(EngineFeature f) const {
 }
 
 void FreescapeEngine::drawStringInSurface(const Common::String &str, int x, int y, uint32 fontColor, uint32 backColor, Graphics::Surface *surface) {
+	if (!_fontLoaded)
+		return;
 	Common::String ustr = str;
 	ustr.toUppercase();
 	for (uint32 c = 0; c < ustr.size(); c++) {
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 951e8f49bf4..1459cfaa595 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -230,6 +230,7 @@ public:
 	Common::StringArray _currentAreaMessages;
 	Common::StringArray _currentEphymeralMessages;
 	Common::BitArray _font;
+	bool _fontLoaded;
 	void drawStringInSurface(const Common::String &str, int x, int y, uint32 fontColor, uint32 backColor, Graphics::Surface *surface);
 
 
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 0bd083b610f..61cf1520175 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -156,6 +156,7 @@ void DrillerEngine::loadAssetsFullGame() {
 		if (file == nullptr)
 			error("Failed to open 'driller' executable for Amiga");
 
+		loadMessagesFixedSize(file, 0xc66e, 14, 20);
 		loadGlobalObjects(file, 0xbd62);
 		// Font data: 0x8940
 		//file->seek(0x29efe);
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 85d72d4b5f0..d33b3bb376c 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -524,6 +524,7 @@ void FreescapeEngine::loadFonts(Common::SeekableReadStream *file, int offset) {
 
 	_font.set_size(48 * charNumber);
 	_font.set_bits((byte *)font);
+	_fontLoaded = true;
 }
 
 void FreescapeEngine::loadMessagesFixedSize(Common::SeekableReadStream *file, int offset, int size, int number) {


Commit: e46b050972d8b1fad4026b0d30e75477a1ed1864
    https://github.com/scummvm/scummvm/commit/e46b050972d8b1fad4026b0d30e75477a1ed1864
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:22+01:00

Commit Message:
FREESCAPE: allow the TinyGL to render in different resolutions

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/games/driller.cpp
    engines/freescape/gfx.cpp
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/gfx_tinygl.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index dddf9774c35..ee510e56b15 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -34,13 +34,21 @@ namespace Freescape {
 FreescapeEngine *g_freescape = NULL;
 
 FreescapeEngine::FreescapeEngine(OSystem *syst, const ADGameDescription *gd)
-	: Engine(syst), _gameDescription(gd), _screenW(320), _screenH(200), _border(nullptr), _gfx(nullptr) {
+	: Engine(syst), _gameDescription(gd), _border(nullptr), _gfx(nullptr) {
 	g_freescape = this;
 	if (!ConfMan.hasKey("render_mode") || ConfMan.get("render_mode").empty())
 		_renderMode = "ega";
 	else
 		_renderMode = ConfMan.get("render_mode");
 
+	if (isAmiga()) {
+		_screenW = 640;
+		_screenH = 480;
+	} else {
+		_screenW = 320;
+		_screenH = 200;
+	}
+
 	if (!Common::parseBool(ConfMan.get("prerecorded_sounds"), _usePrerecordedSounds))
 		error("Failed to parse bool from prerecorded_sounds option");
 
@@ -237,7 +245,7 @@ void FreescapeEngine::shoot() {
 
 Common::Error FreescapeEngine::run() {
 	// Initialize graphics
-	_gfx = createRenderer(_system);
+	_gfx = createRenderer(_system, _screenW, _screenH);
 	_gfx->init();
 	_gfx->clear();
 
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 61cf1520175..a800bf7105b 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -29,7 +29,8 @@
 namespace Freescape {
 
 DrillerEngine::DrillerEngine(OSystem *syst, const ADGameDescription *gd) : FreescapeEngine(syst, gd) {
-	_viewArea = Common::Rect(40, 16, 279, 116);
+	if (!isAmiga())
+		_viewArea = Common::Rect(40, 16, 279, 116);
 	_playerHeightNumber = 1;
 	_playerHeights.push_back(16);
 	_playerHeights.push_back(48);
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index 4b29d7370bc..2d535db03dd 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -33,9 +33,11 @@
 
 namespace Freescape {
 
-Renderer::Renderer(OSystem *system)
+Renderer::Renderer(OSystem *system, int screenW, int screenH)
 		: _system(system) {
 
+	_screenW = screenW;
+	_screenH = screenH;
 	_currentPixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
 	_originalPixelFormat = Graphics::PixelFormat::createFormatCLUT8();
 	_palettePixelFormat = Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0);
@@ -48,7 +50,7 @@ Renderer::~Renderer() {}
 
 Graphics::Surface *Renderer::convertFromPalette(Graphics::PixelBuffer *rawsurf) {
 	Graphics::Surface * surf = new Graphics::Surface();
-	surf->create(kOriginalWidth, kOriginalHeight, _originalPixelFormat);
+	surf->create(_screenW, _screenH, _originalPixelFormat);
 	surf->copyRectToSurface(rawsurf->getRawBuffer(), surf->w, 0, 0, surf->w, surf->h);
 	surf->convertToInPlace(_currentPixelFormat, _palette->getRawBuffer());
 	return surf;
@@ -95,10 +97,10 @@ Common::Rect Renderer::viewport() const {
 void Renderer::computeScreenViewport() {
 	int32 screenWidth = _system->getWidth();
 	int32 screenHeight = _system->getHeight();
-	_screenViewport = Common::Rect(screenWidth, screenHeight);
+	_screenViewport = Common::Rect(_screenW, _screenH);
 }
 
-Renderer *createRenderer(OSystem *system) {
+Renderer *createRenderer(OSystem *system, int screenW, int screenH) {
 	Common::String rendererConfig = ConfMan.get("renderer");
 	Graphics::PixelFormat pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
 	Graphics::RendererType desiredRendererType = Graphics::kRendererTypeTinyGL; //Graphics::parseRendererTypeCode(rendererConfig);
@@ -106,13 +108,10 @@ Renderer *createRenderer(OSystem *system) {
 
 	bool isAccelerated = 0; //matchingRendererType != Graphics::kRendererTypeTinyGL;
 
-	uint width = Renderer::kOriginalWidth;
-	uint height = Renderer::kOriginalHeight;
-
 	if (isAccelerated) {
-		initGraphics3d(width, height);
+		initGraphics3d(screenW, screenH);
 	} else {
-		initGraphics(width, height, &pixelFormat);
+		initGraphics(screenW, screenH, &pixelFormat);
 	}
 
 /*#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS) || defined(USE_GLES2)
@@ -142,7 +141,7 @@ Renderer *createRenderer(OSystem *system) {
 	}
 #endif*/
 	if (matchingRendererType == Graphics::kRendererTypeTinyGL) {
-		return CreateGfxTinyGL(system);
+		return CreateGfxTinyGL(system, screenW, screenH);
 	}
 
 	error("Unable to create a '%s' renderer", rendererConfig.c_str());
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 7727e61f1e8..1b80ee00417 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -53,7 +53,7 @@ public:
 
 class Renderer {
 public:
-	Renderer(OSystem *system);
+	Renderer(OSystem *system, int screenW, int screenH);
 	virtual ~Renderer();
 
 	Graphics::PixelFormat _currentPixelFormat;
@@ -121,9 +121,8 @@ public:
 
 	void flipVertical(Graphics::Surface *s);
 
-	static const int kOriginalWidth = 320;
-	static const int kOriginalHeight = 200;
-	static const int kFrameHeight = 200;
+	int _screenW;
+	int _screenH;
 
 	void computeScreenViewport();
 
@@ -164,8 +163,8 @@ private:
 
 Renderer *CreateGfxOpenGL(OSystem *system);
 Renderer *CreateGfxOpenGLShader(OSystem *system);
-Renderer *CreateGfxTinyGL(OSystem *system);
-Renderer *createRenderer(OSystem *system);
+Renderer *CreateGfxTinyGL(OSystem *system, int screenW, int screenH);
+Renderer *createRenderer(OSystem *system, int screenW, int screenH);
 
 } // End of namespace Freescape
 
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 043e26bb607..4c9cd63382b 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -32,11 +32,11 @@
 
 namespace Freescape {
 
-Renderer *CreateGfxTinyGL(OSystem *system) {
-	return new TinyGLRenderer(system);
+Renderer *CreateGfxTinyGL(OSystem *system, int screenW, int screenH) {
+	return new TinyGLRenderer(system, screenW, screenH);
 }
 
-TinyGLRenderer::TinyGLRenderer(OSystem *system) : Renderer(system) {
+TinyGLRenderer::TinyGLRenderer(OSystem *system, int screenW, int screenH) : Renderer(system, screenW, screenH) {
 }
 
 TinyGLRenderer::~TinyGLRenderer() {
@@ -57,7 +57,7 @@ void TinyGLRenderer::init() {
 
 	computeScreenViewport();
 
-	TinyGL::createContext(kOriginalWidth, kOriginalHeight, g_system->getScreenFormat(), 512, true, ConfMan.getBool("dirtyrects"));
+	TinyGL::createContext(_screenW, _screenH, g_system->getScreenFormat(), 512, true, ConfMan.getBool("dirtyrects"));
 
 	tglMatrixMode(TGL_PROJECTION);
 	tglLoadIdentity();
@@ -98,7 +98,7 @@ void TinyGLRenderer::updateProjectionMatrix(float fov, float nearClipPlane, floa
 	tglMatrixMode(TGL_PROJECTION);
 	tglLoadIdentity();
 
-	float aspectRatio = kOriginalWidth / (float) kFrameHeight;
+	float aspectRatio = _screenW / (float) _screenH;
 
 	float xmaxValue = nearClipPlane * tan(Common::deg2rad(fov) / 2);
 	float ymaxValue = xmaxValue / aspectRatio;
@@ -142,7 +142,7 @@ void TinyGLRenderer::renderCrossair(byte color) {
 
 	tglMatrixMode(TGL_PROJECTION);
 	tglLoadIdentity();
-	tglOrtho(0, kOriginalWidth, kOriginalHeight, 0, 0, 1);
+	tglOrtho(0, _screenW, _screenH, 0, 0, 1);
 	tglMatrixMode(TGL_MODELVIEW);
 	tglLoadIdentity();
 
@@ -152,11 +152,11 @@ void TinyGLRenderer::renderCrossair(byte color) {
 	tglColor3ub(r, g, b);
 
 	tglBegin(TGL_LINES);
-	tglVertex2f(kOriginalWidth / 2 - 1, kOriginalHeight / 2);
-	tglVertex2f(kOriginalWidth / 2 + 3, kOriginalHeight / 2);
+	tglVertex2f(_screenW / 2 - 1, _screenH / 2);
+	tglVertex2f(_screenW / 2 + 3, _screenH / 2);
 
-	tglVertex2f(kOriginalWidth / 2, kOriginalHeight / 2 - 3);
-	tglVertex2f(kOriginalWidth / 2, kOriginalHeight / 2 + 3);
+	tglVertex2f(_screenW / 2, _screenH / 2 - 3);
+	tglVertex2f(_screenW / 2, _screenH / 2 + 3);
 	tglEnd();
 
 	tglDepthMask(TGL_TRUE);
@@ -169,7 +169,7 @@ void TinyGLRenderer::renderShoot(byte color) {
 
 	tglMatrixMode(TGL_PROJECTION);
 	tglLoadIdentity();
-	tglOrtho(0, kOriginalWidth, kOriginalHeight, 0, 0, 1);
+	tglOrtho(0, _screenW, _screenH, 0, 0, 1);
 	tglMatrixMode(TGL_MODELVIEW);
 	tglLoadIdentity();
 
@@ -182,17 +182,17 @@ void TinyGLRenderer::renderShoot(byte color) {
 	tglGetIntegerv(TGL_VIEWPORT, viewPort);
 
 	tglBegin(TGL_LINES);
-	tglVertex2f(0, kOriginalHeight - 2);
-	tglVertex2f(kOriginalWidth / 2, kOriginalHeight / 2);
+	tglVertex2f(0, _screenH - 2);
+	tglVertex2f(_screenW / 2, _screenH / 2);
 
-	tglVertex2f(0, kOriginalHeight - 2);
-	tglVertex2f(kOriginalWidth / 2, kOriginalHeight / 2);
+	tglVertex2f(0, _screenH - 2);
+	tglVertex2f(_screenW / 2, _screenH / 2);
 
-	tglVertex2f(kOriginalWidth, kOriginalHeight - 2);
-	tglVertex2f(kOriginalWidth / 2, kOriginalHeight / 2);
+	tglVertex2f(_screenW, _screenH - 2);
+	tglVertex2f(_screenW / 2, _screenH / 2);
 
-	tglVertex2f(kOriginalWidth, kOriginalHeight);
-	tglVertex2f(kOriginalWidth / 2, kOriginalHeight / 2);
+	tglVertex2f(_screenW, _screenH);
+	tglVertex2f(_screenW / 2, _screenH / 2);
 
 	tglEnd();
 
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index 8cc2aa88f12..3db349a2bf4 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -31,7 +31,7 @@ namespace Freescape {
 
 class TinyGLRenderer : public Renderer {
 public:
-	TinyGLRenderer(OSystem *_system);
+	TinyGLRenderer(OSystem *system, int screenW, int screenH);
 	virtual ~TinyGLRenderer();
 
 	virtual void init() override;


Commit: b78ad84775eb57d8c427bbf24664ae917f153f7c
    https://github.com/scummvm/scummvm/commit/b78ad84775eb57d8c427bbf24664ae917f153f7c
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:22+01:00

Commit Message:
FREESCAPE: adding preliminary border for amiga release of driller

Changed paths:
    dists/engine-data/freescape.dat
    engines/freescape/freescape.cpp
    engines/freescape/games/driller.cpp
    engines/freescape/games/palettes.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/dists/engine-data/freescape.dat b/dists/engine-data/freescape.dat
index 1d571c56ec4..6b1d5b0f85a 100644
Binary files a/dists/engine-data/freescape.dat and b/dists/engine-data/freescape.dat differ
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index ee510e56b15..b24ac3935b5 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -44,6 +44,7 @@ FreescapeEngine::FreescapeEngine(OSystem *syst, const ADGameDescription *gd)
 	if (isAmiga()) {
 		_screenW = 640;
 		_screenH = 480;
+		_renderMode = "amiga";
 	} else {
 		_screenW = 320;
 		_screenH = 200;
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index a800bf7105b..df6fac67d09 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -29,7 +29,9 @@
 namespace Freescape {
 
 DrillerEngine::DrillerEngine(OSystem *syst, const ADGameDescription *gd) : FreescapeEngine(syst, gd) {
-	if (!isAmiga())
+	if (isAmiga())
+		_viewArea = Common::Rect(72, 66, 567, 269);
+	else
 		_viewArea = Common::Rect(40, 16, 279, 116);
 	_playerHeightNumber = 1;
 	_playerHeights.push_back(16);
diff --git a/engines/freescape/games/palettes.cpp b/engines/freescape/games/palettes.cpp
index 566ff4641f9..801af9cb98a 100644
--- a/engines/freescape/games/palettes.cpp
+++ b/engines/freescape/games/palettes.cpp
@@ -56,6 +56,10 @@ void FreescapeEngine::loadColorPalette() {
 		palette = new Graphics::PixelBuffer(_gfx->_palettePixelFormat, (byte*)&dos_EGA_palette);
 	else if (_renderMode == "cga")
 		palette = new Graphics::PixelBuffer(_gfx->_palettePixelFormat, (byte*)&dos_CGA_palette);
+	else if (_renderMode == "amiga")
+		palette = new Graphics::PixelBuffer(_gfx->_palettePixelFormat, (byte*)&dos_EGA_palette);
+	else
+		error("Invalid render mode, no palette selected");
 
 	_gfx->_palette = palette;
 	_gfx->_colorMap = &_colorMap;
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index d33b3bb376c..a39ba475d83 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -505,7 +505,11 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 
 void FreescapeEngine::loadBorder() {
 	Image::BitmapDecoder decoder;
-	Common::String borderFilename = _targetName + "_" + _renderMode + ".bmp";
+	Common::String borderFilename;
+	if (isAmiga())
+		borderFilename = _targetName + ".bmp";
+	else
+		borderFilename = _targetName + "_" + _renderMode + ".bmp";
 
 	if (_dataBundle->hasFile(borderFilename)) {
 		Common::SeekableReadStream *borderFile = _dataBundle->createReadStreamForMember(borderFilename);


Commit: 761497b7c1d5691978925b278a940575ca7c07fe
    https://github.com/scummvm/scummvm/commit/761497b7c1d5691978925b278a940575ca7c07fe
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:22+01:00

Commit Message:
FREESCAPE: correctly parse the palettes from amiga release of driller

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/driller.cpp
    engines/freescape/games/palettes.cpp
    engines/freescape/gfx.cpp
    engines/freescape/gfx.h
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index b24ac3935b5..4318e49e711 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -247,6 +247,7 @@ void FreescapeEngine::shoot() {
 Common::Error FreescapeEngine::run() {
 	// Initialize graphics
 	_gfx = createRenderer(_system, _screenW, _screenH);
+	_gfx->_isAmiga = isAmiga();
 	_gfx->init();
 	_gfx->clear();
 
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 1459cfaa595..fca15d96a4b 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -106,6 +106,9 @@ public:
 	Common::Archive *_dataBundle;
 	void loadDataBundle();
 	void loadBorder();
+	void loadAmigaPalette(Common::SeekableReadStream *file, int offset);
+	void swapAmigaPalette(uint16 areaID);
+	Common::HashMap<uint16, byte*> _amigaPalette;
 	void loadColorPalette();
 
 	uint16 readField(Common::SeekableReadStream *file, int nbits);
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index df6fac67d09..6bb1988428d 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -99,6 +99,9 @@ void DrillerEngine::gotoArea(uint16 areaID, int entranceID) {
 		_gfx->_keyColor = 0;
 	else
 		_gfx->_keyColor = 255;
+
+	if (isAmiga())
+		swapAmigaPalette(areaID);
 }
 
 void DrillerEngine::loadGlobalObjects(Common::SeekableReadStream *file, int offset) {
@@ -169,6 +172,7 @@ void DrillerEngine::loadAssetsFullGame() {
 		load8bitArea(file, 16);*/
 
 		load8bitBinary(file, 0x29c16, 16);
+		loadAmigaPalette(file, 0x297d4);
 	} else if (_renderMode == "ega") {
 		file = gameDir.createReadStreamForMember("DRILLE.EXE");
 
diff --git a/engines/freescape/games/palettes.cpp b/engines/freescape/games/palettes.cpp
index 801af9cb98a..65af556fee3 100644
--- a/engines/freescape/games/palettes.cpp
+++ b/engines/freescape/games/palettes.cpp
@@ -57,7 +57,7 @@ void FreescapeEngine::loadColorPalette() {
 	else if (_renderMode == "cga")
 		palette = new Graphics::PixelBuffer(_gfx->_palettePixelFormat, (byte*)&dos_CGA_palette);
 	else if (_renderMode == "amiga")
-		palette = new Graphics::PixelBuffer(_gfx->_palettePixelFormat, (byte*)&dos_EGA_palette);
+		palette = nullptr; // palette depends on the area
 	else
 		error("Invalid render mode, no palette selected");
 
@@ -65,4 +65,37 @@ void FreescapeEngine::loadColorPalette() {
 	_gfx->_colorMap = &_colorMap;
 }
 
+void FreescapeEngine::loadAmigaPalette(Common::SeekableReadStream *file, int offset) {
+	file->seek(offset);
+	int r, g, b;
+	for (int i = 0; i < int(_areaMap.size()); i++) {
+		int label = readField(file, 8);
+		auto palette = new byte[16][3];
+		debug("Label: %d", label);
+		for (int c = 0; c < 16; c++) {
+			int v = file->readUint16BE();
+			r = (v & 0xf00) >> 8;
+			r = r << 4 | r;
+			palette[c][0] = byte(r);
+			g = (v & 0xf0) >> 4;
+			g = g << 4 | g;
+			palette[c][1] = byte(g);
+			b = v & 0xf;
+			b = b << 4 | b;
+			palette[c][2] = byte(b);
+		}
+
+		assert(!_amigaPalette.contains(label));
+		_amigaPalette[label] = (byte*) palette;
+	}
+}
+
+void FreescapeEngine::swapAmigaPalette(uint16 levelID) {
+	if (_gfx->_palette)
+		delete _gfx->_palette;
+
+	_gfx->_palette = new Graphics::PixelBuffer(_gfx->_palettePixelFormat, _amigaPalette[levelID]);
+}
+
+
 } // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index 2d535db03dd..8380adce77e 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -44,6 +44,7 @@ Renderer::Renderer(OSystem *system, int screenW, int screenH)
 	_keyColor = -1;
 	_palette = nullptr;
 	_colorMap = nullptr;
+	_isAmiga = false;
 }
 
 Renderer::~Renderer() {}
@@ -66,6 +67,11 @@ bool Renderer::getRGBAt(uint8 index, uint8 &r, uint8 &g, uint8 &b) {
 		return true;
 	}
 
+	if (_isAmiga) {
+		_palette->getRGBAt(index, r, g, b);
+		return true;
+	}
+
 	//assert(index-1 < _colorMap->size());
 	byte *entry = (*_colorMap)[index-1];
 	uint8 color = 0;
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 1b80ee00417..5068fc0c78e 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -123,6 +123,7 @@ public:
 
 	int _screenW;
 	int _screenH;
+	bool _isAmiga;
 
 	void computeScreenViewport();
 
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index a39ba475d83..4dc8b17e7a5 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -278,8 +278,8 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	if (skyColor == 0)
 		skyColor = 255;
 
-	ci1 = readField(file, 8) & 15;
-	ci2 = readField(file, 8) & 15;
+	ci1 = readField(file, 8);
+	ci2 = readField(file, 8);
 	ci3 = readField(file, 8);
 	ci4 = readField(file, 8);
 	debugC(1, kFreescapeDebugParser, "Colors: %d %d %d %d %d %d", ci1, ci2, ci3, ci4, skyColor, groundColor);
@@ -405,27 +405,27 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	debugC(1, kFreescapeDebugParser, "Entrace area: %d", startEntrance);
 
 	if (isAmiga())
-		file->seek(offset + 0x16);
+		file->seek(offset + 0x14);
 	else
 		file->seek(offset + 0xa);
 
 	debugC(1, kFreescapeDebugParser, "Color map:");
 	uint8 data;
 	for (int i = 0; i < 15; i++) {
-		byte *entry = (byte*) malloc(4 * sizeof(byte));;
-		data = file->readByte();
+		byte *entry = (byte*) malloc(4 * sizeof(byte));
+		data = readField(file, 8);
 		*entry = data;
 		entry++;
 		debugC(1, kFreescapeDebugParser, "%x", data);
-		data = file->readByte();
+		data = readField(file, 8);
 		*entry = data;
 		entry++;
 		debugC(1, kFreescapeDebugParser, "%x", data);
-		data = file->readByte();
+		data = readField(file, 8);
 		*entry = data;
 		entry++;
 		debugC(1, kFreescapeDebugParser, "%x", data);
-		data = file->readByte();
+		data = readField(file, 8);
 		*entry = data;
 		debugC(1, kFreescapeDebugParser, "%x", data);
 		debugC(1, kFreescapeDebugParser, "---");


Commit: b90b7f7b53bbfbd8340eaa7a811d5a519bcca240
    https://github.com/scummvm/scummvm/commit/b90b7f7b53bbfbd8340eaa7a811d5a519bcca240
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:22+01:00

Commit Message:
FREESCAPE: correctly parse the palettes and border from amiga demo of driller

Changed paths:
    engines/freescape/games/driller.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 6bb1988428d..9736b189e9b 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -145,6 +145,7 @@ void DrillerEngine::loadAssetsDemo() {
 		load8bitArea(file, 16);*/
 
 		load8bitBinary(file, 0x442, 16);
+		loadAmigaPalette(file, 0x0);
 	} else
 		error("Unsupported demo for Driller");
 }
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 4dc8b17e7a5..cec8537fbf9 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -511,6 +511,7 @@ void FreescapeEngine::loadBorder() {
 	else
 		borderFilename = _targetName + "_" + _renderMode + ".bmp";
 
+	Common::replace(borderFilename, "-demo", "");
 	if (_dataBundle->hasFile(borderFilename)) {
 		Common::SeekableReadStream *borderFile = _dataBundle->createReadStreamForMember(borderFilename);
 		decoder.loadStream(*borderFile);


Commit: c40875f97415b27584048680c869e25e79465ae6
    https://github.com/scummvm/scummvm/commit/c40875f97415b27584048680c869e25e79465ae6
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:23+01:00

Commit Message:
FREESCAPE: correctly parse another amiga release from driller

Changed paths:
    engines/freescape/detection.cpp
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/driller.cpp
    engines/freescape/games/palettes.cpp


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index fd7c4fec751..655f53818fe 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -105,7 +105,7 @@ static const ADGameDescription gameDescriptions[] = {
 	 ADGF_NO_FLAGS,
 	 GUIO3(GUIO_NOMIDI, GUIO_RENDEREGA, GUIO_RENDERCGA)},
 	{"driller",
-	 "Driller",
+	 "Retail",
 	 {
 		{"driller", 0, "13dab2e10d8e8b9a364c94a660e0d42a", 282384},
 		{"title.seq", 0, "4dd1b3b45110b24e8240a6132241c973", 185296},
@@ -115,6 +115,17 @@ static const ADGameDescription gameDescriptions[] = {
 	 Common::kPlatformAmiga,
 	 ADGF_NO_FLAGS,
 	 GUIO1(GUIO_NOMIDI)},
+	{"driller",
+	 "Kixx",
+	 {
+		{"driller", 0, "db1afe151d999f369ae9153d8eeaf254", 175236},
+		{"soundfx", 0, "cd91061a1330aef8fcd6b7dc6fa35cf9", 78680},
+		AD_LISTEND
+	 },
+	 Common::EN_ANY,
+	 Common::kPlatformAmiga,
+	 ADGF_NO_FLAGS,
+	 GUIO1(GUIO_NOMIDI)},
 	{"driller",
 	 "Rolling Demo",
 	 {
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 4318e49e711..fe15aac2344 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -50,6 +50,11 @@ FreescapeEngine::FreescapeEngine(OSystem *syst, const ADGameDescription *gd)
 		_screenH = 200;
 	}
 
+	if (gd->extra)
+		_variant = gd->extra;
+	else
+		_variant = "FullGame";
+
 	if (!Common::parseBool(ConfMan.get("prerecorded_sounds"), _usePrerecordedSounds))
 		error("Failed to parse bool from prerecorded_sounds option");
 
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index fca15d96a4b..463d916b731 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -82,11 +82,12 @@ public:
 	bool isDemo() const;
 
 	// Game selection
+	Common::String _variant;
 	bool isDriller() { return _targetName.hasPrefix("driller") || _targetName.hasPrefix("spacestationoblivion"); }
 	bool isDark() { return _targetName.hasPrefix("darkside"); }
 	bool isEclipse() { return _targetName.hasPrefix("totaleclipse"); }
 	bool isCastle() { return _targetName.hasPrefix("castle"); }
-	bool isAmiga() { return _targetName.hasSuffix("-amiga"); }
+	bool isAmiga() { return _targetName.hasSuffix("-amiga") || Common::matchString(_targetName.c_str() ,"*-amiga-#"); }
 
 	Common::Error run() override;
 
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 9736b189e9b..bef11d4666b 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -159,21 +159,18 @@ void DrillerEngine::loadAssetsFullGame() {
 	Common::File exe;
 	if (isAmiga()) {
 		file = gameDir.createReadStreamForMember("driller");
-
 		if (file == nullptr)
 			error("Failed to open 'driller' executable for Amiga");
 
-		loadMessagesFixedSize(file, 0xc66e, 14, 20);
-		loadGlobalObjects(file, 0xbd62);
-		// Font data: 0x8940
-		//file->seek(0x29efe);
-		//load8bitArea(file, 16);
-		//assert(0);
-		/*file->seek(0x2a450);
-		load8bitArea(file, 16);*/
-
-		load8bitBinary(file, 0x29c16, 16);
-		loadAmigaPalette(file, 0x297d4);
+		if (_variant == "Retail") {
+			loadMessagesFixedSize(file, 0xc66e, 14, 20);
+			loadGlobalObjects(file, 0xbd62);
+			load8bitBinary(file, 0x29c16, 16);
+			loadAmigaPalette(file, 0x297d4);
+		} else if (_variant == "Kixx") {
+			load8bitBinary(file, 0x21a3e, 16);
+			loadAmigaPalette(file, 0x215fc);
+		}
 	} else if (_renderMode == "ega") {
 		file = gameDir.createReadStreamForMember("DRILLE.EXE");
 
diff --git a/engines/freescape/games/palettes.cpp b/engines/freescape/games/palettes.cpp
index 65af556fee3..a11cd5e544b 100644
--- a/engines/freescape/games/palettes.cpp
+++ b/engines/freescape/games/palettes.cpp
@@ -71,7 +71,7 @@ void FreescapeEngine::loadAmigaPalette(Common::SeekableReadStream *file, int off
 	for (int i = 0; i < int(_areaMap.size()); i++) {
 		int label = readField(file, 8);
 		auto palette = new byte[16][3];
-		debug("Label: %d", label);
+		debug("Loading palette for area: %d", label);
 		for (int c = 0; c < 16; c++) {
 			int v = file->readUint16BE();
 			r = (v & 0xf00) >> 8;


Commit: 814bec5fe58ec1c7234d5164b9e059073ec2fcb3
    https://github.com/scummvm/scummvm/commit/814bec5fe58ec1c7234d5164b9e059073ec2fcb3
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:23+01:00

Commit Message:
FREESCAPE: initial support for reading and playing driller sounds from amiga releases

Changed paths:
    engines/freescape/freescape.h
    engines/freescape/games/driller.cpp
    engines/freescape/sound.cpp


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 463d916b731..efc2c8aec71 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -212,6 +212,11 @@ public:
 	void playSoundSweepIncWL(double hzFreq1, double hzFreq2, double wlStepPerMS, int resolution, bool sync);
 	void playTeleporter(int totalIters, bool sync);
 
+	void playPaulaSound(int index, bool sync);
+	void loadAmigaSounds(Common::SeekableReadStream *file, int offset, int number);
+	Common::HashMap<uint16, byte*> _amigaSoundsBuffer;
+	Common::HashMap<uint16, int> _amigaSoundsSize;
+
 	// Rendering
 	int _screenW, _screenH;
 	Renderer *_gfx;
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index bef11d4666b..6b368daa1f0 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -167,9 +167,13 @@ void DrillerEngine::loadAssetsFullGame() {
 			loadGlobalObjects(file, 0xbd62);
 			load8bitBinary(file, 0x29c16, 16);
 			loadAmigaPalette(file, 0x297d4);
+			loadAmigaSounds(file, 0x30e80, 25);
 		} else if (_variant == "Kixx") {
 			load8bitBinary(file, 0x21a3e, 16);
 			loadAmigaPalette(file, 0x215fc);
+
+			file = gameDir.createReadStreamForMember("soundfx");
+			loadAmigaSounds(file, 0, 25);
 		}
 	} else if (_renderMode == "ega") {
 		file = gameDir.createReadStreamForMember("DRILLE.EXE");
diff --git a/engines/freescape/sound.cpp b/engines/freescape/sound.cpp
index 5725aec93a3..bb0c335c982 100644
--- a/engines/freescape/sound.cpp
+++ b/engines/freescape/sound.cpp
@@ -20,6 +20,7 @@
  */
 
 #include "freescape/freescape.h"
+#include "audio/mods/paula.h"
 
 namespace Freescape {
 
@@ -32,6 +33,11 @@ void FreescapeEngine::playSound(int index, bool sync) {
 	//	_mixer->stopHandle(_handle);
 
 	debugC(1, kFreescapeDebugMedia, "Playing sound %d with sync: %d", index, sync);
+	if (isAmiga()) {
+		playPaulaSound(index, sync);
+		return;
+	}
+
 	switch (index) {
 		case 1:
 			if (_usePrerecordedSounds) {
@@ -316,4 +322,36 @@ void FreescapeEngine::playTeleporter(int totalIters, bool sync) {
 	}
 }
 
+class AudioPaula : public Audio::Paula {
+	void interrupt() override;
+};
+
+void AudioPaula::interrupt() {}
+
+void FreescapeEngine::playPaulaSound(int index, bool sync) {
+	AudioPaula *paula = new AudioPaula();
+	paula->setInterruptFreq(0x168);
+	paula->readBuffer((int16*)_amigaSoundsBuffer[index], _amigaSoundsSize[index] / 2);
+	paula->startPlay();
+	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_handle, paula);
+	if (sync) {
+		//_system->delayMillis(duration);
+	}
+}
+
+void FreescapeEngine::loadAmigaSounds(Common::SeekableReadStream *file, int offset, int number) {
+	file->seek(offset);
+	for (int i = 1; i < number+1; i++) {
+		int size = file->readUint16BE();
+		assert(size == 0);
+		size = file->readUint16BE();
+		debug("Loading sound: %d (size: %d)", i, size);
+		size = size + 2;
+		byte *palette = (byte*) malloc(size * sizeof(byte));
+		file->read(palette, size);
+		_amigaSoundsBuffer[i] = (byte*) palette;
+		_amigaSoundsSize[i] = size;
+	}
+}
+
 }
\ No newline at end of file


Commit: d5730209f8fddc616aaa5043afe44072730a2979
    https://github.com/scummvm/scummvm/commit/d5730209f8fddc616aaa5043afe44072730a2979
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:23+01:00

Commit Message:
FREESCAPE: initial support for driller demo from atari release

Changed paths:
    engines/freescape/detection.cpp
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/driller.cpp
    engines/freescape/games/palettes.cpp
    engines/freescape/gfx.cpp
    engines/freescape/gfx.h
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index 655f53818fe..a2f7cb0c44f 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -138,6 +138,22 @@ static const ADGameDescription gameDescriptions[] = {
 	 Common::kPlatformAmiga,
 	 ADGF_NO_FLAGS | ADGF_DEMO,
 	 GUIO1(GUIO_NOMIDI)},
+
+	{"driller",
+	 "Rolling Demo",
+	 {
+		{"x.prg", 0, "cf96e25a11bee1b57258c2fc0b315699", 157143},
+		{"data", 0, "0b056286d2d91f302499c97aca235462", 24220},
+		{"demo.cmd", 0, "7b90427c5c3c4bbb42d14076af994d50", 4096},
+		AD_LISTEND
+	 },
+	 Common::EN_ANY,
+	 Common::kPlatformAtariST,
+	 ADGF_NO_FLAGS | ADGF_DEMO,
+	 GUIO1(GUIO_NOMIDI)},
+
+
+
 	{"darkside",
 	 "Dark Side",
 	 {
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index fe15aac2344..fdfce0f6c00 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -41,13 +41,15 @@ FreescapeEngine::FreescapeEngine(OSystem *syst, const ADGameDescription *gd)
 	else
 		_renderMode = ConfMan.get("render_mode");
 
+	_screenW = 320;
+	_screenH = 200;
+
 	if (isAmiga()) {
 		_screenW = 640;
 		_screenH = 480;
 		_renderMode = "amiga";
-	} else {
-		_screenW = 320;
-		_screenH = 200;
+	} else if (isAtariST()) {
+		_renderMode = "atari";
 	}
 
 	if (gd->extra)
@@ -253,6 +255,7 @@ Common::Error FreescapeEngine::run() {
 	// Initialize graphics
 	_gfx = createRenderer(_system, _screenW, _screenH);
 	_gfx->_isAmiga = isAmiga();
+	_gfx->_isAtariST = isAtariST();
 	_gfx->init();
 	_gfx->clear();
 
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index efc2c8aec71..3e966231532 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -88,6 +88,7 @@ public:
 	bool isEclipse() { return _targetName.hasPrefix("totaleclipse"); }
 	bool isCastle() { return _targetName.hasPrefix("castle"); }
 	bool isAmiga() { return _targetName.hasSuffix("-amiga") || Common::matchString(_targetName.c_str() ,"*-amiga-#"); }
+	bool isAtariST() { return _targetName.hasSuffix("-st") || Common::matchString(_targetName.c_str() ,"*-st-#"); }
 
 	Common::Error run() override;
 
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 6b368daa1f0..6f66619b64e 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -100,7 +100,7 @@ void DrillerEngine::gotoArea(uint16 areaID, int entranceID) {
 	else
 		_gfx->_keyColor = 255;
 
-	if (isAmiga())
+	if (isAmiga() || isAtariST())
 		swapAmigaPalette(areaID);
 }
 
@@ -146,7 +146,22 @@ void DrillerEngine::loadAssetsDemo() {
 
 		load8bitBinary(file, 0x442, 16);
 		loadAmigaPalette(file, 0x0);
-	} else
+	} else if (isAtariST()) {
+		file = gameDir.createReadStreamForMember("data");
+
+		if (file == nullptr)
+			error("Failed to open 'data' file");
+
+		//loadGlobalObjects(file, 0xbd62);
+		/*file->seek(0x29efe);
+		load8bitArea(file, 16);
+		file->seek(0x2a450);
+		load8bitArea(file, 16);*/
+
+		load8bitBinary(file, 0x442, 16);
+		loadAmigaPalette(file, 0x0);
+	}
+	else
 		error("Unsupported demo for Driller");
 }
 
diff --git a/engines/freescape/games/palettes.cpp b/engines/freescape/games/palettes.cpp
index a11cd5e544b..734ab9d3df0 100644
--- a/engines/freescape/games/palettes.cpp
+++ b/engines/freescape/games/palettes.cpp
@@ -56,7 +56,7 @@ void FreescapeEngine::loadColorPalette() {
 		palette = new Graphics::PixelBuffer(_gfx->_palettePixelFormat, (byte*)&dos_EGA_palette);
 	else if (_renderMode == "cga")
 		palette = new Graphics::PixelBuffer(_gfx->_palettePixelFormat, (byte*)&dos_CGA_palette);
-	else if (_renderMode == "amiga")
+	else if (_renderMode == "amiga" || _renderMode == "atari")
 		palette = nullptr; // palette depends on the area
 	else
 		error("Invalid render mode, no palette selected");
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index 8380adce77e..54aa3215674 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -45,6 +45,7 @@ Renderer::Renderer(OSystem *system, int screenW, int screenH)
 	_palette = nullptr;
 	_colorMap = nullptr;
 	_isAmiga = false;
+	_isAtariST = false;
 }
 
 Renderer::~Renderer() {}
@@ -67,7 +68,7 @@ bool Renderer::getRGBAt(uint8 index, uint8 &r, uint8 &g, uint8 &b) {
 		return true;
 	}
 
-	if (_isAmiga) {
+	if (_isAmiga || _isAtariST) {
 		_palette->getRGBAt(index, r, g, b);
 		return true;
 	}
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 5068fc0c78e..5551c5e3bb8 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -124,6 +124,7 @@ public:
 	int _screenW;
 	int _screenH;
 	bool _isAmiga;
+	bool _isAtariST;
 
 	void computeScreenViewport();
 
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index cec8537fbf9..5494dfd5103 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -33,7 +33,7 @@ namespace Freescape {
 uint16 FreescapeEngine::readField(Common::SeekableReadStream *file, int bits) {
 	uint16 value;
 	assert(bits == 8 || bits == 16);
-	if (isAmiga()) {
+	if (isAmiga() || isAtariST()) {
 		if (bits == 16) {
 			uint16 lo = file->readUint16BE();
 			assert(lo < 256);
@@ -404,7 +404,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	uint8 startEntrance = readField(file, 8);
 	debugC(1, kFreescapeDebugParser, "Entrace area: %d", startEntrance);
 
-	if (isAmiga())
+	if (isAmiga() || isAtariST())
 		file->seek(offset + 0x14);
 	else
 		file->seek(offset + 0xa);
@@ -432,7 +432,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 		_colorMap.push_back(entry - 3);
 	}
 
-	if (isAmiga())
+	if (isAmiga() || isAtariST())
 		file->seek(offset + 0x8a);
 	else
 		file->seek(offset + 0x46); // 0x46
@@ -448,7 +448,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	file->seek(offset + globalByteCodeTable);
 	uint8 numConditions = readField(file, 8);
 	debugC(1, kFreescapeDebugParser, "%d global conditions", numConditions);
-	while (!isAmiga() && numConditions--) { // TODO: read global conditions in Amiga
+	while (!isAmiga() && !isAtariST() && numConditions--) { // TODO: read global conditions in Amiga
 		FCLInstructionVector instructions;
 		// get the length
 		uint32 lengthOfCondition = readField(file, 8);
@@ -462,7 +462,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 		debugC(1, kFreescapeDebugParser, "%s", conditionSource->c_str());
 	}
 
-	if (isAmiga())
+	if (isAmiga() || isAtariST())
 		file->seek(offset + 0x190);
 	else
 		file->seek(offset + 0xc8);


Commit: 380fdb4a0c7032684ea0cd7288197139b5fc6047
    https://github.com/scummvm/scummvm/commit/380fdb4a0c7032684ea0cd7288197139b5fc6047
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:23+01:00

Commit Message:
FREESCAPE: atari sounds are unimplemented yet

Changed paths:
    engines/freescape/sound.cpp


diff --git a/engines/freescape/sound.cpp b/engines/freescape/sound.cpp
index bb0c335c982..fc75ff458c5 100644
--- a/engines/freescape/sound.cpp
+++ b/engines/freescape/sound.cpp
@@ -36,8 +36,12 @@ void FreescapeEngine::playSound(int index, bool sync) {
 	if (isAmiga()) {
 		playPaulaSound(index, sync);
 		return;
+	} else if (isAtariST()) {
+		// TODO
+		return;
 	}
 
+
 	switch (index) {
 		case 1:
 			if (_usePrerecordedSounds) {


Commit: 182f20dc3c5b17aa96719b7c4ea81a357eb06354
    https://github.com/scummvm/scummvm/commit/182f20dc3c5b17aa96719b7c4ea81a357eb06354
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:23+01:00

Commit Message:
FREESCAPE: correctly parse global conditions in amiga and atari

Changed paths:
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 5494dfd5103..167206d5bb2 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -433,9 +433,9 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	}
 
 	if (isAmiga() || isAtariST())
-		file->seek(offset + 0x8a);
+		file->seek(offset + 0x8c);
 	else
-		file->seek(offset + 0x46); // 0x46
+		file->seek(offset + 0x46);
 
 	uint16 globalSomething;
 	globalSomething = readField(file, 16);
@@ -446,9 +446,11 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	debugC(1, kFreescapeDebugParser, "GBCT: %x\n", globalByteCodeTable);
 
 	file->seek(offset + globalByteCodeTable);
+	debugC(1, kFreescapeDebugParser, "Position: %lx\n", file->pos());
+
 	uint8 numConditions = readField(file, 8);
 	debugC(1, kFreescapeDebugParser, "%d global conditions", numConditions);
-	while (!isAmiga() && !isAtariST() && numConditions--) { // TODO: read global conditions in Amiga
+	while (numConditions--) { // TODO: read global conditions in Amiga
 		FCLInstructionVector instructions;
 		// get the length
 		uint32 lengthOfCondition = readField(file, 8);


Commit: 81e93cff370406cf02a467aeec0f3f3479c9952b
    https://github.com/scummvm/scummvm/commit/81e93cff370406cf02a467aeec0f3f3479c9952b
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:23+01:00

Commit Message:
FREESCAPE: neo image loader to parse images in driller for amiga and atari

Changed paths:
  A engines/freescape/neo.cpp
  A engines/freescape/neo.h
    engines/freescape/freescape.cpp
    engines/freescape/games/driller.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/module.mk


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index fdfce0f6c00..1535f2b7bea 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -45,8 +45,8 @@ FreescapeEngine::FreescapeEngine(OSystem *syst, const ADGameDescription *gd)
 	_screenH = 200;
 
 	if (isAmiga()) {
-		_screenW = 640;
-		_screenH = 480;
+		//_screenW = 640;
+		//_screenH = 480;
 		_renderMode = "amiga";
 	} else if (isAtariST()) {
 		_renderMode = "atari";
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 6f66619b64e..cd489b595d3 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -25,14 +25,15 @@
 
 #include "freescape/freescape.h"
 #include "freescape/language/8bitDetokeniser.h"
+#include "freescape/neo.h"
 
 namespace Freescape {
 
 DrillerEngine::DrillerEngine(OSystem *syst, const ADGameDescription *gd) : FreescapeEngine(syst, gd) {
-	if (isAmiga())
-		_viewArea = Common::Rect(72, 66, 567, 269);
-	else
-		_viewArea = Common::Rect(40, 16, 279, 116);
+	//if (isAmiga())
+	//	_viewArea = Common::Rect(72, 66, 567, 269);
+	//else
+	_viewArea = Common::Rect(40, 16, 279, 116);
 	_playerHeightNumber = 1;
 	_playerHeights.push_back(16);
 	_playerHeights.push_back(48);
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 167206d5bb2..89c6fc38611 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -27,6 +27,7 @@
 #include "freescape/freescape.h"
 #include "freescape/language/8bitDetokeniser.h"
 #include "freescape/objects/sensor.h"
+#include "freescape/neo.h"
 
 namespace Freescape {
 
@@ -506,6 +507,17 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 }
 
 void FreescapeEngine::loadBorder() {
+	if (isAmiga() || isAtariST()) {
+		Image::NeoDecoder decoder;
+		Common::File borderFile;
+		borderFile.open("console.neo");
+		decoder.loadStream(borderFile);
+		_border = new Graphics::Surface();
+		_border->copyFrom(*decoder.getSurface());
+		_border->convertToInPlace(_gfx->_currentPixelFormat, decoder.getPalette());
+		return;
+	}
+
 	Image::BitmapDecoder decoder;
 	Common::String borderFilename;
 	if (isAmiga())
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index bc2da1c8082..f9df6ea1c84 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -22,6 +22,7 @@ MODULE_OBJS := \
 	language/16bitDetokeniser.o \
 	language/instruction.o \
 	movement.o \
+	neo.o \
 	sound.o
 
 
diff --git a/engines/freescape/neo.cpp b/engines/freescape/neo.cpp
new file mode 100644
index 00000000000..30671667437
--- /dev/null
+++ b/engines/freescape/neo.cpp
@@ -0,0 +1,116 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "neo.h"
+
+#include "common/stream.h"
+#include "common/textconsole.h"
+#include "graphics/pixelformat.h"
+#include "graphics/surface.h"
+
+/**
+ * Based on the PCX specs:
+ *
+ */
+
+namespace Image {
+
+NeoDecoder::NeoDecoder() {
+	_surface = 0;
+	_palette = 0;
+	_paletteColorCount = 0;
+}
+
+NeoDecoder::~NeoDecoder() {
+	destroy();
+}
+
+void NeoDecoder::destroy() {
+	if (_surface) {
+		_surface->free();
+		delete _surface;
+		_surface = 0;
+	}
+
+	delete[] _palette;
+	_palette = 0;
+	_paletteColorCount = 0;
+}
+
+bool NeoDecoder::loadStream(Common::SeekableReadStream &stream) {
+	destroy();
+
+	if (stream.readUint16LE() != 0x00)
+		return false;
+
+	if (stream.readUint16LE() != 0x00)
+		return false;
+
+	_palette = new byte[16 * 3];
+	for (int i = 0; i < 16; ++i) {
+		byte v1 = stream.readByte();
+		byte v2 = stream.readByte();
+
+		_palette[i * 3 + 0] = floor((v1 & 0x07) * 255.0 / 7.0);
+		_palette[i * 3 + 1] = floor((v2 & 0x70) * 255.0 / 7.0 / 16.0);
+		_palette[i * 3 + 2] = floor((v2 & 0x07) * 255.0 / 7.0);
+	}
+
+	stream.seek(128);
+
+	int width = 320;
+	int height = 200;
+	_surface = new Graphics::Surface();
+	_surface->create(width, height, Graphics::PixelFormat::createFormatCLUT8());
+	_paletteColorCount = 16;
+
+	// 200 rows of image:
+	for (int y = 0; y < 200; y++) {
+		// 20 column blocks:
+		for (int x = 0; x < 20; x++) {
+			// Fetch the 4 words that make up the
+			// next 16 pixels across 4 bitplanes:
+			uint16 uW0 = stream.readUint16BE();
+			uint16 uW1 = stream.readUint16BE();
+			uint16 uW2 = stream.readUint16BE();
+			uint16 uW3 = stream.readUint16BE();
+
+			// The first pixel is found in the highest bit:
+			uint32 uBit = 0x8000;
+
+			// 16 pixels to process:
+			for (int z = 0; z < 16; z++) {
+				// Work out the colour index:
+				int idx = 0;
+				if (uW0 & uBit) idx += 1;
+				if (uW1 & uBit) idx += 2;
+				if (uW2 & uBit) idx += 4;
+				if (uW3 & uBit) idx += 8;
+
+				_surface->setPixel(x*16 + z, y, idx);
+				uBit >>= 1;
+			}
+		}
+	}
+	return true;
+}
+
+} // End of namespace Image
diff --git a/engines/freescape/neo.h b/engines/freescape/neo.h
new file mode 100644
index 00000000000..27a81a6de0e
--- /dev/null
+++ b/engines/freescape/neo.h
@@ -0,0 +1,58 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef IMAGE_NEO_H
+#define IMAGE_NEO_H
+
+#include "common/scummsys.h"
+#include "common/str.h"
+#include "image/image_decoder.h"
+
+/*
+Atari-ST Neochrome decoder based on NEOLoad by Jason "Joefish" Railton
+*/
+
+namespace Common{
+class SeekableReadStream;
+}
+
+namespace Image {
+
+class NeoDecoder : public ImageDecoder {
+public:
+	NeoDecoder();
+	virtual ~NeoDecoder();
+
+	// ImageDecoder API
+	void destroy();
+	virtual bool loadStream(Common::SeekableReadStream &stream);
+	virtual const Graphics::Surface *getSurface() const { return _surface; }
+	const byte *getPalette() const { return _palette; }
+	uint16 getPaletteColorCount() const { return _paletteColorCount; }
+
+private:
+	Graphics::Surface *_surface;
+	byte *_palette;
+	uint16 _paletteColorCount;
+};
+} // End of namespace Image
+
+#endif
\ No newline at end of file


Commit: 6400b4d5b36a63d208e326fb2660108f29899d1f
    https://github.com/scummvm/scummvm/commit/6400b4d5b36a63d208e326fb2660108f29899d1f
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:24+01:00

Commit Message:
FREESCAPE: refactor code that load images for every game

Changed paths:
    dists/engine-data/freescape.dat
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/dark.cpp
    engines/freescape/games/driller.cpp
    engines/freescape/games/eclipse.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/neo.cpp


diff --git a/dists/engine-data/freescape.dat b/dists/engine-data/freescape.dat
index 6b1d5b0f85a..1d571c56ec4 100644
Binary files a/dists/engine-data/freescape.dat and b/dists/engine-data/freescape.dat differ
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 1535f2b7bea..80100c7dfbc 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -28,13 +28,14 @@
 
 #include "freescape/freescape.h"
 #include "freescape/language/8bitDetokeniser.h"
+#include "freescape/neo.h"
 
 namespace Freescape {
 
 FreescapeEngine *g_freescape = NULL;
 
 FreescapeEngine::FreescapeEngine(OSystem *syst, const ADGameDescription *gd)
-	: Engine(syst), _gameDescription(gd), _border(nullptr), _gfx(nullptr) {
+	: Engine(syst), _gameDescription(gd), _gfx(nullptr) {
 	g_freescape = this;
 	if (!ConfMan.hasKey("render_mode") || ConfMan.get("render_mode").empty())
 		_renderMode = "ega";
@@ -72,6 +73,9 @@ FreescapeEngine::FreescapeEngine(OSystem *syst, const ADGameDescription *gd)
 	_flyMode = false;
 	_noClipMode = false;
 	_playerHeightNumber = 1;
+
+	_border = nullptr;
+	_title = nullptr;
 	_borderTexture = nullptr;
 	_uiTexture = nullptr;
 	_fontLoaded = false;
@@ -261,7 +265,6 @@ Common::Error FreescapeEngine::run() {
 
 	// Load game data and init game state
 	loadDataBundle();
-	loadBorder();
 	loadAssets();
 	initGameState();
 	loadColorPalette();
@@ -464,4 +467,15 @@ void FreescapeEngine::loadDataBundle() {
 	}
 }
 
+Graphics::Surface *FreescapeEngine::loadAndConvertNeoImage(Common::SeekableReadStream *stream, int offset) {
+	stream->seek(offset);
+	Image::NeoDecoder decoder;
+	decoder.loadStream(*stream);
+	Graphics::Surface *surface = new Graphics::Surface();
+	surface->copyFrom(*decoder.getSurface());
+	surface->convertToInPlace(_gfx->_currentPixelFormat, decoder.getPalette());
+	return surface;
+}
+
+
 } // namespace Freescape
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 3e966231532..3ffe52c26c3 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -99,6 +99,8 @@ public:
 	void convertBorder();
 	void drawBorder();
 	virtual void drawUI();
+	Graphics::Surface *_border;
+	Graphics::Surface *_title;
 	Texture *_borderTexture;
 	Texture *_uiTexture;
 
@@ -107,7 +109,8 @@ public:
 	virtual void loadAssets();
 	Common::Archive *_dataBundle;
 	void loadDataBundle();
-	void loadBorder();
+	void loadBundledImages();
+	Graphics::Surface *loadAndConvertNeoImage(Common::SeekableReadStream *stream, int offset);
 	void loadAmigaPalette(Common::SeekableReadStream *file, int offset);
 	void swapAmigaPalette(uint16 areaID);
 	Common::HashMap<uint16, byte*> _amigaPalette;
@@ -229,7 +232,6 @@ public:
 	Math::Vector3d _scaleVector;
 	float _nearClipPlane;
 	float _farClipPlane;
-	Graphics::Surface *_border;
 
 	// Text messages and Fonts
 	Common::StringArray _messagesList;
diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index a4ca5bb11d9..2b9c41095b4 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -46,6 +46,7 @@ void DarkEngine::loadAssets() {
 
 	Common::File exe;
 	if (_renderMode == "ega") {
+		loadBundledImages();
 		file = gameDir.createReadStreamForMember("DSIDEE.EXE");
 
 		if (file == nullptr)
@@ -54,6 +55,7 @@ void DarkEngine::loadAssets() {
 		loadFonts(file, 0xa113);
 		load8bitBinary(file, 0xa280, 16);
 	} else if (_renderMode == "cga") {
+		loadBundledImages();
 		file = gameDir.createReadStreamForMember("DSIDEC.EXE");
 
 		if (file == nullptr)
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index cd489b595d3..9e5d470ed27 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -25,7 +25,6 @@
 
 #include "freescape/freescape.h"
 #include "freescape/language/8bitDetokeniser.h"
-#include "freescape/neo.h"
 
 namespace Freescape {
 
@@ -134,8 +133,19 @@ void DrillerEngine::loadAssetsDemo() {
 
 	Common::File exe;
 	if (isAmiga()) {
-		file = gameDir.createReadStreamForMember("data");
+		file = gameDir.createReadStreamForMember("lift.neo");
+		if (file == nullptr)
+			error("Failed to open 'lift.neo' file");
 
+		_title = loadAndConvertNeoImage(file, 0);
+
+		if (file == nullptr)
+			error("Failed to open 'console.neo' file");
+
+		file = gameDir.createReadStreamForMember("console.neo");
+		_border = loadAndConvertNeoImage(file, 0);
+
+		file = gameDir.createReadStreamForMember("data");
 		if (file == nullptr)
 			error("Failed to open 'data' file");
 
@@ -148,6 +158,18 @@ void DrillerEngine::loadAssetsDemo() {
 		load8bitBinary(file, 0x442, 16);
 		loadAmigaPalette(file, 0x0);
 	} else if (isAtariST()) {
+		file = gameDir.createReadStreamForMember("lift.neo");
+		if (file == nullptr)
+			error("Failed to open 'lift.neo' file");
+
+		_title = loadAndConvertNeoImage(file, 0);
+
+		if (file == nullptr)
+			error("Failed to open 'console.neo' file");
+
+		file = gameDir.createReadStreamForMember("console.neo");
+		_border = loadAndConvertNeoImage(file, 0);
+
 		file = gameDir.createReadStreamForMember("data");
 
 		if (file == nullptr)
@@ -192,6 +214,7 @@ void DrillerEngine::loadAssetsFullGame() {
 			loadAmigaSounds(file, 0, 25);
 		}
 	} else if (_renderMode == "ega") {
+		loadBundledImages();
 		file = gameDir.createReadStreamForMember("DRILLE.EXE");
 
 		if (file == nullptr)
@@ -202,6 +225,7 @@ void DrillerEngine::loadAssetsFullGame() {
 		loadGlobalObjects(file, 0x3b42);
 		load8bitBinary(file, 0x9b40, 16);
 	} else if (_renderMode == "cga") {
+		loadBundledImages();
 		file = gameDir.createReadStreamForMember("DRILLC.EXE");
 
 		if (file == nullptr)
diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index c969932ba63..2027bf6e366 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -108,6 +108,7 @@ void EclipseEngine::loadAssets() {
 
 	Common::File exe;
 	if (_renderMode == "ega") {
+		loadBundledImages();
 		file = gameDir.createReadStreamForMember("TOTEE.EXE");
 
 		if (file == nullptr)
@@ -119,6 +120,7 @@ void EclipseEngine::loadAssets() {
 			iterator->_value->addStructure(_areaMap[255]);
 
 	} else if (_renderMode == "cga") {
+		loadBundledImages();
 		file = gameDir.createReadStreamForMember("TOTEC.EXE");
 
 		if (file == nullptr)
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 89c6fc38611..881de4690f2 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -506,33 +506,16 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	_binaryBits = 8;
 }
 
-void FreescapeEngine::loadBorder() {
-	if (isAmiga() || isAtariST()) {
-		Image::NeoDecoder decoder;
-		Common::File borderFile;
-		borderFile.open("console.neo");
-		decoder.loadStream(borderFile);
-		_border = new Graphics::Surface();
-		_border->copyFrom(*decoder.getSurface());
-		_border->convertToInPlace(_gfx->_currentPixelFormat, decoder.getPalette());
-		return;
-	}
-
+void FreescapeEngine::loadBundledImages() {
 	Image::BitmapDecoder decoder;
-	Common::String borderFilename;
-	if (isAmiga())
-		borderFilename = _targetName + ".bmp";
-	else
-		borderFilename = _targetName + "_" + _renderMode + ".bmp";
-
-	Common::replace(borderFilename, "-demo", "");
+	Common::String borderFilename = _targetName + "_" + _renderMode + ".bmp";
 	if (_dataBundle->hasFile(borderFilename)) {
 		Common::SeekableReadStream *borderFile = _dataBundle->createReadStreamForMember(borderFilename);
 		decoder.loadStream(*borderFile);
 		_border = new Graphics::Surface();
 		_border->copyFrom(*decoder.getSurface());
 	} else
-		debugC(1, kFreescapeDebugParser, "Missing border file '%s' in data bundle", borderFilename.c_str());
+		error("Missing border file '%s' in data bundle", borderFilename.c_str());
 }
 
 void FreescapeEngine::loadFonts(Common::SeekableReadStream *file, int offset) {
diff --git a/engines/freescape/neo.cpp b/engines/freescape/neo.cpp
index 30671667437..7dc97a93154 100644
--- a/engines/freescape/neo.cpp
+++ b/engines/freescape/neo.cpp
@@ -26,11 +26,6 @@
 #include "graphics/pixelformat.h"
 #include "graphics/surface.h"
 
-/**
- * Based on the PCX specs:
- *
- */
-
 namespace Image {
 
 NeoDecoder::NeoDecoder() {


Commit: 550a82e62ff04fe589a6d7d4adefa26176fe90ec
    https://github.com/scummvm/scummvm/commit/550a82e62ff04fe589a6d7d4adefa26176fe90ec
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:24+01:00

Commit Message:
FREESCAPE: implemented title display for some driller releases

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/driller.cpp
    engines/freescape/neo.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 80100c7dfbc..3bcd6199b2b 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -76,6 +76,7 @@ FreescapeEngine::FreescapeEngine(OSystem *syst, const ADGameDescription *gd)
 
 	_border = nullptr;
 	_title = nullptr;
+	_titleTexture = nullptr;
 	_borderTexture = nullptr;
 	_uiTexture = nullptr;
 	_fontLoaded = false;
@@ -105,6 +106,17 @@ void FreescapeEngine::drawBorder() {
 	_gfx->setViewport(_viewArea);
 }
 
+void FreescapeEngine::drawTitle() {
+	if (!_title)
+		return;
+
+	_gfx->setViewport(_fullscreenViewArea);
+	if (!_titleTexture)
+		_titleTexture = _gfx->createTexture(_title);
+	_gfx->drawTexturedRect2D(_fullscreenViewArea, _fullscreenViewArea, _titleTexture);
+	_gfx->setViewport(_viewArea);
+}
+
 void FreescapeEngine::loadAssets() {
 	Common::SeekableReadStream *file = nullptr;
 	Common::String path = ConfMan.get("path");
@@ -286,14 +298,16 @@ Common::Error FreescapeEngine::run() {
 	}
 	int saveSlot = ConfMan.getInt("save_slot");
 
-	if (_border) {
+	if (_title) {
 		if (saveSlot == -1) {
-			drawBorder();
+			drawTitle();
 			_gfx->flipBuffer();
 			g_system->updateScreen();
-			if (isDriller())
-				g_system->delayMillis(1000);
+			g_system->delayMillis(3000);
 		}
+	}
+
+	if (_border) {
 
 		_borderTexture = nullptr;
 		_border->fillRect(_viewArea, 0xA0A0A0FF);
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 3ffe52c26c3..8153d79c6f4 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -98,10 +98,12 @@ public:
 
 	void convertBorder();
 	void drawBorder();
+	void drawTitle();
 	virtual void drawUI();
 	Graphics::Surface *_border;
 	Graphics::Surface *_title;
 	Texture *_borderTexture;
+	Texture *_titleTexture;
 	Texture *_uiTexture;
 
 	// Parsing assets
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 9e5d470ed27..ff44e4876f4 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -196,21 +196,44 @@ void DrillerEngine::loadAssetsFullGame() {
 
 	Common::File exe;
 	if (isAmiga()) {
-		file = gameDir.createReadStreamForMember("driller");
-		if (file == nullptr)
-			error("Failed to open 'driller' executable for Amiga");
-
 		if (_variant == "Retail") {
+			file = gameDir.createReadStreamForMember("driller");
+
+			if (file == nullptr)
+				error("Failed to open 'driller' executable for Amiga");
+
+			_border = loadAndConvertNeoImage(file, 0x137f4);
+			_title = loadAndConvertNeoImage(file, 0x1b572);
+
 			loadMessagesFixedSize(file, 0xc66e, 14, 20);
 			loadGlobalObjects(file, 0xbd62);
 			load8bitBinary(file, 0x29c16, 16);
 			loadAmigaPalette(file, 0x297d4);
 			loadAmigaSounds(file, 0x30e80, 25);
 		} else if (_variant == "Kixx") {
+			file = gameDir.createReadStreamForMember("lift.neo");
+			if (file == nullptr)
+				error("Failed to open 'lift.neo' file");
+
+			_title = loadAndConvertNeoImage(file, 0);
+
+			file = gameDir.createReadStreamForMember("console.neo");
+			if (file == nullptr)
+				error("Failed to open 'console.neo' file");
+
+			_border = loadAndConvertNeoImage(file, 0);
+
+			file = gameDir.createReadStreamForMember("driller");
+			if (file == nullptr)
+				error("Failed to open 'driller' executable for Amiga");
+
 			load8bitBinary(file, 0x21a3e, 16);
 			loadAmigaPalette(file, 0x215fc);
 
 			file = gameDir.createReadStreamForMember("soundfx");
+			if (file == nullptr)
+				error("Failed to open 'soundfx' executable for Amiga");
+
 			loadAmigaSounds(file, 0, 25);
 		}
 	} else if (_renderMode == "ega") {
diff --git a/engines/freescape/neo.cpp b/engines/freescape/neo.cpp
index 7dc97a93154..bb3eba96c99 100644
--- a/engines/freescape/neo.cpp
+++ b/engines/freescape/neo.cpp
@@ -52,6 +52,7 @@ void NeoDecoder::destroy() {
 
 bool NeoDecoder::loadStream(Common::SeekableReadStream &stream) {
 	destroy();
+	int start = stream.pos();
 
 	if (stream.readUint16LE() != 0x00)
 		return false;
@@ -69,7 +70,7 @@ bool NeoDecoder::loadStream(Common::SeekableReadStream &stream) {
 		_palette[i * 3 + 2] = floor((v2 & 0x07) * 255.0 / 7.0);
 	}
 
-	stream.seek(128);
+	stream.seek(start + 128);
 
 	int width = 320;
 	int height = 200;


Commit: 00c44c4c85f3f2fb8899b165903684a5ce315197
    https://github.com/scummvm/scummvm/commit/00c44c4c85f3f2fb8899b165903684a5ce315197
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:24+01:00

Commit Message:
FREESCAPE: refactored neochrome decoder to allow to read images without palettes

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/driller.cpp
    engines/freescape/neo.cpp
    engines/freescape/neo.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 3bcd6199b2b..a83c3bf270c 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -481,10 +481,20 @@ void FreescapeEngine::loadDataBundle() {
 	}
 }
 
-Graphics::Surface *FreescapeEngine::loadAndConvertNeoImage(Common::SeekableReadStream *stream, int offset) {
+byte *FreescapeEngine::getPaletteFromNeoImage(Common::SeekableReadStream *stream, int offset) {
 	stream->seek(offset);
 	Image::NeoDecoder decoder;
 	decoder.loadStream(*stream);
+	byte *palette = (byte*) malloc(16 * 3 * sizeof(byte));
+	memcpy(palette, decoder.getPalette(), 16 * 3 * sizeof(byte));
+	return palette;
+}
+
+
+Graphics::Surface *FreescapeEngine::loadAndConvertNeoImage(Common::SeekableReadStream *stream, int offset, byte* palette) {
+	stream->seek(offset);
+	Image::NeoDecoder decoder(palette);
+	decoder.loadStream(*stream);
 	Graphics::Surface *surface = new Graphics::Surface();
 	surface->copyFrom(*decoder.getSurface());
 	surface->convertToInPlace(_gfx->_currentPixelFormat, decoder.getPalette());
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 8153d79c6f4..fac57a75fc7 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -112,7 +112,8 @@ public:
 	Common::Archive *_dataBundle;
 	void loadDataBundle();
 	void loadBundledImages();
-	Graphics::Surface *loadAndConvertNeoImage(Common::SeekableReadStream *stream, int offset);
+	byte *getPaletteFromNeoImage(Common::SeekableReadStream *stream, int offset);
+	Graphics::Surface *loadAndConvertNeoImage(Common::SeekableReadStream *stream, int offset, byte* palette = nullptr);
 	void loadAmigaPalette(Common::SeekableReadStream *file, int offset);
 	void swapAmigaPalette(uint16 areaID);
 	Common::HashMap<uint16, byte*> _amigaPalette;
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index ff44e4876f4..eae6fdd23bd 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -203,7 +203,13 @@ void DrillerEngine::loadAssetsFullGame() {
 				error("Failed to open 'driller' executable for Amiga");
 
 			_border = loadAndConvertNeoImage(file, 0x137f4);
-			_title = loadAndConvertNeoImage(file, 0x1b572);
+			byte *palette = (byte*) malloc(16 * 3);
+			for (int i = 0; i < 16; i++) { // gray scale palette
+				palette[i * 3 + 0] = i * (255 / 16);
+				palette[i * 3 + 1] = i * (255 / 16);
+				palette[i * 3 + 2] = i * (255 / 16);
+			}
+			_title = loadAndConvertNeoImage(file, 0x10, palette);
 
 			loadMessagesFixedSize(file, 0xc66e, 14, 20);
 			loadGlobalObjects(file, 0xbd62);
diff --git a/engines/freescape/neo.cpp b/engines/freescape/neo.cpp
index bb3eba96c99..a816ef8ace2 100644
--- a/engines/freescape/neo.cpp
+++ b/engines/freescape/neo.cpp
@@ -28,9 +28,10 @@
 
 namespace Image {
 
-NeoDecoder::NeoDecoder() {
-	_surface = 0;
-	_palette = 0;
+NeoDecoder::NeoDecoder(byte *palette) {
+	_surface = nullptr;
+	_paletteDestroy = palette ? false : true;
+	_palette = palette;
 	_paletteColorCount = 0;
 }
 
@@ -42,35 +43,40 @@ void NeoDecoder::destroy() {
 	if (_surface) {
 		_surface->free();
 		delete _surface;
-		_surface = 0;
+		_surface = nullptr;
 	}
 
-	delete[] _palette;
-	_palette = 0;
+	if (_paletteDestroy) {
+		delete[] _palette;
+		_palette = nullptr;
+	}
 	_paletteColorCount = 0;
 }
 
 bool NeoDecoder::loadStream(Common::SeekableReadStream &stream) {
 	destroy();
-	int start = stream.pos();
 
-	if (stream.readUint16LE() != 0x00)
-		return false;
+	if (!_palette) {
+		int start = stream.pos();
 
-	if (stream.readUint16LE() != 0x00)
-		return false;
+		if (stream.readUint16LE() != 0x00)
+			warning("Header check failed for reading neo image");
 
-	_palette = new byte[16 * 3];
-	for (int i = 0; i < 16; ++i) {
-		byte v1 = stream.readByte();
-		byte v2 = stream.readByte();
+		if (stream.readUint16LE() != 0x00)
+			warning("Header check failed for reading neo image");
 
-		_palette[i * 3 + 0] = floor((v1 & 0x07) * 255.0 / 7.0);
-		_palette[i * 3 + 1] = floor((v2 & 0x70) * 255.0 / 7.0 / 16.0);
-		_palette[i * 3 + 2] = floor((v2 & 0x07) * 255.0 / 7.0);
-	}
+		_palette = new byte[16 * 3];
+		for (int i = 0; i < 16; ++i) {
+			byte v1 = stream.readByte();
+			byte v2 = stream.readByte();
 
-	stream.seek(start + 128);
+			_palette[i * 3 + 0] = floor((v1 & 0x07) * 255.0 / 7.0);
+			_palette[i * 3 + 1] = floor((v2 & 0x70) * 255.0 / 7.0 / 16.0);
+			_palette[i * 3 + 2] = floor((v2 & 0x07) * 255.0 / 7.0);
+		}
+
+		stream.seek(start + 128);
+	}
 
 	int width = 320;
 	int height = 200;
diff --git a/engines/freescape/neo.h b/engines/freescape/neo.h
index 27a81a6de0e..ecca4d6eabc 100644
--- a/engines/freescape/neo.h
+++ b/engines/freescape/neo.h
@@ -38,7 +38,7 @@ namespace Image {
 
 class NeoDecoder : public ImageDecoder {
 public:
-	NeoDecoder();
+	NeoDecoder(byte *palette = nullptr);
 	virtual ~NeoDecoder();
 
 	// ImageDecoder API
@@ -50,6 +50,7 @@ public:
 
 private:
 	Graphics::Surface *_surface;
+	bool _paletteDestroy;
 	byte *_palette;
 	uint16 _paletteColorCount;
 };


Commit: 2699defeb7d65ef691ffdd708a0bddc4407fe23f
    https://github.com/scummvm/scummvm/commit/2699defeb7d65ef691ffdd708a0bddc4407fe23f
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:24+01:00

Commit Message:
FREESCAPE: parse strings in driller demos

Changed paths:
    engines/freescape/games/driller.cpp


diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index eae6fdd23bd..5570caf6d7b 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -157,6 +157,12 @@ void DrillerEngine::loadAssetsDemo() {
 
 		load8bitBinary(file, 0x442, 16);
 		loadAmigaPalette(file, 0x0);
+
+		file = gameDir.createReadStreamForMember("driller");
+		if (file == nullptr)
+			error("Failed to open 'driller' file");
+		loadMessagesFixedSize(file, 0x3960, 14, 20);
+
 	} else if (isAtariST()) {
 		file = gameDir.createReadStreamForMember("lift.neo");
 		if (file == nullptr)
@@ -183,6 +189,11 @@ void DrillerEngine::loadAssetsDemo() {
 
 		load8bitBinary(file, 0x442, 16);
 		loadAmigaPalette(file, 0x0);
+
+		file = gameDir.createReadStreamForMember("x.prg");
+		if (file == nullptr)
+			error("Failed to open 'x.prg' file");
+		loadMessagesFixedSize(file, 0x3b90, 14, 20);
 	}
 	else
 		error("Unsupported demo for Driller");


Commit: 854c90414075e3a7cbac8045a47f6e299609fc98
    https://github.com/scummvm/scummvm/commit/854c90414075e3a7cbac8045a47f6e299609fc98
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:24+01:00

Commit Message:
FREESCAPE: proof of concept of the upcoming demo mode for all the games

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/driller.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index a83c3bf270c..753b935ff50 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -70,6 +70,7 @@ FreescapeEngine::FreescapeEngine(OSystem *syst, const ADGameDescription *gd)
 	_cameraRight = Math::Vector3d(0.f, 0.f, 0.f);
 	_movementSpeed = 1.5f;
 	_mouseSensitivity = 0.25f;
+	_demoMode = false;
 	_flyMode = false;
 	_noClipMode = false;
 	_playerHeightNumber = 1;
@@ -170,6 +171,19 @@ void FreescapeEngine::drawFrame() {
 
 void FreescapeEngine::pressedKey(const int keycode) {}
 
+void FreescapeEngine::generateInput() {
+	Common::Event event;
+	event.type = Common::EVENT_KEYDOWN;
+	event.kbd.keycode = Common::KEYCODE_UP;
+	event.customType = 0xde00;
+	g_system->getEventManager()->pushEvent(event);
+
+	event.type = Common::EVENT_KEYDOWN;
+	g_system->getEventManager()->pushEvent(event);
+
+	g_system->delayMillis(500);
+}
+
 void FreescapeEngine::processInput() {
 	float currentFrame = g_system->getMillis();
 	float deltaTime = 20.0;
@@ -180,6 +194,10 @@ void FreescapeEngine::processInput() {
 
 		switch (event.type) {
 		case Common::EVENT_KEYDOWN:
+			if (_demoMode && event.customType != 0xde00) {
+				continue;
+			}
+
 			if (event.kbd.keycode == Common::KEYCODE_o || event.kbd.keycode == Common::KEYCODE_UP)
 				move(FORWARD, _scaleVector.x(), deltaTime);
 			else if (event.kbd.keycode == Common::KEYCODE_k || event.kbd.keycode == Common::KEYCODE_DOWN)
@@ -322,6 +340,9 @@ Common::Error FreescapeEngine::run() {
 	bool endGame = false;
 	while (!shouldQuit() && !endGame) {
 		drawFrame();
+		if (_demoMode)
+			generateInput();
+
 		processInput();
 		_gfx->flipBuffer();
 		g_system->updateScreen();
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index fac57a75fc7..2a284c791b2 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -118,6 +118,8 @@ public:
 	void swapAmigaPalette(uint16 areaID);
 	Common::HashMap<uint16, byte*> _amigaPalette;
 	void loadColorPalette();
+	Common::Array<byte> _demoData;
+	void loadDemoData(Common::SeekableReadStream *file, int offset, int size);
 
 	uint16 readField(Common::SeekableReadStream *file, int nbits);
 	Common::Array<uint8> readArray(Common::SeekableReadStream *file, int size);
@@ -141,9 +143,11 @@ public:
 	Common::HashMap<int, const struct entrancesTableEntry*> _entranceTable;
 
 	// Input
+	bool _demoMode;
 	bool _flyMode;
 	bool _noClipMode;
 	void processInput();
+	void generateInput();
 	virtual void pressedKey(const int keycode);
 	void move(CameraMovement direction, uint8 scale, float deltaTime);
 	void changePlayerHeight(int delta);
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 5570caf6d7b..0331fafb748 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -139,12 +139,18 @@ void DrillerEngine::loadAssetsDemo() {
 
 		_title = loadAndConvertNeoImage(file, 0);
 
+		file = gameDir.createReadStreamForMember("console.neo");
 		if (file == nullptr)
 			error("Failed to open 'console.neo' file");
 
-		file = gameDir.createReadStreamForMember("console.neo");
 		_border = loadAndConvertNeoImage(file, 0);
 
+		file = gameDir.createReadStreamForMember("demo.cmd");
+		if (file == nullptr)
+			error("Failed to open 'demo.cmd' file");
+
+		loadDemoData(file, 0, 0x1000);
+
 		file = gameDir.createReadStreamForMember("data");
 		if (file == nullptr)
 			error("Failed to open 'data' file");
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 881de4690f2..8f675cd3f2a 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -543,6 +543,16 @@ void FreescapeEngine::loadMessagesFixedSize(Common::SeekableReadStream *file, in
 	}
 }
 
+void FreescapeEngine::loadDemoData(Common::SeekableReadStream *file, int offset, int size) {
+	file->seek(offset);
+	debugC(1, kFreescapeDebugParser, "Reading demo data");
+	for (int i = 0; i < size; i++) {
+		byte b = file->readByte();
+		_demoData.push_back(b);
+		debugC(1, kFreescapeDebugParser, "%x", b);
+	}
+}
+
 void FreescapeEngine::loadMessagesVariableSize(Common::SeekableReadStream *file, int offset, int number) {
 	file->seek(offset);
 	debugC(1, kFreescapeDebugParser, "String table:");


Commit: f5aba68844761fbeb356d4fb52107c481791b51c
    https://github.com/scummvm/scummvm/commit/f5aba68844761fbeb356d4fb52107c481791b51c
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:24+01:00

Commit Message:
FREESCAPE: sound fx for some releases of driller in amiga and atari

Changed paths:
    engines/freescape/freescape.h
    engines/freescape/games/driller.cpp
    engines/freescape/sound.cpp


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 2a284c791b2..93863640d12 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -69,6 +69,12 @@ struct entrancesTableEntry {
 	int position[3];
 };
 
+struct soundFx {
+	int size;
+	int sampleRate;
+	byte *data;
+};
+
 class FreescapeEngine : public Engine {
 private:
 	// We need random numbers
@@ -223,10 +229,9 @@ public:
 	void playSoundSweepIncWL(double hzFreq1, double hzFreq2, double wlStepPerMS, int resolution, bool sync);
 	void playTeleporter(int totalIters, bool sync);
 
-	void playPaulaSound(int index, bool sync);
-	void loadAmigaSounds(Common::SeekableReadStream *file, int offset, int number);
-	Common::HashMap<uint16, byte*> _amigaSoundsBuffer;
-	Common::HashMap<uint16, int> _amigaSoundsSize;
+	void playSoundFx(int index, bool sync);
+	void loadSoundsFx(Common::SeekableReadStream *file, int offset, int number);
+	Common::HashMap<uint16, soundFx*> _soundsFx;
 
 	// Rendering
 	int _screenW, _screenH;
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 0331fafb748..c851bb88844 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -169,6 +169,11 @@ void DrillerEngine::loadAssetsDemo() {
 			error("Failed to open 'driller' file");
 		loadMessagesFixedSize(file, 0x3960, 14, 20);
 
+		file = gameDir.createReadStreamForMember("soundfx");
+		if (file == nullptr)
+			error("Failed to open 'soundfx' executable for Amiga");
+
+		loadSoundsFx(file, 0, 25);
 	} else if (isAtariST()) {
 		file = gameDir.createReadStreamForMember("lift.neo");
 		if (file == nullptr)
@@ -232,7 +237,7 @@ void DrillerEngine::loadAssetsFullGame() {
 			loadGlobalObjects(file, 0xbd62);
 			load8bitBinary(file, 0x29c16, 16);
 			loadAmigaPalette(file, 0x297d4);
-			loadAmigaSounds(file, 0x30e80, 25);
+			loadSoundsFx(file, 0x30e80, 25);
 		} else if (_variant == "Kixx") {
 			file = gameDir.createReadStreamForMember("lift.neo");
 			if (file == nullptr)
@@ -257,7 +262,7 @@ void DrillerEngine::loadAssetsFullGame() {
 			if (file == nullptr)
 				error("Failed to open 'soundfx' executable for Amiga");
 
-			loadAmigaSounds(file, 0, 25);
+			loadSoundsFx(file, 0, 25);
 		}
 	} else if (_renderMode == "ega") {
 		loadBundledImages();
diff --git a/engines/freescape/sound.cpp b/engines/freescape/sound.cpp
index fc75ff458c5..482217c30b7 100644
--- a/engines/freescape/sound.cpp
+++ b/engines/freescape/sound.cpp
@@ -20,7 +20,7 @@
  */
 
 #include "freescape/freescape.h"
-#include "audio/mods/paula.h"
+#include "audio/decoders/raw.h"
 
 namespace Freescape {
 
@@ -33,15 +33,11 @@ void FreescapeEngine::playSound(int index, bool sync) {
 	//	_mixer->stopHandle(_handle);
 
 	debugC(1, kFreescapeDebugMedia, "Playing sound %d with sync: %d", index, sync);
-	if (isAmiga()) {
-		playPaulaSound(index, sync);
-		return;
-	} else if (isAtariST()) {
-		// TODO
+	if (isAmiga() || isAtariST()) {
+		playSoundFx(index, sync);
 		return;
 	}
 
-
 	switch (index) {
 		case 1:
 			if (_usePrerecordedSounds) {
@@ -230,6 +226,23 @@ void FreescapeEngine::playWav(const Common::String filename) {
 	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_handle, stream);
 }
 
+void FreescapeEngine::playSoundFx(int index, bool sync) {
+	int size = _soundsFx[index]->size;
+	int sampleRate = _soundsFx[index]->sampleRate;
+	byte *data = _soundsFx[index]->data;
+	int loops = 1;
+
+	if (index == 10)
+		loops = 5;
+	else if (index == 15)
+		loops = 50;
+
+	if (size > 4) {
+		Audio::SeekableAudioStream *s = Audio::makeRawStream(data, size, sampleRate, Audio::FLAG_16BITS, DisposeAfterUse::NO);
+		Audio::AudioStream *stream = new Audio::LoopingAudioStream(s, loops);
+		_mixer->playStream(Audio::Mixer::kSFXSoundType, &_handle, stream);
+	}
+}
 
 void FreescapeEngine::playSoundConst(double hzFreq, int duration, bool sync) {
 	Audio::PCSpeaker *speaker = new Audio::PCSpeaker();
@@ -326,35 +339,23 @@ void FreescapeEngine::playTeleporter(int totalIters, bool sync) {
 	}
 }
 
-class AudioPaula : public Audio::Paula {
-	void interrupt() override;
-};
-
-void AudioPaula::interrupt() {}
-
-void FreescapeEngine::playPaulaSound(int index, bool sync) {
-	AudioPaula *paula = new AudioPaula();
-	paula->setInterruptFreq(0x168);
-	paula->readBuffer((int16*)_amigaSoundsBuffer[index], _amigaSoundsSize[index] / 2);
-	paula->startPlay();
-	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_handle, paula);
-	if (sync) {
-		//_system->delayMillis(duration);
-	}
-}
-
-void FreescapeEngine::loadAmigaSounds(Common::SeekableReadStream *file, int offset, int number) {
+void FreescapeEngine::loadSoundsFx(Common::SeekableReadStream *file, int offset, int number) {
 	file->seek(offset);
-	for (int i = 1; i < number+1; i++) {
+	soundFx *sound = nullptr;
+	_soundsFx[0] = sound;
+	for (int i = 1; i < number + 1; i++) {
+		sound = (soundFx*) malloc(sizeof(soundFx));
+		int zero = file->readUint16BE();
+		assert(zero == 0);
 		int size = file->readUint16BE();
-		assert(size == 0);
-		size = file->readUint16BE();
-		debug("Loading sound: %d (size: %d)", i, size);
-		size = size + 2;
-		byte *palette = (byte*) malloc(size * sizeof(byte));
-		file->read(palette, size);
-		_amigaSoundsBuffer[i] = (byte*) palette;
-		_amigaSoundsSize[i] = size;
+		int sampleRate = file->readUint16BE();
+		debug("Loading sound: %d (size: %d, sample rate: %d)", i, size, sampleRate);
+		byte *data = (byte*) malloc(size * sizeof(byte));
+		file->read(data, size);
+		sound->sampleRate = sampleRate;
+		sound->size = size;
+		sound->data = (byte*) data;
+		_soundsFx[i] = sound;
 	}
 }
 


Commit: c0be12923748ebe925404fa8826f90dfe039df97
    https://github.com/scummvm/scummvm/commit/c0be12923748ebe925404fa8826f90dfe039df97
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:25+01:00

Commit Message:
FREESCAPE: move shoot function to movement.cpp

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/movement.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 753b935ff50..b4da7b8eca4 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -266,25 +266,6 @@ void FreescapeEngine::processInput() {
 	}
 }
 
-void FreescapeEngine::shoot() {
-	playSound(1, true);
-	_mixer->stopAll();
-	_gfx->renderShoot(0);
-	Math::Vector3d direction = directionToVector(_pitch, _yaw);
-	Math::Ray ray(_position, direction);
-	Object *shot = _currentArea->shootRay(ray);
-	if (shot) {
-		GeometricObject *gobj = (GeometricObject*) shot;
-		debug("Shot object %d with flags %x", gobj->getObjectID(), gobj->getObjectFlags());
-
-		if (gobj->conditionSource != nullptr)
-			debug("Must use shot = true when executing: %s", gobj->conditionSource->c_str());
-
-		executeObjectConditions(gobj, true, false);
-	}
-	executeLocalGlobalConditions(true, false); // Only execute "on shot" room/global conditions
-}
-
 Common::Error FreescapeEngine::run() {
 	// Initialize graphics
 	_gfx = createRenderer(_system, _screenW, _screenH);
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index 9875c800b3e..e8c50984c65 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -48,6 +48,25 @@ void FreescapeEngine::traverseEntrance(uint16 entranceID) {
 	_position.setValue(1, _position.y() + scale * _playerHeight);
 }
 
+void FreescapeEngine::shoot() {
+	playSound(1, true);
+	_mixer->stopAll();
+	_gfx->renderShoot(0);
+	Math::Vector3d direction = directionToVector(_pitch, _yaw);
+	Math::Ray ray(_position, direction);
+	Object *shot = _currentArea->shootRay(ray);
+	if (shot) {
+		GeometricObject *gobj = (GeometricObject*) shot;
+		debugC(1, kFreescapeDebugMove, "Shot object %d with flags %x", gobj->getObjectID(), gobj->getObjectFlags());
+
+		if (gobj->conditionSource != nullptr)
+			debugC(1, kFreescapeDebugMove, "Must use shot = true when executing: %s", gobj->conditionSource->c_str());
+
+		executeObjectConditions(gobj, true, false);
+	}
+	executeLocalGlobalConditions(true, false); // Only execute "on shot" room/global conditions
+}
+
 void FreescapeEngine::changePlayerHeight(int index) {
 	int scale = _currentArea->getScale();
 	_position.setValue(1, _position.y() - scale * _playerHeight);


Commit: b4bfb4bf7d972d096bf4cc565013ecc03b16a435
    https://github.com/scummvm/scummvm/commit/b4bfb4bf7d972d096bf4cc565013ecc03b16a435
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:25+01:00

Commit Message:
FREESCAPE: removed debug calls and use debugging chanels instead

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/games/palettes.cpp
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/sound.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index e34af9009b4..4e079f657b7 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -21,6 +21,7 @@
 
 // Based on Phantasma code by Thomas Harte (2013)
 
+#include "freescape/freescape.h"
 #include "freescape/area.h"
 #include "freescape/objects/geometricobject.h"
 #include "freescape/objects/entrance.h"
@@ -102,12 +103,12 @@ Area::~Area() {
 }
 
 void Area::show() {
-	debug("Area name: %s", name.c_str());
+	debugC(1, kFreescapeDebugMove, "Area name: %s", name.c_str());
 	for (ObjectMap::iterator it = objectsByID->begin(); it != objectsByID->end(); it++)
-		debug("objID: %d, type: %d", (*it)._value->getObjectID(), (*it)._value->getType());
+		debugC(1, kFreescapeDebugMove, "objID: %d, type: %d", (*it)._value->getObjectID(), (*it)._value->getType());
 
 	for (ObjectMap::iterator it = entrancesByID->begin(); it != entrancesByID->end(); it++)
-		debug("objID: %d, type: %d (entrance)", (*it)._value->getObjectID(), (*it)._value->getType());
+		debugC(1, kFreescapeDebugMove, "objID: %d, type: %d (entrance)", (*it)._value->getObjectID(), (*it)._value->getType());
 }
 
 void Area::loadObjects(Common::SeekableReadStream *stream, Area *global) {
@@ -165,7 +166,7 @@ Object *Area::shootRay(const Math::Ray &ray) {
 		  && drawableObjects[i]->boundingBox.isValid()
 		  && ray.intersectAABB(drawableObjects[i]->boundingBox)
 		  && size >= objSize) {
-			debug("shot obj id: %d", drawableObjects[i]->getObjectID());
+			debugC(1, kFreescapeDebugMove, "shot obj id: %d", drawableObjects[i]->getObjectID());
 			collided = drawableObjects[i];
 			size = objSize;
 		}
@@ -192,7 +193,7 @@ Object *Area::checkCollisions(const Math::AABB &boundingBox) {
 void Area::addObject(Object *obj) {
 	assert(obj);
 	int id = obj->getObjectID();
-	debug("Adding object %d to room %d", id, areaID);
+	debugC(1, kFreescapeDebugParser, "Adding object %d to room %d", id, areaID);
 	assert(!objectsByID->contains(id));
 	(*objectsByID)[id] = obj;
 	if (obj->isDrawable())
@@ -211,7 +212,7 @@ void Area::removeObject(int16 id) {
 }
 
 void Area::addObjectFromArea(int16 id, Area *global) {
-	debug("Adding object %d to room structure", id);
+	debugC(1, kFreescapeDebugParser, "Adding object %d to room structure", id);
 	Object *obj = global->objectWithID(id);
 	if (!obj) {
 		assert(global->entranceWithID(id));
diff --git a/engines/freescape/games/palettes.cpp b/engines/freescape/games/palettes.cpp
index 734ab9d3df0..ef545639533 100644
--- a/engines/freescape/games/palettes.cpp
+++ b/engines/freescape/games/palettes.cpp
@@ -71,7 +71,7 @@ void FreescapeEngine::loadAmigaPalette(Common::SeekableReadStream *file, int off
 	for (int i = 0; i < int(_areaMap.size()); i++) {
 		int label = readField(file, 8);
 		auto palette = new byte[16][3];
-		debug("Loading palette for area: %d", label);
+		debugC(1, kFreescapeDebugParser, "Loading palette for area: %d", label);
 		for (int c = 0; c < 16; c++) {
 			int v = file->readUint16BE();
 			r = (v & 0xf00) >> 8;
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index 1627c19678d..c15c7ecd428 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -23,7 +23,9 @@
 // John Elliott's 2001 reverse engineering of Driller; see http://www.seasip.demon.co.uk/ZX/Driller/
 
 #include "common/debug.h"
-#include "8bitDetokeniser.h"
+
+#include "freescape/freescape.h"
+#include "freescape/language/8bitDetokeniser.h"
 
 namespace Freescape {
 
@@ -89,7 +91,7 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 		// figure out how many argument bytes we're going to need,
 		// check we have enough bytes left to read
 		if (opcode > 48) {
-			debug("%s", detokenisedStream.c_str());
+			debugC(1, kFreescapeDebugParser, "%s", detokenisedStream.c_str());
 			if (opcode != 0x3f)
 				error("ERROR: failed to read opcode: %x", opcode);
 			break;
diff --git a/engines/freescape/sound.cpp b/engines/freescape/sound.cpp
index 482217c30b7..c71fbfdcb00 100644
--- a/engines/freescape/sound.cpp
+++ b/engines/freescape/sound.cpp
@@ -349,7 +349,7 @@ void FreescapeEngine::loadSoundsFx(Common::SeekableReadStream *file, int offset,
 		assert(zero == 0);
 		int size = file->readUint16BE();
 		int sampleRate = file->readUint16BE();
-		debug("Loading sound: %d (size: %d, sample rate: %d)", i, size, sampleRate);
+		debugC(1, kFreescapeDebugParser, "Loading sound: %d (size: %d, sample rate: %d)", i, size, sampleRate);
 		byte *data = (byte*) malloc(size * sizeof(byte));
 		file->read(data, size);
 		sound->sampleRate = sampleRate;


Commit: 46608d037ca901335d8de59c4298a2f493d35287
    https://github.com/scummvm/scummvm/commit/46608d037ca901335d8de59c4298a2f493d35287
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:25+01:00

Commit Message:
FREESCAPE: rename palette function names

Changed paths:
    engines/freescape/freescape.h
    engines/freescape/games/driller.cpp
    engines/freescape/games/palettes.cpp


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 93863640d12..e05d00e1c27 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -120,9 +120,9 @@ public:
 	void loadBundledImages();
 	byte *getPaletteFromNeoImage(Common::SeekableReadStream *stream, int offset);
 	Graphics::Surface *loadAndConvertNeoImage(Common::SeekableReadStream *stream, int offset, byte* palette = nullptr);
-	void loadAmigaPalette(Common::SeekableReadStream *file, int offset);
-	void swapAmigaPalette(uint16 areaID);
-	Common::HashMap<uint16, byte*> _amigaPalette;
+	void loadPalettes(Common::SeekableReadStream *file, int offset);
+	void swapPalette(uint16 areaID);
+	Common::HashMap<uint16, byte*> _paletteByArea;
 	void loadColorPalette();
 	Common::Array<byte> _demoData;
 	void loadDemoData(Common::SeekableReadStream *file, int offset, int size);
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index c851bb88844..6068ae5e7bf 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -101,7 +101,7 @@ void DrillerEngine::gotoArea(uint16 areaID, int entranceID) {
 		_gfx->_keyColor = 255;
 
 	if (isAmiga() || isAtariST())
-		swapAmigaPalette(areaID);
+		swapPalette(areaID);
 }
 
 void DrillerEngine::loadGlobalObjects(Common::SeekableReadStream *file, int offset) {
@@ -162,7 +162,7 @@ void DrillerEngine::loadAssetsDemo() {
 		load8bitArea(file, 16);*/
 
 		load8bitBinary(file, 0x442, 16);
-		loadAmigaPalette(file, 0x0);
+		loadPalettes(file, 0x0);
 
 		file = gameDir.createReadStreamForMember("driller");
 		if (file == nullptr)
@@ -199,7 +199,7 @@ void DrillerEngine::loadAssetsDemo() {
 		load8bitArea(file, 16);*/
 
 		load8bitBinary(file, 0x442, 16);
-		loadAmigaPalette(file, 0x0);
+		loadPalettes(file, 0x0);
 
 		file = gameDir.createReadStreamForMember("x.prg");
 		if (file == nullptr)
@@ -236,7 +236,7 @@ void DrillerEngine::loadAssetsFullGame() {
 			loadMessagesFixedSize(file, 0xc66e, 14, 20);
 			loadGlobalObjects(file, 0xbd62);
 			load8bitBinary(file, 0x29c16, 16);
-			loadAmigaPalette(file, 0x297d4);
+			loadPalettes(file, 0x297d4);
 			loadSoundsFx(file, 0x30e80, 25);
 		} else if (_variant == "Kixx") {
 			file = gameDir.createReadStreamForMember("lift.neo");
@@ -256,7 +256,7 @@ void DrillerEngine::loadAssetsFullGame() {
 				error("Failed to open 'driller' executable for Amiga");
 
 			load8bitBinary(file, 0x21a3e, 16);
-			loadAmigaPalette(file, 0x215fc);
+			loadPalettes(file, 0x215fc);
 
 			file = gameDir.createReadStreamForMember("soundfx");
 			if (file == nullptr)
diff --git a/engines/freescape/games/palettes.cpp b/engines/freescape/games/palettes.cpp
index ef545639533..7801f39dda4 100644
--- a/engines/freescape/games/palettes.cpp
+++ b/engines/freescape/games/palettes.cpp
@@ -65,7 +65,7 @@ void FreescapeEngine::loadColorPalette() {
 	_gfx->_colorMap = &_colorMap;
 }
 
-void FreescapeEngine::loadAmigaPalette(Common::SeekableReadStream *file, int offset) {
+void FreescapeEngine::loadPalettes(Common::SeekableReadStream *file, int offset) {
 	file->seek(offset);
 	int r, g, b;
 	for (int i = 0; i < int(_areaMap.size()); i++) {
@@ -85,16 +85,16 @@ void FreescapeEngine::loadAmigaPalette(Common::SeekableReadStream *file, int off
 			palette[c][2] = byte(b);
 		}
 
-		assert(!_amigaPalette.contains(label));
-		_amigaPalette[label] = (byte*) palette;
+		assert(!_paletteByArea.contains(label));
+		_paletteByArea[label] = (byte*) palette;
 	}
 }
 
-void FreescapeEngine::swapAmigaPalette(uint16 levelID) {
+void FreescapeEngine::swapPalette(uint16 levelID) {
 	if (_gfx->_palette)
 		delete _gfx->_palette;
 
-	_gfx->_palette = new Graphics::PixelBuffer(_gfx->_palettePixelFormat, _amigaPalette[levelID]);
+	_gfx->_palette = new Graphics::PixelBuffer(_gfx->_palettePixelFormat, _paletteByArea[levelID]);
 }
 
 


Commit: 831bc9eb1fa4523f876f933a8bd21f1c8e514dfd
    https://github.com/scummvm/scummvm/commit/831bc9eb1fa4523f876f933a8bd21f1c8e514dfd
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:25+01:00

Commit Message:
FREESCAPE: added some code to read demo tables

Changed paths:
  A engines/freescape/keyboard.cpp
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/module.mk


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index b4da7b8eca4..8f756e6262c 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -71,6 +71,7 @@ FreescapeEngine::FreescapeEngine(OSystem *syst, const ADGameDescription *gd)
 	_movementSpeed = 1.5f;
 	_mouseSensitivity = 0.25f;
 	_demoMode = false;
+	_demoIndex = 0;
 	_flyMode = false;
 	_noClipMode = false;
 	_playerHeightNumber = 1;
@@ -173,15 +174,54 @@ void FreescapeEngine::pressedKey(const int keycode) {}
 
 void FreescapeEngine::generateInput() {
 	Common::Event event;
-	event.type = Common::EVENT_KEYDOWN;
-	event.kbd.keycode = Common::KEYCODE_UP;
+
+	g_system->getEventManager()->purgeKeyboardEvents();
+	if (isDOS()) {
+		byte repetition = 1;
+		byte keyIndex = _demoData[_demoIndex++];
+
+		if (keyIndex >= 0x80) {
+			repetition = keyIndex / 32;
+			keyIndex = _demoData[_demoIndex++];
+		}
+
+		event = Common::Event();
+		event.type = Common::EVENT_KEYDOWN;
+		event.kbd.keycode = (Common::KeyCode)decodeDOSKey(keyIndex);
+		event.customType = 0xde00;
+
+		while(repetition-- > 0) {
+			debug("Pushing key: %x", event.kbd.keycode);
+			g_system->getEventManager()->pushEvent(event);
+		}
+		g_system->delayMillis(100);
+		return;
+	}
+
+	int mouseX = _demoData[_demoIndex++] << 1;
+	int mouseY = _demoData[_demoIndex++];
+	debug("Mouse moved to: %d, %d", mouseX, mouseY);
+
+	event.type = Common::EVENT_MOUSEMOVE;
+	event.mouse = Common::Point(mouseX, mouseY);
 	event.customType = 0xde00;
 	g_system->getEventManager()->pushEvent(event);
 
-	event.type = Common::EVENT_KEYDOWN;
-	g_system->getEventManager()->pushEvent(event);
+	byte nextKeyCode = _demoData[_demoIndex++];
+	while(nextKeyCode != 0) {
+
+		event = Common::Event();
+		event.type = Common::EVENT_KEYDOWN;
+		event.kbd.keycode = (Common::KeyCode)decodeAmigaAtariKey(nextKeyCode);
+		debug("Pushing key: %x", nextKeyCode);
+		event.customType = 0xde00;
+		g_system->getEventManager()->pushEvent(event);
+		g_system->getEventManager()->pushEvent(event);
+
+		nextKeyCode = _demoData[_demoIndex++];
+	}
 
-	g_system->delayMillis(500);
+	g_system->delayMillis(200);
 }
 
 void FreescapeEngine::processInput() {
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index e05d00e1c27..4d0e54e1a4f 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -95,6 +95,7 @@ public:
 	bool isCastle() { return _targetName.hasPrefix("castle"); }
 	bool isAmiga() { return _targetName.hasSuffix("-amiga") || Common::matchString(_targetName.c_str() ,"*-amiga-#"); }
 	bool isAtariST() { return _targetName.hasSuffix("-st") || Common::matchString(_targetName.c_str() ,"*-st-#"); }
+	bool isDOS() { return !isAmiga() && !isAtariST(); }
 
 	Common::Error run() override;
 
@@ -125,7 +126,10 @@ public:
 	Common::HashMap<uint16, byte*> _paletteByArea;
 	void loadColorPalette();
 	Common::Array<byte> _demoData;
+	int _demoIndex;
 	void loadDemoData(Common::SeekableReadStream *file, int offset, int size);
+	int decodeAmigaAtariKey(int code);
+	int decodeDOSKey(int code);
 
 	uint16 readField(Common::SeekableReadStream *file, int nbits);
 	Common::Array<uint8> readArray(Common::SeekableReadStream *file, int size);
diff --git a/engines/freescape/keyboard.cpp b/engines/freescape/keyboard.cpp
new file mode 100644
index 00000000000..505db0afa4b
--- /dev/null
+++ b/engines/freescape/keyboard.cpp
@@ -0,0 +1,189 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "common/events.h"
+
+#include "freescape/freescape.h"
+
+#define AK_A 0x20
+#define AK_B 0x35
+#define AK_C 0x33
+#define AK_D 0x22
+#define AK_E 0x12
+#define AK_F 0x23
+#define AK_G 0x24
+#define AK_H 0x25
+#define AK_I 0x17
+#define AK_J 0x26
+#define AK_K 0x27
+#define AK_L 0x28
+#define AK_M 0x37
+#define AK_N 0x36
+#define AK_O 0x18
+#define AK_P 0x19
+#define AK_Q 0x10
+#define AK_R 0x13
+#define AK_S 0x21
+#define AK_T 0x14
+#define AK_U 0x16
+#define AK_V 0x34
+#define AK_W 0x11
+#define AK_X 0x32
+#define AK_Y 0x15
+#define AK_Z 0x31
+
+#define AK_0 0x0A
+#define AK_1 0x01
+#define AK_2 0x02
+#define AK_3 0x03
+#define AK_4 0x04
+#define AK_5 0x05
+#define AK_6 0x06
+#define AK_7 0x07
+#define AK_8 0x08
+#define AK_9 0x09
+
+#define AK_NP0 0x0F
+#define AK_NP1 0x1D
+#define AK_NP2 0x1E
+#define AK_NP3 0x1F
+#define AK_NP4 0x2D
+#define AK_NP5 0x2E
+#define AK_NP6 0x2F
+#define AK_NP7 0x3D
+#define AK_NP8 0x3E
+#define AK_NP9 0x3F
+
+#define AK_NPDIV 0x5C
+#define AK_NPMUL 0x5D
+#define AK_NPSUB 0x4A
+#define AK_NPADD 0x5E
+#define AK_NPDEL 0x3C
+#define AK_NPLPAREN 0x5A
+#define AK_NPRPAREN 0x5B
+
+#define AK_F1 0x50
+#define AK_F2 0x51
+#define AK_F3 0x52
+#define AK_F4 0x53
+#define AK_F5 0x54
+#define AK_F6 0x55
+#define AK_F7 0x56
+#define AK_F8 0x57
+#define AK_F9 0x58
+#define AK_F10 0x59
+
+#define AK_UP 0x4C
+#define AK_DN 0x4D
+#define AK_LF 0x4F
+#define AK_RT 0x4E
+
+#define AK_SPC 0x40
+#define AK_BS 0x41
+#define AK_TAB 0x42
+#define AK_ENT 0x43
+#define AK_RET 0x44
+#define AK_ESC 0x45
+#define AK_DEL 0x46
+
+#define AK_LSH 0x60
+#define AK_RSH 0x61
+#define AK_CAPSLOCK 0x62
+#define AK_CTRL 0x63
+#define AK_LALT 0x64
+#define AK_RALT 0x65
+#define AK_LAMI 0x66
+#define AK_RAMI 0x67
+#define AK_HELP 0x5F
+
+namespace Freescape {
+
+int FreescapeEngine::decodeAmigaAtariKey(int code) {
+	switch (code) {
+		case (AK_UP):
+		return Common::KEYCODE_UP;
+
+		case (AK_DN):
+		return Common::KEYCODE_DOWN;
+
+		case (AK_LF):
+		return Common::KEYCODE_LEFT;
+
+		case (AK_RT):
+		return Common::KEYCODE_RIGHT;
+
+		default:
+		return code;
+	}
+}
+
+static const int dosKeyTable[] = {
+	0,
+	Common::KEYCODE_r,
+	Common::KEYCODE_f,
+	Common::KEYCODE_UP,
+	Common::KEYCODE_DOWN,
+	Common::KEYCODE_LEFT,
+	Common::KEYCODE_RIGHT,
+	Common::KEYCODE_p,
+	Common::KEYCODE_l,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	Common::KEYCODE_d
+};
+
+int FreescapeEngine::decodeDOSKey(int index) {
+	if (index <= 40)
+		return dosKeyTable[index];
+	error("Invalid key index: %d", index);
+}
+
+} // End of namespace Freescape
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 8f675cd3f2a..54de1f502a2 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -438,14 +438,16 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	else
 		file->seek(offset + 0x46);
 
-	uint16 globalSomething;
-	globalSomething = readField(file, 16);
-	debugC(1, kFreescapeDebugParser, "Pointer to something: %x\n", globalSomething);
+	uint16 demoDataTable;
+	demoDataTable = readField(file, 16);
+	debugC(1, kFreescapeDebugParser, "Pointer to demo data: %x\n", demoDataTable);
 
 	uint16 globalByteCodeTable;
 	globalByteCodeTable = readField(file, 16);
 	debugC(1, kFreescapeDebugParser, "GBCT: %x\n", globalByteCodeTable);
 
+	loadDemoData(file, offset + demoDataTable, 128); // TODO: check this size
+
 	file->seek(offset + globalByteCodeTable);
 	debugC(1, kFreescapeDebugParser, "Position: %lx\n", file->pos());
 
@@ -545,6 +547,17 @@ void FreescapeEngine::loadMessagesFixedSize(Common::SeekableReadStream *file, in
 
 void FreescapeEngine::loadDemoData(Common::SeekableReadStream *file, int offset, int size) {
 	file->seek(offset);
+	if (isAmiga()) {
+		_demoData.push_back(0x50);
+		_demoData.push_back(0x64);
+		_demoData.push_back(0x30);
+		_demoData.push_back(0x00);
+		_demoData.push_back(0x64);
+		_demoData.push_back(0x64);
+		_demoData.push_back(0x5F);
+		_demoData.push_back(0x00);
+	}
+
 	debugC(1, kFreescapeDebugParser, "Reading demo data");
 	for (int i = 0; i < size; i++) {
 		byte b = file->readByte();
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index f9df6ea1c84..29c53601cbb 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -12,6 +12,7 @@ MODULE_OBJS := \
 	gfx.o \
 	gfx_tinygl.o \
 	gfx_tinygl_texture.o \
+	keyboard.o \
 	objects/object.o \
 	objects/entrance.o \
 	objects/geometricobject.o \


Commit: c08dde399689aa1a1ebd5af82b343b4426cbb9c7
    https://github.com/scummvm/scummvm/commit/c08dde399689aa1a1ebd5af82b343b4426cbb9c7
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:25+01:00

Commit Message:
FREESCAPE: added border image for space station oblivion and make sure it is loaded

Changed paths:
    dists/engine-data/freescape.dat
    engines/freescape/games/driller.cpp


diff --git a/dists/engine-data/freescape.dat b/dists/engine-data/freescape.dat
index 1d571c56ec4..07b6723b490 100644
Binary files a/dists/engine-data/freescape.dat and b/dists/engine-data/freescape.dat differ
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 6068ae5e7bf..1b3ae722f31 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -266,6 +266,7 @@ void DrillerEngine::loadAssetsFullGame() {
 		}
 	} else if (_renderMode == "ega") {
 		loadBundledImages();
+		_title = _border;
 		file = gameDir.createReadStreamForMember("DRILLE.EXE");
 
 		if (file == nullptr)
@@ -277,6 +278,7 @@ void DrillerEngine::loadAssetsFullGame() {
 		load8bitBinary(file, 0x9b40, 16);
 	} else if (_renderMode == "cga") {
 		loadBundledImages();
+		_title = _border;
 		file = gameDir.createReadStreamForMember("DRILLC.EXE");
 
 		if (file == nullptr)


Commit: 3d620f9cf6cf1d8a1003e90d0e682e3248e87161
    https://github.com/scummvm/scummvm/commit/3d620f9cf6cf1d8a1003e90d0e682e3248e87161
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:25+01:00

Commit Message:
FREESCAPE: correctly draw the first frame without getting any input

Changed paths:
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 8f756e6262c..dc2de6a1c03 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -161,7 +161,6 @@ void FreescapeEngine::drawUI() {
 	_gfx->setViewport(_viewArea);
 }
 
-
 void FreescapeEngine::drawFrame() {
 	_gfx->updateProjectionMatrix(60.0, _nearClipPlane, _farClipPlane);
 	_gfx->positionCamera(_position, _position + _cameraFront);
@@ -347,7 +346,6 @@ Common::Error FreescapeEngine::run() {
 	}
 
 	if (_border) {
-
 		_borderTexture = nullptr;
 		_border->fillRect(_viewArea, 0xA0A0A0FF);
 	}
@@ -359,6 +357,13 @@ Common::Error FreescapeEngine::run() {
 	debugC(1, kFreescapeDebugMove, "Starting area %d", _currentArea->getAreaID());
 	_system->lockMouse(true);
 	bool endGame = false;
+	// Draw first frame
+
+	rotate(_lastMousePos, _lastMousePos);
+	drawFrame();
+	_gfx->flipBuffer();
+	g_system->updateScreen();
+
 	while (!shouldQuit() && !endGame) {
 		drawFrame();
 		if (_demoMode)
@@ -387,28 +392,28 @@ void FreescapeEngine::initGameState() {
 }
 
 void FreescapeEngine::rotate(Common::Point lastMousePos, Common::Point mousePos) {
-	if (lastMousePos == Common::Point(0, 0))
-		return;
-	//debug("x: %d, y: %d", mousePos.x, mousePos.y);
-	float xoffset = mousePos.x - lastMousePos.x;
-	float yoffset = mousePos.y - lastMousePos.y;
-
-	xoffset *= _mouseSensitivity;
-	yoffset *= _mouseSensitivity;
-
-	_yaw -= xoffset;
-	_pitch += yoffset;
-
-	// Make sure that when pitch is out of bounds, screen doesn't get flipped
-	if (_pitch > 360.0f)
-		_pitch -= 360.0f;
-	if (_pitch < 0.0f)
-		_pitch += 360.0f;
-
-	if (_yaw > 360.0f)
-		_yaw -= 360.0f;
-	if (_yaw < 0.0f)
-		_yaw += 360.0f;
+	if (lastMousePos != Common::Point(0, 0)) {
+		//debug("x: %d, y: %d", mousePos.x, mousePos.y);
+		float xoffset = mousePos.x - lastMousePos.x;
+		float yoffset = mousePos.y - lastMousePos.y;
+
+		xoffset *= _mouseSensitivity;
+		yoffset *= _mouseSensitivity;
+
+		_yaw -= xoffset;
+		_pitch += yoffset;
+
+		// Make sure that when pitch is out of bounds, screen doesn't get flipped
+		if (_pitch > 360.0f)
+			_pitch -= 360.0f;
+		if (_pitch < 0.0f)
+			_pitch += 360.0f;
+
+		if (_yaw > 360.0f)
+			_yaw -= 360.0f;
+		if (_yaw < 0.0f)
+			_yaw += 360.0f;
+	}
 
 	_cameraFront = directionToVector(_pitch, _yaw);
 


Commit: 75abc87a09030741acb510b5872cd4c14b77ce3e
    https://github.com/scummvm/scummvm/commit/75abc87a09030741acb510b5872cd4c14b77ce3e
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:26+01:00

Commit Message:
FREESCAPE: play restored music in driller, if it is available

Changed paths:
    engines/freescape/freescape.h
    engines/freescape/games/driller.cpp
    engines/freescape/movement.cpp
    engines/freescape/sound.cpp


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 4d0e54e1a4f..03d0ce69313 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -225,10 +225,12 @@ public:
 	void executePrint(FCLInstruction &instruction);
 
 	// Sound
-	Audio::SoundHandle _handle;
+	Audio::SoundHandle _soundFxHandle;
+	Audio::SoundHandle _musicHandle;
 	bool _usePrerecordedSounds;
 	void playSound(int index, bool sync);
 	void playWav(const Common::String filename);
+	void playMusic(const Common::String filename);
 	void playSoundConst(double hzFreq, int duration, bool sync);
 	void playSoundSweepIncWL(double hzFreq1, double hzFreq2, double wlStepPerMS, int resolution, bool sync);
 	void playTeleporter(int totalIters, bool sync);
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 1b3ae722f31..631b83f8dfa 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -208,6 +208,9 @@ void DrillerEngine::loadAssetsDemo() {
 	}
 	else
 		error("Unsupported demo for Driller");
+
+	// Start playing music, if any
+	playMusic("Matt Gray - The Best Of Reformation - 07 Driller Theme.ogg");
 }
 
 
@@ -286,6 +289,9 @@ void DrillerEngine::loadAssetsFullGame() {
 		load8bitBinary(file, 0x7bb0, 4);
 	} else
 		error("Invalid render mode %s for Driller", _renderMode.c_str());
+
+	// Start playing music, if any
+	playMusic("Matt Gray - The Best Of Reformation - 07 Driller Theme.ogg");
 }
 
 void DrillerEngine::drawUI() {
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index e8c50984c65..22eccc24dc3 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -50,7 +50,7 @@ void FreescapeEngine::traverseEntrance(uint16 entranceID) {
 
 void FreescapeEngine::shoot() {
 	playSound(1, true);
-	_mixer->stopAll();
+	_mixer->stopHandle(_soundFxHandle);
 	_gfx->renderShoot(0);
 	Math::Vector3d direction = directionToVector(_pitch, _yaw);
 	Math::Ray ray(_position, direction);
diff --git a/engines/freescape/sound.cpp b/engines/freescape/sound.cpp
index c71fbfdcb00..b9164903593 100644
--- a/engines/freescape/sound.cpp
+++ b/engines/freescape/sound.cpp
@@ -19,8 +19,11 @@
  *
  */
 
-#include "freescape/freescape.h"
 #include "audio/decoders/raw.h"
+#include "audio/decoders/vorbis.h"
+#include "common/file.h"
+
+#include "freescape/freescape.h"
 
 namespace Freescape {
 
@@ -29,8 +32,8 @@ namespace Freescape {
 const double kFreescapeSweepTuneFactor = 10.0;
 
 void FreescapeEngine::playSound(int index, bool sync) {
-	//if (!_mixer->isSoundHandleActive(_handle))
-	//	_mixer->stopHandle(_handle);
+	//if (!_mixer->isSoundHandleActive(_soundFxHandle))
+	//	_mixer->stopHandle(_soundFxHandle);
 
 	debugC(1, kFreescapeDebugMedia, "Playing sound %d with sync: %d", index, sync);
 	if (isAmiga() || isAtariST()) {
@@ -223,7 +226,21 @@ void FreescapeEngine::playWav(const Common::String filename) {
 	Common::SeekableReadStream *s = _dataBundle->createReadStreamForMember(filename);
 	assert(s);
 	Audio::AudioStream *stream = Audio::makeWAVStream(s, DisposeAfterUse::YES);
-	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_handle, stream);
+	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundFxHandle, stream);
+}
+
+void FreescapeEngine::playMusic(const Common::String filename) {
+	Common::File *file = new Common::File();
+
+	if (!file->open(filename)) {
+		debugC(1, kFreescapeDebugMedia, "Unable to find sound file %s", filename.c_str());
+		return;
+	}
+
+	Audio::LoopingAudioStream *stream;
+	stream = new Audio::LoopingAudioStream(Audio::makeVorbisStream(file, DisposeAfterUse::YES), 0);
+	_mixer->playStream(Audio::Mixer::kMusicSoundType, &_musicHandle, stream);
+	_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, Audio::Mixer::kMaxMixerVolume / 4);
 }
 
 void FreescapeEngine::playSoundFx(int index, bool sync) {
@@ -240,7 +257,7 @@ void FreescapeEngine::playSoundFx(int index, bool sync) {
 	if (size > 4) {
 		Audio::SeekableAudioStream *s = Audio::makeRawStream(data, size, sampleRate, Audio::FLAG_16BITS, DisposeAfterUse::NO);
 		Audio::AudioStream *stream = new Audio::LoopingAudioStream(s, loops);
-		_mixer->playStream(Audio::Mixer::kSFXSoundType, &_handle, stream);
+		_mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundFxHandle, stream);
 	}
 }
 
@@ -248,7 +265,7 @@ void FreescapeEngine::playSoundConst(double hzFreq, int duration, bool sync) {
 	Audio::PCSpeaker *speaker = new Audio::PCSpeaker();
 	speaker->setVolume(50);
 	speaker->play(Audio::PCSpeaker::kWaveFormSquare, hzFreq, duration);
-	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_handle, speaker);
+	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundFxHandle, speaker);
 	if (sync) {
 		_system->delayMillis(duration);
 	}
@@ -300,7 +317,7 @@ void FreescapeEngine::playSoundSweepIncWL(double hzFreq1, double hzFreq2, double
 		playSoundConst((1193180.0 / inv1), resolution, sync);
 		inv1 += wlStep;
 	}
-	_mixer->stopHandle(_handle);
+	_mixer->stopHandle(_soundFxHandle);
 }
 
 void FreescapeEngine::playTeleporter(int totalIters, bool sync) {


Commit: 0626f55090d2a94a253dbb7c878286c874bd6931
    https://github.com/scummvm/scummvm/commit/0626f55090d2a94a253dbb7c878286c874bd6931
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:26+01:00

Commit Message:
FREESCAPE: bind keys for turn left/right and look up/down in driller

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index dc2de6a1c03..d5e9f0fff6f 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -68,6 +68,7 @@ FreescapeEngine::FreescapeEngine(OSystem *syst, const ADGameDescription *gd)
 	_velocity = Math::Vector3d(0.f, 0.f, 0.f);
 	_cameraFront = Math::Vector3d(0.f, 0.f, 0.f);
 	_cameraRight = Math::Vector3d(0.f, 0.f, 0.f);
+	_upVector =	Math::Vector3d(0, 1.0f, 0);
 	_movementSpeed = 1.5f;
 	_mouseSensitivity = 0.25f;
 	_demoMode = false;
@@ -241,12 +242,20 @@ void FreescapeEngine::processInput() {
 				move(FORWARD, _scaleVector.x(), deltaTime);
 			else if (event.kbd.keycode == Common::KEYCODE_k || event.kbd.keycode == Common::KEYCODE_DOWN)
 				move(BACKWARD, _scaleVector.x(), deltaTime);
-			else if (event.kbd.keycode == Common::KEYCODE_q || event.kbd.keycode == Common::KEYCODE_LEFT)
+			else if (event.kbd.keycode == Common::KEYCODE_LEFT)
 				move(LEFT, _scaleVector.y(), deltaTime);
-			else if (event.kbd.keycode == Common::KEYCODE_w || event.kbd.keycode == Common::KEYCODE_RIGHT)
+			else if (event.kbd.keycode == Common::KEYCODE_RIGHT)
 				move(RIGHT, _scaleVector.y(), deltaTime);
 			else if (event.kbd.keycode == Common::KEYCODE_KP5 || event.kbd.keycode == Common::KEYCODE_KP0)
 				shoot();
+			else if (event.kbd.keycode == Common::KEYCODE_p)
+				rotate(0, 5);
+			else if (event.kbd.keycode == Common::KEYCODE_l)
+				rotate(0, -5);
+			else if (event.kbd.keycode == Common::KEYCODE_q)
+				rotate(5, 0);
+			else if (event.kbd.keycode == Common::KEYCODE_w)
+				rotate(-5, 0);
 			else if (event.kbd.keycode == Common::KEYCODE_r)
 				rise();
 			else if (event.kbd.keycode == Common::KEYCODE_f)
@@ -391,6 +400,24 @@ void FreescapeEngine::initGameState() {
 		_gameStateBits[it->_key] = 0;
 }
 
+void FreescapeEngine::rotate(float xoffset, float yoffset) {
+	_yaw -= xoffset;
+	_pitch += yoffset;
+
+	// Make sure that when pitch is out of bounds, screen doesn't get flipped
+	if (_pitch > 360.0f)
+		_pitch -= 360.0f;
+	if (_pitch < 0.0f)
+		_pitch += 360.0f;
+
+	if (_yaw > 360.0f)
+		_yaw -= 360.0f;
+	if (_yaw < 0.0f)
+		_yaw += 360.0f;
+
+	updateCamera();
+}
+
 void FreescapeEngine::rotate(Common::Point lastMousePos, Common::Point mousePos) {
 	if (lastMousePos != Common::Point(0, 0)) {
 		//debug("x: %d, y: %d", mousePos.x, mousePos.y);
@@ -414,12 +441,13 @@ void FreescapeEngine::rotate(Common::Point lastMousePos, Common::Point mousePos)
 		if (_yaw < 0.0f)
 			_yaw += 360.0f;
 	}
+	updateCamera();
+}
 
+void FreescapeEngine::updateCamera() {
 	_cameraFront = directionToVector(_pitch, _yaw);
-
-	// // _right = _front x _up;
-	Math::Vector3d up(0, 1, 0); // this should be const
-	Math::Vector3d v = Math::Vector3d::crossProduct(_cameraFront, up);
+	// _right = _front x _up;
+	Math::Vector3d v = Math::Vector3d::crossProduct(_cameraFront, _upVector);
 	v.normalize();
 	_cameraRight = v;
 }
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 03d0ce69313..72c054ce590 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -168,22 +168,25 @@ public:
 	bool tryStepDown(Math::Vector3d currentPosition);
 
 	void rotate(Common::Point lastMousePos, Common::Point mousePos);
+	void rotate(float xoffset, float yoffset);
 	// Input state
 	float _lastFrame;
 	Common::Point _lastMousePos;
 
 	// Interaction
 	void shoot();
+	void traverseEntrance(uint16 entranceID);
 
 	// Euler Angles
 	float _yaw;
 	float _pitch;
-	void traverseEntrance(uint16 entranceID);
 	Math::Vector3d directionToVector(float pitch, float heading);
+	void updateCamera();
 
 	// Camera options
 	float _mouseSensitivity;
 	float _movementSpeed;
+	Math::Vector3d _upVector; // const
 	Math::Vector3d _cameraFront, _cameraRight;
 	// Spacial attributes
 	Math::Vector3d _position, _rotation, _velocity;


Commit: 0fb16f16daaafd055225b03822f8bd3e457dd259
    https://github.com/scummvm/scummvm/commit/0fb16f16daaafd055225b03822f8bd3e457dd259
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:26+01:00

Commit Message:
FREESCAPE: improved demo replaying to decode all the presed keys in DOS

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/keyboard.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index d5e9f0fff6f..67b7200ae75 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -73,6 +73,8 @@ FreescapeEngine::FreescapeEngine(OSystem *syst, const ADGameDescription *gd)
 	_mouseSensitivity = 0.25f;
 	_demoMode = false;
 	_demoIndex = 0;
+	_currentDemoInputCode = 0;
+	_currentDemoInputRepetition = 0;
 	_flyMode = false;
 	_noClipMode = false;
 	_playerHeightNumber = 1;
@@ -174,31 +176,42 @@ void FreescapeEngine::pressedKey(const int keycode) {}
 
 void FreescapeEngine::generateInput() {
 	Common::Event event;
-
-	g_system->getEventManager()->purgeKeyboardEvents();
+	//g_system->getEventManager()->purgeKeyboardEvents();
 	if (isDOS()) {
-		byte repetition = 1;
-		byte keyIndex = _demoData[_demoIndex++];
 
-		if (keyIndex >= 0x80) {
-			repetition = keyIndex / 32;
-			keyIndex = _demoData[_demoIndex++];
+		if (_currentDemoInputRepetition == 0) {
+			_currentDemoInputRepetition = 1;
+			_currentDemoInputCode = _demoData[_demoIndex++];
+			if (_currentDemoInputCode >= 0x80) {
+				_currentDemoInputRepetition = _currentDemoInputCode - 0x80;
+				assert(_currentDemoInputRepetition > 0);
+				_currentDemoInputCode = _demoData[_demoIndex++];
+			}
 		}
 
-		event = Common::Event();
-		event.type = Common::EVENT_KEYDOWN;
-		event.kbd.keycode = (Common::KeyCode)decodeDOSKey(keyIndex);
-		event.customType = 0xde00;
-
-		while(repetition-- > 0) {
-			debug("Pushing key: %x", event.kbd.keycode);
+		if (_currentDemoInputCode >= 0x16 && _currentDemoInputCode <= 0x1a) {
+			// 0x16 -> left click / shoot
+			// 0x17 -> right?
+			// 0x18 -> left
+			// 0x19 -> down?
+			// 0x1a -> up
+			// TODO: mouse events
+		} else if (_currentDemoInputCode == 0x7f) {
+			// TODO: wait?
+		} else {
+			event = Common::Event();
+			event.type = Common::EVENT_KEYDOWN;
+			event.kbd.keycode = (Common::KeyCode)decodeDOSKey(_currentDemoInputCode);
+			event.customType = 0xde00;
 			g_system->getEventManager()->pushEvent(event);
+			debug("Pushing key: %x with repetition %d", event.kbd.keycode, _currentDemoInputRepetition);
 		}
-		g_system->delayMillis(100);
+		_currentDemoInputRepetition--;
+		g_system->delayMillis(50);
 		return;
 	}
 
-	int mouseX = _demoData[_demoIndex++] << 1;
+	/*int mouseX = _demoData[_demoIndex++] << 1;
 	int mouseY = _demoData[_demoIndex++];
 	debug("Mouse moved to: %d, %d", mouseX, mouseY);
 
@@ -219,7 +232,7 @@ void FreescapeEngine::generateInput() {
 		g_system->getEventManager()->pushEvent(event);
 
 		nextKeyCode = _demoData[_demoIndex++];
-	}
+	}*/
 
 	g_system->delayMillis(200);
 }
@@ -232,12 +245,13 @@ void FreescapeEngine::processInput() {
 	while (g_system->getEventManager()->pollEvent(event)) {
 		Common::Point mousePos = g_system->getEventManager()->getMousePos();
 
-		switch (event.type) {
-		case Common::EVENT_KEYDOWN:
-			if (_demoMode && event.customType != 0xde00) {
+		if (_demoMode) {
+			if (event.customType != 0xde00)
 				continue;
-			}
+		}
 
+		switch (event.type) {
+		case Common::EVENT_KEYDOWN:
 			if (event.kbd.keycode == Common::KEYCODE_o || event.kbd.keycode == Common::KEYCODE_UP)
 				move(FORWARD, _scaleVector.x(), deltaTime);
 			else if (event.kbd.keycode == Common::KEYCODE_k || event.kbd.keycode == Common::KEYCODE_DOWN)
@@ -253,9 +267,9 @@ void FreescapeEngine::processInput() {
 			else if (event.kbd.keycode == Common::KEYCODE_l)
 				rotate(0, -5);
 			else if (event.kbd.keycode == Common::KEYCODE_q)
-				rotate(5, 0);
+				rotate(-5.3, 0);
 			else if (event.kbd.keycode == Common::KEYCODE_w)
-				rotate(-5, 0);
+				rotate(5.3, 0);
 			else if (event.kbd.keycode == Common::KEYCODE_r)
 				rise();
 			else if (event.kbd.keycode == Common::KEYCODE_f)
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 72c054ce590..b7ed13b0149 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -127,6 +127,8 @@ public:
 	void loadColorPalette();
 	Common::Array<byte> _demoData;
 	int _demoIndex;
+	int _currentDemoInputCode;
+	int _currentDemoInputRepetition;
 	void loadDemoData(Common::SeekableReadStream *file, int offset, int size);
 	int decodeAmigaAtariKey(int code);
 	int decodeDOSKey(int code);
diff --git a/engines/freescape/keyboard.cpp b/engines/freescape/keyboard.cpp
index 505db0afa4b..10337a1ad5e 100644
--- a/engines/freescape/keyboard.cpp
+++ b/engines/freescape/keyboard.cpp
@@ -135,55 +135,32 @@ int FreescapeEngine::decodeAmigaAtariKey(int code) {
 	}
 }
 
-static const int dosKeyTable[] = {
-	0,
-	Common::KEYCODE_r,
-	Common::KEYCODE_f,
-	Common::KEYCODE_UP,
-	Common::KEYCODE_DOWN,
-	Common::KEYCODE_LEFT,
-	Common::KEYCODE_RIGHT,
-	Common::KEYCODE_p,
-	Common::KEYCODE_l,
-	0,
-	0,
-	0,
-	0,
-	0,
-	0,
-	0,
-	0,
-	0,
-	0,
-	0,
-	0,
-	0,
-	0,
-	0,
-	0,
-	0,
-	0,
-	0,
-	0,
-	0,
-	0,
-	0,
-	0,
-	0,
-	0,
-	0,
-	0,
-	0,
-	0,
-	0,
-	0,
-	Common::KEYCODE_d
-};
-
 int FreescapeEngine::decodeDOSKey(int index) {
-	if (index <= 40)
-		return dosKeyTable[index];
-	error("Invalid key index: %d", index);
+	switch (index) {
+		case 1:
+			return 	Common::KEYCODE_r;
+		case 2:
+			return Common::KEYCODE_f;
+		case 3:
+			return Common::KEYCODE_UP;
+		case 4:
+			return Common::KEYCODE_DOWN;
+		case 5:
+			return Common::KEYCODE_q;
+		case 6:
+			return Common::KEYCODE_w;
+		case 7:
+			return Common::KEYCODE_p;
+		case 8:
+			return Common::KEYCODE_l;
+		case 30:
+			return Common::KEYCODE_SPACE;
+		case 40:
+			return Common::KEYCODE_d;
+		default:
+			error("Invalid key index: %x", index);
+	}
+	return 0;
 }
 
 } // End of namespace Freescape


Commit: b620c2a407a94f440b19e7055412278ecb9ffbde
    https://github.com/scummvm/scummvm/commit/b620c2a407a94f440b19e7055412278ecb9ffbde
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:26+01:00

Commit Message:
FREESCAPE: move/shoot move first implementation

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/dark.cpp
    engines/freescape/games/driller.cpp
    engines/freescape/games/eclipse.cpp
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/gfx_tinygl.h
    engines/freescape/movement.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 67b7200ae75..ea894d286af 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -72,6 +72,9 @@ FreescapeEngine::FreescapeEngine(OSystem *syst, const ADGameDescription *gd)
 	_movementSpeed = 1.5f;
 	_mouseSensitivity = 0.25f;
 	_demoMode = false;
+	_shootMode = false;
+	_crossairPosition.x = _screenW / 2;
+	_crossairPosition.y = _screenH / 2;
 	_demoIndex = 0;
 	_currentDemoInputCode = 0;
 	_currentDemoInputRepetition = 0;
@@ -160,7 +163,7 @@ Math::Vector3d FreescapeEngine::directionToVector(float pitch, float heading) {
 }
 
 void FreescapeEngine::drawUI() {
-	_gfx->renderCrossair(0);
+	_gfx->renderCrossair(0, _crossairPosition);
 	_gfx->setViewport(_viewArea);
 }
 
@@ -279,7 +282,13 @@ void FreescapeEngine::processInput() {
 				_flyMode = _noClipMode;
 			} else if (event.kbd.keycode == Common::KEYCODE_ESCAPE)
 				openMainMenuDialog();
-			else
+			else if (event.kbd.keycode == Common::KEYCODE_SPACE) {
+				_shootMode = !_shootMode;
+				if (!_shootMode) {
+					_crossairPosition.x = _screenW / 2;
+					_crossairPosition.y = _screenH / 2;
+				}
+			} else
 				pressedKey(event.kbd.keycode);
 			break;
 
@@ -290,6 +299,11 @@ void FreescapeEngine::processInput() {
 			break;
 
 		case Common::EVENT_MOUSEMOVE:
+			if (_shootMode) {
+				_crossairPosition = mousePos;
+				break;
+			}
+
 			if (mousePos.x <= 5 || mousePos.x >= _screenW - 5) {
 				g_system->warpMouse(_screenW / 2, mousePos.y);
 
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index b7ed13b0149..45aedf27c10 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -157,6 +157,7 @@ public:
 	// Input
 	bool _demoMode;
 	bool _flyMode;
+	bool _shootMode;
 	bool _noClipMode;
 	void processInput();
 	void generateInput();
@@ -186,6 +187,7 @@ public:
 	void updateCamera();
 
 	// Camera options
+	Common::Point _crossairPosition;
 	float _mouseSensitivity;
 	float _movementSpeed;
 	Math::Vector3d _upVector; // const
diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index 2b9c41095b4..1ef078dcfc0 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -116,7 +116,7 @@ void DarkEngine::gotoArea(uint16 areaID, int entranceID) {
 
 
 void DarkEngine::drawUI() {
-	_gfx->renderCrossair(0);
+	_gfx->renderCrossair(0, _crossairPosition);
 
 	if (_currentAreaMessages.size() == 1) {
 		_gfx->setViewport(_fullscreenViewArea);
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 631b83f8dfa..49ad881a575 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -295,7 +295,7 @@ void DrillerEngine::loadAssetsFullGame() {
 }
 
 void DrillerEngine::drawUI() {
-	_gfx->renderCrossair(0);
+	_gfx->renderCrossair(0, _crossairPosition);
 
 	if (_currentAreaMessages.size() == 2) {
 		_gfx->setViewport(_fullscreenViewArea);
diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index 2027bf6e366..e998edb4d9d 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -175,7 +175,7 @@ void EclipseEngine::gotoArea(uint16 areaID, int entranceID) {
 
 
 void EclipseEngine::drawUI() {
-	_gfx->renderCrossair(0);
+	_gfx->renderCrossair(0, _crossairPosition);
 	_gfx->setViewport(_fullscreenViewArea);
 
 	Graphics::Surface *surface = new Graphics::Surface();
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 5551c5e3bb8..ab305beb50c 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -89,8 +89,8 @@ public:
 	virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture) = 0;
 	virtual void drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint8 g, uint8 b) = 0;
 
-	virtual void renderCrossair(byte color) = 0;
-	virtual void renderShoot(byte color) = 0;
+	virtual void renderCrossair(byte color, const Common::Point position) = 0;
+	virtual void renderShoot(byte color, const Common::Point position) = 0;
 	virtual void renderCube(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) = 0;
 	virtual void renderRectangle(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) = 0;
 	virtual void renderPolygon(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours) = 0;
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 4c9cd63382b..d85c7de476a 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -136,7 +136,7 @@ void TinyGLRenderer::drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint
 	tglDisable(TGL_BLEND);
 }
 
-void TinyGLRenderer::renderCrossair(byte color) {
+void TinyGLRenderer::renderCrossair(byte color, const Common::Point position) {
 	uint8 r, g, b;
 	_palette->getRGBAt(color, r, g, b); // TODO: should use opposite color
 
@@ -152,18 +152,18 @@ void TinyGLRenderer::renderCrossair(byte color) {
 	tglColor3ub(r, g, b);
 
 	tglBegin(TGL_LINES);
-	tglVertex2f(_screenW / 2 - 1, _screenH / 2);
-	tglVertex2f(_screenW / 2 + 3, _screenH / 2);
+	tglVertex2f(position.x - 1, position.y);
+	tglVertex2f(position.x + 3, position.y);
 
-	tglVertex2f(_screenW / 2, _screenH / 2 - 3);
-	tglVertex2f(_screenW / 2, _screenH / 2 + 3);
+	tglVertex2f(position.x, position.y - 3);
+	tglVertex2f(position.x, position.y + 3);
 	tglEnd();
 
 	tglDepthMask(TGL_TRUE);
 	tglEnable(TGL_DEPTH_TEST);
 }
 
-void TinyGLRenderer::renderShoot(byte color) {
+void TinyGLRenderer::renderShoot(byte color, const Common::Point position) {
 	uint8 r, g, b;
 	_palette->getRGBAt(color, r, g, b); // TODO: should use opposite color
 
@@ -183,16 +183,16 @@ void TinyGLRenderer::renderShoot(byte color) {
 
 	tglBegin(TGL_LINES);
 	tglVertex2f(0, _screenH - 2);
-	tglVertex2f(_screenW / 2, _screenH / 2);
+	tglVertex2f(position.x, position.y);
 
 	tglVertex2f(0, _screenH - 2);
-	tglVertex2f(_screenW / 2, _screenH / 2);
+	tglVertex2f(position.x, position.y);
 
 	tglVertex2f(_screenW, _screenH - 2);
-	tglVertex2f(_screenW / 2, _screenH / 2);
+	tglVertex2f(position.x, position.y);
 
 	tglVertex2f(_screenW, _screenH);
-	tglVertex2f(_screenW / 2, _screenH / 2);
+	tglVertex2f(position.x, position.y);
 
 	tglEnd();
 
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index 3db349a2bf4..03d76f2da5d 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -45,8 +45,8 @@ public:
 	virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture) override;
 	virtual void drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint8 g, uint8 b);
 
-	virtual void renderCrossair(byte color) override;
-	virtual void renderShoot(byte color) override;
+	virtual void renderCrossair(byte color, const Common::Point position) override;
+	virtual void renderShoot(byte color, const Common::Point position) override;
 	virtual void renderCube(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) override;
 	virtual void renderRectangle(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) override;
 	virtual void renderPolygon(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours) override;
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index 22eccc24dc3..a5f4e0cf887 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -51,8 +51,12 @@ void FreescapeEngine::traverseEntrance(uint16 entranceID) {
 void FreescapeEngine::shoot() {
 	playSound(1, true);
 	_mixer->stopHandle(_soundFxHandle);
-	_gfx->renderShoot(0);
-	Math::Vector3d direction = directionToVector(_pitch, _yaw);
+	_gfx->renderShoot(0, _crossairPosition);
+
+	float xoffset = _crossairPosition.x - _screenW / 2;
+	float yoffset = _crossairPosition.y - _screenH / 2;
+
+	Math::Vector3d direction = directionToVector(_pitch + yoffset, _yaw - xoffset);
 	Math::Ray ray(_position, direction);
 	Object *shot = _currentArea->shootRay(ray);
 	if (shot) {


Commit: 402ddc5d957c894e06c7206ab1b9d9e2b9ce8d6a
    https://github.com/scummvm/scummvm/commit/402ddc5d957c894e06c7206ab1b9d9e2b9ce8d6a
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:26+01:00

Commit Message:
FREESCAPE: renamed Movement data type

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/movement.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index ea894d286af..950504941ec 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -256,13 +256,13 @@ void FreescapeEngine::processInput() {
 		switch (event.type) {
 		case Common::EVENT_KEYDOWN:
 			if (event.kbd.keycode == Common::KEYCODE_o || event.kbd.keycode == Common::KEYCODE_UP)
-				move(FORWARD, _scaleVector.x(), deltaTime);
+				move(kForwardMovement, _scaleVector.x(), deltaTime);
 			else if (event.kbd.keycode == Common::KEYCODE_k || event.kbd.keycode == Common::KEYCODE_DOWN)
-				move(BACKWARD, _scaleVector.x(), deltaTime);
+				move(kBackwardMovement, _scaleVector.x(), deltaTime);
 			else if (event.kbd.keycode == Common::KEYCODE_LEFT)
-				move(LEFT, _scaleVector.y(), deltaTime);
+				move(kLeftMovement, _scaleVector.y(), deltaTime);
 			else if (event.kbd.keycode == Common::KEYCODE_RIGHT)
-				move(RIGHT, _scaleVector.y(), deltaTime);
+				move(kRightMovement, _scaleVector.y(), deltaTime);
 			else if (event.kbd.keycode == Common::KEYCODE_KP5 || event.kbd.keycode == Common::KEYCODE_KP0)
 				shoot();
 			else if (event.kbd.keycode == Common::KEYCODE_p)
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 45aedf27c10..5f90b664f19 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -46,10 +46,10 @@ class Renderer;
 #define FREESCAPE_DATA_BUNDLE Common::String("freescape.dat")
 
 enum CameraMovement {
-    FORWARD,
-    BACKWARD,
-    LEFT,
-    RIGHT
+	kForwardMovement,
+	kBackwardMovement,
+	kLeftMovement,
+	kRightMovement
 };
 
 typedef Common::HashMap<uint16, Area*> AreaMap;
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index a5f4e0cf887..a677b60870d 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -143,16 +143,16 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 	float velocity = _movementSpeed * deltaTime * areaScale;
 	float positionY = _position.y();
 	switch (direction) {
-	case FORWARD:
+	case kForwardMovement:
 		_position = _position + _cameraFront * velocity;
 		break;
-	case BACKWARD:
+	case kBackwardMovement:
 		_position = _position - _cameraFront * velocity;
 		break;
-	case RIGHT:
+	case kRightMovement:
 		_position = _position - _cameraRight * velocity;
 		break;
-	case LEFT:
+	case kLeftMovement:
 		_position = _position + _cameraRight * velocity;
 		break;
 	}


Commit: c99e9c8bfbc1a5ba635650db951f206d1ecfcd9f
    https://github.com/scummvm/scummvm/commit/c99e9c8bfbc1a5ba635650db951f206d1ecfcd9f
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:26+01:00

Commit Message:
FREESCAPE: parse demo bytes in Amiga/AtariST

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/keyboard.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 950504941ec..ec837c1ab0e 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -214,30 +214,35 @@ void FreescapeEngine::generateInput() {
 		return;
 	}
 
-	/*int mouseX = _demoData[_demoIndex++] << 1;
+	int mouseX = _demoData[_demoIndex++] << 1;
 	int mouseY = _demoData[_demoIndex++];
 	debug("Mouse moved to: %d, %d", mouseX, mouseY);
 
-	event.type = Common::EVENT_MOUSEMOVE;
+	/*event.type = Common::EVENT_MOUSEMOVE;
 	event.mouse = Common::Point(mouseX, mouseY);
 	event.customType = 0xde00;
-	g_system->getEventManager()->pushEvent(event);
+	g_system->getEventManager()->pushEvent(event);*/
 
 	byte nextKeyCode = _demoData[_demoIndex++];
-	while(nextKeyCode != 0) {
-
-		event = Common::Event();
-		event.type = Common::EVENT_KEYDOWN;
-		event.kbd.keycode = (Common::KeyCode)decodeAmigaAtariKey(nextKeyCode);
-		debug("Pushing key: %x", nextKeyCode);
-		event.customType = 0xde00;
-		g_system->getEventManager()->pushEvent(event);
-		g_system->getEventManager()->pushEvent(event);
 
+	if (nextKeyCode == 0x30) {
+		//left click / shoot
 		nextKeyCode = _demoData[_demoIndex++];
-	}*/
+	} else {
+		while(nextKeyCode != 0) {
 
-	g_system->delayMillis(200);
+			event = Common::Event();
+			event.type = Common::EVENT_KEYDOWN;
+			event.kbd.keycode = (Common::KeyCode)decodeAmigaAtariKey(nextKeyCode);
+			debug("Pushing key: %x", nextKeyCode);
+			event.customType = 0xde00;
+			g_system->getEventManager()->pushEvent(event);
+			nextKeyCode = _demoData[_demoIndex++];
+		}
+	}
+	assert(!nextKeyCode);
+	//_currentDemoInputRepetition = 0;
+	g_system->delayMillis(100);
 }
 
 void FreescapeEngine::processInput() {
diff --git a/engines/freescape/keyboard.cpp b/engines/freescape/keyboard.cpp
index 10337a1ad5e..1838cfa8501 100644
--- a/engines/freescape/keyboard.cpp
+++ b/engines/freescape/keyboard.cpp
@@ -23,142 +23,69 @@
 
 #include "freescape/freescape.h"
 
-#define AK_A 0x20
-#define AK_B 0x35
-#define AK_C 0x33
-#define AK_D 0x22
-#define AK_E 0x12
-#define AK_F 0x23
-#define AK_G 0x24
-#define AK_H 0x25
-#define AK_I 0x17
-#define AK_J 0x26
-#define AK_K 0x27
-#define AK_L 0x28
-#define AK_M 0x37
-#define AK_N 0x36
-#define AK_O 0x18
-#define AK_P 0x19
-#define AK_Q 0x10
-#define AK_R 0x13
-#define AK_S 0x21
-#define AK_T 0x14
-#define AK_U 0x16
-#define AK_V 0x34
-#define AK_W 0x11
-#define AK_X 0x32
-#define AK_Y 0x15
-#define AK_Z 0x31
-
-#define AK_0 0x0A
-#define AK_1 0x01
-#define AK_2 0x02
-#define AK_3 0x03
-#define AK_4 0x04
-#define AK_5 0x05
-#define AK_6 0x06
-#define AK_7 0x07
-#define AK_8 0x08
-#define AK_9 0x09
-
-#define AK_NP0 0x0F
-#define AK_NP1 0x1D
-#define AK_NP2 0x1E
-#define AK_NP3 0x1F
-#define AK_NP4 0x2D
-#define AK_NP5 0x2E
-#define AK_NP6 0x2F
-#define AK_NP7 0x3D
-#define AK_NP8 0x3E
-#define AK_NP9 0x3F
-
-#define AK_NPDIV 0x5C
-#define AK_NPMUL 0x5D
-#define AK_NPSUB 0x4A
-#define AK_NPADD 0x5E
-#define AK_NPDEL 0x3C
-#define AK_NPLPAREN 0x5A
-#define AK_NPRPAREN 0x5B
-
-#define AK_F1 0x50
-#define AK_F2 0x51
-#define AK_F3 0x52
-#define AK_F4 0x53
-#define AK_F5 0x54
-#define AK_F6 0x55
-#define AK_F7 0x56
-#define AK_F8 0x57
-#define AK_F9 0x58
-#define AK_F10 0x59
-
-#define AK_UP 0x4C
-#define AK_DN 0x4D
-#define AK_LF 0x4F
-#define AK_RT 0x4E
-
-#define AK_SPC 0x40
-#define AK_BS 0x41
-#define AK_TAB 0x42
-#define AK_ENT 0x43
-#define AK_RET 0x44
-#define AK_ESC 0x45
-#define AK_DEL 0x46
-
-#define AK_LSH 0x60
-#define AK_RSH 0x61
-#define AK_CAPSLOCK 0x62
-#define AK_CTRL 0x63
-#define AK_LALT 0x64
-#define AK_RALT 0x65
-#define AK_LAMI 0x66
-#define AK_RAMI 0x67
-#define AK_HELP 0x5F
-
 namespace Freescape {
 
-int FreescapeEngine::decodeAmigaAtariKey(int code) {
-	switch (code) {
-		case (AK_UP):
+int FreescapeEngine::decodeAmigaAtariKey(int index) {
+	switch (index) {
+	case 0x30:
+		return 0; // shoot?
+
+	case 0x44:
+		return Common::KEYCODE_d;
+
+
+	case 0x4c:
+		return Common::KEYCODE_l;
+
+	case 0x50:
+		return Common::KEYCODE_p;
+
+	case 0x55:
+		return 0; // turn around
+
+
+	case 0x96:
 		return Common::KEYCODE_UP;
 
-		case (AK_DN):
+	case 0x97:
 		return Common::KEYCODE_DOWN;
 
-		case (AK_LF):
-		return Common::KEYCODE_LEFT;
+	case 0x98:
+		return Common::KEYCODE_w;
 
-		case (AK_RT):
-		return Common::KEYCODE_RIGHT;
+	case 0x99:
+		return Common::KEYCODE_q;
 
-		default:
-		return code;
+	default:
+		error("Invalid key index: %x", index);
 	}
+	return 0;
 }
 
 int FreescapeEngine::decodeDOSKey(int index) {
 	switch (index) {
-		case 1:
-			return 	Common::KEYCODE_r;
-		case 2:
-			return Common::KEYCODE_f;
-		case 3:
-			return Common::KEYCODE_UP;
-		case 4:
-			return Common::KEYCODE_DOWN;
-		case 5:
-			return Common::KEYCODE_q;
-		case 6:
-			return Common::KEYCODE_w;
-		case 7:
-			return Common::KEYCODE_p;
-		case 8:
-			return Common::KEYCODE_l;
-		case 30:
-			return Common::KEYCODE_SPACE;
-		case 40:
-			return Common::KEYCODE_d;
-		default:
-			error("Invalid key index: %x", index);
+	case 1:
+		return 	Common::KEYCODE_r;
+	case 2:
+		return Common::KEYCODE_f;
+	case 3:
+		return Common::KEYCODE_UP;
+	case 4:
+		return Common::KEYCODE_DOWN;
+	case 5:
+		return Common::KEYCODE_q;
+	case 6:
+		return Common::KEYCODE_w;
+	case 7:
+		return Common::KEYCODE_p;
+	case 8:
+		return Common::KEYCODE_l;
+	case 30:
+		return Common::KEYCODE_SPACE;
+	case 40:
+		return Common::KEYCODE_d;
+	default:
+		error("Invalid key index: %x", index);
 	}
 	return 0;
 }
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 54de1f502a2..b1699f0e970 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -446,7 +446,8 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	globalByteCodeTable = readField(file, 16);
 	debugC(1, kFreescapeDebugParser, "GBCT: %x\n", globalByteCodeTable);
 
-	loadDemoData(file, offset + demoDataTable, 128); // TODO: check this size
+	if (isDOS())
+		loadDemoData(file, offset + demoDataTable, 128); // TODO: check this size
 
 	file->seek(offset + globalByteCodeTable);
 	debugC(1, kFreescapeDebugParser, "Position: %lx\n", file->pos());
@@ -547,7 +548,7 @@ void FreescapeEngine::loadMessagesFixedSize(Common::SeekableReadStream *file, in
 
 void FreescapeEngine::loadDemoData(Common::SeekableReadStream *file, int offset, int size) {
 	file->seek(offset);
-	if (isAmiga()) {
+	/*if (isAmiga()) {
 		_demoData.push_back(0x50);
 		_demoData.push_back(0x64);
 		_demoData.push_back(0x30);
@@ -556,7 +557,7 @@ void FreescapeEngine::loadDemoData(Common::SeekableReadStream *file, int offset,
 		_demoData.push_back(0x64);
 		_demoData.push_back(0x5F);
 		_demoData.push_back(0x00);
-	}
+	}*/
 
 	debugC(1, kFreescapeDebugParser, "Reading demo data");
 	for (int i = 0; i < size; i++) {


Commit: 54399a3e379d68f3f6e567cbbdbbd13bfc0b74da
    https://github.com/scummvm/scummvm/commit/54399a3e379d68f3f6e567cbbdbbd13bfc0b74da
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:27+01:00

Commit Message:
FREESCAPE: enable mouse generation event in Amiga/AtariST demos

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/games/driller.cpp
    engines/freescape/keyboard.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index ec837c1ab0e..368e4d8577b 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -218,19 +218,19 @@ void FreescapeEngine::generateInput() {
 	int mouseY = _demoData[_demoIndex++];
 	debug("Mouse moved to: %d, %d", mouseX, mouseY);
 
-	/*event.type = Common::EVENT_MOUSEMOVE;
+	event.type = Common::EVENT_MOUSEMOVE;
 	event.mouse = Common::Point(mouseX, mouseY);
 	event.customType = 0xde00;
-	g_system->getEventManager()->pushEvent(event);*/
+	g_system->getEventManager()->pushEvent(event);
 
 	byte nextKeyCode = _demoData[_demoIndex++];
 
 	if (nextKeyCode == 0x30) {
-		//left click / shoot
+		event.type = Common::EVENT_LBUTTONDOWN; // Keep same event fields
+		g_system->getEventManager()->pushEvent(event);
 		nextKeyCode = _demoData[_demoIndex++];
 	} else {
 		while(nextKeyCode != 0) {
-
 			event = Common::Event();
 			event.type = Common::EVENT_KEYDOWN;
 			event.kbd.keycode = (Common::KeyCode)decodeAmigaAtariKey(nextKeyCode);
@@ -250,9 +250,8 @@ void FreescapeEngine::processInput() {
 	float deltaTime = 20.0;
 	_lastFrame = currentFrame;
 	Common::Event event;
+	Common::Point mousePos;
 	while (g_system->getEventManager()->pollEvent(event)) {
-		Common::Point mousePos = g_system->getEventManager()->getMousePos();
-
 		if (_demoMode) {
 			if (event.customType != 0xde00)
 				continue;
@@ -304,6 +303,11 @@ void FreescapeEngine::processInput() {
 			break;
 
 		case Common::EVENT_MOUSEMOVE:
+			mousePos = event.mouse;
+
+			if (_demoMode)
+				g_system->warpMouse(mousePos.x, mousePos.y);
+
 			if (_shootMode) {
 				_crossairPosition = mousePos;
 				break;
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 49ad881a575..b8e0629b87c 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -211,6 +211,7 @@ void DrillerEngine::loadAssetsDemo() {
 
 	// Start playing music, if any
 	playMusic("Matt Gray - The Best Of Reformation - 07 Driller Theme.ogg");
+	_demoMode = true;
 }
 
 
diff --git a/engines/freescape/keyboard.cpp b/engines/freescape/keyboard.cpp
index 1838cfa8501..766a5e97dd3 100644
--- a/engines/freescape/keyboard.cpp
+++ b/engines/freescape/keyboard.cpp
@@ -29,33 +29,22 @@ int FreescapeEngine::decodeAmigaAtariKey(int index) {
 	switch (index) {
 	case 0x30:
 		return 0; // shoot?
-
 	case 0x44:
 		return Common::KEYCODE_d;
-
-
 	case 0x4c:
 		return Common::KEYCODE_l;
-
 	case 0x50:
 		return Common::KEYCODE_p;
-
 	case 0x55:
 		return 0; // turn around
-
-
 	case 0x96:
 		return Common::KEYCODE_UP;
-
 	case 0x97:
 		return Common::KEYCODE_DOWN;
-
 	case 0x98:
 		return Common::KEYCODE_w;
-
 	case 0x99:
 		return Common::KEYCODE_q;
-
 	default:
 		error("Invalid key index: %x", index);
 	}


Commit: e1f07e322914a9e6786684ab02a7d06eebba0049
    https://github.com/scummvm/scummvm/commit/e1f07e322914a9e6786684ab02a7d06eebba0049
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:27+01:00

Commit Message:
FREESCAPE: added key to turn 180 degrees

Changed paths:
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 368e4d8577b..d114db49005 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -273,6 +273,8 @@ void FreescapeEngine::processInput() {
 				rotate(0, 5);
 			else if (event.kbd.keycode == Common::KEYCODE_l)
 				rotate(0, -5);
+			else if (event.kbd.keycode == Common::KEYCODE_u)
+				rotate(180, 0);
 			else if (event.kbd.keycode == Common::KEYCODE_q)
 				rotate(-5.3, 0);
 			else if (event.kbd.keycode == Common::KEYCODE_w)


Commit: a58fcbc0b864f11dc914aa84e92f37e09ea2fb75
    https://github.com/scummvm/scummvm/commit/a58fcbc0b864f11dc914aa84e92f37e09ea2fb75
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:27+01:00

Commit Message:
FREESCAPE: added variable rotation angles

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/driller.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index d114db49005..96709812d86 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -81,7 +81,7 @@ FreescapeEngine::FreescapeEngine(OSystem *syst, const ADGameDescription *gd)
 	_flyMode = false;
 	_noClipMode = false;
 	_playerHeightNumber = 1;
-
+	_angleRotationIndex = 0;
 	_border = nullptr;
 	_title = nullptr;
 	_titleTexture = nullptr;
@@ -276,9 +276,9 @@ void FreescapeEngine::processInput() {
 			else if (event.kbd.keycode == Common::KEYCODE_u)
 				rotate(180, 0);
 			else if (event.kbd.keycode == Common::KEYCODE_q)
-				rotate(-5.3, 0);
+				rotate(-_angleRotations[_angleRotationIndex], 0);
 			else if (event.kbd.keycode == Common::KEYCODE_w)
-				rotate(5.3, 0);
+				rotate(_angleRotations[_angleRotationIndex], 0);
 			else if (event.kbd.keycode == Common::KEYCODE_r)
 				rise();
 			else if (event.kbd.keycode == Common::KEYCODE_f)
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 5f90b664f19..9b48adaa651 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -183,6 +183,9 @@ public:
 	// Euler Angles
 	float _yaw;
 	float _pitch;
+	int _angleRotationIndex;
+	Common::Array<float> _angleRotations;
+
 	Math::Vector3d directionToVector(float pitch, float heading);
 	void updateCamera();
 
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index b8e0629b87c..df82421078d 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -124,6 +124,12 @@ void DrillerEngine::loadAssets() {
 		loadAssetsDemo();
 	else
 		loadAssetsFullGame();
+
+	_angleRotations.push_back(5.3);
+	_angleRotations.push_back(9.5);
+
+	// Start playing music, if any
+	playMusic("Matt Gray - The Best Of Reformation - 07 Driller Theme.ogg");
 }
 
 void DrillerEngine::loadAssetsDemo() {
@@ -209,9 +215,8 @@ void DrillerEngine::loadAssetsDemo() {
 	else
 		error("Unsupported demo for Driller");
 
-	// Start playing music, if any
-	playMusic("Matt Gray - The Best Of Reformation - 07 Driller Theme.ogg");
 	_demoMode = true;
+	_angleRotationIndex = 1;
 }
 
 
@@ -290,9 +295,6 @@ void DrillerEngine::loadAssetsFullGame() {
 		load8bitBinary(file, 0x7bb0, 4);
 	} else
 		error("Invalid render mode %s for Driller", _renderMode.c_str());
-
-	// Start playing music, if any
-	playMusic("Matt Gray - The Best Of Reformation - 07 Driller Theme.ogg");
 }
 
 void DrillerEngine::drawUI() {


Commit: 2250833724a1ba20df82521c50c58cf2b5a83a5c
    https://github.com/scummvm/scummvm/commit/2250833724a1ba20df82521c50c58cf2b5a83a5c
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:27+01:00

Commit Message:
FREESCAPE: load sounds for driller atari st demo

Changed paths:
    engines/freescape/games/driller.cpp


diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index df82421078d..6d478da1d1e 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -211,6 +211,12 @@ void DrillerEngine::loadAssetsDemo() {
 		if (file == nullptr)
 			error("Failed to open 'x.prg' file");
 		loadMessagesFixedSize(file, 0x3b90, 14, 20);
+
+		file = gameDir.createReadStreamForMember("soundfx");
+		if (file == nullptr)
+			error("Failed to open 'soundfx' executable for AtariST demo");
+
+		loadSoundsFx(file, 0, 25);
 	}
 	else
 		error("Unsupported demo for Driller");


Commit: 7ac42e846d9e90e87b89abe27593119f6f2dd630
    https://github.com/scummvm/scummvm/commit/7ac42e846d9e90e87b89abe27593119f6f2dd630
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:27+01:00

Commit Message:
FREESCAPE: load replay demo for driller atari st demo

Changed paths:
    engines/freescape/games/driller.cpp


diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 6d478da1d1e..9fd62c5de73 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -193,6 +193,12 @@ void DrillerEngine::loadAssetsDemo() {
 		file = gameDir.createReadStreamForMember("console.neo");
 		_border = loadAndConvertNeoImage(file, 0);
 
+		file = gameDir.createReadStreamForMember("demo.cmd");
+		if (file == nullptr)
+			error("Failed to open 'demo.cmd' file");
+
+		loadDemoData(file, 0, 0x1000);
+
 		file = gameDir.createReadStreamForMember("data");
 
 		if (file == nullptr)


Commit: 1dc00bf7d15cd553c03b7ec27275c568b98acef8
    https://github.com/scummvm/scummvm/commit/1dc00bf7d15cd553c03b7ec27275c568b98acef8
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:27+01:00

Commit Message:
FREESCAPE: improved decodeAmigaAtariKey

Changed paths:
    engines/freescape/keyboard.cpp


diff --git a/engines/freescape/keyboard.cpp b/engines/freescape/keyboard.cpp
index 766a5e97dd3..afa1e0fccf9 100644
--- a/engines/freescape/keyboard.cpp
+++ b/engines/freescape/keyboard.cpp
@@ -27,8 +27,6 @@ namespace Freescape {
 
 int FreescapeEngine::decodeAmigaAtariKey(int index) {
 	switch (index) {
-	case 0x30:
-		return 0; // shoot?
 	case 0x44:
 		return Common::KEYCODE_d;
 	case 0x4c:
@@ -36,7 +34,7 @@ int FreescapeEngine::decodeAmigaAtariKey(int index) {
 	case 0x50:
 		return Common::KEYCODE_p;
 	case 0x55:
-		return 0; // turn around
+		return Common::KEYCODE_u;
 	case 0x96:
 		return Common::KEYCODE_UP;
 	case 0x97:


Commit: 8466ff5ad27623266a3c4688ff975a259225f4b6
    https://github.com/scummvm/scummvm/commit/8466ff5ad27623266a3c4688ff975a259225f4b6
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:28+01:00

Commit Message:
FREESCAPE: fixed override warnings

Changed paths:
    engines/freescape/gfx_tinygl.h
    engines/freescape/objects/entrance.h
    engines/freescape/objects/geometricobject.h
    engines/freescape/objects/sensor.h


diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index 03d76f2da5d..b53e6803b4b 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -43,14 +43,14 @@ public:
 	Texture *createTexture(const Graphics::Surface *surface) override;
 	void freeTexture(Texture *texture) override;
 	virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture) override;
-	virtual void drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint8 g, uint8 b);
+	virtual void drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint8 g, uint8 b) override;
 
 	virtual void renderCrossair(byte color, const Common::Point position) override;
 	virtual void renderShoot(byte color, const Common::Point position) override;
 	virtual void renderCube(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) override;
 	virtual void renderRectangle(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) override;
 	virtual void renderPolygon(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours) override;
-	virtual void renderPyramid(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours, int type);
+	virtual void renderPyramid(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours, int type) override;
     virtual void renderFace(const Common::Array<Math::Vector3d> &vertices) override;
 
 	virtual void flipBuffer() override;
diff --git a/engines/freescape/objects/entrance.h b/engines/freescape/objects/entrance.h
index a541040e4da..169343046ec 100644
--- a/engines/freescape/objects/entrance.h
+++ b/engines/freescape/objects/entrance.h
@@ -45,8 +45,8 @@ public:
 		const Math::Vector3d &rotation);
 	virtual ~Entrance();
 
-	bool isDrawable();
-	bool isPlanar();
+	bool isDrawable() override;
+	bool isPlanar() override;
 	Type getType() override { return Type::Entrance; };
 	Math::Vector3d getRotation() { return rotation; }
 
diff --git a/engines/freescape/objects/geometricobject.h b/engines/freescape/objects/geometricobject.h
index 5e081f0cbef..c0065278dec 100644
--- a/engines/freescape/objects/geometricobject.h
+++ b/engines/freescape/objects/geometricobject.h
@@ -53,8 +53,8 @@ public:
 	void computeBoundingBox();
 	bool collides(const Math::AABB &boundingBox);
 	void draw(Freescape::Renderer *gfx) override;
-	bool isDrawable();
-	bool isPlanar();
+	bool isDrawable() override;
+	bool isPlanar() override;
 
 	Common::String *conditionSource;
 	FCLInstructionVector condition;
diff --git a/engines/freescape/objects/sensor.h b/engines/freescape/objects/sensor.h
index 65d59406a8b..a4f41d59445 100644
--- a/engines/freescape/objects/sensor.h
+++ b/engines/freescape/objects/sensor.h
@@ -37,8 +37,8 @@ public:
 		const Math::Vector3d &rotation);
 	virtual ~Sensor();
 
-	bool isDrawable();
-	bool isPlanar();
+	bool isDrawable() override;
+	bool isPlanar() override;
 	Type getType() override { return Type::Sensor; };
 	Math::Vector3d getRotation() { return rotation; }
 


Commit: cb50cdc359639b223f8ede2a627a70f2bf462c60
    https://github.com/scummvm/scummvm/commit/cb50cdc359639b223f8ede2a627a70f2bf462c60
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:28+01:00

Commit Message:
FREESCAPE: removed unused variables

Changed paths:
    engines/freescape/gfx.cpp


diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index 54aa3215674..a38d5fe3718 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -102,8 +102,6 @@ Common::Rect Renderer::viewport() const {
 }
 
 void Renderer::computeScreenViewport() {
-	int32 screenWidth = _system->getWidth();
-	int32 screenHeight = _system->getHeight();
 	_screenViewport = Common::Rect(_screenW, _screenH);
 }
 


Commit: b66fe391381eebfae3ec4b5cad28f4521e7dadb5
    https://github.com/scummvm/scummvm/commit/b66fe391381eebfae3ec4b5cad28f4521e7dadb5
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:28+01:00

Commit Message:
FREESCAPE: refactored GlobalStucture into a separated file

Changed paths:
  A engines/freescape/objects/global.cpp
  A engines/freescape/objects/global.h
    engines/freescape/area.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/module.mk
    engines/freescape/objects/entrance.cpp
    engines/freescape/objects/entrance.h


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 4e079f657b7..0347d6c31a4 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -24,6 +24,7 @@
 #include "freescape/freescape.h"
 #include "freescape/area.h"
 #include "freescape/objects/geometricobject.h"
+#include "freescape/objects/global.h"
 #include "freescape/objects/entrance.h"
 #include "common/algorithm.h"
 
@@ -246,7 +247,7 @@ void Area::addStructure(Area *global) {
 		drawableObjects.insert_at(0, obj);
 		return;
 	}
-	RoomStructure *rs = (RoomStructure*) (*entrancesByID)[255];
+	GlobalStructure *rs = (GlobalStructure*) (*entrancesByID)[255];
 
 	for (int i = 0; i < int(rs->structure.size()); i++) {
 		int16 id = rs->structure[i];
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index b1699f0e970..42596104985 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -26,6 +26,7 @@
 
 #include "freescape/freescape.h"
 #include "freescape/language/8bitDetokeniser.h"
+#include "freescape/objects/global.h"
 #include "freescape/objects/sensor.h"
 #include "freescape/neo.h"
 
@@ -112,7 +113,7 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 		if (byteSizeOfObject > 0)
 			file->read(structureData+6, byteSizeOfObject);
 		Common::Array<uint8> structureArray(structureData, byteSizeOfObject + 6);
-		return new RoomStructure(structureArray);
+		return new GlobalStructure(structureArray);
 	}
 
 	debugC(1, kFreescapeDebugParser, "Object %d ; type %d ; size %d", objectID, (int)objectType, byteSizeOfObject);
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index 29c53601cbb..fee7380194e 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -16,6 +16,7 @@ MODULE_OBJS := \
 	objects/object.o \
 	objects/entrance.o \
 	objects/geometricobject.o \
+	objects/global.o \
 	objects/sensor.o \
 	loaders/8bitBinaryLoader.o \
 	language/8bitDetokeniser.o \
diff --git a/engines/freescape/objects/entrance.cpp b/engines/freescape/objects/entrance.cpp
index abbeecdd351..fe4f9d9302b 100644
--- a/engines/freescape/objects/entrance.cpp
+++ b/engines/freescape/objects/entrance.cpp
@@ -25,11 +25,6 @@
 
 namespace Freescape {
 
-RoomStructure::RoomStructure(const Common::Array<byte> _structure) {
-	objectID = 255;
-	structure = _structure;
-}
-
 Entrance::Entrance(
 	uint16 _objectID,
 	const Math::Vector3d &_origin,
diff --git a/engines/freescape/objects/entrance.h b/engines/freescape/objects/entrance.h
index 169343046ec..96c9735a2bb 100644
--- a/engines/freescape/objects/entrance.h
+++ b/engines/freescape/objects/entrance.h
@@ -28,14 +28,6 @@
 
 namespace Freescape {
 
-class RoomStructure : public Object {
-public:
-	Common::Array<byte> structure;
-	RoomStructure(const Common::Array<byte> _structure);
-	Type getType() override { return Type::Entrance; };
-	void draw(Freescape::Renderer *gfx) override { error("cannot render RoomStructure"); };
-};
-
 class Entrance : public Object {
 public:
 
diff --git a/engines/freescape/objects/global.cpp b/engines/freescape/objects/global.cpp
new file mode 100644
index 00000000000..402f6926174
--- /dev/null
+++ b/engines/freescape/objects/global.cpp
@@ -0,0 +1,33 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "common/array.h"
+
+#include "freescape/objects/global.h"
+
+namespace Freescape {
+
+GlobalStructure::GlobalStructure(const Common::Array<byte> _structure) {
+	objectID = 255;
+	structure = _structure;
+}
+
+} // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/objects/global.h b/engines/freescape/objects/global.h
new file mode 100644
index 00000000000..99139003df4
--- /dev/null
+++ b/engines/freescape/objects/global.h
@@ -0,0 +1,39 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef FREESCAPE_GLOB_H
+#define FREESCAPE_GLOB_H
+
+#include "freescape/objects/object.h"
+
+namespace Freescape {
+
+class GlobalStructure : public Object {
+public:
+	Common::Array<byte> structure;
+	GlobalStructure(const Common::Array<byte> _structure);
+	Type getType() override { return Type::Entrance; };
+	void draw(Freescape::Renderer *gfx) override { error("cannot render GlobalStructure"); };
+};
+
+} // End of namespace Freescape
+
+#endif
\ No newline at end of file


Commit: 5df94787eafeae4ede6f564f640c993ee7c896a0
    https://github.com/scummvm/scummvm/commit/5df94787eafeae4ede6f564f640c993ee7c896a0
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:28+01:00

Commit Message:
FREESCAPE: free memory of the border and title images

Changed paths:
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 96709812d86..b2ad5ed516e 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -96,9 +96,20 @@ FreescapeEngine::FreescapeEngine(OSystem *syst, const ADGameDescription *gd)
 
 FreescapeEngine::~FreescapeEngine() {
 	delete _rnd;
-	delete _border;
+
+	if (_title && _title != _border) {
+		_title->free();
+		delete _title;
+	}
+
+	if (_border) {
+		_border->free();
+		delete _border;
+	}
+
 	delete _borderTexture;
 	delete _uiTexture;
+	delete _titleTexture;
 
 	delete _gfx;
 }


Commit: 95630cc9d9827c7fd415d06e9471a51faf2d4861
    https://github.com/scummvm/scummvm/commit/95630cc9d9827c7fd415d06e9471a51faf2d4861
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:28+01:00

Commit Message:
FREESCAPE: correctly deallocate hash tables and arrays in each areas

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 0347d6c31a4..26696b08676 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -93,14 +93,21 @@ Area::Area(uint16 _areaID, uint16 _areaFlags, ObjectMap *_objectsByID, ObjectMap
 }
 
 Area::~Area() {
-	for (ObjectMap::iterator iterator = entrancesByID->begin(); iterator != entrancesByID->end(); iterator++)
-		delete iterator->_value;
+	if (entrancesByID) {
+		for (ObjectMap::iterator iterator = entrancesByID->begin(); iterator != entrancesByID->end(); iterator++)
+			delete iterator->_value;
+	}
 
-	for (ObjectMap::iterator iterator = objectsByID->begin(); iterator != objectsByID->end(); iterator++)
-		delete iterator->_value;
+	if (objectsByID) {
+		for (ObjectMap::iterator iterator = objectsByID->begin(); iterator != objectsByID->end(); iterator++)
+			delete iterator->_value;
+	}
 
 	delete entrancesByID;
 	delete objectsByID;
+
+	for (Common::Array<Common::String*>::iterator iterator = conditionSources.begin(); iterator != conditionSources.end(); iterator++)
+		delete *iterator;
 }
 
 void Area::show() {
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index b2ad5ed516e..42989ec95de 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -111,6 +111,9 @@ FreescapeEngine::~FreescapeEngine() {
 	delete _uiTexture;
 	delete _titleTexture;
 
+	for (AreaMap::iterator it = _areaMap.begin(); it != _areaMap.end(); ++it)
+		delete it->_value;
+
 	delete _gfx;
 }
 


Commit: 5df7776f37730c2e297cd799474c6bb6e5fcb190
    https://github.com/scummvm/scummvm/commit/5df7776f37730c2e297cd799474c6bb6e5fcb190
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:29+01:00

Commit Message:
FREESCAPE: correctly deallocate geometric objects and the data bundle

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/objects/geometricobject.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 42989ec95de..d26a65ea8ac 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -115,6 +115,7 @@ FreescapeEngine::~FreescapeEngine() {
 		delete it->_value;
 
 	delete _gfx;
+	delete _dataBundle;
 }
 
 void FreescapeEngine::drawBorder() {
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index f4558a9f6ea..dd1a3688cca 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -305,6 +305,9 @@ void GeometricObject::computeBoundingBox() {
 }
 
 GeometricObject::~GeometricObject() {
+	delete conditionSource;
+	delete colours;
+	delete ordinates;
 }
 
 bool GeometricObject::isDrawable() { return true; }


Commit: 6c3dbcb183f39612bb95e84cb5c64bc1c048a4a2
    https://github.com/scummvm/scummvm/commit/6c3dbcb183f39612bb95e84cb5c64bc1c048a4a2
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:29+01:00

Commit Message:
FREESCAPE: correctly deallocate bitmap decoder after usage

Changed paths:
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 42596104985..0b70a1e6368 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -518,6 +518,7 @@ void FreescapeEngine::loadBundledImages() {
 		decoder.loadStream(*borderFile);
 		_border = new Graphics::Surface();
 		_border->copyFrom(*decoder.getSurface());
+		decoder.destroy();
 	} else
 		error("Missing border file '%s' in data bundle", borderFilename.c_str());
 }


Commit: 5ed0c4a0cfe081351da359b46568d640aa080385
    https://github.com/scummvm/scummvm/commit/5ed0c4a0cfe081351da359b46568d640aa080385
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:29+01:00

Commit Message:
FREESCAPE: avoid reallocing memory from colours and ordinates

Changed paths:
    engines/freescape/objects/geometricobject.cpp


diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index dd1a3688cca..da09f11dc05 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -133,12 +133,12 @@ GeometricObject::GeometricObject(
 	colours = nullptr;
 
 	if (_colours)
-		colours = new Common::Array<uint8>(*_colours);
+		colours = _colours;
 
 	ordinates = nullptr;
 
 	if (_ordinates)
-		ordinates = new Common::Array<uint16>(*_ordinates);
+		ordinates = _ordinates;
 	condition = _conditionInstructions;
 	conditionSource = _conditionSource;
 


Commit: f694efb7de25e14b1fd2ff2f37a4437ab14fd290
    https://github.com/scummvm/scummvm/commit/f694efb7de25e14b1fd2ff2f37a4437ab14fd290
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:29+01:00

Commit Message:
FREESCAPE: deallocate duplicated font data

Changed paths:
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 0b70a1e6368..0d38eb16b00 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -532,6 +532,7 @@ void FreescapeEngine::loadFonts(Common::SeekableReadStream *file, int offset) {
 	_font.set_size(48 * charNumber);
 	_font.set_bits((byte *)font);
 	_fontLoaded = true;
+	free(font);
 }
 
 void FreescapeEngine::loadMessagesFixedSize(Common::SeekableReadStream *file, int offset, int size, int number) {


Commit: 0e0026db5d5a6555011a4e28df9578a51037db88
    https://github.com/scummvm/scummvm/commit/0e0026db5d5a6555011a4e28df9578a51037db88
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:29+01:00

Commit Message:
FREESCAPE: properly initialize all the class variables

Changed paths:
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index d26a65ea8ac..be9df881622 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -42,12 +42,11 @@ FreescapeEngine::FreescapeEngine(OSystem *syst, const ADGameDescription *gd)
 	else
 		_renderMode = ConfMan.get("render_mode");
 
+	_binaryBits = 0;
 	_screenW = 320;
 	_screenH = 200;
 
 	if (isAmiga()) {
-		//_screenW = 640;
-		//_screenH = 480;
 		_renderMode = "amiga";
 	} else if (isAtariST()) {
 		_renderMode = "atari";
@@ -61,14 +60,18 @@ FreescapeEngine::FreescapeEngine(OSystem *syst, const ADGameDescription *gd)
 	if (!Common::parseBool(ConfMan.get("prerecorded_sounds"), _usePrerecordedSounds))
 		error("Failed to parse bool from prerecorded_sounds option");
 
+	_startArea = 0;
+	_startEntrance = 0;
 	_currentArea = nullptr;
-	_rotation = Math::Vector3d(0.f, 0.f, 0.f);
-	_position = Math::Vector3d(0.f, 0.f, 0.f);
-	_lastPosition = Math::Vector3d(0.f, 0.f, 0.f);
-	_velocity = Math::Vector3d(0.f, 0.f, 0.f);
-	_cameraFront = Math::Vector3d(0.f, 0.f, 0.f);
-	_cameraRight = Math::Vector3d(0.f, 0.f, 0.f);
-	_upVector =	Math::Vector3d(0, 1.0f, 0);
+	_rotation = Math::Vector3d(0, 0, 0);
+	_position = Math::Vector3d(0, 0, 0);
+	_lastPosition = Math::Vector3d(0, 0, 0);
+	_velocity = Math::Vector3d(0, 0, 0);
+	_cameraFront = Math::Vector3d(0, 0, 0);
+	_cameraRight = Math::Vector3d(0, 0, 0);
+	_yaw = 0;
+	_pitch = 0;
+	_upVector = Math::Vector3d(0, 1, 0);
 	_movementSpeed = 1.5f;
 	_mouseSensitivity = 0.25f;
 	_demoMode = false;
@@ -88,10 +91,23 @@ FreescapeEngine::FreescapeEngine(OSystem *syst, const ADGameDescription *gd)
 	_borderTexture = nullptr;
 	_uiTexture = nullptr;
 	_fontLoaded = false;
+	_dataBundle = nullptr;
+
+	_lastMousePos = Common::Point(0, 0);
+	_lastFrame = 0;
+	_nearClipPlane = 1;
+
+	// These depends on the specific game
+	_farClipPlane = 0;
+	_playerHeight = 0;
+	_playerWidth = 0;
+	_playerDepth = 0;
+	_colorNumber = 0;
 
 	_fullscreenViewArea = Common::Rect(0, 0, _screenW, _screenH);
 	_viewArea = _fullscreenViewArea;
 	_rnd = new Common::RandomSource("freescape");
+	_gfx = nullptr;
 }
 
 FreescapeEngine::~FreescapeEngine() {
@@ -383,11 +399,6 @@ Common::Error FreescapeEngine::run() {
 	loadColorPalette();
 
 	// Simple main event loop
-	_lastMousePos = Common::Point(0, 0);
-	_lastFrame = 0.f;
-	// used to create a projection matrix;
-	_nearClipPlane = 1.f;
-
 	if (_binaryBits == 16) {
 		// Do not render face if color is zero
 		_gfx->_keyColor = 0;


Commit: 0340ce775ff9d052fc3199cbf2f6e42628fa87a6
    https://github.com/scummvm/scummvm/commit/0340ce775ff9d052fc3199cbf2f6e42628fa87a6
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:29+01:00

Commit Message:
FREESCAPE: removed some debug statements

Changed paths:
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index be9df881622..5cd7ea97695 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -210,7 +210,6 @@ void FreescapeEngine::pressedKey(const int keycode) {}
 
 void FreescapeEngine::generateInput() {
 	Common::Event event;
-	//g_system->getEventManager()->purgeKeyboardEvents();
 	if (isDOS()) {
 
 		if (_currentDemoInputRepetition == 0) {
@@ -238,7 +237,7 @@ void FreescapeEngine::generateInput() {
 			event.kbd.keycode = (Common::KeyCode)decodeDOSKey(_currentDemoInputCode);
 			event.customType = 0xde00;
 			g_system->getEventManager()->pushEvent(event);
-			debug("Pushing key: %x with repetition %d", event.kbd.keycode, _currentDemoInputRepetition);
+			debugC(1, kFreescapeDebugMove, "Pushing key: %x with repetition %d", event.kbd.keycode, _currentDemoInputRepetition);
 		}
 		_currentDemoInputRepetition--;
 		g_system->delayMillis(50);
@@ -247,7 +246,7 @@ void FreescapeEngine::generateInput() {
 
 	int mouseX = _demoData[_demoIndex++] << 1;
 	int mouseY = _demoData[_demoIndex++];
-	debug("Mouse moved to: %d, %d", mouseX, mouseY);
+	debugC(1, kFreescapeDebugMove, "Mouse moved to: %d, %d", mouseX, mouseY);
 
 	event.type = Common::EVENT_MOUSEMOVE;
 	event.mouse = Common::Point(mouseX, mouseY);
@@ -261,19 +260,18 @@ void FreescapeEngine::generateInput() {
 		g_system->getEventManager()->pushEvent(event);
 		nextKeyCode = _demoData[_demoIndex++];
 	} else {
-		while(nextKeyCode != 0) {
+		while (nextKeyCode != 0) {
 			event = Common::Event();
 			event.type = Common::EVENT_KEYDOWN;
 			event.kbd.keycode = (Common::KeyCode)decodeAmigaAtariKey(nextKeyCode);
-			debug("Pushing key: %x", nextKeyCode);
+			debugC(1, kFreescapeDebugMove, "Pushing key: %x", event.kbd.keycode);
 			event.customType = 0xde00;
 			g_system->getEventManager()->pushEvent(event);
 			nextKeyCode = _demoData[_demoIndex++];
 		}
 	}
 	assert(!nextKeyCode);
-	//_currentDemoInputRepetition = 0;
-	g_system->delayMillis(100);
+	g_system->delayMillis(50);
 }
 
 void FreescapeEngine::processInput() {
@@ -485,7 +483,6 @@ void FreescapeEngine::rotate(float xoffset, float yoffset) {
 
 void FreescapeEngine::rotate(Common::Point lastMousePos, Common::Point mousePos) {
 	if (lastMousePos != Common::Point(0, 0)) {
-		//debug("x: %d, y: %d", mousePos.x, mousePos.y);
 		float xoffset = mousePos.x - lastMousePos.x;
 		float yoffset = mousePos.y - lastMousePos.y;
 


Commit: 8c74b956bac92dc75a15035176b8a23fde6f0343
    https://github.com/scummvm/scummvm/commit/8c74b956bac92dc75a15035176b8a23fde6f0343
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:30+01:00

Commit Message:
FREESCAPE: removed 16bit game code until is ready

Changed paths:
  R engines/freescape/language/16bitDetokeniser.cpp
  R engines/freescape/language/16bitDetokeniser.h
  R engines/freescape/loaders/16bitBinaryLoader.cpp
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/module.mk


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 5cd7ea97695..eb8c2f73f94 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -157,25 +157,7 @@ void FreescapeEngine::drawTitle() {
 }
 
 void FreescapeEngine::loadAssets() {
-	Common::SeekableReadStream *file = nullptr;
-	Common::String path = ConfMan.get("path");
-	Common::FSDirectory gameDir(path);
-
-	if (_targetName.hasPrefix("3dkit") || _targetName == "menace") {
-		Common::ArchiveMemberList files;
-        gameDir.listMatchingMembers(files, "*.RUN");
-
-		if (files.size() == 0) {
-			error("No .RUN was found in %s", path.c_str());
-		} else if (files.size() > 1) {
-			debugC(1, kFreescapeDebugParser, "More than one .RUN file found, only the first one will be used!");
-		}
-
-		file = files.begin()->get()->createReadStream();
-		load16bitBinary(file);
-	} else
-		error("'%s' is an invalid game", _targetName.c_str());
-
+	error("Function \"%s\" not implemented", __FUNCTION__);
 }
 
 // Taken from the Myst 3 codebase, it should be abstracted
@@ -397,15 +379,6 @@ Common::Error FreescapeEngine::run() {
 	loadColorPalette();
 
 	// Simple main event loop
-	if (_binaryBits == 16) {
-		// Do not render face if color is zero
-		_gfx->_keyColor = 0;
-		// the 16-bit kit permits the range 0-8192 to be used along all three axes and from that comes the far plane distance of 14189.
-		_farClipPlane = 14189.f;
-		_startArea = 1;
-	} else {
-		_farClipPlane = 8192.f;
-	}
 	int saveSlot = ConfMan.getInt("save_slot");
 
 	if (_title) {
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 9b48adaa651..85f03724d4c 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -135,8 +135,6 @@ public:
 
 	uint16 readField(Common::SeekableReadStream *file, int nbits);
 	Common::Array<uint8> readArray(Common::SeekableReadStream *file, int size);
-	// 16-bit
-	void load16bitBinary(Common::SeekableReadStream *file);
 
 	// 8-bit
 	void load8bitBinary(Common::SeekableReadStream *file, int offset, int ncolors);
diff --git a/engines/freescape/language/16bitDetokeniser.cpp b/engines/freescape/language/16bitDetokeniser.cpp
deleted file mode 100644
index 13b8265a659..00000000000
--- a/engines/freescape/language/16bitDetokeniser.cpp
+++ /dev/null
@@ -1,300 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-// Based on Phantasma code by Thomas Harte (2013)
-
-#include "16bitDetokeniser.h"
-
-Common::String *detokenise16bitCondition(Common::Array<uint8> &tokenisedCondition) {
-	Common::String detokenisedStream;
-	Common::Array<uint8>::size_type bytePointer = 0;
-	Common::Array<uint8>::size_type sizeOfTokenisedContent = tokenisedCondition.size();
-
-	while (bytePointer < sizeOfTokenisedContent - 1) {
-		// byte 1 = number of arguments, byte 2 = opcode
-		uint8 numberOfArguments = tokenisedCondition[bytePointer];
-		uint8 opcode = tokenisedCondition[bytePointer + 1];
-		bytePointer += 2;
-
-		// make sure we have enough buffer left to read all the arguments
-		if (bytePointer + numberOfArguments * 2 > sizeOfTokenisedContent)
-			break;
-
-		// write out the operation
-		switch (opcode) {
-		case 0x01:
-			detokenisedStream += "ACTIVATED? ";
-			break;
-		case 0x02:
-			detokenisedStream += "COLLIDED? ";
-			break;
-		case 0x03:
-			detokenisedStream += "SHOT? ";
-			break;
-		case 0x04:
-			detokenisedStream += "TIMER? ";
-			break;
-
-		case 0x10:
-			detokenisedStream += "SETVAR ";
-			break;
-		case 0x11:
-			detokenisedStream += "ADDVAR ";
-			break;
-		case 0x12:
-			detokenisedStream += "SUBVAR ";
-			break;
-
-		case 0x13:
-			detokenisedStream += "ANDV ";
-			break;
-		case 0x14:
-			detokenisedStream += "ORV ";
-			break;
-		case 0x15:
-			detokenisedStream += "NOTV ";
-			break;
-
-		case 0x16:
-			detokenisedStream += "VAR=? ";
-			break;
-		case 0x17:
-			detokenisedStream += "VAR>? ";
-			break;
-		case 0x18:
-			detokenisedStream += "VAR<? ";
-			break;
-
-		case 0x2f:
-			detokenisedStream += "DESTROYED? ";
-			break;
-
-		case 0x30:
-			detokenisedStream += "INVIS ";
-			break;
-		case 0x31:
-			detokenisedStream += "VIS ";
-			break;
-		case 0x32:
-			detokenisedStream += "TOGVIS ";
-			break;
-		case 0x33:
-			detokenisedStream += "DESTROY ";
-			break;
-
-		case 0x34:
-			detokenisedStream += "INVIS? ";
-			break;
-		case 0x35:
-			detokenisedStream += "VIS? ";
-			break;
-
-		case 0x36:
-			detokenisedStream += "MOVE ";
-			break;
-
-		case 0x37:
-			detokenisedStream += "GETXPOS ";
-			break;
-		case 0x38:
-			detokenisedStream += "GETYPOS ";
-			break;
-		case 0x39:
-			detokenisedStream += "GETZPOS ";
-			break;
-
-		case 0x3a:
-			detokenisedStream += "MOVETO ";
-			break;
-
-		case 0x40:
-			detokenisedStream += "IF ";
-			break;
-		case 0x41:
-			detokenisedStream += "THEN ";
-			break;
-		case 0x42:
-			detokenisedStream += "ELSE ";
-			break;
-		case 0x43:
-			detokenisedStream += "ENDIF ";
-			break;
-		case 0x44:
-			detokenisedStream += "AND ";
-			break;
-		case 0x45:
-			detokenisedStream += "OR ";
-			break;
-
-		case 0x50:
-			detokenisedStream += "STARTANIM ";
-			break;
-		case 0x51:
-			detokenisedStream += "STOPANIM ";
-			break;
-
-		case 0x52:
-			detokenisedStream += "START ";
-			break;
-		case 0x53:
-			detokenisedStream += "RESTART ";
-			break;
-
-		case 0x54:
-			detokenisedStream += "INCLUDE ";
-			break;
-
-		case 0x55:
-			detokenisedStream += "WAITTRIG ";
-			break;
-		case 0x56:
-			detokenisedStream += "TRIGANIM ";
-			break;
-		case 0x57:
-			detokenisedStream += "REMOVE ";
-			break;
-
-		case 0x60:
-			detokenisedStream += "LOOP ";
-			break;
-		case 0x61:
-			detokenisedStream += "AGAIN ";
-			break;
-
-		case 0x70:
-			detokenisedStream += "SOUND ";
-			break;
-		case 0x71:
-			detokenisedStream += "SYNCSND ";
-			break;
-
-		case 0x80:
-			detokenisedStream += "WAIT ";
-			break;
-		case 0x81:
-			detokenisedStream += "DELAY ";
-			break;
-
-		case 0x82:
-			detokenisedStream += "UPDATEI ";
-			break;
-		case 0x83:
-			detokenisedStream += "PRINT ";
-			break;
-		case 0x84:
-			detokenisedStream += "REDRAW ";
-			break;
-
-		case 0x85:
-			detokenisedStream += "MODE ";
-			break;
-		case 0x86:
-			detokenisedStream += "ENDGAME ";
-			break;
-
-		case 0x87:
-			detokenisedStream += "EXECUTE ";
-			break;
-		case 0x90:
-			detokenisedStream += "GOTO ";
-			break;
-
-		case 0xff:
-			detokenisedStream += "END ";
-			break;
-
-		default:
-			detokenisedStream += "<UNKNOWN 16 bit: ";
-			detokenisedStream += Common::String::format("%x, ", (int)numberOfArguments);
-			detokenisedStream += Common::String::format("%x", (int)opcode);
-			detokenisedStream += " > ";
-			break;
-		}
-
-		// PRINT is a special case, requiring us to grab a string,
-		// but everything else is uniform
-		if (numberOfArguments) {
-			// arguments are enclosed in brackets
-			detokenisedStream += "(";
-
-			if (opcode == 0x83) {
-				// the first argument is a string, which is encoded as
-				// a two-byte string length (in big endian form)
-				uint16 stringLength =
-					(uint16)(
-						(tokenisedCondition[bytePointer] << 8) |
-						tokenisedCondition[bytePointer + 1]);
-				bytePointer += 2;
-				numberOfArguments--;
-
-				detokenisedStream += "\"";
-				for (uint16 stringPosition = 0; stringPosition < stringLength; stringPosition++) {
-					char nextChar = (char)tokenisedCondition[bytePointer + stringPosition];
-
-					// TODO: spot special characters here
-
-					if (nextChar)
-						detokenisedStream += nextChar;
-				}
-				detokenisedStream += "\"";
-				bytePointer += stringLength;
-
-				// strings are rounded up in length to the end
-				// of this two-byte quantity
-				if (stringLength & 1)
-					bytePointer++;
-				numberOfArguments -= (stringLength + 1) >> 1;
-
-				// that should leave an argument, but you can't be too safe
-				if (numberOfArguments)
-					detokenisedStream += ", ";
-			}
-
-			for (uint8 argumentNumber = 0; argumentNumber < numberOfArguments; argumentNumber++) {
-				// each argument is encoded in two bytes...
-				uint8 indexHighByte = tokenisedCondition[bytePointer];
-				uint8 indexLowByte = tokenisedCondition[bytePointer + 1];
-				bytePointer += 2;
-
-				// if the high bit of the first byte is clear then this
-				// argument is a constant; if it's set then this is a variable
-				if (indexHighByte & 0x80)
-					detokenisedStream += "V";
-				indexHighByte &= 0x7f;
-
-				// the second byte is either the constant or the index of
-				// the variable
-				detokenisedStream += Common::String::format("%d", (int)(indexLowByte | (indexHighByte << 8)));
-
-				// ... and arguments are separated by commas, of course
-				if (argumentNumber + 1 < numberOfArguments)
-					detokenisedStream += ", ";
-			}
-
-			// add a closing bracket
-			detokenisedStream += ")";
-		}
-
-		detokenisedStream += "\n";
-	}
-
-	return (new Common::String(detokenisedStream));
-}
diff --git a/engines/freescape/language/16bitDetokeniser.h b/engines/freescape/language/16bitDetokeniser.h
deleted file mode 100644
index 668ddf45f4c..00000000000
--- a/engines/freescape/language/16bitDetokeniser.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-// Based on Phantasma code by Thomas Harte (2013)
-
-#ifndef FREESCAPE_16BITDETOKENIZER_H
-#define FREESCAPE_16BITDETOKENIZER_H
-
-#include "common/array.h"
-
-Common::String *detokenise16bitCondition(Common::Array<uint8> &tokenisedCondition);
-
-#endif
diff --git a/engines/freescape/loaders/16bitBinaryLoader.cpp b/engines/freescape/loaders/16bitBinaryLoader.cpp
deleted file mode 100644
index 8c3a9befb02..00000000000
--- a/engines/freescape/loaders/16bitBinaryLoader.cpp
+++ /dev/null
@@ -1,529 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-// Based on Phantasma code by Thomas Harte (2013)
-
-#include "freescape/freescape.h"
-#include "freescape/language/16bitDetokeniser.h"
-
-namespace Freescape {
-
-typedef enum {
-		First = 0x0000,
-		Border = 0x4524,
-} ChunkType;
-
-static Object *load16bitObject(Common::SeekableReadStream *file) {
-	// get object flags and type
-	uint8 objectFlags = file->readByte();
-	Object::Type objectType = (Object::Type)file->readByte();
-
-	/*
-		Notes to self:
-
-			0 = no flags
-			128 = Movable, Animated
-			134 = Movable, Animated, Default invis, invis
-			6 = Default invis, Invis
-			32 = collided
-	*/
-
-	// get unknown value
-	uint16 skippedShort = file->readUint16BE();
-	debug("skippedShort: %d", skippedShort);
-
-	// grab location, size
-	Math::Vector3d position, size;
-	position.x() = file->readUint16BE();
-	position.y() = file->readUint16BE();
-	position.z() = file->readUint16BE();
-	size.x() = file->readUint16BE();
-	size.y() = file->readUint16BE();
-	size.z() = file->readUint16BE();
-
-	// object ID
-	uint16 objectID = file->readUint16BE();
-
-	// size of object on disk; we've accounted for 20 bytes
-	// already so we can subtract that to get the remaining
-	// length beyond here
-	uint32 byteSizeOfObject = (uint32)(file->readUint16BE() << 1) - 20;
-
-	debug("Object %d ; type %d ; flags %d ; size %d", (int)objectID, (int)objectType, (int)objectFlags, byteSizeOfObject);
-	debug("Location: %f, %f, %f", position.x(), position.y(), position.z());
-	debug("Size: %f, %f, %f", size.x(), size.y(), size.z());
-
-	switch (objectType) {
-	default: {
-		// read the appropriate number of colours
-		int numberOfColours = GeometricObject::numberOfColoursForObjectOfType(objectType);
-		Common::Array<uint8> *colours = new Common::Array<uint8>;
-		for (uint8 colour = 0; colour < numberOfColours/2; colour++) {
-			uint8 c1 = file->readByte();
-			byteSizeOfObject--;
-			uint8 c2 = file->readByte();
-			byteSizeOfObject--;
-			colours->push_back((c1 & 0x0f) | ((c2 & 0x0f) << 4));
-			debug("color[%d] = %d", 2*colour, (c1 & 0x0f) | ((c2 & 0x0f) << 4));
-			colours->push_back((c1 >> 4) | (c2 & 0xf0));
-			debug("color[%d] = %d", 2*colour+1, (c1 >> 4) | (c2 & 0xf0));
-		}
-
-		// read extra vertices if required...
-		int numberOfOrdinates = GeometricObject::numberOfOrdinatesForType(objectType);
-		debug("number of ordinates %d", numberOfOrdinates);
-		Common::Array<uint16> *ordinates = nullptr;
-
-		if (numberOfOrdinates) {
-			assert(byteSizeOfObject > 0);
-			ordinates = new Common::Array<uint16>;
-
-			for (int ordinate = 0; ordinate < numberOfOrdinates; ordinate++) {
-				ordinates->push_back(file->readUint16BE());
-				byteSizeOfObject -= 2;
-			}
-		}
-
-		// grab the object condition, if there is one
-		FCLInstructionVector instructions;
-		if (byteSizeOfObject > 0) {
-			// get the condition
-			byte *conditionData = (byte*)malloc(byteSizeOfObject);
-			file->read(conditionData, byteSizeOfObject);
-			Common::Array<uint8> conditionArray(conditionData, byteSizeOfObject);
-			Common::String *conditionSource = detokenise16bitCondition(conditionArray);
-		 	debug("Condition: %s", conditionSource->c_str());
-			byteSizeOfObject = 0;
-		// 	//instructions = getInstructions(conditionSource);
-		}
-
-		debug("Skipping %d bytes", byteSizeOfObject);
-		file->seek(byteSizeOfObject, SEEK_CUR);
-		debug("End of object at %lx", file->pos());
-
-		// create an object
-		return new GeometricObject(
-			objectType,
-			objectID,
-			objectFlags,
-			position,
-			size,
-			colours,
-			ordinates,
-			instructions);
-	} break;
-
-	case Object::Entrance:
-		debug("Skipping %d bytes", byteSizeOfObject);
-		file->seek(byteSizeOfObject, SEEK_CUR);
-		debug("End of object at %lx", file->pos());
-		return new Entrance(objectID, position, size); // size will be always 0,0,0?
-		break;
-	case Object::Sensor:
-	case Object::Group:
-		break;
-	}
-
-	// skip whatever we didn't understand
-	//cout << "bytes we don't understand:" << endl;
-	//int i = 0;
-	//int j = 0;
-	//for (i = 0; i < byteSizeOfObject/2; i++)
-	//	cout << i << stream.get16() << endl;
-	file->seek(byteSizeOfObject, SEEK_CUR);
-	debug("End of object at %lx", file->pos());
-
-	return nullptr;
-}
-
-/*void load16bitInstrument(StreamLoader &stream) {
-	uint16 zero = stream.get16();
-	assert( zero == 0);
-	uint16 type = stream.get16();
-	uint16 x = stream.get16();
-	uint16 y = stream.get16();
-	uint16 length = stream.get16();
-	uint16 height = stream.get16();
-	stream.get16();
-	stream.get16();
-	uint16 lb = stream.get16();
-	uint16 rt = stream.get16();
-	uint16 v = stream.get16();
-	uint16 fgcolor = stream.get16();
-	uint16 bgcolor = stream.get16();
-
-	stream.get16();
-	stream.get16();
-	stream.get16();
-	stream.get16();
-	debug("type %d ; x %d ; y %d ; length %d ; height %d ; lb %d ; rt %d ; variable: %d", type, x, y, length, height, lb, rt, v);
-}*/
-
-Area *load16bitArea(Common::SeekableReadStream *file) {
-	// the lowest bit of this value seems to indicate
-	// horizon on or off; this is as much as I currently know
-	uint16 areaFlags = file->readUint16BE();
-	uint16 numberOfObjects = file->readUint16BE();
-	uint16 areaNumber = file->readUint16BE();
-
-	debug("Area %d", areaNumber);
-	debug("Area flags %d", areaFlags);
-	debug("Objects: %d", numberOfObjects);
-
-	// I've yet to decipher this fully
-	file->readUint16BE();
-	file->readUint16BE();
-	file->readUint16BE();
-
-	uint8 skyColor = file->readByte();
-	skyColor = (file->readByte() << 4) | skyColor;
-
-	debug("Sky color %x", skyColor);
-	uint8 groundColor = file->readByte();
-	groundColor = (file->readByte() << 4) | groundColor;
-	debug("Ground color %x", groundColor);
-	file->seek(14, SEEK_CUR);
-
-	// this is just a complete guess
-	/*Common::Array<uint8> palette;
-	uint32 i;
-	for (i = 0; i < 7*3; i++) {
-		uint8 c = stream.get8();
-		palette.push_back(c);
-		debug("color %d", c);
-	}
-	stream.get8(); // ????*/
-	//for (int paletteEntry = 0; paletteEntry < 22; paletteEntry++) {
-	//	uint8 paletteColour = stream.get8() << 2;
-	//	debug("Palette colour (?) %x", paletteColour);
-	//}
-
-	// we'll need to collate all objects and entrances; it's likely a
-	// plain C array would do but maps are safer and the total application
-	// cost is going to be negligible regardless
-	ObjectMap *objectsByID = new ObjectMap;
-	ObjectMap *entrancesByID = new ObjectMap;
-
-	// get the objects or whatever; entrances use a unique numbering
-	// system and have the high bit of their IDs set in the original file
-	for (uint16 object = 0; object < numberOfObjects; object++) {
-		Object *newObject = load16bitObject(file);
-
-		if (newObject) {
-			if (newObject->getType() == Object::Entrance) {
-				(*entrancesByID)[newObject->getObjectID() & 0x7fff] = newObject;
-			} else {
-				(*objectsByID)[newObject->getObjectID()] = newObject;
-			}
-		}
-	}
-
-	uint16 numberOfLocalConditions = file->readUint16BE();
-	debug("Number of conditions: %d", numberOfLocalConditions);
-	for (uint16 localCondition = 0; localCondition < numberOfLocalConditions; localCondition++) {
-		// 12 bytes for the name of the condition;
-		// we don't care
-		file->seek(12, SEEK_CUR);
-
-		// get the length and the data itself, converting from
-		// shorts to bytes
-		uint32 lengthOfCondition = (uint32)file->readUint16BE() << 1;
-
-		debug("Length of condition: %d", lengthOfCondition);
-		if (lengthOfCondition == 0) {
-			break;
-		}
-
-		// get the condition
-		byte *conditionData = (byte*)malloc(lengthOfCondition);
-		file->read(conditionData, lengthOfCondition);
-		Common::Array<uint8> conditionArray(conditionData, lengthOfCondition);
-
-		debug("Local condition %d at %lx", localCondition + 1, file->pos());
-		debug("%s", detokenise16bitCondition(conditionArray)->c_str());
-	}
-
-	Area *area = new Area(areaNumber, areaFlags, objectsByID, entrancesByID);
-	area->scale = 1;
-	area->skyColor = skyColor;
-	area->groundColor = groundColor;
-
-	return area;
-}
-
-void FreescapeEngine::load16bitBinary(Common::SeekableReadStream *file) {
-	Common::Array<uint8>::size_type baseOffset = 0;
-
-	// check whether this looks like an Amiga game; if so it'll start with AM
-	// XOR'd with the repeating byte pattern 0x71, 0xc1 or with the pattern
-	// 0x88 0x2c if it's on the ST (though the signature will still be AM)
-	uint16 platformID = file->readUint16BE();
-	debug("%d", platformID);
-
-	if (
-		//		(platformID != 0x4120) && (platformID != 0x5043)
-		(platformID == 12428) || (platformID == 51553)) {
-		// TODO: record original platform type, so we can decode the palette
-		// and possibly the border properly
-		debug("Loading an Amiga game");
-		//cout << "AMIGA" << endl;
-
-		// TODO
-		//streamLoader.setReadMask((platformID >> 8) ^ 'A', (platformID & 0xff) ^ 'M');
-	} else {
-		debug("Loading a DOS game");
-		// find DOS end of file and consume it
-		while (!file->eos()) {
-			uint8 b = file->readByte();
-			if (b == 0x1a)
-				break;
-		}
-		file->readByte();
-
-		// advance to the next two-byte boundary if necessary
-		if (file->pos() % 2 > 0)
-			file->readByte();
-
-		// skip bytes with meaning unknown
-		file->readUint16BE();
-
-		// this brings us to the beginning of the embedded
-		// .KIT file, so we'll grab the base offset for
-		// finding areas later
-		baseOffset = file->pos(); //streamLoader.getFileOffset();
-
-		// check that the next two bytes are "PC", then
-		// skip the number that comes after
-		if (file->readByte() != 'C' || file->readByte() != 'P')
-			error("invalid header");
-	}
-
-	// skip an unknown meaning
-	file->readUint16BE();
-
-	// start grabbing some of the basics...
-
-	uint16 numberOfAreas = file->readUint16BE();
-	uint16 sm = file->readUint16BE();
-	debug("Something??: %d", sm); // meaning unknown
-	debug("Number of areas: %d", numberOfAreas);
-
-	uint16 windowCentreX = file->readUint16BE();
-	uint16 windowCentreY = file->readUint16BE();
-	uint16 windowWidth = file->readUint16BE();
-	uint16 windowHeight = file->readUint16BE();
-
-	debug("Window centre: (%d, %d)", windowCentreX, windowCentreY);
-	debug("Window size: (%d, %d)", windowWidth, windowHeight);
-
-	uint16 scaleX = file->readUint16BE();
-	uint16 scaleY = file->readUint16BE();
-	uint16 scaleZ = file->readUint16BE();
-
-	debug("Scale %d, %d, %d", scaleX, scaleY, scaleZ);
-	uint16 timerReload = file->readUint16BE();
-
-	debug("Timer: every %d 50Hz frames", timerReload);
-
-	uint16 maximumActivationDistance = file->readUint16BE();
-	uint16 maximumFallDistance = file->readUint16BE();
-	uint16 maximumClimbDistance = file->readUint16BE();
-
-	debug("Maximum activation distance: %d", maximumActivationDistance);
-	debug("Maximum fall distance: %d", maximumFallDistance);
-	debug("Maximum climb distance: %d", maximumClimbDistance);
-
-	uint16 startArea = file->readUint16BE();
-	uint16 startEntrance = file->readUint16BE();
-
-	debug("Start at entrance %d in area %d", startEntrance, startArea);
-
-	uint16 playerHeight = file->readUint16BE();
-	uint16 playerStep = file->readUint16BE();
-	uint16 playerAngle = file->readUint16BE();
-
-	debug("Height %d, step %d, angle %d", playerHeight, playerStep, playerAngle);
-
-	uint16 startVehicle = file->readUint16BE();
-	uint16 executeGlobalCondition = file->readUint16BE();
-
-	debug("Start vehicle %d, execute global condition %d", startVehicle, executeGlobalCondition);
-	// I haven't figured out what the next 106
-	// bytes mean, so we'll skip them — global objects
-	// maybe? Likely not 106 bytes in every file.
-	//
-	// ADDED: having rediscovered my source for the 8bit
-	// file format, could this be shading information by
-	// analogy with that?
-	/*cout << "global unknown:";
-	int i;
-	int j;
-	for (i = 0; i < 106/2; i++)
-		cout << streamLoader.get16() << endl;*/
-
-	file->seek(106, SEEK_CUR);
-
-	// at this point I should properly load the border/key/mouse
-	// bindings, but I'm not worried about it for now.
-	//
-	// Format is:
-	//		(left x, top y, right x, bottom y) - all 16 bit
-	//		keyboard key as an ASCII character (or zero for none)
-	//		mouse button masl; 00 = both, 01 = left, 02 = right
-	//
-	// So, 10 bytes per binding. Bindings are listed in the order:
-	//
-	//	move forwards, move backwards, move right, move left, rise,
-	//	fall, turn left, turn right, look up, look down, tilt left,
-	//	tilt right, face forward, u-turn, change vehicle type,
-	//	select this vehicle, quit game, fire, activate object,
-	//	centre cursor on/off, save game position, load game position
-	//
-	// So 35 total. Which means this area takes up 350 bytes.
-	//cout << "more global unknown:";
-	//for (i = 0; i < 350/2; i++)
-	//	cout << streamLoader.get16() << endl;
-
-	file->seek(350, SEEK_CUR);
-
-	// there are then file pointers for every area — these are
-	// the number of shorts from the 'PC' tag, so multiply by
-	// two for bytes. Each is four bytes
-	uint32 *fileOffsetForArea = new uint32[numberOfAreas];
-	for (uint16 area = 0; area < numberOfAreas; area++)
-		fileOffsetForArea[area] = file->readUint32BE() << 1;
-
-	// now come the global conditions
-	uint16 numberOfGlobalConditions = file->readUint16BE();
-	for (uint16 globalCondition = 0; globalCondition < numberOfGlobalConditions; globalCondition++) {
-		// 12 bytes for the name of the condition;
-		// we don't care
-		file->seek(12, SEEK_CUR);
-
-		// get the length and the data itself, converting from
-		// shorts to bytes
-		uint32 lengthOfCondition = (uint32)file->readUint16BE() << 1;
-
-		// get the condition
-		byte *conditionData = (byte*)malloc(lengthOfCondition);
-		file->read(conditionData, lengthOfCondition);
-		Common::Array<uint8> conditionArray(conditionData, lengthOfCondition);
-
-		debug("Global condition %d at %lx", globalCondition + 1, file->pos());
-		debug("%s", detokenise16bitCondition(conditionArray)->c_str());
-	}
-
-	// grab the areas
-	for (uint16 area = 0; area < numberOfAreas; area++) {
-		debug("Area offset %d", fileOffsetForArea[area]);
-
-		file->seek(fileOffsetForArea[area] + baseOffset);
-		Area *newArea = load16bitArea(file);
-
-		if (newArea) {
-			_areaMap[newArea->getAreaID()] = newArea;
-		}
-	}
-	// TODO
-	//load16bitInstrument(streamLoader);
-
-	Common::Array<uint8>::size_type o;
-	Common::Array<uint8> *raw_border = nullptr;
-	Common::Array<uint8> *raw_palette = nullptr;
-	uint16 chunkType = 0;
-	uint16 chunkSize = 0;
-	uint16 colorNumber = 0;
-	debug("End of areas at %lx", file->pos());
-	while (!file->eos()) {
-		o = file->pos();
-		chunkType = file->readUint16BE();
-		if (chunkType == First) {
-			chunkSize = file->readUint16LE();
-			if (chunkSize != 0xac) {
-				debug("skip %x", chunkType);
-				file->seek(o+2);
-			} else {
-				debug("First chunk found at %x with size %x", o, chunkSize);
-				file->seek(chunkSize-2, SEEK_CUR);
-			}
-		}
-		else if (chunkType == Border) {
-			chunkSize = file->readUint16LE();
-			debug("Border found at %x with size %x", o, chunkSize);
-
-			if (chunkSize == 320*200 / 4)
-				colorNumber = 4; // CGA
-			else if (chunkSize == 320*200 / 2)
-				colorNumber = 16; // EGA
-			else if (chunkSize == 320*200)
-				colorNumber = 256; // VGA
-			else
-				error("Unexpected size of image %d", chunkSize);
-
-			byte *borderData = (byte*)malloc(chunkSize);
-			file->read(borderData, chunkSize);
-			raw_border = new Common::Array<uint8>(borderData, chunkSize);
-
-			raw_palette = new Common::Array<uint8>();
-			debug("Palete follows at %lx", file->pos());
-			for (int i = 0; i < colorNumber*3; i++)
-				raw_palette->push_back(file->readByte() << 2);
-
-			debug("Palete finishes at %lx", file->pos());
-			chunkSize = file->readUint16LE();
-			debug("Something else of size %x at %lx??", chunkSize, file->pos());
-			file->seek(chunkSize, SEEK_CUR);
-		}
-		else {
-			debug("skip %x", chunkType);
-			//chunkSize = streamLoader.rget16();
-			//if (chunkSize > 0 && streamLoader.getFileOffset() + chunkSize-2 == 0x73ea)
-			//	error("Found at %x!", o);
-			//streamLoader.setFileOffset(o+2);
-			//error("Unknown chunk %x find at %x with size %x", chunkType, o, chunkSize);
-		}
-	}
-
-	if (raw_palette) {
-		Graphics::PixelBuffer *palette = new Graphics::PixelBuffer(_gfx->_palettePixelFormat, colorNumber, DisposeAfterUse::NO);
-		*palette = raw_palette->data();
-		_gfx->_palette = palette;
-	}
-
-	if (raw_border) {
-		Graphics::PixelBuffer *border = new Graphics::PixelBuffer(_gfx->_originalPixelFormat, 320*200, DisposeAfterUse::NO);
-		*border = raw_border->data();
-		_border = _gfx->convertFromPalette(border);
-	}
-
-	delete[] fileOffsetForArea;
-	_playerHeight = playerHeight;
-	_playerWidth = 32;
-	_playerDepth = 32;
-
-	_startArea = startArea;
-	_startEntrance = startEntrance;
-	_colorNumber = colorNumber;
-	_scale = Math::Vector3d(1, 1, 1);
-	_binaryBits = 16;
-}
-
-} // namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index fee7380194e..bebf2b61c96 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -20,8 +20,6 @@ MODULE_OBJS := \
 	objects/sensor.o \
 	loaders/8bitBinaryLoader.o \
 	language/8bitDetokeniser.o \
-	loaders/16bitBinaryLoader.o \
-	language/16bitDetokeniser.o \
 	language/instruction.o \
 	movement.o \
 	neo.o \


Commit: 9680afd677a3417864a70f425ee0ac09df86361a
    https://github.com/scummvm/scummvm/commit/9680afd677a3417864a70f425ee0ac09df86361a
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:30+01:00

Commit Message:
FREESCAPE: removed 16bit game detection code until the rest of engine is added

Changed paths:
    engines/freescape/detection.cpp


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index a2f7cb0c44f..d8a54517c3f 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -40,56 +40,6 @@ static const PlainGameDescriptor freescapeGames[] = {
 	{0, 0}};
 
 static const ADGameDescription gameDescriptions[] = {
-	{"3dkit",
-	 "Simple example",
-	 AD_ENTRY1s("HEX.RUN", "084c0314d0cd8e6d2287f30483a732eb", 83242),
-	 Common::EN_ANY,
-	 Common::kPlatformDOS,
-	 ADGF_NO_FLAGS,
-	 GUIO1(GUIO_NOMIDI)},
-	{"3dkit",
-	 "Simple example (cube)",
-	 AD_ENTRY1s("CUBE.RUN", "3b7930be0f646b98885cfb70c26c89a2", 66138),
-	 Common::EN_ANY,
-	 Common::kPlatformDOS,
-	 ADGF_NO_FLAGS,
-	 GUIO1(GUIO_NOMIDI)},
-	{"menace",
-	 "",
-	 AD_ENTRY1s("MODSS.RUN", "409ac1100a15447e742ec1415b2741c3", 91176),
-	 Common::EN_ANY,
-	 Common::kPlatformDOS,
-	 ADGF_NO_FLAGS,
-	 GUIO1(GUIO_NOMIDI)},
-
-	{"3dkit",
-	 "Chrismas",
-	 AD_ENTRY1s("CHRISTMA.RUN", "106b8f0dd0384d3138a8f0f62caef392", 69910),
-	 Common::EN_ANY,
-	 Common::kPlatformDOS,
-	 ADGF_NO_FLAGS,
-	 GUIO1(GUIO_NOMIDI)},
-	{"3dkit",
-	 "Maze",
-	 AD_ENTRY1s("DESMAZE.RUN", "5cfab15e53d77029bdb02c87acae3186", 99212),
-	 Common::EN_ANY,
-	 Common::kPlatformDOS,
-	 ADGF_NO_FLAGS,
-	 GUIO1(GUIO_NOMIDI)},
-	{"3dkit",
-	 "Mountain",
-	 AD_ENTRY1s("MOUNTAIN.RUN", "ec3bb57fe23b1a6785e870af1baa74d7", 129106),
-	 Common::EN_ANY,
-	 Common::kPlatformDOS,
-	 ADGF_NO_FLAGS,
-	 GUIO1(GUIO_NOMIDI)},
-	{"3dkit",
-	 "Example game",
-	 AD_ENTRY1s("3DKIT.RUN", "f35147729a2f5b6852a504223aeb6a57", 112158),
-	 Common::EN_ANY,
-	 Common::kPlatformDOS,
-	 ADGF_NO_FLAGS,
-	 GUIO1(GUIO_NOMIDI)},
 	{"driller",
 	 "Driller",
 	 {
@@ -138,7 +88,6 @@ static const ADGameDescription gameDescriptions[] = {
 	 Common::kPlatformAmiga,
 	 ADGF_NO_FLAGS | ADGF_DEMO,
 	 GUIO1(GUIO_NOMIDI)},
-
 	{"driller",
 	 "Rolling Demo",
 	 {
@@ -151,9 +100,6 @@ static const ADGameDescription gameDescriptions[] = {
 	 Common::kPlatformAtariST,
 	 ADGF_NO_FLAGS | ADGF_DEMO,
 	 GUIO1(GUIO_NOMIDI)},
-
-
-
 	{"darkside",
 	 "Dark Side",
 	 {


Commit: 3e4b23f24134c83f9ee1843057ddf84a0741afd0
    https://github.com/scummvm/scummvm/commit/3e4b23f24134c83f9ee1843057ddf84a0741afd0
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:30+01:00

Commit Message:
FREESCAPE: used clang-format to improve code formatting

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/castle.cpp
    engines/freescape/games/dark.cpp
    engines/freescape/games/driller.cpp
    engines/freescape/games/eclipse.cpp
    engines/freescape/games/palettes.cpp
    engines/freescape/gfx.cpp
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/gfx_tinygl.h
    engines/freescape/gfx_tinygl_texture.h
    engines/freescape/keyboard.cpp
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/language/instruction.cpp
    engines/freescape/language/instruction.h
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/metaengine.cpp
    engines/freescape/movement.cpp
    engines/freescape/neo.cpp
    engines/freescape/neo.h
    engines/freescape/objects/entrance.h
    engines/freescape/objects/geometricobject.cpp
    engines/freescape/objects/object.h
    engines/freescape/objects/sensor.h
    engines/freescape/sound.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 26696b08676..d2b78912ffc 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -21,19 +21,19 @@
 
 // Based on Phantasma code by Thomas Harte (2013)
 
-#include "freescape/freescape.h"
 #include "freescape/area.h"
+#include "common/algorithm.h"
+#include "freescape/freescape.h"
+#include "freescape/objects/entrance.h"
 #include "freescape/objects/geometricobject.h"
 #include "freescape/objects/global.h"
-#include "freescape/objects/entrance.h"
-#include "common/algorithm.h"
 
 namespace Freescape {
 
 Object *Area::objectWithIDFromMap(ObjectMap *map, uint16 objectID) {
 	if (!map)
 		return nullptr;
-	if(!map->contains(objectID))
+	if (!map->contains(objectID))
 		return nullptr;
 	return (*map)[objectID];
 }
@@ -106,7 +106,7 @@ Area::~Area() {
 	delete entrancesByID;
 	delete objectsByID;
 
-	for (Common::Array<Common::String*>::iterator iterator = conditionSources.begin(); iterator != conditionSources.end(); iterator++)
+	for (Common::Array<Common::String *>::iterator iterator = conditionSources.begin(); iterator != conditionSources.end(); iterator++)
 		delete *iterator;
 }
 
@@ -134,7 +134,7 @@ void Area::loadObjects(Common::SeekableReadStream *stream, Area *global) {
 		} else {
 			obj = global->objectWithID(key);
 			assert(obj);
-			obj = (Object*) ((GeometricObject*) obj)->duplicate();
+			obj = (Object *)((GeometricObject *)obj)->duplicate();
 			addObject(obj);
 		}
 		obj->setObjectFlags(flags);
@@ -170,10 +170,7 @@ Object *Area::shootRay(const Math::Ray &ray) {
 	Object *collided = nullptr;
 	for (int i = 0; i < int(drawableObjects.size()); i++) {
 		float objSize = drawableObjects[i]->getSize().length();
-		if (!drawableObjects[i]->isDestroyed() && !drawableObjects[i]->isInvisible()
-		  && drawableObjects[i]->boundingBox.isValid()
-		  && ray.intersectAABB(drawableObjects[i]->boundingBox)
-		  && size >= objSize) {
+		if (!drawableObjects[i]->isDestroyed() && !drawableObjects[i]->isInvisible() && drawableObjects[i]->boundingBox.isValid() && ray.intersectAABB(drawableObjects[i]->boundingBox) && size >= objSize) {
 			debugC(1, kFreescapeDebugMove, "shot obj id: %d", drawableObjects[i]->getObjectID());
 			collided = drawableObjects[i];
 			size = objSize;
@@ -187,7 +184,7 @@ Object *Area::checkCollisions(const Math::AABB &boundingBox) {
 	Object *collided = nullptr;
 	for (int i = 0; i < int(drawableObjects.size()); i++) {
 		if (!drawableObjects[i]->isDestroyed() && !drawableObjects[i]->isInvisible()) {
-			GeometricObject *obj = (GeometricObject*) drawableObjects[i];
+			GeometricObject *obj = (GeometricObject *)drawableObjects[i];
 			float objSize = obj->getSize().length();
 			if (obj->collides(boundingBox) && size > objSize) {
 				collided = obj;
@@ -240,21 +237,20 @@ void Area::addStructure(Area *global) {
 		for (int i = 0; i < 6; i++)
 			gColors->push_back(groundColor);
 
-		obj = (Object*) new GeometricObject(
+		obj = (Object *)new GeometricObject(
 			Object::Type::Cube,
 			id,
-			0, // flags
-			Math::Vector3d(0, -1, 0), // Position
+			0,                             // flags
+			Math::Vector3d(0, -1, 0),      // Position
 			Math::Vector3d(4128, 1, 4128), // size
 			gColors,
 			nullptr,
-			FCLInstructionVector()
-		);
+			FCLInstructionVector());
 		(*objectsByID)[id] = obj;
 		drawableObjects.insert_at(0, obj);
 		return;
 	}
-	GlobalStructure *rs = (GlobalStructure*) (*entrancesByID)[255];
+	GlobalStructure *rs = (GlobalStructure *)(*entrancesByID)[255];
 
 	for (int i = 0; i < int(rs->structure.size()); i++) {
 		int16 id = rs->structure[i];
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index d82d3f57a27..ceead0e2ede 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -24,11 +24,11 @@
 #ifndef FREESCAPE_AREA_H
 #define FREESCAPE_AREA_H
 
-#include "math/vector3d.h"
 #include "math/ray.h"
+#include "math/vector3d.h"
 
-#include "freescape/objects/object.h"
 #include "freescape/language/instruction.h"
+#include "freescape/objects/object.h"
 
 namespace Freescape {
 
@@ -55,7 +55,7 @@ public:
 	void addStructure(Area *global);
 	void removeObject(int16 id);
 
-	Common::Array<Common::String*> conditionSources;
+	Common::Array<Common::String *> conditionSources;
 	Common::Array<FCLInstructionVector> conditions;
 
 	// Serialization
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index eb8c2f73f94..c72dbf26434 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -359,7 +359,6 @@ void FreescapeEngine::processInput() {
 
 		default:
 			break;
-
 		}
 	}
 }
@@ -487,7 +486,6 @@ void FreescapeEngine::updateCamera() {
 	_cameraRight = v;
 }
 
-
 bool FreescapeEngine::hasFeature(EngineFeature f) const {
 	return (f == kSupportsReturnToLauncher) ||
 		   (f == kSupportsLoadingDuringRuntime) ||
@@ -502,17 +500,15 @@ void FreescapeEngine::drawStringInSurface(const Common::String &str, int x, int
 	for (uint32 c = 0; c < ustr.size(); c++) {
 		for (int j = 0; j < 6; j++) {
 			for (int i = 0; i < 8; i++) {
-				if (_font.get(48*(ustr[c] - 32) + 1 + j*8 + i))
-					surface->setPixel(x + 8 - i + 8*c, y + j, fontColor);
+				if (_font.get(48 * (ustr[c] - 32) + 1 + j * 8 + i))
+					surface->setPixel(x + 8 - i + 8 * c, y + j, fontColor);
 				else
-					surface->setPixel(x + 8 - i + 8*c, y + j, backColor);
-
+					surface->setPixel(x + 8 - i + 8 * c, y + j, backColor);
 			}
 		}
 	}
 }
 
-
 Common::Error FreescapeEngine::loadGameStream(Common::SeekableReadStream *stream) {
 
 	uint16 areaID = stream->readUint16LE();
@@ -587,7 +583,7 @@ Common::Error FreescapeEngine::saveGameStream(Common::WriteStream *stream, bool
 void FreescapeEngine::loadDataBundle() {
 	_dataBundle = Common::makeZipArchive(FREESCAPE_DATA_BUNDLE);
 	if (!_dataBundle) {
-			error("ENGINE: Couldn't load data bundle '%s'.", FREESCAPE_DATA_BUNDLE.c_str());
+		error("ENGINE: Couldn't load data bundle '%s'.", FREESCAPE_DATA_BUNDLE.c_str());
 	}
 }
 
@@ -595,13 +591,12 @@ byte *FreescapeEngine::getPaletteFromNeoImage(Common::SeekableReadStream *stream
 	stream->seek(offset);
 	Image::NeoDecoder decoder;
 	decoder.loadStream(*stream);
-	byte *palette = (byte*) malloc(16 * 3 * sizeof(byte));
+	byte *palette = (byte *)malloc(16 * 3 * sizeof(byte));
 	memcpy(palette, decoder.getPalette(), 16 * 3 * sizeof(byte));
 	return palette;
 }
 
-
-Graphics::Surface *FreescapeEngine::loadAndConvertNeoImage(Common::SeekableReadStream *stream, int offset, byte* palette) {
+Graphics::Surface *FreescapeEngine::loadAndConvertNeoImage(Common::SeekableReadStream *stream, int offset, byte *palette) {
 	stream->seek(offset);
 	Image::NeoDecoder decoder(palette);
 	decoder.loadStream(*stream);
@@ -611,5 +606,4 @@ Graphics::Surface *FreescapeEngine::loadAndConvertNeoImage(Common::SeekableReadS
 	return surface;
 }
 
-
 } // namespace Freescape
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 85f03724d4c..735ff35b669 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -24,20 +24,20 @@
 
 #include "common/bitarray.h"
 #include "common/random.h"
-#include "engines/engine.h"
 #include "engines/advancedDetector.h"
+#include "engines/engine.h"
 #include "graphics/palette.h"
 #include "graphics/surface.h"
 #include "graphics/tinygl/pixelbuffer.h"
 
-#include "audio/mixer.h"
 #include "audio/decoders/wave.h"
+#include "audio/mixer.h"
 #include "audio/softsynth/pcspk.h"
 
 #include "freescape/area.h"
-#include "freescape/objects/geometricobject.h"
-#include "freescape/objects/entrance.h"
 #include "freescape/gfx.h"
+#include "freescape/objects/entrance.h"
+#include "freescape/objects/geometricobject.h"
 
 namespace Freescape {
 
@@ -52,8 +52,8 @@ enum CameraMovement {
 	kRightMovement
 };
 
-typedef Common::HashMap<uint16, Area*> AreaMap;
-typedef Common::Array<byte*> ColorMap;
+typedef Common::HashMap<uint16, Area *> AreaMap;
+typedef Common::Array<byte *> ColorMap;
 typedef Common::HashMap<uint16, int32> StateVars;
 typedef Common::HashMap<uint16, uint32> StateBits;
 
@@ -93,8 +93,8 @@ public:
 	bool isDark() { return _targetName.hasPrefix("darkside"); }
 	bool isEclipse() { return _targetName.hasPrefix("totaleclipse"); }
 	bool isCastle() { return _targetName.hasPrefix("castle"); }
-	bool isAmiga() { return _targetName.hasSuffix("-amiga") || Common::matchString(_targetName.c_str() ,"*-amiga-#"); }
-	bool isAtariST() { return _targetName.hasSuffix("-st") || Common::matchString(_targetName.c_str() ,"*-st-#"); }
+	bool isAmiga() { return _targetName.hasSuffix("-amiga") || Common::matchString(_targetName.c_str(), "*-amiga-#"); }
+	bool isAtariST() { return _targetName.hasSuffix("-st") || Common::matchString(_targetName.c_str(), "*-st-#"); }
 	bool isDOS() { return !isAmiga() && !isAtariST(); }
 
 	Common::Error run() override;
@@ -120,10 +120,10 @@ public:
 	void loadDataBundle();
 	void loadBundledImages();
 	byte *getPaletteFromNeoImage(Common::SeekableReadStream *stream, int offset);
-	Graphics::Surface *loadAndConvertNeoImage(Common::SeekableReadStream *stream, int offset, byte* palette = nullptr);
+	Graphics::Surface *loadAndConvertNeoImage(Common::SeekableReadStream *stream, int offset, byte *palette = nullptr);
 	void loadPalettes(Common::SeekableReadStream *file, int offset);
 	void swapPalette(uint16 areaID);
-	Common::HashMap<uint16, byte*> _paletteByArea;
+	Common::HashMap<uint16, byte *> _paletteByArea;
 	void loadColorPalette();
 	Common::Array<byte> _demoData;
 	int _demoIndex;
@@ -150,7 +150,7 @@ public:
 	virtual void gotoArea(uint16 areaID, int entranceID);
 	// Entrance
 	uint16 _startEntrance;
-	Common::HashMap<int, const struct entrancesTableEntry*> _entranceTable;
+	Common::HashMap<int, const struct entrancesTableEntry *> _entranceTable;
 
 	// Input
 	bool _demoMode;
@@ -203,7 +203,7 @@ public:
 	uint16 _playerDepth;
 
 	// Effects
-	Common::Array<Common::String*> _conditionSources;
+	Common::Array<Common::String *> _conditionSources;
 	Common::Array<FCLInstructionVector> _conditions;
 
 	bool checkCollisions(bool executeCode);
@@ -245,7 +245,7 @@ public:
 
 	void playSoundFx(int index, bool sync);
 	void loadSoundsFx(Common::SeekableReadStream *file, int offset, int number);
-	Common::HashMap<uint16, soundFx*> _soundsFx;
+	Common::HashMap<uint16, soundFx *> _soundsFx;
 
 	// Rendering
 	int _screenW, _screenH;
@@ -271,7 +271,6 @@ public:
 	bool _fontLoaded;
 	void drawStringInSurface(const Common::String &str, int x, int y, uint32 fontColor, uint32 backColor, Graphics::Surface *surface);
 
-
 	// Game state
 	virtual void initGameState();
 	StateVars _gameStateVars;
diff --git a/engines/freescape/games/castle.cpp b/engines/freescape/games/castle.cpp
index e4024bf3d5f..56571dbdd14 100644
--- a/engines/freescape/games/castle.cpp
+++ b/engines/freescape/games/castle.cpp
@@ -43,19 +43,18 @@ Common::SeekableReadStream *CastleEngine::decryptFile(const Common::String filen
 
 	Common::SeekableReadStream *file = gameDir.createReadStreamForMember(filename);
 	int size = file->size();
-	byte *encryptedBuffer = (byte*) malloc(size);
+	byte *encryptedBuffer = (byte *)malloc(size);
 	file->read(encryptedBuffer, size);
 
 	int seed = 24;
 	for (int i = 0; i < size; i++) {
 		encryptedBuffer[i] ^= seed;
 		seed = (seed + 1) & 0xff;
-    }
+	}
 
 	return (new Common::MemoryReadStream(encryptedBuffer, size));
 }
 
-
 void CastleEngine::loadAssets() {
 	Common::SeekableReadStream *file = nullptr;
 	_renderMode = "ega";
@@ -70,10 +69,10 @@ void CastleEngine::loadAssets() {
 		iterator->_value->addStructure(_areaMap[255]);
 
 	// CPC
-	//file = gameDir.createReadStreamForMember("cm.bin");
-	//if (file == nullptr)
+	// file = gameDir.createReadStreamForMember("cm.bin");
+	// if (file == nullptr)
 	//	error("Failed to open cm.bin");
-	//load8bitBinary(file, 0x791a, 16);
+	// load8bitBinary(file, 0x791a, 16);
 }
 
 void CastleEngine::gotoArea(uint16 areaID, int entranceID) {
@@ -98,5 +97,4 @@ void CastleEngine::gotoArea(uint16 areaID, int entranceID) {
 		_gfx->_keyColor = 255;
 }
 
-
 } // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index 1ef078dcfc0..747c9f24ef0 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -84,8 +84,8 @@ void DarkEngine::gotoArea(uint16 areaID, int entranceID) {
 		traverseEntrance(entranceID);
 	} else if (entranceID == 0) {
 		Math::Vector3d diff = _lastPosition - _position;
-		//debug("dif: %f %f %f", diff.x(), diff.y(), diff.z());
-		// diff should be used to determinate which entrance to use
+		// debug("dif: %f %f %f", diff.x(), diff.y(), diff.z());
+		//  diff should be used to determinate which entrance to use
 		int newPos = -1;
 		if (abs(diff.x()) < abs(diff.z())) {
 			if (diff.z() > 0)
@@ -114,7 +114,6 @@ void DarkEngine::gotoArea(uint16 areaID, int entranceID) {
 		_gfx->_keyColor = 255;
 }
 
-
 void DarkEngine::drawUI() {
 	_gfx->renderCrossair(0, _crossairPosition);
 
@@ -135,7 +134,6 @@ void DarkEngine::drawUI() {
 		drawStringInSurface(Common::String::format("%04d", 2 * int(_position.z())), 201, 145, yellow, black, surface);
 		drawStringInSurface(Common::String::format("%04d", 2 * int(_position.y())), 201, 153, yellow, black, surface);
 
-
 		drawStringInSurface(Common::String::format("%07d", score), 95, 8, yellow, black, surface);
 
 		if (!_uiTexture)
@@ -151,5 +149,4 @@ void DarkEngine::drawUI() {
 	_gfx->setViewport(_viewArea);
 }
 
-
 } // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 9fd62c5de73..f4746da136e 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -29,9 +29,9 @@
 namespace Freescape {
 
 DrillerEngine::DrillerEngine(OSystem *syst, const ADGameDescription *gd) : FreescapeEngine(syst, gd) {
-	//if (isAmiga())
+	// if (isAmiga())
 	//	_viewArea = Common::Rect(72, 66, 567, 269);
-	//else
+	// else
 	_viewArea = Common::Rect(40, 16, 279, 116);
 	_playerHeightNumber = 1;
 	_playerHeights.push_back(16);
@@ -72,8 +72,8 @@ void DrillerEngine::gotoArea(uint16 areaID, int entranceID) {
 		traverseEntrance(entranceID);
 	} else if (entranceID == 0) {
 		Math::Vector3d diff = _lastPosition - _position;
-		//debug("dif: %f %f %f", diff.x(), diff.y(), diff.z());
-		// diff should be used to determinate which entrance to use
+		// debug("dif: %f %f %f", diff.x(), diff.y(), diff.z());
+		//  diff should be used to determinate which entrance to use
 		int newPos = -1;
 		if (abs(diff.x()) < abs(diff.z())) {
 			if (diff.z() > 0)
@@ -161,7 +161,7 @@ void DrillerEngine::loadAssetsDemo() {
 		if (file == nullptr)
 			error("Failed to open 'data' file");
 
-		//loadGlobalObjects(file, 0xbd62);
+		// loadGlobalObjects(file, 0xbd62);
 		/*file->seek(0x29efe);
 		load8bitArea(file, 16);
 		file->seek(0x2a450);
@@ -204,7 +204,7 @@ void DrillerEngine::loadAssetsDemo() {
 		if (file == nullptr)
 			error("Failed to open 'data' file");
 
-		//loadGlobalObjects(file, 0xbd62);
+		// loadGlobalObjects(file, 0xbd62);
 		/*file->seek(0x29efe);
 		load8bitArea(file, 16);
 		file->seek(0x2a450);
@@ -223,15 +223,13 @@ void DrillerEngine::loadAssetsDemo() {
 			error("Failed to open 'soundfx' executable for AtariST demo");
 
 		loadSoundsFx(file, 0, 25);
-	}
-	else
+	} else
 		error("Unsupported demo for Driller");
 
 	_demoMode = true;
 	_angleRotationIndex = 1;
 }
 
-
 void DrillerEngine::loadAssetsFullGame() {
 	Common::SeekableReadStream *file = nullptr;
 	Common::String path = ConfMan.get("path");
@@ -246,7 +244,7 @@ void DrillerEngine::loadAssetsFullGame() {
 				error("Failed to open 'driller' executable for Amiga");
 
 			_border = loadAndConvertNeoImage(file, 0x137f4);
-			byte *palette = (byte*) malloc(16 * 3);
+			byte *palette = (byte *)malloc(16 * 3);
 			for (int i = 0; i < 16; i++) { // gray scale palette
 				palette[i * 3 + 0] = i * (255 / 16);
 				palette[i * 3 + 1] = i * (255 / 16);
@@ -331,7 +329,6 @@ void DrillerEngine::drawUI() {
 		drawStringInSurface(Common::String::format("%04d", 2 * int(_position.y())), 150, 161, yellow, black, surface);
 		drawStringInSurface(Common::String::format("%d", _playerHeightNumber), 57, 161, yellow, black, surface);
 
-
 		drawStringInSurface(Common::String::format("%07d", score), 240, 129, yellow, black, surface);
 
 		if (!_uiTexture)
@@ -347,7 +344,7 @@ void DrillerEngine::drawUI() {
 	int energy = _gameStateVars[k8bitVariableEnergy];
 	int shield = _gameStateVars[k8bitVariableShield];
 	if (_renderMode == "ega" && _border) {
-		//Common::Rect black(20, 177, 87, 191);
+		// Common::Rect black(20, 177, 87, 191);
 		//_gfx->drawRect2D(black, 255, 0, 0, 0);
 
 		if (energy >= 0) {
@@ -394,7 +391,7 @@ void DrillerEngine::pressedKey(const int keycode) {
 		_gameStateVars[32]++;
 		// TODO: check if there is space for the drill
 		Math::Vector3d drillPosition = _cameraFront;
-		drillPosition =  _position + 256 * drillPosition;
+		drillPosition = _position + 256 * drillPosition;
 
 		debugC(1, kFreescapeDebugMove, "Current position at %f %f %f", _position.x(), _position.y(), _position.z());
 		drillPosition.setValue(1, _position.y() - _playerHeight * _currentArea->getScale());
@@ -439,7 +436,7 @@ bool DrillerEngine::drillDeployed() {
 }
 
 void DrillerEngine::addDrill(const Math::Vector3d position) {
-	//int drillObjectIDs[8] = {255, 254, 253, 252, 251, 250, 248, 247};
+	// int drillObjectIDs[8] = {255, 254, 253, 252, 251, 250, 248, 247};
 	GeometricObject *obj = nullptr;
 	Math::Vector3d origin = position;
 
@@ -448,11 +445,11 @@ void DrillerEngine::addDrill(const Math::Vector3d position) {
 
 	id = 255;
 	debugC(1, kFreescapeDebugParser, "Adding object %d to room structure", id);
-	obj = (GeometricObject*) _areaMap[255]->objectWithID(id);
+	obj = (GeometricObject *)_areaMap[255]->objectWithID(id);
 	assert(obj);
 	obj = obj->duplicate();
 	obj->setOrigin(origin);
-	//offset.setValue(1, offset.y() + obj->getSize().y());
+	// offset.setValue(1, offset.y() + obj->getSize().y());
 	obj->makeVisible();
 	_currentArea->addObject(obj);
 
@@ -460,7 +457,7 @@ void DrillerEngine::addDrill(const Math::Vector3d position) {
 
 	id = 254;
 	debugC(1, kFreescapeDebugParser, "Adding object %d to room structure", id);
-	obj = (GeometricObject*) _areaMap[255]->objectWithID(id);
+	obj = (GeometricObject *)_areaMap[255]->objectWithID(id);
 	assert(obj);
 	// Set position for object
 	origin.setValue(0, origin.x() - obj->getSize().x() / 5);
@@ -479,7 +476,7 @@ void DrillerEngine::addDrill(const Math::Vector3d position) {
 
 	id = 253;
 	debugC(1, kFreescapeDebugParser, "Adding object %d to room structure", id);
-	obj = (GeometricObject*) _areaMap[255]->objectWithID(id);
+	obj = (GeometricObject *)_areaMap[255]->objectWithID(id);
 	assert(obj);
 	obj = obj->duplicate();
 
@@ -492,13 +489,13 @@ void DrillerEngine::addDrill(const Math::Vector3d position) {
 	_currentArea->addObject(obj);
 
 	// Undo offset
-	//origin.setValue(0, origin.x() - obj->getSize().x() / 5);
+	// origin.setValue(0, origin.x() - obj->getSize().x() / 5);
 	heightLastObject = obj->getSize().y();
-	//origin.setValue(2, origin.z() - obj->getSize().z() / 5);
+	// origin.setValue(2, origin.z() - obj->getSize().z() / 5);
 
 	id = 252;
 	debugC(1, kFreescapeDebugParser, "Adding object %d to room structure", id);
-	obj = (GeometricObject*) _areaMap[255]->objectWithID(id);
+	obj = (GeometricObject *)_areaMap[255]->objectWithID(id);
 	assert(obj);
 	obj = obj->duplicate();
 	origin.setValue(1, origin.y() + heightLastObject);
diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index e998edb4d9d..f3d13034fe8 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -35,7 +35,7 @@ static const entrancesTableEntry rawEntranceTable[] = {
 	{187, {36, 137, 13}}, // TODO
 	{188, {352, 105, 204}},
 	{190, {36, 137, 13}}, // TODO
-	{191, {49, 7, 23}}, // TODO
+	{191, {49, 7, 23}},   // TODO
 	{192, {36, 137, 13}}, // TODO
 	{193, {36, 137, 13}}, // TODO
 	{194, {36, 137, 13}}, // TODO
@@ -50,10 +50,10 @@ static const entrancesTableEntry rawEntranceTable[] = {
 	{203, {207, 25, 384}},
 	{204, {33, 48, 366}},
 	{206, {25, 8, 200}},
-	{0, {0, 0, 0}},        // NULL
+	{0, {0, 0, 0}}, // NULL
 };
 
-static const char* rawMessagesTable[] = {
+static const char *rawMessagesTable[] = {
 	"HEART  FAILURE",
 	"SUN ECLIPSED",
 	"CRUSHED TO DEATH",
@@ -72,8 +72,7 @@ static const char* rawMessagesTable[] = {
 	"REMOVE LID",
 	"POISON AIR",
 	"MATCH MADE",
-	NULL
-};
+	NULL};
 
 EclipseEngine::EclipseEngine(OSystem *syst, const ADGameDescription *gd) : FreescapeEngine(syst, gd) {
 	_viewArea = Common::Rect(40, 32, 280, 132);
@@ -128,7 +127,6 @@ void EclipseEngine::loadAssets() {
 		load8bitBinary(file, 0x7bb0, 4); // TODO
 	} else
 		error("Invalid render mode %s for Total Eclipse", _renderMode.c_str());
-
 }
 
 void EclipseEngine::gotoArea(uint16 areaID, int entranceID) {
@@ -152,7 +150,7 @@ void EclipseEngine::gotoArea(uint16 areaID, int entranceID) {
 
 	assert(entranceID > 0);
 
-	entrance = (Entrance*) _currentArea->entranceWithID(entranceID);
+	entrance = (Entrance *)_currentArea->entranceWithID(entranceID);
 
 	if (!entrance) {
 		assert(_entranceTable.contains(entranceID));
@@ -173,7 +171,6 @@ void EclipseEngine::gotoArea(uint16 areaID, int entranceID) {
 		_gfx->_keyColor = 255;
 }
 
-
 void EclipseEngine::drawUI() {
 	_gfx->renderCrossair(0, _crossairPosition);
 	_gfx->setViewport(_fullscreenViewArea);
@@ -204,5 +201,4 @@ void EclipseEngine::drawUI() {
 	_gfx->setViewport(_viewArea);
 }
 
-
 } // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/games/palettes.cpp b/engines/freescape/games/palettes.cpp
index 7801f39dda4..f9910c7acd4 100644
--- a/engines/freescape/games/palettes.cpp
+++ b/engines/freescape/games/palettes.cpp
@@ -39,8 +39,7 @@ byte dos_EGA_palette[16][3] = {
 	{0xff, 0x55, 0x55},
 	{0xff, 0x55, 0xff},
 	{0xff, 0xff, 0x55},
-	{0xff, 0xff, 0xff}
-};
+	{0xff, 0xff, 0xff}};
 
 byte dos_CGA_palette[4][3] = {
 	{0x00, 0x00, 0x00},
@@ -49,13 +48,12 @@ byte dos_CGA_palette[4][3] = {
 	{0x00, 0xa8, 0xa8},
 };
 
-
 void FreescapeEngine::loadColorPalette() {
 	Graphics::PixelBuffer *palette = nullptr;
 	if (_renderMode == "ega")
-		palette = new Graphics::PixelBuffer(_gfx->_palettePixelFormat, (byte*)&dos_EGA_palette);
+		palette = new Graphics::PixelBuffer(_gfx->_palettePixelFormat, (byte *)&dos_EGA_palette);
 	else if (_renderMode == "cga")
-		palette = new Graphics::PixelBuffer(_gfx->_palettePixelFormat, (byte*)&dos_CGA_palette);
+		palette = new Graphics::PixelBuffer(_gfx->_palettePixelFormat, (byte *)&dos_CGA_palette);
 	else if (_renderMode == "amiga" || _renderMode == "atari")
 		palette = nullptr; // palette depends on the area
 	else
@@ -86,7 +84,7 @@ void FreescapeEngine::loadPalettes(Common::SeekableReadStream *file, int offset)
 		}
 
 		assert(!_paletteByArea.contains(label));
-		_paletteByArea[label] = (byte*) palette;
+		_paletteByArea[label] = (byte *)palette;
 	}
 }
 
@@ -97,5 +95,4 @@ void FreescapeEngine::swapPalette(uint16 levelID) {
 	_gfx->_palette = new Graphics::PixelBuffer(_gfx->_palettePixelFormat, _paletteByArea[levelID]);
 }
 
-
 } // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index a38d5fe3718..a5067769034 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -26,15 +26,15 @@
 #include "graphics/opengl/context.h"
 #endif
 
-#include "math/glmath.h"
 #include "engines/util.h"
+#include "math/glmath.h"
 
 #include "engines/freescape/gfx.h"
 
 namespace Freescape {
 
 Renderer::Renderer(OSystem *system, int screenW, int screenH)
-		: _system(system) {
+	: _system(system) {
 
 	_screenW = screenW;
 	_screenH = screenH;
@@ -51,7 +51,7 @@ Renderer::Renderer(OSystem *system, int screenW, int screenH)
 Renderer::~Renderer() {}
 
 Graphics::Surface *Renderer::convertFromPalette(Graphics::PixelBuffer *rawsurf) {
-	Graphics::Surface * surf = new Graphics::Surface();
+	Graphics::Surface *surf = new Graphics::Surface();
 	surf->create(_screenW, _screenH, _originalPixelFormat);
 	surf->copyRectToSurface(rawsurf->getRawBuffer(), surf->w, 0, 0, surf->w, surf->h);
 	surf->convertToInPlace(_currentPixelFormat, _palette->getRawBuffer());
@@ -73,8 +73,8 @@ bool Renderer::getRGBAt(uint8 index, uint8 &r, uint8 &g, uint8 &b) {
 		return true;
 	}
 
-	//assert(index-1 < _colorMap->size());
-	byte *entry = (*_colorMap)[index-1];
+	// assert(index-1 < _colorMap->size());
+	byte *entry = (*_colorMap)[index - 1];
 	uint8 color = 0;
 	uint8 acc = 1;
 	for (int i = 0; i < 4; i++) {
@@ -96,7 +96,6 @@ bool Renderer::getRGBAt(uint8 index, uint8 &r, uint8 &g, uint8 &b) {
 	return true;
 }
 
-
 Common::Rect Renderer::viewport() const {
 	return _screenViewport;
 }
@@ -108,10 +107,10 @@ void Renderer::computeScreenViewport() {
 Renderer *createRenderer(OSystem *system, int screenW, int screenH) {
 	Common::String rendererConfig = ConfMan.get("renderer");
 	Graphics::PixelFormat pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
-	Graphics::RendererType desiredRendererType = Graphics::kRendererTypeTinyGL; //Graphics::parseRendererTypeCode(rendererConfig);
-	Graphics::RendererType matchingRendererType = Graphics::kRendererTypeTinyGL; //Graphics::getBestMatchingAvailableRendererType(desiredRendererType);
+	Graphics::RendererType desiredRendererType = Graphics::kRendererTypeTinyGL;  // Graphics::parseRendererTypeCode(rendererConfig);
+	Graphics::RendererType matchingRendererType = Graphics::kRendererTypeTinyGL; // Graphics::getBestMatchingAvailableRendererType(desiredRendererType);
 
-	bool isAccelerated = 0; //matchingRendererType != Graphics::kRendererTypeTinyGL;
+	bool isAccelerated = 0; // matchingRendererType != Graphics::kRendererTypeTinyGL;
 
 	if (isAccelerated) {
 		initGraphics3d(screenW, screenH);
@@ -119,32 +118,32 @@ Renderer *createRenderer(OSystem *system, int screenW, int screenH) {
 		initGraphics(screenW, screenH, &pixelFormat);
 	}
 
-/*#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS) || defined(USE_GLES2)
-	bool backendCapableOpenGL = g_system->hasFeature(OSystem::kFeatureOpenGLForGame);
-#endif
+	/*#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS) || defined(USE_GLES2)
+		bool backendCapableOpenGL = g_system->hasFeature(OSystem::kFeatureOpenGLForGame);
+	#endif
 
-#if defined(USE_OPENGL_GAME)
-	// Check the OpenGL context actually supports shaders
-	if (backendCapableOpenGL && matchingRendererType == Graphics::kRendererTypeOpenGLShaders && !OpenGLContext.shadersSupported) {
-		matchingRendererType = Graphics::kRendererTypeOpenGL;
-	}
-#endif*/
+	#if defined(USE_OPENGL_GAME)
+		// Check the OpenGL context actually supports shaders
+		if (backendCapableOpenGL && matchingRendererType == Graphics::kRendererTypeOpenGLShaders && !OpenGLContext.shadersSupported) {
+			matchingRendererType = Graphics::kRendererTypeOpenGL;
+		}
+	#endif*/
 
 	if (matchingRendererType != desiredRendererType && desiredRendererType != Graphics::kRendererTypeDefault) {
 		// Display a warning if unable to use the desired renderer
 		warning("Unable to create a '%s' renderer", rendererConfig.c_str());
 	}
-/*
-#if defined(USE_GLES2) || defined(USE_OPENGL_SHADERS)
-	if (backendCapableOpenGL && matchingRendererType == Graphics::kRendererTypeOpenGLShaders) {
-		return CreateGfxOpenGLShader(system);
-	}
-#endif
-#if defined(USE_OPENGL_GAME) && !defined(USE_GLES2)
-	if (backendCapableOpenGL && matchingRendererType == Graphics::kRendererTypeOpenGL) {
-		return CreateGfxOpenGL(system);
-	}
-#endif*/
+	/*
+	#if defined(USE_GLES2) || defined(USE_OPENGL_SHADERS)
+		if (backendCapableOpenGL && matchingRendererType == Graphics::kRendererTypeOpenGLShaders) {
+			return CreateGfxOpenGLShader(system);
+		}
+	#endif
+	#if defined(USE_OPENGL_GAME) && !defined(USE_GLES2)
+		if (backendCapableOpenGL && matchingRendererType == Graphics::kRendererTypeOpenGL) {
+			return CreateGfxOpenGL(system);
+		}
+	#endif*/
 	if (matchingRendererType == Graphics::kRendererTypeTinyGL) {
 		return CreateGfxTinyGL(system, screenW, screenH);
 	}
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index ab305beb50c..a2c378c00b0 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -25,21 +25,21 @@
 #include "common/rect.h"
 #include "common/system.h"
 
+#include "graphics/tinygl/pixelbuffer.h"
 #include "math/frustum.h"
 #include "math/matrix4.h"
 #include "math/vector3d.h"
-#include "graphics/tinygl/pixelbuffer.h"
 
 namespace Freescape {
 
-typedef Common::Array<byte*> ColorMap;
+typedef Common::Array<byte *> ColorMap;
 
 class Renderer;
 
 class Texture {
 public:
-	Texture() {};
-	virtual ~Texture() {};
+	Texture(){};
+	virtual ~Texture(){};
 
 	uint width;
 	uint height;
@@ -60,12 +60,11 @@ public:
 	Graphics::PixelFormat _originalPixelFormat;
 	Graphics::PixelFormat _palettePixelFormat;
 
-    /**
+	/**
 	 *   Convert from paletted surface
-     */
+	 */
 	Graphics::Surface *convertFromPalette(Graphics::PixelBuffer *rawsurf);
 
-
 	virtual void init() = 0;
 	virtual void clear() = 0;
 	virtual void setViewport(const Common::Rect &rect) = 0;
@@ -82,7 +81,7 @@ public:
 	/**
 	 *  Swap the buffers, making the drawn screen visible
 	 */
-	virtual void flipBuffer() { }
+	virtual void flipBuffer() {}
 
 	virtual Texture *createTexture(const Graphics::Surface *surface) = 0;
 	virtual void freeTexture(Texture *texture) = 0;
@@ -155,6 +154,7 @@ public:
 
 	void startFrame();
 	void delayBeforeSwap();
+
 private:
 	OSystem *_system;
 
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index d85c7de476a..a1c48dd96fa 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -22,10 +22,10 @@
 // Based on Phantasma code by Thomas Harte (2013)
 
 #include "common/config-manager.h"
-#include "common/rect.h"
-#include "math/glmath.h"
 #include "common/math.h"
+#include "common/rect.h"
 #include "graphics/tinygl/tinygl.h"
+#include "math/glmath.h"
 
 #include "engines/freescape/gfx_tinygl.h"
 #include "engines/freescape/gfx_tinygl_texture.h"
@@ -53,7 +53,7 @@ void TinyGLRenderer::freeTexture(Texture *texture) {
 }
 
 void TinyGLRenderer::init() {
-	//debug("Initializing Software 3D Renderer");
+	// debug("Initializing Software 3D Renderer");
 
 	computeScreenViewport();
 
@@ -98,11 +98,11 @@ void TinyGLRenderer::updateProjectionMatrix(float fov, float nearClipPlane, floa
 	tglMatrixMode(TGL_PROJECTION);
 	tglLoadIdentity();
 
-	float aspectRatio = _screenW / (float) _screenH;
+	float aspectRatio = _screenW / (float)_screenH;
 
 	float xmaxValue = nearClipPlane * tan(Common::deg2rad(fov) / 2);
 	float ymaxValue = xmaxValue / aspectRatio;
-	//debug("max values: %f %f", xmaxValue, ymaxValue);
+	// debug("max values: %f %f", xmaxValue, ymaxValue);
 
 	tglFrustum(xmaxValue, -xmaxValue, -ymaxValue, ymaxValue, nearClipPlane, farClipPlane);
 	tglMatrixMode(TGL_MODELVIEW);
@@ -127,10 +127,10 @@ void TinyGLRenderer::drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint
 	}
 
 	tglBegin(TGL_TRIANGLE_STRIP);
-		tglVertex3f(rect.left, rect.bottom, 0.0f);
-		tglVertex3f(rect.right, rect.bottom, 0.0f);
-		tglVertex3f(rect.left, rect.top, 0.0f);
-		tglVertex3f(rect.right, rect.top, 0.0f);
+	tglVertex3f(rect.left, rect.bottom, 0.0f);
+	tglVertex3f(rect.right, rect.bottom, 0.0f);
+	tglVertex3f(rect.left, rect.top, 0.0f);
+	tglVertex3f(rect.right, rect.top, 0.0f);
 	tglEnd();
 
 	tglDisable(TGL_BLEND);
@@ -209,8 +209,8 @@ void TinyGLRenderer::renderFace(const Common::Array<Math::Vector3d> &vertices) {
 		if (v0 == v1)
 			return;
 		tglBegin(TGL_LINES);
-		tglVertex3f(v0.x(), v0.y(),	v0.z());
-		tglVertex3f(v1.x(), v1.y(),	v1.z());
+		tglVertex3f(v0.x(), v0.y(), v0.z());
+		tglVertex3f(v1.x(), v1.y(), v1.z());
 		tglEnd();
 		return;
 	}
@@ -218,16 +218,16 @@ void TinyGLRenderer::renderFace(const Common::Array<Math::Vector3d> &vertices) {
 	tglBegin(TGL_TRIANGLES);
 	for (int i = 1; i < int(vertices.size()) - 1; i++) {
 		const Math::Vector3d &v1 = vertices[i];
-		const Math::Vector3d &v2 = vertices[i+1];
-		tglVertex3f(v0.x(), v0.y(),	v0.z());
-		tglVertex3f(v1.x(), v1.y(),	v1.z());
-		tglVertex3f(v2.x(), v2.y(),	v2.z());
+		const Math::Vector3d &v2 = vertices[i + 1];
+		tglVertex3f(v0.x(), v0.y(), v0.z());
+		tglVertex3f(v1.x(), v1.y(), v1.z());
+		tglVertex3f(v2.x(), v2.y(), v2.z());
 	}
 	tglEnd();
 }
 
 void TinyGLRenderer::renderPolygon(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours) {
-	//assert(size.x() == 0 || size.y() == 0 || size.z() == 0);
+	// assert(size.x() == 0 || size.y() == 0 || size.z() == 0);
 	uint8 r, g, b;
 	if (ordinates->size() % 3 > 0 && ordinates->size() > 0)
 		error("Invalid polygon with size %f %f %f and ordinates %d", size.x(), size.y(), size.z(), ordinates->size());
@@ -236,18 +236,18 @@ void TinyGLRenderer::renderPolygon(const Math::Vector3d &origin, const Math::Vec
 	tglEnable(TGL_POLYGON_OFFSET_FILL);
 	tglPolygonOffset(-2.0f, 1.f);
 
-	if (ordinates->size() == 6) { // Line
+	if (ordinates->size() == 6) {                 // Line
 		assert(getRGBAt((*colours)[0], r, g, b)); // It will never return false?
 		tglColor3ub(r, g, b);
 		for (int i = 0; i < int(ordinates->size()); i = i + 3)
-			vertices.push_back(Math::Vector3d((*ordinates)[i], (*ordinates)[i + 1],	(*ordinates)[i + 2]));
+			vertices.push_back(Math::Vector3d((*ordinates)[i], (*ordinates)[i + 1], (*ordinates)[i + 2]));
 		renderFace(vertices);
 
 		vertices.clear();
 		assert(getRGBAt((*colours)[1], r, g, b)); // It will never return false?
 		tglColor3ub(r, g, b);
 		for (int i = ordinates->size(); i > 0; i = i - 3)
-			vertices.push_back(Math::Vector3d((*ordinates)[i-3], (*ordinates)[i-2],	(*ordinates)[i-1]));
+			vertices.push_back(Math::Vector3d((*ordinates)[i - 3], (*ordinates)[i - 2], (*ordinates)[i - 1]));
 		renderFace(vertices);
 
 	} else {
@@ -262,7 +262,7 @@ void TinyGLRenderer::renderPolygon(const Math::Vector3d &origin, const Math::Vec
 		if (getRGBAt((*colours)[1], r, g, b)) {
 			tglColor3ub(r, g, b);
 			for (int i = ordinates->size(); i > 0; i = i - 3) {
-				vertices.push_back(Math::Vector3d((*ordinates)[i-3], (*ordinates)[i-2], (*ordinates)[i-1]));
+				vertices.push_back(Math::Vector3d((*ordinates)[i - 3], (*ordinates)[i - 2], (*ordinates)[i - 1]));
 			}
 			renderFace(vertices);
 		}
@@ -283,7 +283,7 @@ void TinyGLRenderer::renderRectangle(const Math::Vector3d &origin, const Math::V
 	Common::Array<Math::Vector3d> vertices;
 	for (int i = 0; i < 2; i++) {
 
-		//debug("rec color: %d", (*colours)[i]);
+		// debug("rec color: %d", (*colours)[i]);
 		if (getRGBAt((*colours)[i], r, g, b)) {
 			tglColor3ub(r, g, b);
 			vertices.clear();
@@ -298,7 +298,7 @@ void TinyGLRenderer::renderRectangle(const Math::Vector3d &origin, const Math::V
 				dx = size.x();
 			}
 
-			vertices.push_back(Math::Vector3d(origin.x() + dx,	origin.y() + dy, origin.z() + dz));
+			vertices.push_back(Math::Vector3d(origin.x() + dx, origin.y() + dy, origin.z() + dz));
 			vertices.push_back(Math::Vector3d(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z()));
 			renderFace(vertices);
 
@@ -314,7 +314,7 @@ void TinyGLRenderer::renderRectangle(const Math::Vector3d &origin, const Math::V
 				dy = size.y();
 			}
 
-			vertices.push_back(Math::Vector3d(origin.x() + dx,	origin.y() + dy, origin.z() + dz));
+			vertices.push_back(Math::Vector3d(origin.x() + dx, origin.y() + dy, origin.z() + dz));
 			vertices.push_back(Math::Vector3d(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z()));
 			renderFace(vertices);
 		}
@@ -326,80 +326,87 @@ void TinyGLRenderer::renderRectangle(const Math::Vector3d &origin, const Math::V
 
 void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours, int type) {
 	Math::Vector3d vertices[8] = {
-		origin,		origin,		origin,		origin,
-		origin,		origin,		origin,		origin,
+		origin,
+		origin,
+		origin,
+		origin,
+		origin,
+		origin,
+		origin,
+		origin,
 	};
 	PyramidType pyramidType = (PyramidType)type;
-	switch(pyramidType) {
-		default: break;
-		case EastPyramid:
-			vertices[0] += Math::Vector3d(0, 0, size.z());
-			vertices[1] += Math::Vector3d(0, size.y(), size.z());
-			vertices[2] += Math::Vector3d(0, size.y(), 0);
-
-			vertices[4] += Math::Vector3d(size.x(), (*ordinates)[0], (*ordinates)[3]);
-			vertices[5] += Math::Vector3d(size.x(), (*ordinates)[2], (*ordinates)[3]);
-			vertices[6] += Math::Vector3d(size.x(), (*ordinates)[2], (*ordinates)[1]);
-			vertices[7] += Math::Vector3d(size.x(), (*ordinates)[0], (*ordinates)[1]);
-			break;
-		case WestPyramid:
-
-			vertices[0] += Math::Vector3d(size.x(), 0, 0);
-			vertices[1] += Math::Vector3d(size.x(), size.y(), 0);
-			vertices[2] += Math::Vector3d(size.x(), size.y(), size.z());
-			vertices[3] += Math::Vector3d(size.x(), 0, size.z());
-
-			vertices[4] += Math::Vector3d(0, (*ordinates)[0], (*ordinates)[1]);
-			vertices[5] += Math::Vector3d(0, (*ordinates)[2], (*ordinates)[1]);
-			vertices[6] += Math::Vector3d(0, (*ordinates)[2], (*ordinates)[3]);
-			vertices[7] += Math::Vector3d(0, (*ordinates)[0], (*ordinates)[3]);
-			break;
-
-		case UpPyramid:
-			vertices[1] += Math::Vector3d(size.x(), 0, 0);
-			vertices[2] += Math::Vector3d(size.x(), 0, size.z());
-			vertices[3] += Math::Vector3d(0, 0, size.z());
-
-			vertices[4] += Math::Vector3d((*ordinates)[0], size.y(), (*ordinates)[1]);
-			vertices[5] += Math::Vector3d((*ordinates)[2], size.y(), (*ordinates)[1]);
-			vertices[6] += Math::Vector3d((*ordinates)[2], size.y(), (*ordinates)[3]);
-			vertices[7] += Math::Vector3d((*ordinates)[0], size.y(), (*ordinates)[3]);
-			break;
-
-		case DownPyramid:
-
-			vertices[0] += Math::Vector3d(size.x(), size.y(), 0);
-			vertices[1] += Math::Vector3d(0, size.y(), 0);
-			vertices[2] += Math::Vector3d(0, size.y(), size.z());
-			vertices[3] += Math::Vector3d(size.x(), size.y(), size.z());
-
-			vertices[4] += Math::Vector3d((*ordinates)[2], 0, (*ordinates)[1]);
-			vertices[5] += Math::Vector3d((*ordinates)[0], 0, (*ordinates)[1]);
-			vertices[6] += Math::Vector3d((*ordinates)[0], 0, (*ordinates)[3]);
-			vertices[7] += Math::Vector3d((*ordinates)[2], 0, (*ordinates)[3]);
-			break;
-
-		case NorthPyramid:
-			vertices[0] += Math::Vector3d(0, size.y(), 0);
-			vertices[1] += Math::Vector3d(size.x(), size.y(), 0);
-			vertices[2] += Math::Vector3d(size.x(), 0, 0);
-
-			vertices[4] += Math::Vector3d((*ordinates)[0], (*ordinates)[3], size.z());
-			vertices[5] += Math::Vector3d((*ordinates)[2], (*ordinates)[3], size.z());
-			vertices[6] += Math::Vector3d((*ordinates)[2], (*ordinates)[1], size.z());
-			vertices[7] += Math::Vector3d((*ordinates)[0], (*ordinates)[1], size.z());
-			break;
-		case SouthPyramid:
-			vertices[0] += Math::Vector3d(0, 0, size.z());
-			vertices[1] += Math::Vector3d(size.x(), 0, size.z());
-			vertices[2] += Math::Vector3d(size.x(), size.y(), size.z());
-
-			vertices[3] += Math::Vector3d(0, size.y(), size.z());
-			vertices[4] += Math::Vector3d((*ordinates)[0], (*ordinates)[1], 0);
-			vertices[5] += Math::Vector3d((*ordinates)[2], (*ordinates)[1], 0);
-			vertices[6] += Math::Vector3d((*ordinates)[2], (*ordinates)[3], 0);
-			vertices[7] += Math::Vector3d((*ordinates)[0], (*ordinates)[3], 0);
-			break;
+	switch (pyramidType) {
+	default:
+		break;
+	case EastPyramid:
+		vertices[0] += Math::Vector3d(0, 0, size.z());
+		vertices[1] += Math::Vector3d(0, size.y(), size.z());
+		vertices[2] += Math::Vector3d(0, size.y(), 0);
+
+		vertices[4] += Math::Vector3d(size.x(), (*ordinates)[0], (*ordinates)[3]);
+		vertices[5] += Math::Vector3d(size.x(), (*ordinates)[2], (*ordinates)[3]);
+		vertices[6] += Math::Vector3d(size.x(), (*ordinates)[2], (*ordinates)[1]);
+		vertices[7] += Math::Vector3d(size.x(), (*ordinates)[0], (*ordinates)[1]);
+		break;
+	case WestPyramid:
+
+		vertices[0] += Math::Vector3d(size.x(), 0, 0);
+		vertices[1] += Math::Vector3d(size.x(), size.y(), 0);
+		vertices[2] += Math::Vector3d(size.x(), size.y(), size.z());
+		vertices[3] += Math::Vector3d(size.x(), 0, size.z());
+
+		vertices[4] += Math::Vector3d(0, (*ordinates)[0], (*ordinates)[1]);
+		vertices[5] += Math::Vector3d(0, (*ordinates)[2], (*ordinates)[1]);
+		vertices[6] += Math::Vector3d(0, (*ordinates)[2], (*ordinates)[3]);
+		vertices[7] += Math::Vector3d(0, (*ordinates)[0], (*ordinates)[3]);
+		break;
+
+	case UpPyramid:
+		vertices[1] += Math::Vector3d(size.x(), 0, 0);
+		vertices[2] += Math::Vector3d(size.x(), 0, size.z());
+		vertices[3] += Math::Vector3d(0, 0, size.z());
+
+		vertices[4] += Math::Vector3d((*ordinates)[0], size.y(), (*ordinates)[1]);
+		vertices[5] += Math::Vector3d((*ordinates)[2], size.y(), (*ordinates)[1]);
+		vertices[6] += Math::Vector3d((*ordinates)[2], size.y(), (*ordinates)[3]);
+		vertices[7] += Math::Vector3d((*ordinates)[0], size.y(), (*ordinates)[3]);
+		break;
+
+	case DownPyramid:
+
+		vertices[0] += Math::Vector3d(size.x(), size.y(), 0);
+		vertices[1] += Math::Vector3d(0, size.y(), 0);
+		vertices[2] += Math::Vector3d(0, size.y(), size.z());
+		vertices[3] += Math::Vector3d(size.x(), size.y(), size.z());
+
+		vertices[4] += Math::Vector3d((*ordinates)[2], 0, (*ordinates)[1]);
+		vertices[5] += Math::Vector3d((*ordinates)[0], 0, (*ordinates)[1]);
+		vertices[6] += Math::Vector3d((*ordinates)[0], 0, (*ordinates)[3]);
+		vertices[7] += Math::Vector3d((*ordinates)[2], 0, (*ordinates)[3]);
+		break;
+
+	case NorthPyramid:
+		vertices[0] += Math::Vector3d(0, size.y(), 0);
+		vertices[1] += Math::Vector3d(size.x(), size.y(), 0);
+		vertices[2] += Math::Vector3d(size.x(), 0, 0);
+
+		vertices[4] += Math::Vector3d((*ordinates)[0], (*ordinates)[3], size.z());
+		vertices[5] += Math::Vector3d((*ordinates)[2], (*ordinates)[3], size.z());
+		vertices[6] += Math::Vector3d((*ordinates)[2], (*ordinates)[1], size.z());
+		vertices[7] += Math::Vector3d((*ordinates)[0], (*ordinates)[1], size.z());
+		break;
+	case SouthPyramid:
+		vertices[0] += Math::Vector3d(0, 0, size.z());
+		vertices[1] += Math::Vector3d(size.x(), 0, size.z());
+		vertices[2] += Math::Vector3d(size.x(), size.y(), size.z());
+
+		vertices[3] += Math::Vector3d(0, size.y(), size.z());
+		vertices[4] += Math::Vector3d((*ordinates)[0], (*ordinates)[1], 0);
+		vertices[5] += Math::Vector3d((*ordinates)[2], (*ordinates)[1], 0);
+		vertices[6] += Math::Vector3d((*ordinates)[2], (*ordinates)[3], 0);
+		vertices[7] += Math::Vector3d((*ordinates)[0], (*ordinates)[3], 0);
+		break;
 	}
 
 	Common::Array<Math::Vector3d> face;
@@ -475,21 +482,21 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 	assert(size.y() > 0);
 	assert(size.z() > 0);*/
 
-	//debug("Rendering cube at %f, %f, %f", origin.x(), origin.y(), origin.z());
-	//debug("with size %f, %f, %f", size.x(), size.y(), size.z());
+	// debug("Rendering cube at %f, %f, %f", origin.x(), origin.y(), origin.z());
+	// debug("with size %f, %f, %f", size.x(), size.y(), size.z());
 	uint8 r, g, b;
 
 	// Face 0
 	if (getRGBAt((*colours)[0], r, g, b)) {
 		tglColor3ub(r, g, b);
 		tglBegin(TGL_TRIANGLES);
-		tglVertex3f(origin.x(),	origin.y(),				origin.z());
-		tglVertex3f(origin.x(),	origin.y(),				origin.z() + size.z());
-		tglVertex3f(origin.x(),	origin.y() + size.y(),	origin.z() + size.z());
+		tglVertex3f(origin.x(), origin.y(), origin.z());
+		tglVertex3f(origin.x(), origin.y(), origin.z() + size.z());
+		tglVertex3f(origin.x(), origin.y() + size.y(), origin.z() + size.z());
 
-		tglVertex3f(origin.x(),	origin.y(),				origin.z());
-		tglVertex3f(origin.x(),	origin.y() + size.y(),	origin.z() + size.z());
-		tglVertex3f(origin.x(),	origin.y() + size.y(),	origin.z());
+		tglVertex3f(origin.x(), origin.y(), origin.z());
+		tglVertex3f(origin.x(), origin.y() + size.y(), origin.z() + size.z());
+		tglVertex3f(origin.x(), origin.y() + size.y(), origin.z());
 		tglEnd();
 	}
 
@@ -497,13 +504,13 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 	if (getRGBAt((*colours)[1], r, g, b)) {
 		tglColor3ub(r, g, b);
 		tglBegin(TGL_TRIANGLES);
-		tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z());
-		tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z() + size.z());
-		tglVertex3f(origin.x() + size.x(),	origin.y(),				origin.z() + size.z());
+		tglVertex3f(origin.x() + size.x(), origin.y() + size.y(), origin.z());
+		tglVertex3f(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z());
+		tglVertex3f(origin.x() + size.x(), origin.y(), origin.z() + size.z());
 
-		tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z());
-		tglVertex3f(origin.x() + size.x(),	origin.y(),				origin.z() + size.z());
-		tglVertex3f(origin.x() + size.x(),	origin.y(),				origin.z());
+		tglVertex3f(origin.x() + size.x(), origin.y() + size.y(), origin.z());
+		tglVertex3f(origin.x() + size.x(), origin.y(), origin.z() + size.z());
+		tglVertex3f(origin.x() + size.x(), origin.y(), origin.z());
 		tglEnd();
 	}
 
@@ -511,13 +518,13 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 	if (getRGBAt((*colours)[2], r, g, b)) {
 		tglColor3ub(r, g, b);
 		tglBegin(TGL_TRIANGLES);
-		tglVertex3f(origin.x() + size.x(),	origin.y(),	origin.z());
-		tglVertex3f(origin.x() + size.x(),	origin.y(),	origin.z() + size.z());
-		tglVertex3f(origin.x(),			origin.y(),		origin.z() + size.z());
+		tglVertex3f(origin.x() + size.x(), origin.y(), origin.z());
+		tglVertex3f(origin.x() + size.x(), origin.y(), origin.z() + size.z());
+		tglVertex3f(origin.x(), origin.y(), origin.z() + size.z());
 
-		tglVertex3f(origin.x() + size.x(),	origin.y(),	origin.z());
-		tglVertex3f(origin.x(),			origin.y(),		origin.z() + size.z());
-		tglVertex3f(origin.x(),			origin.y(),		origin.z());
+		tglVertex3f(origin.x() + size.x(), origin.y(), origin.z());
+		tglVertex3f(origin.x(), origin.y(), origin.z() + size.z());
+		tglVertex3f(origin.x(), origin.y(), origin.z());
 		tglEnd();
 	}
 
@@ -525,13 +532,13 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 	if (getRGBAt((*colours)[3], r, g, b)) {
 		tglColor3ub(r, g, b);
 		tglBegin(TGL_TRIANGLES);
-		tglVertex3f(origin.x(),				origin.y() + size.y(),	origin.z());
-		tglVertex3f(origin.x(),				origin.y() + size.y(),	origin.z() + size.z());
-		tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z() + size.z());
+		tglVertex3f(origin.x(), origin.y() + size.y(), origin.z());
+		tglVertex3f(origin.x(), origin.y() + size.y(), origin.z() + size.z());
+		tglVertex3f(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z());
 
-		tglVertex3f(origin.x(),				origin.y() + size.y(),	origin.z());
-		tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z() + size.z());
-		tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z());
+		tglVertex3f(origin.x(), origin.y() + size.y(), origin.z());
+		tglVertex3f(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z());
+		tglVertex3f(origin.x() + size.x(), origin.y() + size.y(), origin.z());
 		tglEnd();
 	}
 
@@ -539,13 +546,13 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 	if (getRGBAt((*colours)[4], r, g, b)) {
 		tglColor3ub(r, g, b);
 		tglBegin(TGL_TRIANGLES);
-		tglVertex3f(origin.x(),				origin.y() + size.y(),	origin.z());
-		tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z());
-		tglVertex3f(origin.x() + size.x(),	origin.y(),				origin.z());
+		tglVertex3f(origin.x(), origin.y() + size.y(), origin.z());
+		tglVertex3f(origin.x() + size.x(), origin.y() + size.y(), origin.z());
+		tglVertex3f(origin.x() + size.x(), origin.y(), origin.z());
 
-		tglVertex3f(origin.x(),				origin.y() + size.y(),	origin.z());
-		tglVertex3f(origin.x() + size.x(),	origin.y(),				origin.z());
-		tglVertex3f(origin.x(),				origin.y(),				origin.z());
+		tglVertex3f(origin.x(), origin.y() + size.y(), origin.z());
+		tglVertex3f(origin.x() + size.x(), origin.y(), origin.z());
+		tglVertex3f(origin.x(), origin.y(), origin.z());
 		tglEnd();
 	}
 
@@ -553,13 +560,13 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 	if (getRGBAt((*colours)[5], r, g, b)) {
 		tglColor3ub(r, g, b);
 		tglBegin(TGL_TRIANGLES);
-		tglVertex3f(origin.x(),		        origin.y(),				origin.z() + size.z());
-		tglVertex3f(origin.x() + size.x(),	origin.y(),				origin.z() + size.z());
-		tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z() + size.z());
+		tglVertex3f(origin.x(), origin.y(), origin.z() + size.z());
+		tglVertex3f(origin.x() + size.x(), origin.y(), origin.z() + size.z());
+		tglVertex3f(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z());
 
-		tglVertex3f(origin.x(),		        origin.y(),				origin.z() + size.z());
-		tglVertex3f(origin.x() + size.x(),	origin.y() + size.y(),	origin.z() + size.z());
-		tglVertex3f(origin.x(),		        origin.y() + size.y(),	origin.z() + size.z());
+		tglVertex3f(origin.x(), origin.y(), origin.z() + size.z());
+		tglVertex3f(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z());
+		tglVertex3f(origin.x(), origin.y() + size.y(), origin.z() + size.z());
 		tglEnd();
 	}
 }
@@ -593,7 +600,7 @@ void TinyGLRenderer::flipBuffer() {
 	if (!dirtyAreas.empty()) {
 		for (Common::List<Common::Rect>::iterator itRect = dirtyAreas.begin(); itRect != dirtyAreas.end(); ++itRect) {
 			g_system->copyRectToScreen(glBuffer.getBasePtr((*itRect).left, (*itRect).top), glBuffer.pitch,
-			                           (*itRect).left, (*itRect).top, (*itRect).width(), (*itRect).height());
+									   (*itRect).left, (*itRect).top, (*itRect).width(), (*itRect).height());
 		}
 	}
 }
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index b53e6803b4b..e592c2b0c73 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -51,7 +51,7 @@ public:
 	virtual void renderRectangle(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) override;
 	virtual void renderPolygon(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours) override;
 	virtual void renderPyramid(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours, int type) override;
-    virtual void renderFace(const Common::Array<Math::Vector3d> &vertices) override;
+	virtual void renderFace(const Common::Array<Math::Vector3d> &vertices) override;
 
 	virtual void flipBuffer() override;
 	virtual void setSkyColor(uint8 color) override;
diff --git a/engines/freescape/gfx_tinygl_texture.h b/engines/freescape/gfx_tinygl_texture.h
index 79272e61ea9..fa2027e3dc0 100644
--- a/engines/freescape/gfx_tinygl_texture.h
+++ b/engines/freescape/gfx_tinygl_texture.h
@@ -43,6 +43,7 @@ public:
 	TGLuint id;
 	TGLuint internalFormat;
 	TGLuint sourceFormat;
+
 private:
 	TinyGL::BlitImage *_blitImage;
 };
diff --git a/engines/freescape/keyboard.cpp b/engines/freescape/keyboard.cpp
index afa1e0fccf9..b74dba9424a 100644
--- a/engines/freescape/keyboard.cpp
+++ b/engines/freescape/keyboard.cpp
@@ -52,7 +52,7 @@ int FreescapeEngine::decodeAmigaAtariKey(int index) {
 int FreescapeEngine::decodeDOSKey(int index) {
 	switch (index) {
 	case 1:
-		return 	Common::KEYCODE_r;
+		return Common::KEYCODE_r;
 	case 2:
 		return Common::KEYCODE_f;
 	case 3:
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index c15c7ecd428..d6ae2d6fe0b 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -47,13 +47,13 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 
 	// this lookup table tells us how many argument bytes to read per opcode
 	uint8 argumentsRequiredByOpcode[49] =
-		{ 0, 3, 1, 1, 1, 1, 2, 2,
-		  2, 1, 1, 2, 1, 1, 2, 1,
-		  1, 2, 2, 1, 2, 0, 0, 0,
-		  1, 1, 0, 1, 1, 1, 1, 1,
-		  2, 2, 1, 1, 0, 0, 0, 0,
-		  0, 0, 0, 0, 0, 0, 2, 2,
-		  1};
+		{0, 3, 1, 1, 1, 1, 2, 2,
+		 2, 1, 1, 2, 1, 1, 2, 1,
+		 1, 2, 2, 1, 2, 0, 0, 0,
+		 1, 1, 0, 1, 1, 1, 1, 1,
+		 2, 2, 1, 1, 0, 0, 0, 0,
+		 0, 0, 0, 0, 0, 0, 2, 2,
+		 1};
 
 	while (bytePointer < sizeOfTokenisedContent) {
 		// get the conditional type of the next operation
@@ -144,7 +144,7 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 			detokenisedStream += Common::String::format("(%d, v%d)", (int8)tokenisedCondition[bytePointer], k8bitVariableShield);
 			currentInstruction = FCLInstruction(Token::ADDVAR);
 			currentInstruction.setSource(k8bitVariableShield);
-			currentInstruction.setDestination((int8) tokenisedCondition[bytePointer]);
+			currentInstruction.setDestination((int8)tokenisedCondition[bytePointer]);
 			conditionalInstructions->push_back(currentInstruction);
 			currentInstruction = FCLInstruction(Token::UNKNOWN);
 			bytePointer++;
@@ -328,7 +328,7 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 		case 25:
 			// this should toggle border colour or the room palette
 			detokenisedStream += "SPFX (";
-		break;
+			break;
 
 		case 20:
 			detokenisedStream += "SETVAR ";
@@ -394,10 +394,10 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 		detokenisedStream += "\n";
 	}
 
-	//if (!conditionalInstructions)
+	// if (!conditionalInstructions)
 	//	conditionalInstructions = new FCLInstructionVector();
 
-	//conditionalInstructions->push_back(currentInstruction);
+	// conditionalInstructions->push_back(currentInstruction);
 
 	FCLInstruction branch;
 	if (conditionalIsShot)
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index 115efc9975a..4fc7fb1863f 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -21,8 +21,8 @@
 
 // Based on Phantasma code by Thomas Harte (2013)
 
-#include "freescape/language/8bitDetokeniser.h"
 #include "freescape/freescape.h"
+#include "freescape/language/8bitDetokeniser.h"
 
 namespace Freescape {
 
@@ -98,71 +98,71 @@ void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool co
 		FCLInstruction &instruction = code[ip];
 		debugC(1, kFreescapeDebugCode, "Executing ip: %d in code with size: %d", ip, codeSize);
 		switch (instruction.getType()) {
-			default:
+		default:
 			break;
-			case Token::COLLIDEDQ:
+		case Token::COLLIDEDQ:
 			if (collided)
 				executeCode(*instruction.thenInstructions, shot, collided);
 			// else branch is always empty
 			assert(instruction.elseInstructions == nullptr);
 			break;
-			case Token::SHOTQ:
+		case Token::SHOTQ:
 			if (shot)
 				executeCode(*instruction.thenInstructions, shot, collided);
 			// else branch is always empty
 			assert(instruction.elseInstructions == nullptr);
 			break;
-			case Token::VARNOTEQ:
+		case Token::VARNOTEQ:
 			if (executeEndIfNotEqual(instruction))
 				ip = codeSize;
 			break;
-			case Token::SWAPJET:
+		case Token::SWAPJET:
 			executeSwapJet(instruction);
 			break;
-			case Token::ADDVAR:
+		case Token::ADDVAR:
 			executeIncrementVariable(instruction);
 			break;
-			case Token::SUBVAR:
+		case Token::SUBVAR:
 			executeDecrementVariable(instruction);
 			break;
-			case Token::GOTO:
+		case Token::GOTO:
 			executeGoto(instruction);
 			break;
-			case Token::TOGVIS:
+		case Token::TOGVIS:
 			executeToggleVisibility(instruction);
 			break;
-			case Token::INVIS:
+		case Token::INVIS:
 			executeMakeInvisible(instruction);
 			break;
-			case Token::VIS:
+		case Token::VIS:
 			executeMakeVisible(instruction);
 			break;
-			case Token::DESTROY:
+		case Token::DESTROY:
 			executeDestroy(instruction);
 			break;
-			case Token::REDRAW:
+		case Token::REDRAW:
 			executeRedraw(instruction);
 			break;
-			case Token::DELAY:
+		case Token::DELAY:
 			executeDelay(instruction);
 			break;
-			case Token::SOUND:
+		case Token::SOUND:
 			executeSound(instruction);
 			break;
-			case Token::SETBIT:
+		case Token::SETBIT:
 			executeSetBit(instruction);
 			break;
-			case Token::CLEARBIT:
+		case Token::CLEARBIT:
 			executeClearBit(instruction);
 			break;
-			case Token::PRINT:
+		case Token::PRINT:
 			executePrint(instruction);
 			break;
-			case Token::BITNOTEQ:
+		case Token::BITNOTEQ:
 			if (executeEndIfBitNotEqual(instruction))
 				ip = codeSize;
 			break;
-			case Token::INVISQ:
+		case Token::INVISQ:
 			if (executeEndIfVisibilityIsEqual(instruction))
 				ip = codeSize;
 			break;
@@ -172,7 +172,6 @@ void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool co
 	return;
 }
 
-
 void FreescapeEngine::executeRedraw(FCLInstruction &instruction) {
 	debugC(1, kFreescapeDebugCode, "Redrawing screen");
 	drawFrame();
@@ -235,14 +234,14 @@ void FreescapeEngine::executeIncrementVariable(FCLInstruction &instruction) {
 	switch (variable) {
 	case k8bitVariableScore:
 		debugC(1, kFreescapeDebugCode, "Score incremented by %d up to %d", increment, _gameStateVars[variable]);
-	break;
+		break;
 	case k8bitVariableEnergy:
 		if (_gameStateVars[variable] > k8bitMaxEnergy)
 			_gameStateVars[variable] = k8bitMaxEnergy;
 		else if (_gameStateVars[variable] < 0)
 			_gameStateVars[variable] = 0;
 		debugC(1, kFreescapeDebugCode, "Energy incremented by %d up to %d", increment, _gameStateVars[variable]);
-	break;
+		break;
 	case k8bitVariableShield:
 		if (_gameStateVars[variable] > k8bitMaxShield)
 			_gameStateVars[variable] = k8bitMaxShield;
@@ -250,10 +249,10 @@ void FreescapeEngine::executeIncrementVariable(FCLInstruction &instruction) {
 			_gameStateVars[variable] = 0;
 
 		debugC(1, kFreescapeDebugCode, "Shield incremented by %d up to %d", increment, _gameStateVars[variable]);
-	break;
+		break;
 	default:
 		debugC(1, kFreescapeDebugCode, "Variable %d by %d incremented up to %d!", variable, increment, _gameStateVars[variable]);
-	break;
+		break;
 	}
 }
 
@@ -346,7 +345,6 @@ void FreescapeEngine::executeToggleVisibility(FCLInstruction &instruction) {
 		obj = _areaMap[areaID]->objectWithID(objectID);
 		obj->makeVisible();
 	}
-
 }
 
 void FreescapeEngine::executeGoto(FCLInstruction &instruction) {
@@ -360,7 +358,7 @@ void FreescapeEngine::executeSetBit(FCLInstruction &instruction) {
 	assert(index < 32);
 	_gameStateBits[_currentArea->getAreaID()] |= (1 << index);
 	debugC(1, kFreescapeDebugCode, "Setting bit %d", index);
-	//debug("v: %d", (_gameStateBits[_currentArea->getAreaID()] & (1 << index)));
+	// debug("v: %d", (_gameStateBits[_currentArea->getAreaID()] & (1 << index)));
 }
 
 void FreescapeEngine::executeClearBit(FCLInstruction &instruction) {
diff --git a/engines/freescape/language/instruction.h b/engines/freescape/language/instruction.h
index 88fe5508203..fca7c88bb89 100644
--- a/engines/freescape/language/instruction.h
+++ b/engines/freescape/language/instruction.h
@@ -49,6 +49,7 @@ public:
 
 	FCLInstructionVector *thenInstructions;
 	FCLInstructionVector *elseInstructions;
+
 private:
 	enum Token::Type type;
 };
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 0d38eb16b00..3a98f12cb71 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -26,9 +26,9 @@
 
 #include "freescape/freescape.h"
 #include "freescape/language/8bitDetokeniser.h"
+#include "freescape/neo.h"
 #include "freescape/objects/global.h"
 #include "freescape/objects/sensor.h"
-#include "freescape/neo.h"
 
 namespace Freescape {
 
@@ -62,7 +62,7 @@ uint16 FreescapeEngine::readField(Common::SeekableReadStream *file, int bits) {
 }
 
 Common::Array<uint8> FreescapeEngine::readArray(Common::SeekableReadStream *file, int size) {
-	byte *data = (byte*)malloc(size);
+	byte *data = (byte *)malloc(size);
 	for (int i = 0; i < size; i++) {
 		data[i] = readField(file, 8);
 	}
@@ -101,7 +101,7 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 	byteSizeOfObject = byteSizeOfObject - 9;
 	if (objectID == 255 && objectType == Object::Type::Entrance) {
 		debugC(1, kFreescapeDebugParser, "Found the room structure (objectID: 255 with size %d)", byteSizeOfObject + 6);
-		byte *structureData = (byte*)malloc(byteSizeOfObject + 6);
+		byte *structureData = (byte *)malloc(byteSizeOfObject + 6);
 		structureData[0] = int(position.x());
 		structureData[1] = int(position.y());
 		structureData[2] = int(position.z());
@@ -111,36 +111,36 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 		structureData[5] = int(v.z());
 
 		if (byteSizeOfObject > 0)
-			file->read(structureData+6, byteSizeOfObject);
+			file->read(structureData + 6, byteSizeOfObject);
 		Common::Array<uint8> structureArray(structureData, byteSizeOfObject + 6);
 		return new GlobalStructure(structureArray);
 	}
 
 	debugC(1, kFreescapeDebugParser, "Object %d ; type %d ; size %d", objectID, (int)objectType, byteSizeOfObject);
-    debugC(1, kFreescapeDebugParser, "pos: %f %f %f", position.x(), position.y(), position.z());
+	debugC(1, kFreescapeDebugParser, "pos: %f %f %f", position.x(), position.y(), position.z());
 	switch (objectType) {
 	default: {
 		debugC(1, kFreescapeDebugParser, "size: %f %f %f", v.x(), v.y(), v.z());
 		// read the appropriate number of colours
 		int numberOfColours = GeometricObject::numberOfColoursForObjectOfType(objectType);
 		Common::Array<uint8> *colours = new Common::Array<uint8>;
-		debugC(1, kFreescapeDebugParser, "Number of colors: %d", numberOfColours/2);
+		debugC(1, kFreescapeDebugParser, "Number of colors: %d", numberOfColours / 2);
 		uint8 entry;
-		for (uint8 colour = 0; colour < numberOfColours/2; colour++) {
+		for (uint8 colour = 0; colour < numberOfColours / 2; colour++) {
 			uint8 data = readField(file, 8);
 			entry = data & 0xf;
 			if (_renderMode == "cga")
 				entry = entry % 4; // TODO: use dithering
 
 			colours->push_back(entry);
-			debugC(1, kFreescapeDebugParser, "color[%d] = %x", 2*colour, entry);
+			debugC(1, kFreescapeDebugParser, "color[%d] = %x", 2 * colour, entry);
 
 			entry = data >> 4;
 			if (_renderMode == "cga")
 				entry = entry % 4; // TODO: use dithering
 
 			colours->push_back(entry);
-			debugC(1, kFreescapeDebugParser, "color[%d] = %x", 2*colour+1, entry);
+			debugC(1, kFreescapeDebugParser, "color[%d] = %x", 2 * colour + 1, entry);
 			byteSizeOfObject--;
 		}
 
@@ -154,8 +154,8 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 			uint16 ord = 0;
 			if (byteSizeOfObject < numberOfOrdinates) {
 				error("Not enough bytes to read all the ordinates");
-				//file->seek(byteSizeOfObject, SEEK_CUR);
-				//return nullptr;
+				// file->seek(byteSizeOfObject, SEEK_CUR);
+				// return nullptr;
 			}
 			for (int ordinate = 0; ordinate < numberOfOrdinates; ordinate++) {
 				ord = readField(file, 8);
@@ -171,7 +171,7 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 		if (byteSizeOfObject) {
 			Common::Array<uint8> conditionArray = readArray(file, byteSizeOfObject);
 			conditionSource = detokenise8bitCondition(conditionArray, instructions);
-			//instructions = getInstructions(conditionSource);
+			// instructions = getInstructions(conditionSource);
 			debugC(1, kFreescapeDebugParser, "%s", conditionSource->c_str());
 		}
 		debugC(1, kFreescapeDebugParser, "End of object at %lx", file->pos());
@@ -251,8 +251,7 @@ static const char *eclipseRoomName[] = {
 	"PHARAOHS",
 	" SHABAKA",
 	"ILLUSION",
-	"????????"
-};
+	"????????"};
 
 Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 ncolors) {
 
@@ -286,20 +285,20 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	ci4 = readField(file, 8);
 	debugC(1, kFreescapeDebugParser, "Colors: %d %d %d %d %d %d", ci1, ci2, ci3, ci4, skyColor, groundColor);
 	// CPC
-	//groundColor = file->readByte() & 15;
-	//skyColor = file->readByte() & 15;
-	//debugC(1, kFreescapeDebugParser, "Colors: %d %d", skyColor, groundColor);
+	// groundColor = file->readByte() & 15;
+	// skyColor = file->readByte() & 15;
+	// debugC(1, kFreescapeDebugParser, "Colors: %d %d", skyColor, groundColor);
 
 	if (_renderMode == "cga") {
 		skyColor = skyColor % 4;
 		groundColor = groundColor % 4;
 	}
 
-	//Graphics::PixelBuffer *palette = getPalette(areaNumber, ci1, ci2, skyColor, groundColor, ncolors);
+	// Graphics::PixelBuffer *palette = getPalette(areaNumber, ci1, ci2, skyColor, groundColor, ncolors);
 
 	debugC(1, kFreescapeDebugParser, "Area %d", areaNumber);
 	debugC(1, kFreescapeDebugParser, "Flags: %d Objects: %d", areaFlags, numberOfObjects);
-	//debug("Condition Ptr: %x", cPtr);
+	// debug("Condition Ptr: %x", cPtr);
 	debugC(1, kFreescapeDebugParser, "Pos before first object: %lx", file->pos());
 
 	if (areaNumber == 192)
@@ -414,7 +413,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	debugC(1, kFreescapeDebugParser, "Color map:");
 	uint8 data;
 	for (int i = 0; i < 15; i++) {
-		byte *entry = (byte*) malloc(4 * sizeof(byte));
+		byte *entry = (byte *)malloc(4 * sizeof(byte));
 		data = readField(file, 8);
 		*entry = data;
 		entry++;
@@ -462,7 +461,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 		debugC(1, kFreescapeDebugParser, "length of condition: %d at %lx", lengthOfCondition, file->pos());
 		// get the condition
 		Common::Array<uint8> conditionArray = readArray(file, lengthOfCondition);
-		//debug("Global condition %d", numConditions + 1);
+		// debug("Global condition %d", numConditions + 1);
 		Common::String *conditionSource = detokenise8bitCondition(conditionArray, instructions);
 		_conditions.push_back(instructions);
 		_conditionSources.push_back(conditionSource);
@@ -473,7 +472,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 		file->seek(offset + 0x190);
 	else
 		file->seek(offset + 0xc8);
-	//file->seek(offset + 0x4f); //CPC
+	// file->seek(offset + 0x4f); //CPC
 
 	debugC(1, kFreescapeDebugParser, "areas index at: %lx", file->pos());
 	uint16 *fileOffsetForArea = new uint16[numberOfAreas];
@@ -543,7 +542,7 @@ void FreescapeEngine::loadMessagesFixedSize(Common::SeekableReadStream *file, in
 
 	for (int i = 0; i < number; i++) {
 		file->read(buffer, size);
-		Common::String message = (const char*) buffer;
+		Common::String message = (const char *)buffer;
 		_messagesList.push_back(message);
 		debugC(1, kFreescapeDebugParser, "%s", _messagesList[i].c_str());
 	}
diff --git a/engines/freescape/metaengine.cpp b/engines/freescape/metaengine.cpp
index a8bdb92ac98..ff0b9bc69d9 100644
--- a/engines/freescape/metaengine.cpp
+++ b/engines/freescape/metaengine.cpp
@@ -34,11 +34,11 @@ public:
 Common::Error FreescapeMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const {
 	if (Common::String(gd->gameId) == "driller" || Common::String(gd->gameId) == "spacestationoblivion") {
 		*engine = (Engine *)new Freescape::DrillerEngine(syst, gd);
-	} else 	if (Common::String(gd->gameId) == "darkside") {
+	} else if (Common::String(gd->gameId) == "darkside") {
 		*engine = (Engine *)new Freescape::DarkEngine(syst, gd);
-	} else 	if (Common::String(gd->gameId) == "totaleclipse") {
+	} else if (Common::String(gd->gameId) == "totaleclipse") {
 		*engine = (Engine *)new Freescape::EclipseEngine(syst, gd);
-	} else 	if (Common::String(gd->gameId) == "castlemaster") {
+	} else if (Common::String(gd->gameId) == "castlemaster") {
 		*engine = (Engine *)new Freescape::CastleEngine(syst, gd);
 	} else
 		*engine = new Freescape::FreescapeEngine(syst, gd);
@@ -52,7 +52,7 @@ bool FreescapeEngine::isDemo() const {
 	return (bool)(_gameDescription->flags & ADGF_DEMO);
 }
 
-} // End of namespace freescape
+} // namespace Freescape
 
 #if PLUGIN_ENABLED_DYNAMIC(FREESCAPE)
 REGISTER_PLUGIN_DYNAMIC(FREESCAPE, PLUGIN_TYPE_ENGINE, FreescapeMetaEngine);
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index a677b60870d..8c2de2a0729 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -28,7 +28,7 @@ void FreescapeEngine::gotoArea(uint16 areaID, int entranceID) {
 }
 
 void FreescapeEngine::traverseEntrance(uint16 entranceID) {
-	Entrance *entrance = (Entrance*) _currentArea->entranceWithID(entranceID);
+	Entrance *entrance = (Entrance *)_currentArea->entranceWithID(entranceID);
 	assert(entrance);
 
 	int scale = _currentArea->getScale();
@@ -60,7 +60,7 @@ void FreescapeEngine::shoot() {
 	Math::Ray ray(_position, direction);
 	Object *shot = _currentArea->shootRay(ray);
 	if (shot) {
-		GeometricObject *gobj = (GeometricObject*) shot;
+		GeometricObject *gobj = (GeometricObject *)shot;
 		debugC(1, kFreescapeDebugMove, "Shot object %d with flags %x", gobj->getObjectID(), gobj->getObjectFlags());
 
 		if (gobj->conditionSource != nullptr)
@@ -134,7 +134,6 @@ void FreescapeEngine::lower() {
 	debugC(1, kFreescapeDebugMove, "new player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
 }
 
-
 void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTime) {
 	debugC(1, kFreescapeDebugMove, "old player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
 	int previousAreaID = _currentArea->getAreaID();
@@ -172,7 +171,7 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 
 	if (!collided) {
 		bool hasFloor = checkFloor(_position);
-		if (!hasFloor  && !_flyMode) {
+		if (!hasFloor && !_flyMode) {
 			int fallen;
 			for (fallen = 1; fallen < 65 + 1; fallen++) {
 				_position.set(_position.x(), positionY - fallen * areaScale, _position.z());
@@ -182,7 +181,7 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 			fallen++;
 			fallen++;
 			if (fallen >= 67) {
-				_position = _lastPosition; //error("NASTY FALL!");
+				_position = _lastPosition; // error("NASTY FALL!");
 				return;
 			}
 			_position.set(_position.x(), positionY - fallen * areaScale, _position.z());
@@ -256,15 +255,14 @@ bool FreescapeEngine::tryStepDown(Math::Vector3d currentPosition) {
 	}
 }
 
-
 bool FreescapeEngine::checkCollisions(bool executeCode) {
 	if (_noClipMode)
 		return false;
 	int areaScale = _currentArea->getScale();
 	Math::AABB boundingBox(_lastPosition, _lastPosition);
 
-	Math::Vector3d v1(_position.x() - areaScale, _position.y() - areaScale * _playerHeight , _position.z() - areaScale);
-	Math::Vector3d v2(_position.x() + areaScale, _position.y() + areaScale                 , _position.z() + areaScale);
+	Math::Vector3d v1(_position.x() - areaScale, _position.y() - areaScale * _playerHeight, _position.z() - areaScale);
+	Math::Vector3d v2(_position.x() + areaScale, _position.y() + areaScale, _position.z() + areaScale);
 
 	boundingBox.expand(v1);
 	boundingBox.expand(v2);
@@ -272,7 +270,7 @@ bool FreescapeEngine::checkCollisions(bool executeCode) {
 
 	if (obj != nullptr) {
 		debugC(1, kFreescapeDebugMove, "Collided with object id %d of size %f %f %f", obj->getObjectID(), obj->getSize().x(), obj->getSize().y(), obj->getSize().z());
-		GeometricObject *gobj = (GeometricObject*) obj;
+		GeometricObject *gobj = (GeometricObject *)obj;
 		if (!executeCode) // Avoid executing code
 			return true;
 
@@ -282,4 +280,4 @@ bool FreescapeEngine::checkCollisions(bool executeCode) {
 	return false;
 }
 
-} // End of namespace
\ No newline at end of file
+} // namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/neo.cpp b/engines/freescape/neo.cpp
index a816ef8ace2..8a0c19b4420 100644
--- a/engines/freescape/neo.cpp
+++ b/engines/freescape/neo.cpp
@@ -102,12 +102,16 @@ bool NeoDecoder::loadStream(Common::SeekableReadStream &stream) {
 			for (int z = 0; z < 16; z++) {
 				// Work out the colour index:
 				int idx = 0;
-				if (uW0 & uBit) idx += 1;
-				if (uW1 & uBit) idx += 2;
-				if (uW2 & uBit) idx += 4;
-				if (uW3 & uBit) idx += 8;
-
-				_surface->setPixel(x*16 + z, y, idx);
+				if (uW0 & uBit)
+					idx += 1;
+				if (uW1 & uBit)
+					idx += 2;
+				if (uW2 & uBit)
+					idx += 4;
+				if (uW3 & uBit)
+					idx += 8;
+
+				_surface->setPixel(x * 16 + z, y, idx);
 				uBit >>= 1;
 			}
 		}
diff --git a/engines/freescape/neo.h b/engines/freescape/neo.h
index ecca4d6eabc..380aac602ab 100644
--- a/engines/freescape/neo.h
+++ b/engines/freescape/neo.h
@@ -30,7 +30,7 @@
 Atari-ST Neochrome decoder based on NEOLoad by Jason "Joefish" Railton
 */
 
-namespace Common{
+namespace Common {
 class SeekableReadStream;
 }
 
diff --git a/engines/freescape/objects/entrance.h b/engines/freescape/objects/entrance.h
index 96c9735a2bb..80ae7212926 100644
--- a/engines/freescape/objects/entrance.h
+++ b/engines/freescape/objects/entrance.h
@@ -30,7 +30,6 @@ namespace Freescape {
 
 class Entrance : public Object {
 public:
-
 	Entrance(
 		uint16 objectID,
 		const Math::Vector3d &origin,
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index da09f11dc05..4a55019a984 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -93,7 +93,6 @@ bool GeometricObject::isPyramid(Type type) {
 	case SouthPyramid:
 		return true;
 	}
-
 }
 
 bool GeometricObject::isPolygon(Type type) {
@@ -157,7 +156,7 @@ GeometricObject::GeometricObject(
 			ordinates->push_back(origin.x() + size.x());
 			ordinates->push_back(origin.y() + size.y());
 			ordinates->push_back(origin.z() + size.z());
-		   }
+		}
 	}
 
 	computeBoundingBox();
@@ -186,7 +185,7 @@ void GeometricObject::computeBoundingBox() {
 	Math::Vector3d v;
 	switch (type) {
 	default:
-	break;
+		break;
 	case Cube:
 		boundingBox.expand(origin);
 		for (int i = 0; i < 3; i++) {
@@ -320,7 +319,7 @@ bool GeometricObject::collides(const Math::AABB &_boundingBox) {
 	if (isDestroyed() || isInvisible() || !boundingBox.isValid() || !_boundingBox.isValid())
 		return false;
 
-	return(	boundingBox.getMax().x() > _boundingBox.getMin().x() &&
+	return (boundingBox.getMax().x() > _boundingBox.getMin().x() &&
 			boundingBox.getMin().x() < _boundingBox.getMax().x() &&
 			boundingBox.getMax().y() > _boundingBox.getMin().y() &&
 			boundingBox.getMin().y() < _boundingBox.getMax().y() &&
@@ -329,7 +328,7 @@ bool GeometricObject::collides(const Math::AABB &_boundingBox) {
 }
 
 void GeometricObject::draw(Freescape::Renderer *gfx) {
-	//debug("Drawing %d of type %d", this->getObjectID(), this->getType());
+	// debug("Drawing %d of type %d", this->getObjectID(), this->getType());
 	if (this->getType() == Cube) {
 		gfx->renderCube(origin, size, colours);
 	} else if (this->getType() == Rectangle) {
@@ -340,7 +339,7 @@ void GeometricObject::draw(Freescape::Renderer *gfx) {
 		if (this->getType() == Triangle)
 			assert(ordinates->size() == 9);
 
-		//debug("Drawing %d of type %d", this->getObjectID(), this->getType());
+		// debug("Drawing %d of type %d", this->getObjectID(), this->getType());
 		gfx->renderPolygon(origin, size, ordinates, colours);
 	}
 }
diff --git a/engines/freescape/objects/object.h b/engines/freescape/objects/object.h
index bee8474e05a..e63b34503aa 100644
--- a/engines/freescape/objects/object.h
+++ b/engines/freescape/objects/object.h
@@ -24,8 +24,8 @@
 #ifndef FREESCAPE_OBJECT_H
 #define FREESCAPE_OBJECT_H
 
-#include "math/vector3d.h"
 #include "math/aabb.h"
+#include "math/vector3d.h"
 
 #include "freescape/gfx.h"
 
diff --git a/engines/freescape/objects/sensor.h b/engines/freescape/objects/sensor.h
index a4f41d59445..2c81134aa45 100644
--- a/engines/freescape/objects/sensor.h
+++ b/engines/freescape/objects/sensor.h
@@ -30,7 +30,6 @@ namespace Freescape {
 
 class Sensor : public Object {
 public:
-
 	Sensor(
 		uint16 objectID,
 		const Math::Vector3d &origin,
diff --git a/engines/freescape/sound.cpp b/engines/freescape/sound.cpp
index b9164903593..d1f8ca202fb 100644
--- a/engines/freescape/sound.cpp
+++ b/engines/freescape/sound.cpp
@@ -32,7 +32,7 @@ namespace Freescape {
 const double kFreescapeSweepTuneFactor = 10.0;
 
 void FreescapeEngine::playSound(int index, bool sync) {
-	//if (!_mixer->isSoundHandleActive(_soundFxHandle))
+	// if (!_mixer->isSoundHandleActive(_soundFxHandle))
 	//	_mixer->stopHandle(_soundFxHandle);
 
 	debugC(1, kFreescapeDebugMedia, "Playing sound %d with sync: %d", index, sync);
@@ -42,181 +42,181 @@ void FreescapeEngine::playSound(int index, bool sync) {
 	}
 
 	switch (index) {
-		case 1:
-			if (_usePrerecordedSounds) {
-				playWav("fsDOS_laserFire.wav");
-				//_system->delayMillis(50);
-			} else
-				playSoundSweepIncWL(1500, 700, 5.46 * kFreescapeSweepTuneFactor, 1, sync);
+	case 1:
+		if (_usePrerecordedSounds) {
+			playWav("fsDOS_laserFire.wav");
+			//_system->delayMillis(50);
+		} else
+			playSoundSweepIncWL(1500, 700, 5.46 * kFreescapeSweepTuneFactor, 1, sync);
 		break;
-		case 2: // Done
-			if (_usePrerecordedSounds) {
-				playWav("fsDOS_WallBump.wav");
-				//_system->delayMillis(50);
-			} else {
-				playSoundConst(82, 60, sync);
-			}
+	case 2: // Done
+		if (_usePrerecordedSounds) {
+			playWav("fsDOS_WallBump.wav");
+			//_system->delayMillis(50);
+		} else {
+			playSoundConst(82, 60, sync);
+		}
 		break;
-		case 3:
-			if (_usePrerecordedSounds) {
-				playWav("fsDOS_stairDown.wav");
-				//_system->delayMillis(50);
-			} else {
-				playSoundConst(220, 50, sync);
-				playSoundConst(185, 50, sync);
-			}
+	case 3:
+		if (_usePrerecordedSounds) {
+			playWav("fsDOS_stairDown.wav");
+			//_system->delayMillis(50);
+		} else {
+			playSoundConst(220, 50, sync);
+			playSoundConst(185, 50, sync);
+		}
 		break;
-		case 4:
-			if (_usePrerecordedSounds) {
-				playWav("fsDOS_stairUp.wav");
-				//_system->delayMillis(50);
-			} else {
-				playSoundConst(220, 50, sync);
-				playSoundConst(340, 50, sync);
-			}
+	case 4:
+		if (_usePrerecordedSounds) {
+			playWav("fsDOS_stairUp.wav");
+			//_system->delayMillis(50);
+		} else {
+			playSoundConst(220, 50, sync);
+			playSoundConst(340, 50, sync);
+		}
 		break;
-		case 5:
-			if (_usePrerecordedSounds) {
-				playWav("fsDOS_roomChange.wav");
-				//_system->delayMillis(50);
-			} else {
-				playSoundSweepIncWL(262, 100, 65.52 * kFreescapeSweepTuneFactor, 1, sync);
-			}
+	case 5:
+		if (_usePrerecordedSounds) {
+			playWav("fsDOS_roomChange.wav");
+			//_system->delayMillis(50);
+		} else {
+			playSoundSweepIncWL(262, 100, 65.52 * kFreescapeSweepTuneFactor, 1, sync);
+		}
 		break;
-		case 6:
-			if (_usePrerecordedSounds) {
-				playWav("fsDOS_configMenu.wav");
-				//_system->delayMillis(50);
-			} else {
-				playSoundConst(830, 60, sync);
-			}
+	case 6:
+		if (_usePrerecordedSounds) {
+			playWav("fsDOS_configMenu.wav");
+			//_system->delayMillis(50);
+		} else {
+			playSoundConst(830, 60, sync);
+		}
 		break;
-		case 7:
-			if (_usePrerecordedSounds) {
-				playWav("fsDOS_bigHit.wav");
-				//_system->delayMillis(50);
-			} else {
-				playSoundSweepIncWL(3000, 155, 7.28 * kFreescapeSweepTuneFactor, 1, sync);
-			}
+	case 7:
+		if (_usePrerecordedSounds) {
+			playWav("fsDOS_bigHit.wav");
+			//_system->delayMillis(50);
+		} else {
+			playSoundSweepIncWL(3000, 155, 7.28 * kFreescapeSweepTuneFactor, 1, sync);
+		}
 		break;
-		case 8:
-			if (_usePrerecordedSounds) {
-				playWav("fsDOS_teleporterActivated.wav");
-				//_system->delayMillis(50);
-			} else {
-				playTeleporter(22, sync);
-			}
+	case 8:
+		if (_usePrerecordedSounds) {
+			playWav("fsDOS_teleporterActivated.wav");
+			//_system->delayMillis(50);
+		} else {
+			playTeleporter(22, sync);
+		}
 		break;
 
-		case 9:
-			if (_usePrerecordedSounds) {
-				playWav("fsDOS_powerUp.wav");
-				//_system->delayMillis(50);
-			} else {
-				playSoundSweepIncWL(280, 5000, 9.1 * kFreescapeSweepTuneFactor, 1, sync);
-			}
+	case 9:
+		if (_usePrerecordedSounds) {
+			playWav("fsDOS_powerUp.wav");
+			//_system->delayMillis(50);
+		} else {
+			playSoundSweepIncWL(280, 5000, 9.1 * kFreescapeSweepTuneFactor, 1, sync);
+		}
 		break;
 
-		case 10:
-			if (_usePrerecordedSounds) {
-				playWav("fsDOS_energyDrain.wav");
-				//_system->delayMillis(50);
-			} else {
-				playSoundSweepIncWL(240, 255, 1.82 * kFreescapeSweepTuneFactor, 1, sync);
-			}
+	case 10:
+		if (_usePrerecordedSounds) {
+			playWav("fsDOS_energyDrain.wav");
+			//_system->delayMillis(50);
+		} else {
+			playSoundSweepIncWL(240, 255, 1.82 * kFreescapeSweepTuneFactor, 1, sync);
+		}
 		break;
 
-		case 11: // ???
-			debugC(1, kFreescapeDebugMedia, "Playing unknown sound");
-			if (_usePrerecordedSounds) {
-				// TODO
-			} else {
-				// TODO
-			}
+	case 11: // ???
+		debugC(1, kFreescapeDebugMedia, "Playing unknown sound");
+		if (_usePrerecordedSounds) {
+			// TODO
+		} else {
+			// TODO
+		}
 		break;
 
-		case 12:
-			if (_usePrerecordedSounds) {
-				playWav("fsDOS_switchOff.wav");
-				//_system->delayMillis(50);
-			} else {
-				playSoundSweepIncWL(555, 440, 1.82 * kFreescapeSweepTuneFactor, 1, sync);
-			}
+	case 12:
+		if (_usePrerecordedSounds) {
+			playWav("fsDOS_switchOff.wav");
+			//_system->delayMillis(50);
+		} else {
+			playSoundSweepIncWL(555, 440, 1.82 * kFreescapeSweepTuneFactor, 1, sync);
+		}
 		break;
 
-		case 13: // Seems to be repeated?
-			if (_usePrerecordedSounds) {
-				playWav("fsDOS_laserHit.wav");
-				//_system->delayMillis(50);
-			} else {
-				playSoundSweepIncWL(3000, 420, 14.56 * kFreescapeSweepTuneFactor, 1, sync);
-			}
+	case 13: // Seems to be repeated?
+		if (_usePrerecordedSounds) {
+			playWav("fsDOS_laserHit.wav");
+			//_system->delayMillis(50);
+		} else {
+			playSoundSweepIncWL(3000, 420, 14.56 * kFreescapeSweepTuneFactor, 1, sync);
+		}
 		break;
 
-		case 14:
-			if (_usePrerecordedSounds) {
-				playWav("fsDOS_tankFall.wav");
-				//_system->delayMillis(50);
-			} else {
-				playSoundSweepIncWL(785, 310, 1.82 * kFreescapeSweepTuneFactor, 1, sync);
-			}
+	case 14:
+		if (_usePrerecordedSounds) {
+			playWav("fsDOS_tankFall.wav");
+			//_system->delayMillis(50);
+		} else {
+			playSoundSweepIncWL(785, 310, 1.82 * kFreescapeSweepTuneFactor, 1, sync);
+		}
 		break;
 
-		case 15:
-			if (_usePrerecordedSounds) {
-				playWav("fsDOS_successJingle.wav");
-				//_system->delayMillis(50);
-			} else {
-				playSoundConst(587.330, 250, sync);
-				playSoundConst(740, 175, sync);
-				playSoundConst(880, 450, sync);
-			}
+	case 15:
+		if (_usePrerecordedSounds) {
+			playWav("fsDOS_successJingle.wav");
+			//_system->delayMillis(50);
+		} else {
+			playSoundConst(587.330, 250, sync);
+			playSoundConst(740, 175, sync);
+			playSoundConst(880, 450, sync);
+		}
 		break;
 
-		case 16: // Silence?
-			if (_usePrerecordedSounds) {
-				// TODO
-			} else {
-				// TODO
-			}
+	case 16: // Silence?
+		if (_usePrerecordedSounds) {
+			// TODO
+		} else {
+			// TODO
+		}
 		break;
 
-		case 17:
-			if (_usePrerecordedSounds) {
-				playWav("fsDOS_badJingle.wav");
-				//_system->delayMillis(50);
-			} else {
-				playSoundConst(65, 150, sync);
-				playSoundConst(44, 400, sync);
-			}
+	case 17:
+		if (_usePrerecordedSounds) {
+			playWav("fsDOS_badJingle.wav");
+			//_system->delayMillis(50);
+		} else {
+			playSoundConst(65, 150, sync);
+			playSoundConst(44, 400, sync);
+		}
 		break;
 
-		case 18: // Silence?
-			if (_usePrerecordedSounds) {
-				// TODO
-			} else {
-				// TODO
-			}
+	case 18: // Silence?
+		if (_usePrerecordedSounds) {
+			// TODO
+		} else {
+			// TODO
+		}
 		break;
 
-		case 19:
-			debugC(1, kFreescapeDebugMedia, "Playing unknown sound");
-			if (_usePrerecordedSounds) {
-				// TODO
-			} else {
-				// TODO
-			}
+	case 19:
+		debugC(1, kFreescapeDebugMedia, "Playing unknown sound");
+		if (_usePrerecordedSounds) {
+			// TODO
+		} else {
+			// TODO
+		}
 		break;
 
-		case 20:
-			if (_usePrerecordedSounds) {
-				playWav("fsDOS_bigHit.wav");
-				//_system->delayMillis(50);
-			} else {
-				playSoundSweepIncWL(3000, 155, 7.28 * kFreescapeSweepTuneFactor, 1, sync);
-			}
+	case 20:
+		if (_usePrerecordedSounds) {
+			playWav("fsDOS_bigHit.wav");
+			//_system->delayMillis(50);
+		} else {
+			playSoundSweepIncWL(3000, 155, 7.28 * kFreescapeSweepTuneFactor, 1, sync);
+		}
 		break;
-		default:
+	default:
 		debugC(1, kFreescapeDebugMedia, "Unexpected sound %d", index);
 		break;
 	}
@@ -271,7 +271,6 @@ void FreescapeEngine::playSoundConst(double hzFreq, int duration, bool sync) {
 	}
 }
 
-
 void FreescapeEngine::playSoundSweepIncWL(double hzFreq1, double hzFreq2, double wlStepPerMS, int resolution, bool sync) {
 	// Play a PC speaker sweep between sound frequencies, using constant wavelength increment.
 
@@ -341,14 +340,11 @@ void FreescapeEngine::playTeleporter(int totalIters, bool sync) {
 	for (i = 0; i < totalIters; i++) {
 		playSoundConst(1193180.0 / fBase, 21, sync);
 
-		if (stepCycle <= 1)
-		{
+		if (stepCycle <= 1) {
 			// Ascending first two portions of cycle
 			fBase += fInc;
 			stepCycle++;
-		}
-		else
-		{
+		} else {
 			// Descending final portion of cycle
 			fBase -= fInc;
 			stepCycle = 0;
@@ -361,19 +357,19 @@ void FreescapeEngine::loadSoundsFx(Common::SeekableReadStream *file, int offset,
 	soundFx *sound = nullptr;
 	_soundsFx[0] = sound;
 	for (int i = 1; i < number + 1; i++) {
-		sound = (soundFx*) malloc(sizeof(soundFx));
+		sound = (soundFx *)malloc(sizeof(soundFx));
 		int zero = file->readUint16BE();
 		assert(zero == 0);
 		int size = file->readUint16BE();
 		int sampleRate = file->readUint16BE();
 		debugC(1, kFreescapeDebugParser, "Loading sound: %d (size: %d, sample rate: %d)", i, size, sampleRate);
-		byte *data = (byte*) malloc(size * sizeof(byte));
+		byte *data = (byte *)malloc(size * sizeof(byte));
 		file->read(data, size);
 		sound->sampleRate = sampleRate;
 		sound->size = size;
-		sound->data = (byte*) data;
+		sound->data = (byte *)data;
 		_soundsFx[i] = sound;
 	}
 }
 
-}
\ No newline at end of file
+} // namespace Freescape
\ No newline at end of file


Commit: e562c0ce5c0a29173d6d8761ea9eab9b3b38de16
    https://github.com/scummvm/scummvm/commit/e562c0ce5c0a29173d6d8761ea9eab9b3b38de16
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:30+01:00

Commit Message:
FREESCAPE: removed useless comments in the tinygl renderer

Changed paths:
    engines/freescape/gfx_tinygl.cpp


diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index a1c48dd96fa..08a950bf416 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -227,7 +227,6 @@ void TinyGLRenderer::renderFace(const Common::Array<Math::Vector3d> &vertices) {
 }
 
 void TinyGLRenderer::renderPolygon(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours) {
-	// assert(size.x() == 0 || size.y() == 0 || size.z() == 0);
 	uint8 r, g, b;
 	if (ordinates->size() % 3 > 0 && ordinates->size() > 0)
 		error("Invalid polygon with size %f %f %f and ordinates %d", size.x(), size.y(), size.z(), ordinates->size());
@@ -325,16 +324,7 @@ void TinyGLRenderer::renderRectangle(const Math::Vector3d &origin, const Math::V
 }
 
 void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours, int type) {
-	Math::Vector3d vertices[8] = {
-		origin,
-		origin,
-		origin,
-		origin,
-		origin,
-		origin,
-		origin,
-		origin,
-	};
+	Math::Vector3d vertices[8] = { origin, origin, origin, origin, origin, origin, origin, origin };
 	PyramidType pyramidType = (PyramidType)type;
 	switch (pyramidType) {
 	default:
@@ -478,15 +468,8 @@ void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vec
 }
 
 void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector3d &size, Common::Array<uint8> *colours) {
-	/*assert(size.x() > 0);
-	assert(size.y() > 0);
-	assert(size.z() > 0);*/
-
-	// debug("Rendering cube at %f, %f, %f", origin.x(), origin.y(), origin.z());
-	// debug("with size %f, %f, %f", size.x(), size.y(), size.z());
 	uint8 r, g, b;
 
-	// Face 0
 	if (getRGBAt((*colours)[0], r, g, b)) {
 		tglColor3ub(r, g, b);
 		tglBegin(TGL_TRIANGLES);
@@ -500,7 +483,6 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 		tglEnd();
 	}
 
-	// Face 1
 	if (getRGBAt((*colours)[1], r, g, b)) {
 		tglColor3ub(r, g, b);
 		tglBegin(TGL_TRIANGLES);
@@ -514,7 +496,6 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 		tglEnd();
 	}
 
-	// Face 2
 	if (getRGBAt((*colours)[2], r, g, b)) {
 		tglColor3ub(r, g, b);
 		tglBegin(TGL_TRIANGLES);
@@ -528,7 +509,6 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 		tglEnd();
 	}
 
-	// Face 3
 	if (getRGBAt((*colours)[3], r, g, b)) {
 		tglColor3ub(r, g, b);
 		tglBegin(TGL_TRIANGLES);
@@ -542,7 +522,6 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 		tglEnd();
 	}
 
-	// Face 1
 	if (getRGBAt((*colours)[4], r, g, b)) {
 		tglColor3ub(r, g, b);
 		tglBegin(TGL_TRIANGLES);
@@ -556,7 +535,6 @@ void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector
 		tglEnd();
 	}
 
-	// Face 0
 	if (getRGBAt((*colours)[5], r, g, b)) {
 		tglColor3ub(r, g, b);
 		tglBegin(TGL_TRIANGLES);


Commit: 637f22ed9b03a23e24c0cf73ba201a00e620e58b
    https://github.com/scummvm/scummvm/commit/637f22ed9b03a23e24c0cf73ba201a00e620e58b
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:30+01:00

Commit Message:
FREESCAPE: corrected farClipPlane value

Changed paths:
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index c72dbf26434..b8e14be2abe 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -96,9 +96,9 @@ FreescapeEngine::FreescapeEngine(OSystem *syst, const ADGameDescription *gd)
 	_lastMousePos = Common::Point(0, 0);
 	_lastFrame = 0;
 	_nearClipPlane = 1;
+	_farClipPlane = 8192 + 1802; // Added some extra distance to avoid flickering
 
 	// These depends on the specific game
-	_farClipPlane = 0;
 	_playerHeight = 0;
 	_playerWidth = 0;
 	_playerDepth = 0;


Commit: a7ad8d87d5cc5ff2db877eaac29f41fe81daf8fa
    https://github.com/scummvm/scummvm/commit/a7ad8d87d5cc5ff2db877eaac29f41fe81daf8fa
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:30+01:00

Commit Message:
FREESCAPE: removed old debug statements

Changed paths:
    engines/freescape/objects/geometricobject.cpp


diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index 4a55019a984..2f9ad05245f 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -328,7 +328,6 @@ bool GeometricObject::collides(const Math::AABB &_boundingBox) {
 }
 
 void GeometricObject::draw(Freescape::Renderer *gfx) {
-	// debug("Drawing %d of type %d", this->getObjectID(), this->getType());
 	if (this->getType() == Cube) {
 		gfx->renderCube(origin, size, colours);
 	} else if (this->getType() == Rectangle) {
@@ -339,7 +338,6 @@ void GeometricObject::draw(Freescape::Renderer *gfx) {
 		if (this->getType() == Triangle)
 			assert(ordinates->size() == 9);
 
-		// debug("Drawing %d of type %d", this->getObjectID(), this->getType());
 		gfx->renderPolygon(origin, size, ordinates, colours);
 	}
 }


Commit: ceb5aaa50d548f627e6c5e6f263b2d83d520a27f
    https://github.com/scummvm/scummvm/commit/ceb5aaa50d548f627e6c5e6f263b2d83d520a27f
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:31+01:00

Commit Message:
FREESCAPE: use platform enumerated type to implement the platform specific detection

Changed paths:
    engines/freescape/freescape.h


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 735ff35b669..fd61806b603 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -93,9 +93,9 @@ public:
 	bool isDark() { return _targetName.hasPrefix("darkside"); }
 	bool isEclipse() { return _targetName.hasPrefix("totaleclipse"); }
 	bool isCastle() { return _targetName.hasPrefix("castle"); }
-	bool isAmiga() { return _targetName.hasSuffix("-amiga") || Common::matchString(_targetName.c_str(), "*-amiga-#"); }
-	bool isAtariST() { return _targetName.hasSuffix("-st") || Common::matchString(_targetName.c_str(), "*-st-#"); }
-	bool isDOS() { return !isAmiga() && !isAtariST(); }
+	bool isAmiga() { return _gameDescription->platform == Common::kPlatformAmiga; }
+	bool isAtariST() { return _gameDescription->platform == Common::kPlatformAtariST; }
+	bool isDOS() { return _gameDescription->platform == Common::kPlatformDOS; }
 
 	Common::Error run() override;
 


Commit: fdce66ded0d241cb1ae593e778f00167e5c3177a
    https://github.com/scummvm/scummvm/commit/fdce66ded0d241cb1ae593e778f00167e5c3177a
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:31+01:00

Commit Message:
FREESCAPE: Added some 3DCK games to the detection tables

Changed paths:
    engines/freescape/detection.cpp


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index d8a54517c3f..b7018b7a52c 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -30,16 +30,16 @@
 namespace Freescape {
 
 static const PlainGameDescriptor freescapeGames[] = {
-	{"3dkit", "The 3D Kit Game"},
+	{"3dkit", "3D Kit Game"},
 	{"driller", "Driller"},
 	{"spacestationoblivion", "Space Station Oblivion"},
 	{"darkside", "Dark Side"},
 	{"totaleclipse", "Total Eclipse"},
 	{"castlemaster", "Castle Master"},
-	{"menace", "Menace of Dr. Spoil Sport"},
 	{0, 0}};
 
 static const ADGameDescription gameDescriptions[] = {
+	// Original Freescape games
 	{"driller",
 	 "Driller",
 	 {
@@ -196,6 +196,31 @@ static const ADGameDescription gameDescriptions[] = {
 	 Common::kPlatformDOS,
 	 ADGF_NO_FLAGS,
 	 GUIO1(GUIO_NOMIDI)},
+
+	// 3D Construction Kit games
+	{"3dkit",
+	 "The 3-D Kit Game",
+	 AD_ENTRY1s("3DKIT.RUN", "f35147729a2f5b6852a504223aeb6a57", 112158),
+	 Common::EN_ANY,
+	 Common::kPlatformDOS,
+	 ADGF_NO_FLAGS,
+	 GUIO1(GUIO_NOMIDI)},
+	{"3dkit",
+	 "Menace of Dr. Spoil Sport",
+	 AD_ENTRY1s("MODSS.RUN", "409ac1100a15447e742ec1415b2741c3", 91176),
+	 Common::EN_ANY,
+	 Common::kPlatformDOS,
+	 ADGF_NO_FLAGS,
+	 GUIO1(GUIO_NOMIDI)},
+	{"3dkit",
+	 "Anarchy Academy",
+	 AD_ENTRY2s("ANARCHY.PRG", "78d543be4aad9608093c1e91bc100307", 270,
+	            "RUNNER.DAT", "1cf7c049ee59503dd7218b0f45828132", 42802),
+	 Common::EN_ANY,
+	 Common::kPlatformAtariST,
+	 ADGF_NO_FLAGS,
+	 GUIO1(GUIO_NOMIDI)},
+
 	AD_TABLE_END_MARKER};
 } // End of namespace Freescape
 


Commit: 632da50c0206adec2e54a1a658c492a803c4147d
    https://github.com/scummvm/scummvm/commit/632da50c0206adec2e54a1a658c492a803c4147d
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:31+01:00

Commit Message:
FREESCAPE: Fixed curly bracket position in local structure definition

Changed paths:
    engines/freescape/area.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index d2b78912ffc..071fbd65516 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -78,8 +78,7 @@ Area::Area(uint16 _areaID, uint16 _areaFlags, ObjectMap *_objectsByID, ObjectMap
 	}
 
 	// sort so that those that are planar are drawn last
-	struct
-	{
+	struct {
 		bool operator()(Object *object1, Object *object2) {
 			if (!object1->isPlanar() && object2->isPlanar())
 				return true;


Commit: 24c2a0b8d4eb6831047b0e349c8e463f4d8624b3
    https://github.com/scummvm/scummvm/commit/24c2a0b8d4eb6831047b0e349c8e463f4d8624b3
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:31+01:00

Commit Message:
FREESCAPE: Avoid type conversion on float definitions

Changed paths:
    engines/freescape/area.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 071fbd65516..c4367be66a3 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -165,7 +165,7 @@ void Area::draw(Freescape::Renderer *gfx) {
 }
 
 Object *Area::shootRay(const Math::Ray &ray) {
-	float size = 16 * 8192; // TODO: check if this is max size
+	float size = 16.0 * 8192.0; // TODO: check if this is max size
 	Object *collided = nullptr;
 	for (int i = 0; i < int(drawableObjects.size()); i++) {
 		float objSize = drawableObjects[i]->getSize().length();
@@ -179,7 +179,7 @@ Object *Area::shootRay(const Math::Ray &ray) {
 }
 
 Object *Area::checkCollisions(const Math::AABB &boundingBox) {
-	float size = 3 * 8192 * 8192; // TODO: check if this is max size
+	float size = 3.0 * 8192.0 * 8192.0; // TODO: check if this is max size
 	Object *collided = nullptr;
 	for (int i = 0; i < int(drawableObjects.size()); i++) {
 		if (!drawableObjects[i]->isDestroyed() && !drawableObjects[i]->isInvisible()) {


Commit: d1a22f76bf65ab9645a8aac7e0358e3fbfe9fff2
    https://github.com/scummvm/scummvm/commit/d1a22f76bf65ab9645a8aac7e0358e3fbfe9fff2
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:31+01:00

Commit Message:
FREESCAPE: Simplify loops to use auto keywords

Changed paths:
    engines/freescape/area.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index c4367be66a3..5b6af68e30c 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -105,8 +105,8 @@ Area::~Area() {
 	delete entrancesByID;
 	delete objectsByID;
 
-	for (Common::Array<Common::String *>::iterator iterator = conditionSources.begin(); iterator != conditionSources.end(); iterator++)
-		delete *iterator;
+	for (auto &it : conditionSources)
+		delete it;
 }
 
 void Area::show() {
@@ -157,9 +157,9 @@ void Area::saveObjects(Common::WriteStream *stream) {
 void Area::draw(Freescape::Renderer *gfx) {
 	gfx->clear();
 	assert(drawableObjects.size() > 0);
-	for (Common::Array<Object *>::iterator it = drawableObjects.begin(); it != drawableObjects.end(); it++) {
-		if (!(*it)->isDestroyed() && !(*it)->isInvisible()) {
-			(*it)->draw(gfx);
+	for (auto &obj : drawableObjects) {
+		if (!obj->isDestroyed() && !obj->isInvisible()) {
+			obj->draw(gfx);
 		}
 	}
 }
@@ -167,11 +167,11 @@ void Area::draw(Freescape::Renderer *gfx) {
 Object *Area::shootRay(const Math::Ray &ray) {
 	float size = 16.0 * 8192.0; // TODO: check if this is max size
 	Object *collided = nullptr;
-	for (int i = 0; i < int(drawableObjects.size()); i++) {
-		float objSize = drawableObjects[i]->getSize().length();
-		if (!drawableObjects[i]->isDestroyed() && !drawableObjects[i]->isInvisible() && drawableObjects[i]->boundingBox.isValid() && ray.intersectAABB(drawableObjects[i]->boundingBox) && size >= objSize) {
-			debugC(1, kFreescapeDebugMove, "shot obj id: %d", drawableObjects[i]->getObjectID());
-			collided = drawableObjects[i];
+	for (auto &obj : drawableObjects) {
+		float objSize = obj->getSize().length();
+		if (!obj->isDestroyed() && !obj->isInvisible() && obj->boundingBox.isValid() && ray.intersectAABB(obj->boundingBox) && size >= objSize) {
+			debugC(1, kFreescapeDebugMove, "shot obj id: %d", obj->getObjectID());
+			collided = obj;
 			size = objSize;
 		}
 	}
@@ -181,12 +181,12 @@ Object *Area::shootRay(const Math::Ray &ray) {
 Object *Area::checkCollisions(const Math::AABB &boundingBox) {
 	float size = 3.0 * 8192.0 * 8192.0; // TODO: check if this is max size
 	Object *collided = nullptr;
-	for (int i = 0; i < int(drawableObjects.size()); i++) {
-		if (!drawableObjects[i]->isDestroyed() && !drawableObjects[i]->isInvisible()) {
-			GeometricObject *obj = (GeometricObject *)drawableObjects[i];
-			float objSize = obj->getSize().length();
-			if (obj->collides(boundingBox) && size > objSize) {
-				collided = obj;
+	for (auto &obj : drawableObjects) {
+		if (!obj->isDestroyed() && !obj->isInvisible()) {
+			GeometricObject *gobj = (GeometricObject *)obj;
+			float objSize = gobj->getSize().length();
+			if (gobj->collides(boundingBox) && size > objSize) {
+				collided = gobj;
 				size = objSize;
 			}
 		}
@@ -206,7 +206,7 @@ void Area::addObject(Object *obj) {
 
 void Area::removeObject(int16 id) {
 	assert(objectsByID->contains(id));
-	for (int i = 0; i < int(drawableObjects.size()); i++) {
+	for (uint i = 0; i < drawableObjects.size(); i++) {
 		if (drawableObjects[i]->getObjectID() == id) {
 			drawableObjects.remove_at(i);
 			break;


Commit: 1717ef7c98fb445a24d9ad7e1965641986e8b673
    https://github.com/scummvm/scummvm/commit/1717ef7c98fb445a24d9ad7e1965641986e8b673
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:31+01:00

Commit Message:
FREESCAPE: Simplify more loops to use auto keywords

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/freescape.cpp
    engines/freescape/games/castle.cpp
    engines/freescape/games/driller.cpp
    engines/freescape/games/eclipse.cpp
    engines/freescape/gfx_tinygl.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 5b6af68e30c..4c4a32607c5 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -71,9 +71,9 @@ Area::Area(uint16 _areaID, uint16 _areaFlags, ObjectMap *_objectsByID, ObjectMap
 	gasPocketRadius = 0;
 
 	// create a list of drawable objects only
-	for (ObjectMap::iterator iterator = objectsByID->begin(); iterator != objectsByID->end(); iterator++) {
-		if (iterator->_value->isDrawable()) {
-			drawableObjects.push_back(iterator->_value);
+	for (auto &it : *objectsByID) {
+		if (it._value->isDrawable()) {
+			drawableObjects.push_back(it._value);
 		}
 	}
 
@@ -93,13 +93,13 @@ Area::Area(uint16 _areaID, uint16 _areaFlags, ObjectMap *_objectsByID, ObjectMap
 
 Area::~Area() {
 	if (entrancesByID) {
-		for (ObjectMap::iterator iterator = entrancesByID->begin(); iterator != entrancesByID->end(); iterator++)
-			delete iterator->_value;
+		for (auto &it : *entrancesByID)
+			delete it._value;
 	}
 
 	if (objectsByID) {
-		for (ObjectMap::iterator iterator = objectsByID->begin(); iterator != objectsByID->end(); iterator++)
-			delete iterator->_value;
+		for (auto &it : *objectsByID)
+			delete it._value;
 	}
 
 	delete entrancesByID;
@@ -111,11 +111,11 @@ Area::~Area() {
 
 void Area::show() {
 	debugC(1, kFreescapeDebugMove, "Area name: %s", name.c_str());
-	for (ObjectMap::iterator it = objectsByID->begin(); it != objectsByID->end(); it++)
-		debugC(1, kFreescapeDebugMove, "objID: %d, type: %d", (*it)._value->getObjectID(), (*it)._value->getType());
+	for (auto &it : *objectsByID)
+		debugC(1, kFreescapeDebugMove, "objID: %d, type: %d", it._value->getObjectID(), it._value->getType());
 
-	for (ObjectMap::iterator it = entrancesByID->begin(); it != entrancesByID->end(); it++)
-		debugC(1, kFreescapeDebugMove, "objID: %d, type: %d (entrance)", (*it)._value->getObjectID(), (*it)._value->getType());
+	for (auto &it : *entrancesByID)
+		debugC(1, kFreescapeDebugMove, "objID: %d, type: %d (entrance)", it._value->getObjectID(), it._value->getType());
 }
 
 void Area::loadObjects(Common::SeekableReadStream *stream, Area *global) {
@@ -144,9 +144,9 @@ void Area::loadObjects(Common::SeekableReadStream *stream, Area *global) {
 void Area::saveObjects(Common::WriteStream *stream) {
 	stream->writeUint32LE(objectsByID->size());
 
-	for (ObjectMap::iterator iterator = objectsByID->begin(); iterator != objectsByID->end(); iterator++) {
-		Object *obj = iterator->_value;
-		stream->writeUint32LE(iterator->_key);
+	for (auto &it : *objectsByID) {
+		Object *obj = it._value;
+		stream->writeUint32LE(it._key);
 		stream->writeUint32LE(obj->getObjectFlags());
 		stream->writeFloatLE(obj->getOrigin().x());
 		stream->writeFloatLE(obj->getOrigin().y());
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index b8e14be2abe..5dd2e5fa805 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -127,8 +127,8 @@ FreescapeEngine::~FreescapeEngine() {
 	delete _uiTexture;
 	delete _titleTexture;
 
-	for (AreaMap::iterator it = _areaMap.begin(); it != _areaMap.end(); ++it)
-		delete it->_value;
+	for (auto &it : _areaMap)
+		delete it._value;
 
 	delete _gfx;
 	delete _dataBundle;
@@ -431,8 +431,8 @@ void FreescapeEngine::initGameState() {
 	for (int i = 0; i < k8bitMaxVariable; i++) // TODO: check maximum variable
 		_gameStateVars[i] = 0;
 
-	for (AreaMap::iterator it = _areaMap.begin(); it != _areaMap.end(); ++it)
-		_gameStateBits[it->_key] = 0;
+	for (auto &it : _areaMap)
+		_gameStateBits[it._key] = 0;
 }
 
 void FreescapeEngine::rotate(float xoffset, float yoffset) {
@@ -561,19 +561,19 @@ Common::Error FreescapeEngine::saveGameStream(Common::WriteStream *stream, bool
 	stream->writeFloatLE(_pitch);
 
 	// Level state
-	for (StateVars::iterator it = _gameStateVars.begin(); it != _gameStateVars.end(); ++it) {
-		stream->writeUint16LE(it->_key);
-		stream->writeUint32LE(it->_value);
+	for (auto &it : _gameStateVars) {
+		stream->writeUint16LE(it._key);
+		stream->writeUint32LE(it._value);
 	}
 
-	for (StateBits::iterator it = _gameStateBits.begin(); it != _gameStateBits.end(); ++it) {
-		stream->writeUint16LE(it->_key);
-		stream->writeUint32LE(it->_value);
+	for (auto &it : _gameStateBits) {
+		stream->writeUint16LE(it._key);
+		stream->writeUint32LE(it._value);
 	}
 
-	for (AreaMap::iterator it = _areaMap.begin(); it != _areaMap.end(); ++it) {
-		stream->writeUint16LE(it->_key);
-		it->_value->saveObjects(stream);
+	for (auto &it : _areaMap) {
+		stream->writeUint16LE(it._key);
+		it._value->saveObjects(stream);
 	}
 
 	stream->writeByte(_flyMode);
diff --git a/engines/freescape/games/castle.cpp b/engines/freescape/games/castle.cpp
index 56571dbdd14..048d8448fdc 100644
--- a/engines/freescape/games/castle.cpp
+++ b/engines/freescape/games/castle.cpp
@@ -65,8 +65,8 @@ void CastleEngine::loadAssets() {
 
 	file = decryptFile("CMEDF");
 	load8bitBinary(file, 0, 16);
-	for (AreaMap::iterator iterator = _areaMap.begin(); iterator != _areaMap.end(); iterator++)
-		iterator->_value->addStructure(_areaMap[255]);
+	for (auto &it : _areaMap)
+		it._value->addStructure(_areaMap[255]);
 
 	// CPC
 	// file = gameDir.createReadStreamForMember("cm.bin");
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index f4746da136e..94372e7feb6 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -515,8 +515,8 @@ void DrillerEngine::initGameState() {
 	for (int i = 0; i < k8bitMaxVariable; i++) // TODO: check maximum variable
 		_gameStateVars[i] = 0;
 
-	for (AreaMap::iterator it = _areaMap.begin(); it != _areaMap.end(); ++it)
-		_gameStateBits[it->_key] = 0;
+	for (auto &it : _areaMap)
+		_gameStateBits[it._key] = 0;
 
 	_gameStateVars[k8bitVariableEnergy] = _initialProveEnergy;
 	_gameStateVars[k8bitVariableShield] = _initialProveShield;
diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index f3d13034fe8..6be8d38543b 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -115,8 +115,8 @@ void EclipseEngine::loadAssets() {
 
 		loadFonts(file, 0xd403);
 		load8bitBinary(file, 0x3ce0, 16);
-		for (AreaMap::iterator iterator = _areaMap.begin(); iterator != _areaMap.end(); iterator++)
-			iterator->_value->addStructure(_areaMap[255]);
+		for (auto &it : _areaMap)
+			it._value->addStructure(_areaMap[255]);
 
 	} else if (_renderMode == "cga") {
 		loadBundledImages();
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 08a950bf416..fb0107859a0 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -576,9 +576,9 @@ void TinyGLRenderer::flipBuffer() {
 	TinyGL::getSurfaceRef(glBuffer);
 
 	if (!dirtyAreas.empty()) {
-		for (Common::List<Common::Rect>::iterator itRect = dirtyAreas.begin(); itRect != dirtyAreas.end(); ++itRect) {
-			g_system->copyRectToScreen(glBuffer.getBasePtr((*itRect).left, (*itRect).top), glBuffer.pitch,
-									   (*itRect).left, (*itRect).top, (*itRect).width(), (*itRect).height());
+		for (auto &it : dirtyAreas) {
+			g_system->copyRectToScreen(glBuffer.getBasePtr(it.left, it.top), glBuffer.pitch,
+									   it.left, it.top, it.width(), it.height());
 		}
 	}
 }


Commit: a5220abe4fb2e6a6b0b7adde5c4590f773818844
    https://github.com/scummvm/scummvm/commit/a5220abe4fb2e6a6b0b7adde5c4590f773818844
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:32+01:00

Commit Message:
FREESCAPE: Removed unreachable line in processInput

Changed paths:
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 5dd2e5fa805..a776247c4bc 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -313,7 +313,6 @@ void FreescapeEngine::processInput() {
 		case Common::EVENT_RETURN_TO_LAUNCHER:
 			quitGame();
 			return;
-			break;
 
 		case Common::EVENT_MOUSEMOVE:
 			mousePos = event.mouse;


Commit: 1567b31443f009b506a0d82ab6ad1ab351ca4729
    https://github.com/scummvm/scummvm/commit/1567b31443f009b506a0d82ab6ad1ab351ca4729
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:32+01:00

Commit Message:
FREESCAPE: Use ABS instead of abs

Changed paths:
    engines/freescape/games/dark.cpp
    engines/freescape/games/driller.cpp
    engines/freescape/movement.cpp


diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index 747c9f24ef0..09ed603240a 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -87,7 +87,7 @@ void DarkEngine::gotoArea(uint16 areaID, int entranceID) {
 		// debug("dif: %f %f %f", diff.x(), diff.y(), diff.z());
 		//  diff should be used to determinate which entrance to use
 		int newPos = -1;
-		if (abs(diff.x()) < abs(diff.z())) {
+		if (ABS(diff.x()) < ABS(diff.z())) {
 			if (diff.z() > 0)
 				newPos = 4000;
 			else
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 94372e7feb6..ca8f5266702 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -75,7 +75,7 @@ void DrillerEngine::gotoArea(uint16 areaID, int entranceID) {
 		// debug("dif: %f %f %f", diff.x(), diff.y(), diff.z());
 		//  diff should be used to determinate which entrance to use
 		int newPos = -1;
-		if (abs(diff.x()) < abs(diff.z())) {
+		if (ABS(diff.x()) < ABS(diff.z())) {
 			if (diff.z() > 0)
 				newPos = 4000;
 			else
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index 8c2de2a0729..4ad4bb39db8 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -38,7 +38,7 @@ void FreescapeEngine::traverseEntrance(uint16 entranceID) {
 	Math::Vector3d rotation = entrance->getRotation();
 	_position = entrance->getOrigin();
 	_pitch = rotation.x();
-	if (abs(diff.x()) > abs(diff.z()) && _lastPosition != Math::Vector3d(0, 0, 0)) {
+	if (ABS(diff.x()) > ABS(diff.z()) && _lastPosition != Math::Vector3d(0, 0, 0)) {
 		_yaw = rotation.y() - 90;
 	} else {
 		_yaw = rotation.y() + 90;


Commit: 6792afe9b3f2a257b97e82150315705ca52acbf6
    https://github.com/scummvm/scummvm/commit/6792afe9b3f2a257b97e82150315705ca52acbf6
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:32+01:00

Commit Message:
FREESCAPE: Removed old comments in headers

Changed paths:
    engines/freescape/gfx.h
    engines/freescape/language/token.h


diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index a2c378c00b0..9c394d6b400 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -170,4 +170,4 @@ Renderer *createRenderer(OSystem *system, int screenW, int screenH);
 
 } // End of namespace Freescape
 
-#endif // GFX_H_
+#endif // FREESCAPE_GFX_H
diff --git a/engines/freescape/language/token.h b/engines/freescape/language/token.h
index 2186ed33ef0..a63a8175018 100644
--- a/engines/freescape/language/token.h
+++ b/engines/freescape/language/token.h
@@ -119,4 +119,4 @@ private:
 
 } // End of namespace Freescape
 
-#endif /* defined(__Phantasma__Token__) */
+#endif // FREESCAPE_TOKEN_H


Commit: 232be624d2f4f6a7f48f94bf4bbb181df8ae8533
    https://github.com/scummvm/scummvm/commit/232be624d2f4f6a7f48f94bf4bbb181df8ae8533
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:32+01:00

Commit Message:
FREESCAPE: Moved include from gfx file to the specialized class

Changed paths:
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl.cpp


diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 9c394d6b400..23b96f93bd2 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -23,7 +23,6 @@
 #define FREESCAPE_GFX_H
 
 #include "common/rect.h"
-#include "common/system.h"
 
 #include "graphics/tinygl/pixelbuffer.h"
 #include "math/frustum.h"
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index fb0107859a0..e5525e6bf02 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -24,6 +24,7 @@
 #include "common/config-manager.h"
 #include "common/math.h"
 #include "common/rect.h"
+#include "common/system.h"
 #include "graphics/tinygl/tinygl.h"
 #include "math/glmath.h"
 


Commit: 5f353076acb7195ff6cab1b0f335241fe6977f29
    https://github.com/scummvm/scummvm/commit/5f353076acb7195ff6cab1b0f335241fe6977f29
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:32+01:00

Commit Message:
FREESCAPE: Avoid type conversion from int to float

Changed paths:
    engines/freescape/gfx_tinygl.cpp


diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index e5525e6bf02..cb38e3eb817 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -289,7 +289,7 @@ void TinyGLRenderer::renderRectangle(const Math::Vector3d &origin, const Math::V
 			vertices.clear();
 			vertices.push_back(Math::Vector3d(origin.x(), origin.y(), origin.z()));
 
-			dx = dy = dz = 0;
+			dx = dy = dz = 0.0;
 			if (size.x() == 0) {
 				dy = size.y();
 			} else if (size.y() == 0) {
@@ -305,7 +305,7 @@ void TinyGLRenderer::renderRectangle(const Math::Vector3d &origin, const Math::V
 			vertices.clear();
 			vertices.push_back(Math::Vector3d(origin.x(), origin.y(), origin.z()));
 
-			dx = dy = dz = 0;
+			dx = dy = dz = 0.0;
 			if (size.x() == 0) {
 				dz = size.z();
 			} else if (size.y() == 0) {


Commit: cdbd58d6a6ff2f0867bfdaebe0d76807f22b7024
    https://github.com/scummvm/scummvm/commit/cdbd58d6a6ff2f0867bfdaebe0d76807f22b7024
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:32+01:00

Commit Message:
FREESCAPE: Added the copyright year

Changed paths:
    engines/freescape/detection.cpp


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index b7018b7a52c..557090f627e 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -262,7 +262,7 @@ public:
 	}
 
 	const char *getOriginalCopyright() const override {
-		return "Copyright (C) Incentive Software";
+		return "Copyright (C) Incentive Software 1987";
 	}
 
 	const DebugChannelDef *getDebugChannels() const override {


Commit: c7f7382eea162548d868bf221f33967f1fac539e
    https://github.com/scummvm/scummvm/commit/c7f7382eea162548d868bf221f33967f1fac539e
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:33+01:00

Commit Message:
FREESCAPE: Removed full stop from the tooltip message

Changed paths:
    engines/freescape/detection.cpp


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index 557090f627e..024468e3e14 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -237,7 +237,7 @@ static const ADExtraGuiOptionsMap optionsList[] = {
 		GAMEOPTION_PRERECORDED_SOUNDS,
 		{
 			_s("Prerecorded sounds"),
-			_s("Use high-quality pre-recorded sounds instead of pc speaker emulation."),
+			_s("Use high-quality pre-recorded sounds instead of pc speaker emulation"),
 			"prerecorded_sounds",
 			true,
 			0,


Commit: 8a5dd8e6a435203c304532ac68c8e85b8492c453
    https://github.com/scummvm/scummvm/commit/8a5dd8e6a435203c304532ac68c8e85b8492c453
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:33+01:00

Commit Message:
FREESCAPE: Use better ADGF flags for each game

Changed paths:
    engines/freescape/detection.cpp


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index 024468e3e14..5de8c48e5ed 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -86,7 +86,7 @@ static const ADGameDescription gameDescriptions[] = {
 	 },
 	 Common::EN_ANY,
 	 Common::kPlatformAmiga,
-	 ADGF_NO_FLAGS | ADGF_DEMO,
+	 ADGF_UNSTABLE | ADGF_DEMO,
 	 GUIO1(GUIO_NOMIDI)},
 	{"driller",
 	 "Rolling Demo",
@@ -98,7 +98,7 @@ static const ADGameDescription gameDescriptions[] = {
 	 },
 	 Common::EN_ANY,
 	 Common::kPlatformAtariST,
-	 ADGF_NO_FLAGS | ADGF_DEMO,
+	 ADGF_UNSTABLE | ADGF_DEMO,
 	 GUIO1(GUIO_NOMIDI)},
 	{"darkside",
 	 "Dark Side",
@@ -111,7 +111,7 @@ static const ADGameDescription gameDescriptions[] = {
 	 },
 	 Common::EN_ANY,
 	 Common::kPlatformDOS,
-	 ADGF_NO_FLAGS,
+	 ADGF_UNSTABLE,
 	 GUIO3(GUIO_NOMIDI, GUIO_RENDEREGA, GUIO_RENDERCGA)},
 	{"totaleclipse",
 	 "Total Eclipse",
@@ -125,7 +125,7 @@ static const ADGameDescription gameDescriptions[] = {
 	 },
 	 Common::EN_ANY,
 	 Common::kPlatformDOS,
-	 ADGF_NO_FLAGS,
+	 ADGF_UNSTABLE,
 	 GUIO3(GUIO_NOMIDI, GUIO_RENDEREGA, GUIO_RENDERCGA)},
 	{"spacestationoblivion",
 	 "Space Station Oblivion",
@@ -138,7 +138,7 @@ static const ADGameDescription gameDescriptions[] = {
 	 },
 	 Common::EN_ANY,
 	 Common::kPlatformDOS,
-	 ADGF_NO_FLAGS,
+	 ADGF_UNSTABLE,
 	 GUIO3(GUIO_NOMIDI, GUIO_RENDEREGA, GUIO_RENDERCGA)},
 	{"castlemaster",
 	 "Castle Master",
@@ -152,7 +152,7 @@ static const ADGameDescription gameDescriptions[] = {
 	 },
 	 Common::EN_ANY,
 	 Common::kPlatformDOS,
-	 ADGF_NO_FLAGS,
+	 ADGF_UNSTABLE,
 	 GUIO1(GUIO_NOMIDI)},
 	{"castlemaster",
 	 "Castle Master/VirtualWords",
@@ -166,7 +166,7 @@ static const ADGameDescription gameDescriptions[] = {
 	 },
 	 Common::EN_ANY,
 	 Common::kPlatformDOS,
-	 ADGF_NO_FLAGS,
+	 ADGF_UNSTABLE,
 	 GUIO1(GUIO_NOMIDI)},
 	{"castlemaster",
 	 "Castle Master/DomarkPCCollection",
@@ -180,7 +180,7 @@ static const ADGameDescription gameDescriptions[] = {
 	 },
 	 Common::EN_ANY,
 	 Common::kPlatformDOS,
-	 ADGF_NO_FLAGS,
+	 ADGF_UNSTABLE,
 	 GUIO1(GUIO_NOMIDI)},
 	{"castlemaster",
 	 "Castle Master",
@@ -194,7 +194,7 @@ static const ADGameDescription gameDescriptions[] = {
 	 },
 	 Common::ES_ESP,
 	 Common::kPlatformDOS,
-	 ADGF_NO_FLAGS,
+	 ADGF_UNSTABLE,
 	 GUIO1(GUIO_NOMIDI)},
 
 	// 3D Construction Kit games
@@ -203,14 +203,14 @@ static const ADGameDescription gameDescriptions[] = {
 	 AD_ENTRY1s("3DKIT.RUN", "f35147729a2f5b6852a504223aeb6a57", 112158),
 	 Common::EN_ANY,
 	 Common::kPlatformDOS,
-	 ADGF_NO_FLAGS,
+	 ADGF_UNSUPPORTED,
 	 GUIO1(GUIO_NOMIDI)},
 	{"3dkit",
 	 "Menace of Dr. Spoil Sport",
 	 AD_ENTRY1s("MODSS.RUN", "409ac1100a15447e742ec1415b2741c3", 91176),
 	 Common::EN_ANY,
 	 Common::kPlatformDOS,
-	 ADGF_NO_FLAGS,
+	 ADGF_UNSUPPORTED,
 	 GUIO1(GUIO_NOMIDI)},
 	{"3dkit",
 	 "Anarchy Academy",
@@ -218,7 +218,7 @@ static const ADGameDescription gameDescriptions[] = {
 	            "RUNNER.DAT", "1cf7c049ee59503dd7218b0f45828132", 42802),
 	 Common::EN_ANY,
 	 Common::kPlatformAtariST,
-	 ADGF_NO_FLAGS,
+	 ADGF_UNSUPPORTED,
 	 GUIO1(GUIO_NOMIDI)},
 
 	AD_TABLE_END_MARKER};


Commit: eaf69c7feec8c2eb3b86588916425de90f93415b
    https://github.com/scummvm/scummvm/commit/eaf69c7feec8c2eb3b86588916425de90f93415b
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:33+01:00

Commit Message:
FREESCAPE: Use better ADGF flags for each game

Changed paths:
    engines/freescape/detection.cpp


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index 5de8c48e5ed..2a8422141e4 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -52,7 +52,7 @@ static const ADGameDescription gameDescriptions[] = {
 	 },
 	 Common::EN_ANY,
 	 Common::kPlatformDOS,
-	 ADGF_NO_FLAGS,
+	 ADGF_UNSTABLE,
 	 GUIO3(GUIO_NOMIDI, GUIO_RENDEREGA, GUIO_RENDERCGA)},
 	{"driller",
 	 "Retail",
@@ -63,7 +63,7 @@ static const ADGameDescription gameDescriptions[] = {
 	 },
 	 Common::EN_ANY,
 	 Common::kPlatformAmiga,
-	 ADGF_NO_FLAGS,
+	 ADGF_UNSTABLE,
 	 GUIO1(GUIO_NOMIDI)},
 	{"driller",
 	 "Kixx",
@@ -74,7 +74,7 @@ static const ADGameDescription gameDescriptions[] = {
 	 },
 	 Common::EN_ANY,
 	 Common::kPlatformAmiga,
-	 ADGF_NO_FLAGS,
+	 ADGF_UNSTABLE,
 	 GUIO1(GUIO_NOMIDI)},
 	{"driller",
 	 "Rolling Demo",


Commit: 8174cf73691d25eb85d33c6198c5e223d9199c6d
    https://github.com/scummvm/scummvm/commit/8174cf73691d25eb85d33c6198c5e223d9199c6d
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:33+01:00

Commit Message:
FREESCAPE: correctly open and close files when reading assets in driller

Changed paths:
    engines/freescape/games/driller.cpp


diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index ca8f5266702..67fd2070894 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -133,32 +133,31 @@ void DrillerEngine::loadAssets() {
 }
 
 void DrillerEngine::loadAssetsDemo() {
-	Common::SeekableReadStream *file = nullptr;
-	Common::String path = ConfMan.get("path");
-	Common::FSDirectory gameDir(path);
-
-	Common::File exe;
+	Common::File file;
 	if (isAmiga()) {
-		file = gameDir.createReadStreamForMember("lift.neo");
-		if (file == nullptr)
+		file.open("lift.neo");
+		if (!file.isOpen())
 			error("Failed to open 'lift.neo' file");
 
-		_title = loadAndConvertNeoImage(file, 0);
+		_title = loadAndConvertNeoImage(&file, 0);
 
-		file = gameDir.createReadStreamForMember("console.neo");
-		if (file == nullptr)
+		file.close();
+		file.open("console.neo");
+		if (!file.isOpen())
 			error("Failed to open 'console.neo' file");
 
-		_border = loadAndConvertNeoImage(file, 0);
+		_border = loadAndConvertNeoImage(&file, 0);
 
-		file = gameDir.createReadStreamForMember("demo.cmd");
-		if (file == nullptr)
+		file.close();
+		file.open("demo.cmd");
+		if (!file.isOpen())
 			error("Failed to open 'demo.cmd' file");
 
-		loadDemoData(file, 0, 0x1000);
+		loadDemoData(&file, 0, 0x1000);
 
-		file = gameDir.createReadStreamForMember("data");
-		if (file == nullptr)
+		file.close();
+		file.open("data");
+		if (!file.isOpen())
 			error("Failed to open 'data' file");
 
 		// loadGlobalObjects(file, 0xbd62);
@@ -167,41 +166,46 @@ void DrillerEngine::loadAssetsDemo() {
 		file->seek(0x2a450);
 		load8bitArea(file, 16);*/
 
-		load8bitBinary(file, 0x442, 16);
-		loadPalettes(file, 0x0);
+		load8bitBinary(&file, 0x442, 16);
+		loadPalettes(&file, 0x0);
 
-		file = gameDir.createReadStreamForMember("driller");
-		if (file == nullptr)
+		file.close();
+		file.open("driller");
+		if (!file.isOpen())
 			error("Failed to open 'driller' file");
-		loadMessagesFixedSize(file, 0x3960, 14, 20);
+		loadMessagesFixedSize(&file, 0x3960, 14, 20);
 
-		file = gameDir.createReadStreamForMember("soundfx");
-		if (file == nullptr)
+		file.close();
+		file.open("soundfx");
+		if (!file.isOpen())
 			error("Failed to open 'soundfx' executable for Amiga");
 
-		loadSoundsFx(file, 0, 25);
+		loadSoundsFx(&file, 0, 25);
 	} else if (isAtariST()) {
-		file = gameDir.createReadStreamForMember("lift.neo");
-		if (file == nullptr)
+		file.open("lift.neo");
+		if (!file.isOpen())
 			error("Failed to open 'lift.neo' file");
 
-		_title = loadAndConvertNeoImage(file, 0);
+		_title = loadAndConvertNeoImage(&file, 0);
 
-		if (file == nullptr)
+		file.close();
+		file.open("console.neo");
+		if (!file.isOpen())
 			error("Failed to open 'console.neo' file");
 
-		file = gameDir.createReadStreamForMember("console.neo");
-		_border = loadAndConvertNeoImage(file, 0);
+		_border = loadAndConvertNeoImage(&file, 0);
 
-		file = gameDir.createReadStreamForMember("demo.cmd");
-		if (file == nullptr)
+		file.close();
+		file.open("demo.cmd");
+		if (!file.isOpen())
 			error("Failed to open 'demo.cmd' file");
 
-		loadDemoData(file, 0, 0x1000);
+		loadDemoData(&file, 0, 0x1000);
 
-		file = gameDir.createReadStreamForMember("data");
+		file.close();
+		file.open("data");
 
-		if (file == nullptr)
+		if (!file.isOpen())
 			error("Failed to open 'data' file");
 
 		// loadGlobalObjects(file, 0xbd62);
@@ -210,19 +214,21 @@ void DrillerEngine::loadAssetsDemo() {
 		file->seek(0x2a450);
 		load8bitArea(file, 16);*/
 
-		load8bitBinary(file, 0x442, 16);
-		loadPalettes(file, 0x0);
+		load8bitBinary(&file, 0x442, 16);
+		loadPalettes(&file, 0x0);
 
-		file = gameDir.createReadStreamForMember("x.prg");
-		if (file == nullptr)
+		file.close();
+		file.open("x.prg");
+		if (!file.isOpen())
 			error("Failed to open 'x.prg' file");
-		loadMessagesFixedSize(file, 0x3b90, 14, 20);
+		loadMessagesFixedSize(&file, 0x3b90, 14, 20);
 
-		file = gameDir.createReadStreamForMember("soundfx");
-		if (file == nullptr)
+		file.close();
+		file.open("soundfx");
+		if (!file.isOpen())
 			error("Failed to open 'soundfx' executable for AtariST demo");
 
-		loadSoundsFx(file, 0, 25);
+		loadSoundsFx(&file, 0, 25);
 	} else
 		error("Unsupported demo for Driller");
 
@@ -231,78 +237,77 @@ void DrillerEngine::loadAssetsDemo() {
 }
 
 void DrillerEngine::loadAssetsFullGame() {
-	Common::SeekableReadStream *file = nullptr;
-	Common::String path = ConfMan.get("path");
-	Common::FSDirectory gameDir(path);
-
-	Common::File exe;
+	Common::File file;
 	if (isAmiga()) {
 		if (_variant == "Retail") {
-			file = gameDir.createReadStreamForMember("driller");
+			file.open("driller");
 
-			if (file == nullptr)
+			if (!file.isOpen())
 				error("Failed to open 'driller' executable for Amiga");
 
-			_border = loadAndConvertNeoImage(file, 0x137f4);
+			_border = loadAndConvertNeoImage(&file, 0x137f4);
 			byte *palette = (byte *)malloc(16 * 3);
 			for (int i = 0; i < 16; i++) { // gray scale palette
 				palette[i * 3 + 0] = i * (255 / 16);
 				palette[i * 3 + 1] = i * (255 / 16);
 				palette[i * 3 + 2] = i * (255 / 16);
 			}
-			_title = loadAndConvertNeoImage(file, 0x10, palette);
+			_title = loadAndConvertNeoImage(&file, 0x10, palette);
 
-			loadMessagesFixedSize(file, 0xc66e, 14, 20);
-			loadGlobalObjects(file, 0xbd62);
-			load8bitBinary(file, 0x29c16, 16);
-			loadPalettes(file, 0x297d4);
-			loadSoundsFx(file, 0x30e80, 25);
+			loadMessagesFixedSize(&file, 0xc66e, 14, 20);
+			loadGlobalObjects(&file, 0xbd62);
+			load8bitBinary(&file, 0x29c16, 16);
+			loadPalettes(&file, 0x297d4);
+			loadSoundsFx(&file, 0x30e80, 25);
 		} else if (_variant == "Kixx") {
-			file = gameDir.createReadStreamForMember("lift.neo");
-			if (file == nullptr)
+			file.open("lift.neo");
+			if (!file.isOpen())
 				error("Failed to open 'lift.neo' file");
 
-			_title = loadAndConvertNeoImage(file, 0);
+			_title = loadAndConvertNeoImage(&file, 0);
 
-			file = gameDir.createReadStreamForMember("console.neo");
-			if (file == nullptr)
+			file.close();
+			file.open("console.neo");
+			if (!file.isOpen())
 				error("Failed to open 'console.neo' file");
 
-			_border = loadAndConvertNeoImage(file, 0);
+			_border = loadAndConvertNeoImage(&file, 0);
 
-			file = gameDir.createReadStreamForMember("driller");
-			if (file == nullptr)
+			file.close();
+			file.open("driller");
+			if (!file.isOpen())
 				error("Failed to open 'driller' executable for Amiga");
 
-			load8bitBinary(file, 0x21a3e, 16);
-			loadPalettes(file, 0x215fc);
+			load8bitBinary(&file, 0x21a3e, 16);
+			loadPalettes(&file, 0x215fc);
 
-			file = gameDir.createReadStreamForMember("soundfx");
-			if (file == nullptr)
+			file.close();
+			file.open("soundfx");
+			if (!file.isOpen())
 				error("Failed to open 'soundfx' executable for Amiga");
 
-			loadSoundsFx(file, 0, 25);
+			loadSoundsFx(&file, 0, 25);
 		}
 	} else if (_renderMode == "ega") {
 		loadBundledImages();
 		_title = _border;
-		file = gameDir.createReadStreamForMember("DRILLE.EXE");
+		file.open("DRILLE.EXE");
 
-		if (file == nullptr)
+		if (!file.isOpen())
 			error("Failed to open DRILLE.EXE");
 
-		loadMessagesFixedSize(file, 0x4135, 14, 20);
-		loadFonts(file, 0x99dd);
-		loadGlobalObjects(file, 0x3b42);
-		load8bitBinary(file, 0x9b40, 16);
+		loadMessagesFixedSize(&file, 0x4135, 14, 20);
+		loadFonts(&file, 0x99dd);
+		loadGlobalObjects(&file, 0x3b42);
+		load8bitBinary(&file, 0x9b40, 16);
 	} else if (_renderMode == "cga") {
 		loadBundledImages();
 		_title = _border;
-		file = gameDir.createReadStreamForMember("DRILLC.EXE");
+		file.open("DRILLC.EXE");
 
-		if (file == nullptr)
+		if (!file.isOpen())
 			error("Failed to open DRILLC.EXE");
-		load8bitBinary(file, 0x7bb0, 4);
+		load8bitBinary(&file, 0x7bb0, 4);
 	} else
 		error("Invalid render mode %s for Driller", _renderMode.c_str());
 }


Commit: fe6fed03a384680cb8019f18d29a133befd5b390
    https://github.com/scummvm/scummvm/commit/fe6fed03a384680cb8019f18d29a133befd5b390
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:33+01:00

Commit Message:
FREESCAPE: correctly open and close files when reading assets in eclipse

Changed paths:
    engines/freescape/games/eclipse.cpp


diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index 6be8d38543b..54b6d93f936 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -101,30 +101,26 @@ EclipseEngine::EclipseEngine(OSystem *syst, const ADGameDescription *gd) : Frees
 }
 
 void EclipseEngine::loadAssets() {
-	Common::SeekableReadStream *file = nullptr;
-	Common::String path = ConfMan.get("path");
-	Common::FSDirectory gameDir(path);
-
-	Common::File exe;
+	Common::File file;
 	if (_renderMode == "ega") {
 		loadBundledImages();
-		file = gameDir.createReadStreamForMember("TOTEE.EXE");
+		file.open("TOTEE.EXE");
 
-		if (file == nullptr)
+		if (!file.isOpen())
 			error("Failed to open TOTEE.EXE");
 
-		loadFonts(file, 0xd403);
-		load8bitBinary(file, 0x3ce0, 16);
+		loadFonts(&file, 0xd403);
+		load8bitBinary(&file, 0x3ce0, 16);
 		for (auto &it : _areaMap)
 			it._value->addStructure(_areaMap[255]);
 
 	} else if (_renderMode == "cga") {
 		loadBundledImages();
-		file = gameDir.createReadStreamForMember("TOTEC.EXE");
+		file.open("TOTEC.EXE");
 
-		if (file == nullptr)
+		if (!file.isOpen())
 			error("Failed to open TOTEC.EXE");
-		load8bitBinary(file, 0x7bb0, 4); // TODO
+		load8bitBinary(&file, 0x7bb0, 4); // TODO
 	} else
 		error("Invalid render mode %s for Total Eclipse", _renderMode.c_str());
 }


Commit: 2ddbb8c15d549b74079ebec668366d23df4d6f5b
    https://github.com/scummvm/scummvm/commit/2ddbb8c15d549b74079ebec668366d23df4d6f5b
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:34+01:00

Commit Message:
FREESCAPE: correctly open and close files when reading assets in dark

Changed paths:
    engines/freescape/games/dark.cpp


diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index 09ed603240a..5992605c8a9 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -40,27 +40,23 @@ DarkEngine::DarkEngine(OSystem *syst, const ADGameDescription *gd) : FreescapeEn
 }
 
 void DarkEngine::loadAssets() {
-	Common::SeekableReadStream *file = nullptr;
-	Common::String path = ConfMan.get("path");
-	Common::FSDirectory gameDir(path);
-
-	Common::File exe;
+	Common::File file;
 	if (_renderMode == "ega") {
 		loadBundledImages();
-		file = gameDir.createReadStreamForMember("DSIDEE.EXE");
+		file.open("DSIDEE.EXE");
 
-		if (file == nullptr)
+		if (!file.isOpen())
 			error("Failed to open DSIDEE.EXE");
 
-		loadFonts(file, 0xa113);
-		load8bitBinary(file, 0xa280, 16);
+		loadFonts(&file, 0xa113);
+		load8bitBinary(&file, 0xa280, 16);
 	} else if (_renderMode == "cga") {
 		loadBundledImages();
-		file = gameDir.createReadStreamForMember("DSIDEC.EXE");
+		file.open("DSIDEC.EXE");
 
-		if (file == nullptr)
+		if (!file.isOpen())
 			error("Failed to open DSIDEC.EXE");
-		load8bitBinary(file, 0x7bb0, 4); // TODO
+		load8bitBinary(&file, 0x7bb0, 4); // TODO
 	} else
 		error("Invalid render mode %s for Dark Side", _renderMode.c_str());
 }


Commit: 362338c6247e9d2dd6ea0ccc5d4d64f1126889f2
    https://github.com/scummvm/scummvm/commit/362338c6247e9d2dd6ea0ccc5d4d64f1126889f2
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:34+01:00

Commit Message:
FREESCAPE: correctly open and close files when reading assets in castle

Changed paths:
    engines/freescape/games/castle.cpp


diff --git a/engines/freescape/games/castle.cpp b/engines/freescape/games/castle.cpp
index 048d8448fdc..43e71a8a8df 100644
--- a/engines/freescape/games/castle.cpp
+++ b/engines/freescape/games/castle.cpp
@@ -38,13 +38,15 @@ CastleEngine::CastleEngine(OSystem *syst, const ADGameDescription *gd) : Freesca
 }
 
 Common::SeekableReadStream *CastleEngine::decryptFile(const Common::String filename) {
-	Common::String path = ConfMan.get("path");
-	Common::FSDirectory gameDir(path);
+	Common::File file;
+	file.open(filename);
+	if (!file.isOpen())
+		error("Failed to open %s", filename.c_str());
 
-	Common::SeekableReadStream *file = gameDir.createReadStreamForMember(filename);
-	int size = file->size();
+	int size = file.size();
 	byte *encryptedBuffer = (byte *)malloc(size);
-	file->read(encryptedBuffer, size);
+	file.read(encryptedBuffer, size);
+	file.close();
 
 	int seed = 24;
 	for (int i = 0; i < size; i++) {
@@ -56,17 +58,18 @@ Common::SeekableReadStream *CastleEngine::decryptFile(const Common::String filen
 }
 
 void CastleEngine::loadAssets() {
-	Common::SeekableReadStream *file = nullptr;
+	Common::SeekableReadStream *stream = nullptr;
 	_renderMode = "ega";
 
-	file = decryptFile("CMLE");
-	loadMessagesVariableSize(file, 0, 172);
-	delete file;
+	stream = decryptFile("CMLE");
+	loadMessagesVariableSize(stream, 0, 172);
+	delete stream;
 
-	file = decryptFile("CMEDF");
-	load8bitBinary(file, 0, 16);
+	stream = decryptFile("CMEDF");
+	load8bitBinary(stream, 0, 16);
 	for (auto &it : _areaMap)
 		it._value->addStructure(_areaMap[255]);
+	delete stream;
 
 	// CPC
 	// file = gameDir.createReadStreamForMember("cm.bin");


Commit: b5c1a6ef465c817433e6bcdec7797108c30fd7be
    https://github.com/scummvm/scummvm/commit/b5c1a6ef465c817433e6bcdec7797108c30fd7be
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:34+01:00

Commit Message:
FREESCAPE: removed redudant strings in the detection tables

Changed paths:
    engines/freescape/detection.cpp


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index 2a8422141e4..d2789a344a6 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -41,7 +41,7 @@ static const PlainGameDescriptor freescapeGames[] = {
 static const ADGameDescription gameDescriptions[] = {
 	// Original Freescape games
 	{"driller",
-	 "Driller",
+	 "",
 	 {
 		{"DRILLER.EXE", 0, "cafc0ea0d3424640a7723af87f8bfc0b", 17427},
 		{"DRILLC.EXE", 0, "908dd1f8732ebcbaece7d8f0cffd8830", 43864},
@@ -101,7 +101,7 @@ static const ADGameDescription gameDescriptions[] = {
 	 ADGF_UNSTABLE | ADGF_DEMO,
 	 GUIO1(GUIO_NOMIDI)},
 	{"darkside",
-	 "Dark Side",
+	 "",
 	 {
 		{"DARKSIDE.EXE", 0, "c6c0d0186ec45e6cecd72bf5550c7f98", 1600},
 		{"DSIDEC.EXE", 0, "31e6c169d9270b6de8c1c2e746ac238e", 49504},
@@ -114,7 +114,7 @@ static const ADGameDescription gameDescriptions[] = {
 	 ADGF_UNSTABLE,
 	 GUIO3(GUIO_NOMIDI, GUIO_RENDEREGA, GUIO_RENDERCGA)},
 	{"totaleclipse",
-	 "Total Eclipse",
+	 "",
 	 {
 		{"TOTAL.EXE", 0, "959703c1cd37b0d9744c492240a8178b", 13327},
 		{"TOTEH.EXE", 0, "c68d59874ab2a93cc9cc1b1d3aed8f17", 60628},
@@ -128,7 +128,7 @@ static const ADGameDescription gameDescriptions[] = {
 	 ADGF_UNSTABLE,
 	 GUIO3(GUIO_NOMIDI, GUIO_RENDEREGA, GUIO_RENDERCGA)},
 	{"spacestationoblivion",
-	 "Space Station Oblivion",
+	 "",
 	 {
 		{"OBLIVION.EXE", 0, "80783622013750d7c88fd1d35dde919a", 6765},
 		{"DRILLC.EXE", 0, "56394eae69f535cbddaa463888086ac6", 43864},
@@ -141,7 +141,7 @@ static const ADGameDescription gameDescriptions[] = {
 	 ADGF_UNSTABLE,
 	 GUIO3(GUIO_NOMIDI, GUIO_RENDEREGA, GUIO_RENDERCGA)},
 	{"castlemaster",
-	 "Castle Master",
+	 "",
 	 {
 		{"CASTLE.EXE", 0, "f1a141df0e47860246716db20d2ba061", 2806},
 		{"CMC.EXE", 0, "03af2b79b1aad690684cf89025c5f425", 60240},
@@ -155,7 +155,7 @@ static const ADGameDescription gameDescriptions[] = {
 	 ADGF_UNSTABLE,
 	 GUIO1(GUIO_NOMIDI)},
 	{"castlemaster",
-	 "Castle Master/VirtualWords",
+	 "VirtualWords",
 	 {
 		{"CASTLE.EXE", 0, "f1a141df0e47860246716db20d2ba061", 2806},
 		{"CMC.EXE", 0, "7b9275df446f82fdd0c377f6ec2db546", 57168},
@@ -169,7 +169,7 @@ static const ADGameDescription gameDescriptions[] = {
 	 ADGF_UNSTABLE,
 	 GUIO1(GUIO_NOMIDI)},
 	{"castlemaster",
-	 "Castle Master/DomarkPCCollection",
+	 "DomarkPCCollection",
 	 {
 		{"X.EXE", 0, "d51d7db1e06814cbf763c43f411df616", 2157},
 		{"CMC.EXE", 0, "7b9275df446f82fdd0c377f6ec2db546", 57168},
@@ -183,7 +183,7 @@ static const ADGameDescription gameDescriptions[] = {
 	 ADGF_UNSTABLE,
 	 GUIO1(GUIO_NOMIDI)},
 	{"castlemaster",
-	 "Castle Master",
+	 "",
 	 {
 		{"CASTLE.EXE", 0, "42a7d46b418d68e75e31c1cb9d89af14", 2678},
 		{"CMC.EXE", 0, "9015c244dc8a97fe55df7b235b31e00c", 57168},


Commit: 882797ea17ed4e2005b1a063f739a7626c591781
    https://github.com/scummvm/scummvm/commit/882797ea17ed4e2005b1a063f739a7626c591781
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:34+01:00

Commit Message:
FREESCAPE: use the RenderMode type instead of string to load game assets

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/castle.cpp
    engines/freescape/games/dark.cpp
    engines/freescape/games/driller.cpp
    engines/freescape/games/eclipse.cpp
    engines/freescape/games/palettes.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index a776247c4bc..760e65051bd 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -38,18 +38,18 @@ FreescapeEngine::FreescapeEngine(OSystem *syst, const ADGameDescription *gd)
 	: Engine(syst), _gameDescription(gd), _gfx(nullptr) {
 	g_freescape = this;
 	if (!ConfMan.hasKey("render_mode") || ConfMan.get("render_mode").empty())
-		_renderMode = "ega";
+		_renderMode = Common::kRenderEGA;
 	else
-		_renderMode = ConfMan.get("render_mode");
+		_renderMode = Common::parseRenderMode(ConfMan.get("render_mode"));
 
 	_binaryBits = 0;
 	_screenW = 320;
 	_screenH = 200;
 
 	if (isAmiga()) {
-		_renderMode = "amiga";
+		_renderMode = Common::kRenderAmiga;
 	} else if (isAtariST()) {
-		_renderMode = "atari";
+		_renderMode = Common::kRenderAtariST;
 	}
 
 	if (gd->extra)
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index fd61806b603..8ef5d1cb1c9 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -24,6 +24,7 @@
 
 #include "common/bitarray.h"
 #include "common/random.h"
+#include "common/rendermode.h"
 #include "engines/advancedDetector.h"
 #include "engines/engine.h"
 #include "graphics/palette.h"
@@ -250,7 +251,7 @@ public:
 	// Rendering
 	int _screenW, _screenH;
 	Renderer *_gfx;
-	Common::String _renderMode;
+	Common::RenderMode _renderMode;
 	Graphics::PixelBuffer *getPalette(uint8 areaNumber, uint8 c1, uint8 c2, uint8 c3, uint8 c4, uint16 ncolors);
 	ColorMap _colorMap;
 	void drawFrame();
diff --git a/engines/freescape/games/castle.cpp b/engines/freescape/games/castle.cpp
index 43e71a8a8df..8cd4c14927d 100644
--- a/engines/freescape/games/castle.cpp
+++ b/engines/freescape/games/castle.cpp
@@ -59,7 +59,6 @@ Common::SeekableReadStream *CastleEngine::decryptFile(const Common::String filen
 
 void CastleEngine::loadAssets() {
 	Common::SeekableReadStream *stream = nullptr;
-	_renderMode = "ega";
 
 	stream = decryptFile("CMLE");
 	loadMessagesVariableSize(stream, 0, 172);
diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index 5992605c8a9..57a120bdfe8 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -41,7 +41,7 @@ DarkEngine::DarkEngine(OSystem *syst, const ADGameDescription *gd) : FreescapeEn
 
 void DarkEngine::loadAssets() {
 	Common::File file;
-	if (_renderMode == "ega") {
+	if (_renderMode == Common::kRenderEGA) {
 		loadBundledImages();
 		file.open("DSIDEE.EXE");
 
@@ -50,7 +50,7 @@ void DarkEngine::loadAssets() {
 
 		loadFonts(&file, 0xa113);
 		load8bitBinary(&file, 0xa280, 16);
-	} else if (_renderMode == "cga") {
+	} else if (_renderMode == Common::kRenderCGA) {
 		loadBundledImages();
 		file.open("DSIDEC.EXE");
 
@@ -58,7 +58,7 @@ void DarkEngine::loadAssets() {
 			error("Failed to open DSIDEC.EXE");
 		load8bitBinary(&file, 0x7bb0, 4); // TODO
 	} else
-		error("Invalid render mode %s for Dark Side", _renderMode.c_str());
+		error("Invalid or unsupported render mode %s for Dark Side", Common::getRenderModeDescription(_renderMode));
 }
 
 void DarkEngine::gotoArea(uint16 areaID, int entranceID) {
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 67fd2070894..399a9fa1c8d 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -288,7 +288,7 @@ void DrillerEngine::loadAssetsFullGame() {
 
 			loadSoundsFx(&file, 0, 25);
 		}
-	} else if (_renderMode == "ega") {
+	} else if (_renderMode == Common::kRenderEGA) {
 		loadBundledImages();
 		_title = _border;
 		file.open("DRILLE.EXE");
@@ -300,7 +300,7 @@ void DrillerEngine::loadAssetsFullGame() {
 		loadFonts(&file, 0x99dd);
 		loadGlobalObjects(&file, 0x3b42);
 		load8bitBinary(&file, 0x9b40, 16);
-	} else if (_renderMode == "cga") {
+	} else if (_renderMode == Common::kRenderEGA) {
 		loadBundledImages();
 		_title = _border;
 		file.open("DRILLC.EXE");
@@ -309,7 +309,7 @@ void DrillerEngine::loadAssetsFullGame() {
 			error("Failed to open DRILLC.EXE");
 		load8bitBinary(&file, 0x7bb0, 4);
 	} else
-		error("Invalid render mode %s for Driller", _renderMode.c_str());
+		error("Invalid or unsupported render mode %s for Driller", Common::getRenderModeDescription(_renderMode));
 }
 
 void DrillerEngine::drawUI() {
@@ -348,7 +348,7 @@ void DrillerEngine::drawUI() {
 
 	int energy = _gameStateVars[k8bitVariableEnergy];
 	int shield = _gameStateVars[k8bitVariableShield];
-	if (_renderMode == "ega" && _border) {
+	if (_renderMode == Common::kRenderEGA && _border) {
 		// Common::Rect black(20, 177, 87, 191);
 		//_gfx->drawRect2D(black, 255, 0, 0, 0);
 
diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index 54b6d93f936..d6cdd7f4cc1 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -102,7 +102,7 @@ EclipseEngine::EclipseEngine(OSystem *syst, const ADGameDescription *gd) : Frees
 
 void EclipseEngine::loadAssets() {
 	Common::File file;
-	if (_renderMode == "ega") {
+	if (_renderMode == Common::kRenderEGA) {
 		loadBundledImages();
 		file.open("TOTEE.EXE");
 
@@ -114,7 +114,7 @@ void EclipseEngine::loadAssets() {
 		for (auto &it : _areaMap)
 			it._value->addStructure(_areaMap[255]);
 
-	} else if (_renderMode == "cga") {
+	} else if (_renderMode == Common::kRenderCGA) {
 		loadBundledImages();
 		file.open("TOTEC.EXE");
 
@@ -122,7 +122,7 @@ void EclipseEngine::loadAssets() {
 			error("Failed to open TOTEC.EXE");
 		load8bitBinary(&file, 0x7bb0, 4); // TODO
 	} else
-		error("Invalid render mode %s for Total Eclipse", _renderMode.c_str());
+		error("Invalid or unsupported render mode %s for Total Eclipse", Common::getRenderModeDescription(_renderMode));
 }
 
 void EclipseEngine::gotoArea(uint16 areaID, int entranceID) {
diff --git a/engines/freescape/games/palettes.cpp b/engines/freescape/games/palettes.cpp
index f9910c7acd4..f718b1975bf 100644
--- a/engines/freescape/games/palettes.cpp
+++ b/engines/freescape/games/palettes.cpp
@@ -50,11 +50,11 @@ byte dos_CGA_palette[4][3] = {
 
 void FreescapeEngine::loadColorPalette() {
 	Graphics::PixelBuffer *palette = nullptr;
-	if (_renderMode == "ega")
+	if (_renderMode == Common::kRenderEGA)
 		palette = new Graphics::PixelBuffer(_gfx->_palettePixelFormat, (byte *)&dos_EGA_palette);
-	else if (_renderMode == "cga")
+	else if (_renderMode == Common::kRenderCGA)
 		palette = new Graphics::PixelBuffer(_gfx->_palettePixelFormat, (byte *)&dos_CGA_palette);
-	else if (_renderMode == "amiga" || _renderMode == "atari")
+	else if (_renderMode == Common::kRenderAmiga || _renderMode == Common::kRenderAtariST)
 		palette = nullptr; // palette depends on the area
 	else
 		error("Invalid render mode, no palette selected");
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 3a98f12cb71..163f26fbc0a 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -129,14 +129,14 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 		for (uint8 colour = 0; colour < numberOfColours / 2; colour++) {
 			uint8 data = readField(file, 8);
 			entry = data & 0xf;
-			if (_renderMode == "cga")
+			if (_renderMode == Common::kRenderCGA)
 				entry = entry % 4; // TODO: use dithering
 
 			colours->push_back(entry);
 			debugC(1, kFreescapeDebugParser, "color[%d] = %x", 2 * colour, entry);
 
 			entry = data >> 4;
-			if (_renderMode == "cga")
+			if (_renderMode == Common::kRenderCGA)
 				entry = entry % 4; // TODO: use dithering
 
 			colours->push_back(entry);
@@ -289,7 +289,7 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	// skyColor = file->readByte() & 15;
 	// debugC(1, kFreescapeDebugParser, "Colors: %d %d", skyColor, groundColor);
 
-	if (_renderMode == "cga") {
+	if (_renderMode == Common::kRenderCGA) {
 		skyColor = skyColor % 4;
 		groundColor = groundColor % 4;
 	}
@@ -511,7 +511,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 
 void FreescapeEngine::loadBundledImages() {
 	Image::BitmapDecoder decoder;
-	Common::String borderFilename = _targetName + "_" + _renderMode + ".bmp";
+	Common::String borderFilename = _targetName + "_" + Common::getRenderModeDescription(_renderMode) + ".bmp";
 	if (_dataBundle->hasFile(borderFilename)) {
 		Common::SeekableReadStream *borderFile = _dataBundle->createReadStreamForMember(borderFilename);
 		decoder.loadStream(*borderFile);


Commit: 64b575ea79113d5b289629f878a3f0b130724e55
    https://github.com/scummvm/scummvm/commit/64b575ea79113d5b289629f878a3f0b130724e55
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:34+01:00

Commit Message:
FREESCAPE: use the RenderMode type in gfx

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/gfx.cpp
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/gfx_tinygl.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 760e65051bd..21dbfcbace3 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -364,9 +364,7 @@ void FreescapeEngine::processInput() {
 
 Common::Error FreescapeEngine::run() {
 	// Initialize graphics
-	_gfx = createRenderer(_system, _screenW, _screenH);
-	_gfx->_isAmiga = isAmiga();
-	_gfx->_isAtariST = isAtariST();
+	_gfx = createRenderer(_system, _screenW, _screenH, _renderMode);
 	_gfx->init();
 	_gfx->clear();
 
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index a5067769034..7a0506551ef 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -33,7 +33,7 @@
 
 namespace Freescape {
 
-Renderer::Renderer(OSystem *system, int screenW, int screenH)
+Renderer::Renderer(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode)
 	: _system(system) {
 
 	_screenW = screenW;
@@ -44,8 +44,7 @@ Renderer::Renderer(OSystem *system, int screenW, int screenH)
 	_keyColor = -1;
 	_palette = nullptr;
 	_colorMap = nullptr;
-	_isAmiga = false;
-	_isAtariST = false;
+	_renderMode = renderMode;
 }
 
 Renderer::~Renderer() {}
@@ -68,7 +67,7 @@ bool Renderer::getRGBAt(uint8 index, uint8 &r, uint8 &g, uint8 &b) {
 		return true;
 	}
 
-	if (_isAmiga || _isAtariST) {
+	if (_renderMode == Common::kRenderAmiga || _renderMode == Common::kRenderAtariST) {
 		_palette->getRGBAt(index, r, g, b);
 		return true;
 	}
@@ -104,7 +103,7 @@ void Renderer::computeScreenViewport() {
 	_screenViewport = Common::Rect(_screenW, _screenH);
 }
 
-Renderer *createRenderer(OSystem *system, int screenW, int screenH) {
+Renderer *createRenderer(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode) {
 	Common::String rendererConfig = ConfMan.get("renderer");
 	Graphics::PixelFormat pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
 	Graphics::RendererType desiredRendererType = Graphics::kRendererTypeTinyGL;  // Graphics::parseRendererTypeCode(rendererConfig);
@@ -145,7 +144,7 @@ Renderer *createRenderer(OSystem *system, int screenW, int screenH) {
 		}
 	#endif*/
 	if (matchingRendererType == Graphics::kRendererTypeTinyGL) {
-		return CreateGfxTinyGL(system, screenW, screenH);
+		return CreateGfxTinyGL(system, screenW, screenH, renderMode);
 	}
 
 	error("Unable to create a '%s' renderer", rendererConfig.c_str());
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 23b96f93bd2..0ea15f1d845 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -22,6 +22,7 @@
 #ifndef FREESCAPE_GFX_H
 #define FREESCAPE_GFX_H
 
+#include "common/rendermode.h"
 #include "common/rect.h"
 
 #include "graphics/tinygl/pixelbuffer.h"
@@ -52,7 +53,7 @@ public:
 
 class Renderer {
 public:
-	Renderer(OSystem *system, int screenW, int screenH);
+	Renderer(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode);
 	virtual ~Renderer();
 
 	Graphics::PixelFormat _currentPixelFormat;
@@ -121,8 +122,7 @@ public:
 
 	int _screenW;
 	int _screenH;
-	bool _isAmiga;
-	bool _isAtariST;
+	Common::RenderMode _renderMode;
 
 	void computeScreenViewport();
 
@@ -162,10 +162,10 @@ private:
 	uint _startFrameTime;
 };
 
-Renderer *CreateGfxOpenGL(OSystem *system);
-Renderer *CreateGfxOpenGLShader(OSystem *system);
-Renderer *CreateGfxTinyGL(OSystem *system, int screenW, int screenH);
-Renderer *createRenderer(OSystem *system, int screenW, int screenH);
+Renderer *CreateGfxOpenGL(OSystem *system, Common::RenderMode renderMode);
+Renderer *CreateGfxOpenGLShader(OSystem *system, Common::RenderMode renderMode);
+Renderer *CreateGfxTinyGL(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode);
+Renderer *createRenderer(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode);
 
 } // End of namespace Freescape
 
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index cb38e3eb817..30e2c7bc6de 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -33,11 +33,11 @@
 
 namespace Freescape {
 
-Renderer *CreateGfxTinyGL(OSystem *system, int screenW, int screenH) {
-	return new TinyGLRenderer(system, screenW, screenH);
+Renderer *CreateGfxTinyGL(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode) {
+	return new TinyGLRenderer(system, screenW, screenH, renderMode);
 }
 
-TinyGLRenderer::TinyGLRenderer(OSystem *system, int screenW, int screenH) : Renderer(system, screenW, screenH) {
+TinyGLRenderer::TinyGLRenderer(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode) : Renderer(system, screenW, screenH, renderMode) {
 }
 
 TinyGLRenderer::~TinyGLRenderer() {
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index e592c2b0c73..1598adcb5dd 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -31,7 +31,7 @@ namespace Freescape {
 
 class TinyGLRenderer : public Renderer {
 public:
-	TinyGLRenderer(OSystem *system, int screenW, int screenH);
+	TinyGLRenderer(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode);
 	virtual ~TinyGLRenderer();
 
 	virtual void init() override;


Commit: 5406ed59297df4f9675aee96b410887d556e8c85
    https://github.com/scummvm/scummvm/commit/5406ed59297df4f9675aee96b410887d556e8c85
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:34+01:00

Commit Message:
FREESCAPE: specify RGB colors with a portable function

Changed paths:
    engines/freescape/games/dark.cpp
    engines/freescape/games/driller.cpp
    engines/freescape/games/eclipse.cpp


diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index 57a120bdfe8..8bc8b9a807d 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -118,12 +118,13 @@ void DarkEngine::drawUI() {
 
 		Graphics::Surface *surface = new Graphics::Surface();
 		surface->create(_screenW, _screenH, _gfx->_currentPixelFormat);
-		surface->fillRect(_fullscreenViewArea, 0xA0A0A0FF);
+		uint32 gray = _gfx->_currentPixelFormat.RGBToColor(0xA0, 0xA0, 0xA0);
+		surface->fillRect(_fullscreenViewArea, gray);
 
 		int score = _gameStateVars[k8bitVariableScore];
 
-		uint32 yellow = 0xFFFF55FF;
-		uint32 black = 0x000000FF;
+		uint32 yellow = _gfx->_currentPixelFormat.RGBToColor(0xFF, 0xFF, 0x55);
+		uint32 black = _gfx->_currentPixelFormat.RGBToColor(0x00, 0x00, 0x00);
 
 		drawStringInSurface(_currentAreaMessages[0], 112, 177, yellow, black, surface);
 		drawStringInSurface(Common::String::format("%04d", 2 * int(_position.x())), 201, 137, yellow, black, surface);
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 399a9fa1c8d..ff9ff81cc82 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -320,12 +320,13 @@ void DrillerEngine::drawUI() {
 
 		Graphics::Surface *surface = new Graphics::Surface();
 		surface->create(_screenW, _screenH, _gfx->_currentPixelFormat);
-		surface->fillRect(_fullscreenViewArea, 0xA0A0A0FF);
+		uint32 gray = _gfx->_currentPixelFormat.RGBToColor(0xA0, 0xA0, 0xA0);
+		surface->fillRect(_fullscreenViewArea, gray);
 
 		int score = _gameStateVars[k8bitVariableScore];
 
-		uint32 yellow = 0xFFFF55FF;
-		uint32 black = 0x000000FF;
+		uint32 yellow = _gfx->_currentPixelFormat.RGBToColor(0xFF, 0xFF, 0x55);
+		uint32 black = _gfx->_currentPixelFormat.RGBToColor(0x00, 0x00, 0x00);
 
 		drawStringInSurface(_currentAreaMessages[0], 196, 177, yellow, black, surface);
 		drawStringInSurface(_currentAreaMessages[1], 196, 185, yellow, black, surface);
diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index d6cdd7f4cc1..5a6e444ca0b 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -173,12 +173,13 @@ void EclipseEngine::drawUI() {
 
 	Graphics::Surface *surface = new Graphics::Surface();
 	surface->create(_screenW, _screenH, _gfx->_currentPixelFormat);
-	surface->fillRect(_fullscreenViewArea, 0xA0A0A0FF);
+	uint32 gray = _gfx->_currentPixelFormat.RGBToColor(0xA0, 0xA0, 0xA0);
+	surface->fillRect(_fullscreenViewArea, gray);
 
 	int score = _gameStateVars[k8bitVariableScore];
-	uint32 yellow = 0xFFFF55FF;
-	uint32 black = 0x000000FF;
-	uint32 white = 0xFFFFFFFF;
+	uint32 yellow = _gfx->_currentPixelFormat.RGBToColor(0xFF, 0xFF, 0x55);
+	uint32 black = _gfx->_currentPixelFormat.RGBToColor(0x00, 0x00, 0x00);
+	uint32 white = _gfx->_currentPixelFormat.RGBToColor(0xFF, 0xFF, 0xFF);
 
 	if (!_currentAreaMessages.empty())
 		drawStringInSurface(_currentAreaMessages[0], 102, 135, black, yellow, surface);


Commit: 4b79f528ddd0ff9b3975f96a6a3c188850fe0f1f
    https://github.com/scummvm/scummvm/commit/4b79f528ddd0ff9b3975f96a6a3c188850fe0f1f
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:35+01:00

Commit Message:
FREESCAPE: renamed variable names from Area class to follow code conventions

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/games/castle.cpp
    engines/freescape/games/dark.cpp
    engines/freescape/games/driller.cpp
    engines/freescape/games/eclipse.cpp
    engines/freescape/language/instruction.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 4c4a32607c5..afccde86ca0 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -39,41 +39,41 @@ Object *Area::objectWithIDFromMap(ObjectMap *map, uint16 objectID) {
 }
 
 Object *Area::objectWithID(uint16 objectID) {
-	return objectWithIDFromMap(objectsByID, objectID);
+	return objectWithIDFromMap(_objectsByID, objectID);
 }
 
 Object *Area::entranceWithID(uint16 objectID) {
-	return objectWithIDFromMap(entrancesByID, objectID);
+	return objectWithIDFromMap(_entrancesByID, objectID);
 }
 
 uint16 Area::getAreaID() {
-	return areaID;
+	return _areaID;
 }
 
 uint16 Area::getAreaFlags() {
-	return areaFlags;
+	return _areaFlags;
 }
 
 uint8 Area::getScale() {
-	return scale;
+	return _scale;
 }
 
-Area::Area(uint16 _areaID, uint16 _areaFlags, ObjectMap *_objectsByID, ObjectMap *_entrancesByID) {
-	areaID = _areaID;
-	areaFlags = _areaFlags;
-	objectsByID = _objectsByID;
-	entrancesByID = _entrancesByID;
+Area::Area(uint16 areaID_, uint16 areaFlags_, ObjectMap *objectsByID_, ObjectMap *entrancesByID_) {
+	_areaID = areaID_;
+	_areaFlags = areaFlags_;
+	_objectsByID = objectsByID_;
+	_entrancesByID = entrancesByID_;
 
-	scale = 0;
-	palette = 0;
-	skyColor = 255;
-	groundColor = 255;
-	gasPocketRadius = 0;
+	_scale = 0;
+	_palette = 0;
+	_skyColor = 255;
+	_groundColor = 255;
+	_gasPocketRadius = 0;
 
 	// create a list of drawable objects only
-	for (auto &it : *objectsByID) {
+	for (auto &it : *_objectsByID) {
 		if (it._value->isDrawable()) {
-			drawableObjects.push_back(it._value);
+			_drawableObjects.push_back(it._value);
 		}
 	}
 
@@ -88,33 +88,33 @@ Area::Area(uint16 _areaID, uint16 _areaFlags, ObjectMap *_objectsByID, ObjectMap
 		};
 	} compareObjects;
 
-	Common::sort(drawableObjects.begin(), drawableObjects.end(), compareObjects);
+	Common::sort(_drawableObjects.begin(), _drawableObjects.end(), compareObjects);
 }
 
 Area::~Area() {
-	if (entrancesByID) {
-		for (auto &it : *entrancesByID)
+	if (_entrancesByID) {
+		for (auto &it : *_entrancesByID)
 			delete it._value;
 	}
 
-	if (objectsByID) {
-		for (auto &it : *objectsByID)
+	if (_objectsByID) {
+		for (auto &it : *_objectsByID)
 			delete it._value;
 	}
 
-	delete entrancesByID;
-	delete objectsByID;
+	delete _entrancesByID;
+	delete _objectsByID;
 
-	for (auto &it : conditionSources)
+	for (auto &it : _conditionSources)
 		delete it;
 }
 
 void Area::show() {
-	debugC(1, kFreescapeDebugMove, "Area name: %s", name.c_str());
-	for (auto &it : *objectsByID)
+	debugC(1, kFreescapeDebugMove, "Area name: %s", _name.c_str());
+	for (auto &it : *_objectsByID)
 		debugC(1, kFreescapeDebugMove, "objID: %d, type: %d", it._value->getObjectID(), it._value->getType());
 
-	for (auto &it : *entrancesByID)
+	for (auto &it : *_entrancesByID)
 		debugC(1, kFreescapeDebugMove, "objID: %d, type: %d (entrance)", it._value->getObjectID(), it._value->getType());
 }
 
@@ -128,8 +128,8 @@ void Area::loadObjects(Common::SeekableReadStream *stream, Area *global) {
 		float y = stream->readFloatLE();
 		float z = stream->readFloatLE();
 		Object *obj = nullptr;
-		if (objectsByID->contains(key)) {
-			obj = (*objectsByID)[key];
+		if (_objectsByID->contains(key)) {
+			obj = (*_objectsByID)[key];
 		} else {
 			obj = global->objectWithID(key);
 			assert(obj);
@@ -142,9 +142,9 @@ void Area::loadObjects(Common::SeekableReadStream *stream, Area *global) {
 }
 
 void Area::saveObjects(Common::WriteStream *stream) {
-	stream->writeUint32LE(objectsByID->size());
+	stream->writeUint32LE(_objectsByID->size());
 
-	for (auto &it : *objectsByID) {
+	for (auto &it : *_objectsByID) {
 		Object *obj = it._value;
 		stream->writeUint32LE(it._key);
 		stream->writeUint32LE(obj->getObjectFlags());
@@ -156,8 +156,8 @@ void Area::saveObjects(Common::WriteStream *stream) {
 
 void Area::draw(Freescape::Renderer *gfx) {
 	gfx->clear();
-	assert(drawableObjects.size() > 0);
-	for (auto &obj : drawableObjects) {
+	assert(_drawableObjects.size() > 0);
+	for (auto &obj : _drawableObjects) {
 		if (!obj->isDestroyed() && !obj->isInvisible()) {
 			obj->draw(gfx);
 		}
@@ -167,7 +167,7 @@ void Area::draw(Freescape::Renderer *gfx) {
 Object *Area::shootRay(const Math::Ray &ray) {
 	float size = 16.0 * 8192.0; // TODO: check if this is max size
 	Object *collided = nullptr;
-	for (auto &obj : drawableObjects) {
+	for (auto &obj : _drawableObjects) {
 		float objSize = obj->getSize().length();
 		if (!obj->isDestroyed() && !obj->isInvisible() && obj->boundingBox.isValid() && ray.intersectAABB(obj->boundingBox) && size >= objSize) {
 			debugC(1, kFreescapeDebugMove, "shot obj id: %d", obj->getObjectID());
@@ -181,7 +181,7 @@ Object *Area::shootRay(const Math::Ray &ray) {
 Object *Area::checkCollisions(const Math::AABB &boundingBox) {
 	float size = 3.0 * 8192.0 * 8192.0; // TODO: check if this is max size
 	Object *collided = nullptr;
-	for (auto &obj : drawableObjects) {
+	for (auto &obj : _drawableObjects) {
 		if (!obj->isDestroyed() && !obj->isInvisible()) {
 			GeometricObject *gobj = (GeometricObject *)obj;
 			float objSize = gobj->getSize().length();
@@ -197,22 +197,22 @@ Object *Area::checkCollisions(const Math::AABB &boundingBox) {
 void Area::addObject(Object *obj) {
 	assert(obj);
 	int id = obj->getObjectID();
-	debugC(1, kFreescapeDebugParser, "Adding object %d to room %d", id, areaID);
-	assert(!objectsByID->contains(id));
-	(*objectsByID)[id] = obj;
+	debugC(1, kFreescapeDebugParser, "Adding object %d to room %d", id, _areaID);
+	assert(!_objectsByID->contains(id));
+	(*_objectsByID)[id] = obj;
 	if (obj->isDrawable())
-		drawableObjects.insert_at(0, obj);
+		_drawableObjects.insert_at(0, obj);
 }
 
 void Area::removeObject(int16 id) {
-	assert(objectsByID->contains(id));
-	for (uint i = 0; i < drawableObjects.size(); i++) {
-		if (drawableObjects[i]->getObjectID() == id) {
-			drawableObjects.remove_at(i);
+	assert(_objectsByID->contains(id));
+	for (uint i = 0; i < _drawableObjects.size(); i++) {
+		if (_drawableObjects[i]->getObjectID() == id) {
+			_drawableObjects.remove_at(i);
 			break;
 		}
 	}
-	objectsByID->erase(id);
+	_objectsByID->erase(id);
 }
 
 void Area::addObjectFromArea(int16 id, Area *global) {
@@ -220,21 +220,21 @@ void Area::addObjectFromArea(int16 id, Area *global) {
 	Object *obj = global->objectWithID(id);
 	if (!obj) {
 		assert(global->entranceWithID(id));
-		(*entrancesByID)[id] = global->entranceWithID(id);
+		(*_entrancesByID)[id] = global->entranceWithID(id);
 	} else {
-		(*objectsByID)[id] = global->objectWithID(id);
+		(*_objectsByID)[id] = global->objectWithID(id);
 		if (obj->isDrawable())
-			drawableObjects.insert_at(0, obj);
+			_drawableObjects.insert_at(0, obj);
 	}
 }
 
 void Area::addStructure(Area *global) {
 	Object *obj = nullptr;
-	if (!global || !entrancesByID->contains(255)) {
+	if (!global || !_entrancesByID->contains(255)) {
 		int id = 254;
 		Common::Array<uint8> *gColors = new Common::Array<uint8>;
 		for (int i = 0; i < 6; i++)
-			gColors->push_back(groundColor);
+			gColors->push_back(_groundColor);
 
 		obj = (Object *)new GeometricObject(
 			Object::Type::Cube,
@@ -245,11 +245,11 @@ void Area::addStructure(Area *global) {
 			gColors,
 			nullptr,
 			FCLInstructionVector());
-		(*objectsByID)[id] = obj;
-		drawableObjects.insert_at(0, obj);
+		(*_objectsByID)[id] = obj;
+		_drawableObjects.insert_at(0, obj);
 		return;
 	}
-	GlobalStructure *rs = (GlobalStructure *)(*entrancesByID)[255];
+	GlobalStructure *rs = (GlobalStructure *)(*_entrancesByID)[255];
 
 	for (int i = 0; i < int(rs->structure.size()); i++) {
 		int16 id = rs->structure[i];
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index ceead0e2ede..f47d701935c 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -39,7 +39,7 @@ public:
 	Area(uint16 areaID, uint16 areaFlags, ObjectMap *objectsByID, ObjectMap *entrancesByID);
 	virtual ~Area();
 
-	Common::String name;
+	Common::String _name;
 	Object *objectWithID(uint16 objectID);
 	Object *entranceWithID(uint16 objectID);
 	uint16 getAreaID();
@@ -55,28 +55,28 @@ public:
 	void addStructure(Area *global);
 	void removeObject(int16 id);
 
-	Common::Array<Common::String *> conditionSources;
-	Common::Array<FCLInstructionVector> conditions;
+	Common::Array<Common::String *> _conditionSources;
+	Common::Array<FCLInstructionVector> _conditions;
 
 	// Serialization
 	void saveObjects(Common::WriteStream *stream);
 	void loadObjects(Common::SeekableReadStream *stream, Area *global);
 
 	// Driller specific
-	Common::Point gasPocketPosition;
-	uint32 gasPocketRadius;
+	Common::Point _gasPocketPosition;
+	uint32 _gasPocketRadius;
 
-	uint8 scale;
-	Graphics::PixelBuffer *palette;
-	uint8 skyColor;
-	uint8 groundColor;
+	uint8 _scale;
+	Graphics::PixelBuffer *_palette;
+	uint8 _skyColor;
+	uint8 _groundColor;
 
 private:
-	uint16 areaID;
-	uint16 areaFlags;
-	ObjectMap *objectsByID;
-	ObjectMap *entrancesByID;
-	Common::Array<Object *> drawableObjects;
+	uint16 _areaID;
+	uint16 _areaFlags;
+	ObjectMap *_objectsByID;
+	ObjectMap *_entrancesByID;
+	Common::Array<Object *> _drawableObjects;
 	Object *objectWithIDFromMap(ObjectMap *map, uint16 objectID);
 };
 
diff --git a/engines/freescape/games/castle.cpp b/engines/freescape/games/castle.cpp
index 8cd4c14927d..da03f298b74 100644
--- a/engines/freescape/games/castle.cpp
+++ b/engines/freescape/games/castle.cpp
@@ -92,9 +92,9 @@ void CastleEngine::gotoArea(uint16 areaID, int entranceID) {
 	playSound(5, false);
 	_lastPosition = _position;
 
-	if (_currentArea->skyColor > 0 && _currentArea->skyColor != 255) {
+	if (_currentArea->_skyColor > 0 && _currentArea->_skyColor != 255) {
 		_gfx->_keyColor = 0;
-		_gfx->setSkyColor(_currentArea->skyColor);
+		_gfx->setSkyColor(_currentArea->_skyColor);
 	} else
 		_gfx->_keyColor = 255;
 }
diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index 8bc8b9a807d..d9223ecc2c3 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -71,7 +71,7 @@ void DarkEngine::gotoArea(uint16 areaID, int entranceID) {
 	_currentArea->show();
 
 	_currentAreaMessages.clear();
-	_currentAreaMessages.push_back(_currentArea->name);
+	_currentAreaMessages.push_back(_currentArea->_name);
 
 	int scale = _currentArea->getScale();
 	assert(scale > 0);
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index ff9ff81cc82..b240018ac34 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -60,12 +60,12 @@ void DrillerEngine::gotoArea(uint16 areaID, int entranceID) {
 
 	_currentAreaMessages.clear();
 	if (_messagesList.size() > 2) {
-		if (_currentArea->gasPocketRadius > 0)
+		if (_currentArea->_gasPocketRadius > 0)
 			_currentAreaMessages.push_back(_messagesList[1]);
 		else
 			_currentAreaMessages.push_back(_messagesList[2]);
 
-		_currentAreaMessages.push_back(_currentArea->name);
+		_currentAreaMessages.push_back(_currentArea->_name);
 	}
 
 	if (entranceID > 0 || areaID == 127) {
@@ -373,8 +373,8 @@ void DrillerEngine::drawUI() {
 
 void DrillerEngine::pressedKey(const int keycode) {
 	if (keycode == Common::KEYCODE_d) {
-		Common::Point gasPocket = _currentArea->gasPocketPosition;
-		uint32 gasPocketRadius = _currentArea->gasPocketRadius;
+		Common::Point gasPocket = _currentArea->_gasPocketPosition;
+		uint32 gasPocketRadius = _currentArea->_gasPocketRadius;
 		if (gasPocketRadius == 0)
 			return;
 
@@ -407,12 +407,12 @@ void DrillerEngine::pressedKey(const int keycode) {
 		const Math::Vector3d gasPocket3D(gasPocket.x, 1, gasPocket.y);
 		addDrill(drillPosition);
 		float distance = (gasPocket3D - drillPosition).length();
-		debugC(1, kFreescapeDebugMove, "length to gas pocket: %f with radius %d", distance, _currentArea->gasPocketRadius);
+		debugC(1, kFreescapeDebugMove, "length to gas pocket: %f with radius %d", distance, _currentArea->_gasPocketRadius);
 		// TODO: show the result of the drilling
 		_currentAreaMessages[0] = _messagesList[3];
 
 	} else if (keycode == Common::KEYCODE_c) {
-		uint32 gasPocketRadius = _currentArea->gasPocketRadius;
+		uint32 gasPocketRadius = _currentArea->_gasPocketRadius;
 		if (gasPocketRadius == 0)
 			return;
 
diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index 5a6e444ca0b..5c4e57c8954 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -135,7 +135,7 @@ void EclipseEngine::gotoArea(uint16 areaID, int entranceID) {
 	_currentArea->show();
 
 	_currentAreaMessages.clear();
-	_currentAreaMessages.push_back(_currentArea->name);
+	_currentAreaMessages.push_back(_currentArea->_name);
 
 	int scale = _currentArea->getScale();
 	assert(scale > 0);
@@ -160,9 +160,9 @@ void EclipseEngine::gotoArea(uint16 areaID, int entranceID) {
 
 	_lastPosition = _position;
 
-	if (_currentArea->skyColor > 0 && _currentArea->skyColor != 255) {
+	if (_currentArea->_skyColor > 0 && _currentArea->_skyColor != 255) {
 		_gfx->_keyColor = 0;
-		_gfx->setSkyColor(_currentArea->skyColor);
+		_gfx->setSkyColor(_currentArea->_skyColor);
 	} else
 		_gfx->_keyColor = 255;
 }
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index 4fc7fb1863f..d785865294e 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -78,9 +78,9 @@ void FreescapeEngine::executeLocalGlobalConditions(bool shot, bool collided) {
 	if (isCastle())
 		return;
 	debugC(1, kFreescapeDebugCode, "Executing room conditions");
-	for (int i = 0; i < int(_currentArea->conditions.size()); i++) {
-		debugC(1, kFreescapeDebugCode, "%s", _currentArea->conditionSources[i]->c_str());
-		executeCode(_currentArea->conditions[i], shot, collided);
+	for (int i = 0; i < int(_currentArea->_conditions.size()); i++) {
+		debugC(1, kFreescapeDebugCode, "%s", _currentArea->_conditionSources[i]->c_str());
+		executeCode(_currentArea->_conditions[i], shot, collided);
 	}
 
 	debugC(1, kFreescapeDebugCode, "Executing global conditions (%d)", _conditions.size());
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 163f26fbc0a..86b7ffcd5f9 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -366,14 +366,14 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	debugC(1, kFreescapeDebugParser, "%d area conditions at %x of area %d", numConditions, base + cPtr, areaNumber);
 
 	Area *area = new Area(areaNumber, areaFlags, objectsByID, entrancesByID);
-	area->name = name;
-	area->scale = scale;
-	area->skyColor = skyColor;
-	area->groundColor = groundColor;
+	area->_name = name;
+	area->_scale = scale;
+	area->_skyColor = skyColor;
+	area->_groundColor = groundColor;
 
 	// Driller specific
-	area->gasPocketPosition = Common::Point(32 * gasPocketX, 32 * gasPocketY);
-	area->gasPocketRadius = gasPocketRadius;
+	area->_gasPocketPosition = Common::Point(32 * gasPocketX, 32 * gasPocketY);
+	area->_gasPocketRadius = gasPocketRadius;
 
 	while (numConditions--) {
 		FCLInstructionVector instructions;
@@ -383,8 +383,8 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 		// get the condition
 		Common::Array<uint8> conditionArray = readArray(file, lengthOfCondition);
 		Common::String *conditionSource = detokenise8bitCondition(conditionArray, instructions);
-		area->conditions.push_back(instructions);
-		area->conditionSources.push_back(conditionSource);
+		area->_conditions.push_back(instructions);
+		area->_conditionSources.push_back(conditionSource);
 		debugC(1, kFreescapeDebugParser, "%s", conditionSource->c_str());
 	}
 


Commit: ae9f7d64d643502396a6e7085a055498913db1c0
    https://github.com/scummvm/scummvm/commit/ae9f7d64d643502396a6e7085a055498913db1c0
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:35+01:00

Commit Message:
FREESCAPE: renamed variable names from Instruction class to follow code conventions

Changed paths:
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/language/instruction.cpp
    engines/freescape/language/instruction.h


diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index d6ae2d6fe0b..c1836dfc47a 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -155,22 +155,22 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 		case 3:
 			detokenisedStream += "TOGVIS (";
 			currentInstruction = FCLInstruction(Token::TOGVIS);
-			currentInstruction.source = 0;
-			currentInstruction.destination = 0;
+			currentInstruction.setSource(0);
+			currentInstruction.setDestination(0);
 			break; // these all come in unary and binary versions,
 		case 7:
 		case 4:
 			detokenisedStream += "VIS (";
 			currentInstruction = FCLInstruction(Token::VIS);
-			currentInstruction.source = 0;
-			currentInstruction.destination = 0;
+			currentInstruction.setSource(0);
+			currentInstruction.setDestination(0);
 			break; // hence each getting two case statement entries
 		case 8:
 		case 5:
 			detokenisedStream += "INVIS (";
 			currentInstruction = FCLInstruction(Token::INVIS);
-			currentInstruction.source = 0;
-			currentInstruction.destination = 0;
+			currentInstruction.setSource(0);
+			currentInstruction.setDestination(0);
 			break;
 
 		case 9:
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index d785865294e..073914c6c37 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -26,44 +26,43 @@
 
 namespace Freescape {
 
-FCLInstruction::FCLInstruction(Token::Type _type) {
-	source = 0;
-	destination = 0;
-	additional = 0;
-	// TODO: learn modern constructor syntax
-	type = _type;
-	thenInstructions = nullptr;
-	elseInstructions = nullptr;
+FCLInstruction::FCLInstruction(Token::Type type_) {
+	_source = 0;
+	_destination = 0;
+	_additional = 0;
+	_type = type_;
+	_thenInstructions = nullptr;
+	_elseInstructions = nullptr;
 }
 
 FCLInstruction::FCLInstruction() {
-	source = 0;
-	destination = 0;
-	additional = 0;
-	type = Token::UNKNOWN;
-	thenInstructions = nullptr;
-	elseInstructions = nullptr;
+	_source = 0;
+	_destination = 0;
+	_additional = 0;
+	_type = Token::UNKNOWN;
+	_thenInstructions = nullptr;
+	_elseInstructions = nullptr;
 }
 
-void FCLInstruction::setSource(int32 _source) {
-	source = _source;
+void FCLInstruction::setSource(int32 source_) {
+	_source = source_;
 }
 
-void FCLInstruction::setAdditional(int32 _additional) {
-	additional = _additional;
+void FCLInstruction::setAdditional(int32 additional_) {
+	_additional = additional_;
 }
 
-void FCLInstruction::setDestination(int32 _destination) {
-	destination = _destination;
+void FCLInstruction::setDestination(int32 destination_) {
+	_destination = destination_;
 }
 
 void FCLInstruction::setBranches(FCLInstructionVector *thenBranch, FCLInstructionVector *elseBranch) {
-	thenInstructions = thenBranch;
-	elseInstructions = elseBranch;
+	_thenInstructions = thenBranch;
+	_elseInstructions = elseBranch;
 }
 
 Token::Type FCLInstruction::getType() {
-	return type;
+	return _type;
 }
 
 void FreescapeEngine::executeObjectConditions(GeometricObject *obj, bool shot, bool collided) {
@@ -102,15 +101,15 @@ void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool co
 			break;
 		case Token::COLLIDEDQ:
 			if (collided)
-				executeCode(*instruction.thenInstructions, shot, collided);
+				executeCode(*instruction._thenInstructions, shot, collided);
 			// else branch is always empty
-			assert(instruction.elseInstructions == nullptr);
+			assert(instruction._elseInstructions == nullptr);
 			break;
 		case Token::SHOTQ:
 			if (shot)
-				executeCode(*instruction.thenInstructions, shot, collided);
+				executeCode(*instruction._thenInstructions, shot, collided);
 			// else branch is always empty
-			assert(instruction.elseInstructions == nullptr);
+			assert(instruction._elseInstructions == nullptr);
 			break;
 		case Token::VARNOTEQ:
 			if (executeEndIfNotEqual(instruction))
@@ -181,29 +180,29 @@ void FreescapeEngine::executeRedraw(FCLInstruction &instruction) {
 }
 
 void FreescapeEngine::executeSound(FCLInstruction &instruction) {
-	uint16 index = instruction.source;
-	bool sync = instruction.additional;
+	uint16 index = instruction._source;
+	bool sync = instruction._additional;
 	debugC(1, kFreescapeDebugCode, "Playing sound %d", index);
 	playSound(index, sync);
 }
 
 void FreescapeEngine::executeDelay(FCLInstruction &instruction) {
-	uint16 delay = instruction.source;
+	uint16 delay = instruction._source;
 	debugC(1, kFreescapeDebugCode, "Delaying %d * 1/50 seconds", delay);
 	g_system->delayMillis(20 * delay);
 }
 
 void FreescapeEngine::executePrint(FCLInstruction &instruction) {
-	uint16 index = instruction.source - 1;
+	uint16 index = instruction._source - 1;
 	debugC(1, kFreescapeDebugCode, "Printing message %d", index);
 	_currentAreaMessages.clear();
 	_currentAreaMessages.push_back(_messagesList[index]);
 }
 
 bool FreescapeEngine::executeEndIfVisibilityIsEqual(FCLInstruction &instruction) {
-	uint16 source = instruction.source;
-	uint16 additional = instruction.additional;
-	uint16 value = instruction.destination;
+	uint16 source = instruction._source;
+	uint16 additional = instruction._additional;
+	uint16 value = instruction._destination;
 
 	Object *obj = nullptr;
 	if (additional == 0) {
@@ -221,15 +220,15 @@ bool FreescapeEngine::executeEndIfVisibilityIsEqual(FCLInstruction &instruction)
 }
 
 bool FreescapeEngine::executeEndIfNotEqual(FCLInstruction &instruction) {
-	uint16 variable = instruction.source;
-	uint16 value = instruction.destination;
+	uint16 variable = instruction._source;
+	uint16 value = instruction._destination;
 	debugC(1, kFreescapeDebugCode, "End condition if variable %d is not equal to %d!", variable, value);
 	return (_gameStateVars[variable] != value);
 }
 
 void FreescapeEngine::executeIncrementVariable(FCLInstruction &instruction) {
-	int32 variable = instruction.source;
-	int32 increment = instruction.destination;
+	int32 variable = instruction._source;
+	int32 increment = instruction._destination;
 	_gameStateVars[variable] = _gameStateVars[variable] + increment;
 	switch (variable) {
 	case k8bitVariableScore:
@@ -257,8 +256,8 @@ void FreescapeEngine::executeIncrementVariable(FCLInstruction &instruction) {
 }
 
 void FreescapeEngine::executeDecrementVariable(FCLInstruction &instruction) {
-	uint16 variable = instruction.source;
-	uint16 decrement = instruction.destination;
+	uint16 variable = instruction._source;
+	uint16 decrement = instruction._destination;
 	_gameStateVars[variable] = _gameStateVars[variable] - decrement;
 	if (variable == k8bitVariableEnergy) {
 		debugC(1, kFreescapeDebugCode, "Energy decrement by %d up to %d", decrement, _gameStateVars[variable]);
@@ -270,11 +269,11 @@ void FreescapeEngine::executeDestroy(FCLInstruction &instruction) {
 	uint16 objectID = 0;
 	uint16 areaID = _currentArea->getAreaID();
 
-	if (instruction.destination > 0) {
-		objectID = instruction.destination;
-		areaID = instruction.source;
+	if (instruction._destination > 0) {
+		objectID = instruction._destination;
+		areaID = instruction._source;
 	} else {
-		objectID = instruction.source;
+		objectID = instruction._source;
 	}
 
 	debugC(1, kFreescapeDebugCode, "Destroying obj %d in area %d!", objectID, areaID);
@@ -290,11 +289,11 @@ void FreescapeEngine::executeMakeInvisible(FCLInstruction &instruction) {
 	uint16 objectID = 0;
 	uint16 areaID = _currentArea->getAreaID();
 
-	if (instruction.destination > 0) {
-		objectID = instruction.destination;
-		areaID = instruction.source;
+	if (instruction._destination > 0) {
+		objectID = instruction._destination;
+		areaID = instruction._source;
 	} else {
-		objectID = instruction.source;
+		objectID = instruction._source;
 	}
 
 	debugC(1, kFreescapeDebugCode, "Making obj %d invisible in area %d!", objectID, areaID);
@@ -306,11 +305,11 @@ void FreescapeEngine::executeMakeVisible(FCLInstruction &instruction) {
 	uint16 objectID = 0;
 	uint16 areaID = _currentArea->getAreaID();
 
-	if (instruction.destination > 0) {
-		objectID = instruction.destination;
-		areaID = instruction.source;
+	if (instruction._destination > 0) {
+		objectID = instruction._destination;
+		areaID = instruction._source;
 	} else {
-		objectID = instruction.source;
+		objectID = instruction._source;
 	}
 
 	debugC(1, kFreescapeDebugCode, "Making obj %d visible in area %d!", objectID, areaID);
@@ -322,11 +321,11 @@ void FreescapeEngine::executeToggleVisibility(FCLInstruction &instruction) {
 	uint16 objectID = 0;
 	uint16 areaID = _currentArea->getAreaID();
 
-	if (instruction.destination > 0) {
-		objectID = instruction.destination;
-		areaID = instruction.source;
+	if (instruction._destination > 0) {
+		objectID = instruction._destination;
+		areaID = instruction._source;
 	} else {
-		objectID = instruction.source;
+		objectID = instruction._source;
 	}
 
 	debugC(1, kFreescapeDebugCode, "Toggling obj %d visibility in area %d!", objectID, areaID);
@@ -348,13 +347,13 @@ void FreescapeEngine::executeToggleVisibility(FCLInstruction &instruction) {
 }
 
 void FreescapeEngine::executeGoto(FCLInstruction &instruction) {
-	uint16 areaID = instruction.source;
-	uint16 entranceID = instruction.destination;
+	uint16 areaID = instruction._source;
+	uint16 entranceID = instruction._destination;
 	gotoArea(areaID, entranceID);
 }
 
 void FreescapeEngine::executeSetBit(FCLInstruction &instruction) {
-	uint16 index = instruction.source - 1; // Starts in 1
+	uint16 index = instruction._source - 1; // Starts in 1
 	assert(index < 32);
 	_gameStateBits[_currentArea->getAreaID()] |= (1 << index);
 	debugC(1, kFreescapeDebugCode, "Setting bit %d", index);
@@ -362,21 +361,21 @@ void FreescapeEngine::executeSetBit(FCLInstruction &instruction) {
 }
 
 void FreescapeEngine::executeClearBit(FCLInstruction &instruction) {
-	uint16 index = instruction.source - 1; // Starts in 1
+	uint16 index = instruction._source - 1; // Starts in 1
 	assert(index < 32);
 	_gameStateBits[_currentArea->getAreaID()] &= ~(1 << index);
 	debugC(1, kFreescapeDebugCode, "Clearing bit %d", index);
 }
 
 void FreescapeEngine::executeToggleBit(FCLInstruction &instruction) {
-	uint16 index = instruction.source - 1; // Starts in 1
+	uint16 index = instruction._source - 1; // Starts in 1
 	_gameStateBits[_currentArea->getAreaID()] ^= (1 << index);
 	debugC(1, kFreescapeDebugCode, "Toggling bit %d", index);
 }
 
 bool FreescapeEngine::executeEndIfBitNotEqual(FCLInstruction &instruction) {
-	uint16 index = instruction.source - 1; // Starts in 1
-	uint16 value = instruction.destination;
+	uint16 index = instruction._source - 1; // Starts in 1
+	uint16 value = instruction._destination;
 	assert(index < 32);
 	debugC(1, kFreescapeDebugCode, "End condition if bit %d is not equal to %d!", index, value);
 	return (((_gameStateBits[_currentArea->getAreaID()] >> index) & 1) != value);
diff --git a/engines/freescape/language/instruction.h b/engines/freescape/language/instruction.h
index fca7c88bb89..e3ca2b89d58 100644
--- a/engines/freescape/language/instruction.h
+++ b/engines/freescape/language/instruction.h
@@ -36,22 +36,22 @@ class FCLInstruction {
 public:
 	FCLInstruction();
 	FCLInstruction(Token::Type type);
-	void setSource(int32 _source);
-	void setAdditional(int32 _additional);
-	void setDestination(int32 _destination);
+	void setSource(int32 source);
+	void setAdditional(int32 additional);
+	void setDestination(int32 destination);
 
 	Token::Type getType();
 	void setBranches(FCLInstructionVector *thenBranch, FCLInstructionVector *elseBranch);
 
-	int32 source;
-	int32 additional;
-	int32 destination;
+	int32 _source;
+	int32 _additional;
+	int32 _destination;
 
-	FCLInstructionVector *thenInstructions;
-	FCLInstructionVector *elseInstructions;
+	FCLInstructionVector *_thenInstructions;
+	FCLInstructionVector *_elseInstructions;
 
 private:
-	enum Token::Type type;
+	enum Token::Type _type;
 };
 
 } // End of namespace Freescape


Commit: da4ac7f45637587c649733febb2b95afca689eaa
    https://github.com/scummvm/scummvm/commit/da4ac7f45637587c649733febb2b95afca689eaa
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:35+01:00

Commit Message:
FREESCAPE: use uint for loop variables and avoid type conversion

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/freescape.cpp
    engines/freescape/games/palettes.cpp
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/language/instruction.cpp
    engines/freescape/objects/geometricobject.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index afccde86ca0..f1ae56e899d 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -251,7 +251,7 @@ void Area::addStructure(Area *global) {
 	}
 	GlobalStructure *rs = (GlobalStructure *)(*_entrancesByID)[255];
 
-	for (int i = 0; i < int(rs->structure.size()); i++) {
+	for (uint i = 0; i < rs->structure.size(); i++) {
 		int16 id = rs->structure[i];
 		if (id == 0)
 			continue;
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 21dbfcbace3..8c1ed8fc149 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -519,17 +519,17 @@ Common::Error FreescapeEngine::loadGameStream(Common::SeekableReadStream *stream
 	_pitch = stream->readFloatLE();
 
 	// Level state
-	for (int i = 0; i < int(_gameStateVars.size()); i++) {
+	for (uint i = 0; i < _gameStateVars.size(); i++) {
 		uint16 key = stream->readUint16LE();
 		_gameStateVars[key] = stream->readUint32LE();
 	}
 
-	for (int i = 0; i < int(_gameStateBits.size()); i++) {
+	for (uint i = 0; i < _gameStateBits.size(); i++) {
 		uint16 key = stream->readUint16LE();
 		_gameStateBits[key] = stream->readUint32LE();
 	}
 
-	for (int i = 0; i < int(_areaMap.size()); i++) {
+	for (uint i = 0; i < _areaMap.size(); i++) {
 		uint16 key = stream->readUint16LE();
 		assert(_areaMap.contains(key));
 		Area *area = _areaMap[key];
diff --git a/engines/freescape/games/palettes.cpp b/engines/freescape/games/palettes.cpp
index f718b1975bf..68d93ed41ab 100644
--- a/engines/freescape/games/palettes.cpp
+++ b/engines/freescape/games/palettes.cpp
@@ -66,7 +66,7 @@ void FreescapeEngine::loadColorPalette() {
 void FreescapeEngine::loadPalettes(Common::SeekableReadStream *file, int offset) {
 	file->seek(offset);
 	int r, g, b;
-	for (int i = 0; i < int(_areaMap.size()); i++) {
+	for (uint i = 0; i < _areaMap.size(); i++) {
 		int label = readField(file, 8);
 		auto palette = new byte[16][3];
 		debugC(1, kFreescapeDebugParser, "Loading palette for area: %d", label);
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 30e2c7bc6de..26831a051b2 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -217,7 +217,7 @@ void TinyGLRenderer::renderFace(const Common::Array<Math::Vector3d> &vertices) {
 	}
 
 	tglBegin(TGL_TRIANGLES);
-	for (int i = 1; i < int(vertices.size()) - 1; i++) {
+	for (uint i = 1; i < vertices.size() - 1; i++) { // no underflow since vertices.size() > 2
 		const Math::Vector3d &v1 = vertices[i];
 		const Math::Vector3d &v2 = vertices[i + 1];
 		tglVertex3f(v0.x(), v0.y(), v0.z());
@@ -239,7 +239,7 @@ void TinyGLRenderer::renderPolygon(const Math::Vector3d &origin, const Math::Vec
 	if (ordinates->size() == 6) {                 // Line
 		assert(getRGBAt((*colours)[0], r, g, b)); // It will never return false?
 		tglColor3ub(r, g, b);
-		for (int i = 0; i < int(ordinates->size()); i = i + 3)
+		for (uint i = 0; i < ordinates->size(); i = i + 3)
 			vertices.push_back(Math::Vector3d((*ordinates)[i], (*ordinates)[i + 1], (*ordinates)[i + 2]));
 		renderFace(vertices);
 
@@ -253,7 +253,7 @@ void TinyGLRenderer::renderPolygon(const Math::Vector3d &origin, const Math::Vec
 	} else {
 		if (getRGBAt((*colours)[0], r, g, b)) {
 			tglColor3ub(r, g, b);
-			for (int i = 0; i < int(ordinates->size()); i = i + 3) {
+			for (uint i = 0; i < ordinates->size(); i = i + 3) {
 				vertices.push_back(Math::Vector3d((*ordinates)[i], (*ordinates)[i + 1], (*ordinates)[i + 2]));
 			}
 			renderFace(vertices);
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index 073914c6c37..136bde3ce55 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -77,13 +77,13 @@ void FreescapeEngine::executeLocalGlobalConditions(bool shot, bool collided) {
 	if (isCastle())
 		return;
 	debugC(1, kFreescapeDebugCode, "Executing room conditions");
-	for (int i = 0; i < int(_currentArea->_conditions.size()); i++) {
+	for (uint i = 0; i < _currentArea->_conditions.size(); i++) {
 		debugC(1, kFreescapeDebugCode, "%s", _currentArea->_conditionSources[i]->c_str());
 		executeCode(_currentArea->_conditions[i], shot, collided);
 	}
 
 	debugC(1, kFreescapeDebugCode, "Executing global conditions (%d)", _conditions.size());
-	for (int i = 0; i < int(_conditions.size()); i++) {
+	for (uint i = 0; i < _conditions.size(); i++) {
 		debugC(1, kFreescapeDebugCode, "%s", _conditionSources[i]->c_str());
 		executeCode(_conditions[i], shot, collided);
 	}
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index 2f9ad05245f..b2a7f5a8ebb 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -207,7 +207,7 @@ void GeometricObject::computeBoundingBox() {
 		boundingBox.expand(origin + size);
 		break;
 	case Line:
-		for (int i = 0; i < int(ordinates->size()); i = i + 3) {
+		for (uint i = 0; i < ordinates->size(); i = i + 3) {
 			boundingBox.expand(Math::Vector3d((*ordinates)[i], (*ordinates)[i + 1], (*ordinates)[i + 2]));
 		}
 		int dx, dy, dz;
@@ -223,7 +223,7 @@ void GeometricObject::computeBoundingBox() {
 			dz = 2;
 		}
 
-		for (int i = 0; i < int(ordinates->size()); i = i + 3) {
+		for (uint i = 0; i < ordinates->size(); i = i + 3) {
 			boundingBox.expand(Math::Vector3d((*ordinates)[i] + dx, (*ordinates)[i + 1] + dy, (*ordinates)[i + 2] + dz));
 		}
 
@@ -232,7 +232,7 @@ void GeometricObject::computeBoundingBox() {
 	case Quadrilateral:
 	case Pentagon:
 	case Hexagon:
-		for (int i = 0; i < int(ordinates->size()); i = i + 3) {
+		for (uint i = 0; i < ordinates->size(); i = i + 3) {
 			boundingBox.expand(Math::Vector3d((*ordinates)[i], (*ordinates)[i + 1], (*ordinates)[i + 2]));
 		}
 		break;


Commit: aba5bac2edd7891292d8d6efcc1aacfe5e90eb17
    https://github.com/scummvm/scummvm/commit/aba5bac2edd7891292d8d6efcc1aacfe5e90eb17
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:35+01:00

Commit Message:
FREESCAPE: renamed variable names from Object classes to follow code conventions

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/language/instruction.cpp
    engines/freescape/movement.cpp
    engines/freescape/objects/entrance.cpp
    engines/freescape/objects/entrance.h
    engines/freescape/objects/geometricobject.cpp
    engines/freescape/objects/geometricobject.h
    engines/freescape/objects/global.cpp
    engines/freescape/objects/global.h
    engines/freescape/objects/object.cpp
    engines/freescape/objects/object.h
    engines/freescape/objects/sensor.cpp
    engines/freescape/objects/sensor.h


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index f1ae56e899d..4377269b41f 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -169,7 +169,7 @@ Object *Area::shootRay(const Math::Ray &ray) {
 	Object *collided = nullptr;
 	for (auto &obj : _drawableObjects) {
 		float objSize = obj->getSize().length();
-		if (!obj->isDestroyed() && !obj->isInvisible() && obj->boundingBox.isValid() && ray.intersectAABB(obj->boundingBox) && size >= objSize) {
+		if (!obj->isDestroyed() && !obj->isInvisible() && obj->_boundingBox.isValid() && ray.intersectAABB(obj->_boundingBox) && size >= objSize) {
 			debugC(1, kFreescapeDebugMove, "shot obj id: %d", obj->getObjectID());
 			collided = obj;
 			size = objSize;
@@ -251,8 +251,8 @@ void Area::addStructure(Area *global) {
 	}
 	GlobalStructure *rs = (GlobalStructure *)(*_entrancesByID)[255];
 
-	for (uint i = 0; i < rs->structure.size(); i++) {
-		int16 id = rs->structure[i];
+	for (uint i = 0; i < rs->_structure.size(); i++) {
+		int16 id = rs->_structure[i];
 		if (id == 0)
 			continue;
 
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index 136bde3ce55..48aa8b1f4c9 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -67,9 +67,9 @@ Token::Type FCLInstruction::getType() {
 
 void FreescapeEngine::executeObjectConditions(GeometricObject *obj, bool shot, bool collided) {
 	assert(obj != nullptr);
-	if (obj->conditionSource != nullptr) {
-		debugC(1, kFreescapeDebugCode, "Executing with collision flag: %s", obj->conditionSource->c_str());
-		executeCode(obj->condition, shot, collided);
+	if (obj->_conditionSource != nullptr) {
+		debugC(1, kFreescapeDebugCode, "Executing with collision flag: %s", obj->_conditionSource->c_str());
+		executeCode(obj->_condition, shot, collided);
 	}
 }
 
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index 4ad4bb39db8..addc46bbd32 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -63,8 +63,8 @@ void FreescapeEngine::shoot() {
 		GeometricObject *gobj = (GeometricObject *)shot;
 		debugC(1, kFreescapeDebugMove, "Shot object %d with flags %x", gobj->getObjectID(), gobj->getObjectFlags());
 
-		if (gobj->conditionSource != nullptr)
-			debugC(1, kFreescapeDebugMove, "Must use shot = true when executing: %s", gobj->conditionSource->c_str());
+		if (gobj->_conditionSource != nullptr)
+			debugC(1, kFreescapeDebugMove, "Must use shot = true when executing: %s", gobj->_conditionSource->c_str());
 
 		executeObjectConditions(gobj, true, false);
 	}
diff --git a/engines/freescape/objects/entrance.cpp b/engines/freescape/objects/entrance.cpp
index fe4f9d9302b..f3879cd4ed8 100644
--- a/engines/freescape/objects/entrance.cpp
+++ b/engines/freescape/objects/entrance.cpp
@@ -26,13 +26,13 @@
 namespace Freescape {
 
 Entrance::Entrance(
-	uint16 _objectID,
-	const Math::Vector3d &_origin,
-	const Math::Vector3d &_rotation) {
-	objectID = _objectID;
-	origin = _origin;
-	rotation = _rotation;
-	flags = 0;
+	uint16 objectID_,
+	const Math::Vector3d &origin_,
+	const Math::Vector3d &rotation_) {
+	_objectID = objectID_;
+	_origin = origin_;
+	_rotation = rotation_;
+	_flags = 0;
 }
 
 Entrance::~Entrance() {}
diff --git a/engines/freescape/objects/entrance.h b/engines/freescape/objects/entrance.h
index 80ae7212926..1d7001ecd0a 100644
--- a/engines/freescape/objects/entrance.h
+++ b/engines/freescape/objects/entrance.h
@@ -39,7 +39,7 @@ public:
 	bool isDrawable() override;
 	bool isPlanar() override;
 	Type getType() override { return Type::Entrance; };
-	Math::Vector3d getRotation() { return rotation; }
+	Math::Vector3d getRotation() { return _rotation; }
 
 	void draw(Freescape::Renderer *gfx) override { error("cannot render Entrance"); };
 };
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index b2a7f5a8ebb..bbf8b100c0a 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -110,121 +110,121 @@ bool GeometricObject::isPolygon(Type type) {
 }
 
 GeometricObject::GeometricObject(
-	Type _type,
-	uint16 _objectID,
-	uint16 _flags,
-	const Math::Vector3d &_origin,
-	const Math::Vector3d &_size,
-	Common::Array<uint8> *_colours,
-	Common::Array<uint16> *_ordinates,
-	FCLInstructionVector _conditionInstructions,
-	Common::String *_conditionSource) {
-	type = _type;
-	flags = _flags;
+	Type type_,
+	uint16 objectID_,
+	uint16 flags_,
+	const Math::Vector3d &origin_,
+	const Math::Vector3d &size_,
+	Common::Array<uint8> *colours_,
+	Common::Array<uint16> *ordinates_,
+	FCLInstructionVector conditionInstructions_,
+	Common::String *conditionSource_) {
+	_type = type_;
+	_flags = flags_;
 
 	if (isDestroyed()) // If the object is destroyed, restore it
-		flags = flags & ~0x20;
+		_flags = _flags & ~0x20;
 
-	objectID = _objectID;
-	origin = _origin;
-	size = _size;
+	_objectID = objectID_;
+	_origin = origin_;
+	_size = size_;
 
-	colours = nullptr;
+	_colours = nullptr;
 
-	if (_colours)
-		colours = _colours;
+	if (colours_)
+		_colours = colours_;
 
-	ordinates = nullptr;
+	_ordinates = nullptr;
 
-	if (_ordinates)
-		ordinates = _ordinates;
-	condition = _conditionInstructions;
-	conditionSource = _conditionSource;
+	if (ordinates_)
+		_ordinates = ordinates_;
+	_condition = conditionInstructions_;
+	_conditionSource = conditionSource_;
 
-	if (type == Type::Rectangle) {
-		if ((size.x() == 0 && size.y() == 0) ||
-			(size.y() == 0 && size.z() == 0) ||
-			(size.x() == 0 && size.z() == 0)) {
+	if (_type == Type::Rectangle) {
+		if ((_size.x() == 0 && _size.y() == 0) ||
+			(_size.y() == 0 && _size.z() == 0) ||
+			(_size.x() == 0 && _size.z() == 0)) {
 
-			type = Type::Line;
-			assert(!ordinates);
-			ordinates = new Common::Array<uint16>();
-			ordinates->push_back(origin.x());
-			ordinates->push_back(origin.y());
-			ordinates->push_back(origin.z());
+			_type = Type::Line;
+			assert(!_ordinates);
+			_ordinates = new Common::Array<uint16>();
+			_ordinates->push_back(_origin.x());
+			_ordinates->push_back(_origin.y());
+			_ordinates->push_back(_origin.z());
 
-			ordinates->push_back(origin.x() + size.x());
-			ordinates->push_back(origin.y() + size.y());
-			ordinates->push_back(origin.z() + size.z());
+			_ordinates->push_back(_origin.x() + _size.x());
+			_ordinates->push_back(_origin.y() + _size.y());
+			_ordinates->push_back(_origin.z() + _size.z());
 		}
 	}
 
 	computeBoundingBox();
 }
 
-void GeometricObject::setOrigin(Math::Vector3d _origin) {
-	origin = _origin;
+void GeometricObject::setOrigin(Math::Vector3d origin_) {
+	_origin = origin_;
 	computeBoundingBox();
 };
 
 GeometricObject *GeometricObject::duplicate() {
 	return new GeometricObject(
-		type,
-		objectID,
-		flags,
-		origin,
-		size,
-		colours,
-		ordinates,
-		condition,
-		conditionSource);
+		_type,
+		_objectID,
+		_flags,
+		_origin,
+		_size,
+		_colours,
+		_ordinates,
+		_condition,
+		_conditionSource);
 }
 
 void GeometricObject::computeBoundingBox() {
-	boundingBox = Math::AABB();
+	_boundingBox = Math::AABB();
 	Math::Vector3d v;
-	switch (type) {
+	switch (_type) {
 	default:
 		break;
 	case Cube:
-		boundingBox.expand(origin);
+		_boundingBox.expand(_origin);
 		for (int i = 0; i < 3; i++) {
-			v = origin;
-			v.setValue(i, v.getValue(i) + size.getValue(i));
-			boundingBox.expand(v);
+			v = _origin;
+			v.setValue(i, v.getValue(i) + _size.getValue(i));
+			_boundingBox.expand(v);
 		}
 
 		for (int i = 0; i < 3; i++) {
-			v = origin + size;
-			v.setValue(i, v.getValue(i) - size.getValue(i));
-			boundingBox.expand(v);
+			v = _origin + _size;
+			v.setValue(i, v.getValue(i) - _size.getValue(i));
+			_boundingBox.expand(v);
 		}
-		boundingBox.expand(origin + size);
-		assert(boundingBox.isValid());
+		_boundingBox.expand(_origin + _size);
+		assert(_boundingBox.isValid());
 		break;
 	case Rectangle:
-		boundingBox.expand(origin);
-		boundingBox.expand(origin + size);
+		_boundingBox.expand(_origin);
+		_boundingBox.expand(_origin + _size);
 		break;
 	case Line:
-		for (uint i = 0; i < ordinates->size(); i = i + 3) {
-			boundingBox.expand(Math::Vector3d((*ordinates)[i], (*ordinates)[i + 1], (*ordinates)[i + 2]));
+		for (uint i = 0; i < _ordinates->size(); i = i + 3) {
+			_boundingBox.expand(Math::Vector3d((*_ordinates)[i], (*_ordinates)[i + 1], (*_ordinates)[i + 2]));
 		}
 		int dx, dy, dz;
 		dx = dy = dz = 0;
-		if (size.x() == 0 && size.y() == 0) {
+		if (_size.x() == 0 && _size.y() == 0) {
 			dx = 2;
 			dy = 2;
-		} else if (size.x() == 0 && size.z() == 0) {
+		} else if (_size.x() == 0 && _size.z() == 0) {
 			dx = 2;
 			dz = 2;
-		} else if (size.y() == 0 && size.z() == 0) {
+		} else if (_size.y() == 0 && _size.z() == 0) {
 			dy = 2;
 			dz = 2;
 		}
 
-		for (uint i = 0; i < ordinates->size(); i = i + 3) {
-			boundingBox.expand(Math::Vector3d((*ordinates)[i] + dx, (*ordinates)[i + 1] + dy, (*ordinates)[i + 2] + dz));
+		for (uint i = 0; i < _ordinates->size(); i = i + 3) {
+			_boundingBox.expand(Math::Vector3d((*_ordinates)[i] + dx, (*_ordinates)[i + 1] + dy, (*_ordinates)[i + 2] + dz));
 		}
 
 		break;
@@ -232,113 +232,113 @@ void GeometricObject::computeBoundingBox() {
 	case Quadrilateral:
 	case Pentagon:
 	case Hexagon:
-		for (uint i = 0; i < ordinates->size(); i = i + 3) {
-			boundingBox.expand(Math::Vector3d((*ordinates)[i], (*ordinates)[i + 1], (*ordinates)[i + 2]));
+		for (uint i = 0; i < _ordinates->size(); i = i + 3) {
+			_boundingBox.expand(Math::Vector3d((*_ordinates)[i], (*_ordinates)[i + 1], (*_ordinates)[i + 2]));
 		}
 		break;
 
 	case EastPyramid:
-		boundingBox.expand(origin + Math::Vector3d(0, 0, size.z()));
-		boundingBox.expand(origin + Math::Vector3d(0, size.y(), size.z()));
-		boundingBox.expand(origin + Math::Vector3d(0, size.y(), 0));
-
-		boundingBox.expand(origin + Math::Vector3d(size.x(), (*ordinates)[0], (*ordinates)[3]));
-		boundingBox.expand(origin + Math::Vector3d(size.x(), (*ordinates)[2], (*ordinates)[3]));
-		boundingBox.expand(origin + Math::Vector3d(size.x(), (*ordinates)[2], (*ordinates)[1]));
-		boundingBox.expand(origin + Math::Vector3d(size.x(), (*ordinates)[0], (*ordinates)[1]));
+		_boundingBox.expand(_origin + Math::Vector3d(0, 0, _size.z()));
+		_boundingBox.expand(_origin + Math::Vector3d(0, _size.y(), _size.z()));
+		_boundingBox.expand(_origin + Math::Vector3d(0, _size.y(), 0));
+
+		_boundingBox.expand(_origin + Math::Vector3d(_size.x(), (*_ordinates)[0], (*_ordinates)[3]));
+		_boundingBox.expand(_origin + Math::Vector3d(_size.x(), (*_ordinates)[2], (*_ordinates)[3]));
+		_boundingBox.expand(_origin + Math::Vector3d(_size.x(), (*_ordinates)[2], (*_ordinates)[1]));
+		_boundingBox.expand(_origin + Math::Vector3d(_size.x(), (*_ordinates)[0], (*_ordinates)[1]));
 		break;
 	case WestPyramid:
-		boundingBox.expand(origin + Math::Vector3d(size.x(), 0, 0));
-		boundingBox.expand(origin + Math::Vector3d(size.x(), size.y(), 0));
-		boundingBox.expand(origin + Math::Vector3d(size.x(), size.y(), size.z()));
-		boundingBox.expand(origin + Math::Vector3d(size.x(), 0, size.z()));
-
-		boundingBox.expand(origin + Math::Vector3d(0, (*ordinates)[0], (*ordinates)[1]));
-		boundingBox.expand(origin + Math::Vector3d(0, (*ordinates)[2], (*ordinates)[1]));
-		boundingBox.expand(origin + Math::Vector3d(0, (*ordinates)[2], (*ordinates)[3]));
-		boundingBox.expand(origin + Math::Vector3d(0, (*ordinates)[0], (*ordinates)[3]));
+		_boundingBox.expand(_origin + Math::Vector3d(_size.x(), 0, 0));
+		_boundingBox.expand(_origin + Math::Vector3d(_size.x(), _size.y(), 0));
+		_boundingBox.expand(_origin + Math::Vector3d(_size.x(), _size.y(), _size.z()));
+		_boundingBox.expand(_origin + Math::Vector3d(_size.x(), 0, _size.z()));
+
+		_boundingBox.expand(_origin + Math::Vector3d(0, (*_ordinates)[0], (*_ordinates)[1]));
+		_boundingBox.expand(_origin + Math::Vector3d(0, (*_ordinates)[2], (*_ordinates)[1]));
+		_boundingBox.expand(_origin + Math::Vector3d(0, (*_ordinates)[2], (*_ordinates)[3]));
+		_boundingBox.expand(_origin + Math::Vector3d(0, (*_ordinates)[0], (*_ordinates)[3]));
 		break;
 	case UpPyramid:
-		boundingBox.expand(origin + Math::Vector3d(size.x(), 0, 0));
-		boundingBox.expand(origin + Math::Vector3d(size.x(), 0, size.z()));
-		boundingBox.expand(origin + Math::Vector3d(0, 0, size.z()));
-
-		boundingBox.expand(origin + Math::Vector3d((*ordinates)[0], size.y(), (*ordinates)[1]));
-		boundingBox.expand(origin + Math::Vector3d((*ordinates)[2], size.y(), (*ordinates)[1]));
-		boundingBox.expand(origin + Math::Vector3d((*ordinates)[2], size.y(), (*ordinates)[3]));
-		boundingBox.expand(origin + Math::Vector3d((*ordinates)[0], size.y(), (*ordinates)[3]));
+		_boundingBox.expand(_origin + Math::Vector3d(_size.x(), 0, 0));
+		_boundingBox.expand(_origin + Math::Vector3d(_size.x(), 0, _size.z()));
+		_boundingBox.expand(_origin + Math::Vector3d(0, 0, _size.z()));
+
+		_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[0], _size.y(), (*_ordinates)[1]));
+		_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[2], _size.y(), (*_ordinates)[1]));
+		_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[2], _size.y(), (*_ordinates)[3]));
+		_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[0], _size.y(), (*_ordinates)[3]));
 		break;
 	case DownPyramid:
-		boundingBox.expand(origin + Math::Vector3d(size.x(), size.y(), 0));
-		boundingBox.expand(origin + Math::Vector3d(0, size.y(), 0));
-		boundingBox.expand(origin + Math::Vector3d(0, size.y(), size.z()));
-		boundingBox.expand(origin + Math::Vector3d(size.x(), size.y(), size.z()));
-
-		boundingBox.expand(origin + Math::Vector3d((*ordinates)[2], 0, (*ordinates)[1]));
-		boundingBox.expand(origin + Math::Vector3d((*ordinates)[0], 0, (*ordinates)[1]));
-		boundingBox.expand(origin + Math::Vector3d((*ordinates)[0], 0, (*ordinates)[3]));
-		boundingBox.expand(origin + Math::Vector3d((*ordinates)[2], 0, (*ordinates)[3]));
+		_boundingBox.expand(_origin + Math::Vector3d(_size.x(), _size.y(), 0));
+		_boundingBox.expand(_origin + Math::Vector3d(0, _size.y(), 0));
+		_boundingBox.expand(_origin + Math::Vector3d(0, _size.y(), _size.z()));
+		_boundingBox.expand(_origin + Math::Vector3d(_size.x(), _size.y(), _size.z()));
+
+		_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[2], 0, (*_ordinates)[1]));
+		_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[0], 0, (*_ordinates)[1]));
+		_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[0], 0, (*_ordinates)[3]));
+		_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[2], 0, (*_ordinates)[3]));
 		break;
 	case NorthPyramid:
-		boundingBox.expand(origin + Math::Vector3d(0, size.y(), 0));
-		boundingBox.expand(origin + Math::Vector3d(size.x(), size.y(), 0));
-		boundingBox.expand(origin + Math::Vector3d(size.x(), 0, 0));
-
-		boundingBox.expand(origin + Math::Vector3d((*ordinates)[0], (*ordinates)[3], size.z()));
-		boundingBox.expand(origin + Math::Vector3d((*ordinates)[2], (*ordinates)[3], size.z()));
-		boundingBox.expand(origin + Math::Vector3d((*ordinates)[2], (*ordinates)[1], size.z()));
-		boundingBox.expand(origin + Math::Vector3d((*ordinates)[0], (*ordinates)[1], size.z()));
+		_boundingBox.expand(_origin + Math::Vector3d(0, _size.y(), 0));
+		_boundingBox.expand(_origin + Math::Vector3d(_size.x(), _size.y(), 0));
+		_boundingBox.expand(_origin + Math::Vector3d(_size.x(), 0, 0));
+
+		_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[0], (*_ordinates)[3], _size.z()));
+		_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[2], (*_ordinates)[3], _size.z()));
+		_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[2], (*_ordinates)[1], _size.z()));
+		_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[0], (*_ordinates)[1], _size.z()));
 		break;
 	case SouthPyramid:
-		boundingBox.expand(origin + Math::Vector3d(0, 0, size.z()));
-		boundingBox.expand(origin + Math::Vector3d(size.x(), 0, size.z()));
-		boundingBox.expand(origin + Math::Vector3d(size.x(), size.y(), size.z()));
-
-		boundingBox.expand(origin + Math::Vector3d(0, size.y(), size.z()));
-		boundingBox.expand(origin + Math::Vector3d((*ordinates)[0], (*ordinates)[1], 0));
-		boundingBox.expand(origin + Math::Vector3d((*ordinates)[2], (*ordinates)[1], 0));
-		boundingBox.expand(origin + Math::Vector3d((*ordinates)[2], (*ordinates)[3], 0));
-		boundingBox.expand(origin + Math::Vector3d((*ordinates)[0], (*ordinates)[3], 0));
+		_boundingBox.expand(_origin + Math::Vector3d(0, 0, _size.z()));
+		_boundingBox.expand(_origin + Math::Vector3d(_size.x(), 0, _size.z()));
+		_boundingBox.expand(_origin + Math::Vector3d(_size.x(), _size.y(), _size.z()));
+
+		_boundingBox.expand(_origin + Math::Vector3d(0, _size.y(), _size.z()));
+		_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[0], (*_ordinates)[1], 0));
+		_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[2], (*_ordinates)[1], 0));
+		_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[2], (*_ordinates)[3], 0));
+		_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[0], (*_ordinates)[3], 0));
 		break;
 	}
 }
 
 GeometricObject::~GeometricObject() {
-	delete conditionSource;
-	delete colours;
-	delete ordinates;
+	delete _conditionSource;
+	delete _colours;
+	delete _ordinates;
 }
 
 bool GeometricObject::isDrawable() { return true; }
 bool GeometricObject::isPlanar() {
 	Type t = this->getType();
-	return (t >= Object::Line) || t == Object::Rectangle || !size.x() || !size.y() || !size.z();
+	return (t >= Object::Line) || t == Object::Rectangle || !_size.x() || !_size.y() || !_size.z();
 }
 
-bool GeometricObject::collides(const Math::AABB &_boundingBox) {
-	if (isDestroyed() || isInvisible() || !boundingBox.isValid() || !_boundingBox.isValid())
+bool GeometricObject::collides(const Math::AABB &boundingBox_) {
+	if (isDestroyed() || isInvisible() || !_boundingBox.isValid() || !boundingBox_.isValid())
 		return false;
 
-	return (boundingBox.getMax().x() > _boundingBox.getMin().x() &&
-			boundingBox.getMin().x() < _boundingBox.getMax().x() &&
-			boundingBox.getMax().y() > _boundingBox.getMin().y() &&
-			boundingBox.getMin().y() < _boundingBox.getMax().y() &&
-			boundingBox.getMax().z() > _boundingBox.getMin().z() &&
-			boundingBox.getMin().z() < _boundingBox.getMax().z());
+	return (_boundingBox.getMax().x() > boundingBox_.getMin().x() &&
+			_boundingBox.getMin().x() < boundingBox_.getMax().x() &&
+			_boundingBox.getMax().y() > boundingBox_.getMin().y() &&
+			_boundingBox.getMin().y() < boundingBox_.getMax().y() &&
+			_boundingBox.getMax().z() > boundingBox_.getMin().z() &&
+			_boundingBox.getMin().z() < boundingBox_.getMax().z());
 }
 
 void GeometricObject::draw(Freescape::Renderer *gfx) {
 	if (this->getType() == Cube) {
-		gfx->renderCube(origin, size, colours);
+		gfx->renderCube(_origin, _size, _colours);
 	} else if (this->getType() == Rectangle) {
-		gfx->renderRectangle(origin, size, colours);
+		gfx->renderRectangle(_origin, _size, _colours);
 	} else if (isPyramid(this->getType())) {
-		gfx->renderPyramid(origin, size, ordinates, colours, this->getType());
-	} else if (this->isPlanar() && type <= 14) {
+		gfx->renderPyramid(_origin, _size, _ordinates, _colours, this->getType());
+	} else if (this->isPlanar() && _type <= 14) {
 		if (this->getType() == Triangle)
-			assert(ordinates->size() == 9);
+			assert(_ordinates->size() == 9);
 
-		gfx->renderPolygon(origin, size, ordinates, colours);
+		gfx->renderPolygon(_origin, _size, _ordinates, _colours);
 	}
 }
 
diff --git a/engines/freescape/objects/geometricobject.h b/engines/freescape/objects/geometricobject.h
index c0065278dec..60682e0f3dc 100644
--- a/engines/freescape/objects/geometricobject.h
+++ b/engines/freescape/objects/geometricobject.h
@@ -56,12 +56,12 @@ public:
 	bool isDrawable() override;
 	bool isPlanar() override;
 
-	Common::String *conditionSource;
-	FCLInstructionVector condition;
+	Common::String *_conditionSource;
+	FCLInstructionVector _condition;
 
 private:
-	Common::Array<uint8> *colours;
-	Common::Array<uint16> *ordinates;
+	Common::Array<uint8> *_colours;
+	Common::Array<uint16> *_ordinates;
 };
 
 } // End of namespace Freescape
diff --git a/engines/freescape/objects/global.cpp b/engines/freescape/objects/global.cpp
index 402f6926174..dfdbd5889b2 100644
--- a/engines/freescape/objects/global.cpp
+++ b/engines/freescape/objects/global.cpp
@@ -25,9 +25,9 @@
 
 namespace Freescape {
 
-GlobalStructure::GlobalStructure(const Common::Array<byte> _structure) {
-	objectID = 255;
-	structure = _structure;
+GlobalStructure::GlobalStructure(const Common::Array<byte> structure_) {
+	_objectID = 255;
+	_structure = structure_;
 }
 
 } // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/objects/global.h b/engines/freescape/objects/global.h
index 99139003df4..001c136c8f4 100644
--- a/engines/freescape/objects/global.h
+++ b/engines/freescape/objects/global.h
@@ -28,7 +28,7 @@ namespace Freescape {
 
 class GlobalStructure : public Object {
 public:
-	Common::Array<byte> structure;
+	Common::Array<byte> _structure;
 	GlobalStructure(const Common::Array<byte> _structure);
 	Type getType() override { return Type::Entrance; };
 	void draw(Freescape::Renderer *gfx) override { error("cannot render GlobalStructure"); };
diff --git a/engines/freescape/objects/object.cpp b/engines/freescape/objects/object.cpp
index b57a815ff89..43a0527ca47 100644
--- a/engines/freescape/objects/object.cpp
+++ b/engines/freescape/objects/object.cpp
@@ -25,23 +25,23 @@
 
 namespace Freescape {
 
-Object::Type Object::getType() { return type; }
-uint16 Object::getObjectID() { return objectID; }
-uint16 Object::getObjectFlags() { return flags; }
-void Object::setObjectFlags(uint32 _flags) { flags = _flags; }
-Math::Vector3d Object::getOrigin() { return origin; }
-void Object::setOrigin(Math::Vector3d _origin) { origin = _origin; };
-Math::Vector3d Object::getSize() { return size; }
+Object::Type Object::getType() { return _type; }
+uint16 Object::getObjectID() { return _objectID; }
+uint16 Object::getObjectFlags() { return _flags; }
+void Object::setObjectFlags(uint32 flags_) { _flags = flags_; }
+Math::Vector3d Object::getOrigin() { return _origin; }
+void Object::setOrigin(Math::Vector3d origin_) { _origin = origin_; };
+Math::Vector3d Object::getSize() { return _size; }
 
 bool Object::isDrawable() { return false; }
 bool Object::isPlanar() { return false; }
 
-bool Object::isInvisible() { return flags & 0x80; }
-void Object::makeInvisible() { flags = flags | 0x80; }
-void Object::makeVisible() { flags = flags & ~0x80; }
-bool Object::isDestroyed() { return flags & 0x20; }
-void Object::destroy() { flags = flags | 0x20; }
-void Object::toggleVisibility() { flags = flags ^ 0x80; }
+bool Object::isInvisible() { return _flags & 0x80; }
+void Object::makeInvisible() { _flags = _flags | 0x80; }
+void Object::makeVisible() { _flags = _flags & ~0x80; }
+bool Object::isDestroyed() { return _flags & 0x20; }
+void Object::destroy() { _flags = _flags | 0x20; }
+void Object::toggleVisibility() { _flags = _flags ^ 0x80; }
 
 Object::~Object() {}
 
diff --git a/engines/freescape/objects/object.h b/engines/freescape/objects/object.h
index e63b34503aa..69f226aeaa7 100644
--- a/engines/freescape/objects/object.h
+++ b/engines/freescape/objects/object.h
@@ -76,11 +76,11 @@ public:
 
 	virtual ~Object();
 
-	uint16 flags;
-	Type type;
-	uint16 objectID;
-	Math::Vector3d origin, size, rotation;
-	Math::AABB boundingBox;
+	uint16 _flags;
+	Type _type;
+	uint16 _objectID;
+	Math::Vector3d _origin, _size, _rotation;
+	Math::AABB _boundingBox;
 };
 
 } // End of namespace Freescape
diff --git a/engines/freescape/objects/sensor.cpp b/engines/freescape/objects/sensor.cpp
index 0262fb3db9e..5537e7f9038 100644
--- a/engines/freescape/objects/sensor.cpp
+++ b/engines/freescape/objects/sensor.cpp
@@ -26,13 +26,13 @@
 namespace Freescape {
 
 Sensor::Sensor(
-	uint16 _objectID,
-	const Math::Vector3d &_origin,
-	const Math::Vector3d &_rotation) {
-	objectID = _objectID;
-	origin = _origin;
-	rotation = _rotation;
-	flags = 0;
+	uint16 objectID_,
+	const Math::Vector3d &origin_,
+	const Math::Vector3d &rotation_) {
+	_objectID = objectID_;
+	_origin = origin_;
+	_rotation = rotation_;
+	_flags = 0;
 }
 
 Sensor::~Sensor() {}
diff --git a/engines/freescape/objects/sensor.h b/engines/freescape/objects/sensor.h
index 2c81134aa45..905f3d2100f 100644
--- a/engines/freescape/objects/sensor.h
+++ b/engines/freescape/objects/sensor.h
@@ -39,7 +39,7 @@ public:
 	bool isDrawable() override;
 	bool isPlanar() override;
 	Type getType() override { return Type::Sensor; };
-	Math::Vector3d getRotation() { return rotation; }
+	Math::Vector3d getRotation() { return _rotation; }
 
 	void draw(Freescape::Renderer *gfx) override { error("cannot render sensor"); };
 };


Commit: 8c6ee3163eda0b44d4fba3d808abb309dd5f7efa
    https://github.com/scummvm/scummvm/commit/8c6ee3163eda0b44d4fba3d808abb309dd5f7efa
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:35+01:00

Commit Message:
FREESCAPE: renamed variable names from Token class to follow code conventions

Changed paths:
    engines/freescape/language/token.h


diff --git a/engines/freescape/language/token.h b/engines/freescape/language/token.h
index a63a8175018..0326cea166c 100644
--- a/engines/freescape/language/token.h
+++ b/engines/freescape/language/token.h
@@ -103,18 +103,18 @@ public:
 	Type getType();
 
 	Token() {
-		type = UNKNOWN;
-		value = 0;
+		_type = UNKNOWN;
+		_value = 0;
 	}
-	Token(Type _type) {
-		type = _type;
-		value = 0;
+	Token(Type type_) {
+		_type = type_;
+		_value = 0;
 	}
 
 private:
-	Type type;
-	int32 value;
-	Common::String string;
+	Type _type;
+	int32 _value;
+	Common::String _string;
 };
 
 } // End of namespace Freescape


Commit: 5af2aa097d1c003bb5767797e55ce7186af8cee1
    https://github.com/scummvm/scummvm/commit/5af2aa097d1c003bb5767797e55ce7186af8cee1
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:35+01:00

Commit Message:
FREESCAPE: renamed variable names from the Texture classes to follow code conventions

Changed paths:
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl_texture.cpp
    engines/freescape/gfx_tinygl_texture.h


diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 0ea15f1d845..8537cb12612 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -41,9 +41,9 @@ public:
 	Texture(){};
 	virtual ~Texture(){};
 
-	uint width;
-	uint height;
-	Graphics::PixelFormat format;
+	uint _width;
+	uint _height;
+	Graphics::PixelFormat _format;
 
 	virtual void update(const Graphics::Surface *surface) = 0;
 	virtual void updatePartial(const Graphics::Surface *surface, const Common::Rect &rect) = 0;
diff --git a/engines/freescape/gfx_tinygl_texture.cpp b/engines/freescape/gfx_tinygl_texture.cpp
index a73baffa172..44a7754486a 100644
--- a/engines/freescape/gfx_tinygl_texture.cpp
+++ b/engines/freescape/gfx_tinygl_texture.cpp
@@ -25,9 +25,9 @@
 namespace Freescape {
 
 TinyGLTexture::TinyGLTexture(const Graphics::Surface *surface) {
-	width = surface->w;
-	height = surface->h;
-	format = surface->format;
+	_width = surface->w;
+	_height = surface->h;
+	_format = surface->format;
 
 	_blitImage = tglGenBlitImage();
 
@@ -35,7 +35,7 @@ TinyGLTexture::TinyGLTexture(const Graphics::Surface *surface) {
 }
 
 TinyGLTexture::~TinyGLTexture() {
-	tglDeleteTextures(1, &id);
+	tglDeleteTextures(1, &_id);
 	tglDeleteBlitImage(_blitImage);
 }
 
diff --git a/engines/freescape/gfx_tinygl_texture.h b/engines/freescape/gfx_tinygl_texture.h
index fa2027e3dc0..36ceec71413 100644
--- a/engines/freescape/gfx_tinygl_texture.h
+++ b/engines/freescape/gfx_tinygl_texture.h
@@ -40,9 +40,9 @@ public:
 	void update(const Graphics::Surface *surface) override;
 	void updatePartial(const Graphics::Surface *surface, const Common::Rect &rect) override;
 
-	TGLuint id;
-	TGLuint internalFormat;
-	TGLuint sourceFormat;
+	TGLuint _id;
+	TGLuint _internalFormat;
+	TGLuint _sourceFormat;
 
 private:
 	TinyGL::BlitImage *_blitImage;


Commit: 5e736da809930f28464a2eff1a980c468b91bbf3
    https://github.com/scummvm/scummvm/commit/5e736da809930f28464a2eff1a980c468b91bbf3
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:36+01:00

Commit Message:
FREESCAPE: renamed ObjectType enum to follow code conventions

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/objects/entrance.h
    engines/freescape/objects/geometricobject.cpp
    engines/freescape/objects/geometricobject.h
    engines/freescape/objects/global.h
    engines/freescape/objects/object.cpp
    engines/freescape/objects/object.h
    engines/freescape/objects/sensor.h


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 4377269b41f..4fe4b70b91e 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -237,7 +237,7 @@ void Area::addStructure(Area *global) {
 			gColors->push_back(_groundColor);
 
 		obj = (Object *)new GeometricObject(
-			Object::Type::Cube,
+			ObjectType::kCubeType,
 			id,
 			0,                             // flags
 			Math::Vector3d(0, -1, 0),      // Position
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 86b7ffcd5f9..61903a80254 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -74,7 +74,7 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 
 	byte rawFlagsAndType = readField(file, 8);
 	debugC(1, kFreescapeDebugParser, "Raw object data flags and type: %d", rawFlagsAndType);
-	Object::Type objectType = (Object::Type)(rawFlagsAndType & 0x1F);
+	ObjectType objectType = (ObjectType)(rawFlagsAndType & 0x1F);
 
 	Math::Vector3d position, v;
 
@@ -99,7 +99,7 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 
 	assert(byteSizeOfObject >= 9);
 	byteSizeOfObject = byteSizeOfObject - 9;
-	if (objectID == 255 && objectType == Object::Type::Entrance) {
+	if (objectID == 255 && objectType == ObjectType::kEntranceType) {
 		debugC(1, kFreescapeDebugParser, "Found the room structure (objectID: 255 with size %d)", byteSizeOfObject + 6);
 		byte *structureData = (byte *)malloc(byteSizeOfObject + 6);
 		structureData[0] = int(position.x());
@@ -191,7 +191,7 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 			instructions,
 			conditionSource);
 	} break;
-	case Object::Entrance: {
+	case kEntranceType: {
 		debugC(1, kFreescapeDebugParser, "rotation: %f %f %f", v.x(), v.y(), v.z());
 		if (byteSizeOfObject > 0) {
 			// TODO: there is something here
@@ -210,7 +210,7 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 			5 * v); // rotation
 	} break;
 
-	case Object::Sensor: {
+	case kSensorType: {
 		debugC(1, kFreescapeDebugParser, "rotation: %f %f %f", v.x(), v.y(), v.z());
 		if (byteSizeOfObject > 0) {
 			// TODO: there is something here
@@ -228,7 +228,7 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 			5 * v); // rotation
 	} break;
 
-	case Object::Group:
+	case kGroupType:
 		debugC(1, kFreescapeDebugParser, "Object of type 'group'");
 		file->seek(byteSizeOfObject, SEEK_CUR);
 		return new Sensor(
@@ -345,7 +345,7 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 		Object *newObject = load8bitObject(file);
 
 		if (newObject) {
-			if (newObject->getType() == Object::Entrance) {
+			if (newObject->getType() == kEntranceType) {
 				if (entrancesByID->contains(newObject->getObjectID() & 0x7fff))
 					error("WARNING: replacing object id %d (%d)", newObject->getObjectID(), newObject->getObjectID() & 0x7fff);
 
diff --git a/engines/freescape/objects/entrance.h b/engines/freescape/objects/entrance.h
index 1d7001ecd0a..593740a326c 100644
--- a/engines/freescape/objects/entrance.h
+++ b/engines/freescape/objects/entrance.h
@@ -38,7 +38,7 @@ public:
 
 	bool isDrawable() override;
 	bool isPlanar() override;
-	Type getType() override { return Type::Entrance; };
+	ObjectType getType() override { return ObjectType::kEntranceType; };
 	Math::Vector3d getRotation() { return _rotation; }
 
 	void draw(Freescape::Renderer *gfx) override { error("cannot render Entrance"); };
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index bbf8b100c0a..71edc75a218 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -25,92 +25,92 @@
 
 namespace Freescape {
 
-int GeometricObject::numberOfColoursForObjectOfType(Type type) {
+int GeometricObject::numberOfColoursForObjectOfType(ObjectType type) {
 	switch (type) {
 	default:
-	case Entrance:
-	case Group:
-	case Sensor:
+	case kEntranceType:
+	case kGroupType:
+	case kSensorType:
 		return 0;
 
-	case Line:
+	case kLineType:
 		return 2;
 
-	case Rectangle:
-	case Triangle:
-	case Quadrilateral:
-	case Pentagon:
-	case Hexagon:
+	case kRectangleType:
+	case kTriangleType:
+	case kQuadrilateralType:
+	case kPentagonType:
+	case kHexagonType:
 		return 2;
 
-	case Cube:
-	case EastPyramid:
-	case WestPyramid:
-	case UpPyramid:
-	case DownPyramid:
-	case NorthPyramid:
-	case SouthPyramid:
+	case kCubeType:
+	case kEastPyramidType:
+	case kWestPyramidType:
+	case kUpPyramidType:
+	case kDownPyramidType:
+	case kNorthPyramidType:
+	case kSouthPyramidType:
 		return 6;
 	}
 }
 
-int GeometricObject::numberOfOrdinatesForType(Type type) {
+int GeometricObject::numberOfOrdinatesForType(ObjectType type) {
 	switch (type) {
 	default:
-	case Entrance:
-	case Group:
-	case Rectangle:
-	case Sensor:
+	case kEntranceType:
+	case kGroupType:
+	case kRectangleType:
+	case kSensorType:
 		return 0;
 
-	case EastPyramid:
-	case WestPyramid:
-	case UpPyramid:
-	case DownPyramid:
-	case NorthPyramid:
-	case SouthPyramid:
+	case kEastPyramidType:
+	case kWestPyramidType:
+	case kUpPyramidType:
+	case kDownPyramidType:
+	case kNorthPyramidType:
+	case kSouthPyramidType:
 		return 4;
 
-	case Line:
-	case Triangle:
-	case Quadrilateral:
-	case Pentagon:
-	case Hexagon:
-		return 3 * (2 + type - Line);
+	case kLineType:
+	case kTriangleType:
+	case kQuadrilateralType:
+	case kPentagonType:
+	case kHexagonType:
+		return 3 * (2 + type - kLineType);
 	}
 }
 
-bool GeometricObject::isPyramid(Type type) {
+bool GeometricObject::isPyramid(ObjectType type) {
 	switch (type) {
 	default:
 		return false;
 
-	case EastPyramid:
-	case WestPyramid:
-	case UpPyramid:
-	case DownPyramid:
-	case NorthPyramid:
-	case SouthPyramid:
+	case kEastPyramidType:
+	case kWestPyramidType:
+	case kUpPyramidType:
+	case kDownPyramidType:
+	case kNorthPyramidType:
+	case kSouthPyramidType:
 		return true;
 	}
 }
 
-bool GeometricObject::isPolygon(Type type) {
+bool GeometricObject::isPolygon(ObjectType type) {
 	switch (type) {
 	default:
 		return false;
 
-	case Line:
-	case Triangle:
-	case Quadrilateral:
-	case Pentagon:
-	case Hexagon:
+	case kLineType:
+	case kTriangleType:
+	case kQuadrilateralType:
+	case kPentagonType:
+	case kHexagonType:
 		return true;
 	}
 }
 
 GeometricObject::GeometricObject(
-	Type type_,
+	ObjectType type_,
 	uint16 objectID_,
 	uint16 flags_,
 	const Math::Vector3d &origin_,
@@ -141,12 +141,12 @@ GeometricObject::GeometricObject(
 	_condition = conditionInstructions_;
 	_conditionSource = conditionSource_;
 
-	if (_type == Type::Rectangle) {
+	if (_type == kRectangleType) {
 		if ((_size.x() == 0 && _size.y() == 0) ||
 			(_size.y() == 0 && _size.z() == 0) ||
 			(_size.x() == 0 && _size.z() == 0)) {
 
-			_type = Type::Line;
+			_type = kLineType;
 			assert(!_ordinates);
 			_ordinates = new Common::Array<uint16>();
 			_ordinates->push_back(_origin.x());
@@ -186,7 +186,7 @@ void GeometricObject::computeBoundingBox() {
 	switch (_type) {
 	default:
 		break;
-	case Cube:
+	case kCubeType:
 		_boundingBox.expand(_origin);
 		for (int i = 0; i < 3; i++) {
 			v = _origin;
@@ -202,11 +202,11 @@ void GeometricObject::computeBoundingBox() {
 		_boundingBox.expand(_origin + _size);
 		assert(_boundingBox.isValid());
 		break;
-	case Rectangle:
+	case kRectangleType:
 		_boundingBox.expand(_origin);
 		_boundingBox.expand(_origin + _size);
 		break;
-	case Line:
+	case kLineType:
 		for (uint i = 0; i < _ordinates->size(); i = i + 3) {
 			_boundingBox.expand(Math::Vector3d((*_ordinates)[i], (*_ordinates)[i + 1], (*_ordinates)[i + 2]));
 		}
@@ -228,16 +228,16 @@ void GeometricObject::computeBoundingBox() {
 		}
 
 		break;
-	case Triangle:
-	case Quadrilateral:
-	case Pentagon:
-	case Hexagon:
+	case kTriangleType:
+	case kQuadrilateralType:
+	case kPentagonType:
+	case kHexagonType:
 		for (uint i = 0; i < _ordinates->size(); i = i + 3) {
 			_boundingBox.expand(Math::Vector3d((*_ordinates)[i], (*_ordinates)[i + 1], (*_ordinates)[i + 2]));
 		}
 		break;
 
-	case EastPyramid:
+	case kEastPyramidType:
 		_boundingBox.expand(_origin + Math::Vector3d(0, 0, _size.z()));
 		_boundingBox.expand(_origin + Math::Vector3d(0, _size.y(), _size.z()));
 		_boundingBox.expand(_origin + Math::Vector3d(0, _size.y(), 0));
@@ -247,7 +247,7 @@ void GeometricObject::computeBoundingBox() {
 		_boundingBox.expand(_origin + Math::Vector3d(_size.x(), (*_ordinates)[2], (*_ordinates)[1]));
 		_boundingBox.expand(_origin + Math::Vector3d(_size.x(), (*_ordinates)[0], (*_ordinates)[1]));
 		break;
-	case WestPyramid:
+	case kWestPyramidType:
 		_boundingBox.expand(_origin + Math::Vector3d(_size.x(), 0, 0));
 		_boundingBox.expand(_origin + Math::Vector3d(_size.x(), _size.y(), 0));
 		_boundingBox.expand(_origin + Math::Vector3d(_size.x(), _size.y(), _size.z()));
@@ -258,7 +258,7 @@ void GeometricObject::computeBoundingBox() {
 		_boundingBox.expand(_origin + Math::Vector3d(0, (*_ordinates)[2], (*_ordinates)[3]));
 		_boundingBox.expand(_origin + Math::Vector3d(0, (*_ordinates)[0], (*_ordinates)[3]));
 		break;
-	case UpPyramid:
+	case kUpPyramidType:
 		_boundingBox.expand(_origin + Math::Vector3d(_size.x(), 0, 0));
 		_boundingBox.expand(_origin + Math::Vector3d(_size.x(), 0, _size.z()));
 		_boundingBox.expand(_origin + Math::Vector3d(0, 0, _size.z()));
@@ -268,7 +268,7 @@ void GeometricObject::computeBoundingBox() {
 		_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[2], _size.y(), (*_ordinates)[3]));
 		_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[0], _size.y(), (*_ordinates)[3]));
 		break;
-	case DownPyramid:
+	case kDownPyramidType:
 		_boundingBox.expand(_origin + Math::Vector3d(_size.x(), _size.y(), 0));
 		_boundingBox.expand(_origin + Math::Vector3d(0, _size.y(), 0));
 		_boundingBox.expand(_origin + Math::Vector3d(0, _size.y(), _size.z()));
@@ -279,7 +279,7 @@ void GeometricObject::computeBoundingBox() {
 		_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[0], 0, (*_ordinates)[3]));
 		_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[2], 0, (*_ordinates)[3]));
 		break;
-	case NorthPyramid:
+	case kNorthPyramidType:
 		_boundingBox.expand(_origin + Math::Vector3d(0, _size.y(), 0));
 		_boundingBox.expand(_origin + Math::Vector3d(_size.x(), _size.y(), 0));
 		_boundingBox.expand(_origin + Math::Vector3d(_size.x(), 0, 0));
@@ -289,7 +289,7 @@ void GeometricObject::computeBoundingBox() {
 		_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[2], (*_ordinates)[1], _size.z()));
 		_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[0], (*_ordinates)[1], _size.z()));
 		break;
-	case SouthPyramid:
+	case kSouthPyramidType:
 		_boundingBox.expand(_origin + Math::Vector3d(0, 0, _size.z()));
 		_boundingBox.expand(_origin + Math::Vector3d(_size.x(), 0, _size.z()));
 		_boundingBox.expand(_origin + Math::Vector3d(_size.x(), _size.y(), _size.z()));
@@ -311,8 +311,8 @@ GeometricObject::~GeometricObject() {
 
 bool GeometricObject::isDrawable() { return true; }
 bool GeometricObject::isPlanar() {
-	Type t = this->getType();
-	return (t >= Object::Line) || t == Object::Rectangle || !_size.x() || !_size.y() || !_size.z();
+	ObjectType t = this->getType();
+	return (t >= kLineType) || t == kRectangleType || !_size.x() || !_size.y() || !_size.z();
 }
 
 bool GeometricObject::collides(const Math::AABB &boundingBox_) {
@@ -328,14 +328,14 @@ bool GeometricObject::collides(const Math::AABB &boundingBox_) {
 }
 
 void GeometricObject::draw(Freescape::Renderer *gfx) {
-	if (this->getType() == Cube) {
+	if (this->getType() == kCubeType) {
 		gfx->renderCube(_origin, _size, _colours);
-	} else if (this->getType() == Rectangle) {
+	} else if (this->getType() == kRectangleType) {
 		gfx->renderRectangle(_origin, _size, _colours);
 	} else if (isPyramid(this->getType())) {
 		gfx->renderPyramid(_origin, _size, _ordinates, _colours, this->getType());
 	} else if (this->isPlanar() && _type <= 14) {
-		if (this->getType() == Triangle)
+		if (this->getType() == kTriangleType)
 			assert(_ordinates->size() == 9);
 
 		gfx->renderPolygon(_origin, _size, _ordinates, _colours);
diff --git a/engines/freescape/objects/geometricobject.h b/engines/freescape/objects/geometricobject.h
index 60682e0f3dc..4d270435c30 100644
--- a/engines/freescape/objects/geometricobject.h
+++ b/engines/freescape/objects/geometricobject.h
@@ -31,13 +31,13 @@ namespace Freescape {
 
 class GeometricObject : public Object {
 public:
-	static int numberOfColoursForObjectOfType(Type type);
-	static int numberOfOrdinatesForType(Type type);
-	static bool isPyramid(Type type);
-	static bool isPolygon(Type type);
+	static int numberOfColoursForObjectOfType(ObjectType type);
+	static int numberOfOrdinatesForType(ObjectType type);
+	static bool isPyramid(ObjectType type);
+	static bool isPolygon(ObjectType type);
 
 	GeometricObject(
-		Type type,
+		ObjectType type,
 		uint16 objectID,
 		uint16 flags,
 		const Math::Vector3d &origin,
diff --git a/engines/freescape/objects/global.h b/engines/freescape/objects/global.h
index 001c136c8f4..2e647242a62 100644
--- a/engines/freescape/objects/global.h
+++ b/engines/freescape/objects/global.h
@@ -30,7 +30,7 @@ class GlobalStructure : public Object {
 public:
 	Common::Array<byte> _structure;
 	GlobalStructure(const Common::Array<byte> _structure);
-	Type getType() override { return Type::Entrance; };
+	ObjectType getType() override { return ObjectType::kEntranceType; };
 	void draw(Freescape::Renderer *gfx) override { error("cannot render GlobalStructure"); };
 };
 
diff --git a/engines/freescape/objects/object.cpp b/engines/freescape/objects/object.cpp
index 43a0527ca47..0e5d5bc7b3d 100644
--- a/engines/freescape/objects/object.cpp
+++ b/engines/freescape/objects/object.cpp
@@ -25,7 +25,7 @@
 
 namespace Freescape {
 
-Object::Type Object::getType() { return _type; }
+ObjectType Object::getType() { return _type; }
 uint16 Object::getObjectID() { return _objectID; }
 uint16 Object::getObjectFlags() { return _flags; }
 void Object::setObjectFlags(uint32 flags_) { _flags = flags_; }
diff --git a/engines/freescape/objects/object.h b/engines/freescape/objects/object.h
index 69f226aeaa7..98dd960ecb4 100644
--- a/engines/freescape/objects/object.h
+++ b/engines/freescape/objects/object.h
@@ -31,31 +31,31 @@
 
 namespace Freescape {
 
+enum ObjectType {
+	kEntranceType = 0,
+	kCubeType = 1,
+	kSensorType = 2,
+	kRectangleType = 3,
+
+	kEastPyramidType = 4,
+	kWestPyramidType = 5,
+	kUpPyramidType = 6,
+	kDownPyramidType = 7,
+	kNorthPyramidType = 8,
+	kSouthPyramidType = 9,
+
+	kLineType = 10,
+	kTriangleType = 11,
+	kQuadrilateralType = 12,
+	kPentagonType = 13,
+	kHexagonType = 14,
+
+	kGroupType = 15
+};
+
 class Object {
 public:
-	typedef enum {
-		Entrance = 0,
-		Cube = 1,
-		Sensor = 2,
-		Rectangle = 3,
-
-		EastPyramid = 4,
-		WestPyramid = 5,
-		UpPyramid = 6,
-		DownPyramid = 7,
-		NorthPyramid = 8,
-		SouthPyramid = 9,
-
-		Line = 10,
-		Triangle = 11,
-		Quadrilateral = 12,
-		Pentagon = 13,
-		Hexagon = 14,
-
-		Group = 15
-	} Type;
-
-	virtual Type getType();
+	virtual ObjectType getType();
 	uint16 getObjectID();
 	uint16 getObjectFlags();
 	void setObjectFlags(uint32 flags);
@@ -77,7 +77,7 @@ public:
 	virtual ~Object();
 
 	uint16 _flags;
-	Type _type;
+	ObjectType _type;
 	uint16 _objectID;
 	Math::Vector3d _origin, _size, _rotation;
 	Math::AABB _boundingBox;
diff --git a/engines/freescape/objects/sensor.h b/engines/freescape/objects/sensor.h
index 905f3d2100f..710670bd7fd 100644
--- a/engines/freescape/objects/sensor.h
+++ b/engines/freescape/objects/sensor.h
@@ -38,7 +38,7 @@ public:
 
 	bool isDrawable() override;
 	bool isPlanar() override;
-	Type getType() override { return Type::Sensor; };
+	ObjectType getType() override { return kSensorType; };
 	Math::Vector3d getRotation() { return _rotation; }
 
 	void draw(Freescape::Renderer *gfx) override { error("cannot render sensor"); };


Commit: 1c19a5d7012fa71de8d80b3eaefcb69a4b302f67
    https://github.com/scummvm/scummvm/commit/1c19a5d7012fa71de8d80b3eaefcb69a4b302f67
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:36+01:00

Commit Message:
FREESCAPE: removed redudant enum

Changed paths:
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl.cpp


diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 8537cb12612..a9b7816402f 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -69,15 +69,6 @@ public:
 	virtual void clear() = 0;
 	virtual void setViewport(const Common::Rect &rect) = 0;
 
-	typedef enum {
-		EastPyramid = 4,
-		WestPyramid = 5,
-		UpPyramid = 6,
-		DownPyramid = 7,
-		NorthPyramid = 8,
-		SouthPyramid = 9,
-	} PyramidType;
-
 	/**
 	 *  Swap the buffers, making the drawn screen visible
 	 */
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 26831a051b2..ab2aab3c0d2 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -28,8 +28,9 @@
 #include "graphics/tinygl/tinygl.h"
 #include "math/glmath.h"
 
-#include "engines/freescape/gfx_tinygl.h"
-#include "engines/freescape/gfx_tinygl_texture.h"
+#include "freescape/objects/object.h"
+#include "freescape/gfx_tinygl.h"
+#include "freescape/gfx_tinygl_texture.h"
 
 namespace Freescape {
 
@@ -326,11 +327,10 @@ void TinyGLRenderer::renderRectangle(const Math::Vector3d &origin, const Math::V
 
 void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours, int type) {
 	Math::Vector3d vertices[8] = { origin, origin, origin, origin, origin, origin, origin, origin };
-	PyramidType pyramidType = (PyramidType)type;
-	switch (pyramidType) {
+	switch (type) {
 	default:
-		break;
-	case EastPyramid:
+		error("Invalid pyramid type: %d", type);
+	case kEastPyramidType:
 		vertices[0] += Math::Vector3d(0, 0, size.z());
 		vertices[1] += Math::Vector3d(0, size.y(), size.z());
 		vertices[2] += Math::Vector3d(0, size.y(), 0);
@@ -340,7 +340,7 @@ void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vec
 		vertices[6] += Math::Vector3d(size.x(), (*ordinates)[2], (*ordinates)[1]);
 		vertices[7] += Math::Vector3d(size.x(), (*ordinates)[0], (*ordinates)[1]);
 		break;
-	case WestPyramid:
+	case kWestPyramidType:
 
 		vertices[0] += Math::Vector3d(size.x(), 0, 0);
 		vertices[1] += Math::Vector3d(size.x(), size.y(), 0);
@@ -353,7 +353,7 @@ void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vec
 		vertices[7] += Math::Vector3d(0, (*ordinates)[0], (*ordinates)[3]);
 		break;
 
-	case UpPyramid:
+	case kUpPyramidType:
 		vertices[1] += Math::Vector3d(size.x(), 0, 0);
 		vertices[2] += Math::Vector3d(size.x(), 0, size.z());
 		vertices[3] += Math::Vector3d(0, 0, size.z());
@@ -364,7 +364,7 @@ void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vec
 		vertices[7] += Math::Vector3d((*ordinates)[0], size.y(), (*ordinates)[3]);
 		break;
 
-	case DownPyramid:
+	case kDownPyramidType:
 
 		vertices[0] += Math::Vector3d(size.x(), size.y(), 0);
 		vertices[1] += Math::Vector3d(0, size.y(), 0);
@@ -377,7 +377,7 @@ void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vec
 		vertices[7] += Math::Vector3d((*ordinates)[2], 0, (*ordinates)[3]);
 		break;
 
-	case NorthPyramid:
+	case kNorthPyramidType:
 		vertices[0] += Math::Vector3d(0, size.y(), 0);
 		vertices[1] += Math::Vector3d(size.x(), size.y(), 0);
 		vertices[2] += Math::Vector3d(size.x(), 0, 0);
@@ -387,7 +387,7 @@ void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vec
 		vertices[6] += Math::Vector3d((*ordinates)[2], (*ordinates)[1], size.z());
 		vertices[7] += Math::Vector3d((*ordinates)[0], (*ordinates)[1], size.z());
 		break;
-	case SouthPyramid:
+	case kSouthPyramidType:
 		vertices[0] += Math::Vector3d(0, 0, size.z());
 		vertices[1] += Math::Vector3d(size.x(), 0, size.z());
 		vertices[2] += Math::Vector3d(size.x(), size.y(), size.z());


Commit: f8ad38857336d1ca073402d43d01bf2c74e2b14e
    https://github.com/scummvm/scummvm/commit/f8ad38857336d1ca073402d43d01bf2c74e2b14e
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:36+01:00

Commit Message:
FREESCAPE: improved demo decoding loop

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/games/driller.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 8c1ed8fc149..c6d60347446 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -197,9 +197,10 @@ void FreescapeEngine::generateInput() {
 		if (_currentDemoInputRepetition == 0) {
 			_currentDemoInputRepetition = 1;
 			_currentDemoInputCode = _demoData[_demoIndex++];
-			if (_currentDemoInputCode >= 0x80) {
-				_currentDemoInputRepetition = _currentDemoInputCode - 0x80;
-				assert(_currentDemoInputRepetition > 0);
+			if (_currentDemoInputCode & 0x80) {
+				_currentDemoInputRepetition = (_currentDemoInputCode & 0x7F) + 1;
+				if (_currentDemoInputRepetition == 1)
+					_currentDemoInputRepetition = 255;
 				_currentDemoInputCode = _demoData[_demoIndex++];
 			}
 		}
@@ -212,7 +213,7 @@ void FreescapeEngine::generateInput() {
 			// 0x1a -> up
 			// TODO: mouse events
 		} else if (_currentDemoInputCode == 0x7f) {
-			// TODO: wait?
+			// NOP
 		} else {
 			event = Common::Event();
 			event.type = Common::EVENT_KEYDOWN;
@@ -220,9 +221,9 @@ void FreescapeEngine::generateInput() {
 			event.customType = 0xde00;
 			g_system->getEventManager()->pushEvent(event);
 			debugC(1, kFreescapeDebugMove, "Pushing key: %x with repetition %d", event.kbd.keycode, _currentDemoInputRepetition);
+			g_system->delayMillis(100);
 		}
 		_currentDemoInputRepetition--;
-		g_system->delayMillis(50);
 		return;
 	}
 
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index b240018ac34..109247735c6 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -125,7 +125,7 @@ void DrillerEngine::loadAssets() {
 	else
 		loadAssetsFullGame();
 
-	_angleRotations.push_back(5.3);
+	_angleRotations.push_back(5.0);
 	_angleRotations.push_back(9.5);
 
 	// Start playing music, if any


Commit: 81acd105c3776a4df38e6682ab29ea60c02c6987
    https://github.com/scummvm/scummvm/commit/81acd105c3776a4df38e6682ab29ea60c02c6987
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:36+01:00

Commit Message:
FREESCAPE: added proper comment next to each endif

Changed paths:
    engines/freescape/area.h
    engines/freescape/freescape.h
    engines/freescape/gfx_tinygl.h
    engines/freescape/gfx_tinygl_texture.h
    engines/freescape/language/8bitDetokeniser.h
    engines/freescape/language/instruction.h
    engines/freescape/neo.h
    engines/freescape/objects/entrance.h
    engines/freescape/objects/geometricobject.h
    engines/freescape/objects/global.h
    engines/freescape/objects/object.h
    engines/freescape/objects/sensor.h


diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index f47d701935c..b6dcae8e550 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -82,4 +82,4 @@ private:
 
 } // End of namespace Freescape
 
-#endif
+#endif // FREESCAPE_AREA_H
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 8ef5d1cb1c9..210ba2460fd 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -352,4 +352,4 @@ extern FreescapeEngine *g_freescape;
 
 } // namespace Freescape
 
-#endif
+#endif // FREESCAPE_H
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index 1598adcb5dd..3fda3fd2917 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -19,8 +19,8 @@
  *
  */
 
-#ifndef FREESCAPE_GFX_TINYGL_H_
-#define FREESCAPE_GFX_TINYGL_H_
+#ifndef FREESCAPE_GFX_TINYGL_H
+#define FREESCAPE_GFX_TINYGL_H
 
 #include "common/rect.h"
 #include "math/vector3d.h"
@@ -60,4 +60,4 @@ public:
 
 } // End of namespace Freescape
 
-#endif
+#endif // FREESCAPE_GFX_TINYGL_H
diff --git a/engines/freescape/gfx_tinygl_texture.h b/engines/freescape/gfx_tinygl_texture.h
index 36ceec71413..3a1649cabd9 100644
--- a/engines/freescape/gfx_tinygl_texture.h
+++ b/engines/freescape/gfx_tinygl_texture.h
@@ -19,8 +19,8 @@
  *
  */
 
-#ifndef GFX_TINYGL_TEXTURE_H
-#define GFX_TINYGL_TEXTURE_H
+#ifndef FREESCAPE_GFX_TINYGL_TEXTURE_H
+#define FREESCAPE_GFX_TINYGL_TEXTURE_H
 
 #include "graphics/surface.h"
 #include "graphics/tinygl/zgl.h"
@@ -50,4 +50,4 @@ private:
 
 } // End of namespace Freescape
 
-#endif
+#endif // FREESCAPE_GFX_TINYGL_TEXTURE_H
diff --git a/engines/freescape/language/8bitDetokeniser.h b/engines/freescape/language/8bitDetokeniser.h
index 80de0ae31df..fb9ba350619 100644
--- a/engines/freescape/language/8bitDetokeniser.h
+++ b/engines/freescape/language/8bitDetokeniser.h
@@ -42,4 +42,4 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 
 } // End of namespace Freescape
 
-#endif
+#endif // FREESCAPE_8BITDETOKENIZER_H
\ No newline at end of file
diff --git a/engines/freescape/language/instruction.h b/engines/freescape/language/instruction.h
index e3ca2b89d58..698bea0ad78 100644
--- a/engines/freescape/language/instruction.h
+++ b/engines/freescape/language/instruction.h
@@ -56,4 +56,4 @@ private:
 
 } // End of namespace Freescape
 
-#endif
+#endif // FREESCAPE_INSTRUCTION_H
diff --git a/engines/freescape/neo.h b/engines/freescape/neo.h
index 380aac602ab..ff11540c186 100644
--- a/engines/freescape/neo.h
+++ b/engines/freescape/neo.h
@@ -19,8 +19,8 @@
  *
  */
 
-#ifndef IMAGE_NEO_H
-#define IMAGE_NEO_H
+#ifndef FREESCAPE_NEO_H
+#define FREESCAPE_NEO_H
 
 #include "common/scummsys.h"
 #include "common/str.h"
@@ -56,4 +56,4 @@ private:
 };
 } // End of namespace Image
 
-#endif
\ No newline at end of file
+#endif // FREESCAPE_NEO_H
\ No newline at end of file
diff --git a/engines/freescape/objects/entrance.h b/engines/freescape/objects/entrance.h
index 593740a326c..638983e754f 100644
--- a/engines/freescape/objects/entrance.h
+++ b/engines/freescape/objects/entrance.h
@@ -46,4 +46,4 @@ public:
 
 } // End of namespace Freescape
 
-#endif
+#endif // FREESCAPE_ENTRANCE_H
diff --git a/engines/freescape/objects/geometricobject.h b/engines/freescape/objects/geometricobject.h
index 4d270435c30..6147bc94d24 100644
--- a/engines/freescape/objects/geometricobject.h
+++ b/engines/freescape/objects/geometricobject.h
@@ -66,4 +66,4 @@ private:
 
 } // End of namespace Freescape
 
-#endif
+#endif // FREESCAPE_GEOMETRICOBJECT_H
diff --git a/engines/freescape/objects/global.h b/engines/freescape/objects/global.h
index 2e647242a62..ed4ff459a06 100644
--- a/engines/freescape/objects/global.h
+++ b/engines/freescape/objects/global.h
@@ -19,8 +19,8 @@
  *
  */
 
-#ifndef FREESCAPE_GLOB_H
-#define FREESCAPE_GLOB_H
+#ifndef FREESCAPE_GLOBAL_H
+#define FREESCAPE_GLOBAL_H
 
 #include "freescape/objects/object.h"
 
@@ -36,4 +36,4 @@ public:
 
 } // End of namespace Freescape
 
-#endif
\ No newline at end of file
+#endif // FREESCAPE_GLOBAL_H
\ No newline at end of file
diff --git a/engines/freescape/objects/object.h b/engines/freescape/objects/object.h
index 98dd960ecb4..3f963c5f1fb 100644
--- a/engines/freescape/objects/object.h
+++ b/engines/freescape/objects/object.h
@@ -85,4 +85,4 @@ public:
 
 } // End of namespace Freescape
 
-#endif
+#endif // FREESCAPE_OBJECT_H
diff --git a/engines/freescape/objects/sensor.h b/engines/freescape/objects/sensor.h
index 710670bd7fd..8d2a4f773c5 100644
--- a/engines/freescape/objects/sensor.h
+++ b/engines/freescape/objects/sensor.h
@@ -46,4 +46,4 @@ public:
 
 } // End of namespace Freescape
 
-#endif
+#endif // FREESCAPE_SENSOR_H


Commit: 3f56b2e00911a4fc88b0d3826097e98a9d77176b
    https://github.com/scummvm/scummvm/commit/3f56b2e00911a4fc88b0d3826097e98a9d77176b
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:36+01:00

Commit Message:
FREESCAPE: added new line at the end of each file

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/games/castle.cpp
    engines/freescape/games/dark.cpp
    engines/freescape/games/driller.cpp
    engines/freescape/games/eclipse.cpp
    engines/freescape/games/palettes.cpp
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/language/8bitDetokeniser.h
    engines/freescape/language/instruction.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/movement.cpp
    engines/freescape/neo.h
    engines/freescape/objects/entrance.cpp
    engines/freescape/objects/geometricobject.cpp
    engines/freescape/objects/global.cpp
    engines/freescape/objects/global.h
    engines/freescape/sound.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 4fe4b70b91e..50ee23171e7 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -260,4 +260,4 @@ void Area::addStructure(Area *global) {
 	}
 }
 
-} // End of namespace Freescape
\ No newline at end of file
+} // End of namespace Freescape
diff --git a/engines/freescape/games/castle.cpp b/engines/freescape/games/castle.cpp
index da03f298b74..8294f88b96a 100644
--- a/engines/freescape/games/castle.cpp
+++ b/engines/freescape/games/castle.cpp
@@ -99,4 +99,4 @@ void CastleEngine::gotoArea(uint16 areaID, int entranceID) {
 		_gfx->_keyColor = 255;
 }
 
-} // End of namespace Freescape
\ No newline at end of file
+} // End of namespace Freescape
diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index d9223ecc2c3..d91a44f53cc 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -146,4 +146,4 @@ void DarkEngine::drawUI() {
 	_gfx->setViewport(_viewArea);
 }
 
-} // End of namespace Freescape
\ No newline at end of file
+} // End of namespace Freescape
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 109247735c6..690884106b8 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -541,4 +541,4 @@ bool DrillerEngine::checkIfGameEnded() {
 	return false;
 }
 
-} // End of namespace Freescape
\ No newline at end of file
+} // End of namespace Freescape
diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index 5c4e57c8954..6f9b8d03101 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -198,4 +198,4 @@ void EclipseEngine::drawUI() {
 	_gfx->setViewport(_viewArea);
 }
 
-} // End of namespace Freescape
\ No newline at end of file
+} // End of namespace Freescape
diff --git a/engines/freescape/games/palettes.cpp b/engines/freescape/games/palettes.cpp
index 68d93ed41ab..7594050f8ea 100644
--- a/engines/freescape/games/palettes.cpp
+++ b/engines/freescape/games/palettes.cpp
@@ -95,4 +95,4 @@ void FreescapeEngine::swapPalette(uint16 levelID) {
 	_gfx->_palette = new Graphics::PixelBuffer(_gfx->_palettePixelFormat, _paletteByArea[levelID]);
 }
 
-} // End of namespace Freescape
\ No newline at end of file
+} // End of namespace Freescape
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index c1836dfc47a..b60881b7990 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -411,4 +411,4 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 	return (new Common::String(detokenisedStream));
 }
 
-} // End of namespace Freescape
\ No newline at end of file
+} // End of namespace Freescape
diff --git a/engines/freescape/language/8bitDetokeniser.h b/engines/freescape/language/8bitDetokeniser.h
index fb9ba350619..11370951ed5 100644
--- a/engines/freescape/language/8bitDetokeniser.h
+++ b/engines/freescape/language/8bitDetokeniser.h
@@ -42,4 +42,4 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 
 } // End of namespace Freescape
 
-#endif // FREESCAPE_8BITDETOKENIZER_H
\ No newline at end of file
+#endif // FREESCAPE_8BITDETOKENIZER_H
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index 48aa8b1f4c9..83207df3706 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -390,4 +390,4 @@ void FreescapeEngine::executeSwapJet(FCLInstruction &instruction) {
 	// TODO: implement the rest of the changes (e.g. border)
 }
 
-} // End of namespace Freescape
\ No newline at end of file
+} // End of namespace Freescape
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 61903a80254..078c32e582e 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -587,4 +587,4 @@ void FreescapeEngine::loadMessagesVariableSize(Common::SeekableReadStream *file,
 	}
 }
 
-} // namespace Freescape
\ No newline at end of file
+} // namespace Freescape
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index addc46bbd32..8a5dc5d6464 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -280,4 +280,4 @@ bool FreescapeEngine::checkCollisions(bool executeCode) {
 	return false;
 }
 
-} // namespace Freescape
\ No newline at end of file
+} // namespace Freescape
diff --git a/engines/freescape/neo.h b/engines/freescape/neo.h
index ff11540c186..5e1fe0c4a13 100644
--- a/engines/freescape/neo.h
+++ b/engines/freescape/neo.h
@@ -56,4 +56,4 @@ private:
 };
 } // End of namespace Image
 
-#endif // FREESCAPE_NEO_H
\ No newline at end of file
+#endif // FREESCAPE_NEO_H
diff --git a/engines/freescape/objects/entrance.cpp b/engines/freescape/objects/entrance.cpp
index f3879cd4ed8..e002cbdb74f 100644
--- a/engines/freescape/objects/entrance.cpp
+++ b/engines/freescape/objects/entrance.cpp
@@ -40,4 +40,4 @@ Entrance::~Entrance() {}
 bool Entrance::isDrawable() { return false; }
 bool Entrance::isPlanar() { return true; }
 
-} // End of namespace Freescape
\ No newline at end of file
+} // End of namespace Freescape
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index 71edc75a218..16b7d0f9f24 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -342,4 +342,4 @@ void GeometricObject::draw(Freescape::Renderer *gfx) {
 	}
 }
 
-} // End of namespace Freescape
\ No newline at end of file
+} // End of namespace Freescape
diff --git a/engines/freescape/objects/global.cpp b/engines/freescape/objects/global.cpp
index dfdbd5889b2..1ab04738362 100644
--- a/engines/freescape/objects/global.cpp
+++ b/engines/freescape/objects/global.cpp
@@ -30,4 +30,4 @@ GlobalStructure::GlobalStructure(const Common::Array<byte> structure_) {
 	_structure = structure_;
 }
 
-} // End of namespace Freescape
\ No newline at end of file
+} // End of namespace Freescape
diff --git a/engines/freescape/objects/global.h b/engines/freescape/objects/global.h
index ed4ff459a06..b6a58d3ffb0 100644
--- a/engines/freescape/objects/global.h
+++ b/engines/freescape/objects/global.h
@@ -36,4 +36,4 @@ public:
 
 } // End of namespace Freescape
 
-#endif // FREESCAPE_GLOBAL_H
\ No newline at end of file
+#endif // FREESCAPE_GLOBAL_H
diff --git a/engines/freescape/sound.cpp b/engines/freescape/sound.cpp
index d1f8ca202fb..b56c64db290 100644
--- a/engines/freescape/sound.cpp
+++ b/engines/freescape/sound.cpp
@@ -372,4 +372,4 @@ void FreescapeEngine::loadSoundsFx(Common::SeekableReadStream *file, int offset,
 	}
 }
 
-} // namespace Freescape
\ No newline at end of file
+} // namespace Freescape


Commit: 2ea1b339ee3eb8e0b659fc9d98c6926761e51c82
    https://github.com/scummvm/scummvm/commit/2ea1b339ee3eb8e0b659fc9d98c6926761e51c82
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:36+01:00

Commit Message:
FREESCAPE: use ADGF flags instead of strings

Changed paths:
    engines/freescape/detection.cpp
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/driller.cpp


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index d2789a344a6..11d088e6f4d 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -55,7 +55,7 @@ static const ADGameDescription gameDescriptions[] = {
 	 ADGF_UNSTABLE,
 	 GUIO3(GUIO_NOMIDI, GUIO_RENDEREGA, GUIO_RENDERCGA)},
 	{"driller",
-	 "Retail",
+	 "",
 	 {
 		{"driller", 0, "13dab2e10d8e8b9a364c94a660e0d42a", 282384},
 		{"title.seq", 0, "4dd1b3b45110b24e8240a6132241c973", 185296},
@@ -63,10 +63,10 @@ static const ADGameDescription gameDescriptions[] = {
 	 },
 	 Common::EN_ANY,
 	 Common::kPlatformAmiga,
-	 ADGF_UNSTABLE,
+	 ADGF_AMIGA_RETAIL | ADGF_UNSTABLE,
 	 GUIO1(GUIO_NOMIDI)},
 	{"driller",
-	 "Kixx",
+	 "",
 	 {
 		{"driller", 0, "db1afe151d999f369ae9153d8eeaf254", 175236},
 		{"soundfx", 0, "cd91061a1330aef8fcd6b7dc6fa35cf9", 78680},
@@ -74,7 +74,7 @@ static const ADGameDescription gameDescriptions[] = {
 	 },
 	 Common::EN_ANY,
 	 Common::kPlatformAmiga,
-	 ADGF_UNSTABLE,
+	 ADGF_AMIGA_BUDGET | ADGF_UNSTABLE,
 	 GUIO1(GUIO_NOMIDI)},
 	{"driller",
 	 "Rolling Demo",
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index c6d60347446..1eda368135c 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -52,10 +52,7 @@ FreescapeEngine::FreescapeEngine(OSystem *syst, const ADGameDescription *gd)
 		_renderMode = Common::kRenderAtariST;
 	}
 
-	if (gd->extra)
-		_variant = gd->extra;
-	else
-		_variant = "FullGame";
+	_variant = gd->flags;
 
 	if (!Common::parseBool(ConfMan.get("prerecorded_sounds"), _usePrerecordedSounds))
 		error("Failed to parse bool from prerecorded_sounds option");
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 210ba2460fd..558ebf2926f 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -89,7 +89,7 @@ public:
 	bool isDemo() const;
 
 	// Game selection
-	Common::String _variant;
+	uint32 _variant;
 	bool isDriller() { return _targetName.hasPrefix("driller") || _targetName.hasPrefix("spacestationoblivion"); }
 	bool isDark() { return _targetName.hasPrefix("darkside"); }
 	bool isEclipse() { return _targetName.hasPrefix("totaleclipse"); }
@@ -286,6 +286,11 @@ public:
 	Common::Error saveGameStream(Common::WriteStream *stream, bool isAutosave = false) override;
 };
 
+enum DrillerReleaseFlags {
+		ADGF_AMIGA_RETAIL = (1 << 0),
+		ADGF_AMIGA_BUDGET = (1 << 1),
+};
+
 class DrillerEngine : public FreescapeEngine {
 public:
 	DrillerEngine(OSystem *syst, const ADGameDescription *gd);
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 690884106b8..a749bd60c86 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -239,7 +239,7 @@ void DrillerEngine::loadAssetsDemo() {
 void DrillerEngine::loadAssetsFullGame() {
 	Common::File file;
 	if (isAmiga()) {
-		if (_variant == "Retail") {
+		if (_variant & ADGF_AMIGA_RETAIL) {
 			file.open("driller");
 
 			if (!file.isOpen())
@@ -259,7 +259,7 @@ void DrillerEngine::loadAssetsFullGame() {
 			load8bitBinary(&file, 0x29c16, 16);
 			loadPalettes(&file, 0x297d4);
 			loadSoundsFx(&file, 0x30e80, 25);
-		} else if (_variant == "Kixx") {
+		} else if (_variant & ADGF_AMIGA_BUDGET) {
 			file.open("lift.neo");
 			if (!file.isOpen())
 				error("Failed to open 'lift.neo' file");
@@ -288,6 +288,8 @@ void DrillerEngine::loadAssetsFullGame() {
 
 			loadSoundsFx(&file, 0, 25);
 		}
+		else
+			error("Invalid or unknown Amiga release");
 	} else if (_renderMode == Common::kRenderEGA) {
 		loadBundledImages();
 		_title = _border;


Commit: 81717815f28c9d864d4ba2b7260d21a0c15eaac6
    https://github.com/scummvm/scummvm/commit/81717815f28c9d864d4ba2b7260d21a0c15eaac6
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:37+01:00

Commit Message:
FREESCAPE: added POTFILES

Changed paths:
  A engines/freescape/POTFILES


diff --git a/engines/freescape/POTFILES b/engines/freescape/POTFILES
new file mode 100644
index 00000000000..692e1a8b87b
--- /dev/null
+++ b/engines/freescape/POTFILES
@@ -0,0 +1 @@
+engines/freescape/detection.cpp
\ No newline at end of file


Commit: 76d1f26d6e28c6a30968b4a3f46982abde8e6a9c
    https://github.com/scummvm/scummvm/commit/76d1f26d6e28c6a30968b4a3f46982abde8e6a9c
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:37+01:00

Commit Message:
FREESCAPE: simplify palette handling and allow to compile without TinyGL

Changed paths:
    engines/freescape/games/palettes.cpp
    engines/freescape/gfx.cpp
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/module.mk


diff --git a/engines/freescape/games/palettes.cpp b/engines/freescape/games/palettes.cpp
index 7594050f8ea..cab5871e1d8 100644
--- a/engines/freescape/games/palettes.cpp
+++ b/engines/freescape/games/palettes.cpp
@@ -49,17 +49,15 @@ byte dos_CGA_palette[4][3] = {
 };
 
 void FreescapeEngine::loadColorPalette() {
-	Graphics::PixelBuffer *palette = nullptr;
-	if (_renderMode == Common::kRenderEGA)
-		palette = new Graphics::PixelBuffer(_gfx->_palettePixelFormat, (byte *)&dos_EGA_palette);
-	else if (_renderMode == Common::kRenderCGA)
-		palette = new Graphics::PixelBuffer(_gfx->_palettePixelFormat, (byte *)&dos_CGA_palette);
-	else if (_renderMode == Common::kRenderAmiga || _renderMode == Common::kRenderAtariST)
-		palette = nullptr; // palette depends on the area
-	else
+	if (_renderMode == Common::kRenderEGA) {
+		_gfx->_palette = (byte *)&dos_EGA_palette;
+	} else if (_renderMode == Common::kRenderCGA) {
+		_gfx->_palette = (byte *)&dos_CGA_palette;
+	} else if (_renderMode == Common::kRenderAmiga || _renderMode == Common::kRenderAtariST) {
+		_gfx->_palette = nullptr; // palette depends on the area
+	} else
 		error("Invalid render mode, no palette selected");
 
-	_gfx->_palette = palette;
 	_gfx->_colorMap = &_colorMap;
 }
 
@@ -89,10 +87,7 @@ void FreescapeEngine::loadPalettes(Common::SeekableReadStream *file, int offset)
 }
 
 void FreescapeEngine::swapPalette(uint16 levelID) {
-	if (_gfx->_palette)
-		delete _gfx->_palette;
-
-	_gfx->_palette = new Graphics::PixelBuffer(_gfx->_palettePixelFormat, _paletteByArea[levelID]);
+	_gfx->_palette = _paletteByArea[levelID];
 }
 
 } // End of namespace Freescape
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index 7a0506551ef..aa69c4387fa 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -20,12 +20,9 @@
  */
 
 #include "common/config-manager.h"
+
 #include "graphics/renderer.h"
 #include "graphics/surface.h"
-#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS) || defined(USE_GLES2)
-#include "graphics/opengl/context.h"
-#endif
-
 #include "engines/util.h"
 #include "math/glmath.h"
 
@@ -49,12 +46,10 @@ Renderer::Renderer(OSystem *system, int screenW, int screenH, Common::RenderMode
 
 Renderer::~Renderer() {}
 
-Graphics::Surface *Renderer::convertFromPalette(Graphics::PixelBuffer *rawsurf) {
-	Graphics::Surface *surf = new Graphics::Surface();
-	surf->create(_screenW, _screenH, _originalPixelFormat);
-	surf->copyRectToSurface(rawsurf->getRawBuffer(), surf->w, 0, 0, surf->w, surf->h);
-	surf->convertToInPlace(_currentPixelFormat, _palette->getRawBuffer());
-	return surf;
+void Renderer::readFromPalette(uint8 index, uint8 &r, uint8 &g, uint8 &b) {
+	r = _palette[3 * index + 0];
+	g = _palette[3 * index + 1];
+	b = _palette[3 * index + 2];
 }
 
 bool Renderer::getRGBAt(uint8 index, uint8 &r, uint8 &g, uint8 &b) {
@@ -63,12 +58,12 @@ bool Renderer::getRGBAt(uint8 index, uint8 &r, uint8 &g, uint8 &b) {
 		return false;
 
 	if (index == 0) {
-		_palette->getRGBAt(0, r, g, b);
+		readFromPalette(0, r, g, b);
 		return true;
 	}
 
 	if (_renderMode == Common::kRenderAmiga || _renderMode == Common::kRenderAtariST) {
-		_palette->getRGBAt(index, r, g, b);
+		readFromPalette(index, r, g, b);
 		return true;
 	}
 
@@ -80,7 +75,7 @@ bool Renderer::getRGBAt(uint8 index, uint8 &r, uint8 &g, uint8 &b) {
 		byte be = *entry;
 		if (be != 0 && be != 0xff) {
 			// TODO: fix colors for non-DOS releases
-			_palette->getRGBAt(index, r, g, b);
+			readFromPalette(index, r, g, b);
 			return true;
 		}
 
@@ -91,7 +86,7 @@ bool Renderer::getRGBAt(uint8 index, uint8 &r, uint8 &g, uint8 &b) {
 		entry++;
 	}
 	assert(color < 16);
-	_palette->getRGBAt(color, r, g, b);
+	readFromPalette(color, r, g, b);
 	return true;
 }
 
@@ -104,50 +99,19 @@ void Renderer::computeScreenViewport() {
 }
 
 Renderer *createRenderer(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode) {
-	Common::String rendererConfig = ConfMan.get("renderer");
 	Graphics::PixelFormat pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
-	Graphics::RendererType desiredRendererType = Graphics::kRendererTypeTinyGL;  // Graphics::parseRendererTypeCode(rendererConfig);
-	Graphics::RendererType matchingRendererType = Graphics::kRendererTypeTinyGL; // Graphics::getBestMatchingAvailableRendererType(desiredRendererType);
+	// This code will allow different renderers, but right now, it only support TinyGL
+	Graphics::RendererType desiredRendererType = Graphics::kRendererTypeTinyGL;
 
-	bool isAccelerated = 0; // matchingRendererType != Graphics::kRendererTypeTinyGL;
-
-	if (isAccelerated) {
-		initGraphics3d(screenW, screenH);
-	} else {
-		initGraphics(screenW, screenH, &pixelFormat);
-	}
+	initGraphics(screenW, screenH, &pixelFormat);
 
-	/*#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS) || defined(USE_GLES2)
-		bool backendCapableOpenGL = g_system->hasFeature(OSystem::kFeatureOpenGLForGame);
-	#endif
-
-	#if defined(USE_OPENGL_GAME)
-		// Check the OpenGL context actually supports shaders
-		if (backendCapableOpenGL && matchingRendererType == Graphics::kRendererTypeOpenGLShaders && !OpenGLContext.shadersSupported) {
-			matchingRendererType = Graphics::kRendererTypeOpenGL;
-		}
-	#endif*/
-
-	if (matchingRendererType != desiredRendererType && desiredRendererType != Graphics::kRendererTypeDefault) {
-		// Display a warning if unable to use the desired renderer
-		warning("Unable to create a '%s' renderer", rendererConfig.c_str());
-	}
-	/*
-	#if defined(USE_GLES2) || defined(USE_OPENGL_SHADERS)
-		if (backendCapableOpenGL && matchingRendererType == Graphics::kRendererTypeOpenGLShaders) {
-			return CreateGfxOpenGLShader(system);
-		}
-	#endif
-	#if defined(USE_OPENGL_GAME) && !defined(USE_GLES2)
-		if (backendCapableOpenGL && matchingRendererType == Graphics::kRendererTypeOpenGL) {
-			return CreateGfxOpenGL(system);
-		}
-	#endif*/
-	if (matchingRendererType == Graphics::kRendererTypeTinyGL) {
+	#if defined(USE_TINYGL)
+	if (desiredRendererType == Graphics::kRendererTypeTinyGL) {
 		return CreateGfxTinyGL(system, screenW, screenH, renderMode);
 	}
+	#endif
 
-	error("Unable to create a '%s' renderer", rendererConfig.c_str());
+	error("Unable to create a renderer");
 }
 
 } // End of namespace Freescape
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index a9b7816402f..618a5ac3a16 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -60,11 +60,6 @@ public:
 	Graphics::PixelFormat _originalPixelFormat;
 	Graphics::PixelFormat _palettePixelFormat;
 
-	/**
-	 *   Convert from paletted surface
-	 */
-	Graphics::Surface *convertFromPalette(Graphics::PixelBuffer *rawsurf);
-
 	virtual void init() = 0;
 	virtual void clear() = 0;
 	virtual void setViewport(const Common::Rect &rect) = 0;
@@ -93,8 +88,9 @@ public:
 	Common::Rect viewport() const;
 
 	// palette
+	void readFromPalette(uint8 index, uint8 &r, uint8 &g, uint8 &b);
 	bool getRGBAt(uint8 index, uint8 &r, uint8 &g, uint8 &b);
-	Graphics::PixelBuffer *_palette;
+	byte *_palette;
 	ColorMap *_colorMap;
 	int _keyColor;
 
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index ab2aab3c0d2..1912a0b1972 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -140,7 +140,7 @@ void TinyGLRenderer::drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint
 
 void TinyGLRenderer::renderCrossair(byte color, const Common::Point position) {
 	uint8 r, g, b;
-	_palette->getRGBAt(color, r, g, b); // TODO: should use opposite color
+	readFromPalette(color, r, g, b); // TODO: should use opposite color
 
 	tglMatrixMode(TGL_PROJECTION);
 	tglLoadIdentity();
@@ -167,7 +167,7 @@ void TinyGLRenderer::renderCrossair(byte color, const Common::Point position) {
 
 void TinyGLRenderer::renderShoot(byte color, const Common::Point position) {
 	uint8 r, g, b;
-	_palette->getRGBAt(color, r, g, b); // TODO: should use opposite color
+	readFromPalette(color, r, g, b); // TODO: should use opposite color
 
 	tglMatrixMode(TGL_PROJECTION);
 	tglLoadIdentity();
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index bebf2b61c96..fc7d76b07de 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -10,8 +10,6 @@ MODULE_OBJS := \
 	games/eclipse.o \
 	games/palettes.o \
 	gfx.o \
-	gfx_tinygl.o \
-	gfx_tinygl_texture.o \
 	keyboard.o \
 	objects/object.o \
 	objects/entrance.o \
@@ -25,6 +23,11 @@ MODULE_OBJS := \
 	neo.o \
 	sound.o
 
+ifdef USE_TINYGL
+MODULE_OBJS += \
+	gfx_tinygl.o \
+	gfx_tinygl_texture.o
+endif
 
 MODULE_DIRS += \
 	engines/freescape


Commit: d35cbc41cb301a8effc9f1879808128c83ced55f
    https://github.com/scummvm/scummvm/commit/d35cbc41cb301a8effc9f1879808128c83ced55f
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:37+01:00

Commit Message:
FREESCAPE: removed pointers to strings to avoid memory leaks

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/freescape.h
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/language/8bitDetokeniser.h
    engines/freescape/language/instruction.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/movement.cpp
    engines/freescape/objects/geometricobject.cpp
    engines/freescape/objects/geometricobject.h


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 50ee23171e7..5835ffeef36 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -104,9 +104,6 @@ Area::~Area() {
 
 	delete _entrancesByID;
 	delete _objectsByID;
-
-	for (auto &it : _conditionSources)
-		delete it;
 }
 
 void Area::show() {
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index b6dcae8e550..eebf9ca976f 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -55,7 +55,7 @@ public:
 	void addStructure(Area *global);
 	void removeObject(int16 id);
 
-	Common::Array<Common::String *> _conditionSources;
+	Common::Array<Common::String> _conditionSources;
 	Common::Array<FCLInstructionVector> _conditions;
 
 	// Serialization
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 558ebf2926f..c3714723dc9 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -204,7 +204,7 @@ public:
 	uint16 _playerDepth;
 
 	// Effects
-	Common::Array<Common::String *> _conditionSources;
+	Common::Array<Common::String> _conditionSources;
 	Common::Array<FCLInstructionVector> _conditions;
 
 	bool checkCollisions(bool executeCode);
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index b60881b7990..c0a31d03fbd 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -33,7 +33,7 @@ uint8 k8bitMaxVariable = 64;
 uint8 k8bitMaxShield = 64;
 uint8 k8bitMaxEnergy = 64;
 
-Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition, FCLInstructionVector &instructions) {
+Common::String detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition, FCLInstructionVector &instructions) {
 	Common::String detokenisedStream;
 	Common::Array<uint8>::size_type bytePointer = 0;
 	Common::Array<uint8>::size_type sizeOfTokenisedContent = tokenisedCondition.size();
@@ -408,7 +408,7 @@ Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition
 	branch.setBranches(conditionalInstructions, nullptr);
 	instructions.push_back(branch);
 
-	return (new Common::String(detokenisedStream));
+	return detokenisedStream;
 }
 
 } // End of namespace Freescape
diff --git a/engines/freescape/language/8bitDetokeniser.h b/engines/freescape/language/8bitDetokeniser.h
index 11370951ed5..8829586cbb1 100644
--- a/engines/freescape/language/8bitDetokeniser.h
+++ b/engines/freescape/language/8bitDetokeniser.h
@@ -38,7 +38,7 @@ extern uint8 k8bitMaxVariable;
 extern uint8 k8bitMaxShield;
 extern uint8 k8bitMaxEnergy;
 
-Common::String *detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition, FCLInstructionVector &instructions);
+Common::String detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition, FCLInstructionVector &instructions);
 
 } // End of namespace Freescape
 
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index 83207df3706..93df3ab209d 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -67,8 +67,8 @@ Token::Type FCLInstruction::getType() {
 
 void FreescapeEngine::executeObjectConditions(GeometricObject *obj, bool shot, bool collided) {
 	assert(obj != nullptr);
-	if (obj->_conditionSource != nullptr) {
-		debugC(1, kFreescapeDebugCode, "Executing with collision flag: %s", obj->_conditionSource->c_str());
+	if (!obj->_conditionSource.empty()) {
+		debugC(1, kFreescapeDebugCode, "Executing with collision flag: %s", obj->_conditionSource.c_str());
 		executeCode(obj->_condition, shot, collided);
 	}
 }
@@ -78,13 +78,13 @@ void FreescapeEngine::executeLocalGlobalConditions(bool shot, bool collided) {
 		return;
 	debugC(1, kFreescapeDebugCode, "Executing room conditions");
 	for (uint i = 0; i < _currentArea->_conditions.size(); i++) {
-		debugC(1, kFreescapeDebugCode, "%s", _currentArea->_conditionSources[i]->c_str());
+		debugC(1, kFreescapeDebugCode, "%s", _currentArea->_conditionSources[i].c_str());
 		executeCode(_currentArea->_conditions[i], shot, collided);
 	}
 
 	debugC(1, kFreescapeDebugCode, "Executing global conditions (%d)", _conditions.size());
 	for (uint i = 0; i < _conditions.size(); i++) {
-		debugC(1, kFreescapeDebugCode, "%s", _conditionSources[i]->c_str());
+		debugC(1, kFreescapeDebugCode, "%s", _conditionSources[i].c_str());
 		executeCode(_conditions[i], shot, collided);
 	}
 }
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 078c32e582e..4509c383701 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -167,12 +167,12 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 
 		// grab the object condition, if there is one
 		FCLInstructionVector instructions;
-		Common::String *conditionSource = nullptr;
+		Common::String conditionSource;
 		if (byteSizeOfObject) {
 			Common::Array<uint8> conditionArray = readArray(file, byteSizeOfObject);
 			conditionSource = detokenise8bitCondition(conditionArray, instructions);
 			// instructions = getInstructions(conditionSource);
-			debugC(1, kFreescapeDebugParser, "%s", conditionSource->c_str());
+			debugC(1, kFreescapeDebugParser, "%s", conditionSource.c_str());
 		}
 		debugC(1, kFreescapeDebugParser, "End of object at %lx", file->pos());
 
@@ -382,10 +382,10 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 		debugC(1, kFreescapeDebugParser, "length of condition: %d", lengthOfCondition);
 		// get the condition
 		Common::Array<uint8> conditionArray = readArray(file, lengthOfCondition);
-		Common::String *conditionSource = detokenise8bitCondition(conditionArray, instructions);
+		Common::String conditionSource = detokenise8bitCondition(conditionArray, instructions);
 		area->_conditions.push_back(instructions);
 		area->_conditionSources.push_back(conditionSource);
-		debugC(1, kFreescapeDebugParser, "%s", conditionSource->c_str());
+		debugC(1, kFreescapeDebugParser, "%s", conditionSource.c_str());
 	}
 
 	debugC(1, kFreescapeDebugParser, "End of area at %lx", file->pos());
@@ -462,10 +462,10 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 		// get the condition
 		Common::Array<uint8> conditionArray = readArray(file, lengthOfCondition);
 		// debug("Global condition %d", numConditions + 1);
-		Common::String *conditionSource = detokenise8bitCondition(conditionArray, instructions);
+		Common::String conditionSource = detokenise8bitCondition(conditionArray, instructions);
 		_conditions.push_back(instructions);
 		_conditionSources.push_back(conditionSource);
-		debugC(1, kFreescapeDebugParser, "%s", conditionSource->c_str());
+		debugC(1, kFreescapeDebugParser, "%s", conditionSource.c_str());
 	}
 
 	if (isAmiga() || isAtariST())
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index 8a5dc5d6464..fe238dd0358 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -63,8 +63,8 @@ void FreescapeEngine::shoot() {
 		GeometricObject *gobj = (GeometricObject *)shot;
 		debugC(1, kFreescapeDebugMove, "Shot object %d with flags %x", gobj->getObjectID(), gobj->getObjectFlags());
 
-		if (gobj->_conditionSource != nullptr)
-			debugC(1, kFreescapeDebugMove, "Must use shot = true when executing: %s", gobj->_conditionSource->c_str());
+		if (!gobj->_conditionSource.empty())
+			debugC(1, kFreescapeDebugMove, "Must use shot = true when executing: %s", gobj->_conditionSource.c_str());
 
 		executeObjectConditions(gobj, true, false);
 	}
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index 16b7d0f9f24..8b75fbcf123 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -118,7 +118,7 @@ GeometricObject::GeometricObject(
 	Common::Array<uint8> *colours_,
 	Common::Array<uint16> *ordinates_,
 	FCLInstructionVector conditionInstructions_,
-	Common::String *conditionSource_) {
+	Common::String conditionSource_) {
 	_type = type_;
 	_flags = flags_;
 
@@ -304,7 +304,6 @@ void GeometricObject::computeBoundingBox() {
 }
 
 GeometricObject::~GeometricObject() {
-	delete _conditionSource;
 	delete _colours;
 	delete _ordinates;
 }
diff --git a/engines/freescape/objects/geometricobject.h b/engines/freescape/objects/geometricobject.h
index 6147bc94d24..7365c30900b 100644
--- a/engines/freescape/objects/geometricobject.h
+++ b/engines/freescape/objects/geometricobject.h
@@ -45,7 +45,7 @@ public:
 		Common::Array<uint8> *colours,
 		Common::Array<uint16> *ordinates,
 		FCLInstructionVector conditionInstructions,
-		Common::String *conditionSource = nullptr);
+		Common::String conditionSource = "");
 	virtual ~GeometricObject();
 	void setOrigin(Math::Vector3d origin) override;
 
@@ -56,7 +56,7 @@ public:
 	bool isDrawable() override;
 	bool isPlanar() override;
 
-	Common::String *_conditionSource;
+	Common::String _conditionSource;
 	FCLInstructionVector _condition;
 
 private:


Commit: 8db4952775309aef3d79524c111ff71f4eff632b
    https://github.com/scummvm/scummvm/commit/8db4952775309aef3d79524c111ff71f4eff632b
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:37+01:00

Commit Message:
FREESCAPE: use GUI::MessageDialog instead of error and return to launcher, when there are no available renderers

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/gfx.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 1eda368135c..d81b8bb1a13 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -363,6 +363,11 @@ void FreescapeEngine::processInput() {
 Common::Error FreescapeEngine::run() {
 	// Initialize graphics
 	_gfx = createRenderer(_system, _screenW, _screenH, _renderMode);
+	// The following error code will force return to launcher
+	// but it will not force any other GUI message to be displayed
+	if (!_gfx)
+		return Common::kUserCanceled;
+
 	_gfx->init();
 	_gfx->clear();
 
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index aa69c4387fa..36780a03a7b 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -21,10 +21,10 @@
 
 #include "common/config-manager.h"
 
+#include "gui/message.h"
 #include "graphics/renderer.h"
 #include "graphics/surface.h"
 #include "engines/util.h"
-#include "math/glmath.h"
 
 #include "engines/freescape/gfx.h"
 
@@ -111,7 +111,10 @@ Renderer *createRenderer(OSystem *system, int screenW, int screenH, Common::Rend
 	}
 	#endif
 
-	error("Unable to create a renderer");
+	GUI::MessageDialog dialog("Unable to create a renderer. Please compile with support for TinyGL");
+	// TODO: improve message with other renders
+	dialog.runModal();
+	return nullptr;
 }
 
 } // End of namespace Freescape


Commit: 119d6639434d9c012d26abf3bee5ed8d95bcad87
    https://github.com/scummvm/scummvm/commit/119d6639434d9c012d26abf3bee5ed8d95bcad87
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:37+01:00

Commit Message:
FREESCAPE: sorted, removed and simplified a number of includes

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/detection.cpp
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/castle.cpp
    engines/freescape/games/dark.cpp
    engines/freescape/games/driller.cpp
    engines/freescape/games/eclipse.cpp
    engines/freescape/gfx.cpp
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/gfx_tinygl.h
    engines/freescape/gfx_tinygl_texture.cpp
    engines/freescape/gfx_tinygl_texture.h
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/language/token.h
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/metaengine.cpp
    engines/freescape/neo.cpp
    engines/freescape/neo.h
    engines/freescape/objects/global.cpp
    engines/freescape/objects/object.h
    engines/freescape/sound.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 5835ffeef36..80ba2bafe07 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -21,11 +21,10 @@
 
 // Based on Phantasma code by Thomas Harte (2013)
 
-#include "freescape/area.h"
 #include "common/algorithm.h"
+
 #include "freescape/freescape.h"
-#include "freescape/objects/entrance.h"
-#include "freescape/objects/geometricobject.h"
+#include "freescape/area.h"
 #include "freescape/objects/global.h"
 
 namespace Freescape {
@@ -65,7 +64,6 @@ Area::Area(uint16 areaID_, uint16 areaFlags_, ObjectMap *objectsByID_, ObjectMap
 	_entrancesByID = entrancesByID_;
 
 	_scale = 0;
-	_palette = 0;
 	_skyColor = 255;
 	_groundColor = 255;
 	_gasPocketRadius = 0;
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index eebf9ca976f..e50caa44759 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -67,7 +67,6 @@ public:
 	uint32 _gasPocketRadius;
 
 	uint8 _scale;
-	Graphics::PixelBuffer *_palette;
 	uint8 _skyColor;
 	uint8 _groundColor;
 
diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index 11d088e6f4d..862b911b4f3 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -19,8 +19,6 @@
  *
  */
 
-#include "base/plugins.h"
-#include "engines/advancedDetector.h"
 #include "common/translation.h"
 
 #include "freescape/freescape.h"
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index d81b8bb1a13..479f6684483 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -21,9 +21,9 @@
 
 #include "common/config-manager.h"
 #include "common/events.h"
-#include "common/file.h"
 #include "common/math.h"
 #include "common/unzip.h"
+#include "common/random.h"
 #include "graphics/cursorman.h"
 
 #include "freescape/freescape.h"
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index c3714723dc9..5faea821da6 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -23,13 +23,8 @@
 #define FREESCAPE_H
 
 #include "common/bitarray.h"
-#include "common/random.h"
-#include "common/rendermode.h"
 #include "engines/advancedDetector.h"
-#include "engines/engine.h"
-#include "graphics/palette.h"
 #include "graphics/surface.h"
-#include "graphics/tinygl/pixelbuffer.h"
 
 #include "audio/decoders/wave.h"
 #include "audio/mixer.h"
@@ -40,6 +35,10 @@
 #include "freescape/objects/entrance.h"
 #include "freescape/objects/geometricobject.h"
 
+namespace Common {
+class RandomSource;
+}
+
 namespace Freescape {
 
 class Renderer;
@@ -252,7 +251,6 @@ public:
 	int _screenW, _screenH;
 	Renderer *_gfx;
 	Common::RenderMode _renderMode;
-	Graphics::PixelBuffer *getPalette(uint8 areaNumber, uint8 c1, uint8 c2, uint8 c3, uint8 c4, uint16 ncolors);
 	ColorMap _colorMap;
 	void drawFrame();
 	uint8 _colorNumber;
diff --git a/engines/freescape/games/castle.cpp b/engines/freescape/games/castle.cpp
index 8294f88b96a..afb7a76c339 100644
--- a/engines/freescape/games/castle.cpp
+++ b/engines/freescape/games/castle.cpp
@@ -19,7 +19,6 @@
  *
  */
 
-#include "common/config-manager.h"
 #include "common/file.h"
 #include "common/memstream.h"
 
diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index d91a44f53cc..aedad42b7b6 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -19,7 +19,6 @@
  *
  */
 
-#include "common/config-manager.h"
 #include "common/file.h"
 
 #include "freescape/freescape.h"
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index a749bd60c86..70f7d17b76d 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -19,7 +19,6 @@
  *
  */
 
-#include "common/config-manager.h"
 #include "common/events.h"
 #include "common/file.h"
 
diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index 6f9b8d03101..42767b80171 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -19,7 +19,6 @@
  *
  */
 
-#include "common/config-manager.h"
 #include "common/file.h"
 
 #include "freescape/freescape.h"
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index 36780a03a7b..ef01ee2ea61 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -19,14 +19,11 @@
  *
  */
 
-#include "common/config-manager.h"
-
 #include "gui/message.h"
 #include "graphics/renderer.h"
-#include "graphics/surface.h"
 #include "engines/util.h"
 
-#include "engines/freescape/gfx.h"
+#include "freescape/gfx.h"
 
 namespace Freescape {
 
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 618a5ac3a16..2887ebfebd6 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -25,9 +25,8 @@
 #include "common/rendermode.h"
 #include "common/rect.h"
 
-#include "graphics/tinygl/pixelbuffer.h"
+#include "graphics/pixelformat.h"
 #include "math/frustum.h"
-#include "math/matrix4.h"
 #include "math/vector3d.h"
 
 namespace Freescape {
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 1912a0b1972..8ead1eb10ee 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -23,7 +23,6 @@
 
 #include "common/config-manager.h"
 #include "common/math.h"
-#include "common/rect.h"
 #include "common/system.h"
 #include "graphics/tinygl/tinygl.h"
 #include "math/glmath.h"
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index 3fda3fd2917..a5a65d4356a 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -22,10 +22,9 @@
 #ifndef FREESCAPE_GFX_TINYGL_H
 #define FREESCAPE_GFX_TINYGL_H
 
-#include "common/rect.h"
 #include "math/vector3d.h"
 
-#include "engines/freescape/gfx.h"
+#include "freescape/gfx.h"
 
 namespace Freescape {
 
diff --git a/engines/freescape/gfx_tinygl_texture.cpp b/engines/freescape/gfx_tinygl_texture.cpp
index 44a7754486a..7f684a29543 100644
--- a/engines/freescape/gfx_tinygl_texture.cpp
+++ b/engines/freescape/gfx_tinygl_texture.cpp
@@ -19,9 +19,10 @@
  *
  */
 
-#include "engines/freescape/gfx_tinygl_texture.h"
 #include "graphics/tinygl/zblit.h"
 
+#include "freescape/gfx_tinygl_texture.h"
+
 namespace Freescape {
 
 TinyGLTexture::TinyGLTexture(const Graphics::Surface *surface) {
diff --git a/engines/freescape/gfx_tinygl_texture.h b/engines/freescape/gfx_tinygl_texture.h
index 3a1649cabd9..8d59543bdec 100644
--- a/engines/freescape/gfx_tinygl_texture.h
+++ b/engines/freescape/gfx_tinygl_texture.h
@@ -22,11 +22,9 @@
 #ifndef FREESCAPE_GFX_TINYGL_TEXTURE_H
 #define FREESCAPE_GFX_TINYGL_TEXTURE_H
 
-#include "graphics/surface.h"
 #include "graphics/tinygl/zgl.h"
 
-#include "engines/freescape/gfx.h"
-#include "graphics/tinygl/zblit.h"
+#include "freescape/gfx.h"
 
 namespace Freescape {
 
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index c0a31d03fbd..b82d92dde7e 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -22,8 +22,6 @@
 // Based on Phantasma code by Thomas Harte (2013), which was implemented based on
 // John Elliott's 2001 reverse engineering of Driller; see http://www.seasip.demon.co.uk/ZX/Driller/
 
-#include "common/debug.h"
-
 #include "freescape/freescape.h"
 #include "freescape/language/8bitDetokeniser.h"
 
diff --git a/engines/freescape/language/token.h b/engines/freescape/language/token.h
index 0326cea166c..8ba13c5dccb 100644
--- a/engines/freescape/language/token.h
+++ b/engines/freescape/language/token.h
@@ -24,8 +24,6 @@
 #ifndef FREESCAPE_TOKEN_H
 #define FREESCAPE_TOKEN_H
 
-#include "common/str.h"
-
 namespace Freescape {
 
 struct Token {
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 4509c383701..ed64d041c38 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -21,12 +21,10 @@
 
 // Based on Phantasma code by Thomas Harte (2013)
 
-#include "common/file.h"
 #include "image/bmp.h"
 
 #include "freescape/freescape.h"
 #include "freescape/language/8bitDetokeniser.h"
-#include "freescape/neo.h"
 #include "freescape/objects/global.h"
 #include "freescape/objects/sensor.h"
 
diff --git a/engines/freescape/metaengine.cpp b/engines/freescape/metaengine.cpp
index ff0b9bc69d9..6b96ee7658b 100644
--- a/engines/freescape/metaengine.cpp
+++ b/engines/freescape/metaengine.cpp
@@ -19,7 +19,6 @@
  *
  */
 
-#include "engines/advancedDetector.h"
 #include "freescape/freescape.h"
 
 class FreescapeMetaEngine : public AdvancedMetaEngine {
diff --git a/engines/freescape/neo.cpp b/engines/freescape/neo.cpp
index 8a0c19b4420..884d2b1c98e 100644
--- a/engines/freescape/neo.cpp
+++ b/engines/freescape/neo.cpp
@@ -19,13 +19,13 @@
  *
  */
 
-#include "neo.h"
-
 #include "common/stream.h"
 #include "common/textconsole.h"
 #include "graphics/pixelformat.h"
 #include "graphics/surface.h"
 
+#include "freescape/neo.h"
+
 namespace Image {
 
 NeoDecoder::NeoDecoder(byte *palette) {
diff --git a/engines/freescape/neo.h b/engines/freescape/neo.h
index 5e1fe0c4a13..1a88a771a76 100644
--- a/engines/freescape/neo.h
+++ b/engines/freescape/neo.h
@@ -22,8 +22,6 @@
 #ifndef FREESCAPE_NEO_H
 #define FREESCAPE_NEO_H
 
-#include "common/scummsys.h"
-#include "common/str.h"
 #include "image/image_decoder.h"
 
 /*
diff --git a/engines/freescape/objects/global.cpp b/engines/freescape/objects/global.cpp
index 1ab04738362..1bf85f0f397 100644
--- a/engines/freescape/objects/global.cpp
+++ b/engines/freescape/objects/global.cpp
@@ -19,8 +19,6 @@
  *
  */
 
-#include "common/array.h"
-
 #include "freescape/objects/global.h"
 
 namespace Freescape {
diff --git a/engines/freescape/objects/object.h b/engines/freescape/objects/object.h
index 3f963c5f1fb..7a8207b773e 100644
--- a/engines/freescape/objects/object.h
+++ b/engines/freescape/objects/object.h
@@ -25,7 +25,6 @@
 #define FREESCAPE_OBJECT_H
 
 #include "math/aabb.h"
-#include "math/vector3d.h"
 
 #include "freescape/gfx.h"
 
diff --git a/engines/freescape/sound.cpp b/engines/freescape/sound.cpp
index b56c64db290..d3e8b1feb7f 100644
--- a/engines/freescape/sound.cpp
+++ b/engines/freescape/sound.cpp
@@ -19,9 +19,9 @@
  *
  */
 
+#include "common/file.h"
 #include "audio/decoders/raw.h"
 #include "audio/decoders/vorbis.h"
-#include "common/file.h"
 
 #include "freescape/freescape.h"
 


Commit: 679b0281a4ba69233952538e9c6ad85109702b61
    https://github.com/scummvm/scummvm/commit/679b0281a4ba69233952538e9c6ad85109702b61
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:37+01:00

Commit Message:
FREESCAPE: improved user message when a renderer cannot be created

Changed paths:
    engines/freescape/gfx.cpp


diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index ef01ee2ea61..55efdd8f6c6 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -108,7 +108,7 @@ Renderer *createRenderer(OSystem *system, int screenW, int screenH, Common::Rend
 	}
 	#endif
 
-	GUI::MessageDialog dialog("Unable to create a renderer. Please compile with support for TinyGL");
+	GUI::MessageDialog dialog("No available renderers enabled");
 	// TODO: improve message with other renders
 	dialog.runModal();
 	return nullptr;


Commit: 2ac4af2347724f4535571624909a9e8cd25a26fb
    https://github.com/scummvm/scummvm/commit/2ac4af2347724f4535571624909a9e8cd25a26fb
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:38+01:00

Commit Message:
FREESCAPE: improved comments on original code atribution

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/language/8bitDetokeniser.h
    engines/freescape/language/instruction.cpp
    engines/freescape/language/instruction.h
    engines/freescape/language/token.h
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/objects/entrance.cpp
    engines/freescape/objects/entrance.h
    engines/freescape/objects/geometricobject.cpp
    engines/freescape/objects/geometricobject.h
    engines/freescape/objects/object.cpp
    engines/freescape/objects/object.h
    engines/freescape/objects/sensor.cpp
    engines/freescape/objects/sensor.h


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 80ba2bafe07..1b4ac001018 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -19,7 +19,8 @@
  *
  */
 
-// Based on Phantasma code by Thomas Harte (2013)
+// Based on Phantasma code by Thomas Harte (2013),
+// available at https://github.com/TomHarte/Phantasma/ (MIT)
 
 #include "common/algorithm.h"
 
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index e50caa44759..3ff50dcbee2 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -19,7 +19,8 @@
  *
  */
 
-// Based on Phantasma code by Thomas Harte (2013)
+// Based on Phantasma code by Thomas Harte (2013),
+// available at https://github.com/TomHarte/Phantasma/ (MIT)
 
 #ifndef FREESCAPE_AREA_H
 #define FREESCAPE_AREA_H
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index b82d92dde7e..518827a7a76 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -19,8 +19,10 @@
  *
  */
 
-// Based on Phantasma code by Thomas Harte (2013), which was implemented based on
-// John Elliott's 2001 reverse engineering of Driller; see http://www.seasip.demon.co.uk/ZX/Driller/
+// Based on Phantasma code by Thomas Harte (2013),
+// available at https://github.com/TomHarte/Phantasma/ (MIT)
+// which was implemented based on John Elliott's reverse engineering of Driller (2001)
+// http://www.seasip.demon.co.uk/ZX/Driller/
 
 #include "freescape/freescape.h"
 #include "freescape/language/8bitDetokeniser.h"
diff --git a/engines/freescape/language/8bitDetokeniser.h b/engines/freescape/language/8bitDetokeniser.h
index 8829586cbb1..873f49264cb 100644
--- a/engines/freescape/language/8bitDetokeniser.h
+++ b/engines/freescape/language/8bitDetokeniser.h
@@ -19,8 +19,6 @@
  *
  */
 
-// Based on Phantasma code by Thomas Harte (2013)
-
 #ifndef FREESCAPE_8BITDETOKENIZER_H
 #define FREESCAPE_8BITDETOKENIZER_H
 
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index 93df3ab209d..42299bc082d 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -19,7 +19,8 @@
  *
  */
 
-// Based on Phantasma code by Thomas Harte (2013)
+// Based on Phantasma code by Thomas Harte (2013),
+// available at https://github.com/TomHarte/Phantasma/ (MIT)
 
 #include "freescape/freescape.h"
 #include "freescape/language/8bitDetokeniser.h"
diff --git a/engines/freescape/language/instruction.h b/engines/freescape/language/instruction.h
index 698bea0ad78..c045cc7e2ff 100644
--- a/engines/freescape/language/instruction.h
+++ b/engines/freescape/language/instruction.h
@@ -19,7 +19,8 @@
  *
  */
 
-// Based on Phantasma code by Thomas Harte (2013)
+// Based on Phantasma code by Thomas Harte (2013),
+// available at https://github.com/TomHarte/Phantasma/ (MIT)
 
 #ifndef FREESCAPE_INSTRUCTION_H
 #define FREESCAPE_INSTRUCTION_H
diff --git a/engines/freescape/language/token.h b/engines/freescape/language/token.h
index 8ba13c5dccb..2c4d19d56b7 100644
--- a/engines/freescape/language/token.h
+++ b/engines/freescape/language/token.h
@@ -19,7 +19,8 @@
  *
  */
 
-// Based on Phantasma code by Thomas Harte (2013)
+// Based on Phantasma code by Thomas Harte (2013),
+// available at https://github.com/TomHarte/Phantasma/ (MIT)
 
 #ifndef FREESCAPE_TOKEN_H
 #define FREESCAPE_TOKEN_H
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index ed64d041c38..97621b8674e 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -19,7 +19,8 @@
  *
  */
 
-// Based on Phantasma code by Thomas Harte (2013)
+// Based on Phantasma code by Thomas Harte (2013),
+// available at https://github.com/TomHarte/Phantasma/ (MIT)
 
 #include "image/bmp.h"
 
diff --git a/engines/freescape/objects/entrance.cpp b/engines/freescape/objects/entrance.cpp
index e002cbdb74f..3e97a5fddc2 100644
--- a/engines/freescape/objects/entrance.cpp
+++ b/engines/freescape/objects/entrance.cpp
@@ -19,7 +19,8 @@
  *
  */
 
-// Based on Phantasma code by Thomas Harte (2013)
+// Based on Phantasma code by Thomas Harte (2013),
+// available at https://github.com/TomHarte/Phantasma/ (MIT)
 
 #include "freescape/objects/entrance.h"
 
diff --git a/engines/freescape/objects/entrance.h b/engines/freescape/objects/entrance.h
index 638983e754f..fd1c482add2 100644
--- a/engines/freescape/objects/entrance.h
+++ b/engines/freescape/objects/entrance.h
@@ -19,7 +19,8 @@
  *
  */
 
-// Based on Phantasma code by Thomas Harte (2013)
+// Based on Phantasma code by Thomas Harte (2013),
+// available at https://github.com/TomHarte/Phantasma/ (MIT)
 
 #ifndef FREESCAPE_ENTRANCE_H
 #define FREESCAPE_ENTRANCE_H
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index 8b75fbcf123..6d1954b1565 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -19,7 +19,8 @@
  *
  */
 
-// Based on Phantasma code by Thomas Harte (2013)
+// Based on Phantasma code by Thomas Harte (2013),
+// available at https://github.com/TomHarte/Phantasma/ (MIT)
 
 #include "freescape/objects/geometricobject.h"
 
diff --git a/engines/freescape/objects/geometricobject.h b/engines/freescape/objects/geometricobject.h
index 7365c30900b..0dfe8654054 100644
--- a/engines/freescape/objects/geometricobject.h
+++ b/engines/freescape/objects/geometricobject.h
@@ -19,7 +19,8 @@
  *
  */
 
-// Based on Phantasma code by Thomas Harte (2013)
+// Based on Phantasma code by Thomas Harte (2013),
+// available at https://github.com/TomHarte/Phantasma/ (MIT)
 
 #ifndef FREESCAPE_GEOMETRICOBJECT_H
 #define FREESCAPE_GEOMETRICOBJECT_H
diff --git a/engines/freescape/objects/object.cpp b/engines/freescape/objects/object.cpp
index 0e5d5bc7b3d..52c9f8ac61b 100644
--- a/engines/freescape/objects/object.cpp
+++ b/engines/freescape/objects/object.cpp
@@ -19,7 +19,8 @@
  *
  */
 
-// Based on Phantasma code by Thomas Harte (2013)
+// Based on Phantasma code by Thomas Harte (2013),
+// available at https://github.com/TomHarte/Phantasma/ (MIT)
 
 #include "freescape/objects/object.h"
 
diff --git a/engines/freescape/objects/object.h b/engines/freescape/objects/object.h
index 7a8207b773e..6ce775242f7 100644
--- a/engines/freescape/objects/object.h
+++ b/engines/freescape/objects/object.h
@@ -19,7 +19,8 @@
  *
  */
 
-// Based on Phantasma code by Thomas Harte (2013)
+// Based on Phantasma code by Thomas Harte (2013),
+// available at https://github.com/TomHarte/Phantasma/ (MIT)
 
 #ifndef FREESCAPE_OBJECT_H
 #define FREESCAPE_OBJECT_H
diff --git a/engines/freescape/objects/sensor.cpp b/engines/freescape/objects/sensor.cpp
index 5537e7f9038..f4331845865 100644
--- a/engines/freescape/objects/sensor.cpp
+++ b/engines/freescape/objects/sensor.cpp
@@ -19,7 +19,8 @@
  *
  */
 
-// Based on Phantasma code by Thomas Harte (2013)
+// Based on Phantasma code by Thomas Harte (2013),
+// available at https://github.com/TomHarte/Phantasma/ (MIT)
 
 #include "freescape/objects/sensor.h"
 
diff --git a/engines/freescape/objects/sensor.h b/engines/freescape/objects/sensor.h
index 8d2a4f773c5..ed02b5a7a7f 100644
--- a/engines/freescape/objects/sensor.h
+++ b/engines/freescape/objects/sensor.h
@@ -19,7 +19,8 @@
  *
  */
 
-// Based on Phantasma code by Thomas Harte (2013)
+// Based on Phantasma code by Thomas Harte (2013),
+// available at https://github.com/TomHarte/Phantasma/ (MIT)
 
 #ifndef FREESCAPE_SENSOR_H
 #define FREESCAPE_SENSOR_H


Commit: 640687a8d000f7e51bd70fbb277209f98e6440e7
    https://github.com/scummvm/scummvm/commit/640687a8d000f7e51bd70fbb277209f98e6440e7
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:38+01:00

Commit Message:
FREESCAPE: added devtools/create_freescape directory with a script and data to create freescape.dat

Changed paths:
  A devtools/create_freescape/create_freescape.sh
  A devtools/create_freescape/darkside_ega.bmp
  A devtools/create_freescape/driller_cga.bmp
  A devtools/create_freescape/driller_ega.bmp
  A devtools/create_freescape/fsDOS_badJingle.wav
  A devtools/create_freescape/fsDOS_bigHit.wav
  A devtools/create_freescape/fsDOS_configMenu.wav
  A devtools/create_freescape/fsDOS_energyDrain.wav
  A devtools/create_freescape/fsDOS_laserFire.wav
  A devtools/create_freescape/fsDOS_laserHit.wav
  A devtools/create_freescape/fsDOS_powerUp.wav
  A devtools/create_freescape/fsDOS_roomChange.wav
  A devtools/create_freescape/fsDOS_stairDown.wav
  A devtools/create_freescape/fsDOS_stairUp.wav
  A devtools/create_freescape/fsDOS_successJingle.wav
  A devtools/create_freescape/fsDOS_switchOff.wav
  A devtools/create_freescape/fsDOS_tankFall.wav
  A devtools/create_freescape/fsDOS_teleporterActivated.wav
  A devtools/create_freescape/spacestationoblivion_ega.bmp
  A devtools/create_freescape/totaleclipse_ega.bmp


diff --git a/devtools/create_freescape/create_freescape.sh b/devtools/create_freescape/create_freescape.sh
new file mode 100755
index 00000000000..ead6f8945cf
--- /dev/null
+++ b/devtools/create_freescape/create_freescape.sh
@@ -0,0 +1,10 @@
+#!/usr/bin/env bash
+
+printf "Creating border/sounds file...\n"
+
+zip -r freescape.zip *.bmp *.wav
+mv freescape.zip freescape.dat
+
+echo done
+
+ls -l freescape.dat
diff --git a/devtools/create_freescape/darkside_ega.bmp b/devtools/create_freescape/darkside_ega.bmp
new file mode 100644
index 00000000000..7622c9e58b2
Binary files /dev/null and b/devtools/create_freescape/darkside_ega.bmp differ
diff --git a/devtools/create_freescape/driller_cga.bmp b/devtools/create_freescape/driller_cga.bmp
new file mode 100644
index 00000000000..180d239aa9a
Binary files /dev/null and b/devtools/create_freescape/driller_cga.bmp differ
diff --git a/devtools/create_freescape/driller_ega.bmp b/devtools/create_freescape/driller_ega.bmp
new file mode 100644
index 00000000000..ec3df6b4bb7
Binary files /dev/null and b/devtools/create_freescape/driller_ega.bmp differ
diff --git a/devtools/create_freescape/fsDOS_badJingle.wav b/devtools/create_freescape/fsDOS_badJingle.wav
new file mode 100644
index 00000000000..9e1a91f858b
Binary files /dev/null and b/devtools/create_freescape/fsDOS_badJingle.wav differ
diff --git a/devtools/create_freescape/fsDOS_bigHit.wav b/devtools/create_freescape/fsDOS_bigHit.wav
new file mode 100644
index 00000000000..e973cbededf
Binary files /dev/null and b/devtools/create_freescape/fsDOS_bigHit.wav differ
diff --git a/devtools/create_freescape/fsDOS_configMenu.wav b/devtools/create_freescape/fsDOS_configMenu.wav
new file mode 100644
index 00000000000..160868e59e0
Binary files /dev/null and b/devtools/create_freescape/fsDOS_configMenu.wav differ
diff --git a/devtools/create_freescape/fsDOS_energyDrain.wav b/devtools/create_freescape/fsDOS_energyDrain.wav
new file mode 100644
index 00000000000..9977a8bc7d7
Binary files /dev/null and b/devtools/create_freescape/fsDOS_energyDrain.wav differ
diff --git a/devtools/create_freescape/fsDOS_laserFire.wav b/devtools/create_freescape/fsDOS_laserFire.wav
new file mode 100644
index 00000000000..3986ff5e691
Binary files /dev/null and b/devtools/create_freescape/fsDOS_laserFire.wav differ
diff --git a/devtools/create_freescape/fsDOS_laserHit.wav b/devtools/create_freescape/fsDOS_laserHit.wav
new file mode 100644
index 00000000000..c1b6d799434
Binary files /dev/null and b/devtools/create_freescape/fsDOS_laserHit.wav differ
diff --git a/devtools/create_freescape/fsDOS_powerUp.wav b/devtools/create_freescape/fsDOS_powerUp.wav
new file mode 100644
index 00000000000..1aa7253e304
Binary files /dev/null and b/devtools/create_freescape/fsDOS_powerUp.wav differ
diff --git a/devtools/create_freescape/fsDOS_roomChange.wav b/devtools/create_freescape/fsDOS_roomChange.wav
new file mode 100644
index 00000000000..706a9e38005
Binary files /dev/null and b/devtools/create_freescape/fsDOS_roomChange.wav differ
diff --git a/devtools/create_freescape/fsDOS_stairDown.wav b/devtools/create_freescape/fsDOS_stairDown.wav
new file mode 100644
index 00000000000..5d56fe399a6
Binary files /dev/null and b/devtools/create_freescape/fsDOS_stairDown.wav differ
diff --git a/devtools/create_freescape/fsDOS_stairUp.wav b/devtools/create_freescape/fsDOS_stairUp.wav
new file mode 100644
index 00000000000..e22d115d14d
Binary files /dev/null and b/devtools/create_freescape/fsDOS_stairUp.wav differ
diff --git a/devtools/create_freescape/fsDOS_successJingle.wav b/devtools/create_freescape/fsDOS_successJingle.wav
new file mode 100644
index 00000000000..209222199e6
Binary files /dev/null and b/devtools/create_freescape/fsDOS_successJingle.wav differ
diff --git a/devtools/create_freescape/fsDOS_switchOff.wav b/devtools/create_freescape/fsDOS_switchOff.wav
new file mode 100644
index 00000000000..f30dc3c0235
Binary files /dev/null and b/devtools/create_freescape/fsDOS_switchOff.wav differ
diff --git a/devtools/create_freescape/fsDOS_tankFall.wav b/devtools/create_freescape/fsDOS_tankFall.wav
new file mode 100644
index 00000000000..6b7562fc3c1
Binary files /dev/null and b/devtools/create_freescape/fsDOS_tankFall.wav differ
diff --git a/devtools/create_freescape/fsDOS_teleporterActivated.wav b/devtools/create_freescape/fsDOS_teleporterActivated.wav
new file mode 100644
index 00000000000..f0a7a6040c1
Binary files /dev/null and b/devtools/create_freescape/fsDOS_teleporterActivated.wav differ
diff --git a/devtools/create_freescape/spacestationoblivion_ega.bmp b/devtools/create_freescape/spacestationoblivion_ega.bmp
new file mode 100644
index 00000000000..5965512fc9e
Binary files /dev/null and b/devtools/create_freescape/spacestationoblivion_ega.bmp differ
diff --git a/devtools/create_freescape/totaleclipse_ega.bmp b/devtools/create_freescape/totaleclipse_ega.bmp
new file mode 100644
index 00000000000..738d6af20b4
Binary files /dev/null and b/devtools/create_freescape/totaleclipse_ega.bmp differ


Commit: 63555f3f53e0fb304790a76cf52f13a723507914
    https://github.com/scummvm/scummvm/commit/63555f3f53e0fb304790a76cf52f13a723507914
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:38+01:00

Commit Message:
FREESCAPE: regenerate freescape.dat using dedicated script

Changed paths:
    dists/engine-data/freescape.dat


diff --git a/dists/engine-data/freescape.dat b/dists/engine-data/freescape.dat
index 07b6723b490..56b678d8f74 100644
Binary files a/dists/engine-data/freescape.dat and b/dists/engine-data/freescape.dat differ


Commit: 57af8e2cc38ffd7ccb46e94a6de7b13c96b3c21a
    https://github.com/scummvm/scummvm/commit/57af8e2cc38ffd7ccb46e94a6de7b13c96b3c21a
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:38+01:00

Commit Message:
FREESCAPE: change API in detection class

Changed paths:
    engines/freescape/detection.cpp


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index 862b911b4f3..945110c6ba5 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -251,11 +251,11 @@ public:
 		_guiOptions = GUIO2(GUIO_NOMIDI, GAMEOPTION_PRERECORDED_SOUNDS);
 	}
 
-	const char *getEngineId() const override {
+	const char *getName() const override {
 		return "freescape";
 	}
 
-	const char *getName() const override {
+	const char *getEngineName() const override {
 		return "Freescape";
 	}
 


Commit: 3c6c95c7ec1b7048d1600db5d173e86257167cc7
    https://github.com/scummvm/scummvm/commit/3c6c95c7ec1b7048d1600db5d173e86257167cc7
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:38+01:00

Commit Message:
FREESCAPE: removed unused string field in token class

Changed paths:
    engines/freescape/language/token.h


diff --git a/engines/freescape/language/token.h b/engines/freescape/language/token.h
index 2c4d19d56b7..4b18d36e408 100644
--- a/engines/freescape/language/token.h
+++ b/engines/freescape/language/token.h
@@ -113,7 +113,6 @@ public:
 private:
 	Type _type;
 	int32 _value;
-	Common::String _string;
 };
 
 } // End of namespace Freescape


Commit: e847698122315642fd3760ec6acc82a200ebfceb
    https://github.com/scummvm/scummvm/commit/e847698122315642fd3760ec6acc82a200ebfceb
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:38+01:00

Commit Message:
FREESCAPE: avoid leaking memory when reading global area data

Changed paths:
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 97621b8674e..a40d017849c 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -100,18 +100,18 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 	byteSizeOfObject = byteSizeOfObject - 9;
 	if (objectID == 255 && objectType == ObjectType::kEntranceType) {
 		debugC(1, kFreescapeDebugParser, "Found the room structure (objectID: 255 with size %d)", byteSizeOfObject + 6);
-		byte *structureData = (byte *)malloc(byteSizeOfObject + 6);
-		structureData[0] = int(position.x());
-		structureData[1] = int(position.y());
-		structureData[2] = int(position.z());
-
-		structureData[3] = int(v.x());
-		structureData[4] = int(v.y());
-		structureData[5] = int(v.z());
-
-		if (byteSizeOfObject > 0)
-			file->read(structureData + 6, byteSizeOfObject);
-		Common::Array<uint8> structureArray(structureData, byteSizeOfObject + 6);
+		Common::Array<uint8> structureArray;
+		structureArray.push_back(uint8(position.x()));
+		structureArray.push_back(uint8(position.y()));
+		structureArray.push_back(uint8(position.z()));
+
+		structureArray.push_back(uint8(v.x()));
+		structureArray.push_back(uint8(v.y()));
+		structureArray.push_back(uint8(v.z()));
+
+		byteSizeOfObject++;
+		while(--byteSizeOfObject > 0)
+			structureArray.push_back(file->readByte());
 		return new GlobalStructure(structureArray);
 	}
 


Commit: bbc6b8987aa0e5dd2df23e9b6e21609e579ead4b
    https://github.com/scummvm/scummvm/commit/bbc6b8987aa0e5dd2df23e9b6e21609e579ead4b
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:39+01:00

Commit Message:
FREESCAPE: refactored large if into a switch when handling pressed keys

Changed paths:
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 479f6684483..b2ada506389 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -268,43 +268,64 @@ void FreescapeEngine::processInput() {
 
 		switch (event.type) {
 		case Common::EVENT_KEYDOWN:
-			if (event.kbd.keycode == Common::KEYCODE_o || event.kbd.keycode == Common::KEYCODE_UP)
+			switch (event.kbd.keycode) {
+			case Common::KEYCODE_o:
+			case Common::KEYCODE_UP:
 				move(kForwardMovement, _scaleVector.x(), deltaTime);
-			else if (event.kbd.keycode == Common::KEYCODE_k || event.kbd.keycode == Common::KEYCODE_DOWN)
+				break;
+			case Common::KEYCODE_k:
+			case Common::KEYCODE_DOWN:
 				move(kBackwardMovement, _scaleVector.x(), deltaTime);
-			else if (event.kbd.keycode == Common::KEYCODE_LEFT)
+				break;
+			case Common::KEYCODE_LEFT:
 				move(kLeftMovement, _scaleVector.y(), deltaTime);
-			else if (event.kbd.keycode == Common::KEYCODE_RIGHT)
+				break;
+			case Common::KEYCODE_RIGHT:
 				move(kRightMovement, _scaleVector.y(), deltaTime);
-			else if (event.kbd.keycode == Common::KEYCODE_KP5 || event.kbd.keycode == Common::KEYCODE_KP0)
+				break;
+			case Common::KEYCODE_KP5:
+			case Common::KEYCODE_KP0:
 				shoot();
-			else if (event.kbd.keycode == Common::KEYCODE_p)
+				break;
+			case Common::KEYCODE_p:
 				rotate(0, 5);
-			else if (event.kbd.keycode == Common::KEYCODE_l)
+				break;
+			case Common::KEYCODE_l:
 				rotate(0, -5);
-			else if (event.kbd.keycode == Common::KEYCODE_u)
+				break;
+			case Common::KEYCODE_u:
 				rotate(180, 0);
-			else if (event.kbd.keycode == Common::KEYCODE_q)
+				break;
+			case Common::KEYCODE_q:
 				rotate(-_angleRotations[_angleRotationIndex], 0);
-			else if (event.kbd.keycode == Common::KEYCODE_w)
+				break;
+			case Common::KEYCODE_w:
 				rotate(_angleRotations[_angleRotationIndex], 0);
-			else if (event.kbd.keycode == Common::KEYCODE_r)
+				break;
+			case Common::KEYCODE_r:
 				rise();
-			else if (event.kbd.keycode == Common::KEYCODE_f)
+				break;
+			case Common::KEYCODE_f:
 				lower();
-			else if (event.kbd.keycode == Common::KEYCODE_n) {
+				break;
+			case Common::KEYCODE_n:
 				_noClipMode = !_noClipMode;
 				_flyMode = _noClipMode;
-			} else if (event.kbd.keycode == Common::KEYCODE_ESCAPE)
+				break;
+			case Common::KEYCODE_ESCAPE:
 				openMainMenuDialog();
-			else if (event.kbd.keycode == Common::KEYCODE_SPACE) {
+				break;
+			case Common::KEYCODE_SPACE:
 				_shootMode = !_shootMode;
 				if (!_shootMode) {
 					_crossairPosition.x = _screenW / 2;
 					_crossairPosition.y = _screenH / 2;
 				}
-			} else
+				break;
+			default:
 				pressedKey(event.kbd.keycode);
+				break;
+			}
 			break;
 
 		case Common::EVENT_QUIT:


Commit: 51fbc89b30d443dad9cd353e4b5627ef3796efed
    https://github.com/scummvm/scummvm/commit/51fbc89b30d443dad9cd353e4b5627ef3796efed
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:39+01:00

Commit Message:
FREESCAPE: avoid use-after-free when deallocating global areas in eclipse and castle

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 1b4ac001018..c546eafa4dd 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -92,13 +92,17 @@ Area::Area(uint16 areaID_, uint16 areaFlags_, ObjectMap *objectsByID_, ObjectMap
 
 Area::~Area() {
 	if (_entrancesByID) {
-		for (auto &it : *_entrancesByID)
-			delete it._value;
+		for (auto &it : *_entrancesByID) {
+			if (!_addedObjects.contains(it._value->getObjectID()))
+				delete it._value;
+		}
 	}
 
 	if (_objectsByID) {
-		for (auto &it : *_objectsByID)
-			delete it._value;
+		for (auto &it : *_objectsByID) {
+			if (!_addedObjects.contains(it._value->getObjectID()))
+				delete it._value;
+		}
 	}
 
 	delete _entrancesByID;
@@ -198,6 +202,8 @@ void Area::addObject(Object *obj) {
 	(*_objectsByID)[id] = obj;
 	if (obj->isDrawable())
 		_drawableObjects.insert_at(0, obj);
+
+	_addedObjects[id] = obj;
 }
 
 void Area::removeObject(int16 id) {
@@ -209,6 +215,7 @@ void Area::removeObject(int16 id) {
 		}
 	}
 	_objectsByID->erase(id);
+	_addedObjects.erase(id);
 }
 
 void Area::addObjectFromArea(int16 id, Area *global) {
@@ -216,9 +223,11 @@ void Area::addObjectFromArea(int16 id, Area *global) {
 	Object *obj = global->objectWithID(id);
 	if (!obj) {
 		assert(global->entranceWithID(id));
+		_addedObjects[id] = global->entranceWithID(id);
 		(*_entrancesByID)[id] = global->entranceWithID(id);
 	} else {
 		(*_objectsByID)[id] = global->objectWithID(id);
+		_addedObjects[id] = global->objectWithID(id);
 		if (obj->isDrawable())
 			_drawableObjects.insert_at(0, obj);
 	}
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index 3ff50dcbee2..3053736bb45 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -77,6 +77,7 @@ private:
 	ObjectMap *_objectsByID;
 	ObjectMap *_entrancesByID;
 	Common::Array<Object *> _drawableObjects;
+	ObjectMap _addedObjects;
 	Object *objectWithIDFromMap(ObjectMap *map, uint16 objectID);
 };
 
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index b2ada506389..314009104e8 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -124,8 +124,13 @@ FreescapeEngine::~FreescapeEngine() {
 	delete _uiTexture;
 	delete _titleTexture;
 
-	for (auto &it : _areaMap)
-		delete it._value;
+	for (auto &it : _areaMap) {
+		if (it._value->getAreaID() != 255)
+			delete it._value;
+	}
+
+	if (_areaMap.contains(255))
+		delete _areaMap[255];
 
 	delete _gfx;
 	delete _dataBundle;


Commit: a71ccf301975d240449e4fea0ef1dff2f0f60dbf
    https://github.com/scummvm/scummvm/commit/a71ccf301975d240449e4fea0ef1dff2f0f60dbf
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:39+01:00

Commit Message:
FREESCAPE: parse each area name in castle

Changed paths:
    engines/freescape/games/castle.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/games/castle.cpp b/engines/freescape/games/castle.cpp
index afb7a76c339..eb643b2667b 100644
--- a/engines/freescape/games/castle.cpp
+++ b/engines/freescape/games/castle.cpp
@@ -60,7 +60,7 @@ void CastleEngine::loadAssets() {
 	Common::SeekableReadStream *stream = nullptr;
 
 	stream = decryptFile("CMLE");
-	loadMessagesVariableSize(stream, 0, 172);
+	loadMessagesVariableSize(stream, 0x11, 164);
 	delete stream;
 
 	stream = decryptFile("CMEDF");
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index a40d017849c..e5824d993cb 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -333,9 +333,15 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 			name = name + char(readField(file, 8));
 			i++;
 		}
-		debugC(1, kFreescapeDebugParser, "Area name: %s", name.c_str());
-	} else if (isCastle())
-		file->seek(5, SEEK_CUR);
+	} else if (isCastle()) {
+		byte idx = file->readByte();
+		name = _messagesList[idx + 41];
+		debug("byte: %d", file->readByte());
+		debug("byte: %d", file->readByte());
+		debug("byte: %d", file->readByte());
+		debug("byte: %d", file->readByte());
+	}
+	debugC(1, kFreescapeDebugParser, "Area name: %s", name.c_str());
 
 	ObjectMap *objectsByID = new ObjectMap;
 	ObjectMap *entrancesByID = new ObjectMap;


Commit: cb2d09b5b8dcff46f7f73cdf4e24bf180bb79536
    https://github.com/scummvm/scummvm/commit/cb2d09b5b8dcff46f7f73cdf4e24bf180bb79536
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:39+01:00

Commit Message:
FREESCAPE: corrected the number of total areas in castle (thanks to @farmboy0)

Changed paths:
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index e5824d993cb..4b80737165c 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -300,9 +300,6 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	// debug("Condition Ptr: %x", cPtr);
 	debugC(1, kFreescapeDebugParser, "Pos before first object: %lx", file->pos());
 
-	if (areaNumber == 192)
-		return nullptr;
-
 	uint8 gasPocketX = 0;
 	uint8 gasPocketY = 0;
 	uint8 gasPocketRadius = 0;
@@ -402,6 +399,9 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	uint8 numberOfAreas = readField(file, 8);
 	debugC(1, kFreescapeDebugParser, "Number of areas: %d", numberOfAreas);
 
+	if (isDOS() && isCastle()) // Castle Master for DOS has an invalid number of areas
+		numberOfAreas = 104;
+
 	uint32 dbSize = readField(file, 16);
 	debugC(1, kFreescapeDebugParser, "Database ends at %x", dbSize);
 
@@ -500,8 +500,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 			else
 				debugC(1, kFreescapeDebugParser, "WARNING: area ID repeated: %d", newArea->getAreaID());
 		} else {
-			debugC(1, kFreescapeDebugParser, "Invalid area %d?", area);
-			break;
+			error("Invalid area %d?", area);
 		}
 	}
 


Commit: e397eba42c5ded725d9699cebef01d5942ead900
    https://github.com/scummvm/scummvm/commit/e397eba42c5ded725d9699cebef01d5942ead900
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:39+01:00

Commit Message:
FREESCAPE: added detection and preliminary code of driller release for AtariST

Changed paths:
    engines/freescape/detection.cpp
    engines/freescape/games/driller.cpp


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index 945110c6ba5..80ea8e4b53a 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -52,6 +52,17 @@ static const ADGameDescription gameDescriptions[] = {
 	 Common::kPlatformDOS,
 	 ADGF_UNSTABLE,
 	 GUIO3(GUIO_NOMIDI, GUIO_RENDEREGA, GUIO_RENDERCGA)},
+	{"driller",
+	 "",
+	 {
+		{"x.prg", 0, "1a79e68e6c2c223c96de0ca2d65149ae", 293062},
+		{"playseq.prg", 0, "535e9f6baf132831aa7fa066a06f242e", 973},
+		AD_LISTEND
+	 },
+	 Common::EN_ANY,
+	 Common::kPlatformAtariST,
+	 ADGF_UNSTABLE,
+	 GUIO1(GUIO_NOMIDI)},
 	{"driller",
 	 "",
 	 {
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 70f7d17b76d..d9e021f9aa8 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -289,6 +289,26 @@ void DrillerEngine::loadAssetsFullGame() {
 		}
 		else
 			error("Invalid or unknown Amiga release");
+	} else if (isAtariST()) {
+		file.open("x.prg");
+
+		if (!file.isOpen())
+			error("Failed to open 'x.prg' executable for AtariST");
+
+		_border = loadAndConvertNeoImage(&file, 0x1371a);
+		byte *palette = (byte *)malloc(16 * 3);
+		for (int i = 0; i < 16; i++) { // gray scale palette
+			palette[i * 3 + 0] = i * (255 / 16);
+			palette[i * 3 + 1] = i * (255 / 16);
+			palette[i * 3 + 2] = i * (255 / 16);
+		}
+		_title = loadAndConvertNeoImage(&file, 0x10, palette);
+
+		//loadMessagesFixedSize(&file, 0xc66e, 14, 20);
+		//loadGlobalObjects(&file, 0xbd62);
+		load8bitBinary(&file, 0x29b3c, 16);
+		loadPalettes(&file, 0x296fa);
+		loadSoundsFx(&file, 0x30da6, 25);
 	} else if (_renderMode == Common::kRenderEGA) {
 		loadBundledImages();
 		_title = _border;


Commit: 5aca1cda80b044d0a61e8396c93a11cac5580f91
    https://github.com/scummvm/scummvm/commit/5aca1cda80b044d0a61e8396c93a11cac5580f91
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:40+01:00

Commit Message:
FREESCAPE: added detection for space station oblivion for AtariST (but unsupported)

Changed paths:
    engines/freescape/detection.cpp


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index 80ea8e4b53a..034ff0c46c1 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -63,6 +63,17 @@ static const ADGameDescription gameDescriptions[] = {
 	 Common::kPlatformAtariST,
 	 ADGF_UNSTABLE,
 	 GUIO1(GUIO_NOMIDI)},
+	{"spacestationoblivion",
+	 "",
+	 {
+		{"x.prg", 0, "bf546ee243c38f51d9beb25c203ccb93", 292624},
+		{"al_intr4.prg", 0, "4f50f281c9ae9c1b6b95ee5270d246ab", 28726},
+		AD_LISTEND
+	 },
+	 Common::EN_ANY,
+	 Common::kPlatformAtariST,
+	 ADGF_UNSUPPORTED,
+	 GUIO1(GUIO_NOMIDI)},
 	{"driller",
 	 "",
 	 {


Commit: ad9297eb8b1d0a1dae2e2fa32b6f9b9af51a4360
    https://github.com/scummvm/scummvm/commit/ad9297eb8b1d0a1dae2e2fa32b6f9b9af51a4360
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:40+01:00

Commit Message:
FREESCAPE: first attempt to use DrawArray in TinyGL renderer

Changed paths:
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/gfx_tinygl.h


diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 8ead1eb10ee..bdff578148f 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -38,10 +38,12 @@ Renderer *CreateGfxTinyGL(OSystem *system, int screenW, int screenH, Common::Ren
 }
 
 TinyGLRenderer::TinyGLRenderer(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode) : Renderer(system, screenW, screenH, renderMode) {
+	_verts = (Vertex*) malloc(sizeof(Vertex) * 20);
 }
 
 TinyGLRenderer::~TinyGLRenderer() {
 	TinyGL::destroyContext();
+	free(_verts);
 }
 
 Texture *TinyGLRenderer::createTexture(const Graphics::Surface *surface) {
@@ -209,22 +211,29 @@ void TinyGLRenderer::renderFace(const Common::Array<Math::Vector3d> &vertices) {
 		const Math::Vector3d &v1 = vertices[1];
 		if (v0 == v1)
 			return;
-		tglBegin(TGL_LINES);
-		tglVertex3f(v0.x(), v0.y(), v0.z());
-		tglVertex3f(v1.x(), v1.y(), v1.z());
-		tglEnd();
+
+		tglEnableClientState(TGL_VERTEX_ARRAY);
+		copyToVertexArray(0, v0);
+		copyToVertexArray(1, v1);
+		tglVertexPointer(3, TGL_FLOAT, 0, _verts);
+		tglDrawArrays(TGL_LINES, 0, 2);
+		tglDisableClientState(TGL_VERTEX_ARRAY);
 		return;
 	}
 
-	tglBegin(TGL_TRIANGLES);
+	tglEnableClientState(TGL_VERTEX_ARRAY);
+	uint vi = 0;
 	for (uint i = 1; i < vertices.size() - 1; i++) { // no underflow since vertices.size() > 2
 		const Math::Vector3d &v1 = vertices[i];
 		const Math::Vector3d &v2 = vertices[i + 1];
-		tglVertex3f(v0.x(), v0.y(), v0.z());
-		tglVertex3f(v1.x(), v1.y(), v1.z());
-		tglVertex3f(v2.x(), v2.y(), v2.z());
+		vi = 3 * (i - 1); // no underflow since i >= 1
+		copyToVertexArray(vi + 0, v0);
+		copyToVertexArray(vi + 1, v1);
+		copyToVertexArray(vi + 2, v2);
 	}
-	tglEnd();
+	tglVertexPointer(3, TGL_FLOAT, 0, _verts);
+	tglDrawArrays(TGL_TRIANGLES, 0, vi + 3);
+	tglDisableClientState(TGL_VERTEX_ARRAY);
 }
 
 void TinyGLRenderer::renderPolygon(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours) {
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index a5a65d4356a..90ecc9d25a0 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -33,6 +33,18 @@ public:
 	TinyGLRenderer(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode);
 	virtual ~TinyGLRenderer();
 
+	struct Vertex {
+		TGLfloat x;
+		TGLfloat y;
+		TGLfloat z;
+	};
+
+	void copyToVertexArray(uint idx, const Math::Vector3d &src) {
+		_verts[idx].x = src.x(); _verts[idx].y = src.y(); _verts[idx].z = src.z();
+	}
+
+	Vertex *_verts;
+
 	virtual void init() override;
 	virtual void clear() override;
 	virtual void setViewport(const Common::Rect &rect) override;


Commit: 4c26d13dd54bbbdfab95000c9fda8eda337600b5
    https://github.com/scummvm/scummvm/commit/4c26d13dd54bbbdfab95000c9fda8eda337600b5
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:40+01:00

Commit Message:
FREESCAPE: rewrite renderCube to use renderFace

Changed paths:
    engines/freescape/gfx_tinygl.cpp


diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index bdff578148f..3fda00f8653 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -478,83 +478,65 @@ void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vec
 
 void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector3d &size, Common::Array<uint8> *colours) {
 	uint8 r, g, b;
+	Common::Array<Math::Vector3d> face;
 
 	if (getRGBAt((*colours)[0], r, g, b)) {
 		tglColor3ub(r, g, b);
-		tglBegin(TGL_TRIANGLES);
-		tglVertex3f(origin.x(), origin.y(), origin.z());
-		tglVertex3f(origin.x(), origin.y(), origin.z() + size.z());
-		tglVertex3f(origin.x(), origin.y() + size.y(), origin.z() + size.z());
-
-		tglVertex3f(origin.x(), origin.y(), origin.z());
-		tglVertex3f(origin.x(), origin.y() + size.y(), origin.z() + size.z());
-		tglVertex3f(origin.x(), origin.y() + size.y(), origin.z());
-		tglEnd();
+		face.push_back(origin);
+		face.push_back(Math::Vector3d(origin.x(), origin.y(), origin.z() + size.z()));
+		face.push_back(Math::Vector3d(origin.x(), origin.y() + size.y(), origin.z() + size.z()));
+		face.push_back(Math::Vector3d(origin.x(), origin.y() + size.y(), origin.z()));
+		renderFace(face);
 	}
 
 	if (getRGBAt((*colours)[1], r, g, b)) {
 		tglColor3ub(r, g, b);
-		tglBegin(TGL_TRIANGLES);
-		tglVertex3f(origin.x() + size.x(), origin.y() + size.y(), origin.z());
-		tglVertex3f(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z());
-		tglVertex3f(origin.x() + size.x(), origin.y(), origin.z() + size.z());
-
-		tglVertex3f(origin.x() + size.x(), origin.y() + size.y(), origin.z());
-		tglVertex3f(origin.x() + size.x(), origin.y(), origin.z() + size.z());
-		tglVertex3f(origin.x() + size.x(), origin.y(), origin.z());
-		tglEnd();
+		face.clear();
+		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y() + size.y(), origin.z()));
+		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z()));
+		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y(), origin.z() + size.z()));
+		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y(), origin.z()));
+		renderFace(face);
 	}
 
 	if (getRGBAt((*colours)[2], r, g, b)) {
 		tglColor3ub(r, g, b);
-		tglBegin(TGL_TRIANGLES);
-		tglVertex3f(origin.x() + size.x(), origin.y(), origin.z());
-		tglVertex3f(origin.x() + size.x(), origin.y(), origin.z() + size.z());
-		tglVertex3f(origin.x(), origin.y(), origin.z() + size.z());
-
-		tglVertex3f(origin.x() + size.x(), origin.y(), origin.z());
-		tglVertex3f(origin.x(), origin.y(), origin.z() + size.z());
-		tglVertex3f(origin.x(), origin.y(), origin.z());
-		tglEnd();
+		face.clear();
+		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y(), origin.z()));
+		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y(), origin.z() + size.z()));
+		face.push_back(Math::Vector3d(origin.x(), origin.y(), origin.z() + size.z()));
+		face.push_back(Math::Vector3d(origin.x(), origin.y(), origin.z()));
+		renderFace(face);
 	}
 
 	if (getRGBAt((*colours)[3], r, g, b)) {
 		tglColor3ub(r, g, b);
-		tglBegin(TGL_TRIANGLES);
-		tglVertex3f(origin.x(), origin.y() + size.y(), origin.z());
-		tglVertex3f(origin.x(), origin.y() + size.y(), origin.z() + size.z());
-		tglVertex3f(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z());
-
-		tglVertex3f(origin.x(), origin.y() + size.y(), origin.z());
-		tglVertex3f(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z());
-		tglVertex3f(origin.x() + size.x(), origin.y() + size.y(), origin.z());
-		tglEnd();
+		face.clear();
+		face.push_back(Math::Vector3d(origin.x(), origin.y() + size.y(), origin.z()));
+		face.push_back(Math::Vector3d(origin.x(), origin.y() + size.y(), origin.z() + size.z()));
+		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z()));
+		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y() + size.y(), origin.z()));
+		renderFace(face);
 	}
 
 	if (getRGBAt((*colours)[4], r, g, b)) {
 		tglColor3ub(r, g, b);
-		tglBegin(TGL_TRIANGLES);
-		tglVertex3f(origin.x(), origin.y() + size.y(), origin.z());
-		tglVertex3f(origin.x() + size.x(), origin.y() + size.y(), origin.z());
-		tglVertex3f(origin.x() + size.x(), origin.y(), origin.z());
-
-		tglVertex3f(origin.x(), origin.y() + size.y(), origin.z());
-		tglVertex3f(origin.x() + size.x(), origin.y(), origin.z());
-		tglVertex3f(origin.x(), origin.y(), origin.z());
-		tglEnd();
+		face.clear();
+		face.push_back(Math::Vector3d(origin.x(), origin.y() + size.y(), origin.z()));
+		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y() + size.y(), origin.z()));
+		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y(), origin.z()));
+		face.push_back(origin);
+		renderFace(face);
 	}
 
 	if (getRGBAt((*colours)[5], r, g, b)) {
 		tglColor3ub(r, g, b);
-		tglBegin(TGL_TRIANGLES);
-		tglVertex3f(origin.x(), origin.y(), origin.z() + size.z());
-		tglVertex3f(origin.x() + size.x(), origin.y(), origin.z() + size.z());
-		tglVertex3f(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z());
-
-		tglVertex3f(origin.x(), origin.y(), origin.z() + size.z());
-		tglVertex3f(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z());
-		tglVertex3f(origin.x(), origin.y() + size.y(), origin.z() + size.z());
-		tglEnd();
+		face.clear();
+		face.push_back(Math::Vector3d(origin.x(), origin.y(), origin.z() + size.z()));
+		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y(), origin.z() + size.z()));
+		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z()));
+		face.push_back(Math::Vector3d(origin.x(), origin.y() + size.y(), origin.z() + size.z()));
+		renderFace(face);
 	}
 }
 


Commit: 8abfc528368cc15d4790aa8742dcdb12a005866f
    https://github.com/scummvm/scummvm/commit/8abfc528368cc15d4790aa8742dcdb12a005866f
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:40+01:00

Commit Message:
FREESCAPE: rewrite drawFloor to use DrawArrays

Changed paths:
    engines/freescape/gfx_tinygl.cpp


diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 3fda00f8653..85acf6b6aa1 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -551,12 +551,15 @@ void TinyGLRenderer::drawFloor(uint8 color) {
 	uint8 r, g, b;
 	assert(getRGBAt(color, r, g, b)); // TODO: move check inside this function
 	tglColor3ub(r, g, b);
-	tglBegin(TGL_QUADS);
-	tglVertex3f(-100000.f, 0.f, -100000.f);
-	tglVertex3f(100000.f, 0.f, -100000.f);
-	tglVertex3f(100000.f, 0.f, 100000.f);
-	tglVertex3f(-100000.f, 0.f, 100000.f);
-	tglEnd();
+
+	tglEnableClientState(TGL_VERTEX_ARRAY);
+	copyToVertexArray(0, Math::Vector3d(-100000.0, 0.0, -100000.0));
+	copyToVertexArray(1, Math::Vector3d(100000.0, 0.0, -100000.0));
+	copyToVertexArray(2, Math::Vector3d(100000.0, 0.0, 100000.0));
+	copyToVertexArray(3, Math::Vector3d(-100000.0, 0.0, 100000.0));
+	tglVertexPointer(3, TGL_FLOAT, 0, _verts);
+	tglDrawArrays(TGL_QUADS, 0, 4);
+	tglDisableClientState(TGL_VERTEX_ARRAY);
 }
 
 void TinyGLRenderer::flipBuffer() {


Commit: 42bc152f1ae35916ee940420240d009b9a988cdd
    https://github.com/scummvm/scummvm/commit/42bc152f1ae35916ee940420240d009b9a988cdd
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:40+01:00

Commit Message:
FREESCAPE: rewrite drawRect2D to use DrawArrays

Changed paths:
    engines/freescape/gfx_tinygl.cpp


diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 85acf6b6aa1..1d79ee22d7d 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -129,13 +129,14 @@ void TinyGLRenderer::drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint
 		tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE_MINUS_SRC_ALPHA);
 	}
 
-	tglBegin(TGL_TRIANGLE_STRIP);
-	tglVertex3f(rect.left, rect.bottom, 0.0f);
-	tglVertex3f(rect.right, rect.bottom, 0.0f);
-	tglVertex3f(rect.left, rect.top, 0.0f);
-	tglVertex3f(rect.right, rect.top, 0.0f);
-	tglEnd();
-
+	tglEnableClientState(TGL_VERTEX_ARRAY);
+	copyToVertexArray(0, Math::Vector3d(rect.left, rect.bottom, 0.0));
+	copyToVertexArray(1, Math::Vector3d(rect.right, rect.bottom, 0.0));
+	copyToVertexArray(2, Math::Vector3d(rect.left, rect.top, 0.0));
+	copyToVertexArray(3, Math::Vector3d(rect.right, rect.top, 0.0));
+	tglVertexPointer(3, TGL_FLOAT, 0, _verts);
+	tglDrawArrays(TGL_TRIANGLE_STRIP, 0, 4);
+	tglDisableClientState(TGL_VERTEX_ARRAY);
 	tglDisable(TGL_BLEND);
 }
 


Commit: 5730f1106ddb1463e8c9e31792c19caf6c4d88d6
    https://github.com/scummvm/scummvm/commit/5730f1106ddb1463e8c9e31792c19caf6c4d88d6
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:40+01:00

Commit Message:
FREESCAPE: moved common code for rendering to Renderer

Changed paths:
    engines/freescape/gfx.cpp
    engines/freescape/gfx.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/gfx_tinygl.h


diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index 55efdd8f6c6..b333b3bcadb 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -24,6 +24,7 @@
 #include "engines/util.h"
 
 #include "freescape/gfx.h"
+#include "freescape/objects/object.h"
 
 namespace Freescape {
 
@@ -95,6 +96,309 @@ void Renderer::computeScreenViewport() {
 	_screenViewport = Common::Rect(_screenW, _screenH);
 }
 
+void Renderer::renderPyramid(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours, int type) {
+	Math::Vector3d vertices[8] = { origin, origin, origin, origin, origin, origin, origin, origin };
+	switch (type) {
+	default:
+		error("Invalid pyramid type: %d", type);
+	case kEastPyramidType:
+		vertices[0] += Math::Vector3d(0, 0, size.z());
+		vertices[1] += Math::Vector3d(0, size.y(), size.z());
+		vertices[2] += Math::Vector3d(0, size.y(), 0);
+
+		vertices[4] += Math::Vector3d(size.x(), (*ordinates)[0], (*ordinates)[3]);
+		vertices[5] += Math::Vector3d(size.x(), (*ordinates)[2], (*ordinates)[3]);
+		vertices[6] += Math::Vector3d(size.x(), (*ordinates)[2], (*ordinates)[1]);
+		vertices[7] += Math::Vector3d(size.x(), (*ordinates)[0], (*ordinates)[1]);
+		break;
+	case kWestPyramidType:
+
+		vertices[0] += Math::Vector3d(size.x(), 0, 0);
+		vertices[1] += Math::Vector3d(size.x(), size.y(), 0);
+		vertices[2] += Math::Vector3d(size.x(), size.y(), size.z());
+		vertices[3] += Math::Vector3d(size.x(), 0, size.z());
+
+		vertices[4] += Math::Vector3d(0, (*ordinates)[0], (*ordinates)[1]);
+		vertices[5] += Math::Vector3d(0, (*ordinates)[2], (*ordinates)[1]);
+		vertices[6] += Math::Vector3d(0, (*ordinates)[2], (*ordinates)[3]);
+		vertices[7] += Math::Vector3d(0, (*ordinates)[0], (*ordinates)[3]);
+		break;
+
+	case kUpPyramidType:
+		vertices[1] += Math::Vector3d(size.x(), 0, 0);
+		vertices[2] += Math::Vector3d(size.x(), 0, size.z());
+		vertices[3] += Math::Vector3d(0, 0, size.z());
+
+		vertices[4] += Math::Vector3d((*ordinates)[0], size.y(), (*ordinates)[1]);
+		vertices[5] += Math::Vector3d((*ordinates)[2], size.y(), (*ordinates)[1]);
+		vertices[6] += Math::Vector3d((*ordinates)[2], size.y(), (*ordinates)[3]);
+		vertices[7] += Math::Vector3d((*ordinates)[0], size.y(), (*ordinates)[3]);
+		break;
+
+	case kDownPyramidType:
+
+		vertices[0] += Math::Vector3d(size.x(), size.y(), 0);
+		vertices[1] += Math::Vector3d(0, size.y(), 0);
+		vertices[2] += Math::Vector3d(0, size.y(), size.z());
+		vertices[3] += Math::Vector3d(size.x(), size.y(), size.z());
+
+		vertices[4] += Math::Vector3d((*ordinates)[2], 0, (*ordinates)[1]);
+		vertices[5] += Math::Vector3d((*ordinates)[0], 0, (*ordinates)[1]);
+		vertices[6] += Math::Vector3d((*ordinates)[0], 0, (*ordinates)[3]);
+		vertices[7] += Math::Vector3d((*ordinates)[2], 0, (*ordinates)[3]);
+		break;
+
+	case kNorthPyramidType:
+		vertices[0] += Math::Vector3d(0, size.y(), 0);
+		vertices[1] += Math::Vector3d(size.x(), size.y(), 0);
+		vertices[2] += Math::Vector3d(size.x(), 0, 0);
+
+		vertices[4] += Math::Vector3d((*ordinates)[0], (*ordinates)[3], size.z());
+		vertices[5] += Math::Vector3d((*ordinates)[2], (*ordinates)[3], size.z());
+		vertices[6] += Math::Vector3d((*ordinates)[2], (*ordinates)[1], size.z());
+		vertices[7] += Math::Vector3d((*ordinates)[0], (*ordinates)[1], size.z());
+		break;
+	case kSouthPyramidType:
+		vertices[0] += Math::Vector3d(0, 0, size.z());
+		vertices[1] += Math::Vector3d(size.x(), 0, size.z());
+		vertices[2] += Math::Vector3d(size.x(), size.y(), size.z());
+
+		vertices[3] += Math::Vector3d(0, size.y(), size.z());
+		vertices[4] += Math::Vector3d((*ordinates)[0], (*ordinates)[1], 0);
+		vertices[5] += Math::Vector3d((*ordinates)[2], (*ordinates)[1], 0);
+		vertices[6] += Math::Vector3d((*ordinates)[2], (*ordinates)[3], 0);
+		vertices[7] += Math::Vector3d((*ordinates)[0], (*ordinates)[3], 0);
+		break;
+	}
+
+	Common::Array<Math::Vector3d> face;
+	uint8 r, g, b;
+	if (getRGBAt((*colours)[0], r, g, b)) {
+		useColor(r, g, b);
+
+		face.push_back(vertices[4]);
+		face.push_back(vertices[5]);
+		face.push_back(vertices[1]);
+		face.push_back(vertices[0]);
+
+		renderFace(face);
+		face.clear();
+	}
+
+	if (getRGBAt((*colours)[1], r, g, b)) {
+		useColor(r, g, b);
+
+		face.push_back(vertices[5]);
+		face.push_back(vertices[6]);
+		face.push_back(vertices[2]);
+		face.push_back(vertices[1]);
+
+		renderFace(face);
+		face.clear();
+	}
+
+	if (getRGBAt((*colours)[2], r, g, b)) {
+		useColor(r, g, b);
+
+		face.push_back(vertices[6]);
+		face.push_back(vertices[7]);
+		face.push_back(vertices[3]);
+		face.push_back(vertices[2]);
+		renderFace(face);
+		face.clear();
+	}
+
+	if (getRGBAt((*colours)[3], r, g, b)) {
+		useColor(r, g, b);
+
+		face.push_back(vertices[7]);
+		face.push_back(vertices[4]);
+		face.push_back(vertices[0]);
+		face.push_back(vertices[3]);
+
+		renderFace(face);
+		face.clear();
+	}
+
+	if (getRGBAt((*colours)[4], r, g, b)) {
+		useColor(r, g, b);
+
+		face.push_back(vertices[0]);
+		face.push_back(vertices[1]);
+		face.push_back(vertices[2]);
+		face.push_back(vertices[3]);
+		renderFace(face);
+		face.clear();
+	}
+
+	if (getRGBAt((*colours)[5], r, g, b)) {
+		useColor(r, g, b);
+
+		face.push_back(vertices[7]);
+		face.push_back(vertices[6]);
+		face.push_back(vertices[5]);
+		face.push_back(vertices[4]);
+		renderFace(face);
+	}
+}
+
+void Renderer::renderCube(const Math::Vector3d &origin, const Math::Vector3d &size, Common::Array<uint8> *colours) {
+	uint8 r, g, b;
+	Common::Array<Math::Vector3d> face;
+
+	if (getRGBAt((*colours)[0], r, g, b)) {
+		useColor(r, g, b);
+		face.push_back(origin);
+		face.push_back(Math::Vector3d(origin.x(), origin.y(), origin.z() + size.z()));
+		face.push_back(Math::Vector3d(origin.x(), origin.y() + size.y(), origin.z() + size.z()));
+		face.push_back(Math::Vector3d(origin.x(), origin.y() + size.y(), origin.z()));
+		renderFace(face);
+	}
+
+	if (getRGBAt((*colours)[1], r, g, b)) {
+		useColor(r, g, b);
+		face.clear();
+		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y() + size.y(), origin.z()));
+		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z()));
+		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y(), origin.z() + size.z()));
+		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y(), origin.z()));
+		renderFace(face);
+	}
+
+	if (getRGBAt((*colours)[2], r, g, b)) {
+		useColor(r, g, b);
+		face.clear();
+		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y(), origin.z()));
+		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y(), origin.z() + size.z()));
+		face.push_back(Math::Vector3d(origin.x(), origin.y(), origin.z() + size.z()));
+		face.push_back(Math::Vector3d(origin.x(), origin.y(), origin.z()));
+		renderFace(face);
+	}
+
+	if (getRGBAt((*colours)[3], r, g, b)) {
+		useColor(r, g, b);
+		face.clear();
+		face.push_back(Math::Vector3d(origin.x(), origin.y() + size.y(), origin.z()));
+		face.push_back(Math::Vector3d(origin.x(), origin.y() + size.y(), origin.z() + size.z()));
+		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z()));
+		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y() + size.y(), origin.z()));
+		renderFace(face);
+	}
+
+	if (getRGBAt((*colours)[4], r, g, b)) {
+		useColor(r, g, b);
+		face.clear();
+		face.push_back(Math::Vector3d(origin.x(), origin.y() + size.y(), origin.z()));
+		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y() + size.y(), origin.z()));
+		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y(), origin.z()));
+		face.push_back(origin);
+		renderFace(face);
+	}
+
+	if (getRGBAt((*colours)[5], r, g, b)) {
+		useColor(r, g, b);
+		face.clear();
+		face.push_back(Math::Vector3d(origin.x(), origin.y(), origin.z() + size.z()));
+		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y(), origin.z() + size.z()));
+		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z()));
+		face.push_back(Math::Vector3d(origin.x(), origin.y() + size.y(), origin.z() + size.z()));
+		renderFace(face);
+	}
+}
+
+void Renderer::renderRectangle(const Math::Vector3d &origin, const Math::Vector3d &size, Common::Array<uint8> *colours) {
+
+	assert(size.x() == 0 || size.y() == 0 || size.z() == 0);
+	polygonOffset(true);
+
+	float dx, dy, dz;
+	uint8 r, g, b;
+	Common::Array<Math::Vector3d> vertices;
+	for (int i = 0; i < 2; i++) {
+
+		// debug("rec color: %d", (*colours)[i]);
+		if (getRGBAt((*colours)[i], r, g, b)) {
+			useColor(r, g, b);
+			vertices.clear();
+			vertices.push_back(Math::Vector3d(origin.x(), origin.y(), origin.z()));
+
+			dx = dy = dz = 0.0;
+			if (size.x() == 0) {
+				dy = size.y();
+			} else if (size.y() == 0) {
+				dx = size.x();
+			} else if (size.z() == 0) {
+				dx = size.x();
+			}
+
+			vertices.push_back(Math::Vector3d(origin.x() + dx, origin.y() + dy, origin.z() + dz));
+			vertices.push_back(Math::Vector3d(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z()));
+			renderFace(vertices);
+
+			vertices.clear();
+			vertices.push_back(Math::Vector3d(origin.x(), origin.y(), origin.z()));
+
+			dx = dy = dz = 0.0;
+			if (size.x() == 0) {
+				dz = size.z();
+			} else if (size.y() == 0) {
+				dz = size.z();
+			} else if (size.z() == 0) {
+				dy = size.y();
+			}
+
+			vertices.push_back(Math::Vector3d(origin.x() + dx, origin.y() + dy, origin.z() + dz));
+			vertices.push_back(Math::Vector3d(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z()));
+			renderFace(vertices);
+		}
+	}
+	polygonOffset(false);
+}
+
+void Renderer::renderPolygon(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours) {
+	uint8 r, g, b;
+	if (ordinates->size() % 3 > 0 && ordinates->size() > 0)
+		error("Invalid polygon with size %f %f %f and ordinates %d", size.x(), size.y(), size.z(), ordinates->size());
+
+	Common::Array<Math::Vector3d> vertices;
+	polygonOffset(true);
+
+	if (ordinates->size() == 6) {                 // Line
+		assert(getRGBAt((*colours)[0], r, g, b)); // It will never return false?
+		useColor(r, g, b);
+		for (uint i = 0; i < ordinates->size(); i = i + 3)
+			vertices.push_back(Math::Vector3d((*ordinates)[i], (*ordinates)[i + 1], (*ordinates)[i + 2]));
+		renderFace(vertices);
+
+		vertices.clear();
+		assert(getRGBAt((*colours)[1], r, g, b)); // It will never return false?
+		useColor(r, g, b);
+		for (int i = ordinates->size(); i > 0; i = i - 3)
+			vertices.push_back(Math::Vector3d((*ordinates)[i - 3], (*ordinates)[i - 2], (*ordinates)[i - 1]));
+		renderFace(vertices);
+
+	} else {
+		if (getRGBAt((*colours)[0], r, g, b)) {
+			useColor(r, g, b);
+			for (uint i = 0; i < ordinates->size(); i = i + 3) {
+				vertices.push_back(Math::Vector3d((*ordinates)[i], (*ordinates)[i + 1], (*ordinates)[i + 2]));
+			}
+			renderFace(vertices);
+		}
+		vertices.clear();
+		if (getRGBAt((*colours)[1], r, g, b)) {
+			useColor(r, g, b);
+			for (int i = ordinates->size(); i > 0; i = i - 3) {
+				vertices.push_back(Math::Vector3d((*ordinates)[i - 3], (*ordinates)[i - 2], (*ordinates)[i - 1]));
+			}
+			renderFace(vertices);
+		}
+	}
+
+	polygonOffset(false);
+}
+
+
 Renderer *createRenderer(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode) {
 	Graphics::PixelFormat pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
 	// This code will allow different renderers, but right now, it only support TinyGL
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 2887ebfebd6..545d6b811af 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -67,6 +67,8 @@ public:
 	 *  Swap the buffers, making the drawn screen visible
 	 */
 	virtual void flipBuffer() {}
+	virtual void useColor(uint8 r, uint8 g, uint8 b) = 0;
+	virtual void polygonOffset(bool enabled) = 0;
 
 	virtual Texture *createTexture(const Graphics::Surface *surface) = 0;
 	virtual void freeTexture(Texture *texture) = 0;
@@ -75,10 +77,10 @@ public:
 
 	virtual void renderCrossair(byte color, const Common::Point position) = 0;
 	virtual void renderShoot(byte color, const Common::Point position) = 0;
-	virtual void renderCube(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) = 0;
-	virtual void renderRectangle(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) = 0;
-	virtual void renderPolygon(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours) = 0;
-	virtual void renderPyramid(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours, int type) = 0;
+	virtual void renderCube(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours);
+	virtual void renderRectangle(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours);
+	virtual void renderPolygon(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours);
+	virtual void renderPyramid(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours, int type);
 	virtual void renderFace(const Common::Array<Math::Vector3d> &vertices) = 0;
 
 	virtual void setSkyColor(uint8 color) = 0;
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 1d79ee22d7d..8b5721b2b85 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -237,308 +237,18 @@ void TinyGLRenderer::renderFace(const Common::Array<Math::Vector3d> &vertices) {
 	tglDisableClientState(TGL_VERTEX_ARRAY);
 }
 
-void TinyGLRenderer::renderPolygon(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours) {
-	uint8 r, g, b;
-	if (ordinates->size() % 3 > 0 && ordinates->size() > 0)
-		error("Invalid polygon with size %f %f %f and ordinates %d", size.x(), size.y(), size.z(), ordinates->size());
-
-	Common::Array<Math::Vector3d> vertices;
-	tglEnable(TGL_POLYGON_OFFSET_FILL);
-	tglPolygonOffset(-2.0f, 1.f);
-
-	if (ordinates->size() == 6) {                 // Line
-		assert(getRGBAt((*colours)[0], r, g, b)); // It will never return false?
-		tglColor3ub(r, g, b);
-		for (uint i = 0; i < ordinates->size(); i = i + 3)
-			vertices.push_back(Math::Vector3d((*ordinates)[i], (*ordinates)[i + 1], (*ordinates)[i + 2]));
-		renderFace(vertices);
-
-		vertices.clear();
-		assert(getRGBAt((*colours)[1], r, g, b)); // It will never return false?
-		tglColor3ub(r, g, b);
-		for (int i = ordinates->size(); i > 0; i = i - 3)
-			vertices.push_back(Math::Vector3d((*ordinates)[i - 3], (*ordinates)[i - 2], (*ordinates)[i - 1]));
-		renderFace(vertices);
-
+void TinyGLRenderer::polygonOffset(bool enabled) {
+	if (enabled) {
+		tglEnable(TGL_POLYGON_OFFSET_FILL);
+		tglPolygonOffset(-2.0f, 1.0f);
 	} else {
-		if (getRGBAt((*colours)[0], r, g, b)) {
-			tglColor3ub(r, g, b);
-			for (uint i = 0; i < ordinates->size(); i = i + 3) {
-				vertices.push_back(Math::Vector3d((*ordinates)[i], (*ordinates)[i + 1], (*ordinates)[i + 2]));
-			}
-			renderFace(vertices);
-		}
-		vertices.clear();
-		if (getRGBAt((*colours)[1], r, g, b)) {
-			tglColor3ub(r, g, b);
-			for (int i = ordinates->size(); i > 0; i = i - 3) {
-				vertices.push_back(Math::Vector3d((*ordinates)[i - 3], (*ordinates)[i - 2], (*ordinates)[i - 1]));
-			}
-			renderFace(vertices);
-		}
-	}
-
-	tglPolygonOffset(0, 0);
-	tglDisable(TGL_POLYGON_OFFSET_FILL);
-}
-
-void TinyGLRenderer::renderRectangle(const Math::Vector3d &origin, const Math::Vector3d &size, Common::Array<uint8> *colours) {
-
-	assert(size.x() == 0 || size.y() == 0 || size.z() == 0);
-	tglEnable(TGL_POLYGON_OFFSET_FILL);
-	tglPolygonOffset(-2.0f, 1.0f);
-
-	float dx, dy, dz;
-	uint8 r, g, b;
-	Common::Array<Math::Vector3d> vertices;
-	for (int i = 0; i < 2; i++) {
-
-		// debug("rec color: %d", (*colours)[i]);
-		if (getRGBAt((*colours)[i], r, g, b)) {
-			tglColor3ub(r, g, b);
-			vertices.clear();
-			vertices.push_back(Math::Vector3d(origin.x(), origin.y(), origin.z()));
-
-			dx = dy = dz = 0.0;
-			if (size.x() == 0) {
-				dy = size.y();
-			} else if (size.y() == 0) {
-				dx = size.x();
-			} else if (size.z() == 0) {
-				dx = size.x();
-			}
-
-			vertices.push_back(Math::Vector3d(origin.x() + dx, origin.y() + dy, origin.z() + dz));
-			vertices.push_back(Math::Vector3d(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z()));
-			renderFace(vertices);
-
-			vertices.clear();
-			vertices.push_back(Math::Vector3d(origin.x(), origin.y(), origin.z()));
-
-			dx = dy = dz = 0.0;
-			if (size.x() == 0) {
-				dz = size.z();
-			} else if (size.y() == 0) {
-				dz = size.z();
-			} else if (size.z() == 0) {
-				dy = size.y();
-			}
-
-			vertices.push_back(Math::Vector3d(origin.x() + dx, origin.y() + dy, origin.z() + dz));
-			vertices.push_back(Math::Vector3d(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z()));
-			renderFace(vertices);
-		}
+		tglPolygonOffset(0, 0);
+		tglDisable(TGL_POLYGON_OFFSET_FILL);
 	}
-
-	tglPolygonOffset(0, 0);
-	tglDisable(TGL_POLYGON_OFFSET_FILL);
 }
 
-void TinyGLRenderer::renderPyramid(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours, int type) {
-	Math::Vector3d vertices[8] = { origin, origin, origin, origin, origin, origin, origin, origin };
-	switch (type) {
-	default:
-		error("Invalid pyramid type: %d", type);
-	case kEastPyramidType:
-		vertices[0] += Math::Vector3d(0, 0, size.z());
-		vertices[1] += Math::Vector3d(0, size.y(), size.z());
-		vertices[2] += Math::Vector3d(0, size.y(), 0);
-
-		vertices[4] += Math::Vector3d(size.x(), (*ordinates)[0], (*ordinates)[3]);
-		vertices[5] += Math::Vector3d(size.x(), (*ordinates)[2], (*ordinates)[3]);
-		vertices[6] += Math::Vector3d(size.x(), (*ordinates)[2], (*ordinates)[1]);
-		vertices[7] += Math::Vector3d(size.x(), (*ordinates)[0], (*ordinates)[1]);
-		break;
-	case kWestPyramidType:
-
-		vertices[0] += Math::Vector3d(size.x(), 0, 0);
-		vertices[1] += Math::Vector3d(size.x(), size.y(), 0);
-		vertices[2] += Math::Vector3d(size.x(), size.y(), size.z());
-		vertices[3] += Math::Vector3d(size.x(), 0, size.z());
-
-		vertices[4] += Math::Vector3d(0, (*ordinates)[0], (*ordinates)[1]);
-		vertices[5] += Math::Vector3d(0, (*ordinates)[2], (*ordinates)[1]);
-		vertices[6] += Math::Vector3d(0, (*ordinates)[2], (*ordinates)[3]);
-		vertices[7] += Math::Vector3d(0, (*ordinates)[0], (*ordinates)[3]);
-		break;
-
-	case kUpPyramidType:
-		vertices[1] += Math::Vector3d(size.x(), 0, 0);
-		vertices[2] += Math::Vector3d(size.x(), 0, size.z());
-		vertices[3] += Math::Vector3d(0, 0, size.z());
-
-		vertices[4] += Math::Vector3d((*ordinates)[0], size.y(), (*ordinates)[1]);
-		vertices[5] += Math::Vector3d((*ordinates)[2], size.y(), (*ordinates)[1]);
-		vertices[6] += Math::Vector3d((*ordinates)[2], size.y(), (*ordinates)[3]);
-		vertices[7] += Math::Vector3d((*ordinates)[0], size.y(), (*ordinates)[3]);
-		break;
-
-	case kDownPyramidType:
-
-		vertices[0] += Math::Vector3d(size.x(), size.y(), 0);
-		vertices[1] += Math::Vector3d(0, size.y(), 0);
-		vertices[2] += Math::Vector3d(0, size.y(), size.z());
-		vertices[3] += Math::Vector3d(size.x(), size.y(), size.z());
-
-		vertices[4] += Math::Vector3d((*ordinates)[2], 0, (*ordinates)[1]);
-		vertices[5] += Math::Vector3d((*ordinates)[0], 0, (*ordinates)[1]);
-		vertices[6] += Math::Vector3d((*ordinates)[0], 0, (*ordinates)[3]);
-		vertices[7] += Math::Vector3d((*ordinates)[2], 0, (*ordinates)[3]);
-		break;
-
-	case kNorthPyramidType:
-		vertices[0] += Math::Vector3d(0, size.y(), 0);
-		vertices[1] += Math::Vector3d(size.x(), size.y(), 0);
-		vertices[2] += Math::Vector3d(size.x(), 0, 0);
-
-		vertices[4] += Math::Vector3d((*ordinates)[0], (*ordinates)[3], size.z());
-		vertices[5] += Math::Vector3d((*ordinates)[2], (*ordinates)[3], size.z());
-		vertices[6] += Math::Vector3d((*ordinates)[2], (*ordinates)[1], size.z());
-		vertices[7] += Math::Vector3d((*ordinates)[0], (*ordinates)[1], size.z());
-		break;
-	case kSouthPyramidType:
-		vertices[0] += Math::Vector3d(0, 0, size.z());
-		vertices[1] += Math::Vector3d(size.x(), 0, size.z());
-		vertices[2] += Math::Vector3d(size.x(), size.y(), size.z());
-
-		vertices[3] += Math::Vector3d(0, size.y(), size.z());
-		vertices[4] += Math::Vector3d((*ordinates)[0], (*ordinates)[1], 0);
-		vertices[5] += Math::Vector3d((*ordinates)[2], (*ordinates)[1], 0);
-		vertices[6] += Math::Vector3d((*ordinates)[2], (*ordinates)[3], 0);
-		vertices[7] += Math::Vector3d((*ordinates)[0], (*ordinates)[3], 0);
-		break;
-	}
-
-	Common::Array<Math::Vector3d> face;
-	uint8 r, g, b;
-	if (getRGBAt((*colours)[0], r, g, b)) {
-		tglColor3ub(r, g, b);
-		face.push_back(vertices[4]);
-		face.push_back(vertices[5]);
-		face.push_back(vertices[1]);
-		face.push_back(vertices[0]);
-
-		renderFace(face);
-		face.clear();
-	}
-
-	if (getRGBAt((*colours)[1], r, g, b)) {
-		tglColor3ub(r, g, b);
-		face.push_back(vertices[5]);
-		face.push_back(vertices[6]);
-		face.push_back(vertices[2]);
-		face.push_back(vertices[1]);
-
-		renderFace(face);
-		face.clear();
-	}
-
-	if (getRGBAt((*colours)[2], r, g, b)) {
-		tglColor3ub(r, g, b);
-
-		face.push_back(vertices[6]);
-		face.push_back(vertices[7]);
-		face.push_back(vertices[3]);
-		face.push_back(vertices[2]);
-		renderFace(face);
-		face.clear();
-	}
-
-	if (getRGBAt((*colours)[3], r, g, b)) {
-		tglColor3ub(r, g, b);
-		face.push_back(vertices[7]);
-		face.push_back(vertices[4]);
-		face.push_back(vertices[0]);
-		face.push_back(vertices[3]);
-
-		renderFace(face);
-		face.clear();
-	}
-
-	if (getRGBAt((*colours)[4], r, g, b)) {
-		tglColor3ub(r, g, b);
-
-		face.push_back(vertices[0]);
-		face.push_back(vertices[1]);
-		face.push_back(vertices[2]);
-		face.push_back(vertices[3]);
-		renderFace(face);
-		face.clear();
-	}
-
-	if (getRGBAt((*colours)[5], r, g, b)) {
-		tglColor3ub(r, g, b);
-
-		face.push_back(vertices[7]);
-		face.push_back(vertices[6]);
-		face.push_back(vertices[5]);
-		face.push_back(vertices[4]);
-		renderFace(face);
-	}
-}
-
-void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector3d &size, Common::Array<uint8> *colours) {
-	uint8 r, g, b;
-	Common::Array<Math::Vector3d> face;
-
-	if (getRGBAt((*colours)[0], r, g, b)) {
-		tglColor3ub(r, g, b);
-		face.push_back(origin);
-		face.push_back(Math::Vector3d(origin.x(), origin.y(), origin.z() + size.z()));
-		face.push_back(Math::Vector3d(origin.x(), origin.y() + size.y(), origin.z() + size.z()));
-		face.push_back(Math::Vector3d(origin.x(), origin.y() + size.y(), origin.z()));
-		renderFace(face);
-	}
-
-	if (getRGBAt((*colours)[1], r, g, b)) {
-		tglColor3ub(r, g, b);
-		face.clear();
-		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y() + size.y(), origin.z()));
-		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z()));
-		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y(), origin.z() + size.z()));
-		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y(), origin.z()));
-		renderFace(face);
-	}
-
-	if (getRGBAt((*colours)[2], r, g, b)) {
-		tglColor3ub(r, g, b);
-		face.clear();
-		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y(), origin.z()));
-		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y(), origin.z() + size.z()));
-		face.push_back(Math::Vector3d(origin.x(), origin.y(), origin.z() + size.z()));
-		face.push_back(Math::Vector3d(origin.x(), origin.y(), origin.z()));
-		renderFace(face);
-	}
-
-	if (getRGBAt((*colours)[3], r, g, b)) {
-		tglColor3ub(r, g, b);
-		face.clear();
-		face.push_back(Math::Vector3d(origin.x(), origin.y() + size.y(), origin.z()));
-		face.push_back(Math::Vector3d(origin.x(), origin.y() + size.y(), origin.z() + size.z()));
-		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z()));
-		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y() + size.y(), origin.z()));
-		renderFace(face);
-	}
-
-	if (getRGBAt((*colours)[4], r, g, b)) {
-		tglColor3ub(r, g, b);
-		face.clear();
-		face.push_back(Math::Vector3d(origin.x(), origin.y() + size.y(), origin.z()));
-		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y() + size.y(), origin.z()));
-		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y(), origin.z()));
-		face.push_back(origin);
-		renderFace(face);
-	}
-
-	if (getRGBAt((*colours)[5], r, g, b)) {
-		tglColor3ub(r, g, b);
-		face.clear();
-		face.push_back(Math::Vector3d(origin.x(), origin.y(), origin.z() + size.z()));
-		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y(), origin.z() + size.z()));
-		face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z()));
-		face.push_back(Math::Vector3d(origin.x(), origin.y() + size.y(), origin.z() + size.z()));
-		renderFace(face);
-	}
+void TinyGLRenderer::useColor(uint8 r, uint8 g, uint8 b) {
+	tglColor3ub(r, g, b);
 }
 
 void TinyGLRenderer::setSkyColor(uint8 color) {
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index 90ecc9d25a0..a9ad29e2f77 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -51,6 +51,9 @@ public:
 	virtual void positionCamera(const Math::Vector3d &pos, const Math::Vector3d &interest) override;
 	virtual void updateProjectionMatrix(float fov, float nearClipPlane, float farClipPlane) override;
 
+	virtual void useColor(uint8 r, uint8 g, uint8 b) override;
+	virtual void polygonOffset(bool enabled) override;
+
 	Texture *createTexture(const Graphics::Surface *surface) override;
 	void freeTexture(Texture *texture) override;
 	virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture) override;
@@ -58,10 +61,6 @@ public:
 
 	virtual void renderCrossair(byte color, const Common::Point position) override;
 	virtual void renderShoot(byte color, const Common::Point position) override;
-	virtual void renderCube(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) override;
-	virtual void renderRectangle(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) override;
-	virtual void renderPolygon(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours) override;
-	virtual void renderPyramid(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours, int type) override;
 	virtual void renderFace(const Common::Array<Math::Vector3d> &vertices) override;
 
 	virtual void flipBuffer() override;


Commit: bcedbac36ab33ab66187def02a979c98f7be4d6c
    https://github.com/scummvm/scummvm/commit/bcedbac36ab33ab66187def02a979c98f7be4d6c
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:41+01:00

Commit Message:
FREESCAPE: preliminar code for OpenGL renderer

Changed paths:
  A engines/freescape/gfx_opengl.cpp
  A engines/freescape/gfx_opengl.h
  A engines/freescape/gfx_opengl_texture.cpp
  A engines/freescape/gfx_opengl_texture.h
    engines/freescape/gfx.cpp
    engines/freescape/gfx.h
    engines/freescape/module.mk


diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index b333b3bcadb..15dac19e403 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -19,10 +19,16 @@
  *
  */
 
+#include "common/config-manager.h"
+
 #include "gui/message.h"
 #include "graphics/renderer.h"
 #include "engines/util.h"
 
+#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS) || defined(USE_GLES2)
+#include "graphics/opengl/context.h"
+#endif
+
 #include "freescape/gfx.h"
 #include "freescape/objects/object.h"
 
@@ -400,11 +406,36 @@ void Renderer::renderPolygon(const Math::Vector3d &origin, const Math::Vector3d
 
 
 Renderer *createRenderer(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode) {
+	Common::String rendererConfig = ConfMan.get("renderer");
 	Graphics::PixelFormat pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
-	// This code will allow different renderers, but right now, it only support TinyGL
-	Graphics::RendererType desiredRendererType = Graphics::kRendererTypeTinyGL;
+	Graphics::RendererType desiredRendererType = Graphics::Renderer::parseTypeCode(rendererConfig);
+	Graphics::RendererType matchingRendererType = Graphics::Renderer::getBestMatchingAvailableType(desiredRendererType,
+#if defined(USE_OPENGL_GAME)
+						Graphics::kRendererTypeOpenGL |
+#endif
+#if defined(USE_TINYGL)
+						Graphics::kRendererTypeTinyGL |
+#endif
+						0);
+
+	bool isAccelerated = matchingRendererType != Graphics::kRendererTypeTinyGL;
+
+	if (isAccelerated) {
+		initGraphics3d(screenW, screenH);
+	} else {
+		initGraphics(screenW, screenH, &pixelFormat);
+	}
 
-	initGraphics(screenW, screenH, &pixelFormat);
+	if (matchingRendererType != desiredRendererType && desiredRendererType != Graphics::kRendererTypeDefault) {
+		// Display a warning if unable to use the desired renderer
+		warning("Unable to create a '%s' renderer", rendererConfig.c_str());
+	}
+
+	#if defined(USE_OPENGL_GAME) && !defined(USE_GLES2)
+		if (matchingRendererType == Graphics::kRendererTypeOpenGL) {
+			return CreateGfxOpenGL(system, screenW, screenH, renderMode);
+		}
+	#endif
 
 	#if defined(USE_TINYGL)
 	if (desiredRendererType == Graphics::kRendererTypeTinyGL) {
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 545d6b811af..214fb6cd068 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -150,8 +150,8 @@ private:
 	uint _startFrameTime;
 };
 
-Renderer *CreateGfxOpenGL(OSystem *system, Common::RenderMode renderMode);
-Renderer *CreateGfxOpenGLShader(OSystem *system, Common::RenderMode renderMode);
+Renderer *CreateGfxOpenGL(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode);
+Renderer *CreateGfxOpenGLShader(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode);
 Renderer *CreateGfxTinyGL(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode);
 Renderer *createRenderer(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode);
 
diff --git a/engines/freescape/gfx_opengl.cpp b/engines/freescape/gfx_opengl.cpp
new file mode 100644
index 00000000000..82fa5bd6290
--- /dev/null
+++ b/engines/freescape/gfx_opengl.cpp
@@ -0,0 +1,298 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+// Based on Phantasma code by Thomas Harte (2013)
+
+#include "common/config-manager.h"
+#include "common/math.h"
+#include "common/system.h"
+#include "math/glmath.h"
+
+#include "freescape/objects/object.h"
+#include "freescape/gfx_opengl.h"
+#include "freescape/gfx_opengl_texture.h"
+
+namespace Freescape {
+
+Renderer *CreateGfxOpenGL(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode) {
+	return new OpenGLRenderer(system, screenW, screenH, renderMode);
+}
+
+OpenGLRenderer::OpenGLRenderer(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode) : Renderer(system, screenW, screenH, renderMode) {
+	_verts = (Vertex*) malloc(sizeof(Vertex) * 20);
+}
+
+OpenGLRenderer::~OpenGLRenderer() {
+	free(_verts);
+}
+
+Texture *OpenGLRenderer::createTexture(const Graphics::Surface *surface) {
+	return new OpenGLTexture(surface);
+}
+
+void OpenGLRenderer::freeTexture(Texture *texture) {
+	delete texture;
+}
+
+void OpenGLRenderer::init() {
+
+	computeScreenViewport();
+
+	glMatrixMode(GL_PROJECTION);
+	glLoadIdentity();
+
+	glMatrixMode(GL_MODELVIEW);
+	glLoadIdentity();
+
+	glDisable(GL_LIGHTING);
+	glDisable(GL_TEXTURE_2D);
+	glEnable(GL_DEPTH_TEST);
+}
+
+void OpenGLRenderer::setViewport(const Common::Rect &rect) {
+	glViewport(rect.left, g_system->getHeight() - rect.bottom, rect.width(), rect.height());
+}
+
+void OpenGLRenderer::clear() {
+	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+	glColor3f(1.0f, 1.0f, 1.0f);
+}
+
+void OpenGLRenderer::drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture) {
+	OpenGLTexture *glTexture = static_cast<OpenGLTexture *>(texture);
+
+	const float tLeft = textureRect.left / (float)glTexture->_internalWidth;
+	const float tWidth = textureRect.width() / (float)glTexture->_internalWidth;
+	const float tTop = textureRect.top / (float)glTexture->_internalHeight;
+	const float tHeight = textureRect.height() / (float)glTexture->_internalHeight;
+
+	float sLeft = screenRect.left;
+	float sTop = screenRect.top;
+	float sRight = sLeft + screenRect.width();
+	float sBottom = sTop + screenRect.height();
+
+	if (glTexture->_upsideDown) {
+		SWAP(sTop, sBottom);
+    }
+
+
+	//glEnable(GL_TEXTURE_2D);
+	glColor4f(1.0, 1.0, 1.0, 1.0);
+	glDepthMask(GL_FALSE);
+
+	glBindTexture(GL_TEXTURE_2D, glTexture->_id);
+	glBegin(GL_TRIANGLE_STRIP);
+	glTexCoord2f(tLeft, tTop + tHeight);
+	glVertex3f(sLeft + 0, sBottom, 1.0f);
+
+	glTexCoord2f(tLeft + tWidth, tTop + tHeight);
+	glVertex3f(sRight, sBottom, 1.0f);
+
+	glTexCoord2f(tLeft, tTop);
+	glVertex3f(sLeft + 0, sTop + 0, 1.0f);
+
+	glTexCoord2f(tLeft + tWidth, tTop);
+	glVertex3f(sRight, sTop + 0, 1.0f);
+	glEnd();
+
+	glDisable(GL_BLEND);
+	glDepthMask(GL_TRUE);
+}
+
+void OpenGLRenderer::updateProjectionMatrix(float fov, float nearClipPlane, float farClipPlane) {
+	glMatrixMode(GL_PROJECTION);
+	glLoadIdentity();
+
+	float aspectRatio = _screenW / (float)_screenH;
+
+	float xmaxValue = nearClipPlane * tan(Common::deg2rad(fov) / 2);
+	float ymaxValue = xmaxValue / aspectRatio;
+	// debug("max values: %f %f", xmaxValue, ymaxValue);
+
+	glFrustum(xmaxValue, -xmaxValue, -ymaxValue, ymaxValue, nearClipPlane, farClipPlane);
+	glMatrixMode(GL_MODELVIEW);
+	glLoadIdentity();
+}
+
+void OpenGLRenderer::positionCamera(const Math::Vector3d &pos, const Math::Vector3d &interest) {
+	Math::Vector3d up_vec(0, 1, 0);
+
+	Math::Matrix4 lookMatrix = Math::makeLookAtMatrix(pos, interest, up_vec);
+	glMultMatrixf(lookMatrix.getData());
+	glTranslatef(-pos.x(), -pos.y(), -pos.z());
+}
+
+void OpenGLRenderer::drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint8 g, uint8 b) {
+	glDisable(GL_TEXTURE_2D);
+	glColor4ub(r, g, b, a);
+
+	if (a != 255) {
+		glEnable(GL_BLEND);
+		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+	}
+
+	glEnableClientState(GL_VERTEX_ARRAY);
+	copyToVertexArray(0, Math::Vector3d(rect.left, rect.bottom, 0.0));
+	copyToVertexArray(1, Math::Vector3d(rect.right, rect.bottom, 0.0));
+	copyToVertexArray(2, Math::Vector3d(rect.left, rect.top, 0.0));
+	copyToVertexArray(3, Math::Vector3d(rect.right, rect.top, 0.0));
+	glVertexPointer(3, GL_FLOAT, 0, _verts);
+	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+	glDisableClientState(GL_VERTEX_ARRAY);
+	glDisable(GL_BLEND);
+}
+
+void OpenGLRenderer::renderCrossair(byte color, const Common::Point position) {
+	uint8 r, g, b;
+	readFromPalette(color, r, g, b); // TODO: should use opposite color
+
+	glMatrixMode(GL_PROJECTION);
+	glLoadIdentity();
+	glOrtho(0, _screenW, _screenH, 0, 0, 1);
+	glMatrixMode(GL_MODELVIEW);
+	glLoadIdentity();
+
+	glDisable(GL_DEPTH_TEST);
+	glDepthMask(GL_FALSE);
+
+	glColor3ub(r, g, b);
+
+	glBegin(GL_LINES);
+	glVertex2f(position.x - 1, position.y);
+	glVertex2f(position.x + 3, position.y);
+
+	glVertex2f(position.x, position.y - 3);
+	glVertex2f(position.x, position.y + 3);
+	glEnd();
+
+	glDepthMask(GL_TRUE);
+	glEnable(GL_DEPTH_TEST);
+}
+
+void OpenGLRenderer::renderShoot(byte color, const Common::Point position) {
+	uint8 r, g, b;
+	readFromPalette(color, r, g, b); // TODO: should use opposite color
+
+	glMatrixMode(GL_PROJECTION);
+	glLoadIdentity();
+	glOrtho(0, _screenW, _screenH, 0, 0, 1);
+	glMatrixMode(GL_MODELVIEW);
+	glLoadIdentity();
+
+	glDisable(GL_DEPTH_TEST);
+	glDepthMask(GL_FALSE);
+
+	glColor3ub(r, g, b);
+
+	int viewPort[4];
+	glGetIntegerv(GL_VIEWPORT, viewPort);
+
+	glBegin(GL_LINES);
+	glVertex2f(0, _screenH - 2);
+	glVertex2f(position.x, position.y);
+
+	glVertex2f(0, _screenH - 2);
+	glVertex2f(position.x, position.y);
+
+	glVertex2f(_screenW, _screenH - 2);
+	glVertex2f(position.x, position.y);
+
+	glVertex2f(_screenW, _screenH);
+	glVertex2f(position.x, position.y);
+
+	glEnd();
+
+	glEnable(GL_DEPTH_TEST);
+	glDepthMask(GL_TRUE);
+}
+
+void OpenGLRenderer::renderFace(const Common::Array<Math::Vector3d> &vertices) {
+	assert(vertices.size() >= 2);
+	const Math::Vector3d &v0 = vertices[0];
+
+	if (vertices.size() == 2) {
+		const Math::Vector3d &v1 = vertices[1];
+		if (v0 == v1)
+			return;
+
+		glEnableClientState(GL_VERTEX_ARRAY);
+		copyToVertexArray(0, v0);
+		copyToVertexArray(1, v1);
+		glVertexPointer(3, GL_FLOAT, 0, _verts);
+		glDrawArrays(GL_LINES, 0, 2);
+		glDisableClientState(GL_VERTEX_ARRAY);
+		return;
+	}
+
+	glEnableClientState(GL_VERTEX_ARRAY);
+	uint vi = 0;
+	for (uint i = 1; i < vertices.size() - 1; i++) { // no underflow since vertices.size() > 2
+		const Math::Vector3d &v1 = vertices[i];
+		const Math::Vector3d &v2 = vertices[i + 1];
+		vi = 3 * (i - 1); // no underflow since i >= 1
+		copyToVertexArray(vi + 0, v0);
+		copyToVertexArray(vi + 1, v1);
+		copyToVertexArray(vi + 2, v2);
+	}
+	glVertexPointer(3, GL_FLOAT, 0, _verts);
+	glDrawArrays(GL_TRIANGLES, 0, vi + 3);
+	glDisableClientState(GL_VERTEX_ARRAY);
+}
+
+void OpenGLRenderer::polygonOffset(bool enabled) {
+	if (enabled) {
+		glEnable(GL_POLYGON_OFFSET_FILL);
+		glPolygonOffset(-2.0f, 1.0f);
+	} else {
+		glPolygonOffset(0, 0);
+		glDisable(GL_POLYGON_OFFSET_FILL);
+	}
+}
+
+void OpenGLRenderer::useColor(uint8 r, uint8 g, uint8 b) {
+	glColor3ub(r, g, b);
+}
+
+void OpenGLRenderer::setSkyColor(uint8 color) {
+	uint8 r, g, b;
+	assert(getRGBAt(color, r, g, b)); // TODO: move check inside this function
+	glClearColor(r / 255., g / 255., b / 255., 1.0);
+	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+}
+
+void OpenGLRenderer::drawFloor(uint8 color) {
+	uint8 r, g, b;
+	assert(getRGBAt(color, r, g, b)); // TODO: move check inside this function
+	glColor3ub(r, g, b);
+
+	glEnableClientState(GL_VERTEX_ARRAY);
+	copyToVertexArray(0, Math::Vector3d(-100000.0, 0.0, -100000.0));
+	copyToVertexArray(1, Math::Vector3d(100000.0, 0.0, -100000.0));
+	copyToVertexArray(2, Math::Vector3d(100000.0, 0.0, 100000.0));
+	copyToVertexArray(3, Math::Vector3d(-100000.0, 0.0, 100000.0));
+	glVertexPointer(3, GL_FLOAT, 0, _verts);
+	glDrawArrays(GL_QUADS, 0, 4);
+	glDisableClientState(GL_VERTEX_ARRAY);
+}
+
+void OpenGLRenderer::flipBuffer() {}
+
+} // End of namespace Freescape
diff --git a/engines/freescape/gfx_opengl.h b/engines/freescape/gfx_opengl.h
new file mode 100644
index 00000000000..ca16c3e366a
--- /dev/null
+++ b/engines/freescape/gfx_opengl.h
@@ -0,0 +1,74 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef FREESCAPE_GFX_OPENGL_H
+#define FREESCAPE_GFX_OPENGL_H
+
+#include "graphics/opengl/system_headers.h"
+#include "math/vector3d.h"
+
+#include "freescape/gfx.h"
+
+namespace Freescape {
+
+class OpenGLRenderer : public Renderer {
+public:
+	OpenGLRenderer(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode);
+	virtual ~OpenGLRenderer();
+
+	struct Vertex {
+		GLfloat x;
+		GLfloat y;
+		GLfloat z;
+	};
+
+	void copyToVertexArray(uint idx, const Math::Vector3d &src) {
+		_verts[idx].x = src.x(); _verts[idx].y = src.y(); _verts[idx].z = src.z();
+	}
+
+	Vertex *_verts;
+
+	virtual void init() override;
+	virtual void clear() override;
+	virtual void setViewport(const Common::Rect &rect) override;
+	virtual void positionCamera(const Math::Vector3d &pos, const Math::Vector3d &interest) override;
+	virtual void updateProjectionMatrix(float fov, float nearClipPlane, float farClipPlane) override;
+
+	virtual void useColor(uint8 r, uint8 g, uint8 b) override;
+	virtual void polygonOffset(bool enabled) override;
+
+	Texture *createTexture(const Graphics::Surface *surface) override;
+	void freeTexture(Texture *texture) override;
+	virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture) override;
+	virtual void drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint8 g, uint8 b) override;
+
+	virtual void renderCrossair(byte color, const Common::Point position) override;
+	virtual void renderShoot(byte color, const Common::Point position) override;
+	virtual void renderFace(const Common::Array<Math::Vector3d> &vertices) override;
+
+	virtual void flipBuffer() override;
+	virtual void setSkyColor(uint8 color) override;
+	virtual void drawFloor(uint8 color) override;
+};
+
+} // End of namespace Freescape
+
+#endif // FREESCAPE_GFX_OPENGL_H
diff --git a/engines/freescape/gfx_opengl_texture.cpp b/engines/freescape/gfx_opengl_texture.cpp
new file mode 100644
index 00000000000..943c8f27909
--- /dev/null
+++ b/engines/freescape/gfx_opengl_texture.cpp
@@ -0,0 +1,156 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS)
+
+#include "freescape/gfx_opengl_texture.h"
+
+#include "graphics/opengl/context.h"
+
+namespace Freescape {
+
+// From Bit Twiddling Hacks
+static uint32 upperPowerOfTwo(uint32 v) {
+	v--;
+	v |= v >> 1;
+	v |= v >> 2;
+	v |= v >> 4;
+	v |= v >> 8;
+	v |= v >> 16;
+	v++;
+	return v;
+}
+
+/*const Graphics::PixelFormat Texture::getRGBAPixelFormat() {
+#ifdef SCUMM_BIG_ENDIAN
+		return Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
+#else
+		return Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24);
+#endif
+}*/
+
+OpenGLTexture::OpenGLTexture() :
+		_internalFormat(0),
+		_sourceFormat(0),
+		_internalWidth(0),
+		_internalHeight(0),
+		_upsideDown(false) {
+	glGenTextures(1, &_id);
+}
+
+OpenGLTexture::OpenGLTexture(const Graphics::Surface *surface) {
+	_width = surface->w;
+	_height = surface->h;
+	_format = surface->format;
+	_upsideDown = false;
+
+	// Pad the textures if non power of two support is unavailable
+	if (OpenGLContext.NPOTSupported) {
+		_internalHeight = _height;
+		_internalWidth = _width;
+	} else {
+		_internalHeight = upperPowerOfTwo(_height);
+		_internalWidth = upperPowerOfTwo(_width);
+	}
+
+	if (_format.bytesPerPixel == 4) {
+		//assert(surface->format == getRGBAPixelFormat());
+
+		_internalFormat = GL_RGBA;
+		_sourceFormat = GL_UNSIGNED_BYTE;
+	} else if (_format.bytesPerPixel == 2) {
+		_internalFormat = GL_RGB;
+		_sourceFormat = GL_UNSIGNED_SHORT_5_6_5;
+	} else
+		error("Unknown pixel format");
+
+	glGenTextures(1, &_id);
+	glBindTexture(GL_TEXTURE_2D, _id);
+	glTexImage2D(GL_TEXTURE_2D, 0, _internalFormat, _internalWidth, _internalHeight, 0, _internalFormat, _sourceFormat, nullptr);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+	// TODO: If non power of two textures are unavailable this clamping
+	// has no effect on the padded sides (resulting in white lines on the edges)
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+	update(surface);
+}
+
+OpenGLTexture::~OpenGLTexture() {
+	glDeleteTextures(1, &_id);
+}
+
+void OpenGLTexture::update(const Graphics::Surface *surface) {
+	updatePartial(surface, Common::Rect(surface->w, surface->h));
+}
+
+void OpenGLTexture::updateTexture(const Graphics::Surface *surface, const Common::Rect &rect) {
+	assert(surface->format == _format);
+
+	glBindTexture(GL_TEXTURE_2D, _id);
+
+	if (OpenGLContext.unpackSubImageSupported) {
+		const Graphics::Surface subArea = surface->getSubArea(rect);
+
+		glPixelStorei(GL_UNPACK_ROW_LENGTH, surface->pitch / surface->format.bytesPerPixel);
+
+		glTexSubImage2D(GL_TEXTURE_2D, 0, rect.left, rect.top, subArea.w, subArea.h, _internalFormat, _sourceFormat, const_cast<void *>(subArea.getPixels()));
+		glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+	} else {
+		// GL_UNPACK_ROW_LENGTH is not supported, don't bother and do a full texture update
+		glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, surface->w, surface->h, _internalFormat, _sourceFormat, const_cast<void *>(surface->getPixels()));
+	}
+}
+
+void OpenGLTexture::updatePartial(const Graphics::Surface *surface, const Common::Rect &rect) {
+	updateTexture(surface, rect);
+}
+
+void OpenGLTexture::copyFromFramebuffer(const Common::Rect &screen) {
+	_internalFormat = GL_RGB;
+	_width  = screen.width();
+	_height = screen.height();
+	_upsideDown = true;
+
+	// Pad the textures if non power of two support is unavailable
+	if (OpenGLContext.NPOTSupported) {
+		_internalHeight = _height;
+		_internalWidth = _width;
+	} else {
+		_internalHeight = upperPowerOfTwo(_height);
+		_internalWidth = upperPowerOfTwo(_width);
+	}
+
+	glBindTexture(GL_TEXTURE_2D, _id);
+	glTexImage2D(GL_TEXTURE_2D, 0, _internalFormat, _internalWidth, _internalHeight, 0, _internalFormat, GL_UNSIGNED_BYTE, nullptr);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+	glCopyTexImage2D(GL_TEXTURE_2D, 0, _internalFormat, screen.left, screen.top, _internalWidth, _internalHeight, 0);
+}
+
+} // End of namespace Freescape
+
+#endif
diff --git a/engines/freescape/gfx_opengl_texture.h b/engines/freescape/gfx_opengl_texture.h
new file mode 100644
index 00000000000..31d8c3592f2
--- /dev/null
+++ b/engines/freescape/gfx_opengl_texture.h
@@ -0,0 +1,56 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef FREESCAPE_GFX_OPENGL_TEXTURE_H
+#define FREESCAPE_GFX_OPENGL_TEXTURE_H
+
+#include "graphics/opengl/system_headers.h"
+#include "graphics/surface.h"
+
+#include "freescape/gfx.h"
+
+namespace Freescape {
+
+class OpenGLTexture : public Texture {
+public:
+	OpenGLTexture(const Graphics::Surface *surface);
+	OpenGLTexture();
+	virtual ~OpenGLTexture();
+
+	void update(const Graphics::Surface *surface) override;
+	void updatePartial(const Graphics::Surface *surface, const Common::Rect &rect) override;
+
+	void copyFromFramebuffer(const Common::Rect &screen);
+
+	GLuint _id;
+	GLuint _internalFormat;
+	GLuint _sourceFormat;
+	uint32 _internalWidth;
+	uint32 _internalHeight;
+	bool _upsideDown;
+
+private:
+	void updateTexture(const Graphics::Surface *surface, const Common::Rect &rect);
+};
+
+} // End of namespace Freescape
+
+#endif // FREESCAPE_GFX_OPENGL_TEXTURE_H
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index fc7d76b07de..5e013a689b6 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -29,6 +29,13 @@ MODULE_OBJS += \
 	gfx_tinygl_texture.o
 endif
 
+ifdef USE_OPENGL
+MODULE_OBJS += \
+	gfx_opengl.o \
+	gfx_opengl_texture.o
+endif
+
+
 MODULE_DIRS += \
 	engines/freescape
 


Commit: 28418d0def3c39cb30783f0a831e852525b4b70f
    https://github.com/scummvm/scummvm/commit/28418d0def3c39cb30783f0a831e852525b4b70f
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:41+01:00

Commit Message:
FREESCAPE: use TinyGL renderer by default

Changed paths:
    engines/freescape/gfx.cpp


diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index 15dac19e403..a1759519f0e 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -418,6 +418,11 @@ Renderer *createRenderer(OSystem *system, int screenW, int screenH, Common::Rend
 #endif
 						0);
 
+	#if defined(USE_TINYGL) // Prefer TinyGL until OpenGL is good enough
+	if (desiredRendererType == Graphics::kRendererTypeDefault)
+		matchingRendererType = desiredRendererType = Graphics::kRendererTypeTinyGL;
+	#endif
+
 	bool isAccelerated = matchingRendererType != Graphics::kRendererTypeTinyGL;
 
 	if (isAccelerated) {


Commit: a816adcd369aed3e8b3f0616cb796e9bd37dcc38
    https://github.com/scummvm/scummvm/commit/a816adcd369aed3e8b3f0616cb796e9bd37dcc38
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:41+01:00

Commit Message:
FREESCAPE: improved OpenGL texture handling with preliminary code

Changed paths:
    engines/freescape/gfx.cpp
    engines/freescape/gfx.h
    engines/freescape/gfx_opengl.cpp
    engines/freescape/gfx_opengl_texture.cpp


diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index a1759519f0e..b35146fa137 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -20,6 +20,7 @@
  */
 
 #include "common/config-manager.h"
+#include "common/system.h"
 
 #include "gui/message.h"
 #include "graphics/renderer.h"
@@ -98,8 +99,31 @@ Common::Rect Renderer::viewport() const {
 	return _screenViewport;
 }
 
-void Renderer::computeScreenViewport() {
-	_screenViewport = Common::Rect(_screenW, _screenH);
+bool Renderer::computeScreenViewport() {
+	int32 screenWidth = g_system->getWidth();
+	int32 screenHeight = g_system->getHeight();
+
+	Common::Rect viewport;
+	if (g_system->getFeatureState(OSystem::kFeatureAspectRatioCorrection)) {
+			// Aspect ratio correction
+			int32 viewportWidth = MIN<int32>(screenWidth, screenHeight * float(_screenW) / _screenH);
+			int32 viewportHeight = MIN<int32>(screenHeight, screenWidth * float(_screenH) / _screenW);
+			viewport = Common::Rect(viewportWidth, viewportHeight);
+
+			// Pillarboxing
+			viewport.translate((screenWidth - viewportWidth) / 2,
+				(screenHeight - viewportHeight) / 2);
+	} else {
+			// Aspect ratio correction disabled, just stretch
+			viewport = Common::Rect(screenWidth, screenHeight);
+	}
+
+	if (viewport == _screenViewport) {
+		return false;
+	}
+
+	_screenViewport = viewport;
+	return true;
 }
 
 void Renderer::renderPyramid(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours, int type) {
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 214fb6cd068..d7b9225d329 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -112,11 +112,13 @@ public:
 	int _screenH;
 	Common::RenderMode _renderMode;
 
-	void computeScreenViewport();
+	bool computeScreenViewport();
 
 protected:
 	OSystem *_system;
 	Common::Rect _screenViewport;
+	Common::Rect _viewport;
+	Common::Rect _unscaledViewport;
 
 	Math::Matrix4 _projectionMatrix;
 	Math::Matrix4 _modelViewMatrix;
diff --git a/engines/freescape/gfx_opengl.cpp b/engines/freescape/gfx_opengl.cpp
index 82fa5bd6290..016253f8a4c 100644
--- a/engines/freescape/gfx_opengl.cpp
+++ b/engines/freescape/gfx_opengl.cpp
@@ -65,10 +65,24 @@ void OpenGLRenderer::init() {
 	glDisable(GL_LIGHTING);
 	glDisable(GL_TEXTURE_2D);
 	glEnable(GL_DEPTH_TEST);
+	glEnable(GL_SCISSOR_TEST);
+	setViewport(_viewport);
 }
 
 void OpenGLRenderer::setViewport(const Common::Rect &rect) {
-	glViewport(rect.left, g_system->getHeight() - rect.bottom, rect.width(), rect.height());
+	_viewport = Common::Rect(
+					_screenViewport.width() * rect.width() / _screenW,
+					_screenViewport.height() * rect.height() / _screenH
+					);
+
+	_viewport.translate(
+					_screenViewport.left + _screenViewport.width() * rect.left / _screenW,
+					_screenViewport.top + _screenViewport.height() * rect.top / _screenH
+					);
+
+	_unscaledViewport = rect;
+	glViewport(_viewport.left, g_system->getHeight() - _viewport.bottom, _viewport.width(), _viewport.height());
+	glScissor(_viewport.left, g_system->getHeight() - _viewport.bottom, _viewport.width(), _viewport.height());
 }
 
 void OpenGLRenderer::clear() {
@@ -89,12 +103,14 @@ void OpenGLRenderer::drawTexturedRect2D(const Common::Rect &screenRect, const Co
 	float sRight = sLeft + screenRect.width();
 	float sBottom = sTop + screenRect.height();
 
-	if (glTexture->_upsideDown) {
-		SWAP(sTop, sBottom);
-    }
+	SWAP(sTop, sBottom);
 
+	glMatrixMode(GL_PROJECTION);
+	glOrtho(0, _screenH, 0, _screenW, -1, 1);
+	glMatrixMode(GL_MODELVIEW);
 
-	//glEnable(GL_TEXTURE_2D);
+	glDisable(GL_DEPTH_TEST);
+	glEnable(GL_TEXTURE_2D);
 	glColor4f(1.0, 1.0, 1.0, 1.0);
 	glDepthMask(GL_FALSE);
 
@@ -115,6 +131,7 @@ void OpenGLRenderer::drawTexturedRect2D(const Common::Rect &screenRect, const Co
 
 	glDisable(GL_BLEND);
 	glDepthMask(GL_TRUE);
+	glEnable(GL_DEPTH_TEST);
 }
 
 void OpenGLRenderer::updateProjectionMatrix(float fov, float nearClipPlane, float farClipPlane) {
diff --git a/engines/freescape/gfx_opengl_texture.cpp b/engines/freescape/gfx_opengl_texture.cpp
index 943c8f27909..74e585524b6 100644
--- a/engines/freescape/gfx_opengl_texture.cpp
+++ b/engines/freescape/gfx_opengl_texture.cpp
@@ -41,13 +41,13 @@ static uint32 upperPowerOfTwo(uint32 v) {
 	return v;
 }
 
-/*const Graphics::PixelFormat Texture::getRGBAPixelFormat() {
+const Graphics::PixelFormat Texture::getRGBAPixelFormat() {
 #ifdef SCUMM_BIG_ENDIAN
 		return Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
 #else
 		return Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24);
 #endif
-}*/
+}
 
 OpenGLTexture::OpenGLTexture() :
 		_internalFormat(0),
@@ -73,9 +73,12 @@ OpenGLTexture::OpenGLTexture(const Graphics::Surface *surface) {
 		_internalWidth = upperPowerOfTwo(_width);
 	}
 
+	Graphics::Surface *convertedSurface = nullptr;
 	if (_format.bytesPerPixel == 4) {
-		//assert(surface->format == getRGBAPixelFormat());
+		convertedSurface = surface->convertTo(getRGBAPixelFormat());
+		assert(convertedSurface->format == getRGBAPixelFormat());
 
+		_format = convertedSurface->format;
 		_internalFormat = GL_RGBA;
 		_sourceFormat = GL_UNSIGNED_BYTE;
 	} else if (_format.bytesPerPixel == 2) {
@@ -95,7 +98,12 @@ OpenGLTexture::OpenGLTexture(const Graphics::Surface *surface) {
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 
-	update(surface);
+	if (convertedSurface) {
+		update(convertedSurface);
+		convertedSurface->free();
+		delete convertedSurface;
+	} else
+		update(surface);
 }
 
 OpenGLTexture::~OpenGLTexture() {
@@ -107,20 +115,21 @@ void OpenGLTexture::update(const Graphics::Surface *surface) {
 }
 
 void OpenGLTexture::updateTexture(const Graphics::Surface *surface, const Common::Rect &rect) {
-	assert(surface->format == _format);
+	Graphics::Surface *convertedSurface = surface->convertTo(getRGBAPixelFormat());
+	assert(convertedSurface->format == _format);
 
 	glBindTexture(GL_TEXTURE_2D, _id);
 
 	if (OpenGLContext.unpackSubImageSupported) {
-		const Graphics::Surface subArea = surface->getSubArea(rect);
+		const Graphics::Surface subArea = convertedSurface->getSubArea(rect);
 
-		glPixelStorei(GL_UNPACK_ROW_LENGTH, surface->pitch / surface->format.bytesPerPixel);
+		glPixelStorei(GL_UNPACK_ROW_LENGTH, convertedSurface->pitch / convertedSurface->format.bytesPerPixel);
 
 		glTexSubImage2D(GL_TEXTURE_2D, 0, rect.left, rect.top, subArea.w, subArea.h, _internalFormat, _sourceFormat, const_cast<void *>(subArea.getPixels()));
 		glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
 	} else {
 		// GL_UNPACK_ROW_LENGTH is not supported, don't bother and do a full texture update
-		glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, surface->w, surface->h, _internalFormat, _sourceFormat, const_cast<void *>(surface->getPixels()));
+		glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, convertedSurface->w, convertedSurface->h, _internalFormat, _sourceFormat, const_cast<void *>(convertedSurface->getPixels()));
 	}
 }
 


Commit: 1c12bb6040d69a08b977a9abb18c43ff55bd9c4b
    https://github.com/scummvm/scummvm/commit/1c12bb6040d69a08b977a9abb18c43ff55bd9c4b
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:41+01:00

Commit Message:
FREESCAPE: define texture pixel format and convert images if necessary

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/games/driller.cpp
    engines/freescape/gfx.cpp
    engines/freescape/gfx.h
    engines/freescape/gfx_opengl.cpp
    engines/freescape/gfx_opengl_texture.cpp
    engines/freescape/gfx_opengl_texture.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/gfx_tinygl_texture.cpp
    engines/freescape/gfx_tinygl_texture.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 314009104e8..877f6530ffe 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -403,6 +403,10 @@ Common::Error FreescapeEngine::run() {
 	initGameState();
 	loadColorPalette();
 
+
+	_title = _gfx->convertImageFormatIfNecessary(_title);
+	_border = _gfx->convertImageFormatIfNecessary(_border);
+
 	// Simple main event loop
 	int saveSlot = ConfMan.getInt("save_slot");
 
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index d9e021f9aa8..2918b02992f 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -340,14 +340,14 @@ void DrillerEngine::drawUI() {
 		_gfx->setViewport(_fullscreenViewArea);
 
 		Graphics::Surface *surface = new Graphics::Surface();
-		surface->create(_screenW, _screenH, _gfx->_currentPixelFormat);
-		uint32 gray = _gfx->_currentPixelFormat.RGBToColor(0xA0, 0xA0, 0xA0);
+		surface->create(_screenW, _screenH, _gfx->_texturePixelFormat);
+		uint32 gray = _gfx->_texturePixelFormat.RGBToColor(0xA0, 0xA0, 0xA0);
 		surface->fillRect(_fullscreenViewArea, gray);
 
 		int score = _gameStateVars[k8bitVariableScore];
 
-		uint32 yellow = _gfx->_currentPixelFormat.RGBToColor(0xFF, 0xFF, 0x55);
-		uint32 black = _gfx->_currentPixelFormat.RGBToColor(0x00, 0x00, 0x00);
+		uint32 yellow = _gfx->_texturePixelFormat.RGBToColor(0xFF, 0xFF, 0x55);
+		uint32 black = _gfx->_texturePixelFormat.RGBToColor(0x00, 0x00, 0x00);
 
 		drawStringInSurface(_currentAreaMessages[0], 196, 177, yellow, black, surface);
 		drawStringInSurface(_currentAreaMessages[1], 196, 185, yellow, black, surface);
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index b35146fa137..074aa5bf10e 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -41,7 +41,6 @@ Renderer::Renderer(OSystem *system, int screenW, int screenH, Common::RenderMode
 	_screenW = screenW;
 	_screenH = screenH;
 	_currentPixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
-	_originalPixelFormat = Graphics::PixelFormat::createFormatCLUT8();
 	_palettePixelFormat = Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0);
 	_keyColor = -1;
 	_palette = nullptr;
@@ -95,6 +94,16 @@ bool Renderer::getRGBAt(uint8 index, uint8 &r, uint8 &g, uint8 &b) {
 	return true;
 }
 
+Graphics::Surface *Renderer::convertImageFormatIfNecessary(Graphics::Surface *surface) {
+	if (!surface)
+		return surface;
+
+	if (surface->format != _texturePixelFormat)
+		return surface->convertTo(_texturePixelFormat);
+
+	return surface;
+}
+
 Common::Rect Renderer::viewport() const {
 	return _screenViewport;
 }
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index d7b9225d329..604fa59eb56 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -56,8 +56,9 @@ public:
 	virtual ~Renderer();
 
 	Graphics::PixelFormat _currentPixelFormat;
-	Graphics::PixelFormat _originalPixelFormat;
 	Graphics::PixelFormat _palettePixelFormat;
+	Graphics::PixelFormat _texturePixelFormat;
+	bool _isAccelerated;
 
 	virtual void init() = 0;
 	virtual void clear() = 0;
@@ -71,6 +72,8 @@ public:
 	virtual void polygonOffset(bool enabled) = 0;
 
 	virtual Texture *createTexture(const Graphics::Surface *surface) = 0;
+	Graphics::Surface *convertImageFormatIfNecessary(Graphics::Surface *surface);
+
 	virtual void freeTexture(Texture *texture) = 0;
 	virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture) = 0;
 	virtual void drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint8 g, uint8 b) = 0;
diff --git a/engines/freescape/gfx_opengl.cpp b/engines/freescape/gfx_opengl.cpp
index 016253f8a4c..6ee523a6efd 100644
--- a/engines/freescape/gfx_opengl.cpp
+++ b/engines/freescape/gfx_opengl.cpp
@@ -38,6 +38,7 @@ Renderer *CreateGfxOpenGL(OSystem *system, int screenW, int screenH, Common::Ren
 
 OpenGLRenderer::OpenGLRenderer(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode) : Renderer(system, screenW, screenH, renderMode) {
 	_verts = (Vertex*) malloc(sizeof(Vertex) * 20);
+	_texturePixelFormat = OpenGLTexture::getRGBAPixelFormat();
 }
 
 OpenGLRenderer::~OpenGLRenderer() {
diff --git a/engines/freescape/gfx_opengl_texture.cpp b/engines/freescape/gfx_opengl_texture.cpp
index 74e585524b6..c4b7b20d754 100644
--- a/engines/freescape/gfx_opengl_texture.cpp
+++ b/engines/freescape/gfx_opengl_texture.cpp
@@ -41,7 +41,7 @@ static uint32 upperPowerOfTwo(uint32 v) {
 	return v;
 }
 
-const Graphics::PixelFormat Texture::getRGBAPixelFormat() {
+const Graphics::PixelFormat OpenGLTexture::getRGBAPixelFormat() {
 #ifdef SCUMM_BIG_ENDIAN
 		return Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
 #else
@@ -73,12 +73,9 @@ OpenGLTexture::OpenGLTexture(const Graphics::Surface *surface) {
 		_internalWidth = upperPowerOfTwo(_width);
 	}
 
-	Graphics::Surface *convertedSurface = nullptr;
 	if (_format.bytesPerPixel == 4) {
-		convertedSurface = surface->convertTo(getRGBAPixelFormat());
-		assert(convertedSurface->format == getRGBAPixelFormat());
-
-		_format = convertedSurface->format;
+		assert(surface->format == getRGBAPixelFormat());
+		_format = surface->format;
 		_internalFormat = GL_RGBA;
 		_sourceFormat = GL_UNSIGNED_BYTE;
 	} else if (_format.bytesPerPixel == 2) {
@@ -98,12 +95,7 @@ OpenGLTexture::OpenGLTexture(const Graphics::Surface *surface) {
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 
-	if (convertedSurface) {
-		update(convertedSurface);
-		convertedSurface->free();
-		delete convertedSurface;
-	} else
-		update(surface);
+	update(surface);
 }
 
 OpenGLTexture::~OpenGLTexture() {
@@ -115,21 +107,20 @@ void OpenGLTexture::update(const Graphics::Surface *surface) {
 }
 
 void OpenGLTexture::updateTexture(const Graphics::Surface *surface, const Common::Rect &rect) {
-	Graphics::Surface *convertedSurface = surface->convertTo(getRGBAPixelFormat());
-	assert(convertedSurface->format == _format);
+	assert(surface->format == _format);
 
 	glBindTexture(GL_TEXTURE_2D, _id);
 
 	if (OpenGLContext.unpackSubImageSupported) {
-		const Graphics::Surface subArea = convertedSurface->getSubArea(rect);
+		const Graphics::Surface subArea = surface->getSubArea(rect);
 
-		glPixelStorei(GL_UNPACK_ROW_LENGTH, convertedSurface->pitch / convertedSurface->format.bytesPerPixel);
+		glPixelStorei(GL_UNPACK_ROW_LENGTH, surface->pitch / surface->format.bytesPerPixel);
 
 		glTexSubImage2D(GL_TEXTURE_2D, 0, rect.left, rect.top, subArea.w, subArea.h, _internalFormat, _sourceFormat, const_cast<void *>(subArea.getPixels()));
 		glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
 	} else {
 		// GL_UNPACK_ROW_LENGTH is not supported, don't bother and do a full texture update
-		glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, convertedSurface->w, convertedSurface->h, _internalFormat, _sourceFormat, const_cast<void *>(convertedSurface->getPixels()));
+		glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, surface->w, surface->h, _internalFormat, _sourceFormat, const_cast<void *>(surface->getPixels()));
 	}
 }
 
diff --git a/engines/freescape/gfx_opengl_texture.h b/engines/freescape/gfx_opengl_texture.h
index 31d8c3592f2..cd3f3b073ee 100644
--- a/engines/freescape/gfx_opengl_texture.h
+++ b/engines/freescape/gfx_opengl_texture.h
@@ -35,6 +35,8 @@ public:
 	OpenGLTexture();
 	virtual ~OpenGLTexture();
 
+	const static Graphics::PixelFormat getRGBAPixelFormat();
+
 	void update(const Graphics::Surface *surface) override;
 	void updatePartial(const Graphics::Surface *surface, const Common::Rect &rect) override;
 
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 8b5721b2b85..f1f4a6d088c 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -39,6 +39,7 @@ Renderer *CreateGfxTinyGL(OSystem *system, int screenW, int screenH, Common::Ren
 
 TinyGLRenderer::TinyGLRenderer(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode) : Renderer(system, screenW, screenH, renderMode) {
 	_verts = (Vertex*) malloc(sizeof(Vertex) * 20);
+	_texturePixelFormat = TinyGLTexture::getRGBAPixelFormat();
 }
 
 TinyGLRenderer::~TinyGLRenderer() {
diff --git a/engines/freescape/gfx_tinygl_texture.cpp b/engines/freescape/gfx_tinygl_texture.cpp
index 7f684a29543..a13eb9ebc0c 100644
--- a/engines/freescape/gfx_tinygl_texture.cpp
+++ b/engines/freescape/gfx_tinygl_texture.cpp
@@ -25,6 +25,10 @@
 
 namespace Freescape {
 
+const Graphics::PixelFormat TinyGLTexture::getRGBAPixelFormat() {
+	return Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
+}
+
 TinyGLTexture::TinyGLTexture(const Graphics::Surface *surface) {
 	_width = surface->w;
 	_height = surface->h;
@@ -41,7 +45,8 @@ TinyGLTexture::~TinyGLTexture() {
 }
 
 void TinyGLTexture::update(const Graphics::Surface *surface) {
-	tglUploadBlitImage(_blitImage, *surface, 0xA0A0A0FF, true);
+	uint32 keyColor = getRGBAPixelFormat().RGBToColor(0xA0, 0xA0, 0xA0);
+	tglUploadBlitImage(_blitImage, *surface, keyColor, true);
 }
 
 void TinyGLTexture::updatePartial(const Graphics::Surface *surface, const Common::Rect &rect) {
diff --git a/engines/freescape/gfx_tinygl_texture.h b/engines/freescape/gfx_tinygl_texture.h
index 8d59543bdec..cb87a3552bc 100644
--- a/engines/freescape/gfx_tinygl_texture.h
+++ b/engines/freescape/gfx_tinygl_texture.h
@@ -33,6 +33,8 @@ public:
 	TinyGLTexture(const Graphics::Surface *surface);
 	virtual ~TinyGLTexture();
 
+	const static Graphics::PixelFormat getRGBAPixelFormat();
+
 	TinyGL::BlitImage *getBlitTexture() const;
 
 	void update(const Graphics::Surface *surface) override;


Commit: a72378c35d7f5c0d33bddfe2cb269778f9967b18
    https://github.com/scummvm/scummvm/commit/a72378c35d7f5c0d33bddfe2cb269778f9967b18
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:41+01:00

Commit Message:
FREESCAPE: enable arbitrary resolution for OpenGL renderer

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/gfx.cpp
    engines/freescape/gfx.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 877f6530ffe..68c734ec015 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -517,9 +517,12 @@ void FreescapeEngine::updateCamera() {
 }
 
 bool FreescapeEngine::hasFeature(EngineFeature f) const {
+	// The TinyGL renderer does not support arbitrary resolutions for now
+	bool softRenderer = determinateRenderType() == Graphics::kRendererTypeTinyGL;
 	return (f == kSupportsReturnToLauncher) ||
 		   (f == kSupportsLoadingDuringRuntime) ||
-		   (f == kSupportsSavingDuringRuntime);
+		   (f == kSupportsSavingDuringRuntime) ||
+		   (f == kSupportsArbitraryResolutions && !softRenderer);
 }
 
 void FreescapeEngine::drawStringInSurface(const Common::String &str, int x, int y, uint32 fontColor, uint32 backColor, Graphics::Surface *surface) {
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index 074aa5bf10e..fc3b4e7a28a 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -23,7 +23,6 @@
 #include "common/system.h"
 
 #include "gui/message.h"
-#include "graphics/renderer.h"
 #include "engines/util.h"
 
 #if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS) || defined(USE_GLES2)
@@ -437,10 +436,8 @@ void Renderer::renderPolygon(const Math::Vector3d &origin, const Math::Vector3d
 	polygonOffset(false);
 }
 
-
-Renderer *createRenderer(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode) {
+Graphics::RendererType determinateRenderType() {
 	Common::String rendererConfig = ConfMan.get("renderer");
-	Graphics::PixelFormat pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
 	Graphics::RendererType desiredRendererType = Graphics::Renderer::parseTypeCode(rendererConfig);
 	Graphics::RendererType matchingRendererType = Graphics::Renderer::getBestMatchingAvailableType(desiredRendererType,
 #if defined(USE_OPENGL_GAME)
@@ -456,7 +453,29 @@ Renderer *createRenderer(OSystem *system, int screenW, int screenH, Common::Rend
 		matchingRendererType = desiredRendererType = Graphics::kRendererTypeTinyGL;
 	#endif
 
-	bool isAccelerated = matchingRendererType != Graphics::kRendererTypeTinyGL;
+	if (matchingRendererType != desiredRendererType && desiredRendererType != Graphics::kRendererTypeDefault) {
+		// Display a warning if unable to use the desired renderer
+		warning("Unable to create a '%s' renderer", rendererConfig.c_str());
+	}
+
+	#if defined(USE_OPENGL_GAME) && !defined(USE_GLES2)
+		if (matchingRendererType == Graphics::kRendererTypeOpenGL)
+			return matchingRendererType;
+	#endif
+
+	#if defined(USE_TINYGL)
+	if (desiredRendererType == Graphics::kRendererTypeTinyGL)
+		return desiredRendererType;
+	#endif
+
+	return Graphics::kRendererTypeDefault;
+}
+
+Renderer *createRenderer(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode) {
+	Graphics::PixelFormat pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
+	Graphics::RendererType rendererType = determinateRenderType();
+
+	bool isAccelerated = rendererType != Graphics::kRendererTypeTinyGL;
 
 	if (isAccelerated) {
 		initGraphics3d(screenW, screenH);
@@ -464,19 +483,14 @@ Renderer *createRenderer(OSystem *system, int screenW, int screenH, Common::Rend
 		initGraphics(screenW, screenH, &pixelFormat);
 	}
 
-	if (matchingRendererType != desiredRendererType && desiredRendererType != Graphics::kRendererTypeDefault) {
-		// Display a warning if unable to use the desired renderer
-		warning("Unable to create a '%s' renderer", rendererConfig.c_str());
-	}
-
 	#if defined(USE_OPENGL_GAME) && !defined(USE_GLES2)
-		if (matchingRendererType == Graphics::kRendererTypeOpenGL) {
+		if (rendererType == Graphics::kRendererTypeOpenGL) {
 			return CreateGfxOpenGL(system, screenW, screenH, renderMode);
 		}
 	#endif
 
 	#if defined(USE_TINYGL)
-	if (desiredRendererType == Graphics::kRendererTypeTinyGL) {
+	if (rendererType == Graphics::kRendererTypeTinyGL) {
 		return CreateGfxTinyGL(system, screenW, screenH, renderMode);
 	}
 	#endif
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 604fa59eb56..1b0b166b767 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -26,6 +26,7 @@
 #include "common/rect.h"
 
 #include "graphics/pixelformat.h"
+#include "graphics/renderer.h"
 #include "math/frustum.h"
 #include "math/vector3d.h"
 
@@ -155,6 +156,7 @@ private:
 	uint _startFrameTime;
 };
 
+Graphics::RendererType determinateRenderType();
 Renderer *CreateGfxOpenGL(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode);
 Renderer *CreateGfxOpenGLShader(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode);
 Renderer *CreateGfxTinyGL(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode);


Commit: 46e135e9f1207b0271bab8fa6b27611bdb19da45
    https://github.com/scummvm/scummvm/commit/46e135e9f1207b0271bab8fa6b27611bdb19da45
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:41+01:00

Commit Message:
FREESCAPE: recompute screen viewport on every EVENT_SCREEN_CHANGED

Changed paths:
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 68c734ec015..49ddcfda2c7 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -338,6 +338,10 @@ void FreescapeEngine::processInput() {
 			quitGame();
 			return;
 
+		case Common::EVENT_SCREEN_CHANGED:
+			_gfx->computeScreenViewport();
+			break;
+
 		case Common::EVENT_MOUSEMOVE:
 			mousePos = event.mouse;
 


Commit: d2816b55c21ed8db84006172053c504e363fbe3b
    https://github.com/scummvm/scummvm/commit/d2816b55c21ed8db84006172053c504e363fbe3b
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:42+01:00

Commit Message:
FREESCAPE: removed unused code in engines/freescape/gfx_opengl_texture.cpp

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/games/driller.cpp
    engines/freescape/gfx_opengl_texture.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 49ddcfda2c7..f83fd8af760 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -425,7 +425,7 @@ Common::Error FreescapeEngine::run() {
 
 	if (_border) {
 		_borderTexture = nullptr;
-		_border->fillRect(_viewArea, 0xA0A0A0FF);
+		_border->fillRect(_viewArea, _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0xA0, 0xA0, 0xA0));
 	}
 	if (saveSlot >= 0) { // load the savegame
 		loadGameState(saveSlot);
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 2918b02992f..4d251ccb649 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -341,13 +341,13 @@ void DrillerEngine::drawUI() {
 
 		Graphics::Surface *surface = new Graphics::Surface();
 		surface->create(_screenW, _screenH, _gfx->_texturePixelFormat);
-		uint32 gray = _gfx->_texturePixelFormat.RGBToColor(0xA0, 0xA0, 0xA0);
+		uint32 gray = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0xA0, 0xA0, 0xA0);
 		surface->fillRect(_fullscreenViewArea, gray);
 
 		int score = _gameStateVars[k8bitVariableScore];
 
-		uint32 yellow = _gfx->_texturePixelFormat.RGBToColor(0xFF, 0xFF, 0x55);
-		uint32 black = _gfx->_texturePixelFormat.RGBToColor(0x00, 0x00, 0x00);
+		uint32 yellow = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0xFF, 0xFF, 0x55);
+		uint32 black = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0x00, 0x00, 0x00);
 
 		drawStringInSurface(_currentAreaMessages[0], 196, 177, yellow, black, surface);
 		drawStringInSurface(_currentAreaMessages[1], 196, 185, yellow, black, surface);
diff --git a/engines/freescape/gfx_opengl_texture.cpp b/engines/freescape/gfx_opengl_texture.cpp
index c4b7b20d754..39125fc06f4 100644
--- a/engines/freescape/gfx_opengl_texture.cpp
+++ b/engines/freescape/gfx_opengl_texture.cpp
@@ -128,29 +128,6 @@ void OpenGLTexture::updatePartial(const Graphics::Surface *surface, const Common
 	updateTexture(surface, rect);
 }
 
-void OpenGLTexture::copyFromFramebuffer(const Common::Rect &screen) {
-	_internalFormat = GL_RGB;
-	_width  = screen.width();
-	_height = screen.height();
-	_upsideDown = true;
-
-	// Pad the textures if non power of two support is unavailable
-	if (OpenGLContext.NPOTSupported) {
-		_internalHeight = _height;
-		_internalWidth = _width;
-	} else {
-		_internalHeight = upperPowerOfTwo(_height);
-		_internalWidth = upperPowerOfTwo(_width);
-	}
-
-	glBindTexture(GL_TEXTURE_2D, _id);
-	glTexImage2D(GL_TEXTURE_2D, 0, _internalFormat, _internalWidth, _internalHeight, 0, _internalFormat, GL_UNSIGNED_BYTE, nullptr);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
-	glCopyTexImage2D(GL_TEXTURE_2D, 0, _internalFormat, screen.left, screen.top, _internalWidth, _internalHeight, 0);
-}
-
 } // End of namespace Freescape
 
 #endif


Commit: 2efe16255613eb4bef6820bd8bf671c89165e58f
    https://github.com/scummvm/scummvm/commit/2efe16255613eb4bef6820bd8bf671c89165e58f
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:42+01:00

Commit Message:
FREESCAPE: use inplace conversion for texture surface

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/gfx.cpp
    engines/freescape/gfx.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index f83fd8af760..ae2738e8fe5 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -408,8 +408,8 @@ Common::Error FreescapeEngine::run() {
 	loadColorPalette();
 
 
-	_title = _gfx->convertImageFormatIfNecessary(_title);
-	_border = _gfx->convertImageFormatIfNecessary(_border);
+	_gfx->convertImageFormatIfNecessary(_title);
+	_gfx->convertImageFormatIfNecessary(_border);
 
 	// Simple main event loop
 	int saveSlot = ConfMan.getInt("save_slot");
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index fc3b4e7a28a..6365ff81060 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -93,14 +93,12 @@ bool Renderer::getRGBAt(uint8 index, uint8 &r, uint8 &g, uint8 &b) {
 	return true;
 }
 
-Graphics::Surface *Renderer::convertImageFormatIfNecessary(Graphics::Surface *surface) {
+void Renderer::convertImageFormatIfNecessary(Graphics::Surface *surface) {
 	if (!surface)
-		return surface;
+		return;
 
 	if (surface->format != _texturePixelFormat)
-		return surface->convertTo(_texturePixelFormat);
-
-	return surface;
+		surface->convertToInPlace(_texturePixelFormat);
 }
 
 Common::Rect Renderer::viewport() const {
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 1b0b166b767..c0bd7ba48c1 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -73,7 +73,7 @@ public:
 	virtual void polygonOffset(bool enabled) = 0;
 
 	virtual Texture *createTexture(const Graphics::Surface *surface) = 0;
-	Graphics::Surface *convertImageFormatIfNecessary(Graphics::Surface *surface);
+	void convertImageFormatIfNecessary(Graphics::Surface *surface);
 
 	virtual void freeTexture(Texture *texture) = 0;
 	virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture) = 0;


Commit: 791abdcb23a790caf1b8268da1c24e5b9f6fbbf0
    https://github.com/scummvm/scummvm/commit/791abdcb23a790caf1b8268da1c24e5b9f6fbbf0
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:42+01:00

Commit Message:
FREESCAPE: fixed incorrect parameters in drawTexturedRect2D (OpenGL renderer)

Changed paths:
    engines/freescape/gfx_opengl.cpp


diff --git a/engines/freescape/gfx_opengl.cpp b/engines/freescape/gfx_opengl.cpp
index 6ee523a6efd..9e4e11d24ab 100644
--- a/engines/freescape/gfx_opengl.cpp
+++ b/engines/freescape/gfx_opengl.cpp
@@ -107,7 +107,7 @@ void OpenGLRenderer::drawTexturedRect2D(const Common::Rect &screenRect, const Co
 	SWAP(sTop, sBottom);
 
 	glMatrixMode(GL_PROJECTION);
-	glOrtho(0, _screenH, 0, _screenW, -1, 1);
+	glOrtho(0, _screenW, 0, _screenH, -1, 1);
 	glMatrixMode(GL_MODELVIEW);
 
 	glDisable(GL_DEPTH_TEST);


Commit: 4a48c9929ebec4adb24e4bd31f14076bf7317c1b
    https://github.com/scummvm/scummvm/commit/4a48c9929ebec4adb24e4bd31f14076bf7317c1b
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:42+01:00

Commit Message:
FREESCAPE: forced a flush in drawTexturedRect2D (OpenGL renderer)

Changed paths:
    engines/freescape/gfx_opengl.cpp


diff --git a/engines/freescape/gfx_opengl.cpp b/engines/freescape/gfx_opengl.cpp
index 9e4e11d24ab..723b7bdfb02 100644
--- a/engines/freescape/gfx_opengl.cpp
+++ b/engines/freescape/gfx_opengl.cpp
@@ -133,6 +133,7 @@ void OpenGLRenderer::drawTexturedRect2D(const Common::Rect &screenRect, const Co
 	glDisable(GL_BLEND);
 	glDepthMask(GL_TRUE);
 	glEnable(GL_DEPTH_TEST);
+	glFlush();
 }
 
 void OpenGLRenderer::updateProjectionMatrix(float fov, float nearClipPlane, float farClipPlane) {


Commit: 76c27997362deeaf440b910586c45a2afc961f99
    https://github.com/scummvm/scummvm/commit/76c27997362deeaf440b910586c45a2afc961f99
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:42+01:00

Commit Message:
FREESCAPE: allow transparent pixels in drawTexturedRect2D (OpenGL renderer)

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/games/driller.cpp
    engines/freescape/gfx_opengl.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index ae2738e8fe5..8ec51905e4c 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -425,7 +425,8 @@ Common::Error FreescapeEngine::run() {
 
 	if (_border) {
 		_borderTexture = nullptr;
-		_border->fillRect(_viewArea, _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0xA0, 0xA0, 0xA0));
+		uint32 gray = _gfx->_texturePixelFormat.ARGBToColor(0x00, 0xA0, 0xA0, 0xA0);
+		_border->fillRect(_viewArea, gray);
 	}
 	if (saveSlot >= 0) { // load the savegame
 		loadGameState(saveSlot);
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 4d251ccb649..4adc274a2c7 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -341,7 +341,7 @@ void DrillerEngine::drawUI() {
 
 		Graphics::Surface *surface = new Graphics::Surface();
 		surface->create(_screenW, _screenH, _gfx->_texturePixelFormat);
-		uint32 gray = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0xA0, 0xA0, 0xA0);
+		uint32 gray = _gfx->_texturePixelFormat.ARGBToColor(0x00, 0xA0, 0xA0, 0xA0);
 		surface->fillRect(_fullscreenViewArea, gray);
 
 		int score = _gameStateVars[k8bitVariableScore];
diff --git a/engines/freescape/gfx_opengl.cpp b/engines/freescape/gfx_opengl.cpp
index 723b7bdfb02..cfd9e3cc924 100644
--- a/engines/freescape/gfx_opengl.cpp
+++ b/engines/freescape/gfx_opengl.cpp
@@ -106,9 +106,14 @@ void OpenGLRenderer::drawTexturedRect2D(const Common::Rect &screenRect, const Co
 
 	SWAP(sTop, sBottom);
 
+	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+	glEnable(GL_BLEND);
+
 	glMatrixMode(GL_PROJECTION);
+	glLoadIdentity();
 	glOrtho(0, _screenW, 0, _screenH, -1, 1);
 	glMatrixMode(GL_MODELVIEW);
+	glLoadIdentity();
 
 	glDisable(GL_DEPTH_TEST);
 	glEnable(GL_TEXTURE_2D);


Commit: 95c2ccaa4a3af19c9b36b449a94431bff79236c4
    https://github.com/scummvm/scummvm/commit/95c2ccaa4a3af19c9b36b449a94431bff79236c4
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:42+01:00

Commit Message:
FREESCAPE: reimplemented driller UI using only 2d surfaces

Changed paths:
    engines/freescape/games/driller.cpp


diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 4adc274a2c7..7acdd71177e 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -335,20 +335,18 @@ void DrillerEngine::loadAssetsFullGame() {
 
 void DrillerEngine::drawUI() {
 	_gfx->renderCrossair(0, _crossairPosition);
+	uint32 yellow = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0xFF, 0xFF, 0x55);
+	uint32 black = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0x00, 0x00, 0x00);
+	uint32 gray = _gfx->_texturePixelFormat.ARGBToColor(0x00, 0xA0, 0xA0, 0xA0);
 
+	Graphics::Surface *surface = nullptr;
 	if (_currentAreaMessages.size() == 2) {
-		_gfx->setViewport(_fullscreenViewArea);
-
-		Graphics::Surface *surface = new Graphics::Surface();
+		surface = new Graphics::Surface();
 		surface->create(_screenW, _screenH, _gfx->_texturePixelFormat);
-		uint32 gray = _gfx->_texturePixelFormat.ARGBToColor(0x00, 0xA0, 0xA0, 0xA0);
 		surface->fillRect(_fullscreenViewArea, gray);
 
 		int score = _gameStateVars[k8bitVariableScore];
 
-		uint32 yellow = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0xFF, 0xFF, 0x55);
-		uint32 black = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0x00, 0x00, 0x00);
-
 		drawStringInSurface(_currentAreaMessages[0], 196, 177, yellow, black, surface);
 		drawStringInSurface(_currentAreaMessages[1], 196, 185, yellow, black, surface);
 		drawStringInSurface(Common::String::format("%04d", 2 * int(_position.x())), 150, 145, yellow, black, surface);
@@ -357,39 +355,40 @@ void DrillerEngine::drawUI() {
 		drawStringInSurface(Common::String::format("%d", _playerHeightNumber), 57, 161, yellow, black, surface);
 
 		drawStringInSurface(Common::String::format("%07d", score), 240, 129, yellow, black, surface);
-
-		if (!_uiTexture)
-			_uiTexture = _gfx->createTexture(surface);
-		else
-			_uiTexture->update(surface);
-
-		_gfx->drawTexturedRect2D(_fullscreenViewArea, _fullscreenViewArea, _uiTexture);
-		surface->free();
-		delete surface;
 	}
 
 	int energy = _gameStateVars[k8bitVariableEnergy];
 	int shield = _gameStateVars[k8bitVariableShield];
 	if (_renderMode == Common::kRenderEGA && _border) {
-		// Common::Rect black(20, 177, 87, 191);
-		//_gfx->drawRect2D(black, 255, 0, 0, 0);
-
 		if (energy >= 0) {
-			Common::Rect black(20, 186, 87 - energy, 191);
-			_gfx->drawRect2D(black, 255, 0, 0, 0);
-			Common::Rect energyBar(87 - energy, 186, 87, 191);
-			_gfx->drawRect2D(energyBar, 255, 0xfc, 0xfc, 0x54);
+			Common::Rect back(20, 185, 88 - energy, 191);
+			surface->fillRect(back, black);
+			Common::Rect energyBar(87 - energy, 185, 88, 191);
+			surface->fillRect(energyBar, yellow);
 		}
 
 		if (shield >= 0) {
-			Common::Rect black(20, 178, 87 - shield, 183);
-			_gfx->drawRect2D(black, 255, 0, 0, 0);
+			Common::Rect back(20, 176, 88 - shield, 183);
+			surface->fillRect(back, black);
 
-			Common::Rect shieldBar(87 - shield, 178, 87, 183);
-			_gfx->drawRect2D(shieldBar, 255, 0xfc, 0xfc, 0x54);
+			Common::Rect shieldBar(87 - shield, 176, 88, 183);
+			surface->fillRect(shieldBar, yellow);
 		}
 	}
-	_gfx->setViewport(_viewArea);
+	if (surface) {
+		if (!_uiTexture)
+			_uiTexture = _gfx->createTexture(surface);
+		else
+			_uiTexture->update(surface);
+
+		_gfx->setViewport(_fullscreenViewArea);
+		_gfx->drawTexturedRect2D(_fullscreenViewArea, _fullscreenViewArea, _uiTexture);
+		_gfx->setViewport(_viewArea);
+
+		surface->free();
+		delete surface;
+	}
+
 }
 
 void DrillerEngine::pressedKey(const int keycode) {


Commit: c5fc1cae3ef5ab808018dbf770875c0685a2f735
    https://github.com/scummvm/scummvm/commit/c5fc1cae3ef5ab808018dbf770875c0685a2f735
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:43+01:00

Commit Message:
FREESCAPE: removed drawRect2D function from renderer

Changed paths:
    engines/freescape/gfx.h
    engines/freescape/gfx_opengl.cpp
    engines/freescape/gfx_opengl.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/gfx_tinygl.h


diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index c0bd7ba48c1..a74aaefa51c 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -77,7 +77,6 @@ public:
 
 	virtual void freeTexture(Texture *texture) = 0;
 	virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture) = 0;
-	virtual void drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint8 g, uint8 b) = 0;
 
 	virtual void renderCrossair(byte color, const Common::Point position) = 0;
 	virtual void renderShoot(byte color, const Common::Point position) = 0;
diff --git a/engines/freescape/gfx_opengl.cpp b/engines/freescape/gfx_opengl.cpp
index cfd9e3cc924..5bc09322e5c 100644
--- a/engines/freescape/gfx_opengl.cpp
+++ b/engines/freescape/gfx_opengl.cpp
@@ -164,26 +164,6 @@ void OpenGLRenderer::positionCamera(const Math::Vector3d &pos, const Math::Vecto
 	glTranslatef(-pos.x(), -pos.y(), -pos.z());
 }
 
-void OpenGLRenderer::drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint8 g, uint8 b) {
-	glDisable(GL_TEXTURE_2D);
-	glColor4ub(r, g, b, a);
-
-	if (a != 255) {
-		glEnable(GL_BLEND);
-		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-	}
-
-	glEnableClientState(GL_VERTEX_ARRAY);
-	copyToVertexArray(0, Math::Vector3d(rect.left, rect.bottom, 0.0));
-	copyToVertexArray(1, Math::Vector3d(rect.right, rect.bottom, 0.0));
-	copyToVertexArray(2, Math::Vector3d(rect.left, rect.top, 0.0));
-	copyToVertexArray(3, Math::Vector3d(rect.right, rect.top, 0.0));
-	glVertexPointer(3, GL_FLOAT, 0, _verts);
-	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-	glDisableClientState(GL_VERTEX_ARRAY);
-	glDisable(GL_BLEND);
-}
-
 void OpenGLRenderer::renderCrossair(byte color, const Common::Point position) {
 	uint8 r, g, b;
 	readFromPalette(color, r, g, b); // TODO: should use opposite color
diff --git a/engines/freescape/gfx_opengl.h b/engines/freescape/gfx_opengl.h
index ca16c3e366a..636cbdf17c5 100644
--- a/engines/freescape/gfx_opengl.h
+++ b/engines/freescape/gfx_opengl.h
@@ -58,7 +58,6 @@ public:
 	Texture *createTexture(const Graphics::Surface *surface) override;
 	void freeTexture(Texture *texture) override;
 	virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture) override;
-	virtual void drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint8 g, uint8 b) override;
 
 	virtual void renderCrossair(byte color, const Common::Point position) override;
 	virtual void renderShoot(byte color, const Common::Point position) override;
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index f1f4a6d088c..9c8fefa2c95 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -121,26 +121,6 @@ void TinyGLRenderer::positionCamera(const Math::Vector3d &pos, const Math::Vecto
 	tglTranslatef(-pos.x(), -pos.y(), -pos.z());
 }
 
-void TinyGLRenderer::drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint8 g, uint8 b) {
-	tglDisable(TGL_TEXTURE_2D);
-	tglColor4ub(r, g, b, a);
-
-	if (a != 255) {
-		tglEnable(TGL_BLEND);
-		tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE_MINUS_SRC_ALPHA);
-	}
-
-	tglEnableClientState(TGL_VERTEX_ARRAY);
-	copyToVertexArray(0, Math::Vector3d(rect.left, rect.bottom, 0.0));
-	copyToVertexArray(1, Math::Vector3d(rect.right, rect.bottom, 0.0));
-	copyToVertexArray(2, Math::Vector3d(rect.left, rect.top, 0.0));
-	copyToVertexArray(3, Math::Vector3d(rect.right, rect.top, 0.0));
-	tglVertexPointer(3, TGL_FLOAT, 0, _verts);
-	tglDrawArrays(TGL_TRIANGLE_STRIP, 0, 4);
-	tglDisableClientState(TGL_VERTEX_ARRAY);
-	tglDisable(TGL_BLEND);
-}
-
 void TinyGLRenderer::renderCrossair(byte color, const Common::Point position) {
 	uint8 r, g, b;
 	readFromPalette(color, r, g, b); // TODO: should use opposite color
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index a9ad29e2f77..4e94765b34f 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -57,7 +57,6 @@ public:
 	Texture *createTexture(const Graphics::Surface *surface) override;
 	void freeTexture(Texture *texture) override;
 	virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture) override;
-	virtual void drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint8 g, uint8 b) override;
 
 	virtual void renderCrossair(byte color, const Common::Point position) override;
 	virtual void renderShoot(byte color, const Common::Point position) override;


Commit: 1f3f7f42871c52a2d542e1036185e3c7198a71c5
    https://github.com/scummvm/scummvm/commit/1f3f7f42871c52a2d542e1036185e3c7198a71c5
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:43+01:00

Commit Message:
FREESCAPE: avoid blurry textures in OpenGL

Changed paths:
    engines/freescape/gfx_opengl_texture.cpp


diff --git a/engines/freescape/gfx_opengl_texture.cpp b/engines/freescape/gfx_opengl_texture.cpp
index 39125fc06f4..e9db5c3cd4a 100644
--- a/engines/freescape/gfx_opengl_texture.cpp
+++ b/engines/freescape/gfx_opengl_texture.cpp
@@ -87,8 +87,8 @@ OpenGLTexture::OpenGLTexture(const Graphics::Surface *surface) {
 	glGenTextures(1, &_id);
 	glBindTexture(GL_TEXTURE_2D, _id);
 	glTexImage2D(GL_TEXTURE_2D, 0, _internalFormat, _internalWidth, _internalHeight, 0, _internalFormat, _sourceFormat, nullptr);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
 	// TODO: If non power of two textures are unavailable this clamping
 	// has no effect on the padded sides (resulting in white lines on the edges)


Commit: dff5d766299cadfe149a9b9744a1ce78b2e48265
    https://github.com/scummvm/scummvm/commit/dff5d766299cadfe149a9b9744a1ce78b2e48265
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:43+01:00

Commit Message:
FREESCAPE: use wider lines when rendering shots and crossair in OpenGL

Changed paths:
    engines/freescape/gfx_opengl.cpp


diff --git a/engines/freescape/gfx_opengl.cpp b/engines/freescape/gfx_opengl.cpp
index 5bc09322e5c..10658c52abe 100644
--- a/engines/freescape/gfx_opengl.cpp
+++ b/engines/freescape/gfx_opengl.cpp
@@ -179,6 +179,8 @@ void OpenGLRenderer::renderCrossair(byte color, const Common::Point position) {
 
 	glColor3ub(r, g, b);
 
+	glLineWidth(15); // It will not work in every OpenGL implementation since the
+					 // spec doesn't require support for line widths other than 1
 	glBegin(GL_LINES);
 	glVertex2f(position.x - 1, position.y);
 	glVertex2f(position.x + 3, position.y);
@@ -186,6 +188,7 @@ void OpenGLRenderer::renderCrossair(byte color, const Common::Point position) {
 	glVertex2f(position.x, position.y - 3);
 	glVertex2f(position.x, position.y + 3);
 	glEnd();
+	glLineWidth(1);
 
 	glDepthMask(GL_TRUE);
 	glEnable(GL_DEPTH_TEST);
@@ -209,6 +212,8 @@ void OpenGLRenderer::renderShoot(byte color, const Common::Point position) {
 	int viewPort[4];
 	glGetIntegerv(GL_VIEWPORT, viewPort);
 
+	glLineWidth(10); // It will not work in every OpenGL implementation since the
+					 // spec doesn't require support for line widths other than 1
 	glBegin(GL_LINES);
 	glVertex2f(0, _screenH - 2);
 	glVertex2f(position.x, position.y);
@@ -223,6 +228,7 @@ void OpenGLRenderer::renderShoot(byte color, const Common::Point position) {
 	glVertex2f(position.x, position.y);
 
 	glEnd();
+	glLineWidth(1);
 
 	glEnable(GL_DEPTH_TEST);
 	glDepthMask(GL_TRUE);


Commit: 57b5af8cdf4d602509bd92027a48ca530cb3b68f
    https://github.com/scummvm/scummvm/commit/57b5af8cdf4d602509bd92027a48ca530cb3b68f
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:43+01:00

Commit Message:
FREESCAPE: small fix in driller UI

Changed paths:
    engines/freescape/games/driller.cpp


diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 7acdd71177e..10ff6242646 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -368,10 +368,10 @@ void DrillerEngine::drawUI() {
 		}
 
 		if (shield >= 0) {
-			Common::Rect back(20, 176, 88 - shield, 183);
+			Common::Rect back(20, 177, 88 - shield, 183);
 			surface->fillRect(back, black);
 
-			Common::Rect shieldBar(87 - shield, 176, 88, 183);
+			Common::Rect shieldBar(87 - shield, 177, 88, 183);
 			surface->fillRect(shieldBar, yellow);
 		}
 	}


Commit: 43a694913d2c7c329160b867ddc6ea343d41defc
    https://github.com/scummvm/scummvm/commit/43a694913d2c7c329160b867ddc6ea343d41defc
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:43+01:00

Commit Message:
FREESCAPE: tweak polygon offset in OpenGL

Changed paths:
    engines/freescape/gfx_opengl.cpp


diff --git a/engines/freescape/gfx_opengl.cpp b/engines/freescape/gfx_opengl.cpp
index 10658c52abe..017bb557293 100644
--- a/engines/freescape/gfx_opengl.cpp
+++ b/engines/freescape/gfx_opengl.cpp
@@ -270,7 +270,7 @@ void OpenGLRenderer::renderFace(const Common::Array<Math::Vector3d> &vertices) {
 void OpenGLRenderer::polygonOffset(bool enabled) {
 	if (enabled) {
 		glEnable(GL_POLYGON_OFFSET_FILL);
-		glPolygonOffset(-2.0f, 1.0f);
+		glPolygonOffset(-10.0f, 1.0f);
 	} else {
 		glPolygonOffset(0, 0);
 		glDisable(GL_POLYGON_OFFSET_FILL);


Commit: 8a81870cf13e7da5052a1d4737d6efa5bb0b6551
    https://github.com/scummvm/scummvm/commit/8a81870cf13e7da5052a1d4737d6efa5bb0b6551
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:44+01:00

Commit Message:
FREESCAPE: removed unused global pointer to the engine

Changed paths:
    engines/freescape/freescape.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 8ec51905e4c..587ab795215 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -32,11 +32,8 @@
 
 namespace Freescape {
 
-FreescapeEngine *g_freescape = NULL;
-
 FreescapeEngine::FreescapeEngine(OSystem *syst, const ADGameDescription *gd)
 	: Engine(syst), _gameDescription(gd), _gfx(nullptr) {
-	g_freescape = this;
 	if (!ConfMan.hasKey("render_mode") || ConfMan.get("render_mode").empty())
 		_renderMode = Common::kRenderEGA;
 	else


Commit: ec2d8fb67f39fc341146b0ae9f92f36fcd4e7796
    https://github.com/scummvm/scummvm/commit/ec2d8fb67f39fc341146b0ae9f92f36fcd4e7796
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:44+01:00

Commit Message:
FREESCAPE: reworded original copyright statement

Changed paths:
    engines/freescape/detection.cpp


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index 034ff0c46c1..f1cf0883d80 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -282,7 +282,7 @@ public:
 	}
 
 	const char *getOriginalCopyright() const override {
-		return "Copyright (C) Incentive Software 1987";
+		return "Copyright (C) 1987 Incentive Software";
 	}
 
 	const DebugChannelDef *getDebugChannels() const override {


Commit: b105f05a3dc0bcf9c0666a2c14f8386407ebdc39
    https://github.com/scummvm/scummvm/commit/b105f05a3dc0bcf9c0666a2c14f8386407ebdc39
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:44+01:00

Commit Message:
FREESCAPE: added missing EOL

Changed paths:
    engines/freescape/POTFILES


diff --git a/engines/freescape/POTFILES b/engines/freescape/POTFILES
index 692e1a8b87b..69559eb9fe8 100644
--- a/engines/freescape/POTFILES
+++ b/engines/freescape/POTFILES
@@ -1 +1 @@
-engines/freescape/detection.cpp
\ No newline at end of file
+engines/freescape/detection.cpp


Commit: c4f683d20afcf5c4564d3f81b6bb1e436b540388
    https://github.com/scummvm/scummvm/commit/c4f683d20afcf5c4564d3f81b6bb1e436b540388
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:44+01:00

Commit Message:
FREESCAPE: use texture format when building the eclipse UI

Changed paths:
    engines/freescape/games/eclipse.cpp


diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index 42767b80171..ad128026193 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -171,14 +171,14 @@ void EclipseEngine::drawUI() {
 	_gfx->setViewport(_fullscreenViewArea);
 
 	Graphics::Surface *surface = new Graphics::Surface();
-	surface->create(_screenW, _screenH, _gfx->_currentPixelFormat);
-	uint32 gray = _gfx->_currentPixelFormat.RGBToColor(0xA0, 0xA0, 0xA0);
+	surface->create(_screenW, _screenH, _gfx->_texturePixelFormat);
+	uint32 gray = _gfx->_texturePixelFormat.ARGBToColor(0x00, 0xA0, 0xA0, 0xA0);
 	surface->fillRect(_fullscreenViewArea, gray);
 
 	int score = _gameStateVars[k8bitVariableScore];
-	uint32 yellow = _gfx->_currentPixelFormat.RGBToColor(0xFF, 0xFF, 0x55);
-	uint32 black = _gfx->_currentPixelFormat.RGBToColor(0x00, 0x00, 0x00);
-	uint32 white = _gfx->_currentPixelFormat.RGBToColor(0xFF, 0xFF, 0xFF);
+	uint32 yellow = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0xFF, 0xFF, 0x55);
+	uint32 black = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0x00, 0x00, 0x00);
+	uint32 white = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0xFF, 0xFF, 0xFF);
 
 	if (!_currentAreaMessages.empty())
 		drawStringInSurface(_currentAreaMessages[0], 102, 135, black, yellow, surface);


Commit: c20e5af8b81f0fbbb2f750370313b2e080f5f236
    https://github.com/scummvm/scummvm/commit/c20e5af8b81f0fbbb2f750370313b2e080f5f236
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:44+01:00

Commit Message:
FREESCAPE: simplify low-level byte operations

Changed paths:
    engines/freescape/games/palettes.cpp


diff --git a/engines/freescape/games/palettes.cpp b/engines/freescape/games/palettes.cpp
index cab5871e1d8..7d336773dd9 100644
--- a/engines/freescape/games/palettes.cpp
+++ b/engines/freescape/games/palettes.cpp
@@ -72,13 +72,13 @@ void FreescapeEngine::loadPalettes(Common::SeekableReadStream *file, int offset)
 			int v = file->readUint16BE();
 			r = (v & 0xf00) >> 8;
 			r = r << 4 | r;
-			palette[c][0] = byte(r);
+			palette[c][0] = r & 0xff;
 			g = (v & 0xf0) >> 4;
 			g = g << 4 | g;
-			palette[c][1] = byte(g);
+			palette[c][1] = g & 0xff;
 			b = v & 0xf;
 			b = b << 4 | b;
-			palette[c][2] = byte(b);
+			palette[c][2] = b & 0xff;
 		}
 
 		assert(!_paletteByArea.contains(label));


Commit: 3fc21a8080d917af141651c951b565c0e9a233fb
    https://github.com/scummvm/scummvm/commit/3fc21a8080d917af141651c951b565c0e9a233fb
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:44+01:00

Commit Message:
FREESCAPE: sorted filenames in module.mk

Changed paths:
    engines/freescape/module.mk


diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index 5e013a689b6..09f2b5a640e 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -1,9 +1,8 @@
 MODULE := engines/freescape
 
 MODULE_OBJS := \
-	metaengine.o \
-	freescape.o \
 	area.o \
+	freescape.o \
 	games/castle.o \
 	games/dark.o \
 	games/driller.o \
@@ -11,16 +10,17 @@ MODULE_OBJS := \
 	games/palettes.o \
 	gfx.o \
 	keyboard.o \
-	objects/object.o \
-	objects/entrance.o \
-	objects/geometricobject.o \
-	objects/global.o \
-	objects/sensor.o \
 	loaders/8bitBinaryLoader.o \
 	language/8bitDetokeniser.o \
 	language/instruction.o \
+	metaengine.o \
 	movement.o \
 	neo.o \
+	objects/entrance.o \
+	objects/geometricobject.o \
+	objects/global.o \
+	objects/object.o \
+	objects/sensor.o \
 	sound.o
 
 ifdef USE_TINYGL


Commit: 5d6e0edc5b4d02dc3d388203477ea81dea1f9928
    https://github.com/scummvm/scummvm/commit/5d6e0edc5b4d02dc3d388203477ea81dea1f9928
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:45+01:00

Commit Message:
FREESCAPE: Object is a header-only class

Changed paths:
  R engines/freescape/objects/object.cpp
    engines/freescape/module.mk
    engines/freescape/objects/object.h


diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index 09f2b5a640e..26bc2ab77b0 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -19,7 +19,6 @@ MODULE_OBJS := \
 	objects/entrance.o \
 	objects/geometricobject.o \
 	objects/global.o \
-	objects/object.o \
 	objects/sensor.o \
 	sound.o
 
diff --git a/engines/freescape/objects/object.cpp b/engines/freescape/objects/object.cpp
deleted file mode 100644
index 52c9f8ac61b..00000000000
--- a/engines/freescape/objects/object.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-// Based on Phantasma code by Thomas Harte (2013),
-// available at https://github.com/TomHarte/Phantasma/ (MIT)
-
-#include "freescape/objects/object.h"
-
-namespace Freescape {
-
-ObjectType Object::getType() { return _type; }
-uint16 Object::getObjectID() { return _objectID; }
-uint16 Object::getObjectFlags() { return _flags; }
-void Object::setObjectFlags(uint32 flags_) { _flags = flags_; }
-Math::Vector3d Object::getOrigin() { return _origin; }
-void Object::setOrigin(Math::Vector3d origin_) { _origin = origin_; };
-Math::Vector3d Object::getSize() { return _size; }
-
-bool Object::isDrawable() { return false; }
-bool Object::isPlanar() { return false; }
-
-bool Object::isInvisible() { return _flags & 0x80; }
-void Object::makeInvisible() { _flags = _flags | 0x80; }
-void Object::makeVisible() { _flags = _flags & ~0x80; }
-bool Object::isDestroyed() { return _flags & 0x20; }
-void Object::destroy() { _flags = _flags | 0x20; }
-void Object::toggleVisibility() { _flags = _flags ^ 0x80; }
-
-Object::~Object() {}
-
-} // End of namespace Freescape
diff --git a/engines/freescape/objects/object.h b/engines/freescape/objects/object.h
index 6ce775242f7..5ff6fdd1a19 100644
--- a/engines/freescape/objects/object.h
+++ b/engines/freescape/objects/object.h
@@ -55,27 +55,28 @@ enum ObjectType {
 
 class Object {
 public:
-	virtual ObjectType getType();
-	uint16 getObjectID();
-	uint16 getObjectFlags();
-	void setObjectFlags(uint32 flags);
-	Math::Vector3d getOrigin();
-	virtual void setOrigin(Math::Vector3d origin);
-	Math::Vector3d getSize();
+	virtual ObjectType getType() { return _type; }
+	uint16 getObjectID() { return _objectID; }
+	uint16 getObjectFlags() { return _flags; }
+	void setObjectFlags(uint32 flags_) { _flags = flags_; }
+	Math::Vector3d getOrigin() { return _origin; }
+	virtual void setOrigin(Math::Vector3d origin_) { _origin = origin_; };
+	Math::Vector3d getSize() { return _size; }
+
+	virtual bool isDrawable() { return false; }
+	virtual bool isPlanar() { return false; }
+
+	bool isInvisible() { return _flags & 0x80; }
+	void makeInvisible() { _flags = _flags | 0x80; }
+	void makeVisible() { _flags = _flags & ~0x80; }
+	bool isDestroyed() { return _flags & 0x20; }
+	void destroy() { _flags = _flags | 0x20; }
+	void toggleVisibility() { _flags = _flags ^ 0x80; }
+
+	virtual ~Object() {}
 
 	virtual void draw(Freescape::Renderer *gfx) = 0;
 
-	virtual bool isDrawable();
-	virtual bool isPlanar();
-	bool isInvisible();
-	void makeInvisible();
-	void makeVisible();
-	void toggleVisibility();
-	bool isDestroyed();
-	void destroy();
-
-	virtual ~Object();
-
 	uint16 _flags;
 	ObjectType _type;
 	uint16 _objectID;


Commit: 3450bb7474824fbfc9224e7dc668d2b3b0099269
    https://github.com/scummvm/scummvm/commit/3450bb7474824fbfc9224e7dc668d2b3b0099269
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:45+01:00

Commit Message:
FREESCAPE: Sensor is a header-only class

Changed paths:
  R engines/freescape/objects/sensor.cpp
    engines/freescape/module.mk
    engines/freescape/objects/sensor.h


diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index 26bc2ab77b0..491774b3820 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -19,7 +19,6 @@ MODULE_OBJS := \
 	objects/entrance.o \
 	objects/geometricobject.o \
 	objects/global.o \
-	objects/sensor.o \
 	sound.o
 
 ifdef USE_TINYGL
diff --git a/engines/freescape/objects/sensor.cpp b/engines/freescape/objects/sensor.cpp
deleted file mode 100644
index f4331845865..00000000000
--- a/engines/freescape/objects/sensor.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-// Based on Phantasma code by Thomas Harte (2013),
-// available at https://github.com/TomHarte/Phantasma/ (MIT)
-
-#include "freescape/objects/sensor.h"
-
-namespace Freescape {
-
-Sensor::Sensor(
-	uint16 objectID_,
-	const Math::Vector3d &origin_,
-	const Math::Vector3d &rotation_) {
-	_objectID = objectID_;
-	_origin = origin_;
-	_rotation = rotation_;
-	_flags = 0;
-}
-
-Sensor::~Sensor() {}
-
-bool Sensor::isDrawable() { return false; }
-bool Sensor::isPlanar() { return true; }
-
-} // End of namespace Freescape
diff --git a/engines/freescape/objects/sensor.h b/engines/freescape/objects/sensor.h
index ed02b5a7a7f..1b843bdc761 100644
--- a/engines/freescape/objects/sensor.h
+++ b/engines/freescape/objects/sensor.h
@@ -32,13 +32,18 @@ namespace Freescape {
 class Sensor : public Object {
 public:
 	Sensor(
-		uint16 objectID,
-		const Math::Vector3d &origin,
-		const Math::Vector3d &rotation);
-	virtual ~Sensor();
-
-	bool isDrawable() override;
-	bool isPlanar() override;
+		uint16 objectID_,
+		const Math::Vector3d &origin_,
+		const Math::Vector3d &rotation_) {
+		_objectID = objectID_;
+		_origin = origin_;
+		_rotation = rotation_;
+		_flags = 0;
+	}
+
+	virtual ~Sensor() {}
+	bool isDrawable() { return false; }
+	bool isPlanar() { return true; }
 	ObjectType getType() override { return kSensorType; };
 	Math::Vector3d getRotation() { return _rotation; }
 


Commit: 5d21f8b223e1d49120f42019a9179004346aa580
    https://github.com/scummvm/scummvm/commit/5d21f8b223e1d49120f42019a9179004346aa580
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:45+01:00

Commit Message:
FREESCAPE: GlobalStructure is a header-only class

Changed paths:
  R engines/freescape/objects/global.cpp
    engines/freescape/module.mk
    engines/freescape/objects/global.h


diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index 491774b3820..c1a46efc174 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -18,7 +18,6 @@ MODULE_OBJS := \
 	neo.o \
 	objects/entrance.o \
 	objects/geometricobject.o \
-	objects/global.o \
 	sound.o
 
 ifdef USE_TINYGL
diff --git a/engines/freescape/objects/global.cpp b/engines/freescape/objects/global.cpp
deleted file mode 100644
index 1bf85f0f397..00000000000
--- a/engines/freescape/objects/global.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "freescape/objects/global.h"
-
-namespace Freescape {
-
-GlobalStructure::GlobalStructure(const Common::Array<byte> structure_) {
-	_objectID = 255;
-	_structure = structure_;
-}
-
-} // End of namespace Freescape
diff --git a/engines/freescape/objects/global.h b/engines/freescape/objects/global.h
index b6a58d3ffb0..5d2dcf0ddaf 100644
--- a/engines/freescape/objects/global.h
+++ b/engines/freescape/objects/global.h
@@ -29,7 +29,11 @@ namespace Freescape {
 class GlobalStructure : public Object {
 public:
 	Common::Array<byte> _structure;
-	GlobalStructure(const Common::Array<byte> _structure);
+	GlobalStructure(const Common::Array<byte> structure_) {
+		_objectID = 255;
+		_structure = structure_;
+	}
+
 	ObjectType getType() override { return ObjectType::kEntranceType; };
 	void draw(Freescape::Renderer *gfx) override { error("cannot render GlobalStructure"); };
 };


Commit: d135f25e7ed13c21bd71025e820cbecd64a7315c
    https://github.com/scummvm/scummvm/commit/d135f25e7ed13c21bd71025e820cbecd64a7315c
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:45+01:00

Commit Message:
FREESCAPE: removed FrameLimiter class

Changed paths:
    engines/freescape/gfx.h


diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index a74aaefa51c..d3ea98633aa 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -132,29 +132,6 @@ protected:
 	Math::Matrix4 makeProjectionMatrix(float fov, float nearClipPlane, float farClipPlane) const;
 };
 
-/**
- * A framerate limiter
- *
- * Ensures the framerate does not exceed the specified value
- * by delaying until all of the timeslot allocated to the frame
- * is consumed.
- * Allows to curb CPU usage and have a stable framerate.
- */
-class FrameLimiter {
-public:
-	FrameLimiter(OSystem *system, const uint framerate);
-
-	void startFrame();
-	void delayBeforeSwap();
-
-private:
-	OSystem *_system;
-
-	bool _enabled;
-	uint _speedLimitMs;
-	uint _startFrameTime;
-};
-
 Graphics::RendererType determinateRenderType();
 Renderer *CreateGfxOpenGL(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode);
 Renderer *CreateGfxOpenGLShader(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode);


Commit: 9002723d7340b713d30afd6f79aa8cbafbe80f6a
    https://github.com/scummvm/scummvm/commit/9002723d7340b713d30afd6f79aa8cbafbe80f6a
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:45+01:00

Commit Message:
FREESCAPE: make sure the border surface is always correctly used in driller

Changed paths:
    engines/freescape/games/driller.cpp


diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 10ff6242646..816b02ca921 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -340,20 +340,20 @@ void DrillerEngine::drawUI() {
 	uint32 gray = _gfx->_texturePixelFormat.ARGBToColor(0x00, 0xA0, 0xA0, 0xA0);
 
 	Graphics::Surface *surface = nullptr;
-	if (_currentAreaMessages.size() == 2) {
+	if (_border) {
 		surface = new Graphics::Surface();
 		surface->create(_screenW, _screenH, _gfx->_texturePixelFormat);
 		surface->fillRect(_fullscreenViewArea, gray);
+	}
 
+	if (_currentAreaMessages.size() == 2) {
 		int score = _gameStateVars[k8bitVariableScore];
-
 		drawStringInSurface(_currentAreaMessages[0], 196, 177, yellow, black, surface);
 		drawStringInSurface(_currentAreaMessages[1], 196, 185, yellow, black, surface);
 		drawStringInSurface(Common::String::format("%04d", 2 * int(_position.x())), 150, 145, yellow, black, surface);
 		drawStringInSurface(Common::String::format("%04d", 2 * int(_position.z())), 150, 153, yellow, black, surface);
 		drawStringInSurface(Common::String::format("%04d", 2 * int(_position.y())), 150, 161, yellow, black, surface);
 		drawStringInSurface(Common::String::format("%d", _playerHeightNumber), 57, 161, yellow, black, surface);
-
 		drawStringInSurface(Common::String::format("%07d", score), 240, 129, yellow, black, surface);
 	}
 


Commit: ec31a66b2a4b85b38b740d2bd3ba1f7480430849
    https://github.com/scummvm/scummvm/commit/ec31a66b2a4b85b38b740d2bd3ba1f7480430849
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:45+01:00

Commit Message:
FREESCAPE: make sure the border surface is always correctly used in dark

Changed paths:
    engines/freescape/games/dark.cpp


diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index aedad42b7b6..be8a2a37ce3 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -111,38 +111,39 @@ void DarkEngine::gotoArea(uint16 areaID, int entranceID) {
 
 void DarkEngine::drawUI() {
 	_gfx->renderCrossair(0, _crossairPosition);
-
-	if (_currentAreaMessages.size() == 1) {
-		_gfx->setViewport(_fullscreenViewArea);
-
-		Graphics::Surface *surface = new Graphics::Surface();
-		surface->create(_screenW, _screenH, _gfx->_currentPixelFormat);
-		uint32 gray = _gfx->_currentPixelFormat.RGBToColor(0xA0, 0xA0, 0xA0);
+	uint32 gray = _gfx->_texturePixelFormat.ARGBToColor(0x00, 0xA0, 0xA0, 0xA0);
+	uint32 yellow = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0xFF, 0xFF, 0x55);
+	uint32 black = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0x00, 0x00, 0x00);
+
+	Graphics::Surface *surface = nullptr;
+	if (_border) {
+		surface = new Graphics::Surface();
+		surface->create(_screenW, _screenH, _gfx->_texturePixelFormat);
 		surface->fillRect(_fullscreenViewArea, gray);
+	}
 
+	if (_currentAreaMessages.size() == 1) {
 		int score = _gameStateVars[k8bitVariableScore];
-
-		uint32 yellow = _gfx->_currentPixelFormat.RGBToColor(0xFF, 0xFF, 0x55);
-		uint32 black = _gfx->_currentPixelFormat.RGBToColor(0x00, 0x00, 0x00);
-
 		drawStringInSurface(_currentAreaMessages[0], 112, 177, yellow, black, surface);
 		drawStringInSurface(Common::String::format("%04d", 2 * int(_position.x())), 201, 137, yellow, black, surface);
 		drawStringInSurface(Common::String::format("%04d", 2 * int(_position.z())), 201, 145, yellow, black, surface);
 		drawStringInSurface(Common::String::format("%04d", 2 * int(_position.y())), 201, 153, yellow, black, surface);
-
 		drawStringInSurface(Common::String::format("%07d", score), 95, 8, yellow, black, surface);
+	}
 
+	if (surface) {
 		if (!_uiTexture)
 			_uiTexture = _gfx->createTexture(surface);
 		else
 			_uiTexture->update(surface);
 
+		_gfx->setViewport(_fullscreenViewArea);
 		_gfx->drawTexturedRect2D(_fullscreenViewArea, _fullscreenViewArea, _uiTexture);
+		_gfx->setViewport(_viewArea);
+
 		surface->free();
 		delete surface;
 	}
-
-	_gfx->setViewport(_viewArea);
 }
 
 } // End of namespace Freescape


Commit: 1210c6ff8585817bf45a4edc23d123a8ba25a362
    https://github.com/scummvm/scummvm/commit/1210c6ff8585817bf45a4edc23d123a8ba25a362
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:46+01:00

Commit Message:
FREESCAPE: removed redudant pointer to OSystem

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/gfx.cpp
    engines/freescape/gfx.h
    engines/freescape/gfx_opengl.cpp
    engines/freescape/gfx_opengl.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/gfx_tinygl.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 587ab795215..6382b443cb9 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -389,7 +389,7 @@ void FreescapeEngine::processInput() {
 
 Common::Error FreescapeEngine::run() {
 	// Initialize graphics
-	_gfx = createRenderer(_system, _screenW, _screenH, _renderMode);
+	_gfx = createRenderer(_screenW, _screenH, _renderMode);
 	// The following error code will force return to launcher
 	// but it will not force any other GUI message to be displayed
 	if (!_gfx)
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index 6365ff81060..7dbe599f418 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -34,9 +34,7 @@
 
 namespace Freescape {
 
-Renderer::Renderer(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode)
-	: _system(system) {
-
+Renderer::Renderer(int screenW, int screenH, Common::RenderMode renderMode) {
 	_screenW = screenW;
 	_screenH = screenH;
 	_currentPixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
@@ -469,7 +467,7 @@ Graphics::RendererType determinateRenderType() {
 	return Graphics::kRendererTypeDefault;
 }
 
-Renderer *createRenderer(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode) {
+Renderer *createRenderer(int screenW, int screenH, Common::RenderMode renderMode) {
 	Graphics::PixelFormat pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
 	Graphics::RendererType rendererType = determinateRenderType();
 
@@ -483,13 +481,13 @@ Renderer *createRenderer(OSystem *system, int screenW, int screenH, Common::Rend
 
 	#if defined(USE_OPENGL_GAME) && !defined(USE_GLES2)
 		if (rendererType == Graphics::kRendererTypeOpenGL) {
-			return CreateGfxOpenGL(system, screenW, screenH, renderMode);
+			return CreateGfxOpenGL(screenW, screenH, renderMode);
 		}
 	#endif
 
 	#if defined(USE_TINYGL)
 	if (rendererType == Graphics::kRendererTypeTinyGL) {
-		return CreateGfxTinyGL(system, screenW, screenH, renderMode);
+		return CreateGfxTinyGL(screenW, screenH, renderMode);
 	}
 	#endif
 
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index d3ea98633aa..1af4de22323 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -53,7 +53,7 @@ public:
 
 class Renderer {
 public:
-	Renderer(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode);
+	Renderer(int screenW, int screenH, Common::RenderMode renderMode);
 	virtual ~Renderer();
 
 	Graphics::PixelFormat _currentPixelFormat;
@@ -118,7 +118,6 @@ public:
 	bool computeScreenViewport();
 
 protected:
-	OSystem *_system;
 	Common::Rect _screenViewport;
 	Common::Rect _viewport;
 	Common::Rect _unscaledViewport;
@@ -133,10 +132,10 @@ protected:
 };
 
 Graphics::RendererType determinateRenderType();
-Renderer *CreateGfxOpenGL(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode);
-Renderer *CreateGfxOpenGLShader(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode);
-Renderer *CreateGfxTinyGL(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode);
-Renderer *createRenderer(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode);
+Renderer *CreateGfxOpenGL(int screenW, int screenH, Common::RenderMode renderMode);
+Renderer *CreateGfxOpenGLShader(int screenW, int screenH, Common::RenderMode renderMode);
+Renderer *CreateGfxTinyGL(int screenW, int screenH, Common::RenderMode renderMode);
+Renderer *createRenderer(int screenW, int screenH, Common::RenderMode renderMode);
 
 } // End of namespace Freescape
 
diff --git a/engines/freescape/gfx_opengl.cpp b/engines/freescape/gfx_opengl.cpp
index 017bb557293..79fe4ac10f6 100644
--- a/engines/freescape/gfx_opengl.cpp
+++ b/engines/freescape/gfx_opengl.cpp
@@ -32,11 +32,11 @@
 
 namespace Freescape {
 
-Renderer *CreateGfxOpenGL(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode) {
-	return new OpenGLRenderer(system, screenW, screenH, renderMode);
+Renderer *CreateGfxOpenGL(int screenW, int screenH, Common::RenderMode renderMode) {
+	return new OpenGLRenderer(screenW, screenH, renderMode);
 }
 
-OpenGLRenderer::OpenGLRenderer(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode) : Renderer(system, screenW, screenH, renderMode) {
+OpenGLRenderer::OpenGLRenderer(int screenW, int screenH, Common::RenderMode renderMode) : Renderer(screenW, screenH, renderMode) {
 	_verts = (Vertex*) malloc(sizeof(Vertex) * 20);
 	_texturePixelFormat = OpenGLTexture::getRGBAPixelFormat();
 }
diff --git a/engines/freescape/gfx_opengl.h b/engines/freescape/gfx_opengl.h
index 636cbdf17c5..660d50971da 100644
--- a/engines/freescape/gfx_opengl.h
+++ b/engines/freescape/gfx_opengl.h
@@ -31,7 +31,7 @@ namespace Freescape {
 
 class OpenGLRenderer : public Renderer {
 public:
-	OpenGLRenderer(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode);
+	OpenGLRenderer(int screenW, int screenH, Common::RenderMode renderMode);
 	virtual ~OpenGLRenderer();
 
 	struct Vertex {
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 9c8fefa2c95..9a4e27b4a30 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -33,11 +33,11 @@
 
 namespace Freescape {
 
-Renderer *CreateGfxTinyGL(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode) {
-	return new TinyGLRenderer(system, screenW, screenH, renderMode);
+Renderer *CreateGfxTinyGL(int screenW, int screenH, Common::RenderMode renderMode) {
+	return new TinyGLRenderer(screenW, screenH, renderMode);
 }
 
-TinyGLRenderer::TinyGLRenderer(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode) : Renderer(system, screenW, screenH, renderMode) {
+TinyGLRenderer::TinyGLRenderer(int screenW, int screenH, Common::RenderMode renderMode) : Renderer(screenW, screenH, renderMode) {
 	_verts = (Vertex*) malloc(sizeof(Vertex) * 20);
 	_texturePixelFormat = TinyGLTexture::getRGBAPixelFormat();
 }
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index 4e94765b34f..79a726fe31c 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -30,7 +30,7 @@ namespace Freescape {
 
 class TinyGLRenderer : public Renderer {
 public:
-	TinyGLRenderer(OSystem *system, int screenW, int screenH, Common::RenderMode renderMode);
+	TinyGLRenderer(int screenW, int screenH, Common::RenderMode renderMode);
 	virtual ~TinyGLRenderer();
 
 	struct Vertex {


Commit: 401ebf9c269c285fd2d7fc4e291a428aa0f11eb5
    https://github.com/scummvm/scummvm/commit/401ebf9c269c285fd2d7fc4e291a428aa0f11eb5
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:46+01:00

Commit Message:
FREESCAPE: added missing headers to the renderers implementations

Changed paths:
    engines/freescape/gfx_opengl.cpp
    engines/freescape/gfx_tinygl.cpp


diff --git a/engines/freescape/gfx_opengl.cpp b/engines/freescape/gfx_opengl.cpp
index 79fe4ac10f6..bbfe8ff5419 100644
--- a/engines/freescape/gfx_opengl.cpp
+++ b/engines/freescape/gfx_opengl.cpp
@@ -19,7 +19,8 @@
  *
  */
 
-// Based on Phantasma code by Thomas Harte (2013)
+// Based on Phantasma code by Thomas Harte (2013),
+// available at https://github.com/TomHarte/Phantasma/ (MIT)
 
 #include "common/config-manager.h"
 #include "common/math.h"
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 9a4e27b4a30..3bc758013cf 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -19,7 +19,8 @@
  *
  */
 
-// Based on Phantasma code by Thomas Harte (2013)
+// Based on Phantasma code by Thomas Harte (2013),
+// available at https://github.com/TomHarte/Phantasma/ (MIT)
 
 #include "common/config-manager.h"
 #include "common/math.h"


Commit: 5b335031a5fb511547dde763582dacb715e2ef25
    https://github.com/scummvm/scummvm/commit/5b335031a5fb511547dde763582dacb715e2ef25
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:46+01:00

Commit Message:
FREESCAPE: reimplemented playMusic using Audio::SeekableAudioStream::openStreamFile

Changed paths:
    engines/freescape/games/driller.cpp
    engines/freescape/sound.cpp


diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 816b02ca921..cc0f6a4120f 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -127,8 +127,8 @@ void DrillerEngine::loadAssets() {
 	_angleRotations.push_back(5.0);
 	_angleRotations.push_back(9.5);
 
-	// Start playing music, if any
-	playMusic("Matt Gray - The Best Of Reformation - 07 Driller Theme.ogg");
+	// Start playing music, if any, in any supported format
+	playMusic("Matt Gray - The Best Of Reformation - 07 Driller Theme");
 }
 
 void DrillerEngine::loadAssetsDemo() {
diff --git a/engines/freescape/sound.cpp b/engines/freescape/sound.cpp
index d3e8b1feb7f..948cef266d9 100644
--- a/engines/freescape/sound.cpp
+++ b/engines/freescape/sound.cpp
@@ -20,8 +20,8 @@
  */
 
 #include "common/file.h"
+#include "audio/audiostream.h"
 #include "audio/decoders/raw.h"
-#include "audio/decoders/vorbis.h"
 
 #include "freescape/freescape.h"
 
@@ -230,17 +230,13 @@ void FreescapeEngine::playWav(const Common::String filename) {
 }
 
 void FreescapeEngine::playMusic(const Common::String filename) {
-	Common::File *file = new Common::File();
-
-	if (!file->open(filename)) {
-		debugC(1, kFreescapeDebugMedia, "Unable to find sound file %s", filename.c_str());
-		return;
+	Audio::SeekableAudioStream *stream = nullptr;
+	stream = Audio::SeekableAudioStream::openStreamFile(filename);
+	if (stream) {
+		Audio::LoopingAudioStream *loop = new Audio::LoopingAudioStream(stream, 0);
+		_mixer->playStream(Audio::Mixer::kMusicSoundType, &_musicHandle, loop);
+		_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, Audio::Mixer::kMaxMixerVolume / 4);
 	}
-
-	Audio::LoopingAudioStream *stream;
-	stream = new Audio::LoopingAudioStream(Audio::makeVorbisStream(file, DisposeAfterUse::YES), 0);
-	_mixer->playStream(Audio::Mixer::kMusicSoundType, &_musicHandle, stream);
-	_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, Audio::Mixer::kMaxMixerVolume / 4);
 }
 
 void FreescapeEngine::playSoundFx(int index, bool sync) {


Commit: cdeec2977a400e6caa3aaffc1738d516d680c2bb
    https://github.com/scummvm/scummvm/commit/cdeec2977a400e6caa3aaffc1738d516d680c2bb
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:46+01:00

Commit Message:
FREESCAPE: moved NeoDecoder into the Freescape namespace

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/neo.cpp
    engines/freescape/neo.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 6382b443cb9..2e91023fec5 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -624,7 +624,7 @@ void FreescapeEngine::loadDataBundle() {
 
 byte *FreescapeEngine::getPaletteFromNeoImage(Common::SeekableReadStream *stream, int offset) {
 	stream->seek(offset);
-	Image::NeoDecoder decoder;
+	NeoDecoder decoder;
 	decoder.loadStream(*stream);
 	byte *palette = (byte *)malloc(16 * 3 * sizeof(byte));
 	memcpy(palette, decoder.getPalette(), 16 * 3 * sizeof(byte));
@@ -633,7 +633,7 @@ byte *FreescapeEngine::getPaletteFromNeoImage(Common::SeekableReadStream *stream
 
 Graphics::Surface *FreescapeEngine::loadAndConvertNeoImage(Common::SeekableReadStream *stream, int offset, byte *palette) {
 	stream->seek(offset);
-	Image::NeoDecoder decoder(palette);
+	NeoDecoder decoder(palette);
 	decoder.loadStream(*stream);
 	Graphics::Surface *surface = new Graphics::Surface();
 	surface->copyFrom(*decoder.getSurface());
diff --git a/engines/freescape/neo.cpp b/engines/freescape/neo.cpp
index 884d2b1c98e..4adb268e041 100644
--- a/engines/freescape/neo.cpp
+++ b/engines/freescape/neo.cpp
@@ -26,7 +26,7 @@
 
 #include "freescape/neo.h"
 
-namespace Image {
+namespace Freescape {
 
 NeoDecoder::NeoDecoder(byte *palette) {
 	_surface = nullptr;
@@ -119,4 +119,4 @@ bool NeoDecoder::loadStream(Common::SeekableReadStream &stream) {
 	return true;
 }
 
-} // End of namespace Image
+} // End of namespace Freescape
diff --git a/engines/freescape/neo.h b/engines/freescape/neo.h
index 1a88a771a76..d52309319f1 100644
--- a/engines/freescape/neo.h
+++ b/engines/freescape/neo.h
@@ -32,9 +32,9 @@ namespace Common {
 class SeekableReadStream;
 }
 
-namespace Image {
+namespace Freescape {
 
-class NeoDecoder : public ImageDecoder {
+class NeoDecoder : public Image::ImageDecoder {
 public:
 	NeoDecoder(byte *palette = nullptr);
 	virtual ~NeoDecoder();
@@ -52,6 +52,6 @@ private:
 	byte *_palette;
 	uint16 _paletteColorCount;
 };
-} // End of namespace Image
+} // End of namespace Freescape
 
 #endif // FREESCAPE_NEO_H


Commit: 6a1dc05132ba658f228a5d5335a72a567a6d414a
    https://github.com/scummvm/scummvm/commit/6a1dc05132ba658f228a5d5335a72a567a6d414a
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-06T22:00:46+01:00

Commit Message:
FREESCAPE: check bounds in copyToVertexArray

Changed paths:
    engines/freescape/gfx.h
    engines/freescape/gfx_opengl.cpp
    engines/freescape/gfx_opengl.h
    engines/freescape/gfx_tinygl.cpp
    engines/freescape/gfx_tinygl.h


diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 1af4de22323..cbd41842a0b 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -32,6 +32,8 @@
 
 namespace Freescape {
 
+#define kVertexArraySize 20
+
 typedef Common::Array<byte *> ColorMap;
 
 class Renderer;
diff --git a/engines/freescape/gfx_opengl.cpp b/engines/freescape/gfx_opengl.cpp
index bbfe8ff5419..23f54e6200d 100644
--- a/engines/freescape/gfx_opengl.cpp
+++ b/engines/freescape/gfx_opengl.cpp
@@ -38,7 +38,7 @@ Renderer *CreateGfxOpenGL(int screenW, int screenH, Common::RenderMode renderMod
 }
 
 OpenGLRenderer::OpenGLRenderer(int screenW, int screenH, Common::RenderMode renderMode) : Renderer(screenW, screenH, renderMode) {
-	_verts = (Vertex*) malloc(sizeof(Vertex) * 20);
+	_verts = (Vertex *)malloc(sizeof(Vertex) * kVertexArraySize);
 	_texturePixelFormat = OpenGLTexture::getRGBAPixelFormat();
 }
 
diff --git a/engines/freescape/gfx_opengl.h b/engines/freescape/gfx_opengl.h
index 660d50971da..19d8e47fc98 100644
--- a/engines/freescape/gfx_opengl.h
+++ b/engines/freescape/gfx_opengl.h
@@ -41,6 +41,7 @@ public:
 	};
 
 	void copyToVertexArray(uint idx, const Math::Vector3d &src) {
+		assert(idx < kVertexArraySize);
 		_verts[idx].x = src.x(); _verts[idx].y = src.y(); _verts[idx].z = src.z();
 	}
 
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 3bc758013cf..4185081b03f 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -39,7 +39,7 @@ Renderer *CreateGfxTinyGL(int screenW, int screenH, Common::RenderMode renderMod
 }
 
 TinyGLRenderer::TinyGLRenderer(int screenW, int screenH, Common::RenderMode renderMode) : Renderer(screenW, screenH, renderMode) {
-	_verts = (Vertex*) malloc(sizeof(Vertex) * 20);
+	_verts = (Vertex *)malloc(sizeof(Vertex) * kVertexArraySize);
 	_texturePixelFormat = TinyGLTexture::getRGBAPixelFormat();
 }
 
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index 79a726fe31c..41a06324080 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -40,6 +40,7 @@ public:
 	};
 
 	void copyToVertexArray(uint idx, const Math::Vector3d &src) {
+		assert(idx < kVertexArraySize);
 		_verts[idx].x = src.x(); _verts[idx].y = src.y(); _verts[idx].z = src.z();
 	}
 




More information about the Scummvm-git-logs mailing list