Compare commits

..
Author SHA1 Message Date
cambragol 342fbdd3ae Merge branch 'main' into fallout2.cfg-enhancement 2025-06-23 17:03:07 +09:00
Mike Klaas 0adc9c9e77 Prevent pop-in by drawing city circles/names to temp buffer (#178)
* Draw city/name to a temp buffer to prevent pop-in
2025-06-22 22:48:08 -07:00
cambragol af413125bd Merge branch 'main' into fallout2.cfg-enhancement 2025-06-22 20:23:26 +09:00
cambragol ea0afc84fa Merge pull request #215 from fallout2-ce/decrypt-win-refresh
Decryption of `_GNW_win_refresh`
2025-06-22 11:03:10 +09:00
Mike Klaas c663d79b97 fix bug(?) 2025-06-21 14:43:10 -07:00
Mike Klaas eaa9091bcd one omre 2025-06-19 23:48:01 -07:00
Mike Klaas 76ab99cf73 add a few more notes 2025-06-19 23:47:42 -07:00
github-actions[bot] bed9555f9a chore: auto-format with clang-format 2025-06-20 06:10:55 +00:00
Mike Klaas 9c5294ca88 Decryption of _GNW_win_refresh 2025-06-19 23:09:16 -07:00
cambragol 781d8ab282 Merge pull request #177 from fallout2-ce/dat-error-handling
Update xfile.cc
2025-06-20 08:44:44 +09:00
cambragol afd99fa01b Merge branch 'main' into fallout2.cfg-enhancement 2025-06-19 16:26:26 +09:00
cambragol 34ef1c2f26 Merge pull request #213 from fallout2-ce/disappearing-inventory-item-fix
Update inventory.cc
2025-06-18 14:17:52 +09:00
cambragol fdc54cfd0b Update inventory.cc
Restoring fix to make items disappear when selecting in inventory #160
2025-06-18 07:53:59 +09:00
cambragol 3e469ea8e8 Update svga.cc
Removed commented out lines
2025-06-17 19:35:05 +09:00
cambragol ddefda32e7 Update ddraw.ini
Added missing features to ddraw.

-iface stuff
-worldmaptravelmarkers
-gapless music
2025-06-17 14:28:57 +09:00
cambragol 0334b8de05 Update README.md
small fix to readme to clarify.
2025-06-17 14:24:55 +09:00
cambragol 1cab275037 Update .gitignore
removed accidentally updated .gitignore entries.
2025-06-17 14:23:06 +09:00
github-actions[bot] 7eb269bab8 chore: auto-format with clang-format 2025-06-17 05:21:51 +00:00
cambragol c18d7ab25e hires_stencil
Moved hires_stencil from ddraw to fallout2.cfg
2025-06-17 09:06:18 +09:00
cambragol 59bf337583 Update README.md
Updated to reflect changes to fallout2.cfg and removal of f2_res.ini
2025-06-17 08:34:44 +09:00
cambragol 88179574e8 Making 'graphics' settings category
moved all new f2_res settings into seperate 'graphics' category - was dumped in 'system' before
2025-06-17 07:43:47 +09:00
cambragol 0733acfad7 Iface to ddraw
removed f2_res.ini res in game.cc for splash screens - replaced with settings.system.splash_size;
added game config for all f2_res setting, except iface/sidebars
Moved iface/sidebars setting to sfall -ddraw.ini
2025-06-17 07:23:26 +09:00
Mike Klaas a63aff09ce (sfall) Implement set_map_time_multi (#207)
* (sfall) Implement `set_map_time_multi`
2025-06-16 12:02:40 -07:00
cambragol 1388ca1f83 First Draft
Moving f2_res.ini setting into fallout2.cfg, where appropriate

Added some setting for stretching/aspect/highquality

renamed screen_width/height to game_width/height (to later make clear that this will be the 'in game (map) size' - *not* the menu etc. Will make sense with stretching.

Added config for falloutce.dat loading.
2025-06-16 15:44:38 +09:00
cambragol 3d2aced2f7 Merge pull request #149 from fallout2-ce/worldmap-fallout1-trail-feature
Worldmap Fallout1 trail Feature
2025-06-12 14:26:27 +09:00
cambragol 1d6111b89f Merge pull request #202 from fallout2-ce/fix-for-splash-screens
Fix for Splash Screens
2025-06-12 14:24:04 +09:00
Mike Klaas 21c906cc5c Implement op_get_world_map_x/y_pos (#205) 2025-06-11 22:16:55 -07:00
Vasilii Rogin a67fe7ead1 Merge pull request #191 from fallout2-ce/scan_scripts_for_unknown_opcodes_2
Scanner of not implemented opcodes, metarules, config options
2025-06-11 16:18:21 +03:00
Vasilii Rogin f0691d2c24 Fix for hooks 2025-06-11 16:00:55 +03:00
github-actions[bot] fb30648e2e chore: auto-format with clang-format 2025-06-11 12:53:54 +00:00
Vasilii Rogin 216cbb3861 Add hooks scan 2025-06-11 15:52:41 +03:00
github-actions[bot] be63df4bf6 chore: auto-format with clang-format 2025-06-11 12:10:59 +00:00
Vasilii Rogin 4cf35fd946 Enable scanner of unimplemented by command line argument 2025-06-11 15:10:27 +03:00
Vasilii Rogin dd418ee0f5 Merge branch 'main' into scan_scripts_for_unknown_opcodes_2 2025-06-11 14:47:56 +03:00
Mike Klaas eb5cc7be4f QoL: Ctrl-click to equip in inventory screen (#175)
Very similar to sfall's implementation.
2025-06-10 22:27:22 -07:00
Vasilii Rogin 8c6f28b018 Merge pull request #193 from fallout2-ce/update_sdl2_into_2_32_8
Update SDL2 into 2.32.8
2025-06-10 11:17:26 +03:00
Vasilii Rogin 2e36030389 Merge branch 'main' into update_sdl2_into_2_32_8 2025-06-09 23:19:02 +03:00
Mike Klaas a88ca9f7e7 Fix build warnings introduced by sfall opcodes/metarules (#201) 2025-06-09 08:26:47 -07:00
Mike Klaas 72d9ae85c8 sfall: get_ini_section(s) (#199)
Implements get_ini_section, needed for Et Tu, and get_ini_sections. Fixes buggy set_ini_setting.

Also includes tests for existing ini functions, and moves them all to sfall_init.cc. (opcodes and metarules files were getting long, and this matches sfall's structure)
2025-06-09 08:26:30 -07:00
cambragol a8f2de1a56 Update xfile.cc
removed redundant chdir and added final cleanup for failure
2025-06-09 21:09:15 +09:00
github-actions[bot] 51b82ac1ac chore: auto-format with clang-format 2025-06-09 11:37:04 +00:00
cambragol 0d97222797 Update game.cc
Load options before show splash, so brightness is correct
2025-06-09 20:34:22 +09:00
cambragol b30463ab01 Update svga.cc
Missing fix for Splash Screens courtesy of Alex
2025-06-09 20:31:29 +09:00
github-actions[bot] 9d932b0d2c chore: auto-format with clang-format 2025-06-09 10:25:20 +00:00
Vasilii Rogin 8d76b9655c Use custom to_lower 2025-06-09 13:24:51 +03:00
Vasilii Rogin 0e6c4d9684 Use custom comparator 2025-06-09 13:01:03 +03:00
Vasilii Rogin 02c5efac26 Merge remote-tracking branch 'fallout2-ce/main' into scan_scripts_for_unknown_opcodes_2 2025-06-09 12:52:29 +03:00
cambragol b7933f6b80 Merge pull request #159 from fallout2-ce/inventory-character-display-fix
Fix Backgrounds on Spinning Characters
2025-06-09 17:03:46 +09:00
cambragol fcb1680db2 Merge pull request #144 from fallout2-ce/Localize-Fonts
Localize fonts
2025-06-09 17:03:23 +09:00
github-actions[bot] ea4d978bc1 chore: auto-format with clang-format 2025-06-08 06:48:28 +00:00
Vasilii Rogin 22548a3c70 Merge branch 'main' into scan_scripts_for_unknown_opcodes_2 2025-06-08 09:47:58 +03:00
Vasilii Rogin 3dc89d49e2 Merge branch 'main' into scan_scripts_for_unknown_opcodes_2 2025-06-07 12:43:50 +03:00
Vasilii Rogin 822d5dfd7d Do not use build-in directory_iterator for android 2025-06-07 12:37:14 +03:00
Vasilii Rogin 879634bf9c Remove import of dirent 2025-06-07 12:28:29 +03:00
Vasilii Rogin 795ef54d70 fix formatting 2025-06-07 12:21:45 +03:00
Vasilii Rogin 14b06d2dcc Add scan for windows 2025-06-07 12:21:20 +03:00
Vasilii Rogin ed959edbbb Split scanned by files 2025-06-07 12:15:26 +03:00
Vasilii Rogin 7940ea791c Add polyfill for directory_iterator 2025-06-07 11:19:53 +03:00
Vasilii Rogin 3f270aa4cc Merge branch 'main' into scan_scripts_for_unknown_opcodes_2 2025-06-07 11:10:41 +03:00
Vasilii Rogin b8769fded1 Bump CI cache 2025-06-06 21:30:38 +03:00
Vasilii Rogin 43d5b6028d Update SDL2 into 2.32.8 2025-06-06 21:21:53 +03:00
Vasilii Rogin da3f1cc426 Fixes 2025-06-04 21:25:47 +03:00
github-actions[bot] a892461dac chore: auto-format with clang-format 2025-06-04 17:56:15 +00:00
Vasilii Rogin 209d2d027b Add TODO 2025-06-04 20:52:25 +03:00
Vasilii Rogin b8385d7775 Do not exit 2025-06-04 20:45:16 +03:00
Vasilii Rogin a3c365f9fe Rename scanner 2025-06-04 20:44:53 +03:00
Vasilii Rogin 87d4a4b8ca Scan f2_res.ini 2025-06-04 20:41:37 +03:00
Vasilii Rogin 1aa53a4720 Add scan for fallout2.cfg 2025-06-04 20:31:32 +03:00
Vasilii Rogin 6bcf2952f6 Add config scan 2025-06-04 20:26:40 +03:00
Vasilii Rogin e2927e1d0e Some intermedite progress 2025-06-04 20:00:26 +03:00
Vasilii Rogin bb839cd6c1 some fixes & improvements 2025-06-04 19:34:56 +03:00
Vasilii Rogin caa0e1bf1a Add scan in .dat files 2025-06-04 19:08:27 +03:00
Vasilii Rogin f3759d07a5 Adding .dat files scan 2025-06-04 18:58:43 +03:00
Vasilii Rogin 604fde895f Split by funcs 2025-06-04 18:45:46 +03:00
Vasilii Rogin f46c391e5d Merge remote-tracking branch 'fallout2-ce/main' into scan_scripts_for_unknown_opcodes_2 2025-06-03 23:06:35 +03:00
Vasilii Rogin 1e45b0184b Merge remote-tracking branch 'fallout2-ce/main' into scan_scripts_for_unknown_opcodes_2 2025-06-02 21:10:35 +03:00
Vasilii Rogin 447ea23862 Merge remote-tracking branch 'fallout2-ce/main' into scan_scripts_for_unknown_opcodes_2 2025-06-02 17:55:56 +03:00
Vasilii Rogin 72786c4d43 Merge remote-tracking branch 'fallout2-ce/main' into scan_scripts_for_unknown_opcodes_2 2025-06-01 20:04:07 +03:00
Vasilii Rogin 3d3e47c9db Scan for .int.expected too 2025-06-01 11:56:22 +03:00
Vasilii Rogin a9726cab56 Show by-file 2025-06-01 11:21:18 +03:00
Vasilii Rogin 400aa4d8a3 Update visual 2025-06-01 11:11:46 +03:00
Vasilii Rogin 599d3ab392 Merge remote-tracking branch 'fallout2-ce/main' into scan_scripts_for_unknown_opcodes_2 2025-06-01 10:46:24 +03:00
Vasilii Rogin 84336d4655 Fix warning 2025-06-01 10:45:49 +03:00
Vasilii Rogin 696e926177 Add note 2025-05-31 22:57:37 +03:00
Vasilii Rogin 30babd7e1f Improvements 2025-05-31 22:47:51 +03:00
Vasilii Rogin 6ff0b411e4 Show opcode cmd name 2025-05-31 22:26:16 +03:00
Vasilii Rogin 9f623f3f3e Add sfall human-readable opcodes 2025-05-31 22:09:52 +03:00
Vasilii Rogin d8bee457f4 Improve scanner 2025-05-31 22:04:14 +03:00
Vasilii Rogin fcabd63561 Still scanning for strings 2025-05-31 22:00:18 +03:00
Vasilii Rogin 73c024c705 Make kMetarules available 2025-05-31 21:09:19 +03:00
Vasilii Rogin 27da084b65 Scanning opcodes 2025-05-31 21:00:59 +03:00
Vasilii Rogin dfa610f352 Adding script scanner 2025-05-31 20:57:27 +03:00
Vasilii Rogin a0a597725a Fix extensions scan 2025-05-31 20:47:23 +03:00
Vasilii Rogin 7ae194a8ee Adding .ssl scanner 2025-05-31 20:44:30 +03:00
cambragol 7f7e103465 Update xfile.cc
This removes the creation of a 'dat' folder when opening or path finding fails. This may have been a leftover from development, or part of the mapper, however, in practice it prevents users getting correct error messages when opening the app with missing dats or incorrect dat paths.

With this fix, missing dats or paths should give a popup message to the user, instead of the ubiquitous 'cannot find fonts error'
2025-05-31 10:58:28 +09:00
cambragol 721e40f784 Merge branch 'main' into inventory-character-display-fix 2025-05-31 09:56:20 +09:00
github-actions[bot] 59c64451ff chore: auto-format with clang-format 2025-05-28 22:40:35 +00:00
cambragol 965f360578 Update worldmap.cc
Enclosed trail logic in config option
2025-05-29 07:40:09 +09:00
cambragol 3f79d79f25 Update sfall_config.h
Config option for worldmap trails. Name is from an Sfall option (I believe): WorldMapTravelMarkers
2025-05-29 07:19:31 +09:00
github-actions[bot] cad023a73e chore: auto-format with clang-format 2025-05-28 22:18:21 +00:00
cambragol 7490c900b3 Update sfall_config.cc
adding config option for the worldmap trail
2025-05-29 07:17:55 +09:00
github-actions[bot] 67a6119f34 chore: auto-format with clang-format 2025-05-26 07:36:34 +00:00
cambragol aa036c574e Update inventory.cc
Added some comments regarding which window is which
2025-05-26 16:36:06 +09:00
github-actions[bot] a17d7fb7d5 chore: auto-format with clang-format 2025-05-25 11:07:47 +00:00
cambragol 8ed777ba83 Merge branch 'main' into Localize-Fonts 2025-05-25 19:53:57 +09:00
cambragol 7c182b66a6 Update worldmap.cc
tweaked the drop parameters - looks closer to Fallout 1, paths more clearly defined (speeds).
2025-05-23 23:15:44 +09:00
cambragol f6320d3a66 Update worldmap.cc
Removed 'scaled' variables (leftover from my personal builds)
scaledViewWidth, scaledViewHeight, scaledWidth, scaledViewY, and scaledViewX
2025-05-23 20:03:32 +09:00
cambragol ec2ecd17d9 Update inventory.cc
First pass on fix for #148 

Adds correct blitting backgrounds for behind the spinning character
2025-05-23 15:13:07 +09:00
cambragol de06827c01 Update worldmap.cc
First draft (after many different tries) of worldmap trail enhancement, like in Fallout 1. Meant to be optional in the end.
2025-05-23 14:45:09 +09:00
cambragol e3437a8d0e Merge branch 'main' into Localize-Fonts 2025-05-21 09:26:38 +09:00
cambragol f12babe525 Update text_font.cc 2025-05-20 14:45:07 +09:00
cambragol cb990ac154 Update font_manager.cc 2025-05-20 14:44:33 +09:00
cambragol a3fc8d21be Update text_font.cc 2025-05-20 14:36:33 +09:00
cambragol cc805db194 Update font_manager.cc 2025-05-20 14:35:37 +09:00
45 changed files with 2197 additions and 941 deletions
+5 -5
View File
@@ -87,7 +87,7 @@ jobs:
uses: actions/cache@v4
with:
path: os/android/app/.cxx
key: android-cmake-v2
key: android-cmake-v100
- name: Setup signing config
if: env.KEYSTORE_FILE_BASE64 != '' && env.KEYSTORE_PROPERTIES_FILE_BASE64 != ''
@@ -128,7 +128,7 @@ jobs:
uses: actions/cache@v4
with:
path: out
key: ios-cmake-v5
key: ios-cmake-v100
- name: Configure
run: |
@@ -183,7 +183,7 @@ jobs:
uses: actions/cache@v4
with:
path: out
key: linux-${{ matrix.arch }}-cmake-v3
key: linux-${{ matrix.arch }}-cmake-v100
- name: Configure
run: |
@@ -288,7 +288,7 @@ jobs:
uses: actions/cache@v4
with:
path: out
key: macos-cmake-v6
key: macos-cmake-v100
- name: Configure
run: |
@@ -337,7 +337,7 @@ jobs:
uses: actions/cache@v4
with:
path: out
key: windows-${{ matrix.arch }}-cmake-v3
key: windows-${{ matrix.arch }}-cmake-v100
- name: Configure
shell: cmd
+1
View File
@@ -290,6 +290,7 @@ target_sources(${EXECUTABLE_NAME} PUBLIC
"src/sfall_arrays.h"
"src/touch.cc"
"src/touch.h"
"src/scan_unimplemented.cc"
)
if(IOS)
+26 -21
View File
@@ -96,16 +96,32 @@ The main configuration file is `fallout2.cfg`. There are several important setti
The `sound` folder (with `music` folder inside) might be located either in `data` folder, or be in the Fallout folder. Update `music_path1` setting to match your hierarchy, usually it's `data/sound/music/` or `sound/music/`. Make sure it matches your path exactly (so it might be `SOUND/MUSIC/` if you've installed Fallout from CD). Music files themselves (with `ACM` extension) should be all uppercased, regardless of `sound` and `music` folders.
The second configuration file is `f2_res.ini`. Use it to change game window size, enable/disable fullscreen mode and configure IFACE settings (the control bar at the bottom of the game screen).
Additionally, the [graphics] section provides options for fine tuning the appearence of the game. The included settings are:
```ini
[MAIN]
SCR_WIDTH=1280
SCR_HEIGHT=720
WINDOWED=1 ; 0 = fullscreen
SCALE_2X=1 ; 0 = original scale, 1 = 2x - requires increasing the minimum resolution from 640x480 to 1280x960.
```
[graphics]
fullscreen=0 ; 1 = fullscreeen, 0 = windowed
game_height=480 ; main play area height
game_width=640 ; main play area width
scale2x=0 ; 0 = original scale, 1 = 2x - requires increasing the minimum resolution from 640x480 to 1280x960.
splash_size=0 ; 0 = normal, 1 = aspect stretch, 2 = fullscreen stretch
```
[IFACE]
Recommendations:
- **Desktops**: Use any size you see fit.
- **Tablets**: Set these values to logical resolution of your device, for example iPad Pro 11 is 1668x2388 (pixels), but it's logical resolution is 834x1194 (points).
- **Mobile phones**: Set height to 480, calculate width according to your device screen (aspect) ratio, for example Samsung S21 is 20:9 device, so the width should be 480 * 20 / 9 = 1067.
In time this graphcs settings will receive an in-game interface. For the time being it must be configured manually.
The second configuration file is `ddraw.ini` (part of Sfall). There are dozens of options that adjust or override engine behaviour and gameplay mechanics. This file is intended for modders and advanced users.
For a sample ddraw.ini configuration file, containing all currently working settings use this link: [ddraw.ini](https://raw.githubusercontent.com/fallout2-ce/fallout2-ce/refs/heads/main/files/ddraw.ini)
Further, Fallout2-CE supports the following additional settings in ddraw.ini:
```
[Misc]
; if IFACE_BAR_MODE=0 - the bottom of the map view window sits at the top of the IFACE Bar.
; if IFACE_BAR_MODE=1 - the bottom of the map view window extends to the base of the screen and is overlapped by the IFACE Bar.
IFACE_BAR_MODE=0
@@ -128,22 +144,11 @@ IFACE_BAR_SIDES_ORI=0
;IFACE_BAR_WIDTH=640
```
Recommendations:
- **Desktops**: Use any size you see fit.
- **Tablets**: Set these values to logical resolution of your device, for example iPad Pro 11 is 1668x2388 (pixels), but it's logical resolution is 834x1194 (points).
- **Mobile phones**: Set height to 480, calculate width according to your device screen (aspect) ratio, for example Samsung S21 is 20:9 device, so the width should be 480 * 20 / 9 = 1067.
In time this stuff will receive in-game interface, right now you have to do it manually. For a sample f2_res.ini configuration file, containing all currently working settings use this link: [f2_res.ini](https://raw.githubusercontent.com/fallout2-ce/fallout2-ce/refs/heads/mainmenu/files/f2_res.ini)
*Note*: use of the IFACE_BAR settings requires the f2_res.dat file, which contains graphical assets. Various versions are available, but one compatible with the above f2_res.ini be found here: [f2_res.dat](https://github.com/fallout2-ce/fallout2-ce/raw/refs/heads/mainmenu/files/f2_res.dat)
The third configuration file is `ddraw.ini` (part of Sfall). There are dozens of options that adjust or override engine behaviour and gameplay mechanics. This file is intended for modders and advanced users.
For a sample ddraw.ini configuration file, containing all currently working settings use this link: [ddraw.ini](https://raw.githubusercontent.com/fallout2-ce/fallout2-ce/refs/heads/main/files/ddraw.ini)
*Note*: use of the IFACE_BAR settings requires the f2_res.dat file, which contains graphical assets. Various versions are available, but one compatible with the above settings be found here: [f2_res.dat](https://github.com/fallout2-ce/fallout2-ce/raw/refs/heads/mainmenu/files/f2_res.dat)
## Quality of life benefits over vanilla Fallout
* High resolution support
* Large game area support (through HiResMode=1 in ddraw.ini and game_height=480 and game_width=640 settings in fallout2.cfg)
* Increased pathfinding nodes 5x for more accurate pathfinding
* Ctrl-click to quickly move items when bartering, looting, or stealing
* _a_ to select "all" when selecting item quantity
+27
View File
@@ -10,6 +10,33 @@
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
[Misc]
; if IFACE_BAR_MODE=0 - the bottom of the map view window sits at the top of the IFACE Bar.
; if IFACE_BAR_MODE=1 - the bottom of the map view window extends to the base of the screen and is overlapped by the IFACE Bar.
IFACE_BAR_MODE=0
;if IFACE_BAR_SIDE_ART=0 - Black, No Iface-bar side art used.
;if IFACE_BAR_SIDE_ART=1 - Metal (grey) look Iface-bar side art used.
;if IFACE_BAR_SIDE_ART=2 - Leather look Iface-bar side art used.
;if IFACE_BAR_SIDE_ART=3-6 - Alternative Metal look Iface-bar side art used.
;if IFACE_BAR_SIDE_ART=7 - Alternative Leather look Iface-bar side art used.
;if IFACE_BAR_SIDE_ART=8 - Metal (brown) look Iface-bar side art used.
IFACE_BAR_SIDE_ART=5
;if IFACE_BAR_SIDES_ORI=0 - Iface-bar side graphics extend from the Iface-Bar to the Screen edges.
;if IFACE_BAR_SIDES_ORI=1 - Iface-bar side graphics extend from the Screen edges to the Iface-Bar.
IFACE_BAR_SIDES_ORI=1
;This will increase the width of the interface bar expanding the area used to display text.
;if IFACE_BAR_WIDTH=640 - Interface bar will remain at it's original width.
IFACE_BAR_WIDTH=800
;Adds Fallout 1 style travel/trail dots
WorldMapTravelMarkers=0
;Prevents pausing music between map areas with the same music
GaplessMusic=0
;Uncomment these lines to change the timers of how many days after the game starts Hakunin dream sequences will occur
;MovieTimer_artimer1=5000
;MovieTimer_artimer2=5000
-189
View File
@@ -1,189 +0,0 @@
#include "constants.h"
#include "headers/define_extra.h" // For sfall functions if not in constants
procedure start;
procedure description_proc; // For visual checks during game
variable new_tag1_id = -1;
variable new_tag2_id = -1;
variable max_tags_test_id = -1;
procedure start begin
// Test Predefined Tags
debug_msg("Testing Predefined Interface Tags...");
// SNEAK (0)
debug_msg("Activating SNEAK (0)...");
show_iface_tag(0);
if (is_iface_tag_active(0)) then
debug_msg("SNEAK is active. (Visual check needed)");
else
debug_msg("ERROR: SNEAK failed to activate or is_iface_tag_active(0) failed.");
hide_iface_tag(0);
if (not is_iface_tag_active(0)) then
debug_msg("SNEAK is inactive.");
else
debug_msg("ERROR: SNEAK failed to deactivate or is_iface_tag_active(0) failed after hide.");
// POISONED (1) - Test requires making the player poisoned by other means to truly verify show/hide effect on game state
// For now, just test is_iface_tag_active if it reflects direct calls or underlying state.
// The opcodes show_iface_tag/hide_iface_tag are not meant to directly poison/cure the player for tags 1 and 2.
// They are for custom tags or the specific PC flags (0,3,4). is_iface_tag_active *should* work for 1 and 2.
debug_msg("Checking POISONED (1) (depends on game state): " + is_iface_tag_active(1));
// Similar for RADIATED (2)
debug_msg("Checking RADIATED (2) (depends on game state): " + is_iface_tag_active(2));
// LEVEL (3)
debug_msg("Activating LEVEL (3)...");
show_iface_tag(3);
if (is_iface_tag_active(3)) then
debug_msg("LEVEL is active. (Visual check needed)");
else
debug_msg("ERROR: LEVEL failed to activate or is_iface_tag_active(3) failed.");
hide_iface_tag(3);
if (not is_iface_tag_active(3)) then
debug_msg("LEVEL is inactive.");
else
debug_msg("ERROR: LEVEL failed to deactivate or is_iface_tag_active(3) failed after hide.");
// ADDICT (4)
debug_msg("Activating ADDICT (4)...");
show_iface_tag(4);
if (is_iface_tag_active(4)) then
debug_msg("ADDICT is active. (Visual check needed)");
else
debug_msg("ERROR: ADDICT failed to activate or is_iface_tag_active(4) failed.");
hide_iface_tag(4);
if (not is_iface_tag_active(4)) then
debug_msg("ADDICT is inactive.");
else
debug_msg("ERROR: ADDICT failed to deactivate or is_iface_tag_active(4) failed after hide.");
debug_msg("Predefined tag tests complete.");
debug_msg("---");
// Test Custom Tags
debug_msg("Testing Custom Interface Tags...");
// Add first custom tag
new_tag1_id = add_iface_tag;
if (new_tag1_id != -1) then
debug_msg("Added custom tag 1 with ID: " + new_tag1_id + " (expected 5 if first)");
else
debug_msg("ERROR: Failed to add custom tag 1.");
return; // Stop if first add fails
// Show it
show_iface_tag(new_tag1_id);
if (is_iface_tag_active(new_tag1_id)) then
debug_msg("Custom tag 1 is active. (Visual check: should show 'NEW' in green)");
else
debug_msg("ERROR: Custom tag 1 failed to activate or is_iface_tag_active failed.");
// Set its text and color
set_iface_tag_text(new_tag1_id, "HELLO TAG1", 2); // Color 2 (White from issue description's reference)
debug_msg("Set text for custom tag 1 to 'HELLO TAG1' (color white). (Visual check needed)");
// Verify text length truncation (19 chars)
set_iface_tag_text(new_tag1_id, "ThisIsAVeryLongTextStringIndeed", 3); // Color 3 (Yellow)
debug_msg("Set text for custom tag 1 to 'ThisIsAVeryLongTextStringIndeed' (color yellow) - should be truncated. (Visual check needed)");
// Add second custom tag
new_tag2_id = add_iface_tag;
if (new_tag2_id != -1) then
debug_msg("Added custom tag 2 with ID: " + new_tag2_id + " (expected 6 if second)");
else
debug_msg("ERROR: Failed to add custom tag 2.");
// Continue to test tag1 hide
if (new_tag2_id != -1) then
show_iface_tag(new_tag2_id);
set_iface_tag_text(new_tag2_id, "AWESOME", 6); // Color 6 (GoodColor/Green)
debug_msg("Custom tag 2 ('AWESOME', green) should be active. (Visual check needed)");
end
// Hide first custom tag
hide_iface_tag(new_tag1_id);
if (not is_iface_tag_active(new_tag1_id)) then
debug_msg("Custom tag 1 is now inactive.");
else
debug_msg("ERROR: Custom tag 1 failed to deactivate.");
if (new_tag2_id != -1 and is_iface_tag_active(new_tag2_id)) then
debug_msg("Custom tag 2 should still be active. (Visual check needed)");
else if (new_tag2_id != -1) then
debug_msg("ERROR: Custom tag 2 became inactive or failed check.");
end
// Test max tags
debug_msg("Attempting to add maximum custom tags (up to 126)...");
variable i;
variable current_tags = 2; // Assuming new_tag1_id and new_tag2_id were successful (IDs 5 and 6)
if (new_tag1_id == -1) then current_tags = 0;
if (new_tag1_id != -1 and new_tag2_id == -1) then current_tags = 1;
for (i = current_tags; i < 126; i++) begin
max_tags_test_id = add_iface_tag;
if (max_tags_test_id == -1) then begin
debug_msg("ERROR: Failed to add tag at iteration " + i + ". Max tags might be less than 126 or error in add_iface_tag.");
break;
end
// Minimal show/set_text to ensure they are processed
show_iface_tag(max_tags_test_id);
set_iface_tag_text(max_tags_test_id, "Tag " + max_tags_test_id, 0); // Default color
end
if (i == 126) then
debug_msg("Successfully added up to 126 custom tags (IDs 5 through 130). Last ID: " + max_tags_test_id);
else
debug_msg("Stopped adding tags at count " + i + ". Last successful ID: " + max_tags_test_id);
end
// Test adding one more tag (should fail if 126 was the limit)
max_tags_test_id = add_iface_tag;
if (max_tags_test_id == -1) then
debug_msg("Correctly failed to add tag beyond limit (127th attempt).");
else
debug_msg("ERROR: Added tag beyond 126 limit! ID: " + max_tags_test_id);
end
// Test invalid IDs
debug_msg("Testing invalid tag IDs...");
show_iface_tag(-1); // Invalid
show_iface_tag(1000); // Likely invalid (beyond max added)
hide_iface_tag(-2);
hide_iface_tag(1001);
debug_msg("is_iface_tag_active(-3): " + is_iface_tag_active(-3));
debug_msg("is_iface_tag_active(1002): " + is_iface_tag_active(1002));
set_iface_tag_text(-4, "INVALID", 0);
set_iface_tag_text(1003, "INVALID", 0);
debug_msg("Invalid ID tests complete (check console for debug prints from C++).");
debug_msg("---");
debug_msg("Interface Tag testing complete. Check console and game screen.");
debug_msg("Will keep some tags active for 10 seconds for visual check then clear...");
// Keep some tags visible for a moment if run in game
// This part is for easier visual checking if you load a game with this script.
// For automated testing, the debug_msg output is key.
if (game_loaded) then begin
if (new_tag1_id != -1) then hide_iface_tag(new_tag1_id); // ensure it's hidden from previous test
if (new_tag2_id != -1) then show_iface_tag(new_tag2_id); // ensure tag2 is visible
set_iface_tag_text(new_tag2_id, "Testing Done!", 4); // Peanut butter color
game_time_advance(game_ticks(10)); // Wait 10 seconds
if (new_tag2_id != -1) then hide_iface_tag(new_tag2_id);
debug_msg("Visual check period ended.");
end
end
// This can be used with `debug_map_scripts` or similar to run on map enter
// procedure map_enter_p_proc begin call start; end
// procedure map_update_p_proc begin call start; end // If you want it to run repeatedly (not recommended for this test script)
// For `description_proc` usage with `debug(F5)`:
// Create a global script that calls `start` from `description_proc`
// Example:
// procedure description_proc begin
// if (game_loaded) then call start;
// end
+69
View File
@@ -0,0 +1,69 @@
#include "lib.arrays.h" // For arrays_equal, len_array, etc.
#include "test_utils.h" // For assertEquals, VALTYPE_STR, report_test_results
// To test: copy test.ini into the game folder before running
procedure ini_test_suite begin
variable result_array, expected_array, key_type, value_type, count, key_val_pair;
display_msg("--- Testing ini functions");
// Test Case 1: Valid file, valid section
result_array := get_ini_section("test.ini", "ValidSection");
expected_array := {"Key1": "Value1", "Key2": "2"};
call assertEquals("TC1 Size", len_array(result_array), 2);
call assertEquals("TC1 Content", arrays_equal(result_array, expected_array), true);
count := 0;
foreach key_val_pair in result_array begin
count += 1;
call assertEquals("TC1 Key Type " + count, typeof(key_val_pair[0]), VALTYPE_STR);
call assertEquals("TC1 Value Type " + count, typeof(key_val_pair[1]), VALTYPE_STR);
end
// basic fetchers
call assertEquals("TC2 Specific Key1 Value", result_array["Key1"], "Value1");
call assertEquals("TC2 get_ini_setting string", get_ini_setting("test.ini|ValidSection|Key1"), 0);
call assertEquals("TC2 get_ini_string string", get_ini_string("test.ini|ValidSection|Key1"), "Value1");
call assertEquals("TC2 get_ini_setting int", get_ini_setting("test.ini|ValidSection|Key2"), 2);
call assertEquals("TC2 get_ini_string int", get_ini_string("test.ini|ValidSection|Key2"), "2");
// INI file not found
result_array := get_ini_section("nonexistent.ini", "AnySection");
call assertEquals("TC3 Size", len_array(result_array), 0);
call assertEquals("TC3 Is Map", array_key(result_array, -1), 1); // Should still be an associative array
call assertEquals("TC3 get_ini_setting", get_ini_setting("notexist.ini|ValidSection|Key2"), 0);
call assertEquals("TC3 get_ini_string", get_ini_string("notexist.ini|ValidSection|Key2"), "");
// Valid file, section not found
result_array := get_ini_section("test.ini", "NonExistentSection");
call assertEquals("TC4 Size", len_array(result_array), 0);
call assertEquals("TC4 Is Map", array_key(result_array, -1), 1);
call assertEquals("TC4 get_ini_setting", get_ini_setting("test.ini|NonExistentSection|Key2"), 0);
call assertEquals("TC4 get_ini_string", get_ini_string("test.ini|NonExistentSection|Key2"), "");
// Valid file, empty section
result_array := get_ini_section("test.ini", "EmptySection");
call assertEquals("TC5 Size", len_array(result_array), 0);
call assertEquals("TC5 Is Map", array_key(result_array, -1), 1);
call assertEquals("TC5 get_ini_setting", get_ini_setting("test.ini|EmptySection|Key2"), 0);
call assertEquals("TC5 get_ini_string", get_ini_string("test.ini|EmptySection|Key2"), "");
// set ini setting
set_ini_setting("test_set.ini|ValidSection|Key3", "OldValue");
call assertEquals("TC6 set_ini_setting 1", get_ini_string("test_set.ini|ValidSection|Key3"), "OldValue");
set_ini_setting("test_set.ini|ValidSection|Key3", "NewValue");
call assertEquals("TC6 set_ini_setting 2", get_ini_string("test_set.ini|ValidSection|Key3"), "NewValue");
set_ini_setting("test_set.ini|ValidSection|Key3", 2);
call assertEquals("TC6 set_ini_setting int", get_ini_setting("test_set.ini|ValidSection|Key3"), 2);
// get_init_sections
result_array := get_ini_sections("test.ini");
call assertEquals("TC7 get_ini_sections size", len_array(result_array), 3);
call assertTrue("TC7 get_ini_sections", scan_array(result_array, "TestMisc") >= 0);
call report_test_results("ini");
end
procedure start begin
call ini_test_suite();
end
+7
View File
@@ -0,0 +1,7 @@
#include "sfall.h"
procedure start begin
// this isn't a unit test, just a way to easily test different values manually
display_msg("Setting world map mult");
set_map_time_multi(1.0);
end
+16
View File
@@ -0,0 +1,16 @@
[ValidSection]
Key1=Value1
Key2=2
[SectionWithSpaces]
LeadingSpaceKey = LeadingSpaceValue
TrailingSpaceKey = TrailingSpaceValue
Both Sides Space Key = Both Sides Space Value
SimpleKey=SimpleValue
[EmptySection]
; This is TestMisc, it's not empty but won't be directly tested for content here.
[TestMisc]
Alpha=Beta
Gamma=Delta
+11
View File
@@ -7,6 +7,17 @@ variable test_suite_errors := 0;
variable test_suite_verbose := false;
variable test_suite_assertions := 0;
procedure assertTrue(variable desc, variable a) begin
test_suite_assertions++;
if (not a) then begin
display_msg("Assertion failed \""+desc+"\": is not true");
test_suite_errors ++;
end else if (test_suite_verbose) then begin
display_msg("Assert \""+desc+"\" ok");
end
end
procedure assertEquals(variable desc, variable a, variable b) begin
test_suite_assertions++;
+18 -3
View File
@@ -6,6 +6,7 @@
#include "color.h"
#include "db.h"
#include "memory_manager.h"
#include "settings.h"
// The maximum number of interface fonts.
#define INTERFACE_FONT_MAX (16)
@@ -119,11 +120,25 @@ static int interfaceFontLoad(int font_index)
InterfaceFontDescriptor* fontDescriptor = &(gInterfaceFontDescriptors[font_index]);
char path[56];
snprintf(path, sizeof(path), "font%d.aaf", font_index);
File* stream = nullptr;
File* stream = fileOpen(path, "rb");
// Try set language path first
snprintf(path, sizeof(path), "text/%s/font%d.aaf", settings.system.language.c_str(), font_index);
stream = fileOpen(path, "rb");
// Fallback to English if needed
if (stream == nullptr && compat_stricmp(settings.system.language.c_str(), ENGLISH) != 0) {
snprintf(path, sizeof(path), "text/%s/font%d.aaf", ENGLISH, font_index);
stream = fileOpen(path, "rb");
}
// Fallback to original path
if (stream == nullptr) {
return -1;
snprintf(path, sizeof(path), "font%d.aaf", font_index);
stream = fileOpen(path, "rb");
if (stream == nullptr) {
return -1;
}
}
int fileSize = fileGetSize(stream);
+9 -18
View File
@@ -168,6 +168,14 @@ int gameInitWithOptions(const char* windowTitle, bool isMapper, int font, int fl
int skipOpeningMovies = 0;
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_SKIP_OPENING_MOVIES_KEY, &skipOpeningMovies);
// load preferences before Splash screen to get proper brightness
if (_init_options_menu() != 0) {
debugPrint("Failed on init_options_menu\n");
return -1;
}
debugPrint(">init_options_menu\n");
if (!gIsMapper && skipOpeningMovies < 2) {
showSplash();
}
@@ -341,13 +349,6 @@ int gameInitWithOptions(const char* windowTitle, bool isMapper, int font, int fl
debugPrint(">scr_disable\t");
if (_init_options_menu() != 0) {
debugPrint("Failed on init_options_menu\n");
return -1;
}
debugPrint(">init_options_menu\n");
if (endgameDeathEndingInit() != 0) {
debugPrint("Failed on endgameDeathEndingInit");
return -1;
@@ -1469,17 +1470,7 @@ static void showSplash()
}
}
int size = 0;
// TODO: Move to settings.
Config config;
if (configInit(&config)) {
if (configRead(&config, "f2_res.ini", false)) {
configGetInt(&config, "STATIC_SCREENS", "SPLASH_SCRN_SIZE", &size);
}
configFree(&config);
}
int size = settings.graphics.splash_size;
int screenWidth = screenGetWidth();
int screenHeight = screenGetHeight();
+16
View File
@@ -7,6 +7,7 @@
#include "db.h"
#include "main.h"
#include "platform_compat.h"
#include "scan_unimplemented.h"
#if defined(__EMSCRIPTEN__)
#include <emscripten.h>
@@ -66,6 +67,8 @@ bool gameConfigInit(bool isMapper, int argc, char** argv)
configSetString(&gGameConfig, GAME_CONFIG_SYSTEM_KEY, GAME_CONFIG_MASTER_PATCHES_KEY, "data");
configSetString(&gGameConfig, GAME_CONFIG_SYSTEM_KEY, GAME_CONFIG_CRITTER_DAT_KEY, "critter.dat");
configSetString(&gGameConfig, GAME_CONFIG_SYSTEM_KEY, GAME_CONFIG_CRITTER_PATCHES_KEY, "data");
configSetString(&gGameConfig, GAME_CONFIG_SYSTEM_KEY, GAME_CONFIG_FALLOUTCE_DAT_KEY, "falloutce.dat");
configSetString(&gGameConfig, GAME_CONFIG_SYSTEM_KEY, GAME_CONFIG_FALLOUTCE_PATCHES_KEY, "data");
configSetString(&gGameConfig, GAME_CONFIG_SYSTEM_KEY, GAME_CONFIG_LANGUAGE_KEY, ENGLISH);
configSetInt(&gGameConfig, GAME_CONFIG_SYSTEM_KEY, GAME_CONFIG_SCROLL_LOCK_KEY, 0);
configSetInt(&gGameConfig, GAME_CONFIG_SYSTEM_KEY, GAME_CONFIG_INTERRUPT_WALK_KEY, 1);
@@ -74,6 +77,7 @@ bool gameConfigInit(bool isMapper, int argc, char** argv)
configSetInt(&gGameConfig, GAME_CONFIG_SYSTEM_KEY, GAME_CONFIG_HASHING_KEY, 1);
configSetInt(&gGameConfig, GAME_CONFIG_SYSTEM_KEY, GAME_CONFIG_SPLASH_KEY, 0);
configSetInt(&gGameConfig, GAME_CONFIG_SYSTEM_KEY, GAME_CONFIG_FREE_SPACE_KEY, 20480);
configSetInt(&gGameConfig, GAME_CONFIG_PREFERENCES_KEY, GAME_CONFIG_GAME_DIFFICULTY_KEY, 1);
configSetInt(&gGameConfig, GAME_CONFIG_PREFERENCES_KEY, GAME_CONFIG_COMBAT_DIFFICULTY_KEY, 1);
configSetInt(&gGameConfig, GAME_CONFIG_PREFERENCES_KEY, GAME_CONFIG_VIOLENCE_LEVEL_KEY, 3);
@@ -112,6 +116,16 @@ bool gameConfigInit(bool isMapper, int argc, char** argv)
configSetInt(&gGameConfig, GAME_CONFIG_DEBUG_KEY, GAME_CONFIG_SHOW_LOAD_INFO_KEY, 0);
configSetInt(&gGameConfig, GAME_CONFIG_DEBUG_KEY, GAME_CONFIG_OUTPUT_MAP_DATA_INFO_KEY, 0);
configSetInt(&gGameConfig, GAME_CONFIG_GRAPHICS_KEY, GAME_CONFIG_GAME_WIDTH, 640);
configSetInt(&gGameConfig, GAME_CONFIG_GRAPHICS_KEY, GAME_CONFIG_GAME_HEIGHT, 480);
configSetInt(&gGameConfig, GAME_CONFIG_GRAPHICS_KEY, GAME_CONFIG_SCALE_2X, 0);
configSetInt(&gGameConfig, GAME_CONFIG_GRAPHICS_KEY, GAME_CONFIG_SPLASH_SIZE, 0);
configSetBool(&gGameConfig, GAME_CONFIG_GRAPHICS_KEY, GAME_CONFIG_FULLSCREEN, true);
configSetBool(&gGameConfig, GAME_CONFIG_GRAPHICS_KEY, GAME_CONFIG_STRETCH_ENABLED, true);
configSetBool(&gGameConfig, GAME_CONFIG_GRAPHICS_KEY, GAME_CONFIG_PRESERVE_ASPECT, true);
configSetBool(&gGameConfig, GAME_CONFIG_GRAPHICS_KEY, GAME_CONFIG_HIGH_QUALITY, false);
configSetBool(&gGameConfig, GAME_CONFIG_GRAPHICS_KEY, GAME_CONFIG_ENABLE_HIRES_STENCIL, true);
if (isMapper) {
configSetString(&gGameConfig, GAME_CONFIG_SYSTEM_KEY, GAME_CONFIG_EXECUTABLE_KEY, "mapper");
configSetInt(&gGameConfig, GAME_CONFIG_MAPPER_KEY, GAME_CONFIG_OVERRIDE_LIBRARIAN_KEY, 0);
@@ -179,9 +193,11 @@ bool gameConfigInit(bool isMapper, int argc, char** argv)
}
}
auto configChecker = ConfigChecker(gGameConfig, gGameConfigFilePath);
// Read contents of `fallout2.cfg` into config. The values from the file
// will override the defaults above.
configRead(&gGameConfig, gGameConfigFilePath, false);
configChecker.check(gGameConfig);
// Add key-values from command line, which overrides both defaults and
// whatever was loaded from `fallout2.cfg`.
+12
View File
@@ -13,12 +13,15 @@ namespace fallout {
#define GAME_CONFIG_SOUND_KEY "sound"
#define GAME_CONFIG_MAPPER_KEY "mapper"
#define GAME_CONFIG_DEBUG_KEY "debug"
#define GAME_CONFIG_GRAPHICS_KEY "graphics"
#define GAME_CONFIG_EXECUTABLE_KEY "executable"
#define GAME_CONFIG_MASTER_DAT_KEY "master_dat"
#define GAME_CONFIG_MASTER_PATCHES_KEY "master_patches"
#define GAME_CONFIG_CRITTER_DAT_KEY "critter_dat"
#define GAME_CONFIG_CRITTER_PATCHES_KEY "critter_patches"
#define GAME_CONFIG_FALLOUTCE_DAT_KEY "falloutce_dat"
#define GAME_CONFIG_FALLOUTCE_PATCHES_KEY "falloutce_patches"
#define GAME_CONFIG_LANGUAGE_KEY "language"
#define GAME_CONFIG_SCROLL_LOCK_KEY "scroll_lock"
#define GAME_CONFIG_INTERRUPT_WALK_KEY "interrupt_walk"
@@ -28,6 +31,15 @@ namespace fallout {
#define GAME_CONFIG_HASHING_KEY "hashing"
#define GAME_CONFIG_SPLASH_KEY "splash"
#define GAME_CONFIG_FREE_SPACE_KEY "free_space"
#define GAME_CONFIG_GAME_WIDTH "game_width"
#define GAME_CONFIG_GAME_HEIGHT "game_height"
#define GAME_CONFIG_FULLSCREEN "fullscreen"
#define GAME_CONFIG_SCALE_2X "scale2x"
#define GAME_CONFIG_SPLASH_SIZE "splash_size"
#define GAME_CONFIG_STRETCH_ENABLED "stretch_enabled"
#define GAME_CONFIG_PRESERVE_ASPECT "preserve_aspect"
#define GAME_CONFIG_HIGH_QUALITY "high_quality"
#define GAME_CONFIG_ENABLE_HIRES_STENCIL "highres_stencil"
#define GAME_CONFIG_TIMES_RUN_KEY "times_run"
#define GAME_CONFIG_GAME_DIFFICULTY_KEY "game_difficulty"
#define GAME_CONFIG_RUNNING_BURNING_GUY_KEY "running_burning_guy"
+8 -175
View File
@@ -258,9 +258,6 @@ static unsigned char* gInterfaceWindowBuffer;
// 0x59D40C
static unsigned char gInterfaceActionPointsBarBackground[90 * 5];
CustomIndicatorBox gCustomIndicatorBoxes[MAX_CUSTOM_INDICATOR_BOXES];
static int gActiveCustomTagsCount = 0;
// Should the game window stretch all the way to the bottom or sit at the top of the interface bar (default)
bool gInterfaceBarMode = false;
@@ -584,13 +581,6 @@ int interfaceInit()
// SFALL
sidePanelsInit();
for (int i = 0; i < MAX_CUSTOM_INDICATOR_BOXES; ++i) {
gCustomIndicatorBoxes[i].isActive = false;
gCustomIndicatorBoxes[i].text[0] = '\0';
gCustomIndicatorBoxes[i].color = 0;
}
gActiveCustomTagsCount = 0;
gInterfaceBarEnabled = true;
gInterfaceBarInitialized = false;
gInterfaceBarHidden = true;
@@ -707,10 +697,6 @@ void interfaceFree()
customInterfaceBarExit();
interfaceBarFree();
// TODO: Consider if a dedicated function to free custom tag resources is needed.
// For now, gCustomIndicatorBoxes is a global static array, so no dynamic memory to free.
// Resetting active tags count.
gActiveCustomTagsCount = 0;
}
// 0x45E860
@@ -2376,64 +2362,6 @@ int indicatorBarRefresh()
windowRefresh(gIndicatorBarWindow);
}
// START Custom Tag Handling in indicatorBarRefresh
int customTagStartSlot = count; // Where to start adding custom tags in gIndicatorSlots
for (int i = 0; i < gActiveCustomTagsCount && customTagStartSlot < INDICATOR_SLOTS_COUNT; ++i) {
if (gCustomIndicatorBoxes[i].isActive) {
// Using a convention: custom tag IDs are INDICATOR_COUNT + i
gIndicatorSlots[customTagStartSlot++] = INDICATOR_COUNT + i;
}
}
count = customTagStartSlot; // Update total count of displayed indicators
if (count > 1 && (gIndicatorSlots[0] < INDICATOR_COUNT || (count > 0 && gIndicatorSlots[0] >= INDICATOR_COUNT && gIndicatorSlots[1] < INDICATOR_COUNT))) { // Only sort if there are standard indicators or a mix
// qsort might behave unexpectedly if all elements are custom tags due to how IDs are structured.
// Custom tags are already ordered by their addition.
// We only need to sort the standard part, or if custom tags are mixed in a way that needs sorting relative to standard ones.
// For simplicity, if there are any standard tags, sort the whole array up to the original count.
// Custom tags will be appended after this sorted list of standard tags.
// This logic might need refinement if standard and custom tags need to interleave based on some criteria.
// For now, custom tags are appended after standard ones.
int standardIndicatorsCount = 0;
for(int i=0; i < count; ++i) {
if(gIndicatorSlots[i] < INDICATOR_COUNT) standardIndicatorsCount++;
}
if(standardIndicatorsCount > 1) {
qsort(gIndicatorSlots, standardIndicatorsCount, sizeof(*gIndicatorSlots), indicatorBoxCompareByPosition);
}
// After sorting standard indicators, append custom ones.
// This re-iterates the custom tag addition logic, but ensures they come after sorted standard tags.
customTagStartSlot = standardIndicatorsCount;
for (int i = 0; i < gActiveCustomTagsCount && customTagStartSlot < INDICATOR_SLOTS_COUNT; ++i) {
if (gCustomIndicatorBoxes[i].isActive) {
gIndicatorSlots[customTagStartSlot++] = INDICATOR_COUNT + i;
}
}
count = customTagStartSlot;
}
if (gIndicatorBarWindow != -1 && count == 0) { // If no indicators (standard or custom), destroy window.
windowDestroy(gIndicatorBarWindow);
gIndicatorBarWindow = -1;
} else if (count > 0) {
if (gIndicatorBarWindow == -1) { // Create window if it doesn't exist and there are indicators
Rect interfaceBarWindowRect;
windowGetRect(gInterfaceBarWindow, &interfaceBarWindowRect);
gIndicatorBarWindow = windowCreate(interfaceBarWindowRect.left,
screenGetHeight() - INTERFACE_BAR_HEIGHT - INDICATOR_BOX_HEIGHT,
(INDICATOR_BOX_WIDTH - INDICATOR_BOX_CONNECTOR_WIDTH) * count, // Adjust width based on actual count
INDICATOR_BOX_HEIGHT,
_colorTable[0],
0);
} else { // If window exists, adjust its width if necessary
windowResize(gIndicatorBarWindow, (INDICATOR_BOX_WIDTH - INDICATOR_BOX_CONNECTOR_WIDTH) * count, INDICATOR_BOX_HEIGHT);
}
indicatorBarRender(count); // Render all (standard + custom)
windowRefresh(gIndicatorBarWindow);
}
// END Custom Tag Handling in indicatorBarRefresh
return count;
}
@@ -2493,62 +2421,17 @@ static void indicatorBarRender(int count)
int connectorWidthCompensation = INDICATOR_BOX_CONNECTOR_WIDTH;
for (int index = 0; index < count; index++) {
int indicatorId = gIndicatorSlots[index];
int indicator = gIndicatorSlots[index];
IndicatorDescription* indicatorDescription = &(gIndicatorDescriptions[indicator]);
if (indicatorId >= INDICATOR_COUNT) { // This is a custom tag
int customTagIndex = indicatorId - INDICATOR_COUNT;
if (customTagIndex < gActiveCustomTagsCount && gCustomIndicatorBoxes[customTagIndex].isActive) {
CustomIndicatorBox* customBox = &gCustomIndicatorBoxes[customTagIndex];
// Prepare a temporary IndicatorDescription-like structure or directly use customBox properties
// For simplicity, let's assume a generic background for custom tags for now
// and render text directly. A more advanced approach might involve
// creating a temporary prerendered box similar to standard indicators.
// Fallback generic box (e.g. using SNEAK's background, but ideally a new generic one)
// This is a placeholder. Proper handling would involve a generic custom box graphic.
unsigned char* boxArt = gIndicatorDescriptions[INDICATOR_SNEAK].data; // Placeholder
// Create a temporary buffer for this custom tag's rendering
unsigned char tempBoxData[INDICATOR_BOX_WIDTH * INDICATOR_BOX_HEIGHT];
memcpy(tempBoxData, boxArt, INDICATOR_BOX_WIDTH * INDICATOR_BOX_HEIGHT);
// Render custom text onto this temporary buffer
// Need to set font and color appropriately
int oldFont = fontGetCurrent();
fontSetCurrent(101); // Assuming same font as standard indicators
// Calculate text position (centering)
int textY = (INDICATOR_BOX_HEIGHT - fontGetLineHeight()) / 2; // Adjusted for actual box height
int textX = (INDICATOR_BOX_WIDTH - fontGetStringWidth(customBox->text)) / 2;
// Ensure textX is not negative if text is too long (it should be truncated already, but as a safeguard)
if (textX < 0) textX = 0;
fontDrawText(tempBoxData + INDICATOR_BOX_WIDTH * textY + textX,
customBox->text,
INDICATOR_BOX_WIDTH, // Max width for text area
INDICATOR_BOX_WIDTH, // Stride
customBox->color); // Use color from custom tag
fontSetCurrent(oldFont); // Restore original font
blitBufferToBufferTrans(tempBoxData + connectorWidthCompensation,
INDICATOR_BOX_WIDTH - connectorWidthCompensation,
INDICATOR_BOX_HEIGHT,
INDICATOR_BOX_WIDTH, // Source buffer stride
windowBuffer + x, windowWidth);
}
} else { // This is a standard indicator
IndicatorDescription* indicatorDescription = &(gIndicatorDescriptions[indicatorId]);
blitBufferToBufferTrans(indicatorDescription->data + connectorWidthCompensation,
INDICATOR_BOX_WIDTH - connectorWidthCompensation,
INDICATOR_BOX_HEIGHT,
INDICATOR_BOX_WIDTH,
windowBuffer + x, windowWidth);
}
blitBufferToBufferTrans(indicatorDescription->data + connectorWidthCompensation,
INDICATOR_BOX_WIDTH - connectorWidthCompensation,
INDICATOR_BOX_HEIGHT,
INDICATOR_BOX_WIDTH,
windowBuffer + x, windowWidth);
connectorWidthCompensation = 0;
unconnectedIndicatorsWidth += INDICATOR_BOX_WIDTH;
x = unconnectedIndicatorsWidth - INDICATOR_BOX_CONNECTOR_WIDTH * connections;
connections++;
@@ -2770,54 +2653,4 @@ bool interface_get_current_attack_mode(int* hit_mode)
return true;
}
int interfaceAddCustomTag() {
if (gActiveCustomTagsCount >= MAX_CUSTOM_INDICATOR_BOXES) {
return -1; // No slot available
}
// Find the first non-active slot conceptually, but since we use gActiveCustomTagsCount,
// we just append to the current list of active ones.
// The actual "slot" in gCustomIndicatorBoxes is gActiveCustomTagsCount.
int tagId = gActiveCustomTagsCount;
gCustomIndicatorBoxes[tagId].isActive = true; // Mark as active conceptually
// Default text/color can be set here if desired, e.g.:
strncpy(gCustomIndicatorBoxes[tagId].text, "NEW", 19);
gCustomIndicatorBoxes[tagId].text[19] = '\0';
gCustomIndicatorBoxes[tagId].color = _colorTable[992]; // Default to green, like SNEAK
gActiveCustomTagsCount++;
// Note: indicatorBarRefresh() is not called here;
// it's typically called after a batch of changes or by show/hide.
return tagId;
}
void interfaceShowCustomTag(int tagId) {
if (tagId < 0 || tagId >= gActiveCustomTagsCount) return;
gCustomIndicatorBoxes[tagId].isActive = true;
indicatorBarRefresh();
}
void interfaceHideCustomTag(int tagId) {
if (tagId < 0 || tagId >= gActiveCustomTagsCount) return;
gCustomIndicatorBoxes[tagId].isActive = false;
indicatorBarRefresh();
}
bool interfaceIsCustomTagActive(int tagId) {
if (tagId < 0 || tagId >= gActiveCustomTagsCount) return false;
return gCustomIndicatorBoxes[tagId].isActive;
}
void interfaceSetCustomTagText(int tagId, const char* text, int color) {
if (tagId < 0 || tagId >= gActiveCustomTagsCount) return;
strncpy(gCustomIndicatorBoxes[tagId].text, text, 19);
gCustomIndicatorBoxes[tagId].text[19] = '\0'; // Ensure null termination
gCustomIndicatorBoxes[tagId].color = color;
if (gCustomIndicatorBoxes[tagId].isActive) {
indicatorBarRefresh();
}
}
} // namespace fallout
-22
View File
@@ -12,22 +12,6 @@ namespace fallout {
#define INTERFACE_BAR_WIDTH 640
#define INTERFACE_BAR_HEIGHT 100
// Minimum radiation amount to display RADIATED indicator.
#define RADATION_INDICATOR_THRESHOLD 65
// Minimum poison amount to display POISONED indicator.
#define POISON_INDICATOR_THRESHOLD 0
#define MAX_CUSTOM_INDICATOR_BOXES 126
typedef struct CustomIndicatorBox {
char text[20]; // 19 chars + null terminator
int color; // Could be an enum or int mapped to color values
bool isActive;
// Potentially add a specific ID if needed, though array index might suffice
} CustomIndicatorBox;
extern CustomIndicatorBox gCustomIndicatorBoxes[MAX_CUSTOM_INDICATOR_BOXES];
typedef enum InterfaceItemAction {
INTERFACE_ITEM_ACTION_DEFAULT = -1,
INTERFACE_ITEM_ACTION_USE,
@@ -79,12 +63,6 @@ bool indicatorBarShow();
bool indicatorBarHide();
bool interface_get_current_attack_mode(int* hit_mode);
int interfaceAddCustomTag();
void interfaceShowCustomTag(int tagId);
void interfaceHideCustomTag(int tagId);
bool interfaceIsCustomTagActive(int tagId);
void interfaceSetCustomTagText(int tagId, const char* text, int color);
unsigned char* customInterfaceBarGetBackgroundImageData();
} // namespace fallout
+22 -5
View File
@@ -30,8 +30,8 @@ static char* _defaultFilename_(char* s);
static int _outputStr(char* a1);
static int _checkWait(Program* program);
static char* programGetCurrentProcedureName(Program* s);
static opcode_t stackReadInt16(unsigned char* data, int pos);
static int stackReadInt32(unsigned char* data, int pos);
opcode_t stackReadInt16(unsigned char* data, int pos);
int stackReadInt32(unsigned char* data, int pos);
static void stackWriteInt16(int value, unsigned char* data, int pos);
static void stackWriteInt32(int value, unsigned char* data, int pos);
static void stackPushInt16(unsigned char* data, int* pointer, int value);
@@ -155,7 +155,7 @@ static int (*_outputFunc)(char*) = _outputStr;
static int _cpuBurstSize = 10;
// 0x59E230
static OpcodeHandler* gInterpreterOpcodeHandlers[OPCODE_MAX_COUNT];
OpcodeHandler* gInterpreterOpcodeHandlers[OPCODE_MAX_COUNT];
// 0x59E78C
static Program* gInterpreterCurrentProgram;
@@ -276,7 +276,7 @@ static char* programGetCurrentProcedureName(Program* program)
}
// 0x467290
static opcode_t stackReadInt16(unsigned char* data, int pos)
opcode_t stackReadInt16(unsigned char* data, int pos)
{
// TODO: The return result is probably short.
opcode_t value = 0;
@@ -286,7 +286,7 @@ static opcode_t stackReadInt16(unsigned char* data, int pos)
}
// 0x4672A4
static int stackReadInt32(unsigned char* data, int pos)
int stackReadInt32(unsigned char* data, int pos)
{
int value = 0;
value |= data[pos++] << 24;
@@ -3346,4 +3346,21 @@ int ProgramValue::asInt() const
}
}
// CE
ProgramValue programMakeString(Program* program, const char* str)
{
ProgramValue valuePv;
valuePv.opcode = VALUE_TYPE_DYNAMIC_STRING;
valuePv.integerValue = programPushString(program, str);
return valuePv;
}
ProgramValue programMakeInt(Program* program, int val)
{
ProgramValue valuePv;
valuePv.opcode = VALUE_TYPE_INT;
valuePv.integerValue = val;
return valuePv;
}
} // namespace fallout
+8
View File
@@ -241,6 +241,14 @@ ProgramValue programReturnStackPopValue(Program* program);
int programReturnStackPopInteger(Program* program);
void* programReturnStackPopPointer(Program* program);
opcode_t stackReadInt16(unsigned char* data, int pos);
int stackReadInt32(unsigned char* data, int pos);
extern OpcodeHandler* gInterpreterOpcodeHandlers[OPCODE_MAX_COUNT];
ProgramValue programMakeString(Program* program, const char* str);
ProgramValue programMakeInt(Program* program, int val);
} // namespace fallout
#endif /* INTERPRETER_H */
+79 -57
View File
@@ -2078,34 +2078,51 @@ static void _display_body(int fid, int inventoryWindowType)
unsigned char* windowBuffer = windowGetBuffer(gInventoryWindow);
int windowPitch = windowGetWidth(gInventoryWindow);
FrmImage backgroundFrmImage;
int Fid = 114;
int sourceXOffset = 0;
if (index == 1) {
if (inventoryWindowType == INVENTORY_WINDOW_TYPE_LOOT) {
rect.left = 426;
rect.left = 426; // loot right cha window (or container)
rect.top = 39;
Fid = 114;
sourceXOffset = 538;
} else {
rect.left = 297;
rect.left = 297; // inventory data window? ?not used?
rect.top = 37;
Fid = 48;
sourceXOffset = 229;
}
} else {
if (inventoryWindowType == INVENTORY_WINDOW_TYPE_LOOT) {
rect.left = 48;
rect.left = 48; // loot left cha window
rect.top = 39;
} else {
rect.left = 176;
Fid = 114;
sourceXOffset = 0;
} else if (inventoryWindowType == INVENTORY_WINDOW_TYPE_USE_ITEM_ON) {
rect.left = 176; // Use item cha window
rect.top = 37;
Fid = 113;
sourceXOffset = 292;
} else {
rect.left = 176; // inventory cha window (same as use on)
rect.top = 37;
Fid = 48;
sourceXOffset = 0;
}
}
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, Fid, 0, 0, 0);
rect.right = rect.left + INVENTORY_BODY_VIEW_WIDTH - 1;
rect.bottom = rect.top + INVENTORY_BODY_VIEW_HEIGHT - 1;
FrmImage backgroundFrmImage;
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 114, 0, 0, 0);
if (backgroundFrmImage.lock(backgroundFid)) {
blitBufferToBuffer(backgroundFrmImage.getData() + INVENTORY_LOOT_WINDOW_WIDTH * rect.top + rect.left,
blitBufferToBuffer(backgroundFrmImage.getData() + backgroundFrmImage.getWidth() * rect.top + rect.left + sourceXOffset,
INVENTORY_BODY_VIEW_WIDTH,
INVENTORY_BODY_VIEW_HEIGHT,
INVENTORY_LOOT_WINDOW_WIDTH,
backgroundFrmImage.getWidth(),
windowBuffer + windowPitch * rect.top + rect.left,
windowPitch);
}
@@ -2286,23 +2303,23 @@ static void _inven_pickup(int buttonCode, int indexOffset)
Rect rect;
switch (buttonCode) {
case 1006:
rect.left = 245;
rect.top = 286;
case 1006: // right hand slot
rect.left = INVENTORY_RIGHT_HAND_SLOT_X;
rect.top = INVENTORY_RIGHT_HAND_SLOT_Y;
if (_inven_dude == gDude && interfaceGetCurrentHand() != HAND_LEFT) {
itemInHand = item;
}
break;
case 1007:
rect.left = 154;
rect.top = 286;
case 1007: // left hand slot
rect.left = INVENTORY_LEFT_HAND_SLOT_X;
rect.top = INVENTORY_LEFT_HAND_SLOT_Y;
if (_inven_dude == gDude && interfaceGetCurrentHand() == HAND_LEFT) {
itemInHand = item;
}
break;
case 1008:
rect.left = 154;
rect.top = 183;
case 1008: // armor slot
rect.left = INVENTORY_ARMOR_SLOT_X;
rect.top = INVENTORY_ARMOR_SLOT_Y;
break;
default:
// NOTE: Original code a little bit different, this code path
@@ -2313,50 +2330,39 @@ static void _inven_pickup(int buttonCode, int indexOffset)
break;
}
// fix for disappearing/not disappearing inventory items
if (itemIndex == -1 || _pud->items[_pud->length - (itemIndex + indexOffset + 1)].quantity <= 1) { // slots
bool pickUpFromSlot = itemIndex == -1; // true if item was picked up from armor or weapon slots
if (pickUpFromSlot || _pud->items[_pud->length - (itemIndex + indexOffset + 1)].quantity <= 1) {
// erase background unless item is part of a 2+ quantity stack
unsigned char* windowBuffer = windowGetBuffer(gInventoryWindow);
int width, height;
if (gInventoryRightHandItem != gInventoryLeftHandItem || item != gInventoryLeftHandItem) {
int height;
int width;
if (itemIndex == -1) {
if (pickUpFromSlot) {
height = INVENTORY_LARGE_SLOT_HEIGHT;
width = INVENTORY_LARGE_SLOT_WIDTH;
} else {
height = INVENTORY_SLOT_HEIGHT;
width = INVENTORY_SLOT_WIDTH;
}
FrmImage backgroundFrmImage;
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 48, 0, 0, 0);
if (backgroundFrmImage.lock(backgroundFid)) {
blitBufferToBuffer(backgroundFrmImage.getData() + INVENTORY_WINDOW_WIDTH * rect.top + rect.left,
width,
height,
INVENTORY_WINDOW_WIDTH,
windowBuffer + INVENTORY_WINDOW_WIDTH * rect.top + rect.left,
INVENTORY_WINDOW_WIDTH);
}
rect.right = rect.left + width - 1;
rect.bottom = rect.top + height - 1;
} else {
FrmImage backgroundFrmImage;
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 48, 0, 0, 0);
if (backgroundFrmImage.lock(backgroundFid)) {
blitBufferToBuffer(backgroundFrmImage.getData() + INVENTORY_WINDOW_WIDTH * 286 + 154,
180,
61,
INVENTORY_WINDOW_WIDTH,
windowBuffer + INVENTORY_WINDOW_WIDTH * 286 + 154,
INVENTORY_WINDOW_WIDTH);
}
rect.left = 154;
rect.top = 286;
rect.right = rect.left + 180 - 1;
rect.bottom = rect.top + 61 - 1;
// seems to wipe both hand slots at once, but I don't know how to trigger this in game
height = INVENTORY_LARGE_SLOT_HEIGHT;
width = 180;
rect.left = INVENTORY_LEFT_HAND_SLOT_X;
rect.top = INVENTORY_LEFT_HAND_SLOT_Y;
}
rect.right = rect.left + width - 1;
rect.bottom = rect.top + height - 1;
FrmImage backgroundFrmImage;
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 48, 0, 0, 0);
if (backgroundFrmImage.lock(backgroundFid)) {
blitBufferToBuffer(backgroundFrmImage.getData() + INVENTORY_WINDOW_WIDTH * rect.top + rect.left,
width,
height,
INVENTORY_WINDOW_WIDTH,
windowBuffer + INVENTORY_WINDOW_WIDTH * rect.top + rect.left,
INVENTORY_WINDOW_WIDTH);
}
windowRefreshRect(gInventoryWindow, &rect);
} else {
_display_inventory(indexOffset, itemIndex, INVENTORY_WINDOW_TYPE_NORMAL);
@@ -2366,11 +2372,12 @@ static void _inven_pickup(int buttonCode, int indexOffset)
_inven_update_lighting(nullptr);
}
// SFALL: allow ctrl-click to unequip
bool immediate = itemIndex == -1 && _ctrl_pressed();
// allow ctrl-click to quick unequip or equip item
bool immediate = _ctrl_pressed();
_drag_item_loop(item, immediate);
if (immediate || mouseHitTestInWindow(gInventoryWindow, INVENTORY_SCROLLER_X, INVENTORY_SCROLLER_Y, INVENTORY_SCROLLER_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_SCROLLER_Y)) {
// drag into inventory list, or ctrl-click from slot
if (pickUpFromSlot && (immediate || mouseHitTestInWindow(gInventoryWindow, INVENTORY_SCROLLER_X, INVENTORY_SCROLLER_Y, INVENTORY_SCROLLER_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_SCROLLER_Y))) {
int x;
int y;
mouseGetPositionInWindow(gInventoryWindow, &x, &y);
@@ -2392,7 +2399,7 @@ static void _inven_pickup(int buttonCode, int indexOffset)
}
}
if (immediate || itemIndex == -1) {
if (immediate || pickUpFromSlot) {
// TODO: Holy shit, needs refactoring.
*itemSlot = nullptr;
if (itemAdd(_inven_dude, item, 1)) {
@@ -2404,19 +2411,34 @@ static void _inven_pickup(int buttonCode, int indexOffset)
gInventoryRightHandItem = nullptr;
}
}
} else if (!pickUpFromSlot && immediate && itemGetType(item) != ITEM_TYPE_ARMOR) {
// ctrl-click non-armor to quick-equip:
// default to first empty hand, or left hand if both are full
bool left = gInventoryLeftHandItem == nullptr || gInventoryRightHandItem != nullptr;
if (left) {
_switch_hand(item, &gInventoryLeftHandItem, itemSlot, buttonCode);
} else {
_switch_hand(item, &gInventoryRightHandItem, itemSlot, buttonCode);
}
// drop in left hand slot
} else if (mouseHitTestInWindow(gInventoryWindow, INVENTORY_LEFT_HAND_SLOT_X, INVENTORY_LEFT_HAND_SLOT_Y, INVENTORY_LEFT_HAND_SLOT_MAX_X, INVENTORY_LEFT_HAND_SLOT_MAX_Y)) {
if (gInventoryLeftHandItem != nullptr && itemGetType(gInventoryLeftHandItem) == ITEM_TYPE_CONTAINER && gInventoryLeftHandItem != item) {
_drop_into_container(gInventoryLeftHandItem, item, itemIndex, itemSlot, count);
} else if (gInventoryLeftHandItem == nullptr || _drop_ammo_into_weapon(gInventoryLeftHandItem, item, itemSlot, count, buttonCode)) {
_switch_hand(item, &gInventoryLeftHandItem, itemSlot, buttonCode);
}
// drop in right hand slot
} else if (mouseHitTestInWindow(gInventoryWindow, INVENTORY_RIGHT_HAND_SLOT_X, INVENTORY_RIGHT_HAND_SLOT_Y, INVENTORY_RIGHT_HAND_SLOT_MAX_X, INVENTORY_RIGHT_HAND_SLOT_MAX_Y)) {
if (gInventoryRightHandItem != nullptr && itemGetType(gInventoryRightHandItem) == ITEM_TYPE_CONTAINER && gInventoryRightHandItem != item) {
_drop_into_container(gInventoryRightHandItem, item, itemIndex, itemSlot, count);
} else if (gInventoryRightHandItem == nullptr || _drop_ammo_into_weapon(gInventoryRightHandItem, item, itemSlot, count, buttonCode)) {
_switch_hand(item, &gInventoryRightHandItem, itemSlot, itemIndex);
}
} else if (mouseHitTestInWindow(gInventoryWindow, INVENTORY_ARMOR_SLOT_X, INVENTORY_ARMOR_SLOT_Y, INVENTORY_ARMOR_SLOT_MAX_X, INVENTORY_ARMOR_SLOT_MAX_Y)) {
} else if ((immediate && itemGetType(item) == ITEM_TYPE_ARMOR) || mouseHitTestInWindow(gInventoryWindow, INVENTORY_ARMOR_SLOT_X, INVENTORY_ARMOR_SLOT_Y, INVENTORY_ARMOR_SLOT_MAX_X, INVENTORY_ARMOR_SLOT_MAX_Y)) {
if (itemGetType(item) == ITEM_TYPE_ARMOR) {
Object* currentArmor = gInventoryArmor;
int itemAddResult = 0;
+1 -1
View File
@@ -38,7 +38,7 @@ typedef struct Region {
} Region;
void _regionSetBound(Region* region);
Region* regionCreate(int a1);
Region* regionCreate(int initialCapacity);
void regionAddPoint(Region* region, int x, int y);
void regionDelete(Region* region);
void regionSetName(Region* region, const char* src);
+34
View File
@@ -0,0 +1,34 @@
#include "scan_unimplemented.h"
#include "config.h"
#include "dfile.h"
#include "dictionary.h"
#include "interpreter.h"
#include "platform_compat.h"
#include "scan_unimplemented_configs.h"
#include "scan_unimplemented_opcodes.h"
#include "scan_unimplemented_sfall.h"
#include "scan_unimplemented_utils.h"
#include "sfall_metarules.h"
#include <algorithm>
#include <filesystem>
#include <iomanip>
#include <iostream>
#include <map>
#include <memory>
#include <set>
#include <stdio.h>
#include <string.h>
#include <string>
#include <sys/stat.h>
bool gScanUnimplementedEnabled = false;
void scanUnimplementdParseCommandLineArguments(int argc, char** argv)
{
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "--scan-unimplemented") == 0) {
gScanUnimplementedEnabled = true;
printf("== Scanning of unimplemented is enabled == \n");
};
}
}

Some files were not shown because too many files have changed in this diff Show More