diff --git a/.gitattributes b/.gitattributes index 2e6e67b..3833b81 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,6 +1,7 @@ # Force LF *.c text eol=lf *.cc text eol=lf +*.cmake text eol=lf *.h text eol=lf *.md text eol=lf *.json text eol=lf diff --git a/.github/workflows/Build.yml b/.github/workflows/Build.yml index 53b9d20..4be625f 100644 --- a/.github/workflows/Build.yml +++ b/.github/workflows/Build.yml @@ -4,15 +4,17 @@ on: push: paths: - '.github/workflows/Build.yml' - - 'src/**.c' + - 'src/**.cc' - 'src/**.h' - '**/CMakeLists.txt' + - '**/*.cmake' pull_request: paths: - '.github/workflows/Build.yml' - - 'src/**.c' + - 'src/**.cc' - 'src/**.h' - '**/CMakeLists.txt' + - '**/*.cmake' defaults: run: @@ -20,23 +22,195 @@ defaults: jobs: - Build: - runs-on: windows-latest + StaticAnalysis: + name: Static analysis + runs-on: ubuntu-latest steps: + - name: Install + run: | + : + echo ::group::apt update + sudo apt update 2>&1 + echo ::endgroup:: + sudo apt install cppcheck + - 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..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 - 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 - run: cmake --build Build --config Release + - name: Build + 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 with: - name: fallout2-ce - path: | - Build/*/fallout2-ce.exe + name: fallout2-ce-${{ matrix.cfg.artifact-os }} + path: "${{ matrix.cfg.artifact-os }}/x${{ matrix.cfg.arch }}" retention-days: 7 diff --git a/CMakeLists.txt b/CMakeLists.txt index 3dd60d4..e7fba32 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -247,6 +247,11 @@ if(WIN32) _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_WARNINGS ) +else() + target_compile_definitions(${EXECUTABLE_NAME} PRIVATE + $<$:_DEBUG> + $<$:_DEBUG> + ) endif() if(WIN32) @@ -259,7 +264,7 @@ add_subdirectory("third_party/fpattern") target_link_libraries(${EXECUTABLE_NAME} ${FPATTERN_LIBRARY}) 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/sdl2") else() diff --git a/cmake/toolchain/Linux32.cmake b/cmake/toolchain/Linux32.cmake new file mode 100644 index 0000000..3582f6b --- /dev/null +++ b/cmake/toolchain/Linux32.cmake @@ -0,0 +1,4 @@ +set( CMAKE_SYSTEM_NAME "Linux" ) +set( CMAKE_SYSTEM_PROCESSOR "i386" ) +set( CMAKE_C_FLAGS "-m32" ) +set( CMAKE_CXX_FLAGS "-m32" ) diff --git a/src/actions.cc b/src/actions.cc index e5c4d91..1cbd6b6 100644 --- a/src/actions.cc +++ b/src/actions.cc @@ -40,8 +40,8 @@ int _action_in_explode = 0; const int gNormalDeathAnimations[DAMAGE_TYPE_COUNT] = { ANIM_DANCING_AUTOFIRE, ANIM_SLICED_IN_HALF, - ANIM_CHUNKS_OF_FLESH, - ANIM_CHUNKS_OF_FLESH, + ANIM_CHARRED_BODY, + ANIM_CHARRED_BODY, ANIM_ELECTRIFY, ANIM_FALL_BACK, ANIM_BIG_HOLE, @@ -1454,7 +1454,7 @@ int _pick_fall(Object* obj, int anim) } } } else if (anim == ANIM_FALL_BACK) { - rotation = (obj->rotation + 3) % 6u; + rotation = (obj->rotation + 3) % ROTATION_COUNT; for (i = 1; i < 3; i++) { tile_num = tileGetTileInDirection(obj->tile, rotation, i); 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 ((a3->flags & OBJECT_FLAG_0x800) == 0) { + if ((a3->flags & OBJECT_MULTIHEX) == 0) { *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 ((obj->flags & OBJECT_FLAG_0x800) == 0 && damageType != DAMAGE_TYPE_ELECTRICAL) { + if ((obj->flags & OBJECT_MULTIHEX) == 0 && damageType != DAMAGE_TYPE_ELECTRICAL) { *a4 = v10 / 10; } } diff --git a/src/animation.cc b/src/animation.cc index dbd6e5a..b56f94a 100644 --- a/src/animation.cc +++ b/src/animation.cc @@ -1682,7 +1682,7 @@ int _make_straight_path_func(Object* a1, int from, int to, STRUCT_530014_28* a4, if (a5 != NULL) { Object* v11 = a7(a1, from, a1->elevation); 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; 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 pathNodeIndex = 0; - int v50 = from; + int prevTile = from; int v22 = 0; int tile; @@ -1770,17 +1770,17 @@ int _make_straight_path_func(Object* a1, int from, int to, STRUCT_530014_28* a4, tileY += stepY; middle += v48; - if (tile != v50) { + if (tile != prevTile) { if (a5 != NULL) { Object* obj = a7(a1, tile, a1->elevation); 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; break; } } } - v50 = tile; + prevTile = tile; } } } else { @@ -1823,16 +1823,17 @@ int _make_straight_path_func(Object* a1, int from, int to, STRUCT_530014_28* a4, tileX += stepX; middle += v47; - if (tile != v50) { + if (tile != prevTile) { if (a5 != NULL) { Object* obj = a7(a1, tile, a1->elevation); 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; break; } } } + prevTile = tile; } } } @@ -1863,38 +1864,35 @@ int _make_straight_path_func(Object* a1, int from, int to, STRUCT_530014_28* a4, } // 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; - int v13; - STRUCT_530014* ptr; + bool hidden = (to->flags & OBJECT_HIDDEN); + to->flags |= OBJECT_HIDDEN; - int hidden = (a2->flags & OBJECT_HIDDEN); - a2->flags |= OBJECT_HIDDEN; + int moveSadIndex = _anim_move(from, to->tile, to->elevation, -1, anim, 0, animationSequenceIndex); - v10 = _anim_move(a1, a2->tile, a2->elevation, -1, anim, 0, animationSequenceIndex); - - if (hidden == 0) { - a2->flags &= ~OBJECT_HIDDEN; + if (!hidden) { + to->flags &= ~OBJECT_HIDDEN; } - if (v10 == -1) { + if (moveSadIndex == -1) { return -1; } - ptr = &(_sad[v10]); - v13 = (((a1->flags & OBJECT_FLAG_0x800) != 0) + 1); // TODO: What the hell is this? - ptr->field_1C -= v13; + STRUCT_530014* ptr = &(_sad[moveSadIndex]); + // NOTE: Original code is somewhat different. Due to some kind of + // 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) { ptr->field_20 = -1000; _anim_set_continue(animationSequenceIndex, 0); } - if (v13) { - ptr->field_24 = tileGetTileInDirection(a2->tile, ptr->field_24 + v13 + ptr->field_1C + 3, 1); - } + ptr->field_24 = tileGetTileInDirection(to->tile, ptr->rotations[isMultihex ? ptr->field_1C + 1 : ptr->field_1C], 1); - if (v13 == 2) { + if (isMultihex) { ptr->field_24 = tileGetTileInDirection(ptr->field_24, ptr->rotations[ptr->field_1C], 1); } diff --git a/src/animation.h b/src/animation.h index a96b9f9..8003405 100644 --- a/src/animation.h +++ b/src/animation.h @@ -257,15 +257,15 @@ int _idist(int a1, int a2, int a3, int a4); 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_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 animateMoveObjectToTile(Object* obj, int tile_num, int elev, int a4, int a5, int a6); -int _anim_move(Object* obj, int tile, int elev, int a3, int a4, 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_on_stairs(Object* obj, int a2, int a3, int fid, int a5); -int _check_for_falling(Object* obj, int a2, int a3); +int animateMoveObjectToObject(Object* from, Object* to, int a3, int anim, int animationSequenceIndex); +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 anim, int a5, int animationSequenceIndex); +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 tile, int elevation, int anim, int animationSequenceIndex); +int _check_for_falling(Object* obj, int anim, int a3); void _object_move(int index); -void _object_straight_move(int a1); -int _anim_animate(Object* obj, int a2, int a3, int a4); +void _object_straight_move(int index); +int _anim_animate(Object* obj, int anim, int animationSequenceIndex, int flags); void _object_animate(); void _object_anim_compact(); int _check_move(int* a1); @@ -274,8 +274,8 @@ int _dude_run(int a1); void _dude_fidget(); void _dude_stand(Object* obj, int rotation, int fid); void _dude_standup(Object* a1); -int actionRotate(Object* obj, int a2, int a3); -int _anim_change_fid(Object* obj, int a2, int fid); +int actionRotate(Object* obj, int delta, int animationSequenceIndex); +int _anim_change_fid(Object* obj, int animationSequenceIndex, int fid); void _anim_stop(); int _check_gravity(int tile, int elevation); unsigned int _compute_tpf(Object* object, int fid); diff --git a/src/art.cc b/src/art.cc index fc4ab4d..d2c832d 100644 --- a/src/art.cc +++ b/src/art.cc @@ -7,11 +7,24 @@ #include "memory.h" #include "object.h" #include "proto.h" +#include "sfall_config.h" #include #include #include +// 0x5002D8 +char gDefaultJumpsuitMaleFileName[] = "hmjmps"; + +// 0x05002E0 +char gDefaultJumpsuitFemaleFileName[] = "hfjmps"; + +// 0x5002E8 +char gDefaultTribalMaleFileName[] = "hmwarr"; + +// 0x5002F0 +char gDefaultTribalFemaleFileName[] = "hfprim"; + // 0x510738 ArtListDescription gArtListDescriptions[OBJ_TYPE_COUNT] = { { 0, "items", 0, 0, 0 }, @@ -153,18 +166,43 @@ int artInit() 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; 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; - } 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; } - 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_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; } diff --git a/src/art.h b/src/art.h index 38258f8..7c96067 100644 --- a/src/art.h +++ b/src/art.h @@ -124,6 +124,11 @@ typedef enum DudeNativeLook { DUDE_NATIVE_LOOK_COUNT, } DudeNativeLook; +extern char gDefaultJumpsuitMaleFileName[]; +extern char gDefaultJumpsuitFemaleFileName[]; +extern char gDefaultTribalMaleFileName[]; +extern char gDefaultTribalFemaleFileName[]; + extern ArtListDescription gArtListDescriptions[OBJ_TYPE_COUNT]; extern bool gArtLanguageInitialized; extern const char* _head1; diff --git a/src/automap.cc b/src/automap.cc index 6542970..1808aac 100644 --- a/src/automap.cc +++ b/src/automap.cc @@ -458,7 +458,7 @@ void automapRenderInMapWindow(int window, int elevation, unsigned char* backgrou && (object->data.critter.combat.results & DAM_DEAD) == 0) { objectColor = _colorTable[31744]; } else { - if ((object->flags & OBJECT_FLAG_0x40000000) == 0) { + if ((object->flags & OBJECT_SEEN) == 0) { continue; } @@ -1011,7 +1011,7 @@ void _decode_map_data(int elevation) Object* object = objectFindFirstAtElevation(elevation); 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 objectType = (object->fid & 0xF000000) >> 24; diff --git a/src/cache.cc b/src/cache.cc index e2c77f3..6f2d346 100644 --- a/src/cache.cc +++ b/src/cache.cc @@ -5,7 +5,7 @@ #include "sound.h" #include -#include // qsort +#include #include #include diff --git a/src/character_editor.cc b/src/character_editor.cc index 021f5f7..198bdf1 100644 --- a/src/character_editor.cc +++ b/src/character_editor.cc @@ -23,6 +23,7 @@ #include "platform_compat.h" #include "proto.h" #include "scripts.h" +#include "sfall_config.h" #include "skill.h" #include "stat.h" #include "text_font.h" @@ -36,6 +37,8 @@ #include #include +#include + #define RENDER_ALL_STATS 7 #define EDITOR_WINDOW_WIDTH 640 @@ -88,7 +91,7 @@ #define BIG_NUM_ANIMATION_DELAY 123 // 0x431C40 -int _grph_id[EDITOR_GRAPHIC_COUNT] = { +int gCharacterEditorFrmIds[EDITOR_GRAPHIC_COUNT] = { 170, 175, 176, @@ -144,7 +147,7 @@ int _grph_id[EDITOR_GRAPHIC_COUNT] = { // flags to preload fid // // 0x431D08 -const unsigned char _copyflag[EDITOR_GRAPHIC_COUNT] = { +const unsigned char gCharacterEditorFrmShouldCopy[EDITOR_GRAPHIC_COUNT] = { 0, 0, 1, @@ -201,7 +204,7 @@ const unsigned char _copyflag[EDITOR_GRAPHIC_COUNT] = { // NOTE: the type originally short // // 0x431D3A -const int word_431D3A[EDITOR_DERIVED_STAT_COUNT] = { +const int gCharacterEditorDerivedStatFrmIds[EDITOR_DERIVED_STAT_COUNT] = { 18, 19, 20, @@ -217,7 +220,7 @@ const int word_431D3A[EDITOR_DERIVED_STAT_COUNT] = { // y offsets for stats +/- buttons // // 0x431D50 -const int _StatYpos[7] = { +const int gCharacterEditorPrimaryStatY[7] = { 37, 70, 103, @@ -231,7 +234,7 @@ const int _StatYpos[7] = { // NOTE: the type is originally short // // 0x431D6 -const int word_431D6C[EDITOR_DERIVED_STAT_COUNT] = { +const int gCharacterEditorDerivedStatsMap[EDITOR_DERIVED_STAT_COUNT] = { STAT_ARMOR_CLASS, STAT_MAXIMUM_ACTION_POINTS, STAT_CARRY_WEIGHT, @@ -274,16 +277,16 @@ const double dbl_5018F0 = 19.2; const double dbl_5019BE = 14.4; // 0x518528 -bool _bk_enable_0 = false; +bool gCharacterEditorIsoWasEnabled = false; // 0x51852C -int _skill_cursor = 0; +int gCharacterEditorCurrentSkill = 0; // 0x518534 -int _slider_y = 27; +int gCharacterEditorSkillValueAdjustmentSliderY = 27; // 0x518538 -int characterEditorRemainingCharacterPoints = 0; +int gCharacterEditorRemainingCharacterPoints = 0; // 0x51853C KarmaEntry* gKarmaEntries = NULL; @@ -345,170 +348,170 @@ const int gAddictionReputationFrmIds[ADDICTION_REPUTATION_COUNT] = { }; // 0x518624 -int _folder_up_button = -1; +int gCharacterEditorFolderViewScrollUpBtn = -1; // 0x518628 -int _folder_down_button = -1; +int gCharacterEditorFolderViewScrollDownBtn = -1; // 0x56FB60 -char _folder_card_string[256]; +char gCharacterEditorFolderCardString[256]; // 0x56FC60 -int _skillsav[SKILL_COUNT]; +int gCharacterEditorSkillsBackup[SKILL_COUNT]; // 0x56FCA8 -MessageList editorMessageList; +MessageList gCharacterEditorMessageList; // 0x56FCB0 -STRUCT_56FCB0 _name_sort_list[DIALOG_PICKER_NUM_OPTIONS]; +PerkDialogOption gPerkDialogOptionList[DIALOG_PICKER_NUM_OPTIONS]; // buttons for selecting traits // // 0x5700A8 -int _trait_bids[TRAIT_COUNT]; +int gCharacterEditorOptionalTraitBtns[TRAIT_COUNT]; // 0x5700E8 -MessageListItem editorMessageListItem; +MessageListItem gCharacterEditorMessageListItem; // 0x5700F8 -char _old_str1[48]; +char gCharacterEditorCardTitle[48]; // 0x570128 -char _old_str2[48]; +char gPerkDialogCardTitle[48]; // buttons for tagging skills // // 0x570158 -int _tag_bids[SKILL_COUNT]; +int gCharacterEditorTagSkillBtns[SKILL_COUNT]; // pc name // // 0x5701A0 -char _name_save[32]; +char gCharacterEditorNameBackup[32]; // 0x5701C0 -Size _GInfo[EDITOR_GRAPHIC_COUNT]; +Size gCharacterEditorFrmSize[EDITOR_GRAPHIC_COUNT]; // 0x570350 -CacheEntry* _grph_key[EDITOR_GRAPHIC_COUNT]; +CacheEntry* gCharacterEditorFrmHandle[EDITOR_GRAPHIC_COUNT]; // 0x570418 -unsigned char* _grphcpy[EDITOR_GRAPHIC_COUNT]; +unsigned char* gCharacterEditorFrmCopy[EDITOR_GRAPHIC_COUNT]; // 0x5704E0 -unsigned char* _grphbmp[EDITOR_GRAPHIC_COUNT]; +unsigned char* gCharacterEditorFrmData[EDITOR_GRAPHIC_COUNT]; // 0x5705A8 -int _folder_max_lines; +int gCharacterEditorFolderViewMaxLines; // 0x5705AC -int _folder_line; +int gCharacterEditorFolderViewCurrentLine; // 0x5705B0 -int _folder_card_fid; +int gCharacterEditorFolderCardFrmId; // 0x5705B4 -int _folder_top_line; +int gCharacterEditorFolderViewTopLine; // 0x5705B8 -char* _folder_card_title; +char* gCharacterEditorFolderCardTitle; // 0x5705BC -char* _folder_card_title2; +char* gCharacterEditorFolderCardSubtitle; // 0x5705C0 -int _folder_yoffset; +int gCharacterEditorFolderViewOffsetY; // 0x5705C4 -int _folder_karma_top_line; +int gCharacterEditorKarmaFolderTopLine; // 0x5705C8 -int _folder_highlight_line; +int gCharacterEditorFolderViewHighlightedLine; // 0x5705CC -char* _folder_card_desc; +char* gCharacterEditorFolderCardDescription; // 0x5705D0 -int _folder_ypos; +int gCharacterEditorFolderViewNextY; // 0x5705D4 -int _folder_kills_top_line; +int gCharacterEditorKillsFolderTopLine; // 0x5705D8 -int _folder_perk_top_line; +int gCharacterEditorPerkFolderTopLine; // 0x5705DC -unsigned char* gEditorPerkBackgroundBuffer; +unsigned char* gPerkDialogBackgroundBuffer; // 0x5705E0 -int gEditorPerkWindow; +int gPerkDialogWindow; // 0x5705E4 -int _SliderPlusID; +int gCharacterEditorSliderPlusBtn; // 0x5705E8 -int _SliderNegID; +int gCharacterEditorSliderMinusBtn; // - stats buttons // // 0x5705EC -int _stat_bids_minus[7]; +int gCharacterEditorPrimaryStatMinusBtns[7]; // 0x570608 -unsigned char* characterEditorWindowBuf; +unsigned char* gCharacterEditorWindowBuffer; // 0x57060C -int characterEditorWindowHandle; +int gCharacterEditorWindow; // + stats buttons // // 0x570610 -int _stat_bids_plus[7]; +int gCharacterEditorPrimaryStatPlusBtns[7]; // 0x57062C -unsigned char* gEditorPerkWindowBuffer; +unsigned char* gPerkDialogWindowBuffer; // 0x570630 -CritterProtoData _dude_data; +CritterProtoData gCharacterEditorDudeDataBackup; // 0x5707A4 -unsigned char* characterEditorWindowBackgroundBuf; +unsigned char* gCharacterEditorWindowBackgroundBuffer; // 0x5707A8 -int _cline; +int gPerkDialogCurrentLine; // 0x5707AC -int _oldsline; +int gPerkDialogPreviousCurrentLine; // unspent skill points // // 0x5707B0 -int _upsent_points_back; +int gCharacterEditorUnspentSkillPointsBackup; // 0x5707B4 -int _last_level; +int gCharacterEditorLastLevel; // 0x5707B8 -int characterEditorWindowOldFont; +int gCharacterEditorOldFont; // 0x5707BC -int _kills_count; +int gCharacterEditorKillsCount; // character editor background // // 0x5707C0 -CacheEntry* _bck_key; +CacheEntry* gCharacterEditorWindowBackgroundHandle; // current hit points // // 0x5707C4 -int _hp_back; +int gCharacterEditorHitPointsBackup; // 0x5707C8 -int _mouse_ypos; // mouse y +int gCharacterEditorMouseY; // mouse y // 0x5707CC -int _mouse_xpos; // mouse x +int gCharacterEditorMouseX; // mouse x // 0x5707D0 int characterEditorSelectedItem; @@ -517,16 +520,16 @@ int characterEditorSelectedItem; int characterEditorWindowSelectedFolder; // 0x5707D8 -int _frstc_draw1; +bool gCharacterEditorCardDrawn; // 0x5707DC -int _crow; +int gPerkDialogTopLine; // 0x5707E0 -int _frstc_draw2; +bool gPerkDialogCardDrawn; // 0x5707E4 -int _perk_back[PERK_COUNT]; +int gCharacterEditorPerksBackup[PERK_COUNT]; // 0x5709C0 unsigned int _repFtime; @@ -535,54 +538,61 @@ unsigned int _repFtime; unsigned int _frame_time; // 0x5709C8 -int _old_tags; +int gCharacterEditorOldTaggedSkillCount; // 0x5709CC -int _last_level_back; +int gCharacterEditorLastLevelBackup; // 0x5709E8 -int _card_old_fid2; +int gPerkDialogCardFrmId; // 0x5709EC -int _card_old_fid1; +int gCharacterEditorCardFrmId; // 0x5709D0 bool gCharacterEditorIsCreationMode; // 0x5709D4 -int _tag_skill_back[NUM_TAGGED_SKILLS]; +int gCharacterEditorTaggedSkillsBackup[NUM_TAGGED_SKILLS]; // 0x5709F0 -int _trait_back[3]; +int gCharacterEditorOptionalTraitsBackup[3]; // current index for selecting new trait // // 0x5709FC -int _trait_count; +int gCharacterEditorTempTraitCount; // 0x570A00 -int _optrt_count; +int gPerkDialogOptionCount; // 0x570A04 -int _temp_trait[3]; +int gCharacterEditorTempTraits[3]; // 0x570A10 -int _tagskill_count; +int gCharacterEditorTaggedSkillCount; // 0x570A14 -int _temp_tag_skill[NUM_TAGGED_SKILLS]; +int gCharacterEditorTempTaggedSkills[NUM_TAGGED_SKILLS]; // 0x570A28 -char _free_perk_back; +char gCharacterEditorHasFreePerkBackup; // 0x570A29 -unsigned char _free_perk; +unsigned char gCharacterEditorHasFreePerk; // 0x570A2A -unsigned char _first_skill_list; +unsigned char gCharacterEditorIsSkillsFirstDraw; + +struct CustomKarmaFolderDescription { + int frmId; + int threshold; +}; + +static std::vector gCustomKarmaFolderDescriptions; // 0x431DF8 -int _editor_design(bool isCreationMode) +int characterEditorShow(bool isCreationMode) { char* messageListItemText; char line1[128]; @@ -591,7 +601,7 @@ int _editor_design(bool isCreationMode) gCharacterEditorIsCreationMode = isCreationMode; - _SavePlayer(); + characterEditorSavePlayer(); if (characterEditorWindowInit() == -1) { debugPrint("\n ** Error loading character editor data! **\n"); @@ -599,13 +609,13 @@ int _editor_design(bool isCreationMode) } if (!gCharacterEditorIsCreationMode) { - if (_UpdateLevel()) { + if (characterEditorUpdateLevel()) { critterUpdateDerivedStats(gDude); - characterEditorWindowRenderTraits(); - editorRenderSkills(0); - editorRenderPrimaryStat(RENDER_ALL_STATS, 0, 0); - editorRenderSecondaryStats(); - editorRenderDetails(); + characterEditorDrawOptionalTraits(); + characterEditorDrawSkills(0); + characterEditorDrawPrimaryStat(RENDER_ALL_STATS, 0, 0); + characterEditorDrawDerivedStats(); + characterEditorDrawCard(); } } @@ -626,37 +636,37 @@ int _editor_design(bool isCreationMode) if (done) { if (gCharacterEditorIsCreationMode) { - if (characterEditorRemainingCharacterPoints != 0) { + if (gCharacterEditorRemainingCharacterPoints != 0) { soundPlayFile("iisxxxx1"); // You must use all character points - messageListItemText = getmsg(&editorMessageList, &editorMessageListItem, 118); + messageListItemText = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 118); strcpy(line1, messageListItemText); // before starting the game! - messageListItemText = getmsg(&editorMessageList, &editorMessageListItem, 119); + messageListItemText = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 119); strcpy(line2, messageListItemText); showDialogBox(line1, lines, 1, 192, 126, _colorTable[32328], 0, _colorTable[32328], 0); - windowRefresh(characterEditorWindowHandle); + windowRefresh(gCharacterEditorWindow); rc = -1; continue; } - if (_tagskill_count > 0) { + if (gCharacterEditorTaggedSkillCount > 0) { soundPlayFile("iisxxxx1"); // You must select all tag skills - messageListItemText = getmsg(&editorMessageList, &editorMessageListItem, 142); + messageListItemText = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 142); strcpy(line1, messageListItemText); // before starting the game! - messageListItemText = getmsg(&editorMessageList, &editorMessageListItem, 143); + messageListItemText = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 143); strcpy(line2, messageListItemText); showDialogBox(line1, lines, 1, 192, 126, _colorTable[32328], 0, _colorTable[32328], 0); - windowRefresh(characterEditorWindowHandle); + windowRefresh(gCharacterEditorWindow); rc = -1; continue; @@ -666,15 +676,15 @@ int _editor_design(bool isCreationMode) soundPlayFile("iisxxxx1"); // All stats must be between 1 and 10 - messageListItemText = getmsg(&editorMessageList, &editorMessageListItem, 157); + messageListItemText = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 157); strcpy(line1, messageListItemText); // before starting the game! - messageListItemText = getmsg(&editorMessageList, &editorMessageListItem, 158); + messageListItemText = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 158); strcpy(line2, messageListItemText); showDialogBox(line1, lines, 1, 192, 126, _colorTable[32328], 0, _colorTable[32328], 0); - windowRefresh(characterEditorWindowHandle); + windowRefresh(gCharacterEditorWindow); rc = -1; continue; @@ -684,15 +694,15 @@ int _editor_design(bool isCreationMode) soundPlayFile("iisxxxx1"); // Warning: You haven't changed your player - messageListItemText = getmsg(&editorMessageList, &editorMessageListItem, 160); + messageListItemText = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 160); strcpy(line1, messageListItemText); // name. Use this character any way? - messageListItemText = getmsg(&editorMessageList, &editorMessageListItem, 161); + messageListItemText = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 161); strcpy(line2, messageListItemText); if (showDialogBox(line1, lines, 1, 192, 126, _colorTable[32328], 0, _colorTable[32328], DIALOG_BOX_YES_NO) == 0) { - windowRefresh(characterEditorWindowHandle); + windowRefresh(gCharacterEditorWindow); rc = -1; continue; @@ -700,33 +710,33 @@ int _editor_design(bool isCreationMode) } } - windowRefresh(characterEditorWindowHandle); + windowRefresh(gCharacterEditorWindow); rc = 0; } else if (keyCode == KEY_CTRL_Q || keyCode == KEY_CTRL_X || keyCode == KEY_F10) { showQuitConfirmationDialog(); - windowRefresh(characterEditorWindowHandle); + windowRefresh(gCharacterEditorWindow); } else if (keyCode == 502 || keyCode == KEY_ESCAPE || keyCode == KEY_UPPERCASE_C || keyCode == KEY_LOWERCASE_C || _game_user_wants_to_quit != 0) { - windowRefresh(characterEditorWindowHandle); + windowRefresh(gCharacterEditorWindow); rc = 1; } else if (gCharacterEditorIsCreationMode && (keyCode == 517 || keyCode == KEY_UPPERCASE_N || keyCode == KEY_LOWERCASE_N)) { characterEditorEditName(); - windowRefresh(characterEditorWindowHandle); + windowRefresh(gCharacterEditorWindow); } else if (gCharacterEditorIsCreationMode && (keyCode == 519 || keyCode == KEY_UPPERCASE_A || keyCode == KEY_LOWERCASE_A)) { - characterEditorRunEditAgeDialog(); - windowRefresh(characterEditorWindowHandle); + characterEditorEditAge(); + windowRefresh(gCharacterEditorWindow); } else if (gCharacterEditorIsCreationMode && (keyCode == 520 || keyCode == KEY_UPPERCASE_S || keyCode == KEY_LOWERCASE_S)) { characterEditorEditGender(); - windowRefresh(characterEditorWindowHandle); + windowRefresh(gCharacterEditorWindow); } else if (gCharacterEditorIsCreationMode && (keyCode >= 503 && keyCode < 517)) { - characterEditorHandleIncDecPrimaryStat(keyCode); - windowRefresh(characterEditorWindowHandle); + characterEditorAdjustPrimaryStat(keyCode); + windowRefresh(gCharacterEditorWindow); } else if ((gCharacterEditorIsCreationMode && (keyCode == 501 || keyCode == KEY_UPPERCASE_O || keyCode == KEY_LOWERCASE_O)) || (!gCharacterEditorIsCreationMode && (keyCode == 501 || keyCode == KEY_UPPERCASE_P || keyCode == KEY_LOWERCASE_P))) { - // _OptionWindow(); - windowRefresh(characterEditorWindowHandle); + characterEditorShowOptions(); + windowRefresh(gCharacterEditorWindow); } else if (keyCode >= 525 && keyCode < 535) { - _InfoButton(keyCode); - windowRefresh(characterEditorWindowHandle); + characterEditorHandleInfoButtonPressed(keyCode); + windowRefresh(gCharacterEditorWindow); } else { switch (keyCode) { case KEY_TAB: @@ -762,35 +772,35 @@ int _editor_design(bool isCreationMode) } else if (characterEditorSelectedItem >= 82 && characterEditorSelectedItem < 98) { characterEditorSelectedItem = 43; } - editorRenderPrimaryStat(RENDER_ALL_STATS, 0, 0); - characterEditorWindowRenderTraits(); - editorRenderSkills(0); - editorRenderPcStats(); - editorRenderFolders(); - editorRenderSecondaryStats(); - editorRenderDetails(); - windowRefresh(characterEditorWindowHandle); + characterEditorDrawPrimaryStat(RENDER_ALL_STATS, 0, 0); + characterEditorDrawOptionalTraits(); + characterEditorDrawSkills(0); + characterEditorDrawPcStats(); + characterEditorDrawFolders(); + characterEditorDrawDerivedStats(); + characterEditorDrawCard(); + windowRefresh(gCharacterEditorWindow); break; case KEY_ARROW_LEFT: case KEY_MINUS: case KEY_UPPERCASE_J: if (characterEditorSelectedItem >= 0 && characterEditorSelectedItem < 7) { if (gCharacterEditorIsCreationMode) { - _win_button_press_and_release(_stat_bids_minus[characterEditorSelectedItem]); - windowRefresh(characterEditorWindowHandle); + _win_button_press_and_release(gCharacterEditorPrimaryStatMinusBtns[characterEditorSelectedItem]); + windowRefresh(gCharacterEditorWindow); } } else if (characterEditorSelectedItem >= 61 && characterEditorSelectedItem < 79) { if (gCharacterEditorIsCreationMode) { - _win_button_press_and_release(_tag_bids[gCharacterEditorIsCreationMode - 61]); - windowRefresh(characterEditorWindowHandle); + _win_button_press_and_release(gCharacterEditorTagSkillBtns[gCharacterEditorIsCreationMode - 61]); + windowRefresh(gCharacterEditorWindow); } else { - editorAdjustSkill(keyCode); - windowRefresh(characterEditorWindowHandle); + characterEditorHandleAdjustSkillButtonPressed(keyCode); + windowRefresh(gCharacterEditorWindow); } } else if (characterEditorSelectedItem >= 82 && characterEditorSelectedItem < 98) { if (gCharacterEditorIsCreationMode) { - _win_button_press_and_release(_trait_bids[gCharacterEditorIsCreationMode - 82]); - windowRefresh(characterEditorWindowHandle); + _win_button_press_and_release(gCharacterEditorOptionalTraitBtns[gCharacterEditorIsCreationMode - 82]); + windowRefresh(gCharacterEditorWindow); } } break; @@ -799,40 +809,40 @@ int _editor_design(bool isCreationMode) case KEY_UPPERCASE_N: if (characterEditorSelectedItem >= 0 && characterEditorSelectedItem < 7) { if (gCharacterEditorIsCreationMode) { - _win_button_press_and_release(_stat_bids_plus[characterEditorSelectedItem]); - windowRefresh(characterEditorWindowHandle); + _win_button_press_and_release(gCharacterEditorPrimaryStatPlusBtns[characterEditorSelectedItem]); + windowRefresh(gCharacterEditorWindow); } } else if (characterEditorSelectedItem >= 61 && characterEditorSelectedItem < 79) { if (gCharacterEditorIsCreationMode) { - _win_button_press_and_release(_tag_bids[gCharacterEditorIsCreationMode - 61]); - windowRefresh(characterEditorWindowHandle); + _win_button_press_and_release(gCharacterEditorTagSkillBtns[gCharacterEditorIsCreationMode - 61]); + windowRefresh(gCharacterEditorWindow); } else { - editorAdjustSkill(keyCode); - windowRefresh(characterEditorWindowHandle); + characterEditorHandleAdjustSkillButtonPressed(keyCode); + windowRefresh(gCharacterEditorWindow); } } else if (characterEditorSelectedItem >= 82 && characterEditorSelectedItem < 98) { if (gCharacterEditorIsCreationMode) { - _win_button_press_and_release(_trait_bids[gCharacterEditorIsCreationMode - 82]); - windowRefresh(characterEditorWindowHandle); + _win_button_press_and_release(gCharacterEditorOptionalTraitBtns[gCharacterEditorIsCreationMode - 82]); + windowRefresh(gCharacterEditorWindow); } } break; case KEY_ARROW_UP: if (characterEditorSelectedItem >= 10 && characterEditorSelectedItem < 43) { if (characterEditorSelectedItem == 10) { - if (_folder_top_line > 0) { - _folder_scroll(-1); + if (gCharacterEditorFolderViewTopLine > 0) { + characterEditorFolderViewScroll(-1); characterEditorSelectedItem--; - editorRenderFolders(); - editorRenderDetails(); + characterEditorDrawFolders(); + characterEditorDrawCard(); } } else { characterEditorSelectedItem--; - editorRenderFolders(); - editorRenderDetails(); + characterEditorDrawFolders(); + characterEditorDrawCard(); } - windowRefresh(characterEditorWindowHandle); + windowRefresh(gCharacterEditorWindow); } else { switch (characterEditorSelectedItem) { case 0: @@ -859,33 +869,33 @@ int _editor_design(bool isCreationMode) } if (characterEditorSelectedItem >= 61 && characterEditorSelectedItem < 79) { - _skill_cursor = characterEditorSelectedItem - 61; + gCharacterEditorCurrentSkill = characterEditorSelectedItem - 61; } - editorRenderPrimaryStat(RENDER_ALL_STATS, 0, 0); - characterEditorWindowRenderTraits(); - editorRenderSkills(0); - editorRenderPcStats(); - editorRenderFolders(); - editorRenderSecondaryStats(); - editorRenderDetails(); - windowRefresh(characterEditorWindowHandle); + characterEditorDrawPrimaryStat(RENDER_ALL_STATS, 0, 0); + characterEditorDrawOptionalTraits(); + characterEditorDrawSkills(0); + characterEditorDrawPcStats(); + characterEditorDrawFolders(); + characterEditorDrawDerivedStats(); + characterEditorDrawCard(); + windowRefresh(gCharacterEditorWindow); } break; case KEY_ARROW_DOWN: if (characterEditorSelectedItem >= 10 && characterEditorSelectedItem < 43) { - if (characterEditorSelectedItem - 10 < _folder_line - _folder_top_line) { - if (characterEditorSelectedItem - 10 == _folder_max_lines - 1) { - _folder_scroll(1); + if (characterEditorSelectedItem - 10 < gCharacterEditorFolderViewCurrentLine - gCharacterEditorFolderViewTopLine) { + if (characterEditorSelectedItem - 10 == gCharacterEditorFolderViewMaxLines - 1) { + characterEditorFolderViewScroll(1); } characterEditorSelectedItem++; - editorRenderFolders(); - editorRenderDetails(); + characterEditorDrawFolders(); + characterEditorDrawCard(); } - windowRefresh(characterEditorWindowHandle); + windowRefresh(gCharacterEditorWindow); } else { switch (characterEditorSelectedItem) { case 6: @@ -912,49 +922,49 @@ int _editor_design(bool isCreationMode) } if (characterEditorSelectedItem >= 61 && characterEditorSelectedItem < 79) { - _skill_cursor = characterEditorSelectedItem - 61; + gCharacterEditorCurrentSkill = characterEditorSelectedItem - 61; } - editorRenderPrimaryStat(RENDER_ALL_STATS, 0, 0); - characterEditorWindowRenderTraits(); - editorRenderSkills(0); - editorRenderPcStats(); - editorRenderFolders(); - editorRenderSecondaryStats(); - editorRenderDetails(); - windowRefresh(characterEditorWindowHandle); + characterEditorDrawPrimaryStat(RENDER_ALL_STATS, 0, 0); + characterEditorDrawOptionalTraits(); + characterEditorDrawSkills(0); + characterEditorDrawPcStats(); + characterEditorDrawFolders(); + characterEditorDrawDerivedStats(); + characterEditorDrawCard(); + windowRefresh(gCharacterEditorWindow); } break; case 521: case 523: - editorAdjustSkill(keyCode); - windowRefresh(characterEditorWindowHandle); + characterEditorHandleAdjustSkillButtonPressed(keyCode); + windowRefresh(gCharacterEditorWindow); break; case 535: - _FldrButton(); - windowRefresh(characterEditorWindowHandle); + characterEditorHandleFolderButtonPressed(); + windowRefresh(gCharacterEditorWindow); break; case 17000: - _folder_scroll(-1); - windowRefresh(characterEditorWindowHandle); + characterEditorFolderViewScroll(-1); + windowRefresh(gCharacterEditorWindow); break; case 17001: - _folder_scroll(1); - windowRefresh(characterEditorWindowHandle); + characterEditorFolderViewScroll(1); + windowRefresh(gCharacterEditorWindow); break; default: if (gCharacterEditorIsCreationMode && (keyCode >= 536 && keyCode < 554)) { characterEditorToggleTaggedSkill(keyCode - 536); - windowRefresh(characterEditorWindowHandle); + windowRefresh(gCharacterEditorWindow); } else if (gCharacterEditorIsCreationMode && (keyCode >= 555 && keyCode < 571)) { characterEditorToggleOptionalTrait(keyCode - 555); - windowRefresh(characterEditorWindowHandle); + windowRefresh(gCharacterEditorWindow); } else { if (keyCode == 390) { takeScreenshot(); } - windowRefresh(characterEditorWindowHandle); + windowRefresh(gCharacterEditorWindow); } } } @@ -970,7 +980,7 @@ int _editor_design(bool isCreationMode) characterEditorWindowFree(); if (rc == 1) { - _RestorePlayer(); + characterEditorRestorePlayer(); } if (dudeHasState(0x03)) { @@ -999,27 +1009,27 @@ int characterEditorWindowInit() char karma[32]; char kills[32]; - characterEditorWindowOldFont = fontGetCurrent(); - _old_tags = 0; - _bk_enable_0 = 0; - _card_old_fid2 = -1; - _card_old_fid1 = -1; - _frstc_draw2 = 0; - _frstc_draw1 = 0; - _first_skill_list = 1; - _old_str2[0] = '\0'; - _old_str1[0] = '\0'; + gCharacterEditorOldFont = fontGetCurrent(); + gCharacterEditorOldTaggedSkillCount = 0; + gCharacterEditorIsoWasEnabled = 0; + gPerkDialogCardFrmId = -1; + gCharacterEditorCardFrmId = -1; + gPerkDialogCardDrawn = false; + gCharacterEditorCardDrawn = false; + gCharacterEditorIsSkillsFirstDraw = 1; + gPerkDialogCardTitle[0] = '\0'; + gCharacterEditorCardTitle[0] = '\0'; fontSetCurrent(101); - _slider_y = _skill_cursor * (fontGetLineHeight() + 1) + 27; + gCharacterEditorSkillValueAdjustmentSliderY = gCharacterEditorCurrentSkill * (fontGetLineHeight() + 1) + 27; // skills - skillsGetTagged(_temp_tag_skill, NUM_TAGGED_SKILLS); + skillsGetTagged(gCharacterEditorTempTaggedSkills, NUM_TAGGED_SKILLS); v1 = 0; for (i = 3; i >= 0; i--) { - if (_temp_tag_skill[i] != -1) { + if (gCharacterEditorTempTaggedSkills[i] != -1) { break; } @@ -1030,43 +1040,43 @@ int characterEditorWindowInit() v1--; } - _tagskill_count = v1; + gCharacterEditorTaggedSkillCount = v1; // traits - traitsGetSelected(&(_temp_trait[0]), &(_temp_trait[1])); + traitsGetSelected(&(gCharacterEditorTempTraits[0]), &(gCharacterEditorTempTraits[1])); v3 = 0; for (i = 1; i >= 0; i--) { - if (_temp_trait[i] != -1) { + if (gCharacterEditorTempTraits[i] != -1) { break; } v3++; } - _trait_count = v3; + gCharacterEditorTempTraitCount = v3; if (!gCharacterEditorIsCreationMode) { - _bk_enable_0 = isoDisable(); + gCharacterEditorIsoWasEnabled = isoDisable(); } colorCycleDisable(); gameMouseSetCursor(MOUSE_CURSOR_ARROW); - if (!messageListInit(&editorMessageList)) { + if (!messageListInit(&gCharacterEditorMessageList)) { return -1; } sprintf(path, "%s%s", asc_5186C8, "editor.msg"); - if (!messageListLoad(&editorMessageList, path)) { + if (!messageListLoad(&gCharacterEditorMessageList, path)) { return -1; } fid = buildFid(6, (gCharacterEditorIsCreationMode ? 169 : 177), 0, 0, 0); - characterEditorWindowBackgroundBuf = artLockFrameDataReturningSize(fid, &_bck_key, &(_GInfo[0].width), &(_GInfo[0].height)); - if (characterEditorWindowBackgroundBuf == NULL) { - messageListFree(&editorMessageList); + gCharacterEditorWindowBackgroundBuffer = artLockFrameDataReturningSize(fid, &gCharacterEditorWindowBackgroundHandle, &(gCharacterEditorFrmSize[0].width), &(gCharacterEditorFrmSize[0].height)); + if (gCharacterEditorWindowBackgroundBuffer == NULL) { + messageListFree(&gCharacterEditorMessageList); return -1; } @@ -1078,27 +1088,30 @@ int characterEditorWindowInit() return -1; } + // SFALL: Custom karma folder. + customKarmaFolderInit(); + soundContinueAll(); for (i = 0; i < EDITOR_GRAPHIC_COUNT; i++) { - fid = buildFid(6, _grph_id[i], 0, 0, 0); - _grphbmp[i] = artLockFrameDataReturningSize(fid, &(_grph_key[i]), &(_GInfo[i].width), &(_GInfo[i].height)); - if (_grphbmp[i] == NULL) { + fid = buildFid(6, gCharacterEditorFrmIds[i], 0, 0, 0); + gCharacterEditorFrmData[i] = artLockFrameDataReturningSize(fid, &(gCharacterEditorFrmHandle[i]), &(gCharacterEditorFrmSize[i].width), &(gCharacterEditorFrmSize[i].height)); + if (gCharacterEditorFrmData[i] == NULL) { break; } } if (i != EDITOR_GRAPHIC_COUNT) { while (--i >= 0) { - artUnlock(_grph_key[i]); + artUnlock(gCharacterEditorFrmHandle[i]); } return -1; - artUnlock(_bck_key); + artUnlock(gCharacterEditorWindowBackgroundHandle); - messageListFree(&editorMessageList); + messageListFree(&gCharacterEditorMessageList); - if (_bk_enable_0) { + if (gCharacterEditorIsoWasEnabled) { isoEnable(); } @@ -1110,32 +1123,32 @@ int characterEditorWindowInit() soundContinueAll(); for (i = 0; i < EDITOR_GRAPHIC_COUNT; i++) { - if (_copyflag[i]) { - _grphcpy[i] = (unsigned char*)internal_malloc(_GInfo[i].width * _GInfo[i].height); - if (_grphcpy[i] == NULL) { + if (gCharacterEditorFrmShouldCopy[i]) { + gCharacterEditorFrmCopy[i] = (unsigned char*)internal_malloc(gCharacterEditorFrmSize[i].width * gCharacterEditorFrmSize[i].height); + if (gCharacterEditorFrmCopy[i] == NULL) { break; } - memcpy(_grphcpy[i], _grphbmp[i], _GInfo[i].width * _GInfo[i].height); + memcpy(gCharacterEditorFrmCopy[i], gCharacterEditorFrmData[i], gCharacterEditorFrmSize[i].width * gCharacterEditorFrmSize[i].height); } else { - _grphcpy[i] = (unsigned char*)-1; + gCharacterEditorFrmCopy[i] = (unsigned char*)-1; } } if (i != EDITOR_GRAPHIC_COUNT) { while (--i >= 0) { - if (_copyflag[i]) { - internal_free(_grphcpy[i]); + if (gCharacterEditorFrmShouldCopy[i]) { + internal_free(gCharacterEditorFrmCopy[i]); } } for (i = 0; i < EDITOR_GRAPHIC_COUNT; i++) { - artUnlock(_grph_key[i]); + artUnlock(gCharacterEditorFrmHandle[i]); } - artUnlock(_bck_key); + artUnlock(gCharacterEditorWindowBackgroundHandle); - messageListFree(&editorMessageList); - if (_bk_enable_0) { + messageListFree(&gCharacterEditorMessageList); + if (gCharacterEditorIsoWasEnabled) { isoEnable(); } @@ -1147,24 +1160,24 @@ int characterEditorWindowInit() int editorWindowX = (screenGetWidth() - EDITOR_WINDOW_WIDTH) / 2; int editorWindowY = (screenGetHeight() - EDITOR_WINDOW_HEIGHT) / 2; - characterEditorWindowHandle = windowCreate(editorWindowX, + gCharacterEditorWindow = windowCreate(editorWindowX, editorWindowY, EDITOR_WINDOW_WIDTH, EDITOR_WINDOW_HEIGHT, 256, WINDOW_FLAG_0x10 | WINDOW_FLAG_0x02); - if (characterEditorWindowHandle == -1) { + if (gCharacterEditorWindow == -1) { for (i = 0; i < EDITOR_GRAPHIC_COUNT; i++) { - if (_copyflag[i]) { - internal_free(_grphcpy[i]); + if (gCharacterEditorFrmShouldCopy[i]) { + internal_free(gCharacterEditorFrmCopy[i]); } - artUnlock(_grph_key[i]); + artUnlock(gCharacterEditorFrmHandle[i]); } - artUnlock(_bck_key); + artUnlock(gCharacterEditorWindowBackgroundHandle); - messageListFree(&editorMessageList); - if (_bk_enable_0) { + messageListFree(&gCharacterEditorMessageList); + if (gCharacterEditorIsoWasEnabled) { isoEnable(); } @@ -1174,323 +1187,323 @@ int characterEditorWindowInit() return -1; } - characterEditorWindowBuf = windowGetBuffer(characterEditorWindowHandle); - memcpy(characterEditorWindowBuf, characterEditorWindowBackgroundBuf, 640 * 480); + gCharacterEditorWindowBuffer = windowGetBuffer(gCharacterEditorWindow); + memcpy(gCharacterEditorWindowBuffer, gCharacterEditorWindowBackgroundBuffer, 640 * 480); if (gCharacterEditorIsCreationMode) { fontSetCurrent(103); // CHAR POINTS - str = getmsg(&editorMessageList, &editorMessageListItem, 116); - fontDrawText(characterEditorWindowBuf + (286 * 640) + 14, str, 640, 640, _colorTable[18979]); - characterEditorRenderBigNumber(126, 282, 0, characterEditorRemainingCharacterPoints, 0, characterEditorWindowHandle); + str = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 116); + fontDrawText(gCharacterEditorWindowBuffer + (286 * 640) + 14, str, 640, 640, _colorTable[18979]); + characterEditorDrawBigNumber(126, 282, 0, gCharacterEditorRemainingCharacterPoints, 0, gCharacterEditorWindow); // OPTIONS - str = getmsg(&editorMessageList, &editorMessageListItem, 101); - fontDrawText(characterEditorWindowBuf + (454 * 640) + 363, str, 640, 640, _colorTable[18979]); + str = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 101); + fontDrawText(gCharacterEditorWindowBuffer + (454 * 640) + 363, str, 640, 640, _colorTable[18979]); // OPTIONAL TRAITS - str = getmsg(&editorMessageList, &editorMessageListItem, 139); - fontDrawText(characterEditorWindowBuf + (326 * 640) + 52, str, 640, 640, _colorTable[18979]); - characterEditorRenderBigNumber(522, 228, 0, _optrt_count, 0, characterEditorWindowHandle); + str = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 139); + fontDrawText(gCharacterEditorWindowBuffer + (326 * 640) + 52, str, 640, 640, _colorTable[18979]); + characterEditorDrawBigNumber(522, 228, 0, gPerkDialogOptionCount, 0, gCharacterEditorWindow); // TAG SKILLS - str = getmsg(&editorMessageList, &editorMessageListItem, 138); - fontDrawText(characterEditorWindowBuf + (233 * 640) + 422, str, 640, 640, _colorTable[18979]); - characterEditorRenderBigNumber(522, 228, 0, _tagskill_count, 0, characterEditorWindowHandle); + str = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 138); + fontDrawText(gCharacterEditorWindowBuffer + (233 * 640) + 422, str, 640, 640, _colorTable[18979]); + characterEditorDrawBigNumber(522, 228, 0, gCharacterEditorTaggedSkillCount, 0, gCharacterEditorWindow); } else { fontSetCurrent(103); - str = getmsg(&editorMessageList, &editorMessageListItem, 109); + str = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 109); strcpy(perks, str); - str = getmsg(&editorMessageList, &editorMessageListItem, 110); + str = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 110); strcpy(karma, str); - str = getmsg(&editorMessageList, &editorMessageListItem, 111); + str = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 111); strcpy(kills, str); // perks selected len = fontGetStringWidth(perks); fontDrawText( - _grphcpy[46] + 5 * _GInfo[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width + 61 - len / 2, + gCharacterEditorFrmCopy[46] + 5 * gCharacterEditorFrmSize[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width + 61 - len / 2, perks, - _GInfo[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, - _GInfo[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, _colorTable[18979]); len = fontGetStringWidth(karma); - fontDrawText(_grphcpy[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED] + 5 * _GInfo[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width + 159 - len / 2, + fontDrawText(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED] + 5 * gCharacterEditorFrmSize[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width + 159 - len / 2, karma, - _GInfo[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, - _GInfo[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, _colorTable[14723]); len = fontGetStringWidth(kills); - fontDrawText(_grphcpy[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED] + 5 * _GInfo[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width + 257 - len / 2, + fontDrawText(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED] + 5 * gCharacterEditorFrmSize[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width + 257 - len / 2, kills, - _GInfo[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, - _GInfo[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, _colorTable[14723]); // karma selected len = fontGetStringWidth(perks); - fontDrawText(_grphcpy[EDITOR_GRAPHIC_KARMA_FOLDER_SELECTED] + 5 * _GInfo[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width + 61 - len / 2, + fontDrawText(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_KARMA_FOLDER_SELECTED] + 5 * gCharacterEditorFrmSize[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width + 61 - len / 2, perks, - _GInfo[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, - _GInfo[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, _colorTable[14723]); len = fontGetStringWidth(karma); - fontDrawText(_grphcpy[EDITOR_GRAPHIC_KARMA_FOLDER_SELECTED] + 5 * _GInfo[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width + 159 - len / 2, + fontDrawText(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_KARMA_FOLDER_SELECTED] + 5 * gCharacterEditorFrmSize[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width + 159 - len / 2, karma, - _GInfo[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, - _GInfo[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, _colorTable[18979]); len = fontGetStringWidth(kills); - fontDrawText(_grphcpy[EDITOR_GRAPHIC_KARMA_FOLDER_SELECTED] + 5 * _GInfo[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width + 257 - len / 2, + fontDrawText(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_KARMA_FOLDER_SELECTED] + 5 * gCharacterEditorFrmSize[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width + 257 - len / 2, kills, - _GInfo[46].width, - _GInfo[46].width, + gCharacterEditorFrmSize[46].width, + gCharacterEditorFrmSize[46].width, _colorTable[14723]); // kills selected len = fontGetStringWidth(perks); - fontDrawText(_grphcpy[EDITOR_GRAPHIC_KILLS_FOLDER_SELECTED] + 5 * _GInfo[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width + 61 - len / 2, + fontDrawText(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_KILLS_FOLDER_SELECTED] + 5 * gCharacterEditorFrmSize[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width + 61 - len / 2, perks, - _GInfo[46].width, - _GInfo[46].width, + gCharacterEditorFrmSize[46].width, + gCharacterEditorFrmSize[46].width, _colorTable[14723]); len = fontGetStringWidth(karma); - fontDrawText(_grphcpy[EDITOR_GRAPHIC_KILLS_FOLDER_SELECTED] + 5 * _GInfo[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width + 159 - len / 2, + fontDrawText(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_KILLS_FOLDER_SELECTED] + 5 * gCharacterEditorFrmSize[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width + 159 - len / 2, karma, - _GInfo[46].width, - _GInfo[46].width, + gCharacterEditorFrmSize[46].width, + gCharacterEditorFrmSize[46].width, _colorTable[14723]); len = fontGetStringWidth(kills); - fontDrawText(_grphcpy[EDITOR_GRAPHIC_KILLS_FOLDER_SELECTED] + 5 * _GInfo[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width + 257 - len / 2, + fontDrawText(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_KILLS_FOLDER_SELECTED] + 5 * gCharacterEditorFrmSize[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width + 257 - len / 2, kills, - _GInfo[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, - _GInfo[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, _colorTable[18979]); - editorRenderFolders(); + characterEditorDrawFolders(); fontSetCurrent(103); // PRINT - str = getmsg(&editorMessageList, &editorMessageListItem, 103); - fontDrawText(characterEditorWindowBuf + (EDITOR_WINDOW_WIDTH * PRINT_BTN_Y) + PRINT_BTN_X, str, EDITOR_WINDOW_WIDTH, EDITOR_WINDOW_WIDTH, _colorTable[18979]); + str = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 103); + fontDrawText(gCharacterEditorWindowBuffer + (EDITOR_WINDOW_WIDTH * PRINT_BTN_Y) + PRINT_BTN_X, str, EDITOR_WINDOW_WIDTH, EDITOR_WINDOW_WIDTH, _colorTable[18979]); - editorRenderPcStats(); - _folder_init(); + characterEditorDrawPcStats(); + characterEditorFolderViewInit(); } fontSetCurrent(103); // CANCEL - str = getmsg(&editorMessageList, &editorMessageListItem, 102); - fontDrawText(characterEditorWindowBuf + (EDITOR_WINDOW_WIDTH * CANCEL_BTN_Y) + CANCEL_BTN_X, str, EDITOR_WINDOW_WIDTH, EDITOR_WINDOW_WIDTH, _colorTable[18979]); + str = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 102); + fontDrawText(gCharacterEditorWindowBuffer + (EDITOR_WINDOW_WIDTH * CANCEL_BTN_Y) + CANCEL_BTN_X, str, EDITOR_WINDOW_WIDTH, EDITOR_WINDOW_WIDTH, _colorTable[18979]); // DONE - str = getmsg(&editorMessageList, &editorMessageListItem, 100); - fontDrawText(characterEditorWindowBuf + (EDITOR_WINDOW_WIDTH * DONE_BTN_Y) + DONE_BTN_X, str, EDITOR_WINDOW_WIDTH, EDITOR_WINDOW_WIDTH, _colorTable[18979]); + str = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 100); + fontDrawText(gCharacterEditorWindowBuffer + (EDITOR_WINDOW_WIDTH * DONE_BTN_Y) + DONE_BTN_X, str, EDITOR_WINDOW_WIDTH, EDITOR_WINDOW_WIDTH, _colorTable[18979]); - editorRenderPrimaryStat(RENDER_ALL_STATS, 0, 0); - editorRenderSecondaryStats(); + characterEditorDrawPrimaryStat(RENDER_ALL_STATS, 0, 0); + characterEditorDrawDerivedStats(); if (!gCharacterEditorIsCreationMode) { - _SliderPlusID = buttonCreate( - characterEditorWindowHandle, + gCharacterEditorSliderPlusBtn = buttonCreate( + gCharacterEditorWindow, 614, 20, - _GInfo[EDITOR_GRAPHIC_SLIDER_PLUS_ON].width, - _GInfo[EDITOR_GRAPHIC_SLIDER_PLUS_ON].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_SLIDER_PLUS_ON].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_SLIDER_PLUS_ON].height, -1, 522, 521, 522, - _grphbmp[EDITOR_GRAPHIC_SLIDER_PLUS_OFF], - _grphbmp[EDITOR_GRAPHIC_SLIDER_PLUS_ON], + gCharacterEditorFrmData[EDITOR_GRAPHIC_SLIDER_PLUS_OFF], + gCharacterEditorFrmData[EDITOR_GRAPHIC_SLIDER_PLUS_ON], 0, 96); - _SliderNegID = buttonCreate( - characterEditorWindowHandle, + gCharacterEditorSliderMinusBtn = buttonCreate( + gCharacterEditorWindow, 614, - 20 + _GInfo[EDITOR_GRAPHIC_SLIDER_MINUS_ON].height - 1, - _GInfo[EDITOR_GRAPHIC_SLIDER_MINUS_ON].width, - _GInfo[EDITOR_GRAPHIC_SLIDER_MINUS_OFF].height, + 20 + gCharacterEditorFrmSize[EDITOR_GRAPHIC_SLIDER_MINUS_ON].height - 1, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_SLIDER_MINUS_ON].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_SLIDER_MINUS_OFF].height, -1, 524, 523, 524, - _grphbmp[EDITOR_GRAPHIC_SLIDER_MINUS_OFF], - _grphbmp[EDITOR_GRAPHIC_SLIDER_MINUS_ON], + gCharacterEditorFrmData[EDITOR_GRAPHIC_SLIDER_MINUS_OFF], + gCharacterEditorFrmData[EDITOR_GRAPHIC_SLIDER_MINUS_ON], 0, 96); - buttonSetCallbacks(_SliderPlusID, _gsound_red_butt_press, NULL); - buttonSetCallbacks(_SliderNegID, _gsound_red_butt_press, NULL); + buttonSetCallbacks(gCharacterEditorSliderPlusBtn, _gsound_red_butt_press, NULL); + buttonSetCallbacks(gCharacterEditorSliderMinusBtn, _gsound_red_butt_press, NULL); } - editorRenderSkills(0); - editorRenderDetails(); + characterEditorDrawSkills(0); + characterEditorDrawCard(); soundContinueAll(); - editorRenderName(); - editorRenderAge(); - editorRenderGender(); + characterEditorDrawName(); + characterEditorDrawAge(); + characterEditorDrawGender(); if (gCharacterEditorIsCreationMode) { x = NAME_BUTTON_X; btn = buttonCreate( - characterEditorWindowHandle, + gCharacterEditorWindow, x, NAME_BUTTON_Y, - _GInfo[EDITOR_GRAPHIC_NAME_ON].width, - _GInfo[EDITOR_GRAPHIC_NAME_ON].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_NAME_ON].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_NAME_ON].height, -1, -1, -1, NAME_BTN_CODE, - _grphcpy[EDITOR_GRAPHIC_NAME_OFF], - _grphcpy[EDITOR_GRAPHIC_NAME_ON], + gCharacterEditorFrmCopy[EDITOR_GRAPHIC_NAME_OFF], + gCharacterEditorFrmCopy[EDITOR_GRAPHIC_NAME_ON], 0, 32); if (btn != -1) { - buttonSetMask(btn, _grphbmp[EDITOR_GRAPHIC_NAME_MASK]); + buttonSetMask(btn, gCharacterEditorFrmData[EDITOR_GRAPHIC_NAME_MASK]); buttonSetCallbacks(btn, _gsound_lrg_butt_press, NULL); } - x += _GInfo[EDITOR_GRAPHIC_NAME_ON].width; + x += gCharacterEditorFrmSize[EDITOR_GRAPHIC_NAME_ON].width; btn = buttonCreate( - characterEditorWindowHandle, + gCharacterEditorWindow, x, NAME_BUTTON_Y, - _GInfo[EDITOR_GRAPHIC_AGE_ON].width, - _GInfo[EDITOR_GRAPHIC_AGE_ON].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_AGE_ON].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_AGE_ON].height, -1, -1, -1, AGE_BTN_CODE, - _grphcpy[EDITOR_GRAPHIC_AGE_OFF], - _grphcpy[EDITOR_GRAPHIC_AGE_ON], + gCharacterEditorFrmCopy[EDITOR_GRAPHIC_AGE_OFF], + gCharacterEditorFrmCopy[EDITOR_GRAPHIC_AGE_ON], 0, 32); if (btn != -1) { - buttonSetMask(btn, _grphbmp[EDITOR_GRAPHIC_AGE_MASK]); + buttonSetMask(btn, gCharacterEditorFrmData[EDITOR_GRAPHIC_AGE_MASK]); buttonSetCallbacks(btn, _gsound_lrg_butt_press, NULL); } - x += _GInfo[EDITOR_GRAPHIC_AGE_ON].width; + x += gCharacterEditorFrmSize[EDITOR_GRAPHIC_AGE_ON].width; btn = buttonCreate( - characterEditorWindowHandle, + gCharacterEditorWindow, x, NAME_BUTTON_Y, - _GInfo[EDITOR_GRAPHIC_SEX_ON].width, - _GInfo[EDITOR_GRAPHIC_SEX_ON].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_SEX_ON].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_SEX_ON].height, -1, -1, -1, SEX_BTN_CODE, - _grphcpy[EDITOR_GRAPHIC_SEX_OFF], - _grphcpy[EDITOR_GRAPHIC_SEX_ON], + gCharacterEditorFrmCopy[EDITOR_GRAPHIC_SEX_OFF], + gCharacterEditorFrmCopy[EDITOR_GRAPHIC_SEX_ON], 0, 32); if (btn != -1) { - buttonSetMask(btn, _grphbmp[EDITOR_GRAPHIC_SEX_MASK]); + buttonSetMask(btn, gCharacterEditorFrmData[EDITOR_GRAPHIC_SEX_MASK]); buttonSetCallbacks(btn, _gsound_lrg_butt_press, NULL); } y = TAG_SKILLS_BUTTON_Y; for (i = 0; i < SKILL_COUNT; i++) { - _tag_bids[i] = buttonCreate( - characterEditorWindowHandle, + gCharacterEditorTagSkillBtns[i] = buttonCreate( + gCharacterEditorWindow, TAG_SKILLS_BUTTON_X, y, - _GInfo[EDITOR_GRAPHIC_TAG_SKILL_BUTTON_ON].width, - _GInfo[EDITOR_GRAPHIC_TAG_SKILL_BUTTON_ON].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_TAG_SKILL_BUTTON_ON].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_TAG_SKILL_BUTTON_ON].height, -1, -1, -1, TAG_SKILLS_BUTTON_CODE + i, - _grphbmp[EDITOR_GRAPHIC_TAG_SKILL_BUTTON_OFF], - _grphbmp[EDITOR_GRAPHIC_TAG_SKILL_BUTTON_ON], + gCharacterEditorFrmData[EDITOR_GRAPHIC_TAG_SKILL_BUTTON_OFF], + gCharacterEditorFrmData[EDITOR_GRAPHIC_TAG_SKILL_BUTTON_ON], NULL, 32); - y += _GInfo[EDITOR_GRAPHIC_TAG_SKILL_BUTTON_ON].height; + y += gCharacterEditorFrmSize[EDITOR_GRAPHIC_TAG_SKILL_BUTTON_ON].height; } y = OPTIONAL_TRAITS_BTN_Y; for (i = 0; i < TRAIT_COUNT / 2; i++) { - _trait_bids[i] = buttonCreate( - characterEditorWindowHandle, + gCharacterEditorOptionalTraitBtns[i] = buttonCreate( + gCharacterEditorWindow, OPTIONAL_TRAITS_LEFT_BTN_X, y, - _GInfo[EDITOR_GRAPHIC_TAG_SKILL_BUTTON_ON].width, - _GInfo[EDITOR_GRAPHIC_TAG_SKILL_BUTTON_ON].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_TAG_SKILL_BUTTON_ON].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_TAG_SKILL_BUTTON_ON].height, -1, -1, -1, OPTIONAL_TRAITS_BTN_CODE + i, - _grphbmp[EDITOR_GRAPHIC_TAG_SKILL_BUTTON_OFF], - _grphbmp[EDITOR_GRAPHIC_TAG_SKILL_BUTTON_ON], + gCharacterEditorFrmData[EDITOR_GRAPHIC_TAG_SKILL_BUTTON_OFF], + gCharacterEditorFrmData[EDITOR_GRAPHIC_TAG_SKILL_BUTTON_ON], NULL, 32); - y += _GInfo[EDITOR_GRAPHIC_TAG_SKILL_BUTTON_ON].height + OPTIONAL_TRAITS_BTN_SPACE; + y += gCharacterEditorFrmSize[EDITOR_GRAPHIC_TAG_SKILL_BUTTON_ON].height + OPTIONAL_TRAITS_BTN_SPACE; } y = OPTIONAL_TRAITS_BTN_Y; for (i = TRAIT_COUNT / 2; i < TRAIT_COUNT; i++) { - _trait_bids[i] = buttonCreate( - characterEditorWindowHandle, + gCharacterEditorOptionalTraitBtns[i] = buttonCreate( + gCharacterEditorWindow, OPTIONAL_TRAITS_RIGHT_BTN_X, y, - _GInfo[EDITOR_GRAPHIC_TAG_SKILL_BUTTON_ON].width, - _GInfo[EDITOR_GRAPHIC_TAG_SKILL_BUTTON_ON].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_TAG_SKILL_BUTTON_ON].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_TAG_SKILL_BUTTON_ON].height, -1, -1, -1, OPTIONAL_TRAITS_BTN_CODE + i, - _grphbmp[EDITOR_GRAPHIC_TAG_SKILL_BUTTON_OFF], - _grphbmp[EDITOR_GRAPHIC_TAG_SKILL_BUTTON_ON], + gCharacterEditorFrmData[EDITOR_GRAPHIC_TAG_SKILL_BUTTON_OFF], + gCharacterEditorFrmData[EDITOR_GRAPHIC_TAG_SKILL_BUTTON_ON], NULL, 32); - y += _GInfo[EDITOR_GRAPHIC_TAG_SKILL_BUTTON_ON].height + OPTIONAL_TRAITS_BTN_SPACE; + y += gCharacterEditorFrmSize[EDITOR_GRAPHIC_TAG_SKILL_BUTTON_ON].height + OPTIONAL_TRAITS_BTN_SPACE; } - characterEditorWindowRenderTraits(); + characterEditorDrawOptionalTraits(); } else { x = NAME_BUTTON_X; - blitBufferToBufferTrans(_grphcpy[EDITOR_GRAPHIC_NAME_OFF], - _GInfo[EDITOR_GRAPHIC_NAME_ON].width, - _GInfo[EDITOR_GRAPHIC_NAME_ON].height, - _GInfo[EDITOR_GRAPHIC_NAME_ON].width, - characterEditorWindowBuf + (EDITOR_WINDOW_WIDTH * NAME_BUTTON_Y) + x, + blitBufferToBufferTrans(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_NAME_OFF], + gCharacterEditorFrmSize[EDITOR_GRAPHIC_NAME_ON].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_NAME_ON].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_NAME_ON].width, + gCharacterEditorWindowBuffer + (EDITOR_WINDOW_WIDTH * NAME_BUTTON_Y) + x, EDITOR_WINDOW_WIDTH); - x += _GInfo[EDITOR_GRAPHIC_NAME_ON].width; - blitBufferToBufferTrans(_grphcpy[EDITOR_GRAPHIC_AGE_OFF], - _GInfo[EDITOR_GRAPHIC_AGE_ON].width, - _GInfo[EDITOR_GRAPHIC_AGE_ON].height, - _GInfo[EDITOR_GRAPHIC_AGE_ON].width, - characterEditorWindowBuf + (EDITOR_WINDOW_WIDTH * NAME_BUTTON_Y) + x, + x += gCharacterEditorFrmSize[EDITOR_GRAPHIC_NAME_ON].width; + blitBufferToBufferTrans(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_AGE_OFF], + gCharacterEditorFrmSize[EDITOR_GRAPHIC_AGE_ON].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_AGE_ON].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_AGE_ON].width, + gCharacterEditorWindowBuffer + (EDITOR_WINDOW_WIDTH * NAME_BUTTON_Y) + x, EDITOR_WINDOW_WIDTH); - x += _GInfo[EDITOR_GRAPHIC_AGE_ON].width; - blitBufferToBufferTrans(_grphcpy[EDITOR_GRAPHIC_SEX_OFF], - _GInfo[EDITOR_GRAPHIC_SEX_ON].width, - _GInfo[EDITOR_GRAPHIC_SEX_ON].height, - _GInfo[EDITOR_GRAPHIC_SEX_ON].width, - characterEditorWindowBuf + (EDITOR_WINDOW_WIDTH * NAME_BUTTON_Y) + x, + x += gCharacterEditorFrmSize[EDITOR_GRAPHIC_AGE_ON].width; + blitBufferToBufferTrans(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_SEX_OFF], + gCharacterEditorFrmSize[EDITOR_GRAPHIC_SEX_ON].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_SEX_ON].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_SEX_ON].width, + gCharacterEditorWindowBuffer + (EDITOR_WINDOW_WIDTH * NAME_BUTTON_Y) + x, EDITOR_WINDOW_WIDTH); - btn = buttonCreate(characterEditorWindowHandle, + btn = buttonCreate(gCharacterEditorWindow, 11, 327, - _GInfo[EDITOR_GRAPHIC_FOLDER_MASK].width, - _GInfo[EDITOR_GRAPHIC_FOLDER_MASK].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_FOLDER_MASK].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_FOLDER_MASK].height, -1, -1, -1, @@ -1500,64 +1513,64 @@ int characterEditorWindowInit() NULL, BUTTON_FLAG_TRANSPARENT); if (btn != -1) { - buttonSetMask(btn, _grphbmp[EDITOR_GRAPHIC_FOLDER_MASK]); + buttonSetMask(btn, gCharacterEditorFrmData[EDITOR_GRAPHIC_FOLDER_MASK]); } } if (gCharacterEditorIsCreationMode) { // +/- buttons for stats for (i = 0; i < 7; i++) { - _stat_bids_plus[i] = buttonCreate(characterEditorWindowHandle, + gCharacterEditorPrimaryStatPlusBtns[i] = buttonCreate(gCharacterEditorWindow, SPECIAL_STATS_BTN_X, - _StatYpos[i], - _GInfo[EDITOR_GRAPHIC_SLIDER_PLUS_ON].width, - _GInfo[EDITOR_GRAPHIC_SLIDER_PLUS_ON].height, + gCharacterEditorPrimaryStatY[i], + gCharacterEditorFrmSize[EDITOR_GRAPHIC_SLIDER_PLUS_ON].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_SLIDER_PLUS_ON].height, -1, 518, 503 + i, 518, - _grphbmp[EDITOR_GRAPHIC_SLIDER_PLUS_OFF], - _grphbmp[EDITOR_GRAPHIC_SLIDER_PLUS_ON], + gCharacterEditorFrmData[EDITOR_GRAPHIC_SLIDER_PLUS_OFF], + gCharacterEditorFrmData[EDITOR_GRAPHIC_SLIDER_PLUS_ON], NULL, 32); - if (_stat_bids_plus[i] != -1) { - buttonSetCallbacks(_stat_bids_plus[i], _gsound_red_butt_press, NULL); + if (gCharacterEditorPrimaryStatPlusBtns[i] != -1) { + buttonSetCallbacks(gCharacterEditorPrimaryStatPlusBtns[i], _gsound_red_butt_press, NULL); } - _stat_bids_minus[i] = buttonCreate(characterEditorWindowHandle, + gCharacterEditorPrimaryStatMinusBtns[i] = buttonCreate(gCharacterEditorWindow, SPECIAL_STATS_BTN_X, - _StatYpos[i] + _GInfo[EDITOR_GRAPHIC_SLIDER_PLUS_ON].height - 1, - _GInfo[EDITOR_GRAPHIC_SLIDER_MINUS_ON].width, - _GInfo[EDITOR_GRAPHIC_SLIDER_MINUS_ON].height, + gCharacterEditorPrimaryStatY[i] + gCharacterEditorFrmSize[EDITOR_GRAPHIC_SLIDER_PLUS_ON].height - 1, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_SLIDER_MINUS_ON].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_SLIDER_MINUS_ON].height, -1, 518, 510 + i, 518, - _grphbmp[EDITOR_GRAPHIC_SLIDER_MINUS_OFF], - _grphbmp[EDITOR_GRAPHIC_SLIDER_MINUS_ON], + gCharacterEditorFrmData[EDITOR_GRAPHIC_SLIDER_MINUS_OFF], + gCharacterEditorFrmData[EDITOR_GRAPHIC_SLIDER_MINUS_ON], NULL, 32); - if (_stat_bids_minus[i] != -1) { - buttonSetCallbacks(_stat_bids_minus[i], _gsound_red_butt_press, NULL); + if (gCharacterEditorPrimaryStatMinusBtns[i] != -1) { + buttonSetCallbacks(gCharacterEditorPrimaryStatMinusBtns[i], _gsound_red_butt_press, NULL); } } } - _RegInfoAreas(); + characterEditorRegisterInfoAreas(); soundContinueAll(); btn = buttonCreate( - characterEditorWindowHandle, + gCharacterEditorWindow, 343, 454, - _GInfo[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP].width, - _GInfo[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP].height, -1, -1, -1, 501, - _grphbmp[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP], - _grphbmp[EDITOR_GRAPHIC_LILTTLE_RED_BUTTON_DOWN], + gCharacterEditorFrmData[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP], + gCharacterEditorFrmData[EDITOR_GRAPHIC_LILTTLE_RED_BUTTON_DOWN], NULL, BUTTON_FLAG_TRANSPARENT); if (btn != -1) { @@ -1565,17 +1578,17 @@ int characterEditorWindowInit() } btn = buttonCreate( - characterEditorWindowHandle, + gCharacterEditorWindow, 552, 454, - _GInfo[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP].width, - _GInfo[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP].height, -1, -1, -1, 502, - _grphbmp[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP], - _grphbmp[EDITOR_GRAPHIC_LILTTLE_RED_BUTTON_DOWN], + gCharacterEditorFrmData[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP], + gCharacterEditorFrmData[EDITOR_GRAPHIC_LILTTLE_RED_BUTTON_DOWN], 0, BUTTON_FLAG_TRANSPARENT); if (btn != -1) { @@ -1583,24 +1596,24 @@ int characterEditorWindowInit() } btn = buttonCreate( - characterEditorWindowHandle, + gCharacterEditorWindow, 455, 454, - _GInfo[23].width, - _GInfo[23].height, + gCharacterEditorFrmSize[23].width, + gCharacterEditorFrmSize[23].height, -1, -1, -1, 500, - _grphbmp[23], - _grphbmp[24], + gCharacterEditorFrmData[23], + gCharacterEditorFrmData[24], 0, BUTTON_FLAG_TRANSPARENT); if (btn != -1) { buttonSetCallbacks(btn, _gsound_red_butt_press, _gsound_red_butt_release); } - windowRefresh(characterEditorWindowHandle); + windowRefresh(gCharacterEditorWindow); indicatorBarHide(); return 0; @@ -1609,27 +1622,27 @@ int characterEditorWindowInit() // 0x433AA8 void characterEditorWindowFree() { - if (_folder_down_button != -1) { - buttonDestroy(_folder_down_button); - _folder_down_button = -1; + if (gCharacterEditorFolderViewScrollDownBtn != -1) { + buttonDestroy(gCharacterEditorFolderViewScrollDownBtn); + gCharacterEditorFolderViewScrollDownBtn = -1; } - if (_folder_up_button != -1) { - buttonDestroy(_folder_up_button); - _folder_up_button = -1; + if (gCharacterEditorFolderViewScrollUpBtn != -1) { + buttonDestroy(gCharacterEditorFolderViewScrollUpBtn); + gCharacterEditorFolderViewScrollUpBtn = -1; } - windowDestroy(characterEditorWindowHandle); + windowDestroy(gCharacterEditorWindow); for (int index = 0; index < EDITOR_GRAPHIC_COUNT; index++) { - artUnlock(_grph_key[index]); + artUnlock(gCharacterEditorFrmHandle[index]); - if (_copyflag[index]) { - internal_free(_grphcpy[index]); + if (gCharacterEditorFrmShouldCopy[index]) { + internal_free(gCharacterEditorFrmCopy[index]); } } - artUnlock(_bck_key); + artUnlock(gCharacterEditorWindowBackgroundHandle); // NOTE: Uninline. genericReputationFree(); @@ -1637,22 +1650,25 @@ void characterEditorWindowFree() // NOTE: Uninline. karmaFree(); - messageListFree(&editorMessageList); + // SFALL: Custom karma folder. + customKarmaFolderFree(); + + messageListFree(&gCharacterEditorMessageList); interfaceBarRefresh(); - if (_bk_enable_0) { + if (gCharacterEditorIsoWasEnabled) { isoEnable(); } colorCycleEnable(); gameMouseSetCursor(MOUSE_CURSOR_ARROW); - fontSetCurrent(characterEditorWindowOldFont); + fontSetCurrent(gCharacterEditorOldFont); if (gCharacterEditorIsCreationMode == 1) { - skillsSetTagged(_temp_tag_skill, 3); - traitsSetSelected(_temp_trait[0], _temp_trait[1]); + skillsSetTagged(gCharacterEditorTempTaggedSkills, 3); + traitsSetSelected(gCharacterEditorTempTraits[0], gCharacterEditorTempTraits[1]); characterEditorSelectedItem = 0; critterAdjustHitPoints(gDude, 1000); } @@ -1662,23 +1678,23 @@ void characterEditorWindowFree() // CharEditInit // 0x433C0C -void _CharEditInit() +void characterEditorInit() { int i; characterEditorSelectedItem = 0; - _skill_cursor = 0; - _slider_y = 27; - _free_perk = 0; + gCharacterEditorCurrentSkill = 0; + gCharacterEditorSkillValueAdjustmentSliderY = 27; + gCharacterEditorHasFreePerk = 0; characterEditorWindowSelectedFolder = EDITOR_FOLDER_PERKS; for (i = 0; i < 2; i++) { - _temp_trait[i] = -1; - _trait_back[i] = -1; + gCharacterEditorTempTraits[i] = -1; + gCharacterEditorOptionalTraitsBackup[i] = -1; } - characterEditorRemainingCharacterPoints = 5; - _last_level = 1; + gCharacterEditorRemainingCharacterPoints = 5; + gCharacterEditorLastLevel = 1; } // handle name input @@ -1810,43 +1826,43 @@ char* _strmfe(char* dest, const char* name, const char* ext) } // 0x43410C -void editorRenderFolders() +void characterEditorDrawFolders() { if (gCharacterEditorIsCreationMode) { return; } - blitBufferToBuffer(characterEditorWindowBackgroundBuf + (360 * 640) + 34, 280, 120, 640, characterEditorWindowBuf + (360 * 640) + 34, 640); + blitBufferToBuffer(gCharacterEditorWindowBackgroundBuffer + (360 * 640) + 34, 280, 120, 640, gCharacterEditorWindowBuffer + (360 * 640) + 34, 640); fontSetCurrent(101); switch (characterEditorWindowSelectedFolder) { case EDITOR_FOLDER_PERKS: - blitBufferToBuffer(_grphcpy[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED], - _GInfo[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, - _GInfo[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].height, - _GInfo[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, - characterEditorWindowBuf + (327 * 640) + 11, + blitBufferToBuffer(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED], + gCharacterEditorFrmSize[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, + gCharacterEditorWindowBuffer + (327 * 640) + 11, 640); - editorRenderPerks(); + characterEditorDrawPerksFolder(); break; case EDITOR_FOLDER_KARMA: - blitBufferToBuffer(_grphcpy[EDITOR_GRAPHIC_KARMA_FOLDER_SELECTED], - _GInfo[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, - _GInfo[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].height, - _GInfo[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, - characterEditorWindowBuf + (327 * 640) + 11, + blitBufferToBuffer(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_KARMA_FOLDER_SELECTED], + gCharacterEditorFrmSize[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, + gCharacterEditorWindowBuffer + (327 * 640) + 11, 640); - editorRenderKarma(); + characterEditorDrawKarmaFolder(); break; case EDITOR_FOLDER_KILLS: - blitBufferToBuffer(_grphcpy[EDITOR_GRAPHIC_KILLS_FOLDER_SELECTED], - _GInfo[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, - _GInfo[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].height, - _GInfo[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, - characterEditorWindowBuf + (327 * 640) + 11, + blitBufferToBuffer(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_KILLS_FOLDER_SELECTED], + gCharacterEditorFrmSize[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].width, + gCharacterEditorWindowBuffer + (327 * 640) + 11, 640); - _kills_count = editorRenderKills(); + gCharacterEditorKillsCount = characterEditorDrawKillsFolder(); break; default: debugPrint("\n ** Unknown folder type! **\n"); @@ -1855,7 +1871,7 @@ void editorRenderFolders() } // 0x434238 -void editorRenderPerks() +void characterEditorDrawPerksFolder() { const char* string; char perkName[80]; @@ -1863,39 +1879,39 @@ void editorRenderPerks() int perkLevel; bool hasContent = false; - _folder_clear(); + characterEditorFolderViewClear(); - if (_temp_trait[0] != -1) { + if (gCharacterEditorTempTraits[0] != -1) { // TRAITS - string = getmsg(&editorMessageList, &editorMessageListItem, 156); - if (_folder_print_seperator(string)) { - _folder_card_fid = 54; + string = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 156); + if (characterEditorFolderViewDrawHeading(string)) { + gCharacterEditorFolderCardFrmId = 54; // Optional Traits - _folder_card_title = getmsg(&editorMessageList, &editorMessageListItem, 146); - _folder_card_title2 = NULL; + gCharacterEditorFolderCardTitle = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 146); + gCharacterEditorFolderCardSubtitle = NULL; // Optional traits describe your character in more detail. All traits will have positive and negative effects. You may choose up to two traits during creation. - _folder_card_desc = getmsg(&editorMessageList, &editorMessageListItem, 147); + gCharacterEditorFolderCardDescription = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 147); hasContent = true; } - if (_temp_trait[0] != -1) { - string = traitGetName(_temp_trait[0]); - if (_folder_print_line(string)) { - _folder_card_fid = traitGetFrmId(_temp_trait[0]); - _folder_card_title = traitGetName(_temp_trait[0]); - _folder_card_title2 = NULL; - _folder_card_desc = traitGetDescription(_temp_trait[0]); + if (gCharacterEditorTempTraits[0] != -1) { + string = traitGetName(gCharacterEditorTempTraits[0]); + if (characterEditorFolderViewDrawString(string)) { + gCharacterEditorFolderCardFrmId = traitGetFrmId(gCharacterEditorTempTraits[0]); + gCharacterEditorFolderCardTitle = traitGetName(gCharacterEditorTempTraits[0]); + gCharacterEditorFolderCardSubtitle = NULL; + gCharacterEditorFolderCardDescription = traitGetDescription(gCharacterEditorTempTraits[0]); hasContent = true; } } - if (_temp_trait[1] != -1) { - string = traitGetName(_temp_trait[1]); - if (_folder_print_line(string)) { - _folder_card_fid = traitGetFrmId(_temp_trait[1]); - _folder_card_title = traitGetName(_temp_trait[1]); - _folder_card_title2 = NULL; - _folder_card_desc = traitGetDescription(_temp_trait[1]); + if (gCharacterEditorTempTraits[1] != -1) { + string = traitGetName(gCharacterEditorTempTraits[1]); + if (characterEditorFolderViewDrawString(string)) { + gCharacterEditorFolderCardFrmId = traitGetFrmId(gCharacterEditorTempTraits[1]); + gCharacterEditorFolderCardTitle = traitGetName(gCharacterEditorTempTraits[1]); + gCharacterEditorFolderCardSubtitle = NULL; + gCharacterEditorFolderCardDescription = traitGetDescription(gCharacterEditorTempTraits[1]); hasContent = true; } } @@ -1909,8 +1925,8 @@ void editorRenderPerks() if (perk != PERK_COUNT) { // PERKS - string = getmsg(&editorMessageList, &editorMessageListItem, 109); - _folder_print_seperator(string); + string = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 109); + characterEditorFolderViewDrawHeading(string); for (perk = 0; perk < PERK_COUNT; perk++) { perkLevel = perkGetRank(gDude, perk); @@ -1923,11 +1939,11 @@ void editorRenderPerks() sprintf(perkName, "%s (%d)", string, perkLevel); } - if (_folder_print_line(perkName)) { - _folder_card_fid = perkGetFrmId(perk); - _folder_card_title = perkGetName(perk); - _folder_card_title2 = NULL; - _folder_card_desc = perkGetDescription(perk); + if (characterEditorFolderViewDrawString(perkName)) { + gCharacterEditorFolderCardFrmId = perkGetFrmId(perk); + gCharacterEditorFolderCardTitle = perkGetName(perk); + gCharacterEditorFolderCardSubtitle = NULL; + gCharacterEditorFolderCardDescription = perkGetDescription(perk); hasContent = true; } } @@ -1935,23 +1951,25 @@ void editorRenderPerks() } if (!hasContent) { - _folder_card_fid = 71; + gCharacterEditorFolderCardFrmId = 71; // Perks - _folder_card_title = getmsg(&editorMessageList, &editorMessageListItem, 124); - _folder_card_title2 = NULL; + gCharacterEditorFolderCardTitle = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 124); + gCharacterEditorFolderCardSubtitle = NULL; // Perks add additional abilities. Every third experience level, you can choose one perk. - _folder_card_desc = getmsg(&editorMessageList, &editorMessageListItem, 127); + gCharacterEditorFolderCardDescription = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 127); } } // 0x434498 -int _kills_list_comp(const KillInfo* a, const KillInfo* b) +int characterEditorKillsCompare(const void* a1, const void* a2) { - return compat_stricmp(a->name, b->name); + const KillInfo* v1 = (const KillInfo*)a1; + const KillInfo* v2 = (const KillInfo*)a2; + return compat_stricmp(v1->name, v2->name); } // 0x4344A4 -int editorRenderKills() +int characterEditorDrawKillsFolder() { int i; int killsCount; @@ -1959,7 +1977,7 @@ int editorRenderKills() int usedKills = 0; bool hasContent = false; - _folder_clear(); + characterEditorFolderViewClear(); for (i = 0; i < KILL_TYPE_COUNT; i++) { killsCount = killsGetByType(i); @@ -1973,33 +1991,33 @@ int editorRenderKills() } if (usedKills != 0) { - qsort(kills, usedKills, 12, (int (*)(const void*, const void*))_kills_list_comp); + qsort(kills, usedKills, 12, characterEditorKillsCompare); for (i = 0; i < usedKills; i++) { KillInfo* killInfo = &(kills[i]); - if (editorDrawKillsEntry(killInfo->name, killInfo->kills)) { - _folder_card_fid = 46; - _folder_card_title = _folder_card_string; - _folder_card_title2 = NULL; - _folder_card_desc = killTypeGetDescription(kills[i].killTypeId); - sprintf(_folder_card_string, "%s %s", killInfo->name, getmsg(&editorMessageList, &editorMessageListItem, 126)); + if (characterEditorFolderViewDrawKillsEntry(killInfo->name, killInfo->kills)) { + gCharacterEditorFolderCardFrmId = 46; + gCharacterEditorFolderCardTitle = gCharacterEditorFolderCardString; + gCharacterEditorFolderCardSubtitle = NULL; + gCharacterEditorFolderCardDescription = killTypeGetDescription(kills[i].killTypeId); + sprintf(gCharacterEditorFolderCardString, "%s %s", killInfo->name, getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 126)); hasContent = true; } } } if (!hasContent) { - _folder_card_fid = 46; - _folder_card_title = getmsg(&editorMessageList, &editorMessageListItem, 126); - _folder_card_title2 = NULL; - _folder_card_desc = getmsg(&editorMessageList, &editorMessageListItem, 129); + gCharacterEditorFolderCardFrmId = 46; + gCharacterEditorFolderCardTitle = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 126); + gCharacterEditorFolderCardSubtitle = NULL; + gCharacterEditorFolderCardDescription = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 129); } return usedKills; } // 0x4345DC -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) { Rect rect; int windowWidth; @@ -2018,12 +2036,12 @@ void characterEditorRenderBigNumber(int x, int y, int flags, int value, int prev rect.right = x + BIG_NUM_WIDTH * 2; rect.bottom = y + BIG_NUM_HEIGHT; - numbersGraphicBufferPtr = _grphbmp[0]; + numbersGraphicBufferPtr = gCharacterEditorFrmData[0]; if (flags & RED_NUMBERS) { // First half of the bignum.frm is white, // second half is red. - numbersGraphicBufferPtr += _GInfo[EDITOR_GRAPHIC_BIG_NUMBERS].width / 2; + numbersGraphicBufferPtr += gCharacterEditorFrmSize[EDITOR_GRAPHIC_BIG_NUMBERS].width / 2; } tensBufferPtr = windowBuf + windowWidth * y + x; @@ -2039,7 +2057,7 @@ void characterEditorRenderBigNumber(int x, int y, int flags, int value, int prev blitBufferToBuffer(numbersGraphicBufferPtr + BIG_NUM_WIDTH * 11, BIG_NUM_WIDTH, BIG_NUM_HEIGHT, - _GInfo[EDITOR_GRAPHIC_BIG_NUMBERS].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_BIG_NUMBERS].width, onesBufferPtr, windowWidth); windowRefreshRect(windowHandle, &rect); @@ -2050,7 +2068,7 @@ void characterEditorRenderBigNumber(int x, int y, int flags, int value, int prev blitBufferToBuffer(numbersGraphicBufferPtr + BIG_NUM_WIDTH * ones, BIG_NUM_WIDTH, BIG_NUM_HEIGHT, - _GInfo[EDITOR_GRAPHIC_BIG_NUMBERS].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_BIG_NUMBERS].width, onesBufferPtr, windowWidth); windowRefreshRect(windowHandle, &rect); @@ -2060,7 +2078,7 @@ void characterEditorRenderBigNumber(int x, int y, int flags, int value, int prev blitBufferToBuffer(numbersGraphicBufferPtr + BIG_NUM_WIDTH * 11, BIG_NUM_WIDTH, BIG_NUM_HEIGHT, - _GInfo[EDITOR_GRAPHIC_BIG_NUMBERS].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_BIG_NUMBERS].width, tensBufferPtr, windowWidth); windowRefreshRect(windowHandle, &rect); @@ -2071,7 +2089,7 @@ void characterEditorRenderBigNumber(int x, int y, int flags, int value, int prev blitBufferToBuffer(numbersGraphicBufferPtr + BIG_NUM_WIDTH * tens, BIG_NUM_WIDTH, BIG_NUM_HEIGHT, - _GInfo[EDITOR_GRAPHIC_BIG_NUMBERS].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_BIG_NUMBERS].width, tensBufferPtr, windowWidth); windowRefreshRect(windowHandle, &rect); @@ -2079,13 +2097,13 @@ void characterEditorRenderBigNumber(int x, int y, int flags, int value, int prev blitBufferToBuffer(numbersGraphicBufferPtr + BIG_NUM_WIDTH * tens, BIG_NUM_WIDTH, BIG_NUM_HEIGHT, - _GInfo[EDITOR_GRAPHIC_BIG_NUMBERS].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_BIG_NUMBERS].width, tensBufferPtr, windowWidth); blitBufferToBuffer(numbersGraphicBufferPtr + BIG_NUM_WIDTH * ones, BIG_NUM_WIDTH, BIG_NUM_HEIGHT, - _GInfo[EDITOR_GRAPHIC_BIG_NUMBERS].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_BIG_NUMBERS].width, onesBufferPtr, windowWidth); } @@ -2094,20 +2112,20 @@ void characterEditorRenderBigNumber(int x, int y, int flags, int value, int prev blitBufferToBuffer(numbersGraphicBufferPtr + BIG_NUM_WIDTH * 9, BIG_NUM_WIDTH, BIG_NUM_HEIGHT, - _GInfo[EDITOR_GRAPHIC_BIG_NUMBERS].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_BIG_NUMBERS].width, tensBufferPtr, windowWidth); blitBufferToBuffer(numbersGraphicBufferPtr + BIG_NUM_WIDTH * 9, BIG_NUM_WIDTH, BIG_NUM_HEIGHT, - _GInfo[EDITOR_GRAPHIC_BIG_NUMBERS].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_BIG_NUMBERS].width, onesBufferPtr, windowWidth); } } // 0x434920 -void editorRenderPcStats() +void characterEditorDrawPcStats() { int color; int y; @@ -2132,7 +2150,7 @@ void editorRenderPcStats() fontSetCurrent(101); - blitBufferToBuffer(characterEditorWindowBackgroundBuf + 640 * 280 + 32, 124, 32, 640, characterEditorWindowBuf + 640 * 280 + 32, 640); + blitBufferToBuffer(gCharacterEditorWindowBackgroundBuffer + 640 * 280 + 32, 124, 32, 640, gCharacterEditorWindowBuffer + 640 * 280 + 32, 640); // LEVEL y = 280; @@ -2144,9 +2162,9 @@ void editorRenderPcStats() int level = pcGetStat(PC_STAT_LEVEL); sprintf(stringBuffer, "%s %d", - getmsg(&editorMessageList, &editorMessageListItem, 113), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 113), level); - fontDrawText(characterEditorWindowBuf + 640 * y + 32, stringBuffer, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 32, stringBuffer, 640, 640, color); // EXPERIENCE y += fontGetLineHeight() + 1; @@ -2158,9 +2176,9 @@ void editorRenderPcStats() int exp = pcGetStat(PC_STAT_EXPERIENCE); sprintf(stringBuffer, "%s %s", - getmsg(&editorMessageList, &editorMessageListItem, 114), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 114), _itostndn(exp, formattedValueBuffer)); - fontDrawText(characterEditorWindowBuf + 640 * y + 32, stringBuffer, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 32, stringBuffer, 640, 640, color); // EXP NEEDED TO NEXT LEVEL y += fontGetLineHeight() + 1; @@ -2184,13 +2202,13 @@ void editorRenderPcStats() } sprintf(stringBuffer, "%s %s", - getmsg(&editorMessageList, &editorMessageListItem, expMsgId), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, expMsgId), formattedValue); - fontDrawText(characterEditorWindowBuf + 640 * y + 32, stringBuffer, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 32, stringBuffer, 640, 640, color); } // 0x434B38 -void editorRenderPrimaryStat(int stat, bool animate, int previousValue) +void characterEditorDrawPrimaryStat(int stat, bool animate, int previousValue) { int off; int color; @@ -2205,7 +2223,7 @@ void editorRenderPrimaryStat(int stat, bool animate, int previousValue) // NOTE: Original code is different, looks like tail recursion // optimization. for (stat = 0; stat < 7; stat++) { - editorRenderPrimaryStat(stat, 0, 0); + characterEditorDrawPrimaryStat(stat, 0, 0); } return; } @@ -2216,7 +2234,7 @@ void editorRenderPrimaryStat(int stat, bool animate, int previousValue) color = _colorTable[992]; } - off = 640 * (_StatYpos[stat] + 8) + 103; + off = 640 * (gCharacterEditorPrimaryStatY[stat] + 8) + 103; // TODO: The original code is different. if (gCharacterEditorIsCreationMode) { @@ -2232,21 +2250,21 @@ void editorRenderPrimaryStat(int stat, bool animate, int previousValue) flags |= RED_NUMBERS; } - characterEditorRenderBigNumber(58, _StatYpos[stat], flags, value, previousValue, characterEditorWindowHandle); + characterEditorDrawBigNumber(58, gCharacterEditorPrimaryStatY[stat], flags, value, previousValue, gCharacterEditorWindow); - blitBufferToBuffer(characterEditorWindowBackgroundBuf + off, 40, fontGetLineHeight(), 640, characterEditorWindowBuf + off, 640); + blitBufferToBuffer(gCharacterEditorWindowBackgroundBuffer + off, 40, fontGetLineHeight(), 640, gCharacterEditorWindowBuffer + off, 640); messageListItemId = critterGetStat(gDude, stat) + 199; if (messageListItemId > 210) { messageListItemId = 210; } - description = getmsg(&editorMessageList, &editorMessageListItem, messageListItemId); - fontDrawText(characterEditorWindowBuf + 640 * (_StatYpos[stat] + 8) + 103, description, 640, 640, color); + description = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, messageListItemId); + fontDrawText(gCharacterEditorWindowBuffer + 640 * (gCharacterEditorPrimaryStatY[stat] + 8) + 103, description, 640, 640, color); } else { value = critterGetStat(gDude, stat); - characterEditorRenderBigNumber(58, _StatYpos[stat], 0, value, 0, characterEditorWindowHandle); - blitBufferToBuffer(characterEditorWindowBackgroundBuf + off, 40, fontGetLineHeight(), 640, characterEditorWindowBuf + off, 640); + characterEditorDrawBigNumber(58, gCharacterEditorPrimaryStatY[stat], 0, value, 0, gCharacterEditorWindow); + blitBufferToBuffer(gCharacterEditorWindowBackgroundBuffer + off, 40, fontGetLineHeight(), 640, gCharacterEditorWindowBuffer + off, 640); value = critterGetStat(gDude, stat); if (value > 10) { @@ -2254,12 +2272,12 @@ void editorRenderPrimaryStat(int stat, bool animate, int previousValue) } description = statGetValueDescription(value); - fontDrawText(characterEditorWindowBuf + off, description, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + off, description, 640, 640, color); } } // 0x434F18 -void editorRenderGender() +void characterEditorDrawGender() { int gender; char* str; @@ -2269,27 +2287,27 @@ void editorRenderGender() fontSetCurrent(103); gender = critterGetStat(gDude, STAT_GENDER); - str = getmsg(&editorMessageList, &editorMessageListItem, 107 + gender); + str = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 107 + gender); strcpy(text, str); - width = _GInfo[EDITOR_GRAPHIC_SEX_ON].width; + width = gCharacterEditorFrmSize[EDITOR_GRAPHIC_SEX_ON].width; x = (width / 2) - (fontGetStringWidth(text) / 2); - memcpy(_grphcpy[11], - _grphbmp[EDITOR_GRAPHIC_SEX_ON], - width * _GInfo[EDITOR_GRAPHIC_SEX_ON].height); - memcpy(_grphcpy[EDITOR_GRAPHIC_SEX_OFF], - _grphbmp[10], - width * _GInfo[EDITOR_GRAPHIC_SEX_OFF].height); + memcpy(gCharacterEditorFrmCopy[11], + gCharacterEditorFrmData[EDITOR_GRAPHIC_SEX_ON], + width * gCharacterEditorFrmSize[EDITOR_GRAPHIC_SEX_ON].height); + memcpy(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_SEX_OFF], + gCharacterEditorFrmData[10], + width * gCharacterEditorFrmSize[EDITOR_GRAPHIC_SEX_OFF].height); x += 6 * width; - fontDrawText(_grphcpy[EDITOR_GRAPHIC_SEX_ON] + x, text, width, width, _colorTable[14723]); - fontDrawText(_grphcpy[EDITOR_GRAPHIC_SEX_OFF] + x, text, width, width, _colorTable[18979]); + fontDrawText(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_SEX_ON] + x, text, width, width, _colorTable[14723]); + fontDrawText(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_SEX_OFF] + x, text, width, width, _colorTable[18979]); } // 0x43501C -void editorRenderAge() +void characterEditorDrawAge() { int age; char* str; @@ -2299,27 +2317,27 @@ void editorRenderAge() fontSetCurrent(103); age = critterGetStat(gDude, STAT_AGE); - str = getmsg(&editorMessageList, &editorMessageListItem, 104); + str = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 104); sprintf(text, "%s %d", str, age); - width = _GInfo[EDITOR_GRAPHIC_AGE_ON].width; + width = gCharacterEditorFrmSize[EDITOR_GRAPHIC_AGE_ON].width; x = (width / 2) + 1 - (fontGetStringWidth(text) / 2); - memcpy(_grphcpy[EDITOR_GRAPHIC_AGE_ON], - _grphbmp[EDITOR_GRAPHIC_AGE_ON], - width * _GInfo[EDITOR_GRAPHIC_AGE_ON].height); - memcpy(_grphcpy[EDITOR_GRAPHIC_AGE_OFF], - _grphbmp[EDITOR_GRAPHIC_AGE_OFF], - width * _GInfo[EDITOR_GRAPHIC_AGE_ON].height); + memcpy(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_AGE_ON], + gCharacterEditorFrmData[EDITOR_GRAPHIC_AGE_ON], + width * gCharacterEditorFrmSize[EDITOR_GRAPHIC_AGE_ON].height); + memcpy(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_AGE_OFF], + gCharacterEditorFrmData[EDITOR_GRAPHIC_AGE_OFF], + width * gCharacterEditorFrmSize[EDITOR_GRAPHIC_AGE_ON].height); x += 6 * width; - fontDrawText(_grphcpy[EDITOR_GRAPHIC_AGE_ON] + x, text, width, width, _colorTable[14723]); - fontDrawText(_grphcpy[EDITOR_GRAPHIC_AGE_OFF] + x, text, width, width, _colorTable[18979]); + fontDrawText(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_AGE_ON] + x, text, width, width, _colorTable[14723]); + fontDrawText(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_AGE_OFF] + x, text, width, width, _colorTable[18979]); } // 0x435118 -void editorRenderName() +void characterEditorDrawName() { char* str; char text[32]; @@ -2359,23 +2377,23 @@ void editorRenderName() } } - width = _GInfo[EDITOR_GRAPHIC_NAME_ON].width; + width = gCharacterEditorFrmSize[EDITOR_GRAPHIC_NAME_ON].width; x = (width / 2) + 3 - (fontGetStringWidth(text) / 2); - memcpy(_grphcpy[EDITOR_GRAPHIC_NAME_ON], - _grphbmp[EDITOR_GRAPHIC_NAME_ON], - _GInfo[EDITOR_GRAPHIC_NAME_ON].width * _GInfo[EDITOR_GRAPHIC_NAME_ON].height); - memcpy(_grphcpy[EDITOR_GRAPHIC_NAME_OFF], - _grphbmp[EDITOR_GRAPHIC_NAME_OFF], - _GInfo[EDITOR_GRAPHIC_NAME_OFF].width * _GInfo[EDITOR_GRAPHIC_NAME_OFF].height); + memcpy(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_NAME_ON], + gCharacterEditorFrmData[EDITOR_GRAPHIC_NAME_ON], + gCharacterEditorFrmSize[EDITOR_GRAPHIC_NAME_ON].width * gCharacterEditorFrmSize[EDITOR_GRAPHIC_NAME_ON].height); + memcpy(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_NAME_OFF], + gCharacterEditorFrmData[EDITOR_GRAPHIC_NAME_OFF], + gCharacterEditorFrmSize[EDITOR_GRAPHIC_NAME_OFF].width * gCharacterEditorFrmSize[EDITOR_GRAPHIC_NAME_OFF].height); x += 6 * width; - fontDrawText(_grphcpy[EDITOR_GRAPHIC_NAME_ON] + x, text, width, width, _colorTable[14723]); - fontDrawText(_grphcpy[EDITOR_GRAPHIC_NAME_OFF] + x, text, width, width, _colorTable[18979]); + fontDrawText(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_NAME_ON] + x, text, width, width, _colorTable[14723]); + fontDrawText(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_NAME_OFF] + x, text, width, width, _colorTable[18979]); } // 0x43527C -void editorRenderSecondaryStats() +void characterEditorDrawDerivedStats() { int conditions; int color; @@ -2389,7 +2407,7 @@ void editorRenderSecondaryStats() y = 46; - blitBufferToBuffer(characterEditorWindowBackgroundBuf + 640 * y + 194, 118, 108, 640, characterEditorWindowBuf + 640 * y + 194, 640); + blitBufferToBuffer(gCharacterEditorWindowBackgroundBuffer + 640 * y + 194, 118, 108, 640, gCharacterEditorWindowBuffer + 640 * y + 194, 640); // Hit Points if (characterEditorSelectedItem == EDITOR_HIT_POINTS) { @@ -2408,12 +2426,12 @@ void editorRenderSecondaryStats() currHp = critterGetHitPoints(gDude); } - messageListItemText = getmsg(&editorMessageList, &editorMessageListItem, 300); + messageListItemText = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 300); sprintf(t, "%s", messageListItemText); - fontDrawText(characterEditorWindowBuf + 640 * y + 194, t, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 194, t, 640, 640, color); sprintf(t, "%d/%d", currHp, maxHp); - fontDrawText(characterEditorWindowBuf + 640 * y + 263, t, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 263, t, 640, 640, color); // Poisoned y += fontGetLineHeight() + 3; @@ -2424,9 +2442,9 @@ void editorRenderSecondaryStats() color = critterGetPoison(gDude) != 0 ? _colorTable[992] : _colorTable[1313]; } - messageListItemText = getmsg(&editorMessageList, &editorMessageListItem, 312); + messageListItemText = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 312); sprintf(t, "%s", messageListItemText); - fontDrawText(characterEditorWindowBuf + 640 * y + 194, t, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 194, t, 640, 640, color); // Radiated y += fontGetLineHeight() + 3; @@ -2437,9 +2455,9 @@ void editorRenderSecondaryStats() color = critterGetRadiation(gDude) != 0 ? _colorTable[992] : _colorTable[1313]; } - messageListItemText = getmsg(&editorMessageList, &editorMessageListItem, 313); + messageListItemText = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 313); sprintf(t, "%s", messageListItemText); - fontDrawText(characterEditorWindowBuf + 640 * y + 194, t, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 194, t, 640, 640, color); // Eye Damage y += fontGetLineHeight() + 3; @@ -2450,9 +2468,9 @@ void editorRenderSecondaryStats() color = (conditions & DAM_BLIND) ? _colorTable[992] : _colorTable[1313]; } - messageListItemText = getmsg(&editorMessageList, &editorMessageListItem, 314); + messageListItemText = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 314); sprintf(t, "%s", messageListItemText); - fontDrawText(characterEditorWindowBuf + 640 * y + 194, t, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 194, t, 640, 640, color); // Crippled Right Arm y += fontGetLineHeight() + 3; @@ -2463,9 +2481,9 @@ void editorRenderSecondaryStats() color = (conditions & DAM_CRIP_ARM_RIGHT) ? _colorTable[992] : _colorTable[1313]; } - messageListItemText = getmsg(&editorMessageList, &editorMessageListItem, 315); + messageListItemText = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 315); sprintf(t, "%s", messageListItemText); - fontDrawText(characterEditorWindowBuf + 640 * y + 194, t, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 194, t, 640, 640, color); // Crippled Left Arm y += fontGetLineHeight() + 3; @@ -2476,9 +2494,9 @@ void editorRenderSecondaryStats() color = (conditions & DAM_CRIP_ARM_LEFT) ? _colorTable[992] : _colorTable[1313]; } - messageListItemText = getmsg(&editorMessageList, &editorMessageListItem, 316); + messageListItemText = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 316); sprintf(t, "%s", messageListItemText); - fontDrawText(characterEditorWindowBuf + 640 * y + 194, t, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 194, t, 640, 640, color); // Crippled Right Leg y += fontGetLineHeight() + 3; @@ -2489,9 +2507,9 @@ void editorRenderSecondaryStats() color = (conditions & DAM_CRIP_LEG_RIGHT) ? _colorTable[992] : _colorTable[1313]; } - messageListItemText = getmsg(&editorMessageList, &editorMessageListItem, 317); + messageListItemText = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 317); sprintf(t, "%s", messageListItemText); - fontDrawText(characterEditorWindowBuf + 640 * y + 194, t, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 194, t, 640, 640, color); // Crippled Left Leg y += fontGetLineHeight() + 3; @@ -2502,13 +2520,13 @@ void editorRenderSecondaryStats() color = (conditions & DAM_CRIP_LEG_LEFT) ? _colorTable[992] : _colorTable[1313]; } - messageListItemText = getmsg(&editorMessageList, &editorMessageListItem, 318); + messageListItemText = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 318); sprintf(t, "%s", messageListItemText); - fontDrawText(characterEditorWindowBuf + 640 * y + 194, t, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 194, t, 640, 640, color); y = 179; - blitBufferToBuffer(characterEditorWindowBackgroundBuf + 640 * y + 194, 116, 130, 640, characterEditorWindowBuf + 640 * y + 194, 640); + blitBufferToBuffer(gCharacterEditorWindowBackgroundBuffer + 640 * y + 194, 116, 130, 640, gCharacterEditorWindowBuffer + 640 * y + 194, 640); // Armor Class if (characterEditorSelectedItem == EDITOR_FIRST_DERIVED_STAT + EDITOR_DERIVED_STAT_ARMOR_CLASS) { @@ -2517,12 +2535,12 @@ void editorRenderSecondaryStats() color = _colorTable[992]; } - messageListItemText = getmsg(&editorMessageList, &editorMessageListItem, 302); + messageListItemText = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 302); sprintf(t, "%s", messageListItemText); - fontDrawText(characterEditorWindowBuf + 640 * y + 194, t, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 194, t, 640, 640, color); compat_itoa(critterGetStat(gDude, STAT_ARMOR_CLASS), t, 10); - fontDrawText(characterEditorWindowBuf + 640 * y + 288, t, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 288, t, 640, 640, color); // Action Points y += fontGetLineHeight() + 3; @@ -2533,12 +2551,12 @@ void editorRenderSecondaryStats() color = _colorTable[992]; } - messageListItemText = getmsg(&editorMessageList, &editorMessageListItem, 301); + messageListItemText = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 301); sprintf(t, "%s", messageListItemText); - fontDrawText(characterEditorWindowBuf + 640 * y + 194, t, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 194, t, 640, 640, color); compat_itoa(critterGetStat(gDude, STAT_MAXIMUM_ACTION_POINTS), t, 10); - fontDrawText(characterEditorWindowBuf + 640 * y + 288, t, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 288, t, 640, 640, color); // Carry Weight y += fontGetLineHeight() + 3; @@ -2549,12 +2567,12 @@ void editorRenderSecondaryStats() color = _colorTable[992]; } - messageListItemText = getmsg(&editorMessageList, &editorMessageListItem, 311); + messageListItemText = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 311); sprintf(t, "%s", messageListItemText); - fontDrawText(characterEditorWindowBuf + 640 * y + 194, t, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 194, t, 640, 640, color); compat_itoa(critterGetStat(gDude, STAT_CARRY_WEIGHT), t, 10); - fontDrawText(characterEditorWindowBuf + 640 * y + 288, t, 640, 640, critterIsEncumbered(gDude) ? _colorTable[31744] : color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 288, t, 640, 640, critterIsEncumbered(gDude) ? _colorTable[31744] : color); // Melee Damage y += fontGetLineHeight() + 3; @@ -2565,12 +2583,12 @@ void editorRenderSecondaryStats() color = _colorTable[992]; } - messageListItemText = getmsg(&editorMessageList, &editorMessageListItem, 304); + messageListItemText = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 304); sprintf(t, "%s", messageListItemText); - fontDrawText(characterEditorWindowBuf + 640 * y + 194, t, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 194, t, 640, 640, color); compat_itoa(critterGetStat(gDude, STAT_MELEE_DAMAGE), t, 10); - fontDrawText(characterEditorWindowBuf + 640 * y + 288, t, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 288, t, 640, 640, color); // Damage Resistance y += fontGetLineHeight() + 3; @@ -2581,12 +2599,12 @@ void editorRenderSecondaryStats() color = _colorTable[992]; } - messageListItemText = getmsg(&editorMessageList, &editorMessageListItem, 305); + messageListItemText = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 305); sprintf(t, "%s", messageListItemText); - fontDrawText(characterEditorWindowBuf + 640 * y + 194, t, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 194, t, 640, 640, color); sprintf(t, "%d%%", critterGetStat(gDude, STAT_DAMAGE_RESISTANCE)); - fontDrawText(characterEditorWindowBuf + 640 * y + 288, t, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 288, t, 640, 640, color); // Poison Resistance y += fontGetLineHeight() + 3; @@ -2597,12 +2615,12 @@ void editorRenderSecondaryStats() color = _colorTable[992]; } - messageListItemText = getmsg(&editorMessageList, &editorMessageListItem, 306); + messageListItemText = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 306); sprintf(t, "%s", messageListItemText); - fontDrawText(characterEditorWindowBuf + 640 * y + 194, t, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 194, t, 640, 640, color); sprintf(t, "%d%%", critterGetStat(gDude, STAT_POISON_RESISTANCE)); - fontDrawText(characterEditorWindowBuf + 640 * y + 288, t, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 288, t, 640, 640, color); // Radiation Resistance y += fontGetLineHeight() + 3; @@ -2613,12 +2631,12 @@ void editorRenderSecondaryStats() color = _colorTable[992]; } - messageListItemText = getmsg(&editorMessageList, &editorMessageListItem, 307); + messageListItemText = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 307); sprintf(t, "%s", messageListItemText); - fontDrawText(characterEditorWindowBuf + 640 * y + 194, t, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 194, t, 640, 640, color); sprintf(t, "%d%%", critterGetStat(gDude, STAT_RADIATION_RESISTANCE)); - fontDrawText(characterEditorWindowBuf + 640 * y + 288, t, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 288, t, 640, 640, color); // Sequence y += fontGetLineHeight() + 3; @@ -2629,12 +2647,12 @@ void editorRenderSecondaryStats() color = _colorTable[992]; } - messageListItemText = getmsg(&editorMessageList, &editorMessageListItem, 308); + messageListItemText = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 308); sprintf(t, "%s", messageListItemText); - fontDrawText(characterEditorWindowBuf + 640 * y + 194, t, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 194, t, 640, 640, color); compat_itoa(critterGetStat(gDude, STAT_SEQUENCE), t, 10); - fontDrawText(characterEditorWindowBuf + 640 * y + 288, t, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 288, t, 640, 640, color); // Healing Rate y += fontGetLineHeight() + 3; @@ -2645,12 +2663,12 @@ void editorRenderSecondaryStats() color = _colorTable[992]; } - messageListItemText = getmsg(&editorMessageList, &editorMessageListItem, 309); + messageListItemText = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 309); sprintf(t, "%s", messageListItemText); - fontDrawText(characterEditorWindowBuf + 640 * y + 194, t, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 194, t, 640, 640, color); compat_itoa(critterGetStat(gDude, STAT_HEALING_RATE), t, 10); - fontDrawText(characterEditorWindowBuf + 640 * y + 288, t, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 288, t, 640, 640, color); // Critical Chance y += fontGetLineHeight() + 3; @@ -2661,16 +2679,16 @@ void editorRenderSecondaryStats() color = _colorTable[992]; } - messageListItemText = getmsg(&editorMessageList, &editorMessageListItem, 310); + messageListItemText = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 310); sprintf(t, "%s", messageListItemText); - fontDrawText(characterEditorWindowBuf + 640 * y + 194, t, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 194, t, 640, 640, color); sprintf(t, "%d%%", critterGetStat(gDude, STAT_CRITICAL_CHANCE)); - fontDrawText(characterEditorWindowBuf + 640 * y + 288, t, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 288, t, 640, 640, color); } // 0x436154 -void editorRenderSkills(int a1) +void characterEditorDrawSkills(int a1) { int selectedSkill = -1; const char* str; @@ -2685,55 +2703,55 @@ void editorRenderSkills(int a1) } if (gCharacterEditorIsCreationMode == 0 && a1 == 0) { - buttonDestroy(_SliderPlusID); - buttonDestroy(_SliderNegID); - _SliderNegID = -1; - _SliderPlusID = -1; + buttonDestroy(gCharacterEditorSliderPlusBtn); + buttonDestroy(gCharacterEditorSliderMinusBtn); + gCharacterEditorSliderMinusBtn = -1; + gCharacterEditorSliderPlusBtn = -1; } - blitBufferToBuffer(characterEditorWindowBackgroundBuf + 370, 270, 252, 640, characterEditorWindowBuf + 370, 640); + blitBufferToBuffer(gCharacterEditorWindowBackgroundBuffer + 370, 270, 252, 640, gCharacterEditorWindowBuffer + 370, 640); fontSetCurrent(103); // SKILLS - str = getmsg(&editorMessageList, &editorMessageListItem, 117); - fontDrawText(characterEditorWindowBuf + 640 * 5 + 380, str, 640, 640, _colorTable[18979]); + str = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 117); + fontDrawText(gCharacterEditorWindowBuffer + 640 * 5 + 380, str, 640, 640, _colorTable[18979]); if (!gCharacterEditorIsCreationMode) { // SKILL POINTS - str = getmsg(&editorMessageList, &editorMessageListItem, 112); - fontDrawText(characterEditorWindowBuf + 640 * 233 + 400, str, 640, 640, _colorTable[18979]); + str = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 112); + fontDrawText(gCharacterEditorWindowBuffer + 640 * 233 + 400, str, 640, 640, _colorTable[18979]); value = pcGetStat(PC_STAT_UNSPENT_SKILL_POINTS); - characterEditorRenderBigNumber(522, 228, 0, value, 0, characterEditorWindowHandle); + characterEditorDrawBigNumber(522, 228, 0, value, 0, gCharacterEditorWindow); } else { // TAG SKILLS - str = getmsg(&editorMessageList, &editorMessageListItem, 138); - fontDrawText(characterEditorWindowBuf + 640 * 233 + 422, str, 640, 640, _colorTable[18979]); + str = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 138); + fontDrawText(gCharacterEditorWindowBuffer + 640 * 233 + 422, str, 640, 640, _colorTable[18979]); // TODO: Check. - if (a1 == 2 && !_first_skill_list) { - characterEditorRenderBigNumber(522, 228, ANIMATE, _tagskill_count, _old_tags, characterEditorWindowHandle); + if (a1 == 2 && !gCharacterEditorIsSkillsFirstDraw) { + characterEditorDrawBigNumber(522, 228, ANIMATE, gCharacterEditorTaggedSkillCount, gCharacterEditorOldTaggedSkillCount, gCharacterEditorWindow); } else { - characterEditorRenderBigNumber(522, 228, 0, _tagskill_count, 0, characterEditorWindowHandle); - _first_skill_list = 0; + characterEditorDrawBigNumber(522, 228, 0, gCharacterEditorTaggedSkillCount, 0, gCharacterEditorWindow); + gCharacterEditorIsSkillsFirstDraw = 0; } } - skillsSetTagged(_temp_tag_skill, NUM_TAGGED_SKILLS); + skillsSetTagged(gCharacterEditorTempTaggedSkills, NUM_TAGGED_SKILLS); fontSetCurrent(101); y = 27; for (i = 0; i < SKILL_COUNT; i++) { if (i == selectedSkill) { - if (i != _temp_tag_skill[0] && i != _temp_tag_skill[1] && i != _temp_tag_skill[2] && i != _temp_tag_skill[3]) { + if (i != gCharacterEditorTempTaggedSkills[0] && i != gCharacterEditorTempTaggedSkills[1] && i != gCharacterEditorTempTaggedSkills[2] && i != gCharacterEditorTempTaggedSkills[3]) { color = _colorTable[32747]; } else { color = _colorTable[32767]; } } else { - if (i != _temp_tag_skill[0] && i != _temp_tag_skill[1] && i != _temp_tag_skill[2] && i != _temp_tag_skill[3]) { + if (i != gCharacterEditorTempTaggedSkills[0] && i != gCharacterEditorTempTaggedSkills[1] && i != gCharacterEditorTempTaggedSkills[2] && i != gCharacterEditorTempTaggedSkills[3]) { color = _colorTable[992]; } else { color = _colorTable[21140]; @@ -2741,71 +2759,71 @@ void editorRenderSkills(int a1) } str = skillGetName(i); - fontDrawText(characterEditorWindowBuf + 640 * y + 380, str, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 380, str, 640, 640, color); value = skillGetValue(gDude, i); sprintf(valueString, "%d%%", value); // TODO: Check text position. - fontDrawText(characterEditorWindowBuf + 640 * y + 573, valueString, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 573, valueString, 640, 640, color); y += fontGetLineHeight() + 1; } if (!gCharacterEditorIsCreationMode) { - y = _skill_cursor * (fontGetLineHeight() + 1); - _slider_y = y + 27; + y = gCharacterEditorCurrentSkill * (fontGetLineHeight() + 1); + gCharacterEditorSkillValueAdjustmentSliderY = y + 27; blitBufferToBufferTrans( - _grphbmp[EDITOR_GRAPHIC_SLIDER], - _GInfo[EDITOR_GRAPHIC_SLIDER].width, - _GInfo[EDITOR_GRAPHIC_SLIDER].height, - _GInfo[EDITOR_GRAPHIC_SLIDER].width, - characterEditorWindowBuf + 640 * (y + 16) + 592, + gCharacterEditorFrmData[EDITOR_GRAPHIC_SLIDER], + gCharacterEditorFrmSize[EDITOR_GRAPHIC_SLIDER].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_SLIDER].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_SLIDER].width, + gCharacterEditorWindowBuffer + 640 * (y + 16) + 592, 640); if (a1 == 0) { - if (_SliderPlusID == -1) { - _SliderPlusID = buttonCreate( - characterEditorWindowHandle, + if (gCharacterEditorSliderPlusBtn == -1) { + gCharacterEditorSliderPlusBtn = buttonCreate( + gCharacterEditorWindow, 614, - _slider_y - 7, - _GInfo[EDITOR_GRAPHIC_SLIDER_PLUS_ON].width, - _GInfo[EDITOR_GRAPHIC_SLIDER_PLUS_ON].height, + gCharacterEditorSkillValueAdjustmentSliderY - 7, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_SLIDER_PLUS_ON].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_SLIDER_PLUS_ON].height, -1, 522, 521, 522, - _grphbmp[EDITOR_GRAPHIC_SLIDER_PLUS_OFF], - _grphbmp[EDITOR_GRAPHIC_SLIDER_PLUS_ON], + gCharacterEditorFrmData[EDITOR_GRAPHIC_SLIDER_PLUS_OFF], + gCharacterEditorFrmData[EDITOR_GRAPHIC_SLIDER_PLUS_ON], NULL, 96); - buttonSetCallbacks(_SliderPlusID, _gsound_red_butt_press, NULL); + buttonSetCallbacks(gCharacterEditorSliderPlusBtn, _gsound_red_butt_press, NULL); } - if (_SliderNegID == -1) { - _SliderNegID = buttonCreate( - characterEditorWindowHandle, + if (gCharacterEditorSliderMinusBtn == -1) { + gCharacterEditorSliderMinusBtn = buttonCreate( + gCharacterEditorWindow, 614, - _slider_y + 4 - 12 + _GInfo[EDITOR_GRAPHIC_SLIDER_MINUS_ON].height, - _GInfo[EDITOR_GRAPHIC_SLIDER_MINUS_ON].width, - _GInfo[EDITOR_GRAPHIC_SLIDER_MINUS_OFF].height, + gCharacterEditorSkillValueAdjustmentSliderY + 4 - 12 + gCharacterEditorFrmSize[EDITOR_GRAPHIC_SLIDER_MINUS_ON].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_SLIDER_MINUS_ON].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_SLIDER_MINUS_OFF].height, -1, 524, 523, 524, - _grphbmp[EDITOR_GRAPHIC_SLIDER_MINUS_OFF], - _grphbmp[EDITOR_GRAPHIC_SLIDER_MINUS_ON], + gCharacterEditorFrmData[EDITOR_GRAPHIC_SLIDER_MINUS_OFF], + gCharacterEditorFrmData[EDITOR_GRAPHIC_SLIDER_MINUS_ON], NULL, 96); - buttonSetCallbacks(_SliderNegID, _gsound_red_butt_press, NULL); + buttonSetCallbacks(gCharacterEditorSliderMinusBtn, _gsound_red_butt_press, NULL); } } } } // 0x4365AC -void editorRenderDetails() +void characterEditorDrawCard() { int graphicId; char* title; @@ -2815,21 +2833,21 @@ void editorRenderDetails() return; } - blitBufferToBuffer(characterEditorWindowBackgroundBuf + (640 * 267) + 345, 277, 170, 640, characterEditorWindowBuf + (267 * 640) + 345, 640); + blitBufferToBuffer(gCharacterEditorWindowBackgroundBuffer + (640 * 267) + 345, 277, 170, 640, gCharacterEditorWindowBuffer + (267 * 640) + 345, 640); if (characterEditorSelectedItem >= 0 && characterEditorSelectedItem < 7) { description = statGetDescription(characterEditorSelectedItem); title = statGetName(characterEditorSelectedItem); graphicId = statGetFrmId(characterEditorSelectedItem); - _DrawCard(graphicId, title, NULL, description); + characterEditorDrawCardWithOptions(graphicId, title, NULL, description); } else if (characterEditorSelectedItem >= 7 && characterEditorSelectedItem < 10) { if (gCharacterEditorIsCreationMode) { switch (characterEditorSelectedItem) { case 7: // Character Points - description = getmsg(&editorMessageList, &editorMessageListItem, 121); - title = getmsg(&editorMessageList, &editorMessageListItem, 120); - _DrawCard(7, title, NULL, description); + description = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 121); + title = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 120); + characterEditorDrawCardWithOptions(7, title, NULL, description); break; } } else { @@ -2837,113 +2855,113 @@ void editorRenderDetails() case 7: description = pcStatGetDescription(PC_STAT_LEVEL); title = pcStatGetName(PC_STAT_LEVEL); - _DrawCard(7, title, NULL, description); + characterEditorDrawCardWithOptions(7, title, NULL, description); break; case 8: description = pcStatGetDescription(PC_STAT_EXPERIENCE); title = pcStatGetName(PC_STAT_EXPERIENCE); - _DrawCard(8, title, NULL, description); + characterEditorDrawCardWithOptions(8, title, NULL, description); break; case 9: // Next Level - description = getmsg(&editorMessageList, &editorMessageListItem, 123); - title = getmsg(&editorMessageList, &editorMessageListItem, 122); - _DrawCard(9, title, NULL, description); + description = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 123); + title = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 122); + characterEditorDrawCardWithOptions(9, title, NULL, description); break; } } } else if ((characterEditorSelectedItem >= 10 && characterEditorSelectedItem < 43) || (characterEditorSelectedItem >= 82 && characterEditorSelectedItem < 98)) { - _DrawCard(_folder_card_fid, _folder_card_title, _folder_card_title2, _folder_card_desc); + characterEditorDrawCardWithOptions(gCharacterEditorFolderCardFrmId, gCharacterEditorFolderCardTitle, gCharacterEditorFolderCardSubtitle, gCharacterEditorFolderCardDescription); } else if (characterEditorSelectedItem >= 43 && characterEditorSelectedItem < 51) { switch (characterEditorSelectedItem) { case EDITOR_HIT_POINTS: description = statGetDescription(STAT_MAXIMUM_HIT_POINTS); - title = getmsg(&editorMessageList, &editorMessageListItem, 300); + title = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 300); graphicId = statGetFrmId(STAT_MAXIMUM_HIT_POINTS); - _DrawCard(graphicId, title, NULL, description); + characterEditorDrawCardWithOptions(graphicId, title, NULL, description); break; case EDITOR_POISONED: - description = getmsg(&editorMessageList, &editorMessageListItem, 400); - title = getmsg(&editorMessageList, &editorMessageListItem, 312); - _DrawCard(11, title, NULL, description); + description = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 400); + title = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 312); + characterEditorDrawCardWithOptions(11, title, NULL, description); break; case EDITOR_RADIATED: - description = getmsg(&editorMessageList, &editorMessageListItem, 401); - title = getmsg(&editorMessageList, &editorMessageListItem, 313); - _DrawCard(12, title, NULL, description); + description = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 401); + title = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 313); + characterEditorDrawCardWithOptions(12, title, NULL, description); break; case EDITOR_EYE_DAMAGE: - description = getmsg(&editorMessageList, &editorMessageListItem, 402); - title = getmsg(&editorMessageList, &editorMessageListItem, 314); - _DrawCard(13, title, NULL, description); + description = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 402); + title = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 314); + characterEditorDrawCardWithOptions(13, title, NULL, description); break; case EDITOR_CRIPPLED_RIGHT_ARM: - description = getmsg(&editorMessageList, &editorMessageListItem, 403); - title = getmsg(&editorMessageList, &editorMessageListItem, 315); - _DrawCard(14, title, NULL, description); + description = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 403); + title = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 315); + characterEditorDrawCardWithOptions(14, title, NULL, description); break; case EDITOR_CRIPPLED_LEFT_ARM: - description = getmsg(&editorMessageList, &editorMessageListItem, 404); - title = getmsg(&editorMessageList, &editorMessageListItem, 316); - _DrawCard(15, title, NULL, description); + description = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 404); + title = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 316); + characterEditorDrawCardWithOptions(15, title, NULL, description); break; case EDITOR_CRIPPLED_RIGHT_LEG: - description = getmsg(&editorMessageList, &editorMessageListItem, 405); - title = getmsg(&editorMessageList, &editorMessageListItem, 317); - _DrawCard(16, title, NULL, description); + description = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 405); + title = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 317); + characterEditorDrawCardWithOptions(16, title, NULL, description); break; case EDITOR_CRIPPLED_LEFT_LEG: - description = getmsg(&editorMessageList, &editorMessageListItem, 406); - title = getmsg(&editorMessageList, &editorMessageListItem, 318); - _DrawCard(17, title, NULL, description); + description = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 406); + title = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 318); + characterEditorDrawCardWithOptions(17, title, NULL, description); break; } } else if (characterEditorSelectedItem >= EDITOR_FIRST_DERIVED_STAT && characterEditorSelectedItem < 61) { int derivedStatIndex = characterEditorSelectedItem - 51; - int stat = word_431D6C[derivedStatIndex]; + int stat = gCharacterEditorDerivedStatsMap[derivedStatIndex]; description = statGetDescription(stat); title = statGetName(stat); - graphicId = word_431D3A[derivedStatIndex]; - _DrawCard(graphicId, title, NULL, description); + graphicId = gCharacterEditorDerivedStatFrmIds[derivedStatIndex]; + characterEditorDrawCardWithOptions(graphicId, title, NULL, description); } else if (characterEditorSelectedItem >= EDITOR_FIRST_SKILL && characterEditorSelectedItem < 79) { int skill = characterEditorSelectedItem - 61; const char* attributesDescription = skillGetAttributes(skill); char formatted[150]; // TODO: Size is probably wrong. - const char* base = getmsg(&editorMessageList, &editorMessageListItem, 137); + const char* base = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 137); int defaultValue = skillGetDefaultValue(skill); sprintf(formatted, "%s %d%% %s", base, defaultValue, attributesDescription); graphicId = skillGetFrmId(skill); title = skillGetName(skill); description = skillGetDescription(skill); - _DrawCard(graphicId, title, formatted, description); + characterEditorDrawCardWithOptions(graphicId, title, formatted, description); } else if (characterEditorSelectedItem >= 79 && characterEditorSelectedItem < 82) { switch (characterEditorSelectedItem) { case EDITOR_TAG_SKILL: if (gCharacterEditorIsCreationMode) { // Tag Skill - description = getmsg(&editorMessageList, &editorMessageListItem, 145); - title = getmsg(&editorMessageList, &editorMessageListItem, 144); - _DrawCard(27, title, NULL, description); + description = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 145); + title = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 144); + characterEditorDrawCardWithOptions(27, title, NULL, description); } else { // Skill Points - description = getmsg(&editorMessageList, &editorMessageListItem, 131); - title = getmsg(&editorMessageList, &editorMessageListItem, 130); - _DrawCard(27, title, NULL, description); + description = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 131); + title = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 130); + characterEditorDrawCardWithOptions(27, title, NULL, description); } break; case EDITOR_SKILLS: // Skills - description = getmsg(&editorMessageList, &editorMessageListItem, 151); - title = getmsg(&editorMessageList, &editorMessageListItem, 150); - _DrawCard(27, title, NULL, description); + description = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 151); + title = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 150); + characterEditorDrawCardWithOptions(27, title, NULL, description); break; case EDITOR_OPTIONAL_TRAITS: // Optional Traits - description = getmsg(&editorMessageList, &editorMessageListItem, 147); - title = getmsg(&editorMessageList, &editorMessageListItem, 146); - _DrawCard(27, title, NULL, description); + description = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 147); + title = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 146); + characterEditorDrawCardWithOptions(27, title, NULL, description); break; } } @@ -2954,8 +2972,8 @@ int characterEditorEditName() { char* text; - int windowWidth = _GInfo[EDITOR_GRAPHIC_CHARWIN].width; - int windowHeight = _GInfo[EDITOR_GRAPHIC_CHARWIN].height; + int windowWidth = gCharacterEditorFrmSize[EDITOR_GRAPHIC_CHARWIN].width; + int windowHeight = gCharacterEditorFrmSize[EDITOR_GRAPHIC_CHARWIN].height; int nameWindowX = (screenGetWidth() - EDITOR_WINDOW_WIDTH) / 2 + 17; int nameWindowY = (screenGetHeight() - EDITOR_WINDOW_HEIGHT) / 2; @@ -2967,38 +2985,38 @@ int characterEditorEditName() unsigned char* windowBuf = windowGetBuffer(win); // Copy background - memcpy(windowBuf, _grphbmp[EDITOR_GRAPHIC_CHARWIN], windowWidth * windowHeight); + memcpy(windowBuf, gCharacterEditorFrmData[EDITOR_GRAPHIC_CHARWIN], windowWidth * windowHeight); blitBufferToBufferTrans( - _grphbmp[EDITOR_GRAPHIC_NAME_BOX], - _GInfo[EDITOR_GRAPHIC_NAME_BOX].width, - _GInfo[EDITOR_GRAPHIC_NAME_BOX].height, - _GInfo[EDITOR_GRAPHIC_NAME_BOX].width, + gCharacterEditorFrmData[EDITOR_GRAPHIC_NAME_BOX], + gCharacterEditorFrmSize[EDITOR_GRAPHIC_NAME_BOX].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_NAME_BOX].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_NAME_BOX].width, windowBuf + windowWidth * 13 + 13, windowWidth); - blitBufferToBufferTrans(_grphbmp[EDITOR_GRAPHIC_DONE_BOX], - _GInfo[EDITOR_GRAPHIC_DONE_BOX].width, - _GInfo[EDITOR_GRAPHIC_DONE_BOX].height, - _GInfo[EDITOR_GRAPHIC_DONE_BOX].width, + blitBufferToBufferTrans(gCharacterEditorFrmData[EDITOR_GRAPHIC_DONE_BOX], + gCharacterEditorFrmSize[EDITOR_GRAPHIC_DONE_BOX].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_DONE_BOX].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_DONE_BOX].width, windowBuf + windowWidth * 40 + 13, windowWidth); fontSetCurrent(103); - text = getmsg(&editorMessageList, &editorMessageListItem, 100); + text = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 100); fontDrawText(windowBuf + windowWidth * 44 + 50, text, windowWidth, windowWidth, _colorTable[18979]); int doneBtn = buttonCreate(win, 26, 44, - _GInfo[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP].width, - _GInfo[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP].height, -1, -1, -1, 500, - _grphbmp[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP], - _grphbmp[EDITOR_GRAPHIC_LILTTLE_RED_BUTTON_DOWN], + gCharacterEditorFrmData[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP], + gCharacterEditorFrmData[EDITOR_GRAPHIC_LILTTLE_RED_BUTTON_DOWN], NULL, BUTTON_FLAG_TRANSPARENT); if (doneBtn != -1) { @@ -3024,7 +3042,7 @@ int characterEditorEditName() if (_get_input_str(win, 500, nameCopy, 11, 23, 19, _colorTable[992], 100, 0) != -1) { if (nameCopy[0] != '\0') { dudeSetName(nameCopy); - editorRenderName(); + characterEditorDrawName(); windowDestroy(win); return 0; } @@ -3033,14 +3051,14 @@ int characterEditorEditName() // NOTE: original code is a bit different, the following chunk of code written two times. fontSetCurrent(101); - blitBufferToBuffer(_grphbmp[EDITOR_GRAPHIC_NAME_BOX], - _GInfo[EDITOR_GRAPHIC_NAME_BOX].width, - _GInfo[EDITOR_GRAPHIC_NAME_BOX].height, - _GInfo[EDITOR_GRAPHIC_NAME_BOX].width, - windowBuf + _GInfo[EDITOR_GRAPHIC_CHARWIN].width * 13 + 13, - _GInfo[EDITOR_GRAPHIC_CHARWIN].width); + blitBufferToBuffer(gCharacterEditorFrmData[EDITOR_GRAPHIC_NAME_BOX], + gCharacterEditorFrmSize[EDITOR_GRAPHIC_NAME_BOX].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_NAME_BOX].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_NAME_BOX].width, + windowBuf + gCharacterEditorFrmSize[EDITOR_GRAPHIC_CHARWIN].width * 13 + 13, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_CHARWIN].width); - _PrintName(windowBuf, _GInfo[EDITOR_GRAPHIC_CHARWIN].width); + _PrintName(windowBuf, gCharacterEditorFrmSize[EDITOR_GRAPHIC_CHARWIN].width); strcpy(nameCopy, name); @@ -3050,7 +3068,7 @@ int characterEditorEditName() } // 0x436F70 -void _PrintName(unsigned char* buf, int a2) +void _PrintName(unsigned char* buf, int pitch) { char str[64]; char* v4; @@ -3064,11 +3082,11 @@ void _PrintName(unsigned char* buf, int a2) // TODO: Check. strcpy(str, v4); - fontDrawText(buf + 19 * a2 + 21, str, a2, a2, _colorTable[992]); + fontDrawText(buf + 19 * pitch + 21, str, pitch, pitch, _colorTable[992]); } // 0x436FEC -int characterEditorRunEditAgeDialog() +int characterEditorEditAge() { int win; unsigned char* windowBuf; @@ -3086,10 +3104,10 @@ int characterEditorRunEditAgeDialog() int savedAge = critterGetStat(gDude, STAT_AGE); - windowWidth = _GInfo[EDITOR_GRAPHIC_CHARWIN].width; - windowHeight = _GInfo[EDITOR_GRAPHIC_CHARWIN].height; + windowWidth = gCharacterEditorFrmSize[EDITOR_GRAPHIC_CHARWIN].width; + windowHeight = gCharacterEditorFrmSize[EDITOR_GRAPHIC_CHARWIN].height; - int ageWindowX = (screenGetWidth() - EDITOR_WINDOW_WIDTH) / 2 + _GInfo[EDITOR_GRAPHIC_NAME_ON].width + 9; + int ageWindowX = (screenGetWidth() - EDITOR_WINDOW_WIDTH) / 2 + gCharacterEditorFrmSize[EDITOR_GRAPHIC_NAME_ON].width + 9; int ageWindowY = (screenGetHeight() - EDITOR_WINDOW_HEIGHT) / 2; win = windowCreate(ageWindowX, ageWindowY, windowWidth, windowHeight, 256, WINDOW_FLAG_0x10 | WINDOW_FLAG_0x02); if (win == -1) { @@ -3098,42 +3116,42 @@ int characterEditorRunEditAgeDialog() windowBuf = windowGetBuffer(win); - memcpy(windowBuf, _grphbmp[EDITOR_GRAPHIC_CHARWIN], windowWidth * windowHeight); + memcpy(windowBuf, gCharacterEditorFrmData[EDITOR_GRAPHIC_CHARWIN], windowWidth * windowHeight); blitBufferToBufferTrans( - _grphbmp[EDITOR_GRAPHIC_AGE_BOX], - _GInfo[EDITOR_GRAPHIC_AGE_BOX].width, - _GInfo[EDITOR_GRAPHIC_AGE_BOX].height, - _GInfo[EDITOR_GRAPHIC_AGE_BOX].width, + gCharacterEditorFrmData[EDITOR_GRAPHIC_AGE_BOX], + gCharacterEditorFrmSize[EDITOR_GRAPHIC_AGE_BOX].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_AGE_BOX].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_AGE_BOX].width, windowBuf + windowWidth * 7 + 8, windowWidth); blitBufferToBufferTrans( - _grphbmp[EDITOR_GRAPHIC_DONE_BOX], - _GInfo[EDITOR_GRAPHIC_DONE_BOX].width, - _GInfo[EDITOR_GRAPHIC_DONE_BOX].height, - _GInfo[EDITOR_GRAPHIC_DONE_BOX].width, + gCharacterEditorFrmData[EDITOR_GRAPHIC_DONE_BOX], + gCharacterEditorFrmSize[EDITOR_GRAPHIC_DONE_BOX].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_DONE_BOX].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_DONE_BOX].width, windowBuf + windowWidth * 40 + 13, - _GInfo[EDITOR_GRAPHIC_CHARWIN].width); + gCharacterEditorFrmSize[EDITOR_GRAPHIC_CHARWIN].width); fontSetCurrent(103); - messageListItemText = getmsg(&editorMessageList, &editorMessageListItem, 100); + messageListItemText = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 100); fontDrawText(windowBuf + windowWidth * 44 + 50, messageListItemText, windowWidth, windowWidth, _colorTable[18979]); age = critterGetStat(gDude, STAT_AGE); - characterEditorRenderBigNumber(55, 10, 0, age, 0, win); + characterEditorDrawBigNumber(55, 10, 0, age, 0, win); doneBtn = buttonCreate(win, 26, 44, - _GInfo[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP].width, - _GInfo[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP].height, -1, -1, -1, 500, - _grphbmp[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP], - _grphbmp[EDITOR_GRAPHIC_LILTTLE_RED_BUTTON_DOWN], + gCharacterEditorFrmData[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP], + gCharacterEditorFrmData[EDITOR_GRAPHIC_LILTTLE_RED_BUTTON_DOWN], NULL, BUTTON_FLAG_TRANSPARENT); if (doneBtn != -1) { @@ -3143,14 +3161,14 @@ int characterEditorRunEditAgeDialog() nextBtn = buttonCreate(win, 105, 13, - _GInfo[EDITOR_GRAPHIC_LEFT_ARROW_DOWN].width, - _GInfo[EDITOR_GRAPHIC_LEFT_ARROW_DOWN].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_LEFT_ARROW_DOWN].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_LEFT_ARROW_DOWN].height, -1, 503, 501, 503, - _grphbmp[EDITOR_GRAPHIC_RIGHT_ARROW_UP], - _grphbmp[EDITOR_GRAPHIC_RIGHT_ARROW_DOWN], + gCharacterEditorFrmData[EDITOR_GRAPHIC_RIGHT_ARROW_UP], + gCharacterEditorFrmData[EDITOR_GRAPHIC_RIGHT_ARROW_DOWN], NULL, BUTTON_FLAG_TRANSPARENT); if (nextBtn != -1) { @@ -3160,14 +3178,14 @@ int characterEditorRunEditAgeDialog() prevBtn = buttonCreate(win, 19, 13, - _GInfo[EDITOR_GRAPHIC_RIGHT_ARROW_DOWN].width, - _GInfo[EDITOR_GRAPHIC_RIGHT_ARROW_DOWN].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_RIGHT_ARROW_DOWN].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_RIGHT_ARROW_DOWN].height, -1, 504, 502, 504, - _grphbmp[EDITOR_GRAPHIC_LEFT_ARROW_UP], - _grphbmp[EDITOR_GRAPHIC_LEFT_ARROW_DOWN], + gCharacterEditorFrmData[EDITOR_GRAPHIC_LEFT_ARROW_UP], + gCharacterEditorFrmData[EDITOR_GRAPHIC_LEFT_ARROW_DOWN], NULL, BUTTON_FLAG_TRANSPARENT); if (prevBtn != -1) { @@ -3209,7 +3227,7 @@ int characterEditorRunEditAgeDialog() flags = 0; } age = critterGetStat(gDude, STAT_AGE); - characterEditorRenderBigNumber(55, 10, flags, age, previousAge, win); + characterEditorDrawBigNumber(55, 10, flags, age, previousAge, win); } } else if (keyCode == KEY_MINUS || keyCode == KEY_UPPERCASE_J || keyCode == KEY_ARROW_DOWN) { previousAge = critterGetStat(gDude, STAT_AGE); @@ -3220,15 +3238,15 @@ int characterEditorRunEditAgeDialog() } age = critterGetStat(gDude, STAT_AGE); - characterEditorRenderBigNumber(55, 10, flags, age, previousAge, win); + characterEditorDrawBigNumber(55, 10, flags, age, previousAge, win); } } if (flags == ANIMATE) { - editorRenderAge(); - editorRenderPrimaryStat(RENDER_ALL_STATS, 0, 0); - editorRenderSecondaryStats(); - windowRefresh(characterEditorWindowHandle); + characterEditorDrawAge(); + characterEditorDrawPrimaryStat(RENDER_ALL_STATS, 0, 0); + characterEditorDrawDerivedStats(); + windowRefresh(gCharacterEditorWindow); windowRefresh(win); } @@ -3270,12 +3288,12 @@ int characterEditorRunEditAgeDialog() } age = critterGetStat(gDude, STAT_AGE); - characterEditorRenderBigNumber(55, 10, flags, age, previousAge, win); + characterEditorDrawBigNumber(55, 10, flags, age, previousAge, win); if (flags == ANIMATE) { - editorRenderAge(); - editorRenderPrimaryStat(RENDER_ALL_STATS, 0, 0); - editorRenderSecondaryStats(); - windowRefresh(characterEditorWindowHandle); + characterEditorDrawAge(); + characterEditorDrawPrimaryStat(RENDER_ALL_STATS, 0, 0); + characterEditorDrawDerivedStats(); + windowRefresh(gCharacterEditorWindow); windowRefresh(win); } } @@ -3302,10 +3320,10 @@ int characterEditorRunEditAgeDialog() } critterSetBaseStat(gDude, STAT_AGE, savedAge); - editorRenderAge(); - editorRenderPrimaryStat(RENDER_ALL_STATS, 0, 0); - editorRenderSecondaryStats(); - windowRefresh(characterEditorWindowHandle); + characterEditorDrawAge(); + characterEditorDrawPrimaryStat(RENDER_ALL_STATS, 0, 0); + characterEditorDrawDerivedStats(); + windowRefresh(gCharacterEditorWindow); windowRefresh(win); windowDestroy(win); return 0; @@ -3316,12 +3334,12 @@ void characterEditorEditGender() { char* text; - int windowWidth = _GInfo[EDITOR_GRAPHIC_CHARWIN].width; - int windowHeight = _GInfo[EDITOR_GRAPHIC_CHARWIN].height; + int windowWidth = gCharacterEditorFrmSize[EDITOR_GRAPHIC_CHARWIN].width; + int windowHeight = gCharacterEditorFrmSize[EDITOR_GRAPHIC_CHARWIN].height; int genderWindowX = (screenGetWidth() - EDITOR_WINDOW_WIDTH) / 2 + 9 - + _GInfo[EDITOR_GRAPHIC_NAME_ON].width - + _GInfo[EDITOR_GRAPHIC_AGE_ON].width; + + gCharacterEditorFrmSize[EDITOR_GRAPHIC_NAME_ON].width + + gCharacterEditorFrmSize[EDITOR_GRAPHIC_AGE_ON].width; int genderWindowY = (screenGetHeight() - EDITOR_WINDOW_HEIGHT) / 2; int win = windowCreate(genderWindowX, genderWindowY, windowWidth, windowHeight, 256, WINDOW_FLAG_0x10 | WINDOW_FLAG_0x02); @@ -3332,31 +3350,31 @@ void characterEditorEditGender() unsigned char* windowBuf = windowGetBuffer(win); // Copy background - memcpy(windowBuf, _grphbmp[EDITOR_GRAPHIC_CHARWIN], windowWidth * windowHeight); + memcpy(windowBuf, gCharacterEditorFrmData[EDITOR_GRAPHIC_CHARWIN], windowWidth * windowHeight); - blitBufferToBufferTrans(_grphbmp[EDITOR_GRAPHIC_DONE_BOX], - _GInfo[EDITOR_GRAPHIC_DONE_BOX].width, - _GInfo[EDITOR_GRAPHIC_DONE_BOX].height, - _GInfo[EDITOR_GRAPHIC_DONE_BOX].width, + blitBufferToBufferTrans(gCharacterEditorFrmData[EDITOR_GRAPHIC_DONE_BOX], + gCharacterEditorFrmSize[EDITOR_GRAPHIC_DONE_BOX].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_DONE_BOX].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_DONE_BOX].width, windowBuf + windowWidth * 44 + 15, windowWidth); fontSetCurrent(103); - text = getmsg(&editorMessageList, &editorMessageListItem, 100); + text = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 100); fontDrawText(windowBuf + windowWidth * 48 + 52, text, windowWidth, windowWidth, _colorTable[18979]); int doneBtn = buttonCreate(win, 28, 48, - _GInfo[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP].width, - _GInfo[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP].height, -1, -1, -1, 500, - _grphbmp[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP], - _grphbmp[EDITOR_GRAPHIC_LILTTLE_RED_BUTTON_DOWN], + gCharacterEditorFrmData[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP], + gCharacterEditorFrmData[EDITOR_GRAPHIC_LILTTLE_RED_BUTTON_DOWN], NULL, BUTTON_FLAG_TRANSPARENT); if (doneBtn != -1) { @@ -3367,14 +3385,14 @@ void characterEditorEditGender() btns[0] = buttonCreate(win, 22, 2, - _GInfo[EDITOR_GRAPHIC_MALE_ON].width, - _GInfo[EDITOR_GRAPHIC_MALE_ON].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_MALE_ON].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_MALE_ON].height, -1, -1, 501, -1, - _grphbmp[EDITOR_GRAPHIC_MALE_OFF], - _grphbmp[EDITOR_GRAPHIC_MALE_ON], + gCharacterEditorFrmData[EDITOR_GRAPHIC_MALE_OFF], + gCharacterEditorFrmData[EDITOR_GRAPHIC_MALE_ON], NULL, BUTTON_FLAG_TRANSPARENT | BUTTON_FLAG_0x04 | BUTTON_FLAG_0x02 | BUTTON_FLAG_0x01); if (btns[0] != -1) { @@ -3384,14 +3402,14 @@ void characterEditorEditGender() btns[1] = buttonCreate(win, 71, 3, - _GInfo[EDITOR_GRAPHIC_FEMALE_ON].width, - _GInfo[EDITOR_GRAPHIC_FEMALE_ON].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_FEMALE_ON].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_FEMALE_ON].height, -1, -1, 502, -1, - _grphbmp[EDITOR_GRAPHIC_FEMALE_OFF], - _grphbmp[EDITOR_GRAPHIC_FEMALE_ON], + gCharacterEditorFrmData[EDITOR_GRAPHIC_FEMALE_OFF], + gCharacterEditorFrmData[EDITOR_GRAPHIC_FEMALE_ON], NULL, BUTTON_FLAG_TRANSPARENT | BUTTON_FLAG_0x04 | BUTTON_FLAG_0x02 | BUTTON_FLAG_0x01); if (btns[1] != -1) { @@ -3416,9 +3434,9 @@ void characterEditorEditGender() if (eventCode == KEY_ESCAPE || _game_user_wants_to_quit != 0) { critterSetBaseStat(gDude, STAT_GENDER, savedGender); - editorRenderPrimaryStat(RENDER_ALL_STATS, 0, 0); - editorRenderSecondaryStats(); - windowRefresh(characterEditorWindowHandle); + characterEditorDrawPrimaryStat(RENDER_ALL_STATS, 0, 0); + characterEditorDrawDerivedStats(); + windowRefresh(gCharacterEditorWindow); break; } @@ -3435,8 +3453,8 @@ void characterEditorEditGender() case 502: // TODO: Original code is slightly different. critterSetBaseStat(gDude, STAT_GENDER, eventCode - 501); - editorRenderPrimaryStat(RENDER_ALL_STATS, 0, 0); - editorRenderSecondaryStats(); + characterEditorDrawPrimaryStat(RENDER_ALL_STATS, 0, 0); + characterEditorDrawDerivedStats(); break; } @@ -3446,16 +3464,16 @@ void characterEditorEditGender() ; } - editorRenderGender(); + characterEditorDrawGender(); windowDestroy(win); } // 0x4379BC -void characterEditorHandleIncDecPrimaryStat(int eventCode) +void characterEditorAdjustPrimaryStat(int eventCode) { _repFtime = 4; - int savedRemainingCharacterPoints = characterEditorRemainingCharacterPoints; + int savedRemainingCharacterPoints = gCharacterEditorRemainingCharacterPoints; if (!gCharacterEditorIsCreationMode) { return; @@ -3484,35 +3502,35 @@ void characterEditorHandleIncDecPrimaryStat(int eventCode) if (eventCode >= 510) { int previousValue = critterGetStat(gDude, decrementingStat); if (critterDecBaseStat(gDude, decrementingStat) == 0) { - characterEditorRemainingCharacterPoints++; + gCharacterEditorRemainingCharacterPoints++; } else { cont = false; } - editorRenderPrimaryStat(decrementingStat, cont ? ANIMATE : 0, previousValue); - characterEditorRenderBigNumber(126, 282, cont ? ANIMATE : 0, characterEditorRemainingCharacterPoints, savedRemainingCharacterPoints, characterEditorWindowHandle); + characterEditorDrawPrimaryStat(decrementingStat, cont ? ANIMATE : 0, previousValue); + characterEditorDrawBigNumber(126, 282, cont ? ANIMATE : 0, gCharacterEditorRemainingCharacterPoints, savedRemainingCharacterPoints, gCharacterEditorWindow); critterUpdateDerivedStats(gDude); - editorRenderSecondaryStats(); - editorRenderSkills(0); + characterEditorDrawDerivedStats(); + characterEditorDrawSkills(0); characterEditorSelectedItem = decrementingStat; } else { int previousValue = critterGetBaseStatWithTraitModifier(gDude, incrementingStat); previousValue += critterGetBonusStat(gDude, incrementingStat); - if (characterEditorRemainingCharacterPoints > 0 && previousValue < 10 && critterIncBaseStat(gDude, incrementingStat) == 0) { - characterEditorRemainingCharacterPoints--; + if (gCharacterEditorRemainingCharacterPoints > 0 && previousValue < 10 && critterIncBaseStat(gDude, incrementingStat) == 0) { + gCharacterEditorRemainingCharacterPoints--; } else { cont = false; } - editorRenderPrimaryStat(incrementingStat, cont ? ANIMATE : 0, previousValue); - characterEditorRenderBigNumber(126, 282, cont ? ANIMATE : 0, characterEditorRemainingCharacterPoints, savedRemainingCharacterPoints, characterEditorWindowHandle); + characterEditorDrawPrimaryStat(incrementingStat, cont ? ANIMATE : 0, previousValue); + characterEditorDrawBigNumber(126, 282, cont ? ANIMATE : 0, gCharacterEditorRemainingCharacterPoints, savedRemainingCharacterPoints, gCharacterEditorWindow); critterUpdateDerivedStats(gDude); - editorRenderSecondaryStats(); - editorRenderSkills(0); + characterEditorDrawDerivedStats(); + characterEditorDrawSkills(0); characterEditorSelectedItem = incrementingStat; } - windowRefresh(characterEditorWindowHandle); + windowRefresh(gCharacterEditorWindow); } if (v11 >= 19.2) { @@ -3525,25 +3543,48 @@ void characterEditorHandleIncDecPrimaryStat(int eventCode) } } while (_get_input() != 518 && cont); - editorRenderDetails(); + characterEditorDrawCard(); } // handle options dialog // // 0x437C08 -int _OptionWindow() +int characterEditorShowOptions() { - int width = _GInfo[43].width; - int height = _GInfo[43].height; + int width = gCharacterEditorFrmSize[43].width; + int height = gCharacterEditorFrmSize[43].height; + + // NOTE: The following is a block of general purpose string buffers used in + // this function. They are either store path, or strings from .msg files. I + // don't know if such usage was intentional in the original code or it's a + // result of some kind of compiler optimization. + char string1[512]; + char string2[512]; + char string3[512]; + char string4[512]; + char string5[512]; + + // Only two of the these blocks are used as a dialog body. Depending on the + // dialog either 1 or 2 strings used from this array. + const char* dialogBody[2] = { + string5, + string2, + }; if (gCharacterEditorIsCreationMode) { - int win = windowCreate(238, 90, _GInfo[41].width, _GInfo[41].height, 256, WINDOW_FLAG_0x10 | WINDOW_FLAG_0x02); + int optionsWindowX = (screenGetWidth() != 640) + ? (screenGetWidth() - gCharacterEditorFrmSize[41].width) / 2 + : 238; + int optionsWindowY = (screenGetHeight() != 480) + ? (screenGetHeight() - gCharacterEditorFrmSize[41].height) / 2 + : 90; + int win = windowCreate(optionsWindowX, optionsWindowY, gCharacterEditorFrmSize[41].width, gCharacterEditorFrmSize[41].height, 256, WINDOW_FLAG_0x10 | WINDOW_FLAG_0x02); if (win == -1) { return -1; } unsigned char* windowBuffer = windowGetBuffer(win); - memcpy(windowBuffer, _grphbmp[41], _GInfo[41].width * _GInfo[41].height); + memcpy(windowBuffer, gCharacterEditorFrmData[41], gCharacterEditorFrmSize[41].width * gCharacterEditorFrmSize[41].height); fontSetCurrent(103); @@ -3572,18 +3613,14 @@ int _OptionWindow() break; } - memcpy(down[index], _grphbmp[43], size); - memcpy(up[index], _grphbmp[42], size); + memcpy(down[index], gCharacterEditorFrmData[43], size); + memcpy(up[index], gCharacterEditorFrmData[42], size); - const char* msg = getmsg(&editorMessageList, &editorMessageListItem, 600 + index); + strcpy(string4, getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 600 + index)); - char dest[512]; - strcpy(dest, msg); - - int length = fontGetStringWidth(dest); - int v60 = width / 2 - length / 2; - fontDrawText(up[index] + v60, dest, width, width, _colorTable[18979]); - fontDrawText(down[index] + v60, dest, width, width, _colorTable[14723]); + int offset = width * 7 + width / 2 - fontGetStringWidth(string4) / 2; + fontDrawText(up[index] + offset, string4, width, width, _colorTable[18979]); + fontDrawText(down[index] + offset, string4, width, width, _colorTable[14723]); int btn = buttonCreate(win, 13, y, width, height, -1, -1, -1, 500 + index, up[index], down[index], NULL, BUTTON_FLAG_TRANSPARENT); if (btn != -1) { @@ -3610,7 +3647,7 @@ int _OptionWindow() fontSetCurrent(101); int rc = 0; - while (rc != 0) { + while (rc == 0) { int keyCode = _get_input(); if (_game_user_wants_to_quit != 0) { @@ -3625,84 +3662,74 @@ int _OptionWindow() rc = 2; } else if (keyCode == 503 || keyCode == KEY_UPPERCASE_E || keyCode == KEY_LOWERCASE_E) { // ERASE - char line1[512]; - strcpy(line1, getmsg(&editorMessageList, &editorMessageListItem, 605)); + strcpy(string5, getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 605)); + strcpy(string2, getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 606)); - char line2[512]; - strcpy(line2, getmsg(&editorMessageList, &editorMessageListItem, 606)); - - const char* lines[] = { line1, line2 }; - if (showDialogBox(NULL, lines, 2, 169, 126, _colorTable[992], NULL, _colorTable[992], 0x10) != 0) { + if (showDialogBox(NULL, dialogBody, 2, 169, 126, _colorTable[992], NULL, _colorTable[992], DIALOG_BOX_YES_NO) != 0) { _ResetPlayer(); - skillsGetTagged(_temp_tag_skill, NUM_TAGGED_SKILLS); + skillsGetTagged(gCharacterEditorTempTaggedSkills, NUM_TAGGED_SKILLS); - int v224 = 3; - int v225 = 0; - do { - if (_temp_tag_skill[v224] != -1) { + int taggedSkillCount = 0; + for (int index = 3; index >= 0; index--) { + if (gCharacterEditorTempTaggedSkills[index] != -1) { break; } - --v224; - ++v225; - } while (v224 > -1); - - if (gCharacterEditorIsCreationMode) { - v225--; + taggedSkillCount++; } - _tagskill_count = v225; + if (gCharacterEditorIsCreationMode) { + taggedSkillCount--; + } - traitsGetSelected(&_temp_trait[0], &_temp_trait[1]); + gCharacterEditorTaggedSkillCount = taggedSkillCount; - int v226 = 1; - int v227 = 0; - do { - if (_temp_trait[v226] != -1) { + traitsGetSelected(&gCharacterEditorTempTraits[0], &gCharacterEditorTempTraits[1]); + + int traitCount = 0; + for (int index = 1; index >= 0; index--) { + if (gCharacterEditorTempTraits[index] != -1) { break; } - --v226; - ++v227; - } while (v226 > -1); + traitCount++; + } - _trait_count = v227; + gCharacterEditorTempTraitCount = traitCount; critterUpdateDerivedStats(gDude); - _ResetScreen(); + characterEditorResetScreen(); } } else if (keyCode == 502 || keyCode == KEY_UPPERCASE_P || keyCode == KEY_LOWERCASE_P) { // PRINT TO FILE - char dest[512]; - dest[0] = '\0'; + string4[0] = '\0'; - strcat(dest, "*.TXT"); + strcat(string4, "*."); + strcat(string4, "TXT"); char** fileList; - int fileListLength = fileNameListInit(dest, &fileList, 0, 0); + int fileListLength = fileNameListInit(string4, &fileList, 0, 0); if (fileListLength != -1) { - char v236[512]; - // PRINT - strcpy(v236, getmsg(&editorMessageList, &editorMessageListItem, 616)); + strcpy(string1, getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 616)); // PRINT TO FILE - strcpy(dest, getmsg(&editorMessageList, &editorMessageListItem, 602)); + strcpy(string4, getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 602)); - if (_save_file_dialog(dest, fileList, v236, fileListLength, 168, 80, 0) == 0) { - strcat(v236, ".TXT"); + if (showSaveFileDialog(string4, fileList, string1, fileListLength, 168, 80, 0) == 0) { + strcat(string1, "."); + strcat(string1, "TXT"); - dest[0] = '\0'; + string4[0] = '\0'; + strcat(string4, string1); - if (!characterFileExists(dest)) { + if (!characterFileExists(string4)) { // already exists - sprintf(dest, + sprintf(string4, "%s %s", - compat_strupr(v236), - getmsg(&editorMessageList, &editorMessageListItem, 609)); + compat_strupr(string1), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 609)); - char v240[512]; - strcpy(v240, getmsg(&editorMessageList, &editorMessageListItem, 610)); + strcpy(string5, getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 610)); - const char* lines[] = { v240 }; - if (showDialogBox(dest, lines, 1, 169, 126, _colorTable[32328], NULL, _colorTable[32328], 0x10) != 0) { + if (showDialogBox(string4, dialogBody, 1, 169, 126, _colorTable[32328], NULL, _colorTable[32328], 0x10) != 0) { rc = 1; } else { rc = 0; @@ -3712,24 +3739,24 @@ int _OptionWindow() } if (rc != 0) { - dest[0] = '\0'; - strcat(dest, v236); + string4[0] = '\0'; + strcat(string4, string1); - if (characterPrintToFile(dest) == 0) { - sprintf(dest, + if (characterPrintToFile(string4) == 0) { + sprintf(string4, "%s%s", - compat_strupr(v236), - getmsg(&editorMessageList, &editorMessageListItem, 607)); - showDialogBox(dest, NULL, 0, 169, 126, _colorTable[992], NULL, _colorTable[992], 0); + compat_strupr(string1), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 607)); + showDialogBox(string4, NULL, 0, 169, 126, _colorTable[992], NULL, _colorTable[992], 0); } else { soundPlayFile("iisxxxx1"); - sprintf(dest, + sprintf(string4, "%s%s%s", - getmsg(&editorMessageList, &editorMessageListItem, 611), - compat_strupr(v236), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 611), + compat_strupr(string1), "!"); - showDialogBox(dest, NULL, 0, 169, 126, _colorTable[32328], NULL, _colorTable[992], 0x01); + showDialogBox(string4, NULL, 0, 169, 126, _colorTable[32328], NULL, _colorTable[992], 0x01); } } } @@ -3738,33 +3765,173 @@ int _OptionWindow() } else { soundPlayFile("iisxxxx1"); - strcpy(dest, getmsg(&editorMessageList, &editorMessageListItem, 615)); - showDialogBox(dest, NULL, 0, 169, 126, _colorTable[32328], NULL, _colorTable[32328], 0); + strcpy(string4, getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 615)); + showDialogBox(string4, NULL, 0, 169, 126, _colorTable[32328], NULL, _colorTable[32328], 0); rc = 0; } } else if (keyCode == 501 || keyCode == KEY_UPPERCASE_L || keyCode == KEY_LOWERCASE_L) { // LOAD - char path[COMPAT_MAX_PATH]; - path[0] = '\0'; - strcat(path, "*."); - strcat(path, "GCD"); + string4[0] = '\0'; + strcat(string4, "*."); + strcat(string4, "GCD"); - char** fileNames; - int filesCount = fileNameListInit(path, &fileNames, 0, 0); - if (filesCount != -1) { + char** fileNameList; + int fileNameListLength = fileNameListInit(string4, &fileNameList, 0, 0); + if (fileNameListLength != -1) { + // NOTE: This value is not copied as in save dialog. + char* title = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 601); + int loadFileDialogRc = showLoadFileDialog(title, fileNameList, string3, fileNameListLength, 168, 80, 0); + if (loadFileDialogRc == -1) { + fileNameListFree(&fileNameList, 0); + // FIXME: This branch ignores cleanup at the end of the loop. + return -1; + } + if (loadFileDialogRc == 0) { + string4[0] = '\0'; + strcat(string4, string3); + + int oldRemainingCharacterPoints = gCharacterEditorRemainingCharacterPoints; + + _ResetPlayer(); + + if (gcdLoad(string4) == 0) { + critterUpdateDerivedStats(gDude); + pcStatsReset(); + for (int stat = 0; stat < SAVEABLE_STAT_COUNT; stat++) { + critterSetBonusStat(gDude, stat, 0); + } + perksReset(); + critterUpdateDerivedStats(gDude); + skillsGetTagged(gCharacterEditorTempTaggedSkills, 4); + + int taggedSkillCount = 0; + for (int index = 3; index >= 0; index--) { + if (gCharacterEditorTempTaggedSkills[index] != -1) { + break; + } + taggedSkillCount++; + } + + if (gCharacterEditorIsCreationMode) { + taggedSkillCount--; + } + + gCharacterEditorTaggedSkillCount = taggedSkillCount; + + traitsGetSelected(&(gCharacterEditorTempTraits[0]), &(gCharacterEditorTempTraits[1])); + + int traitCount = 0; + for (int index = 1; index >= 0; index--) { + if (gCharacterEditorTempTraits[index] != -1) { + break; + } + traitCount++; + } + + gCharacterEditorTempTraitCount = traitCount; + + critterUpdateDerivedStats(gDude); + + critterAdjustHitPoints(gDude, 1000); + + rc = 1; + } else { + characterEditorRestorePlayer(); + gCharacterEditorRemainingCharacterPoints = oldRemainingCharacterPoints; + critterAdjustHitPoints(gDude, 1000); + soundPlayFile("iisxxxx1"); + + strcpy(string4, getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 612)); + strcat(string4, string3); + strcat(string4, "!"); + + showDialogBox(string4, NULL, 0, 169, 126, _colorTable[32328], NULL, _colorTable[32328], 0); + } + + characterEditorResetScreen(); + } + + fileNameListFree(&fileNameList, 0); } else { soundPlayFile("iisxxxx1"); // Error reading file list! - strcpy(path, getmsg(&editorMessageList, &editorMessageListItem, 615)); + strcpy(string4, getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 615)); rc = 0; - showDialogBox(path, NULL, 0, 169, 126, _colorTable[32328], NULL, _colorTable[32328], 0); + showDialogBox(string4, NULL, 0, 169, 126, _colorTable[32328], NULL, _colorTable[32328], 0); } } else if (keyCode == 500 || keyCode == KEY_UPPERCASE_S || keyCode == KEY_LOWERCASE_S) { - // TODO: Incomplete. + // SAVE + string4[0] = '\0'; + strcat(string4, "*."); + strcat(string4, "GCD"); + + char** fileNameList; + int fileNameListLength = fileNameListInit(string4, &fileNameList, 0, 0); + if (fileNameListLength != -1) { + strcpy(string1, getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 617)); + strcpy(string4, getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 600)); + + if (showSaveFileDialog(string4, fileNameList, string1, fileNameListLength, 168, 80, 0) == 0) { + strcat(string1, "."); + strcat(string1, "GCD"); + + string4[0] = '\0'; + strcat(string4, string1); + + bool shouldSave; + if (characterFileExists(string4)) { + sprintf(string4, "%s %s", + compat_strupr(string1), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 609)); + strcpy(string5, getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 610)); + + if (showDialogBox(string4, dialogBody, 1, 169, 126, _colorTable[32328], NULL, _colorTable[32328], DIALOG_BOX_YES_NO) != 0) { + shouldSave = true; + } else { + shouldSave = false; + } + } else { + shouldSave = true; + } + + if (shouldSave) { + skillsSetTagged(gCharacterEditorTempTaggedSkills, 4); + traitsSetSelected(gCharacterEditorTempTraits[0], gCharacterEditorTempTraits[1]); + + string4[0] = '\0'; + strcat(string4, string1); + + if (gcdSave(string4) != 0) { + soundPlayFile("iisxxxx1"); + sprintf(string4, "%s%s!", + compat_strupr(string1), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 611)); + showDialogBox(string4, NULL, 0, 169, 126, _colorTable[32328], NULL, _colorTable[32328], DIALOG_BOX_LARGE); + rc = 0; + } else { + sprintf(string4, "%s%s", + compat_strupr(string1), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 607)); + showDialogBox(string4, NULL, 0, 169, 126, _colorTable[992], NULL, _colorTable[992], DIALOG_BOX_LARGE); + rc = 1; + } + } + } + + fileNameListFree(&fileNameList, 0); + } else { + soundPlayFile("iisxxxx1"); + + // Error reading file list! + char* msg = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 615); + showDialogBox(msg, NULL, 0, 169, 126, _colorTable[32328], NULL, _colorTable[32328], 0); + + rc = 0; + } } windowRefresh(win); @@ -3792,19 +3959,19 @@ int _OptionWindow() soundPlayFile("iisxxxx1"); // Error reading file list! - strcpy(pattern, getmsg(&editorMessageList, &editorMessageListItem, 615)); + strcpy(pattern, getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 615)); showDialogBox(pattern, NULL, 0, 169, 126, _colorTable[32328], NULL, _colorTable[32328], 0); return 0; } // PRINT char fileName[512]; - strcpy(fileName, getmsg(&editorMessageList, &editorMessageListItem, 616)); + strcpy(fileName, getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 616)); char title[512]; - strcpy(title, getmsg(&editorMessageList, &editorMessageListItem, 602)); + strcpy(title, getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 602)); - if (_save_file_dialog(title, fileNames, fileName, filesCount, 168, 80, 0) == 0) { + if (showSaveFileDialog(title, fileNames, fileName, filesCount, 168, 80, 0) == 0) { strcat(fileName, ".TXT"); title[0] = '\0'; @@ -3815,10 +3982,10 @@ int _OptionWindow() sprintf(title, "%s %s", compat_strupr(fileName), - getmsg(&editorMessageList, &editorMessageListItem, 609)); + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 609)); char line2[512]; - strcpy(line2, getmsg(&editorMessageList, &editorMessageListItem, 610)); + strcpy(line2, getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 610)); const char* lines[] = { line2 }; v42 = showDialogBox(title, lines, 1, 169, 126, _colorTable[32328], NULL, _colorTable[32328], 0x10); @@ -3838,7 +4005,7 @@ int _OptionWindow() sprintf(title, "%s%s%s", - getmsg(&editorMessageList, &editorMessageListItem, 611), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 611), compat_strupr(fileName), "!"); showDialogBox(title, NULL, 0, 169, 126, _colorTable[32328], NULL, _colorTable[32328], 1); @@ -3880,7 +4047,7 @@ int characterPrintToFile(const char* fileName) char padding[256]; // FALLOUT - strcpy(title1, getmsg(&editorMessageList, &editorMessageListItem, 620)); + strcpy(title1, getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 620)); // NOTE: Uninline. padding[0] = '\0'; @@ -3891,7 +4058,7 @@ int characterPrintToFile(const char* fileName) fileWriteString(padding, stream); // VAULT-13 PERSONNEL RECORD - strcpy(title1, getmsg(&editorMessageList, &editorMessageListItem, 621)); + strcpy(title1, getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 621)); // NOTE: Uninline. padding[0] = '\0'; @@ -3908,10 +4075,10 @@ int characterPrintToFile(const char* fileName) sprintf(title1, "%.2d %s %d %.4d %s", day, - getmsg(&editorMessageList, &editorMessageListItem, 500 + month - 1), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 500 + month - 1), year, gameTimeGetHour(), - getmsg(&editorMessageList, &editorMessageListItem, 622)); + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 622)); // NOTE: Uninline. padding[0] = '\0'; @@ -3927,7 +4094,7 @@ int characterPrintToFile(const char* fileName) // Name sprintf(title1, "%s %s", - getmsg(&editorMessageList, &editorMessageListItem, 642), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 642), critterGetName(gDude)); int paddingLength = 27 - strlen(title1); @@ -3943,24 +4110,24 @@ int characterPrintToFile(const char* fileName) sprintf(title2, "%s%s %d", title1, - getmsg(&editorMessageList, &editorMessageListItem, 643), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 643), critterGetStat(gDude, STAT_AGE)); // Gender sprintf(title3, "%s%s %s", title2, - getmsg(&editorMessageList, &editorMessageListItem, 644), - getmsg(&editorMessageList, &editorMessageListItem, 645 + critterGetStat(gDude, STAT_GENDER))); + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 644), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 645 + critterGetStat(gDude, STAT_GENDER))); fileWriteString(title3, stream); fileWriteString("\n", stream); sprintf(title1, "%s %.2d %s %s ", - getmsg(&editorMessageList, &editorMessageListItem, 647), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 647), pcGetStat(PC_STAT_LEVEL), - getmsg(&editorMessageList, &editorMessageListItem, 648), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 648), _itostndn(pcGetStat(PC_STAT_EXPERIENCE), title3)); paddingLength = 12 - strlen(title3); @@ -3975,26 +4142,26 @@ int characterPrintToFile(const char* fileName) sprintf(title2, "%s%s %s", title1, - getmsg(&editorMessageList, &editorMessageListItem, 649), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 649), _itostndn(pcGetExperienceForNextLevel(), title3)); fileWriteString(title2, stream); fileWriteString("\n", stream); fileWriteString("\n", stream); // Statistics - sprintf(title1, "%s\n", getmsg(&editorMessageList, &editorMessageListItem, 623)); + sprintf(title1, "%s\n", getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 623)); // Strength / Hit Points / Sequence // // FIXME: There is bug - it shows strength instead of sequence. sprintf(title1, "%s %.2d %s %.3d/%.3d %s %.2d", - getmsg(&editorMessageList, &editorMessageListItem, 624), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 624), critterGetStat(gDude, STAT_STRENGTH), - getmsg(&editorMessageList, &editorMessageListItem, 625), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 625), critterGetHitPoints(gDude), critterGetStat(gDude, STAT_MAXIMUM_HIT_POINTS), - getmsg(&editorMessageList, &editorMessageListItem, 626), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 626), critterGetStat(gDude, STAT_STRENGTH)); fileWriteString(title1, stream); fileWriteString("\n", stream); @@ -4002,11 +4169,11 @@ int characterPrintToFile(const char* fileName) // Perception / Armor Class / Healing Rate sprintf(title1, "%s %.2d %s %.3d %s %.2d", - getmsg(&editorMessageList, &editorMessageListItem, 627), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 627), critterGetStat(gDude, STAT_PERCEPTION), - getmsg(&editorMessageList, &editorMessageListItem, 628), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 628), critterGetStat(gDude, STAT_ARMOR_CLASS), - getmsg(&editorMessageList, &editorMessageListItem, 629), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 629), critterGetStat(gDude, STAT_HEALING_RATE)); fileWriteString(title1, stream); fileWriteString("\n", stream); @@ -4014,11 +4181,11 @@ int characterPrintToFile(const char* fileName) // Endurance / Action Points / Critical Chance sprintf(title1, "%s %.2d %s %.2d %s %.3d%%", - getmsg(&editorMessageList, &editorMessageListItem, 630), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 630), critterGetStat(gDude, STAT_ENDURANCE), - getmsg(&editorMessageList, &editorMessageListItem, 631), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 631), critterGetStat(gDude, STAT_MAXIMUM_ACTION_POINTS), - getmsg(&editorMessageList, &editorMessageListItem, 632), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 632), critterGetStat(gDude, STAT_CRITICAL_CHANCE)); fileWriteString(title1, stream); fileWriteString("\n", stream); @@ -4026,11 +4193,11 @@ int characterPrintToFile(const char* fileName) // Charisma / Melee Damage / Carry Weight sprintf(title1, "%s %.2d %s %.2d %s %.3d lbs.", - getmsg(&editorMessageList, &editorMessageListItem, 633), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 633), critterGetStat(gDude, STAT_CHARISMA), - getmsg(&editorMessageList, &editorMessageListItem, 634), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 634), critterGetStat(gDude, STAT_MELEE_DAMAGE), - getmsg(&editorMessageList, &editorMessageListItem, 635), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 635), critterGetStat(gDude, STAT_CARRY_WEIGHT)); fileWriteString(title1, stream); fileWriteString("\n", stream); @@ -4038,9 +4205,9 @@ int characterPrintToFile(const char* fileName) // Intelligence / Damage Resistance sprintf(title1, "%s %.2d %s %.3d%%", - getmsg(&editorMessageList, &editorMessageListItem, 636), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 636), critterGetStat(gDude, STAT_INTELLIGENCE), - getmsg(&editorMessageList, &editorMessageListItem, 637), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 637), critterGetStat(gDude, STAT_DAMAGE_RESISTANCE)); fileWriteString(title1, stream); fileWriteString("\n", stream); @@ -4048,9 +4215,9 @@ int characterPrintToFile(const char* fileName) // Agility / Radiation Resistance sprintf(title1, "%s %.2d %s %.3d%%", - getmsg(&editorMessageList, &editorMessageListItem, 638), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 638), critterGetStat(gDude, STAT_AGILITY), - getmsg(&editorMessageList, &editorMessageListItem, 639), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 639), critterGetStat(gDude, STAT_RADIATION_RESISTANCE)); fileWriteString(title1, stream); fileWriteString("\n", stream); @@ -4058,9 +4225,9 @@ int characterPrintToFile(const char* fileName) // Luck / Poison Resistance sprintf(title1, "%s %.2d %s %.3d%%", - getmsg(&editorMessageList, &editorMessageListItem, 640), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 640), critterGetStat(gDude, STAT_LUCK), - getmsg(&editorMessageList, &editorMessageListItem, 641), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 641), critterGetStat(gDude, STAT_POISON_RESISTANCE)); fileWriteString(title1, stream); fileWriteString("\n", stream); @@ -4068,15 +4235,15 @@ int characterPrintToFile(const char* fileName) fileWriteString("\n", stream); fileWriteString("\n", stream); - if (_temp_trait[0] != -1) { + if (gCharacterEditorTempTraits[0] != -1) { // ::: Traits ::: - sprintf(title1, "%s\n", getmsg(&editorMessageList, &editorMessageListItem, 650)); + sprintf(title1, "%s\n", getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 650)); fileWriteString(title1, stream); // NOTE: The original code does not use loop, or it was optimized away. for (int index = 0; index < TRAITS_MAX_SELECTED_COUNT; index++) { - if (_temp_trait[index] != -1) { - sprintf(title1, " %s", traitGetName(_temp_trait[index])); + if (gCharacterEditorTempTraits[index] != -1) { + sprintf(title1, " %s", traitGetName(gCharacterEditorTempTraits[index])); fileWriteString(title1, stream); fileWriteString("\n", stream); } @@ -4092,7 +4259,7 @@ int characterPrintToFile(const char* fileName) if (perk < PERK_COUNT) { // ::: Perks ::: - sprintf(title1, "%s\n", getmsg(&editorMessageList, &editorMessageListItem, 651)); + sprintf(title1, "%s\n", getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 651)); fileWriteString(title1, stream); for (perk = 0; perk < PERK_COUNT; perk++) { @@ -4113,7 +4280,7 @@ int characterPrintToFile(const char* fileName) fileWriteString("\n", stream); // ::: Karma ::: - sprintf(title1, "%s\n", getmsg(&editorMessageList, &editorMessageListItem, 652)); + sprintf(title1, "%s\n", getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 652)); fileWriteString(title1, stream); for (int index = 0; index < gKarmaEntriesLength; index++) { @@ -4131,15 +4298,15 @@ int characterPrintToFile(const char* fileName) GenericReputationEntry* reputationDescription = &(gGenericReputationEntries[reputation]); sprintf(title1, " %s: %s (%s)", - getmsg(&editorMessageList, &editorMessageListItem, 125), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 125), compat_itoa(gGameGlobalVars[GVAR_PLAYER_REPUTATION], title2, 10), - getmsg(&editorMessageList, &editorMessageListItem, reputationDescription->name)); + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, reputationDescription->name)); fileWriteString(title1, stream); fileWriteString("\n", stream); } } else { if (gGameGlobalVars[karmaEntry->gvar] != 0) { - sprintf(title1, " %s", getmsg(&editorMessageList, &editorMessageListItem, karmaEntry->name)); + sprintf(title1, " %s", getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, karmaEntry->name)); fileWriteString(title1, stream); fileWriteString("\n", stream); } @@ -4154,7 +4321,7 @@ int characterPrintToFile(const char* fileName) fileWriteString("\n", stream); // ::: Reputation ::: - sprintf(title1, "%s\n", getmsg(&editorMessageList, &editorMessageListItem, 657)); + sprintf(title1, "%s\n", getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 657)); fileWriteString(title1, stream); hasTownReputationHeading = true; } @@ -4184,7 +4351,7 @@ int characterPrintToFile(const char* fileName) sprintf(title1, " %s: %s", title2, - getmsg(&editorMessageList, &editorMessageListItem, townReputationMessageId)); + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, townReputationMessageId)); fileWriteString(title1, stream); fileWriteString("\n", stream); } @@ -4197,14 +4364,14 @@ int characterPrintToFile(const char* fileName) fileWriteString("\n", stream); // ::: Addictions ::: - sprintf(title1, "%s\n", getmsg(&editorMessageList, &editorMessageListItem, 656)); + sprintf(title1, "%s\n", getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 656)); fileWriteString(title1, stream); hasAddictionsHeading = true; } sprintf(title1, " %s", - getmsg(&editorMessageList, &editorMessageListItem, 1004 + index)); + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 1004 + index)); fileWriteString(title1, stream); fileWriteString("\n", stream); } @@ -4213,7 +4380,7 @@ int characterPrintToFile(const char* fileName) fileWriteString("\n", stream); // ::: Skills ::: / ::: Kills ::: - sprintf(title1, "%s\n", getmsg(&editorMessageList, &editorMessageListItem, 653)); + sprintf(title1, "%s\n", getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 653)); fileWriteString(title1, stream); int killType = 0; @@ -4256,7 +4423,7 @@ int characterPrintToFile(const char* fileName) fileWriteString("\n", stream); // ::: Inventory ::: - sprintf(title1, "%s\n", getmsg(&editorMessageList, &editorMessageListItem, 654)); + sprintf(title1, "%s\n", getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 654)); fileWriteString(title1, stream); Inventory* inventory = &(gDude->data.inventory); @@ -4295,7 +4462,7 @@ int characterPrintToFile(const char* fileName) // Total Weight: sprintf(title1, "%s %d lbs.", - getmsg(&editorMessageList, &editorMessageListItem, 655), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 655), objectGetInventoryWeight(gDude)); fileWriteString(title1, stream); @@ -4338,86 +4505,86 @@ char* _AddDots(char* string, int length) } // 0x43A4BC -void _ResetScreen() +void characterEditorResetScreen() { characterEditorSelectedItem = 0; - _skill_cursor = 0; - _slider_y = 27; + gCharacterEditorCurrentSkill = 0; + gCharacterEditorSkillValueAdjustmentSliderY = 27; characterEditorWindowSelectedFolder = 0; if (gCharacterEditorIsCreationMode) { - characterEditorRenderBigNumber(126, 282, 0, characterEditorRemainingCharacterPoints, 0, characterEditorWindowHandle); + characterEditorDrawBigNumber(126, 282, 0, gCharacterEditorRemainingCharacterPoints, 0, gCharacterEditorWindow); } else { - editorRenderFolders(); - editorRenderPcStats(); + characterEditorDrawFolders(); + characterEditorDrawPcStats(); } - editorRenderName(); - editorRenderAge(); - editorRenderGender(); - characterEditorWindowRenderTraits(); - editorRenderSkills(0); - editorRenderPrimaryStat(7, 0, 0); - editorRenderSecondaryStats(); - editorRenderDetails(); - windowRefresh(characterEditorWindowHandle); + characterEditorDrawName(); + characterEditorDrawAge(); + characterEditorDrawGender(); + characterEditorDrawOptionalTraits(); + characterEditorDrawSkills(0); + characterEditorDrawPrimaryStat(7, 0, 0); + characterEditorDrawDerivedStats(); + characterEditorDrawCard(); + windowRefresh(gCharacterEditorWindow); } // 0x43A5BC -void _RegInfoAreas() +void characterEditorRegisterInfoAreas() { - buttonCreate(characterEditorWindowHandle, 19, 38, 125, 227, -1, -1, 525, -1, NULL, NULL, NULL, 0); - buttonCreate(characterEditorWindowHandle, 28, 280, 124, 32, -1, -1, 526, -1, NULL, NULL, NULL, 0); + buttonCreate(gCharacterEditorWindow, 19, 38, 125, 227, -1, -1, 525, -1, NULL, NULL, NULL, 0); + buttonCreate(gCharacterEditorWindow, 28, 280, 124, 32, -1, -1, 526, -1, NULL, NULL, NULL, 0); if (gCharacterEditorIsCreationMode) { - buttonCreate(characterEditorWindowHandle, 52, 324, 169, 20, -1, -1, 533, -1, NULL, NULL, NULL, 0); - buttonCreate(characterEditorWindowHandle, 47, 353, 245, 100, -1, -1, 534, -1, NULL, NULL, NULL, 0); + buttonCreate(gCharacterEditorWindow, 52, 324, 169, 20, -1, -1, 533, -1, NULL, NULL, NULL, 0); + buttonCreate(gCharacterEditorWindow, 47, 353, 245, 100, -1, -1, 534, -1, NULL, NULL, NULL, 0); } else { - buttonCreate(characterEditorWindowHandle, 28, 363, 283, 105, -1, -1, 527, -1, NULL, NULL, NULL, 0); + buttonCreate(gCharacterEditorWindow, 28, 363, 283, 105, -1, -1, 527, -1, NULL, NULL, NULL, 0); } - buttonCreate(characterEditorWindowHandle, 191, 41, 122, 110, -1, -1, 528, -1, NULL, NULL, NULL, 0); - buttonCreate(characterEditorWindowHandle, 191, 175, 122, 135, -1, -1, 529, -1, NULL, NULL, NULL, 0); - buttonCreate(characterEditorWindowHandle, 376, 5, 223, 20, -1, -1, 530, -1, NULL, NULL, NULL, 0); - buttonCreate(characterEditorWindowHandle, 370, 27, 223, 195, -1, -1, 531, -1, NULL, NULL, NULL, 0); - buttonCreate(characterEditorWindowHandle, 396, 228, 171, 25, -1, -1, 532, -1, NULL, NULL, NULL, 0); + buttonCreate(gCharacterEditorWindow, 191, 41, 122, 110, -1, -1, 528, -1, NULL, NULL, NULL, 0); + buttonCreate(gCharacterEditorWindow, 191, 175, 122, 135, -1, -1, 529, -1, NULL, NULL, NULL, 0); + buttonCreate(gCharacterEditorWindow, 376, 5, 223, 20, -1, -1, 530, -1, NULL, NULL, NULL, 0); + buttonCreate(gCharacterEditorWindow, 370, 27, 223, 195, -1, -1, 531, -1, NULL, NULL, NULL, 0); + buttonCreate(gCharacterEditorWindow, 396, 228, 171, 25, -1, -1, 532, -1, NULL, NULL, NULL, 0); } // copy character to editor // // 0x43A7DC -void _SavePlayer() +void characterEditorSavePlayer() { Proto* proto; protoGetProto(gDude->pid, &proto); - critterProtoDataCopy(&_dude_data, &(proto->critter.data)); + critterProtoDataCopy(&gCharacterEditorDudeDataBackup, &(proto->critter.data)); - _hp_back = critterGetHitPoints(gDude); + gCharacterEditorHitPointsBackup = critterGetHitPoints(gDude); - strncpy(_name_save, critterGetName(gDude), 32); + strncpy(gCharacterEditorNameBackup, critterGetName(gDude), 32); - _last_level_back = _last_level; + gCharacterEditorLastLevelBackup = gCharacterEditorLastLevel; for (int perk = 0; perk < PERK_COUNT; perk++) { - _perk_back[perk] = perkGetRank(gDude, perk); + gCharacterEditorPerksBackup[perk] = perkGetRank(gDude, perk); } - _free_perk_back = _free_perk; + gCharacterEditorHasFreePerkBackup = gCharacterEditorHasFreePerk; - _upsent_points_back = pcGetStat(PC_STAT_UNSPENT_SKILL_POINTS); + gCharacterEditorUnspentSkillPointsBackup = pcGetStat(PC_STAT_UNSPENT_SKILL_POINTS); - skillsGetTagged(_tag_skill_back, NUM_TAGGED_SKILLS); + skillsGetTagged(gCharacterEditorTaggedSkillsBackup, NUM_TAGGED_SKILLS); - traitsGetSelected(&(_trait_back[0]), &(_trait_back[1])); + traitsGetSelected(&(gCharacterEditorOptionalTraitsBackup[0]), &(gCharacterEditorOptionalTraitsBackup[1])); for (int skill = 0; skill < SKILL_COUNT; skill++) { - _skillsav[skill] = skillGetValue(gDude, skill); + gCharacterEditorSkillsBackup[skill] = skillGetValue(gDude, skill); } } // copy editor to character // // 0x43A8BC -void _RestorePlayer() +void characterEditorRestorePlayer() { Proto* proto; int i; @@ -4427,25 +4594,25 @@ void _RestorePlayer() _pop_perks(); protoGetProto(gDude->pid, &proto); - critterProtoDataCopy(&(proto->critter.data), &_dude_data); + critterProtoDataCopy(&(proto->critter.data), &gCharacterEditorDudeDataBackup); - dudeSetName(_name_save); + dudeSetName(gCharacterEditorNameBackup); - _last_level = _last_level_back; - _free_perk = _free_perk_back; + gCharacterEditorLastLevel = gCharacterEditorLastLevelBackup; + gCharacterEditorHasFreePerk = gCharacterEditorHasFreePerkBackup; - pcSetStat(PC_STAT_UNSPENT_SKILL_POINTS, _upsent_points_back); + pcSetStat(PC_STAT_UNSPENT_SKILL_POINTS, gCharacterEditorUnspentSkillPointsBackup); - skillsSetTagged(_tag_skill_back, NUM_TAGGED_SKILLS); + skillsSetTagged(gCharacterEditorTaggedSkillsBackup, NUM_TAGGED_SKILLS); - traitsSetSelected(_trait_back[0], _trait_back[1]); + traitsSetSelected(gCharacterEditorOptionalTraitsBackup[0], gCharacterEditorOptionalTraitsBackup[1]); - skillsGetTagged(_temp_tag_skill, NUM_TAGGED_SKILLS); + skillsGetTagged(gCharacterEditorTempTaggedSkills, NUM_TAGGED_SKILLS); i = 4; v3 = 0; for (v3 = 0; v3 < 4; v3++) { - if (_temp_tag_skill[--i] != -1) { + if (gCharacterEditorTempTaggedSkills[--i] != -1) { break; } } @@ -4454,24 +4621,24 @@ void _RestorePlayer() v3 -= gCharacterEditorIsCreationMode; } - _tagskill_count = v3; + gCharacterEditorTaggedSkillCount = v3; - traitsGetSelected(&(_temp_trait[0]), &(_temp_trait[1])); + traitsGetSelected(&(gCharacterEditorTempTraits[0]), &(gCharacterEditorTempTraits[1])); i = 2; v3 = 0; for (v3 = 0; v3 < 2; v3++) { - if (_temp_trait[v3] != -1) { + if (gCharacterEditorTempTraits[v3] != -1) { break; } } - _trait_count = v3; + gCharacterEditorTempTraitCount = v3; critterUpdateDerivedStats(gDude); cur_hp = critterGetHitPoints(gDude); - critterAdjustHitPoints(gDude, _hp_back - cur_hp); + critterAdjustHitPoints(gDude, gCharacterEditorHitPointsBackup - cur_hp); } // 0x43A9CC @@ -4510,7 +4677,7 @@ char* _itostndn(int value, char* dest) } // 0x43AAEC -int _DrawCard(int graphicId, const char* name, const char* attributes, char* description) +int characterEditorDrawCardWithOptions(int graphicId, const char* name, const char* attributes, char* description) { CacheEntry* graphicHandle; Size size; @@ -4529,7 +4696,7 @@ int _DrawCard(int graphicId, const char* name, const char* attributes, char* des return -1; } - blitBufferToBuffer(buf, size.width, size.height, size.width, characterEditorWindowBuf + 640 * 309 + 484, 640); + blitBufferToBuffer(buf, size.width, size.height, size.width, gCharacterEditorWindowBuffer + 640 * 309 + 484, 640); v9 = 150; ptr = buf; @@ -4549,19 +4716,19 @@ int _DrawCard(int graphicId, const char* name, const char* attributes, char* des fontSetCurrent(102); - fontDrawText(characterEditorWindowBuf + 640 * 272 + 348, name, 640, 640, _colorTable[0]); + fontDrawText(gCharacterEditorWindowBuffer + 640 * 272 + 348, name, 640, 640, _colorTable[0]); int nameFontLineHeight = fontGetLineHeight(); if (attributes != NULL) { int nameWidth = fontGetStringWidth(name); fontSetCurrent(101); int attributesFontLineHeight = fontGetLineHeight(); - fontDrawText(characterEditorWindowBuf + 640 * (268 + nameFontLineHeight - attributesFontLineHeight) + 348 + nameWidth + 8, attributes, 640, 640, _colorTable[0]); + fontDrawText(gCharacterEditorWindowBuffer + 640 * (268 + nameFontLineHeight - attributesFontLineHeight) + 348 + nameWidth + 8, attributes, 640, 640, _colorTable[0]); } y = nameFontLineHeight; - windowDrawLine(characterEditorWindowHandle, 348, y + 272, 613, y + 272, _colorTable[0]); - windowDrawLine(characterEditorWindowHandle, 348, y + 273, 613, y + 273, _colorTable[0]); + windowDrawLine(gCharacterEditorWindow, 348, y + 272, 613, y + 272, _colorTable[0]); + windowDrawLine(gCharacterEditorWindow, 348, y + 273, 613, y + 273, _colorTable[0]); fontSetCurrent(101); @@ -4578,19 +4745,20 @@ int _DrawCard(int graphicId, const char* name, const char* attributes, char* des short ending = beginnings[i + 1]; char c = description[ending]; description[ending] = '\0'; - fontDrawText(characterEditorWindowBuf + 640 * y + 348, description + beginning, 640, 640, _colorTable[0]); + fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 348, description + beginning, 640, 640, _colorTable[0]); description[ending] = c; y += descriptionFontLineHeight; } - if ((graphicId != _card_old_fid1 || strcmp(name, _old_str1) != 0) && _frstc_draw1) { - soundPlayFile("isdxxxx1"); + if (graphicId != gCharacterEditorCardFrmId || strcmp(name, gCharacterEditorCardTitle) != 0) { + if (gCharacterEditorCardDrawn) { + soundPlayFile("isdxxxx1"); + } } - strcpy(_old_str1, name); - - _card_old_fid1 = graphicId; - _frstc_draw1 = 1; + strcpy(gCharacterEditorCardTitle, name); + gCharacterEditorCardFrmId = graphicId; + gCharacterEditorCardDrawn = true; artUnlock(graphicHandle); @@ -4598,15 +4766,15 @@ int _DrawCard(int graphicId, const char* name, const char* attributes, char* des } // 0x43AE8 -void _FldrButton() +void characterEditorHandleFolderButtonPressed() { - mouseGetPositionInWindow(characterEditorWindowHandle, &_mouse_xpos, &_mouse_ypos); + mouseGetPositionInWindow(gCharacterEditorWindow, &gCharacterEditorMouseX, &gCharacterEditorMouseY); soundPlayFile("ib3p1xx1"); - if (_mouse_xpos >= 208) { + if (gCharacterEditorMouseX >= 208) { characterEditorSelectedItem = 41; characterEditorWindowSelectedFolder = EDITOR_FOLDER_KILLS; - } else if (_mouse_xpos > 110) { + } else if (gCharacterEditorMouseX > 110) { characterEditorSelectedItem = 42; characterEditorWindowSelectedFolder = EDITOR_FOLDER_KARMA; } else { @@ -4614,23 +4782,23 @@ void _FldrButton() characterEditorWindowSelectedFolder = EDITOR_FOLDER_PERKS; } - editorRenderFolders(); - editorRenderDetails(); + characterEditorDrawFolders(); + characterEditorDrawCard(); } // 0x43AF40 -void _InfoButton(int eventCode) +void characterEditorHandleInfoButtonPressed(int eventCode) { - mouseGetPositionInWindow(characterEditorWindowHandle, &_mouse_xpos, &_mouse_ypos); + mouseGetPositionInWindow(gCharacterEditorWindow, &gCharacterEditorMouseX, &gCharacterEditorMouseY); switch (eventCode) { case 525: if (1) { // TODO: Original code is slightly different. - double mouseY = _mouse_ypos; + double mouseY = gCharacterEditorMouseY; for (int index = 0; index < 7; index++) { - double buttonTop = _StatYpos[index]; - double buttonBottom = _StatYpos[index] + 22; + double buttonTop = gCharacterEditorPrimaryStatY[index]; + double buttonBottom = gCharacterEditorPrimaryStatY[index] + 22; double allowance = 5.0 - index * 0.25; if (mouseY >= buttonTop - allowance && mouseY <= buttonBottom + allowance) { characterEditorSelectedItem = index; @@ -4643,7 +4811,7 @@ void _InfoButton(int eventCode) if (gCharacterEditorIsCreationMode) { characterEditorSelectedItem = 7; } else { - int offset = _mouse_ypos - 280; + int offset = gCharacterEditorMouseY - 280; if (offset < 0) { offset = 0; } @@ -4654,7 +4822,7 @@ void _InfoButton(int eventCode) case 527: if (!gCharacterEditorIsCreationMode) { fontSetCurrent(101); - int offset = _mouse_ypos - 364; + int offset = gCharacterEditorMouseY - 364; if (offset < 0) { offset = 0; } @@ -4663,7 +4831,7 @@ void _InfoButton(int eventCode) break; case 528: if (1) { - int offset = _mouse_ypos - 41; + int offset = gCharacterEditorMouseY - 41; if (offset < 0) { offset = 0; } @@ -4672,7 +4840,7 @@ void _InfoButton(int eventCode) } break; case 529: { - int offset = _mouse_ypos - 175; + int offset = gCharacterEditorMouseY - 175; if (offset < 0) { offset = 0; } @@ -4685,17 +4853,17 @@ void _InfoButton(int eventCode) break; case 531: if (1) { - int offset = _mouse_ypos - 27; + int offset = gCharacterEditorMouseY - 27; if (offset < 0) { offset = 0; } - _skill_cursor = offset * 0.092307694; - if (_skill_cursor >= 18) { - _skill_cursor = 17; + gCharacterEditorCurrentSkill = offset * 0.092307694; + if (gCharacterEditorCurrentSkill >= 18) { + gCharacterEditorCurrentSkill = 17; } - characterEditorSelectedItem = _skill_cursor + 61; + characterEditorSelectedItem = gCharacterEditorCurrentSkill + 61; } break; case 532: @@ -4709,7 +4877,7 @@ void _InfoButton(int eventCode) fontSetCurrent(101); // TODO: Original code is slightly different. - double mouseY = _mouse_ypos; + double mouseY = gCharacterEditorMouseY; double fontLineHeight = fontGetLineHeight(); double y = 353.0; double step = fontGetLineHeight() + 3 + 0.56; @@ -4726,24 +4894,24 @@ void _InfoButton(int eventCode) } characterEditorSelectedItem = index + 82; - if (_mouse_xpos >= 169) { + if (gCharacterEditorMouseX >= 169) { characterEditorSelectedItem += 8; } } break; } - editorRenderPrimaryStat(RENDER_ALL_STATS, 0, 0); - characterEditorWindowRenderTraits(); - editorRenderSkills(0); - editorRenderPcStats(); - editorRenderFolders(); - editorRenderSecondaryStats(); - editorRenderDetails(); + characterEditorDrawPrimaryStat(RENDER_ALL_STATS, 0, 0); + characterEditorDrawOptionalTraits(); + characterEditorDrawSkills(0); + characterEditorDrawPcStats(); + characterEditorDrawFolders(); + characterEditorDrawDerivedStats(); + characterEditorDrawCard(); } // 0x43B230 -void editorAdjustSkill(int keyCode) +void characterEditorHandleAdjustSkillButtonPressed(int keyCode) { if (gCharacterEditorIsCreationMode) { return; @@ -4797,14 +4965,14 @@ void editorAdjustSkill(int keyCode) rc = 1; if (keyCode == 521) { if (pcGetStat(PC_STAT_UNSPENT_SKILL_POINTS) > 0) { - if (skillAdd(gDude, _skill_cursor) == -3) { + if (skillAdd(gDude, gCharacterEditorCurrentSkill) == -3) { soundPlayFile("iisxxxx1"); - sprintf(title, "%s:", skillGetName(_skill_cursor)); + sprintf(title, "%s:", skillGetName(gCharacterEditorCurrentSkill)); // At maximum level. - strcpy(body1, getmsg(&editorMessageList, &editorMessageListItem, 132)); + strcpy(body1, getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 132)); // Unable to increment it. - strcpy(body2, getmsg(&editorMessageList, &editorMessageListItem, 133)); + strcpy(body2, getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 133)); showDialogBox(title, body, 2, 192, 126, _colorTable[32328], NULL, _colorTable[32328], DIALOG_BOX_LARGE); rc = -1; } @@ -4812,15 +4980,15 @@ void editorAdjustSkill(int keyCode) soundPlayFile("iisxxxx1"); // Not enough skill points available. - strcpy(title, getmsg(&editorMessageList, &editorMessageListItem, 136)); + strcpy(title, getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 136)); showDialogBox(title, NULL, 0, 192, 126, _colorTable[32328], NULL, _colorTable[32328], DIALOG_BOX_LARGE); rc = -1; } } else if (keyCode == 523) { - if (skillGetValue(gDude, _skill_cursor) <= _skillsav[_skill_cursor]) { + if (skillGetValue(gDude, gCharacterEditorCurrentSkill) <= gCharacterEditorSkillsBackup[gCharacterEditorCurrentSkill]) { rc = 0; } else { - if (skillSub(gDude, _skill_cursor) == -2) { + if (skillSub(gDude, gCharacterEditorCurrentSkill) == -2) { rc = 0; } } @@ -4828,19 +4996,19 @@ void editorAdjustSkill(int keyCode) if (rc == 0) { soundPlayFile("iisxxxx1"); - sprintf(title, "%s:", skillGetName(_skill_cursor)); + sprintf(title, "%s:", skillGetName(gCharacterEditorCurrentSkill)); // At minimum level. - strcpy(body1, getmsg(&editorMessageList, &editorMessageListItem, 134)); + strcpy(body1, getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 134)); // Unable to decrement it. - strcpy(body2, getmsg(&editorMessageList, &editorMessageListItem, 135)); + strcpy(body2, getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 135)); showDialogBox(title, body, 2, 192, 126, _colorTable[32328], NULL, _colorTable[32328], DIALOG_BOX_LARGE); rc = -1; } } - characterEditorSelectedItem = _skill_cursor + 61; - editorRenderDetails(); - editorRenderSkills(1); + characterEditorSelectedItem = gCharacterEditorCurrentSkill + 61; + characterEditorDrawCard(); + characterEditorDrawSkills(1); int flags; if (rc == 1) { @@ -4849,9 +5017,9 @@ void editorAdjustSkill(int keyCode) flags = 0; } - characterEditorRenderBigNumber(522, 228, flags, pcGetStat(PC_STAT_UNSPENT_SKILL_POINTS), unspentSp, characterEditorWindowHandle); + characterEditorDrawBigNumber(522, 228, flags, pcGetStat(PC_STAT_UNSPENT_SKILL_POINTS), unspentSp, gCharacterEditorWindow); - windowRefresh(characterEditorWindowHandle); + windowRefresh(gCharacterEditorWindow); } if (!isUsingKeyboard) { @@ -4880,7 +5048,7 @@ void characterEditorToggleTaggedSkill(int skill) insertionIndex = 0; for (int index = 3; index >= 0; index--) { - if (_temp_tag_skill[index] != -1) { + if (gCharacterEditorTempTaggedSkills[index] != -1) { break; } insertionIndex++; @@ -4890,37 +5058,37 @@ void characterEditorToggleTaggedSkill(int skill) insertionIndex -= 1; } - _old_tags = insertionIndex; + gCharacterEditorOldTaggedSkillCount = insertionIndex; - if (skill == _temp_tag_skill[0] || skill == _temp_tag_skill[1] || skill == _temp_tag_skill[2] || skill == _temp_tag_skill[3]) { - if (skill == _temp_tag_skill[0]) { - _temp_tag_skill[0] = _temp_tag_skill[1]; - _temp_tag_skill[1] = _temp_tag_skill[2]; - _temp_tag_skill[2] = -1; - } else if (skill == _temp_tag_skill[1]) { - _temp_tag_skill[1] = _temp_tag_skill[2]; - _temp_tag_skill[2] = -1; + if (skill == gCharacterEditorTempTaggedSkills[0] || skill == gCharacterEditorTempTaggedSkills[1] || skill == gCharacterEditorTempTaggedSkills[2] || skill == gCharacterEditorTempTaggedSkills[3]) { + if (skill == gCharacterEditorTempTaggedSkills[0]) { + gCharacterEditorTempTaggedSkills[0] = gCharacterEditorTempTaggedSkills[1]; + gCharacterEditorTempTaggedSkills[1] = gCharacterEditorTempTaggedSkills[2]; + gCharacterEditorTempTaggedSkills[2] = -1; + } else if (skill == gCharacterEditorTempTaggedSkills[1]) { + gCharacterEditorTempTaggedSkills[1] = gCharacterEditorTempTaggedSkills[2]; + gCharacterEditorTempTaggedSkills[2] = -1; } else { - _temp_tag_skill[2] = -1; + gCharacterEditorTempTaggedSkills[2] = -1; } } else { - if (_tagskill_count > 0) { + if (gCharacterEditorTaggedSkillCount > 0) { insertionIndex = 0; for (int index = 0; index < 3; index++) { - if (_temp_tag_skill[index] == -1) { + if (gCharacterEditorTempTaggedSkills[index] == -1) { break; } insertionIndex++; } - _temp_tag_skill[insertionIndex] = skill; + gCharacterEditorTempTaggedSkills[insertionIndex] = skill; } else { soundPlayFile("iisxxxx1"); char line1[128]; - strcpy(line1, getmsg(&editorMessageList, &editorMessageListItem, 140)); + strcpy(line1, getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 140)); char line2[128]; - strcpy(line2, getmsg(&editorMessageList, &editorMessageListItem, 141)); + strcpy(line2, getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 141)); const char* lines[] = { line2 }; showDialogBox(line1, lines, 1, 192, 126, _colorTable[32328], 0, _colorTable[32328], 0); @@ -4929,7 +5097,7 @@ void characterEditorToggleTaggedSkill(int skill) insertionIndex = 0; for (int index = 3; index >= 0; index--) { - if (_temp_tag_skill[index] != -1) { + if (gCharacterEditorTempTaggedSkills[index] != -1) { break; } insertionIndex++; @@ -4939,18 +5107,18 @@ void characterEditorToggleTaggedSkill(int skill) insertionIndex -= 1; } - _tagskill_count = insertionIndex; + gCharacterEditorTaggedSkillCount = insertionIndex; characterEditorSelectedItem = skill + 61; - editorRenderPrimaryStat(RENDER_ALL_STATS, 0, 0); - editorRenderSecondaryStats(); - editorRenderSkills(2); - editorRenderDetails(); - windowRefresh(characterEditorWindowHandle); + characterEditorDrawPrimaryStat(RENDER_ALL_STATS, 0, 0); + characterEditorDrawDerivedStats(); + characterEditorDrawSkills(2); + characterEditorDrawCard(); + windowRefresh(gCharacterEditorWindow); } // 0x43B8A8 -void characterEditorWindowRenderTraits() +void characterEditorDrawOptionalTraits() { int v0 = -1; int i; @@ -4967,28 +5135,28 @@ void characterEditorWindowRenderTraits() v0 = characterEditorSelectedItem - 82; } - blitBufferToBuffer(characterEditorWindowBackgroundBuf + 640 * 353 + 47, 245, 100, 640, characterEditorWindowBuf + 640 * 353 + 47, 640); + blitBufferToBuffer(gCharacterEditorWindowBackgroundBuffer + 640 * 353 + 47, 245, 100, 640, gCharacterEditorWindowBuffer + 640 * 353 + 47, 640); fontSetCurrent(101); - traitsSetSelected(_temp_trait[0], _temp_trait[1]); + traitsSetSelected(gCharacterEditorTempTraits[0], gCharacterEditorTempTraits[1]); step = fontGetLineHeight() + 3 + 0.56; y = 353; for (i = 0; i < 8; i++) { if (i == v0) { - if (i != _temp_trait[0] && i != _temp_trait[1]) { + if (i != gCharacterEditorTempTraits[0] && i != gCharacterEditorTempTraits[1]) { color = _colorTable[32747]; } else { color = _colorTable[32767]; } - _folder_card_fid = traitGetFrmId(i); - _folder_card_title = traitGetName(i); - _folder_card_title2 = NULL; - _folder_card_desc = traitGetDescription(i); + gCharacterEditorFolderCardFrmId = traitGetFrmId(i); + gCharacterEditorFolderCardTitle = traitGetName(i); + gCharacterEditorFolderCardSubtitle = NULL; + gCharacterEditorFolderCardDescription = traitGetDescription(i); } else { - if (i != _temp_trait[0] && i != _temp_trait[1]) { + if (i != gCharacterEditorTempTraits[0] && i != gCharacterEditorTempTraits[1]) { color = _colorTable[992]; } else { color = _colorTable[21140]; @@ -4996,25 +5164,25 @@ void characterEditorWindowRenderTraits() } traitName = traitGetName(i); - fontDrawText(characterEditorWindowBuf + 640 * (int)y + 47, traitName, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * (int)y + 47, traitName, 640, 640, color); y += step; } y = 353; for (i = 8; i < 16; i++) { if (i == v0) { - if (i != _temp_trait[0] && i != _temp_trait[1]) { + if (i != gCharacterEditorTempTraits[0] && i != gCharacterEditorTempTraits[1]) { color = _colorTable[32747]; } else { color = _colorTable[32767]; } - _folder_card_fid = traitGetFrmId(i); - _folder_card_title = traitGetName(i); - _folder_card_title2 = NULL; - _folder_card_desc = traitGetDescription(i); + gCharacterEditorFolderCardFrmId = traitGetFrmId(i); + gCharacterEditorFolderCardTitle = traitGetName(i); + gCharacterEditorFolderCardSubtitle = NULL; + gCharacterEditorFolderCardDescription = traitGetDescription(i); } else { - if (i != _temp_trait[0] && i != _temp_trait[1]) { + if (i != gCharacterEditorTempTraits[0] && i != gCharacterEditorTempTraits[1]) { color = _colorTable[992]; } else { color = _colorTable[21140]; @@ -5022,7 +5190,7 @@ void characterEditorWindowRenderTraits() } traitName = traitGetName(i); - fontDrawText(characterEditorWindowBuf + 640 * (int)y + 199, traitName, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * (int)y + 199, traitName, 640, 640, color); y += step; } } @@ -5030,62 +5198,62 @@ void characterEditorWindowRenderTraits() // 0x43BB0C void characterEditorToggleOptionalTrait(int trait) { - if (trait == _temp_trait[0] || trait == _temp_trait[1]) { - if (trait == _temp_trait[0]) { - _temp_trait[0] = _temp_trait[1]; - _temp_trait[1] = -1; + if (trait == gCharacterEditorTempTraits[0] || trait == gCharacterEditorTempTraits[1]) { + if (trait == gCharacterEditorTempTraits[0]) { + gCharacterEditorTempTraits[0] = gCharacterEditorTempTraits[1]; + gCharacterEditorTempTraits[1] = -1; } else { - _temp_trait[1] = -1; + gCharacterEditorTempTraits[1] = -1; } } else { - if (_trait_count == 0) { + if (gCharacterEditorTempTraitCount == 0) { soundPlayFile("iisxxxx1"); char line1[128]; - strcpy(line1, getmsg(&editorMessageList, &editorMessageListItem, 148)); + strcpy(line1, getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 148)); char line2[128]; - strcpy(line2, getmsg(&editorMessageList, &editorMessageListItem, 149)); + strcpy(line2, getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 149)); const char* lines = { line2 }; showDialogBox(line1, &lines, 1, 192, 126, _colorTable[32328], 0, _colorTable[32328], 0); } else { for (int index = 0; index < 2; index++) { - if (_temp_trait[index] == -1) { - _temp_trait[index] = trait; + if (gCharacterEditorTempTraits[index] == -1) { + gCharacterEditorTempTraits[index] = trait; break; } } } } - _trait_count = 0; + gCharacterEditorTempTraitCount = 0; for (int index = 1; index != 0; index--) { - if (_temp_trait[index] != -1) { + if (gCharacterEditorTempTraits[index] != -1) { break; } - _trait_count++; + gCharacterEditorTempTraitCount++; } characterEditorSelectedItem = trait + EDITOR_FIRST_TRAIT; - characterEditorWindowRenderTraits(); - editorRenderSkills(0); + characterEditorDrawOptionalTraits(); + characterEditorDrawSkills(0); critterUpdateDerivedStats(gDude); - characterEditorRenderBigNumber(126, 282, 0, characterEditorRemainingCharacterPoints, 0, characterEditorWindowHandle); - editorRenderPrimaryStat(RENDER_ALL_STATS, false, 0); - editorRenderSecondaryStats(); - editorRenderDetails(); - windowRefresh(characterEditorWindowHandle); + characterEditorDrawBigNumber(126, 282, 0, gCharacterEditorRemainingCharacterPoints, 0, gCharacterEditorWindow); + characterEditorDrawPrimaryStat(RENDER_ALL_STATS, false, 0); + characterEditorDrawDerivedStats(); + characterEditorDrawCard(); + windowRefresh(gCharacterEditorWindow); } // 0x43BCE0 -void editorRenderKarma() +void characterEditorDrawKarmaFolder() { char* msg; char formattedText[256]; - _folder_clear(); + characterEditorFolderViewClear(); bool hasSelection = false; for (int index = 0; index < gKarmaEntriesLength; index++) { @@ -5107,26 +5275,26 @@ void editorRenderKarma() sprintf(formattedText, "%s: %s (%s)", - getmsg(&editorMessageList, &editorMessageListItem, 125), + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 125), reputationValue, - getmsg(&editorMessageList, &editorMessageListItem, reputationDescription->name)); + getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, reputationDescription->name)); - if (_folder_print_line(formattedText)) { - _folder_card_fid = karmaDescription->art_num; - _folder_card_title = getmsg(&editorMessageList, &editorMessageListItem, 125); - _folder_card_title2 = NULL; - _folder_card_desc = getmsg(&editorMessageList, &editorMessageListItem, karmaDescription->description); + if (characterEditorFolderViewDrawString(formattedText)) { + gCharacterEditorFolderCardFrmId = karmaDescription->art_num; + gCharacterEditorFolderCardTitle = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 125); + gCharacterEditorFolderCardSubtitle = NULL; + gCharacterEditorFolderCardDescription = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, karmaDescription->description); hasSelection = true; } } } else { if (gGameGlobalVars[karmaDescription->gvar] != 0) { - msg = getmsg(&editorMessageList, &editorMessageListItem, karmaDescription->name); - if (_folder_print_line(msg)) { - _folder_card_fid = karmaDescription->art_num; - _folder_card_title = getmsg(&editorMessageList, &editorMessageListItem, karmaDescription->name); - _folder_card_title2 = NULL; - _folder_card_desc = getmsg(&editorMessageList, &editorMessageListItem, karmaDescription->description); + msg = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, karmaDescription->name); + if (characterEditorFolderViewDrawString(msg)) { + gCharacterEditorFolderCardFrmId = karmaDescription->art_num; + gCharacterEditorFolderCardTitle = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, karmaDescription->name); + gCharacterEditorFolderCardSubtitle = NULL; + gCharacterEditorFolderCardDescription = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, karmaDescription->description); hasSelection = true; } } @@ -5138,12 +5306,12 @@ void editorRenderKarma() const TownReputationEntry* pair = &(gTownReputationEntries[index]); if (_wmAreaIsKnown(pair->city)) { if (!hasTownReputationHeading) { - msg = getmsg(&editorMessageList, &editorMessageListItem, 4000); - if (_folder_print_seperator(msg)) { - _folder_card_fid = 48; - _folder_card_title = getmsg(&editorMessageList, &editorMessageListItem, 4000); - _folder_card_title2 = NULL; - _folder_card_desc = getmsg(&editorMessageList, &editorMessageListItem, 4100); + msg = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 4000); + if (characterEditorFolderViewDrawHeading(msg)) { + gCharacterEditorFolderCardFrmId = 48; + gCharacterEditorFolderCardTitle = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 4000); + gCharacterEditorFolderCardSubtitle = NULL; + gCharacterEditorFolderCardDescription = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 4100); } hasTownReputationHeading = true; } @@ -5179,17 +5347,17 @@ void editorRenderKarma() townReputationBaseMessageId = 2000; // Idolized } - msg = getmsg(&editorMessageList, &editorMessageListItem, townReputationBaseMessageId); + msg = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, townReputationBaseMessageId); sprintf(formattedText, "%s: %s", cityShortName, msg); - if (_folder_print_line(formattedText)) { - _folder_card_fid = townReputationGraphicId; - _folder_card_title = getmsg(&editorMessageList, &editorMessageListItem, townReputationBaseMessageId); - _folder_card_title2 = NULL; - _folder_card_desc = getmsg(&editorMessageList, &editorMessageListItem, townReputationBaseMessageId + 100); + if (characterEditorFolderViewDrawString(formattedText)) { + gCharacterEditorFolderCardFrmId = townReputationGraphicId; + gCharacterEditorFolderCardTitle = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, townReputationBaseMessageId); + gCharacterEditorFolderCardSubtitle = NULL; + gCharacterEditorFolderCardDescription = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, townReputationBaseMessageId + 100); hasSelection = 1; } } @@ -5200,73 +5368,74 @@ void editorRenderKarma() if (gGameGlobalVars[gAddictionReputationVars[index]] != 0) { if (!hasAddictionsHeading) { // Addictions - msg = getmsg(&editorMessageList, &editorMessageListItem, 4001); - if (_folder_print_seperator(msg)) { - _folder_card_fid = 53; - _folder_card_title = getmsg(&editorMessageList, &editorMessageListItem, 4001); - _folder_card_title2 = NULL; - _folder_card_desc = getmsg(&editorMessageList, &editorMessageListItem, 4101); + msg = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 4001); + if (characterEditorFolderViewDrawHeading(msg)) { + gCharacterEditorFolderCardFrmId = 53; + gCharacterEditorFolderCardTitle = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 4001); + gCharacterEditorFolderCardSubtitle = NULL; + gCharacterEditorFolderCardDescription = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 4101); hasSelection = 1; } hasAddictionsHeading = true; } - msg = getmsg(&editorMessageList, &editorMessageListItem, 1004 + index); - if (_folder_print_line(msg)) { - _folder_card_fid = gAddictionReputationFrmIds[index]; - _folder_card_title = getmsg(&editorMessageList, &editorMessageListItem, 1004 + index); - _folder_card_title2 = NULL; - _folder_card_desc = getmsg(&editorMessageList, &editorMessageListItem, 1104 + index); + msg = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 1004 + index); + if (characterEditorFolderViewDrawString(msg)) { + gCharacterEditorFolderCardFrmId = gAddictionReputationFrmIds[index]; + gCharacterEditorFolderCardTitle = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 1004 + index); + gCharacterEditorFolderCardSubtitle = NULL; + gCharacterEditorFolderCardDescription = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 1104 + index); hasSelection = 1; } } } if (!hasSelection) { - _folder_card_fid = 47; - _folder_card_title = getmsg(&editorMessageList, &editorMessageListItem, 125); - _folder_card_title2 = NULL; - _folder_card_desc = getmsg(&editorMessageList, &editorMessageListItem, 128); + // SFALL: Custom karma folder. + gCharacterEditorFolderCardFrmId = customKarmaFolderGetFrmId(); + gCharacterEditorFolderCardTitle = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 125); + gCharacterEditorFolderCardSubtitle = NULL; + gCharacterEditorFolderCardDescription = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 128); } } // 0x43C1B0 -int _editor_save(File* stream) +int characterEditorSave(File* stream) { - if (fileWriteInt32(stream, _last_level) == -1) + if (fileWriteInt32(stream, gCharacterEditorLastLevel) == -1) return -1; - if (fileWriteUInt8(stream, _free_perk) == -1) + if (fileWriteUInt8(stream, gCharacterEditorHasFreePerk) == -1) return -1; return 0; } // 0x43C1E0 -int _editor_load(File* stream) +int characterEditorLoad(File* stream) { - if (fileReadInt32(stream, &_last_level) == -1) + if (fileReadInt32(stream, &gCharacterEditorLastLevel) == -1) return -1; - if (fileReadUInt8(stream, &_free_perk) == -1) + if (fileReadUInt8(stream, &gCharacterEditorHasFreePerk) == -1) return -1; return 0; } // 0x43C20C -void _editor_reset() +void characterEditorReset() { - characterEditorRemainingCharacterPoints = 5; - _last_level = 1; + gCharacterEditorRemainingCharacterPoints = 5; + gCharacterEditorLastLevel = 1; } // level up if needed // // 0x43C228 -int _UpdateLevel() +int characterEditorUpdateLevel() { int level = pcGetStat(PC_STAT_LEVEL); - if (level != _last_level && level <= PC_LEVEL_MAX) { - for (int nextLevel = _last_level + 1; nextLevel <= level; nextLevel++) { + if (level != gCharacterEditorLastLevel && level <= PC_LEVEL_MAX) { + for (int nextLevel = gCharacterEditorLastLevel + 1; nextLevel <= level; nextLevel++) { int sp = pcGetStat(PC_STAT_UNSPENT_SKILL_POINTS); sp += 5; sp += critterGetBaseStatWithTraitModifier(gDude, STAT_INTELLIGENCE) * 2; @@ -5301,49 +5470,49 @@ int _UpdateLevel() } if (nextLevel % progression == 0) { - _free_perk = 1; + gCharacterEditorHasFreePerk = 1; } } } } - if (_free_perk != 0) { + if (gCharacterEditorHasFreePerk != 0) { characterEditorWindowSelectedFolder = 0; - editorRenderFolders(); - windowRefresh(characterEditorWindowHandle); + characterEditorDrawFolders(); + windowRefresh(gCharacterEditorWindow); - int rc = editorSelectPerk(); + int rc = perkDialogShow(); if (rc == -1) { debugPrint("\n *** Error running perks dialog! ***\n"); return -1; } else if (rc == 0) { - editorRenderFolders(); + characterEditorDrawFolders(); } else if (rc == 1) { - editorRenderFolders(); - _free_perk = 0; + characterEditorDrawFolders(); + gCharacterEditorHasFreePerk = 0; } } - _last_level = level; + gCharacterEditorLastLevel = level; return 1; } // 0x43C398 -void _RedrwDPrks() +void perkDialogRefreshPerks() { blitBufferToBuffer( - gEditorPerkBackgroundBuffer + 280, + gPerkDialogBackgroundBuffer + 280, 293, PERK_WINDOW_HEIGHT, PERK_WINDOW_WIDTH, - gEditorPerkWindowBuffer + 280, + gPerkDialogWindowBuffer + 280, PERK_WINDOW_WIDTH); - _ListDPerks(); + perkDialogDrawPerks(); // NOTE: Original code is slightly different, but basically does the same thing. - int perk = _name_sort_list[_crow + _cline].field_0; + int perk = gPerkDialogOptionList[gPerkDialogTopLine + gPerkDialogCurrentLine].value; int perkFrmId = perkGetFrmId(perk); char* perkName = perkGetName(perk); char* perkDescription = perkGetDescription(perk); @@ -5356,26 +5525,26 @@ void _RedrwDPrks() perkRank = perkRankBuffer; } - _DrawCard2(perkFrmId, perkName, perkRank, perkDescription); + perkDialogDrawCard(perkFrmId, perkName, perkRank, perkDescription); - windowRefresh(gEditorPerkWindow); + windowRefresh(gPerkDialogWindow); } // 0x43C4F0 -int editorSelectPerk() +int perkDialogShow() { - _crow = 0; - _cline = 0; - _card_old_fid2 = -1; - _old_str2[0] = '\0'; - _frstc_draw2 = 0; + gPerkDialogTopLine = 0; + gPerkDialogCurrentLine = 0; + gPerkDialogCardFrmId = -1; + gPerkDialogCardTitle[0] = '\0'; + gPerkDialogCardDrawn = false; CacheEntry* backgroundFrmHandle; int backgroundWidth; int backgroundHeight; int fid = buildFid(6, 86, 0, 0, 0); - gEditorPerkBackgroundBuffer = artLockFrameDataReturningSize(fid, &backgroundFrmHandle, &backgroundWidth, &backgroundHeight); - if (gEditorPerkBackgroundBuffer == NULL) { + gPerkDialogBackgroundBuffer = artLockFrameDataReturningSize(fid, &backgroundFrmHandle, &backgroundWidth, &backgroundHeight); + if (gPerkDialogBackgroundBuffer == NULL) { debugPrint("\n *** Error running perks dialog window ***\n"); return -1; } @@ -5387,87 +5556,87 @@ int editorSelectPerk() int perkWindowY = screenGetHeight() != 480 ? (screenGetHeight() - PERK_WINDOW_HEIGHT) / 2 : PERK_WINDOW_Y; - gEditorPerkWindow = windowCreate(perkWindowX, perkWindowY, PERK_WINDOW_WIDTH, PERK_WINDOW_HEIGHT, 256, WINDOW_FLAG_0x10 | WINDOW_FLAG_0x02); - if (gEditorPerkWindow == -1) { + gPerkDialogWindow = windowCreate(perkWindowX, perkWindowY, PERK_WINDOW_WIDTH, PERK_WINDOW_HEIGHT, 256, WINDOW_FLAG_0x10 | WINDOW_FLAG_0x02); + if (gPerkDialogWindow == -1) { artUnlock(backgroundFrmHandle); debugPrint("\n *** Error running perks dialog window ***\n"); return -1; } - gEditorPerkWindowBuffer = windowGetBuffer(gEditorPerkWindow); - memcpy(gEditorPerkWindowBuffer, gEditorPerkBackgroundBuffer, PERK_WINDOW_WIDTH * PERK_WINDOW_HEIGHT); + gPerkDialogWindowBuffer = windowGetBuffer(gPerkDialogWindow); + memcpy(gPerkDialogWindowBuffer, gPerkDialogBackgroundBuffer, PERK_WINDOW_WIDTH * PERK_WINDOW_HEIGHT); int btn; - btn = buttonCreate(gEditorPerkWindow, + btn = buttonCreate(gPerkDialogWindow, 48, 186, - _GInfo[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP].width, - _GInfo[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP].height, -1, -1, -1, 500, - _grphbmp[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP], - _grphbmp[EDITOR_GRAPHIC_LILTTLE_RED_BUTTON_DOWN], + gCharacterEditorFrmData[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP], + gCharacterEditorFrmData[EDITOR_GRAPHIC_LILTTLE_RED_BUTTON_DOWN], NULL, BUTTON_FLAG_TRANSPARENT); if (btn != -1) { buttonSetCallbacks(btn, _gsound_red_butt_press, _gsound_red_butt_release); } - btn = buttonCreate(gEditorPerkWindow, + btn = buttonCreate(gPerkDialogWindow, 153, 186, - _GInfo[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP].width, - _GInfo[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP].height, -1, -1, -1, 502, - _grphbmp[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP], - _grphbmp[EDITOR_GRAPHIC_LILTTLE_RED_BUTTON_DOWN], + gCharacterEditorFrmData[EDITOR_GRAPHIC_LITTLE_RED_BUTTON_UP], + gCharacterEditorFrmData[EDITOR_GRAPHIC_LILTTLE_RED_BUTTON_DOWN], NULL, BUTTON_FLAG_TRANSPARENT); if (btn != -1) { buttonSetCallbacks(btn, _gsound_red_butt_press, _gsound_red_butt_release); } - btn = buttonCreate(gEditorPerkWindow, + btn = buttonCreate(gPerkDialogWindow, 25, 46, - _GInfo[EDITOR_GRAPHIC_UP_ARROW_ON].width, - _GInfo[EDITOR_GRAPHIC_UP_ARROW_ON].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_UP_ARROW_ON].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_UP_ARROW_ON].height, -1, 574, 572, 574, - _grphbmp[EDITOR_GRAPHIC_UP_ARROW_OFF], - _grphbmp[EDITOR_GRAPHIC_UP_ARROW_ON], + gCharacterEditorFrmData[EDITOR_GRAPHIC_UP_ARROW_OFF], + gCharacterEditorFrmData[EDITOR_GRAPHIC_UP_ARROW_ON], NULL, BUTTON_FLAG_TRANSPARENT); if (btn != -1) { buttonSetCallbacks(btn, _gsound_red_butt_press, NULL); } - btn = buttonCreate(gEditorPerkWindow, + btn = buttonCreate(gPerkDialogWindow, 25, - 47 + _GInfo[EDITOR_GRAPHIC_UP_ARROW_ON].height, - _GInfo[EDITOR_GRAPHIC_UP_ARROW_ON].width, - _GInfo[EDITOR_GRAPHIC_UP_ARROW_ON].height, + 47 + gCharacterEditorFrmSize[EDITOR_GRAPHIC_UP_ARROW_ON].height, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_UP_ARROW_ON].width, + gCharacterEditorFrmSize[EDITOR_GRAPHIC_UP_ARROW_ON].height, -1, 575, 573, 575, - _grphbmp[EDITOR_GRAPHIC_DOWN_ARROW_OFF], - _grphbmp[EDITOR_GRAPHIC_DOWN_ARROW_ON], + gCharacterEditorFrmData[EDITOR_GRAPHIC_DOWN_ARROW_OFF], + gCharacterEditorFrmData[EDITOR_GRAPHIC_DOWN_ARROW_ON], NULL, BUTTON_FLAG_TRANSPARENT); if (btn != -1) { buttonSetCallbacks(btn, _gsound_red_butt_press, NULL); } - buttonCreate(gEditorPerkWindow, + buttonCreate(gPerkDialogWindow, PERK_WINDOW_LIST_X, PERK_WINDOW_LIST_Y, PERK_WINDOW_LIST_WIDTH, @@ -5486,21 +5655,21 @@ int editorSelectPerk() const char* msg; // PICK A NEW PERK - msg = getmsg(&editorMessageList, &editorMessageListItem, 152); - fontDrawText(gEditorPerkWindowBuffer + PERK_WINDOW_WIDTH * 16 + 49, msg, PERK_WINDOW_WIDTH, PERK_WINDOW_WIDTH, _colorTable[18979]); + msg = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 152); + fontDrawText(gPerkDialogWindowBuffer + PERK_WINDOW_WIDTH * 16 + 49, msg, PERK_WINDOW_WIDTH, PERK_WINDOW_WIDTH, _colorTable[18979]); // DONE - msg = getmsg(&editorMessageList, &editorMessageListItem, 100); - fontDrawText(gEditorPerkWindowBuffer + PERK_WINDOW_WIDTH * 186 + 69, msg, PERK_WINDOW_WIDTH, PERK_WINDOW_WIDTH, _colorTable[18979]); + msg = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 100); + fontDrawText(gPerkDialogWindowBuffer + PERK_WINDOW_WIDTH * 186 + 69, msg, PERK_WINDOW_WIDTH, PERK_WINDOW_WIDTH, _colorTable[18979]); // CANCEL - msg = getmsg(&editorMessageList, &editorMessageListItem, 102); - fontDrawText(gEditorPerkWindowBuffer + PERK_WINDOW_WIDTH * 186 + 171, msg, PERK_WINDOW_WIDTH, PERK_WINDOW_WIDTH, _colorTable[18979]); + msg = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 102); + fontDrawText(gPerkDialogWindowBuffer + PERK_WINDOW_WIDTH * 186 + 171, msg, PERK_WINDOW_WIDTH, PERK_WINDOW_WIDTH, _colorTable[18979]); - int count = _ListDPerks(); + int count = perkDialogDrawPerks(); // NOTE: Original code is slightly different, but does the same thing. - int perk = _name_sort_list[_crow + _cline].field_0; + int perk = gPerkDialogOptionList[gPerkDialogTopLine + gPerkDialogCurrentLine].value; int perkFrmId = perkGetFrmId(perk); char* perkName = perkGetName(perk); char* perkDescription = perkGetDescription(perk); @@ -5513,13 +5682,13 @@ int editorSelectPerk() perkRank = perkRankBuffer; } - _DrawCard2(perkFrmId, perkName, perkRank, perkDescription); - windowRefresh(gEditorPerkWindow); + perkDialogDrawCard(perkFrmId, perkName, perkRank, perkDescription); + windowRefresh(gPerkDialogWindow); - int rc = _InputPDLoop(count, _RedrwDPrks); + int rc = perkDialogHandleInput(count, perkDialogRefreshPerks); if (rc == 1) { - if (perkAdd(gDude, _name_sort_list[_crow + _cline].field_0) == -1) { + if (perkAdd(gDude, gPerkDialogOptionList[gPerkDialogTopLine + gPerkDialogCurrentLine].value) == -1) { debugPrint("\n*** Unable to add perk! ***\n"); rc = 2; } @@ -5528,48 +5697,48 @@ int editorSelectPerk() rc &= 1; if (rc != 0) { - if (perkGetRank(gDude, PERK_TAG) != 0 && _perk_back[PERK_TAG] == 0) { - if (!editorHandleTag()) { + if (perkGetRank(gDude, PERK_TAG) != 0 && gCharacterEditorPerksBackup[PERK_TAG] == 0) { + if (!perkDialogHandleTagPerk()) { perkRemove(gDude, PERK_TAG); } - } else if (perkGetRank(gDude, PERK_MUTATE) != 0 && _perk_back[PERK_MUTATE] == 0) { - if (!editorHandleMutate()) { + } else if (perkGetRank(gDude, PERK_MUTATE) != 0 && gCharacterEditorPerksBackup[PERK_MUTATE] == 0) { + if (!perkDialogHandleMutatePerk()) { perkRemove(gDude, PERK_MUTATE); } - } else if (perkGetRank(gDude, PERK_LIFEGIVER) != _perk_back[PERK_LIFEGIVER]) { + } else if (perkGetRank(gDude, PERK_LIFEGIVER) != gCharacterEditorPerksBackup[PERK_LIFEGIVER]) { int maxHp = critterGetBonusStat(gDude, STAT_MAXIMUM_HIT_POINTS); critterSetBonusStat(gDude, STAT_MAXIMUM_HIT_POINTS, maxHp + 4); critterAdjustHitPoints(gDude, 4); - } else if (perkGetRank(gDude, PERK_EDUCATED) != _perk_back[PERK_EDUCATED]) { + } else if (perkGetRank(gDude, PERK_EDUCATED) != gCharacterEditorPerksBackup[PERK_EDUCATED]) { int sp = pcGetStat(PC_STAT_UNSPENT_SKILL_POINTS); pcSetStat(PC_STAT_UNSPENT_SKILL_POINTS, sp + 2); } } - editorRenderSkills(0); - editorRenderPrimaryStat(RENDER_ALL_STATS, 0, 0); - editorRenderPcStats(); - editorRenderSecondaryStats(); - editorRenderFolders(); - editorRenderDetails(); - windowRefresh(characterEditorWindowHandle); + characterEditorDrawSkills(0); + characterEditorDrawPrimaryStat(RENDER_ALL_STATS, 0, 0); + characterEditorDrawPcStats(); + characterEditorDrawDerivedStats(); + characterEditorDrawFolders(); + characterEditorDrawCard(); + windowRefresh(gCharacterEditorWindow); artUnlock(backgroundFrmHandle); - windowDestroy(gEditorPerkWindow); + windowDestroy(gPerkDialogWindow); return rc; } // 0x43CACC -int _InputPDLoop(int count, void (*refreshProc)()) +int perkDialogHandleInput(int count, void (*refreshProc)()) { fontSetCurrent(101); int v3 = count - 11; int height = fontGetLineHeight(); - _oldsline = -2; + gPerkDialogPreviousCurrentLine = -2; int v16 = height + 2; int v7 = 0; @@ -5585,51 +5754,51 @@ int _InputPDLoop(int count, void (*refreshProc)()) soundPlayFile("ib1p1xx1"); rc = 1; } else if (keyCode == 501) { - mouseGetPositionInWindow(gEditorPerkWindow , &_mouse_xpos, &_mouse_ypos); - _cline = (_mouse_ypos - PERK_WINDOW_LIST_Y) / v16; - if (_cline >= 0) { - if (count - 1 < _cline) - _cline = count - 1; + mouseGetPositionInWindow(gPerkDialogWindow , &gCharacterEditorMouseX, &gCharacterEditorMouseY); + gPerkDialogCurrentLine = (gCharacterEditorMouseY - PERK_WINDOW_LIST_Y) / v16; + if (gPerkDialogCurrentLine >= 0) { + if (count - 1 < gPerkDialogCurrentLine) + gPerkDialogCurrentLine = count - 1; } else { - _cline = 0; + gPerkDialogCurrentLine = 0; } - if (_cline == _oldsline) { + if (gPerkDialogCurrentLine == gPerkDialogPreviousCurrentLine) { soundPlayFile("ib1p1xx1"); rc = 1; } - _oldsline = _cline; + gPerkDialogPreviousCurrentLine = gPerkDialogCurrentLine; refreshProc(); } else if (keyCode == 502 || keyCode == KEY_ESCAPE || _game_user_wants_to_quit != 0) { rc = 2; } else { switch (keyCode) { case KEY_ARROW_UP: - _oldsline = -2; + gPerkDialogPreviousCurrentLine = -2; - _crow--; - if (_crow < 0) { - _crow = 0; + gPerkDialogTopLine--; + if (gPerkDialogTopLine < 0) { + gPerkDialogTopLine = 0; - _cline--; - if (_cline < 0) { - _cline = 0; + gPerkDialogCurrentLine--; + if (gPerkDialogCurrentLine < 0) { + gPerkDialogCurrentLine = 0; } } refreshProc(); break; case KEY_PAGE_UP: - _oldsline = -2; + gPerkDialogPreviousCurrentLine = -2; for (int index = 0; index < 11; index++) { - _crow--; - if (_crow < 0) { - _crow = 0; + gPerkDialogTopLine--; + if (gPerkDialogTopLine < 0) { + gPerkDialogTopLine = 0; - _cline--; - if (_cline < 0) { - _cline = 0; + gPerkDialogCurrentLine--; + if (gPerkDialogCurrentLine < 0) { + gPerkDialogCurrentLine = 0; } } } @@ -5637,45 +5806,45 @@ int _InputPDLoop(int count, void (*refreshProc)()) refreshProc(); break; case KEY_ARROW_DOWN: - _oldsline = -2; + gPerkDialogPreviousCurrentLine = -2; if (count > 11) { - _crow++; - if (_crow > count - 11) { - _crow = count - 11; + gPerkDialogTopLine++; + if (gPerkDialogTopLine > count - 11) { + gPerkDialogTopLine = count - 11; - _cline++; - if (_cline > 10) { - _cline = 10; + gPerkDialogCurrentLine++; + if (gPerkDialogCurrentLine > 10) { + gPerkDialogCurrentLine = 10; } } } else { - _cline++; - if (_cline > count - 1) { - _cline = count - 1; + gPerkDialogCurrentLine++; + if (gPerkDialogCurrentLine > count - 1) { + gPerkDialogCurrentLine = count - 1; } } refreshProc(); break; case KEY_PAGE_DOWN: - _oldsline = -2; + gPerkDialogPreviousCurrentLine = -2; for (int index = 0; index < 11; index++) { if (count > 11) { - _crow++; - if (_crow > count - 11) { - _crow = count - 11; + gPerkDialogTopLine++; + if (gPerkDialogTopLine > count - 11) { + gPerkDialogTopLine = count - 11; - _cline++; - if (_cline > 10) { - _cline = 10; + gPerkDialogCurrentLine++; + if (gPerkDialogCurrentLine > 10) { + gPerkDialogCurrentLine = 10; } } } else { - _cline++; - if (_cline > count - 1) { - _cline = count - 1; + gPerkDialogCurrentLine++; + if (gPerkDialogCurrentLine > count - 1) { + gPerkDialogCurrentLine = count - 1; } } } @@ -5684,7 +5853,7 @@ int _InputPDLoop(int count, void (*refreshProc)()) break; case 572: _repFtime = 4; - _oldsline = -2; + gPerkDialogPreviousCurrentLine = -2; do { _frame_time = _get_time(); @@ -5700,13 +5869,13 @@ int _InputPDLoop(int count, void (*refreshProc)()) } } - _crow--; - if (_crow < 0) { - _crow = 0; + gPerkDialogTopLine--; + if (gPerkDialogTopLine < 0) { + gPerkDialogTopLine = 0; - _cline--; - if (_cline < 0) { - _cline = 0; + gPerkDialogCurrentLine--; + if (gPerkDialogCurrentLine < 0) { + gPerkDialogCurrentLine = 0; } } refreshProc(); @@ -5723,7 +5892,7 @@ int _InputPDLoop(int count, void (*refreshProc)()) break; case 573: - _oldsline = -2; + gPerkDialogPreviousCurrentLine = -2; _repFtime = 4; if (count > 11) { @@ -5741,13 +5910,13 @@ int _InputPDLoop(int count, void (*refreshProc)()) } } - _crow++; - if (_crow > count - 11) { - _crow = count - 11; + gPerkDialogTopLine++; + if (gPerkDialogTopLine > count - 11) { + gPerkDialogTopLine = count - 11; - _cline++; - if (_cline > 10) { - _cline = 10; + gPerkDialogCurrentLine++; + if (gPerkDialogCurrentLine > 10) { + gPerkDialogCurrentLine = 10; } } @@ -5777,9 +5946,9 @@ int _InputPDLoop(int count, void (*refreshProc)()) } } - _cline++; - if (_cline > count - 1) { - _cline = count - 1; + gPerkDialogCurrentLine++; + if (gPerkDialogCurrentLine > count - 1) { + gPerkDialogCurrentLine = count - 1; } refreshProc(); @@ -5796,25 +5965,25 @@ int _InputPDLoop(int count, void (*refreshProc)()) } break; case KEY_HOME: - _crow = 0; - _cline = 0; - _oldsline = -2; + gPerkDialogTopLine = 0; + gPerkDialogCurrentLine = 0; + gPerkDialogPreviousCurrentLine = -2; refreshProc(); break; case KEY_END: - _oldsline = -2; + gPerkDialogPreviousCurrentLine = -2; if (count > 11) { - _crow = count - 11; - _cline = 10; + gPerkDialogTopLine = count - 11; + gPerkDialogCurrentLine = 10; } else { - _cline = count - 1; + gPerkDialogCurrentLine = count - 1; } refreshProc(); break; default: if (getTicksSince(_frame_time) > 700) { _frame_time = _get_time(); - _oldsline = -2; + gPerkDialogPreviousCurrentLine = -2; } break; } @@ -5825,14 +5994,14 @@ int _InputPDLoop(int count, void (*refreshProc)()) } // 0x43D0BC -int _ListDPerks() +int perkDialogDrawPerks() { blitBufferToBuffer( - gEditorPerkBackgroundBuffer + PERK_WINDOW_WIDTH * 43 + 45, + gPerkDialogBackgroundBuffer + PERK_WINDOW_WIDTH * 43 + 45, 192, 129, PERK_WINDOW_WIDTH, - gEditorPerkWindowBuffer + PERK_WINDOW_WIDTH * 43 + 45, + gPerkDialogWindowBuffer + PERK_WINDOW_WIDTH * 43 + 45, PERK_WINDOW_WIDTH); fontSetCurrent(101); @@ -5844,40 +6013,40 @@ int _ListDPerks() } for (int perk = 0; perk < PERK_COUNT; perk++) { - _name_sort_list[perk].field_0 = 0; - _name_sort_list[perk].field_4 = NULL; + gPerkDialogOptionList[perk].value = 0; + gPerkDialogOptionList[perk].name = NULL; } for (int index = 0; index < count; index++) { - _name_sort_list[index].field_0 = perks[index]; - _name_sort_list[index].field_4 = perkGetName(perks[index]); + gPerkDialogOptionList[index].value = perks[index]; + gPerkDialogOptionList[index].name = perkGetName(perks[index]); } - qsort(_name_sort_list, count, sizeof(*_name_sort_list), _name_sort_comp); + qsort(gPerkDialogOptionList, count, sizeof(*gPerkDialogOptionList), perkDialogOptionCompare); - int v16 = count - _crow; + int v16 = count - gPerkDialogTopLine; if (v16 > 11) { v16 = 11; } - v16 += _crow; + v16 += gPerkDialogTopLine; int y = 43; int yStep = fontGetLineHeight() + 2; - for (int index = _crow; index < v16; index++) { + for (int index = gPerkDialogTopLine; index < v16; index++) { int color; - if (index == _crow + _cline) { + if (index == gPerkDialogTopLine + gPerkDialogCurrentLine) { color = _colorTable[32747]; } else { color = _colorTable[992]; } - fontDrawText(gEditorPerkWindowBuffer + PERK_WINDOW_WIDTH * y + 45, _name_sort_list[index].field_4, PERK_WINDOW_WIDTH, PERK_WINDOW_WIDTH, color); + fontDrawText(gPerkDialogWindowBuffer + PERK_WINDOW_WIDTH * y + 45, gPerkDialogOptionList[index].name, PERK_WINDOW_WIDTH, PERK_WINDOW_WIDTH, color); - if (perkGetRank(gDude, _name_sort_list[index].field_0) != 0) { + if (perkGetRank(gDude, gPerkDialogOptionList[index].value) != 0) { char rankString[256]; - sprintf(rankString, "(%d)", perkGetRank(gDude, _name_sort_list[index].field_0)); - fontDrawText(gEditorPerkWindowBuffer + PERK_WINDOW_WIDTH * y + 207, rankString, PERK_WINDOW_WIDTH, PERK_WINDOW_WIDTH, color); + sprintf(rankString, "(%d)", perkGetRank(gDude, gPerkDialogOptionList[index].value)); + fontDrawText(gPerkDialogWindowBuffer + PERK_WINDOW_WIDTH * y + 207, rankString, PERK_WINDOW_WIDTH, PERK_WINDOW_WIDTH, color); } y += yStep; @@ -5887,74 +6056,74 @@ int _ListDPerks() } // 0x43D2F8 -void _RedrwDMPrk() +void perkDialogRefreshTraits() { - blitBufferToBuffer(gEditorPerkBackgroundBuffer + 280, 293, PERK_WINDOW_HEIGHT, PERK_WINDOW_WIDTH, gEditorPerkWindowBuffer + 280, PERK_WINDOW_WIDTH); + blitBufferToBuffer(gPerkDialogBackgroundBuffer + 280, 293, PERK_WINDOW_HEIGHT, PERK_WINDOW_WIDTH, gPerkDialogWindowBuffer + 280, PERK_WINDOW_WIDTH); - _ListMyTraits(_optrt_count); + perkDialogDrawTraits(gPerkDialogOptionCount); - char* traitName = _name_sort_list[_crow + _cline].field_4; - char* tratDescription = traitGetDescription(_name_sort_list[_crow + _cline].field_0); - int frmId = traitGetFrmId(_name_sort_list[_crow + _cline].field_0); - _DrawCard2(frmId, traitName, NULL, tratDescription); + char* traitName = gPerkDialogOptionList[gPerkDialogTopLine + gPerkDialogCurrentLine].name; + char* tratDescription = traitGetDescription(gPerkDialogOptionList[gPerkDialogTopLine + gPerkDialogCurrentLine].value); + int frmId = traitGetFrmId(gPerkDialogOptionList[gPerkDialogTopLine + gPerkDialogCurrentLine].value); + perkDialogDrawCard(frmId, traitName, NULL, tratDescription); - windowRefresh(gEditorPerkWindow); + windowRefresh(gPerkDialogWindow); } // 0x43D38C -bool editorHandleMutate() +bool perkDialogHandleMutatePerk() { - _card_old_fid2 = -1; - _old_str2[0] = '\0'; - _frstc_draw2 = 0; + gPerkDialogCardFrmId = -1; + gPerkDialogCardTitle[0] = '\0'; + gPerkDialogCardDrawn = false; int traitCount = TRAITS_MAX_SELECTED_COUNT - 1; int traitIndex = 0; while (traitCount >= 0) { - if (_temp_trait[traitIndex] != -1) { + if (gCharacterEditorTempTraits[traitIndex] != -1) { break; } traitCount--; traitIndex++; } - _trait_count = TRAITS_MAX_SELECTED_COUNT - traitIndex; + gCharacterEditorTempTraitCount = TRAITS_MAX_SELECTED_COUNT - traitIndex; bool result = true; - if (_trait_count >= 1) { + if (gCharacterEditorTempTraitCount >= 1) { fontSetCurrent(103); - blitBufferToBuffer(gEditorPerkBackgroundBuffer + PERK_WINDOW_WIDTH * 14 + 49, 206, fontGetLineHeight() + 2, PERK_WINDOW_WIDTH, gEditorPerkWindowBuffer + PERK_WINDOW_WIDTH * 15 + 49, PERK_WINDOW_WIDTH); + blitBufferToBuffer(gPerkDialogBackgroundBuffer + PERK_WINDOW_WIDTH * 14 + 49, 206, fontGetLineHeight() + 2, PERK_WINDOW_WIDTH, gPerkDialogWindowBuffer + PERK_WINDOW_WIDTH * 15 + 49, PERK_WINDOW_WIDTH); // LOSE A TRAIT - char* msg = getmsg(&editorMessageList, &editorMessageListItem, 154); - fontDrawText(gEditorPerkWindowBuffer + PERK_WINDOW_WIDTH * 16 + 49, msg, PERK_WINDOW_WIDTH, PERK_WINDOW_WIDTH, _colorTable[18979]); + char* msg = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 154); + fontDrawText(gPerkDialogWindowBuffer + PERK_WINDOW_WIDTH * 16 + 49, msg, PERK_WINDOW_WIDTH, PERK_WINDOW_WIDTH, _colorTable[18979]); - _optrt_count = 0; - _cline = 0; - _crow = 0; - _RedrwDMPrk(); + gPerkDialogOptionCount = 0; + gPerkDialogCurrentLine = 0; + gPerkDialogTopLine = 0; + perkDialogRefreshTraits(); - int rc = _InputPDLoop(_trait_count, _RedrwDMPrk); + int rc = perkDialogHandleInput(gCharacterEditorTempTraitCount, perkDialogRefreshTraits); if (rc == 1) { - if (_cline == 0) { - if (_trait_count == 1) { - _temp_trait[0] = -1; - _temp_trait[1] = -1; + if (gPerkDialogCurrentLine == 0) { + if (gCharacterEditorTempTraitCount == 1) { + gCharacterEditorTempTraits[0] = -1; + gCharacterEditorTempTraits[1] = -1; } else { - if (_name_sort_list[0].field_0 == _temp_trait[0]) { - _temp_trait[0] = _temp_trait[1]; - _temp_trait[1] = -1; + if (gPerkDialogOptionList[0].value == gCharacterEditorTempTraits[0]) { + gCharacterEditorTempTraits[0] = gCharacterEditorTempTraits[1]; + gCharacterEditorTempTraits[1] = -1; } else { - _temp_trait[1] = -1; + gCharacterEditorTempTraits[1] = -1; } } } else { - if (_name_sort_list[0].field_0 == _temp_trait[0]) { - _temp_trait[1] = -1; + if (gPerkDialogOptionList[0].value == gCharacterEditorTempTraits[0]) { + gCharacterEditorTempTraits[1] = -1; } else { - _temp_trait[0] = _temp_trait[1]; - _temp_trait[1] = -1; + gCharacterEditorTempTraits[0] = gCharacterEditorTempTraits[1]; + gCharacterEditorTempTraits[1] = -1; } } } else { @@ -5965,130 +6134,130 @@ bool editorHandleMutate() if (result) { fontSetCurrent(103); - blitBufferToBuffer(gEditorPerkBackgroundBuffer + PERK_WINDOW_WIDTH * 14 + 49, 206, fontGetLineHeight() + 2, PERK_WINDOW_WIDTH, gEditorPerkWindowBuffer + PERK_WINDOW_WIDTH * 15 + 49, PERK_WINDOW_WIDTH); + blitBufferToBuffer(gPerkDialogBackgroundBuffer + PERK_WINDOW_WIDTH * 14 + 49, 206, fontGetLineHeight() + 2, PERK_WINDOW_WIDTH, gPerkDialogWindowBuffer + PERK_WINDOW_WIDTH * 15 + 49, PERK_WINDOW_WIDTH); // PICK A NEW TRAIT - char* msg = getmsg(&editorMessageList, &editorMessageListItem, 153); - fontDrawText(gEditorPerkWindowBuffer + PERK_WINDOW_WIDTH * 16 + 49, msg, PERK_WINDOW_WIDTH, PERK_WINDOW_WIDTH, _colorTable[18979]); + char* msg = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 153); + fontDrawText(gPerkDialogWindowBuffer + PERK_WINDOW_WIDTH * 16 + 49, msg, PERK_WINDOW_WIDTH, PERK_WINDOW_WIDTH, _colorTable[18979]); - _cline = 0; - _crow = 0; - _optrt_count = 1; + gPerkDialogCurrentLine = 0; + gPerkDialogTopLine = 0; + gPerkDialogOptionCount = 1; - _RedrwDMPrk(); + perkDialogRefreshTraits(); - int count = 16 - _trait_count; + int count = 16 - gCharacterEditorTempTraitCount; if (count > 16) { count = 16; } - int rc = _InputPDLoop(count, _RedrwDMPrk); + int rc = perkDialogHandleInput(count, perkDialogRefreshTraits); if (rc == 1) { - if (_trait_count != 0) { - _temp_trait[1] = _name_sort_list[_cline + _crow].field_0; + if (gCharacterEditorTempTraitCount != 0) { + gCharacterEditorTempTraits[1] = gPerkDialogOptionList[gPerkDialogCurrentLine + gPerkDialogTopLine].value; } else { - _temp_trait[0] = _name_sort_list[_cline + _crow].field_0; - _temp_trait[1] = -1; + gCharacterEditorTempTraits[0] = gPerkDialogOptionList[gPerkDialogCurrentLine + gPerkDialogTopLine].value; + gCharacterEditorTempTraits[1] = -1; } - traitsSetSelected(_temp_trait[0], _temp_trait[1]); + traitsSetSelected(gCharacterEditorTempTraits[0], gCharacterEditorTempTraits[1]); } else { result = false; } } if (!result) { - memcpy(_temp_trait, _trait_back, sizeof(_temp_trait)); + memcpy(gCharacterEditorTempTraits, gCharacterEditorOptionalTraitsBackup, sizeof(gCharacterEditorTempTraits)); } return result; } // 0x43D668 -void _RedrwDMTagSkl() +void perkDialogRefreshSkills() { - blitBufferToBuffer(gEditorPerkBackgroundBuffer + 280, 293, PERK_WINDOW_HEIGHT, PERK_WINDOW_WIDTH, gEditorPerkWindowBuffer + 280, PERK_WINDOW_WIDTH); + blitBufferToBuffer(gPerkDialogBackgroundBuffer + 280, 293, PERK_WINDOW_HEIGHT, PERK_WINDOW_WIDTH, gPerkDialogWindowBuffer + 280, PERK_WINDOW_WIDTH); - _ListNewTagSkills(); + perkDialogDrawSkills(); - char* name = _name_sort_list[_crow + _cline].field_4; - char* description = skillGetDescription(_name_sort_list[_crow + _cline].field_0); - int frmId = skillGetFrmId(_name_sort_list[_crow + _cline].field_0); - _DrawCard2(frmId, name, NULL, description); + char* name = gPerkDialogOptionList[gPerkDialogTopLine + gPerkDialogCurrentLine].name; + char* description = skillGetDescription(gPerkDialogOptionList[gPerkDialogTopLine + gPerkDialogCurrentLine].value); + int frmId = skillGetFrmId(gPerkDialogOptionList[gPerkDialogTopLine + gPerkDialogCurrentLine].value); + perkDialogDrawCard(frmId, name, NULL, description); - windowRefresh(gEditorPerkWindow); + windowRefresh(gPerkDialogWindow); } // 0x43D6F8 -bool editorHandleTag() +bool perkDialogHandleTagPerk() { fontSetCurrent(103); - blitBufferToBuffer(gEditorPerkBackgroundBuffer + 573 * 14 + 49, 206, fontGetLineHeight() + 2, 573, gEditorPerkWindowBuffer + 573 * 15 + 49, 573); + blitBufferToBuffer(gPerkDialogBackgroundBuffer + 573 * 14 + 49, 206, fontGetLineHeight() + 2, 573, gPerkDialogWindowBuffer + 573 * 15 + 49, 573); // PICK A NEW TAG SKILL - char* messageListItemText = getmsg(&editorMessageList, &editorMessageListItem, 155); - fontDrawText(gEditorPerkWindowBuffer + 573 * 16 + 49, messageListItemText, 573, 573, _colorTable[18979]); + char* messageListItemText = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 155); + fontDrawText(gPerkDialogWindowBuffer + 573 * 16 + 49, messageListItemText, 573, 573, _colorTable[18979]); - _cline = 0; - _crow = 0; - _card_old_fid2 = -1; - _old_str2[0] = '\0'; - _frstc_draw2 = 0; - _RedrwDMTagSkl(); + gPerkDialogCurrentLine = 0; + gPerkDialogTopLine = 0; + gPerkDialogCardFrmId = -1; + gPerkDialogCardTitle[0] = '\0'; + gPerkDialogCardDrawn = false; + perkDialogRefreshSkills(); - int rc = _InputPDLoop(_optrt_count, _RedrwDMTagSkl); + int rc = perkDialogHandleInput(gPerkDialogOptionCount, perkDialogRefreshSkills); if (rc != 1) { - memcpy(_temp_tag_skill, _tag_skill_back, sizeof(_temp_tag_skill)); - skillsSetTagged(_tag_skill_back, NUM_TAGGED_SKILLS); + memcpy(gCharacterEditorTempTaggedSkills, gCharacterEditorTaggedSkillsBackup, sizeof(gCharacterEditorTempTaggedSkills)); + skillsSetTagged(gCharacterEditorTaggedSkillsBackup, NUM_TAGGED_SKILLS); return false; } - _temp_tag_skill[3] = _name_sort_list[_crow + _cline].field_0; - skillsSetTagged(_temp_tag_skill, NUM_TAGGED_SKILLS); + gCharacterEditorTempTaggedSkills[3] = gPerkDialogOptionList[gPerkDialogTopLine + gPerkDialogCurrentLine].value; + skillsSetTagged(gCharacterEditorTempTaggedSkills, NUM_TAGGED_SKILLS); return true; } // 0x43D81C -void _ListNewTagSkills() +void perkDialogDrawSkills() { - blitBufferToBuffer(gEditorPerkBackgroundBuffer + PERK_WINDOW_WIDTH * 43 + 45, 192, 129, PERK_WINDOW_WIDTH, gEditorPerkWindowBuffer + PERK_WINDOW_WIDTH * 43 + 45, PERK_WINDOW_WIDTH); + blitBufferToBuffer(gPerkDialogBackgroundBuffer + PERK_WINDOW_WIDTH * 43 + 45, 192, 129, PERK_WINDOW_WIDTH, gPerkDialogWindowBuffer + PERK_WINDOW_WIDTH * 43 + 45, PERK_WINDOW_WIDTH); fontSetCurrent(101); - _optrt_count = 0; + gPerkDialogOptionCount = 0; int y = 43; int yStep = fontGetLineHeight() + 2; for (int skill = 0; skill < SKILL_COUNT; skill++) { - if (skill != _temp_tag_skill[0] && skill != _temp_tag_skill[1] && skill != _temp_tag_skill[2] && skill != _temp_tag_skill[3]) { - _name_sort_list[_optrt_count].field_0 = skill; - _name_sort_list[_optrt_count].field_4 = skillGetName(skill); - _optrt_count++; + if (skill != gCharacterEditorTempTaggedSkills[0] && skill != gCharacterEditorTempTaggedSkills[1] && skill != gCharacterEditorTempTaggedSkills[2] && skill != gCharacterEditorTempTaggedSkills[3]) { + gPerkDialogOptionList[gPerkDialogOptionCount].value = skill; + gPerkDialogOptionList[gPerkDialogOptionCount].name = skillGetName(skill); + gPerkDialogOptionCount++; } } - qsort(_name_sort_list, _optrt_count, sizeof(*_name_sort_list), _name_sort_comp); + qsort(gPerkDialogOptionList, gPerkDialogOptionCount, sizeof(*gPerkDialogOptionList), perkDialogOptionCompare); - for (int index = _crow; index < _crow + 11; index++) { + for (int index = gPerkDialogTopLine; index < gPerkDialogTopLine + 11; index++) { int color; - if (index == _cline + _crow) { + if (index == gPerkDialogCurrentLine + gPerkDialogTopLine) { color = _colorTable[32747]; } else { color = _colorTable[992]; } - fontDrawText(gEditorPerkWindowBuffer + PERK_WINDOW_WIDTH * y + 45, _name_sort_list[index].field_4, PERK_WINDOW_WIDTH, PERK_WINDOW_WIDTH, color); + fontDrawText(gPerkDialogWindowBuffer + PERK_WINDOW_WIDTH * y + 45, gPerkDialogOptionList[index].name, PERK_WINDOW_WIDTH, PERK_WINDOW_WIDTH, color); y += yStep; } } // 0x43D960 -int _ListMyTraits(int a1) +int perkDialogDrawTraits(int a1) { - blitBufferToBuffer(gEditorPerkBackgroundBuffer + PERK_WINDOW_WIDTH * 43 + 45, 192, 129, PERK_WINDOW_WIDTH, gEditorPerkWindowBuffer + PERK_WINDOW_WIDTH * 43 + 45, PERK_WINDOW_WIDTH); + blitBufferToBuffer(gPerkDialogBackgroundBuffer + PERK_WINDOW_WIDTH * 43 + 45, 192, 129, PERK_WINDOW_WIDTH, gPerkDialogWindowBuffer + PERK_WINDOW_WIDTH * 43 + 45, PERK_WINDOW_WIDTH); fontSetCurrent(101); @@ -6098,46 +6267,46 @@ int _ListMyTraits(int a1) if (a1 != 0) { int count = 0; for (int trait = 0; trait < TRAIT_COUNT; trait++) { - if (trait != _trait_back[0] && trait != _trait_back[1]) { - _name_sort_list[count].field_0 = trait; - _name_sort_list[count].field_4 = traitGetName(trait); + if (trait != gCharacterEditorOptionalTraitsBackup[0] && trait != gCharacterEditorOptionalTraitsBackup[1]) { + gPerkDialogOptionList[count].value = trait; + gPerkDialogOptionList[count].name = traitGetName(trait); count++; } } - qsort(_name_sort_list, count, sizeof(*_name_sort_list), _name_sort_comp); + qsort(gPerkDialogOptionList, count, sizeof(*gPerkDialogOptionList), perkDialogOptionCompare); - for (int index = _crow; index < _crow + 11; index++) { + for (int index = gPerkDialogTopLine; index < gPerkDialogTopLine + 11; index++) { int color; - if (index == _cline + _crow) { + if (index == gPerkDialogCurrentLine + gPerkDialogTopLine) { color = _colorTable[32747]; } else { color = _colorTable[992]; } - fontDrawText(gEditorPerkWindowBuffer + PERK_WINDOW_WIDTH * y + 45, _name_sort_list[index].field_4, PERK_WINDOW_WIDTH, PERK_WINDOW_WIDTH, color); + fontDrawText(gPerkDialogWindowBuffer + PERK_WINDOW_WIDTH * y + 45, gPerkDialogOptionList[index].name, PERK_WINDOW_WIDTH, PERK_WINDOW_WIDTH, color); y += yStep; } } else { // NOTE: Original code does not use loop. for (int index = 0; index < TRAITS_MAX_SELECTED_COUNT; index++) { - _name_sort_list[index].field_0 = _temp_trait[index]; - _name_sort_list[index].field_4 = traitGetName(_temp_trait[index]); + gPerkDialogOptionList[index].value = gCharacterEditorTempTraits[index]; + gPerkDialogOptionList[index].name = traitGetName(gCharacterEditorTempTraits[index]); } - if (_trait_count > 1) { - qsort(_name_sort_list, _trait_count, sizeof(*_name_sort_list), _name_sort_comp); + if (gCharacterEditorTempTraitCount > 1) { + qsort(gPerkDialogOptionList, gCharacterEditorTempTraitCount, sizeof(*gPerkDialogOptionList), perkDialogOptionCompare); } - for (int index = 0; index < _trait_count; index++) { + for (int index = 0; index < gCharacterEditorTempTraitCount; index++) { int color; - if (index == _cline) { + if (index == gPerkDialogCurrentLine) { color = _colorTable[32747]; } else { color = _colorTable[992]; } - fontDrawText(gEditorPerkWindowBuffer + PERK_WINDOW_WIDTH * y + 45, _name_sort_list[index].field_4, PERK_WINDOW_WIDTH, PERK_WINDOW_WIDTH, color); + fontDrawText(gPerkDialogWindowBuffer + PERK_WINDOW_WIDTH * y + 45, gPerkDialogOptionList[index].name, PERK_WINDOW_WIDTH, PERK_WINDOW_WIDTH, color); y += yStep; } } @@ -6145,15 +6314,15 @@ int _ListMyTraits(int a1) } // 0x43DB48 -int _name_sort_comp(const void* a1, const void* a2) +int perkDialogOptionCompare(const void* a1, const void* a2) { - STRUCT_56FCB0* v1 = (STRUCT_56FCB0*)a1; - STRUCT_56FCB0* v2 = (STRUCT_56FCB0*)a2; - return strcmp(v1->field_4, v2->field_4); + PerkDialogOption* v1 = (PerkDialogOption*)a1; + PerkDialogOption* v2 = (PerkDialogOption*)a2; + return strcmp(v1->name, v2->name); } // 0x43DB54 -int _DrawCard2(int frmId, const char* name, const char* rank, char* description) +int perkDialogDrawCard(int frmId, const char* name, const char* rank, char* description) { int fid = buildFid(10, frmId, 0, 0, 0); @@ -6165,7 +6334,7 @@ int _DrawCard2(int frmId, const char* name, const char* rank, char* description) return -1; } - blitBufferToBuffer(data, width, height, width, gEditorPerkWindowBuffer + PERK_WINDOW_WIDTH * 64 + 413, PERK_WINDOW_WIDTH); + blitBufferToBuffer(data, width, height, width, gPerkDialogWindowBuffer + PERK_WINDOW_WIDTH * 64 + 413, PERK_WINDOW_WIDTH); // Calculate width of transparent pixels on the left side of the image. This // space will be occupied by description (in addition to fixed width). @@ -6192,18 +6361,18 @@ int _DrawCard2(int frmId, const char* name, const char* rank, char* description) fontSetCurrent(102); int nameHeight = fontGetLineHeight(); - fontDrawText(gEditorPerkWindowBuffer + PERK_WINDOW_WIDTH * 27 + 280, name, PERK_WINDOW_WIDTH, PERK_WINDOW_WIDTH, _colorTable[0]); + fontDrawText(gPerkDialogWindowBuffer + PERK_WINDOW_WIDTH * 27 + 280, name, PERK_WINDOW_WIDTH, PERK_WINDOW_WIDTH, _colorTable[0]); if (rank != NULL) { int rankX = fontGetStringWidth(name) + 280 + 8; fontSetCurrent(101); int rankHeight = fontGetLineHeight(); - fontDrawText(gEditorPerkWindowBuffer + PERK_WINDOW_WIDTH * (23 + nameHeight - rankHeight) + rankX, rank, PERK_WINDOW_WIDTH, PERK_WINDOW_WIDTH, _colorTable[0]); + fontDrawText(gPerkDialogWindowBuffer + PERK_WINDOW_WIDTH * (23 + nameHeight - rankHeight) + rankX, rank, PERK_WINDOW_WIDTH, PERK_WINDOW_WIDTH, _colorTable[0]); } - windowDrawLine(gEditorPerkWindow, 280, 27 + nameHeight, 545, 27 + nameHeight, _colorTable[0]); - windowDrawLine(gEditorPerkWindow, 280, 28 + nameHeight, 545, 28 + nameHeight, _colorTable[0]); + windowDrawLine(gPerkDialogWindow, 280, 27 + nameHeight, 545, 27 + nameHeight, _colorTable[0]); + windowDrawLine(gPerkDialogWindow, 280, 28 + nameHeight, 545, 28 + nameHeight, _colorTable[0]); fontSetCurrent(101); @@ -6224,23 +6393,23 @@ int _DrawCard2(int frmId, const char* name, const char* rank, char* description) char ch = *ending; *ending = '\0'; - fontDrawText(gEditorPerkWindowBuffer + PERK_WINDOW_WIDTH * y + 280, beginning, PERK_WINDOW_WIDTH, PERK_WINDOW_WIDTH, _colorTable[0]); + fontDrawText(gPerkDialogWindowBuffer + PERK_WINDOW_WIDTH * y + 280, beginning, PERK_WINDOW_WIDTH, PERK_WINDOW_WIDTH, _colorTable[0]); *ending = ch; y += yStep; } - if (frmId != _card_old_fid2 || strcmp(_old_str2, name) != 0) { - if (_frstc_draw2) { + if (frmId != gPerkDialogCardFrmId || strcmp(gPerkDialogCardTitle, name) != 0) { + if (gPerkDialogCardDrawn) { soundPlayFile("isdxxxx1"); } } - strcpy(_old_str2, name); - - _card_old_fid2 = frmId; - _frstc_draw2 = 1; + strcpy(gPerkDialogCardTitle, name); + gPerkDialogCardFrmId = frmId; + gPerkDialogCardDrawn = true; + artUnlock(handle); return 0; @@ -6254,7 +6423,7 @@ void _pop_perks() for (int perk = 0; perk < PERK_COUNT; perk++) { for (;;) { int rank = perkGetRank(gDude, perk); - if (rank <= _perk_back[perk]) { + if (rank <= gCharacterEditorPerksBackup[perk]) { break; } @@ -6265,7 +6434,7 @@ void _pop_perks() for (int i = 0; i < PERK_COUNT; i++) { for (;;) { int rank = perkGetRank(gDude, i); - if (rank >= _perk_back[i]) { + if (rank >= gCharacterEditorPerksBackup[i]) { break; } @@ -6291,130 +6460,130 @@ int _is_supper_bonus() } // 0x43DF8C -int _folder_init() +int characterEditorFolderViewInit() { - _folder_karma_top_line = 0; - _folder_perk_top_line = 0; - _folder_kills_top_line = 0; + gCharacterEditorKarmaFolderTopLine = 0; + gCharacterEditorPerkFolderTopLine = 0; + gCharacterEditorKillsFolderTopLine = 0; - if (_folder_up_button == -1) { - _folder_up_button = buttonCreate(characterEditorWindowHandle, 317, 364, _GInfo[22].width, _GInfo[22].height, -1, -1, -1, 17000, _grphbmp[21], _grphbmp[22], NULL, 32); - if (_folder_up_button == -1) { + if (gCharacterEditorFolderViewScrollUpBtn == -1) { + gCharacterEditorFolderViewScrollUpBtn = buttonCreate(gCharacterEditorWindow, 317, 364, gCharacterEditorFrmSize[22].width, gCharacterEditorFrmSize[22].height, -1, -1, -1, 17000, gCharacterEditorFrmData[21], gCharacterEditorFrmData[22], NULL, 32); + if (gCharacterEditorFolderViewScrollUpBtn == -1) { return -1; } - buttonSetCallbacks(_folder_up_button, _gsound_red_butt_press, NULL); + buttonSetCallbacks(gCharacterEditorFolderViewScrollUpBtn, _gsound_red_butt_press, NULL); } - if (_folder_down_button == -1) { - _folder_down_button = buttonCreate(characterEditorWindowHandle, + if (gCharacterEditorFolderViewScrollDownBtn == -1) { + gCharacterEditorFolderViewScrollDownBtn = buttonCreate(gCharacterEditorWindow, 317, - 365 + _GInfo[22].height, - _GInfo[4].width, - _GInfo[4].height, - _folder_down_button, - _folder_down_button, - _folder_down_button, + 365 + gCharacterEditorFrmSize[22].height, + gCharacterEditorFrmSize[4].width, + gCharacterEditorFrmSize[4].height, + gCharacterEditorFolderViewScrollDownBtn, + gCharacterEditorFolderViewScrollDownBtn, + gCharacterEditorFolderViewScrollDownBtn, 17001, - _grphbmp[3], - _grphbmp[4], + gCharacterEditorFrmData[3], + gCharacterEditorFrmData[4], 0, 32); - if (_folder_down_button == -1) { - buttonDestroy(_folder_up_button); + if (gCharacterEditorFolderViewScrollDownBtn == -1) { + buttonDestroy(gCharacterEditorFolderViewScrollUpBtn); return -1; } - buttonSetCallbacks(_folder_down_button, _gsound_red_butt_press, NULL); + buttonSetCallbacks(gCharacterEditorFolderViewScrollDownBtn, _gsound_red_butt_press, NULL); } return 0; } // 0x43E0D4 -void _folder_scroll(int direction) +void characterEditorFolderViewScroll(int direction) { int* v1; switch (characterEditorWindowSelectedFolder) { case EDITOR_FOLDER_PERKS: - v1 = &_folder_perk_top_line; + v1 = &gCharacterEditorPerkFolderTopLine; break; case EDITOR_FOLDER_KARMA: - v1 = &_folder_karma_top_line; + v1 = &gCharacterEditorKarmaFolderTopLine; break; case EDITOR_FOLDER_KILLS: - v1 = &_folder_kills_top_line; + v1 = &gCharacterEditorKillsFolderTopLine; break; default: return; } if (direction >= 0) { - if (_folder_max_lines + _folder_top_line <= _folder_line) { - _folder_top_line++; + if (gCharacterEditorFolderViewMaxLines + gCharacterEditorFolderViewTopLine <= gCharacterEditorFolderViewCurrentLine) { + gCharacterEditorFolderViewTopLine++; if (characterEditorSelectedItem >= 10 && characterEditorSelectedItem < 43 && characterEditorSelectedItem != 10) { characterEditorSelectedItem--; } } } else { - if (_folder_top_line > 0) { - _folder_top_line--; - if (characterEditorSelectedItem >= 10 && characterEditorSelectedItem < 43 && _folder_max_lines + 9 > characterEditorSelectedItem) { + if (gCharacterEditorFolderViewTopLine > 0) { + gCharacterEditorFolderViewTopLine--; + if (characterEditorSelectedItem >= 10 && characterEditorSelectedItem < 43 && gCharacterEditorFolderViewMaxLines + 9 > characterEditorSelectedItem) { characterEditorSelectedItem++; } } } - *v1 = _folder_top_line; - editorRenderFolders(); + *v1 = gCharacterEditorFolderViewTopLine; + characterEditorDrawFolders(); if (characterEditorSelectedItem >= 10 && characterEditorSelectedItem < 43) { blitBufferToBuffer( - characterEditorWindowBackgroundBuf + 640 * 267 + 345, + gCharacterEditorWindowBackgroundBuffer + 640 * 267 + 345, 277, 170, 640, - characterEditorWindowBuf + 640 * 267 + 345, + gCharacterEditorWindowBuffer + 640 * 267 + 345, 640); - _DrawCard(_folder_card_fid, _folder_card_title, _folder_card_title2, _folder_card_desc); + characterEditorDrawCardWithOptions(gCharacterEditorFolderCardFrmId, gCharacterEditorFolderCardTitle, gCharacterEditorFolderCardSubtitle, gCharacterEditorFolderCardDescription); } } // 0x43E200 -void _folder_clear() +void characterEditorFolderViewClear() { int v0; - _folder_line = 0; - _folder_ypos = 364; + gCharacterEditorFolderViewCurrentLine = 0; + gCharacterEditorFolderViewNextY = 364; v0 = fontGetLineHeight(); - _folder_max_lines = 9; - _folder_yoffset = v0 + 1; + gCharacterEditorFolderViewMaxLines = 9; + gCharacterEditorFolderViewOffsetY = v0 + 1; if (characterEditorSelectedItem < 10 || characterEditorSelectedItem >= 43) - _folder_highlight_line = -1; + gCharacterEditorFolderViewHighlightedLine = -1; else - _folder_highlight_line = characterEditorSelectedItem - 10; + gCharacterEditorFolderViewHighlightedLine = characterEditorSelectedItem - 10; if (characterEditorWindowSelectedFolder < 1) { if (characterEditorWindowSelectedFolder) return; - _folder_top_line = _folder_perk_top_line; + gCharacterEditorFolderViewTopLine = gCharacterEditorPerkFolderTopLine; } else if (characterEditorWindowSelectedFolder == 1) { - _folder_top_line = _folder_karma_top_line; + gCharacterEditorFolderViewTopLine = gCharacterEditorKarmaFolderTopLine; } else if (characterEditorWindowSelectedFolder == 2) { - _folder_top_line = _folder_kills_top_line; + gCharacterEditorFolderViewTopLine = gCharacterEditorKillsFolderTopLine; } } // render heading string with line // // 0x43E28C -int _folder_print_seperator(const char* string) +int characterEditorFolderViewDrawHeading(const char* string) { int lineHeight; int x; @@ -6423,26 +6592,26 @@ int _folder_print_seperator(const char* string) int gap; int v8 = 0; - if (_folder_max_lines + _folder_top_line > _folder_line) { - if (_folder_line >= _folder_top_line) { - if (_folder_line - _folder_top_line == _folder_highlight_line) { + if (gCharacterEditorFolderViewMaxLines + gCharacterEditorFolderViewTopLine > gCharacterEditorFolderViewCurrentLine) { + if (gCharacterEditorFolderViewCurrentLine >= gCharacterEditorFolderViewTopLine) { + if (gCharacterEditorFolderViewCurrentLine - gCharacterEditorFolderViewTopLine == gCharacterEditorFolderViewHighlightedLine) { v8 = 1; } lineHeight = fontGetLineHeight(); x = 280; - y = _folder_ypos + lineHeight / 2; + y = gCharacterEditorFolderViewNextY + lineHeight / 2; if (string != NULL) { gap = fontGetLetterSpacing(); // TODO: Not sure about this. lineLen = fontGetStringWidth(string) + gap * 4; x = (x - lineLen) / 2; - fontDrawText(characterEditorWindowBuf + 640 * _folder_ypos + 34 + x + gap * 2, string, 640, 640, _colorTable[992]); - windowDrawLine(characterEditorWindowHandle, 34 + x + lineLen, y, 34 + 280, y, _colorTable[992]); + fontDrawText(gCharacterEditorWindowBuffer + 640 * gCharacterEditorFolderViewNextY + 34 + x + gap * 2, string, 640, 640, _colorTable[992]); + windowDrawLine(gCharacterEditorWindow, 34 + x + lineLen, y, 34 + 280, y, _colorTable[992]); } - windowDrawLine(characterEditorWindowHandle, 34, y, 34 + x, y, _colorTable[992]); - _folder_ypos += _folder_yoffset; + windowDrawLine(gCharacterEditorWindow, 34, y, 34 + x, y, _colorTable[992]); + gCharacterEditorFolderViewNextY += gCharacterEditorFolderViewOffsetY; } - _folder_line++; + gCharacterEditorFolderViewCurrentLine++; return v8; } else { return 0; @@ -6450,41 +6619,41 @@ int _folder_print_seperator(const char* string) } // 0x43E3D8 -bool _folder_print_line(const char* string) +bool characterEditorFolderViewDrawString(const char* string) { bool success = false; int color; - if (_folder_max_lines + _folder_top_line > _folder_line) { - if (_folder_line >= _folder_top_line) { - if (_folder_line - _folder_top_line == _folder_highlight_line) { + if (gCharacterEditorFolderViewMaxLines + gCharacterEditorFolderViewTopLine > gCharacterEditorFolderViewCurrentLine) { + if (gCharacterEditorFolderViewCurrentLine >= gCharacterEditorFolderViewTopLine) { + if (gCharacterEditorFolderViewCurrentLine - gCharacterEditorFolderViewTopLine == gCharacterEditorFolderViewHighlightedLine) { success = true; color = _colorTable[32747]; } else { color = _colorTable[992]; } - fontDrawText(characterEditorWindowBuf + 640 * _folder_ypos + 34, string, 640, 640, color); - _folder_ypos += _folder_yoffset; + fontDrawText(gCharacterEditorWindowBuffer + 640 * gCharacterEditorFolderViewNextY + 34, string, 640, 640, color); + gCharacterEditorFolderViewNextY += gCharacterEditorFolderViewOffsetY; } - _folder_line++; + gCharacterEditorFolderViewCurrentLine++; } return success; } // 0x43E470 -bool editorDrawKillsEntry(const char* name, int kills) +bool characterEditorFolderViewDrawKillsEntry(const char* name, int kills) { char killsString[8]; int color; int gap; bool success = false; - if (_folder_max_lines + _folder_top_line > _folder_line) { - if (_folder_line >= _folder_top_line) { - if (_folder_line - _folder_top_line == _folder_highlight_line) { + if (gCharacterEditorFolderViewMaxLines + gCharacterEditorFolderViewTopLine > gCharacterEditorFolderViewCurrentLine) { + if (gCharacterEditorFolderViewCurrentLine >= gCharacterEditorFolderViewTopLine) { + if (gCharacterEditorFolderViewCurrentLine - gCharacterEditorFolderViewTopLine == gCharacterEditorFolderViewHighlightedLine) { color = _colorTable[32747]; success = true; } else { @@ -6496,18 +6665,18 @@ bool editorDrawKillsEntry(const char* name, int kills) // TODO: Check. gap = fontGetLetterSpacing(); - int v11 = _folder_ypos + fontGetLineHeight() / 2; + int v11 = gCharacterEditorFolderViewNextY + fontGetLineHeight() / 2; - fontDrawText(characterEditorWindowBuf + 640 * _folder_ypos + 34, name, 640, 640, color); + fontDrawText(gCharacterEditorWindowBuffer + 640 * gCharacterEditorFolderViewNextY + 34, name, 640, 640, color); int v12 = fontGetStringWidth(name); - windowDrawLine(characterEditorWindowHandle, 34 + v12 + gap, v11, 314 - v6 - gap, v11, color); + windowDrawLine(gCharacterEditorWindow, 34 + v12 + gap, v11, 314 - v6 - gap, v11, color); - fontDrawText(characterEditorWindowBuf + 640 * _folder_ypos + 314 - v6, killsString, 640, 640, color); - _folder_ypos += _folder_yoffset; + fontDrawText(gCharacterEditorWindowBuffer + 640 * gCharacterEditorFolderViewNextY + 314 - v6, killsString, 640, 640, color); + gCharacterEditorFolderViewNextY += gCharacterEditorFolderViewOffsetY; } - _folder_line++; + gCharacterEditorFolderViewCurrentLine++; } return success; @@ -6702,3 +6871,92 @@ int genericReputationCompare(const void* a1, const void* a2) } return 0; } + +void customKarmaFolderInit() +{ + char* karmaFrms = NULL; + configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_KARMA_FRMS_KEY, &karmaFrms); + if (karmaFrms != NULL && karmaFrms[0] == '\0') { + karmaFrms = NULL; + } + + if (karmaFrms == NULL) { + return; + } + + char* karmaPoints = NULL; + configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_KARMA_POINTS_KEY, &karmaPoints); + if (karmaPoints != NULL && karmaPoints[0] == '\0') { + karmaPoints = NULL; + } + + if (karmaPoints == NULL) { + return; + } + + int karmaFrmsCount = 0; + for (char* pch = karmaFrms; pch != NULL; pch = strchr(pch + 1, ',')) { + karmaFrmsCount++; + } + + int karmaPointsCount = 0; + for (char* pch = karmaPoints; pch != NULL; pch = strchr(pch + 1, ',')) { + karmaPointsCount++; + } + + gCustomKarmaFolderDescriptions.resize(karmaFrmsCount); + + for (int index = 0; index < karmaFrmsCount; index++) { + char* pch; + + pch = strchr(karmaFrms, ','); + if (pch != NULL) { + *pch = '\0'; + } + + gCustomKarmaFolderDescriptions[index].frmId = atoi(karmaFrms); + + if (pch != NULL) { + *pch = ','; + } + + karmaFrms = pch + 1; + + if (index < karmaPointsCount) { + pch = strchr(karmaPoints, ','); + if (pch != NULL) { + *pch = '\0'; + } + + gCustomKarmaFolderDescriptions[index].threshold = atoi(karmaPoints); + + if (pch != NULL) { + *pch = ','; + } + + karmaPoints = pch + 1; + } else { + gCustomKarmaFolderDescriptions[index].threshold = INT_MAX; + } + } +} + +void customKarmaFolderFree() +{ + gCustomKarmaFolderDescriptions.clear(); +} + +int customKarmaFolderGetFrmId() +{ + if (gCustomKarmaFolderDescriptions.empty()) { + return 47; + } + + int reputation = gGameGlobalVars[GVAR_PLAYER_REPUTATION]; + for (auto& entry : gCustomKarmaFolderDescriptions) { + if (reputation < entry.threshold) { + return entry.frmId; + } + } + return gCustomKarmaFolderDescriptions.end()->frmId; +} diff --git a/src/character_editor.h b/src/character_editor.h index a562caa..a851eb0 100644 --- a/src/character_editor.h +++ b/src/character_editor.h @@ -126,10 +126,12 @@ typedef struct TownReputationEntry { int city; } TownReputationEntry; -typedef struct STRUCT_56FCB0 { - int field_0; - char* field_4; -} STRUCT_56FCB0; +typedef struct PerkDialogOption { + // Depending on the current mode this value is the id of either + // perk, trait (handling Mutate perk), or skill (handling Tag perk). + int value; + char* name; +} PerkDialogOption; // TODO: Field order is probably wrong. typedef struct KillInfo { @@ -138,11 +140,11 @@ typedef struct KillInfo { int kills; } KillInfo; -extern int _grph_id[50]; -extern const unsigned char _copyflag[EDITOR_GRAPHIC_COUNT]; -extern const int word_431D3A[EDITOR_DERIVED_STAT_COUNT]; -extern const int _StatYpos[7]; -extern const int word_431D6C[EDITOR_DERIVED_STAT_COUNT]; +extern int gCharacterEditorFrmIds[50]; +extern const unsigned char gCharacterEditorFrmShouldCopy[EDITOR_GRAPHIC_COUNT]; +extern const int gCharacterEditorDerivedStatFrmIds[EDITOR_DERIVED_STAT_COUNT]; +extern const int gCharacterEditorPrimaryStatY[7]; +extern const int gCharacterEditorDerivedStatsMap[EDITOR_DERIVED_STAT_COUNT]; extern char byte_431D93[64]; extern const int dword_431DD4[7]; @@ -151,10 +153,10 @@ extern const double dbl_501713; extern const double dbl_5018F0; extern const double dbl_5019BE; -extern bool _bk_enable_0; -extern int _skill_cursor; -extern int _slider_y; -extern int characterEditorRemainingCharacterPoints; +extern bool gCharacterEditorIsoWasEnabled; +extern int gCharacterEditorCurrentSkill; +extern int gCharacterEditorSkillValueAdjustmentSliderY; +extern int gCharacterEditorRemainingCharacterPoints; extern KarmaEntry* gKarmaEntries; extern int gKarmaEntriesLength; extern GenericReputationEntry* gGenericReputationEntries; @@ -162,148 +164,148 @@ extern int gGenericReputationEntriesLength; extern const TownReputationEntry gTownReputationEntries[TOWN_REPUTATION_COUNT]; extern const int gAddictionReputationVars[ADDICTION_REPUTATION_COUNT]; extern const int gAddictionReputationFrmIds[ADDICTION_REPUTATION_COUNT]; -extern int _folder_up_button; -extern int _folder_down_button; +extern int gCharacterEditorFolderViewScrollUpBtn; +extern int gCharacterEditorFolderViewScrollDownBtn; -extern char _folder_card_string[256]; -extern int _skillsav[SKILL_COUNT]; -extern MessageList editorMessageList; -extern STRUCT_56FCB0 _name_sort_list[DIALOG_PICKER_NUM_OPTIONS]; -extern int _trait_bids[TRAIT_COUNT]; -extern MessageListItem editorMessageListItem; -extern char _old_str1[48]; -extern char _old_str2[48]; -extern int _tag_bids[SKILL_COUNT]; -extern char _name_save[32]; -extern Size _GInfo[EDITOR_GRAPHIC_COUNT]; -extern CacheEntry* _grph_key[EDITOR_GRAPHIC_COUNT]; -extern unsigned char* _grphcpy[EDITOR_GRAPHIC_COUNT]; -extern unsigned char* _grphbmp[EDITOR_GRAPHIC_COUNT]; -extern int _folder_max_lines; -extern int _folder_line; -extern int _folder_card_fid; -extern int _folder_top_line; -extern char* _folder_card_title; -extern char* _folder_card_title2; -extern int _folder_yoffset; -extern int _folder_karma_top_line; -extern int _folder_highlight_line; -extern char* _folder_card_desc; -extern int _folder_ypos; -extern int _folder_kills_top_line; -extern int _folder_perk_top_line; -extern unsigned char* gEditorPerkBackgroundBuffer; -extern int gEditorPerkWindow; -extern int _SliderPlusID; -extern int _SliderNegID; -extern int _stat_bids_minus[7]; -extern unsigned char* characterEditorWindowBuf; -extern int characterEditorWindowHandle; -extern int _stat_bids_plus[7]; -extern unsigned char* gEditorPerkWindowBuffer; -extern CritterProtoData _dude_data; -extern unsigned char* characterEditorWindowBackgroundBuf; -extern int _cline; -extern int _oldsline; -extern int _upsent_points_back; -extern int _last_level; -extern int characterEditorWindowOldFont; -extern int _kills_count; -extern CacheEntry* _bck_key; -extern int _hp_back; -extern int _mouse_ypos; -extern int _mouse_xpos; +extern char gCharacterEditorFolderCardString[256]; +extern int gCharacterEditorSkillsBackup[SKILL_COUNT]; +extern MessageList gCharacterEditorMessageList; +extern PerkDialogOption gPerkDialogOptionList[DIALOG_PICKER_NUM_OPTIONS]; +extern int gCharacterEditorOptionalTraitBtns[TRAIT_COUNT]; +extern MessageListItem gCharacterEditorMessageListItem; +extern char gCharacterEditorCardTitle[48]; +extern char gPerkDialogCardTitle[48]; +extern int gCharacterEditorTagSkillBtns[SKILL_COUNT]; +extern char gCharacterEditorNameBackup[32]; +extern Size gCharacterEditorFrmSize[EDITOR_GRAPHIC_COUNT]; +extern CacheEntry* gCharacterEditorFrmHandle[EDITOR_GRAPHIC_COUNT]; +extern unsigned char* gCharacterEditorFrmCopy[EDITOR_GRAPHIC_COUNT]; +extern unsigned char* gCharacterEditorFrmData[EDITOR_GRAPHIC_COUNT]; +extern int gCharacterEditorFolderViewMaxLines; +extern int gCharacterEditorFolderViewCurrentLine; +extern int gCharacterEditorFolderCardFrmId; +extern int gCharacterEditorFolderViewTopLine; +extern char* gCharacterEditorFolderCardTitle; +extern char* gCharacterEditorFolderCardSubtitle; +extern int gCharacterEditorFolderViewOffsetY; +extern int gCharacterEditorKarmaFolderTopLine; +extern int gCharacterEditorFolderViewHighlightedLine; +extern char* gCharacterEditorFolderCardDescription; +extern int gCharacterEditorFolderViewNextY; +extern int gCharacterEditorKillsFolderTopLine; +extern int gCharacterEditorPerkFolderTopLine; +extern unsigned char* gPerkDialogBackgroundBuffer; +extern int gPerkDialogWindow; +extern int gCharacterEditorSliderPlusBtn; +extern int gCharacterEditorSliderMinusBtn; +extern int gCharacterEditorPrimaryStatMinusBtns[7]; +extern unsigned char* gCharacterEditorWindowBuffer; +extern int gCharacterEditorWindow; +extern int gCharacterEditorPrimaryStatPlusBtns[7]; +extern unsigned char* gPerkDialogWindowBuffer; +extern CritterProtoData gCharacterEditorDudeDataBackup; +extern unsigned char* gCharacterEditorWindowBackgroundBuffer; +extern int gPerkDialogCurrentLine; +extern int gPerkDialogPreviousCurrentLine; +extern int gCharacterEditorUnspentSkillPointsBackup; +extern int gCharacterEditorLastLevel; +extern int gCharacterEditorOldFont; +extern int gCharacterEditorKillsCount; +extern CacheEntry* gCharacterEditorWindowBackgroundHandle; +extern int gCharacterEditorHitPointsBackup; +extern int gCharacterEditorMouseY; +extern int gCharacterEditorMouseX; extern int characterEditorSelectedItem; extern int characterEditorWindowSelectedFolder; -extern int _frstc_draw1; -extern int _crow; -extern int _frstc_draw2; -extern int _perk_back[PERK_COUNT]; +extern bool gCharacterEditorCardDrawn; +extern int gPerkDialogTopLine; +extern bool gPerkDialogCardDrawn; +extern int gCharacterEditorPerksBackup[PERK_COUNT]; extern unsigned int _repFtime; extern unsigned int _frame_time; -extern int _old_tags; -extern int _last_level_back; +extern int gCharacterEditorOldTaggedSkillCount; +extern int gCharacterEditorLastLevelBackup; extern bool gCharacterEditorIsCreationMode; -extern int _tag_skill_back[NUM_TAGGED_SKILLS]; -extern int _card_old_fid2; -extern int _card_old_fid1; -extern int _trait_back[3]; -extern int _trait_count; -extern int _optrt_count; -extern int _temp_trait[3]; -extern int _tagskill_count; -extern int _temp_tag_skill[NUM_TAGGED_SKILLS]; -extern char _free_perk_back; -extern unsigned char _free_perk; -extern unsigned char _first_skill_list; +extern int gCharacterEditorTaggedSkillsBackup[NUM_TAGGED_SKILLS]; +extern int gPerkDialogCardFrmId; +extern int gCharacterEditorCardFrmId; +extern int gCharacterEditorOptionalTraitsBackup[3]; +extern int gCharacterEditorTempTraitCount; +extern int gPerkDialogOptionCount; +extern int gCharacterEditorTempTraits[3]; +extern int gCharacterEditorTaggedSkillCount; +extern int gCharacterEditorTempTaggedSkills[NUM_TAGGED_SKILLS]; +extern char gCharacterEditorHasFreePerkBackup; +extern unsigned char gCharacterEditorHasFreePerk; +extern unsigned char gCharacterEditorIsSkillsFirstDraw; -int _editor_design(bool isCreationMode); +int characterEditorShow(bool isCreationMode); int characterEditorWindowInit(); 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); bool _isdoschar(int ch); char* _strmfe(char* dest, const char* name, const char* ext); -void editorRenderFolders(); -void editorRenderPerks(); -int _kills_list_comp(const KillInfo* a, const KillInfo* b); -int editorRenderKills(); -void characterEditorRenderBigNumber(int x, int y, int flags, int value, int previousValue, int windowHandle); -void editorRenderPcStats(); -void editorRenderPrimaryStat(int stat, bool animate, int previousValue); -void editorRenderGender(); -void editorRenderAge(); -void editorRenderName(); -void editorRenderSecondaryStats(); -void editorRenderSkills(int a1); -void editorRenderDetails(); +void characterEditorDrawFolders(); +void characterEditorDrawPerksFolder(); +int characterEditorKillsCompare(const void* a1, const void* a2); +int characterEditorDrawKillsFolder(); +void characterEditorDrawBigNumber(int x, int y, int flags, int value, int previousValue, int windowHandle); +void characterEditorDrawPcStats(); +void characterEditorDrawPrimaryStat(int stat, bool animate, int previousValue); +void characterEditorDrawGender(); +void characterEditorDrawAge(); +void characterEditorDrawName(); +void characterEditorDrawDerivedStats(); +void characterEditorDrawSkills(int a1); +void characterEditorDrawCard(); int characterEditorEditName(); -void _PrintName(unsigned char* buf, int a2); -int characterEditorRunEditAgeDialog(); +void _PrintName(unsigned char* buf, int pitch); +int characterEditorEditAge(); void characterEditorEditGender(); -void characterEditorHandleIncDecPrimaryStat(int eventCode); -int _OptionWindow(); +void characterEditorAdjustPrimaryStat(int eventCode); +int characterEditorShowOptions(); bool characterFileExists(const char* fname); int characterPrintToFile(const char* fileName); char* _AddSpaces(char* string, int length); char* _AddDots(char* string, int length); -void _ResetScreen(); -void _RegInfoAreas(); -void _SavePlayer(); -void _RestorePlayer(); +void characterEditorResetScreen(); +void characterEditorRegisterInfoAreas(); +void characterEditorSavePlayer(); +void characterEditorRestorePlayer(); char* _itostndn(int value, char* dest); -int _DrawCard(int graphicId, const char* name, const char* attributes, char* description); -void _FldrButton(); -void _InfoButton(int eventCode); -void editorAdjustSkill(int a1); +int characterEditorDrawCardWithOptions(int graphicId, const char* name, const char* attributes, char* description); +void characterEditorHandleFolderButtonPressed(); +void characterEditorHandleInfoButtonPressed(int eventCode); +void characterEditorHandleAdjustSkillButtonPressed(int a1); void characterEditorToggleTaggedSkill(int skill); -void characterEditorWindowRenderTraits(); +void characterEditorDrawOptionalTraits(); void characterEditorToggleOptionalTrait(int trait); -void editorRenderKarma(); -int _editor_save(File* stream); -int _editor_load(File* stream); -void _editor_reset(); -int _UpdateLevel(); -void _RedrwDPrks(); -int editorSelectPerk(); -int _InputPDLoop(int count, void (*refreshProc)()); -int _ListDPerks(); -void _RedrwDMPrk(); -bool editorHandleMutate(); -void _RedrwDMTagSkl(); -bool editorHandleTag(); -void _ListNewTagSkills(); -int _ListMyTraits(int a1); -int _name_sort_comp(const void* a1, const void* a2); -int _DrawCard2(int frmId, const char* name, const char* rank, char* description); +void characterEditorDrawKarmaFolder(); +int characterEditorSave(File* stream); +int characterEditorLoad(File* stream); +void characterEditorReset(); +int characterEditorUpdateLevel(); +void perkDialogRefreshPerks(); +int perkDialogShow(); +int perkDialogHandleInput(int count, void (*refreshProc)()); +int perkDialogDrawPerks(); +void perkDialogRefreshTraits(); +bool perkDialogHandleMutatePerk(); +void perkDialogRefreshSkills(); +bool perkDialogHandleTagPerk(); +void perkDialogDrawSkills(); +int perkDialogDrawTraits(int a1); +int perkDialogOptionCompare(const void* a1, const void* a2); +int perkDialogDrawCard(int frmId, const char* name, const char* rank, char* description); void _pop_perks(); int _is_supper_bonus(); -int _folder_init(); -void _folder_scroll(int direction); -void _folder_clear(); -int _folder_print_seperator(const char* string); -bool _folder_print_line(const char* string); -bool editorDrawKillsEntry(const char* name, int kills); +int characterEditorFolderViewInit(); +void characterEditorFolderViewScroll(int direction); +void characterEditorFolderViewClear(); +int characterEditorFolderViewDrawHeading(const char* string); +bool characterEditorFolderViewDrawString(const char* string); +bool characterEditorFolderViewDrawKillsEntry(const char* name, int kills); int karmaInit(); void karmaFree(); int karmaEntryCompare(const void* a1, const void* a2); @@ -311,4 +313,8 @@ int genericReputationInit(); void genericReputationFree(); int genericReputationCompare(const void* a1, const void* a2); +void customKarmaFolderInit(); +void customKarmaFolderFree(); +int customKarmaFolderGetFrmId(); + #endif /* CHARACTER_EDITOR_H */ diff --git a/src/character_selector.cc b/src/character_selector.cc index b53fbc6..80af31c 100644 --- a/src/character_selector.cc +++ b/src/character_selector.cc @@ -179,7 +179,7 @@ int characterSelectorOpen() case KEY_UPPERCASE_C: case KEY_LOWERCASE_C: _ResetPlayer(); - if (_editor_design(1) == 0) { + if (characterEditorShow(1) == 0) { rc = 2; done = true; } @@ -187,7 +187,7 @@ int characterSelectorOpen() break; case KEY_UPPERCASE_M: case KEY_LOWERCASE_M: - if (!_editor_design(1)) { + if (!characterEditorShow(1)) { rc = 2; done = true; } diff --git a/src/color.cc b/src/color.cc index bac5c2d..75f81e8 100644 --- a/src/color.cc +++ b/src/color.cc @@ -354,7 +354,7 @@ void _setMixTableColor(int a1) } // 0x4C78E4 -bool colorPaletteLoad(char* path) +bool colorPaletteLoad(const char* path) { if (gColorFileNameMangler != NULL) { path = gColorFileNameMangler(path); diff --git a/src/color.h b/src/color.h index 0ad16c7..9ddf65d 100644 --- a/src/color.h +++ b/src/color.h @@ -5,7 +5,7 @@ #include -typedef char*(ColorFileNameManger)(char*); +typedef const char*(ColorFileNameManger)(const char*); typedef void(ColorTransitionCallback)(); 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 _setIntensityTables(); void _setMixTableColor(int a1); -bool colorPaletteLoad(char* path); +bool colorPaletteLoad(const char* path); char* _colorError(); void _buildBlendTable(unsigned char* ptr, unsigned char ch); void _rebuildColorBlendTables(); diff --git a/src/combat.cc b/src/combat.cc index 045d0fa..05c71db 100644 --- a/src/combat.cc +++ b/src/combat.cc @@ -2542,7 +2542,7 @@ void _combat_update_critter_outline_for_los(Object* critter, bool a2) } else { int v7 = objectGetDistanceBetween(gDude, critter); int v8 = critterGetStat(gDude, STAT_PERCEPTION) * 5; - if ((critter->flags & OBJECT_FLAG_0x20000) != 0) { + if ((critter->flags & OBJECT_TRANS_GLASS) != 0) { v8 /= 2; } @@ -3382,7 +3382,7 @@ bool _check_ranged_miss(Attack* attack) while (curr != to) { _make_straight_path_func(attack->attacker, curr, to, NULL, &critter, 32, _obj_shoot_blocking_at); 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) { roll = ROLL_SUCCESS; break; @@ -3412,7 +3412,7 @@ bool _check_ranged_miss(Attack* attack) 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; } @@ -3747,7 +3747,7 @@ int attackCompute(Attack* attack) 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->defender = v25; attackComputeDamage(attack, 1, 2); @@ -3834,7 +3834,7 @@ void _compute_explosion_on_extras(Attack* attack, int a2, int a3, int a4) if (v11 != NULL && (v11->fid & 0xF000000) >> 24 == OBJ_TYPE_CRITTER && (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)) { if (v11 == attack->attacker) { attack->attackerFlags &= ~DAM_HIT; @@ -4224,7 +4224,7 @@ int attackDetermineToHit(Object* attacker, int tile, Object* defender, int hitLo 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; } @@ -4406,7 +4406,7 @@ void attackComputeDamage(Attack* attack, int ammoQuantity, int a3) } 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) && (critter->pid >> 24) == OBJ_TYPE_CRITTER && _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) { *a5 += 1; - if ((obstacle->flags & OBJECT_FLAG_0x800) != 0) { + if ((obstacle->flags & OBJECT_MULTIHEX) != 0) { *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); current = tileGetTileInDirection(current, rotation, 1); } else { diff --git a/src/combat_ai.cc b/src/combat_ai.cc index ef8080a..40c0d16 100644 --- a/src/combat_ai.cc +++ b/src/combat_ai.cc @@ -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 ((a2->flags & OBJECT_FLAG_0x800) != 0) { + if ((a2->flags & OBJECT_MULTIHEX) != 0) { reg_anim_obj_run_to_obj(a1, a2, actionPoints, 0); } else { reg_anim_obj_run_to_tile(a1, tile, a1->elevation, actionPoints, 0); } } else { - if ((a2->flags & OBJECT_FLAG_0x800) != 0) { + if ((a2->flags & OBJECT_MULTIHEX) != 0) { reg_anim_obj_move_to_obj(a1, a2, actionPoints, 0); } else { 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); if (_can_see(a1, a2)) { int v8 = perception * 5; - if ((a2->flags & OBJECT_FLAG_0x20000) != 0) { + if ((a2->flags & OBJECT_TRANS_GLASS) != 0) { v8 /= 2; } diff --git a/src/config.cc b/src/config.cc index dbbc52c..3dc7e15 100644 --- a/src/config.cc +++ b/src/config.cc @@ -5,6 +5,8 @@ #include "platform_compat.h" #include +#include +#include #include #include #include @@ -178,8 +180,8 @@ bool configSetString(Config* config, const char* sectionKey, const char* key, co return true; } -// 0x42C05C -bool configGetInt(Config* config, const char* sectionKey, const char* key, int* valuePtr) +// 0x42C05C customized: atoi() replaced with strtol() +bool configGetInt(Config* config, const char* sectionKey, const char* key, int* valuePtr, unsigned char base /* = 0 */ ) { if (valuePtr == NULL) { return false; @@ -190,7 +192,13 @@ bool configGetInt(Config* config, const char* sectionKey, const char* key, int* 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; } diff --git a/src/config.h b/src/config.h index 34a5488..4a509b4 100644 --- a/src/config.h +++ b/src/config.h @@ -27,7 +27,7 @@ void configFree(Config* config); bool configParseCommandLineArguments(Config* config, int argc, char** argv); 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 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 configSetInt(Config* config, const char* sectionKey, const char* key, int value); bool configRead(Config* config, const char* filePath, bool isDb); diff --git a/src/core.cc b/src/core.cc index b2a7be2..3e2131d 100644 --- a/src/core.cc +++ b/src/core.cc @@ -15,7 +15,9 @@ #include #include #include +#if _WIN32 #include +#endif // NOT USED. void (*_idle_func)() = NULL; @@ -4276,9 +4278,11 @@ void _kb_init_lock_status() gModifierKeysState |= MODIFIER_KEY_STATE_NUM_LOCK; } +#if SDL_VERSION_ATLEAST(2, 0, 18) if ((SDL_GetModState() & KMOD_SCROLL) != 0) { gModifierKeysState |= MODIFIER_KEY_STATE_SCROLL_LOCK; } +#endif } // Get pointer to pending key event from the queue but do not consume it. diff --git a/src/critter.cc b/src/critter.cc index f042c7b..443a314 100644 --- a/src/critter.cc +++ b/src/critter.cc @@ -976,7 +976,7 @@ int gcdLoad(const char* path) return -1; } - if (fileReadInt32(stream, &characterEditorRemainingCharacterPoints) == -1) { + if (fileReadInt32(stream, &gCharacterEditorRemainingCharacterPoints) == -1) { fileClose(stream); return -1; } @@ -1048,7 +1048,7 @@ int gcdSave(const char* path) return -1; } - if (fileWriteInt32(stream, characterEditorRemainingCharacterPoints) == -1) { + if (fileWriteInt32(stream, gCharacterEditorRemainingCharacterPoints) == -1) { fileClose(stream); return -1; } diff --git a/src/db.cc b/src/db.cc index b00d767..734cc37 100644 --- a/src/db.cc +++ b/src/db.cc @@ -650,7 +650,12 @@ int fileNameListInit(const char* pattern, char*** fileNameListPtr, int a3, int a } 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++; } } diff --git a/src/dbox.cc b/src/dbox.cc index 6600724..56ce9ca 100644 --- a/src/dbox.cc +++ b/src/dbox.cc @@ -1,6 +1,7 @@ #include "dbox.h" #include "art.h" +#include "character_editor.h" #include "color.h" #include "core.h" #include "debug.h" @@ -18,6 +19,45 @@ #include +#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 const int gDialogBoxBackgroundFrmIds[DIALOG_TYPE_COUNT] = { 218, // MEDIALOG.FRM - Medium generic dialog box @@ -55,7 +95,7 @@ const int _dblines[DIALOG_TYPE_COUNT] = { }; // 0x510900 -int _flgids[7] = { +int gLoadFileDialogFrmIds[FILE_DIALOG_FRM_COUNT] = { 224, // loadbox.frm - character editor 8, // lilredup.frm - little red button up 9, // lilreddn.frm - little red button down @@ -66,7 +106,7 @@ int _flgids[7] = { }; // 0x51091C -int _flgids2[7] = { +int gSaveFileDialogFrmIds[FILE_DIALOG_FRM_COUNT] = { 225, // savebox.frm - character editor 8, // lilredup.frm - little red button up 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; } -// 0x41EA78 -int _save_file_dialog(char* a1, char** fileList, char* fileName, int fileListLength, int x, int y, int flags) +// 0x41DE90 +int showLoadFileDialog(char *title, char** fileList, char* dest, int fileListLength, int x, int y, int flags) { int oldFont = fontGetCurrent(); - unsigned char* frmBuffers[7]; - CacheEntry* frmHandles[7]; - Size frmSizes[7]; + bool isScrollable = false; + if (fileListLength > FILE_DIALOG_LINE_COUNT) { + isScrollable = true; + } - for (int index = 0; index < 7; index++) { - int fid = buildFid(6, _flgids2[index], 0, 0, 0); + 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, gLoadFileDialogFrmIds[index], 0, 0, 0); frmBuffers[index] = artLockFrameDataReturningSize(fid, &(frmHandles[index]), &(frmSizes[index].width), &(frmSizes[index].height)); if (frmBuffers[index] == NULL) { 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) { - for (int index = 0; index < 7; index++) { + for (int index = 0; index < FILE_DIALOG_FRM_COUNT; index++) { artUnlock(frmHandles[index]); } return -1; } 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; MessageListItem messageListItem; @@ -488,7 +550,7 @@ int _save_file_dialog(char* a1, char** fileList, char* fileName, int fileListLen if (!messageListInit(&messageList)) { windowDestroy(win); - for (int index = 0; index < 7; index++) { + for (int index = 0; index < FILE_DIALOG_FRM_COUNT; index++) { artUnlock(frmHandles[index]); } @@ -501,7 +563,7 @@ int _save_file_dialog(char* a1, char** fileList, char* fileName, int fileListLen if (!messageListLoad(&messageList, path)) { windowDestroy(win); - for (int index = 0; index < 7; index++) { + for (int index = 0; index < FILE_DIALOG_FRM_COUNT; index++) { artUnlock(frmHandles[index]); } @@ -512,23 +574,23 @@ int _save_file_dialog(char* a1, char** fileList, char* fileName, int fileListLen // DONE 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 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, - 58, - 214, - frmSizes[2].width, - frmSizes[2].height, + LOAD_FILE_DIALOG_DONE_BUTTON_X, + LOAD_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[1], - frmBuffers[2], + frmBuffers[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_NORMAL], + frmBuffers[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED], NULL, BUTTON_FLAG_TRANSPARENT); if (doneBtn != -1) { @@ -536,16 +598,16 @@ int _save_file_dialog(char* a1, char** fileList, char* fileName, int fileListLen } int cancelBtn = buttonCreate(win, - 163, - 214, - frmSizes[2].width, - frmSizes[2].height, + LOAD_FILE_DIALOG_CANCEL_BUTTON_X, + LOAD_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[1], - frmBuffers[2], + frmBuffers[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_NORMAL], + frmBuffers[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED], NULL, BUTTON_FLAG_TRANSPARENT); if (cancelBtn != -1) { @@ -553,16 +615,16 @@ int _save_file_dialog(char* a1, char** fileList, char* fileName, int fileListLen } int scrollUpBtn = buttonCreate(win, - 36, - 44, - frmSizes[6].width, - frmSizes[6].height, + 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[5], - frmBuffers[6], + frmBuffers[FILE_DIALOG_FRM_SCROLL_UP_ARROW_NORMAL], + frmBuffers[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED], NULL, BUTTON_FLAG_TRANSPARENT); if (scrollUpBtn != -1) { @@ -570,16 +632,16 @@ int _save_file_dialog(char* a1, char** fileList, char* fileName, int fileListLen } int scrollDownButton = buttonCreate(win, - 36, - 44 + frmSizes[6].height, - frmSizes[4].width, - frmSizes[4].height, + 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[3], - frmBuffers[4], + frmBuffers[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_NORMAL], + frmBuffers[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_PRESSED], NULL, BUTTON_FLAG_TRANSPARENT); if (scrollUpBtn != -1) { @@ -588,10 +650,10 @@ int _save_file_dialog(char* a1, char** fileList, char* fileName, int fileListLen buttonCreate( win, - 55, - 49, - 190, - 124, + FILE_DIALOG_FILE_LIST_X, + FILE_DIALOG_FILE_LIST_Y, + FILE_DIALOG_FILE_LIST_WIDTH, + FILE_DIALOG_FILE_LIST_HEIGHT, -1, -1, -1, @@ -601,25 +663,714 @@ int _save_file_dialog(char* a1, char** fileList, char* fileName, int fileListLen NULL, 0); - if (a1 != NULL) { - fontDrawText(windowBuffer + frmSizes[0].width * 16 + 49, a1, frmSizes[0].width, frmSizes[0].width, _colorTable[18979]); + if (title != NULL) { + 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 -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 y = 49; - bufferFill(buffer + y * pitch + 55, 190, 124, pitch, 100); + int y = FILE_DIALOG_FILE_LIST_Y; + 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 - pageOffset > 12) { - fileListLength = 12; + if (fileListLength - pageOffset > FILE_DIALOG_LINE_COUNT) { + fileListLength = FILE_DIALOG_LINE_COUNT; } for (int index = 0; index < fileListLength; index++) { 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; } } diff --git a/src/dbox.h b/src/dbox.h index 50196e4..f6bc916 100644 --- a/src/dbox.h +++ b/src/dbox.h @@ -16,17 +16,35 @@ typedef enum DialogType { DIALOG_TYPE_COUNT, } 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 _ytable[DIALOG_TYPE_COUNT]; extern const int _xtable[DIALOG_TYPE_COUNT]; extern const int _doneY[DIALOG_TYPE_COUNT]; extern const int _doneX[DIALOG_TYPE_COUNT]; extern const int _dblines[DIALOG_TYPE_COUNT]; -extern int _flgids[7]; -extern int _flgids2[7]; +extern int gLoadFileDialogFrmIds[FILE_DIALOG_FRM_COUNT]; +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 _save_file_dialog(char* a1, char** fileList, char* fileName, int fileListLength, int x, int y, int flags); -void _PrntFlist(unsigned char* buffer, char** fileList, int pageOffset, int fileListLength, int selectedIndex, int pitch); +int showLoadFileDialog(char* title, char** fileList, char* dest, int fileListLength, int x, int y, int flags); +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 */ diff --git a/src/debug.cc b/src/debug.cc index b448310..810a487 100644 --- a/src/debug.cc +++ b/src/debug.cc @@ -142,7 +142,7 @@ int debugPrint(const char* format, ...) #ifdef _WIN32 OutputDebugStringA(string); #else - printf(string); + printf("%s", string); #endif #endif rc = -1; diff --git a/src/endgame.cc b/src/endgame.cc index 92dac41..7dd1d61 100644 --- a/src/endgame.cc +++ b/src/endgame.cc @@ -493,7 +493,12 @@ int endgameEndingSlideshowWindowInit() int windowEndgameEndingX = (screenGetWidth() - ENDGAME_ENDING_WINDOW_WIDTH) / 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) { return -1; } diff --git a/src/game.cc b/src/game.cc index 3c9c366..cb5732a 100644 --- a/src/game.cc +++ b/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(); } @@ -263,7 +267,7 @@ int gameInitWithOptions(const char* windowTitle, bool isMapper, int font, int a4 debugPrint(">wmWorldMap_init\t"); - _CharEditInit(); + characterEditorInit(); debugPrint(">CharEditInit\t"); pipboyInit(); @@ -363,7 +367,7 @@ void gameReset() scriptsReset(); worldmapReset(); partyMembersReset(); - _CharEditInit(); + characterEditorInit(); pipboyReset(); _ResetLoadSave(); gameDialogReset(); @@ -512,7 +516,7 @@ int gameHandleKey(int eventCode, bool isInCombatMode) if (interfaceBarEnabled()) { soundPlayFile("ib1p1xx1"); bool isoWasEnabled = isoDisable(); - _editor_design(false); + characterEditorShow(false); if (isoWasEnabled) { isoEnable(); } @@ -887,6 +891,24 @@ int gameSetGlobalVar(int var, int value) 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; return 0; diff --git a/src/game_dialog.cc b/src/game_dialog.cc index b454c14..8d74ad4 100644 --- a/src/game_dialog.cc +++ b/src/game_dialog.cc @@ -571,7 +571,7 @@ void gameDialogEnter(Object* a1, int a2) 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; 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 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) { return -1; } @@ -1548,7 +1553,12 @@ int _gdProcessInit() 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; - 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) { goto err; } @@ -2174,7 +2184,12 @@ int _gdCreateHeadWindow() int backgroundWindowX = (screenGetWidth() - GAME_DIALOG_WINDOW_WIDTH) / 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(); unsigned char* buf = windowGetBuffer(gGameDialogBackgroundWindow); @@ -2594,6 +2609,9 @@ void gameDialogTicker() if (_gd_optionsWin != -1) { 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; @@ -2980,7 +2998,12 @@ int _gdialog_barter_create_win() int barterWindowX = (screenGetWidth() - GAME_DIALOG_WINDOW_WIDTH) / 2; 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) { artUnlock(backgroundHandle); return -1; @@ -3133,7 +3156,12 @@ int partyMemberControlWindowInit() _dialogue_subwin_len = artGetHeight(backgroundFrm, 0, 0); int controlWindowX = (screenGetWidth() - GAME_DIALOG_WINDOW_WIDTH) / 2; 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) { partyMemberControlWindowFree(); return -1; @@ -3567,7 +3595,12 @@ int partyMemberCustomizationWindowInit() int customizationWindowX = (screenGetWidth() - GAME_DIALOG_WINDOW_WIDTH) / 2; 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) { partyMemberCustomizationWindowFree(); return -1; @@ -4102,7 +4135,7 @@ int _gdialog_window_create() int dialogSubwindowX = (screenGetWidth() - GAME_DIALOG_WINDOW_WIDTH) / 2; 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) { unsigned char* v10 = windowGetBuffer(gGameDialogWindow); @@ -4369,11 +4402,19 @@ void gameDialogRenderTalkingHead(Art* headFrm, int frame) } 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( - 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, 200, - screenGetWidth(), + windowGetWidth(gIsoWindow), gGameDialogDisplayBuffer, GAME_DIALOG_WINDOW_WIDTH); } diff --git a/src/game_mouse.cc b/src/game_mouse.cc index 3181e4d..0c3abd8 100644 --- a/src/game_mouse.cc +++ b/src/game_mouse.cc @@ -1927,16 +1927,16 @@ int gameMouseObjectsInit() return -1; } - gGameMouseBouncingCursor->flags |= OBJECT_FLAG_0x20000000; + gGameMouseBouncingCursor->flags |= OBJECT_LIGHT_THRU; gGameMouseBouncingCursor->flags |= OBJECT_TEMPORARY; gGameMouseBouncingCursor->flags |= OBJECT_FLAG_0x400; - gGameMouseBouncingCursor->flags |= OBJECT_FLAG_0x80000000; + gGameMouseBouncingCursor->flags |= OBJECT_SHOOT_THRU; gGameMouseBouncingCursor->flags |= OBJECT_NO_BLOCK; gGameMouseHexCursor->flags |= OBJECT_FLAG_0x400; gGameMouseHexCursor->flags |= OBJECT_TEMPORARY; - gGameMouseHexCursor->flags |= OBJECT_FLAG_0x20000000; - gGameMouseHexCursor->flags |= OBJECT_FLAG_0x80000000; + gGameMouseHexCursor->flags |= OBJECT_LIGHT_THRU; + gGameMouseHexCursor->flags |= OBJECT_SHOOT_THRU; gGameMouseHexCursor->flags |= OBJECT_NO_BLOCK; _obj_toggle_flat(gGameMouseHexCursor, NULL); diff --git a/src/game_movie.cc b/src/game_movie.cc index 8dd2ca3..8bce85e 100644 --- a/src/game_movie.cc +++ b/src/game_movie.cc @@ -46,7 +46,7 @@ const char* gMovieFileNames[MOVIE_COUNT] = { }; // 0x518DE4 -char* gMoviePaletteFilePaths[MOVIE_COUNT] = { +const char* gMoviePaletteFilePaths[MOVIE_COUNT] = { NULL, "art\\cuts\\introsub.pal", "art\\cuts\\eldersub.pal", @@ -209,7 +209,7 @@ int gameMoviePlay(int movie, int flags) int oldTextColor; int oldFont; if (subtitlesEnabled) { - char* subtitlesPaletteFilePath; + const char* subtitlesPaletteFilePath; if (gMoviePaletteFilePaths[movie] != NULL) { subtitlesPaletteFilePath = gMoviePaletteFilePaths[movie]; } else { diff --git a/src/game_movie.h b/src/game_movie.h index 7ca8cb0..a85bad9 100644 --- a/src/game_movie.h +++ b/src/game_movie.h @@ -35,7 +35,7 @@ typedef enum GameMovie { extern const float flt_50352A; extern const char* gMovieFileNames[MOVIE_COUNT]; -extern char* gMoviePaletteFilePaths[MOVIE_COUNT]; +extern const char* gMoviePaletteFilePaths[MOVIE_COUNT]; extern bool gGameMovieIsPlaying; extern bool gGameMovieFaded; diff --git a/src/inventory.cc b/src/inventory.cc index ed2ef57..0340595 100644 --- a/src/inventory.cc +++ b/src/inventory.cc @@ -41,6 +41,14 @@ #include +#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_HEIGHT 61 @@ -550,10 +558,10 @@ bool _setup_inventory(int inventoryWindowType) // Maintain original position in original resolution, otherwise center it. int inventoryWindowX = screenGetWidth() != 640 ? (screenGetWidth() - windowDescription->width) / 2 - : 80; + : INVENTORY_WINDOW_X; int inventoryWindowY = screenGetHeight() != 480 ? (screenGetHeight() - windowDescription->height) / 2 - : 0; + : INVENTORY_WINDOW_Y; gInventoryWindow = windowCreate(inventoryWindowX, inventoryWindowY, windowDescription->width, @@ -582,15 +590,15 @@ bool _setup_inventory(int inventoryWindowType) gInventorySlotsCount = 3; // Trade inventory window is a part of game dialog, which is 640x480. - int tradeWindowX = (screenGetWidth() - 640) / 2 + 80; - int tradeWindowY = (screenGetHeight() - 480) / 2 + 290; - gInventoryWindow = windowCreate(tradeWindowX, tradeWindowY, 480, 180, 257, 0); - gInventoryWindowMaxX = tradeWindowX + 480; - gInventoryWindowMaxY = tradeWindowY + 180; + int tradeWindowX = (screenGetWidth() - 640) / 2 + INVENTORY_TRADE_WINDOW_X; + int tradeWindowY = (screenGetHeight() - 480) / 2 + INVENTORY_TRADE_WINDOW_Y; + gInventoryWindow = windowCreate(tradeWindowX, tradeWindowY, INVENTORY_TRADE_WINDOW_WIDTH, INVENTORY_TRADE_WINDOW_HEIGHT, 257, 0); + gInventoryWindowMaxX = tradeWindowX + INVENTORY_TRADE_WINDOW_WIDTH; + gInventoryWindowMaxY = tradeWindowY + INVENTORY_TRADE_WINDOW_HEIGHT; unsigned char* dest = windowGetBuffer(gInventoryWindow); 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; } @@ -606,7 +614,7 @@ bool _setup_inventory(int inventoryWindowType) } 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 // 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 y; - mouseGetPositionInWindow(gInventoryWindow, &x, &y); + mouseGetPosition(&x, &y); int actionMenuItemsLength; const int* actionMenuItems; @@ -3035,9 +3043,15 @@ void inventoryWindowOpenContextMenu(int keyCode, int inventoryWindowType) } const InventoryWindowDescription* windowDescription = &(gInventoryWindowDescriptions[inventoryWindowType]); + + Rect windowRect; + windowGetRect(gInventoryWindow, &windowRect); + int inventoryWindowX = windowRect.left; + int inventoryWindowY = windowRect.top; + gameMouseRenderActionMenuItems(x, y, actionMenuItems, actionMenuItemsLength, - windowDescription->width + windowDescription->x, - windowDescription->height + windowDescription->y); + windowDescription->width + inventoryWindowX, + windowDescription->height + inventoryWindowY); InventoryCursorData* cursorData = &(gInventoryCursorData[INVENTORY_WINDOW_CURSOR_MENU]); @@ -3046,8 +3060,8 @@ void inventoryWindowOpenContextMenu(int keyCode, int inventoryWindowType) artGetRotationOffsets(cursorData->frm, 0, &offsetX, &offsetY); Rect rect; - rect.left = x - windowDescription->x - cursorData->width / 2 + offsetX; - rect.top = y - windowDescription->y - cursorData->height + 1 + offsetY; + rect.left = x - inventoryWindowX - cursorData->width / 2 + offsetX; + rect.top = y - inventoryWindowY - cursorData->height + 1 + offsetY; rect.right = rect.left + cursorData->width - 1; rect.bottom = rect.top + cursorData->height - 1; @@ -3082,7 +3096,7 @@ void inventoryWindowOpenContextMenu(int keyCode, int inventoryWindowType) int x; int y; - mouseGetPositionInWindow(gInventoryWindow, &x, &y); + mouseGetPosition(&x, &y); if (y - previousMouseY > 10 || previousMouseY - y > 10) { if (y >= previousMouseY || menuItemIndex <= 0) { if (previousMouseY < y && menuItemIndex < actionMenuItemsLength - 1) { @@ -4476,6 +4490,7 @@ void _container_enter(int keyCode, int inventoryWindowType) _stack[_curr_stack] = item; _stack_offset[_curr_stack] = 0; + _inven_dude = _stack[_curr_stack]; _pud = &(item->data.inventory); _adjust_fid(); diff --git a/src/item.cc b/src/item.cc index 9bcb921..332aad7 100644 --- a/src/item.cc +++ b/src/item.cc @@ -576,11 +576,11 @@ bool _item_identical(Object* a1, Object* a2) return false; } - if ((a1->flags & (OBJECT_EQUIPPED | OBJECT_FLAG_0x2000)) != 0) { + if ((a1->flags & (OBJECT_EQUIPPED | OBJECT_USED)) != 0) { return false; } - if ((a2->flags & (OBJECT_EQUIPPED | OBJECT_FLAG_0x2000)) != 0) { + if ((a2->flags & (OBJECT_EQUIPPED | OBJECT_USED)) != 0) { return false; } @@ -989,14 +989,14 @@ int _item_queued(Object* obj) return false; } - if ((obj->flags & OBJECT_FLAG_0x2000) != 0) { + if ((obj->flags & OBJECT_USED) != 0) { return true; } Inventory* inventory = &(obj->data.inventory); for (int index = 0; index < inventory->length; index++) { InventoryItem* inventoryItem = &(inventory->items[index]); - if ((inventoryItem->item->flags & OBJECT_FLAG_0x2000) != 0) { + if ((inventoryItem->item->flags & OBJECT_USED) != 0) { return true; } @@ -2402,11 +2402,11 @@ int _item_m_turn_off_from_queue(Object* obj, void* data) // 0x479960 int stealthBoyTurnOn(Object* object) { - if ((object->flags & OBJECT_FLAG_0x20000) != 0) { + if ((object->flags & OBJECT_TRANS_GLASS) != 0) { return -1; } - object->flags |= OBJECT_FLAG_0x20000; + object->flags |= OBJECT_TRANS_GLASS; Rect rect; objectGetRect(object, &rect); @@ -2428,11 +2428,11 @@ int stealthBoyTurnOff(Object* critter, Object* item) return -1; } - if ((critter->flags & OBJECT_FLAG_0x20000) == 0) { + if ((critter->flags & OBJECT_TRANS_GLASS) == 0) { return -1; } - critter->flags &= ~OBJECT_FLAG_0x20000; + critter->flags &= ~OBJECT_TRANS_GLASS; Rect rect; objectGetRect(critter, &rect); diff --git a/src/lips.cc b/src/lips.cc index fb3657f..8b1c9f2 100644 --- a/src/lips.cc +++ b/src/lips.cc @@ -177,44 +177,46 @@ int lipsStart() } // 0x47AD98 -int lipsReadV1(LipsData* a1, File* stream) +int lipsReadV1(LipsData* lipsData, File* stream) { - int field_C; + int sound; int field_14; - int field_18; - int field_30; + int phonemes; + int markers; - if (fileReadInt32(stream, &(a1->version)) == -1) return -1; - if (fileReadInt32(stream, &(a1->field_4)) == -1) return -1; - if (fileReadInt32(stream, &(a1->flags)) == -1) return -1; - if (fileReadInt32(stream, &(field_C)) == -1) return -1; - if (fileReadInt32(stream, &(a1->field_10)) == -1) return -1; + if (fileReadInt32(stream, &(lipsData->version)) == -1) return -1; + if (fileReadInt32(stream, &(lipsData->field_4)) == -1) return -1; + if (fileReadInt32(stream, &(lipsData->flags)) == -1) return -1; + if (fileReadInt32(stream, &(sound)) == -1) return -1; + if (fileReadInt32(stream, &(lipsData->field_10)) == -1) return -1; if (fileReadInt32(stream, &(field_14)) == -1) return -1; - if (fileReadInt32(stream, &(field_18)) == -1) return -1; - if (fileReadInt32(stream, &(a1->field_1C)) == -1) return -1; - if (fileReadInt32(stream, &(a1->field_20)) == -1) return -1; - if (fileReadInt32(stream, &(a1->field_24)) == -1) return -1; - if (fileReadInt32(stream, &(a1->field_28)) == -1) return -1; - if (fileReadInt32(stream, &(a1->field_2C)) == -1) return -1; - if (fileReadInt32(stream, &(field_30)) == -1) return -1; - if (fileReadInt32(stream, &(a1->field_34)) == -1) return -1; - if (fileReadInt32(stream, &(a1->field_38)) == -1) return -1; - if (fileReadInt32(stream, &(a1->field_3C)) == -1) return -1; - if (fileReadInt32(stream, &(a1->field_40)) == -1) return -1; - if (fileReadInt32(stream, &(a1->field_44)) == -1) return -1; - if (fileReadInt32(stream, &(a1->field_48)) == -1) return -1; - if (fileReadInt32(stream, &(a1->field_4C)) == -1) return -1; - if (fileReadFixedLengthString(stream, a1->field_50, 8) == -1) return -1; - if (fileReadFixedLengthString(stream, a1->field_58, 4) == -1) return -1; - if (fileReadFixedLengthString(stream, a1->field_5C, 4) == -1) return -1; - if (fileReadFixedLengthString(stream, a1->field_60, 4) == -1) return -1; - if (fileReadFixedLengthString(stream, a1->field_64, 260) == -1) return -1; + if (fileReadInt32(stream, &(phonemes)) == -1) return -1; + if (fileReadInt32(stream, &(lipsData->field_1C)) == -1) return -1; + if (fileReadInt32(stream, &(lipsData->field_20)) == -1) return -1; + if (fileReadInt32(stream, &(lipsData->field_24)) == -1) return -1; + if (fileReadInt32(stream, &(lipsData->field_28)) == -1) return -1; + if (fileReadInt32(stream, &(lipsData->field_2C)) == -1) return -1; + if (fileReadInt32(stream, &(markers)) == -1) return -1; + if (fileReadInt32(stream, &(lipsData->field_34)) == -1) return -1; + if (fileReadInt32(stream, &(lipsData->field_38)) == -1) return -1; + if (fileReadInt32(stream, &(lipsData->field_3C)) == -1) return -1; + if (fileReadInt32(stream, &(lipsData->field_40)) == -1) return -1; + if (fileReadInt32(stream, &(lipsData->field_44)) == -1) return -1; + if (fileReadInt32(stream, &(lipsData->field_48)) == -1) return -1; + if (fileReadInt32(stream, &(lipsData->field_4C)) == -1) return -1; + if (fileReadFixedLengthString(stream, lipsData->field_50, 8) == -1) return -1; + if (fileReadFixedLengthString(stream, lipsData->field_58, 4) == -1) return -1; + if (fileReadFixedLengthString(stream, lipsData->field_5C, 4) == -1) return -1; + if (fileReadFixedLengthString(stream, lipsData->field_60, 4) == -1) return -1; + if (fileReadFixedLengthString(stream, lipsData->field_64, 260) == -1) return -1; - // TODO: What for? - a1->sound = (Sound*)field_C; - a1->field_14 = (void*)field_14; - a1->phonemes = (unsigned char*)field_18; - a1->markers = (SpeechMarker*)field_30; + // NOTE: Original code is different. For unknown reason it assigns values + // from file (integers) and treat them as pointers, which is obviously wrong + // is in this case. + lipsData->sound = NULL; + lipsData->field_14 = NULL; + lipsData->phonemes = NULL; + lipsData->markers = NULL; return 0; } diff --git a/src/loadsave.cc b/src/loadsave.cc index f336201..fefd03f 100644 --- a/src/loadsave.cc +++ b/src/loadsave.cc @@ -111,7 +111,7 @@ SaveGameHandler* _master_save_list[LOAD_SAVE_HANDLER_COUNT] = { traitsSave, automapSave, preferencesSave, - _editor_save, + characterEditorSave, worldmapSave, pipboySave, gameMoviesSave, @@ -142,7 +142,7 @@ LoadGameHandler* _master_load_list[LOAD_SAVE_HANDLER_COUNT] = { traitsLoad, automapLoad, preferencesLoad, - _editor_load, + characterEditorLoad, worldmapLoad, pipboyLoad, gameMoviesLoad, @@ -626,9 +626,10 @@ int _QuickSnapShot() } // For preview take 640x380 area in the center of isometric window. - unsigned char* isoWindowBuffer = windowGetBuffer(gIsoWindow) - + (screenGetWidth() - ORIGINAL_ISO_WINDOW_WIDTH) / 2 * (screenGetHeight() - ORIGINAL_ISO_WINDOW_HEIGHT) / 2 - + (screenGetWidth() - ORIGINAL_ISO_WINDOW_WIDTH) / 2; + Window* window = windowGetWindow(gIsoWindow); + unsigned char* isoWindowBuffer = window->buffer + + window->width * (window->height - ORIGINAL_ISO_WINDOW_HEIGHT) / 2 + + (window->width - ORIGINAL_ISO_WINDOW_WIDTH) / 2; blitBufferToBufferStretch(isoWindowBuffer, ORIGINAL_ISO_WINDOW_WIDTH, ORIGINAL_ISO_WINDOW_HEIGHT, @@ -1107,9 +1108,10 @@ int lsgWindowInit(int windowType) } // For preview take 640x380 area in the center of isometric window. - unsigned char* isoWindowBuffer = windowGetBuffer(gIsoWindow) - + (screenGetWidth() - ORIGINAL_ISO_WINDOW_WIDTH) / 2 * (screenGetHeight() - ORIGINAL_ISO_WINDOW_HEIGHT) / 2 - + (screenGetWidth() - ORIGINAL_ISO_WINDOW_WIDTH) / 2; + Window* window = windowGetWindow(gIsoWindow); + unsigned char* isoWindowBuffer = window->buffer + + window->width * (window->height - ORIGINAL_ISO_WINDOW_HEIGHT) / 2 + + (window->width - ORIGINAL_ISO_WINDOW_WIDTH) / 2; blitBufferToBufferStretch(isoWindowBuffer, ORIGINAL_ISO_WINDOW_WIDTH, ORIGINAL_ISO_WINDOW_HEIGHT, diff --git a/src/main.cc b/src/main.cc index da1e42a..c4f1417 100644 --- a/src/main.cc +++ b/src/main.cc @@ -132,9 +132,14 @@ int falloutMain(int argc, char** argv) return 1; } - gameMoviePlay(MOVIE_IPLOGO, GAME_MOVIE_FADE_IN); - gameMoviePlay(MOVIE_INTRO, 0); - gameMoviePlay(MOVIE_CREDITS, 0); + // SFALL: Allow to skip intro movies + int skipOpeningMovies; + 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; @@ -194,7 +199,7 @@ int falloutMain(int argc, char** argv) mainMenuWindowHide(true); mainMenuWindowFree(); _game_user_wants_to_quit = 0; - gDude->flags &= ~OBJECT_FLAG_0x08; + gDude->flags &= ~OBJECT_FLAT; _main_show_death_scene = 0; objectShow(gDude, NULL); mouseHideCursor(); @@ -296,7 +301,7 @@ int _main_load_new(char* mapFileName) { _game_user_wants_to_quit = 0; _main_show_death_scene = 0; - gDude->flags &= ~OBJECT_FLAG_0x08; + gDude->flags &= ~OBJECT_FLAT; objectShow(gDude, NULL); mouseHideCursor(); @@ -639,17 +644,31 @@ int mainMenuWindowInit() int oldFont = fontGetCurrent(); 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. msg.num = 20; 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. char version[VERSION_MAX]; versionGetVersion(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 fid = buildFid(6, 299, 0, 0, 0); @@ -683,11 +702,18 @@ int mainMenuWindowInit() 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++) { msg.num = 9 + index; if (messageListGetItem(&gMiscMessageList, &msg)) { 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); } } diff --git a/src/map.cc b/src/map.cc index a19ea21..b298f51 100644 --- a/src/map.cc +++ b/src/map.cc @@ -903,7 +903,7 @@ int mapLoad(File* stream) Object* object; int fid = buildFid(5, 12, 0, 0, 0); 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); object->sid = gMapSid; scriptSetFixedParam(gMapSid, (gMapHeader.flags & 1) == 0); diff --git a/src/memory.cc b/src/memory.cc index cefcd5a..1386e8e 100644 --- a/src/memory.cc +++ b/src/memory.cc @@ -22,10 +22,10 @@ int gMemoryBlocksCurrentCount = 0; int gMemoryBlockMaximumCount = 0; // 0x51DEE4 -int gMemoryBlocksCurrentSize = 0; +size_t gMemoryBlocksCurrentSize = 0; // 0x51DEE8 -int gMemoryBlocksMaximumSize = 0; +size_t gMemoryBlocksMaximumSize = 0; // 0x4C5A80 char* internal_strdup(const char* string) diff --git a/src/memory.h b/src/memory.h index c6e0de4..3db421e 100644 --- a/src/memory.h +++ b/src/memory.h @@ -29,8 +29,8 @@ extern ReallocProc* gReallocProc; extern FreeProc* gFreeProc; extern int gMemoryBlocksCurrentCount; extern int gMemoryBlockMaximumCount; -extern int gMemoryBlocksCurrentSize; -extern int gMemoryBlocksMaximumSize; +extern size_t gMemoryBlocksCurrentSize; +extern size_t gMemoryBlocksMaximumSize; char* internal_strdup(const char* string); void* internal_malloc(size_t size); diff --git a/src/mmx.cc b/src/mmx.cc index d0bda0b..fdf467c 100644 --- a/src/mmx.cc +++ b/src/mmx.cc @@ -9,23 +9,7 @@ // 0x4E08A0 bool mmxIsSupported() { - int v1; - - // 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; + return SDL_HasMMX() == SDL_TRUE; } // 0x4E0DB0 diff --git a/src/obj_types.h b/src/obj_types.h index e765e2e..f133774 100644 --- a/src/obj_types.h +++ b/src/obj_types.h @@ -39,31 +39,31 @@ typedef enum OutlineType { typedef enum ObjectFlags { OBJECT_HIDDEN = 0x01, OBJECT_TEMPORARY = 0x04, - OBJECT_FLAG_0x08 = 0x08, + OBJECT_FLAT = 0x08, OBJECT_NO_BLOCK = 0x10, OBJECT_LIGHTING = 0x20, - OBJECT_FLAG_0x400 = 0x400, - OBJECT_FLAG_0x800 = 0x800, - OBJECT_FLAG_0x1000 = 0x1000, - OBJECT_FLAG_0x2000 = 0x2000, - OBJECT_FLAG_0x4000 = 0x4000, - OBJECT_FLAG_0x8000 = 0x8000, - OBJECT_FLAG_0x10000 = 0x10000, - OBJECT_FLAG_0x20000 = 0x20000, - OBJECT_FLAG_0x40000 = 0x40000, - OBJECT_FLAG_0x80000 = 0x80000, + OBJECT_FLAG_0x400 = 0x400, // ??? + OBJECT_MULTIHEX = 0x800, + OBJECT_NO_HIGHLIGHT = 0x1000, + OBJECT_USED = 0x2000, // set if there was/is any event for the object + OBJECT_TRANS_RED = 0x4000, + OBJECT_TRANS_NONE = 0x8000, + OBJECT_TRANS_WALL = 0x10000, + OBJECT_TRANS_GLASS = 0x20000, + OBJECT_TRANS_STEAM = 0x40000, + OBJECT_TRANS_ENERGY = 0x80000, OBJECT_IN_LEFT_HAND = 0x1000000, OBJECT_IN_RIGHT_HAND = 0x2000000, OBJECT_WORN = 0x4000000, - OBJECT_FLAG_0x10000000 = 0x10000000, - OBJECT_FLAG_0x20000000 = 0x20000000, - OBJECT_FLAG_0x40000000 = 0x40000000, - OBJECT_FLAG_0x80000000 = 0x80000000, + OBJECT_WALL_TRANS_END = 0x10000000, + OBJECT_LIGHT_THRU = 0x20000000, + OBJECT_SEEN = 0x40000000, + OBJECT_SHOOT_THRU = 0x80000000, OBJECT_IN_ANY_HAND = OBJECT_IN_LEFT_HAND | OBJECT_IN_RIGHT_HAND, 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_OPEN_DOOR = OBJECT_FLAG_0x80000000 | OBJECT_FLAG_0x20000000 | OBJECT_NO_BLOCK, + 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_SHOOT_THRU | OBJECT_LIGHT_THRU | OBJECT_NO_BLOCK, } ObjectFlags; #define OUTLINE_TYPE_MASK 0xFFFFFF diff --git a/src/object.cc b/src/object.cc index ee25871..f80fc8c 100644 --- a/src/object.cc +++ b/src/object.cc @@ -30,13 +30,13 @@ bool gObjectsInitialized = false; // 0x5195FC -int _updateHexWidth = 0; +int gObjectsUpdateAreaHexWidth = 0; // 0x519600 -int _updateHexHeight = 0; +int gObjectsUpdateAreaHexHeight = 0; // 0x519604 -int _updateHexArea = 0; +int gObjectsUpdateAreaHexSize = 0; // 0x519608 int* _orderTable[2] = { @@ -204,16 +204,7 @@ Rect gObjectsWindowRect; Object* _outlinedObjects[100]; // 0x639D90 -int _updateAreaPixelBounds; - -// 0x639D94 -int dword_639D94; - -// 0x639D98 -int dword_639D98; - -// 0x639D9C -int dword_639D9C; +Rect gObjectsUpdateAreaPixelBounds; // Contains objects that are bounded to tiles. // @@ -264,14 +255,14 @@ int objectsInit(unsigned char* buf, int width, int height, int pitch) int eggFid; memset(_obj_seen, 0, 5001); - dword_639D98 = width + 320; - _updateAreaPixelBounds = -320; - dword_639D9C = height + 240; - dword_639D94 = -240; + gObjectsUpdateAreaPixelBounds.right = width + 320; + gObjectsUpdateAreaPixelBounds.left = -320; + gObjectsUpdateAreaPixelBounds.bottom = height + 240; + gObjectsUpdateAreaPixelBounds.top = -240; - _updateHexWidth = (dword_639D98 + 320 + 1) / 32 + 1; - _updateHexHeight = (dword_639D9C + 240 + 1) / 12 + 1; - _updateHexArea = _updateHexWidth * _updateHexHeight; + gObjectsUpdateAreaHexWidth = (gObjectsUpdateAreaPixelBounds.right + 320 + 1) / 32 + 1; + gObjectsUpdateAreaHexHeight = (gObjectsUpdateAreaPixelBounds.bottom + 240 + 1) / 12 + 1; + gObjectsUpdateAreaHexSize = gObjectsUpdateAreaHexWidth * gObjectsUpdateAreaHexHeight; 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_blend_table_init(); - _centerToUpperLeft = tileFromScreenXY(_updateAreaPixelBounds, dword_639D94, 0) - gCenterTile; + _centerToUpperLeft = tileFromScreenXY(gObjectsUpdateAreaPixelBounds.left, gObjectsUpdateAreaPixelBounds.top, 0) - gCenterTile; gObjectsWindowWidth = width; gObjectsWindowHeight = height; 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_TEMPORARY; gDude->flags |= OBJECT_HIDDEN; - gDude->flags |= OBJECT_FLAG_0x20000000; + gDude->flags |= OBJECT_LIGHT_THRU; objectSetLight(gDude, 4, 0x10000, NULL); 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_TEMPORARY; gEgg->flags |= OBJECT_HIDDEN; - gEgg->flags |= OBJECT_FLAG_0x20000000; + gEgg->flags |= OBJECT_LIGHT_THRU; gObjectsInitialized = true; @@ -767,35 +758,59 @@ void _obj_render_pre_roof(Rect* rect, int elevation) return; } - int lightLevel = lightGetLightLevel(); - int v5 = updatedRect.left - 320; - int v4 = updatedRect.top - 240; - int v17 = updatedRect.right + 320; - int v18 = updatedRect.bottom + 240; - int v19 = tileFromScreenXY(v5, v4, elevation); - int v20 = (v17 - v5 + 1) / 32; - int v23 = (v18 - v4 + 1) / 12; + int ambientLight = lightGetLightLevel(); + int minX = updatedRect.left - 320; + int minY = updatedRect.top - 240; + int maxX = updatedRect.right + 320; + int maxY = updatedRect.bottom + 240; + int topLeftTile = tileFromScreenXY(minX, minY, elevation); + int updateAreaHexWidth = (maxX - minX + 1) / 32; + int updateAreaHexHeight = (maxY - minY + 1) / 12; - int odd = gCenterTile & 1; - int* v7 = _orderTable[odd]; - int* v8 = _offsetTable[odd]; + // On some maps (which were designed too close to edges) HRP brings a new + // problem - extended update rect (+/- 320/240 stuff above) may end up + // 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; - int v34 = 0; - for (int i = 0; i < _updateHexArea; i++) { - int v9 = *v7++; - if (v23 > _offsetDivTable[v9] && v20 > _offsetModTable[v9]) { - int v2; + int renderCount = 0; + for (int i = 0; i < gObjectsUpdateAreaHexSize; i++) { + int offsetIndex = *orders++; + if (updateAreaHexHeight > _offsetDivTable[offsetIndex] && updateAreaHexWidth > _offsetModTable[offsetIndex]) { + int light; - ObjectListNode* objectListNode = gObjectListHeadByTile[v19 + v8[v9]]; + ObjectListNode* objectListNode = hexGridTileIsValid(topLeftTile + offsets[offsetIndex]) + ? gObjectListHeadByTile[topLeftTile + offsets[offsetIndex]] + : NULL; if (objectListNode != NULL) { // NOTE: calls _light_get_tile two times, probably result of min/max macro - int q = _light_get_tile(elevation, objectListNode->obj->tile); - if (q >= lightLevel) { - v2 = q; + int tileLight = _light_get_tile(elevation, objectListNode->obj->tile); + if (tileLight >= ambientLight) { + light = tileLight; } else { - v2 = lightLevel; + light = ambientLight; } } @@ -805,12 +820,12 @@ void _obj_render_pre_roof(Rect* rect, int elevation) } if (elevation == objectListNode->obj->elevation) { - if ((objectListNode->obj->flags & OBJECT_FLAG_0x08) == 0) { + if ((objectListNode->obj->flags & OBJECT_FLAT) == 0) { break; } 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_DISABLED) == 0 && _outlineCount < 100) { @@ -824,20 +839,22 @@ void _obj_render_pre_roof(Rect* rect, int elevation) } if (objectListNode != NULL) { - _renderTable[v34++] = objectListNode; + _renderTable[renderCount++] = objectListNode; } } } - for (int i = 0; i < v34; i++) { - int v2; + for (int i = 0; i < renderCount; i++) { + int light; ObjectListNode* objectListNode = _renderTable[i]; if (objectListNode != NULL) { - v2 = lightLevel; - int w = _light_get_tile(elevation, objectListNode->obj->tile); - if (w > v2) { - v2 = w; + // NOTE: calls _light_get_tile two times, probably result of min/max macro + int tileLight = _light_get_tile(elevation, objectListNode->obj->tile); + if (tileLight >= ambientLight) { + light = tileLight; + } else { + light = ambientLight; } } @@ -849,7 +866,7 @@ void _obj_render_pre_roof(Rect* rect, int elevation) if (elevation == objectListNode->obj->elevation) { 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_DISABLED) == 0 && _outlineCount < 100) { @@ -943,39 +960,39 @@ int objectCreateWithFidPid(Object** objectPtr, int fid, int pid) } if ((proto->flags & 0x800) != 0) { - objectListNode->obj->flags |= OBJECT_FLAG_0x800; + objectListNode->obj->flags |= OBJECT_MULTIHEX; } if ((proto->flags & 0x8000) != 0) { - objectListNode->obj->flags |= OBJECT_FLAG_0x8000; + objectListNode->obj->flags |= OBJECT_TRANS_NONE; } else { if ((proto->flags & 0x10000) != 0) { - objectListNode->obj->flags |= OBJECT_FLAG_0x10000; + objectListNode->obj->flags |= OBJECT_TRANS_WALL; } else if ((proto->flags & 0x20000) != 0) { - objectListNode->obj->flags |= OBJECT_FLAG_0x20000; + objectListNode->obj->flags |= OBJECT_TRANS_GLASS; } else if ((proto->flags & 0x40000) != 0) { - objectListNode->obj->flags |= OBJECT_FLAG_0x40000; + objectListNode->obj->flags |= OBJECT_TRANS_STEAM; } else if ((proto->flags & 0x80000) != 0) { - objectListNode->obj->flags |= OBJECT_FLAG_0x80000; + objectListNode->obj->flags |= OBJECT_TRANS_ENERGY; } else if ((proto->flags & 0x4000) != 0) { - objectListNode->obj->flags |= OBJECT_FLAG_0x4000; + objectListNode->obj->flags |= OBJECT_TRANS_RED; } } if ((proto->flags & 0x20000000) != 0) { - objectListNode->obj->flags |= OBJECT_FLAG_0x20000000; + objectListNode->obj->flags |= OBJECT_LIGHT_THRU; } if ((proto->flags & 0x80000000) != 0) { - objectListNode->obj->flags |= OBJECT_FLAG_0x80000000; + objectListNode->obj->flags |= OBJECT_SHOOT_THRU; } if ((proto->flags & 0x10000000) != 0) { - objectListNode->obj->flags |= OBJECT_FLAG_0x10000000; + objectListNode->obj->flags |= OBJECT_WALL_TRANS_END; } 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)); @@ -1041,7 +1058,7 @@ int _obj_copy(Object** a1, Object* a2) return -1; } - objectListNode->obj->flags &= ~OBJECT_FLAG_0x2000; + objectListNode->obj->flags &= ~OBJECT_USED; Inventory* newInventory = &(objectListNode->obj->data.inventory); 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); 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); } @@ -2419,7 +2436,7 @@ Object* _obj_blocking_at(Object* a1, int tile, int elev) objectListNode = gObjectListHeadByTile[neighboor]; while (objectListNode != NULL) { v7 = objectListNode->obj; - if ((v7->flags & OBJECT_FLAG_0x800) != 0) { + if ((v7->flags & OBJECT_MULTIHEX) != 0) { if (v7->elevation == elev) { if ((v7->flags & OBJECT_HIDDEN) == 0 && (v7->flags & OBJECT_NO_BLOCK) == 0 && v7 != a1) { type = (v7->fid & 0xF000000) >> 24; @@ -2451,7 +2468,7 @@ Object* _obj_shoot_blocking_at(Object* obj, int tile, int elev) Object* candidate = objectListItem->obj; if (candidate->elevation == elev) { 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; // SFALL: Fix to prevent corpses from blocking line of fire. 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) { Object* candidate = objectListItem->obj; unsigned int flags = candidate->flags; - if ((flags & OBJECT_FLAG_0x800) != 0) { + if ((flags & OBJECT_MULTIHEX) != 0) { if (candidate->elevation == elev) { if ((flags & OBJECT_HIDDEN) == 0 && (flags & OBJECT_NO_BLOCK) == 0 && candidate != obj) { int type = (candidate->fid & 0xF000000) >> 24; @@ -2533,7 +2550,7 @@ Object* _obj_ai_blocking_at(Object* a1, int tile, int elevation) objectListNode = gObjectListHeadByTile[candidate]; while (objectListNode != NULL) { Object* object = objectListNode->obj; - if ((object->flags & OBJECT_FLAG_0x800) != 0) { + if ((object->flags & OBJECT_MULTIHEX) != 0) { if (object->elevation == elevation) { if ((object->flags & OBJECT_HIDDEN) == 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; if (object->elevation == elevation && (object->flags & OBJECT_HIDDEN) == 0 - && (object->flags & OBJECT_FLAG_0x20000000) == 0 + && (object->flags & OBJECT_LIGHT_THRU) == 0 && object != a1) { int objectType = (object->fid & 0xF000000) >> 24; 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); - if ((object1->flags & OBJECT_FLAG_0x800) != 0) { + if ((object1->flags & OBJECT_MULTIHEX) != 0) { distance -= 1; } - if ((object2->flags & OBJECT_FLAG_0x800) != 0) { + if ((object2->flags & OBJECT_MULTIHEX) != 0) { distance -= 1; } @@ -2636,11 +2653,11 @@ int objectGetDistanceBetweenTiles(Object* object1, int tile1, Object* object2, i int distance = tileDistanceBetween(tile1, tile2); - if ((object1->flags & OBJECT_FLAG_0x800) != 0) { + if ((object1->flags & OBJECT_MULTIHEX) != 0) { distance -= 1; } - if ((object2->flags & OBJECT_FLAG_0x800) != 0) { + if ((object2->flags & OBJECT_MULTIHEX) != 0) { distance -= 1; } @@ -2869,7 +2886,7 @@ int objectSetOutline(Object* obj, int outlineType, Rect* rect) return -1; } - if ((obj->flags & OBJECT_FLAG_0x1000) != 0) { + if ((obj->flags & OBJECT_NO_HIGHLIGHT) != 0) { return -1; } @@ -2951,7 +2968,7 @@ int _obj_intersects_with(Object* object, int x, int y) flags |= 0x01; if ((object->flags & OBJECT_FLAG_0xFC000) != 0) { - if ((object->flags & OBJECT_FLAG_0x8000) == 0) { + if ((object->flags & OBJECT_TRANS_NONE) == 0) { flags &= ~0x03; 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); *entriesPtr = NULL; - if (_updateHexArea <= 0) { + if (gObjectsUpdateAreaHexSize <= 0) { return 0; } int count = 0; int parity = gCenterTile & 1; - for (int index = 0; index < _updateHexArea; index++) { + for (int index = 0; index < gObjectsUpdateAreaHexSize; index++) { int v7 = _orderTable[parity][index]; if (_offsetDivTable[v7] < 30 && _offsetModTable[v7] < 20) { ObjectListNode* objectListNode = gObjectListHeadByTile[_offsetTable[parity][v7] + v5]; @@ -3100,7 +3117,7 @@ void _obj_process_seen() if (v5 < 40000) { for (obj_entry = gObjectListHeadByTile[v5]; obj_entry != NULL; obj_entry = obj_entry->next) { 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; } - _offsetTable[0] = (int*)internal_malloc(sizeof(int) * _updateHexArea); + _offsetTable[0] = (int*)internal_malloc(sizeof(int) * gObjectsUpdateAreaHexSize); if (_offsetTable[0] == NULL) { goto err; } - _offsetTable[1] = (int*)internal_malloc(sizeof(int) * _updateHexArea); + _offsetTable[1] = (int*)internal_malloc(sizeof(int) * gObjectsUpdateAreaHexSize); if (_offsetTable[1] == NULL) { goto err; } - for (int i = 0; i < 2; i++) { - int tile = tileFromScreenXY(_updateAreaPixelBounds, dword_639D94, 0); - if (tile != -1) { - int* v5 = _offsetTable[gCenterTile & 1]; - int v20; - int v19; - tileToScreenXY(tile, &v20, &v19, 0); + for (int parity = 0; parity < 2; parity++) { + int originTile = tileFromScreenXY(gObjectsUpdateAreaPixelBounds.left, gObjectsUpdateAreaPixelBounds.top, 0); + if (originTile != -1) { + int* offsets = _offsetTable[gCenterTile & 1]; + int originTileX; + int originTileY; + tileToScreenXY(originTile, &originTileX, &originTileY, 0); - int v23 = 16; - v20 += 16; - v19 += 8; - if (v20 > _updateAreaPixelBounds) { - v23 = -v23; + int parityShift = 16; + originTileX += 16; + originTileY += 8; + if (originTileX > gObjectsUpdateAreaPixelBounds.left) { + parityShift = -parityShift; } - int v6 = v20; - for (int j = 0; j < _updateHexHeight; j++) { - for (int m = 0; m < _updateHexWidth; m++) { - int t = tileFromScreenXY(v6, v19, 0); - if (t == -1) { + int tileX = originTileX; + for (int y = 0; y < gObjectsUpdateAreaHexHeight; y++) { + for (int x = 0; x < gObjectsUpdateAreaHexWidth; x++) { + int tile = tileFromScreenXY(tileX, originTileY, 0); + if (tile == -1) { goto err; } - v6 += 32; - *v5++ = t - tile; + tileX += 32; + *offsets++ = tile - originTile; } - v6 = v23 + v20; - v19 += 12; - v23 = -v23; + tileX = parityShift + originTileX; + originTileY += 12; + 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) { goto err; } - for (i = 0; i < _updateHexArea; i++) { - _offsetDivTable[i] = i / _updateHexWidth; + for (i = 0; i < gObjectsUpdateAreaHexSize; i++) { + _offsetDivTable[i] = i / gObjectsUpdateAreaHexWidth; } - _offsetModTable = (int*)internal_malloc(sizeof(int) * _updateHexArea); + _offsetModTable = (int*)internal_malloc(sizeof(int) * gObjectsUpdateAreaHexSize); if (_offsetModTable == NULL) { goto err; } - for (i = 0; i < _updateHexArea; i++) { - _offsetModTable[i] = i % _updateHexWidth; + for (i = 0; i < gObjectsUpdateAreaHexSize; i++) { + _offsetModTable[i] = i % gObjectsUpdateAreaHexWidth; } return 0; @@ -3343,23 +3360,23 @@ int _obj_order_table_init() return -1; } - _orderTable[0] = (int*)internal_malloc(sizeof(int) * _updateHexArea); + _orderTable[0] = (int*)internal_malloc(sizeof(int) * gObjectsUpdateAreaHexSize); if (_orderTable[0] == NULL) { goto err; } - _orderTable[1] = (int*)internal_malloc(sizeof(int) * _updateHexArea); + _orderTable[1] = (int*)internal_malloc(sizeof(int) * gObjectsUpdateAreaHexSize); if (_orderTable[1] == NULL) { goto err; } - for (int index = 0; index < _updateHexArea; index++) { + for (int index = 0; index < gObjectsUpdateAreaHexSize; index++) { _orderTable[0][index] = index; _orderTable[1][index] = index; } - qsort(_orderTable[0], _updateHexArea, sizeof(int), _obj_order_comp_func_even); - qsort(_orderTable[1], _updateHexArea, sizeof(int), _obj_order_comp_func_odd); + qsort(_orderTable[0], gObjectsUpdateAreaHexSize, sizeof(int), _obj_order_comp_func_even); + qsort(_orderTable[1], gObjectsUpdateAreaHexSize, sizeof(int), _obj_order_comp_func_odd); return 0; @@ -3410,12 +3427,12 @@ int _obj_render_table_init() return -1; } - _renderTable = (ObjectListNode**)internal_malloc(sizeof(*_renderTable) * _updateHexArea); + _renderTable = (ObjectListNode**)internal_malloc(sizeof(*_renderTable) * gObjectsUpdateAreaHexSize); if (_renderTable == NULL) { return -1; } - for (int index = 0; index < _updateHexArea; index++) { + for (int index = 0; index < gObjectsUpdateAreaHexSize; index++) { _renderTable[index] = NULL; } @@ -3438,11 +3455,11 @@ void _obj_light_table_init() { for (int s = 0; s < 2; s++) { int v4 = gCenterTile + s; - for (int i = 0; i < 6; i++) { + for (int i = 0; i < ROTATION_COUNT; i++) { int v15 = 8; int* p = _light_offsets[v4 & 1][i]; 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++) { *p++ = tileGetTileInDirection(tile, i, m + 1) - v4; @@ -3856,11 +3873,11 @@ void _obj_insert(ObjectListNode* objectListNode) } 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; } - 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; CacheEntry* 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); 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->flags & OBJECT_FLAG_0x08) == 0) { + if ((objectListNode->obj->flags & OBJECT_FLAT) == 0) { Proto* proto; protoGetProto(objectListNode->obj->pid, &proto); 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); if (!v17 || !tileIsToRightOf(object->tile, gDude->tile) - || (object->flags & OBJECT_FLAG_0x10000000) == 0) { + || (object->flags & OBJECT_WALL_TRANS_END) == 0) { // nothing } else { v17 = false; @@ -4980,7 +4997,7 @@ void _obj_render_object(Object* object, Rect* rect, int light) v17 = tileIsToRightOf(gDude->tile, object->tile); if (v17 && tileIsInFrontOf(gDude->tile, object->tile) - && (object->flags & OBJECT_FLAG_0x10000000) != 0) { + && (object->flags & OBJECT_WALL_TRANS_END) != 0) { v17 = 0; } } @@ -5071,19 +5088,19 @@ void _obj_render_object(Object* object, Rect* rect, int light) } 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); 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); 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); 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); 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); break; default: diff --git a/src/object.h b/src/object.h index 16f53c9..6cf12cf 100644 --- a/src/object.h +++ b/src/object.h @@ -13,9 +13,9 @@ typedef struct ObjectWithFlags { } ObjectWithFlags; extern bool gObjectsInitialized; -extern int _updateHexWidth; -extern int _updateHexHeight; -extern int _updateHexArea; +extern int gObjectsUpdateAreaHexWidth; +extern int gObjectsUpdateAreaHexHeight; +extern int gObjectsUpdateAreaHexSize; extern int* _orderTable[2]; extern int* _offsetTable[2]; extern int* _offsetModTable; @@ -49,10 +49,7 @@ extern int _light_blocked[6][36]; extern int _light_offsets[2][6][36]; extern Rect gObjectsWindowRect; extern Object* _outlinedObjects[100]; -extern int _updateAreaPixelBounds; -extern int dword_639D94; -extern int dword_639D98; -extern int dword_639D9C; +extern Rect gObjectsUpdateAreaPixelBounds; extern ObjectListNode* gObjectListHeadByTile[HEX_GRID_SIZE]; extern unsigned char _glassGrayTable[256]; extern unsigned char _commonGrayTable[256]; diff --git a/src/platform_compat.cc b/src/platform_compat.cc index b71be7b..69da2c5 100644 --- a/src/platform_compat.cc +++ b/src/platform_compat.cc @@ -21,7 +21,7 @@ #ifdef _WIN32 #include #else -#include +#include #endif int compat_stricmp(const char* string1, const char* string2) @@ -145,8 +145,8 @@ unsigned int compat_timeGetTime() #ifdef _WIN32 return timeGetTime(); #else - struct timeval tv; - gettimeofday(&tv, NULL); - return tv.tv_usec / 1000; + static auto start = std::chrono::steady_clock::now(); + auto now = std::chrono::steady_clock::now(); + return static_cast(std::chrono::duration_cast(now - start).count()); #endif } diff --git a/src/proto.cc b/src/proto.cc index 027fb3c..0fb6709 100644 --- a/src/proto.cc +++ b/src/proto.cc @@ -777,7 +777,7 @@ int _proto_dude_init(const char* path) _proto_dude_update_gender(); _inven_reset_dude(); - if ((gDude->flags & OBJECT_FLAG_0x08) != 0) { + if ((gDude->flags & OBJECT_FLAT) != 0) { _obj_toggle_flat(gDude, NULL); } @@ -1854,7 +1854,7 @@ int _ResetPlayer() pcStatsReset(); protoCritterDataResetStats(&(proto->critter.data)); critterReset(); - _editor_reset(); + characterEditorReset(); protoCritterDataResetSkills(&(proto->critter.data)); skillsReset(); perksReset(); diff --git a/src/proto_instance.cc b/src/proto_instance.cc index dc28e6d..a246990 100644 --- a/src/proto_instance.cc +++ b/src/proto_instance.cc @@ -796,7 +796,7 @@ int _obj_use_flare(Object* critter_obj, Object* flare) return -1; } - if ((flare->flags & OBJECT_FLAG_0x2000) != 0) { + if ((flare->flags & OBJECT_USED) != 0) { if (critter_obj == gDude) { // The flare is already lit. messageListItem.num = 588; @@ -854,7 +854,7 @@ int _obj_use_explosive(Object* explosive) return -1; } - if ((explosive->flags & OBJECT_FLAG_0x2000) != 0) { + if ((explosive->flags & OBJECT_USED) != 0) { // The timer is already ticking. messageListItem.num = 590; if (messageListGetItem(&gProtoMessageList, &messageListItem)) { @@ -2198,7 +2198,7 @@ int _objPMAttemptPlacement(Object* obj, int tile, int elevation) for (int v4 = 1; v4 <= 100; v4++) { // TODO: Check. v7++; - v9 = tileGetTileInDirection(v9, v7 % 6, 1); + v9 = tileGetTileInDirection(v9, v7 % ROTATION_COUNT, 1); if (_wmEvalTileNumForPlacement(v9) != 0) { break; } diff --git a/src/queue.cc b/src/queue.cc index 0b20890..34b89e8 100644 --- a/src/queue.cc +++ b/src/queue.cc @@ -232,7 +232,7 @@ int queueAddEvent(int delay, Object* obj, void* data, int eventType) newQueueListNode->data = data; if (obj != NULL) { - obj->flags |= OBJECT_FLAG_0x2000; + obj->flags |= OBJECT_USED; } QueueListNode** v3 = &gQueueListHead; diff --git a/src/scripts.cc b/src/scripts.cc index c4d0169..6bb43a6 100644 --- a/src/scripts.cc +++ b/src/scripts.cc @@ -1723,7 +1723,8 @@ int scriptWrite(Script* scr, File* stream) if (fileWriteInt32(stream, scr->flags) == -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->localVarsOffset) == -1) return -1; if (fileWriteInt32(stream, scr->localVarsCount) == -1) return -1; @@ -1753,8 +1754,8 @@ int scriptListExtentWrite(ScriptListExtent* a1, File* stream) return -1; } - if (fileWriteInt32(stream, (int)a1->next) != 0) { - // FIXME: writing pointer to file + // NOTE: Original code writes `a1->next` pointer which is meaningless. + if (fileWriteInt32(stream, 0) != 0) { return -1; } @@ -1778,18 +1779,16 @@ int scriptSaveAll(File* stream) for (int index = 0; index < scriptExtent->length; index++) { Script* script = &(scriptExtent->scripts[index]); + lastScriptExtent = scriptList->tail; if ((script->flags & SCRIPT_FLAG_0x08) != 0) { scriptCount--; - lastScriptExtent = scriptList->tail; int backwardsIndex = lastScriptExtent->length - 1; - while (lastScriptExtent != scriptExtent || backwardsIndex > index) { - if (lastScriptExtent == scriptExtent) { - if (backwardsIndex >= index) { - break; - } - } + if (lastScriptExtent == scriptExtent && backwardsIndex <= index) { + break; + } + while (lastScriptExtent != scriptExtent || backwardsIndex > index) { Script* backwardsScript = &(lastScriptExtent->scripts[backwardsIndex]); if ((backwardsScript->flags & SCRIPT_FLAG_0x08) == 0) { break; @@ -2427,7 +2426,7 @@ bool scriptsExecSpatialProc(Object* object, int tile, int elevation) 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; } @@ -2685,7 +2684,7 @@ int scriptGetLocalVar(int sid, int variable, int* value) } Script* script; - if (scriptGetScript(sid, &script) == 1) { + if (scriptGetScript(sid, &script) == -1) { *value = -1; return -1; } diff --git a/src/sfall_config.cc b/src/sfall_config.cc index 5122495..46f3c8e 100644 --- a/src/sfall_config.cc +++ b/src/sfall_config.cc @@ -21,7 +21,15 @@ bool sfallConfigInit(int argc, char** argv) } // 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, ""); + configSetBool(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_DISPLAY_KARMA_CHANGES_KEY, false); char path[COMPAT_MAX_PATH]; char* executable = argv[0]; diff --git a/src/sfall_config.h b/src/sfall_config.h index 69be7a0..a1d423f 100644 --- a/src/sfall_config.h +++ b/src/sfall_config.h @@ -7,7 +7,17 @@ #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_KARMA_FRMS_KEY "KarmaFRMs" +#define SFALL_CONFIG_KARMA_POINTS_KEY "KarmaPoints" +#define SFALL_CONFIG_DISPLAY_KARMA_CHANGES_KEY "DisplayKarmaChanges" extern bool gSfallConfigInitialized; extern Config gSfallConfig; diff --git a/src/stat.cc b/src/stat.cc index f08ca84..dcc02c8 100644 --- a/src/stat.cc +++ b/src/stat.cc @@ -323,6 +323,7 @@ int critterGetStat(Object* critter, int stat) } break; case STAT_DAMAGE_RESISTANCE: + case STAT_DAMAGE_RESISTANCE_EXPLOSION: if (perkGetRank(critter, PERK_DERMAL_IMPACT_ARMOR)) { value += 5; } else if (perkGetRank(critter, PERK_DERMAL_IMPACT_ASSAULT_ENHANCEMENT)) { diff --git a/src/text_font.cc b/src/text_font.cc index cd43447..df76706 100644 --- a/src/text_font.cc +++ b/src/text_font.cc @@ -125,9 +125,18 @@ int textFontLoad(int font) goto out; } - if (fileRead(textFontDescriptor, sizeof(TextFontDescriptor), 1, stream) != 1) { - goto out; - } + // NOTE: Original code reads entire descriptor in one go. This does not work + // 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)); if (textFontDescriptor->glyphs == NULL) { diff --git a/src/tile.cc b/src/tile.cc index 7721d28..f0a18c7 100644 --- a/src/tile.cc +++ b/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]); } + // 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); 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; configGetString(&gGameConfig, GAME_CONFIG_SYSTEM_KEY, GAME_CONFIG_EXECUTABLE_KEY, &executable); if (compat_stricmp(executable, "mapper") == 0) { diff --git a/src/window_manager.cc b/src/window_manager.cc index d7bc980..217ea94 100644 --- a/src/window_manager.cc +++ b/src/window_manager.cc @@ -265,6 +265,8 @@ void windowManagerExit(void) textFontsExit(); _colorsClose(); + SDL_DestroyWindow(gSdlWindow); + gWindowSystemInitialized = false; #ifdef _WIN32 diff --git a/src/xfile.cc b/src/xfile.cc index c4096aa..27589db 100644 --- a/src/xfile.cc +++ b/src/xfile.cc @@ -617,7 +617,7 @@ bool xlistEnumerate(const char* pattern, XListEnumerationHandler* handler, XList } } while (fileFindNext(&directoryFileFindData)); } - return findFindClose(&directoryFileFindData); + findFindClose(&directoryFileFindData); } xbase = xbase->next; }