mirror of
https://github.com/fallout2-ce/fallout2-ce.git
synced 2026-07-27 16:47:11 -07:00
Compare commits
264
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8751a2551b | ||
|
|
2bf0aecff3 | ||
|
|
2b0c1deebf | ||
|
|
1aa36af8b4 | ||
|
|
d672346a64 | ||
|
|
20e8ff3725 | ||
|
|
811d5de9ac | ||
|
|
14300f3f97 | ||
|
|
3a3675d846 | ||
|
|
036f63ffa8 | ||
|
|
60bf86231a | ||
|
|
608d758864 | ||
|
|
e0384a37b5 | ||
|
|
65922b8dd2 | ||
|
|
7c1c9d287e | ||
|
|
c8cf50540f | ||
|
|
ebcd124ba4 | ||
|
|
07c55842b4 | ||
|
|
7ad7c43ce6 | ||
|
|
9baea460c9 | ||
|
|
9b182e4c25 | ||
|
|
9b490e9627 | ||
|
|
f5d976d199 | ||
|
|
c352107b09 | ||
|
|
b6bfcff9b3 | ||
|
|
1df5841810 | ||
|
|
98ff03c0b9 | ||
|
|
404236c0cb | ||
|
|
3cd817d4b5 | ||
|
|
e8d85dbdd8 | ||
|
|
3633652884 | ||
|
|
e86dce3266 | ||
|
|
a738c38a81 | ||
|
|
be4569315f | ||
|
|
a2505f8412 | ||
|
|
018d3dd48b | ||
|
|
41eafedf87 | ||
|
|
c914e62f44 | ||
|
|
a478e24c8a | ||
|
|
2703af882c | ||
|
|
36e8b90831 | ||
|
|
3249b7dc07 | ||
|
|
f291f52a61 | ||
|
|
4bc2ed5d0d | ||
|
|
b6a522a065 | ||
|
|
bbb01398ef | ||
|
|
fb5e1f9c07 | ||
|
|
625928265e | ||
|
|
a6ccac2a58 | ||
|
|
19e72a5b6d | ||
|
|
44f5477ee5 | ||
|
|
8d0587566f | ||
|
|
0ed3725124 | ||
|
|
86787e2c97 | ||
|
|
f60b773ed4 | ||
|
|
b6384ce8e9 | ||
|
|
15aa1db286 | ||
|
|
763169f33e | ||
|
|
58b811f2ae | ||
|
|
bfcfaa9540 | ||
|
|
a478bad7fa | ||
|
|
9a3ec752dd | ||
|
|
f940766379 | ||
|
|
87e1d1f11b | ||
|
|
5d17e0ef89 | ||
|
|
2bf08228c5 | ||
|
|
571b43410d | ||
|
|
f0e6002df9 | ||
|
|
d593c481f2 | ||
|
|
76f3d82679 | ||
|
|
0e1270a606 | ||
|
|
55a32a00ab | ||
|
|
7b9b545baa | ||
|
|
a96edd9f0c | ||
|
|
55c528f346 | ||
|
|
5c28dc798f | ||
|
|
7ef6943588 | ||
|
|
40bbd6c02a | ||
|
|
45c491c11f | ||
|
|
18c05d438e | ||
|
|
c3a501a644 | ||
|
|
2767a399c5 | ||
|
|
1237d8561d | ||
|
|
89b6812711 | ||
|
|
339146c5b3 | ||
|
|
3949c5d7c1 | ||
|
|
84a64035e8 | ||
|
|
164be5105a | ||
|
|
d532e4c398 | ||
|
|
950c12dbf7 | ||
|
|
2be9b7db65 | ||
|
|
138ce8be9b | ||
|
|
96b9323a97 | ||
|
|
7c6d339e3d | ||
|
|
2ec8240820 | ||
|
|
ca72573c14 | ||
|
|
9974a23c1e | ||
|
|
cd6cce3f34 | ||
|
|
361b9a0b30 | ||
|
|
7c7cb87f65 | ||
|
|
20bcb2360c | ||
|
|
75dbc98321 | ||
|
|
d792cfa32e | ||
|
|
e81a07dcaf | ||
|
|
0d78119680 | ||
|
|
79d0fcfcaa | ||
|
|
2d5e69d740 | ||
|
|
b5cf3ee148 | ||
|
|
a571a985c6 | ||
|
|
6ccba74836 | ||
|
|
30c3af01f5 | ||
|
|
fd25944a9e | ||
|
|
41c5d77f89 | ||
|
|
75513058a5 | ||
|
|
0cf55eca75 | ||
|
|
e6cbdd5466 | ||
|
|
90f634b285 | ||
|
|
666ee6f41c | ||
|
|
4342aefa5d | ||
|
|
7224c7d7fb | ||
|
|
dff7529707 | ||
|
|
2435b33480 | ||
|
|
c4652d799a | ||
|
|
5140b00ccf | ||
|
|
f1ba068d05 | ||
|
|
01db7078c7 | ||
|
|
64fd857da6 | ||
|
|
555652d9c3 | ||
|
|
8c35203b7d | ||
|
|
0303a00299 | ||
|
|
dd16e374ee | ||
|
|
ce4495589b | ||
|
|
af350914ef | ||
|
|
8dd2afc4fa | ||
|
|
240aa8a212 | ||
|
|
c58b5eac1d | ||
|
|
0bd8a76b05 | ||
|
|
853266b380 | ||
|
|
0adc9c9e77 | ||
|
|
150e734955 | ||
|
|
d0ba0151d1 | ||
|
|
67c70661a6 | ||
|
|
9c4efeb59d | ||
|
|
ea0afc84fa | ||
|
|
c663d79b97 | ||
|
|
8bd87be687 | ||
|
|
8101c78e78 | ||
|
|
9b5737a14e | ||
|
|
3d4c073856 | ||
|
|
f868ac0e1a | ||
|
|
eaa9091bcd | ||
|
|
76ab99cf73 | ||
|
|
bed9555f9a | ||
|
|
9c5294ca88 | ||
|
|
781d8ab282 | ||
|
|
34ef1c2f26 | ||
|
|
fdc54cfd0b | ||
|
|
a63aff09ce | ||
|
|
3d2aced2f7 | ||
|
|
1d6111b89f | ||
|
|
21c906cc5c | ||
|
|
a67fe7ead1 | ||
|
|
f0691d2c24 | ||
|
|
fb30648e2e | ||
|
|
216cbb3861 | ||
|
|
be63df4bf6 | ||
|
|
4cf35fd946 | ||
|
|
dd418ee0f5 | ||
|
|
eb5cc7be4f | ||
|
|
8c6f28b018 | ||
|
|
2e36030389 | ||
|
|
a88ca9f7e7 | ||
|
|
72d9ae85c8 | ||
|
|
a8f2de1a56 | ||
|
|
51b82ac1ac | ||
|
|
0d97222797 | ||
|
|
b30463ab01 | ||
|
|
9d932b0d2c | ||
|
|
8d76b9655c | ||
|
|
0e6c4d9684 | ||
|
|
02c5efac26 | ||
|
|
b7933f6b80 | ||
|
|
fcb1680db2 | ||
|
|
ea4d978bc1 | ||
|
|
22548a3c70 | ||
|
|
cd6ca76988 | ||
|
|
5d3cbd567a | ||
|
|
70ef1d4009 | ||
|
|
3acf0ac6c4 | ||
|
|
a73c336ead | ||
|
|
d46aea53bd | ||
|
|
3dc89d49e2 | ||
|
|
822d5dfd7d | ||
|
|
879634bf9c | ||
|
|
795ef54d70 | ||
|
|
14b06d2dcc | ||
|
|
ed959edbbb | ||
|
|
7940ea791c | ||
|
|
3f270aa4cc | ||
|
|
b8769fded1 | ||
|
|
43d5b6028d | ||
|
|
da3f1cc426 | ||
|
|
a892461dac | ||
|
|
209d2d027b | ||
|
|
b8385d7775 | ||
|
|
a3c365f9fe | ||
|
|
87d4a4b8ca | ||
|
|
1aa53a4720 | ||
|
|
6bcf2952f6 | ||
|
|
e2927e1d0e | ||
|
|
bb839cd6c1 | ||
|
|
caa0e1bf1a | ||
|
|
f3759d07a5 | ||
|
|
604fde895f | ||
|
|
f46c391e5d | ||
|
|
1e45b0184b | ||
|
|
447ea23862 | ||
|
|
72786c4d43 | ||
|
|
3d3e47c9db | ||
|
|
a9726cab56 | ||
|
|
400aa4d8a3 | ||
|
|
599d3ab392 | ||
|
|
84336d4655 | ||
|
|
696e926177 | ||
|
|
30babd7e1f | ||
|
|
6ff0b411e4 | ||
|
|
9f623f3f3e | ||
|
|
d8bee457f4 | ||
|
|
fcabd63561 | ||
|
|
73c024c705 | ||
|
|
27da084b65 | ||
|
|
dfa610f352 | ||
|
|
a0a597725a | ||
|
|
7ae194a8ee | ||
|
|
7f7e103465 | ||
|
|
721e40f784 | ||
|
|
59c64451ff | ||
|
|
965f360578 | ||
|
|
3f79d79f25 | ||
|
|
cad023a73e | ||
|
|
7490c900b3 | ||
|
|
67a6119f34 | ||
|
|
aa036c574e | ||
|
|
a17d7fb7d5 | ||
|
|
8ed777ba83 | ||
|
|
7c182b66a6 | ||
|
|
f6320d3a66 | ||
|
|
ec2ecd17d9 | ||
|
|
de06827c01 | ||
|
|
e3437a8d0e | ||
|
|
f12babe525 | ||
|
|
cb990ac154 | ||
|
|
a3fc8d21be | ||
|
|
cc805db194 | ||
|
|
41a7c97e69 | ||
|
|
2ca921c525 | ||
|
|
e676089f83 | ||
|
|
e119aa4c4d | ||
|
|
ea66287551 | ||
|
|
db07e95f5b | ||
|
|
acd0413626 | ||
|
|
196ad2267f | ||
|
|
22a864a0c9 | ||
|
|
252d7fe83e |
@@ -14,6 +14,16 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
permissions: write-all
|
||||
steps:
|
||||
- name: start deployment
|
||||
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
|
||||
uses: bobheadxi/deployments@v1
|
||||
id: deployment
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
step: start
|
||||
debug: true
|
||||
env: preview-${{ github.event.pull_request.number }}
|
||||
|
||||
- name: Clone
|
||||
uses: actions/checkout@v4
|
||||
|
||||
@@ -76,6 +86,10 @@ jobs:
|
||||
SITE_BASE: ${{ steps.set-path.outputs.SITE_BASE }}
|
||||
F2_GAME_VERSION: Game=${{github.event.pull_request.head.sha || github.sha }}
|
||||
|
||||
- name: Place hash file
|
||||
if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository)
|
||||
run: echo "$GITHUB_SHA" > fallout2-ce-ems/dist/site_hash.txt
|
||||
|
||||
- name: Install rsync (required for the next step)
|
||||
if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository)
|
||||
run: |
|
||||
@@ -91,10 +105,37 @@ jobs:
|
||||
clean: false
|
||||
single-commit: true
|
||||
|
||||
- name: Comment preview URL on PR
|
||||
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
|
||||
|
||||
|
||||
- name: Check that site is deployed
|
||||
if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository)
|
||||
run: |
|
||||
gh pr comment ${{ github.event.pull_request.number }} \
|
||||
--body "🚀 WebAssembly PR Preview for ${{github.event.pull_request.head.sha || github.sha }} is available at: https://${{ github.repository_owner }}.github.io/fallout2-ce/PR-${{ github.event.pull_request.number }}/"
|
||||
URL="$SITE_ORIGIN""$SITE_BASE""site_hash.txt"
|
||||
echo "Expecting $GITHUB_SHA from $URL"
|
||||
for i in `seq 1 80`; do
|
||||
got="$(curl -fsSL --max-time 10 "$URL" | tr -d '\r\n' || true)"
|
||||
if [ "$got" = "$GITHUB_SHA" ]; then
|
||||
echo "âś… Match on attempt $i: ${got}"
|
||||
exit 0
|
||||
fi
|
||||
echo "Received $got, waiting"
|
||||
sleep 5
|
||||
done
|
||||
exit 1
|
||||
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SITE_ORIGIN: https://${{ github.repository_owner }}.github.io
|
||||
SITE_BASE: ${{ steps.set-path.outputs.SITE_BASE }}
|
||||
|
||||
- name: Update deployment status
|
||||
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
|
||||
uses: bobheadxi/deployments@v1
|
||||
with:
|
||||
step: finish
|
||||
status: success
|
||||
debug: true
|
||||
env: ${{ steps.deployment.outputs.env }}
|
||||
deployment_id: ${{ steps.deployment.outputs.deployment_id }}
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
env_url: https://${{ github.repository_owner }}.github.io/fallout2-ce/PR-${{ github.event.pull_request.number }}/
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ jobs:
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: os/android/app/.cxx
|
||||
key: android-cmake-v2
|
||||
key: android-cmake-v101
|
||||
|
||||
- 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-v101
|
||||
|
||||
- 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-v101
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
@@ -288,7 +288,7 @@ jobs:
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: out
|
||||
key: macos-cmake-v6
|
||||
key: macos-cmake-v101
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
@@ -328,16 +328,16 @@ jobs:
|
||||
- name: Clone
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Visual Studio 2019 Build Tools with v141_xp
|
||||
- name: Install Visual Studio 2022 Build Tools with v141_xp
|
||||
shell: cmd
|
||||
run: |
|
||||
choco install visualstudio2019buildtools -y --package-parameters="'--add Microsoft.VisualStudio.Workload.VCTools --add Microsoft.VisualStudio.Component.VC.v141.x86.x64 --add Microsoft.VisualStudio.Component.VC.v141.xp --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --add Microsoft.VisualStudio.Component.Windows10SDK.10240 --add Microsoft.VisualStudio.ComponentGroup.NativeDesktop.WinXP --add Microsoft.VisualStudio.Component.WinXP'"
|
||||
choco install visualstudio2022buildtools -y --package-parameters="'--add Microsoft.VisualStudio.Workload.VCTools --add Microsoft.VisualStudio.Component.VC.v141.x86.x64 --add Microsoft.VisualStudio.Component.VC.v141.xp --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --add Microsoft.VisualStudio.Component.Windows10SDK.10240 --add Microsoft.VisualStudio.ComponentGroup.NativeDesktop.WinXP --add Microsoft.VisualStudio.Component.WinXP'"
|
||||
|
||||
- name: Cache cmake build
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: out
|
||||
key: windows-${{ matrix.arch }}-cmake-v3
|
||||
key: windows-${{ matrix.arch }}-cmake-v102
|
||||
|
||||
- name: Configure
|
||||
shell: cmd
|
||||
@@ -432,4 +432,4 @@ jobs:
|
||||
tag_name: continious
|
||||
draft: false
|
||||
prerelease: true
|
||||
name: Fallout2-CE Continuous Build
|
||||
name: Fallout2-CE Continuous Build
|
||||
|
||||
@@ -12,6 +12,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
deployments: write
|
||||
steps:
|
||||
- name: Checkout gh-pages branch
|
||||
uses: actions/checkout@v4
|
||||
@@ -43,4 +44,12 @@ jobs:
|
||||
else
|
||||
git commit --amend -m "đźš® Remove preview for closed PR #${{ github.event.pull_request.number }}"
|
||||
git push --force
|
||||
fi
|
||||
fi
|
||||
|
||||
- name: mark environment as deactivated
|
||||
uses: bobheadxi/deployments@v1
|
||||
with:
|
||||
step: deactivate-env
|
||||
env: preview-${{ github.event.pull_request.number }}
|
||||
desc: Environment was pruned
|
||||
debug: true
|
||||
|
||||
+8
-1
@@ -288,10 +288,16 @@ target_sources(${EXECUTABLE_NAME} PUBLIC
|
||||
"src/sfall_opcodes.h"
|
||||
"src/sfall_arrays.cc"
|
||||
"src/sfall_arrays.h"
|
||||
"src/sfall_callbacks.cc"
|
||||
"src/sfall_callbacks.h"
|
||||
"src/touch.cc"
|
||||
"src/touch.h"
|
||||
"src/scan_unimplemented.cc"
|
||||
"third_party/lodepng/lodepng.cpp"
|
||||
)
|
||||
|
||||
target_include_directories(${EXECUTABLE_NAME} PUBLIC "third_party/lodepng")
|
||||
|
||||
if(IOS)
|
||||
target_sources(${EXECUTABLE_NAME} PUBLIC
|
||||
"src/platform/ios/paths.h"
|
||||
@@ -312,7 +318,8 @@ endif()
|
||||
if(WIN32)
|
||||
target_link_libraries(${EXECUTABLE_NAME}
|
||||
winmm
|
||||
libcpmt
|
||||
debug libcpmtd
|
||||
optimized libcpmt
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
+2
-2
@@ -28,7 +28,7 @@
|
||||
"inherits": [
|
||||
"windows-base"
|
||||
],
|
||||
"generator": "Visual Studio 16 2019",
|
||||
"generator": "Visual Studio 17 2022",
|
||||
"architecture": "Win32",
|
||||
"cacheVariables": {
|
||||
"CMAKE_GENERATOR_TOOLSET": "v141_xp",
|
||||
@@ -42,7 +42,7 @@
|
||||
"inherits": [
|
||||
"windows-base"
|
||||
],
|
||||
"generator": "Visual Studio 16 2019",
|
||||
"generator": "Visual Studio 17 2022",
|
||||
"architecture": "x64",
|
||||
"cacheVariables": {
|
||||
"CMAKE_MSVC_RUNTIME_LIBRARY": "MultiThreaded$<$<CONFIG:Debug>:Debug>"
|
||||
|
||||
@@ -44,7 +44,7 @@ $ sudo apt install libsdl2-2.0-0
|
||||
|
||||
- Alternatively you can use Fallout 2 from Macplay/The Omni Group as a base - you need to extract game assets from the original bundle. Mount CD/DMG, right click `Fallout 2` -> `Show Package Contents`, navigate to `Contents/Resources`. Copy `GameData` folder somewhere, for example `/Applications/Fallout2`.
|
||||
|
||||
- Or if you're a Terminal user and have Homebrew installed you can extract the needed files from the GoG installer:
|
||||
- Or if you're a Terminal user and have Homebrew installed you can extract the needed files from the GoG installer. **Note**: You must use "Offline backup game installer", not the main game installer.
|
||||
|
||||
```console
|
||||
$ brew install innoextract
|
||||
@@ -126,6 +126,17 @@ IFACE_BAR_SIDES_ORI=0
|
||||
;if IFACE_BAR_WIDTH=640 - Interface bar will remain at it's original width.
|
||||
;if IFACE_BAR_WIDTH=800 - Interface bar will use 800pix wide asset from f2_res.dat.
|
||||
;IFACE_BAR_WIDTH=640
|
||||
|
||||
[STATIC_SCREENS]
|
||||
;if SPLASH_SCRN_SIZE=0 - Splash screen shows at original size if it fits, otherwise scales down while preserving aspect ratio.
|
||||
;if SPLASH_SCRN_SIZE=1 - Splash screen scales to fit the screen while preserving aspect ratio.
|
||||
;if SPLASH_SCRN_SIZE=2 - Splash screen stretches to fill the entire screen.
|
||||
SPLASH_SCRN_SIZE=0
|
||||
|
||||
[MAPS]
|
||||
;if IGNORE_MAP_EDGES=0 - Hi-Res map scroll edges are enabled.
|
||||
;if IGNORE_MAP_EDGES=1 - Hi-Res map scroll edges are ignored.
|
||||
IGNORE_MAP_EDGES=0
|
||||
```
|
||||
|
||||
Recommendations:
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#include "test_utils.h"
|
||||
#include "sfall.h"
|
||||
|
||||
procedure start begin
|
||||
display_msg("Testing iface_tag functions...");
|
||||
// assumes no iface tags active in the save game
|
||||
|
||||
// SNEAK
|
||||
show_iface_tag(0);
|
||||
call assertTrue("show_iface_tag(SNEAK)", is_iface_tag_active(0));
|
||||
hide_iface_tag(0);
|
||||
call assertFalse("hide_iface_tag(SNEAK)", is_iface_tag_active(0));
|
||||
|
||||
// LEVEL
|
||||
show_iface_tag(3);
|
||||
call assertTrue("show_iface_tag(LEVEL)", is_iface_tag_active(3));
|
||||
hide_iface_tag(3);
|
||||
call assertFalse("hide_iface_tag(LEVEL)", is_iface_tag_active(3));
|
||||
|
||||
// ADDICTED
|
||||
show_iface_tag(4);
|
||||
call assertTrue("show_iface_tag(ADDICTED)", is_iface_tag_active(4));
|
||||
hide_iface_tag(4);
|
||||
call assertFalse("hide_iface_tag(ADDICTED)", is_iface_tag_active(4));
|
||||
|
||||
// POISONED
|
||||
call assertFalse("hide_iface_tag(POISONED)", is_iface_tag_active(1));
|
||||
|
||||
// RADIATED
|
||||
call assertFalse("hide_iface_tag(RADIATED)", is_iface_tag_active(2));
|
||||
|
||||
call report_test_results("iface_tag");
|
||||
end
|
||||
@@ -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
|
||||
@@ -0,0 +1,14 @@
|
||||
|
||||
#include "sfall.h"
|
||||
|
||||
// this is the basic message_box function used by RPU and Et Tu
|
||||
#define message_box_warning(text) message_box4(text, 0x01, 134, 145)
|
||||
|
||||
procedure start begin
|
||||
// I don't see a practice way to auto test message_box, so this is just a way to do manual testing
|
||||
variable ret = message_box1("Basic Dialog\nwith multiple lines\nand such.");
|
||||
display_msg("chose: " + ret);
|
||||
message_box2("Basic Dialog\nwith default flags.", -1); // -1 means use default flags
|
||||
message_box2("Basic Dialog\nsmall.", 0x02);
|
||||
message_box_warning("Missing config values\n(just testing).");
|
||||
end
|
||||
@@ -0,0 +1,30 @@
|
||||
#include "test_utils.h"
|
||||
#include "sfall.h"
|
||||
|
||||
procedure start begin
|
||||
|
||||
display_msg("Testing metarule_exist functions...");
|
||||
|
||||
call assertEquals("string_format", metarule_exist("string_format"), 1);
|
||||
call assertEquals("metarule_exist", metarule_exist("metarule_exist"), 1);
|
||||
|
||||
// This will fail on sFall
|
||||
call assertEquals("opcode_exists", metarule_exist("opcode_exists"), 1);
|
||||
|
||||
if metarule_exist("opcode_exists") then begin // And example if how to use it
|
||||
#define opcode_exists(opcode) sfall_func1("opcode_exists", opcode)
|
||||
#define OP_GET_UPTIME 0x81B3
|
||||
#define OP_NOOP 0x8000
|
||||
#define OP_WRITE_INT 0x81D1
|
||||
|
||||
call assertEquals("opcode_exists OP_GET_UPTIME", opcode_exists(OP_GET_UPTIME), 1);
|
||||
call assertEquals("opcode_exists OP_NOOP", opcode_exists(OP_NOOP), 1);
|
||||
// Probably will never be implemented on fallout2-ce
|
||||
call assertEquals("opcode_exists OP_WRITE_INT", opcode_exists(OP_WRITE_INT), 0);
|
||||
call assertEquals("opcode_exists 0xFFFF", opcode_exists(0xFFFF), 0);
|
||||
end else begin
|
||||
display_msg("Opcode exists metarule is not available, skipping tests.");
|
||||
end
|
||||
|
||||
call report_test_results("metarule_exist");
|
||||
end
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -7,6 +7,28 @@ 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 assertFalse(variable desc, variable a) begin
|
||||
test_suite_assertions++;
|
||||
|
||||
if (a) then begin
|
||||
display_msg("Assertion failed \""+desc+"\": is not false");
|
||||
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++;
|
||||
|
||||
|
||||
+32
-45
@@ -103,7 +103,7 @@ static int hideProjectile(void* _, void* projectile);
|
||||
// 0x410468
|
||||
int actionKnockdown(Object* obj, int* anim, int maxDistance, int rotation, int delay)
|
||||
{
|
||||
if (_critter_flag_check(obj->pid, CRITTER_NO_KNOCKBACK)) {
|
||||
if (critterFlagCheck(obj->pid, CRITTER_NO_KNOCKBACK)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -208,7 +208,7 @@ int _pick_death(Object* attacker, Object* defender, Object* weapon, int damage,
|
||||
|
||||
int violenceLevel = settings.preferences.violence_level;
|
||||
|
||||
if (_critter_flag_check(defender->pid, CRITTER_SPECIAL_DEATH)) {
|
||||
if (critterFlagCheck(defender->pid, CRITTER_SPECIAL_DEATH)) {
|
||||
return _check_death(defender, ANIM_EXPLODED_TO_NOTHING, VIOLENCE_LEVEL_NORMAL, hitFromFront);
|
||||
}
|
||||
|
||||
@@ -285,7 +285,7 @@ int _check_death(Object* obj, int anim, int minViolenceLevel, bool hitFromFront)
|
||||
// 0x4108C8
|
||||
int _internal_destroy(Object* _, Object* toDestroy)
|
||||
{
|
||||
return _obj_destroy(toDestroy);
|
||||
return objectDestroy(toDestroy);
|
||||
}
|
||||
|
||||
// TODO: Check very carefully, lots of conditions and jumps.
|
||||
@@ -297,12 +297,12 @@ void _show_damage_to_object(Object* defender, int damage, int flags, Object* wea
|
||||
int fid;
|
||||
const char* sfx_name;
|
||||
|
||||
if (_critter_flag_check(defender->pid, CRITTER_NO_KNOCKBACK)) {
|
||||
if (critterFlagCheck(defender->pid, CRITTER_NO_KNOCKBACK)) {
|
||||
knockbackDistance = 0;
|
||||
}
|
||||
|
||||
anim = FID_ANIM_TYPE(defender->fid);
|
||||
if (!_critter_is_prone(defender)) {
|
||||
if (!critterIsProne(defender)) {
|
||||
if ((flags & DAM_DEAD) != 0) {
|
||||
fid = buildFid(OBJ_TYPE_MISC, 10, 0, 0, 0);
|
||||
if (fid == attacker->fid) {
|
||||
@@ -447,7 +447,7 @@ void _show_damage_to_object(Object* defender, int damage, int flags, Object* wea
|
||||
|
||||
if (weapon != nullptr) {
|
||||
if ((flags & DAM_EXPLODE) != 0) {
|
||||
animationRegisterCallbackForced(defender, weapon, (AnimationCallback*)_obj_drop, -1);
|
||||
animationRegisterCallbackForced(defender, weapon, (AnimationCallback*)objectDrop, -1);
|
||||
fid = buildFid(OBJ_TYPE_MISC, 10, 0, 0, 0);
|
||||
animationRegisterSetFid(weapon, fid, 0);
|
||||
animationRegisterAnimateAndHide(weapon, ANIM_STAND, 0);
|
||||
@@ -459,7 +459,7 @@ void _show_damage_to_object(Object* defender, int damage, int flags, Object* wea
|
||||
} else if ((flags & DAM_DESTROY) != 0) {
|
||||
animationRegisterCallbackForced(defender, weapon, (AnimationCallback*)_internal_destroy, -1);
|
||||
} else if ((flags & DAM_DROP) != 0) {
|
||||
animationRegisterCallbackForced(defender, weapon, (AnimationCallback*)_obj_drop, -1);
|
||||
animationRegisterCallbackForced(defender, weapon, (AnimationCallback*)objectDrop, -1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -488,7 +488,7 @@ int _show_death(Object* obj, int anim)
|
||||
}
|
||||
}
|
||||
|
||||
if (!_critter_flag_check(obj->pid, CRITTER_FLAT)) {
|
||||
if (!critterFlagCheck(obj->pid, CRITTER_FLAT)) {
|
||||
obj->flags |= OBJECT_NO_BLOCK;
|
||||
if (_obj_toggle_flat(obj, &tempRect) == 0) {
|
||||
rectUnion(&dirtyRect, &tempRect, &dirtyRect);
|
||||
@@ -499,7 +499,7 @@ int _show_death(Object* obj, int anim)
|
||||
rectUnion(&dirtyRect, &tempRect, &dirtyRect);
|
||||
}
|
||||
|
||||
if (anim >= 30 && anim <= 31 && !_critter_flag_check(obj->pid, CRITTER_SPECIAL_DEATH) && !_critter_flag_check(obj->pid, CRITTER_NO_DROP)) {
|
||||
if (anim >= 30 && anim <= 31 && !critterFlagCheck(obj->pid, CRITTER_SPECIAL_DEATH) && !critterFlagCheck(obj->pid, CRITTER_NO_DROP)) {
|
||||
itemDropAll(obj, obj->tile);
|
||||
}
|
||||
|
||||
@@ -1032,9 +1032,7 @@ int _action_climb_ladder(Object* critter, Object* ladder)
|
||||
reg_anim_begin(animationRequestOptions);
|
||||
|
||||
int tile = tileGetTileInDirection(ladder->tile, ROTATION_SE, 1);
|
||||
int walkDistance = 5;
|
||||
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_USE_WALK_DISTANCE, &walkDistance);
|
||||
if (actionPoints != -1 || objectGetDistanceBetween(critter, ladder) < walkDistance) {
|
||||
if (actionPoints != -1 || objectWithinWalkDistance(critter, ladder)) {
|
||||
animationRegisterMoveToTile(critter, tile, ladder->elevation, actionPoints, 0);
|
||||
} else {
|
||||
animationRegisterRunToTile(critter, tile, ladder->elevation, actionPoints, 0);
|
||||
@@ -1042,7 +1040,7 @@ int _action_climb_ladder(Object* critter, Object* ladder)
|
||||
|
||||
animationRegisterCallbackForced(critter, ladder, (AnimationCallback*)_is_next_to, -1);
|
||||
animationRegisterRotateToTile(critter, ladder->tile);
|
||||
animationRegisterCallbackForced(critter, ladder, (AnimationCallback*)_check_scenery_ap_cost, -1);
|
||||
animationRegisterCallbackForced(critter, ladder, (AnimationCallback*)checkSceneryUseActionPointCost, -1);
|
||||
|
||||
int weaponAnimationCode = (critter->fid & 0xF000) >> 12;
|
||||
if (weaponAnimationCode != 0) {
|
||||
@@ -1054,7 +1052,7 @@ int _action_climb_ladder(Object* critter, Object* ladder)
|
||||
const char* climbingSfx = sfxBuildCharName(critter, ANIM_CLIMB_LADDER, CHARACTER_SOUND_EFFECT_UNUSED);
|
||||
animationRegisterPlaySoundEffect(critter, climbingSfx, -1);
|
||||
animationRegisterAnimate(critter, ANIM_CLIMB_LADDER, 0);
|
||||
animationRegisterCallback(critter, ladder, (AnimationCallback*)_obj_use, -1);
|
||||
animationRegisterCallback(critter, ladder, (AnimationCallback*)objectUse, -1);
|
||||
|
||||
if (weaponAnimationCode != 0) {
|
||||
animationRegisterTakeOutWeapon(critter, weaponAnimationCode, -1);
|
||||
@@ -1101,9 +1099,7 @@ int _action_use_an_item_on_object(Object* user, Object* targetObj, Object* item)
|
||||
|
||||
reg_anim_begin(animationRequestOptions);
|
||||
|
||||
int walkDistance = 5;
|
||||
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_USE_WALK_DISTANCE, &walkDistance);
|
||||
if (actionPoints != -1 || objectGetDistanceBetween(user, targetObj) < walkDistance) {
|
||||
if (actionPoints != -1 || objectWithinWalkDistance(user, targetObj)) {
|
||||
animationRegisterMoveToObject(user, targetObj, actionPoints, 0);
|
||||
} else {
|
||||
animationRegisterRunToObject(user, targetObj, -1, 0);
|
||||
@@ -1112,7 +1108,7 @@ int _action_use_an_item_on_object(Object* user, Object* targetObj, Object* item)
|
||||
animationRegisterCallbackForced(user, targetObj, (AnimationCallback*)_is_next_to, -1);
|
||||
|
||||
if (item == nullptr) {
|
||||
animationRegisterCallback(user, targetObj, (AnimationCallback*)_check_scenery_ap_cost, -1);
|
||||
animationRegisterCallback(user, targetObj, (AnimationCallback*)checkSceneryUseActionPointCost, -1);
|
||||
}
|
||||
|
||||
int weaponAnimCode = (user->fid & 0xF000) >> 12;
|
||||
@@ -1124,9 +1120,9 @@ int _action_use_an_item_on_object(Object* user, Object* targetObj, Object* item)
|
||||
|
||||
int anim;
|
||||
int objectType = FID_TYPE(targetObj->fid);
|
||||
if (objectType == OBJ_TYPE_CRITTER && _critter_is_prone(targetObj)) {
|
||||
if (objectType == OBJ_TYPE_CRITTER && critterIsProne(targetObj)) {
|
||||
anim = ANIM_MAGIC_HANDS_GROUND;
|
||||
} else if (objectType == OBJ_TYPE_SCENERY && (proto->scenery.extendedFlags & 0x01) != 0) {
|
||||
} else if (objectType == OBJ_TYPE_SCENERY && (proto->scenery.extendedFlags & PROTO_EXT_FLAG_MAGIC_HANDS_GROUND) != 0) {
|
||||
anim = ANIM_MAGIC_HANDS_GROUND;
|
||||
} else {
|
||||
anim = ANIM_MAGIC_HANDS_MIDDLE;
|
||||
@@ -1138,9 +1134,9 @@ int _action_use_an_item_on_object(Object* user, Object* targetObj, Object* item)
|
||||
|
||||
if (item != nullptr) {
|
||||
// TODO: Get rid of cast.
|
||||
animationRegisterCallback3(user, targetObj, item, (AnimationCallback3*)_obj_use_item_on, -1);
|
||||
animationRegisterCallback3(user, targetObj, item, (AnimationCallback3*)objectUseItemOn, -1);
|
||||
} else {
|
||||
animationRegisterCallback(user, targetObj, (AnimationCallback*)_obj_use, -1);
|
||||
animationRegisterCallback(user, targetObj, (AnimationCallback*)objectUse, -1);
|
||||
}
|
||||
|
||||
if (weaponAnimCode != 0) {
|
||||
@@ -1173,15 +1169,12 @@ int actionPickUp(Object* critter, Object* item)
|
||||
}
|
||||
}
|
||||
|
||||
int walkDistance = 5;
|
||||
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_USE_WALK_DISTANCE, &walkDistance);
|
||||
|
||||
if (isInCombat()) {
|
||||
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
|
||||
animationRegisterMoveToObject(critter, item, critter->data.critter.combat.ap, 0);
|
||||
} else {
|
||||
reg_anim_begin(critter == gDude ? ANIMATION_REQUEST_RESERVED : ANIMATION_REQUEST_UNRESERVED);
|
||||
if (objectGetDistanceBetween(critter, item) >= walkDistance) {
|
||||
if (!objectWithinWalkDistance(critter, item)) {
|
||||
animationRegisterRunToObject(critter, item, -1, 0);
|
||||
} else {
|
||||
animationRegisterMoveToObject(critter, item, -1, 0);
|
||||
@@ -1189,7 +1182,7 @@ int actionPickUp(Object* critter, Object* item)
|
||||
}
|
||||
|
||||
animationRegisterCallbackForced(critter, item, (AnimationCallback*)_is_next_to, -1);
|
||||
animationRegisterCallback(critter, item, (AnimationCallback*)_check_scenery_ap_cost, -1);
|
||||
animationRegisterCallback(critter, item, (AnimationCallback*)checkSceneryUseActionPointCost, -1);
|
||||
|
||||
Proto* itemProto;
|
||||
protoGetProto(item->pid, &itemProto);
|
||||
@@ -1214,7 +1207,7 @@ int actionPickUp(Object* critter, Object* item)
|
||||
animationRegisterPlaySoundEffect(item, sfx, actionFrame);
|
||||
}
|
||||
|
||||
animationRegisterCallback(critter, item, (AnimationCallback*)_obj_pickup, actionFrame);
|
||||
animationRegisterCallback(critter, item, (AnimationCallback*)objectPickup, actionFrame);
|
||||
} else {
|
||||
int weaponAnimationCode = (critter->fid & 0xF000) >> 12;
|
||||
if (weaponAnimationCode != 0) {
|
||||
@@ -1242,7 +1235,7 @@ int actionPickUp(Object* critter, Object* item)
|
||||
}
|
||||
|
||||
if (item->frame != 1) {
|
||||
animationRegisterCallback(critter, item, (AnimationCallback*)_obj_use_container, actionFrame);
|
||||
animationRegisterCallback(critter, item, (AnimationCallback*)objectUseContainer, actionFrame);
|
||||
}
|
||||
|
||||
if (weaponAnimationCode != 0) {
|
||||
@@ -1270,7 +1263,7 @@ int _action_loot_container(Object* critter, Object* container)
|
||||
}
|
||||
|
||||
// SFALL: Fix for trying to loot corpses with the "NoSteal" flag.
|
||||
if (_critter_flag_check(container->pid, CRITTER_NO_STEAL)) {
|
||||
if (critterFlagCheck(container->pid, CRITTER_NO_STEAL)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1281,16 +1274,13 @@ int _action_loot_container(Object* critter, Object* container)
|
||||
}
|
||||
}
|
||||
|
||||
int walkDistance = 5;
|
||||
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_USE_WALK_DISTANCE, &walkDistance);
|
||||
|
||||
if (isInCombat()) {
|
||||
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
|
||||
animationRegisterMoveToObject(critter, container, critter->data.critter.combat.ap, 0);
|
||||
} else {
|
||||
reg_anim_begin(critter == gDude ? ANIMATION_REQUEST_RESERVED : ANIMATION_REQUEST_UNRESERVED);
|
||||
|
||||
if (objectGetDistanceBetween(critter, container) < walkDistance) {
|
||||
if (objectWithinWalkDistance(critter, container)) {
|
||||
animationRegisterMoveToObject(critter, container, -1, 0);
|
||||
} else {
|
||||
animationRegisterRunToObject(critter, container, -1, 0);
|
||||
@@ -1298,7 +1288,7 @@ int _action_loot_container(Object* critter, Object* container)
|
||||
}
|
||||
|
||||
animationRegisterCallbackForced(critter, container, (AnimationCallback*)_is_next_to, -1);
|
||||
animationRegisterCallback(critter, container, (AnimationCallback*)_check_scenery_ap_cost, -1);
|
||||
animationRegisterCallback(critter, container, (AnimationCallback*)checkSceneryUseActionPointCost, -1);
|
||||
animationRegisterCallback(critter, container, (AnimationCallback*)scriptsRequestLooting, -1);
|
||||
return reg_anim_end();
|
||||
}
|
||||
@@ -1488,16 +1478,13 @@ int actionUseSkill(Object* user, Object* target, int skill)
|
||||
}
|
||||
}
|
||||
|
||||
int walkDistance = 5;
|
||||
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_USE_WALK_DISTANCE, &walkDistance);
|
||||
|
||||
if (isInCombat()) {
|
||||
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
|
||||
animationRegisterMoveToObject(performer, target, performer->data.critter.combat.ap, 0);
|
||||
} else {
|
||||
reg_anim_begin(user == gDude ? ANIMATION_REQUEST_RESERVED : ANIMATION_REQUEST_UNRESERVED);
|
||||
if (target != gDude) {
|
||||
if (objectGetDistanceBetween(performer, target) >= walkDistance) {
|
||||
if (!objectWithinWalkDistance(performer, target)) {
|
||||
animationRegisterRunToObject(performer, target, -1, 0);
|
||||
} else {
|
||||
animationRegisterMoveToObject(performer, target, -1, 0);
|
||||
@@ -1507,7 +1494,7 @@ int actionUseSkill(Object* user, Object* target, int skill)
|
||||
|
||||
animationRegisterCallbackForced(performer, target, (AnimationCallback*)_is_next_to, -1);
|
||||
|
||||
int anim = (FID_TYPE(target->fid) == OBJ_TYPE_CRITTER && _critter_is_prone(target)) ? ANIM_MAGIC_HANDS_GROUND : ANIM_MAGIC_HANDS_MIDDLE;
|
||||
int anim = (FID_TYPE(target->fid) == OBJ_TYPE_CRITTER && critterIsProne(target)) ? ANIM_MAGIC_HANDS_GROUND : ANIM_MAGIC_HANDS_MIDDLE;
|
||||
int fid = buildFid(OBJ_TYPE_CRITTER, performer->fid & 0xFFF, anim, 0, performer->rotation + 1);
|
||||
|
||||
CacheEntry* artHandle;
|
||||
@@ -1519,7 +1506,7 @@ int actionUseSkill(Object* user, Object* target, int skill)
|
||||
|
||||
animationRegisterAnimate(performer, anim, -1);
|
||||
// TODO: Get rid of casts.
|
||||
animationRegisterCallback3(performer, target, (void*)(uintptr_t)skill, (AnimationCallback3*)_obj_use_skill_on, -1);
|
||||
animationRegisterCallback3(performer, target, (void*)(uintptr_t)skill, (AnimationCallback3*)objectUseSkillOn, -1);
|
||||
return reg_anim_end();
|
||||
}
|
||||
|
||||
@@ -1766,7 +1753,7 @@ int _report_explosion(Attack* attack, Object* sourceObj)
|
||||
xp += critterGetExp(attack->defender);
|
||||
}
|
||||
} else {
|
||||
_critter_set_who_hit_me(attack->defender, sourceObj);
|
||||
critterSetWhoHitMe(attack->defender, sourceObj);
|
||||
anyDefender = attack->defender;
|
||||
}
|
||||
}
|
||||
@@ -1779,7 +1766,7 @@ int _report_explosion(Attack* attack, Object* sourceObj)
|
||||
xp += critterGetExp(critter);
|
||||
}
|
||||
} else {
|
||||
_critter_set_who_hit_me(critter, sourceObj);
|
||||
critterSetWhoHitMe(critter, sourceObj);
|
||||
|
||||
if (anyDefender == nullptr) {
|
||||
anyDefender = critter;
|
||||
@@ -1985,7 +1972,7 @@ int _report_dmg(Attack* attack, Object* _)
|
||||
// 0x413660
|
||||
int _compute_dmg_damage(int min, int max, Object* obj, int* knockbackDistancePtr, int damageType)
|
||||
{
|
||||
if (!_critter_flag_check(obj->pid, CRITTER_NO_KNOCKBACK)) {
|
||||
if (!critterFlagCheck(obj->pid, CRITTER_NO_KNOCKBACK)) {
|
||||
knockbackDistancePtr = nullptr;
|
||||
}
|
||||
|
||||
@@ -2059,7 +2046,7 @@ int actionPush(Object* obj, Object* target)
|
||||
}
|
||||
|
||||
int sid;
|
||||
if (_obj_sid(target, &sid) == 0) {
|
||||
if (objectGetSid(target, &sid) == 0) {
|
||||
scriptSetObjects(sid, obj, target);
|
||||
scriptExecProc(sid, SCRIPT_PROC_PUSH);
|
||||
|
||||
|
||||
+30
-28
@@ -1418,7 +1418,7 @@ static int animationRunSequence(int animationSequenceIndex)
|
||||
rc = _anim_animate(animationDescription->owner, animationDescription->anim, animationSequenceIndex, ANIM_SAD_FOREVER);
|
||||
break;
|
||||
case ANIM_KIND_ROTATE_TO_TILE:
|
||||
if (!_critter_is_prone(animationDescription->owner)) {
|
||||
if (!critterIsProne(animationDescription->owner)) {
|
||||
int rotation = tileGetRotationTo(animationDescription->owner->tile, animationDescription->tile);
|
||||
_dude_stand(animationDescription->owner, rotation, -1);
|
||||
}
|
||||
@@ -1637,7 +1637,7 @@ static int _anim_set_end(int animationSequenceIndex)
|
||||
}
|
||||
}
|
||||
|
||||
if ((animationSequence->flags & ANIM_SEQ_NO_STAND) == 0 && !_critter_is_prone(owner)) {
|
||||
if ((animationSequence->flags & ANIM_SEQ_NO_STAND) == 0 && !critterIsProne(owner)) {
|
||||
_dude_stand(owner, owner->rotation, -1);
|
||||
}
|
||||
}
|
||||
@@ -1713,16 +1713,18 @@ static bool canUseDoor(Object* critter, Object* door)
|
||||
}
|
||||
|
||||
// 0x415EE8
|
||||
int _make_path(Object* object, int from, int to, unsigned char* rotations, int a5)
|
||||
int _make_path(Object* object, int from, int to, unsigned char* rotations, int requireEmptyDest)
|
||||
{
|
||||
return pathfinderFindPath(object, from, to, rotations, a5, _obj_blocking_at);
|
||||
return pathfinderFindPath(object, from, to, rotations, requireEmptyDest, _obj_blocking_at);
|
||||
}
|
||||
|
||||
// TODO: move pathfinding into another unit
|
||||
// If requireEmptyDest == 1, will not return a path if the destination tile is blocked (according to `callback`).
|
||||
// Returns path length, or 0 if no path is available.
|
||||
// 0x415EFC
|
||||
int pathfinderFindPath(Object* object, int from, int to, unsigned char* rotations, int a5, PathBuilderCallback* callback)
|
||||
int pathfinderFindPath(Object* object, int from, int to, unsigned char* rotations, int requireEmptyDest, PathBuilderCallback* callback)
|
||||
{
|
||||
if (a5) {
|
||||
if (requireEmptyDest) {
|
||||
if (callback(object, to, object->elevation) != nullptr) {
|
||||
return 0;
|
||||
}
|
||||
@@ -1753,7 +1755,7 @@ int pathfinderFindPath(Object* object, int from, int to, unsigned char* rotation
|
||||
|
||||
int toScreenX;
|
||||
int toScreenY;
|
||||
tileToScreenXY(to, &toScreenX, &toScreenY, object->elevation);
|
||||
tileToScreenXY(to, &toScreenX, &toScreenY);
|
||||
|
||||
int closedPathNodeListLength = 0;
|
||||
int openPathNodeListLength = 1;
|
||||
@@ -1838,7 +1840,7 @@ int pathfinderFindPath(Object* object, int from, int to, unsigned char* rotation
|
||||
|
||||
int newX;
|
||||
int newY;
|
||||
tileToScreenXY(tile, &newX, &newY, object->elevation);
|
||||
tileToScreenXY(tile, &newX, &newY);
|
||||
|
||||
v27->estimate = _idist(newX, newY, toScreenX, toScreenY);
|
||||
v27->cost = temp.cost + 50;
|
||||
@@ -1938,11 +1940,11 @@ static int _tile_idistance(int tile1, int tile2)
|
||||
{
|
||||
int x1;
|
||||
int y1;
|
||||
tileToScreenXY(tile1, &x1, &y1, gElevation);
|
||||
tileToScreenXY(tile1, &x1, &y1);
|
||||
|
||||
int x2;
|
||||
int y2;
|
||||
tileToScreenXY(tile2, &x2, &y2, gElevation);
|
||||
tileToScreenXY(tile2, &x2, &y2);
|
||||
|
||||
return _idist(x1, y1, x2, y2);
|
||||
}
|
||||
@@ -1975,13 +1977,13 @@ int _make_straight_path_func(Object* obj, int from, int to, StraightPathNode* st
|
||||
|
||||
int fromX;
|
||||
int fromY;
|
||||
tileToScreenXY(from, &fromX, &fromY, obj->elevation);
|
||||
tileToScreenXY(from, &fromX, &fromY);
|
||||
fromX += 16;
|
||||
fromY += 8;
|
||||
|
||||
int toX;
|
||||
int toY;
|
||||
tileToScreenXY(to, &toX, &toY, obj->elevation);
|
||||
tileToScreenXY(to, &toX, &toY);
|
||||
toX += 16;
|
||||
toY += 8;
|
||||
|
||||
@@ -2019,7 +2021,7 @@ int _make_straight_path_func(Object* obj, int from, int to, StraightPathNode* st
|
||||
if (ddx <= ddy) {
|
||||
int middle = ddx - ddy / 2;
|
||||
while (true) {
|
||||
tile = tileFromScreenXY(tileX, tileY, obj->elevation);
|
||||
tile = tileFromScreenXY(tileX, tileY);
|
||||
|
||||
v22 += 1;
|
||||
if (v22 == a6) {
|
||||
@@ -2032,7 +2034,7 @@ int _make_straight_path_func(Object* obj, int from, int to, StraightPathNode* st
|
||||
pathNode->tile = tile;
|
||||
pathNode->elevation = obj->elevation;
|
||||
|
||||
tileToScreenXY(tile, &fromX, &fromY, obj->elevation);
|
||||
tileToScreenXY(tile, &fromX, &fromY);
|
||||
pathNode->x = tileX - fromX - 16;
|
||||
pathNode->y = tileY - fromY - 8;
|
||||
}
|
||||
@@ -2072,7 +2074,7 @@ int _make_straight_path_func(Object* obj, int from, int to, StraightPathNode* st
|
||||
} else {
|
||||
int middle = ddy - ddx / 2;
|
||||
while (true) {
|
||||
tile = tileFromScreenXY(tileX, tileY, obj->elevation);
|
||||
tile = tileFromScreenXY(tileX, tileY);
|
||||
|
||||
v22 += 1;
|
||||
if (v22 == a6) {
|
||||
@@ -2085,7 +2087,7 @@ int _make_straight_path_func(Object* obj, int from, int to, StraightPathNode* st
|
||||
pathNode->tile = tile;
|
||||
pathNode->elevation = obj->elevation;
|
||||
|
||||
tileToScreenXY(tile, &fromX, &fromY, obj->elevation);
|
||||
tileToScreenXY(tile, &fromX, &fromY);
|
||||
pathNode->x = tileX - fromX - 16;
|
||||
pathNode->y = tileY - fromY - 8;
|
||||
}
|
||||
@@ -2134,7 +2136,7 @@ int _make_straight_path_func(Object* obj, int from, int to, StraightPathNode* st
|
||||
pathNode->tile = tile;
|
||||
pathNode->elevation = obj->elevation;
|
||||
|
||||
tileToScreenXY(tile, &fromX, &fromY, obj->elevation);
|
||||
tileToScreenXY(tile, &fromX, &fromY);
|
||||
pathNode->x = tileX - fromX - 16;
|
||||
pathNode->y = tileY - fromY - 8;
|
||||
}
|
||||
@@ -2199,13 +2201,13 @@ int _make_stair_path(Object* object, int from, int fromElevation, int to, int to
|
||||
|
||||
int fromX;
|
||||
int fromY;
|
||||
tileToScreenXY(from, &fromX, &fromY, fromElevation);
|
||||
tileToScreenXY(from, &fromX, &fromY);
|
||||
fromX += 16;
|
||||
fromY += 8;
|
||||
|
||||
int toX;
|
||||
int toY;
|
||||
tileToScreenXY(to, &toX, &toY, toElevation);
|
||||
tileToScreenXY(to, &toX, &toY);
|
||||
toX += 16;
|
||||
toY += 8;
|
||||
|
||||
@@ -2248,7 +2250,7 @@ int _make_stair_path(Object* object, int from, int fromElevation, int to, int to
|
||||
if (ddx > ddy) {
|
||||
int middle = ddy - ddx / 2;
|
||||
while (true) {
|
||||
tile = tileFromScreenXY(tileX, tileY, elevation);
|
||||
tile = tileFromScreenXY(tileX, tileY);
|
||||
|
||||
iteration += 1;
|
||||
if (iteration == 16) {
|
||||
@@ -2261,7 +2263,7 @@ int _make_stair_path(Object* object, int from, int fromElevation, int to, int to
|
||||
pathNode->tile = tile;
|
||||
pathNode->elevation = elevation;
|
||||
|
||||
tileToScreenXY(tile, &fromX, &fromY, elevation);
|
||||
tileToScreenXY(tile, &fromX, &fromY);
|
||||
pathNode->x = tileX - fromX - 16;
|
||||
pathNode->y = tileY - fromY - 8;
|
||||
}
|
||||
@@ -2295,7 +2297,7 @@ int _make_stair_path(Object* object, int from, int fromElevation, int to, int to
|
||||
} else {
|
||||
int middle = ddx - ddy / 2;
|
||||
while (true) {
|
||||
tile = tileFromScreenXY(tileX, tileY, elevation);
|
||||
tile = tileFromScreenXY(tileX, tileY);
|
||||
|
||||
iteration += 1;
|
||||
if (iteration == 16) {
|
||||
@@ -2308,7 +2310,7 @@ int _make_stair_path(Object* object, int from, int fromElevation, int to, int to
|
||||
pathNode->tile = tile;
|
||||
pathNode->elevation = elevation;
|
||||
|
||||
tileToScreenXY(tile, &fromX, &fromY, elevation);
|
||||
tileToScreenXY(tile, &fromX, &fromY);
|
||||
pathNode->x = tileX - fromX - 16;
|
||||
pathNode->y = tileY - fromY - 8;
|
||||
}
|
||||
@@ -2351,7 +2353,7 @@ int _make_stair_path(Object* object, int from, int fromElevation, int to, int to
|
||||
pathNode->tile = tile;
|
||||
pathNode->elevation = elevation;
|
||||
|
||||
tileToScreenXY(tile, &fromX, &fromY, elevation);
|
||||
tileToScreenXY(tile, &fromX, &fromY);
|
||||
pathNode->x = tileX - fromX - 16;
|
||||
pathNode->y = tileY - fromY - 8;
|
||||
}
|
||||
@@ -2611,7 +2613,7 @@ static void _object_move(int index)
|
||||
}
|
||||
nextTile = -1;
|
||||
} else {
|
||||
_obj_use_door(object, obstacle, 0);
|
||||
objectUseDoor(object, obstacle, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2960,7 +2962,7 @@ int _check_move(int* actionPointsPtr)
|
||||
int y;
|
||||
mouseGetPosition(&x, &y);
|
||||
|
||||
int tile = tileFromScreenXY(x, y, gElevation);
|
||||
int tile = tileFromScreenXY(x, y);
|
||||
if (tile == -1) {
|
||||
return -1;
|
||||
}
|
||||
@@ -3217,7 +3219,7 @@ void _dude_standup(Object* a1)
|
||||
// 0x4185EC
|
||||
static int actionRotate(Object* obj, int delta, int animationSequenceIndex)
|
||||
{
|
||||
if (!_critter_is_prone(obj)) {
|
||||
if (!critterIsProne(obj)) {
|
||||
int rotation = obj->rotation + delta;
|
||||
if (rotation >= ROTATION_COUNT) {
|
||||
rotation = ROTATION_NE;
|
||||
@@ -3291,7 +3293,7 @@ static int _check_gravity(int tile, int elevation)
|
||||
for (; elevation > 0; elevation--) {
|
||||
int x;
|
||||
int y;
|
||||
tileToScreenXY(tile, &x, &y, elevation);
|
||||
tileToScreenXY(tile, &x, &y);
|
||||
|
||||
int squareTile = squareTileFromScreenXY(x + 2, y + 8, elevation);
|
||||
int fid = buildFid(OBJ_TYPE_TILE, _square[elevation]->field_0[squareTile] & 0xFFF, 0, 0, 0);
|
||||
|
||||
+2
-2
@@ -143,8 +143,8 @@ int animationRegisterToggleOutline(Object* object, bool outline, int delay);
|
||||
int animationRegisterPlaySoundEffect(Object* owner, const char* soundEffectName, int delay);
|
||||
int animationRegisterAnimateForever(Object* owner, int anim, int delay);
|
||||
int animationRegisterPing(int flags, int delay);
|
||||
int _make_path(Object* object, int from, int to, unsigned char* a4, int a5);
|
||||
int pathfinderFindPath(Object* object, int from, int to, unsigned char* rotations, int a5, PathBuilderCallback* callback);
|
||||
int _make_path(Object* object, int from, int to, unsigned char* rotations, int requireEmptyDest);
|
||||
int pathfinderFindPath(Object* object, int from, int to, unsigned char* rotations, int requireEmptyDest, PathBuilderCallback* callback);
|
||||
int _make_straight_path(Object* object, int from, int to, StraightPathNode* straightPathNodeList, Object** obstaclePtr, int a6);
|
||||
int _make_straight_path_func(Object* object, int from, int to, StraightPathNode* straightPathNodeList, Object** obstaclePtr, int a6, PathBuilderCallback* callback);
|
||||
void _object_animate();
|
||||
|
||||
+64
-53
@@ -1,5 +1,6 @@
|
||||
#include "art.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -541,72 +542,72 @@ int artCopyFileName(int objectType, int id, char* dest)
|
||||
}
|
||||
|
||||
// 0x419314
|
||||
int _art_get_code(int animation, int weaponType, char* a3, char* a4)
|
||||
int _art_get_code(int animation, int weaponType, char* weaponCodePtr, char* animationCodePtr)
|
||||
{
|
||||
if (weaponType < 0 || weaponType >= WEAPON_ANIMATION_COUNT) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (animation >= ANIM_TAKE_OUT && animation <= ANIM_FIRE_CONTINUOUS) {
|
||||
*a4 = 'c' + (animation - ANIM_TAKE_OUT);
|
||||
*animationCodePtr = 'c' + (animation - ANIM_TAKE_OUT);
|
||||
if (weaponType == WEAPON_ANIMATION_NONE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*a3 = 'd' + (weaponType - 1);
|
||||
*weaponCodePtr = 'd' + (weaponType - 1);
|
||||
return 0;
|
||||
} else if (animation == ANIM_PRONE_TO_STANDING) {
|
||||
*a4 = 'h';
|
||||
*a3 = 'c';
|
||||
*animationCodePtr = 'h';
|
||||
*weaponCodePtr = 'c';
|
||||
return 0;
|
||||
} else if (animation == ANIM_BACK_TO_STANDING) {
|
||||
*a4 = 'j';
|
||||
*a3 = 'c';
|
||||
*animationCodePtr = 'j';
|
||||
*weaponCodePtr = 'c';
|
||||
return 0;
|
||||
} else if (animation == ANIM_CALLED_SHOT_PIC) {
|
||||
*a4 = 'a';
|
||||
*a3 = 'n';
|
||||
*animationCodePtr = 'a';
|
||||
*weaponCodePtr = 'n';
|
||||
return 0;
|
||||
} else if (animation >= FIRST_SF_DEATH_ANIM) {
|
||||
*a4 = 'a' + (animation - FIRST_SF_DEATH_ANIM);
|
||||
*a3 = 'r';
|
||||
*animationCodePtr = 'a' + (animation - FIRST_SF_DEATH_ANIM);
|
||||
*weaponCodePtr = 'r';
|
||||
return 0;
|
||||
} else if (animation >= FIRST_KNOCKDOWN_AND_DEATH_ANIM) {
|
||||
*a4 = 'a' + (animation - FIRST_KNOCKDOWN_AND_DEATH_ANIM);
|
||||
*a3 = 'b';
|
||||
*animationCodePtr = 'a' + (animation - FIRST_KNOCKDOWN_AND_DEATH_ANIM);
|
||||
*weaponCodePtr = 'b';
|
||||
return 0;
|
||||
} else if (animation == ANIM_THROW_ANIM) {
|
||||
if (weaponType == WEAPON_ANIMATION_KNIFE) {
|
||||
// knife
|
||||
*a3 = 'd';
|
||||
*a4 = 'm';
|
||||
*weaponCodePtr = 'd';
|
||||
*animationCodePtr = 'm';
|
||||
} else if (weaponType == WEAPON_ANIMATION_SPEAR) {
|
||||
// spear
|
||||
*a3 = 'g';
|
||||
*a4 = 'm';
|
||||
*weaponCodePtr = 'g';
|
||||
*animationCodePtr = 'm';
|
||||
} else {
|
||||
// other -> probably rock or grenade
|
||||
*a3 = 'a';
|
||||
*a4 = 's';
|
||||
*weaponCodePtr = 'a';
|
||||
*animationCodePtr = 's';
|
||||
}
|
||||
return 0;
|
||||
} else if (animation == ANIM_DODGE_ANIM) {
|
||||
if (weaponType <= 0) {
|
||||
*a3 = 'a';
|
||||
*a4 = 'n';
|
||||
*weaponCodePtr = 'a';
|
||||
*animationCodePtr = 'n';
|
||||
} else {
|
||||
*a3 = 'd' + (weaponType - 1);
|
||||
*a4 = 'e';
|
||||
*weaponCodePtr = 'd' + (weaponType - 1);
|
||||
*animationCodePtr = 'e';
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
*a4 = 'a' + animation;
|
||||
*animationCodePtr = 'a' + animation;
|
||||
if (animation <= ANIM_WALK && weaponType > 0) {
|
||||
*a3 = 'd' + (weaponType - 1);
|
||||
*weaponCodePtr = 'd' + (weaponType - 1);
|
||||
return 0;
|
||||
}
|
||||
*a3 = 'a';
|
||||
*weaponCodePtr = 'a';
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -614,53 +615,51 @@ int _art_get_code(int animation, int weaponType, char* a3, char* a4)
|
||||
// 0x419428
|
||||
char* artBuildFilePath(int fid)
|
||||
{
|
||||
int v1, v2, v3, v4, v5, type, v8, v10;
|
||||
char v9, v11, v12;
|
||||
int baseFid = fid;
|
||||
int rotation = FID_ROTATION(fid);
|
||||
|
||||
v2 = fid;
|
||||
|
||||
v10 = (fid & 0x70000000) >> 28;
|
||||
|
||||
v1 = artAliasFid(fid);
|
||||
if (v1 != -1) {
|
||||
v2 = v1;
|
||||
int aliasFid = artAliasFid(fid);
|
||||
if (aliasFid != -1) {
|
||||
baseFid = aliasFid;
|
||||
}
|
||||
|
||||
*_art_name = '\0';
|
||||
|
||||
v3 = v2 & 0xFFF;
|
||||
v4 = FID_ANIM_TYPE(v2);
|
||||
v5 = (v2 & 0xF000) >> 12;
|
||||
type = FID_TYPE(v2);
|
||||
int frmId = baseFid & 0xFFF;
|
||||
int animType = FID_ANIM_TYPE(baseFid);
|
||||
int weaponCode = (baseFid & 0xF000) >> 12;
|
||||
int objectType = FID_TYPE(baseFid);
|
||||
|
||||
if (type < OBJ_TYPE_ITEM || type >= OBJ_TYPE_COUNT) {
|
||||
if (objectType < OBJ_TYPE_ITEM || objectType >= OBJ_TYPE_COUNT) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (v3 >= gArtListDescriptions[type].fileNamesLength) {
|
||||
if (frmId >= gArtListDescriptions[objectType].fileNamesLength) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
v8 = v3 * 13;
|
||||
int fileNameOffset = frmId * 13;
|
||||
|
||||
if (type == 1) {
|
||||
if (_art_get_code(v4, v5, &v11, &v12) == -1) {
|
||||
if (objectType == OBJ_TYPE_CRITTER) {
|
||||
char critterWeaponCode;
|
||||
char critterAnimationCode;
|
||||
if (_art_get_code(animType, weaponCode, &critterWeaponCode, &critterAnimationCode) == -1) {
|
||||
return nullptr;
|
||||
}
|
||||
if (v10) {
|
||||
snprintf(_art_name, sizeof(_art_name), "%s%s%s\\%s%c%c.fr%c", _cd_path_base, "art\\", gArtListDescriptions[1].name, gArtListDescriptions[1].fileNames + v8, v11, v12, v10 + 47);
|
||||
if (rotation != 0) {
|
||||
snprintf(_art_name, sizeof(_art_name), "%s%s%s\\%s%c%c.fr%c", _cd_path_base, "art\\", gArtListDescriptions[OBJ_TYPE_CRITTER].name, gArtListDescriptions[OBJ_TYPE_CRITTER].fileNames + fileNameOffset, critterWeaponCode, critterAnimationCode, rotation + 47);
|
||||
} else {
|
||||
snprintf(_art_name, sizeof(_art_name), "%s%s%s\\%s%c%c.frm", _cd_path_base, "art\\", gArtListDescriptions[1].name, gArtListDescriptions[1].fileNames + v8, v11, v12);
|
||||
snprintf(_art_name, sizeof(_art_name), "%s%s%s\\%s%c%c.frm", _cd_path_base, "art\\", gArtListDescriptions[OBJ_TYPE_CRITTER].name, gArtListDescriptions[OBJ_TYPE_CRITTER].fileNames + fileNameOffset, critterWeaponCode, critterAnimationCode);
|
||||
}
|
||||
} else if (type == 8) {
|
||||
v9 = _head2[v4];
|
||||
if (v9 == 'f') {
|
||||
snprintf(_art_name, sizeof(_art_name), "%s%s%s\\%s%c%c%d.frm", _cd_path_base, "art\\", gArtListDescriptions[8].name, gArtListDescriptions[8].fileNames + v8, _head1[v4], 102, v5);
|
||||
} else if (objectType == OBJ_TYPE_HEAD) {
|
||||
char headSuffix = _head2[animType];
|
||||
if (headSuffix == 'f') {
|
||||
snprintf(_art_name, sizeof(_art_name), "%s%s%s\\%s%c%c%d.frm", _cd_path_base, "art\\", gArtListDescriptions[OBJ_TYPE_HEAD].name, gArtListDescriptions[OBJ_TYPE_HEAD].fileNames + fileNameOffset, _head1[animType], 102, weaponCode);
|
||||
} else {
|
||||
snprintf(_art_name, sizeof(_art_name), "%s%s%s\\%s%c%c.frm", _cd_path_base, "art\\", gArtListDescriptions[8].name, gArtListDescriptions[8].fileNames + v8, _head1[v4], v9);
|
||||
snprintf(_art_name, sizeof(_art_name), "%s%s%s\\%s%c%c.frm", _cd_path_base, "art\\", gArtListDescriptions[OBJ_TYPE_HEAD].name, gArtListDescriptions[OBJ_TYPE_HEAD].fileNames + fileNameOffset, _head1[animType], headSuffix);
|
||||
}
|
||||
} else {
|
||||
snprintf(_art_name, sizeof(_art_name), "%s%s%s\\%s", _cd_path_base, "art\\", gArtListDescriptions[type].name, gArtListDescriptions[type].fileNames + v8);
|
||||
snprintf(_art_name, sizeof(_art_name), "%s%s%s\\%s", _cd_path_base, "art\\", gArtListDescriptions[objectType].name, gArtListDescriptions[objectType].fileNames + fileNameOffset);
|
||||
}
|
||||
|
||||
return _art_name;
|
||||
@@ -702,8 +701,13 @@ static int artReadList(const char* path, char** artListPtr, int* artListSizePtr)
|
||||
artList[12] = '\0';
|
||||
|
||||
artList += 13;
|
||||
|
||||
count--;
|
||||
}
|
||||
|
||||
// Sanity check. There was a bug with uncompressed database file seek
|
||||
assert(count == 0);
|
||||
|
||||
fileClose(stream);
|
||||
|
||||
return 0;
|
||||
@@ -1006,6 +1010,13 @@ static void artCacheFreeImpl(void* ptr)
|
||||
internal_free(ptr);
|
||||
}
|
||||
|
||||
/* FID Structure:
|
||||
3 bits for rotation
|
||||
4 bits for object type
|
||||
8 bits for animation type
|
||||
4 bits for weapon code
|
||||
12 bits for frame ID
|
||||
*/
|
||||
static int buildFidInternal(unsigned short frmId, unsigned char weaponCode, unsigned char animType, unsigned char objectType, unsigned char rotation)
|
||||
{
|
||||
return ((rotation << 28) & 0x70000000) | (objectType << 24) | ((animType << 16) & 0xFF0000) | ((weaponCode << 12) & 0xF000) | (frmId & 0xFFF);
|
||||
|
||||
@@ -129,8 +129,8 @@ unsigned char* artLockFrameData(int fid, int frame, int direction, CacheEntry**
|
||||
unsigned char* artLockFrameDataReturningSize(int fid, CacheEntry** out_cache_entry, int* widthPtr, int* heightPtr);
|
||||
int artUnlock(CacheEntry* cache_entry);
|
||||
int artCacheFlush();
|
||||
int artCopyFileName(int objectType, int id, char* a3);
|
||||
int _art_get_code(int animation, int weaponType, char* a3, char* a4);
|
||||
int artCopyFileName(int objectType, int id, char* dest);
|
||||
int _art_get_code(int animation, int weaponType, char* weaponCodePtr, char* animationCodePtr);
|
||||
char* artBuildFilePath(int fid);
|
||||
int artGetFramesPerSecond(Art* art);
|
||||
int artGetActionFrame(Art* art);
|
||||
@@ -138,7 +138,7 @@ int artGetFrameCount(Art* art);
|
||||
int artGetWidth(Art* art, int frame, int direction);
|
||||
int artGetHeight(Art* art, int frame, int direction);
|
||||
int artGetSize(Art* art, int frame, int direction, int* out_width, int* out_height);
|
||||
int artGetFrameOffsets(Art* art, int frame, int direction, int* a4, int* a5);
|
||||
int artGetFrameOffsets(Art* art, int frame, int direction, int* xPtr, int* yPtr);
|
||||
int artGetRotationOffsets(Art* art, int rotation, int* out_offset_x, int* out_offset_y);
|
||||
unsigned char* artGetFrameData(Art* art, int frame, int direction);
|
||||
ArtFrame* artGetFrame(Art* art, int frame, int direction);
|
||||
|
||||
+6
-6
@@ -148,7 +148,7 @@ long audioSeek(int handle, long offset, int origin)
|
||||
{
|
||||
int pos;
|
||||
unsigned char* buf;
|
||||
int v10;
|
||||
int remainingBytesToSkip;
|
||||
|
||||
Audio* audioFile = &(gAudioList[handle - 1]);
|
||||
|
||||
@@ -189,14 +189,14 @@ long audioSeek(int handle, long offset, int origin)
|
||||
}
|
||||
} else {
|
||||
buf = (unsigned char*)internal_malloc_safe(1024, __FILE__, __LINE__); // "..\int\audio.c", 321
|
||||
v10 = audioFile->position - pos;
|
||||
while (v10 > 1024) {
|
||||
v10 -= 1024;
|
||||
remainingBytesToSkip = audioFile->position - pos;
|
||||
while (remainingBytesToSkip > 1024) {
|
||||
remainingBytesToSkip -= 1024;
|
||||
audioRead(handle, buf, 1024);
|
||||
}
|
||||
|
||||
if (v10 != 0) {
|
||||
audioRead(handle, buf, v10);
|
||||
if (remainingBytesToSkip != 0) {
|
||||
audioRead(handle, buf, remainingBytesToSkip);
|
||||
}
|
||||
|
||||
// TODO: Probably leaks memory.
|
||||
|
||||
+11
-11
@@ -148,26 +148,26 @@ long audioFileSeek(int handle, long offset, int origin)
|
||||
{
|
||||
void* buf;
|
||||
int remaining;
|
||||
int a4;
|
||||
int targetPosition;
|
||||
|
||||
AudioFile* audioFile = &(gAudioFileList[handle - 1]);
|
||||
|
||||
switch (origin) {
|
||||
case SEEK_SET:
|
||||
a4 = offset;
|
||||
targetPosition = offset;
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
a4 = audioFile->fileSize + offset;
|
||||
targetPosition = audioFile->fileSize + offset;
|
||||
break;
|
||||
case SEEK_END:
|
||||
a4 = audioFile->position + offset;
|
||||
targetPosition = audioFile->position + offset;
|
||||
break;
|
||||
default:
|
||||
assert(false && "Should be unreachable");
|
||||
}
|
||||
|
||||
if ((audioFile->flags & AUDIO_FILE_COMPRESSED) != 0) {
|
||||
if (a4 <= audioFile->position) {
|
||||
if (targetPosition <= audioFile->position) {
|
||||
soundDecoderFree(audioFile->soundDecoder);
|
||||
|
||||
fseek(audioFile->stream, 0, 0);
|
||||
@@ -176,20 +176,20 @@ long audioFileSeek(int handle, long offset, int origin)
|
||||
audioFile->fileSize *= 2;
|
||||
audioFile->position = 0;
|
||||
|
||||
if (a4) {
|
||||
if (targetPosition != 0) {
|
||||
buf = internal_malloc_safe(4096, __FILE__, __LINE__); // "..\int\audiof.c", 364
|
||||
while (a4 > 4096) {
|
||||
while (targetPosition > 4096) {
|
||||
audioFileRead(handle, buf, 4096);
|
||||
a4 -= 4096;
|
||||
targetPosition -= 4096;
|
||||
}
|
||||
if (a4 != 0) {
|
||||
audioFileRead(handle, buf, a4);
|
||||
if (targetPosition != 0) {
|
||||
audioFileRead(handle, buf, targetPosition);
|
||||
}
|
||||
internal_free_safe(buf, __FILE__, __LINE__); // "..\int\audiof.c", 370
|
||||
}
|
||||
} else {
|
||||
buf = internal_malloc_safe(0x400, __FILE__, __LINE__); // "..\int\audiof.c", 316
|
||||
remaining = audioFile->position - a4;
|
||||
remaining = audioFile->position - targetPosition;
|
||||
while (remaining > 1024) {
|
||||
audioFileRead(handle, buf, 1024);
|
||||
remaining -= 1024;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user