Merge branch 'main' into mingw-fixes
This commit is contained in:
commit
39efadcb6b
|
@ -1,6 +1,7 @@
|
||||||
# Force LF
|
# Force LF
|
||||||
*.c text eol=lf
|
*.c text eol=lf
|
||||||
*.cc text eol=lf
|
*.cc text eol=lf
|
||||||
|
*.cmake text eol=lf
|
||||||
*.h text eol=lf
|
*.h text eol=lf
|
||||||
*.md text eol=lf
|
*.md text eol=lf
|
||||||
*.json text eol=lf
|
*.json text eol=lf
|
||||||
|
|
|
@ -4,15 +4,17 @@ on:
|
||||||
push:
|
push:
|
||||||
paths:
|
paths:
|
||||||
- '.github/workflows/Build.yml'
|
- '.github/workflows/Build.yml'
|
||||||
- 'src/**.c'
|
- 'src/**.cc'
|
||||||
- 'src/**.h'
|
- 'src/**.h'
|
||||||
- '**/CMakeLists.txt'
|
- '**/CMakeLists.txt'
|
||||||
|
- '**/*.cmake'
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- '.github/workflows/Build.yml'
|
- '.github/workflows/Build.yml'
|
||||||
- 'src/**.c'
|
- 'src/**.cc'
|
||||||
- 'src/**.h'
|
- 'src/**.h'
|
||||||
- '**/CMakeLists.txt'
|
- '**/CMakeLists.txt'
|
||||||
|
- '**/*.cmake'
|
||||||
|
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
|
@ -20,23 +22,195 @@ defaults:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
Build:
|
StaticAnalysis:
|
||||||
runs-on: windows-latest
|
name: Static analysis
|
||||||
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
|
- name: Install
|
||||||
|
run: |
|
||||||
|
:
|
||||||
|
echo ::group::apt update
|
||||||
|
sudo apt update 2>&1
|
||||||
|
echo ::endgroup::
|
||||||
|
sudo apt install cppcheck
|
||||||
|
|
||||||
- name: Clone
|
- name: Clone
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: cppcheck
|
||||||
|
run: cppcheck --std=c++17 src/
|
||||||
|
|
||||||
|
Build:
|
||||||
|
name: ${{ matrix.cfg.name }} x${{ matrix.cfg.arch }}
|
||||||
|
runs-on: ${{ matrix.cfg.os }}
|
||||||
|
needs: [StaticAnalysis]
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
cfg:
|
||||||
|
#
|
||||||
|
# name .......... overrides job name in GitHub UI
|
||||||
|
# os ............ defines system image; passed to job.<id>.runs-on
|
||||||
|
# cc ............ defines C compiler; passed to CMake configuration step (as `CC` environment variable)
|
||||||
|
# cxx ........... defines C++ compiler; passed to CMake configuration step (as `CXX` environment variable)
|
||||||
|
# ver ........... defines optional suffix to package name when installing compiler with apt, and whenever compiler version is important for build process
|
||||||
|
# cc: gcc, cxx: g++, ver: null --becomes--> sudo apt install gcc g++
|
||||||
|
# cc: gcc, cxx: g++, ver: 10 --becomes--> sudo apt install gcc-10 g++-10
|
||||||
|
# arch .......... defines if building 32bit or 64bit application; used in multiple places to prepare build environment
|
||||||
|
# also used as job name suffix (" x32" or " x64")
|
||||||
|
# generator ..... passed to CMake configuration step (as `-G` switch)
|
||||||
|
# can-fail ...... defines if job status should be set to success even if compilation fails
|
||||||
|
# applies *only* to compilation step; errors in any other steps (installation, preparing build directory, etc.) still mark job as failed
|
||||||
|
# artifact ...... path to compiled application; use "NO" if given job run should not generate any artifacts (case sensitive)
|
||||||
|
# artifact-os ... defines artifact name suffix
|
||||||
|
#
|
||||||
|
- { name: Linux GCC, os: ubuntu-20.04, cc: gcc, cxx: g++, ver: null, arch: 32, generator: "Unix Makefiles", can-fail: false, artifact: Build/fallout2-ce, artifact-os: linux }
|
||||||
|
# { name: Linux GCC, os: ubuntu-22.04, cc: gcc, cxx: g++, ver: null, arch: 64, generator: "Unix Makefiles", can-fail: true, artifact: Build/fallout2-ce, artifact-os: linux }
|
||||||
|
- { name: Linux GCC 10, os: ubuntu-22.04, cc: gcc, cxx: g++, ver: 10, arch: 32, generator: "Unix Makefiles", can-fail: false, artifact: NO, artifact-os: linux }
|
||||||
|
# { name: Linux GCC 10, os: ubuntu-22.04, cc: gcc, cxx: g++, ver: 10, arch: 64, generator: "Unix Makefiles", can-fail: true, artifact: NO, artifact-os: linux }
|
||||||
|
# { name: MacOS 11 CLang, os: macOS-11, cc: clang, cxx: clang++, ver: null, arch: 64, generator: "Unix Makefiles", can-fail: true, artifact: NO, artifact-os: mac }
|
||||||
|
# { name: MacOS 12 CLang, os: macOS-12, cc: clang, cxx: clang++, ver: null, arch: 64, generator: "Unix Makefiles", can-fail: true, artifact: NO, artifact-os: mac }
|
||||||
|
- { name: Windows VS2019, os: windows-2019, cc: cl, cxx: cl, ver: null, arch: 32, generator: "Visual Studio 16 2019", can-fail: false, artifact: NO, artifact-os: windows }
|
||||||
|
# { name: Windows VS2019, os: windows-2019, cc: cl, cxx: cl, ver: null, arch: 64, generator: "Visual Studio 16 2019", can-fail: true, artifact: NO, artifact-os: windows }
|
||||||
|
- { name: Windows VS2022, os: windows-2022, cc: cl, cxx, cl, ver: null, arch: 32, generator: "Visual Studio 17 2022", can-fail: false, artifact: Build/Release/fallout2-ce.exe, artifact-os: windows }
|
||||||
|
# { name: Windows VS2022, os: windows-2022, cc: cl, cxx, cl, ver: null, arch: 64, generator: "Visual Studio 17 2022", can-fail: true, artifact: Build/Release/fallout2-ce.exe, artifact-os: windows }
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Configure
|
||||||
|
run: |
|
||||||
|
: Here be dragons :
|
||||||
|
#set -x
|
||||||
|
arch=${{ matrix.cfg.arch }}
|
||||||
|
ver="${{ matrix.cfg.ver }}"
|
||||||
|
cc="${{ matrix.cfg.cc }}"
|
||||||
|
cxx="${{ matrix.cfg.cxx }}"
|
||||||
|
|
||||||
|
# Variables exported for other steps:
|
||||||
|
#
|
||||||
|
# GHA_PM .................. packages manager executable (might include `sudo`); if not exported, `Install` step is skipped
|
||||||
|
# GHA_PM_COMPILER ......... compiler package(s), including version (if set in matrix)
|
||||||
|
# GHA_PM_COMPILER_EXTRA ... extra compiler packages
|
||||||
|
# GHA_PM_LIBS ............. required libraries packages
|
||||||
|
# GHA_CC .................. C compiler executable, including version (if set in matrix)
|
||||||
|
# GHA_CXX ................. C++ compiler executable, including version (if set in matrix)
|
||||||
|
# GHA_PLATFORM ............ CMake -A ... switch, for configure step
|
||||||
|
# GHA_TOOLCHAIN ........... CMake -DCMAKE_TOOLCHAIN_FILE=... switch, for configure step
|
||||||
|
|
||||||
|
# Compiler executables names
|
||||||
|
[[ "$ver" != "" ]] && verCMAKE="-$ver"
|
||||||
|
echo GHA_CC="$cc$verCMAKE" >> $GITHUB_ENV
|
||||||
|
echo GHA_CXX="$cxx$verCMAKE" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
if [[ $arch -ne 32 ]] && [[ $arch -ne 64 ]]; then
|
||||||
|
echo "[ERROR] matrix.cfg.arch must be set to 32 or 64"
|
||||||
|
exit 1
|
||||||
|
elif [[ "$ver" != "" ]] && ! [[ "$ver" =~ [0-9]+ ]]; then
|
||||||
|
echo "[ERROR] matrix.cfg.ver must be null or number"
|
||||||
|
exit 1
|
||||||
|
elif [[ $RUNNER_OS == "Linux" ]]; then
|
||||||
|
[[ "$ver" != "" ]] && verPM="-$ver"
|
||||||
|
|
||||||
|
echo GHA_PM="sudo apt" >> $GITHUB_ENV
|
||||||
|
apt="amd64"
|
||||||
|
|
||||||
|
if [[ "$cc" == "clang" ]] && [[ "$cxx" == "clang++" ]]; then
|
||||||
|
echo GHA_PM_COMPILER="$cc$verPM" >> $GITHUB_ENV
|
||||||
|
else
|
||||||
|
echo GHA_PM_COMPILER="$cc$verPM $cxx$verPM" >> $GITHUB_ENV
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Handle building 32bit executable on 64bit host
|
||||||
|
if [[ $arch -eq 32 ]]; then
|
||||||
|
apt="i386"
|
||||||
|
sudo dpkg --add-architecture $apt
|
||||||
|
|
||||||
|
# Extra packages
|
||||||
|
echo GHA_PM_COMPILER_EXTRA="gcc${verPM}-multilib g++${verPM}-multilib" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
# Toolchain file; without proper 32@64 toolchain setup CMake can't find OpenGL libraries
|
||||||
|
echo GHA_TOOLCHAIN="-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain/Linux32.cmake" >> $GITHUB_ENV
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo GHA_PM_LIBS="libsdl2-dev:$apt zlib1g-dev:$apt" >> $GITHUB_ENV
|
||||||
|
elif [[ $RUNNER_OS == "macOS" ]]; then
|
||||||
|
[[ "$ver" != "" ]] && verPM="@$ver"
|
||||||
|
echo GHA_PM="brew" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
if [[ "$cc" == "gcc" ]] && [[ "$cxx" == "g++" ]]; then
|
||||||
|
echo GHA_PM_COMPILER="$cc$verPM" >> $GITHUB_ENV
|
||||||
|
elif [[ "$cc" == "clang" ]] && [[ "$cxx" == "clang++" ]]; then
|
||||||
|
echo GHA_PM_COMPILER="llvm$verPM" >> $GITHUB_ENV
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo GHA_PM_LIBS="sdl2" >> $GITHUB_ENV
|
||||||
|
elif [[ $RUNNER_OS == "Windows" ]]; then
|
||||||
|
# VisualStudio; '-A' switch is used to compile 32bit targets on 64bit hosts
|
||||||
|
if [[ "${{ matrix.cfg.generator }}" =~ ^Visual ]]; then
|
||||||
|
if [[ $arch -eq 32 ]]; then
|
||||||
|
echo GHA_PLATFORM="-A Win32" >> $GITHUB_ENV
|
||||||
|
else
|
||||||
|
echo GHA_PLATFORM="-A x64" >> $GITHUB_ENV
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Install
|
||||||
|
if: env.GHA_PM != ''
|
||||||
|
run: |
|
||||||
|
:
|
||||||
|
#set -x
|
||||||
|
|
||||||
|
echo ::group::Update package manager
|
||||||
|
$GHA_PM update 2>&1
|
||||||
|
echo ::endgroup::
|
||||||
|
|
||||||
|
if [[ ${{ matrix.cfg.arch }} -eq 32 ]] && ([[ "$ImageOS" == "ubuntu20" ]] || [[ "${{ matrix.cfg.os }}" == "ubuntu-20.04" ]]); then
|
||||||
|
echo ::group::Fix Ubuntu 20
|
||||||
|
$GHA_PM install --allow-downgrades libpcre2-8-0=10.34-7
|
||||||
|
echo ::endgroup::
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$GHA_PM_COMPILER" != "" ]] || [[ "$GHA_PM_COMPILER_EXTRA" ]]; then
|
||||||
|
echo ::group::Compiler
|
||||||
|
$GHA_PM install $GHA_PM_COMPILER $GHA_PM_COMPILER_EXTRA
|
||||||
|
echo ::endgroup::
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$GHA_PM_LIBS" != "" ]]; then
|
||||||
|
echo ::group::Libraries
|
||||||
|
$GHA_PM install $GHA_PM_LIBS
|
||||||
|
echo :endgroup::
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Clone
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
# Using ${{ env.NAME }} here (instead of usual $NAME) to make full command line clearly displayed, without need to check step environment first
|
||||||
- name: Prepare
|
- name: Prepare
|
||||||
run: cmake -B Build -A Win32
|
run: cmake -B Build -G "${{ matrix.cfg.generator }}" ${{ env.GHA_PLATFORM }} ${{ env.GHA_TOOLCHAIN }} 2>&1
|
||||||
|
env:
|
||||||
|
CC: ${{ env.GHA_CC }}
|
||||||
|
CXX: ${{ env.GHA_CXX }}
|
||||||
|
|
||||||
- name: Release build
|
- name: Build
|
||||||
run: cmake --build Build --config Release
|
run: cmake --build Build --config Release && echo BUILD_OK=1 >> $GITHUB_ENV
|
||||||
|
continue-on-error: ${{ matrix.cfg.can-fail }}
|
||||||
|
|
||||||
- name: Artifact
|
- name: Artifact prepare
|
||||||
|
if: matrix.cfg.artifact != 'NO' && env.BUILD_OK == 1
|
||||||
|
run: |
|
||||||
|
:
|
||||||
|
echo BUILD_OK=0 >> $GITHUB_ENV
|
||||||
|
dir="${{ matrix.cfg.artifact-os }}/x${{ matrix.cfg.arch }}"
|
||||||
|
mkdir -p "$dir"
|
||||||
|
cp "${{ matrix.cfg.artifact }}" "$dir"
|
||||||
|
echo BUILD_OK=1 >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Artifact upload
|
||||||
|
if: matrix.cfg.artifact != 'NO' && env.BUILD_OK == 1
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: fallout2-ce
|
name: fallout2-ce-${{ matrix.cfg.artifact-os }}
|
||||||
path: |
|
path: "${{ matrix.cfg.artifact-os }}/x${{ matrix.cfg.arch }}"
|
||||||
Build/*/fallout2-ce.exe
|
|
||||||
retention-days: 7
|
retention-days: 7
|
||||||
|
|
|
@ -247,6 +247,11 @@ if(WIN32)
|
||||||
_CRT_SECURE_NO_WARNINGS
|
_CRT_SECURE_NO_WARNINGS
|
||||||
_CRT_NONSTDC_NO_WARNINGS
|
_CRT_NONSTDC_NO_WARNINGS
|
||||||
)
|
)
|
||||||
|
else()
|
||||||
|
target_compile_definitions(${EXECUTABLE_NAME} PRIVATE
|
||||||
|
$<$<CONFIG:Debug>:_DEBUG>
|
||||||
|
$<$<CONFIG:RelWithDebInfo>:_DEBUG>
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
|
@ -259,7 +264,7 @@ add_subdirectory("third_party/fpattern")
|
||||||
target_link_libraries(${EXECUTABLE_NAME} ${FPATTERN_LIBRARY})
|
target_link_libraries(${EXECUTABLE_NAME} ${FPATTERN_LIBRARY})
|
||||||
target_include_directories(${EXECUTABLE_NAME} PRIVATE ${FPATTERN_INCLUDE_DIR})
|
target_include_directories(${EXECUTABLE_NAME} PRIVATE ${FPATTERN_INCLUDE_DIR})
|
||||||
|
|
||||||
if(NOT APPLE)
|
if(NOT APPLE AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||||
add_subdirectory("third_party/zlib")
|
add_subdirectory("third_party/zlib")
|
||||||
add_subdirectory("third_party/sdl2")
|
add_subdirectory("third_party/sdl2")
|
||||||
else()
|
else()
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
set( CMAKE_SYSTEM_NAME "Linux" )
|
||||||
|
set( CMAKE_SYSTEM_PROCESSOR "i386" )
|
||||||
|
set( CMAKE_C_FLAGS "-m32" )
|
||||||
|
set( CMAKE_CXX_FLAGS "-m32" )
|
|
@ -40,8 +40,8 @@ int _action_in_explode = 0;
|
||||||
const int gNormalDeathAnimations[DAMAGE_TYPE_COUNT] = {
|
const int gNormalDeathAnimations[DAMAGE_TYPE_COUNT] = {
|
||||||
ANIM_DANCING_AUTOFIRE,
|
ANIM_DANCING_AUTOFIRE,
|
||||||
ANIM_SLICED_IN_HALF,
|
ANIM_SLICED_IN_HALF,
|
||||||
ANIM_CHUNKS_OF_FLESH,
|
ANIM_CHARRED_BODY,
|
||||||
ANIM_CHUNKS_OF_FLESH,
|
ANIM_CHARRED_BODY,
|
||||||
ANIM_ELECTRIFY,
|
ANIM_ELECTRIFY,
|
||||||
ANIM_FALL_BACK,
|
ANIM_FALL_BACK,
|
||||||
ANIM_BIG_HOLE,
|
ANIM_BIG_HOLE,
|
||||||
|
@ -1454,7 +1454,7 @@ int _pick_fall(Object* obj, int anim)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (anim == ANIM_FALL_BACK) {
|
} else if (anim == ANIM_FALL_BACK) {
|
||||||
rotation = (obj->rotation + 3) % 6u;
|
rotation = (obj->rotation + 3) % ROTATION_COUNT;
|
||||||
for (i = 1; i < 3; i++) {
|
for (i = 1; i < 3; i++) {
|
||||||
tile_num = tileGetTileInDirection(obj->tile, rotation, i);
|
tile_num = tileGetTileInDirection(obj->tile, rotation, i);
|
||||||
if (_obj_blocking_at(obj, tile_num, obj->elevation) != NULL) {
|
if (_obj_blocking_at(obj, tile_num, obj->elevation) != NULL) {
|
||||||
|
@ -1725,7 +1725,7 @@ int _compute_explosion_damage(int min, int max, Object* a3, int* a4)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a4 != NULL) {
|
if (a4 != NULL) {
|
||||||
if ((a3->flags & OBJECT_FLAG_0x800) == 0) {
|
if ((a3->flags & OBJECT_MULTIHEX) == 0) {
|
||||||
*a4 = v7 / 10;
|
*a4 = v7 / 10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1892,7 +1892,7 @@ int _compute_dmg_damage(int min, int max, Object* obj, int* a4, int damageType)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a4 != NULL) {
|
if (a4 != NULL) {
|
||||||
if ((obj->flags & OBJECT_FLAG_0x800) == 0 && damageType != DAMAGE_TYPE_ELECTRICAL) {
|
if ((obj->flags & OBJECT_MULTIHEX) == 0 && damageType != DAMAGE_TYPE_ELECTRICAL) {
|
||||||
*a4 = v10 / 10;
|
*a4 = v10 / 10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1682,7 +1682,7 @@ int _make_straight_path_func(Object* a1, int from, int to, STRUCT_530014_28* a4,
|
||||||
if (a5 != NULL) {
|
if (a5 != NULL) {
|
||||||
Object* v11 = a7(a1, from, a1->elevation);
|
Object* v11 = a7(a1, from, a1->elevation);
|
||||||
if (v11 != NULL) {
|
if (v11 != NULL) {
|
||||||
if (v11 != *a5 && (a6 != 32 || (v11->flags & OBJECT_FLAG_0x80000000) == 0)) {
|
if (v11 != *a5 && (a6 != 32 || (v11->flags & OBJECT_SHOOT_THRU) == 0)) {
|
||||||
*a5 = v11;
|
*a5 = v11;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1726,7 +1726,7 @@ int _make_straight_path_func(Object* a1, int from, int to, STRUCT_530014_28* a4,
|
||||||
int tileY = fromY;
|
int tileY = fromY;
|
||||||
|
|
||||||
int pathNodeIndex = 0;
|
int pathNodeIndex = 0;
|
||||||
int v50 = from;
|
int prevTile = from;
|
||||||
int v22 = 0;
|
int v22 = 0;
|
||||||
int tile;
|
int tile;
|
||||||
|
|
||||||
|
@ -1770,17 +1770,17 @@ int _make_straight_path_func(Object* a1, int from, int to, STRUCT_530014_28* a4,
|
||||||
tileY += stepY;
|
tileY += stepY;
|
||||||
middle += v48;
|
middle += v48;
|
||||||
|
|
||||||
if (tile != v50) {
|
if (tile != prevTile) {
|
||||||
if (a5 != NULL) {
|
if (a5 != NULL) {
|
||||||
Object* obj = a7(a1, tile, a1->elevation);
|
Object* obj = a7(a1, tile, a1->elevation);
|
||||||
if (obj != NULL) {
|
if (obj != NULL) {
|
||||||
if (obj != *a5 && (a6 != 32 || (obj->flags & OBJECT_FLAG_0x80000000) == 0)) {
|
if (obj != *a5 && (a6 != 32 || (obj->flags & OBJECT_SHOOT_THRU) == 0)) {
|
||||||
*a5 = obj;
|
*a5 = obj;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
v50 = tile;
|
prevTile = tile;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1823,16 +1823,17 @@ int _make_straight_path_func(Object* a1, int from, int to, STRUCT_530014_28* a4,
|
||||||
tileX += stepX;
|
tileX += stepX;
|
||||||
middle += v47;
|
middle += v47;
|
||||||
|
|
||||||
if (tile != v50) {
|
if (tile != prevTile) {
|
||||||
if (a5 != NULL) {
|
if (a5 != NULL) {
|
||||||
Object* obj = a7(a1, tile, a1->elevation);
|
Object* obj = a7(a1, tile, a1->elevation);
|
||||||
if (obj != NULL) {
|
if (obj != NULL) {
|
||||||
if (obj != *a5 && (a6 != 32 || (obj->flags & OBJECT_FLAG_0x80000000) == 0)) {
|
if (obj != *a5 && (a6 != 32 || (obj->flags & OBJECT_SHOOT_THRU) == 0)) {
|
||||||
*a5 = obj;
|
*a5 = obj;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
prevTile = tile;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1863,38 +1864,35 @@ int _make_straight_path_func(Object* a1, int from, int to, STRUCT_530014_28* a4,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x4167F8
|
// 0x4167F8
|
||||||
int animateMoveObjectToObject(Object* a1, Object* a2, int a3, int anim, int animationSequenceIndex)
|
int animateMoveObjectToObject(Object* from, Object* to, int a3, int anim, int animationSequenceIndex)
|
||||||
{
|
{
|
||||||
int v10;
|
bool hidden = (to->flags & OBJECT_HIDDEN);
|
||||||
int v13;
|
to->flags |= OBJECT_HIDDEN;
|
||||||
STRUCT_530014* ptr;
|
|
||||||
|
|
||||||
int hidden = (a2->flags & OBJECT_HIDDEN);
|
int moveSadIndex = _anim_move(from, to->tile, to->elevation, -1, anim, 0, animationSequenceIndex);
|
||||||
a2->flags |= OBJECT_HIDDEN;
|
|
||||||
|
|
||||||
v10 = _anim_move(a1, a2->tile, a2->elevation, -1, anim, 0, animationSequenceIndex);
|
if (!hidden) {
|
||||||
|
to->flags &= ~OBJECT_HIDDEN;
|
||||||
if (hidden == 0) {
|
|
||||||
a2->flags &= ~OBJECT_HIDDEN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v10 == -1) {
|
if (moveSadIndex == -1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr = &(_sad[v10]);
|
STRUCT_530014* ptr = &(_sad[moveSadIndex]);
|
||||||
v13 = (((a1->flags & OBJECT_FLAG_0x800) != 0) + 1); // TODO: What the hell is this?
|
// NOTE: Original code is somewhat different. Due to some kind of
|
||||||
ptr->field_1C -= v13;
|
// optimization this value is either 1 or 2, which is later used in
|
||||||
|
// subsequent calculations and rotations array lookup.
|
||||||
|
bool isMultihex = (from->flags & OBJECT_MULTIHEX);
|
||||||
|
ptr->field_1C -= (isMultihex ? 2 : 1);
|
||||||
if (ptr->field_1C <= 0) {
|
if (ptr->field_1C <= 0) {
|
||||||
ptr->field_20 = -1000;
|
ptr->field_20 = -1000;
|
||||||
_anim_set_continue(animationSequenceIndex, 0);
|
_anim_set_continue(animationSequenceIndex, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v13) {
|
ptr->field_24 = tileGetTileInDirection(to->tile, ptr->rotations[isMultihex ? ptr->field_1C + 1 : ptr->field_1C], 1);
|
||||||
ptr->field_24 = tileGetTileInDirection(a2->tile, ptr->field_24 + v13 + ptr->field_1C + 3, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (v13 == 2) {
|
if (isMultihex) {
|
||||||
ptr->field_24 = tileGetTileInDirection(ptr->field_24, ptr->rotations[ptr->field_1C], 1);
|
ptr->field_24 = tileGetTileInDirection(ptr->field_24, ptr->rotations[ptr->field_1C], 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -257,15 +257,15 @@ int _idist(int a1, int a2, int a3, int a4);
|
||||||
int _tile_idistance(int tile1, int tile2);
|
int _tile_idistance(int tile1, int tile2);
|
||||||
int _make_straight_path(Object* a1, int from, int to, STRUCT_530014_28* pathNodes, Object** a5, int a6);
|
int _make_straight_path(Object* a1, int from, int to, STRUCT_530014_28* pathNodes, Object** a5, int a6);
|
||||||
int _make_straight_path_func(Object* a1, int from, int to, STRUCT_530014_28* a4, Object** a5, int a6, Object* (*a7)(Object*, int, int));
|
int _make_straight_path_func(Object* a1, int from, int to, STRUCT_530014_28* a4, Object** a5, int a6, Object* (*a7)(Object*, int, int));
|
||||||
int animateMoveObjectToObject(Object* a1, Object* a2, int a3, int a4, int a5);
|
int animateMoveObjectToObject(Object* from, Object* to, int a3, int anim, int animationSequenceIndex);
|
||||||
int animateMoveObjectToTile(Object* obj, int tile_num, int elev, int a4, int a5, int a6);
|
int animateMoveObjectToTile(Object* obj, int tile_num, int elev, int a4, int anim, int animationSequenceIndex);
|
||||||
int _anim_move(Object* obj, int tile, int elev, int a3, int a4, int a5, int animationSequenceIndex);
|
int _anim_move(Object* obj, int tile, int elev, int a3, int anim, int a5, int animationSequenceIndex);
|
||||||
int _anim_move_straight_to_tile(Object* obj, int a2, int a3, int fid, int a5, int a6);
|
int _anim_move_straight_to_tile(Object* obj, int tile, int elevation, int anim, int animationSequenceIndex, int flags);
|
||||||
int _anim_move_on_stairs(Object* obj, int a2, int a3, int fid, int a5);
|
int _anim_move_on_stairs(Object* obj, int tile, int elevation, int anim, int animationSequenceIndex);
|
||||||
int _check_for_falling(Object* obj, int a2, int a3);
|
int _check_for_falling(Object* obj, int anim, int a3);
|
||||||
void _object_move(int index);
|
void _object_move(int index);
|
||||||
void _object_straight_move(int a1);
|
void _object_straight_move(int index);
|
||||||
int _anim_animate(Object* obj, int a2, int a3, int a4);
|
int _anim_animate(Object* obj, int anim, int animationSequenceIndex, int flags);
|
||||||
void _object_animate();
|
void _object_animate();
|
||||||
void _object_anim_compact();
|
void _object_anim_compact();
|
||||||
int _check_move(int* a1);
|
int _check_move(int* a1);
|
||||||
|
@ -274,8 +274,8 @@ int _dude_run(int a1);
|
||||||
void _dude_fidget();
|
void _dude_fidget();
|
||||||
void _dude_stand(Object* obj, int rotation, int fid);
|
void _dude_stand(Object* obj, int rotation, int fid);
|
||||||
void _dude_standup(Object* a1);
|
void _dude_standup(Object* a1);
|
||||||
int actionRotate(Object* obj, int a2, int a3);
|
int actionRotate(Object* obj, int delta, int animationSequenceIndex);
|
||||||
int _anim_change_fid(Object* obj, int a2, int fid);
|
int _anim_change_fid(Object* obj, int animationSequenceIndex, int fid);
|
||||||
void _anim_stop();
|
void _anim_stop();
|
||||||
int _check_gravity(int tile, int elevation);
|
int _check_gravity(int tile, int elevation);
|
||||||
unsigned int _compute_tpf(Object* object, int fid);
|
unsigned int _compute_tpf(Object* object, int fid);
|
||||||
|
|
46
src/art.cc
46
src/art.cc
|
@ -7,11 +7,24 @@
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "object.h"
|
#include "object.h"
|
||||||
#include "proto.h"
|
#include "proto.h"
|
||||||
|
#include "sfall_config.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
// 0x5002D8
|
||||||
|
char gDefaultJumpsuitMaleFileName[] = "hmjmps";
|
||||||
|
|
||||||
|
// 0x05002E0
|
||||||
|
char gDefaultJumpsuitFemaleFileName[] = "hfjmps";
|
||||||
|
|
||||||
|
// 0x5002E8
|
||||||
|
char gDefaultTribalMaleFileName[] = "hmwarr";
|
||||||
|
|
||||||
|
// 0x5002F0
|
||||||
|
char gDefaultTribalFemaleFileName[] = "hfprim";
|
||||||
|
|
||||||
// 0x510738
|
// 0x510738
|
||||||
ArtListDescription gArtListDescriptions[OBJ_TYPE_COUNT] = {
|
ArtListDescription gArtListDescriptions[OBJ_TYPE_COUNT] = {
|
||||||
{ 0, "items", 0, 0, 0 },
|
{ 0, "items", 0, 0, 0 },
|
||||||
|
@ -153,18 +166,43 @@ int artInit()
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SFALL: Modify player model settings.
|
||||||
|
char* jumpsuitMaleFileName = NULL;
|
||||||
|
configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_DUDE_NATIVE_LOOK_JUMPSUIT_MALE_KEY, &jumpsuitMaleFileName);
|
||||||
|
if (jumpsuitMaleFileName == NULL || jumpsuitMaleFileName[0] == '\0') {
|
||||||
|
jumpsuitMaleFileName = gDefaultJumpsuitMaleFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* jumpsuitFemaleFileName = NULL;
|
||||||
|
configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_DUDE_NATIVE_LOOK_JUMPSUIT_FEMALE_KEY, &jumpsuitFemaleFileName);
|
||||||
|
if (jumpsuitFemaleFileName == NULL || jumpsuitFemaleFileName[0] == '\0') {
|
||||||
|
jumpsuitFemaleFileName = gDefaultJumpsuitFemaleFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* tribalMaleFileName = NULL;
|
||||||
|
configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_DUDE_NATIVE_LOOK_TRIBAL_MALE_KEY, &tribalMaleFileName);
|
||||||
|
if (tribalMaleFileName == NULL || tribalMaleFileName[0] == '\0') {
|
||||||
|
tribalMaleFileName = gDefaultTribalMaleFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *tribalFemaleFileName = NULL;
|
||||||
|
configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_DUDE_NATIVE_LOOK_TRIBAL_FEMALE_KEY, &tribalFemaleFileName);
|
||||||
|
if (tribalFemaleFileName == NULL || tribalFemaleFileName[0] == '\0') {
|
||||||
|
tribalFemaleFileName = gDefaultTribalFemaleFileName;
|
||||||
|
}
|
||||||
|
|
||||||
ptr = gArtListDescriptions[1].fileNames;
|
ptr = gArtListDescriptions[1].fileNames;
|
||||||
for (i = 0; i < gArtListDescriptions[1].fileNamesLength; i++) {
|
for (i = 0; i < gArtListDescriptions[1].fileNamesLength; i++) {
|
||||||
if (compat_stricmp(ptr, "hmjmps") == 0) {
|
if (compat_stricmp(ptr, jumpsuitMaleFileName) == 0) {
|
||||||
_art_vault_person_nums[DUDE_NATIVE_LOOK_JUMPSUIT][GENDER_MALE] = i;
|
_art_vault_person_nums[DUDE_NATIVE_LOOK_JUMPSUIT][GENDER_MALE] = i;
|
||||||
} else if (compat_stricmp(ptr, "hfjmps") == 0) {
|
} else if (compat_stricmp(ptr, jumpsuitFemaleFileName) == 0) {
|
||||||
_art_vault_person_nums[DUDE_NATIVE_LOOK_JUMPSUIT][GENDER_FEMALE] = i;
|
_art_vault_person_nums[DUDE_NATIVE_LOOK_JUMPSUIT][GENDER_FEMALE] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compat_stricmp(ptr, "hmwarr") == 0) {
|
if (compat_stricmp(ptr, tribalMaleFileName) == 0) {
|
||||||
_art_vault_person_nums[DUDE_NATIVE_LOOK_TRIBAL][GENDER_MALE] = i;
|
_art_vault_person_nums[DUDE_NATIVE_LOOK_TRIBAL][GENDER_MALE] = i;
|
||||||
_art_vault_guy_num = i;
|
_art_vault_guy_num = i;
|
||||||
} else if (compat_stricmp(ptr, "hfprim") == 0) {
|
} else if (compat_stricmp(ptr, tribalFemaleFileName) == 0) {
|
||||||
_art_vault_person_nums[DUDE_NATIVE_LOOK_TRIBAL][GENDER_FEMALE] = i;
|
_art_vault_person_nums[DUDE_NATIVE_LOOK_TRIBAL][GENDER_FEMALE] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -124,6 +124,11 @@ typedef enum DudeNativeLook {
|
||||||
DUDE_NATIVE_LOOK_COUNT,
|
DUDE_NATIVE_LOOK_COUNT,
|
||||||
} DudeNativeLook;
|
} DudeNativeLook;
|
||||||
|
|
||||||
|
extern char gDefaultJumpsuitMaleFileName[];
|
||||||
|
extern char gDefaultJumpsuitFemaleFileName[];
|
||||||
|
extern char gDefaultTribalMaleFileName[];
|
||||||
|
extern char gDefaultTribalFemaleFileName[];
|
||||||
|
|
||||||
extern ArtListDescription gArtListDescriptions[OBJ_TYPE_COUNT];
|
extern ArtListDescription gArtListDescriptions[OBJ_TYPE_COUNT];
|
||||||
extern bool gArtLanguageInitialized;
|
extern bool gArtLanguageInitialized;
|
||||||
extern const char* _head1;
|
extern const char* _head1;
|
||||||
|
|
|
@ -458,7 +458,7 @@ void automapRenderInMapWindow(int window, int elevation, unsigned char* backgrou
|
||||||
&& (object->data.critter.combat.results & DAM_DEAD) == 0) {
|
&& (object->data.critter.combat.results & DAM_DEAD) == 0) {
|
||||||
objectColor = _colorTable[31744];
|
objectColor = _colorTable[31744];
|
||||||
} else {
|
} else {
|
||||||
if ((object->flags & OBJECT_FLAG_0x40000000) == 0) {
|
if ((object->flags & OBJECT_SEEN) == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1011,7 +1011,7 @@ void _decode_map_data(int elevation)
|
||||||
|
|
||||||
Object* object = objectFindFirstAtElevation(elevation);
|
Object* object = objectFindFirstAtElevation(elevation);
|
||||||
while (object != NULL) {
|
while (object != NULL) {
|
||||||
if (object->tile != -1 && (object->flags & OBJECT_FLAG_0x40000000) != 0) {
|
if (object->tile != -1 && (object->flags & OBJECT_SEEN) != 0) {
|
||||||
int contentType;
|
int contentType;
|
||||||
|
|
||||||
int objectType = (object->fid & 0xF000000) >> 24;
|
int objectType = (object->fid & 0xF000000) >> 24;
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdlib.h> // qsort
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -126,10 +126,12 @@ typedef struct TownReputationEntry {
|
||||||
int city;
|
int city;
|
||||||
} TownReputationEntry;
|
} TownReputationEntry;
|
||||||
|
|
||||||
typedef struct STRUCT_56FCB0 {
|
typedef struct PerkDialogOption {
|
||||||
int field_0;
|
// Depending on the current mode this value is the id of either
|
||||||
char* field_4;
|
// perk, trait (handling Mutate perk), or skill (handling Tag perk).
|
||||||
} STRUCT_56FCB0;
|
int value;
|
||||||
|
char* name;
|
||||||
|
} PerkDialogOption;
|
||||||
|
|
||||||
// TODO: Field order is probably wrong.
|
// TODO: Field order is probably wrong.
|
||||||
typedef struct KillInfo {
|
typedef struct KillInfo {
|
||||||
|
@ -138,11 +140,11 @@ typedef struct KillInfo {
|
||||||
int kills;
|
int kills;
|
||||||
} KillInfo;
|
} KillInfo;
|
||||||
|
|
||||||
extern int _grph_id[50];
|
extern int gCharacterEditorFrmIds[50];
|
||||||
extern const unsigned char _copyflag[EDITOR_GRAPHIC_COUNT];
|
extern const unsigned char gCharacterEditorFrmShouldCopy[EDITOR_GRAPHIC_COUNT];
|
||||||
extern const int word_431D3A[EDITOR_DERIVED_STAT_COUNT];
|
extern const int gCharacterEditorDerivedStatFrmIds[EDITOR_DERIVED_STAT_COUNT];
|
||||||
extern const int _StatYpos[7];
|
extern const int gCharacterEditorPrimaryStatY[7];
|
||||||
extern const int word_431D6C[EDITOR_DERIVED_STAT_COUNT];
|
extern const int gCharacterEditorDerivedStatsMap[EDITOR_DERIVED_STAT_COUNT];
|
||||||
extern char byte_431D93[64];
|
extern char byte_431D93[64];
|
||||||
extern const int dword_431DD4[7];
|
extern const int dword_431DD4[7];
|
||||||
|
|
||||||
|
@ -151,10 +153,10 @@ extern const double dbl_501713;
|
||||||
extern const double dbl_5018F0;
|
extern const double dbl_5018F0;
|
||||||
extern const double dbl_5019BE;
|
extern const double dbl_5019BE;
|
||||||
|
|
||||||
extern bool _bk_enable_0;
|
extern bool gCharacterEditorIsoWasEnabled;
|
||||||
extern int _skill_cursor;
|
extern int gCharacterEditorCurrentSkill;
|
||||||
extern int _slider_y;
|
extern int gCharacterEditorSkillValueAdjustmentSliderY;
|
||||||
extern int characterEditorRemainingCharacterPoints;
|
extern int gCharacterEditorRemainingCharacterPoints;
|
||||||
extern KarmaEntry* gKarmaEntries;
|
extern KarmaEntry* gKarmaEntries;
|
||||||
extern int gKarmaEntriesLength;
|
extern int gKarmaEntriesLength;
|
||||||
extern GenericReputationEntry* gGenericReputationEntries;
|
extern GenericReputationEntry* gGenericReputationEntries;
|
||||||
|
@ -162,148 +164,148 @@ extern int gGenericReputationEntriesLength;
|
||||||
extern const TownReputationEntry gTownReputationEntries[TOWN_REPUTATION_COUNT];
|
extern const TownReputationEntry gTownReputationEntries[TOWN_REPUTATION_COUNT];
|
||||||
extern const int gAddictionReputationVars[ADDICTION_REPUTATION_COUNT];
|
extern const int gAddictionReputationVars[ADDICTION_REPUTATION_COUNT];
|
||||||
extern const int gAddictionReputationFrmIds[ADDICTION_REPUTATION_COUNT];
|
extern const int gAddictionReputationFrmIds[ADDICTION_REPUTATION_COUNT];
|
||||||
extern int _folder_up_button;
|
extern int gCharacterEditorFolderViewScrollUpBtn;
|
||||||
extern int _folder_down_button;
|
extern int gCharacterEditorFolderViewScrollDownBtn;
|
||||||
|
|
||||||
extern char _folder_card_string[256];
|
extern char gCharacterEditorFolderCardString[256];
|
||||||
extern int _skillsav[SKILL_COUNT];
|
extern int gCharacterEditorSkillsBackup[SKILL_COUNT];
|
||||||
extern MessageList editorMessageList;
|
extern MessageList gCharacterEditorMessageList;
|
||||||
extern STRUCT_56FCB0 _name_sort_list[DIALOG_PICKER_NUM_OPTIONS];
|
extern PerkDialogOption gPerkDialogOptionList[DIALOG_PICKER_NUM_OPTIONS];
|
||||||
extern int _trait_bids[TRAIT_COUNT];
|
extern int gCharacterEditorOptionalTraitBtns[TRAIT_COUNT];
|
||||||
extern MessageListItem editorMessageListItem;
|
extern MessageListItem gCharacterEditorMessageListItem;
|
||||||
extern char _old_str1[48];
|
extern char gCharacterEditorCardTitle[48];
|
||||||
extern char _old_str2[48];
|
extern char gPerkDialogCardTitle[48];
|
||||||
extern int _tag_bids[SKILL_COUNT];
|
extern int gCharacterEditorTagSkillBtns[SKILL_COUNT];
|
||||||
extern char _name_save[32];
|
extern char gCharacterEditorNameBackup[32];
|
||||||
extern Size _GInfo[EDITOR_GRAPHIC_COUNT];
|
extern Size gCharacterEditorFrmSize[EDITOR_GRAPHIC_COUNT];
|
||||||
extern CacheEntry* _grph_key[EDITOR_GRAPHIC_COUNT];
|
extern CacheEntry* gCharacterEditorFrmHandle[EDITOR_GRAPHIC_COUNT];
|
||||||
extern unsigned char* _grphcpy[EDITOR_GRAPHIC_COUNT];
|
extern unsigned char* gCharacterEditorFrmCopy[EDITOR_GRAPHIC_COUNT];
|
||||||
extern unsigned char* _grphbmp[EDITOR_GRAPHIC_COUNT];
|
extern unsigned char* gCharacterEditorFrmData[EDITOR_GRAPHIC_COUNT];
|
||||||
extern int _folder_max_lines;
|
extern int gCharacterEditorFolderViewMaxLines;
|
||||||
extern int _folder_line;
|
extern int gCharacterEditorFolderViewCurrentLine;
|
||||||
extern int _folder_card_fid;
|
extern int gCharacterEditorFolderCardFrmId;
|
||||||
extern int _folder_top_line;
|
extern int gCharacterEditorFolderViewTopLine;
|
||||||
extern char* _folder_card_title;
|
extern char* gCharacterEditorFolderCardTitle;
|
||||||
extern char* _folder_card_title2;
|
extern char* gCharacterEditorFolderCardSubtitle;
|
||||||
extern int _folder_yoffset;
|
extern int gCharacterEditorFolderViewOffsetY;
|
||||||
extern int _folder_karma_top_line;
|
extern int gCharacterEditorKarmaFolderTopLine;
|
||||||
extern int _folder_highlight_line;
|
extern int gCharacterEditorFolderViewHighlightedLine;
|
||||||
extern char* _folder_card_desc;
|
extern char* gCharacterEditorFolderCardDescription;
|
||||||
extern int _folder_ypos;
|
extern int gCharacterEditorFolderViewNextY;
|
||||||
extern int _folder_kills_top_line;
|
extern int gCharacterEditorKillsFolderTopLine;
|
||||||
extern int _folder_perk_top_line;
|
extern int gCharacterEditorPerkFolderTopLine;
|
||||||
extern unsigned char* gEditorPerkBackgroundBuffer;
|
extern unsigned char* gPerkDialogBackgroundBuffer;
|
||||||
extern int gEditorPerkWindow;
|
extern int gPerkDialogWindow;
|
||||||
extern int _SliderPlusID;
|
extern int gCharacterEditorSliderPlusBtn;
|
||||||
extern int _SliderNegID;
|
extern int gCharacterEditorSliderMinusBtn;
|
||||||
extern int _stat_bids_minus[7];
|
extern int gCharacterEditorPrimaryStatMinusBtns[7];
|
||||||
extern unsigned char* characterEditorWindowBuf;
|
extern unsigned char* gCharacterEditorWindowBuffer;
|
||||||
extern int characterEditorWindowHandle;
|
extern int gCharacterEditorWindow;
|
||||||
extern int _stat_bids_plus[7];
|
extern int gCharacterEditorPrimaryStatPlusBtns[7];
|
||||||
extern unsigned char* gEditorPerkWindowBuffer;
|
extern unsigned char* gPerkDialogWindowBuffer;
|
||||||
extern CritterProtoData _dude_data;
|
extern CritterProtoData gCharacterEditorDudeDataBackup;
|
||||||
extern unsigned char* characterEditorWindowBackgroundBuf;
|
extern unsigned char* gCharacterEditorWindowBackgroundBuffer;
|
||||||
extern int _cline;
|
extern int gPerkDialogCurrentLine;
|
||||||
extern int _oldsline;
|
extern int gPerkDialogPreviousCurrentLine;
|
||||||
extern int _upsent_points_back;
|
extern int gCharacterEditorUnspentSkillPointsBackup;
|
||||||
extern int _last_level;
|
extern int gCharacterEditorLastLevel;
|
||||||
extern int characterEditorWindowOldFont;
|
extern int gCharacterEditorOldFont;
|
||||||
extern int _kills_count;
|
extern int gCharacterEditorKillsCount;
|
||||||
extern CacheEntry* _bck_key;
|
extern CacheEntry* gCharacterEditorWindowBackgroundHandle;
|
||||||
extern int _hp_back;
|
extern int gCharacterEditorHitPointsBackup;
|
||||||
extern int _mouse_ypos;
|
extern int gCharacterEditorMouseY;
|
||||||
extern int _mouse_xpos;
|
extern int gCharacterEditorMouseX;
|
||||||
extern int characterEditorSelectedItem;
|
extern int characterEditorSelectedItem;
|
||||||
extern int characterEditorWindowSelectedFolder;
|
extern int characterEditorWindowSelectedFolder;
|
||||||
extern int _frstc_draw1;
|
extern bool gCharacterEditorCardDrawn;
|
||||||
extern int _crow;
|
extern int gPerkDialogTopLine;
|
||||||
extern int _frstc_draw2;
|
extern bool gPerkDialogCardDrawn;
|
||||||
extern int _perk_back[PERK_COUNT];
|
extern int gCharacterEditorPerksBackup[PERK_COUNT];
|
||||||
extern unsigned int _repFtime;
|
extern unsigned int _repFtime;
|
||||||
extern unsigned int _frame_time;
|
extern unsigned int _frame_time;
|
||||||
extern int _old_tags;
|
extern int gCharacterEditorOldTaggedSkillCount;
|
||||||
extern int _last_level_back;
|
extern int gCharacterEditorLastLevelBackup;
|
||||||
extern bool gCharacterEditorIsCreationMode;
|
extern bool gCharacterEditorIsCreationMode;
|
||||||
extern int _tag_skill_back[NUM_TAGGED_SKILLS];
|
extern int gCharacterEditorTaggedSkillsBackup[NUM_TAGGED_SKILLS];
|
||||||
extern int _card_old_fid2;
|
extern int gPerkDialogCardFrmId;
|
||||||
extern int _card_old_fid1;
|
extern int gCharacterEditorCardFrmId;
|
||||||
extern int _trait_back[3];
|
extern int gCharacterEditorOptionalTraitsBackup[3];
|
||||||
extern int _trait_count;
|
extern int gCharacterEditorTempTraitCount;
|
||||||
extern int _optrt_count;
|
extern int gPerkDialogOptionCount;
|
||||||
extern int _temp_trait[3];
|
extern int gCharacterEditorTempTraits[3];
|
||||||
extern int _tagskill_count;
|
extern int gCharacterEditorTaggedSkillCount;
|
||||||
extern int _temp_tag_skill[NUM_TAGGED_SKILLS];
|
extern int gCharacterEditorTempTaggedSkills[NUM_TAGGED_SKILLS];
|
||||||
extern char _free_perk_back;
|
extern char gCharacterEditorHasFreePerkBackup;
|
||||||
extern unsigned char _free_perk;
|
extern unsigned char gCharacterEditorHasFreePerk;
|
||||||
extern unsigned char _first_skill_list;
|
extern unsigned char gCharacterEditorIsSkillsFirstDraw;
|
||||||
|
|
||||||
int _editor_design(bool isCreationMode);
|
int characterEditorShow(bool isCreationMode);
|
||||||
int characterEditorWindowInit();
|
int characterEditorWindowInit();
|
||||||
void characterEditorWindowFree();
|
void characterEditorWindowFree();
|
||||||
void _CharEditInit();
|
void characterEditorInit();
|
||||||
int _get_input_str(int win, int cancelKeyCode, char* text, int maxLength, int x, int y, int textColor, int backgroundColor, int flags);
|
int _get_input_str(int win, int cancelKeyCode, char* text, int maxLength, int x, int y, int textColor, int backgroundColor, int flags);
|
||||||
bool _isdoschar(int ch);
|
bool _isdoschar(int ch);
|
||||||
char* _strmfe(char* dest, const char* name, const char* ext);
|
char* _strmfe(char* dest, const char* name, const char* ext);
|
||||||
void editorRenderFolders();
|
void characterEditorDrawFolders();
|
||||||
void editorRenderPerks();
|
void characterEditorDrawPerksFolder();
|
||||||
int _kills_list_comp(const KillInfo* a, const KillInfo* b);
|
int characterEditorKillsCompare(const void* a1, const void* a2);
|
||||||
int editorRenderKills();
|
int characterEditorDrawKillsFolder();
|
||||||
void characterEditorRenderBigNumber(int x, int y, int flags, int value, int previousValue, int windowHandle);
|
void characterEditorDrawBigNumber(int x, int y, int flags, int value, int previousValue, int windowHandle);
|
||||||
void editorRenderPcStats();
|
void characterEditorDrawPcStats();
|
||||||
void editorRenderPrimaryStat(int stat, bool animate, int previousValue);
|
void characterEditorDrawPrimaryStat(int stat, bool animate, int previousValue);
|
||||||
void editorRenderGender();
|
void characterEditorDrawGender();
|
||||||
void editorRenderAge();
|
void characterEditorDrawAge();
|
||||||
void editorRenderName();
|
void characterEditorDrawName();
|
||||||
void editorRenderSecondaryStats();
|
void characterEditorDrawDerivedStats();
|
||||||
void editorRenderSkills(int a1);
|
void characterEditorDrawSkills(int a1);
|
||||||
void editorRenderDetails();
|
void characterEditorDrawCard();
|
||||||
int characterEditorEditName();
|
int characterEditorEditName();
|
||||||
void _PrintName(unsigned char* buf, int a2);
|
void _PrintName(unsigned char* buf, int pitch);
|
||||||
int characterEditorRunEditAgeDialog();
|
int characterEditorEditAge();
|
||||||
void characterEditorEditGender();
|
void characterEditorEditGender();
|
||||||
void characterEditorHandleIncDecPrimaryStat(int eventCode);
|
void characterEditorAdjustPrimaryStat(int eventCode);
|
||||||
int _OptionWindow();
|
int characterEditorShowOptions();
|
||||||
bool characterFileExists(const char* fname);
|
bool characterFileExists(const char* fname);
|
||||||
int characterPrintToFile(const char* fileName);
|
int characterPrintToFile(const char* fileName);
|
||||||
char* _AddSpaces(char* string, int length);
|
char* _AddSpaces(char* string, int length);
|
||||||
char* _AddDots(char* string, int length);
|
char* _AddDots(char* string, int length);
|
||||||
void _ResetScreen();
|
void characterEditorResetScreen();
|
||||||
void _RegInfoAreas();
|
void characterEditorRegisterInfoAreas();
|
||||||
void _SavePlayer();
|
void characterEditorSavePlayer();
|
||||||
void _RestorePlayer();
|
void characterEditorRestorePlayer();
|
||||||
char* _itostndn(int value, char* dest);
|
char* _itostndn(int value, char* dest);
|
||||||
int _DrawCard(int graphicId, const char* name, const char* attributes, char* description);
|
int characterEditorDrawCardWithOptions(int graphicId, const char* name, const char* attributes, char* description);
|
||||||
void _FldrButton();
|
void characterEditorHandleFolderButtonPressed();
|
||||||
void _InfoButton(int eventCode);
|
void characterEditorHandleInfoButtonPressed(int eventCode);
|
||||||
void editorAdjustSkill(int a1);
|
void characterEditorHandleAdjustSkillButtonPressed(int a1);
|
||||||
void characterEditorToggleTaggedSkill(int skill);
|
void characterEditorToggleTaggedSkill(int skill);
|
||||||
void characterEditorWindowRenderTraits();
|
void characterEditorDrawOptionalTraits();
|
||||||
void characterEditorToggleOptionalTrait(int trait);
|
void characterEditorToggleOptionalTrait(int trait);
|
||||||
void editorRenderKarma();
|
void characterEditorDrawKarmaFolder();
|
||||||
int _editor_save(File* stream);
|
int characterEditorSave(File* stream);
|
||||||
int _editor_load(File* stream);
|
int characterEditorLoad(File* stream);
|
||||||
void _editor_reset();
|
void characterEditorReset();
|
||||||
int _UpdateLevel();
|
int characterEditorUpdateLevel();
|
||||||
void _RedrwDPrks();
|
void perkDialogRefreshPerks();
|
||||||
int editorSelectPerk();
|
int perkDialogShow();
|
||||||
int _InputPDLoop(int count, void (*refreshProc)());
|
int perkDialogHandleInput(int count, void (*refreshProc)());
|
||||||
int _ListDPerks();
|
int perkDialogDrawPerks();
|
||||||
void _RedrwDMPrk();
|
void perkDialogRefreshTraits();
|
||||||
bool editorHandleMutate();
|
bool perkDialogHandleMutatePerk();
|
||||||
void _RedrwDMTagSkl();
|
void perkDialogRefreshSkills();
|
||||||
bool editorHandleTag();
|
bool perkDialogHandleTagPerk();
|
||||||
void _ListNewTagSkills();
|
void perkDialogDrawSkills();
|
||||||
int _ListMyTraits(int a1);
|
int perkDialogDrawTraits(int a1);
|
||||||
int _name_sort_comp(const void* a1, const void* a2);
|
int perkDialogOptionCompare(const void* a1, const void* a2);
|
||||||
int _DrawCard2(int frmId, const char* name, const char* rank, char* description);
|
int perkDialogDrawCard(int frmId, const char* name, const char* rank, char* description);
|
||||||
void _pop_perks();
|
void _pop_perks();
|
||||||
int _is_supper_bonus();
|
int _is_supper_bonus();
|
||||||
int _folder_init();
|
int characterEditorFolderViewInit();
|
||||||
void _folder_scroll(int direction);
|
void characterEditorFolderViewScroll(int direction);
|
||||||
void _folder_clear();
|
void characterEditorFolderViewClear();
|
||||||
int _folder_print_seperator(const char* string);
|
int characterEditorFolderViewDrawHeading(const char* string);
|
||||||
bool _folder_print_line(const char* string);
|
bool characterEditorFolderViewDrawString(const char* string);
|
||||||
bool editorDrawKillsEntry(const char* name, int kills);
|
bool characterEditorFolderViewDrawKillsEntry(const char* name, int kills);
|
||||||
int karmaInit();
|
int karmaInit();
|
||||||
void karmaFree();
|
void karmaFree();
|
||||||
int karmaEntryCompare(const void* a1, const void* a2);
|
int karmaEntryCompare(const void* a1, const void* a2);
|
||||||
|
@ -311,4 +313,8 @@ int genericReputationInit();
|
||||||
void genericReputationFree();
|
void genericReputationFree();
|
||||||
int genericReputationCompare(const void* a1, const void* a2);
|
int genericReputationCompare(const void* a1, const void* a2);
|
||||||
|
|
||||||
|
void customKarmaFolderInit();
|
||||||
|
void customKarmaFolderFree();
|
||||||
|
int customKarmaFolderGetFrmId();
|
||||||
|
|
||||||
#endif /* CHARACTER_EDITOR_H */
|
#endif /* CHARACTER_EDITOR_H */
|
||||||
|
|
|
@ -179,7 +179,7 @@ int characterSelectorOpen()
|
||||||
case KEY_UPPERCASE_C:
|
case KEY_UPPERCASE_C:
|
||||||
case KEY_LOWERCASE_C:
|
case KEY_LOWERCASE_C:
|
||||||
_ResetPlayer();
|
_ResetPlayer();
|
||||||
if (_editor_design(1) == 0) {
|
if (characterEditorShow(1) == 0) {
|
||||||
rc = 2;
|
rc = 2;
|
||||||
done = true;
|
done = true;
|
||||||
}
|
}
|
||||||
|
@ -187,7 +187,7 @@ int characterSelectorOpen()
|
||||||
break;
|
break;
|
||||||
case KEY_UPPERCASE_M:
|
case KEY_UPPERCASE_M:
|
||||||
case KEY_LOWERCASE_M:
|
case KEY_LOWERCASE_M:
|
||||||
if (!_editor_design(1)) {
|
if (!characterEditorShow(1)) {
|
||||||
rc = 2;
|
rc = 2;
|
||||||
done = true;
|
done = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -354,7 +354,7 @@ void _setMixTableColor(int a1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x4C78E4
|
// 0x4C78E4
|
||||||
bool colorPaletteLoad(char* path)
|
bool colorPaletteLoad(const char* path)
|
||||||
{
|
{
|
||||||
if (gColorFileNameMangler != NULL) {
|
if (gColorFileNameMangler != NULL) {
|
||||||
path = gColorFileNameMangler(path);
|
path = gColorFileNameMangler(path);
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
typedef char*(ColorFileNameManger)(char*);
|
typedef const char*(ColorFileNameManger)(const char*);
|
||||||
typedef void(ColorTransitionCallback)();
|
typedef void(ColorTransitionCallback)();
|
||||||
|
|
||||||
typedef int(ColorPaletteFileOpenProc)(const char* path, int mode);
|
typedef int(ColorPaletteFileOpenProc)(const char* path, int mode);
|
||||||
|
@ -54,7 +54,7 @@ void _setSystemPaletteEntries(unsigned char* a1, int a2, int a3);
|
||||||
void _setIntensityTableColor(int a1);
|
void _setIntensityTableColor(int a1);
|
||||||
void _setIntensityTables();
|
void _setIntensityTables();
|
||||||
void _setMixTableColor(int a1);
|
void _setMixTableColor(int a1);
|
||||||
bool colorPaletteLoad(char* path);
|
bool colorPaletteLoad(const char* path);
|
||||||
char* _colorError();
|
char* _colorError();
|
||||||
void _buildBlendTable(unsigned char* ptr, unsigned char ch);
|
void _buildBlendTable(unsigned char* ptr, unsigned char ch);
|
||||||
void _rebuildColorBlendTables();
|
void _rebuildColorBlendTables();
|
||||||
|
|
|
@ -2542,7 +2542,7 @@ void _combat_update_critter_outline_for_los(Object* critter, bool a2)
|
||||||
} else {
|
} else {
|
||||||
int v7 = objectGetDistanceBetween(gDude, critter);
|
int v7 = objectGetDistanceBetween(gDude, critter);
|
||||||
int v8 = critterGetStat(gDude, STAT_PERCEPTION) * 5;
|
int v8 = critterGetStat(gDude, STAT_PERCEPTION) * 5;
|
||||||
if ((critter->flags & OBJECT_FLAG_0x20000) != 0) {
|
if ((critter->flags & OBJECT_TRANS_GLASS) != 0) {
|
||||||
v8 /= 2;
|
v8 /= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3382,7 +3382,7 @@ bool _check_ranged_miss(Attack* attack)
|
||||||
while (curr != to) {
|
while (curr != to) {
|
||||||
_make_straight_path_func(attack->attacker, curr, to, NULL, &critter, 32, _obj_shoot_blocking_at);
|
_make_straight_path_func(attack->attacker, curr, to, NULL, &critter, 32, _obj_shoot_blocking_at);
|
||||||
if (critter != NULL) {
|
if (critter != NULL) {
|
||||||
if ((critter->flags & OBJECT_FLAG_0x80000000) == 0) {
|
if ((critter->flags & OBJECT_SHOOT_THRU) == 0) {
|
||||||
if ((critter->fid & 0xF000000) >> 24 != OBJ_TYPE_CRITTER) {
|
if ((critter->fid & 0xF000000) >> 24 != OBJ_TYPE_CRITTER) {
|
||||||
roll = ROLL_SUCCESS;
|
roll = ROLL_SUCCESS;
|
||||||
break;
|
break;
|
||||||
|
@ -3412,7 +3412,7 @@ bool _check_ranged_miss(Attack* attack)
|
||||||
|
|
||||||
attack->defenderHitLocation = HIT_LOCATION_TORSO;
|
attack->defenderHitLocation = HIT_LOCATION_TORSO;
|
||||||
|
|
||||||
if (roll < ROLL_SUCCESS || critter == NULL || (critter->flags & OBJECT_FLAG_0x80000000) == 0) {
|
if (roll < ROLL_SUCCESS || critter == NULL || (critter->flags & OBJECT_SHOOT_THRU) == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3747,7 +3747,7 @@ int attackCompute(Attack* attack)
|
||||||
v25 = _obj_blocking_at(NULL, attack->tile, attack->defender->elevation);
|
v25 = _obj_blocking_at(NULL, attack->tile, attack->defender->elevation);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v25 != NULL && (v25->flags & OBJECT_FLAG_0x80000000) == 0) {
|
if (v25 != NULL && (v25->flags & OBJECT_SHOOT_THRU) == 0) {
|
||||||
attack->attackerFlags |= DAM_HIT;
|
attack->attackerFlags |= DAM_HIT;
|
||||||
attack->defender = v25;
|
attack->defender = v25;
|
||||||
attackComputeDamage(attack, 1, 2);
|
attackComputeDamage(attack, 1, 2);
|
||||||
|
@ -3834,7 +3834,7 @@ void _compute_explosion_on_extras(Attack* attack, int a2, int a3, int a4)
|
||||||
if (v11 != NULL
|
if (v11 != NULL
|
||||||
&& (v11->fid & 0xF000000) >> 24 == OBJ_TYPE_CRITTER
|
&& (v11->fid & 0xF000000) >> 24 == OBJ_TYPE_CRITTER
|
||||||
&& (v11->data.critter.combat.results & DAM_DEAD) == 0
|
&& (v11->data.critter.combat.results & DAM_DEAD) == 0
|
||||||
&& (v11->flags & OBJECT_FLAG_0x80000000) == 0
|
&& (v11->flags & OBJECT_SHOOT_THRU) == 0
|
||||||
&& !_combat_is_shot_blocked(v11, v11->tile, tile, NULL, NULL)) {
|
&& !_combat_is_shot_blocked(v11, v11->tile, tile, NULL, NULL)) {
|
||||||
if (v11 == attack->attacker) {
|
if (v11 == attack->attacker) {
|
||||||
attack->attackerFlags &= ~DAM_HIT;
|
attack->attackerFlags &= ~DAM_HIT;
|
||||||
|
@ -4224,7 +4224,7 @@ int attackDetermineToHit(Object* attacker, int tile, Object* defender, int hitLo
|
||||||
accuracy += _hit_location_penalty[hitLocation] / 2;
|
accuracy += _hit_location_penalty[hitLocation] / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (defender != NULL && (defender->flags & OBJECT_FLAG_0x800) != 0) {
|
if (defender != NULL && (defender->flags & OBJECT_MULTIHEX) != 0) {
|
||||||
accuracy += 15;
|
accuracy += 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4406,7 +4406,7 @@ void attackComputeDamage(Attack* attack, int ammoQuantity, int a3)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (knockbackDistancePtr != NULL
|
if (knockbackDistancePtr != NULL
|
||||||
&& (critter->flags & OBJECT_FLAG_0x800) == 0
|
&& (critter->flags & OBJECT_MULTIHEX) == 0
|
||||||
&& (damageType == DAMAGE_TYPE_EXPLOSION || attack->weapon == NULL || weaponGetAttackTypeForHitMode(attack->weapon, attack->hitMode) == ATTACK_TYPE_MELEE)
|
&& (damageType == DAMAGE_TYPE_EXPLOSION || attack->weapon == NULL || weaponGetAttackTypeForHitMode(attack->weapon, attack->hitMode) == ATTACK_TYPE_MELEE)
|
||||||
&& (critter->pid >> 24) == OBJ_TYPE_CRITTER
|
&& (critter->pid >> 24) == OBJ_TYPE_CRITTER
|
||||||
&& _critter_flag_check(critter->pid, 0x4000) == 0) {
|
&& _critter_flag_check(critter->pid, 0x4000) == 0) {
|
||||||
|
@ -5686,7 +5686,7 @@ bool _combat_is_shot_blocked(Object* a1, int from, int to, Object* a4, int* a5)
|
||||||
if ((obstacle->data.critter.combat.results & (DAM_DEAD | DAM_KNOCKED_DOWN | DAM_KNOCKED_OUT)) == 0) {
|
if ((obstacle->data.critter.combat.results & (DAM_DEAD | DAM_KNOCKED_DOWN | DAM_KNOCKED_OUT)) == 0) {
|
||||||
*a5 += 1;
|
*a5 += 1;
|
||||||
|
|
||||||
if ((obstacle->flags & OBJECT_FLAG_0x800) != 0) {
|
if ((obstacle->flags & OBJECT_MULTIHEX) != 0) {
|
||||||
*a5 += 1;
|
*a5 += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5694,7 +5694,7 @@ bool _combat_is_shot_blocked(Object* a1, int from, int to, Object* a4, int* a5)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((obstacle->flags & OBJECT_FLAG_0x800) != 0) {
|
if ((obstacle->flags & OBJECT_MULTIHEX) != 0) {
|
||||||
int rotation = tileGetRotationTo(current, to);
|
int rotation = tileGetRotationTo(current, to);
|
||||||
current = tileGetTileInDirection(current, rotation, 1);
|
current = tileGetTileInDirection(current, rotation, 1);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -2143,13 +2143,13 @@ int _ai_move_steps_closer(Object* a1, Object* a2, int actionPoints, int a4)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actionPoints >= critterGetStat(a1, STAT_MAXIMUM_ACTION_POINTS) / 2 && artCritterFidShouldRun(a1->fid)) {
|
if (actionPoints >= critterGetStat(a1, STAT_MAXIMUM_ACTION_POINTS) / 2 && artCritterFidShouldRun(a1->fid)) {
|
||||||
if ((a2->flags & OBJECT_FLAG_0x800) != 0) {
|
if ((a2->flags & OBJECT_MULTIHEX) != 0) {
|
||||||
reg_anim_obj_run_to_obj(a1, a2, actionPoints, 0);
|
reg_anim_obj_run_to_obj(a1, a2, actionPoints, 0);
|
||||||
} else {
|
} else {
|
||||||
reg_anim_obj_run_to_tile(a1, tile, a1->elevation, actionPoints, 0);
|
reg_anim_obj_run_to_tile(a1, tile, a1->elevation, actionPoints, 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((a2->flags & OBJECT_FLAG_0x800) != 0) {
|
if ((a2->flags & OBJECT_MULTIHEX) != 0) {
|
||||||
reg_anim_obj_move_to_obj(a1, a2, actionPoints, 0);
|
reg_anim_obj_move_to_obj(a1, a2, actionPoints, 0);
|
||||||
} else {
|
} else {
|
||||||
reg_anim_obj_move_to_tile(a1, tile, a1->elevation, actionPoints, 0);
|
reg_anim_obj_move_to_tile(a1, tile, a1->elevation, actionPoints, 0);
|
||||||
|
@ -3198,7 +3198,7 @@ bool objectCanHearObject(Object* a1, Object* a2)
|
||||||
int sneak = skillGetValue(a2, SKILL_SNEAK);
|
int sneak = skillGetValue(a2, SKILL_SNEAK);
|
||||||
if (_can_see(a1, a2)) {
|
if (_can_see(a1, a2)) {
|
||||||
int v8 = perception * 5;
|
int v8 = perception * 5;
|
||||||
if ((a2->flags & OBJECT_FLAG_0x20000) != 0) {
|
if ((a2->flags & OBJECT_TRANS_GLASS) != 0) {
|
||||||
v8 /= 2;
|
v8 /= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#include "platform_compat.h"
|
#include "platform_compat.h"
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -178,8 +180,8 @@ bool configSetString(Config* config, const char* sectionKey, const char* key, co
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x42C05C
|
// 0x42C05C customized: atoi() replaced with strtol()
|
||||||
bool configGetInt(Config* config, const char* sectionKey, const char* key, int* valuePtr)
|
bool configGetInt(Config* config, const char* sectionKey, const char* key, int* valuePtr, unsigned char base /* = 0 */ )
|
||||||
{
|
{
|
||||||
if (valuePtr == NULL) {
|
if (valuePtr == NULL) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -190,7 +192,13 @@ bool configGetInt(Config* config, const char* sectionKey, const char* key, int*
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*valuePtr = atoi(stringValue);
|
char* end;
|
||||||
|
errno = 0;
|
||||||
|
long l = strtol(stringValue, &end, base); // see https://stackoverflow.com/a/6154614
|
||||||
|
if (((errno == ERANGE && 1 == LONG_MAX) || l > INT_MAX) || ((errno == ERANGE && l == LONG_MIN) || l < INT_MIN) || (*stringValue == '\0' || *end != '\0'))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*valuePtr = l;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ void configFree(Config* config);
|
||||||
bool configParseCommandLineArguments(Config* config, int argc, char** argv);
|
bool configParseCommandLineArguments(Config* config, int argc, char** argv);
|
||||||
bool configGetString(Config* config, const char* sectionKey, const char* key, char** valuePtr);
|
bool configGetString(Config* config, const char* sectionKey, const char* key, char** valuePtr);
|
||||||
bool configSetString(Config* config, const char* sectionKey, const char* key, const char* value);
|
bool configSetString(Config* config, const char* sectionKey, const char* key, const char* value);
|
||||||
bool configGetInt(Config* config, const char* sectionKey, const char* key, int* valuePtr);
|
bool configGetInt(Config* config, const char* sectionKey, const char* key, int* valuePtr, unsigned char base = 0);
|
||||||
bool configGetIntList(Config* config, const char* section, const char* key, int* arr, int count);
|
bool configGetIntList(Config* config, const char* section, const char* key, int* arr, int count);
|
||||||
bool configSetInt(Config* config, const char* sectionKey, const char* key, int value);
|
bool configSetInt(Config* config, const char* sectionKey, const char* key, int value);
|
||||||
bool configRead(Config* config, const char* filePath, bool isDb);
|
bool configRead(Config* config, const char* filePath, bool isDb);
|
||||||
|
|
|
@ -15,7 +15,9 @@
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
|
#if _WIN32
|
||||||
#include <SDL_syswm.h>
|
#include <SDL_syswm.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
// NOT USED.
|
// NOT USED.
|
||||||
void (*_idle_func)() = NULL;
|
void (*_idle_func)() = NULL;
|
||||||
|
@ -4276,9 +4278,11 @@ void _kb_init_lock_status()
|
||||||
gModifierKeysState |= MODIFIER_KEY_STATE_NUM_LOCK;
|
gModifierKeysState |= MODIFIER_KEY_STATE_NUM_LOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SDL_VERSION_ATLEAST(2, 0, 18)
|
||||||
if ((SDL_GetModState() & KMOD_SCROLL) != 0) {
|
if ((SDL_GetModState() & KMOD_SCROLL) != 0) {
|
||||||
gModifierKeysState |= MODIFIER_KEY_STATE_SCROLL_LOCK;
|
gModifierKeysState |= MODIFIER_KEY_STATE_SCROLL_LOCK;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get pointer to pending key event from the queue but do not consume it.
|
// Get pointer to pending key event from the queue but do not consume it.
|
||||||
|
|
|
@ -976,7 +976,7 @@ int gcdLoad(const char* path)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fileReadInt32(stream, &characterEditorRemainingCharacterPoints) == -1) {
|
if (fileReadInt32(stream, &gCharacterEditorRemainingCharacterPoints) == -1) {
|
||||||
fileClose(stream);
|
fileClose(stream);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1048,7 +1048,7 @@ int gcdSave(const char* path)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fileWriteInt32(stream, characterEditorRemainingCharacterPoints) == -1) {
|
if (fileWriteInt32(stream, gCharacterEditorRemainingCharacterPoints) == -1) {
|
||||||
fileClose(stream);
|
fileClose(stream);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -650,7 +650,12 @@ int fileNameListInit(const char* pattern, char*** fileNameListPtr, int a3, int a
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!v2) {
|
if (!v2) {
|
||||||
sprintf(xlist->fileNames[index], "%s%s", fileName, extension);
|
// NOTE: Quick and dirty fix to buffer overflow. See RE to
|
||||||
|
// understand the problem.
|
||||||
|
char path[COMPAT_MAX_PATH];
|
||||||
|
sprintf(path, "%s%s", fileName, extension);
|
||||||
|
free(xlist->fileNames[length]);
|
||||||
|
xlist->fileNames[length] = strdup(path);
|
||||||
length++;
|
length++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
855
src/dbox.cc
855
src/dbox.cc
|
@ -1,6 +1,7 @@
|
||||||
#include "dbox.h"
|
#include "dbox.h"
|
||||||
|
|
||||||
#include "art.h"
|
#include "art.h"
|
||||||
|
#include "character_editor.h"
|
||||||
#include "color.h"
|
#include "color.h"
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
@ -18,6 +19,45 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
#define FILE_DIALOG_LINE_COUNT 12
|
||||||
|
|
||||||
|
#define FILE_DIALOG_DOUBLE_CLICK_DELAY 32
|
||||||
|
|
||||||
|
#define LOAD_FILE_DIALOG_DONE_BUTTON_X 58
|
||||||
|
#define LOAD_FILE_DIALOG_DONE_BUTTON_Y 187
|
||||||
|
|
||||||
|
#define LOAD_FILE_DIALOG_DONE_LABEL_X 79
|
||||||
|
#define LOAD_FILE_DIALOG_DONE_LABEL_Y 187
|
||||||
|
|
||||||
|
#define LOAD_FILE_DIALOG_CANCEL_BUTTON_X 163
|
||||||
|
#define LOAD_FILE_DIALOG_CANCEL_BUTTON_Y 187
|
||||||
|
|
||||||
|
#define LOAD_FILE_DIALOG_CANCEL_LABEL_X 182
|
||||||
|
#define LOAD_FILE_DIALOG_CANCEL_LABEL_Y 187
|
||||||
|
|
||||||
|
#define SAVE_FILE_DIALOG_DONE_BUTTON_X 58
|
||||||
|
#define SAVE_FILE_DIALOG_DONE_BUTTON_Y 214
|
||||||
|
|
||||||
|
#define SAVE_FILE_DIALOG_DONE_LABEL_X 79
|
||||||
|
#define SAVE_FILE_DIALOG_DONE_LABEL_Y 213
|
||||||
|
|
||||||
|
#define SAVE_FILE_DIALOG_CANCEL_BUTTON_X 163
|
||||||
|
#define SAVE_FILE_DIALOG_CANCEL_BUTTON_Y 214
|
||||||
|
|
||||||
|
#define SAVE_FILE_DIALOG_CANCEL_LABEL_X 182
|
||||||
|
#define SAVE_FILE_DIALOG_CANCEL_LABEL_Y 213
|
||||||
|
|
||||||
|
#define FILE_DIALOG_TITLE_X 49
|
||||||
|
#define FILE_DIALOG_TITLE_Y 16
|
||||||
|
|
||||||
|
#define FILE_DIALOG_SCROLL_BUTTON_X 36
|
||||||
|
#define FILE_DIALOG_SCROLL_BUTTON_Y 44
|
||||||
|
|
||||||
|
#define FILE_DIALOG_FILE_LIST_X 55
|
||||||
|
#define FILE_DIALOG_FILE_LIST_Y 49
|
||||||
|
#define FILE_DIALOG_FILE_LIST_WIDTH 190
|
||||||
|
#define FILE_DIALOG_FILE_LIST_HEIGHT 124
|
||||||
|
|
||||||
// 0x5108C8
|
// 0x5108C8
|
||||||
const int gDialogBoxBackgroundFrmIds[DIALOG_TYPE_COUNT] = {
|
const int gDialogBoxBackgroundFrmIds[DIALOG_TYPE_COUNT] = {
|
||||||
218, // MEDIALOG.FRM - Medium generic dialog box
|
218, // MEDIALOG.FRM - Medium generic dialog box
|
||||||
|
@ -55,7 +95,7 @@ const int _dblines[DIALOG_TYPE_COUNT] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
// 0x510900
|
// 0x510900
|
||||||
int _flgids[7] = {
|
int gLoadFileDialogFrmIds[FILE_DIALOG_FRM_COUNT] = {
|
||||||
224, // loadbox.frm - character editor
|
224, // loadbox.frm - character editor
|
||||||
8, // lilredup.frm - little red button up
|
8, // lilredup.frm - little red button up
|
||||||
9, // lilreddn.frm - little red button down
|
9, // lilreddn.frm - little red button down
|
||||||
|
@ -66,7 +106,7 @@ int _flgids[7] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
// 0x51091C
|
// 0x51091C
|
||||||
int _flgids2[7] = {
|
int gSaveFileDialogFrmIds[FILE_DIALOG_FRM_COUNT] = {
|
||||||
225, // savebox.frm - character editor
|
225, // savebox.frm - character editor
|
||||||
8, // lilredup.frm - little red button up
|
8, // lilredup.frm - little red button up
|
||||||
9, // lilreddn.frm - little red button down
|
9, // lilreddn.frm - little red button down
|
||||||
|
@ -451,17 +491,32 @@ int showDialogBox(const char* title, const char** body, int bodyLength, int x, i
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x41EA78
|
// 0x41DE90
|
||||||
int _save_file_dialog(char* a1, char** fileList, char* fileName, int fileListLength, int x, int y, int flags)
|
int showLoadFileDialog(char *title, char** fileList, char* dest, int fileListLength, int x, int y, int flags)
|
||||||
{
|
{
|
||||||
int oldFont = fontGetCurrent();
|
int oldFont = fontGetCurrent();
|
||||||
|
|
||||||
unsigned char* frmBuffers[7];
|
bool isScrollable = false;
|
||||||
CacheEntry* frmHandles[7];
|
if (fileListLength > FILE_DIALOG_LINE_COUNT) {
|
||||||
Size frmSizes[7];
|
isScrollable = true;
|
||||||
|
}
|
||||||
|
|
||||||
for (int index = 0; index < 7; index++) {
|
int selectedFileIndex = 0;
|
||||||
int fid = buildFid(6, _flgids2[index], 0, 0, 0);
|
int pageOffset = 0;
|
||||||
|
int maxPageOffset = fileListLength - (FILE_DIALOG_LINE_COUNT + 1);
|
||||||
|
if (maxPageOffset < 0) {
|
||||||
|
maxPageOffset = fileListLength - 1;
|
||||||
|
if (maxPageOffset < 0) {
|
||||||
|
maxPageOffset = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char* frmBuffers[FILE_DIALOG_FRM_COUNT];
|
||||||
|
CacheEntry* frmHandles[FILE_DIALOG_FRM_COUNT];
|
||||||
|
Size frmSizes[FILE_DIALOG_FRM_COUNT];
|
||||||
|
|
||||||
|
for (int index = 0; index < FILE_DIALOG_FRM_COUNT; index++) {
|
||||||
|
int fid = buildFid(6, gLoadFileDialogFrmIds[index], 0, 0, 0);
|
||||||
frmBuffers[index] = artLockFrameDataReturningSize(fid, &(frmHandles[index]), &(frmSizes[index].width), &(frmSizes[index].height));
|
frmBuffers[index] = artLockFrameDataReturningSize(fid, &(frmHandles[index]), &(frmSizes[index].width), &(frmSizes[index].height));
|
||||||
if (frmBuffers[index] == NULL) {
|
if (frmBuffers[index] == NULL) {
|
||||||
while (--index >= 0) {
|
while (--index >= 0) {
|
||||||
|
@ -471,16 +526,23 @@ int _save_file_dialog(char* a1, char** fileList, char* fileName, int fileListLen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int win = windowCreate(x, y, frmSizes[0].width, frmSizes[0].height, 256, WINDOW_FLAG_0x10 | WINDOW_FLAG_0x04);
|
|
||||||
|
int backgroundWidth = frmSizes[FILE_DIALOG_FRM_BACKGROUND].width;
|
||||||
|
int backgroundHeight = frmSizes[FILE_DIALOG_FRM_BACKGROUND].height;
|
||||||
|
|
||||||
|
// Maintain original position in original resolution, otherwise center it.
|
||||||
|
if (screenGetWidth() != 640) x = (screenGetWidth() - backgroundWidth) / 2;
|
||||||
|
if (screenGetHeight() != 480) y = (screenGetHeight() - backgroundHeight) / 2;
|
||||||
|
int win = windowCreate(x, y, backgroundWidth, backgroundHeight, 256, WINDOW_FLAG_0x10 | WINDOW_FLAG_0x04);
|
||||||
if (win == -1) {
|
if (win == -1) {
|
||||||
for (int index = 0; index < 7; index++) {
|
for (int index = 0; index < FILE_DIALOG_FRM_COUNT; index++) {
|
||||||
artUnlock(frmHandles[index]);
|
artUnlock(frmHandles[index]);
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char* windowBuffer = windowGetBuffer(win);
|
unsigned char* windowBuffer = windowGetBuffer(win);
|
||||||
memcpy(windowBuffer, frmBuffers[0], frmSizes[0].width * frmSizes[0].height);
|
memcpy(windowBuffer, frmBuffers[FILE_DIALOG_FRM_BACKGROUND], backgroundWidth * backgroundHeight);
|
||||||
|
|
||||||
MessageList messageList;
|
MessageList messageList;
|
||||||
MessageListItem messageListItem;
|
MessageListItem messageListItem;
|
||||||
|
@ -488,7 +550,7 @@ int _save_file_dialog(char* a1, char** fileList, char* fileName, int fileListLen
|
||||||
if (!messageListInit(&messageList)) {
|
if (!messageListInit(&messageList)) {
|
||||||
windowDestroy(win);
|
windowDestroy(win);
|
||||||
|
|
||||||
for (int index = 0; index < 7; index++) {
|
for (int index = 0; index < FILE_DIALOG_FRM_COUNT; index++) {
|
||||||
artUnlock(frmHandles[index]);
|
artUnlock(frmHandles[index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -501,7 +563,7 @@ int _save_file_dialog(char* a1, char** fileList, char* fileName, int fileListLen
|
||||||
if (!messageListLoad(&messageList, path)) {
|
if (!messageListLoad(&messageList, path)) {
|
||||||
windowDestroy(win);
|
windowDestroy(win);
|
||||||
|
|
||||||
for (int index = 0; index < 7; index++) {
|
for (int index = 0; index < FILE_DIALOG_FRM_COUNT; index++) {
|
||||||
artUnlock(frmHandles[index]);
|
artUnlock(frmHandles[index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -512,23 +574,23 @@ int _save_file_dialog(char* a1, char** fileList, char* fileName, int fileListLen
|
||||||
|
|
||||||
// DONE
|
// DONE
|
||||||
const char* done = getmsg(&messageList, &messageListItem, 100);
|
const char* done = getmsg(&messageList, &messageListItem, 100);
|
||||||
fontDrawText(windowBuffer + frmSizes[0].width * 213 + 79, done, frmSizes[0].width, frmSizes[0].width, _colorTable[18979]);
|
fontDrawText(windowBuffer + LOAD_FILE_DIALOG_DONE_LABEL_Y * backgroundWidth + LOAD_FILE_DIALOG_DONE_LABEL_X, done, backgroundWidth, backgroundWidth, _colorTable[18979]);
|
||||||
|
|
||||||
// CANCEL
|
// CANCEL
|
||||||
const char* cancel = getmsg(&messageList, &messageListItem, 103);
|
const char* cancel = getmsg(&messageList, &messageListItem, 103);
|
||||||
fontDrawText(windowBuffer + frmSizes[0].width * 213 + 182, cancel, frmSizes[0].width, frmSizes[0].width, _colorTable[18979]);
|
fontDrawText(windowBuffer + LOAD_FILE_DIALOG_CANCEL_LABEL_Y * backgroundWidth + LOAD_FILE_DIALOG_CANCEL_LABEL_X, cancel, backgroundWidth, backgroundWidth, _colorTable[18979]);
|
||||||
|
|
||||||
int doneBtn = buttonCreate(win,
|
int doneBtn = buttonCreate(win,
|
||||||
58,
|
LOAD_FILE_DIALOG_DONE_BUTTON_X,
|
||||||
214,
|
LOAD_FILE_DIALOG_DONE_BUTTON_Y,
|
||||||
frmSizes[2].width,
|
frmSizes[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].width,
|
||||||
frmSizes[2].height,
|
frmSizes[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].height,
|
||||||
-1,
|
-1,
|
||||||
-1,
|
-1,
|
||||||
-1,
|
-1,
|
||||||
500,
|
500,
|
||||||
frmBuffers[1],
|
frmBuffers[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_NORMAL],
|
||||||
frmBuffers[2],
|
frmBuffers[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED],
|
||||||
NULL,
|
NULL,
|
||||||
BUTTON_FLAG_TRANSPARENT);
|
BUTTON_FLAG_TRANSPARENT);
|
||||||
if (doneBtn != -1) {
|
if (doneBtn != -1) {
|
||||||
|
@ -536,16 +598,16 @@ int _save_file_dialog(char* a1, char** fileList, char* fileName, int fileListLen
|
||||||
}
|
}
|
||||||
|
|
||||||
int cancelBtn = buttonCreate(win,
|
int cancelBtn = buttonCreate(win,
|
||||||
163,
|
LOAD_FILE_DIALOG_CANCEL_BUTTON_X,
|
||||||
214,
|
LOAD_FILE_DIALOG_CANCEL_BUTTON_Y,
|
||||||
frmSizes[2].width,
|
frmSizes[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].width,
|
||||||
frmSizes[2].height,
|
frmSizes[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].height,
|
||||||
-1,
|
-1,
|
||||||
-1,
|
-1,
|
||||||
-1,
|
-1,
|
||||||
501,
|
501,
|
||||||
frmBuffers[1],
|
frmBuffers[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_NORMAL],
|
||||||
frmBuffers[2],
|
frmBuffers[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED],
|
||||||
NULL,
|
NULL,
|
||||||
BUTTON_FLAG_TRANSPARENT);
|
BUTTON_FLAG_TRANSPARENT);
|
||||||
if (cancelBtn != -1) {
|
if (cancelBtn != -1) {
|
||||||
|
@ -553,16 +615,16 @@ int _save_file_dialog(char* a1, char** fileList, char* fileName, int fileListLen
|
||||||
}
|
}
|
||||||
|
|
||||||
int scrollUpBtn = buttonCreate(win,
|
int scrollUpBtn = buttonCreate(win,
|
||||||
36,
|
FILE_DIALOG_SCROLL_BUTTON_X,
|
||||||
44,
|
FILE_DIALOG_SCROLL_BUTTON_Y,
|
||||||
frmSizes[6].width,
|
frmSizes[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED].width,
|
||||||
frmSizes[6].height,
|
frmSizes[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED].height,
|
||||||
-1,
|
-1,
|
||||||
505,
|
505,
|
||||||
506,
|
506,
|
||||||
505,
|
505,
|
||||||
frmBuffers[5],
|
frmBuffers[FILE_DIALOG_FRM_SCROLL_UP_ARROW_NORMAL],
|
||||||
frmBuffers[6],
|
frmBuffers[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED],
|
||||||
NULL,
|
NULL,
|
||||||
BUTTON_FLAG_TRANSPARENT);
|
BUTTON_FLAG_TRANSPARENT);
|
||||||
if (scrollUpBtn != -1) {
|
if (scrollUpBtn != -1) {
|
||||||
|
@ -570,16 +632,16 @@ int _save_file_dialog(char* a1, char** fileList, char* fileName, int fileListLen
|
||||||
}
|
}
|
||||||
|
|
||||||
int scrollDownButton = buttonCreate(win,
|
int scrollDownButton = buttonCreate(win,
|
||||||
36,
|
FILE_DIALOG_SCROLL_BUTTON_X,
|
||||||
44 + frmSizes[6].height,
|
FILE_DIALOG_SCROLL_BUTTON_Y + frmSizes[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED].height,
|
||||||
frmSizes[4].width,
|
frmSizes[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_PRESSED].width,
|
||||||
frmSizes[4].height,
|
frmSizes[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_PRESSED].height,
|
||||||
-1,
|
-1,
|
||||||
503,
|
503,
|
||||||
504,
|
504,
|
||||||
503,
|
503,
|
||||||
frmBuffers[3],
|
frmBuffers[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_NORMAL],
|
||||||
frmBuffers[4],
|
frmBuffers[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_PRESSED],
|
||||||
NULL,
|
NULL,
|
||||||
BUTTON_FLAG_TRANSPARENT);
|
BUTTON_FLAG_TRANSPARENT);
|
||||||
if (scrollUpBtn != -1) {
|
if (scrollUpBtn != -1) {
|
||||||
|
@ -588,10 +650,10 @@ int _save_file_dialog(char* a1, char** fileList, char* fileName, int fileListLen
|
||||||
|
|
||||||
buttonCreate(
|
buttonCreate(
|
||||||
win,
|
win,
|
||||||
55,
|
FILE_DIALOG_FILE_LIST_X,
|
||||||
49,
|
FILE_DIALOG_FILE_LIST_Y,
|
||||||
190,
|
FILE_DIALOG_FILE_LIST_WIDTH,
|
||||||
124,
|
FILE_DIALOG_FILE_LIST_HEIGHT,
|
||||||
-1,
|
-1,
|
||||||
-1,
|
-1,
|
||||||
-1,
|
-1,
|
||||||
|
@ -601,25 +663,714 @@ int _save_file_dialog(char* a1, char** fileList, char* fileName, int fileListLen
|
||||||
NULL,
|
NULL,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
if (a1 != NULL) {
|
if (title != NULL) {
|
||||||
fontDrawText(windowBuffer + frmSizes[0].width * 16 + 49, a1, frmSizes[0].width, frmSizes[0].width, _colorTable[18979]);
|
fontDrawText(windowBuffer + backgroundWidth * FILE_DIALOG_TITLE_Y + FILE_DIALOG_TITLE_X, title, backgroundWidth, backgroundWidth, _colorTable[18979]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fontSetCurrent(101);
|
||||||
|
|
||||||
|
fileDialogRenderFileList(windowBuffer, fileList, pageOffset, fileListLength, selectedFileIndex, backgroundWidth);
|
||||||
|
windowRefresh(win);
|
||||||
|
|
||||||
|
int doubleClickSelectedFileIndex = -2;
|
||||||
|
int doubleClickTimer = FILE_DIALOG_DOUBLE_CLICK_DELAY;
|
||||||
|
|
||||||
|
int rc = -1;
|
||||||
|
while (rc == -1) {
|
||||||
|
unsigned int tick = _get_time();
|
||||||
|
int keyCode = _get_input();
|
||||||
|
int scrollDirection = FILE_DIALOG_SCROLL_DIRECTION_NONE;
|
||||||
|
int scrollCounter = 0;
|
||||||
|
bool isScrolling = false;
|
||||||
|
|
||||||
|
if (keyCode == 500) {
|
||||||
|
if (fileListLength != 0) {
|
||||||
|
strncpy(dest, fileList[selectedFileIndex + pageOffset], 16);
|
||||||
|
rc = 0;
|
||||||
|
} else {
|
||||||
|
rc = 1;
|
||||||
|
}
|
||||||
|
} else if (keyCode == 501 || keyCode == KEY_ESCAPE) {
|
||||||
|
rc = 1;
|
||||||
|
} else if (keyCode == 502 && fileListLength != 0) {
|
||||||
|
int mouseX;
|
||||||
|
int mouseY;
|
||||||
|
mouseGetPosition(&mouseX, &mouseY);
|
||||||
|
|
||||||
|
int selectedLine = (mouseY - y - FILE_DIALOG_FILE_LIST_Y) / fontGetLineHeight();
|
||||||
|
if (selectedLine - 1 < 0) {
|
||||||
|
selectedLine = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isScrollable || selectedLine < fileListLength) {
|
||||||
|
if (selectedLine >= FILE_DIALOG_LINE_COUNT) {
|
||||||
|
selectedLine = FILE_DIALOG_LINE_COUNT - 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
selectedLine = fileListLength - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedFileIndex = selectedLine;
|
||||||
|
if (selectedFileIndex == doubleClickSelectedFileIndex) {
|
||||||
|
soundPlayFile("ib1p1xx1");
|
||||||
|
strncpy(dest, fileList[selectedFileIndex + pageOffset], 16);
|
||||||
|
rc = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
doubleClickSelectedFileIndex = selectedFileIndex;
|
||||||
|
fileDialogRenderFileList(windowBuffer, fileList, pageOffset, fileListLength, selectedFileIndex, backgroundWidth);
|
||||||
|
} else if (keyCode == 506) {
|
||||||
|
scrollDirection = FILE_DIALOG_SCROLL_DIRECTION_UP;
|
||||||
|
} else if (keyCode == 504) {
|
||||||
|
scrollDirection = FILE_DIALOG_SCROLL_DIRECTION_DOWN;
|
||||||
|
} else {
|
||||||
|
switch (keyCode) {
|
||||||
|
case KEY_ARROW_UP:
|
||||||
|
pageOffset--;
|
||||||
|
if (pageOffset < 0) {
|
||||||
|
selectedFileIndex--;
|
||||||
|
if (selectedFileIndex < 0) {
|
||||||
|
selectedFileIndex = 0;
|
||||||
|
}
|
||||||
|
pageOffset = 0;
|
||||||
|
}
|
||||||
|
fileDialogRenderFileList(windowBuffer, fileList, pageOffset, fileListLength, selectedFileIndex, backgroundWidth);
|
||||||
|
doubleClickSelectedFileIndex = -2;
|
||||||
|
break;
|
||||||
|
case KEY_ARROW_DOWN:
|
||||||
|
if (isScrollable) {
|
||||||
|
pageOffset++;
|
||||||
|
// FIXME: Should be >= maxPageOffset (as in save dialog).
|
||||||
|
// Otherwise out of bounds index is considered selected.
|
||||||
|
if (pageOffset > maxPageOffset) {
|
||||||
|
selectedFileIndex++;
|
||||||
|
// FIXME: Should be >= FILE_DIALOG_LINE_COUNT (as in
|
||||||
|
// save dialog). Otherwise out of bounds index is
|
||||||
|
// considered selected.
|
||||||
|
if (selectedFileIndex > FILE_DIALOG_LINE_COUNT) {
|
||||||
|
selectedFileIndex = FILE_DIALOG_LINE_COUNT - 1;
|
||||||
|
}
|
||||||
|
pageOffset = maxPageOffset;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
selectedFileIndex++;
|
||||||
|
if (selectedFileIndex > maxPageOffset) {
|
||||||
|
selectedFileIndex = maxPageOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fileDialogRenderFileList(windowBuffer, fileList, pageOffset, fileListLength, selectedFileIndex, backgroundWidth);
|
||||||
|
doubleClickSelectedFileIndex = -2;
|
||||||
|
break;
|
||||||
|
case KEY_HOME:
|
||||||
|
selectedFileIndex = 0;
|
||||||
|
pageOffset = 0;
|
||||||
|
fileDialogRenderFileList(windowBuffer, fileList, pageOffset, fileListLength, selectedFileIndex, backgroundWidth);
|
||||||
|
doubleClickSelectedFileIndex = -2;
|
||||||
|
break;
|
||||||
|
case KEY_END:
|
||||||
|
if (isScrollable) {
|
||||||
|
selectedFileIndex = FILE_DIALOG_LINE_COUNT - 1;
|
||||||
|
pageOffset = maxPageOffset;
|
||||||
|
} else {
|
||||||
|
selectedFileIndex = maxPageOffset;
|
||||||
|
pageOffset = 0;
|
||||||
|
}
|
||||||
|
fileDialogRenderFileList(windowBuffer, fileList, pageOffset, fileListLength, selectedFileIndex, backgroundWidth);
|
||||||
|
doubleClickSelectedFileIndex = -2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scrollDirection != FILE_DIALOG_SCROLL_DIRECTION_NONE) {
|
||||||
|
unsigned int scrollDelay = 4;
|
||||||
|
doubleClickSelectedFileIndex = -2;
|
||||||
|
while (1) {
|
||||||
|
unsigned int scrollTick = _get_time();
|
||||||
|
scrollCounter += 1;
|
||||||
|
if ((!isScrolling && scrollCounter == 1) || (isScrolling && scrollCounter > 14.4)) {
|
||||||
|
isScrolling = true;
|
||||||
|
|
||||||
|
if (scrollCounter > 14.4) {
|
||||||
|
scrollDelay += 1;
|
||||||
|
if (scrollDelay > 24) {
|
||||||
|
scrollDelay = 24;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scrollDirection == FILE_DIALOG_SCROLL_DIRECTION_UP) {
|
||||||
|
pageOffset--;
|
||||||
|
if (pageOffset < 0) {
|
||||||
|
selectedFileIndex--;
|
||||||
|
if (selectedFileIndex < 0) {
|
||||||
|
selectedFileIndex = 0;
|
||||||
|
}
|
||||||
|
pageOffset = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (isScrollable) {
|
||||||
|
pageOffset++;
|
||||||
|
if (pageOffset > maxPageOffset) {
|
||||||
|
selectedFileIndex++;
|
||||||
|
if (selectedFileIndex >= FILE_DIALOG_LINE_COUNT) {
|
||||||
|
selectedFileIndex = FILE_DIALOG_LINE_COUNT - 1;
|
||||||
|
}
|
||||||
|
pageOffset = maxPageOffset;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
selectedFileIndex++;
|
||||||
|
if (selectedFileIndex > maxPageOffset) {
|
||||||
|
selectedFileIndex = maxPageOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fileDialogRenderFileList(windowBuffer, fileList, pageOffset, fileListLength, selectedFileIndex, backgroundWidth);
|
||||||
|
windowRefresh(win);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int delay = (scrollCounter > 14.4) ? 1000 / scrollDelay : 1000 / 24;
|
||||||
|
while (getTicksSince(scrollTick) < delay) {
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_game_user_wants_to_quit != 0) {
|
||||||
|
rc = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int keyCode = _get_input();
|
||||||
|
if (keyCode == 505 || keyCode == 503) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
windowRefresh(win);
|
||||||
|
|
||||||
|
doubleClickTimer--;
|
||||||
|
if (doubleClickTimer == 0) {
|
||||||
|
doubleClickTimer = FILE_DIALOG_DOUBLE_CLICK_DELAY;
|
||||||
|
doubleClickSelectedFileIndex = -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (getTicksSince(tick) < (1000 / 24)) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_game_user_wants_to_quit) {
|
||||||
|
rc = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
windowDestroy(win);
|
||||||
|
|
||||||
|
for (int index = 0; index < FILE_DIALOG_FRM_COUNT; index++) {
|
||||||
|
artUnlock(frmHandles[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
messageListFree(&messageList);
|
||||||
|
fontSetCurrent(oldFont);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0x41EA78
|
||||||
|
int showSaveFileDialog(char* title, char** fileList, char* dest, int fileListLength, int x, int y, int flags)
|
||||||
|
{
|
||||||
|
int oldFont = fontGetCurrent();
|
||||||
|
|
||||||
|
bool isScrollable = false;
|
||||||
|
if (fileListLength > FILE_DIALOG_LINE_COUNT) {
|
||||||
|
isScrollable = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int selectedFileIndex = 0;
|
||||||
|
int pageOffset = 0;
|
||||||
|
int maxPageOffset = fileListLength - (FILE_DIALOG_LINE_COUNT + 1);
|
||||||
|
if (maxPageOffset < 0) {
|
||||||
|
maxPageOffset = fileListLength - 1;
|
||||||
|
if (maxPageOffset < 0) {
|
||||||
|
maxPageOffset = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char* frmBuffers[FILE_DIALOG_FRM_COUNT];
|
||||||
|
CacheEntry* frmHandles[FILE_DIALOG_FRM_COUNT];
|
||||||
|
Size frmSizes[FILE_DIALOG_FRM_COUNT];
|
||||||
|
|
||||||
|
for (int index = 0; index < FILE_DIALOG_FRM_COUNT; index++) {
|
||||||
|
int fid = buildFid(6, gSaveFileDialogFrmIds[index], 0, 0, 0);
|
||||||
|
frmBuffers[index] = artLockFrameDataReturningSize(fid, &(frmHandles[index]), &(frmSizes[index].width), &(frmSizes[index].height));
|
||||||
|
if (frmBuffers[index] == NULL) {
|
||||||
|
while (--index >= 0) {
|
||||||
|
artUnlock(frmHandles[index]);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int backgroundWidth = frmSizes[FILE_DIALOG_FRM_BACKGROUND].width;
|
||||||
|
int backgroundHeight = frmSizes[FILE_DIALOG_FRM_BACKGROUND].height;
|
||||||
|
|
||||||
|
// Maintain original position in original resolution, otherwise center it.
|
||||||
|
if (screenGetWidth() != 640) x = (screenGetWidth() - backgroundWidth) / 2;
|
||||||
|
if (screenGetHeight() != 480) y = (screenGetHeight() - backgroundHeight) / 2;
|
||||||
|
int win = windowCreate(x, y, backgroundWidth, backgroundHeight, 256, WINDOW_FLAG_0x10 | WINDOW_FLAG_0x04);
|
||||||
|
if (win == -1) {
|
||||||
|
for (int index = 0; index < FILE_DIALOG_FRM_COUNT; index++) {
|
||||||
|
artUnlock(frmHandles[index]);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char* windowBuffer = windowGetBuffer(win);
|
||||||
|
memcpy(windowBuffer, frmBuffers[FILE_DIALOG_FRM_BACKGROUND], backgroundWidth * backgroundHeight);
|
||||||
|
|
||||||
|
MessageList messageList;
|
||||||
|
MessageListItem messageListItem;
|
||||||
|
|
||||||
|
if (!messageListInit(&messageList)) {
|
||||||
|
windowDestroy(win);
|
||||||
|
|
||||||
|
for (int index = 0; index < FILE_DIALOG_FRM_COUNT; index++) {
|
||||||
|
artUnlock(frmHandles[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char path[COMPAT_MAX_PATH];
|
||||||
|
sprintf(path, "%s%s", asc_5186C8, "DBOX.MSG");
|
||||||
|
|
||||||
|
if (!messageListLoad(&messageList, path)) {
|
||||||
|
windowDestroy(win);
|
||||||
|
|
||||||
|
for (int index = 0; index < FILE_DIALOG_FRM_COUNT; index++) {
|
||||||
|
artUnlock(frmHandles[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fontSetCurrent(103);
|
||||||
|
|
||||||
|
// DONE
|
||||||
|
const char* done = getmsg(&messageList, &messageListItem, 100);
|
||||||
|
fontDrawText(windowBuffer + backgroundWidth * SAVE_FILE_DIALOG_DONE_LABEL_Y + SAVE_FILE_DIALOG_DONE_LABEL_X, done, backgroundWidth, backgroundWidth, _colorTable[18979]);
|
||||||
|
|
||||||
|
// CANCEL
|
||||||
|
const char* cancel = getmsg(&messageList, &messageListItem, 103);
|
||||||
|
fontDrawText(windowBuffer + backgroundWidth * SAVE_FILE_DIALOG_CANCEL_LABEL_Y + SAVE_FILE_DIALOG_CANCEL_LABEL_X, cancel, backgroundWidth, backgroundWidth, _colorTable[18979]);
|
||||||
|
|
||||||
|
int doneBtn = buttonCreate(win,
|
||||||
|
SAVE_FILE_DIALOG_DONE_BUTTON_X,
|
||||||
|
SAVE_FILE_DIALOG_DONE_BUTTON_Y,
|
||||||
|
frmSizes[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].width,
|
||||||
|
frmSizes[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].height,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
500,
|
||||||
|
frmBuffers[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_NORMAL],
|
||||||
|
frmBuffers[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED],
|
||||||
|
NULL,
|
||||||
|
BUTTON_FLAG_TRANSPARENT);
|
||||||
|
if (doneBtn != -1) {
|
||||||
|
buttonSetCallbacks(doneBtn, _gsound_red_butt_press, _gsound_red_butt_release);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cancelBtn = buttonCreate(win,
|
||||||
|
SAVE_FILE_DIALOG_CANCEL_BUTTON_X,
|
||||||
|
SAVE_FILE_DIALOG_CANCEL_BUTTON_Y,
|
||||||
|
frmSizes[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].width,
|
||||||
|
frmSizes[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].height,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
501,
|
||||||
|
frmBuffers[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_NORMAL],
|
||||||
|
frmBuffers[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED],
|
||||||
|
NULL,
|
||||||
|
BUTTON_FLAG_TRANSPARENT);
|
||||||
|
if (cancelBtn != -1) {
|
||||||
|
buttonSetCallbacks(cancelBtn, _gsound_red_butt_press, _gsound_red_butt_release);
|
||||||
|
}
|
||||||
|
|
||||||
|
int scrollUpBtn = buttonCreate(win,
|
||||||
|
FILE_DIALOG_SCROLL_BUTTON_X,
|
||||||
|
FILE_DIALOG_SCROLL_BUTTON_Y,
|
||||||
|
frmSizes[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED].width,
|
||||||
|
frmSizes[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED].height,
|
||||||
|
-1,
|
||||||
|
505,
|
||||||
|
506,
|
||||||
|
505,
|
||||||
|
frmBuffers[FILE_DIALOG_FRM_SCROLL_UP_ARROW_NORMAL],
|
||||||
|
frmBuffers[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED],
|
||||||
|
NULL,
|
||||||
|
BUTTON_FLAG_TRANSPARENT);
|
||||||
|
if (scrollUpBtn != -1) {
|
||||||
|
buttonSetCallbacks(cancelBtn, _gsound_red_butt_press, _gsound_red_butt_release);
|
||||||
|
}
|
||||||
|
|
||||||
|
int scrollDownButton = buttonCreate(win,
|
||||||
|
FILE_DIALOG_SCROLL_BUTTON_X,
|
||||||
|
FILE_DIALOG_SCROLL_BUTTON_Y + frmSizes[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED].height,
|
||||||
|
frmSizes[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_PRESSED].width,
|
||||||
|
frmSizes[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_PRESSED].height,
|
||||||
|
-1,
|
||||||
|
503,
|
||||||
|
504,
|
||||||
|
503,
|
||||||
|
frmBuffers[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_NORMAL],
|
||||||
|
frmBuffers[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_PRESSED],
|
||||||
|
NULL,
|
||||||
|
BUTTON_FLAG_TRANSPARENT);
|
||||||
|
if (scrollUpBtn != -1) {
|
||||||
|
buttonSetCallbacks(cancelBtn, _gsound_red_butt_press, _gsound_red_butt_release);
|
||||||
|
}
|
||||||
|
|
||||||
|
buttonCreate(
|
||||||
|
win,
|
||||||
|
FILE_DIALOG_FILE_LIST_X,
|
||||||
|
FILE_DIALOG_FILE_LIST_Y,
|
||||||
|
FILE_DIALOG_FILE_LIST_WIDTH,
|
||||||
|
FILE_DIALOG_FILE_LIST_HEIGHT,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
502,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
0);
|
||||||
|
|
||||||
|
if (title != NULL) {
|
||||||
|
fontDrawText(windowBuffer + backgroundWidth * FILE_DIALOG_TITLE_Y + FILE_DIALOG_TITLE_X, title, backgroundWidth, backgroundWidth, _colorTable[18979]);
|
||||||
|
}
|
||||||
|
|
||||||
|
fontSetCurrent(101);
|
||||||
|
|
||||||
|
int cursorHeight = fontGetLineHeight();
|
||||||
|
int cursorWidth = fontGetStringWidth("_") - 4;
|
||||||
|
fileDialogRenderFileList(windowBuffer, fileList, pageOffset, fileListLength, selectedFileIndex, backgroundWidth);
|
||||||
|
|
||||||
|
int fileNameLength = 0;
|
||||||
|
char* pch = dest;
|
||||||
|
while (*pch != '\0' && *pch != '.') {
|
||||||
|
fileNameLength++;
|
||||||
|
if (fileNameLength >= 12) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dest[fileNameLength] = '\0';
|
||||||
|
|
||||||
|
char fileNameCopy[32];
|
||||||
|
strncpy(fileNameCopy, dest, 32);
|
||||||
|
|
||||||
|
int fileNameCopyLength = strlen(fileNameCopy);
|
||||||
|
fileNameCopy[fileNameCopyLength + 1] = '\0';
|
||||||
|
fileNameCopy[fileNameCopyLength] = ' ';
|
||||||
|
|
||||||
|
unsigned char* fileNameBufferPtr = windowBuffer + backgroundWidth * 190 + 57;
|
||||||
|
|
||||||
|
bufferFill(fileNameBufferPtr, fontGetStringWidth(fileNameCopy), cursorHeight, backgroundWidth, 100);
|
||||||
|
fontDrawText(fileNameBufferPtr, fileNameCopy, backgroundWidth, backgroundWidth, _colorTable[992]);
|
||||||
|
|
||||||
|
windowRefresh(win);
|
||||||
|
|
||||||
|
int blinkingCounter = 3;
|
||||||
|
bool blink = false;
|
||||||
|
|
||||||
|
int doubleClickSelectedFileIndex = -2;
|
||||||
|
int doubleClickTimer = FILE_DIALOG_DOUBLE_CLICK_DELAY;
|
||||||
|
|
||||||
|
int rc = -1;
|
||||||
|
while (rc == -1) {
|
||||||
|
unsigned int tick = _get_time();
|
||||||
|
int keyCode = _get_input();
|
||||||
|
int scrollDirection = FILE_DIALOG_SCROLL_DIRECTION_NONE;
|
||||||
|
int scrollCounter = 0;
|
||||||
|
bool isScrolling = false;
|
||||||
|
|
||||||
|
if (keyCode == 500) {
|
||||||
|
rc = 0;
|
||||||
|
} else if (keyCode == KEY_RETURN) {
|
||||||
|
soundPlayFile("ib1p1xx1");
|
||||||
|
rc = 0;
|
||||||
|
} else if (keyCode == 501 || keyCode == KEY_ESCAPE) {
|
||||||
|
rc = 1;
|
||||||
|
} else if ((keyCode == KEY_DELETE || keyCode == KEY_BACKSPACE) && fileNameCopyLength > 0) {
|
||||||
|
bufferFill(fileNameBufferPtr, fontGetStringWidth(fileNameCopy), cursorHeight, backgroundWidth, 100);
|
||||||
|
fileNameCopy[fileNameCopyLength - 1] = ' ';
|
||||||
|
fileNameCopy[fileNameCopyLength] = '\0';
|
||||||
|
fontDrawText(fileNameBufferPtr, fileNameCopy, backgroundWidth, backgroundWidth, _colorTable[992]);
|
||||||
|
fileNameCopyLength--;
|
||||||
|
windowRefresh(win);
|
||||||
|
} else if (keyCode < KEY_FIRST_INPUT_CHARACTER || keyCode > KEY_LAST_INPUT_CHARACTER || fileNameCopyLength >= 8) {
|
||||||
|
if (keyCode == 502 && fileListLength != 0) {
|
||||||
|
int mouseX;
|
||||||
|
int mouseY;
|
||||||
|
mouseGetPosition(&mouseX, &mouseY);
|
||||||
|
|
||||||
|
int selectedLine = (mouseY - y - FILE_DIALOG_FILE_LIST_Y) / fontGetLineHeight();
|
||||||
|
if (selectedLine - 1 < 0) {
|
||||||
|
selectedLine = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isScrollable || selectedLine < fileListLength) {
|
||||||
|
if (selectedLine >= FILE_DIALOG_LINE_COUNT) {
|
||||||
|
selectedLine = FILE_DIALOG_LINE_COUNT - 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
selectedLine = fileListLength - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedFileIndex = selectedLine;
|
||||||
|
if (selectedFileIndex == doubleClickSelectedFileIndex) {
|
||||||
|
soundPlayFile("ib1p1xx1");
|
||||||
|
strncpy(dest, fileList[selectedFileIndex + pageOffset], 16);
|
||||||
|
|
||||||
|
int index;
|
||||||
|
for (index = 0; index < 12; index++) {
|
||||||
|
if (dest[index] == '.' || dest[index] == '\0') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dest[index] = '\0';
|
||||||
|
rc = 2;
|
||||||
|
} else {
|
||||||
|
doubleClickSelectedFileIndex = selectedFileIndex;
|
||||||
|
bufferFill(fileNameBufferPtr, fontGetStringWidth(fileNameCopy), cursorHeight, backgroundWidth, 100);
|
||||||
|
strncpy(fileNameCopy, fileList[selectedFileIndex + pageOffset], 16);
|
||||||
|
|
||||||
|
int index;
|
||||||
|
for (index = 0; index < 12; index++) {
|
||||||
|
if (fileNameCopy[index] == '.' || fileNameCopy[index] == '\0') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fileNameCopy[index] = '\0';
|
||||||
|
fileNameCopyLength = strlen(fileNameCopy);
|
||||||
|
fileNameCopy[fileNameCopyLength] = ' ';
|
||||||
|
fileNameCopy[fileNameCopyLength + 1] = '\0';
|
||||||
|
|
||||||
|
fontDrawText(fileNameBufferPtr, fileNameCopy, backgroundWidth, backgroundWidth, _colorTable[992]);
|
||||||
|
fileDialogRenderFileList(windowBuffer, fileList, pageOffset, fileListLength, selectedFileIndex, backgroundWidth);
|
||||||
|
}
|
||||||
|
} else if (keyCode == 506) {
|
||||||
|
scrollDirection = FILE_DIALOG_SCROLL_DIRECTION_UP;
|
||||||
|
} else if (keyCode == 504) {
|
||||||
|
scrollDirection = FILE_DIALOG_SCROLL_DIRECTION_DOWN;
|
||||||
|
} else {
|
||||||
|
switch (keyCode) {
|
||||||
|
case KEY_ARROW_UP:
|
||||||
|
pageOffset--;
|
||||||
|
if (pageOffset < 0) {
|
||||||
|
selectedFileIndex--;
|
||||||
|
if (selectedFileIndex < 0) {
|
||||||
|
selectedFileIndex = 0;
|
||||||
|
}
|
||||||
|
pageOffset = 0;
|
||||||
|
}
|
||||||
|
fileDialogRenderFileList(windowBuffer, fileList, pageOffset, fileListLength, selectedFileIndex, backgroundWidth);
|
||||||
|
doubleClickSelectedFileIndex = -2;
|
||||||
|
break;
|
||||||
|
case KEY_ARROW_DOWN:
|
||||||
|
if (isScrollable) {
|
||||||
|
pageOffset++;
|
||||||
|
if (pageOffset >= maxPageOffset) {
|
||||||
|
selectedFileIndex++;
|
||||||
|
if (selectedFileIndex >= FILE_DIALOG_LINE_COUNT) {
|
||||||
|
selectedFileIndex = FILE_DIALOG_LINE_COUNT - 1;
|
||||||
|
}
|
||||||
|
pageOffset = maxPageOffset;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
selectedFileIndex++;
|
||||||
|
if (selectedFileIndex > maxPageOffset) {
|
||||||
|
selectedFileIndex = maxPageOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fileDialogRenderFileList(windowBuffer, fileList, pageOffset, fileListLength, selectedFileIndex, backgroundWidth);
|
||||||
|
doubleClickSelectedFileIndex = -2;
|
||||||
|
break;
|
||||||
|
case KEY_HOME:
|
||||||
|
selectedFileIndex = 0;
|
||||||
|
pageOffset = 0;
|
||||||
|
fileDialogRenderFileList(windowBuffer, fileList, pageOffset, fileListLength, selectedFileIndex, backgroundWidth);
|
||||||
|
doubleClickSelectedFileIndex = -2;
|
||||||
|
break;
|
||||||
|
case KEY_END:
|
||||||
|
if (isScrollable) {
|
||||||
|
selectedFileIndex = 11;
|
||||||
|
pageOffset = maxPageOffset;
|
||||||
|
} else {
|
||||||
|
selectedFileIndex = maxPageOffset;
|
||||||
|
pageOffset = 0;
|
||||||
|
}
|
||||||
|
fileDialogRenderFileList(windowBuffer, fileList, pageOffset, fileListLength, selectedFileIndex, backgroundWidth);
|
||||||
|
doubleClickSelectedFileIndex = -2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (_isdoschar(keyCode)) {
|
||||||
|
bufferFill(fileNameBufferPtr, fontGetStringWidth(fileNameCopy), cursorHeight, backgroundWidth, 100);
|
||||||
|
|
||||||
|
fileNameCopy[fileNameCopyLength] = keyCode & 0xFF;
|
||||||
|
fileNameCopy[fileNameCopyLength + 1] = ' ';
|
||||||
|
fileNameCopy[fileNameCopyLength + 2] = '\0';
|
||||||
|
fontDrawText(fileNameBufferPtr, fileNameCopy, backgroundWidth, backgroundWidth, _colorTable[992]);
|
||||||
|
fileNameCopyLength++;
|
||||||
|
|
||||||
|
windowRefresh(win);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scrollDirection != FILE_DIALOG_SCROLL_DIRECTION_NONE) {
|
||||||
|
unsigned int scrollDelay = 4;
|
||||||
|
doubleClickSelectedFileIndex = -2;
|
||||||
|
while (1) {
|
||||||
|
unsigned int scrollTick = _get_time();
|
||||||
|
scrollCounter += 1;
|
||||||
|
if ((!isScrolling && scrollCounter == 1) || (isScrolling && scrollCounter > 14.4)) {
|
||||||
|
isScrolling = true;
|
||||||
|
|
||||||
|
if (scrollCounter > 14.4) {
|
||||||
|
scrollDelay += 1;
|
||||||
|
if (scrollDelay > 24) {
|
||||||
|
scrollDelay = 24;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scrollDirection == FILE_DIALOG_SCROLL_DIRECTION_UP) {
|
||||||
|
pageOffset--;
|
||||||
|
if (pageOffset < 0) {
|
||||||
|
selectedFileIndex--;
|
||||||
|
if (selectedFileIndex < 0) {
|
||||||
|
selectedFileIndex = 0;
|
||||||
|
}
|
||||||
|
pageOffset = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (isScrollable) {
|
||||||
|
pageOffset++;
|
||||||
|
if (pageOffset > maxPageOffset) {
|
||||||
|
selectedFileIndex++;
|
||||||
|
if (selectedFileIndex >= FILE_DIALOG_LINE_COUNT) {
|
||||||
|
selectedFileIndex = FILE_DIALOG_LINE_COUNT - 1;
|
||||||
|
}
|
||||||
|
pageOffset = maxPageOffset;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
selectedFileIndex++;
|
||||||
|
if (selectedFileIndex > maxPageOffset) {
|
||||||
|
selectedFileIndex = maxPageOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fileDialogRenderFileList(windowBuffer, fileList, pageOffset, fileListLength, selectedFileIndex, backgroundWidth);
|
||||||
|
windowRefresh(win);
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: Original code is slightly different. For unknown reason
|
||||||
|
// entire blinking stuff is placed into two different branches,
|
||||||
|
// which only differs by amount of delay. Probably result of
|
||||||
|
// using large blinking macro as there are no traces of inlined
|
||||||
|
// function.
|
||||||
|
blinkingCounter -= 1;
|
||||||
|
if (blinkingCounter == 0) {
|
||||||
|
blinkingCounter = 3;
|
||||||
|
|
||||||
|
int color = blink ? 100 : _colorTable[992];
|
||||||
|
blink = !blink;
|
||||||
|
|
||||||
|
bufferFill(fileNameBufferPtr + fontGetStringWidth(fileNameCopy) - cursorWidth, cursorWidth, cursorHeight - 2, backgroundWidth, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Missing windowRefresh makes blinking useless.
|
||||||
|
|
||||||
|
unsigned int delay = (scrollCounter > 14.4) ? 1000 / scrollDelay : 1000 / 24;
|
||||||
|
while (getTicksSince(scrollTick) < delay) {
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_game_user_wants_to_quit != 0) {
|
||||||
|
rc = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int key = _get_input();
|
||||||
|
if (key == 505 || key == 503) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
blinkingCounter -= 1;
|
||||||
|
if (blinkingCounter == 0) {
|
||||||
|
blinkingCounter = 3;
|
||||||
|
|
||||||
|
int color = blink ? 100 : _colorTable[992];
|
||||||
|
blink = !blink;
|
||||||
|
|
||||||
|
bufferFill(fileNameBufferPtr + fontGetStringWidth(fileNameCopy) - cursorWidth, cursorWidth, cursorHeight - 2, backgroundWidth, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
windowRefresh(win);
|
||||||
|
|
||||||
|
doubleClickTimer--;
|
||||||
|
if (doubleClickTimer == 0) {
|
||||||
|
doubleClickTimer = FILE_DIALOG_DOUBLE_CLICK_DELAY;
|
||||||
|
doubleClickSelectedFileIndex = -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (getTicksSince(tick) < (1000 / 24)) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_game_user_wants_to_quit != 0) {
|
||||||
|
rc = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc == 0) {
|
||||||
|
if (fileNameCopyLength != 0) {
|
||||||
|
fileNameCopy[fileNameCopyLength] = '\0';
|
||||||
|
strcpy(dest, fileNameCopy);
|
||||||
|
} else {
|
||||||
|
rc = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (rc == 2) {
|
||||||
|
rc = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
windowDestroy(win);
|
||||||
|
|
||||||
|
for (int index = 0; index < FILE_DIALOG_FRM_COUNT; index++) {
|
||||||
|
artUnlock(frmHandles[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
messageListFree(&messageList);
|
||||||
|
fontSetCurrent(oldFont);
|
||||||
|
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x41FBDC
|
// 0x41FBDC
|
||||||
void _PrntFlist(unsigned char* buffer, char** fileList, int pageOffset, int fileListLength, int selectedIndex, int pitch)
|
void fileDialogRenderFileList(unsigned char* buffer, char** fileList, int pageOffset, int fileListLength, int selectedIndex, int pitch)
|
||||||
{
|
{
|
||||||
int lineHeight = fontGetLineHeight();
|
int lineHeight = fontGetLineHeight();
|
||||||
int y = 49;
|
int y = FILE_DIALOG_FILE_LIST_Y;
|
||||||
bufferFill(buffer + y * pitch + 55, 190, 124, pitch, 100);
|
bufferFill(buffer + y * pitch + FILE_DIALOG_FILE_LIST_X, FILE_DIALOG_FILE_LIST_WIDTH, FILE_DIALOG_FILE_LIST_HEIGHT, pitch, 100);
|
||||||
if (fileListLength != 0) {
|
if (fileListLength != 0) {
|
||||||
if (fileListLength - pageOffset > 12) {
|
if (fileListLength - pageOffset > FILE_DIALOG_LINE_COUNT) {
|
||||||
fileListLength = 12;
|
fileListLength = FILE_DIALOG_LINE_COUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int index = 0; index < fileListLength; index++) {
|
for (int index = 0; index < fileListLength; index++) {
|
||||||
int color = index == selectedIndex ? _colorTable[32747] : _colorTable[992];
|
int color = index == selectedIndex ? _colorTable[32747] : _colorTable[992];
|
||||||
fontDrawText(buffer + y * index + 55, fileList[index], pitch, pitch, color);
|
fontDrawText(buffer + pitch * y + FILE_DIALOG_FILE_LIST_X, fileList[pageOffset + index], pitch, pitch, color);
|
||||||
y += lineHeight;
|
y += lineHeight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
26
src/dbox.h
26
src/dbox.h
|
@ -16,17 +16,35 @@ typedef enum DialogType {
|
||||||
DIALOG_TYPE_COUNT,
|
DIALOG_TYPE_COUNT,
|
||||||
} DialogType;
|
} DialogType;
|
||||||
|
|
||||||
|
typedef enum FileDialogFrm {
|
||||||
|
FILE_DIALOG_FRM_BACKGROUND,
|
||||||
|
FILE_DIALOG_FRM_LITTLE_RED_BUTTON_NORMAL,
|
||||||
|
FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED,
|
||||||
|
FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_NORMAL,
|
||||||
|
FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_PRESSED,
|
||||||
|
FILE_DIALOG_FRM_SCROLL_UP_ARROW_NORMAL,
|
||||||
|
FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED,
|
||||||
|
FILE_DIALOG_FRM_COUNT,
|
||||||
|
} FileDialogFrm;
|
||||||
|
|
||||||
|
typedef enum FileDialogScrollDirection {
|
||||||
|
FILE_DIALOG_SCROLL_DIRECTION_NONE,
|
||||||
|
FILE_DIALOG_SCROLL_DIRECTION_UP,
|
||||||
|
FILE_DIALOG_SCROLL_DIRECTION_DOWN,
|
||||||
|
} FileDialogScrollDirection;
|
||||||
|
|
||||||
extern const int gDialogBoxBackgroundFrmIds[DIALOG_TYPE_COUNT];
|
extern const int gDialogBoxBackgroundFrmIds[DIALOG_TYPE_COUNT];
|
||||||
extern const int _ytable[DIALOG_TYPE_COUNT];
|
extern const int _ytable[DIALOG_TYPE_COUNT];
|
||||||
extern const int _xtable[DIALOG_TYPE_COUNT];
|
extern const int _xtable[DIALOG_TYPE_COUNT];
|
||||||
extern const int _doneY[DIALOG_TYPE_COUNT];
|
extern const int _doneY[DIALOG_TYPE_COUNT];
|
||||||
extern const int _doneX[DIALOG_TYPE_COUNT];
|
extern const int _doneX[DIALOG_TYPE_COUNT];
|
||||||
extern const int _dblines[DIALOG_TYPE_COUNT];
|
extern const int _dblines[DIALOG_TYPE_COUNT];
|
||||||
extern int _flgids[7];
|
extern int gLoadFileDialogFrmIds[FILE_DIALOG_FRM_COUNT];
|
||||||
extern int _flgids2[7];
|
extern int gSaveFileDialogFrmIds[FILE_DIALOG_FRM_COUNT];
|
||||||
|
|
||||||
int showDialogBox(const char* title, const char** body, int bodyLength, int x, int y, int titleColor, const char* a8, int bodyColor, int flags);
|
int showDialogBox(const char* title, const char** body, int bodyLength, int x, int y, int titleColor, const char* a8, int bodyColor, int flags);
|
||||||
int _save_file_dialog(char* a1, char** fileList, char* fileName, int fileListLength, int x, int y, int flags);
|
int showLoadFileDialog(char* title, char** fileList, char* dest, int fileListLength, int x, int y, int flags);
|
||||||
void _PrntFlist(unsigned char* buffer, char** fileList, int pageOffset, int fileListLength, int selectedIndex, int pitch);
|
int showSaveFileDialog(char* title, char** fileList, char* dest, int fileListLength, int x, int y, int flags);
|
||||||
|
void fileDialogRenderFileList(unsigned char* buffer, char** fileList, int pageOffset, int fileListLength, int selectedIndex, int pitch);
|
||||||
|
|
||||||
#endif /* DBOX_H */
|
#endif /* DBOX_H */
|
||||||
|
|
|
@ -142,7 +142,7 @@ int debugPrint(const char* format, ...)
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
OutputDebugStringA(string);
|
OutputDebugStringA(string);
|
||||||
#else
|
#else
|
||||||
printf(string);
|
printf("%s", string);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
rc = -1;
|
rc = -1;
|
||||||
|
|
|
@ -493,7 +493,12 @@ int endgameEndingSlideshowWindowInit()
|
||||||
|
|
||||||
int windowEndgameEndingX = (screenGetWidth() - ENDGAME_ENDING_WINDOW_WIDTH) / 2;
|
int windowEndgameEndingX = (screenGetWidth() - ENDGAME_ENDING_WINDOW_WIDTH) / 2;
|
||||||
int windowEndgameEndingY = (screenGetHeight() - ENDGAME_ENDING_WINDOW_HEIGHT) / 2;
|
int windowEndgameEndingY = (screenGetHeight() - ENDGAME_ENDING_WINDOW_HEIGHT) / 2;
|
||||||
gEndgameEndingSlideshowWindow = windowCreate(windowEndgameEndingX, windowEndgameEndingY, ENDGAME_ENDING_WINDOW_WIDTH, ENDGAME_ENDING_WINDOW_HEIGHT, _colorTable[0], 4);
|
gEndgameEndingSlideshowWindow = windowCreate(windowEndgameEndingX,
|
||||||
|
windowEndgameEndingY,
|
||||||
|
ENDGAME_ENDING_WINDOW_WIDTH,
|
||||||
|
ENDGAME_ENDING_WINDOW_HEIGHT,
|
||||||
|
_colorTable[0],
|
||||||
|
WINDOW_FLAG_0x04);
|
||||||
if (gEndgameEndingSlideshowWindow == -1) {
|
if (gEndgameEndingSlideshowWindow == -1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
30
src/game.cc
30
src/game.cc
|
@ -155,7 +155,11 @@ int gameInitWithOptions(const char* windowTitle, bool isMapper, int font, int a4
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gIsMapper) {
|
// SFALL: Allow to skip splash screen
|
||||||
|
int skipOpeningMovies = 0;
|
||||||
|
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_SKIP_OPENING_MOVIES_KEY, &skipOpeningMovies);
|
||||||
|
|
||||||
|
if (!gIsMapper && skipOpeningMovies < 2) {
|
||||||
showSplash();
|
showSplash();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,7 +267,7 @@ int gameInitWithOptions(const char* windowTitle, bool isMapper, int font, int a4
|
||||||
|
|
||||||
debugPrint(">wmWorldMap_init\t");
|
debugPrint(">wmWorldMap_init\t");
|
||||||
|
|
||||||
_CharEditInit();
|
characterEditorInit();
|
||||||
debugPrint(">CharEditInit\t");
|
debugPrint(">CharEditInit\t");
|
||||||
|
|
||||||
pipboyInit();
|
pipboyInit();
|
||||||
|
@ -363,7 +367,7 @@ void gameReset()
|
||||||
scriptsReset();
|
scriptsReset();
|
||||||
worldmapReset();
|
worldmapReset();
|
||||||
partyMembersReset();
|
partyMembersReset();
|
||||||
_CharEditInit();
|
characterEditorInit();
|
||||||
pipboyReset();
|
pipboyReset();
|
||||||
_ResetLoadSave();
|
_ResetLoadSave();
|
||||||
gameDialogReset();
|
gameDialogReset();
|
||||||
|
@ -512,7 +516,7 @@ int gameHandleKey(int eventCode, bool isInCombatMode)
|
||||||
if (interfaceBarEnabled()) {
|
if (interfaceBarEnabled()) {
|
||||||
soundPlayFile("ib1p1xx1");
|
soundPlayFile("ib1p1xx1");
|
||||||
bool isoWasEnabled = isoDisable();
|
bool isoWasEnabled = isoDisable();
|
||||||
_editor_design(false);
|
characterEditorShow(false);
|
||||||
if (isoWasEnabled) {
|
if (isoWasEnabled) {
|
||||||
isoEnable();
|
isoEnable();
|
||||||
}
|
}
|
||||||
|
@ -887,6 +891,24 @@ int gameSetGlobalVar(int var, int value)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SFALL: Display karma changes.
|
||||||
|
if (var == GVAR_PLAYER_REPUTATION) {
|
||||||
|
bool shouldDisplayKarmaChanges = false;
|
||||||
|
configGetBool(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_DISPLAY_KARMA_CHANGES_KEY, &shouldDisplayKarmaChanges);
|
||||||
|
if (shouldDisplayKarmaChanges) {
|
||||||
|
int diff = value - gGameGlobalVars[var];
|
||||||
|
if (diff != 0) {
|
||||||
|
char formattedMessage[80];
|
||||||
|
if (diff > 0) {
|
||||||
|
sprintf(formattedMessage, "You gained %d karma.", diff);
|
||||||
|
} else {
|
||||||
|
sprintf(formattedMessage, "You lost %d karma.", -diff);
|
||||||
|
}
|
||||||
|
displayMonitorAddMessage(formattedMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gGameGlobalVars[var] = value;
|
gGameGlobalVars[var] = value;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -571,7 +571,7 @@ void gameDialogEnter(Object* a1, int a2)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((a1->pid >> 24) != OBJ_TYPE_ITEM && (a1->pid >> 24) != OBJ_TYPE_CRITTER) {
|
if ((a1->pid >> 24) != OBJ_TYPE_ITEM && (a1->sid >> 24) != SCRIPT_TYPE_SPATIAL) {
|
||||||
MessageListItem messageListItem;
|
MessageListItem messageListItem;
|
||||||
|
|
||||||
int rc = _action_can_talk_to(gDude, a1);
|
int rc = _action_can_talk_to(gDude, a1);
|
||||||
|
@ -1142,7 +1142,12 @@ int gameDialogReviewWindowInit(int* win)
|
||||||
|
|
||||||
int reviewWindowX = (screenGetWidth() - GAME_DIALOG_REVIEW_WINDOW_WIDTH) / 2;
|
int reviewWindowX = (screenGetWidth() - GAME_DIALOG_REVIEW_WINDOW_WIDTH) / 2;
|
||||||
int reviewWindowY = (screenGetHeight() - GAME_DIALOG_REVIEW_WINDOW_HEIGHT) / 2;
|
int reviewWindowY = (screenGetHeight() - GAME_DIALOG_REVIEW_WINDOW_HEIGHT) / 2;
|
||||||
*win = windowCreate(reviewWindowX, reviewWindowY, GAME_DIALOG_REVIEW_WINDOW_WIDTH, GAME_DIALOG_REVIEW_WINDOW_HEIGHT, 256, WINDOW_FLAG_0x10 | WINDOW_FLAG_0x04);
|
*win = windowCreate(reviewWindowX,
|
||||||
|
reviewWindowY,
|
||||||
|
GAME_DIALOG_REVIEW_WINDOW_WIDTH,
|
||||||
|
GAME_DIALOG_REVIEW_WINDOW_HEIGHT,
|
||||||
|
256,
|
||||||
|
WINDOW_FLAG_0x10 | WINDOW_FLAG_0x04);
|
||||||
if (*win == -1) {
|
if (*win == -1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1548,7 +1553,12 @@ int _gdProcessInit()
|
||||||
|
|
||||||
int replyWindowX = (screenGetWidth() - GAME_DIALOG_WINDOW_WIDTH) / 2 + GAME_DIALOG_REPLY_WINDOW_X;
|
int replyWindowX = (screenGetWidth() - GAME_DIALOG_WINDOW_WIDTH) / 2 + GAME_DIALOG_REPLY_WINDOW_X;
|
||||||
int replyWindowY = (screenGetHeight() - GAME_DIALOG_WINDOW_HEIGHT) / 2 + GAME_DIALOG_REPLY_WINDOW_Y;
|
int replyWindowY = (screenGetHeight() - GAME_DIALOG_WINDOW_HEIGHT) / 2 + GAME_DIALOG_REPLY_WINDOW_Y;
|
||||||
gGameDialogReplyWindow = windowCreate(replyWindowX, replyWindowY, GAME_DIALOG_REPLY_WINDOW_WIDTH, GAME_DIALOG_REPLY_WINDOW_HEIGHT, 256, WINDOW_FLAG_0x04);
|
gGameDialogReplyWindow = windowCreate(replyWindowX,
|
||||||
|
replyWindowY,
|
||||||
|
GAME_DIALOG_REPLY_WINDOW_WIDTH,
|
||||||
|
GAME_DIALOG_REPLY_WINDOW_HEIGHT,
|
||||||
|
256,
|
||||||
|
WINDOW_FLAG_0x04);
|
||||||
if (gGameDialogReplyWindow == -1) {
|
if (gGameDialogReplyWindow == -1) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
@ -2174,7 +2184,12 @@ int _gdCreateHeadWindow()
|
||||||
|
|
||||||
int backgroundWindowX = (screenGetWidth() - GAME_DIALOG_WINDOW_WIDTH) / 2;
|
int backgroundWindowX = (screenGetWidth() - GAME_DIALOG_WINDOW_WIDTH) / 2;
|
||||||
int backgroundWindowY = (screenGetHeight() - GAME_DIALOG_WINDOW_HEIGHT) / 2;
|
int backgroundWindowY = (screenGetHeight() - GAME_DIALOG_WINDOW_HEIGHT) / 2;
|
||||||
gGameDialogBackgroundWindow = windowCreate(backgroundWindowX, backgroundWindowY, windowWidth, GAME_DIALOG_WINDOW_HEIGHT, 256, WINDOW_FLAG_0x02);
|
gGameDialogBackgroundWindow = windowCreate(backgroundWindowX,
|
||||||
|
backgroundWindowY,
|
||||||
|
windowWidth,
|
||||||
|
GAME_DIALOG_WINDOW_HEIGHT,
|
||||||
|
256,
|
||||||
|
WINDOW_FLAG_0x02);
|
||||||
gameDialogWindowRenderBackground();
|
gameDialogWindowRenderBackground();
|
||||||
|
|
||||||
unsigned char* buf = windowGetBuffer(gGameDialogBackgroundWindow);
|
unsigned char* buf = windowGetBuffer(gGameDialogBackgroundWindow);
|
||||||
|
@ -2594,6 +2609,9 @@ void gameDialogTicker()
|
||||||
|
|
||||||
if (_gd_optionsWin != -1) {
|
if (_gd_optionsWin != -1) {
|
||||||
windowUnhide(_gd_optionsWin);
|
windowUnhide(_gd_optionsWin);
|
||||||
|
// SFALL: Fix for the player's money not being displayed in the
|
||||||
|
// dialog window after leaving the barter/combat control interface.
|
||||||
|
gameDialogRenderCaps();
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -2980,7 +2998,12 @@ int _gdialog_barter_create_win()
|
||||||
|
|
||||||
int barterWindowX = (screenGetWidth() - GAME_DIALOG_WINDOW_WIDTH) / 2;
|
int barterWindowX = (screenGetWidth() - GAME_DIALOG_WINDOW_WIDTH) / 2;
|
||||||
int barterWindowY = (screenGetHeight() - GAME_DIALOG_WINDOW_HEIGHT) / 2 + GAME_DIALOG_WINDOW_HEIGHT - _dialogue_subwin_len;
|
int barterWindowY = (screenGetHeight() - GAME_DIALOG_WINDOW_HEIGHT) / 2 + GAME_DIALOG_WINDOW_HEIGHT - _dialogue_subwin_len;
|
||||||
gGameDialogWindow = windowCreate(barterWindowX, barterWindowY, GAME_DIALOG_WINDOW_WIDTH, _dialogue_subwin_len, 256, WINDOW_FLAG_0x02);
|
gGameDialogWindow = windowCreate(barterWindowX,
|
||||||
|
barterWindowY,
|
||||||
|
GAME_DIALOG_WINDOW_WIDTH,
|
||||||
|
_dialogue_subwin_len,
|
||||||
|
256,
|
||||||
|
WINDOW_FLAG_0x02);
|
||||||
if (gGameDialogWindow == -1) {
|
if (gGameDialogWindow == -1) {
|
||||||
artUnlock(backgroundHandle);
|
artUnlock(backgroundHandle);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -3133,7 +3156,12 @@ int partyMemberControlWindowInit()
|
||||||
_dialogue_subwin_len = artGetHeight(backgroundFrm, 0, 0);
|
_dialogue_subwin_len = artGetHeight(backgroundFrm, 0, 0);
|
||||||
int controlWindowX = (screenGetWidth() - GAME_DIALOG_WINDOW_WIDTH) / 2;
|
int controlWindowX = (screenGetWidth() - GAME_DIALOG_WINDOW_WIDTH) / 2;
|
||||||
int controlWindowY = (screenGetHeight() - GAME_DIALOG_WINDOW_HEIGHT) / 2 + GAME_DIALOG_WINDOW_HEIGHT - _dialogue_subwin_len;
|
int controlWindowY = (screenGetHeight() - GAME_DIALOG_WINDOW_HEIGHT) / 2 + GAME_DIALOG_WINDOW_HEIGHT - _dialogue_subwin_len;
|
||||||
gGameDialogWindow = windowCreate(controlWindowX, controlWindowY, GAME_DIALOG_WINDOW_WIDTH, _dialogue_subwin_len, 256, WINDOW_FLAG_0x02);
|
gGameDialogWindow = windowCreate(controlWindowX,
|
||||||
|
controlWindowY,
|
||||||
|
GAME_DIALOG_WINDOW_WIDTH,
|
||||||
|
_dialogue_subwin_len,
|
||||||
|
256,
|
||||||
|
WINDOW_FLAG_0x02);
|
||||||
if (gGameDialogWindow == -1) {
|
if (gGameDialogWindow == -1) {
|
||||||
partyMemberControlWindowFree();
|
partyMemberControlWindowFree();
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -3567,7 +3595,12 @@ int partyMemberCustomizationWindowInit()
|
||||||
|
|
||||||
int customizationWindowX = (screenGetWidth() - GAME_DIALOG_WINDOW_WIDTH) / 2;
|
int customizationWindowX = (screenGetWidth() - GAME_DIALOG_WINDOW_WIDTH) / 2;
|
||||||
int customizationWindowY = (screenGetHeight() - GAME_DIALOG_WINDOW_HEIGHT) / 2 + GAME_DIALOG_WINDOW_HEIGHT - _dialogue_subwin_len;
|
int customizationWindowY = (screenGetHeight() - GAME_DIALOG_WINDOW_HEIGHT) / 2 + GAME_DIALOG_WINDOW_HEIGHT - _dialogue_subwin_len;
|
||||||
gGameDialogWindow = windowCreate(customizationWindowX, customizationWindowY, GAME_DIALOG_WINDOW_WIDTH, _dialogue_subwin_len, 256, WINDOW_FLAG_0x02);
|
gGameDialogWindow = windowCreate(customizationWindowX,
|
||||||
|
customizationWindowY,
|
||||||
|
GAME_DIALOG_WINDOW_WIDTH,
|
||||||
|
_dialogue_subwin_len,
|
||||||
|
256,
|
||||||
|
WINDOW_FLAG_0x02);
|
||||||
if (gGameDialogWindow == -1) {
|
if (gGameDialogWindow == -1) {
|
||||||
partyMemberCustomizationWindowFree();
|
partyMemberCustomizationWindowFree();
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -4102,7 +4135,7 @@ int _gdialog_window_create()
|
||||||
|
|
||||||
int dialogSubwindowX = (screenGetWidth() - GAME_DIALOG_WINDOW_WIDTH) / 2;
|
int dialogSubwindowX = (screenGetWidth() - GAME_DIALOG_WINDOW_WIDTH) / 2;
|
||||||
int dialogSubwindowY = (screenGetHeight() - GAME_DIALOG_WINDOW_HEIGHT) / 2 + GAME_DIALOG_WINDOW_HEIGHT - _dialogue_subwin_len;
|
int dialogSubwindowY = (screenGetHeight() - GAME_DIALOG_WINDOW_HEIGHT) / 2 + GAME_DIALOG_WINDOW_HEIGHT - _dialogue_subwin_len;
|
||||||
gGameDialogWindow = windowCreate(dialogSubwindowX, dialogSubwindowY, screenWidth, _dialogue_subwin_len, 256, 2);
|
gGameDialogWindow = windowCreate(dialogSubwindowX, dialogSubwindowY, screenWidth, _dialogue_subwin_len, 256, WINDOW_FLAG_0x02);
|
||||||
if (gGameDialogWindow != -1) {
|
if (gGameDialogWindow != -1) {
|
||||||
|
|
||||||
unsigned char* v10 = windowGetBuffer(gGameDialogWindow);
|
unsigned char* v10 = windowGetBuffer(gGameDialogWindow);
|
||||||
|
@ -4369,11 +4402,19 @@ void gameDialogRenderTalkingHead(Art* headFrm, int frame)
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char* src = windowGetBuffer(gIsoWindow);
|
unsigned char* src = windowGetBuffer(gIsoWindow);
|
||||||
|
|
||||||
|
// Usually rendering functions use `screenGetWidth`/`screenGetHeight` to
|
||||||
|
// determine rendering position. However in this case `windowGetHeight`
|
||||||
|
// is a must because isometric window's height can either include
|
||||||
|
// interface bar or not. Offset is updated accordingly (332 -> 232, the
|
||||||
|
// missing 100 is interface bar height, which is already accounted for
|
||||||
|
// when we're using `windowGetHeight`). `windowGetWidth` is used for
|
||||||
|
// consistency.
|
||||||
blitBufferToBuffer(
|
blitBufferToBuffer(
|
||||||
src + ((GAME_DIALOG_WINDOW_WIDTH - 332) / 2) * (GAME_DIALOG_WINDOW_WIDTH) + (GAME_DIALOG_WINDOW_WIDTH - 388) / 2,
|
src + ((windowGetHeight(gIsoWindow) - 232) / 2) * windowGetWidth(gIsoWindow) + (windowGetWidth(gIsoWindow) - 388) / 2,
|
||||||
388,
|
388,
|
||||||
200,
|
200,
|
||||||
screenGetWidth(),
|
windowGetWidth(gIsoWindow),
|
||||||
gGameDialogDisplayBuffer,
|
gGameDialogDisplayBuffer,
|
||||||
GAME_DIALOG_WINDOW_WIDTH);
|
GAME_DIALOG_WINDOW_WIDTH);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1927,16 +1927,16 @@ int gameMouseObjectsInit()
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
gGameMouseBouncingCursor->flags |= OBJECT_FLAG_0x20000000;
|
gGameMouseBouncingCursor->flags |= OBJECT_LIGHT_THRU;
|
||||||
gGameMouseBouncingCursor->flags |= OBJECT_TEMPORARY;
|
gGameMouseBouncingCursor->flags |= OBJECT_TEMPORARY;
|
||||||
gGameMouseBouncingCursor->flags |= OBJECT_FLAG_0x400;
|
gGameMouseBouncingCursor->flags |= OBJECT_FLAG_0x400;
|
||||||
gGameMouseBouncingCursor->flags |= OBJECT_FLAG_0x80000000;
|
gGameMouseBouncingCursor->flags |= OBJECT_SHOOT_THRU;
|
||||||
gGameMouseBouncingCursor->flags |= OBJECT_NO_BLOCK;
|
gGameMouseBouncingCursor->flags |= OBJECT_NO_BLOCK;
|
||||||
|
|
||||||
gGameMouseHexCursor->flags |= OBJECT_FLAG_0x400;
|
gGameMouseHexCursor->flags |= OBJECT_FLAG_0x400;
|
||||||
gGameMouseHexCursor->flags |= OBJECT_TEMPORARY;
|
gGameMouseHexCursor->flags |= OBJECT_TEMPORARY;
|
||||||
gGameMouseHexCursor->flags |= OBJECT_FLAG_0x20000000;
|
gGameMouseHexCursor->flags |= OBJECT_LIGHT_THRU;
|
||||||
gGameMouseHexCursor->flags |= OBJECT_FLAG_0x80000000;
|
gGameMouseHexCursor->flags |= OBJECT_SHOOT_THRU;
|
||||||
gGameMouseHexCursor->flags |= OBJECT_NO_BLOCK;
|
gGameMouseHexCursor->flags |= OBJECT_NO_BLOCK;
|
||||||
|
|
||||||
_obj_toggle_flat(gGameMouseHexCursor, NULL);
|
_obj_toggle_flat(gGameMouseHexCursor, NULL);
|
||||||
|
|
|
@ -46,7 +46,7 @@ const char* gMovieFileNames[MOVIE_COUNT] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
// 0x518DE4
|
// 0x518DE4
|
||||||
char* gMoviePaletteFilePaths[MOVIE_COUNT] = {
|
const char* gMoviePaletteFilePaths[MOVIE_COUNT] = {
|
||||||
NULL,
|
NULL,
|
||||||
"art\\cuts\\introsub.pal",
|
"art\\cuts\\introsub.pal",
|
||||||
"art\\cuts\\eldersub.pal",
|
"art\\cuts\\eldersub.pal",
|
||||||
|
@ -209,7 +209,7 @@ int gameMoviePlay(int movie, int flags)
|
||||||
int oldTextColor;
|
int oldTextColor;
|
||||||
int oldFont;
|
int oldFont;
|
||||||
if (subtitlesEnabled) {
|
if (subtitlesEnabled) {
|
||||||
char* subtitlesPaletteFilePath;
|
const char* subtitlesPaletteFilePath;
|
||||||
if (gMoviePaletteFilePaths[movie] != NULL) {
|
if (gMoviePaletteFilePaths[movie] != NULL) {
|
||||||
subtitlesPaletteFilePath = gMoviePaletteFilePaths[movie];
|
subtitlesPaletteFilePath = gMoviePaletteFilePaths[movie];
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -35,7 +35,7 @@ typedef enum GameMovie {
|
||||||
extern const float flt_50352A;
|
extern const float flt_50352A;
|
||||||
|
|
||||||
extern const char* gMovieFileNames[MOVIE_COUNT];
|
extern const char* gMovieFileNames[MOVIE_COUNT];
|
||||||
extern char* gMoviePaletteFilePaths[MOVIE_COUNT];
|
extern const char* gMoviePaletteFilePaths[MOVIE_COUNT];
|
||||||
extern bool gGameMovieIsPlaying;
|
extern bool gGameMovieIsPlaying;
|
||||||
extern bool gGameMovieFaded;
|
extern bool gGameMovieFaded;
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,14 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
#define INVENTORY_WINDOW_X 80
|
||||||
|
#define INVENTORY_WINDOW_Y 0
|
||||||
|
|
||||||
|
#define INVENTORY_TRADE_WINDOW_X 80
|
||||||
|
#define INVENTORY_TRADE_WINDOW_Y 290
|
||||||
|
#define INVENTORY_TRADE_WINDOW_WIDTH 480
|
||||||
|
#define INVENTORY_TRADE_WINDOW_HEIGHT 180
|
||||||
|
|
||||||
#define INVENTORY_LARGE_SLOT_WIDTH 90
|
#define INVENTORY_LARGE_SLOT_WIDTH 90
|
||||||
#define INVENTORY_LARGE_SLOT_HEIGHT 61
|
#define INVENTORY_LARGE_SLOT_HEIGHT 61
|
||||||
|
|
||||||
|
@ -550,10 +558,10 @@ bool _setup_inventory(int inventoryWindowType)
|
||||||
// Maintain original position in original resolution, otherwise center it.
|
// Maintain original position in original resolution, otherwise center it.
|
||||||
int inventoryWindowX = screenGetWidth() != 640
|
int inventoryWindowX = screenGetWidth() != 640
|
||||||
? (screenGetWidth() - windowDescription->width) / 2
|
? (screenGetWidth() - windowDescription->width) / 2
|
||||||
: 80;
|
: INVENTORY_WINDOW_X;
|
||||||
int inventoryWindowY = screenGetHeight() != 480
|
int inventoryWindowY = screenGetHeight() != 480
|
||||||
? (screenGetHeight() - windowDescription->height) / 2
|
? (screenGetHeight() - windowDescription->height) / 2
|
||||||
: 0;
|
: INVENTORY_WINDOW_Y;
|
||||||
gInventoryWindow = windowCreate(inventoryWindowX,
|
gInventoryWindow = windowCreate(inventoryWindowX,
|
||||||
inventoryWindowY,
|
inventoryWindowY,
|
||||||
windowDescription->width,
|
windowDescription->width,
|
||||||
|
@ -582,15 +590,15 @@ bool _setup_inventory(int inventoryWindowType)
|
||||||
gInventorySlotsCount = 3;
|
gInventorySlotsCount = 3;
|
||||||
|
|
||||||
// Trade inventory window is a part of game dialog, which is 640x480.
|
// Trade inventory window is a part of game dialog, which is 640x480.
|
||||||
int tradeWindowX = (screenGetWidth() - 640) / 2 + 80;
|
int tradeWindowX = (screenGetWidth() - 640) / 2 + INVENTORY_TRADE_WINDOW_X;
|
||||||
int tradeWindowY = (screenGetHeight() - 480) / 2 + 290;
|
int tradeWindowY = (screenGetHeight() - 480) / 2 + INVENTORY_TRADE_WINDOW_Y;
|
||||||
gInventoryWindow = windowCreate(tradeWindowX, tradeWindowY, 480, 180, 257, 0);
|
gInventoryWindow = windowCreate(tradeWindowX, tradeWindowY, INVENTORY_TRADE_WINDOW_WIDTH, INVENTORY_TRADE_WINDOW_HEIGHT, 257, 0);
|
||||||
gInventoryWindowMaxX = tradeWindowX + 480;
|
gInventoryWindowMaxX = tradeWindowX + INVENTORY_TRADE_WINDOW_WIDTH;
|
||||||
gInventoryWindowMaxY = tradeWindowY + 180;
|
gInventoryWindowMaxY = tradeWindowY + INVENTORY_TRADE_WINDOW_HEIGHT;
|
||||||
|
|
||||||
unsigned char* dest = windowGetBuffer(gInventoryWindow);
|
unsigned char* dest = windowGetBuffer(gInventoryWindow);
|
||||||
unsigned char* src = windowGetBuffer(_barter_back_win);
|
unsigned char* src = windowGetBuffer(_barter_back_win);
|
||||||
blitBufferToBuffer(src + 80, 480, 180, 640, dest, 480);
|
blitBufferToBuffer(src + INVENTORY_TRADE_WINDOW_X, INVENTORY_TRADE_WINDOW_WIDTH, INVENTORY_TRADE_WINDOW_HEIGHT, 640, dest, INVENTORY_TRADE_WINDOW_WIDTH);
|
||||||
|
|
||||||
gInventoryPrintItemDescriptionHandler = gameDialogRenderSupplementaryMessage;
|
gInventoryPrintItemDescriptionHandler = gameDialogRenderSupplementaryMessage;
|
||||||
}
|
}
|
||||||
|
@ -606,7 +614,7 @@ bool _setup_inventory(int inventoryWindowType)
|
||||||
}
|
}
|
||||||
|
|
||||||
int eventCode = 2005;
|
int eventCode = 2005;
|
||||||
int y = INVENTORY_SLOT_HEIGHT * 5 + INVENTORY_SLOT_HEIGHT;
|
int y = INVENTORY_SLOT_HEIGHT * 5 + INVENTORY_LOOT_LEFT_SCROLLER_Y;
|
||||||
|
|
||||||
// Create invisible buttons representing container's inventory item
|
// Create invisible buttons representing container's inventory item
|
||||||
// slots. For unknown reason it loops backwards and it's size is
|
// slots. For unknown reason it loops backwards and it's size is
|
||||||
|
@ -2987,7 +2995,7 @@ void inventoryWindowOpenContextMenu(int keyCode, int inventoryWindowType)
|
||||||
|
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
mouseGetPositionInWindow(gInventoryWindow, &x, &y);
|
mouseGetPosition(&x, &y);
|
||||||
|
|
||||||
int actionMenuItemsLength;
|
int actionMenuItemsLength;
|
||||||
const int* actionMenuItems;
|
const int* actionMenuItems;
|
||||||
|
@ -3035,9 +3043,15 @@ void inventoryWindowOpenContextMenu(int keyCode, int inventoryWindowType)
|
||||||
}
|
}
|
||||||
|
|
||||||
const InventoryWindowDescription* windowDescription = &(gInventoryWindowDescriptions[inventoryWindowType]);
|
const InventoryWindowDescription* windowDescription = &(gInventoryWindowDescriptions[inventoryWindowType]);
|
||||||
|
|
||||||
|
Rect windowRect;
|
||||||
|
windowGetRect(gInventoryWindow, &windowRect);
|
||||||
|
int inventoryWindowX = windowRect.left;
|
||||||
|
int inventoryWindowY = windowRect.top;
|
||||||
|
|
||||||
gameMouseRenderActionMenuItems(x, y, actionMenuItems, actionMenuItemsLength,
|
gameMouseRenderActionMenuItems(x, y, actionMenuItems, actionMenuItemsLength,
|
||||||
windowDescription->width + windowDescription->x,
|
windowDescription->width + inventoryWindowX,
|
||||||
windowDescription->height + windowDescription->y);
|
windowDescription->height + inventoryWindowY);
|
||||||
|
|
||||||
InventoryCursorData* cursorData = &(gInventoryCursorData[INVENTORY_WINDOW_CURSOR_MENU]);
|
InventoryCursorData* cursorData = &(gInventoryCursorData[INVENTORY_WINDOW_CURSOR_MENU]);
|
||||||
|
|
||||||
|
@ -3046,8 +3060,8 @@ void inventoryWindowOpenContextMenu(int keyCode, int inventoryWindowType)
|
||||||
artGetRotationOffsets(cursorData->frm, 0, &offsetX, &offsetY);
|
artGetRotationOffsets(cursorData->frm, 0, &offsetX, &offsetY);
|
||||||
|
|
||||||
Rect rect;
|
Rect rect;
|
||||||
rect.left = x - windowDescription->x - cursorData->width / 2 + offsetX;
|
rect.left = x - inventoryWindowX - cursorData->width / 2 + offsetX;
|
||||||
rect.top = y - windowDescription->y - cursorData->height + 1 + offsetY;
|
rect.top = y - inventoryWindowY - cursorData->height + 1 + offsetY;
|
||||||
rect.right = rect.left + cursorData->width - 1;
|
rect.right = rect.left + cursorData->width - 1;
|
||||||
rect.bottom = rect.top + cursorData->height - 1;
|
rect.bottom = rect.top + cursorData->height - 1;
|
||||||
|
|
||||||
|
@ -3082,7 +3096,7 @@ void inventoryWindowOpenContextMenu(int keyCode, int inventoryWindowType)
|
||||||
|
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
mouseGetPositionInWindow(gInventoryWindow, &x, &y);
|
mouseGetPosition(&x, &y);
|
||||||
if (y - previousMouseY > 10 || previousMouseY - y > 10) {
|
if (y - previousMouseY > 10 || previousMouseY - y > 10) {
|
||||||
if (y >= previousMouseY || menuItemIndex <= 0) {
|
if (y >= previousMouseY || menuItemIndex <= 0) {
|
||||||
if (previousMouseY < y && menuItemIndex < actionMenuItemsLength - 1) {
|
if (previousMouseY < y && menuItemIndex < actionMenuItemsLength - 1) {
|
||||||
|
@ -4476,6 +4490,7 @@ void _container_enter(int keyCode, int inventoryWindowType)
|
||||||
_stack[_curr_stack] = item;
|
_stack[_curr_stack] = item;
|
||||||
_stack_offset[_curr_stack] = 0;
|
_stack_offset[_curr_stack] = 0;
|
||||||
|
|
||||||
|
_inven_dude = _stack[_curr_stack];
|
||||||
_pud = &(item->data.inventory);
|
_pud = &(item->data.inventory);
|
||||||
|
|
||||||
_adjust_fid();
|
_adjust_fid();
|
||||||
|
|
16
src/item.cc
16
src/item.cc
|
@ -576,11 +576,11 @@ bool _item_identical(Object* a1, Object* a2)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((a1->flags & (OBJECT_EQUIPPED | OBJECT_FLAG_0x2000)) != 0) {
|
if ((a1->flags & (OBJECT_EQUIPPED | OBJECT_USED)) != 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((a2->flags & (OBJECT_EQUIPPED | OBJECT_FLAG_0x2000)) != 0) {
|
if ((a2->flags & (OBJECT_EQUIPPED | OBJECT_USED)) != 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -989,14 +989,14 @@ int _item_queued(Object* obj)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((obj->flags & OBJECT_FLAG_0x2000) != 0) {
|
if ((obj->flags & OBJECT_USED) != 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Inventory* inventory = &(obj->data.inventory);
|
Inventory* inventory = &(obj->data.inventory);
|
||||||
for (int index = 0; index < inventory->length; index++) {
|
for (int index = 0; index < inventory->length; index++) {
|
||||||
InventoryItem* inventoryItem = &(inventory->items[index]);
|
InventoryItem* inventoryItem = &(inventory->items[index]);
|
||||||
if ((inventoryItem->item->flags & OBJECT_FLAG_0x2000) != 0) {
|
if ((inventoryItem->item->flags & OBJECT_USED) != 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2402,11 +2402,11 @@ int _item_m_turn_off_from_queue(Object* obj, void* data)
|
||||||
// 0x479960
|
// 0x479960
|
||||||
int stealthBoyTurnOn(Object* object)
|
int stealthBoyTurnOn(Object* object)
|
||||||
{
|
{
|
||||||
if ((object->flags & OBJECT_FLAG_0x20000) != 0) {
|
if ((object->flags & OBJECT_TRANS_GLASS) != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
object->flags |= OBJECT_FLAG_0x20000;
|
object->flags |= OBJECT_TRANS_GLASS;
|
||||||
|
|
||||||
Rect rect;
|
Rect rect;
|
||||||
objectGetRect(object, &rect);
|
objectGetRect(object, &rect);
|
||||||
|
@ -2428,11 +2428,11 @@ int stealthBoyTurnOff(Object* critter, Object* item)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((critter->flags & OBJECT_FLAG_0x20000) == 0) {
|
if ((critter->flags & OBJECT_TRANS_GLASS) == 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
critter->flags &= ~OBJECT_FLAG_0x20000;
|
critter->flags &= ~OBJECT_TRANS_GLASS;
|
||||||
|
|
||||||
Rect rect;
|
Rect rect;
|
||||||
objectGetRect(critter, &rect);
|
objectGetRect(critter, &rect);
|
||||||
|
|
68
src/lips.cc
68
src/lips.cc
|
@ -177,44 +177,46 @@ int lipsStart()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x47AD98
|
// 0x47AD98
|
||||||
int lipsReadV1(LipsData* a1, File* stream)
|
int lipsReadV1(LipsData* lipsData, File* stream)
|
||||||
{
|
{
|
||||||
int field_C;
|
int sound;
|
||||||
int field_14;
|
int field_14;
|
||||||
int field_18;
|
int phonemes;
|
||||||
int field_30;
|
int markers;
|
||||||
|
|
||||||
if (fileReadInt32(stream, &(a1->version)) == -1) return -1;
|
if (fileReadInt32(stream, &(lipsData->version)) == -1) return -1;
|
||||||
if (fileReadInt32(stream, &(a1->field_4)) == -1) return -1;
|
if (fileReadInt32(stream, &(lipsData->field_4)) == -1) return -1;
|
||||||
if (fileReadInt32(stream, &(a1->flags)) == -1) return -1;
|
if (fileReadInt32(stream, &(lipsData->flags)) == -1) return -1;
|
||||||
if (fileReadInt32(stream, &(field_C)) == -1) return -1;
|
if (fileReadInt32(stream, &(sound)) == -1) return -1;
|
||||||
if (fileReadInt32(stream, &(a1->field_10)) == -1) return -1;
|
if (fileReadInt32(stream, &(lipsData->field_10)) == -1) return -1;
|
||||||
if (fileReadInt32(stream, &(field_14)) == -1) return -1;
|
if (fileReadInt32(stream, &(field_14)) == -1) return -1;
|
||||||
if (fileReadInt32(stream, &(field_18)) == -1) return -1;
|
if (fileReadInt32(stream, &(phonemes)) == -1) return -1;
|
||||||
if (fileReadInt32(stream, &(a1->field_1C)) == -1) return -1;
|
if (fileReadInt32(stream, &(lipsData->field_1C)) == -1) return -1;
|
||||||
if (fileReadInt32(stream, &(a1->field_20)) == -1) return -1;
|
if (fileReadInt32(stream, &(lipsData->field_20)) == -1) return -1;
|
||||||
if (fileReadInt32(stream, &(a1->field_24)) == -1) return -1;
|
if (fileReadInt32(stream, &(lipsData->field_24)) == -1) return -1;
|
||||||
if (fileReadInt32(stream, &(a1->field_28)) == -1) return -1;
|
if (fileReadInt32(stream, &(lipsData->field_28)) == -1) return -1;
|
||||||
if (fileReadInt32(stream, &(a1->field_2C)) == -1) return -1;
|
if (fileReadInt32(stream, &(lipsData->field_2C)) == -1) return -1;
|
||||||
if (fileReadInt32(stream, &(field_30)) == -1) return -1;
|
if (fileReadInt32(stream, &(markers)) == -1) return -1;
|
||||||
if (fileReadInt32(stream, &(a1->field_34)) == -1) return -1;
|
if (fileReadInt32(stream, &(lipsData->field_34)) == -1) return -1;
|
||||||
if (fileReadInt32(stream, &(a1->field_38)) == -1) return -1;
|
if (fileReadInt32(stream, &(lipsData->field_38)) == -1) return -1;
|
||||||
if (fileReadInt32(stream, &(a1->field_3C)) == -1) return -1;
|
if (fileReadInt32(stream, &(lipsData->field_3C)) == -1) return -1;
|
||||||
if (fileReadInt32(stream, &(a1->field_40)) == -1) return -1;
|
if (fileReadInt32(stream, &(lipsData->field_40)) == -1) return -1;
|
||||||
if (fileReadInt32(stream, &(a1->field_44)) == -1) return -1;
|
if (fileReadInt32(stream, &(lipsData->field_44)) == -1) return -1;
|
||||||
if (fileReadInt32(stream, &(a1->field_48)) == -1) return -1;
|
if (fileReadInt32(stream, &(lipsData->field_48)) == -1) return -1;
|
||||||
if (fileReadInt32(stream, &(a1->field_4C)) == -1) return -1;
|
if (fileReadInt32(stream, &(lipsData->field_4C)) == -1) return -1;
|
||||||
if (fileReadFixedLengthString(stream, a1->field_50, 8) == -1) return -1;
|
if (fileReadFixedLengthString(stream, lipsData->field_50, 8) == -1) return -1;
|
||||||
if (fileReadFixedLengthString(stream, a1->field_58, 4) == -1) return -1;
|
if (fileReadFixedLengthString(stream, lipsData->field_58, 4) == -1) return -1;
|
||||||
if (fileReadFixedLengthString(stream, a1->field_5C, 4) == -1) return -1;
|
if (fileReadFixedLengthString(stream, lipsData->field_5C, 4) == -1) return -1;
|
||||||
if (fileReadFixedLengthString(stream, a1->field_60, 4) == -1) return -1;
|
if (fileReadFixedLengthString(stream, lipsData->field_60, 4) == -1) return -1;
|
||||||
if (fileReadFixedLengthString(stream, a1->field_64, 260) == -1) return -1;
|
if (fileReadFixedLengthString(stream, lipsData->field_64, 260) == -1) return -1;
|
||||||
|
|
||||||
// TODO: What for?
|
// NOTE: Original code is different. For unknown reason it assigns values
|
||||||
a1->sound = (Sound*)field_C;
|
// from file (integers) and treat them as pointers, which is obviously wrong
|
||||||
a1->field_14 = (void*)field_14;
|
// is in this case.
|
||||||
a1->phonemes = (unsigned char*)field_18;
|
lipsData->sound = NULL;
|
||||||
a1->markers = (SpeechMarker*)field_30;
|
lipsData->field_14 = NULL;
|
||||||
|
lipsData->phonemes = NULL;
|
||||||
|
lipsData->markers = NULL;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,7 @@ SaveGameHandler* _master_save_list[LOAD_SAVE_HANDLER_COUNT] = {
|
||||||
traitsSave,
|
traitsSave,
|
||||||
automapSave,
|
automapSave,
|
||||||
preferencesSave,
|
preferencesSave,
|
||||||
_editor_save,
|
characterEditorSave,
|
||||||
worldmapSave,
|
worldmapSave,
|
||||||
pipboySave,
|
pipboySave,
|
||||||
gameMoviesSave,
|
gameMoviesSave,
|
||||||
|
@ -142,7 +142,7 @@ LoadGameHandler* _master_load_list[LOAD_SAVE_HANDLER_COUNT] = {
|
||||||
traitsLoad,
|
traitsLoad,
|
||||||
automapLoad,
|
automapLoad,
|
||||||
preferencesLoad,
|
preferencesLoad,
|
||||||
_editor_load,
|
characterEditorLoad,
|
||||||
worldmapLoad,
|
worldmapLoad,
|
||||||
pipboyLoad,
|
pipboyLoad,
|
||||||
gameMoviesLoad,
|
gameMoviesLoad,
|
||||||
|
@ -626,9 +626,10 @@ int _QuickSnapShot()
|
||||||
}
|
}
|
||||||
|
|
||||||
// For preview take 640x380 area in the center of isometric window.
|
// For preview take 640x380 area in the center of isometric window.
|
||||||
unsigned char* isoWindowBuffer = windowGetBuffer(gIsoWindow)
|
Window* window = windowGetWindow(gIsoWindow);
|
||||||
+ (screenGetWidth() - ORIGINAL_ISO_WINDOW_WIDTH) / 2 * (screenGetHeight() - ORIGINAL_ISO_WINDOW_HEIGHT) / 2
|
unsigned char* isoWindowBuffer = window->buffer
|
||||||
+ (screenGetWidth() - ORIGINAL_ISO_WINDOW_WIDTH) / 2;
|
+ window->width * (window->height - ORIGINAL_ISO_WINDOW_HEIGHT) / 2
|
||||||
|
+ (window->width - ORIGINAL_ISO_WINDOW_WIDTH) / 2;
|
||||||
blitBufferToBufferStretch(isoWindowBuffer,
|
blitBufferToBufferStretch(isoWindowBuffer,
|
||||||
ORIGINAL_ISO_WINDOW_WIDTH,
|
ORIGINAL_ISO_WINDOW_WIDTH,
|
||||||
ORIGINAL_ISO_WINDOW_HEIGHT,
|
ORIGINAL_ISO_WINDOW_HEIGHT,
|
||||||
|
@ -1107,9 +1108,10 @@ int lsgWindowInit(int windowType)
|
||||||
}
|
}
|
||||||
|
|
||||||
// For preview take 640x380 area in the center of isometric window.
|
// For preview take 640x380 area in the center of isometric window.
|
||||||
unsigned char* isoWindowBuffer = windowGetBuffer(gIsoWindow)
|
Window* window = windowGetWindow(gIsoWindow);
|
||||||
+ (screenGetWidth() - ORIGINAL_ISO_WINDOW_WIDTH) / 2 * (screenGetHeight() - ORIGINAL_ISO_WINDOW_HEIGHT) / 2
|
unsigned char* isoWindowBuffer = window->buffer
|
||||||
+ (screenGetWidth() - ORIGINAL_ISO_WINDOW_WIDTH) / 2;
|
+ window->width * (window->height - ORIGINAL_ISO_WINDOW_HEIGHT) / 2
|
||||||
|
+ (window->width - ORIGINAL_ISO_WINDOW_WIDTH) / 2;
|
||||||
blitBufferToBufferStretch(isoWindowBuffer,
|
blitBufferToBufferStretch(isoWindowBuffer,
|
||||||
ORIGINAL_ISO_WINDOW_WIDTH,
|
ORIGINAL_ISO_WINDOW_WIDTH,
|
||||||
ORIGINAL_ISO_WINDOW_HEIGHT,
|
ORIGINAL_ISO_WINDOW_HEIGHT,
|
||||||
|
|
42
src/main.cc
42
src/main.cc
|
@ -132,9 +132,14 @@ int falloutMain(int argc, char** argv)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
gameMoviePlay(MOVIE_IPLOGO, GAME_MOVIE_FADE_IN);
|
// SFALL: Allow to skip intro movies
|
||||||
gameMoviePlay(MOVIE_INTRO, 0);
|
int skipOpeningMovies;
|
||||||
gameMoviePlay(MOVIE_CREDITS, 0);
|
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_SKIP_OPENING_MOVIES_KEY, &skipOpeningMovies);
|
||||||
|
if(skipOpeningMovies < 1) {
|
||||||
|
gameMoviePlay(MOVIE_IPLOGO, GAME_MOVIE_FADE_IN);
|
||||||
|
gameMoviePlay(MOVIE_INTRO, 0);
|
||||||
|
gameMoviePlay(MOVIE_CREDITS, 0);
|
||||||
|
}
|
||||||
|
|
||||||
FpsLimiter fpsLimiter;
|
FpsLimiter fpsLimiter;
|
||||||
|
|
||||||
|
@ -194,7 +199,7 @@ int falloutMain(int argc, char** argv)
|
||||||
mainMenuWindowHide(true);
|
mainMenuWindowHide(true);
|
||||||
mainMenuWindowFree();
|
mainMenuWindowFree();
|
||||||
_game_user_wants_to_quit = 0;
|
_game_user_wants_to_quit = 0;
|
||||||
gDude->flags &= ~OBJECT_FLAG_0x08;
|
gDude->flags &= ~OBJECT_FLAT;
|
||||||
_main_show_death_scene = 0;
|
_main_show_death_scene = 0;
|
||||||
objectShow(gDude, NULL);
|
objectShow(gDude, NULL);
|
||||||
mouseHideCursor();
|
mouseHideCursor();
|
||||||
|
@ -296,7 +301,7 @@ int _main_load_new(char* mapFileName)
|
||||||
{
|
{
|
||||||
_game_user_wants_to_quit = 0;
|
_game_user_wants_to_quit = 0;
|
||||||
_main_show_death_scene = 0;
|
_main_show_death_scene = 0;
|
||||||
gDude->flags &= ~OBJECT_FLAG_0x08;
|
gDude->flags &= ~OBJECT_FLAT;
|
||||||
objectShow(gDude, NULL);
|
objectShow(gDude, NULL);
|
||||||
mouseHideCursor();
|
mouseHideCursor();
|
||||||
|
|
||||||
|
@ -639,17 +644,31 @@ int mainMenuWindowInit()
|
||||||
int oldFont = fontGetCurrent();
|
int oldFont = fontGetCurrent();
|
||||||
fontSetCurrent(100);
|
fontSetCurrent(100);
|
||||||
|
|
||||||
|
// SFALL: Allow to change font color/flags of copyright/version text
|
||||||
|
// It's the last byte ('3C' by default) that picks the colour used. The first byte supplies additional flags for this option
|
||||||
|
// 0x010000 - change the color for version string only
|
||||||
|
// 0x020000 - underline text (only for the version string)
|
||||||
|
// 0x040000 - monospace font (only for the version string)
|
||||||
|
int fontSettings = _colorTable[21091], fontSettingsSFall = 0;
|
||||||
|
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_MAIN_MENU_FONT_COLOR_KEY, &fontSettingsSFall);
|
||||||
|
if (fontSettingsSFall && !(fontSettingsSFall & 0x010000))
|
||||||
|
fontSettings = fontSettingsSFall & 0xFF;
|
||||||
|
|
||||||
// Copyright.
|
// Copyright.
|
||||||
msg.num = 20;
|
msg.num = 20;
|
||||||
if (messageListGetItem(&gMiscMessageList, &msg)) {
|
if (messageListGetItem(&gMiscMessageList, &msg)) {
|
||||||
windowDrawText(gMainMenuWindow, msg.text, 0, 15, 460, _colorTable[21091] | 0x6000000);
|
windowDrawText(gMainMenuWindow, msg.text, 0, 15, 460, fontSettings | 0x06000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SFALL: Make sure font settings are applied when using 0x010000 flag
|
||||||
|
if (fontSettingsSFall)
|
||||||
|
fontSettings = fontSettingsSFall;
|
||||||
|
|
||||||
// Version.
|
// Version.
|
||||||
char version[VERSION_MAX];
|
char version[VERSION_MAX];
|
||||||
versionGetVersion(version);
|
versionGetVersion(version);
|
||||||
len = fontGetStringWidth(version);
|
len = fontGetStringWidth(version);
|
||||||
windowDrawText(gMainMenuWindow, version, 0, 615 - len, 460, _colorTable[21091] | 0x6000000);
|
windowDrawText(gMainMenuWindow, version, 0, 615 - len, 460, fontSettings | 0x06000000);
|
||||||
|
|
||||||
// menuup.frm
|
// menuup.frm
|
||||||
fid = buildFid(6, 299, 0, 0, 0);
|
fid = buildFid(6, 299, 0, 0, 0);
|
||||||
|
@ -683,11 +702,18 @@ int mainMenuWindowInit()
|
||||||
|
|
||||||
fontSetCurrent(104);
|
fontSetCurrent(104);
|
||||||
|
|
||||||
|
// SFALL: Allow to change font color of buttons
|
||||||
|
fontSettings = _colorTable[21091];
|
||||||
|
fontSettingsSFall = 0;
|
||||||
|
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_MAIN_MENU_BIG_FONT_COLOR_KEY, &fontSettingsSFall);
|
||||||
|
if (fontSettingsSFall)
|
||||||
|
fontSettings = fontSettingsSFall & 0xFF;
|
||||||
|
|
||||||
for (int index = 0; index < MAIN_MENU_BUTTON_COUNT; index++) {
|
for (int index = 0; index < MAIN_MENU_BUTTON_COUNT; index++) {
|
||||||
msg.num = 9 + index;
|
msg.num = 9 + index;
|
||||||
if (messageListGetItem(&gMiscMessageList, &msg)) {
|
if (messageListGetItem(&gMiscMessageList, &msg)) {
|
||||||
len = fontGetStringWidth(msg.text);
|
len = fontGetStringWidth(msg.text);
|
||||||
fontDrawText(gMainMenuWindowBuffer + 640 * (42 * index - index + 20) + 126 - (len / 2), msg.text, 640 - (126 - (len / 2)) - 1, 640, _colorTable[21091]);
|
fontDrawText(gMainMenuWindowBuffer + 640 * (42 * index - index + 20) + 126 - (len / 2), msg.text, 640 - (126 - (len / 2)) - 1, 640, fontSettings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -903,7 +903,7 @@ int mapLoad(File* stream)
|
||||||
Object* object;
|
Object* object;
|
||||||
int fid = buildFid(5, 12, 0, 0, 0);
|
int fid = buildFid(5, 12, 0, 0, 0);
|
||||||
objectCreateWithFidPid(&object, fid, -1);
|
objectCreateWithFidPid(&object, fid, -1);
|
||||||
object->flags |= (OBJECT_FLAG_0x20000000 | OBJECT_TEMPORARY | OBJECT_HIDDEN);
|
object->flags |= (OBJECT_LIGHT_THRU | OBJECT_TEMPORARY | OBJECT_HIDDEN);
|
||||||
objectSetLocation(object, 1, 0, NULL);
|
objectSetLocation(object, 1, 0, NULL);
|
||||||
object->sid = gMapSid;
|
object->sid = gMapSid;
|
||||||
scriptSetFixedParam(gMapSid, (gMapHeader.flags & 1) == 0);
|
scriptSetFixedParam(gMapSid, (gMapHeader.flags & 1) == 0);
|
||||||
|
|
|
@ -22,10 +22,10 @@ int gMemoryBlocksCurrentCount = 0;
|
||||||
int gMemoryBlockMaximumCount = 0;
|
int gMemoryBlockMaximumCount = 0;
|
||||||
|
|
||||||
// 0x51DEE4
|
// 0x51DEE4
|
||||||
int gMemoryBlocksCurrentSize = 0;
|
size_t gMemoryBlocksCurrentSize = 0;
|
||||||
|
|
||||||
// 0x51DEE8
|
// 0x51DEE8
|
||||||
int gMemoryBlocksMaximumSize = 0;
|
size_t gMemoryBlocksMaximumSize = 0;
|
||||||
|
|
||||||
// 0x4C5A80
|
// 0x4C5A80
|
||||||
char* internal_strdup(const char* string)
|
char* internal_strdup(const char* string)
|
||||||
|
|
|
@ -29,8 +29,8 @@ extern ReallocProc* gReallocProc;
|
||||||
extern FreeProc* gFreeProc;
|
extern FreeProc* gFreeProc;
|
||||||
extern int gMemoryBlocksCurrentCount;
|
extern int gMemoryBlocksCurrentCount;
|
||||||
extern int gMemoryBlockMaximumCount;
|
extern int gMemoryBlockMaximumCount;
|
||||||
extern int gMemoryBlocksCurrentSize;
|
extern size_t gMemoryBlocksCurrentSize;
|
||||||
extern int gMemoryBlocksMaximumSize;
|
extern size_t gMemoryBlocksMaximumSize;
|
||||||
|
|
||||||
char* internal_strdup(const char* string);
|
char* internal_strdup(const char* string);
|
||||||
void* internal_malloc(size_t size);
|
void* internal_malloc(size_t size);
|
||||||
|
|
18
src/mmx.cc
18
src/mmx.cc
|
@ -9,23 +9,7 @@
|
||||||
// 0x4E08A0
|
// 0x4E08A0
|
||||||
bool mmxIsSupported()
|
bool mmxIsSupported()
|
||||||
{
|
{
|
||||||
int v1;
|
return SDL_HasMMX() == SDL_TRUE;
|
||||||
|
|
||||||
// TODO: There are other ways to determine MMX using FLAGS register.
|
|
||||||
|
|
||||||
#if defined (_MSC_VER)
|
|
||||||
__asm
|
|
||||||
{
|
|
||||||
mov eax, 1
|
|
||||||
cpuid
|
|
||||||
and edx, 0x800000
|
|
||||||
mov v1, edx
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
v1 = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return v1 != 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x4E0DB0
|
// 0x4E0DB0
|
||||||
|
|
|
@ -39,31 +39,31 @@ typedef enum OutlineType {
|
||||||
typedef enum ObjectFlags {
|
typedef enum ObjectFlags {
|
||||||
OBJECT_HIDDEN = 0x01,
|
OBJECT_HIDDEN = 0x01,
|
||||||
OBJECT_TEMPORARY = 0x04,
|
OBJECT_TEMPORARY = 0x04,
|
||||||
OBJECT_FLAG_0x08 = 0x08,
|
OBJECT_FLAT = 0x08,
|
||||||
OBJECT_NO_BLOCK = 0x10,
|
OBJECT_NO_BLOCK = 0x10,
|
||||||
OBJECT_LIGHTING = 0x20,
|
OBJECT_LIGHTING = 0x20,
|
||||||
OBJECT_FLAG_0x400 = 0x400,
|
OBJECT_FLAG_0x400 = 0x400, // ???
|
||||||
OBJECT_FLAG_0x800 = 0x800,
|
OBJECT_MULTIHEX = 0x800,
|
||||||
OBJECT_FLAG_0x1000 = 0x1000,
|
OBJECT_NO_HIGHLIGHT = 0x1000,
|
||||||
OBJECT_FLAG_0x2000 = 0x2000,
|
OBJECT_USED = 0x2000, // set if there was/is any event for the object
|
||||||
OBJECT_FLAG_0x4000 = 0x4000,
|
OBJECT_TRANS_RED = 0x4000,
|
||||||
OBJECT_FLAG_0x8000 = 0x8000,
|
OBJECT_TRANS_NONE = 0x8000,
|
||||||
OBJECT_FLAG_0x10000 = 0x10000,
|
OBJECT_TRANS_WALL = 0x10000,
|
||||||
OBJECT_FLAG_0x20000 = 0x20000,
|
OBJECT_TRANS_GLASS = 0x20000,
|
||||||
OBJECT_FLAG_0x40000 = 0x40000,
|
OBJECT_TRANS_STEAM = 0x40000,
|
||||||
OBJECT_FLAG_0x80000 = 0x80000,
|
OBJECT_TRANS_ENERGY = 0x80000,
|
||||||
OBJECT_IN_LEFT_HAND = 0x1000000,
|
OBJECT_IN_LEFT_HAND = 0x1000000,
|
||||||
OBJECT_IN_RIGHT_HAND = 0x2000000,
|
OBJECT_IN_RIGHT_HAND = 0x2000000,
|
||||||
OBJECT_WORN = 0x4000000,
|
OBJECT_WORN = 0x4000000,
|
||||||
OBJECT_FLAG_0x10000000 = 0x10000000,
|
OBJECT_WALL_TRANS_END = 0x10000000,
|
||||||
OBJECT_FLAG_0x20000000 = 0x20000000,
|
OBJECT_LIGHT_THRU = 0x20000000,
|
||||||
OBJECT_FLAG_0x40000000 = 0x40000000,
|
OBJECT_SEEN = 0x40000000,
|
||||||
OBJECT_FLAG_0x80000000 = 0x80000000,
|
OBJECT_SHOOT_THRU = 0x80000000,
|
||||||
|
|
||||||
OBJECT_IN_ANY_HAND = OBJECT_IN_LEFT_HAND | OBJECT_IN_RIGHT_HAND,
|
OBJECT_IN_ANY_HAND = OBJECT_IN_LEFT_HAND | OBJECT_IN_RIGHT_HAND,
|
||||||
OBJECT_EQUIPPED = OBJECT_IN_ANY_HAND | OBJECT_WORN,
|
OBJECT_EQUIPPED = OBJECT_IN_ANY_HAND | OBJECT_WORN,
|
||||||
OBJECT_FLAG_0xFC000 = OBJECT_FLAG_0x80000 | OBJECT_FLAG_0x40000 | OBJECT_FLAG_0x20000 | OBJECT_FLAG_0x10000 | OBJECT_FLAG_0x8000 | OBJECT_FLAG_0x4000,
|
OBJECT_FLAG_0xFC000 = OBJECT_TRANS_ENERGY | OBJECT_TRANS_STEAM | OBJECT_TRANS_GLASS | OBJECT_TRANS_WALL | OBJECT_TRANS_NONE | OBJECT_TRANS_RED,
|
||||||
OBJECT_OPEN_DOOR = OBJECT_FLAG_0x80000000 | OBJECT_FLAG_0x20000000 | OBJECT_NO_BLOCK,
|
OBJECT_OPEN_DOOR = OBJECT_SHOOT_THRU | OBJECT_LIGHT_THRU | OBJECT_NO_BLOCK,
|
||||||
} ObjectFlags;
|
} ObjectFlags;
|
||||||
|
|
||||||
#define OUTLINE_TYPE_MASK 0xFFFFFF
|
#define OUTLINE_TYPE_MASK 0xFFFFFF
|
||||||
|
|
281
src/object.cc
281
src/object.cc
|
@ -30,13 +30,13 @@
|
||||||
bool gObjectsInitialized = false;
|
bool gObjectsInitialized = false;
|
||||||
|
|
||||||
// 0x5195FC
|
// 0x5195FC
|
||||||
int _updateHexWidth = 0;
|
int gObjectsUpdateAreaHexWidth = 0;
|
||||||
|
|
||||||
// 0x519600
|
// 0x519600
|
||||||
int _updateHexHeight = 0;
|
int gObjectsUpdateAreaHexHeight = 0;
|
||||||
|
|
||||||
// 0x519604
|
// 0x519604
|
||||||
int _updateHexArea = 0;
|
int gObjectsUpdateAreaHexSize = 0;
|
||||||
|
|
||||||
// 0x519608
|
// 0x519608
|
||||||
int* _orderTable[2] = {
|
int* _orderTable[2] = {
|
||||||
|
@ -204,16 +204,7 @@ Rect gObjectsWindowRect;
|
||||||
Object* _outlinedObjects[100];
|
Object* _outlinedObjects[100];
|
||||||
|
|
||||||
// 0x639D90
|
// 0x639D90
|
||||||
int _updateAreaPixelBounds;
|
Rect gObjectsUpdateAreaPixelBounds;
|
||||||
|
|
||||||
// 0x639D94
|
|
||||||
int dword_639D94;
|
|
||||||
|
|
||||||
// 0x639D98
|
|
||||||
int dword_639D98;
|
|
||||||
|
|
||||||
// 0x639D9C
|
|
||||||
int dword_639D9C;
|
|
||||||
|
|
||||||
// Contains objects that are bounded to tiles.
|
// Contains objects that are bounded to tiles.
|
||||||
//
|
//
|
||||||
|
@ -264,14 +255,14 @@ int objectsInit(unsigned char* buf, int width, int height, int pitch)
|
||||||
int eggFid;
|
int eggFid;
|
||||||
|
|
||||||
memset(_obj_seen, 0, 5001);
|
memset(_obj_seen, 0, 5001);
|
||||||
dword_639D98 = width + 320;
|
gObjectsUpdateAreaPixelBounds.right = width + 320;
|
||||||
_updateAreaPixelBounds = -320;
|
gObjectsUpdateAreaPixelBounds.left = -320;
|
||||||
dword_639D9C = height + 240;
|
gObjectsUpdateAreaPixelBounds.bottom = height + 240;
|
||||||
dword_639D94 = -240;
|
gObjectsUpdateAreaPixelBounds.top = -240;
|
||||||
|
|
||||||
_updateHexWidth = (dword_639D98 + 320 + 1) / 32 + 1;
|
gObjectsUpdateAreaHexWidth = (gObjectsUpdateAreaPixelBounds.right + 320 + 1) / 32 + 1;
|
||||||
_updateHexHeight = (dword_639D9C + 240 + 1) / 12 + 1;
|
gObjectsUpdateAreaHexHeight = (gObjectsUpdateAreaPixelBounds.bottom + 240 + 1) / 12 + 1;
|
||||||
_updateHexArea = _updateHexWidth * _updateHexHeight;
|
gObjectsUpdateAreaHexSize = gObjectsUpdateAreaHexWidth * gObjectsUpdateAreaHexHeight;
|
||||||
|
|
||||||
memset(gObjectListHeadByTile, 0, sizeof(gObjectListHeadByTile));
|
memset(gObjectListHeadByTile, 0, sizeof(gObjectListHeadByTile));
|
||||||
|
|
||||||
|
@ -298,7 +289,7 @@ int objectsInit(unsigned char* buf, int width, int height, int pitch)
|
||||||
_obj_light_table_init();
|
_obj_light_table_init();
|
||||||
_obj_blend_table_init();
|
_obj_blend_table_init();
|
||||||
|
|
||||||
_centerToUpperLeft = tileFromScreenXY(_updateAreaPixelBounds, dword_639D94, 0) - gCenterTile;
|
_centerToUpperLeft = tileFromScreenXY(gObjectsUpdateAreaPixelBounds.left, gObjectsUpdateAreaPixelBounds.top, 0) - gCenterTile;
|
||||||
gObjectsWindowWidth = width;
|
gObjectsWindowWidth = width;
|
||||||
gObjectsWindowHeight = height;
|
gObjectsWindowHeight = height;
|
||||||
gObjectsWindowBuffer = buf;
|
gObjectsWindowBuffer = buf;
|
||||||
|
@ -317,7 +308,7 @@ int objectsInit(unsigned char* buf, int width, int height, int pitch)
|
||||||
gDude->flags |= OBJECT_FLAG_0x400;
|
gDude->flags |= OBJECT_FLAG_0x400;
|
||||||
gDude->flags |= OBJECT_TEMPORARY;
|
gDude->flags |= OBJECT_TEMPORARY;
|
||||||
gDude->flags |= OBJECT_HIDDEN;
|
gDude->flags |= OBJECT_HIDDEN;
|
||||||
gDude->flags |= OBJECT_FLAG_0x20000000;
|
gDude->flags |= OBJECT_LIGHT_THRU;
|
||||||
objectSetLight(gDude, 4, 0x10000, NULL);
|
objectSetLight(gDude, 4, 0x10000, NULL);
|
||||||
|
|
||||||
if (partyMemberAdd(gDude) == -1) {
|
if (partyMemberAdd(gDude) == -1) {
|
||||||
|
@ -330,7 +321,7 @@ int objectsInit(unsigned char* buf, int width, int height, int pitch)
|
||||||
gEgg->flags |= OBJECT_FLAG_0x400;
|
gEgg->flags |= OBJECT_FLAG_0x400;
|
||||||
gEgg->flags |= OBJECT_TEMPORARY;
|
gEgg->flags |= OBJECT_TEMPORARY;
|
||||||
gEgg->flags |= OBJECT_HIDDEN;
|
gEgg->flags |= OBJECT_HIDDEN;
|
||||||
gEgg->flags |= OBJECT_FLAG_0x20000000;
|
gEgg->flags |= OBJECT_LIGHT_THRU;
|
||||||
|
|
||||||
gObjectsInitialized = true;
|
gObjectsInitialized = true;
|
||||||
|
|
||||||
|
@ -767,35 +758,59 @@ void _obj_render_pre_roof(Rect* rect, int elevation)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lightLevel = lightGetLightLevel();
|
int ambientLight = lightGetLightLevel();
|
||||||
int v5 = updatedRect.left - 320;
|
int minX = updatedRect.left - 320;
|
||||||
int v4 = updatedRect.top - 240;
|
int minY = updatedRect.top - 240;
|
||||||
int v17 = updatedRect.right + 320;
|
int maxX = updatedRect.right + 320;
|
||||||
int v18 = updatedRect.bottom + 240;
|
int maxY = updatedRect.bottom + 240;
|
||||||
int v19 = tileFromScreenXY(v5, v4, elevation);
|
int topLeftTile = tileFromScreenXY(minX, minY, elevation);
|
||||||
int v20 = (v17 - v5 + 1) / 32;
|
int updateAreaHexWidth = (maxX - minX + 1) / 32;
|
||||||
int v23 = (v18 - v4 + 1) / 12;
|
int updateAreaHexHeight = (maxY - minY + 1) / 12;
|
||||||
|
|
||||||
int odd = gCenterTile & 1;
|
// On some maps (which were designed too close to edges) HRP brings a new
|
||||||
int* v7 = _orderTable[odd];
|
// problem - extended update rect (+/- 320/240 stuff above) may end up
|
||||||
int* v8 = _offsetTable[odd];
|
// outside of the map edge. In this case `topLeftTile` will be -1 which
|
||||||
|
// affect all subsequent calculations. In order to fix that attempt to
|
||||||
|
// find closest valid tile.
|
||||||
|
while (!hexGridTileIsValid(topLeftTile)) {
|
||||||
|
minX += 32;
|
||||||
|
minY += 12;
|
||||||
|
topLeftTile = tileFromScreenXY(minX, minY, elevation);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do the same for the for bottom-right part of the extended update rect.
|
||||||
|
int bottomRightTile = tileFromScreenXY(maxX, maxY, elevation);
|
||||||
|
while (!hexGridTileIsValid(bottomRightTile)) {
|
||||||
|
maxX -= 32;
|
||||||
|
maxY -= 12;
|
||||||
|
bottomRightTile = tileFromScreenXY(maxX, maxY, elevation);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateAreaHexWidth = (maxX - minX + 1) / 32;
|
||||||
|
updateAreaHexHeight = (maxY - minY + 1) / 12;
|
||||||
|
|
||||||
|
int parity = gCenterTile & 1;
|
||||||
|
int* orders = _orderTable[parity];
|
||||||
|
int* offsets = _offsetTable[parity];
|
||||||
|
|
||||||
_outlineCount = 0;
|
_outlineCount = 0;
|
||||||
|
|
||||||
int v34 = 0;
|
int renderCount = 0;
|
||||||
for (int i = 0; i < _updateHexArea; i++) {
|
for (int i = 0; i < gObjectsUpdateAreaHexSize; i++) {
|
||||||
int v9 = *v7++;
|
int offsetIndex = *orders++;
|
||||||
if (v23 > _offsetDivTable[v9] && v20 > _offsetModTable[v9]) {
|
if (updateAreaHexHeight > _offsetDivTable[offsetIndex] && updateAreaHexWidth > _offsetModTable[offsetIndex]) {
|
||||||
int v2;
|
int light;
|
||||||
|
|
||||||
ObjectListNode* objectListNode = gObjectListHeadByTile[v19 + v8[v9]];
|
ObjectListNode* objectListNode = hexGridTileIsValid(topLeftTile + offsets[offsetIndex])
|
||||||
|
? gObjectListHeadByTile[topLeftTile + offsets[offsetIndex]]
|
||||||
|
: NULL;
|
||||||
if (objectListNode != NULL) {
|
if (objectListNode != NULL) {
|
||||||
// NOTE: calls _light_get_tile two times, probably result of min/max macro
|
// NOTE: calls _light_get_tile two times, probably result of min/max macro
|
||||||
int q = _light_get_tile(elevation, objectListNode->obj->tile);
|
int tileLight = _light_get_tile(elevation, objectListNode->obj->tile);
|
||||||
if (q >= lightLevel) {
|
if (tileLight >= ambientLight) {
|
||||||
v2 = q;
|
light = tileLight;
|
||||||
} else {
|
} else {
|
||||||
v2 = lightLevel;
|
light = ambientLight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -805,12 +820,12 @@ void _obj_render_pre_roof(Rect* rect, int elevation)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (elevation == objectListNode->obj->elevation) {
|
if (elevation == objectListNode->obj->elevation) {
|
||||||
if ((objectListNode->obj->flags & OBJECT_FLAG_0x08) == 0) {
|
if ((objectListNode->obj->flags & OBJECT_FLAT) == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((objectListNode->obj->flags & OBJECT_HIDDEN) == 0) {
|
if ((objectListNode->obj->flags & OBJECT_HIDDEN) == 0) {
|
||||||
_obj_render_object(objectListNode->obj, &updatedRect, v2);
|
_obj_render_object(objectListNode->obj, &updatedRect, light);
|
||||||
|
|
||||||
if ((objectListNode->obj->outline & OUTLINE_TYPE_MASK) != 0) {
|
if ((objectListNode->obj->outline & OUTLINE_TYPE_MASK) != 0) {
|
||||||
if ((objectListNode->obj->outline & OUTLINE_DISABLED) == 0 && _outlineCount < 100) {
|
if ((objectListNode->obj->outline & OUTLINE_DISABLED) == 0 && _outlineCount < 100) {
|
||||||
|
@ -824,20 +839,22 @@ void _obj_render_pre_roof(Rect* rect, int elevation)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (objectListNode != NULL) {
|
if (objectListNode != NULL) {
|
||||||
_renderTable[v34++] = objectListNode;
|
_renderTable[renderCount++] = objectListNode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < v34; i++) {
|
for (int i = 0; i < renderCount; i++) {
|
||||||
int v2;
|
int light;
|
||||||
|
|
||||||
ObjectListNode* objectListNode = _renderTable[i];
|
ObjectListNode* objectListNode = _renderTable[i];
|
||||||
if (objectListNode != NULL) {
|
if (objectListNode != NULL) {
|
||||||
v2 = lightLevel;
|
// NOTE: calls _light_get_tile two times, probably result of min/max macro
|
||||||
int w = _light_get_tile(elevation, objectListNode->obj->tile);
|
int tileLight = _light_get_tile(elevation, objectListNode->obj->tile);
|
||||||
if (w > v2) {
|
if (tileLight >= ambientLight) {
|
||||||
v2 = w;
|
light = tileLight;
|
||||||
|
} else {
|
||||||
|
light = ambientLight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -849,7 +866,7 @@ void _obj_render_pre_roof(Rect* rect, int elevation)
|
||||||
|
|
||||||
if (elevation == objectListNode->obj->elevation) {
|
if (elevation == objectListNode->obj->elevation) {
|
||||||
if ((objectListNode->obj->flags & OBJECT_HIDDEN) == 0) {
|
if ((objectListNode->obj->flags & OBJECT_HIDDEN) == 0) {
|
||||||
_obj_render_object(object, &updatedRect, v2);
|
_obj_render_object(object, &updatedRect, light);
|
||||||
|
|
||||||
if ((objectListNode->obj->outline & OUTLINE_TYPE_MASK) != 0) {
|
if ((objectListNode->obj->outline & OUTLINE_TYPE_MASK) != 0) {
|
||||||
if ((objectListNode->obj->outline & OUTLINE_DISABLED) == 0 && _outlineCount < 100) {
|
if ((objectListNode->obj->outline & OUTLINE_DISABLED) == 0 && _outlineCount < 100) {
|
||||||
|
@ -943,39 +960,39 @@ int objectCreateWithFidPid(Object** objectPtr, int fid, int pid)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((proto->flags & 0x800) != 0) {
|
if ((proto->flags & 0x800) != 0) {
|
||||||
objectListNode->obj->flags |= OBJECT_FLAG_0x800;
|
objectListNode->obj->flags |= OBJECT_MULTIHEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((proto->flags & 0x8000) != 0) {
|
if ((proto->flags & 0x8000) != 0) {
|
||||||
objectListNode->obj->flags |= OBJECT_FLAG_0x8000;
|
objectListNode->obj->flags |= OBJECT_TRANS_NONE;
|
||||||
} else {
|
} else {
|
||||||
if ((proto->flags & 0x10000) != 0) {
|
if ((proto->flags & 0x10000) != 0) {
|
||||||
objectListNode->obj->flags |= OBJECT_FLAG_0x10000;
|
objectListNode->obj->flags |= OBJECT_TRANS_WALL;
|
||||||
} else if ((proto->flags & 0x20000) != 0) {
|
} else if ((proto->flags & 0x20000) != 0) {
|
||||||
objectListNode->obj->flags |= OBJECT_FLAG_0x20000;
|
objectListNode->obj->flags |= OBJECT_TRANS_GLASS;
|
||||||
} else if ((proto->flags & 0x40000) != 0) {
|
} else if ((proto->flags & 0x40000) != 0) {
|
||||||
objectListNode->obj->flags |= OBJECT_FLAG_0x40000;
|
objectListNode->obj->flags |= OBJECT_TRANS_STEAM;
|
||||||
} else if ((proto->flags & 0x80000) != 0) {
|
} else if ((proto->flags & 0x80000) != 0) {
|
||||||
objectListNode->obj->flags |= OBJECT_FLAG_0x80000;
|
objectListNode->obj->flags |= OBJECT_TRANS_ENERGY;
|
||||||
} else if ((proto->flags & 0x4000) != 0) {
|
} else if ((proto->flags & 0x4000) != 0) {
|
||||||
objectListNode->obj->flags |= OBJECT_FLAG_0x4000;
|
objectListNode->obj->flags |= OBJECT_TRANS_RED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((proto->flags & 0x20000000) != 0) {
|
if ((proto->flags & 0x20000000) != 0) {
|
||||||
objectListNode->obj->flags |= OBJECT_FLAG_0x20000000;
|
objectListNode->obj->flags |= OBJECT_LIGHT_THRU;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((proto->flags & 0x80000000) != 0) {
|
if ((proto->flags & 0x80000000) != 0) {
|
||||||
objectListNode->obj->flags |= OBJECT_FLAG_0x80000000;
|
objectListNode->obj->flags |= OBJECT_SHOOT_THRU;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((proto->flags & 0x10000000) != 0) {
|
if ((proto->flags & 0x10000000) != 0) {
|
||||||
objectListNode->obj->flags |= OBJECT_FLAG_0x10000000;
|
objectListNode->obj->flags |= OBJECT_WALL_TRANS_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((proto->flags & 0x1000) != 0) {
|
if ((proto->flags & 0x1000) != 0) {
|
||||||
objectListNode->obj->flags |= OBJECT_FLAG_0x1000;
|
objectListNode->obj->flags |= OBJECT_NO_HIGHLIGHT;
|
||||||
}
|
}
|
||||||
|
|
||||||
_obj_new_sid(objectListNode->obj, &(objectListNode->obj->sid));
|
_obj_new_sid(objectListNode->obj, &(objectListNode->obj->sid));
|
||||||
|
@ -1041,7 +1058,7 @@ int _obj_copy(Object** a1, Object* a2)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
objectListNode->obj->flags &= ~OBJECT_FLAG_0x2000;
|
objectListNode->obj->flags &= ~OBJECT_USED;
|
||||||
|
|
||||||
Inventory* newInventory = &(objectListNode->obj->data.inventory);
|
Inventory* newInventory = &(objectListNode->obj->data.inventory);
|
||||||
newInventory->length = 0;
|
newInventory->length = 0;
|
||||||
|
@ -1948,7 +1965,7 @@ int _obj_toggle_flat(Object* object, Rect* rect)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object->flags ^= OBJECT_FLAG_0x08;
|
object->flags ^= OBJECT_FLAT;
|
||||||
|
|
||||||
_obj_insert(node);
|
_obj_insert(node);
|
||||||
objectGetRect(object, &v1);
|
objectGetRect(object, &v1);
|
||||||
|
@ -1965,7 +1982,7 @@ int _obj_toggle_flat(Object* object, Rect* rect)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object->flags ^= OBJECT_FLAG_0x08;
|
object->flags ^= OBJECT_FLAT;
|
||||||
|
|
||||||
_obj_insert(node);
|
_obj_insert(node);
|
||||||
}
|
}
|
||||||
|
@ -2419,7 +2436,7 @@ Object* _obj_blocking_at(Object* a1, int tile, int elev)
|
||||||
objectListNode = gObjectListHeadByTile[neighboor];
|
objectListNode = gObjectListHeadByTile[neighboor];
|
||||||
while (objectListNode != NULL) {
|
while (objectListNode != NULL) {
|
||||||
v7 = objectListNode->obj;
|
v7 = objectListNode->obj;
|
||||||
if ((v7->flags & OBJECT_FLAG_0x800) != 0) {
|
if ((v7->flags & OBJECT_MULTIHEX) != 0) {
|
||||||
if (v7->elevation == elev) {
|
if (v7->elevation == elev) {
|
||||||
if ((v7->flags & OBJECT_HIDDEN) == 0 && (v7->flags & OBJECT_NO_BLOCK) == 0 && v7 != a1) {
|
if ((v7->flags & OBJECT_HIDDEN) == 0 && (v7->flags & OBJECT_NO_BLOCK) == 0 && v7 != a1) {
|
||||||
type = (v7->fid & 0xF000000) >> 24;
|
type = (v7->fid & 0xF000000) >> 24;
|
||||||
|
@ -2451,7 +2468,7 @@ Object* _obj_shoot_blocking_at(Object* obj, int tile, int elev)
|
||||||
Object* candidate = objectListItem->obj;
|
Object* candidate = objectListItem->obj;
|
||||||
if (candidate->elevation == elev) {
|
if (candidate->elevation == elev) {
|
||||||
unsigned int flags = candidate->flags;
|
unsigned int flags = candidate->flags;
|
||||||
if ((flags & OBJECT_HIDDEN) == 0 && ((flags & OBJECT_NO_BLOCK) == 0 || (flags & OBJECT_FLAG_0x80000000) == 0) && candidate != obj) {
|
if ((flags & OBJECT_HIDDEN) == 0 && ((flags & OBJECT_NO_BLOCK) == 0 || (flags & OBJECT_SHOOT_THRU) == 0) && candidate != obj) {
|
||||||
int type = (candidate->fid & 0xF000000) >> 24;
|
int type = (candidate->fid & 0xF000000) >> 24;
|
||||||
// SFALL: Fix to prevent corpses from blocking line of fire.
|
// SFALL: Fix to prevent corpses from blocking line of fire.
|
||||||
if ((type == OBJ_TYPE_CRITTER && !critterIsDead(candidate))
|
if ((type == OBJ_TYPE_CRITTER && !critterIsDead(candidate))
|
||||||
|
@ -2474,7 +2491,7 @@ Object* _obj_shoot_blocking_at(Object* obj, int tile, int elev)
|
||||||
while (objectListItem != NULL) {
|
while (objectListItem != NULL) {
|
||||||
Object* candidate = objectListItem->obj;
|
Object* candidate = objectListItem->obj;
|
||||||
unsigned int flags = candidate->flags;
|
unsigned int flags = candidate->flags;
|
||||||
if ((flags & OBJECT_FLAG_0x800) != 0) {
|
if ((flags & OBJECT_MULTIHEX) != 0) {
|
||||||
if (candidate->elevation == elev) {
|
if (candidate->elevation == elev) {
|
||||||
if ((flags & OBJECT_HIDDEN) == 0 && (flags & OBJECT_NO_BLOCK) == 0 && candidate != obj) {
|
if ((flags & OBJECT_HIDDEN) == 0 && (flags & OBJECT_NO_BLOCK) == 0 && candidate != obj) {
|
||||||
int type = (candidate->fid & 0xF000000) >> 24;
|
int type = (candidate->fid & 0xF000000) >> 24;
|
||||||
|
@ -2533,7 +2550,7 @@ Object* _obj_ai_blocking_at(Object* a1, int tile, int elevation)
|
||||||
objectListNode = gObjectListHeadByTile[candidate];
|
objectListNode = gObjectListHeadByTile[candidate];
|
||||||
while (objectListNode != NULL) {
|
while (objectListNode != NULL) {
|
||||||
Object* object = objectListNode->obj;
|
Object* object = objectListNode->obj;
|
||||||
if ((object->flags & OBJECT_FLAG_0x800) != 0) {
|
if ((object->flags & OBJECT_MULTIHEX) != 0) {
|
||||||
if (object->elevation == elevation) {
|
if (object->elevation == elevation) {
|
||||||
if ((object->flags & OBJECT_HIDDEN) == 0
|
if ((object->flags & OBJECT_HIDDEN) == 0
|
||||||
&& (object->flags & OBJECT_NO_BLOCK) == 0
|
&& (object->flags & OBJECT_NO_BLOCK) == 0
|
||||||
|
@ -2590,7 +2607,7 @@ Object* _obj_sight_blocking_at(Object* a1, int tile, int elevation)
|
||||||
Object* object = objectListNode->obj;
|
Object* object = objectListNode->obj;
|
||||||
if (object->elevation == elevation
|
if (object->elevation == elevation
|
||||||
&& (object->flags & OBJECT_HIDDEN) == 0
|
&& (object->flags & OBJECT_HIDDEN) == 0
|
||||||
&& (object->flags & OBJECT_FLAG_0x20000000) == 0
|
&& (object->flags & OBJECT_LIGHT_THRU) == 0
|
||||||
&& object != a1) {
|
&& object != a1) {
|
||||||
int objectType = (object->fid & 0xF000000) >> 24;
|
int objectType = (object->fid & 0xF000000) >> 24;
|
||||||
if (objectType == OBJ_TYPE_SCENERY || objectType == OBJ_TYPE_WALL) {
|
if (objectType == OBJ_TYPE_SCENERY || objectType == OBJ_TYPE_WALL) {
|
||||||
|
@ -2612,11 +2629,11 @@ int objectGetDistanceBetween(Object* object1, Object* object2)
|
||||||
|
|
||||||
int distance = tileDistanceBetween(object1->tile, object2->tile);
|
int distance = tileDistanceBetween(object1->tile, object2->tile);
|
||||||
|
|
||||||
if ((object1->flags & OBJECT_FLAG_0x800) != 0) {
|
if ((object1->flags & OBJECT_MULTIHEX) != 0) {
|
||||||
distance -= 1;
|
distance -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((object2->flags & OBJECT_FLAG_0x800) != 0) {
|
if ((object2->flags & OBJECT_MULTIHEX) != 0) {
|
||||||
distance -= 1;
|
distance -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2636,11 +2653,11 @@ int objectGetDistanceBetweenTiles(Object* object1, int tile1, Object* object2, i
|
||||||
|
|
||||||
int distance = tileDistanceBetween(tile1, tile2);
|
int distance = tileDistanceBetween(tile1, tile2);
|
||||||
|
|
||||||
if ((object1->flags & OBJECT_FLAG_0x800) != 0) {
|
if ((object1->flags & OBJECT_MULTIHEX) != 0) {
|
||||||
distance -= 1;
|
distance -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((object2->flags & OBJECT_FLAG_0x800) != 0) {
|
if ((object2->flags & OBJECT_MULTIHEX) != 0) {
|
||||||
distance -= 1;
|
distance -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2869,7 +2886,7 @@ int objectSetOutline(Object* obj, int outlineType, Rect* rect)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((obj->flags & OBJECT_FLAG_0x1000) != 0) {
|
if ((obj->flags & OBJECT_NO_HIGHLIGHT) != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2951,7 +2968,7 @@ int _obj_intersects_with(Object* object, int x, int y)
|
||||||
flags |= 0x01;
|
flags |= 0x01;
|
||||||
|
|
||||||
if ((object->flags & OBJECT_FLAG_0xFC000) != 0) {
|
if ((object->flags & OBJECT_FLAG_0xFC000) != 0) {
|
||||||
if ((object->flags & OBJECT_FLAG_0x8000) == 0) {
|
if ((object->flags & OBJECT_TRANS_NONE) == 0) {
|
||||||
flags &= ~0x03;
|
flags &= ~0x03;
|
||||||
flags |= 0x02;
|
flags |= 0x02;
|
||||||
}
|
}
|
||||||
|
@ -2999,14 +3016,14 @@ int _obj_create_intersect_list(int x, int y, int elevation, int objectType, Obje
|
||||||
int v5 = tileFromScreenXY(x - 320, y - 240, elevation);
|
int v5 = tileFromScreenXY(x - 320, y - 240, elevation);
|
||||||
*entriesPtr = NULL;
|
*entriesPtr = NULL;
|
||||||
|
|
||||||
if (_updateHexArea <= 0) {
|
if (gObjectsUpdateAreaHexSize <= 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
int parity = gCenterTile & 1;
|
int parity = gCenterTile & 1;
|
||||||
for (int index = 0; index < _updateHexArea; index++) {
|
for (int index = 0; index < gObjectsUpdateAreaHexSize; index++) {
|
||||||
int v7 = _orderTable[parity][index];
|
int v7 = _orderTable[parity][index];
|
||||||
if (_offsetDivTable[v7] < 30 && _offsetModTable[v7] < 20) {
|
if (_offsetDivTable[v7] < 30 && _offsetModTable[v7] < 20) {
|
||||||
ObjectListNode* objectListNode = gObjectListHeadByTile[_offsetTable[parity][v7] + v5];
|
ObjectListNode* objectListNode = gObjectListHeadByTile[_offsetTable[parity][v7] + v5];
|
||||||
|
@ -3100,7 +3117,7 @@ void _obj_process_seen()
|
||||||
if (v5 < 40000) {
|
if (v5 < 40000) {
|
||||||
for (obj_entry = gObjectListHeadByTile[v5]; obj_entry != NULL; obj_entry = obj_entry->next) {
|
for (obj_entry = gObjectListHeadByTile[v5]; obj_entry != NULL; obj_entry = obj_entry->next) {
|
||||||
if (obj_entry->obj->elevation == gDude->elevation) {
|
if (obj_entry->obj->elevation == gDude->elevation) {
|
||||||
obj_entry->obj->flags |= OBJECT_FLAG_0x40000000;
|
obj_entry->obj->flags |= OBJECT_SEEN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3238,46 +3255,46 @@ int _obj_offset_table_init()
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
_offsetTable[0] = (int*)internal_malloc(sizeof(int) * _updateHexArea);
|
_offsetTable[0] = (int*)internal_malloc(sizeof(int) * gObjectsUpdateAreaHexSize);
|
||||||
if (_offsetTable[0] == NULL) {
|
if (_offsetTable[0] == NULL) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
_offsetTable[1] = (int*)internal_malloc(sizeof(int) * _updateHexArea);
|
_offsetTable[1] = (int*)internal_malloc(sizeof(int) * gObjectsUpdateAreaHexSize);
|
||||||
if (_offsetTable[1] == NULL) {
|
if (_offsetTable[1] == NULL) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int parity = 0; parity < 2; parity++) {
|
||||||
int tile = tileFromScreenXY(_updateAreaPixelBounds, dword_639D94, 0);
|
int originTile = tileFromScreenXY(gObjectsUpdateAreaPixelBounds.left, gObjectsUpdateAreaPixelBounds.top, 0);
|
||||||
if (tile != -1) {
|
if (originTile != -1) {
|
||||||
int* v5 = _offsetTable[gCenterTile & 1];
|
int* offsets = _offsetTable[gCenterTile & 1];
|
||||||
int v20;
|
int originTileX;
|
||||||
int v19;
|
int originTileY;
|
||||||
tileToScreenXY(tile, &v20, &v19, 0);
|
tileToScreenXY(originTile, &originTileX, &originTileY, 0);
|
||||||
|
|
||||||
int v23 = 16;
|
int parityShift = 16;
|
||||||
v20 += 16;
|
originTileX += 16;
|
||||||
v19 += 8;
|
originTileY += 8;
|
||||||
if (v20 > _updateAreaPixelBounds) {
|
if (originTileX > gObjectsUpdateAreaPixelBounds.left) {
|
||||||
v23 = -v23;
|
parityShift = -parityShift;
|
||||||
}
|
}
|
||||||
|
|
||||||
int v6 = v20;
|
int tileX = originTileX;
|
||||||
for (int j = 0; j < _updateHexHeight; j++) {
|
for (int y = 0; y < gObjectsUpdateAreaHexHeight; y++) {
|
||||||
for (int m = 0; m < _updateHexWidth; m++) {
|
for (int x = 0; x < gObjectsUpdateAreaHexWidth; x++) {
|
||||||
int t = tileFromScreenXY(v6, v19, 0);
|
int tile = tileFromScreenXY(tileX, originTileY, 0);
|
||||||
if (t == -1) {
|
if (tile == -1) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
v6 += 32;
|
tileX += 32;
|
||||||
*v5++ = t - tile;
|
*offsets++ = tile - originTile;
|
||||||
}
|
}
|
||||||
|
|
||||||
v6 = v23 + v20;
|
tileX = parityShift + originTileX;
|
||||||
v19 += 12;
|
originTileY += 12;
|
||||||
v23 = -v23;
|
parityShift = -parityShift;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3286,22 +3303,22 @@ int _obj_offset_table_init()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_offsetDivTable = (int*)internal_malloc(sizeof(int) * _updateHexArea);
|
_offsetDivTable = (int*)internal_malloc(sizeof(int) * gObjectsUpdateAreaHexSize);
|
||||||
if (_offsetDivTable == NULL) {
|
if (_offsetDivTable == NULL) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < _updateHexArea; i++) {
|
for (i = 0; i < gObjectsUpdateAreaHexSize; i++) {
|
||||||
_offsetDivTable[i] = i / _updateHexWidth;
|
_offsetDivTable[i] = i / gObjectsUpdateAreaHexWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
_offsetModTable = (int*)internal_malloc(sizeof(int) * _updateHexArea);
|
_offsetModTable = (int*)internal_malloc(sizeof(int) * gObjectsUpdateAreaHexSize);
|
||||||
if (_offsetModTable == NULL) {
|
if (_offsetModTable == NULL) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < _updateHexArea; i++) {
|
for (i = 0; i < gObjectsUpdateAreaHexSize; i++) {
|
||||||
_offsetModTable[i] = i % _updateHexWidth;
|
_offsetModTable[i] = i % gObjectsUpdateAreaHexWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -3343,23 +3360,23 @@ int _obj_order_table_init()
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
_orderTable[0] = (int*)internal_malloc(sizeof(int) * _updateHexArea);
|
_orderTable[0] = (int*)internal_malloc(sizeof(int) * gObjectsUpdateAreaHexSize);
|
||||||
if (_orderTable[0] == NULL) {
|
if (_orderTable[0] == NULL) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
_orderTable[1] = (int*)internal_malloc(sizeof(int) * _updateHexArea);
|
_orderTable[1] = (int*)internal_malloc(sizeof(int) * gObjectsUpdateAreaHexSize);
|
||||||
if (_orderTable[1] == NULL) {
|
if (_orderTable[1] == NULL) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int index = 0; index < _updateHexArea; index++) {
|
for (int index = 0; index < gObjectsUpdateAreaHexSize; index++) {
|
||||||
_orderTable[0][index] = index;
|
_orderTable[0][index] = index;
|
||||||
_orderTable[1][index] = index;
|
_orderTable[1][index] = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
qsort(_orderTable[0], _updateHexArea, sizeof(int), _obj_order_comp_func_even);
|
qsort(_orderTable[0], gObjectsUpdateAreaHexSize, sizeof(int), _obj_order_comp_func_even);
|
||||||
qsort(_orderTable[1], _updateHexArea, sizeof(int), _obj_order_comp_func_odd);
|
qsort(_orderTable[1], gObjectsUpdateAreaHexSize, sizeof(int), _obj_order_comp_func_odd);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -3410,12 +3427,12 @@ int _obj_render_table_init()
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
_renderTable = (ObjectListNode**)internal_malloc(sizeof(*_renderTable) * _updateHexArea);
|
_renderTable = (ObjectListNode**)internal_malloc(sizeof(*_renderTable) * gObjectsUpdateAreaHexSize);
|
||||||
if (_renderTable == NULL) {
|
if (_renderTable == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int index = 0; index < _updateHexArea; index++) {
|
for (int index = 0; index < gObjectsUpdateAreaHexSize; index++) {
|
||||||
_renderTable[index] = NULL;
|
_renderTable[index] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3438,11 +3455,11 @@ void _obj_light_table_init()
|
||||||
{
|
{
|
||||||
for (int s = 0; s < 2; s++) {
|
for (int s = 0; s < 2; s++) {
|
||||||
int v4 = gCenterTile + s;
|
int v4 = gCenterTile + s;
|
||||||
for (int i = 0; i < 6; i++) {
|
for (int i = 0; i < ROTATION_COUNT; i++) {
|
||||||
int v15 = 8;
|
int v15 = 8;
|
||||||
int* p = _light_offsets[v4 & 1][i];
|
int* p = _light_offsets[v4 & 1][i];
|
||||||
for (int j = 0; j < 8; j++) {
|
for (int j = 0; j < 8; j++) {
|
||||||
int tile = tileGetTileInDirection(v4, (i + 1) % 6, j);
|
int tile = tileGetTileInDirection(v4, (i + 1) % ROTATION_COUNT, j);
|
||||||
|
|
||||||
for (int m = 0; m < v15; m++) {
|
for (int m = 0; m < v15; m++) {
|
||||||
*p++ = tileGetTileInDirection(tile, i, m + 1) - v4;
|
*p++ = tileGetTileInDirection(tile, i, m + 1) - v4;
|
||||||
|
@ -3856,11 +3873,11 @@ void _obj_insert(ObjectListNode* objectListNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj->elevation == objectListNode->obj->elevation) {
|
if (obj->elevation == objectListNode->obj->elevation) {
|
||||||
if ((obj->flags & OBJECT_FLAG_0x08) == 0 && (objectListNode->obj->flags & OBJECT_FLAG_0x08) != 0) {
|
if ((obj->flags & OBJECT_FLAT) == 0 && (objectListNode->obj->flags & OBJECT_FLAT) != 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((obj->flags & OBJECT_FLAG_0x08) == (objectListNode->obj->flags & OBJECT_FLAG_0x08)) {
|
if ((obj->flags & OBJECT_FLAT) == (objectListNode->obj->flags & OBJECT_FLAT)) {
|
||||||
bool v11 = false;
|
bool v11 = false;
|
||||||
CacheEntry* a2;
|
CacheEntry* a2;
|
||||||
Art* v12 = artLock(obj->fid, &a2);
|
Art* v12 = artLock(obj->fid, &a2);
|
||||||
|
@ -4553,10 +4570,10 @@ int _obj_adjust_light(Object* obj, int a2, Rect* rect)
|
||||||
objectGetRect(objectListNode->obj, &v29);
|
objectGetRect(objectListNode->obj, &v29);
|
||||||
rectUnion(&objectRect, &v29, &objectRect);
|
rectUnion(&objectRect, &v29, &objectRect);
|
||||||
|
|
||||||
v14 = (objectListNode->obj->flags & OBJECT_FLAG_0x20000000) == 0;
|
v14 = (objectListNode->obj->flags & OBJECT_LIGHT_THRU) == 0;
|
||||||
|
|
||||||
if ((objectListNode->obj->fid & 0xF000000) >> 24 == OBJ_TYPE_WALL) {
|
if ((objectListNode->obj->fid & 0xF000000) >> 24 == OBJ_TYPE_WALL) {
|
||||||
if ((objectListNode->obj->flags & OBJECT_FLAG_0x08) == 0) {
|
if ((objectListNode->obj->flags & OBJECT_FLAT) == 0) {
|
||||||
Proto* proto;
|
Proto* proto;
|
||||||
protoGetProto(objectListNode->obj->pid, &proto);
|
protoGetProto(objectListNode->obj->pid, &proto);
|
||||||
if ((proto->wall.extendedFlags & 0x8000000) != 0 || (proto->wall.extendedFlags & 0x40000000) != 0) {
|
if ((proto->wall.extendedFlags & 0x8000000) != 0 || (proto->wall.extendedFlags & 0x40000000) != 0) {
|
||||||
|
@ -4964,7 +4981,7 @@ void _obj_render_object(Object* object, Rect* rect, int light)
|
||||||
v17 = tileIsInFrontOf(object->tile, gDude->tile);
|
v17 = tileIsInFrontOf(object->tile, gDude->tile);
|
||||||
if (!v17
|
if (!v17
|
||||||
|| !tileIsToRightOf(object->tile, gDude->tile)
|
|| !tileIsToRightOf(object->tile, gDude->tile)
|
||||||
|| (object->flags & OBJECT_FLAG_0x10000000) == 0) {
|
|| (object->flags & OBJECT_WALL_TRANS_END) == 0) {
|
||||||
// nothing
|
// nothing
|
||||||
} else {
|
} else {
|
||||||
v17 = false;
|
v17 = false;
|
||||||
|
@ -4980,7 +4997,7 @@ void _obj_render_object(Object* object, Rect* rect, int light)
|
||||||
v17 = tileIsToRightOf(gDude->tile, object->tile);
|
v17 = tileIsToRightOf(gDude->tile, object->tile);
|
||||||
if (v17
|
if (v17
|
||||||
&& tileIsInFrontOf(gDude->tile, object->tile)
|
&& tileIsInFrontOf(gDude->tile, object->tile)
|
||||||
&& (object->flags & OBJECT_FLAG_0x10000000) != 0) {
|
&& (object->flags & OBJECT_WALL_TRANS_END) != 0) {
|
||||||
v17 = 0;
|
v17 = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5071,19 +5088,19 @@ void _obj_render_object(Object* object, Rect* rect, int light)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (object->flags & OBJECT_FLAG_0xFC000) {
|
switch (object->flags & OBJECT_FLAG_0xFC000) {
|
||||||
case OBJECT_FLAG_0x4000:
|
case OBJECT_TRANS_RED:
|
||||||
_dark_translucent_trans_buf_to_buf(src, objectWidth, objectHeight, frameWidth, gObjectsWindowBuffer, objectRect.left, objectRect.top, gObjectsWindowPitch, light, _redBlendTable, _commonGrayTable);
|
_dark_translucent_trans_buf_to_buf(src, objectWidth, objectHeight, frameWidth, gObjectsWindowBuffer, objectRect.left, objectRect.top, gObjectsWindowPitch, light, _redBlendTable, _commonGrayTable);
|
||||||
break;
|
break;
|
||||||
case OBJECT_FLAG_0x10000:
|
case OBJECT_TRANS_WALL:
|
||||||
_dark_translucent_trans_buf_to_buf(src, objectWidth, objectHeight, frameWidth, gObjectsWindowBuffer, objectRect.left, objectRect.top, gObjectsWindowPitch, 0x10000, _wallBlendTable, _commonGrayTable);
|
_dark_translucent_trans_buf_to_buf(src, objectWidth, objectHeight, frameWidth, gObjectsWindowBuffer, objectRect.left, objectRect.top, gObjectsWindowPitch, 0x10000, _wallBlendTable, _commonGrayTable);
|
||||||
break;
|
break;
|
||||||
case OBJECT_FLAG_0x20000:
|
case OBJECT_TRANS_GLASS:
|
||||||
_dark_translucent_trans_buf_to_buf(src, objectWidth, objectHeight, frameWidth, gObjectsWindowBuffer, objectRect.left, objectRect.top, gObjectsWindowPitch, light, _glassBlendTable, _glassGrayTable);
|
_dark_translucent_trans_buf_to_buf(src, objectWidth, objectHeight, frameWidth, gObjectsWindowBuffer, objectRect.left, objectRect.top, gObjectsWindowPitch, light, _glassBlendTable, _glassGrayTable);
|
||||||
break;
|
break;
|
||||||
case OBJECT_FLAG_0x40000:
|
case OBJECT_TRANS_STEAM:
|
||||||
_dark_translucent_trans_buf_to_buf(src, objectWidth, objectHeight, frameWidth, gObjectsWindowBuffer, objectRect.left, objectRect.top, gObjectsWindowPitch, light, _steamBlendTable, _commonGrayTable);
|
_dark_translucent_trans_buf_to_buf(src, objectWidth, objectHeight, frameWidth, gObjectsWindowBuffer, objectRect.left, objectRect.top, gObjectsWindowPitch, light, _steamBlendTable, _commonGrayTable);
|
||||||
break;
|
break;
|
||||||
case OBJECT_FLAG_0x80000:
|
case OBJECT_TRANS_ENERGY:
|
||||||
_dark_translucent_trans_buf_to_buf(src, objectWidth, objectHeight, frameWidth, gObjectsWindowBuffer, objectRect.left, objectRect.top, gObjectsWindowPitch, light, _energyBlendTable, _commonGrayTable);
|
_dark_translucent_trans_buf_to_buf(src, objectWidth, objectHeight, frameWidth, gObjectsWindowBuffer, objectRect.left, objectRect.top, gObjectsWindowPitch, light, _energyBlendTable, _commonGrayTable);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
11
src/object.h
11
src/object.h
|
@ -13,9 +13,9 @@ typedef struct ObjectWithFlags {
|
||||||
} ObjectWithFlags;
|
} ObjectWithFlags;
|
||||||
|
|
||||||
extern bool gObjectsInitialized;
|
extern bool gObjectsInitialized;
|
||||||
extern int _updateHexWidth;
|
extern int gObjectsUpdateAreaHexWidth;
|
||||||
extern int _updateHexHeight;
|
extern int gObjectsUpdateAreaHexHeight;
|
||||||
extern int _updateHexArea;
|
extern int gObjectsUpdateAreaHexSize;
|
||||||
extern int* _orderTable[2];
|
extern int* _orderTable[2];
|
||||||
extern int* _offsetTable[2];
|
extern int* _offsetTable[2];
|
||||||
extern int* _offsetModTable;
|
extern int* _offsetModTable;
|
||||||
|
@ -49,10 +49,7 @@ extern int _light_blocked[6][36];
|
||||||
extern int _light_offsets[2][6][36];
|
extern int _light_offsets[2][6][36];
|
||||||
extern Rect gObjectsWindowRect;
|
extern Rect gObjectsWindowRect;
|
||||||
extern Object* _outlinedObjects[100];
|
extern Object* _outlinedObjects[100];
|
||||||
extern int _updateAreaPixelBounds;
|
extern Rect gObjectsUpdateAreaPixelBounds;
|
||||||
extern int dword_639D94;
|
|
||||||
extern int dword_639D98;
|
|
||||||
extern int dword_639D9C;
|
|
||||||
extern ObjectListNode* gObjectListHeadByTile[HEX_GRID_SIZE];
|
extern ObjectListNode* gObjectListHeadByTile[HEX_GRID_SIZE];
|
||||||
extern unsigned char _glassGrayTable[256];
|
extern unsigned char _glassGrayTable[256];
|
||||||
extern unsigned char _commonGrayTable[256];
|
extern unsigned char _commonGrayTable[256];
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <timeapi.h>
|
#include <timeapi.h>
|
||||||
#else
|
#else
|
||||||
#include <sys/time.h>
|
#include <chrono>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int compat_stricmp(const char* string1, const char* string2)
|
int compat_stricmp(const char* string1, const char* string2)
|
||||||
|
@ -145,8 +145,8 @@ unsigned int compat_timeGetTime()
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
return timeGetTime();
|
return timeGetTime();
|
||||||
#else
|
#else
|
||||||
struct timeval tv;
|
static auto start = std::chrono::steady_clock::now();
|
||||||
gettimeofday(&tv, NULL);
|
auto now = std::chrono::steady_clock::now();
|
||||||
return tv.tv_usec / 1000;
|
return static_cast<unsigned int>(std::chrono::duration_cast<std::chrono::milliseconds>(now - start).count());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -777,7 +777,7 @@ int _proto_dude_init(const char* path)
|
||||||
_proto_dude_update_gender();
|
_proto_dude_update_gender();
|
||||||
_inven_reset_dude();
|
_inven_reset_dude();
|
||||||
|
|
||||||
if ((gDude->flags & OBJECT_FLAG_0x08) != 0) {
|
if ((gDude->flags & OBJECT_FLAT) != 0) {
|
||||||
_obj_toggle_flat(gDude, NULL);
|
_obj_toggle_flat(gDude, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1854,7 +1854,7 @@ int _ResetPlayer()
|
||||||
pcStatsReset();
|
pcStatsReset();
|
||||||
protoCritterDataResetStats(&(proto->critter.data));
|
protoCritterDataResetStats(&(proto->critter.data));
|
||||||
critterReset();
|
critterReset();
|
||||||
_editor_reset();
|
characterEditorReset();
|
||||||
protoCritterDataResetSkills(&(proto->critter.data));
|
protoCritterDataResetSkills(&(proto->critter.data));
|
||||||
skillsReset();
|
skillsReset();
|
||||||
perksReset();
|
perksReset();
|
||||||
|
|
|
@ -796,7 +796,7 @@ int _obj_use_flare(Object* critter_obj, Object* flare)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flare->flags & OBJECT_FLAG_0x2000) != 0) {
|
if ((flare->flags & OBJECT_USED) != 0) {
|
||||||
if (critter_obj == gDude) {
|
if (critter_obj == gDude) {
|
||||||
// The flare is already lit.
|
// The flare is already lit.
|
||||||
messageListItem.num = 588;
|
messageListItem.num = 588;
|
||||||
|
@ -854,7 +854,7 @@ int _obj_use_explosive(Object* explosive)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((explosive->flags & OBJECT_FLAG_0x2000) != 0) {
|
if ((explosive->flags & OBJECT_USED) != 0) {
|
||||||
// The timer is already ticking.
|
// The timer is already ticking.
|
||||||
messageListItem.num = 590;
|
messageListItem.num = 590;
|
||||||
if (messageListGetItem(&gProtoMessageList, &messageListItem)) {
|
if (messageListGetItem(&gProtoMessageList, &messageListItem)) {
|
||||||
|
@ -2198,7 +2198,7 @@ int _objPMAttemptPlacement(Object* obj, int tile, int elevation)
|
||||||
for (int v4 = 1; v4 <= 100; v4++) {
|
for (int v4 = 1; v4 <= 100; v4++) {
|
||||||
// TODO: Check.
|
// TODO: Check.
|
||||||
v7++;
|
v7++;
|
||||||
v9 = tileGetTileInDirection(v9, v7 % 6, 1);
|
v9 = tileGetTileInDirection(v9, v7 % ROTATION_COUNT, 1);
|
||||||
if (_wmEvalTileNumForPlacement(v9) != 0) {
|
if (_wmEvalTileNumForPlacement(v9) != 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -232,7 +232,7 @@ int queueAddEvent(int delay, Object* obj, void* data, int eventType)
|
||||||
newQueueListNode->data = data;
|
newQueueListNode->data = data;
|
||||||
|
|
||||||
if (obj != NULL) {
|
if (obj != NULL) {
|
||||||
obj->flags |= OBJECT_FLAG_0x2000;
|
obj->flags |= OBJECT_USED;
|
||||||
}
|
}
|
||||||
|
|
||||||
QueueListNode** v3 = &gQueueListHead;
|
QueueListNode** v3 = &gQueueListHead;
|
||||||
|
|
|
@ -1723,7 +1723,8 @@ int scriptWrite(Script* scr, File* stream)
|
||||||
|
|
||||||
if (fileWriteInt32(stream, scr->flags) == -1) return -1;
|
if (fileWriteInt32(stream, scr->flags) == -1) return -1;
|
||||||
if (fileWriteInt32(stream, scr->field_14) == -1) return -1;
|
if (fileWriteInt32(stream, scr->field_14) == -1) return -1;
|
||||||
if (fileWriteInt32(stream, (int)scr->program) == -1) return -1; // FIXME: writing pointer to file
|
// NOTE: Original code writes `scr->program` pointer which is meaningless.
|
||||||
|
if (fileWriteInt32(stream, 0) == -1) return -1;
|
||||||
if (fileWriteInt32(stream, scr->field_1C) == -1) return -1;
|
if (fileWriteInt32(stream, scr->field_1C) == -1) return -1;
|
||||||
if (fileWriteInt32(stream, scr->localVarsOffset) == -1) return -1;
|
if (fileWriteInt32(stream, scr->localVarsOffset) == -1) return -1;
|
||||||
if (fileWriteInt32(stream, scr->localVarsCount) == -1) return -1;
|
if (fileWriteInt32(stream, scr->localVarsCount) == -1) return -1;
|
||||||
|
@ -1753,8 +1754,8 @@ int scriptListExtentWrite(ScriptListExtent* a1, File* stream)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fileWriteInt32(stream, (int)a1->next) != 0) {
|
// NOTE: Original code writes `a1->next` pointer which is meaningless.
|
||||||
// FIXME: writing pointer to file
|
if (fileWriteInt32(stream, 0) != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1778,18 +1779,16 @@ int scriptSaveAll(File* stream)
|
||||||
for (int index = 0; index < scriptExtent->length; index++) {
|
for (int index = 0; index < scriptExtent->length; index++) {
|
||||||
Script* script = &(scriptExtent->scripts[index]);
|
Script* script = &(scriptExtent->scripts[index]);
|
||||||
|
|
||||||
|
lastScriptExtent = scriptList->tail;
|
||||||
if ((script->flags & SCRIPT_FLAG_0x08) != 0) {
|
if ((script->flags & SCRIPT_FLAG_0x08) != 0) {
|
||||||
scriptCount--;
|
scriptCount--;
|
||||||
|
|
||||||
lastScriptExtent = scriptList->tail;
|
|
||||||
int backwardsIndex = lastScriptExtent->length - 1;
|
int backwardsIndex = lastScriptExtent->length - 1;
|
||||||
while (lastScriptExtent != scriptExtent || backwardsIndex > index) {
|
if (lastScriptExtent == scriptExtent && backwardsIndex <= index) {
|
||||||
if (lastScriptExtent == scriptExtent) {
|
break;
|
||||||
if (backwardsIndex >= index) {
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
while (lastScriptExtent != scriptExtent || backwardsIndex > index) {
|
||||||
Script* backwardsScript = &(lastScriptExtent->scripts[backwardsIndex]);
|
Script* backwardsScript = &(lastScriptExtent->scripts[backwardsIndex]);
|
||||||
if ((backwardsScript->flags & SCRIPT_FLAG_0x08) == 0) {
|
if ((backwardsScript->flags & SCRIPT_FLAG_0x08) == 0) {
|
||||||
break;
|
break;
|
||||||
|
@ -2427,7 +2426,7 @@ bool scriptsExecSpatialProc(Object* object, int tile, int elevation)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((object->flags & OBJECT_HIDDEN) != 0 || (object->flags & OBJECT_FLAG_0x08) != 0) {
|
if ((object->flags & OBJECT_HIDDEN) != 0 || (object->flags & OBJECT_FLAT) != 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2685,7 +2684,7 @@ int scriptGetLocalVar(int sid, int variable, int* value)
|
||||||
}
|
}
|
||||||
|
|
||||||
Script* script;
|
Script* script;
|
||||||
if (scriptGetScript(sid, &script) == 1) {
|
if (scriptGetScript(sid, &script) == -1) {
|
||||||
*value = -1;
|
*value = -1;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,15 @@ bool sfallConfigInit(int argc, char** argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize defaults.
|
// Initialize defaults.
|
||||||
|
configSetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_DUDE_NATIVE_LOOK_JUMPSUIT_MALE_KEY, "");
|
||||||
|
configSetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_DUDE_NATIVE_LOOK_JUMPSUIT_FEMALE_KEY, "");
|
||||||
|
configSetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_DUDE_NATIVE_LOOK_TRIBAL_MALE_KEY, "");
|
||||||
|
configSetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_DUDE_NATIVE_LOOK_TRIBAL_FEMALE_KEY, "");
|
||||||
|
configSetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_MAIN_MENU_BIG_FONT_COLOR_KEY, 0);
|
||||||
|
configSetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_MAIN_MENU_FONT_COLOR_KEY, 0);
|
||||||
|
configSetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_SKIP_OPENING_MOVIES_KEY, 0);
|
||||||
configSetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_STARTING_MAP_KEY, "");
|
configSetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_STARTING_MAP_KEY, "");
|
||||||
|
configSetBool(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_DISPLAY_KARMA_CHANGES_KEY, false);
|
||||||
|
|
||||||
char path[COMPAT_MAX_PATH];
|
char path[COMPAT_MAX_PATH];
|
||||||
char* executable = argv[0];
|
char* executable = argv[0];
|
||||||
|
|
|
@ -7,7 +7,17 @@
|
||||||
|
|
||||||
#define SFALL_CONFIG_MISC_KEY "Misc"
|
#define SFALL_CONFIG_MISC_KEY "Misc"
|
||||||
|
|
||||||
|
#define SFALL_CONFIG_DUDE_NATIVE_LOOK_JUMPSUIT_MALE_KEY "MaleDefaultModel"
|
||||||
|
#define SFALL_CONFIG_DUDE_NATIVE_LOOK_JUMPSUIT_FEMALE_KEY "FemaleDefaultModel"
|
||||||
|
#define SFALL_CONFIG_DUDE_NATIVE_LOOK_TRIBAL_MALE_KEY "MaleStartModel"
|
||||||
|
#define SFALL_CONFIG_DUDE_NATIVE_LOOK_TRIBAL_FEMALE_KEY "FemaleStartModel"
|
||||||
|
#define SFALL_CONFIG_MAIN_MENU_BIG_FONT_COLOR_KEY "MainMenuBigFontColour"
|
||||||
|
#define SFALL_CONFIG_MAIN_MENU_FONT_COLOR_KEY "MainMenuFontColour"
|
||||||
|
#define SFALL_CONFIG_SKIP_OPENING_MOVIES_KEY "SkipOpeningMovies"
|
||||||
#define SFALL_CONFIG_STARTING_MAP_KEY "StartingMap"
|
#define SFALL_CONFIG_STARTING_MAP_KEY "StartingMap"
|
||||||
|
#define SFALL_CONFIG_KARMA_FRMS_KEY "KarmaFRMs"
|
||||||
|
#define SFALL_CONFIG_KARMA_POINTS_KEY "KarmaPoints"
|
||||||
|
#define SFALL_CONFIG_DISPLAY_KARMA_CHANGES_KEY "DisplayKarmaChanges"
|
||||||
|
|
||||||
extern bool gSfallConfigInitialized;
|
extern bool gSfallConfigInitialized;
|
||||||
extern Config gSfallConfig;
|
extern Config gSfallConfig;
|
||||||
|
|
|
@ -323,6 +323,7 @@ int critterGetStat(Object* critter, int stat)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case STAT_DAMAGE_RESISTANCE:
|
case STAT_DAMAGE_RESISTANCE:
|
||||||
|
case STAT_DAMAGE_RESISTANCE_EXPLOSION:
|
||||||
if (perkGetRank(critter, PERK_DERMAL_IMPACT_ARMOR)) {
|
if (perkGetRank(critter, PERK_DERMAL_IMPACT_ARMOR)) {
|
||||||
value += 5;
|
value += 5;
|
||||||
} else if (perkGetRank(critter, PERK_DERMAL_IMPACT_ASSAULT_ENHANCEMENT)) {
|
} else if (perkGetRank(critter, PERK_DERMAL_IMPACT_ASSAULT_ENHANCEMENT)) {
|
||||||
|
|
|
@ -125,9 +125,18 @@ int textFontLoad(int font)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fileRead(textFontDescriptor, sizeof(TextFontDescriptor), 1, stream) != 1) {
|
// NOTE: Original code reads entire descriptor in one go. This does not work
|
||||||
goto out;
|
// in x64 because of the two pointers.
|
||||||
}
|
|
||||||
|
if (fileRead(&(textFontDescriptor->glyphCount), 4, 1, stream) != 1) goto out;
|
||||||
|
if (fileRead(&(textFontDescriptor->lineHeight), 4, 1, stream) != 1) goto out;
|
||||||
|
if (fileRead(&(textFontDescriptor->letterSpacing), 4, 1, stream) != 1) goto out;
|
||||||
|
|
||||||
|
int glyphsPtr;
|
||||||
|
if (fileRead(&glyphsPtr, 4, 1, stream) != 1) goto out;
|
||||||
|
|
||||||
|
int dataPtr;
|
||||||
|
if (fileRead(&dataPtr, 4, 1, stream) != 1) goto out;
|
||||||
|
|
||||||
textFontDescriptor->glyphs = (TextFontGlyph*)internal_malloc(textFontDescriptor->glyphCount * sizeof(TextFontGlyph));
|
textFontDescriptor->glyphs = (TextFontGlyph*)internal_malloc(textFontDescriptor->glyphCount * sizeof(TextFontGlyph));
|
||||||
if (textFontDescriptor->glyphs == NULL) {
|
if (textFontDescriptor->glyphs == NULL) {
|
||||||
|
|
14
src/tile.cc
14
src/tile.cc
|
@ -387,9 +387,23 @@ int tileInit(TileData** a1, int squareGridWidth, int squareGridHeight, int hexGr
|
||||||
bufferDrawLine(_tile_grid_blocked, 32, v25, v20, v22, v20, _colorTable[31744]);
|
bufferDrawLine(_tile_grid_blocked, 32, v25, v20, v22, v20, _colorTable[31744]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// In order to calculate scroll borders correctly we need to pretend we're
|
||||||
|
// at original resolution. Since border is calculated only once at start,
|
||||||
|
// there is not need to change it all the time.
|
||||||
|
gTileWindowWidth = ORIGINAL_ISO_WINDOW_WIDTH;
|
||||||
|
gTileWindowHeight = ORIGINAL_ISO_WINDOW_HEIGHT;
|
||||||
|
|
||||||
tileSetCenter(hexGridWidth * (hexGridHeight / 2) + hexGridWidth / 2, 2);
|
tileSetCenter(hexGridWidth * (hexGridHeight / 2) + hexGridWidth / 2, 2);
|
||||||
tileSetBorder(windowWidth, windowHeight, hexGridWidth, hexGridHeight);
|
tileSetBorder(windowWidth, windowHeight, hexGridWidth, hexGridHeight);
|
||||||
|
|
||||||
|
// Restore actual window size and set center one more time to calculate
|
||||||
|
// correct screen offsets, which are required for subsequent object update
|
||||||
|
// area calculations.
|
||||||
|
gTileWindowWidth = windowWidth;
|
||||||
|
gTileWindowHeight = windowHeight;
|
||||||
|
|
||||||
|
tileSetCenter(hexGridWidth * (hexGridHeight / 2) + hexGridWidth / 2, 2);
|
||||||
|
|
||||||
char* executable;
|
char* executable;
|
||||||
configGetString(&gGameConfig, GAME_CONFIG_SYSTEM_KEY, GAME_CONFIG_EXECUTABLE_KEY, &executable);
|
configGetString(&gGameConfig, GAME_CONFIG_SYSTEM_KEY, GAME_CONFIG_EXECUTABLE_KEY, &executable);
|
||||||
if (compat_stricmp(executable, "mapper") == 0) {
|
if (compat_stricmp(executable, "mapper") == 0) {
|
||||||
|
|
|
@ -265,6 +265,8 @@ void windowManagerExit(void)
|
||||||
textFontsExit();
|
textFontsExit();
|
||||||
_colorsClose();
|
_colorsClose();
|
||||||
|
|
||||||
|
SDL_DestroyWindow(gSdlWindow);
|
||||||
|
|
||||||
gWindowSystemInitialized = false;
|
gWindowSystemInitialized = false;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
|
@ -617,7 +617,7 @@ bool xlistEnumerate(const char* pattern, XListEnumerationHandler* handler, XList
|
||||||
}
|
}
|
||||||
} while (fileFindNext(&directoryFileFindData));
|
} while (fileFindNext(&directoryFileFindData));
|
||||||
}
|
}
|
||||||
return findFindClose(&directoryFileFindData);
|
findFindClose(&directoryFileFindData);
|
||||||
}
|
}
|
||||||
xbase = xbase->next;
|
xbase = xbase->next;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue