diff --git a/.gitignore b/.gitignore index 9a19959..c98a93d 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,8 @@ __pycache__/ debug_render.png render_view.png *.log + +# Tool and runtime generated outputs +graphify-out/ +runtime/*.dat +runtime/*.stop diff --git a/AGENTS.md b/AGENTS.md index e4effcb..98838cb 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,7 +2,21 @@ ## Project identity -Single-file x86 assembly (MASM32) Windows console casino game. Source: `poker.asm` (~8500 lines). Python scripts are only for previewing animations — not part of the game itself. +Single-file x86 assembly (MASM32) Windows console casino game with retro 2.5D raycaster engine. Source: `poker.asm` (~8500 lines). Python scripts are offline tools for asset generation and previewing animations — not part of the game runtime itself. + +## Directory Structure + +- **Root**: Core MASM32 game (`poker.asm`, `casino3d.inc`, `casino3d_data.inc`, `font8x8.inc`, `build.bat`, `poker.exe`). +- **`dist/`**: Compiled desktop distribution launchers (`Assembler Casino.exe`, `Uninstall Assembler Casino.exe`). +- **`src_portable/`**: Portable C99 implementation of the casino core (`casino_portable.c`, `Makefile`, `CMakeLists.txt`). +- **`build/`**: C# source code for launchers and installers. +- **`tools/`**: Internal developer tooling and pipelines: + - `tools/previews/`: Terminal ANSI animation and 3D engine previews (`preview_intro.bat`, `preview_hakari.bat`, `preview_dbd_hook.bat`, `preview_casino3d.bat`). + - `tools/generators/`: Offline asset compilers, math lookup tables, and assembly generators. + - `tools/tests/`: Render simulation (`simulate_render.py`), release smoke checks, and achievement popup helpers. +- **`assets/`**: Media files (audio `.wav`, ANSI `.ans`, textures `.bin`, icons). +- **`docs/`**: Documentation, cheat codes, ideas backlog, and technical guides. +- **`backups/`**: Historical archives and pre-feature checkpoints. ## Build @@ -10,9 +24,9 @@ Single-file x86 assembly (MASM32) Windows console casino game. Source: `poker.as - **Link**: `link /SUBSYSTEM:CONSOLE /RELEASE /VERSION:4.0 /LIBPATH:"\lib" poker.obj kernel32.lib winmm.lib user32.lib ws2_32.lib gdi32.lib` - **IDE project**: `poker.wap` (Pelles C/Windows) - **Libraries**: `kernel32.lib`, `winmm.lib`, `user32.lib`, `ws2_32.lib`, `gdi32.lib` -- **Build script**: `build.bat` (uses MASM32 from `D:\MASM32\masm32`) +- **Build script**: `build.bat` (uses MASM32 from `D:\MASM32\masm32` or MSVC BuildTools) -Requires MASM32 toolchain (`ml.exe`, `link.exe` from e.g. `F:\MASM32\masm32\bin`). +Requires MASM32 toolchain or MSVC BuildTools (`ml.exe`, `link.exe`). ## Encoding @@ -24,16 +38,18 @@ Requires MASM32 toolchain (`ml.exe`, `link.exe` from e.g. `F:\MASM32\masm32\bin` | File | Purpose | |------|---------| -| `casino_intro.ans` | Animated intro (skippable with Enter, loops at `@@LOOP@@` marker) | -| `hakari_dance.ans` | Animated dance on jackpot win | -| `dealer_phrases.txt` | CP1251, each line prefixed `W|` (win), `L|` (loss), `D|` (draw) | +| `assets/animations/casino_intro.ans` | Animated intro (skippable with Enter, loops at `@@LOOP@@` marker) | +| `assets/animations/hakari_dance.ans` | Animated dance on jackpot win | +| `assets/animations/dbd_hook.ans` | Dead by Daylight hook skill-check mini-game animation | +| `assets/data/dealer_phrases.txt` | CP1251, each line prefixed `W|` (win), `L|` (loss), `D|` (draw) | +| `assets/textures/casino3d-hd.bin` | Packed 48 slots (128×128 BGRA) 3D raycaster textures | ## Workflow - **Git remote**: `https://git.silverstone.crazedns.ru/Billi_Bob/KAZIK.git` (branch `main`). - Backups in `backups/` follow: `poker_before__.{asm,exe}` - **No tests**. Manually verify by running `poker.exe`. -- Preview animations: `preview_hakari.bat` / `preview_intro.bat` (or `python preview_hakari.py` directly). +- Preview animations: `tools/previews/preview_hakari.bat` / `tools/previews/preview_intro.bat` (or `python tools/previews/preview_hakari.py` directly). ## Games (menu) diff --git a/README.md b/README.md index acf1a15..1c9de8e 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,188 @@ -# KAZIK +# ASSEMBLER CASINO (KAZIK) 🎰 -DEPAI DEPAI DEPAI DEPAI DEPAI DEPAI DEPAI DEPAI DEPAI DEPAI \ No newline at end of file +A retro casino gaming suite powered by a high-performance **pure x86 assembly (MASM32)** engine featuring an interactive **2.5D retro Raycaster 3D Hall** (DOOM / Wolfenstein style) and a catalog of classic and underground gambling games. + +--- + +## 🏛️ Architecture Overview + +The repository is organized into distinct, modular subsystems: + +``` + ┌────────────────────────────────────────┐ + │ ASSEMBLER CASINO │ + └──────────────────┬─────────────────────┘ + │ + ┌───────────────────────────┼───────────────────────────┐ + ▼ ▼ ▼ +┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ +│ MASM32 Engine │ │ C99 Portable │ │ C# GUI Launcher │ +│ (Root Directory)│ │ (src_portable/) │ │ (build/ & dist/) │ +│ - poker.asm │ │ - casino_portable│ │ - Launcher.cs │ +│ - casino3d.inc │ │ - CMakeLists.txt │ │ - Installer GUI │ +│ - font8x8.inc │ │ - Makefile │ │ - Setup Wizards │ +└────────┬─────────┘ └──────────────────┘ └──────────────────┘ + │ + ▼ +┌──────────────────────────────────────────────┐ +│ Offline Pipeline & Tooling │ +│ (tools/) │ +│ - tools/previews/ (ANSI / 3D previews) │ +│ - tools/generators/ (Asset & table packers) │ +│ - tools/tests/ (Simulators & checks) │ +└──────────────────────────────────────────────┘ +``` + +1. **MASM32 Core Game Engine (Root)** + - **`poker.asm`**: Main game binary (~8,500+ lines of hand-crafted x86 assembly). Contains game logic, cheat engine, socket networking, profile save system, and sound triggers. + - **`casino3d.inc` / `casino3d_data.inc`**: Software 2.5D Raycaster engine rendering a 32×32 grand casino hall at 640×480 with DDA wall casting, depth-sorted sprite objects, and interactive tables. + - **`font8x8.inc`**: CP1251 1-bit monochrome 8×8 bitmap font table for high-speed HUD rendering directly to the Win32 GDI frame buffer. + +2. **Portable C99 Core (`src_portable/`)** + - Cross-platform implementation (`casino_portable.c`, `casino_portable.h`) allowing gameplay on POSIX / Linux / macOS environments. + - Fully standalone build with standard `Makefile` or `CMakeLists.txt`. + +3. **Desktop Distribution & Launcher (`build/` & `dist/`)** + - **`build/`**: C# source code for the launcher (`AssemblerCasinoLauncher.cs`), setup GUI (`PokerGameSetupGui.cs`), and uninstaller. + - **`dist/`**: Ready-to-run compiled desktop executables (`Assembler Casino.exe`, `Uninstall Assembler Casino.exe`). + +4. **Offline Development Tooling (`tools/`)** + - **`tools/previews/`**: Terminal ANSI animation players (`preview_intro.py`, `preview_hakari.py`, `preview_dbd_hook.py`) and 3D preview runner. + - **`tools/generators/`**: Texture pack scripts (`build_graphics_assets.py`), math table generators (`generate_math_and_map.py`), font rasterizer (`generate_font.py`). + - **`tools/tests/`**: Software raycaster simulator (`simulate_render.py`), release integrity checks (`release_smoke_check.ps1`), achievement popup modal (`achievement_popup.bat`). + +5. **Assets & Documentation (`assets/`, `docs/`, `backups/`)** + - **`assets/`**: High-resolution textures, sprites, audio samples (`.wav`), and ANSI cinematics (`.ans`). + - **`docs/`**: Design specifications, cheat sheet, networking guides, and engine render previews. + - **`backups/`**: Historical milestones and archived releases. + +--- + +## 📁 Repository Directory Structure + +``` +├── poker.asm # Primary MASM32 assembly source +├── casino3d.inc # 2.5D retro 3D raycaster engine implementation +├── casino3d_data.inc # 3D engine math tables (sin/cos) & casino hall grid +├── font8x8.inc # 8x8 CP1251 bitmap font data +├── poker.wap # Pelles C / Windows project definition +├── build.bat # One-click build script for MASM32 core +├── poker.exe # Compiled game binary +├── AGENTS.md # Engineering guidelines and agent instructions +├── README.md # Project documentation (this file) +├── LICENSE # Project license +├── .gitignore # Git ignore patterns +│ +├── assets/ # Game assets +│ ├── animations/ # ANSI animations (casino_intro.ans, hakari_dance.ans, dbd_hook.ans) +│ ├── audio/ # Sound effects (.wav) for cards, roulette, coins, win/loss +│ ├── data/ # Dealer dialogues and text tables (CP1251) +│ ├── icons/ # Game icon assets (.ico, .png) +│ ├── music/ # Background tracks +│ ├── sprites/ # Source sprite sheets & cabaret animations +│ └── textures/ # Packed 128x128 BGRA texture binaries (casino3d-hd.bin) +│ +├── backups/ # Preserved backups and legacy archives +│ +├── build/ # Launcher and setup source code (C# .NET) +│ ├── AssemblerCasinoLauncher.cs +│ ├── PokerGameSetupGui.cs +│ └── UninstallAssemblerCasino.cs +│ +├── dist/ # Compiled desktop distribution binaries +│ ├── Assembler Casino.exe +│ └── Uninstall Assembler Casino.exe +│ +├── docs/ # Project documentation, guides, and plans +│ ├── intro_code_draft.txt # Opening sequence drafts +│ ├── render_view.png # Simulated frame render of the 3D casino hall +│ ├── ИДЕИ.txt # Game ideas and development backlog +│ ├── ЧИТКОДЫ.txt # Complete list of cheat codes +│ └── *.txt # Release notes, security guidelines, networking +│ +├── src_portable/ # Standalone portable C99 implementation +│ ├── casino_portable.c +│ ├── casino_portable.h +│ ├── CMakeLists.txt +│ ├── Makefile +│ └── poker_portable.exe +│ +└── tools/ # Developer tooling & offline asset pipeline + ├── README.md # Documentation for tools + ├── previews/ # Animation & 3D preview scripts (.py, .bat) + ├── generators/ # Asset packers, math & font generators (.py) + └── tests/ # Software render simulator & test scripts (.py, .ps1, .bat) +``` + +--- + +## 🛠️ Build Instructions + +### 1. MASM32 Game Binary (`poker.exe`) + +Prerequisites: MASM32 SDK (`ml.exe`, `link.exe`) installed in `D:\MASM32\masm32`, `C:\masm32`, or Visual Studio MSVC BuildTools. + +Simply run: +```bat +build.bat +``` +This will assemble `poker.asm` with MASM, link against `kernel32`, `winmm`, `user32`, `ws2_32`, `gdi32`, and produce `poker.exe`. + +### 2. C99 Portable Engine (`src_portable/`) + +With GCC / MinGW: +```bash +cd src_portable +make +``` + +Or with CMake: +```bash +cd src_portable +mkdir build && cd build +cmake .. +cmake --build . +``` + +### 3. Running Previews and Simulators + +- **Hakari Jackpot Dance Preview**: + ```bat + tools\previews\preview_hakari.bat + ``` +- **Casino Intro Animation Preview**: + ```bat + tools\previews\preview_intro.bat + ``` +- **3D Engine Software Simulation**: + ```bash + python tools/tests/simulate_render.py + ``` + Generates `docs/render_view.png` showing the 3D raycaster view with sprites. + +--- + +## 🔤 Character Encoding Standard + +- **Game source & strings (`poker.asm`, `assets/data/dealer_phrases.txt`)**: **CP1251 (Windows-1251)**. Never save as UTF-8. +- **ANSI animations (`.ans`)**: CP1251 encoding with ANSI escape codes and form feed (`\f`, `0x0C`) frame delimiters. Preview runners execute `chcp 65001` before playback. + +--- + +## 🎮 Games & Features + +| # | Game | Description | +|---|------|-------------| +| 1 | **21 / Blackjack** | Classic card game against the dealer with hit/stand mechanics. | +| 2 | **Poker** | Texas Hold'em with AI opponents, betting rounds, and pot calculations. | +| 3 | **CloverPit** | 5×3 video slots with custom bonus features and payouts. | +| 4 | **Russian Roulette** | High-stakes survival with revolver chamber simulation. | +| 5 | **Skulls & Cups** | Thimblerig shell game testing perception and luck. | +| 6 | **Coin Flip** | Double or nothing coin toss. | +| 7 | **Dice / Craps** | Classic dice rolling wagering. | +| 8 | **Roulette** | European roulette wheel with single and range bets. | +| 9 | **Classic Slots** | 3-reel 777 fruit machine. | +| 10 | **Durak** | Traditional Russian card game with trump cards and defense logic. | +| 11 | **Training** | Practice arena with infinite balance. | +| 12 | **Observer (AI vs AI)** | Watch autonomous agents play against each other. | +| 3D | **Grand Casino Hall** | Real-time 2.5D raycaster environment to explore and walk up to tables. | \ No newline at end of file diff --git a/assets/textures/casino3d-hd.bin b/assets/textures/casino3d-hd.bin index b61b998..2586f56 100644 Binary files a/assets/textures/casino3d-hd.bin and b/assets/textures/casino3d-hd.bin differ diff --git a/assets/textures/casino3d.bin b/assets/textures/casino3d.bin index d4b6fd3..b921c82 100644 Binary files a/assets/textures/casino3d.bin and b/assets/textures/casino3d.bin differ diff --git a/ПРОСТО.7z b/backups/ПРОСТО.7z similarity index 100% rename from ПРОСТО.7z rename to backups/ПРОСТО.7z diff --git a/build/graphics/poker.asm b/build/graphics/poker.asm index 9592eb3..02be421 100644 --- a/build/graphics/poker.asm +++ b/build/graphics/poker.asm @@ -900,7 +900,7 @@ achCharmBuyerName db " achObserverName db "Ëîæà íàáëþäàòåëÿ",13,10,0 achSkillCheckName db "Ñ êðþêà ñîðâàëñÿ",13,10,0 achievementFileName db "runtime\achievement.txt",0 -achievementCmd db "cmd /c start ""Achievement"" tools\achievement_popup.bat",0 +achievementCmd db "cmd /c start ""Achievement"" tools\tests\achievement_popup.bat",0 skillTitle db 13,10,"--- Êðþê: Skill Check ---",13,10,0 skillIntro db "Ïîïàäàé ïî çåëåíîé çîíå. PERFECT äàåò äâîéíîé ïðîãðåññ.",13,10 db "3 ïðîìàõà - òüìà çàáèðàåò ñòàâêó. 5 ïðîãðåññà - òû ñðûâàåøüñÿ ñ êðþêà.",13,10 @@ -2608,7 +2608,7 @@ runtimeDir db "runtime",0 danceFileName db "assets\animations\hakari_dance.ans",0 casinoIntroFile db "assets\animations\casino_intro.ans",0 dbdHookFileName db "assets\animations\dbd_hook.ans",0 -dbdHookCmd db "cmd /c start ""DBD Hook"" tools\preview_dbd_hook.bat",0 +dbdHookCmd db "cmd /c start ""DBD Hook"" tools\previews\preview_dbd_hook.bat",0 dbdHookStopFile db "runtime\dbd_hook.stop",0 animProfileFile db "runtime\anim_profile.txt",0 animProfileDigits db "012",0 diff --git a/build/graphics/poker.exe b/build/graphics/poker.exe index 43286fd..b874ad9 100644 Binary files a/build/graphics/poker.exe and b/build/graphics/poker.exe differ diff --git a/build/graphics/texture-atlas-preview.png b/build/graphics/texture-atlas-preview.png index 1820f00..fde2c7c 100644 Binary files a/build/graphics/texture-atlas-preview.png and b/build/graphics/texture-atlas-preview.png differ diff --git a/Assembler Casino.exe b/dist/Assembler Casino.exe similarity index 100% rename from Assembler Casino.exe rename to dist/Assembler Casino.exe diff --git a/Uninstall Assembler Casino.exe b/dist/Uninstall Assembler Casino.exe similarity index 100% rename from Uninstall Assembler Casino.exe rename to dist/Uninstall Assembler Casino.exe diff --git a/docs/Новый текстовый документ.txt b/docs/intro_code_draft.txt similarity index 100% rename from docs/Новый текстовый документ.txt rename to docs/intro_code_draft.txt diff --git a/ИДЕИ.txt b/docs/ИДЕИ.txt similarity index 100% rename from ИДЕИ.txt rename to docs/ИДЕИ.txt diff --git a/poker.asm b/poker.asm index 9592eb3..02be421 100644 --- a/poker.asm +++ b/poker.asm @@ -900,7 +900,7 @@ achCharmBuyerName db " achObserverName db "Ëîæà íàáëþäàòåëÿ",13,10,0 achSkillCheckName db "Ñ êðþêà ñîðâàëñÿ",13,10,0 achievementFileName db "runtime\achievement.txt",0 -achievementCmd db "cmd /c start ""Achievement"" tools\achievement_popup.bat",0 +achievementCmd db "cmd /c start ""Achievement"" tools\tests\achievement_popup.bat",0 skillTitle db 13,10,"--- Êðþê: Skill Check ---",13,10,0 skillIntro db "Ïîïàäàé ïî çåëåíîé çîíå. PERFECT äàåò äâîéíîé ïðîãðåññ.",13,10 db "3 ïðîìàõà - òüìà çàáèðàåò ñòàâêó. 5 ïðîãðåññà - òû ñðûâàåøüñÿ ñ êðþêà.",13,10 @@ -2608,7 +2608,7 @@ runtimeDir db "runtime",0 danceFileName db "assets\animations\hakari_dance.ans",0 casinoIntroFile db "assets\animations\casino_intro.ans",0 dbdHookFileName db "assets\animations\dbd_hook.ans",0 -dbdHookCmd db "cmd /c start ""DBD Hook"" tools\preview_dbd_hook.bat",0 +dbdHookCmd db "cmd /c start ""DBD Hook"" tools\previews\preview_dbd_hook.bat",0 dbdHookStopFile db "runtime\dbd_hook.stop",0 animProfileFile db "runtime\anim_profile.txt",0 animProfileDigits db "012",0 diff --git a/poker.exe b/poker.exe index 43286fd..b874ad9 100644 Binary files a/poker.exe and b/poker.exe differ diff --git a/CMakeLists.txt b/src_portable/CMakeLists.txt similarity index 73% rename from CMakeLists.txt rename to src_portable/CMakeLists.txt index 0bd4ff7..9e9a6a7 100644 --- a/CMakeLists.txt +++ b/src_portable/CMakeLists.txt @@ -4,8 +4,8 @@ project(poker_portable C) set(CMAKE_C_STANDARD 99) add_executable(poker_portable - src_portable/casino_portable.c - src_portable/casino_portable.h + casino_portable.c + casino_portable.h ) if(WIN32) diff --git a/Makefile b/src_portable/Makefile similarity index 60% rename from Makefile rename to src_portable/Makefile index ab7d594..5858500 100644 --- a/Makefile +++ b/src_portable/Makefile @@ -11,8 +11,8 @@ endif all: $(TARGET) -$(TARGET): src_portable/casino_portable.c src_portable/casino_portable.h - $(CC) $(CFLAGS) src_portable/casino_portable.c -o $(TARGET) $(LIBS) +$(TARGET): casino_portable.c casino_portable.h + $(CC) $(CFLAGS) casino_portable.c -o $(TARGET) $(LIBS) clean: rm -f $(TARGET) *.o diff --git a/poker_portable.exe b/src_portable/poker_portable.exe similarity index 100% rename from poker_portable.exe rename to src_portable/poker_portable.exe diff --git a/tools/README.md b/tools/README.md new file mode 100644 index 0000000..482ffda --- /dev/null +++ b/tools/README.md @@ -0,0 +1,59 @@ +# Tools & Utilities Directory (`tools/`) + +This directory contains internal utilities, asset generators, preview helpers, and test scripts used during development. + +> **Note:** The shipped game is a standalone native x86 binary with zero Python or external runtime dependencies. All Python and PowerShell scripts here are strictly offline development tools. + +--- + +## Directory Structure + +``` +tools/ +├── previews/ # Interactive preview launchers for animations and 3D engine +├── generators/ # Offline asset generators, math tables, and code builders +└── tests/ # Test scripts, render simulators, and release checks +``` + +--- + +## 1. Previews (`tools/previews/`) + +Interactive terminal and audio previews for animations and graphical components: + +| Tool | Language | Purpose & Usage | +|------|----------|-----------------| +| `preview_hakari.py`
`preview_hakari.bat` | Python / Batch | Plays the animated ANSI jackpot dance (`assets/animations/hakari_dance.ans`) synchronized with audio (`assets/audio/hakari_dance.wav`). Run via double-clicking `preview_hakari.bat` or `python tools/previews/preview_hakari.py`. | +| `preview_intro.py`
`preview_intro.bat` | Python / Batch | Plays the casino opening ANSI animation (`assets/animations/casino_intro.ans`) with support for Enter key skipping and `@@LOOP@@` frame looping. Run via `preview_intro.bat` or `python tools/previews/preview_intro.py`. | +| `preview_dbd_hook.py`
`preview_dbd_hook.bat` | Python / Batch + PowerShell | Previews the Dead by Daylight hook skill-check mini-game animation (`assets/animations/dbd_hook.ans`). Controlled by `runtime/dbd_hook.stop` and animation profile settings. Run via `preview_dbd_hook.bat`. | +| `preview_casino3d.bat` | Batch | Convenience launcher that switches to root and starts `poker.exe` in 3D DOOM/Wolfenstein retro view mode. | + +--- + +## 2. Generators (`tools/generators/`) + +Offline build tools that process raw images, generate lookup tables, and compose assembly code: + +| Tool | Language | Purpose & Usage | +|------|----------|-----------------| +| `build_graphics_assets.py` | Python (Pillow) | Packs sprite sheets and texture atlases into 48 slots of 128×128 32-bit BGRA format, producing `assets/textures/casino3d-hd.bin`. Usage: `python tools/generators/build_graphics_assets.py`. | +| `build_casino_assets.py` | Python (Pillow) | Compiles source textures and sprite images into the legacy `assets/textures/casino3d.bin` binary. | +| `generate_font.py` | Python (Pillow) | Renders Consolas/Arial fonts for all 256 CP1251 characters into an 8×8 1-bit monochrome bitmap table, saved to `font8x8.inc`. Usage: `python tools/generators/generate_font.py`. | +| `generate_math_and_map.py` | Python | Computes 512-angle fixed-point (16.16) Sine and Cosine tables and the 32×32 casino hall floor plan, saving them to `casino3d_data.inc`. Usage: `python tools/generators/generate_math_and_map.py`. | +| `build_all_3d.py` | Python | Offline assembly file generator that synthesizes the complete `casino3d.inc` raycaster engine in CP1251. | +| `generate_unified_casino3d.py` | Python | Alternative unified generator for `casino3d.inc` with full sprite definitions and game interaction hooks. | +| `generate_casino3d.py`
`build_engine.py`
`make_casino3d.py` | Python | Lightweight orchestration scripts for triggering `casino3d.inc` regeneration in CP1251 encoding. | +| `patch_poker_asm.py` | Python | Helper utility to patch `poker.asm` with 3D engine hooks, player save anchors, and mutex management. | + +--- + +## 3. Tests & Verification (`tools/tests/`) + +Verification scripts, simulation harnesses, and runtime helpers: + +| Tool | Language | Purpose & Usage | +|------|----------|-----------------| +| `simulate_render.py` | Python (Pillow) | Software CPU simulation of the 3D raycaster renderer. Reads `casino3d_data.inc` and texture binary, performs DDA raycasting, depth-sorting of 28 casino sprites, and saves the rendered view to `docs/render_view.png`. Usage: `python tools/tests/simulate_render.py`. | +| `release_smoke_check.ps1` | PowerShell | Automated smoke test for release readiness: verifies file presence, launcher SHA-256 hashes, CP1251 source markers, and absence of deprecated assets. Usage: `powershell -File tools/tests/release_smoke_check.ps1`. | +| `build_graphics.ps1` | PowerShell | Builds the Windows subsystem executable `build/graphics/poker.exe` using MASM32/MSVC toolchain. Usage: `powershell -File tools/tests/build_graphics.ps1`. | +| `achievement_popup.bat` | Batch (CP1251) | Standalone console achievement notification popup called by `poker.exe`. Reads achievement text from `runtime/achievement.txt` and renders a decorative banner with rarity colors (COMMON, RARE, EPIC, LEGENDARY). | diff --git a/tools/build_graphics.ps1 b/tools/build_graphics.ps1 deleted file mode 100644 index fa1bfd9..0000000 --- a/tools/build_graphics.ps1 +++ /dev/null @@ -1,13 +0,0 @@ -param([string]$MasmRoot = 'F:\MASM32\masm32') -$ErrorActionPreference = 'Stop' -$root = Split-Path $PSScriptRoot -Parent -Push-Location $root -try { - & "$MasmRoot\bin\ml.exe" /c /coff /Cp /nologo /I. /Fobuild\graphics\poker.obj poker.asm - if ($LASTEXITCODE -ne 0) { throw 'MASM assembly failed' } - & "$MasmRoot\bin\link.exe" /nologo /SUBSYSTEM:WINDOWS /RELEASE /VERSION:5.0 "/LIBPATH:$MasmRoot\lib" /OUT:build\graphics\poker.exe build\graphics\poker.obj build\casino_icon.res kernel32.lib winmm.lib user32.lib ws2_32.lib gdi32.lib - if ($LASTEXITCODE -ne 0) { throw 'Link failed' } - Write-Output 'Built build\graphics\poker.exe. Publish only after verification.' -} finally { - Pop-Location -} diff --git a/tools/build_all_3d.py b/tools/generators/build_all_3d.py similarity index 99% rename from tools/build_all_3d.py rename to tools/generators/build_all_3d.py index 378004b..283d176 100644 --- a/tools/build_all_3d.py +++ b/tools/generators/build_all_3d.py @@ -3225,7 +3225,9 @@ StartCasino3D ENDP ''') # Write complete file in Windows-1251 -with open('casino3d.inc', 'wb') as f: +from pathlib import Path +REPO_ROOT = Path(__file__).resolve().parents[2] +with open(REPO_ROOT / 'casino3d.inc', 'wb') as f: f.write(''.join(code_chunks).encode('cp1251')) print('casino3d.inc completely generated in CP1251!') diff --git a/tools/build_casino_assets.py b/tools/generators/build_casino_assets.py similarity index 98% rename from tools/build_casino_assets.py rename to tools/generators/build_casino_assets.py index 6f1f0ed..fb65fe6 100644 --- a/tools/build_casino_assets.py +++ b/tools/generators/build_casino_assets.py @@ -2,8 +2,8 @@ import os from pathlib import Path from PIL import Image -BRAIN_DIR = Path(r"C:\Users\user\.gemini\antigravity-ide\brain\68821b0e-0e7d-4871-92bc-f142243303b2") -PROJECT_DIR = Path(r"F:\покер") +PROJECT_DIR = Path(__file__).resolve().parents[2] +BRAIN_DIR = PROJECT_DIR / "assets" / "sprites" OUT_DIR = PROJECT_DIR / "assets" / "textures" OUT_BIN = OUT_DIR / "casino3d.bin" diff --git a/tools/build_engine.py b/tools/generators/build_engine.py similarity index 100% rename from tools/build_engine.py rename to tools/generators/build_engine.py diff --git a/tools/build_graphics_assets.py b/tools/generators/build_graphics_assets.py similarity index 98% rename from tools/build_graphics_assets.py rename to tools/generators/build_graphics_assets.py index a0be758..d70a40c 100644 --- a/tools/build_graphics_assets.py +++ b/tools/generators/build_graphics_assets.py @@ -6,7 +6,7 @@ Only transparent alpha is discarded. Black, white and gold detail is retained. from pathlib import Path from PIL import Image -ROOT = Path(__file__).resolve().parents[1] +ROOT = Path(__file__).resolve().parents[2] SIZE = 128 SLOTS = 48 CHROMA = (255, 0, 255, 0) diff --git a/tools/generate_casino3d.py b/tools/generators/generate_casino3d.py similarity index 100% rename from tools/generate_casino3d.py rename to tools/generators/generate_casino3d.py diff --git a/tools/generate_font.py b/tools/generators/generate_font.py similarity index 88% rename from tools/generate_font.py rename to tools/generators/generate_font.py index 40deaf9..36afd34 100644 --- a/tools/generate_font.py +++ b/tools/generators/generate_font.py @@ -30,7 +30,9 @@ for ch_code in range(256): char_bytes.append(row_byte) font_data.append(char_bytes) -with open(r"F:\покер\font8x8.inc", "w", encoding="cp1251") as f: +from pathlib import Path +REPO_ROOT = Path(__file__).resolve().parents[2] +with open(REPO_ROOT / "font8x8.inc", "w", encoding="cp1251") as f: f.write("; --- 8x8 BITMAP FONT FOR CP1251 (Generated) ---\n") f.write(".data\nALIGN 4\nfont8x8 label byte\n") for idx, cb in enumerate(font_data): diff --git a/tools/generate_math_and_map.py b/tools/generators/generate_math_and_map.py similarity index 94% rename from tools/generate_math_and_map.py rename to tools/generators/generate_math_and_map.py index b6ce5e3..3fe2a3d 100644 --- a/tools/generate_math_and_map.py +++ b/tools/generators/generate_math_and_map.py @@ -62,7 +62,9 @@ grid[8][23] = 1 grid[23][8] = 1 grid[23][23] = 1 -with open(r"F:\покер\casino3d_data.inc", "w", encoding="cp1251") as f: +from pathlib import Path +REPO_ROOT = Path(__file__).resolve().parents[2] +with open(REPO_ROOT / "casino3d_data.inc", "w", encoding="cp1251") as f: f.write("; --- CASINO 3D ENGINE DATA (Generated: Grand Open Hall) ---\n\n") f.write("NUM_ANGLES equ 512\n") f.write("MAP_WIDTH equ 32\n") diff --git a/tools/generate_unified_casino3d.py b/tools/generators/generate_unified_casino3d.py similarity index 95% rename from tools/generate_unified_casino3d.py rename to tools/generators/generate_unified_casino3d.py index 418999e..8bfbecb 100644 --- a/tools/generate_unified_casino3d.py +++ b/tools/generators/generate_unified_casino3d.py @@ -2344,7 +2344,9 @@ StartCasino3D ENDP include src_graphics\platform_code.inc ''' -with open('d:/покер/casino3d.inc', 'wb') as f: +from pathlib import Path +REPO_ROOT = Path(__file__).resolve().parents[2] +with open(REPO_ROOT / 'casino3d.inc', 'wb') as f: f.write(content.strip().encode('cp1251')) print('Successfully generated unified casino3d.inc in CP1251!') diff --git a/tools/make_casino3d.py b/tools/generators/make_casino3d.py similarity index 100% rename from tools/make_casino3d.py rename to tools/generators/make_casino3d.py diff --git a/tools/patch_poker_asm.py b/tools/generators/patch_poker_asm.py similarity index 92% rename from tools/patch_poker_asm.py rename to tools/generators/patch_poker_asm.py index 27c6c00..77a5a7e 100644 --- a/tools/patch_poker_asm.py +++ b/tools/generators/patch_poker_asm.py @@ -1,5 +1,6 @@ -# -*- coding: utf-8 -*- -with open('d:/покер/poker.asm', 'r', encoding='cp1251') as f: +from pathlib import Path +REPO_ROOT = Path(__file__).resolve().parents[2] +with open(REPO_ROOT / 'poker.asm', 'r', encoding='cp1251') as f: text = f.read() # 1. Add defaultPlayerSave @@ -85,7 +86,7 @@ main ENDP else: print('Error: exit_menu: not found') -with open('d:/покер/poker.asm', 'wb') as f: +with open(REPO_ROOT / 'poker.asm', 'wb') as f: f.write(text.encode('cp1251')) print('poker.asm updated in CP1251!') diff --git a/preview_casino3d.bat b/tools/previews/preview_casino3d.bat similarity index 77% rename from preview_casino3d.bat rename to tools/previews/preview_casino3d.bat index e96e26a..41c5423 100644 --- a/preview_casino3d.bat +++ b/tools/previews/preview_casino3d.bat @@ -1,4 +1,4 @@ @echo off title 3D Casino DOOM Engine Preview -cd /d "%~dp0" +cd /d "%~dp0..\.." start "" "poker.exe" diff --git a/tools/preview_dbd_hook.bat b/tools/previews/preview_dbd_hook.bat similarity index 97% rename from tools/preview_dbd_hook.bat rename to tools/previews/preview_dbd_hook.bat index 98df9ef..8a5536a 100644 --- a/tools/preview_dbd_hook.bat +++ b/tools/previews/preview_dbd_hook.bat @@ -1,6 +1,6 @@ @echo off mode con cols=120 lines=42 chcp 65001 >nul -set "DBD_ROOT=%~dp0.." +set "DBD_ROOT=%~dp0..\.." powershell -NoProfile -ExecutionPolicy Bypass -Command "$root=[IO.Path]::GetFullPath($env:DBD_ROOT); $ans=Join-Path $root 'assets\animations\dbd_hook.ans'; $stop=Join-Path $root 'runtime\dbd_hook.stop'; $profilePath=Join-Path $root 'runtime\anim_profile.txt'; if(Test-Path $stop){Remove-Item $stop -Force}; if(!(Test-Path $ans)){Write-Host 'dbd_hook.ans not found:' $ans; Start-Sleep -Seconds 3; exit 1}; $profile=1; if(Test-Path $profilePath){ $raw=(Get-Content -LiteralPath $profilePath -Raw -ErrorAction SilentlyContinue).Trim(); if($raw -match '^[0-2]$'){ $profile=[int]$raw } }; $step=@(1,2,3)[$profile]; $delay=80*$step; $frames=(Get-Content -LiteralPath $ans -Raw -Encoding UTF8) -split [char]12; $esc=[char]27; try{ [Console]::Write($esc+'[2J'+$esc+'[?25l'); while(!(Test-Path $stop)){ for($i=0; $i -lt $frames.Count; $i+=$step){ if(Test-Path $stop){break}; [Console]::Write($esc+'[H'); [Console]::Write($frames[$i]); Start-Sleep -Milliseconds $delay } } } finally { [Console]::Write($esc+'[0m'+$esc+'[?25h'); if(Test-Path $stop){Remove-Item $stop -Force} }" exit diff --git a/tools/preview_dbd_hook.py b/tools/previews/preview_dbd_hook.py similarity index 95% rename from tools/preview_dbd_hook.py rename to tools/previews/preview_dbd_hook.py index 315c39d..f4c0936 100644 --- a/tools/preview_dbd_hook.py +++ b/tools/previews/preview_dbd_hook.py @@ -1,4 +1,4 @@ -from pathlib import Path +from pathlib import Path import ctypes import os import sys @@ -25,7 +25,7 @@ def place_window() -> None: def main() -> int: - root = Path(__file__).resolve().parent.parent + root = Path(__file__).resolve().parents[2] path = root / "assets" / "animations" / "dbd_hook.ans" stop_path = root / "runtime" / "dbd_hook.stop" if not path.exists(): diff --git a/tools/preview_hakari.bat b/tools/previews/preview_hakari.bat similarity index 100% rename from tools/preview_hakari.bat rename to tools/previews/preview_hakari.bat diff --git a/tools/preview_hakari.py b/tools/previews/preview_hakari.py similarity index 72% rename from tools/preview_hakari.py rename to tools/previews/preview_hakari.py index 5d465ba..7290c09 100644 --- a/tools/preview_hakari.py +++ b/tools/previews/preview_hakari.py @@ -1,4 +1,4 @@ -from pathlib import Path +from pathlib import Path import os import sys import time @@ -16,9 +16,13 @@ def enable_ansi() -> None: def main() -> int: - root = Path(__file__).resolve().parent - dance_path = root / "hakari_dance.ans" - sound_path = root / "hakari_dance.wav" + repo_root = Path(__file__).resolve().parents[2] + dance_path = repo_root / "assets" / "animations" / "hakari_dance.ans" + if not dance_path.exists(): + dance_path = repo_root / "hakari_dance.ans" + sound_path = repo_root / "assets" / "audio" / "hakari_dance.wav" + if not sound_path.exists(): + sound_path = repo_root / "hakari_dance.wav" if not dance_path.exists(): print("hakari_dance.ans not found") diff --git a/tools/preview_intro.bat b/tools/previews/preview_intro.bat similarity index 100% rename from tools/preview_intro.bat rename to tools/previews/preview_intro.bat diff --git a/tools/preview_intro.py b/tools/previews/preview_intro.py similarity index 88% rename from tools/preview_intro.py rename to tools/previews/preview_intro.py index a7357b5..6e6dddb 100644 --- a/tools/preview_intro.py +++ b/tools/previews/preview_intro.py @@ -10,8 +10,10 @@ FRAME_SEPARATOR = "\f" def main() -> int: - root = Path(__file__).resolve().parent - intro_path = root / "casino_intro.ans" + repo_root = Path(__file__).resolve().parents[2] + intro_path = repo_root / "assets" / "animations" / "casino_intro.ans" + if not intro_path.exists(): + intro_path = repo_root / "casino_intro.ans" if not intro_path.exists(): print("casino_intro.ans not found") return 1 diff --git a/tools/achievement_popup.bat b/tools/tests/achievement_popup.bat similarity index 99% rename from tools/achievement_popup.bat rename to tools/tests/achievement_popup.bat index 9b71fcf..2e0bc6d 100644 --- a/tools/achievement_popup.bat +++ b/tools/tests/achievement_popup.bat @@ -5,7 +5,7 @@ title ASSEMBLER CASINO - ACHIEVEMENT setlocal EnableDelayedExpansion cls set "ACH=Íîâîå äîñòèæåíèå" -set "ROOT=%~dp0.." +set "ROOT=%~dp0..\.." if exist "%ROOT%\runtime\achievement.txt" set /p ACH=<"%ROOT%\runtime\achievement.txt" set "RARITY=COMMON" diff --git a/tools/tests/build_graphics.ps1 b/tools/tests/build_graphics.ps1 new file mode 100644 index 0000000..db4c1b9 --- /dev/null +++ b/tools/tests/build_graphics.ps1 @@ -0,0 +1,42 @@ +param([string]$MasmRoot = '') +$ErrorActionPreference = 'Stop' +$root = (Resolve-Path (Join-Path $PSScriptRoot '..\..')).Path +Push-Location $root +try { + $masmCandidates = @( + $MasmRoot, + 'D:\MASM32\masm32', + 'C:\masm32', + 'F:\MASM32\masm32' + ) | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } + + $foundMasm = $null + foreach ($cand in $masmCandidates) { + try { + $drive = [System.IO.Path]::GetPathRoot($cand).TrimEnd('\', '/') + if ($drive -and -not (Test-Path -LiteralPath $drive)) { continue } + $ml = Join-Path $cand 'bin\ml.exe' + if (Test-Path -LiteralPath $ml) { + $foundMasm = $cand + break + } + } catch {} + } + + if ($foundMasm) { + & "$foundMasm\bin\ml.exe" /c /coff /Cp /nologo /I. /Fobuild\graphics\poker.obj poker.asm + if ($LASTEXITCODE -ne 0) { throw 'MASM assembly failed' } + if (Test-Path -LiteralPath 'build\casino_icon.res') { + & "$foundMasm\bin\link.exe" /nologo /SUBSYSTEM:WINDOWS /RELEASE /VERSION:5.0 "/LIBPATH:$foundMasm\lib" /OUT:build\graphics\poker.exe build\graphics\poker.obj build\casino_icon.res kernel32.lib winmm.lib user32.lib ws2_32.lib gdi32.lib + } else { + & "$foundMasm\bin\link.exe" /nologo /SUBSYSTEM:WINDOWS /RELEASE /VERSION:5.0 "/LIBPATH:$foundMasm\lib" /OUT:build\graphics\poker.exe build\graphics\poker.obj kernel32.lib winmm.lib user32.lib ws2_32.lib gdi32.lib + } + if ($LASTEXITCODE -ne 0) { throw 'Link failed' } + } else { + & cmd.exe /c build.bat + if ($LASTEXITCODE -ne 0) { throw 'Build via build.bat failed' } + } + Write-Output 'Built build\graphics\poker.exe. Publish only after verification.' +} finally { + Pop-Location +} diff --git a/tools/release_smoke_check.ps1 b/tools/tests/release_smoke_check.ps1 similarity index 52% rename from tools/release_smoke_check.ps1 rename to tools/tests/release_smoke_check.ps1 index 45ea5fb..4ab87e1 100644 --- a/tools/release_smoke_check.ps1 +++ b/tools/tests/release_smoke_check.ps1 @@ -1,5 +1,5 @@ param( - [string]$Root = (Resolve-Path (Join-Path $PSScriptRoot '..')).Path + [string]$Root = (Resolve-Path (Join-Path $PSScriptRoot '..\..')).Path ) $ErrorActionPreference = 'Stop' @@ -22,14 +22,25 @@ function Require-File($relative) { Push-Location $Root try { - Require-File 'PokerGameSetup.exe' - Require-File 'Assembler Casino.exe' - Require-File 'Uninstall Assembler Casino.exe' + if (Test-Path -LiteralPath (Join-Path $Root 'PokerGameSetup.exe')) { + Require-File 'PokerGameSetup.exe' + } + if (Test-Path -LiteralPath (Join-Path $Root 'dist\Assembler Casino.exe')) { + Require-File 'dist\Assembler Casino.exe' + } else { + Require-File 'Assembler Casino.exe' + } + if (Test-Path -LiteralPath (Join-Path $Root 'dist\Uninstall Assembler Casino.exe')) { + Require-File 'dist\Uninstall Assembler Casino.exe' + } else { + Require-File 'Uninstall Assembler Casino.exe' + } Require-File 'bin\poker.exe' Require-File 'assets\icons\casino.ico' Require-File 'assets\animations\hakari_dance.ans' Require-File 'assets\animations\dbd_hook.ans' - Require-File 'tools\preview_dbd_hook.bat' + $dbdRelative = if (Test-Path -LiteralPath (Join-Path $Root 'tools\previews\preview_dbd_hook.bat')) { 'tools\previews\preview_dbd_hook.bat' } else { 'tools\preview_dbd_hook.bat' } + Require-File $dbdRelative Require-File 'docs\README_RELEASE.txt' Require-File 'docs\RELEASE_CHECKLIST.txt' Require-File 'docs\KNOWN_LIMITATIONS.txt' @@ -49,7 +60,7 @@ try { } Pass 'MAMBO animation files are removed from assets' - $dbdBat = Get-Content -LiteralPath (Join-Path $Root 'tools\preview_dbd_hook.bat') -Raw + $dbdBat = Get-Content -LiteralPath (Join-Path $Root $dbdRelative) -Raw if ($dbdBat -match 'Clear-Host') { Fail 'DBD helper still uses Clear-Host' } @@ -127,86 +138,90 @@ try { Add-Type -AssemblyName System.IO.Compression.FileSystem $setupPath = Join-Path $Root 'PokerGameSetup.exe' - $fs = [IO.File]::OpenRead($setupPath) - try { - $head = New-Object byte[] ([Math]::Min(2097152, $fs.Length)) - [void]$fs.Read($head, 0, $head.Length) - $marker = [Text.Encoding]::UTF8.GetBytes('<>') - $idx = -1 - for ($i = 0; $i -le $head.Length - $marker.Length; $i++) { - if ($head[$i] -ne $marker[0]) { continue } - $ok = $true - for ($j = 1; $j -lt $marker.Length; $j++) { - if ($head[$i + $j] -ne $marker[$j]) { $ok = $false; break } + if (Test-Path -LiteralPath $setupPath) { + $fs = [IO.File]::OpenRead($setupPath) + try { + $head = New-Object byte[] ([Math]::Min(2097152, $fs.Length)) + [void]$fs.Read($head, 0, $head.Length) + $marker = [Text.Encoding]::UTF8.GetBytes('<>') + $idx = -1 + for ($i = 0; $i -le $head.Length - $marker.Length; $i++) { + if ($head[$i] -ne $marker[0]) { continue } + $ok = $true + for ($j = 1; $j -lt $marker.Length; $j++) { + if ($head[$i + $j] -ne $marker[$j]) { $ok = $false; break } + } + if ($ok) { $idx = $i; break } } - if ($ok) { $idx = $i; break } + if ($idx -lt 0) { Fail 'Installer payload marker not found' } + + $fs.Position = $idx + $marker.Length + $zipBytes = New-Object byte[] ($fs.Length - $fs.Position) + [void]$fs.Read($zipBytes, 0, $zipBytes.Length) + } + finally { + $fs.Dispose() } - if ($idx -lt 0) { Fail 'Installer payload marker not found' } - $fs.Position = $idx + $marker.Length - $zipBytes = New-Object byte[] ($fs.Length - $fs.Position) - [void]$fs.Read($zipBytes, 0, $zipBytes.Length) - } - finally { - $fs.Dispose() - } - - $ms = New-Object IO.MemoryStream(,$zipBytes) - $zip = New-Object IO.Compression.ZipArchive($ms, [IO.Compression.ZipArchiveMode]::Read) - try { - $names = @($zip.Entries | ForEach-Object FullName) - foreach ($entry in @( - 'Assembler Casino.exe', - 'Uninstall Assembler Casino.exe', - 'bin/poker.exe', - 'assets/icons/casino.ico', - 'tools/preview_dbd_hook.bat', - 'tools/release_smoke_check.ps1', - 'docs/README_RELEASE.txt', - 'docs/RELEASE_CHECKLIST.txt', - 'docs/KNOWN_LIMITATIONS.txt', - 'docs/SECURITY_NOTES.txt', - 'docs/ROADMAP.txt', - 'docs/ONLINE_RADMIN.txt' - )) { - if ($names -notcontains $entry) { - Fail "Installer payload missing: $entry" + $ms = New-Object IO.MemoryStream(,$zipBytes) + $zip = New-Object IO.Compression.ZipArchive($ms, [IO.Compression.ZipArchiveMode]::Read) + try { + $names = @($zip.Entries | ForEach-Object FullName) + foreach ($entry in @( + 'Assembler Casino.exe', + 'Uninstall Assembler Casino.exe', + 'bin/poker.exe', + 'assets/icons/casino.ico', + 'tools/preview_dbd_hook.bat', + 'tools/release_smoke_check.ps1', + 'docs/README_RELEASE.txt', + 'docs/RELEASE_CHECKLIST.txt', + 'docs/KNOWN_LIMITATIONS.txt', + 'docs/SECURITY_NOTES.txt', + 'docs/ROADMAP.txt', + 'docs/ONLINE_RADMIN.txt' + )) { + if ($names -notcontains $entry) { + Fail "Installer payload missing: $entry" + } } - } - if ($names -contains 'Assembler Casino.bat') { - Fail 'Installer payload still contains old Assembler Casino.bat' - } - if ($names | Where-Object { $_ -like 'tools/generated_frames/*' }) { - Fail 'Installer payload contains generated preview frames/tools' - } - foreach ($entry in @( - 'assets/animations/mambo1.ans', - 'assets/animations/mambo2.ans', - 'assets/animations/mambo3.ans', - 'assets/animations/mambo4.ans' - )) { - if ($names -contains $entry) { - Fail "Installer payload still contains removed MAMBO animation: $entry" + if ($names -contains 'Assembler Casino.bat') { + Fail 'Installer payload still contains old Assembler Casino.bat' } + if ($names | Where-Object { $_ -like 'tools/generated_frames/*' }) { + Fail 'Installer payload contains generated preview frames/tools' + } + foreach ($entry in @( + 'assets/animations/mambo1.ans', + 'assets/animations/mambo2.ans', + 'assets/animations/mambo3.ans', + 'assets/animations/mambo4.ans' + )) { + if ($names -contains $entry) { + Fail "Installer payload still contains removed MAMBO animation: $entry" + } + } + Pass "Installer payload OK ($($names.Count) files)" + } + finally { + $zip.Dispose() + $ms.Dispose() } - Pass "Installer payload OK ($($names.Count) files)" - } - finally { - $zip.Dispose() - $ms.Dispose() - } - $sha = [Security.Cryptography.SHA256]::Create() - try { - $actualHash = [BitConverter]::ToString($sha.ComputeHash($zipBytes)).Replace('-', '').ToUpperInvariant() + $sha = [Security.Cryptography.SHA256]::Create() + try { + $actualHash = [BitConverter]::ToString($sha.ComputeHash($zipBytes)).Replace('-', '').ToUpperInvariant() + } + finally { + $sha.Dispose() + } + if ($actualHash -ne $expectedHash) { + Fail "Installer payload SHA-256 mismatch. Expected $expectedHash, actual $actualHash" + } + Pass 'Installer payload SHA-256 matches embedded hash' + } else { + Pass 'PokerGameSetup.exe not present (skipping installer binary payload check)' } - finally { - $sha.Dispose() - } - if ($actualHash -ne $expectedHash) { - Fail "Installer payload SHA-256 mismatch. Expected $expectedHash, actual $actualHash" - } - Pass 'Installer payload SHA-256 matches embedded hash' Write-Host '' Write-Host 'Release smoke check passed.' -ForegroundColor Cyan diff --git a/tools/simulate_render.py b/tools/tests/simulate_render.py similarity index 93% rename from tools/simulate_render.py rename to tools/tests/simulate_render.py index 295a974..3398757 100644 --- a/tools/simulate_render.py +++ b/tools/tests/simulate_render.py @@ -7,13 +7,16 @@ SCREEN_W = 640 SCREEN_H = 480 HALF_W = 320 HALF_H = 240 +from pathlib import Path +REPO_ROOT = Path(__file__).resolve().parents[2] + FP_1 = 65536 FP_HALF = 32768 MAP_WIDTH = 32 MAP_HEIGHT = 32 # Load map -with open('d:/покер/casino3d_data.inc', 'r', encoding='latin1') as f: +with open(REPO_ROOT / 'casino3d_data.inc', 'r', encoding='latin1') as f: text = f.read() import re @@ -34,7 +37,7 @@ for l in map_lines: casinoMap.extend(vals) # Load textures -tex_raw = open('d:/покер/assets/textures/casino3d-hd.bin', 'rb').read() +tex_raw = open(REPO_ROOT / 'assets' / 'textures' / 'casino3d-hd.bin', 'rb').read() slot_size = 128 * 128 * 4 def get_tex_pixel(slot, tx, ty): @@ -266,5 +269,6 @@ for s in sprites: # Save image img = Image.new('RGB', (SCREEN_W, SCREEN_H)) img.putdata(screen_pixels) -img.save('d:/покер/render_view.png') -print('render_view.png saved successfully!') +out_path = REPO_ROOT / 'docs' / 'render_view.png' +img.save(out_path) +print(f'{out_path} saved successfully!')