feat: add peaceful adventure mode, clean immersive HUD, and genre toggle
This commit is contained in:
parent
25bd6377a7
commit
341966debe
14 changed files with 473 additions and 80 deletions
13
AGENTS.md
13
AGENTS.md
|
|
@ -259,3 +259,16 @@ EblanStudio has evolved from a pure level editor into a **Full Game Engine Studi
|
||||||
- `Game_OnCustomHUD`: custom 2D canvas drawing (health bars, gauges, quest markers).
|
- `Game_OnCustomHUD`: custom 2D canvas drawing (health bars, gauges, quest markers).
|
||||||
- `PlayGameSFX(pszRelativePath)`: safe asynchronous WinMM audio player.
|
- `PlayGameSFX(pszRelativePath)`: safe asynchronous WinMM audio player.
|
||||||
- Built-in automatic gameplay toasts for keys, medkits, ammo, switches, doors, and explosions.
|
- Built-in automatic gameplay toasts for keys, medkits, ammo, switches, doors, and explosions.
|
||||||
|
|
||||||
|
6. **Game Genres, Peaceful Adventure Mode & Immersive Clean HUD**:
|
||||||
|
- `GAME_MODE_ADVENTURE (0)`: pure exploration / quest / horror / puzzle mode without weapons, ammo, crosshair, or combat overlays.
|
||||||
|
- `GAME_MODE_ACTION (1)`: full combat shooter mode with weapon models, crosshair, health bar, and ammo counter.
|
||||||
|
- `HUD_STYLE_CLEAN (0)`: 100% immersive full-screen view (no debug banners, no text collisions, no bottom controls clutter).
|
||||||
|
- `HUD_STYLE_DEBUG (1)`: developer mode displaying FPS counter at top-right (X=250), engine title, score, and controls hints.
|
||||||
|
- Instant in-game switching:
|
||||||
|
- `[ESC] -> [2]`: toggle weapons / peaceful mode on the fly with toast notifications.
|
||||||
|
- `[ESC] -> [3]`: toggle clean vs debug HUD.
|
||||||
|
- `[F1]` or `[H]`: quick hotkey to toggle clean HUD vs debug HUD.
|
||||||
|
- Editor toolbar 1-click genre switcher: `☮ КВЕСТ / БЕЗ ОРУЖИЯ` vs `⚔ ЭКШЕН / С ОРУЖИЕМ`.
|
||||||
|
- Project settings (`project.eblanproj`) persist `GameMode`, `ShowWeapons`, and `ShowCrosshair`.
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -1,22 +1,22 @@
|
||||||
[Window][Workspace]
|
[Window][Workspace]
|
||||||
Pos=0,60
|
Pos=0,60
|
||||||
Size=2560,1292
|
Size=2560,1292
|
||||||
LastUsed=20261022
|
LastUsed=20261023
|
||||||
|
|
||||||
[Window][Debug##Default]
|
[Window][Debug##Default]
|
||||||
Pos=60,60
|
Pos=60,60
|
||||||
Size=400,400
|
Size=400,400
|
||||||
LastUsed=20261022
|
LastUsed=20261023
|
||||||
|
|
||||||
[Window][Toolbar]
|
[Window][Toolbar]
|
||||||
Pos=0,20
|
Pos=0,20
|
||||||
Size=2560,38
|
Size=2560,38
|
||||||
LastUsed=20261022
|
LastUsed=20261023
|
||||||
|
|
||||||
[Window][StatusBar]
|
[Window][StatusBar]
|
||||||
Pos=0,1352
|
Pos=0,1352
|
||||||
Size=2560,32
|
Size=2560,32
|
||||||
LastUsed=20261022
|
LastUsed=20261023
|
||||||
|
|
||||||
[Window][Не удалось запустить игру]
|
[Window][Не удалось запустить игру]
|
||||||
Pos=649,356
|
Pos=649,356
|
||||||
|
|
@ -29,7 +29,12 @@ Size=900,650
|
||||||
LastUsed=20261022
|
LastUsed=20261022
|
||||||
|
|
||||||
[Window][Менеджер ассетов (Texture & Audio Manager)]
|
[Window][Менеджер ассетов (Texture & Audio Manager)]
|
||||||
Pos=60,60
|
Pos=61,60
|
||||||
Size=820,580
|
Size=820,580
|
||||||
LastUsed=20261022
|
LastUsed=20261023
|
||||||
|
|
||||||
|
[Window][Редактор кода MASM32 & Игровых скриптов (F7)]
|
||||||
|
Pos=60,60
|
||||||
|
Size=1020,680
|
||||||
|
LastUsed=20261023
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -255,6 +255,12 @@ bool EditorApp::PreparePlaytest(std::string& startMap, std::string& enginePath)
|
||||||
if (ec) return copyFailure();
|
if (ec) return copyFailure();
|
||||||
if (fs::is_directory(sounds, ec)) fs::copy(sounds, sandbox / "assets/sounds", fs::copy_options::recursive, ec);
|
if (fs::is_directory(sounds, ec)) fs::copy(sounds, sandbox / "assets/sounds", fs::copy_options::recursive, ec);
|
||||||
if (ec) return copyFailure();
|
if (ec) return copyFailure();
|
||||||
|
char modulePath[MAX_PATH]{};
|
||||||
|
GetModuleFileNameA(nullptr, modulePath, MAX_PATH);
|
||||||
|
fs::path projFile = fs::path(modulePath).parent_path() / "project.eblanproj";
|
||||||
|
if (fs::exists(projFile, ec)) {
|
||||||
|
fs::copy_file(projFile, sandbox / "project.eblanproj", fs::copy_options::overwrite_existing, ec);
|
||||||
|
}
|
||||||
// Validate all reachable maps and destination spawns, including reverse links.
|
// Validate all reachable maps and destination spawns, including reverse links.
|
||||||
std::vector<std::string> pending{source.filename().string()};
|
std::vector<std::string> pending{source.filename().string()};
|
||||||
std::set<std::string> visited;
|
std::set<std::string> visited;
|
||||||
|
|
@ -1617,6 +1623,42 @@ void EditorApp::RenderToolbar() {
|
||||||
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
|
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
// Game Mode Quick Selector (Peaceful Adventure vs Action Shooter)
|
||||||
|
if (project && project->gameMode == 0) {
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.12f, 0.45f, 0.40f, 1.0f));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.18f, 0.58f, 0.50f, 1.0f));
|
||||||
|
if (ImGui::Button(" ☮ КВЕСТ / БЕЗ ОРУЖИЯ ")) {
|
||||||
|
project->gameMode = 1;
|
||||||
|
project->showWeapons = true;
|
||||||
|
char module[MAX_PATH]{};
|
||||||
|
GetModuleFileNameA(nullptr, module, MAX_PATH);
|
||||||
|
std::string projPath = (fs::path(module).parent_path() / "project.eblanproj").string();
|
||||||
|
project->Save(projPath);
|
||||||
|
statusMessage = "Режим игры: ЭКШЕН / ШУТЕР (с оружием и стрельбой)";
|
||||||
|
}
|
||||||
|
ImGui::PopStyleColor(2);
|
||||||
|
} else if (project) {
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.55f, 0.30f, 0.10f, 1.0f));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.70f, 0.38f, 0.12f, 1.0f));
|
||||||
|
if (ImGui::Button(" ⚔ ЭКШЕН / С ОРУЖИЕМ ")) {
|
||||||
|
project->gameMode = 0;
|
||||||
|
project->showWeapons = false;
|
||||||
|
char module[MAX_PATH]{};
|
||||||
|
GetModuleFileNameA(nullptr, module, MAX_PATH);
|
||||||
|
std::string projPath = (fs::path(module).parent_path() / "project.eblanproj").string();
|
||||||
|
project->Save(projPath);
|
||||||
|
statusMessage = "Режим игры: КВЕСТ / МИРНЫЙ (без оружия)";
|
||||||
|
}
|
||||||
|
ImGui::PopStyleColor(2);
|
||||||
|
}
|
||||||
|
if (ImGui::IsItemHovered()) {
|
||||||
|
ImGui::SetTooltip("Нажмите для быстрого переключения жанра игры (Квест без оружия / Шутер с оружием)");
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
|
||||||
|
ImGui::SameLine();
|
||||||
|
|
||||||
// Tools
|
// Tools
|
||||||
auto ToolButton = [&](const char* label, ToolMode mode) {
|
auto ToolButton = [&](const char* label, ToolMode mode) {
|
||||||
bool active = (currentTool == mode);
|
bool active = (currentTool == mode);
|
||||||
|
|
@ -2292,12 +2334,18 @@ void EditorApp::RenderProjectSettingsModal() {
|
||||||
static char authorBuf[128] = "";
|
static char authorBuf[128] = "";
|
||||||
static char versionBuf[32] = "";
|
static char versionBuf[32] = "";
|
||||||
static char windowTitleBuf[128] = "";
|
static char windowTitleBuf[128] = "";
|
||||||
|
static int modeChoice = 1;
|
||||||
|
static bool showWeap = true;
|
||||||
|
static bool showCross = true;
|
||||||
static bool init = true;
|
static bool init = true;
|
||||||
if (init) {
|
if (init) {
|
||||||
strncpy_s(titleBuf, project->title.c_str(), sizeof(titleBuf) - 1);
|
strncpy_s(titleBuf, project->title.c_str(), sizeof(titleBuf) - 1);
|
||||||
strncpy_s(authorBuf, project->author.c_str(), sizeof(authorBuf) - 1);
|
strncpy_s(authorBuf, project->author.c_str(), sizeof(authorBuf) - 1);
|
||||||
strncpy_s(versionBuf, project->version.c_str(), sizeof(versionBuf) - 1);
|
strncpy_s(versionBuf, project->version.c_str(), sizeof(versionBuf) - 1);
|
||||||
strncpy_s(windowTitleBuf, project->windowTitle.c_str(), sizeof(windowTitleBuf) - 1);
|
strncpy_s(windowTitleBuf, project->windowTitle.c_str(), sizeof(windowTitleBuf) - 1);
|
||||||
|
modeChoice = project->gameMode;
|
||||||
|
showWeap = project->showWeapons;
|
||||||
|
showCross = project->showCrosshair;
|
||||||
init = false;
|
init = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2309,6 +2357,20 @@ void EditorApp::RenderProjectSettingsModal() {
|
||||||
ImGui::InputText("Версия", versionBuf, sizeof(versionBuf));
|
ImGui::InputText("Версия", versionBuf, sizeof(versionBuf));
|
||||||
ImGui::InputText("Заголовок окна", windowTitleBuf, sizeof(windowTitleBuf));
|
ImGui::InputText("Заголовок окна", windowTitleBuf, sizeof(windowTitleBuf));
|
||||||
|
|
||||||
|
ImGui::Spacing();
|
||||||
|
ImGui::TextColored(ImVec4(0.2f, 0.8f, 1.0f, 1.0f), "Жанр и режим геймплея:");
|
||||||
|
ImGui::RadioButton("Квест / Приключение / Хоррор (Мирный режим, без оружия)", &modeChoice, 0);
|
||||||
|
ImGui::RadioButton("Экшен / Шутер (С оружием, патронами и перестрелками)", &modeChoice, 1);
|
||||||
|
|
||||||
|
if (modeChoice == 1) {
|
||||||
|
ImGui::Checkbox("Отображать оружие от 1-го лица", &showWeap);
|
||||||
|
ImGui::Checkbox("Отображать перекрестие прицела", &showCross);
|
||||||
|
} else {
|
||||||
|
showWeap = false;
|
||||||
|
showCross = false;
|
||||||
|
ImGui::TextDisabled("В мирном режиме оружие, прицел и счетчик патронов скрыты.");
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
ImGui::Text("Стартовая карта: %s", project->startupMap.c_str());
|
ImGui::Text("Стартовая карта: %s", project->startupMap.c_str());
|
||||||
|
|
||||||
|
|
@ -2318,6 +2380,9 @@ void EditorApp::RenderProjectSettingsModal() {
|
||||||
project->author = authorBuf;
|
project->author = authorBuf;
|
||||||
project->version = versionBuf;
|
project->version = versionBuf;
|
||||||
project->windowTitle = windowTitleBuf;
|
project->windowTitle = windowTitleBuf;
|
||||||
|
project->gameMode = modeChoice;
|
||||||
|
project->showWeapons = showWeap;
|
||||||
|
project->showCrosshair = showCross;
|
||||||
|
|
||||||
char module[MAX_PATH]{};
|
char module[MAX_PATH]{};
|
||||||
GetModuleFileNameA(nullptr, module, MAX_PATH);
|
GetModuleFileNameA(nullptr, module, MAX_PATH);
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,9 @@ struct EblanProject {
|
||||||
std::string windowTitle = "EBLAN ENGINE 3D - Standalone Retro Game";
|
std::string windowTitle = "EBLAN ENGINE 3D - Standalone Retro Game";
|
||||||
int defaultWidth = 1280;
|
int defaultWidth = 1280;
|
||||||
int defaultHeight = 960;
|
int defaultHeight = 960;
|
||||||
|
int gameMode = 1; // 0 = Adventure (No weapons / Peaceful), 1 = Action (Weapons)
|
||||||
|
bool showWeapons = true;
|
||||||
|
bool showCrosshair = true;
|
||||||
|
|
||||||
bool Save(const std::string& path) const {
|
bool Save(const std::string& path) const {
|
||||||
HANDLE hFile = CreateFileA(path.c_str(), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
|
HANDLE hFile = CreateFileA(path.c_str(), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||||
|
|
@ -31,6 +34,10 @@ struct EblanProject {
|
||||||
content += std::string("DefaultWidth=") + numBuf + "\r\n";
|
content += std::string("DefaultWidth=") + numBuf + "\r\n";
|
||||||
snprintf(numBuf, sizeof(numBuf), "%d", defaultHeight);
|
snprintf(numBuf, sizeof(numBuf), "%d", defaultHeight);
|
||||||
content += std::string("DefaultHeight=") + numBuf + "\r\n";
|
content += std::string("DefaultHeight=") + numBuf + "\r\n";
|
||||||
|
snprintf(numBuf, sizeof(numBuf), "%d", gameMode);
|
||||||
|
content += std::string("GameMode=") + numBuf + "\r\n";
|
||||||
|
content += std::string("ShowWeapons=") + (showWeapons ? "1" : "0") + "\r\n";
|
||||||
|
content += std::string("ShowCrosshair=") + (showCrosshair ? "1" : "0") + "\r\n";
|
||||||
DWORD written = 0;
|
DWORD written = 0;
|
||||||
WriteFile(hFile, content.data(), static_cast<DWORD>(content.size()), &written, nullptr);
|
WriteFile(hFile, content.data(), static_cast<DWORD>(content.size()), &written, nullptr);
|
||||||
CloseHandle(hFile);
|
CloseHandle(hFile);
|
||||||
|
|
@ -65,6 +72,9 @@ struct EblanProject {
|
||||||
else if (key == "WindowTitle") windowTitle = val;
|
else if (key == "WindowTitle") windowTitle = val;
|
||||||
else if (key == "DefaultWidth") defaultWidth = std::atoi(val.c_str());
|
else if (key == "DefaultWidth") defaultWidth = std::atoi(val.c_str());
|
||||||
else if (key == "DefaultHeight") defaultHeight = std::atoi(val.c_str());
|
else if (key == "DefaultHeight") defaultHeight = std::atoi(val.c_str());
|
||||||
|
else if (key == "GameMode") gameMode = std::atoi(val.c_str());
|
||||||
|
else if (key == "ShowWeapons") showWeapons = (val == "1" || val == "true");
|
||||||
|
else if (key == "ShowCrosshair") showCrosshair = (val == "1" || val == "true");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
BIN
engine.exe
BIN
engine.exe
Binary file not shown.
|
|
@ -37,11 +37,17 @@ UpdateCombat PROC uses ebx ecx edx esi edi
|
||||||
dec playerHitFlash
|
dec playerHitFlash
|
||||||
@@:
|
@@:
|
||||||
|
|
||||||
; If player is dead or game is paused, cannot attack
|
; If player is dead, game is paused, or in peaceful adventure mode, cannot attack
|
||||||
cmp isPlayerDead, 0
|
cmp isPlayerDead, 0
|
||||||
jne combat_done
|
jne combat_done
|
||||||
cmp isGamePaused, 0
|
cmp isGamePaused, 0
|
||||||
jne combat_done
|
jne combat_done
|
||||||
|
cmp gameMode, GAME_MODE_ADVENTURE
|
||||||
|
je combat_done
|
||||||
|
cmp enableWeapons, 0
|
||||||
|
je combat_done
|
||||||
|
cmp playerWeapon, WEAPON_NONE
|
||||||
|
je combat_done
|
||||||
|
|
||||||
; 2. Check attack input
|
; 2. Check attack input
|
||||||
cmp keyAttack, 0
|
cmp keyAttack, 0
|
||||||
|
|
@ -383,10 +389,21 @@ UpdateCombat ENDP
|
||||||
RenderCombatHUD PROC uses ebx ecx edx esi edi
|
RenderCombatHUD PROC uses ebx ecx edx esi edi
|
||||||
LOCAL barW:DWORD, gunY:DWORD
|
LOCAL barW:DWORD, gunY:DWORD
|
||||||
|
|
||||||
|
; If in adventure mode, unarmed, or weapons disabled, skip weapon & combat stats
|
||||||
|
cmp gameMode, GAME_MODE_ADVENTURE
|
||||||
|
je hud_damage_flash
|
||||||
|
cmp enableWeapons, 0
|
||||||
|
je hud_damage_flash
|
||||||
|
cmp playerWeapon, WEAPON_NONE
|
||||||
|
je hud_damage_flash
|
||||||
|
|
||||||
; 1. Center Crosshair (subtle cross at 160, 120)
|
; 1. Center Crosshair (subtle cross at 160, 120)
|
||||||
|
cmp showCrosshair, 0
|
||||||
|
je skip_crosshair
|
||||||
invoke DrawRect, 156, 120, 9, 1, 00FFFFFFh
|
invoke DrawRect, 156, 120, 9, 1, 00FFFFFFh
|
||||||
invoke DrawRect, 160, 116, 1, 9, 00FFFFFFh
|
invoke DrawRect, 160, 116, 1, 9, 00FFFFFFh
|
||||||
invoke DrawRect, 160, 120, 1, 1, 0000FF00h
|
invoke DrawRect, 160, 120, 1, 1, 0000FF00h
|
||||||
|
skip_crosshair:
|
||||||
|
|
||||||
; 2. Render Active Weapon at bottom center
|
; 2. Render Active Weapon at bottom center
|
||||||
cmp playerWeapon, WEAPON_KNIFE
|
cmp playerWeapon, WEAPON_KNIFE
|
||||||
|
|
@ -470,15 +487,15 @@ draw_pistol_barrel:
|
||||||
invoke DrawRect, 152, eax, 17, 22, 00453020h ; brown wood grip plates
|
invoke DrawRect, 152, eax, 17, 22, 00453020h ; brown wood grip plates
|
||||||
|
|
||||||
hud_stats_draw:
|
hud_stats_draw:
|
||||||
; 3. Health Bar
|
; 3. Health Bar at top-left: X=8, Y=8
|
||||||
invoke DrawString8x8, 8, 42, OFFSET strHpLabel, COLOR_GREEN
|
invoke DrawString8x8, 8, 8, OFFSET strHpLabel, COLOR_GREEN
|
||||||
invoke DrawNumber8x8, 34, 42, playerHealth, COLOR_WHITE
|
invoke DrawNumber8x8, 34, 8, playerHealth, COLOR_WHITE
|
||||||
|
|
||||||
invoke DrawRect, 68, 42, 60, 8, 00441010h
|
invoke DrawRect, 66, 8, 50, 8, 00441010h
|
||||||
invoke DrawRectOutline, 68, 42, 60, 8, COLOR_WHITE
|
invoke DrawRectOutline, 66, 8, 50, 8, COLOR_WHITE
|
||||||
|
|
||||||
mov eax, playerHealth
|
mov eax, playerHealth
|
||||||
imul eax, 58
|
imul eax, 48
|
||||||
xor edx, edx
|
xor edx, edx
|
||||||
mov ecx, playerMaxHealth
|
mov ecx, playerMaxHealth
|
||||||
test ecx, ecx
|
test ecx, ecx
|
||||||
|
|
@ -489,57 +506,63 @@ hud_stats_draw:
|
||||||
mov barW, eax
|
mov barW, eax
|
||||||
cmp barW, 0
|
cmp barW, 0
|
||||||
jle hud_ammo_draw
|
jle hud_ammo_draw
|
||||||
cmp barW, 58
|
cmp barW, 48
|
||||||
jle @F
|
jle @F
|
||||||
mov barW, 58
|
mov barW, 48
|
||||||
@@:
|
@@:
|
||||||
mov edx, 0000CC33h ; Green
|
mov edx, 0000CC33h ; Green
|
||||||
cmp playerHealth, 30
|
cmp playerHealth, 30
|
||||||
jg @F
|
jg @F
|
||||||
mov edx, 00FF2222h ; Red warning
|
mov edx, 00FF2222h ; Red warning
|
||||||
@@:
|
@@:
|
||||||
invoke DrawRect, 69, 43, barW, 6, edx
|
invoke DrawRect, 67, 9, barW, 6, edx
|
||||||
|
|
||||||
hud_ammo_draw:
|
hud_ammo_draw:
|
||||||
; 4. Ammo Display
|
; 4. Ammo Display: X=126, Y=8
|
||||||
invoke DrawString8x8, 140, 42, OFFSET strAmmoLabel, COLOR_YELLOW
|
invoke DrawString8x8, 126, 8, OFFSET strAmmoLabel, COLOR_YELLOW
|
||||||
invoke DrawNumber8x8, 182, 42, playerAmmo, COLOR_YELLOW
|
invoke DrawNumber8x8, 168, 8, playerAmmo, COLOR_YELLOW
|
||||||
|
|
||||||
; 5. Score Display
|
; 5. Keys: X=204, Y=8 (if collected)
|
||||||
invoke DrawString8x8, 222, 42, OFFSET strScoreLabel, COLOR_CYAN
|
cmp playerKeys, 0
|
||||||
invoke DrawNumber8x8, 272, 42, playerScore, COLOR_CYAN
|
jle hud_score_draw
|
||||||
|
invoke DrawString8x8, 204, 8, OFFSET strKeysLabel, COLOR_MAGENTA
|
||||||
|
invoke DrawNumber8x8, 238, 8, playerKeys, COLOR_MAGENTA
|
||||||
|
|
||||||
|
hud_score_draw:
|
||||||
|
; 6. Score Display: only in Debug HUD style
|
||||||
|
cmp hudStyle, HUD_STYLE_CLEAN
|
||||||
|
je draw_weapon_badge
|
||||||
|
invoke DrawString8x8, 8, 20, OFFSET strScoreLabel, COLOR_CYAN
|
||||||
|
invoke DrawNumber8x8, 58, 20, playerScore, COLOR_CYAN
|
||||||
|
|
||||||
|
draw_weapon_badge:
|
||||||
|
; 7. Active Weapon Badge at bottom-right corner: X=228, Y=222
|
||||||
|
invoke DrawRect, 228, 222, 88, 14, 00141414h
|
||||||
|
invoke DrawRectOutline, 228, 222, 88, 14, 00444444h
|
||||||
|
|
||||||
; 6. Active Weapon Name & Slot Indicators at top left
|
|
||||||
invoke DrawString8x8, 8, 26, OFFSET strWeaponLabel, COLOR_WHITE
|
|
||||||
cmp playerWeapon, WEAPON_KNIFE
|
cmp playerWeapon, WEAPON_KNIFE
|
||||||
jne @F
|
jne @F
|
||||||
invoke DrawString8x8, 42, 26, OFFSET strWeaponKnife, COLOR_CYAN
|
invoke DrawString8x8, 233, 225, OFFSET strWeaponKnife, COLOR_CYAN
|
||||||
jmp draw_weapon_slots
|
jmp draw_weapon_slots
|
||||||
@@:
|
@@:
|
||||||
cmp playerWeapon, WEAPON_SHOTGUN
|
cmp playerWeapon, WEAPON_SHOTGUN
|
||||||
jne @F
|
jne @F
|
||||||
invoke DrawString8x8, 42, 26, OFFSET strWeaponShotgun, 00FFAA00h
|
invoke DrawString8x8, 233, 225, OFFSET strWeaponShotgun, 00FFAA00h
|
||||||
jmp draw_weapon_slots
|
jmp draw_weapon_slots
|
||||||
@@:
|
@@:
|
||||||
invoke DrawString8x8, 42, 26, OFFSET strWeaponPistol, COLOR_YELLOW
|
invoke DrawString8x8, 233, 225, OFFSET strWeaponPistol, COLOR_YELLOW
|
||||||
|
|
||||||
draw_weapon_slots:
|
draw_weapon_slots:
|
||||||
; Draw small weapon slot indicator boxes: [1] [2] [3]
|
; Draw small weapon slot indicator boxes: [1] [2] [3]
|
||||||
invoke DrawRectOutline, 100, 26, 8, 8, 00555555h
|
invoke DrawRectOutline, 287, 225, 6, 8, 00555555h
|
||||||
invoke DrawRectOutline, 112, 26, 8, 8, 00555555h
|
invoke DrawRectOutline, 295, 225, 6, 8, 00555555h
|
||||||
invoke DrawRectOutline, 124, 26, 8, 8, 00555555h
|
invoke DrawRectOutline, 303, 225, 6, 8, 00555555h
|
||||||
|
|
||||||
; Highlight active slot
|
; Highlight active slot
|
||||||
mov eax, playerWeapon
|
mov eax, playerWeapon
|
||||||
imul eax, 12
|
imul eax, 8
|
||||||
add eax, 100
|
add eax, 287
|
||||||
invoke DrawRectOutline, eax, 26, 8, 8, COLOR_YELLOW
|
invoke DrawRectOutline, eax, 225, 6, 8, COLOR_YELLOW
|
||||||
|
|
||||||
; 7. Keys (if collected)
|
|
||||||
cmp playerKeys, 0
|
|
||||||
jle hud_damage_flash
|
|
||||||
invoke DrawString8x8, 222, 10, OFFSET strKeysLabel, COLOR_MAGENTA
|
|
||||||
invoke DrawNumber8x8, 258, 10, playerKeys, COLOR_MAGENTA
|
|
||||||
|
|
||||||
hud_damage_flash:
|
hud_damage_flash:
|
||||||
; 8. Damage Screen Flash
|
; 8. Damage Screen Flash
|
||||||
|
|
@ -571,19 +594,20 @@ RenderPauseMenu PROC uses ebx ecx edx
|
||||||
cmp isGamePaused, 0
|
cmp isGamePaused, 0
|
||||||
je pause_menu_done
|
je pause_menu_done
|
||||||
|
|
||||||
; Semi-transparent dark overlay panel (centered 200x105 at 60, 65)
|
; Centered semi-transparent panel 220x112 at (50, 64)
|
||||||
invoke DrawRect, 60, 65, 200, 105, 00141416h
|
invoke DrawRect, 50, 64, 220, 112, 00141416h
|
||||||
invoke DrawRectOutline, 60, 65, 200, 105, COLOR_CYAN
|
invoke DrawRectOutline, 50, 64, 220, 112, COLOR_CYAN
|
||||||
invoke DrawRectOutline, 62, 67, 196, 101, COLOR_WHITE
|
invoke DrawRectOutline, 52, 66, 216, 108, COLOR_WHITE
|
||||||
|
|
||||||
; Header
|
; Header
|
||||||
invoke DrawString8x8, 112, 75, OFFSET strPauseTitle, COLOR_YELLOW
|
invoke DrawString8x8, 112, 72, OFFSET strPauseTitle, COLOR_YELLOW
|
||||||
|
|
||||||
; Menu Options
|
; Menu Options
|
||||||
invoke DrawString8x8, 76, 95, OFFSET strPauseOpt1, COLOR_GREEN
|
invoke DrawString8x8, 64, 88, OFFSET strPauseOpt1, COLOR_GREEN
|
||||||
invoke DrawString8x8, 76, 110, OFFSET strPauseOpt2, COLOR_WHITE
|
invoke DrawString8x8, 64, 102, OFFSET strPauseOpt2, COLOR_WHITE
|
||||||
invoke DrawString8x8, 76, 125, OFFSET strPauseOpt3, COLOR_CYAN
|
invoke DrawString8x8, 64, 116, OFFSET strPauseOpt3, COLOR_CYAN
|
||||||
invoke DrawString8x8, 76, 140, OFFSET strPauseOpt4, 00FF4444h
|
invoke DrawString8x8, 64, 130, OFFSET strPauseOpt4, COLOR_YELLOW
|
||||||
|
invoke DrawString8x8, 64, 146, OFFSET strPauseOpt5, 00FF4444h
|
||||||
|
|
||||||
pause_menu_done:
|
pause_menu_done:
|
||||||
ret
|
ret
|
||||||
|
|
|
||||||
|
|
@ -69,10 +69,18 @@ keyWeapon3 db 0
|
||||||
keyWeapon4 db 0
|
keyWeapon4 db 0
|
||||||
keyPause db 0
|
keyPause db 0
|
||||||
keyPauseHeld db 0
|
keyPauseHeld db 0
|
||||||
|
keyHudStyleHeld db 0
|
||||||
|
keyMenuHeld db 0
|
||||||
isGamePaused dd 0
|
isGamePaused dd 0
|
||||||
|
|
||||||
|
; Game Mode & HUD Configuration
|
||||||
|
gameMode dd GAME_MODE_ACTION ; 0 = Adventure (No weapons), 1 = Action / Combat
|
||||||
|
hudStyle dd HUD_STYLE_CLEAN ; 0 = Clean / Immersive, 1 = Debug / Classic
|
||||||
|
enableWeapons dd 1 ; 1 = Weapons active, 0 = Pure exploration
|
||||||
|
showCrosshair dd 1 ; 1 = Show crosshair in Action mode, 0 = Hidden
|
||||||
|
|
||||||
; Player Combat & Gameplay Stats
|
; Player Combat & Gameplay Stats
|
||||||
playerWeapon dd 1 ; Default: WEAPON_PISTOL
|
playerWeapon dd 1 ; Default: WEAPON_PISTOL
|
||||||
playerHealth dd 100
|
playerHealth dd 100
|
||||||
playerMaxHealth dd 100
|
playerMaxHealth dd 100
|
||||||
playerAmmo dd 50
|
playerAmmo dd 50
|
||||||
|
|
@ -129,12 +137,13 @@ strWeaponLabel db "WPN:",0
|
||||||
strWeaponKnife db "KNIFE",0
|
strWeaponKnife db "KNIFE",0
|
||||||
strWeaponPistol db "PISTOL",0
|
strWeaponPistol db "PISTOL",0
|
||||||
strWeaponShotgun db "SHOTGUN",0
|
strWeaponShotgun db "SHOTGUN",0
|
||||||
strPauseTitle db "== PAUSED ==",0
|
strPauseTitle db "== ПАУЗА ==",0
|
||||||
strPauseOpt1 db "[1] RESUME",0
|
strPauseOpt1 db "[1] ПРОДОЛЖИТЬ",0
|
||||||
strPauseOpt2 db "[2] RESTART LEVEL",0
|
strPauseOpt2 db "[2] ОРУЖИЕ: ВКЛ/ВЫКЛ",0
|
||||||
strPauseOpt3 db "[3] MINIMAP RADAR",0
|
strPauseOpt3 db "[3] ИНТЕРФЕЙС: ЧИСТЫЙ/ИНФО",0
|
||||||
strPauseOpt4 db "[4] QUIT TO WINDOWS",0
|
strPauseOpt4 db "[4] ПЕРЕЗАПУСК УРОВНЯ",0
|
||||||
strYouDied db "YOU DIED! PRESS [R] TO RESTART",0
|
strPauseOpt5 db "[5] ВЫХОД В WINDOWS",0
|
||||||
|
strYouDied db "ВЫ ПОГИБЛИ! НАЖМИТЕ [R]",0
|
||||||
cutsceneCount dd 0
|
cutsceneCount dd 0
|
||||||
cutsceneStringCount dd 0
|
cutsceneStringCount dd 0
|
||||||
cutsceneFlags dd 0
|
cutsceneFlags dd 0
|
||||||
|
|
@ -262,3 +271,17 @@ szSwitchOffToast db "ПЕРЕКЛЮЧАТЕЛЬ: ВЫКЛ", 0
|
||||||
szDoorOpenedToast db "ДВЕРЬ ОТКРЫТА", 0
|
szDoorOpenedToast db "ДВЕРЬ ОТКРЫТА", 0
|
||||||
szDoorClosedToast db "ДВЕРЬ ЗАКРЫТА", 0
|
szDoorClosedToast db "ДВЕРЬ ЗАКРЫТА", 0
|
||||||
szBarrelExplodedToast db "ВЗРЫВ БОЧКИ!", 0
|
szBarrelExplodedToast db "ВЗРЫВ БОЧКИ!", 0
|
||||||
|
szWeaponsEnabledToast db "РЕЖИМ: ОРУЖИЕ ВКЛЮЧЕНО", 0
|
||||||
|
szWeaponsDisabledToast db "РЕЖИМ: БЕЗ ОРУЖИЯ (КВЕСТ)", 0
|
||||||
|
szHudCleanToast db "ИНТЕРФЕЙС: ЧИСТЫЙ ВИД", 0
|
||||||
|
szHudDebugToast db "ИНТЕРФЕЙС: РЕЖИМ ОТЛАДКИ", 0
|
||||||
|
szProjectFile db "project.eblanproj", 0
|
||||||
|
szProjGameMode0 db "GameMode=0", 0
|
||||||
|
szProjGameMode1 db "GameMode=1", 0
|
||||||
|
szProjShowWeapons0 db "ShowWeapons=0", 0
|
||||||
|
szFlagNoWeapons db "noweapons", 0
|
||||||
|
szFlagAdventure db "adventure", 0
|
||||||
|
szFlagAction db "action", 0
|
||||||
|
szFlagDebugHud db "debug-hud", 0
|
||||||
|
szFlagCleanHud db "clean-hud", 0
|
||||||
|
previewPrefix db "--preview:", 0
|
||||||
|
|
|
||||||
|
|
@ -71,8 +71,20 @@ VK_KEY_1 equ 31h
|
||||||
VK_KEY_2 equ 32h
|
VK_KEY_2 equ 32h
|
||||||
VK_KEY_3 equ 33h
|
VK_KEY_3 equ 33h
|
||||||
VK_KEY_4 equ 34h
|
VK_KEY_4 equ 34h
|
||||||
|
VK_KEY_5 equ 35h
|
||||||
|
VK_KEY_F1 equ 70h
|
||||||
|
VK_KEY_H equ 48h
|
||||||
|
|
||||||
|
; Game Modes
|
||||||
|
GAME_MODE_ADVENTURE equ 0 ; Exploration / Quest / Horror / Puzzle (No weapons, clean view)
|
||||||
|
GAME_MODE_ACTION equ 1 ; Combat Action (Weapons, Crosshair, Ammo, Health bar)
|
||||||
|
|
||||||
|
; HUD Styles
|
||||||
|
HUD_STYLE_CLEAN equ 0 ; Clean / Immersive (No debug watermark, no bottom bar)
|
||||||
|
HUD_STYLE_DEBUG equ 1 ; Debug Mode (FPS counter, Engine watermark, Minimap)
|
||||||
|
|
||||||
; Weapon Archetypes
|
; Weapon Archetypes
|
||||||
|
WEAPON_NONE equ -1 ; No weapon (Unarmed / Peaceful / Quest)
|
||||||
WEAPON_KNIFE equ 0 ; Melee blade (no ammo, fast, 30 damage)
|
WEAPON_KNIFE equ 0 ; Melee blade (no ammo, fast, 30 damage)
|
||||||
WEAPON_PISTOL equ 1 ; Handgun (1 ammo, accurate, 35 damage)
|
WEAPON_PISTOL equ 1 ; Handgun (1 ammo, accurate, 35 damage)
|
||||||
WEAPON_SHOTGUN equ 2 ; Pump Shotgun (2 ammo, 3-ray spread, 70 damage)
|
WEAPON_SHOTGUN equ 2 ; Pump Shotgun (2 ammo, 3-ray spread, 70 damage)
|
||||||
|
|
|
||||||
|
|
@ -240,3 +240,104 @@ RenderGameHUDOverlays PROC
|
||||||
call Game_OnCustomHUD
|
call Game_OnCustomHUD
|
||||||
ret
|
ret
|
||||||
RenderGameHUDOverlays ENDP
|
RenderGameHUDOverlays ENDP
|
||||||
|
|
||||||
|
; ------------------------------------------------------------------------------
|
||||||
|
; CheckCmdFlag: Case-insensitive substring search (EAX = 1 if found, 0 if not)
|
||||||
|
; ------------------------------------------------------------------------------
|
||||||
|
CheckCmdFlag PROC uses esi edi ecx, pszCmd:DWORD, pszFlag:DWORD
|
||||||
|
mov esi, pszCmd
|
||||||
|
test esi, esi
|
||||||
|
jz flag_not_found
|
||||||
|
check_next_char:
|
||||||
|
cmp byte ptr [esi], 0
|
||||||
|
je flag_not_found
|
||||||
|
mov edi, pszFlag
|
||||||
|
mov ecx, esi
|
||||||
|
compare_loop:
|
||||||
|
mov al, byte ptr [edi]
|
||||||
|
test al, al
|
||||||
|
jz flag_found
|
||||||
|
mov ah, byte ptr [ecx]
|
||||||
|
cmp al, 'A'
|
||||||
|
jl @F
|
||||||
|
cmp al, 'Z'
|
||||||
|
jg @F
|
||||||
|
add al, 32
|
||||||
|
@@:
|
||||||
|
cmp ah, 'A'
|
||||||
|
jl @F
|
||||||
|
cmp ah, 'Z'
|
||||||
|
jg @F
|
||||||
|
add ah, 32
|
||||||
|
@@:
|
||||||
|
cmp al, ah
|
||||||
|
jne mismatch
|
||||||
|
inc edi
|
||||||
|
inc ecx
|
||||||
|
jmp compare_loop
|
||||||
|
mismatch:
|
||||||
|
inc esi
|
||||||
|
jmp check_next_char
|
||||||
|
flag_found:
|
||||||
|
mov eax, 1
|
||||||
|
ret
|
||||||
|
flag_not_found:
|
||||||
|
xor eax, eax
|
||||||
|
ret
|
||||||
|
CheckCmdFlag ENDP
|
||||||
|
|
||||||
|
; ------------------------------------------------------------------------------
|
||||||
|
; LoadProjectSettings: Reads project.eblanproj if present in working directory
|
||||||
|
; ------------------------------------------------------------------------------
|
||||||
|
LoadProjectSettings PROC uses ebx ecx edx esi edi
|
||||||
|
LOCAL hFile:DWORD, bytesRead:DWORD
|
||||||
|
LOCAL projBuf[1024]:BYTE
|
||||||
|
|
||||||
|
invoke CreateFileA, OFFSET szProjectFile, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0
|
||||||
|
cmp eax, INVALID_HANDLE_VALUE
|
||||||
|
je proj_done
|
||||||
|
mov hFile, eax
|
||||||
|
|
||||||
|
lea edx, projBuf
|
||||||
|
invoke ReadFile, hFile, edx, 1023, ADDR bytesRead, 0
|
||||||
|
invoke CloseHandle, hFile
|
||||||
|
|
||||||
|
cmp bytesRead, 0
|
||||||
|
jle proj_done
|
||||||
|
|
||||||
|
mov eax, bytesRead
|
||||||
|
mov byte ptr [projBuf + eax], 0
|
||||||
|
|
||||||
|
lea edx, projBuf
|
||||||
|
invoke CheckCmdFlag, edx, OFFSET szProjGameMode0
|
||||||
|
test eax, eax
|
||||||
|
jnz set_adv_mode
|
||||||
|
|
||||||
|
lea edx, projBuf
|
||||||
|
invoke CheckCmdFlag, edx, OFFSET szProjShowWeapons0
|
||||||
|
test eax, eax
|
||||||
|
jnz set_adv_mode
|
||||||
|
|
||||||
|
lea edx, projBuf
|
||||||
|
invoke CheckCmdFlag, edx, OFFSET szProjGameMode1
|
||||||
|
test eax, eax
|
||||||
|
jnz set_act_mode
|
||||||
|
jmp proj_done
|
||||||
|
|
||||||
|
set_adv_mode:
|
||||||
|
mov gameMode, GAME_MODE_ADVENTURE
|
||||||
|
mov enableWeapons, 0
|
||||||
|
mov playerWeapon, WEAPON_NONE
|
||||||
|
mov showCrosshair, 0
|
||||||
|
jmp proj_done
|
||||||
|
|
||||||
|
set_act_mode:
|
||||||
|
mov gameMode, GAME_MODE_ACTION
|
||||||
|
mov enableWeapons, 1
|
||||||
|
mov playerWeapon, WEAPON_PISTOL
|
||||||
|
mov showCrosshair, 1
|
||||||
|
|
||||||
|
proj_done:
|
||||||
|
ret
|
||||||
|
LoadProjectSettings ENDP
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,34 @@ restart_released:
|
||||||
mov keyRestartHeld, 0
|
mov keyRestartHeld, 0
|
||||||
restart_sampled:
|
restart_sampled:
|
||||||
|
|
||||||
; Weapon Selection Keys: 1, 2, 3
|
; F1 / H: Toggle Clean HUD vs Debug HUD
|
||||||
|
invoke GetAsyncKeyState, VK_KEY_F1
|
||||||
|
mov bx, ax
|
||||||
|
invoke GetAsyncKeyState, VK_KEY_H
|
||||||
|
or bx, ax
|
||||||
|
test bx, 8000h
|
||||||
|
jz hud_key_released
|
||||||
|
cmp keyHudStyleHeld, 0
|
||||||
|
jne hud_key_sampled
|
||||||
|
xor hudStyle, 1
|
||||||
|
mov keyHudStyleHeld, 1
|
||||||
|
cmp hudStyle, HUD_STYLE_CLEAN
|
||||||
|
je toast_hud_clean
|
||||||
|
invoke ShowGameToast, OFFSET szHudDebugToast, 60, COLOR_CYAN
|
||||||
|
jmp hud_key_sampled
|
||||||
|
toast_hud_clean:
|
||||||
|
invoke ShowGameToast, OFFSET szHudCleanToast, 60, COLOR_GREEN
|
||||||
|
jmp hud_key_sampled
|
||||||
|
hud_key_released:
|
||||||
|
mov keyHudStyleHeld, 0
|
||||||
|
hud_key_sampled:
|
||||||
|
|
||||||
|
; Weapon Selection Keys: 1, 2, 3 (only in Action mode with weapons enabled)
|
||||||
|
cmp gameMode, GAME_MODE_ACTION
|
||||||
|
jne skip_weapon_select
|
||||||
|
cmp enableWeapons, 0
|
||||||
|
je skip_weapon_select
|
||||||
|
|
||||||
invoke GetAsyncKeyState, VK_KEY_1
|
invoke GetAsyncKeyState, VK_KEY_1
|
||||||
test ax, 8000h
|
test ax, 8000h
|
||||||
jz @F
|
jz @F
|
||||||
|
|
@ -197,6 +224,7 @@ restart_sampled:
|
||||||
jz @F
|
jz @F
|
||||||
mov playerWeapon, WEAPON_SHOTGUN
|
mov playerWeapon, WEAPON_SHOTGUN
|
||||||
@@:
|
@@:
|
||||||
|
skip_weapon_select:
|
||||||
|
|
||||||
; Escape / Pause Key
|
; Escape / Pause Key
|
||||||
invoke GetAsyncKeyState, VK_KEY_ESCAPE
|
invoke GetAsyncKeyState, VK_KEY_ESCAPE
|
||||||
|
|
@ -224,31 +252,83 @@ pause_key_sampled:
|
||||||
mov keyAttack, 0
|
mov keyAttack, 0
|
||||||
mov keyAction, 0
|
mov keyAction, 0
|
||||||
|
|
||||||
|
; Check if any menu key is pressed
|
||||||
|
invoke GetAsyncKeyState, VK_KEY_1
|
||||||
|
mov bx, ax
|
||||||
|
invoke GetAsyncKeyState, VK_KEY_2
|
||||||
|
or bx, ax
|
||||||
|
invoke GetAsyncKeyState, VK_KEY_3
|
||||||
|
or bx, ax
|
||||||
|
invoke GetAsyncKeyState, VK_KEY_4
|
||||||
|
or bx, ax
|
||||||
|
invoke GetAsyncKeyState, VK_KEY_5
|
||||||
|
or bx, ax
|
||||||
|
test bx, 8000h
|
||||||
|
jz menu_keys_released
|
||||||
|
|
||||||
|
; If a key is pressed, check if already held
|
||||||
|
cmp keyMenuHeld, 0
|
||||||
|
jne pause_menu_done
|
||||||
|
mov keyMenuHeld, 1
|
||||||
|
|
||||||
; Option 1: Resume
|
; Option 1: Resume
|
||||||
invoke GetAsyncKeyState, VK_KEY_1
|
invoke GetAsyncKeyState, VK_KEY_1
|
||||||
test ax, 8000h
|
test ax, 8000h
|
||||||
jz @F
|
jz @F
|
||||||
mov isGamePaused, 0
|
mov isGamePaused, 0
|
||||||
|
jmp pause_menu_done
|
||||||
@@:
|
@@:
|
||||||
; Option 2: Restart level
|
; Option 2: Toggle Weapons / Peaceful Mode
|
||||||
invoke GetAsyncKeyState, VK_KEY_2
|
invoke GetAsyncKeyState, VK_KEY_2
|
||||||
test ax, 8000h
|
test ax, 8000h
|
||||||
jz @F
|
jz @F
|
||||||
|
xor enableWeapons, 1
|
||||||
|
cmp enableWeapons, 0
|
||||||
|
je set_peaceful_mode
|
||||||
|
mov gameMode, GAME_MODE_ACTION
|
||||||
|
mov playerWeapon, WEAPON_PISTOL
|
||||||
|
mov showCrosshair, 1
|
||||||
|
invoke ShowGameToast, OFFSET szWeaponsEnabledToast, 80, COLOR_YELLOW
|
||||||
|
jmp pause_menu_done
|
||||||
|
set_peaceful_mode:
|
||||||
|
mov gameMode, GAME_MODE_ADVENTURE
|
||||||
|
mov playerWeapon, WEAPON_NONE
|
||||||
|
mov showCrosshair, 0
|
||||||
|
invoke ShowGameToast, OFFSET szWeaponsDisabledToast, 80, COLOR_GREEN
|
||||||
|
jmp pause_menu_done
|
||||||
|
@@:
|
||||||
|
; Option 3: Toggle HUD (Clean vs Debug)
|
||||||
|
invoke GetAsyncKeyState, VK_KEY_3
|
||||||
|
test ax, 8000h
|
||||||
|
jz @F
|
||||||
|
xor hudStyle, 1
|
||||||
|
cmp hudStyle, HUD_STYLE_CLEAN
|
||||||
|
je toast_pause_clean
|
||||||
|
invoke ShowGameToast, OFFSET szHudDebugToast, 60, COLOR_CYAN
|
||||||
|
jmp pause_menu_done
|
||||||
|
toast_pause_clean:
|
||||||
|
invoke ShowGameToast, OFFSET szHudCleanToast, 60, COLOR_GREEN
|
||||||
|
jmp pause_menu_done
|
||||||
|
@@:
|
||||||
|
; Option 4: Restart level
|
||||||
|
invoke GetAsyncKeyState, VK_KEY_4
|
||||||
|
test ax, 8000h
|
||||||
|
jz @F
|
||||||
mov isGamePaused, 0
|
mov isGamePaused, 0
|
||||||
mov keyRestart, 1
|
mov keyRestart, 1
|
||||||
|
jmp pause_menu_done
|
||||||
@@:
|
@@:
|
||||||
; Option 3: Toggle Map
|
; Option 5: Quit to Windows
|
||||||
invoke GetAsyncKeyState, VK_KEY_3
|
invoke GetAsyncKeyState, VK_KEY_5
|
||||||
test ax, 8000h
|
test ax, 8000h
|
||||||
jz @F
|
jz pause_menu_done
|
||||||
xor keyShowMap, 1
|
|
||||||
@@:
|
|
||||||
; Option 4: Quit
|
|
||||||
invoke GetAsyncKeyState, VK_KEY_4
|
|
||||||
test ax, 8000h
|
|
||||||
jz @F
|
|
||||||
mov isRunning, 0
|
mov isRunning, 0
|
||||||
@@:
|
jmp pause_menu_done
|
||||||
|
|
||||||
|
menu_keys_released:
|
||||||
|
mov keyMenuHeld, 0
|
||||||
|
|
||||||
|
pause_menu_done:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
not_in_pause_menu:
|
not_in_pause_menu:
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
; Windowless renderer used by EblanStudio. Same Render3DScene and overlays as game.
|
; Windowless renderer used by EblanStudio. Same Render3DScene and overlays as game.
|
||||||
; Fixed wire layout is mirrored by editor/src/preview_protocol.h.
|
; Fixed wire layout is mirrored by editor/src/preview_protocol.h.
|
||||||
.data
|
.data
|
||||||
previewPrefix db "--preview:",0
|
|
||||||
previewHandle dd 0
|
previewHandle dd 0
|
||||||
previewMemory dd 0
|
previewMemory dd 0
|
||||||
previewParent dd 0
|
previewParent dd 0
|
||||||
|
|
|
||||||
85
main.asm
85
main.asm
|
|
@ -220,19 +220,30 @@ Engine_RenderHUD PROC uses ebx ecx edx
|
||||||
call RenderCutsceneOverlay
|
call RenderCutsceneOverlay
|
||||||
ret
|
ret
|
||||||
normal_engine_hud:
|
normal_engine_hud:
|
||||||
|
cmp hudStyle, HUD_STYLE_DEBUG
|
||||||
|
jne clean_hud_mode
|
||||||
|
|
||||||
|
; --- DEBUG / DEVELOPER HUD MODE ---
|
||||||
; 1. Top HUD Header
|
; 1. Top HUD Header
|
||||||
invoke DrawString8x8, 10, 10, OFFSET strEngineName, COLOR_YELLOW
|
invoke DrawString8x8, 8, 8, OFFSET strEngineName, COLOR_YELLOW
|
||||||
|
|
||||||
; 2. FPS Counter
|
; 2. FPS Counter (drawn at top right X=250 so it never overlaps left elements)
|
||||||
invoke DrawString8x8, 10, 24, OFFSET szFpsLabel, COLOR_CYAN
|
invoke DrawString8x8, 250, 8, OFFSET szFpsLabel, COLOR_CYAN
|
||||||
invoke DrawNumber8x8, 42, 24, currentFps, COLOR_CYAN
|
invoke DrawNumber8x8, 282, 8, currentFps, COLOR_CYAN
|
||||||
|
|
||||||
; 3. Controls Bar at Bottom
|
; 3. Controls Bar at Bottom (Debug mode only)
|
||||||
invoke DrawRect, 0, 215, SCREEN_W, 25, 00101010h
|
invoke DrawRect, 0, 215, SCREEN_W, 25, 00101010h
|
||||||
invoke DrawString8x8, 10, 218, OFFSET strControls1, COLOR_WHITE
|
invoke DrawString8x8, 10, 218, OFFSET strControls1, COLOR_WHITE
|
||||||
invoke DrawString8x8, 10, 228, OFFSET strControls3, COLOR_GREEN
|
invoke DrawString8x8, 10, 228, OFFSET strControls3, COLOR_GREEN
|
||||||
|
jmp check_hints
|
||||||
|
|
||||||
; 4. Door / Portal Interaction Hint (center screen)
|
clean_hud_mode:
|
||||||
|
; --- CLEAN / IMMERSIVE HUD MODE ---
|
||||||
|
; In clean mode, no watermarks and no permanent bottom bar.
|
||||||
|
; Full 320x240 view is dedicated to the game world.
|
||||||
|
|
||||||
|
check_hints:
|
||||||
|
; 4. Door / Portal Interaction Hint (Cleanly centered above crosshair)
|
||||||
call CheckDoorHint
|
call CheckDoorHint
|
||||||
cmp eax, 1
|
cmp eax, 1
|
||||||
je show_door_hint
|
je show_door_hint
|
||||||
|
|
@ -241,11 +252,11 @@ normal_engine_hud:
|
||||||
jmp check_minimap
|
jmp check_minimap
|
||||||
|
|
||||||
show_door_hint:
|
show_door_hint:
|
||||||
invoke DrawString8x8, 128, 150, OFFSET strDoorHint, COLOR_YELLOW
|
invoke DrawString8x8, 116, 140, OFFSET strDoorHint, COLOR_YELLOW
|
||||||
jmp check_minimap
|
jmp check_minimap
|
||||||
|
|
||||||
show_portal_hint:
|
show_portal_hint:
|
||||||
invoke DrawString8x8, 110, 150, OFFSET strPortalHint, COLOR_CYAN
|
invoke DrawString8x8, 110, 140, OFFSET strPortalHint, COLOR_CYAN
|
||||||
|
|
||||||
check_minimap:
|
check_minimap:
|
||||||
cmp mapErrorFrames, 0
|
cmp mapErrorFrames, 0
|
||||||
|
|
@ -369,14 +380,14 @@ ParseStartupMap PROC uses ebx ecx edx esi edi
|
||||||
skip_executable_quote:
|
skip_executable_quote:
|
||||||
lodsb
|
lodsb
|
||||||
test al, al
|
test al, al
|
||||||
jz startup_arg_done
|
jz check_cmdline_flags
|
||||||
cmp al, 34
|
cmp al, 34
|
||||||
jne skip_executable_quote
|
jne skip_executable_quote
|
||||||
jmp skip_argument_spaces
|
jmp skip_argument_spaces
|
||||||
skip_executable_word:
|
skip_executable_word:
|
||||||
lodsb
|
lodsb
|
||||||
test al, al
|
test al, al
|
||||||
jz startup_arg_done
|
jz check_cmdline_flags
|
||||||
cmp al, 32
|
cmp al, 32
|
||||||
jne skip_executable_word
|
jne skip_executable_word
|
||||||
skip_argument_spaces:
|
skip_argument_spaces:
|
||||||
|
|
@ -413,10 +424,59 @@ write_startup_char:
|
||||||
dec ecx
|
dec ecx
|
||||||
jnz startup_argument_loop
|
jnz startup_argument_loop
|
||||||
mov startupMapPath, 0
|
mov startupMapPath, 0
|
||||||
ret
|
jmp check_cmdline_flags
|
||||||
terminate_startup_arg:
|
terminate_startup_arg:
|
||||||
mov byte ptr [edi], 0
|
mov byte ptr [edi], 0
|
||||||
startup_arg_done:
|
|
||||||
|
; If startupMapPath starts with '-' and not '--preview:', clear it
|
||||||
|
mov al, byte ptr [startupMapPath]
|
||||||
|
cmp al, '-'
|
||||||
|
jne check_cmdline_flags
|
||||||
|
mov esi, OFFSET startupMapPath
|
||||||
|
mov edi, OFFSET previewPrefix
|
||||||
|
mov ecx, 10
|
||||||
|
repe cmpsb
|
||||||
|
je check_cmdline_flags
|
||||||
|
mov byte ptr [startupMapPath], 0
|
||||||
|
|
||||||
|
check_cmdline_flags:
|
||||||
|
invoke GetCommandLineA
|
||||||
|
mov ebx, eax
|
||||||
|
|
||||||
|
invoke CheckCmdFlag, ebx, OFFSET szFlagNoWeapons
|
||||||
|
test eax, eax
|
||||||
|
jz @F
|
||||||
|
mov gameMode, GAME_MODE_ADVENTURE
|
||||||
|
mov enableWeapons, 0
|
||||||
|
mov playerWeapon, WEAPON_NONE
|
||||||
|
mov showCrosshair, 0
|
||||||
|
@@:
|
||||||
|
invoke CheckCmdFlag, ebx, OFFSET szFlagAdventure
|
||||||
|
test eax, eax
|
||||||
|
jz @F
|
||||||
|
mov gameMode, GAME_MODE_ADVENTURE
|
||||||
|
mov enableWeapons, 0
|
||||||
|
mov playerWeapon, WEAPON_NONE
|
||||||
|
mov showCrosshair, 0
|
||||||
|
@@:
|
||||||
|
invoke CheckCmdFlag, ebx, OFFSET szFlagAction
|
||||||
|
test eax, eax
|
||||||
|
jz @F
|
||||||
|
mov gameMode, GAME_MODE_ACTION
|
||||||
|
mov enableWeapons, 1
|
||||||
|
mov playerWeapon, WEAPON_PISTOL
|
||||||
|
mov showCrosshair, 1
|
||||||
|
@@:
|
||||||
|
invoke CheckCmdFlag, ebx, OFFSET szFlagDebugHud
|
||||||
|
test eax, eax
|
||||||
|
jz @F
|
||||||
|
mov hudStyle, HUD_STYLE_DEBUG
|
||||||
|
@@:
|
||||||
|
invoke CheckCmdFlag, ebx, OFFSET szFlagCleanHud
|
||||||
|
test eax, eax
|
||||||
|
jz @F
|
||||||
|
mov hudStyle, HUD_STYLE_CLEAN
|
||||||
|
@@:
|
||||||
ret
|
ret
|
||||||
ParseStartupMap ENDP
|
ParseStartupMap ENDP
|
||||||
|
|
||||||
|
|
@ -427,6 +487,7 @@ main PROC
|
||||||
LOCAL msg:MSG
|
LOCAL msg:MSG
|
||||||
LOCAL curTick:DWORD, elapsed:DWORD
|
LOCAL curTick:DWORD, elapsed:DWORD
|
||||||
|
|
||||||
|
call LoadProjectSettings
|
||||||
call ParseStartupMap
|
call ParseStartupMap
|
||||||
call TryEnginePreview
|
call TryEnginePreview
|
||||||
call Engine_Init
|
call Engine_Init
|
||||||
|
|
|
||||||
BIN
main.obj
BIN
main.obj
Binary file not shown.
Loading…
Add table
Reference in a new issue