diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..82e7db3 --- /dev/null +++ b/.clang-format @@ -0,0 +1,19 @@ +BasedOnStyle: LLVM +IndentWidth: 4 +TabWidth: 4 +UseTab: Never +BreakBeforeBraces: Allman +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Inline +ColumnLimit: 120 +SpacesInParentheses: false +SpaceAfterCStyleCast: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +PointerAlignment: Left +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignTrailingComments: false +SortIncludes: false +Cpp11BracedListStyle: false diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..426f864 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,64 @@ +Checks: > + bugprone-* + ,cert-* + ,clang-analyzer-* + ,misc-* + ,performance-* + ,readability-* + ,cppcoreguidelines-avoid-c-arrays + ,cppcoreguidelines-avoid-do-while + ,cppcoreguidelines-avoid-goto + ,cppcoreguidelines-init-variables + ,cppcoreguidelines-macro-usage + ,cppcoreguidelines-pro-bounds-array-to-pointer-decay + ,cppcoreguidelines-pro-bounds-constant-array-index + ,cppcoreguidelines-pro-bounds-pointer-arithmetic + ,cppcoreguidelines-pro-type-const-cast + ,cppcoreguidelines-pro-type-cstyle-cast + ,cppcoreguidelines-pro-type-reinterpret-cast + ,cppcoreguidelines-pro-type-static-cast-downcast + ,cppcoreguidelines-pro-type-union-access + ,cppcoreguidelines-pro-type-vararg + ,cppcoreguidelines-slicing + ,cppcoreguidelines-special-member-functions + ,cppcoreguidelines-virtual-class-destructor + ,google-build-namespaces + ,google-build-using-namespace + ,google-explicit-constructor + ,google-readability-braces-around-statements + ,google-readability-casting + ,google-readability-function-size + ,google-readability-namespace-comments + ,google-readability-todo + ,google-runtime-int + ,google-runtime-operator + ,llvm-else-after-return + ,llvm-header-guard + ,llvm-include-order + ,llvm-namespace-comment + ,llvm-prefer-isa-or-dyn-cast-in-conditionals + ,llvm-prefer-register-over-unsigned + ,llvm-twine-local + ,misc-confusable-identifiers + ,misc-const-correctness + ,misc-definitions-in-headers + ,misc-header-include-cycle + ,misc-include-cleaner + ,misc-misleading-bidirectional + ,misc-misleading-identifier + ,misc-misplaced-const + ,misc-new-delete-overloads + ,misc-no-recursion + ,misc-non-copyable-objects + ,misc-non-private-member-variables-in-classes + ,misc-redundant-expression + ,misc-static-assert + ,misc-throw-by-value-catch-by-reference + ,misc-unconventional-assign-operator + ,misc-unused-alias-decls + ,misc-unused-parameters + ,misc-unused-using-decls + ,-modernize-* + ,-abseil-* + ,-fuchsia-* + ,-hicpp-* diff --git a/.clangd b/.clangd new file mode 100644 index 0000000..c944531 --- /dev/null +++ b/.clangd @@ -0,0 +1,22 @@ +CompileFlags: + Add: [ + --target=i686-w64-windows-gnu, + --sysroot=/usr/i686-w64-mingw32, + -std=c++98, + -Wall, + -Wno-pragma-pack, + -D_WIN32, + -DTRACING, + -DTRACE_TERMINAL, + -DTRACE_FILE, + -I/usr/lib/gcc/i686-w64-mingw32/13-win32/include/c++, + -I/usr/lib/gcc/i686-w64-mingw32/13-win32/include/c++/i686-w64-mingw32, + -I/usr/i686-w64-mingw32/include, + -I./src, + -I../openje/src, + -I../tracing/src + ] + +ClangTidy: + Add: + Checks: '*' diff --git a/.cppcheck-suppress b/.cppcheck-suppress new file mode 100644 index 0000000..3e31ea7 --- /dev/null +++ b/.cppcheck-suppress @@ -0,0 +1,3 @@ +unusedVariable +missingIncludeSystem +missingInclude diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml new file mode 100755 index 0000000..9678d44 --- /dev/null +++ b/.github/workflows/nightly.yml @@ -0,0 +1,121 @@ +name: Nightly Windows build + +on: + schedule: + # Runs every night at 03:00 UTC; adjust as needed + - cron: "0 3 * * *" + workflow_dispatch: {} # allow manual runs from the UI + +permissions: + contents: write # needed to create/update releases & upload assets + packages: read # needed to pull GHCR image + +env: + # CHANGE THIS to your GitHub user or org name (the owner of the original repo) + ORIGIN_OWNER: OpenJE + +jobs: + build-nightly-linux-container: + if: github.repository_owner == env.ORIGIN_OWNER + runs-on: ubuntu-latest + + steps: + - name: Checkout source + uses: actions/checkout@v4 + + - name: Log in to GitHub Container Registry + run: | + echo "${{ secrets.GITHUB_TOKEN }}" | + docker login ghcr.io -u "${{ github.actor }}" --password-stdin + + - name: Build with nmake (MSVC 2002 via Docker container) + run: | + # If you need a specific makefile: + # nmake /f path\to\your.mak + docker run --rm \ + -u 0:0 \ + -v "$PWD":/src \ + -w /src \ + ghcr.io/OpenJE/msvc2002:latest \ + nmake + + - name: Locate EXE + id: find-exe + run: | + set -e + exe=$(find . -maxdepth 6 -type f -iname '*.exe' | head -n 1) + if [ -z "$exe" ]; then + echo "No EXE found" >&2 + exit 1 + fi + echo "exe=$exe" >> "$GITHUB_OUTPUT" + echo "Found: $exe" + + - name: Create or update 'nightly' release and upload EXE + uses: ncipollo/release-action@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag: nightly + name: Nightly + body: | + Nightly build (Linux host invoking MSVC 2002 container). + Commit: ${{ github.sha }} + Ref: ${{ github.ref }} + Workflow run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + artifacts: ${{ steps.find-exe.outputs.exe }} + artifactContentType: application/octet-stream + allowUpdates: true + replacesArtifacts: false + makeLatest: false + prerelease: true + + build-nightly-windows-msvc: + if: github.repository_owner != env.ORIGIN_OWNER + runs-on: windows-latest + + steps: + - name: Checkout source + uses: actions/checkout@v4 + + - name: Set up MSVC Developer Command Prompt + uses: ilammy/msvc-dev-cmd@v1 + with: + arch: x86 # or x64 + + - name: Build with nmake (latest MSVC) + run: | + REM If you use a specific .mak: + REM nmake /f path\to\your.mak + nmake + + - name: Locate EXE + id: find-exe + shell: pwsh + run: | + $exe = Get-ChildItem -Path . -Recurse -Filter *.exe | Select-Object -First 1 + if (-not $exe) { + Write-Error "No EXE found" + exit 1 + } + "exe=$($exe.FullName)" >> $env:GITHUB_OUTPUT + Write-Host "Found: $($exe.FullName)" + + - name: Create or update 'nightly' release and upload EXE + uses: ncipollo/release-action@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag: nightly + name: Nightly + body: | + Nightly build (Windows MSVC). + Commit: ${{ github.sha }} + Ref: ${{ github.ref }} + Workflow run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + artifacts: ${{ steps.find-exe.outputs.exe }} + artifactContentType: application/octet-stream + allowUpdates: true + replacesArtifacts: false + makeLatest: false + prerelease: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100755 index 0000000..860ffb6 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,112 @@ +name: Build Windows binary for release + +on: + release: + types: [published] # fires when you publish a GitHub Release + workflow_dispatch: {} # allow manual trigger for testing + +permissions: + contents: write # needed to upload release assets + packages: read # needed to pull GHCR image + +env: + # CHANGE THIS to your GitHub user or org name (the owner of the original repo) + ORIGIN_OWNER: OpenJE + +jobs: + # 1. Linux job that INVOKES the MSVC 2003 container via docker run + build-linux-container: + # Only run: + # - in the original repo (not forks) + if: github.repository_owner == env.ORIGIN_OWNER + + runs-on: ubuntu-latest + + steps: + - name: Checkout source + uses: actions/checkout@v4 + + - name: Log in to GitHub Container Registry + run: | + echo "${{ secrets.GITHUB_TOKEN }}" | + docker login ghcr.io -u "${{ github.actor }}" --password-stdin + + - name: Build with nmake (MSVC 2002 via Docker container) + run: | + # If you use a specific .mak file, change the last argument to e.g.: + # nmake /f path\to\your.mak + docker run --rm \ + -u 0:0 \ + -v "$PWD":/src \ + -w /src \ + ghcr.io/OpenJE/msvc2002:latest \ + nmake + + - name: Locate EXE + id: find-exe + run: | + set -e + exe=$(find . -maxdepth 6 -type f -iname '*.exe' | head -n 1) + if [ -z "$exe" ]; then + echo "No EXE found" >&2 + exit 1 + fi + echo "exe=$exe" >> "$GITHUB_OUTPUT" + echo "Found: $exe" + + - name: Upload EXE to this GitHub Release + if: github.event_name == 'release' + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: ${{ steps.find-exe.outputs.exe }} + asset_name: MyProgram-container-${{ github.ref_name }}.exe + asset_content_type: application/octet-stream + + # 2. Windows job using latest MSVC on windows-latest, with nmake + build-windows-msvc: + # Run on forks (i.e., not the original repo owner) + if: github.repository_owner != env.ORIGIN_OWNER + + runs-on: windows-latest + + steps: + - name: Checkout source + uses: actions/checkout@v4 + + # Set up the Visual C++ build environment (nmake, cl, etc.) + - name: Set up MSVC Developer Command Prompt + uses: ilammy/msvc-dev-cmd@v1 + with: + arch: x86 # or x64, adjust for your app + + - name: Build with nmake (latest MSVC) + run: | + REM If you use a specific .mak file, do: + REM nmake /f path\to\your.mak + nmake + + - name: Locate EXE + id: find-exe + shell: pwsh + run: | + $exe = Get-ChildItem -Path . -Recurse -Filter *.exe | Select-Object -First 1 + if (-not $exe) { + Write-Error "No EXE found" + exit 1 + } + "exe=$($exe.FullName)" >> $env:GITHUB_OUTPUT + Write-Host "Found: $($exe.FullName)" + + - name: Upload EXE to this GitHub Release + if: github.event_name == 'release' + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: ${{ steps.find-exe.outputs.exe }} + asset_name: MyProgram-msvc-${{ github.ref_name }}.exe + asset_content_type: application/octet-stream diff --git a/.gitignore b/.gitignore index 043d84f..7e76577 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ -Debug -Release \ No newline at end of file +build/* +obj/* +vc70.pdb +log.txt diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..73d9183 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "openje"] + path = openje + url = https://github.com/OpenJE/openje +[submodule "tracing"] + path = tracing + url = https://github.com/OpenJE/tracing diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json deleted file mode 100755 index e384315..0000000 --- a/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "configurations": [ - { - "name": "Windows-x86", - "includePath": - [ - "${workspaceFolder}/../openje/src", - "${workspaceFolder}/src", - "${workspaceFolder}/../vc7/include", - "${workspaceFolder}/../vc7/PlatformSDK/Include" - ], - "defines": [], - "compilerPath": "", - "compilerArgs": [], - "cStandard": "c99", - "cppStandard": "c++03", - "intelliSenseMode": "windows-msvc-x86" - } - ], - "version": 4 -} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100755 index 3510f54..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "files.associations": { - "*.cppm": "*.cpp", - "array": "cpp", - "atomic": "cpp", - "bit": "cpp", - "*.tcc": "cpp", - "cctype": "cpp", - "charconv": "cpp", - "clocale": "cpp", - "cmath": "cpp", - "compare": "cpp", - "concepts": "cpp", - "cstdarg": "cpp", - "cstddef": "cpp", - "cstdint": "cpp", - "cstdio": "cpp", - "cstdlib": "cpp", - "ctime": "cpp", - "cwchar": "cpp", - "cwctype": "cpp", - "deque": "cpp", - "set": "cpp", - "string": "cpp", - "unordered_map": "cpp", - "vector": "cpp", - "exception": "cpp", - "algorithm": "cpp", - "functional": "cpp", - "iterator": "cpp", - "memory": "cpp", - "memory_resource": "cpp", - "numeric": "cpp", - "optional": "cpp", - "random": "cpp", - "string_view": "cpp", - "system_error": "cpp", - "tuple": "cpp", - "type_traits": "cpp", - "utility": "cpp", - "format": "cpp", - "initializer_list": "cpp", - "iosfwd": "cpp", - "limits": "cpp", - "new": "cpp", - "numbers": "cpp", - "ostream": "cpp", - "span": "cpp", - "stdexcept": "cpp", - "streambuf": "cpp", - "text_encoding": "cpp", - "typeinfo": "cpp", - "variant": "cpp", - "map": "cpp", - "iostream": "cpp", - "istream": "cpp", - "fstream": "cpp", - "xiosbase": "cpp", - "cerrno": "cpp", - "cstring": "cpp", - "ios": "cpp", - "xdebug": "cpp", - "xlocale": "cpp", - "xlocinfo": "cpp", - "xlocnum": "cpp", - "xmemory": "cpp", - "xstddef": "cpp", - "xstring": "cpp", - "xutility": "cpp" - } -} \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d6cc73e --- /dev/null +++ b/Makefile @@ -0,0 +1,75 @@ +CFG = Debug +OPENVB = . +OPENJE = .\openje +TRACING = .\tracing + +CC = cl +LINK = link + +EXE = F3.exe + +!IF "$(CFG)" == "Debug" +EXE = $(OPENVB)\build\F3-dbg.exe +!ELSE +EXE = $(OPENVB)\build\F3.exe +!ENDIF + +INCS = /I$(OPENVB)\src \ + /I$(OPENJE)\src \ + /I$(TRACING)\src + +SRCS = $(OPENVB)\src\main.cpp \ + $(OPENVB)\src\F3.cpp \ + $(OPENJE)\src\JE.cpp \ + $(TRACING)\src\tracing.cpp + +OBJS = $(OPENVB)\obj\main.obj \ + $(OPENVB)\obj\F3.obj \ + $(OPENJE)\obj\JE.obj \ + $(TRACING)\obj\tracing.obj + +LIBS = user32.lib \ + gdi32.lib \ + winmm.lib \ + shell32.lib + +DEBUG_ARGS = /c \ + /EHsc \ + /Zi \ + /Od \ + /GS \ + /DTRACING \ + /DTRACE_TERMINAL \ + /DTRACE_FILE + +ARGS = /c \ + /EHsc \ + /O2 + +!IF "$(CFG)" == "Debug" +CFLAGS = $(INCS) $(DEBUG_ARGS) +LDFLAGS = /DEBUG +!ELSE +CFLAGS = $(INCS) $(ARGS) +LDFLAGS = +!ENDIF + +all: $(EXE) + +$(OPENVB)\obj\main.obj: $(OPENVB)\src\main.cpp + $(CC) $(CFLAGS) /Fo$(OPENVB)\obj\main.obj $(OPENVB)\src\main.cpp + +$(OPENVB)\obj\F3.obj: $(OPENVB)\src\F3.cpp + $(CC) $(CFLAGS) /Fo$(OPENVB)\obj\F3.obj $(OPENVB)\src\F3.cpp + +$(OPENJE)\obj\JE.obj: $(OPENJE)\src\JE.cpp + $(CC) $(CFLAGS) /Fo$(OPENJE)\obj\JE.obj $(OPENJE)\src\JE.cpp + +$(TRACING)\obj\tracing.obj: $(TRACING)\src\tracing.cpp + $(CC) $(CFLAGS) /Fo$(TRACING)\obj\tracing.obj $(TRACING)\src\tracing.cpp + +$(EXE): $(OBJS) + $(LINK) $(OBJS) $(LIBS) /OUT:$(EXE) $(LDFLAGS) + +clean: + -del $(OBJS) $(EXE) diff --git a/ReadMe.txt b/ReadMe.txt deleted file mode 100755 index 6c10231..0000000 --- a/ReadMe.txt +++ /dev/null @@ -1,54 +0,0 @@ -======================================================================== - WIN32 APPLICATION : OpenVB Project Overview -======================================================================== - -AppWizard has created this openvb application for you. -This file contains a summary of what you will find in each of the files that -make up your openvb application. - - -openvb.vcproj - This is the main project file for VC++ projects generated using an Application Wizard. - It contains information about the version of Visual C++ that generated the file, and - information about the platforms, configurations, and project features selected with the - Application Wizard. - -openvb.cpp - This is the main application source file. - -///////////////////////////////////////////////////////////////////////////// -AppWizard has created the following resources: - -openvb.rc - This is a listing of all of the Microsoft Windows resources that the - program uses. It includes the icons, bitmaps, and cursors that are stored - in the RES subdirectory. This file can be directly edited in Microsoft - Visual C++. - -Resource.h - This is the standard header file, which defines new resource IDs. - Microsoft Visual C++ reads and updates this file. - -openvb.ico - This is an icon file, which is used as the application's icon (32x32). - This icon is included by the main resource file openvb.rc. - -small.ico - This is an icon file, which contains a smaller version (16x16) - of the application's icon. This icon is included by the main resource - file openvb.rc. - -///////////////////////////////////////////////////////////////////////////// -Other standard files: - -StdAfx.h, StdAfx.cpp - These files are used to build a precompiled header (PCH) file - named openvb.pch and a precompiled types file named StdAfx.obj. - -///////////////////////////////////////////////////////////////////////////// -Other notes: - -AppWizard uses "TODO:" comments to indicate parts of the source code you -should add to or customize. - -///////////////////////////////////////////////////////////////////////////// diff --git a/Resource.h b/Resource.h deleted file mode 100755 index 0ea78d3..0000000 --- a/Resource.h +++ /dev/null @@ -1,29 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by openvb.rc -// - -#define IDS_APP_TITLE 103 - -#define IDR_MAINFRAME 128 -#define IDD_OPENVB_DIALOG 102 -#define IDD_ABOUTBOX 103 -#define IDM_ABOUT 104 -#define IDM_EXIT 105 -#define IDI_OPENVB 107 -#define IDI_SMALL 108 -#define IDC_OPENVB 109 -#define IDC_MYICON 2 -#define IDC_STATIC -1 -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS - -#define _APS_NO_MFC 130 -#define _APS_NEXT_RESOURCE_VALUE 129 -#define _APS_NEXT_COMMAND_VALUE 32771 -#define _APS_NEXT_CONTROL_VALUE 1000 -#define _APS_NEXT_SYMED_VALUE 110 -#endif -#endif diff --git a/STYLE.md b/STYLE.md new file mode 100644 index 0000000..9e72b63 --- /dev/null +++ b/STYLE.md @@ -0,0 +1,600 @@ +--- + +# 0. Goals & Constraints + +- **Goal:** Produce C++ code that looks and feels like Black Isle’s Jefferson / Van Buren engine circa 2002–2003. +- **Target toolchain:** MSVC, C++98 dialect, Windows + DirectX (8/8.1 era). +- **Philosophy:** Pragmatic, engine‑style C++: + - Namespaced, object‑oriented. + - Manual memory management (`new`/`delete`). + - Uses STL containers (`std::vector`, `std::map`, etc.). + - Minimal exceptions in engine paths; errors via return codes + logging. + - Naming, error messages, and subsystems consistent with the strings in the binary. + +--- + +# 1. Project Structure + +## 1.1 Files + +- Use **paired `.h`/`.cpp` files** for each major class or subsystem. + - Example: + - `GameEntity.h` / `GameEntity.cpp` + - `Gfx_Texture.h` / `Gfx_Texture.cpp` + - `VFX_ParticleSystem.h` / `VFX_ParticleSystem.cpp` +- Use `#pragma once` at the top of all headers (VC style): + + ```cpp + #pragma once + ``` + +- Use a precompiled header (e.g. `stdafx.h`) included **first in every `.cpp`**: + + ```cpp + #include "stdafx.h" + #include "GameEntity.h" + #include "GameWeapon.h" + ``` + +## 1.2 Namespaces & Modules + +Create namespaces for the major subsystems seen in the strings: + +- `namespace Game { ... }` – core gameplay: + - `GameEntity`, `GameCreature`, `GameWeapon`, `GameWorldMap`, `GameJournal`, `GameClient`, `GameServer`, etc. +- `namespace Gfx { ... }` – graphics abstraction: + - `Gfx_Engine`, `Gfx_Texture`, `Gfx_Texture_Manager`, `Gfx_RenderManager`, `Gfx_AnimationObject`, `Gfx_AnimationData`, `Gfx_AnimMeshInstance`, etc. +- `namespace G3D { ... }` – 3D scene and mesh: + - `G3D_Mesh`, `G3D_Node`, `G3D_Camera`, `G3D_DirectionalLight`. +- `namespace VFX { ... }` – particle and visual effects: + - `VFX_Effect`, `VFX_EffectInstance`, `VFX_ParticleSystem`, `VFX_VEGInstance`, `VFX_Rain`, `VFX_Snow`, `VFX_Wind`. +- `namespace GUI { ... }` – user interface framework: + - `GUI::Window`, `GUI::Button`, `GUI::Label`, `GUI::Picture`, etc. +- `namespace net { ... }` – networking: + - `net::server`, `net::client`, `net::connection`, `net::socket`, `net::packet`, `net::buffer`, etc. +- `namespace Common { ... }` – utilities (chunks, polygons, exceptions, etc.). +- `namespace SS { ... }` – string system: + - `SS::StringSystem`, `SS::EngineStringSystem`. + +**Guideline:** +Put classes in one of these namespaces and/or give them the appropriate prefix: + +- Gameplay: `GameSomething` +- Graphics: `Gfx_Something` +- VFX: `VFX_Something` +- 3D: `G3D_Something` +- GUI: `GUI::Something` or `CWhateverInterface` (see below). + +--- + +# 2. Formatting & Layout + +## 2.1 Indentation and braces + +- Indent with **tabs**, NOT spaces. +- Use **Allman** brace style: + + ```cpp + if (bIsVisible) + { + Render(); + } + else + { + // ... + } + ``` + +- One class per header, one namespace per file where practical. + +## 2.2 Line length and spacing + +- Aim for **≤ 100 characters** per line. +- Put spaces: + - After keywords: `if (`, `while (`, `for (`. + - Around binary operators: `a + b`, `x == y`. + - No spaces just inside parentheses: `Func(a, b)` not `Func( a, b )`. + +Examples: + +```cpp +for (int nIndex = 0; nIndex < nCount; ++nIndex) +{ + float fAlpha = 0.0f; + // ... +} +``` + +--- + +# 3. Naming Conventions + +## 3.1 Types (classes, structs, enums) + +- **Classes/structs:** PascalCase. +- **Subsystem prefixes** are common: + - `GameEntity`, `GameWeapon`, `GameActionAttack`, `GameAnimationCache`. + - `Gfx_Texture`, `Gfx_Engine`, `Gfx_RenderManager`, `Gfx_AnimationObject`. + - `G3D_Mesh`, `G3D_Node`, `G3D_Camera`. + - `VFX_Effect`, `VFX_ParticleSystem`, `VFX_Rain`. + - `StringSystem`, `EngineStringSystem`. +- **GUI and “interface” classes** use `C` prefix: + + ```cpp + class CEngineInterface; + class CPipBoyInterface; + class CMainmenuInterface; + class CInventoryInterface; + class CActionbarInterface; + class COptionsVideoInterface; + ``` + +- **Enums:** + - Type names: `VFX_EffectType`, `VFX_WaterMotionType`, `VFX_CollisionType`, `VFX_LightType`, `GFX_RENDER_PHASE`, etc. + - Enum values: ALL_CAPS with subsystem prefix: + + ```cpp + enum VFX_EffectType + { + VFXEFFECTTYPE_NONE = 0, + VFXEFFECTTYPE_MODEL, + VFXEFFECTTYPE_SPRITE, + VFXEFFECTTYPE_LIGHT, + VFXEFFECTTYPE_TRAIL, + VFXEFFECTTYPE_WATER, + VFXEFFECTTYPE_SOUND, + VFXEFFECTTYPE_RAIN, + VFXEFFECTTYPE_SNOW, + VFXEFFECTTYPE_WIND, + VFXEFFECTTYPE_LIGHTNING, + VFXEFFECTTYPE_PARTICLESYSTEM, + VFXEFFECTTYPE_COLLISION, + VFXEFFECTTYPE_MODELEFFECT, + VFXEFFECTTYPE_MOTIONBLUR + }; + ``` + +## 3.2 Functions and methods + +- **Methods:** PascalCase, verbs first: + + ```cpp + void OnCreate(); + void OnDestroy(); + void OnUpdate(float fDeltaTime); + void OnServerCreate(); + void OnServerUpdate(); + void Queue_Walk(); + void Queue_Limp(); + void QueueToCombat(); + void QueryDefaultAnimation(); + ``` + +- The `_` separator is used occasionally to separate operation and state (`Queue_To_Crouch`, `Queue_Limp`); mimic it where you see it in the original strings. + +- **Global functions / native script functions:** + + ```cpp + void WorldMapSetAreaVisible(int nAreaId, bool bVisible); + void SetWorldMapAreaExplorable(int nAreaId, bool bExplorable); + void SetAreaRestStatus(int nAreaId, bool bAllowed); + + // Script-callable (note A_ prefix): + void A_SendMessageToTeam(int nFromId, int nTeamId, int nMessageId); + void A_Wander(int nEntityId); + void A_PickupItem(int nEntityId, int nItemId); + ``` + +- **Overloads:** Use overloads or additional parameters rather than cryptic suffixes. + +## 3.3 Variables and members + +### 3.3.1 Member variables + +- Prefix with `m_`, then CamelCase: + + ```cpp + class GameWeapon + { + private: + int m_nCaliber; + int m_nModifier; + bool m_bUsesPrimaryAmmo; + bool m_bUsesSecondaryAmmo; + float m_fReloadTime; + }; + ``` + +### 3.3.2 Statics and globals + +- **Static members:** `s_` prefix. + + ```cpp + class Gfx_Engine + { + private: + static Gfx_Engine* s_pInstance; + }; + ``` + +- **Globals / singletons:** `g_` prefix (if you need them): + + ```cpp + extern Game::GameClient* g_pGameClient; + ``` + +### 3.3.3 Locals and parameters (Hungarian‑lite) + +Use short type hints, as seen in the engine’s messages: + +- `p` – pointer: `pOwner`, `pEntity`, `pTexture`. +- `n` – integer number: `nIndex`, `nCount`, `nDamage`, `nCaliber`. +- `b` – boolean: `bVisible`, `bActive`, `bFound`. +- `f` – float: `fDeltaTime`, `fAlpha`, `fRange`. +- `dw` – 32‑bit `DWORD`: `dwFlags`, `dwUID`. +- `sz` / `psz` – C strings: `szBuffer`, `pszName`. + +Examples: + +```cpp +bool GameWeapon::ReloadPrimaryAmmo(GameEntity* pOwner) +{ + if (!pOwner) + return false; + + int nAmmoNeeded = 0; + float fReloadTime = 0.0f; + bool bHasAmmo = false; + + // ... +} +``` + +### 3.3.4 GUI identifiers + +For GUI elements, follow the prefixes you see in the strings: + +- Buttons: `btn...` + - `btnInventory`, `btnCombatSpeed`, `btnMusicVolume`. +- Labels: `lbl...` + - `lblHeadBiologicalValue`, `lblWeapon01AP_up`. +- Pictures: `pic...` + - `picWeapon01Icon_up`, `picTargetHighlight`. +- Windows: `win...` + - `winActionbar`, `winMiniMap`, `winMessageBox`. +- Text edits: `edit...` or `TextEdit` (seen as `TextEdit`). +- Toggle/checkbox: `btn...` plus state suffixes (`Up/Down/Selected/Disabled`). +- Special: `bl...` often for “block” or “label group” (`blHotkeys`, `blGame`), `tn...` for “tiny number” / spinner. + +Example: + +```cpp +GUI::Window* winActionbar = NULL; +GUI::Button* btnInventory = NULL; +GUI::Label* lblActionPointsValue = NULL; +GUI::Picture* picTargetHighlight = NULL; +``` + +--- + +# 4. Error Handling & Logging + +## 4.1 General philosophy + +- Don’t throw exceptions in engine/gameplay hot paths. +- Prefer **return codes** (`bool`, `HRESULT`) plus **logging**. +- Use assertions for internal invariants (you can define `ASSERT` wrapping `_ASSERTE` / `assert`). + +## 4.2 Log message format + +The strings show a consistent pattern: + +- `"ClassName::MethodName() - Message...\n"` + or +- `"Subsystem_Class::Method - Message...\n"` + +Examples to emulate: + +```cpp +LogError("GameWeapon::ReloadPrimaryAmmo() - This weapon doesn't even use ammo.\n"); +LogError("Gfx_Engine::ProcessFogOfWar - trying to use an invalid texture!\n"); +LogError("Gfx_AnimationObject::ApplyAnimation - pModelTrackMask == NULL\n"); +LogError("GameEntity::Queue_Limp() - Unknown weapon stance encountered.\n"); +LogError("GameActionAttack::OnServerUpdate() - Target entity is already dead.\n"); +``` + +For resource or system errors: + +```cpp +LogError("Gfx_Texture_Manager::LoadTextureFromBuffer() failed to load: %s\n", pszFilename); +LogError("ResourceSystem::FileStreamSeek - Tried a bad seek from the end of file %s - endpos = %d tried = %d\n", + pszFilename, nEndPos, nTried); +``` + +**Guideline:** + +- Always include the class and method name at the start of the message. +- End messages with `\n`. +- For functions that are not class methods (e.g. static helpers), use a subsystem prefix: `World::CreateEffect()`, `MapEffectSetActive()`. + +## 4.3 HRESULT and DirectX errors + +- When calling DirectX APIs, check `HRESULT` and log with hex codes and descriptive strings: + + ```cpp + HRESULT hr = m_pDevice->CreateTexture(...); + if (FAILED(hr)) + { + LogError("Gfx_Texture_Manager::AddTexture - CreateTexture Failed (%x %s)\n", hr, pszName); + return false; + } + ``` + +--- + +# 5. Memory Management + +- Use raw pointers and manual `new`/`delete`: + + ```cpp + Gfx_Texture* pTexture = new Gfx_Texture(); + // ... + delete pTexture; + pTexture = NULL; + ``` + +- Use `NULL` (not `nullptr`) for null pointers. +- If implementing custom allocators (`ResourceSystem`, `ResourceCache`), keep their style: + + - Functions like `ResourceSystem::MemStreamOpen`, `ResourceSystem::MemStreamSeek`. + - Log on allocation failures: `ResourceSystem::OpenFile - Couldn't allocate enough memory for ...`. + +- Avoid reference-counted smart pointers unless you can hide them under existing interfaces. They likely used manual reference counting or simple ownership. + +--- + +# 6. Use of STL and Standard Library + +The strings clearly show STL use (`vector too long`, `map/set too long`, etc.), so: + +- **Allowed (and encouraged)** in reconstruction: + - `std::vector` + - `std::map` + - `std::set` + - `std::list` + - `std::deque` + - `std::string` + - Standard exceptions and I/O, but use them judiciously in engine code. + +- Prefer fully‑qualified names in headers: + + ```cpp + #include + #include + + class GameParty + { + private: + std::vector m_PartyMembers; + std::string m_sName; + }; + ``` + +- You can use `using std::vector;` in `.cpp` files if it improves readability, but avoid `using namespace std;` in headers. + +- For authenticity, avoid template‑heavy designs; use STL in straightforward ways. + +--- + +# 7. Windows & DirectX Conventions + +- Use Win32 / DirectX types: + - `DWORD`, `WORD`, `BYTE`, `BOOL`, `HRESULT`. +- Handle errors by mapping them to descriptive strings, as seen in the string table: + - `D3DERR_OUTOFVIDEOMEMORY`, `D3DERR_INVALIDCALL`, `DDERR_SURFACELOST`, `VFW_E_*`, `DMUS_E_*`, etc. +- Wrap DirectX objects in C++ classes: + - `Gfx_D3D`, `Gfx_Engine`, `Gfx_Texture`, `Gfx_RenderStyle`, etc. +- Use D3D 8/9‑style FVF / shader assembly style in `.fx` content (exact effect strings are already inside your resource data; mimic the naming, not necessarily rewrite them). + +--- + +# 8. Scripting Interface Style + +The strings show many script-facing functions: + +- `A_SendMessageToSquad`, `A_AddFloatingSpeechText`, `A_Wander`, `A_PickupItem`, `A_MoveToEntity`. +- Engine‑side wrappers that say “Native...” or “Script_Small::Debugger()`. + +Guidelines: + +- **Script-exposed native functions** should be free functions or static functions with: + + - Simple parameter lists (`int` IDs, primitive types, vector structs). + - C‑style names that start with `A_` (for “Action”) or `Native...` when appropriate. + + ```cpp + void A_SendMessageToTeam(int nFromEntityId, int nTeamId, int nMessageId); + void A_AddFloatingSpeechText(int nEntityId, int nStrRef); + ``` + +- **Error messages** for script functions follow the pattern: + + ```cpp + LogError("A_SendMessageToTeam() was unable to resolve address of parameter %d.\n", nParamIndex); + LogError("DialogueCall() was unable to retrieve the function name.\n"); + ``` + +--- + +# 9. Comments & Documentation + +- Use `//` for single‑line comments. +- Use `/* ... */` only for short blocks or temporarily commenting out code. +- Avoid Doxygen-style tags unless you really want to; the original code likely kept comments fairly plain. + +Examples: + +```cpp +// Apply damage, considering DR/DT, criticals, etc. +bool GameWeapon::ApplyDamage(GameEntity* pAttacker, GameEntity* pTarget) +{ + // ... +} +``` + +--- + +# 10. Example: Full Class Skeleton in BIS Style + +Here is a more complete example of a Van Buren–style class using the guidelines: + +```cpp +// GameWeapon.h +#pragma once + +#include "GameEntity.h" + +namespace Game +{ + class GameWeapon + { + public: + GameWeapon(); + ~GameWeapon(); + + bool ReloadPrimaryAmmo(GameEntity* pOwner); + bool ReloadSecondaryAmmo(GameEntity* pOwner); + + bool CalculateDamage(GameEntity* pAttacker, + GameEntity* pTarget, + int nCalledTarget, + int& rnDamageOut) const; + + float CalculateRangedToHit(GameEntity* pAttacker, + GameEntity* pTarget) const; + + private: + bool ResolveTargets(GameEntity* pAttacker, GameEntity* pTarget) const; + + private: + int m_nCaliber; + int m_nModifier; + bool m_bUsesPrimaryAmmo; + bool m_bUsesSecondaryAmmo; + float m_fReloadTime; + }; +} +``` + +```cpp +// GameWeapon.cpp +#include "stdafx.h" +#include "GameWeapon.h" +#include "StringSystem.h" +#include "ResourceSystem.h" +#include "Log.h" + +using namespace Game; + +GameWeapon::GameWeapon() +: m_nCaliber(0) +, m_nModifier(0) +, m_bUsesPrimaryAmmo(false) +, m_bUsesSecondaryAmmo(false) +, m_fReloadTime(0.0f) +{ +} + +GameWeapon::~GameWeapon() +{ +} + +bool GameWeapon::ReloadPrimaryAmmo(GameEntity* pOwner) +{ + if (!m_bUsesPrimaryAmmo) + { + LogError("GameWeapon::ReloadPrimaryAmmo() - This weapon doesn't even use ammo.\n"); + return false; + } + + if (!pOwner) + { + LogError("GameWeapon::ReloadPrimaryAmmo() - NULL owner pointer.\n"); + return false; + } + + // TODO: Look up ammo in pOwner's inventory and adjust m_fReloadTime. + + return true; +} + +bool GameWeapon::CalculateDamage(GameEntity* pAttacker, + GameEntity* pTarget, + int nCalledTarget, + int& rnDamageOut) const +{ + if (!pAttacker || !pTarget) + { + LogError("GameWeapon::CalculateDamage() - NULL attacker or target.\n"); + return false; + } + + if (!ResolveTargets(pAttacker, pTarget)) + { + LogError("GameWeapon::CalculateDamage() - ResolveTargets() failed.\n"); + return false; + } + + switch (nCalledTarget) + { + case CALLEDTARGET_HEAD: + // ... + break; + + case CALLEDTARGET_TORSO: + // ... + break; + + default: + LogError("GameWeapon::CalculateDamage() - Unknown CALLEDTARGET encountered: %d\n", + nCalledTarget); + return false; + } + + // Set rnDamageOut appropriately... + rnDamageOut = 10; // placeholder + + return true; +} + +float GameWeapon::CalculateRangedToHit(GameEntity* pAttacker, + GameEntity* pTarget) const +{ + if (!pAttacker || !pTarget) + { + LogError("GameWeapon::CalculateRangedToHit() - NULL attacker or target.\n"); + return 0.0f; + } + + // TODO: Implement based on skills, range, etc. + return 75.0f; +} + +bool GameWeapon::ResolveTargets(GameEntity* pAttacker, GameEntity* pTarget) const +{ + if (!pAttacker || !pTarget) + return false; + + // TODO: visibility checks, etc. + return true; +} +``` + +This example follows: + +- Namespaces & prefixes. +- `m_` member naming. +- PascalCase functions, `OnXxx` style where appropriate. +- Logging style matching the real messages. + +--- diff --git a/openje b/openje new file mode 160000 index 0000000..57a9aa8 --- /dev/null +++ b/openje @@ -0,0 +1 @@ +Subproject commit 57a9aa812aa18914205d0e008e4b55675422fcc7 diff --git a/openvb.ico b/openvb.ico deleted file mode 100755 index d551aa3..0000000 Binary files a/openvb.ico and /dev/null differ diff --git a/openvb.ncb b/openvb.ncb deleted file mode 100755 index 1cb1ae0..0000000 Binary files a/openvb.ncb and /dev/null differ diff --git a/openvb.rc b/openvb.rc deleted file mode 100755 index c082fc2..0000000 --- a/openvb.rc +++ /dev/null @@ -1,128 +0,0 @@ -//Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#define APSTUDIO_HIDDEN_SYMBOLS -#include "windows.h" -#undef APSTUDIO_HIDDEN_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE 9, 1 -#pragma code_page(1252) - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. - -IDI_OPENJE ICON "openvb.ico" -IDI_SMALL ICON "small.ico" - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -IDC_OPENJE MENU -BEGIN - POPUP "&File" - BEGIN - MENUITEM "E&xit", IDM_EXIT - END - POPUP "&Help" - BEGIN - MENUITEM "&About ...", IDM_ABOUT - END -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Accelerator -// - -IDC_OPENJE ACCELERATORS -BEGIN - "?", IDM_ABOUT, ASCII, ALT - "/", IDM_ABOUT, ASCII, ALT -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_ABOUTBOX DIALOG 22, 17, 230, 75 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -CAPTION "About" -FONT 8, "System" -BEGIN - ICON IDI_OPENVB,IDC_MYICON,14,9,16,16 - LTEXT "openvb Version 1.0",IDC_STATIC,49,10,119,8,SS_NOPREFIX - LTEXT "Copyright (C) 2024",IDC_STATIC,49,20,119,8 - DEFPUSHBUTTON "OK",IDOK,195,6,30,11,WS_GROUP -END - - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" - "#include ""windows.h""\r\n" - "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE -BEGIN - IDC_OPENVB "OPENVB" - IDS_APP_TITLE "openvb" -END - -#endif -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED diff --git a/openvb.sln b/openvb.sln deleted file mode 100755 index 6bf1586..0000000 --- a/openvb.sln +++ /dev/null @@ -1,21 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 8.00 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "openvb", "openvb.vcproj", "{93140CF9-D749-4BEE-AF2C-5A1F822205D3}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfiguration) = preSolution - Debug = Debug - Release = Release - EndGlobalSection - GlobalSection(ProjectConfiguration) = postSolution - {93140CF9-D749-4BEE-AF2C-5A1F822205D3}.Debug.ActiveCfg = Debug|Win32 - {93140CF9-D749-4BEE-AF2C-5A1F822205D3}.Debug.Build.0 = Debug|Win32 - {93140CF9-D749-4BEE-AF2C-5A1F822205D3}.Release.ActiveCfg = Release|Win32 - {93140CF9-D749-4BEE-AF2C-5A1F822205D3}.Release.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - EndGlobalSection - GlobalSection(ExtensibilityAddIns) = postSolution - EndGlobalSection -EndGlobal diff --git a/openvb.suo b/openvb.suo deleted file mode 100644 index ca9f57b..0000000 Binary files a/openvb.suo and /dev/null differ diff --git a/openvb.vcproj b/openvb.vcproj deleted file mode 100755 index fe8875e..0000000 --- a/openvb.vcproj +++ /dev/null @@ -1,180 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/small.ico b/small.ico deleted file mode 100755 index d551aa3..0000000 Binary files a/small.ico and /dev/null differ diff --git a/src/F3.cpp b/src/F3.cpp new file mode 100755 index 0000000..20a78b4 --- /dev/null +++ b/src/F3.cpp @@ -0,0 +1,191 @@ +// Copyright 2024 OpenJE + +#include +#include +#include +#include +#include + +#include "JE.hpp" +#include "F3.hpp" +#include "tracing.hpp" + +namespace F3 { + // 0x56B000 + char SetupSaveDirectory( CHAR *pcModulePath ) { + tracing::instrument( tracing::LOCATION, "pcModulePath=%s", pcModulePath ); + + int nCharIndexAbsolute; + char cCurrentCharAbsolute; + int nCharIndexRelative; + char cCurrentCharRelative; + char* pcSaveDirectoryRelative; + char cResult; + char szPersonalFolderPath[ MAX_PATH ]; + + if ( !getcwd( g_szCurrentWorkingDirectory, MAX_PATH ) ) { + JE::FatalError( "Unable to retrieve current working directory." ); + } + if ( SHGetFolderPath( (HWND)0x0, CSIDL_FLAG_CREATE | CSIDL_PERSONAL, (HANDLE)0x0, 0, szPersonalFolderPath ) ) { + JE::FatalError( "Unable to retrieve personal folder." ); + } + + nCharIndexAbsolute = 0; + do { + cCurrentCharAbsolute = szPersonalFolderPath[ nCharIndexAbsolute ]; + g_szSaveDirectoryAbsolute[ nCharIndexAbsolute ] = cCurrentCharAbsolute; + nCharIndexAbsolute = nCharIndexAbsolute + 1; + } while ( cCurrentCharAbsolute ); + + //sub_61ADFA( pcSaveDirectoryRelative, (char *)0x0, (char *)0x0, szPersonalFolderPath, (char *)0x0 ); + + nCharIndexRelative = 0; + do { + cCurrentCharRelative = szPersonalFolderPath[ nCharIndexRelative ]; + g_szSaveDirectoryRelative[ nCharIndexRelative ] = cCurrentCharRelative; + nCharIndexRelative = nCharIndexRelative + 1; + } while ( cCurrentCharRelative ); + + pcSaveDirectoryRelative = GetSaveDirectoryRelative(); + F3::PathConcat( g_szSaveDirectoryAbsolute, pcSaveDirectoryRelative ); + //cResult = sub_4C56B0( g_szSaveDirectoryAbsolute ); + if ( !cResult ) { + //cResult = sub_4C5750( g_szSaveDirectoryAbsolute ); + if ( !cResult ) { + JE::FatalError( "Unable to create save folder." ); + } + } + return cResult; + } // SetupSaveDirectory + + /* + // 0x56b220 + void SetupConfigFile( uint nCmdShow ) { + } // SetupConfigFile + */ + + // 0x56B100 + int SetupLogFile() { + tracing::instrument( tracing::LOCATION, "" ); + char* pcSaveDirectoryAbsolute; + int nFileNameOffset; + char cCurrentChar; + char* pcSaveDirectoryRelative; + char* pcExtension; + char cExtension; + char szFilePath[ MAX_PATH ]; + + pcSaveDirectoryAbsolute = GetSaveDirectoryAbsolute(); + nFileNameOffset = (int)( szFilePath - pcSaveDirectoryAbsolute ); + do { + cCurrentChar = *pcSaveDirectoryAbsolute; + pcSaveDirectoryAbsolute[ nFileNameOffset ] = *pcSaveDirectoryAbsolute; + ++pcSaveDirectoryAbsolute; + } + while ( cCurrentChar ); + pcSaveDirectoryRelative = GetSaveDirectoryRelative(); + PathConcat( szFilePath, pcSaveDirectoryRelative ); + pcExtension = &cExtension; + while ( *++pcExtension ) { + ; + } + strcpy( pcExtension, ".log" ); + //return OpenLogFile( FileName ); + return 0; + } // SetupLogFile + + /* + int OpenLogFile( const char* pcLogFilePath ) { + std::ios* ios; + std::ios::iostate ioState; + std::ios::iostate nFlagsToSet; + int nFileOpenResult; + char szLogFile[ MAX_PATH ] + unsigned int securityCookieXorResult; + unsigned int retaddr; + + if ( !F3::g_LogFilebuf.open( pcLogFilePath, std::ios::out | std::ios::in ) ) { + errorFlagsBuffer = &byte_707CF8[*(*byte_707CF8 + 4)]; + nFlagsToSet = ios->rdstate() | std::ios_base::eofbit; + if ( !ios->good() ) { + nFlagsToSet = ios->rdstate() | std::ios::failbit | std::ios::eofbit; + } + ios->clear( nFlagsToSet ); + } + fileOpenResult = *(*byte_707CF8 + 4); + if ( (byte_707CFC[fileOpenResult] & 6) != 0 ) { + JE::FatalError( "Unable to open log file %s.", szLogFile ); + } + return fileOpenResult; + } + */ + + // 0x56af10 + char *GetSaveDirectoryRelative() { + return g_szSaveDirectoryRelative; + } + + // 0x56af00 + char *GetSaveDirectoryAbsolute() { + return g_szSaveDirectoryAbsolute; + } + + // 0x4c58a0 + unsigned int PathConcat( const char *pcPathA, const char *pcPathB ) { + tracing::instrument( tracing::LOCATION, "pcPathA=\"%s\", pcPathB=%s", pcPathA, pcPathB ); + + unsigned int nPathALen; + char cLastCharPathA; + unsigned int nPathBLen; + + nPathALen = strlen( pcPathA ); + cLastCharPathA = pcPathA[ nPathALen - 1 ]; + if ( cLastCharPathA != '\\' && cLastCharPathA != '/' ) { + strcpy( (char *)&pcPathA[ nPathALen ], "\\" ); + } + nPathBLen = strlen( pcPathB ) + 1; + memcpy( (void *)&pcPathB[ strlen( pcPathA ) ], pcPathB, nPathBLen ); + return nPathBLen; + } + + int SetStartupTime( int nTime ) { + tracing::instrument( tracing::LOCATION, "nTime=%d", nTime ); + + int result; + + result = nTime; + g_nStartupTimeMS = nTime; + g_bIsStartupTimeSet = true; + return result; + } + + /* + std::filebuf* ShutdownGlobalLogStream() { + std::filebuf* result; + std::ios* ios; + std::ios::iostate ioState; + + result = g_bIsLogStreamInitialized; + if ( g_bIsLogStreamInitialized ) { + result = g_LogFilebuf.close(); + if ( !result ) { + ios = g_LogIos; + ioState = ios->rdstate() | std::ios_base::eofbit; + if ( !ios->good() ) { + ioState |= ios->rdstate() | std::ios::failbit | std::ios::eofbit; + } + ios->clear( ioState ); + return result; + } + } + return result; + } + */ + + namespace Display { + void DestroyGameWindow() { + tracing::instrument( tracing::LOCATION, "F3::g_window=0x%p", F3::g_window ); + DestroyWindow( F3::g_window ); + } + } // namespace Display +} // namespace F3 diff --git a/src/F3.hpp b/src/F3.hpp new file mode 100755 index 0000000..1ba0452 --- /dev/null +++ b/src/F3.hpp @@ -0,0 +1,67 @@ +// Copyright 2024 OpenJE + +#ifndef F3_H +#define F3_H + +#include +#include +#include + +// F3 Globals +namespace F3 { + static HINSTANCE g_hinstance; + static HWND g_window; + static unsigned long g_nSystemTimeMS; + static std::time_t g_nStartupTimeMS; + static bool g_bIsStartupTimeSet; + static BOOL g_bIsLogStreamInitialized; + static std::filebuf g_LogFilebuf; + static std::ios* g_LogIos; + static char g_szSaveDirectoryAbsolute[ MAX_PATH ]; + static char g_szSaveDirectoryRelative[ MAX_PATH ]; + static char g_save_directory_relative_path_0x70c1b8[ MAX_PATH ]; + static char directory_path_0x70c0b0[ MAX_PATH ]; + static char g_szCurrentWorkingDirectory[ MAX_PATH ]; + static int INT_00707d60; + static bool DAT_00707cf0; + static char CHAR_0070fd41[ 2 ]; + + char SetupSaveDirectory( CHAR *pcModulePath ); + //void SetupConfigFile(); + //int SetupLogFile(); + char *GetSaveDirectoryRelative(); + char *GetSaveDirectoryAbsolute(); + unsigned int PathConcat( const char *string_a, const char *string_b ); + int SetStartupTime( int nTime ); + //int Main(); + //void Quit(); + //void Startup(); + //void RegisterCommand ( const char* command, void (*func)() ); + //void GameStateLoop(); + //bool ProcessMessagesAndUpdateTime() + //void Shutdown(); + //char* FindSubstringInString ( char * string, char * sub_string ); + + //void SetStartupTime( time_t time ); + //char* sub_61B067( char * param_1, size_t param_2 ); + //void sub_61ADFA( char * some_string, char * drive_letter, char * directory_path, char * folder_path, char * file_extension ); + //void sub_4C58A0( char * param_1, undefined4 * param_2 ); + //char sub_4C56B0( LPCSTR param_1 ); + //char sub_4C5750( char * param_1 ); + //void sub_497120( char * format, ... ); + //char* get_some_directory_path_2(); + //undefined4 sub_6174DA( char * param_1, char * param_2 /*int ** param_3*/ ); + //undefined4 sub_61F82F( FILE * param_1, char * param_2 /*int ** param_3*/ ); + //ulonglong sub_616E24(); + //void sub_56B170(); + //void sub_497B70(); + //void sub_56B390(); + //char* sub_61AF79( LPSTR file_name, char *a2, int a3 ); + //BOOL sub_61AF42( LPCSTR root_path_name ); + //char* sub_61A6AA( char* dest, const char* source, size_t count ); + namespace Display { + void DestroyGameWindow(); + } // namespace Display +} + +#endif // F3_H diff --git a/src/f3/CGameFloatingTextInterface.hpp b/src/F3/CGameFloatingTextInterface/CGameFloatingTextInterface.hpp similarity index 100% rename from src/f3/CGameFloatingTextInterface.hpp rename to src/F3/CGameFloatingTextInterface/CGameFloatingTextInterface.hpp diff --git a/src/f3/CGameInterface.hpp b/src/F3/CGameInterface/CGameInterface.hpp similarity index 100% rename from src/f3/CGameInterface.hpp rename to src/F3/CGameInterface/CGameInterface.hpp diff --git a/src/f3/COptionsGameInterface.hpp b/src/F3/COptionsGameInterface/COptionsGameInterface.hpp similarity index 100% rename from src/f3/COptionsGameInterface.hpp rename to src/F3/COptionsGameInterface/COptionsGameInterface.hpp diff --git a/src/f3/CPipBoyAddNoteInterface.hpp b/src/F3/CPipBoyAddNoteInterface/CPipBoyAddNoteInterface.hpp similarity index 100% rename from src/f3/CPipBoyAddNoteInterface.hpp rename to src/F3/CPipBoyAddNoteInterface/CPipBoyAddNoteInterface.hpp diff --git a/src/f3/CPipBoyInterface.hpp b/src/F3/CPipBoyInterface/CPipBoyInterface.hpp similarity index 100% rename from src/f3/CPipBoyInterface.hpp rename to src/F3/CPipBoyInterface/CPipBoyInterface.hpp diff --git a/src/f3/display.cpp b/src/F3/Display/Display.cpp similarity index 96% rename from src/f3/display.cpp rename to src/F3/Display/Display.cpp index 0f6939d..b802d42 100755 --- a/src/f3/display.cpp +++ b/src/F3/Display/Display.cpp @@ -1,12 +1,9 @@ // Copyright 2024 OpenJE -#include "stdafx.h" - -#include "f3.hpp" -#include "f3/display.hpp" +#include "f3/Display/Display.hpp" namespace F3 { - namespace display { + namespace Display { // 0x56b470 bool CreateGameWindow( uint nCmdShow ) { char* some_directory_path_2; // eax @@ -188,4 +185,4 @@ namespace F3 { void DestroyGameWindow (void) { } } -} \ No newline at end of file +} diff --git a/src/f3/display.hpp b/src/F3/Display/Display.hpp similarity index 53% rename from src/f3/display.hpp rename to src/F3/Display/Display.hpp index 60bf01b..391d5cf 100755 --- a/src/f3/display.hpp +++ b/src/F3/Display/Display.hpp @@ -3,14 +3,12 @@ #ifndef F3_DISPLAY_H #define F3_DISPLAY_H -#include "f3/global.hpp" - namespace F3 { - namespace display { + namespace Display { static LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); - bool CreateGameWindow( uint nCmdShow ); - void DestroyGameWindow (void); + bool CreateGameWindow( UINT nCmdShow ); + void DestroyGameWindow(void); } } -#endif // F3_DISPLAY_H \ No newline at end of file +#endif // F3_DISPLAY_H diff --git a/src/f3/GameActionAttack.hpp b/src/F3/GameActionAttack/GameActionAttack.hpp similarity index 100% rename from src/f3/GameActionAttack.hpp rename to src/F3/GameActionAttack/GameActionAttack.hpp diff --git a/src/f3/GameActionDie.hpp b/src/F3/GameActionDie/GameActionDie.hpp similarity index 100% rename from src/f3/GameActionDie.hpp rename to src/F3/GameActionDie/GameActionDie.hpp diff --git a/src/f3/GameActionEquip.hpp b/src/F3/GameActionEquip/GameActionEquip.hpp similarity index 100% rename from src/f3/GameActionEquip.hpp rename to src/F3/GameActionEquip/GameActionEquip.hpp diff --git a/src/f3/GameActionFloatingSpeechText.hpp b/src/F3/GameActionFloatingSpeechText/GameActionFloatingSpeechText.hpp similarity index 100% rename from src/f3/GameActionFloatingSpeechText.hpp rename to src/F3/GameActionFloatingSpeechText/GameActionFloatingSpeechText.hpp diff --git a/src/f3/GameActionGive.hpp b/src/F3/GameActionGive/GameActionGive.hpp similarity index 100% rename from src/f3/GameActionGive.hpp rename to src/F3/GameActionGive/GameActionGive.hpp diff --git a/src/f3/GameActionIdle.hpp b/src/F3/GameActionIdle/GameActionIdle.hpp similarity index 100% rename from src/f3/GameActionIdle.hpp rename to src/F3/GameActionIdle/GameActionIdle.hpp diff --git a/src/f3/GameActionInitiateDialogue.hpp b/src/F3/GameActionInitiateDialogue/GameActionInitiateDialogue.hpp similarity index 100% rename from src/f3/GameActionInitiateDialogue.hpp rename to src/F3/GameActionInitiateDialogue/GameActionInitiateDialogue.hpp diff --git a/src/f3/GameActionMoveTo.hpp b/src/F3/GameActionMoveTo/GameActionMoveTo.hpp similarity index 100% rename from src/f3/GameActionMoveTo.hpp rename to src/F3/GameActionMoveTo/GameActionMoveTo.hpp diff --git a/src/f3/GameActionOperateContainer.hpp b/src/F3/GameActionOperateContainer/GameActionOperateContainer.hpp similarity index 100% rename from src/f3/GameActionOperateContainer.hpp rename to src/F3/GameActionOperateContainer/GameActionOperateContainer.hpp diff --git a/src/f3/GameActionOperateDoor.hpp b/src/F3/GameActionOperateDoor/GameActionOperateDoor.hpp similarity index 100% rename from src/f3/GameActionOperateDoor.hpp rename to src/F3/GameActionOperateDoor/GameActionOperateDoor.hpp diff --git a/src/f3/GameActionPickUp.hpp b/src/F3/GameActionPickUp/GameActionPickUp.hpp similarity index 100% rename from src/f3/GameActionPickUp.hpp rename to src/F3/GameActionPickUp/GameActionPickUp.hpp diff --git a/src/f3/GameActionReload.hpp b/src/F3/GameActionReload/GameActionReload.hpp similarity index 100% rename from src/f3/GameActionReload.hpp rename to src/F3/GameActionReload/GameActionReload.hpp diff --git a/src/f3/GameActionSetActiveWeapon.hpp b/src/F3/GameActionSetActiveWeapon/GameActionSetActiveWeapon.hpp similarity index 100% rename from src/f3/GameActionSetActiveWeapon.hpp rename to src/F3/GameActionSetActiveWeapon/GameActionSetActiveWeapon.hpp diff --git a/src/f3/GameActionUnequip.hpp b/src/F3/GameActionUnequip/GameActionUnequip.hpp similarity index 100% rename from src/f3/GameActionUnequip.hpp rename to src/F3/GameActionUnequip/GameActionUnequip.hpp diff --git a/src/f3/GameActionUseSkill.hpp b/src/F3/GameActionUseSkill/GameActionUseSkill.hpp similarity index 100% rename from src/f3/GameActionUseSkill.hpp rename to src/F3/GameActionUseSkill/GameActionUseSkill.hpp diff --git a/src/f3/GameActionWait.hpp b/src/F3/GameActionWait/GameActionWait.hpp similarity index 100% rename from src/f3/GameActionWait.hpp rename to src/F3/GameActionWait/GameActionWait.hpp diff --git a/src/f3/GameActionWander.hpp b/src/F3/GameActionWander/GameActionWander.hpp similarity index 100% rename from src/f3/GameActionWander.hpp rename to src/F3/GameActionWander/GameActionWander.hpp diff --git a/src/f3/GameAmmo.hpp b/src/F3/GameAmmo/GameAmmo.hpp similarity index 100% rename from src/f3/GameAmmo.hpp rename to src/F3/GameAmmo/GameAmmo.hpp diff --git a/src/f3/GameAnimationCache.hpp b/src/F3/GameAnimationCache/GameAnimationCache.hpp similarity index 100% rename from src/f3/GameAnimationCache.hpp rename to src/F3/GameAnimationCache/GameAnimationCache.hpp diff --git a/src/f3/GameArmor.hpp b/src/F3/GameArmor/GameArmor.hpp similarity index 100% rename from src/f3/GameArmor.hpp rename to src/F3/GameArmor/GameArmor.hpp diff --git a/src/f3/GameAudio.hpp b/src/F3/GameAudio/GameAudio.hpp similarity index 100% rename from src/f3/GameAudio.hpp rename to src/F3/GameAudio/GameAudio.hpp diff --git a/src/f3/GameCSMenuInterface.hpp b/src/F3/GameCSMenuInterface/GameCSMenuInterface.hpp similarity index 100% rename from src/f3/GameCSMenuInterface.hpp rename to src/F3/GameCSMenuInterface/GameCSMenuInterface.hpp diff --git a/src/f3/GameCSSkillMenuInterface.hpp b/src/F3/GameCSSkillMenuInterface/GameCSSkillMenuInterface.hpp similarity index 100% rename from src/f3/GameCSSkillMenuInterface.hpp rename to src/F3/GameCSSkillMenuInterface/GameCSSkillMenuInterface.hpp diff --git a/src/f3/GameClient.hpp b/src/F3/GameClient/GameClient.hpp similarity index 100% rename from src/f3/GameClient.hpp rename to src/F3/GameClient/GameClient.hpp diff --git a/src/f3/GameContainer.hpp b/src/F3/GameContainer/GameContainer.hpp similarity index 100% rename from src/f3/GameContainer.hpp rename to src/F3/GameContainer/GameContainer.hpp diff --git a/src/f3/GameCreature.hpp b/src/F3/GameCreature/GameCreature.hpp similarity index 100% rename from src/f3/GameCreature.hpp rename to src/F3/GameCreature/GameCreature.hpp diff --git a/src/f3/GameCursorManager.hpp b/src/F3/GameCursorManager/GameCursorManager.hpp similarity index 100% rename from src/f3/GameCursorManager.hpp rename to src/F3/GameCursorManager/GameCursorManager.hpp diff --git a/src/f3/GameDialogueInterface.hpp b/src/F3/GameDialogueInterface/GameDialogueInterface.hpp similarity index 100% rename from src/f3/GameDialogueInterface.hpp rename to src/F3/GameDialogueInterface/GameDialogueInterface.hpp diff --git a/src/f3/GameDialogueWindow.hpp b/src/F3/GameDialogueWindow/GameDialogueWindow.hpp similarity index 100% rename from src/f3/GameDialogueWindow.hpp rename to src/F3/GameDialogueWindow/GameDialogueWindow.hpp diff --git a/src/f3/GameDoor.hpp b/src/F3/GameDoor/GameDoor.hpp similarity index 100% rename from src/f3/GameDoor.hpp rename to src/F3/GameDoor/GameDoor.hpp diff --git a/src/f3/GameEffect.hpp b/src/F3/GameEffect/GameEffect.hpp similarity index 100% rename from src/f3/GameEffect.hpp rename to src/F3/GameEffect/GameEffect.hpp diff --git a/src/f3/GameEffectDamage.hpp b/src/F3/GameEffectDamage/GameEffectDamage.hpp similarity index 100% rename from src/f3/GameEffectDamage.hpp rename to src/F3/GameEffectDamage/GameEffectDamage.hpp diff --git a/src/f3/GameEncyclopedia.hpp b/src/F3/GameEncyclopedia/GameEncyclopedia.hpp similarity index 100% rename from src/f3/GameEncyclopedia.hpp rename to src/F3/GameEncyclopedia/GameEncyclopedia.hpp diff --git a/src/f3/GameEntity.hpp b/src/F3/GameEntity/GameEntity.hpp similarity index 100% rename from src/f3/GameEntity.hpp rename to src/F3/GameEntity/GameEntity.hpp diff --git a/src/f3/GameHotKeys.hpp b/src/F3/GameHotKeys/GameHotKeys.hpp similarity index 100% rename from src/f3/GameHotKeys.hpp rename to src/F3/GameHotKeys/GameHotKeys.hpp diff --git a/src/f3/GameInterfaces.hpp b/src/F3/GameInterfaces/GameInterfaces.hpp similarity index 100% rename from src/f3/GameInterfaces.hpp rename to src/F3/GameInterfaces/GameInterfaces.hpp diff --git a/src/f3/GameInventory.hpp b/src/F3/GameInventory/GameInventory.hpp similarity index 100% rename from src/f3/GameInventory.hpp rename to src/F3/GameInventory/GameInventory.hpp diff --git a/src/f3/GameItem.hpp b/src/F3/GameItem/GameItem.hpp similarity index 100% rename from src/f3/GameItem.hpp rename to src/F3/GameItem/GameItem.hpp diff --git a/src/f3/GameJournal.hpp b/src/F3/GameJournal/GameJournal.hpp similarity index 100% rename from src/f3/GameJournal.hpp rename to src/F3/GameJournal/GameJournal.hpp diff --git a/src/f3/GameMap.hpp b/src/F3/GameMap/GameMap.hpp similarity index 100% rename from src/f3/GameMap.hpp rename to src/F3/GameMap/GameMap.hpp diff --git a/src/f3/GameNetwork.hpp b/src/F3/GameNetwork/GameNetwork.hpp similarity index 100% rename from src/f3/GameNetwork.hpp rename to src/F3/GameNetwork/GameNetwork.hpp diff --git a/src/f3/GameParty.hpp b/src/F3/GameParty/GameParty.hpp similarity index 100% rename from src/f3/GameParty.hpp rename to src/F3/GameParty/GameParty.hpp diff --git a/src/f3/GamePathManager.hpp b/src/F3/GamePathManager/GamePathManager.hpp similarity index 100% rename from src/f3/GamePathManager.hpp rename to src/F3/GamePathManager/GamePathManager.hpp diff --git a/src/f3/GamePlayer.hpp b/src/F3/GamePlayer/GamePlayer.hpp similarity index 100% rename from src/f3/GamePlayer.hpp rename to src/F3/GamePlayer/GamePlayer.hpp diff --git a/src/f3/GameProjectile.hpp b/src/F3/GameProjectile/GameProjectile.hpp similarity index 100% rename from src/f3/GameProjectile.hpp rename to src/F3/GameProjectile/GameProjectile.hpp diff --git a/src/f3/GameScripting.hpp b/src/F3/GameScripting/GameScripting.hpp similarity index 100% rename from src/f3/GameScripting.hpp rename to src/F3/GameScripting/GameScripting.hpp diff --git a/src/f3/GameServer.hpp b/src/F3/GameServer/GameServer.hpp similarity index 100% rename from src/f3/GameServer.hpp rename to src/F3/GameServer/GameServer.hpp diff --git a/src/f3/GameStoreManager.hpp b/src/F3/GameStoreManager/GameStoreManager.hpp similarity index 100% rename from src/f3/GameStoreManager.hpp rename to src/F3/GameStoreManager/GameStoreManager.hpp diff --git a/src/f3/GameUsableObject.hpp b/src/F3/GameUsableObject/GameUsableObject.hpp similarity index 100% rename from src/f3/GameUsableObject.hpp rename to src/F3/GameUsableObject/GameUsableObject.hpp diff --git a/src/f3/GameWeapon.hpp b/src/F3/GameWeapon/GameWeapon.hpp similarity index 100% rename from src/f3/GameWeapon.hpp rename to src/F3/GameWeapon/GameWeapon.hpp diff --git a/src/f3/GameWorld.hpp b/src/F3/GameWorld/GameWorld.hpp similarity index 100% rename from src/f3/GameWorld.hpp rename to src/F3/GameWorld/GameWorld.hpp diff --git a/src/f3/GameWorldMap.hpp b/src/F3/GameWorldMap/GameWorldMap.hpp similarity index 100% rename from src/f3/GameWorldMap.hpp rename to src/F3/GameWorldMap/GameWorldMap.hpp diff --git a/src/f3.cpp b/src/f3.cpp deleted file mode 100755 index c04b25f..0000000 --- a/src/f3.cpp +++ /dev/null @@ -1,536 +0,0 @@ -// Copyright 2024 OpenJE - -#include "stdafx.h" - -//#include "std/std.hpp" -#include "f3.hpp" - -void __fastcall _write_char( FILE *param_1 ); - -namespace F3 { - // 0x5ACE00 - int Main() { - bool continue_running; - undefined4 unaff_retaddr = 0; - - Startup(); - RegisterCommand( "quit", &Quit ); - continue_running = ProcessMessagesAndUpdateTime(); - while ( continue_running ) { - GameStateLoop(); - continue_running = ProcessMessagesAndUpdateTime(); - } - Shutdown(); - return 1; - } // Main - - void Quit() { - PostQuitMessage( 1 ); - return; - } // Quit - - // 0x5ACD60 - void Startup() { - - } // Startup - - // 0x59F5D0 - void RegisterCommand( const char * command, void (*func)() ) { - } // RegisterCommand - - // 0x5ACDE0 - void GameStateLoop() { - } // GameStateLoop - - // 0x56AF60 - bool ProcessMessagesAndUpdateTime() { - static DWORD program_time_ms = 0; - BOOL msg_available; - tagMSG lp_msg; - - msg_available = PeekMessageA( &lp_msg, (HWND)0x0, 0, 0, 1 ); - while( true ) { - if ( msg_available == false ) { - DWORD curr_system_time_ms = timeGetTime(); - DWORD delta_system_time_ms = curr_system_time_ms - global_system_time_ms; - global_system_time_ms = curr_system_time_ms; - program_time_ms = program_time_ms + delta_system_time_ms; - return true; - } - if ( lp_msg.message == WM_QUIT ) break; - TranslateMessage( &lp_msg ); - DispatchMessageA( &lp_msg ); - msg_available = PeekMessageA( &lp_msg, (HWND)0x0, 0, 0, 1 ); - } - return false; - } // ProcessMessagesAndUpdateTime - - // 0x5ACDA0 - void Shutdown() { - } // Shutdown - - // 0x48CC40 - void FailWithError( char * format, ... ) { - char buffer [ 1024 ]; - va_list arg_list; - - va_start( arg_list, format ); - vsprintf( buffer, format, arg_list ); - sub_497120( buffer ); - MessageBoxA( (HWND)0x0, buffer, "Fatal Error", MB_ICONERROR | MB_DEFBUTTON2 ); - exit( 1 ); - } // FailWithError - - // 0x56B000 - void SetupSaveDirectory() { - HRESULT result; - int path_index; - char *possible_file_path; - char personal_folder_path[ 64 ]; - char current_path_char; - - if ( !sub_61B067( CHAR_0070bfa8, 260 ) ) { - FailWithError( "Unable to retrieve current working directory." ); - } - result = SHGetFolderPathA( (HWND)0x0, CSIDL_PERSONAL_FOLDER, (HANDLE)0x0, 0, personal_folder_path ); - if ( result != 0 ) { - FailWithError( "Unable to retrieve personal folder." ); - } - - path_index = 0; - do { - current_path_char = personal_folder_path[ path_index ]; - some_directory_path[ path_index ] = current_path_char; - path_index = path_index + 1; - } while ( current_path_char != '\0' ); - - sub_61ADFA( possible_file_path,(char *)0x0, (char *)0x0, personal_folder_path, (char *)0x0 ); - - path_index = 0; - do { - current_path_char = personal_folder_path[ path_index ]; - some_directory_path_2[ path_index ] = current_path_char; - path_index = path_index + 1; - } while ( current_path_char != '\0' ); - - //some_directory_path_2 = (undefined *)get_some_directory_path_2(); - //sub_4c58a0( some_directory_path, some_directory_path_2 ); - current_path_char = sub_4C56B0( some_directory_path ); - if ( current_path_char == '\0' ) { - current_path_char = sub_4C5750( some_directory_path ); - if ( current_path_char == '\0' ) { - FailWithError( "Unable to create save folder." ); - } - } - return; - } // SetupSaveDirectory - - // 0x56B220 - void SetupConfigFile( uint nCmdShow ) { - } // SetupConfigFile - - // 0x56B100 - void SetupLogFile() { - } // SetupLogFile - - // 0x48CCA0 - void SetStartupTime( time_t time32 ) { - } // SetStartupTime - - // 0x61B067 - char* sub_61B067( char * param_1, size_t param_2 ) { - char* local_20; - local_20 = sub_61AF79( (LPSTR)0x0, param_1, param_2 ); - return local_20; - } // sub_61B067 - - // 0x61ADFA - unsigned __int8 *__cdecl sub_61ADFA( - unsigned __int8 *Source, - unsigned __int8 *Dest, - unsigned __int8 *directory_path, - unsigned __int8 *folder_path, - unsigned __int8 *file_extension) - { - unsigned __int8 *v5; // ebx - unsigned __int8 *result; // eax - size_t v7; // esi - unsigned __int8 v8; // cl - size_t v9; // edi - size_t v10; // edi - unsigned int v11; // eax - unsigned int v12; // eax - unsigned __int8 *input_string_local_2; // [esp+Ch] [ebp-8h] - unsigned __int8 *input_string_local_3; // [esp+10h] [ebp-4h] - unsigned __int8 *some_string; // [esp+1Ch] [ebp+8h] - - input_string_local_3 = 0; - v5 = Source; - if ( strlen((const char *)Source) && Source[1] == 58 ) - { - if ( Dest ) - { - sub_61A6AA(Dest, Source, 2u); - Dest[2] = 0; - } - v5 = Source + 2; - } - else if ( Dest ) - { - *Dest = 0; - } - some_string = 0; - result = v5; - input_string_local_2 = v5; - v7 = 255; - if ( !*v5 ) - goto LABEL_23; - do - { - v8 = *result; - if ( ( CHAR_0070fd41[*result] & 4 ) != 0 ) - { - ++result; - } - else if ( v8 == 47 || v8 == 92 ) - { - some_string = result + 1; - } - else if ( v8 == 46 ) - { - input_string_local_3 = result; - } - ++result; - } - while ( *result ); - input_string_local_2 = result; - if ( some_string ) - { - if ( directory_path ) - { - v9 = some_string - v5; - if ( (unsigned int)(some_string - v5) >= 0xFF ) - v9 = 255; - sub_61A6AA(directory_path, v5, v9); - directory_path[v9] = 0; - result = input_string_local_2; - } - v5 = some_string; - } - else - { - LABEL_23: - if ( directory_path ) - *directory_path = 0; - } - if ( input_string_local_3 && input_string_local_3 >= v5 ) - { - if ( folder_path ) - { - v10 = input_string_local_3 - v5; - if ( (unsigned int)(input_string_local_3 - v5) >= 0xFF ) - v10 = 255; - sub_61A6AA(folder_path, v5, v10); - folder_path[v10] = 0; - result = input_string_local_2; - } - if ( file_extension ) - { - v11 = result - input_string_local_3; - if ( v11 < 0xFF ) - v7 = v11; - result = sub_61A6AA(file_extension, input_string_local_3, v7); - file_extension[v7] = 0; - } - } - else - { - if ( folder_path ) - { - v12 = result - v5; - if ( v12 < 0xFF ) - v7 = v12; - sub_61A6AA(folder_path, v5, v7); - folder_path[v7] = 0; - } - result = file_extension; - if ( file_extension ) - *file_extension = 0; - } - return result; - } // sub_61ADFA - - // 0x4C58A0 - void sub_4C58A0( char * param_1, undefined4 * param_2 ) { - } // sub_4C58A0 - - // 0x4C56B0 - char sub_4C56B0( LPCSTR param_1 ) { - return '\0'; // temporary - } // sub_4C56B0 - - // 0x4C5750 - char sub_4C5750( char * param_1 ) { - return '\0'; // temporary - } // sub_4C5750 - - // 0x497120 - void sub_497120( char * format, ... ) { - CHAR buffer[1024]; - uint v3; - uint retaddr; - va_list arg_list; - - va_start( arg_list, format ); - if ( !DAT_00707cf0 ) - { - DAT_00707cf0 = true; - vsprintf( buffer, format, arg_list ); - if ( INT_00707d60 ) - { - //sub_496E00(&unk_707D00, buffer); - //sub_496990(&unk_707D00); - } - OutputDebugStringA( buffer ); - DAT_00707cf0 = 0; - } - } // sub_497120 - - // 0x56AF10 - char* get_some_directory_path_2() { - return some_directory_path_2; - } // get_some_directory_path_2 - - // 0x6174DA - undefined4 sub_6174DA( char * param_1, char * param_2 /*int ** param_3*/ ) - { - undefined4 uVar1; - FILE file; - - file._cnt = 0x7fffffff; - file._flag = 0x42; - file._base = param_1; - file._ptr = param_1; - uVar1 = sub_61F82F( &file, param_2 /*param_3*/ ); - if ( param_1 != (char *)0x0 ) { - file._cnt = file._cnt + -1; - if ( file._cnt < 0 ) { - _flsbuf( 0, &file ); - } - else { - *file._ptr = '\0'; - } - } - return uVar1; - } // sub_6174DA - - // 0x61f82f - undefined4 sub_61F82F( FILE * param_1, char * param_2 /*int ** param_3*/ ) { - return 0; // temporary - } // sub_61F82F - - ulonglong sub_616E24() { - ulonglong uVar1; - uint uVar2; - float fVar3; - float10 in_ST0; - uint local_20; - float fStack_1c; - - uVar1 = (ulonglong)ROUND(in_ST0); - local_20 = (uint)uVar1; - fStack_1c = (float)(uVar1 >> 0x20); - fVar3 = (float)in_ST0; - if ((local_20 != 0) || (fVar3 = fStack_1c, (uVar1 & 0x7fffffff00000000) != 0)) { - if ((int)fVar3 < 0) { - uVar1 = uVar1 + (0x80000000 < ((uint)(float)(in_ST0 - (float10)uVar1) ^ 0x80000000)); - } - else { - uVar2 = (uint)(0x80000000 < (uint)(float)(in_ST0 - (float10)uVar1)); - uVar1 = CONCAT44((int)fStack_1c - (uint)(local_20 < uVar2),local_20 - uVar2); - } - } - return uVar1; - } // sub_616E24 - - void sub_56B170() { - /* - int iVar1; - int *piVar2; - uint uVar3; - - if (INT_00707d60 != 0) { - piVar2 = std::basic_filebuf::meth_0x497930((std::basic_filebuf *)&DAT_00707cfc.field_0x8); - if (piVar2 == (int *)0x0) { - iVar1 = *(int *)(DAT_00707cf8 + 4); - uVar3 = *(uint *)(&DAT_00707cfc.field_0x0 + iVar1) | 2; - if (*(int *)(&DAT_00707cfc.field_0x24 + iVar1) == 0) { - uVar3 = *(uint *)(&DAT_00707cfc.field_0x0 + iVar1) | 6; - } - std::ios_base::clear((std::ios_base *)((int)&DAT_00707cf8 + iVar1),uVar3,false); - } - } - return; - */ - } // sub_56B170 - - void sub_497B70() { - - } // sub_497B70 - - void sub_56B390() { - - } // sub_56B390 - - char* sub_61AF79( LPSTR file_name, char *a2, int a3 ) - { - char v3; // bl - DWORD path_length; // eax - int v6; // eax - char *v7; // ecx - CHAR path[260]; // [esp+4h] [ebp-10Ch] BYREF - LPSTR file_name_component[2]; // [esp+108h] [ebp-8h] BYREF - uint retaddr; // [esp+114h] [ebp+4h] - - if ( file_name ) { - if ( !sub_61AF42( file_name ) ) { - //*sub_61B79D() = 15; - //*sub_61B794() = 13; - return 0; - } - file_name = (LPSTR)CONCAT12( '.', CONCAT11( ':', file_name + '@' ) ); - path_length = GetFullPathNameA( file_name, 260, path, file_name_component ); - } else { - path_length = GetCurrentDirectoryA( 260, path ); - } - if ( !path_length ) { - return 0; - } - v6 = path_length + 1; - if ( (unsigned int)v6 > 260 ) { - return 0; - } - v7 = a2; - if ( a2 ) { - if ( v6 > a3 ) { - //*sub_61B794() = 34; - return 0; - } - } - else { - if ( v6 <= a3 ) - v6 = a3; - v7 = (char *)malloc( v6 ); - if ( !v7 ) { - //*sub_61B794() = 12; - return 0; - } - } - return strcpy(v7, path); - } // sub_61AF79 - - BOOL sub_61AF42( LPCSTR root_path_name ) { - BOOL result = 1; // eax - if ( root_path_name ) { - root_path_name = (LPCSTR)CONCAT12( '\\', CONCAT11( ':', root_path_name + '@' ) ); - if ( GetDriveTypeA( (LPCSTR)&root_path_name ) < 2 ) { - return 0; - } - } - return result; - } // sub_61AF42 - - char* sub_61A6AA( char* dest, const char* source, size_t count ) { - byte bVar1; - byte bVar2; - _ptiddata p_Var3; - int *piVar4; - uint uVar5; - uint uVar6; - char *puVar7; - char *puVar8; - - p_Var3 = __getptd(); - piVar4 = (int *)p_Var3->_tpxcptinfoptrs; - if (piVar4 != DAT_0070fd28) { - piVar4 = sub_625E2A(); - } - if (piVar4[2] == 0) { - dest = strncpy( dest, source, count ); - } - else { - puVar7 = dest; - if (count != 0) { - do { - bVar1 = *source; - uVar5 = count - 1; - bVar2 = *(byte *)(bVar1 + 0x1d + (int)piVar4); - *(byte *)puVar7 = bVar1; - if ((bVar2 & 4) == 0) { - puVar8 = (puVar7 + 1); - source = source + 1; - if (bVar1 == 0) { - LAB_0061a70f: - if (uVar5 == 0) { - return dest; - } - for (uVar6 = uVar5 >> 2; uVar6 != 0; uVar6 = uVar6 - 1) { - *puVar8 = 0; - puVar8 = puVar8 + 1; - } - for (uVar5 = uVar5 & 3; uVar5 != 0; uVar5 = uVar5 - 1) { - *(undefined *)puVar8 = 0; - puVar8 = (puVar8 + 1); - } - return dest; - } - } - else { - if (uVar5 == 0) { - *(undefined *)puVar7 = 0; - return dest; - } - bVar1 = source[1]; - uVar5 = count - 2; - *(byte *)((int)puVar7 + 1) = bVar1; - puVar8 = ((int)puVar7 + 2); - source = source + 2; - if (bVar1 == 0) { - *puVar7 = 0; - goto LAB_0061a70f; - } - } - count = uVar5; - puVar7 = puVar8; - } while (uVar5 != 0); - } - } - return dest; - } // sub_61A6AA -} // namespace F3 - -void __fastcall _write_char( FILE *param_1 ) { - int *piVar1; - byte in_AL; - uint uVar2; - int *unaff_ESI; - - if (((*(byte *)¶m_1->_flag & 0x40) == 0) || (param_1->_base != (char *)0x0)) { - piVar1 = ¶m_1->_cnt; - *piVar1 = *piVar1 + -1; - if (*piVar1 < 0) { - uVar2 = _flsbuf((int)(char)in_AL,param_1); - } - else { - *param_1->_ptr = in_AL; - param_1->_ptr = param_1->_ptr + 1; - uVar2 = (uint)in_AL; - } - if (uVar2 == 0xffffffff) { - *unaff_ESI = -1; - return; - } - } - *unaff_ESI = *unaff_ESI + 1; - return; -} \ No newline at end of file diff --git a/src/f3.hpp b/src/f3.hpp deleted file mode 100755 index 5751098..0000000 --- a/src/f3.hpp +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2024 OpenJE - -#ifndef F3_H -#define F3_H - -#include "stdafx.h" - -#include "f3/global.hpp" -#include "f3/display.hpp" - -namespace F3 { - int Main(); - void Quit(); - void Startup(); - void RegisterCommand ( const char* command, void (*func)() ); - void GameStateLoop(); - bool ProcessMessagesAndUpdateTime(); - void Shutdown(); - char* FindSubstringInString ( char * string, char * sub_string ); - void FailWithError( char * format, ... ); - void SetupSaveDirectory(); - void SetupConfigFile( uint nCmdShow ); - void SetupLogFile(); - void SetStartupTime( time_t time ); - char* sub_61B067( char * param_1, size_t param_2 ); - void sub_61ADFA( char * some_string, char * drive_letter, char * directory_path, char * folder_path, char * file_extension ); - void sub_4C58A0( char * param_1, undefined4 * param_2 ); - char sub_4C56B0( LPCSTR param_1 ); - char sub_4C5750( char * param_1 ); - void sub_497120( char * format, ... ); - char* get_some_directory_path_2(); - undefined4 sub_6174DA( char * param_1, char * param_2 /*int ** param_3*/ ); - undefined4 sub_61F82F( FILE * param_1, char * param_2 /*int ** param_3*/ ); - ulonglong sub_616E24(); - void sub_56B170(); - void sub_497B70(); - void sub_56B390(); - char* sub_61AF79( LPSTR file_name, char *a2, int a3 ); - BOOL sub_61AF42( LPCSTR root_path_name ); - char* sub_61A6AA( char* dest, const char* source, size_t count ); -} - -#endif // F3_H \ No newline at end of file diff --git a/src/f3/global.hpp b/src/f3/global.hpp deleted file mode 100755 index c92c1a1..0000000 --- a/src/f3/global.hpp +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2024 OpenJE - -#ifndef F3_GLOBAL_H -#define F3_GLOBAL_H - -#include "stdafx.h" -#include "types.hpp" -//#include "std/std.hpp" - -// F3 Defines -#define CSIDL_PERSONAL_FOLDER 0x8005 - -// F3 Globals -namespace F3 { - static HINSTANCE global_hinstance; - static HWND global_window; - static DWORD global_system_time_ms; - static char some_directory_path[268]; - static char some_directory_path_2[256]; - static char CHAR_0070bfa8[260]; - static int INT_00707d60; - static bool DAT_00707cf0; - static char CHAR_0070fd41[2]; -} - -#endif // F3_GLOBAL_H \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 4a5affa..6ddeb8d 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,29 +1,48 @@ -// Copyright 2024 OpenJE +// OpenJE -#include "stdafx.h" +#include -#include "f3.hpp" +#include +#include "JE.hpp" +#include "F3.hpp" +#include "tracing.hpp" // 0x56b810 -int APIENTRY _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow ) { - CHAR f3_exe_path [268]; - _mbsstr( reinterpret_cast( lpCmdLine ), reinterpret_cast( "-leakcheck" ) ); - F3::global_hinstance = hInstance; - if( GetModuleFileNameA( (HMODULE)0x0, f3_exe_path, 260 ) == 0 ) { - F3::FailWithError( "Unable to get module file name." ); +int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow ) { + tracing::instrument( tracing::LOCATION, + "hInstance=0x%p, hPrevInstance=0x%p, lpCmdLine=\"%s\", nCmdShow=%d", + hInstance, hPrevInstance, lpCmdLine, nCmdShow + ); + + std::time_t timeStartupTime; + int nMainResult; + char szModulePath[ MAX_PATH ] = { 0 }; + int nExitStatus; + int nSavedRegs; + + F3::g_hinstance = hInstance; + if( !GetModuleFileName( (HMODULE)0x0, szModulePath, MAX_PATH ) ) { + tracing::error( tracing::LOCATION, "Unable to get module file name." ); + JE::FatalError( "Unable to get module file name." ); } - F3::SetupSaveDirectory(); - F3::SetupConfigFile( nCmdShow ); - F3::SetupLogFile(); + tracing::info( tracing::LOCATION, "szModulePath=%s", szModulePath ); + + F3::SetupSaveDirectory( szModulePath ); + //F3::SetupConfigFile( nCmdShow ); + //F3::SetupLogFile(); + timeBeginPeriod( 1 ); - F3::global_system_time_ms = timeGetTime(); - F3::display::CreateGameWindow( nCmdShow ); - F3::SetStartupTime( (time_t)0 ); - GetCommandLineA(); - int main_return = F3::Main(); - F3::display::DestroyGameWindow(); - timeEndPeriod( 1 ); - F3::sub_497B70(); - F3::sub_56B390(); - return main_return; -} // _tWinMain + F3::g_nSystemTimeMS = timeGetTime(); + tracing::info( tracing::LOCATION, "F3::g_nSystemTimeMS=%d", F3::g_nSystemTimeMS ); + + //F3::Display::CreateGameWindow( nCmdShow ); + timeStartupTime = std::time( 0 ); + F3::SetStartupTime( timeStartupTime ); + GetCommandLine(); + //int main_result = F3::Main(); + F3::Display::DestroyGameWindow(); + timeEndPeriod( 1 ); + //F3::ShutdownGlobalLogStream( &nSavedRegs ); + //F3::sub_56B390(); + //return main_result; +} // WinMain diff --git a/src/main.hpp b/src/main.hpp deleted file mode 100755 index 3f79b29..0000000 --- a/src/main.hpp +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright 2024 OpenJE - -#ifndef OPENJE_H -#define OPENJE_H - -#include "resource.h" - -#endif // OPENJE_H \ No newline at end of file diff --git a/src/stdafx.cpp b/src/stdafx.cpp deleted file mode 100755 index ff09303..0000000 --- a/src/stdafx.cpp +++ /dev/null @@ -1,8 +0,0 @@ -// stdafx.cpp : source file that includes just the standard includes -// OpenJE.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - -// TODO: reference any additional headers you need in STDAFX.H -// and not in this file diff --git a/src/stdafx.h b/src/stdafx.h deleted file mode 100755 index 3bb6556..0000000 --- a/src/stdafx.h +++ /dev/null @@ -1,24 +0,0 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#pragma once - -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers -// Windows Header Files: -#include -// C RunTime Header Files -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// TODO: reference additional headers your program requires here diff --git a/tracing b/tracing new file mode 160000 index 0000000..053dd46 --- /dev/null +++ b/tracing @@ -0,0 +1 @@ +Subproject commit 053dd46af4774fdd92e15f8827f6bf9734e75c9b