Fixing logger and windows version - remove terminal

This commit is contained in:
Vladislav Khorev 2026-07-14 20:39:41 +03:00
parent 76287dda46
commit a7d17d9afd
27 changed files with 349 additions and 243 deletions

View File

@ -13,7 +13,7 @@ include(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/ThirdParty.cmake)
# ===========================================
# Основной проект ShadowOverBishkekDemo
# ===========================================
add_executable(ShadowOverBishkekDemo
add_executable(ShadowOverBishkekDemo WIN32
../src/main.cpp
../src/Game.cpp
../src/Game.h
@ -124,7 +124,7 @@ set_target_properties(ShadowOverBishkekDemo PROPERTIES
target_compile_definitions(ShadowOverBishkekDemo PRIVATE
WIN32_LEAN_AND_MEAN
PNG_ENABLED
SDL_MAIN_HANDLED
# SDL_MAIN_HANDLED
# DEBUG_LIGHT
# SHOW_PATH
)
@ -221,7 +221,7 @@ if (WIN32)
add_custom_command(TARGET ShadowOverBishkekDemo POST_BUILD
COMMAND ${CMAKE_COMMAND} -E echo "Copying DLLs to output folder..."
# Копируем SDL2 (целевое имя всегда SDL2.dll)
# Копируем SDL2
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${SDL2_DLL_SRC}"
"${SDL2_DLL_DST}"

View File

@ -1,5 +1,6 @@
#include "AudioPlayerAsync.h"
#include <iostream>
#include "utils/Utils.h"
#ifdef __EMSCRIPTEN__
AudioPlayerAsync::AudioPlayerAsync() {}
@ -36,7 +37,7 @@ bool AudioPlayerAsync::init() {
Mix_AllocateChannels(16);
initialized = true;
std::cout << "AudioPlayerAsync initialized with SDL2_mixer" << std::endl;
ZL::logger() << "AudioPlayerAsync initialized with SDL2_mixer" << std::endl;
return true;
}
@ -60,7 +61,7 @@ void AudioPlayerAsync::shutdown() {
Mix_CloseAudio();
SDL_QuitSubSystem(SDL_INIT_AUDIO);
initialized = false;
std::cout << "AudioPlayerAsync shutdown" << std::endl;
ZL::logger() << "AudioPlayerAsync shutdown" << std::endl;
}
void AudioPlayerAsync::playSoundAsync(const std::string& filePath, int loops, int channel) {

View File

@ -37,7 +37,7 @@ namespace ZL
}
}
std::cout << "Bone name not found: " << name << std::endl;
logger() << "Bone name not found: " << name << std::endl;
throw std::runtime_error("Bone name not found: " + name);
return -1;
@ -435,7 +435,7 @@ namespace ZL
meshNamesOrdered.push_back(meshName);
}
std::cout << "Loaded " << numberMeshes << " meshes from " << fileName << std::endl;
logger() << "Loaded " << numberMeshes << " meshes from " << fileName << std::endl;
// ---- Animation Keyframes ----
std::getline(f, tempLine); // === Animation Keyframes ===
@ -509,7 +509,7 @@ namespace ZL
if (startBones.size() > MAX_GPU_BONES)
{
std::cout << "Warning: model has " << startBones.size()
logger() << "Warning: model has " << startBones.size()
<< " bones, exceeding GPU skinning limit of " << MAX_GPU_BONES << std::endl;
}
}
@ -706,7 +706,7 @@ namespace ZL
if (startBones.size() > MAX_GPU_BONES)
{
std::cout << "Warning: model has " << startBones.size()
logger() << "Warning: model has " << startBones.size()
<< " bones, exceeding GPU skinning limit of " << MAX_GPU_BONES << std::endl;
}
}
@ -736,7 +736,7 @@ namespace ZL
if (startingKeyFrame == -1)
{
std::cout << "Exception here: frame number is out of range of keyframes. Frame: " << frame << std::endl;
logger() << "Exception here: frame number is out of range of keyframes. Frame: " << frame << std::endl;
throw std::runtime_error("Exception here");
}
@ -794,7 +794,7 @@ namespace ZL
{
if (md.verticesBoneWeight[i][j].boneIndex == -1)
{
std::cout << "Exception here: bone index is -1 but weight is > 0" << std::endl;
logger() << "Exception here: bone index is -1 but weight is > 0" << std::endl;
throw std::runtime_error("Bones loaded incorrectly - bone index is -1 but weight is > 0");
}
vMoved = true;

View File

@ -613,7 +613,7 @@ bool Character::prepareGpuSkinning() {
void Character::tryAttackCombo()
{
std::cout << "Try Attack Combo" << std::endl;
logger() << "Try Attack Combo" << std::endl;
auto it = animations.find(state.currentState);
if (it == animations.end()) return;
@ -622,7 +622,7 @@ void Character::tryAttackCombo()
if (static_cast<int>(anim.currentFrame) >= 20 &&
(state.currentState == AnimationState::ACTION_ATTACK ||
state.currentState == AnimationState::ACTION_ATTACK_2)) {
std::cout << "Try Attack Combo Success" << std::endl;
logger() << "Try Attack Combo Success" << std::endl;
anim.currentFrame = anim.model.startingFrame;
}
}
@ -1234,7 +1234,7 @@ void Character::setupHitSparks(std::shared_ptr<Texture> sparkTexture) {
}
void Character::applyDamage(float damageAmount, const Eigen::Vector3f& attackDirection, int attackerIndex) {
std::cout << "Character::applyDamage" << std::endl;
logger() << "Character::applyDamage" << std::endl;
state.hp -= damageAmount;
if (state.hp < 0) state.hp = 0;

View File

@ -116,7 +116,7 @@ public:
std::string weaponAttachBoneName = "RightHand";
SparkEmitter hitSparkEmitter;
AudioPlayerAsync* audioPlayer;
AudioPlayerAsync* audioPlayer = nullptr;
static Dialogue::TranslationDatabase nameTranslations;

View File

@ -22,6 +22,7 @@ int Environment::width = CONST_DEFAULT_WIDTH;
int Environment::height = CONST_DEFAULT_HEIGHT;
float Environment::zoom = DEFAULT_ZOOM;
bool Environment::enableLogging = false;
SDL_Window* Environment::window = nullptr;

View File

@ -31,6 +31,8 @@ public:
static int height;
static float zoom;
static bool enableLogging;
static Eigen::Matrix3f inverseShipMatrix;
static SDL_Window* window;

View File

@ -43,7 +43,7 @@ namespace ZL
Game* Game::s_instance = nullptr;
void Game::onResourcesZipLoaded(unsigned /*handle*/, void* /*userData*/, const char* /*filename*/) {
std::cout << "Resources.zip loaded successfully--0" << std::endl;
logger() << "Resources.zip loaded successfully--0" << std::endl;
if (s_instance) {
s_instance->resourcesDownloadProgress = 1.0f;
// Builds the loadSteps queue (cheap, no GL work); the actual loading
@ -54,7 +54,7 @@ namespace ZL
}
void Game::onResourcesZipError(unsigned /*handle*/, void* /*userData*/, int /*httpStatus*/) {
std::cout << "Failed to download resources.zip" << std::endl;
logger() << "Failed to download resources.zip" << std::endl;
}
void Game::onResourcesZipProgress(unsigned /*handle*/, void* /*userData*/, int percentComplete) {
@ -134,7 +134,7 @@ namespace ZL
// Asynchronously download resources.zip; setupPart2() is called on completion.
// The loading screen stays visible until the download finishes.
s_instance = this;
std::cout << "Load resurces step 1-" << std::endl;
logger() << "Load resurces step 1-" << std::endl;
emscripten_async_wget2("resources.zip", "resources.zip", "GET", nullptr, nullptr,
onResourcesZipLoaded, onResourcesZipError, onResourcesZipProgress);
#else
@ -316,7 +316,7 @@ namespace ZL
loadSteps.push([this]() {
try {
menuManager.setup(gameState.inventory, CONST_ZIP_FILE);
std::cout << "UI loaded successfully" << std::endl;
logger() << "UI loaded successfully" << std::endl;
}
catch (const std::exception& e) {
std::cerr << "Failed to load UI: " << e.what() << std::endl;
@ -366,10 +366,10 @@ namespace ZL
if (audioPlayer->init()) {
audioPlayer->setMusicVolume(100);
audioPlayer->setSoundVolume(80);
std::cout << "Audio initialized successfully" << std::endl;
logger() << "Audio initialized successfully" << std::endl;
}
else {
std::cout << "Audio initialization failed" << std::endl;
logger() << "Audio initialization failed" << std::endl;
}
});
@ -480,12 +480,12 @@ namespace ZL
nlohmann::json root;
gameState.save(root);
const std::string path = "start_state.json";
std::cout << "[reset] saveInitialState called, to " << path << std::endl;
logger() << "[reset] saveInitialState called, to " << path << std::endl;
std::ofstream file(path);
if (file.is_open()) {
file << root.dump(2);
std::cout << "[reset] Saved initial state snapshot to " << path << std::endl;
logger() << "[reset] Saved initial state snapshot to " << path << std::endl;
} else {
std::cerr << "[reset] Could not open " << path << " for writing" << std::endl;
}
@ -796,7 +796,7 @@ namespace ZL
// Teleport callbacks: destination name and position come from the teleport zone data.
auto teleportCallback = [this](const std::string& destName, const Eigen::Vector3f& destPos, float destRotY) {
std::cout << "[TELEPORT] " << " -> " << destName << std::endl;
logger() << "[TELEPORT] " << " -> " << destName << std::endl;
auto it = gameState.locations.find(destName);
if (it == gameState.locations.end()) {
std::cerr << "[TELEPORT] Unknown destination location: " << destName << std::endl;
@ -903,12 +903,12 @@ namespace ZL
void Game::createShadowMapAndProparateToLocations()
{
if (shadowMap) {
std::cout << "Shadow map already exists, skipping creation" << std::endl;
logger() << "Shadow map already exists, skipping creation" << std::endl;
return;
}
shadowMap = std::make_shared<ShadowMap>(2048, 40.0f, 0.1f, 100.0f);
shadowMap->setLightDirection(Eigen::Vector3f(-0.5f, -1.0f, -0.3f));
std::cout << "Shadow map initialized" << std::endl;
logger() << "Shadow map initialized" << std::endl;
for (auto& [name, loc] : gameState.locations) {
loc->shadowMap = shadowMap;
@ -1210,7 +1210,7 @@ namespace ZL
menuManager.onOrientationChanged();
}
std::cout << "Window resized (Render Size): " << Environment::width << "x" << Environment::height << std::endl;
logger() << "Window resized (Render Size): " << Environment::width << "x" << Environment::height << std::endl;
//space.clearTextRendererCache();
}
@ -1300,7 +1300,7 @@ namespace ZL
if (Environment::zoom > zoomMax) {
Environment::zoom = zoomMax;
}
std::cout << "Current zoom: " << Environment::zoom << std::endl;
logger() << "Current zoom: " << Environment::zoom << std::endl;
// Tutorial step3 → step4: any mouse-wheel scroll counts as "zoom gesture".
if (gameState.tutorialStep == TutorialStep::Step3) {
menuManager.advanceTutorialStep();
@ -1345,7 +1345,7 @@ namespace ZL
currentLocation()->editor.selectInteractiveObject(event.key.keysym.sym - SDLK_0);
} else {
currentLocation()->switchNavigation(event.key.keysym.sym - SDLK_0);
std::cout << "Switched to nav mesh " << (event.key.keysym.sym - SDLK_0) << std::endl;
logger() << "Switched to nav mesh " << (event.key.keysym.sym - SDLK_0) << std::endl;
}
break;
case SDLK_f:
@ -1376,50 +1376,50 @@ namespace ZL
const char* modeName = (editorMode == EditorMode::Navigation) ? "Navigation"
: (editorMode == EditorMode::InteractiveObjects) ? "InteractiveObjects"
: "None";
std::cout << "[EDITOR] Mode: " << modeName << std::endl;
logger() << "[EDITOR] Mode: " << modeName << std::endl;
}
break;
case SDLK_o:
x = x + 0.05;
std::cout << "current x: " << x << std::endl;
logger() << "current x: " << x << std::endl;
//y = y + 0.002;
//currentLocation->player->hp = 200;
//currentLocation->npcs[0]->walkSpeed += 0.01f;
//std::cout << "Walk speed: " << currentLocation->npcs[0]->walkSpeed << std::endl;
//logger() << "Walk speed: " << currentLocation->npcs[0]->walkSpeed << std::endl;
break;
case SDLK_k:
x = x - 0.05;
std::cout << "current x: " << x << std::endl;
std::cout << "Player pos: " << currentLocation()->player->state.position.transpose() << std::endl;
std::cout << "Player rotation: " << currentLocation()->player->state.facingAngle*180.0/M_PI << std::endl;
logger() << "current x: " << x << std::endl;
logger() << "Player pos: " << currentLocation()->player->state.position.transpose() << std::endl;
logger() << "Player rotation: " << currentLocation()->player->state.facingAngle*180.0/M_PI << std::endl;
//currentLocation->npcs[0]->walkSpeed -= 0.01f;
//std::cout << "Walk speed: " << currentLocation->npcs[0]->walkSpeed << std::endl;
//logger() << "Walk speed: " << currentLocation->npcs[0]->walkSpeed << std::endl;
break;
case SDLK_p:
gameState.currentLocationName = "uni_interior";
currentLocation()->player->state.position = Eigen::Vector3f(-0.0189243, 0, -13.4314);
currentLocation()->player->setTarget(currentLocation()->player->state.position);
//std::cout << "Switched to location " << ((currentLocation == locations["location1"]) ? "1" : "2") << std::endl;
//logger() << "Switched to location " << ((currentLocation == locations["location1"]) ? "1" : "2") << std::endl;
break;
case SDLK_l:
//x = x - 1;
//std::cout << "current x: " << x << std::endl;
std::cout << "Azimuth: " << currentLocation()->state.cameraAzimuth << std::endl;
std::cout << "Inclination: " << currentLocation()->state.cameraInclination << std::endl;
//logger() << "current x: " << x << std::endl;
logger() << "Azimuth: " << currentLocation()->state.cameraAzimuth << std::endl;
logger() << "Inclination: " << currentLocation()->state.cameraInclination << std::endl;
break;
case SDLK_c:
std::cout << "SLOW-MO activated!" << std::endl;
logger() << "SLOW-MO activated!" << std::endl;
activateSlowMoEffect();
break;
case SDLK_i:
y = y - 1;
std::cout << "current y: " << y << std::endl;
logger() << "current y: " << y << std::endl;
break;
case SDLK_b:
@ -1467,7 +1467,7 @@ namespace ZL
if (event.type == SDL_KEYUP) {
if (event.key.keysym.sym == SDLK_r) {
std::cout << "Camera position: x=" << x << " y=" << y << " z=" << z << std::endl;
logger() << "Camera position: x=" << x << " y=" << y << " z=" << z << std::endl;
}
}

View File

@ -67,7 +67,7 @@ void loadLanguageSetting() {
// Если файла настроек нет (content пустой), определяем язык системы и выходим
if (content.empty()) {
g_currentLanguage = detectSystemLanguage();
std::cout << "[settings] No settings.json found. System language detected: "
logger() << "[settings] No settings.json found. System language detected: "
<< languageToCode(g_currentLanguage) << std::endl;
return;
}

View File

@ -148,7 +148,7 @@ namespace ZL
player->setTarget(params.playerPosition);
player->setupHitSparks(sparkTexture);
player->audioPlayer = audioPlayer;
std::cout << "Load resurces step 9" << std::endl;
logger() << "Load resurces step 9" << std::endl;
SDL_PumpEvents();
// Load NPCs from JSON. Aggressive (canAttack) NPCs need a player target
@ -287,7 +287,7 @@ namespace ZL
teleportZones.push_back(std::move(tz));
}
std::cout << "[TELEPORT] Loaded " << teleportZones.size() << " teleport(s) from " << jsonPath << std::endl;
logger() << "[TELEPORT] Loaded " << teleportZones.size() << " teleport(s) from " << jsonPath << std::endl;
}
@ -338,7 +338,7 @@ namespace ZL
}
std::cout << "[TRIGGER] Loaded " << triggerZones.size() << " trigger zone(s) from " << jsonPath << std::endl;
logger() << "[TRIGGER] Loaded " << triggerZones.size() << " trigger zone(s) from " << jsonPath << std::endl;
}
void Location::loadPointLights(const std::string& jsonPath, const char* zipFile)
@ -400,7 +400,7 @@ namespace ZL
pointLights.push_back(std::move(pl));
}
std::cout << "[LIGHTS] Loaded " << pointLights.size() << " light(s) from " << jsonPath << std::endl;
logger() << "[LIGHTS] Loaded " << pointLights.size() << " light(s) from " << jsonPath << std::endl;
}
void Location::updateTriggerZones(const Eigen::Vector3f& playerPos)
@ -500,28 +500,28 @@ namespace ZL
if (editorMode == EditorMode::Navigation) {
editor.buildNavMeshes();
}
std::cout << "[NAV] Switched to navigation map " << index << "\n";
logger() << "[NAV] Switched to navigation map " << index << "\n";
return true;
}
InteractiveObject* Location::raycastInteractiveObjects(const Eigen::Vector3f& rayOrigin, const Eigen::Vector3f& rayDir) {
if (interactiveObjects.empty()) {
//std::cout << "[RAYCAST] No interactive objects to check" << std::endl;
//logger() << "[RAYCAST] No interactive objects to check" << std::endl;
return nullptr;
}
//std::cout << "[RAYCAST] Starting raycast with " << interactiveObjects.size() << " objects" << std::endl;
//std::cout << "[RAYCAST] Ray origin: (" << rayOrigin.x() << ", " << rayOrigin.y() << ", " << rayOrigin.z() << ")" << std::endl;
//std::cout << "[RAYCAST] Ray dir: (" << rayDir.x() << ", " << rayDir.y() << ", " << rayDir.z() << ")" << std::endl;
//logger() << "[RAYCAST] Starting raycast with " << interactiveObjects.size() << " objects" << std::endl;
//logger() << "[RAYCAST] Ray origin: (" << rayOrigin.x() << ", " << rayOrigin.y() << ", " << rayOrigin.z() << ")" << std::endl;
//logger() << "[RAYCAST] Ray dir: (" << rayDir.x() << ", " << rayDir.y() << ", " << rayDir.z() << ")" << std::endl;
float closestDistance = FLT_MAX;
InteractiveObject* closestObject = nullptr;
for (auto& intObj : interactiveObjects) {
//std::cout << "[RAYCAST] Checking object: " << intObj.loadedObject.name << " (active: " << intObj.isActive << ")" << std::endl;
//logger() << "[RAYCAST] Checking object: " << intObj.loadedObject.name << " (active: " << intObj.isActive << ")" << std::endl;
if (!intObj.state.isActive || intObj.state.isAnimating) {
//std::cout << "[RAYCAST] -> Object inactive or animating, skipping" << std::endl;
//logger() << "[RAYCAST] -> Object inactive or animating, skipping" << std::endl;
continue;
}
@ -531,7 +531,7 @@ namespace ZL
if (!intObj.loadedObject.texture) continue;
}
//std::cout << "[RAYCAST] Position: (" << intObj.position.x() << ", " << intObj.position.y() << ", "
//logger() << "[RAYCAST] Position: (" << intObj.position.x() << ", " << intObj.position.y() << ", "
// << intObj.position.z() << "), Radius: " << intObj.interactionRadius << std::endl;
const bool hasBox = !(intObj.state.boundsMin.isZero() && intObj.state.boundsMax.isZero());
@ -581,10 +581,10 @@ namespace ZL
}
/*
if (closestObject) {
std::cout << "[RAYCAST] *** RAYCAST SUCCESS: Found object " << closestObject->loadedObject.name << " ***" << std::endl;
logger() << "[RAYCAST] *** RAYCAST SUCCESS: Found object " << closestObject->loadedObject.name << " ***" << std::endl;
}
else {
std::cout << "[RAYCAST] No objects hit" << std::endl;
logger() << "[RAYCAST] No objects hit" << std::endl;
}
*/
return closestObject;
@ -600,11 +600,11 @@ namespace ZL
Character* closestNpc = nullptr;
float closestDist = maxDistance;
//std::cout << "[RAYCAST_NPC] Starting raycast with " << npcs.size() << " npcs" << std::endl;
//logger() << "[RAYCAST_NPC] Starting raycast with " << npcs.size() << " npcs" << std::endl;
for (auto& npc : npcs) {
if (npc->getHp() <= 0.f) {
//std::cout << "[RAYCAST_NPC] " << npc->state.npcId << " is dead, skipping" << std::endl;
//logger() << "[RAYCAST_NPC] " << npc->state.npcId << " is dead, skipping" << std::endl;
continue;
}
if (!npc->state.enabled) continue;
@ -640,7 +640,7 @@ namespace ZL
if (entryT > exitT) continue;
//std::cout << "[RAYCAST_NPC] " << npc->npcId << " hit at t=" << entryT << std::endl;
//logger() << "[RAYCAST_NPC] " << npc->npcId << " hit at t=" << entryT << std::endl;
if (entryT < closestDist) {
closestDist = entryT;
@ -649,10 +649,10 @@ namespace ZL
}
if (closestNpc) {
//std::cout << "[RAYCAST_NPC] HIT: " << closestNpc->npcId << std::endl;
//logger() << "[RAYCAST_NPC] HIT: " << closestNpc->npcId << std::endl;
}
else {
//std::cout << "[RAYCAST_NPC] No NPC hit" << std::endl;
//logger() << "[RAYCAST_NPC] No NPC hit" << std::endl;
}
return closestNpc;
@ -1603,7 +1603,7 @@ namespace ZL
if (npc->state.enabled && npc->state.canAttack && (!npc->state.pathWaypoints.empty() || npc->state.battle_state != 0) && npc->getHp() > 0.f)
{
//std::cout << "[NPC] NPC '" << npc->state.npcId << "' is attacking target index " << npc->state.attackTargetIndex << std::endl;
//logger() << "[NPC] NPC '" << npc->state.npcId << "' is attacking target index " << npc->state.attackTargetIndex << std::endl;
npcAttacking = true;
}
}
@ -1640,17 +1640,17 @@ namespace ZL
// If player is close enough to pick up the item
if (distToObject <= obj->state.approachRadius) {
std::cout << "[PICKUP] Player reached object! Distance: " << distToObject << std::endl;
std::cout << "[PICKUP] Calling Lua callback for: " << obj->loadedObject.name << std::endl;
logger() << "[PICKUP] Player reached object! Distance: " << distToObject << std::endl;
logger() << "[PICKUP] Calling Lua callback for: " << obj->loadedObject.name << std::endl;
// Call custom activate function if specified, otherwise use fallback
try {
if (!obj->state.activateFunctionName.empty()) {
std::cout << "[PICKUP] Using custom function: " << obj->state.activateFunctionName << std::endl;
logger() << "[PICKUP] Using custom function: " << obj->state.activateFunctionName << std::endl;
scriptEngine.callActivateFunction(obj->state.activateFunctionName);
}
else {
std::cout << "[PICKUP] Using fallback callback" << std::endl;
logger() << "[PICKUP] Using fallback callback" << std::endl;
scriptEngine.callItemPickupCallback(obj->loadedObject.name);
}
}
@ -1666,7 +1666,7 @@ namespace ZL
if (state.targetInteractNpcIndex >= 0 && player) {
float distToNpc = (player->state.position - npcs[state.targetInteractNpcIndex]->state.position).norm();
if (distToNpc <= NPC_TALK_DISTANCE) {
std::cout << "[NPC] Player reached NPC index " << state.targetInteractNpcIndex
logger() << "[NPC] Player reached NPC index " << state.targetInteractNpcIndex
<< " (distance " << distToNpc << "); firing on_npc_interact" << std::endl;
// Stop the player at the talk distance and have the NPC turn to face them.
player->setTarget(player->state.position);
@ -1686,7 +1686,7 @@ namespace ZL
if (auto* tz = getTargetTeleportZone(); tz && player) {
float dist = (player->state.position - tz->position).norm();
if (dist <= tz->radius) {
std::cout << "[TELEPORT] Player reached teleport zone '" << tz->id << "'" << std::endl;
logger() << "[TELEPORT] Player reached teleport zone '" << tz->id << "'" << std::endl;
if (onTeleport) onTeleport(tz->destinationLocation, tz->destinationPosition, tz->destinationRotationY);
state.targetTeleportZoneIndex = -1;
return;
@ -1710,7 +1710,7 @@ namespace ZL
const bool isInside = (dist <= autoR);
if (isInside && !tz.automaticPlayerInside) {
tz.automaticPlayerInside = true;
std::cout << "[TELEPORT] Auto-teleport triggered by zone '" << tz.id << "'" << std::endl;
logger() << "[TELEPORT] Auto-teleport triggered by zone '" << tz.id << "'" << std::endl;
if (onTeleport) onTeleport(tz.destinationLocation, tz.destinationPosition, tz.destinationRotationY);
return;
} else if (!isInside) {
@ -1743,10 +1743,10 @@ namespace ZL
toTarget.y() = 0.f;
if (toTarget.norm() < car.waypointReachRadius) {
car.currentWaypoint = car.currentWaypoint + 1;
std::cout << "Waypoint current: " << car.currentWaypoint << std::endl;
logger() << "Waypoint current: " << car.currentWaypoint << std::endl;
if (car.currentWaypoint == car.waypoints.size())
{
std::cout << "waypointsOver" << std::endl;
logger() << "waypointsOver" << std::endl;
waypointsOver = true;
}
}
@ -1895,17 +1895,17 @@ namespace ZL
return;
}
std::cout << "[CLICK] Camera position: (" << camPos.x() << ", " << camPos.y() << ", " << camPos.z() << ")" << std::endl;
std::cout << "[CLICK] Ray direction: (" << rayDir.x() << ", " << rayDir.y() << ", " << rayDir.z() << ")" << std::endl;
//logger() << "[CLICK] Camera position: (" << camPos.x() << ", " << camPos.y() << ", " << camPos.z() << ")" << std::endl;
//logger() << "[CLICK] Ray direction: (" << rayDir.x() << ", " << rayDir.y() << ", " << rayDir.z() << ")" << std::endl;
// First check if we clicked on interactive object
InteractiveObject* clickedObject = raycastInteractiveObjects(camPos, rayDir);
if (clickedObject && player && clickedObject->state.isActive) {
std::cout << "[CLICK] *** SUCCESS: Clicked on interactive object: " << clickedObject->loadedObject.name << " ***" << std::endl;
std::cout << "[CLICK] Object position: (" << clickedObject->state.position.x() << ", "
<< clickedObject->state.position.y() << ", " << clickedObject->state.position.z() << ")" << std::endl;
std::cout << "[CLICK] Player position: (" << player->state.position.x() << ", "
<< player->state.position.y() << ", " << player->state.position.z() << ")" << std::endl;
//logger() << "[CLICK] *** SUCCESS: Clicked on interactive object: " << clickedObject->loadedObject.name << " ***" << std::endl;
//logger() << "[CLICK] Object position: (" << clickedObject->state.position.x() << ", "
// << clickedObject->state.position.y() << ", " << clickedObject->state.position.z() << ")" << std::endl;
//logger() << "[CLICK] Player position: (" << player->state.position.x() << ", "
// << player->state.position.y() << ", " << player->state.position.z() << ")" << std::endl;
state.targetInteractiveObjectIndex = findInteractiveObjectIndex(clickedObject);
state.targetInteractNpcIndex = -1;
@ -1914,11 +1914,11 @@ namespace ZL
? clickedObject->state.interactionPosition
: clickedObject->state.position);
player->state.attackTargetIndex = CharacterState::kNoTarget;
std::cout << "[CLICK] Player moving to object..." << std::endl;
//logger() << "[CLICK] Player moving to object..." << std::endl;
}
else {
//std::cout << "Raycast npc step 1" << std::endl;
//logger() << "Raycast npc step 1" << std::endl;
// Check if we clicked on an NPC
Character* clickedNpc = raycastNpcs(camPos, rayDir);
if (clickedNpc && player) {
@ -1931,25 +1931,25 @@ namespace ZL
}
}
if (npcIndex != -1) {
//std::cout << "Raycast npc step 2" << std::endl;
//logger() << "Raycast npc step 2" << std::endl;
state.targetInteractiveObjectIndex = -1;
state.targetTeleportZoneIndex = -1;
if (clickedNpc->state.canAttack) {
//std::cout << "Raycast npc step 3" << std::endl;
//std::cout << "player->state.attackTargetIndex=" << player->state.attackTargetIndex << std::endl;
//std::cout << "npcIndex=" << npcIndex << std::endl;
//logger() << "Raycast npc step 3" << std::endl;
//logger() << "player->state.attackTargetIndex=" << player->state.attackTargetIndex << std::endl;
//logger() << "npcIndex=" << npcIndex << std::endl;
// Hostile NPC: combat logic walks the player in via attackTargetIndex.
if (lastPlayerAttackTarget == npcIndex)
{
//std::cout << "Raycast npc step 4" << std::endl;
//logger() << "Raycast npc step 4" << std::endl;
player->tryAttackCombo();
}
player->state.attackTargetIndex = npcIndex;
state.targetInteractNpcIndex = -1;
if (distance <= clickedNpc->state.interactionRadius) {
std::cout << "[CLICK] Hostile NPC " << npcIndex << " in range; firing on_npc_interact" << std::endl;
//logger() << "[CLICK] Hostile NPC " << npcIndex << " in range; firing on_npc_interact" << std::endl;
scriptEngine.callNpcInteractCallback(npcIndex);
}
}
@ -1959,15 +1959,15 @@ namespace ZL
if (distance <= NPC_TALK_DISTANCE) {
// Already in talk range — fire immediately, stop, and face the player.
std::cout << "[CLICK] *** SUCCESS: Clicked on NPC index: " << npcIndex << " (in range) ***" << std::endl;
//logger() << "[CLICK] *** SUCCESS: Clicked on NPC index: " << npcIndex << " (in range) ***" << std::endl;
player->setTarget(player->state.position);
npcs[npcIndex]->state.faceTargetIndex = CharacterState::kPlayerIndex;
scriptEngine.callNpcInteractCallback(npcIndex);
state.targetInteractNpcIndex = -1;
}
else {
std::cout << "[CLICK] NPC " << npcIndex << " out of talk range (distance " << distance
<< " > " << NPC_TALK_DISTANCE << "); walking to NPC..." << std::endl;
//logger() << "[CLICK] NPC " << npcIndex << " out of talk range (distance " << distance
// << " > " << NPC_TALK_DISTANCE << "); walking to NPC..." << std::endl;
player->setTarget(clickedNpc->state.position);
state.targetInteractNpcIndex = npcIndex;
}
@ -1979,7 +1979,7 @@ namespace ZL
// Unproject click to ground plane for walk target / teleport detection
float t = -camPos.y() / rayDir.y();
Eigen::Vector3f hit = camPos + rayDir * t;
std::cout << "[CLICK] Clicked on ground at: (" << hit.x() << ", " << hit.z() << ")" << std::endl;
//logger() << "[CLICK] Clicked on ground at: (" << hit.x() << ", " << hit.z() << ")" << std::endl;
TeleportZone* clickedTeleport = nullptr;
for (auto& tz : teleportZones) {
@ -1989,7 +1989,7 @@ namespace ZL
}
if (clickedTeleport) {
std::cout << "[CLICK] Clicked teleport zone '" << clickedTeleport->id << "'" << std::endl;
//logger() << "[CLICK] Clicked teleport zone '" << clickedTeleport->id << "'" << std::endl;
state.targetTeleportZoneIndex = findTeleportZoneIndex(clickedTeleport);
state.targetInteractiveObjectIndex = -1;
state.targetInteractNpcIndex = -1;
@ -2004,10 +2004,10 @@ namespace ZL
}
}
else {
std::cout << "[CLICK] No valid target found" << std::endl;
//logger() << "[CLICK] No valid target found" << std::endl;
}
}
std::cout << "========================================\n" << std::endl;
//logger() << "========================================\n" << std::endl;
}
void Location::handleUp(int64_t fingerId, int mx, int my)
{

View File

@ -91,15 +91,15 @@ namespace ZL
if (dx * dx + dz * dz <= removeRadius * removeRadius) {
navigationEditorPoints.erase(it);
rebuildPointsMesh();
std::cout << "[NAV_EDITOR] Removed point, " << navigationEditorPoints.size() << " remaining\n";
logger() << "[NAV_EDITOR] Removed point, " << navigationEditorPoints.size() << " remaining\n";
return;
}
}
std::cout << "[NAV_EDITOR] No point found within " << removeRadius << " units of click\n";
logger() << "[NAV_EDITOR] No point found within " << removeRadius << " units of click\n";
} else {
navigationEditorPoints.push_back(hit);
rebuildPointsMesh();
std::cout << "[NAV_EDITOR] Added point (" << hit.x() << ", " << hit.z()
logger() << "[NAV_EDITOR] Added point (" << hit.x() << ", " << hit.z()
<< "), total: " << navigationEditorPoints.size() << "\n";
}
}
@ -107,7 +107,7 @@ namespace ZL
void LocationEditor::handleRightClick()
{
if (navigationEditorPoints.size() < 3) {
std::cout << "[NAV_EDITOR] Need at least 3 points to form a polygon (have "
logger() << "[NAV_EDITOR] Need at least 3 points to form a polygon (have "
<< navigationEditorPoints.size() << "); clearing\n";
navigationEditorPoints.clear();
rebuildPointsMesh();
@ -121,7 +121,7 @@ namespace ZL
}
if (loc.navigation) loc.navigation->addObstaclePolygon(poly);
std::cout << "[NAV_EDITOR] Added obstacle '" << poly.name << "' with "
logger() << "[NAV_EDITOR] Added obstacle '" << poly.name << "' with "
<< poly.polygon.size() << " vertices\n";
{
@ -150,12 +150,12 @@ namespace ZL
if (!loc.navigation) return;
if (loc.navigation->saveConfig(baseName + ".json"))
std::cout << "[NAV_EDITOR] Saved config to: " << baseName << ".json\n";
logger() << "[NAV_EDITOR] Saved config to: " << baseName << ".json\n";
else
std::cerr << "[NAV_EDITOR] Failed to save config to: " << baseName << ".json\n";
if (loc.navigation->saveGrid(baseName + ".txt"))
std::cout << "[NAV_EDITOR] Saved grid to: " << baseName << ".txt\n";
logger() << "[NAV_EDITOR] Saved grid to: " << baseName << ".txt\n";
else
std::cerr << "[NAV_EDITOR] Failed to save grid to: " << baseName << ".txt\n";
}
@ -163,7 +163,7 @@ namespace ZL
void LocationEditor::reload()
{
loc.setupNavigation(loc.navigationMapPaths);
std::cout << "[NAV_EDITOR] Reloaded navigation maps (" << loc.navigationMapPaths.size() << " maps)\n";
logger() << "[NAV_EDITOR] Reloaded navigation maps (" << loc.navigationMapPaths.size() << " maps)\n";
}
static VertexDataStruct CreateBoundsBoxMesh(const Eigen::Vector3f corners[8], const Eigen::Vector3f& color)
@ -290,14 +290,14 @@ namespace ZL
void LocationEditor::selectInteractiveObject(int index)
{
if (index < 0 || index >= static_cast<int>(loc.interactiveObjects.size())) {
std::cout << "[IO_EDITOR] Index " << index << " out of range ("
logger() << "[IO_EDITOR] Index " << index << " out of range ("
<< loc.interactiveObjects.size() << " objects)\n";
return;
}
selectedInteractiveObjectIndex = index;
boundsClickCount = 0;
buildInteractiveObjectBoundsMeshes();
std::cout << "[IO_EDITOR] Selected object " << index
logger() << "[IO_EDITOR] Selected object " << index
<< " (" << loc.interactiveObjects[index].loadedObject.name << ")\n";
}
@ -305,7 +305,7 @@ namespace ZL
{
if (selectedInteractiveObjectIndex < 0 ||
selectedInteractiveObjectIndex >= static_cast<int>(loc.interactiveObjects.size())) {
std::cout << "[IO_EDITOR] No valid object selected\n";
logger() << "[IO_EDITOR] No valid object selected\n";
return;
}
@ -316,7 +316,7 @@ namespace ZL
target.state.hasInteractionPosition = true;
boundsClickCount = 0; // cancel any in-progress bounds placement
buildInteractiveObjectBoundsMeshes();
std::cout << "[IO_EDITOR] Interaction position set on object " << selectedInteractiveObjectIndex
logger() << "[IO_EDITOR] Interaction position set on object " << selectedInteractiveObjectIndex
<< " (" << target.loadedObject.name << ")"
<< " at (" << worldHit.x() << ", " << worldHit.z() << ")\n";
return;
@ -343,7 +343,7 @@ namespace ZL
if (boundsClickCount == 0) {
boundsClickA = worldHit;
boundsClickCount = 1;
std::cout << "[IO_EDITOR] First corner placed at world ("
logger() << "[IO_EDITOR] First corner placed at world ("
<< worldHit.x() << ", " << worldHit.z() << ") — click again for second corner\n";
} else {
const Eigen::Vector3f localA = worldToLocal(boundsClickA);
@ -358,7 +358,7 @@ namespace ZL
boundsClickCount = 0;
buildInteractiveObjectBoundsMeshes();
std::cout << "[IO_EDITOR] Bounds set on object " << selectedInteractiveObjectIndex
logger() << "[IO_EDITOR] Bounds set on object " << selectedInteractiveObjectIndex
<< " (" << target.loadedObject.name << ")"
<< " min=(" << target.state.boundsMin.x() << ", " << target.state.boundsMin.z() << ")"
<< " max=(" << target.state.boundsMax.x() << ", " << target.state.boundsMax.z() << ")\n";
@ -419,7 +419,7 @@ namespace ZL
std::ofstream out(filename);
if (out.is_open()) {
out << j.dump(4);
std::cout << "[IO_EDITOR] Saved " << loc.interactiveObjects.size()
logger() << "[IO_EDITOR] Saved " << loc.interactiveObjects.size()
<< " interactive object(s) to " << filename << "\n";
} else {
std::cerr << "[IO_EDITOR] Failed to open " << filename << " for writing\n";
@ -485,7 +485,7 @@ namespace ZL
loc.gameObjects[data2.name] = std::move(obj2);
editorPlacedObjects.push_back(data2);
std::cout << "[GAME_EDITOR] Placed '" << data.name << "' at ("
logger() << "[GAME_EDITOR] Placed '" << data.name << "' at ("
<< data.positionX << ", " << data.positionZ
<< ") scale=" << data.scale << " rotY=" << data.rotationY << "\n";
}
@ -493,7 +493,7 @@ namespace ZL
void LocationEditor::saveObjects()
{
if (editorPlacedObjects.empty()) {
std::cout << "[GAME_EDITOR] No editor-placed objects to save\n";
logger() << "[GAME_EDITOR] No editor-placed objects to save\n";
return;
}
@ -527,7 +527,7 @@ namespace ZL
/*std::ofstream out(filename);
if (out.is_open()) {
out << j.dump(4);
std::cout << "[GAME_EDITOR] Saved " << editorPlacedObjects.size()
logger() << "[GAME_EDITOR] Saved " << editorPlacedObjects.size()
<< " object(s) to " << filename << "\n";
} else {
std::cerr << "[GAME_EDITOR] Failed to open " << filename << " for writing\n";

View File

@ -756,7 +756,7 @@ namespace ZL {
}
void MenuManager::selectInventoryItem(int index) {
std::cout << "MenuManager::selectInventoryItem: " << index << std::endl;
logger() << "MenuManager::selectInventoryItem: " << index << std::endl;
const auto& items = inventory->getItems();
if (index < 0 || index >= static_cast<int>(items.size())) return;
@ -862,7 +862,7 @@ namespace ZL {
}
void MenuManager::toggleQuestJournal() {
std::cout << "[quest] toggleQuestJournal: " << (isQuestJournalOpen() ? "closing" : "opening") << std::endl;
logger() << "[quest] toggleQuestJournal: " << (isQuestJournalOpen() ? "closing" : "opening") << std::endl;
if (uiState_ == GameUiState::QuestJournal) {
closeQuestJournal();
}
@ -1274,7 +1274,7 @@ namespace ZL {
void MenuManager::tutorialShowTaxiHint()
{
std::cout << "tutorialShowTaxiHint" << std::endl;
logger() << "tutorialShowTaxiHint" << std::endl;
gameState_.tutorialNeedOpenTaxiScreen = true;
if (uiState_ == GameUiState::Gameplay)
{
@ -1889,7 +1889,7 @@ namespace ZL {
void MenuManager::setDarklandsMode(bool enabled)
{
std::cout << "MenuManager::setDarklandsMode called" << std::endl;
logger() << "MenuManager::setDarklandsMode called" << std::endl;
if (gameState_.currentLocationName == "uni_interior") {
if (enabled && gameState_.uniIntTutorialState == UniIntTutorialState::Step11) {
@ -1979,11 +1979,11 @@ namespace ZL {
}
void MenuManager::applyCurrentHealthBar() {
std::cout << "MenuManager::applyCurrentHealthBar called step 1" << std::endl;
std::cout << "currentPlayerMaxHp_ is " << gameState_.playerMaxHp << std::endl;
logger() << "MenuManager::applyCurrentHealthBar called step 1" << std::endl;
logger() << "currentPlayerMaxHp_ is " << gameState_.playerMaxHp << std::endl;
if (gameState_.playerMaxHp <= 0.f) return;
std::cout << "MenuManager::applyCurrentHealthBar called step 2" << std::endl;
std::cout << "currentPlayerHp_ is " << gameState_.playerHp << std::endl;
logger() << "MenuManager::applyCurrentHealthBar called step 2" << std::endl;
logger() << "currentPlayerHp_ is " << gameState_.playerHp << std::endl;
const float fraction = std::clamp(gameState_.playerHp / gameState_.playerMaxHp, 0.f, 1.f);

View File

@ -124,14 +124,14 @@ namespace ZL {
}
const float rad = angle * static_cast<float>(M_PI) / 180.f;
std::cout << "[script] npc_rotate_to: index " << index << " angle " << angle << " degrees (" << rad << " radians)" << std::endl;
logger() << "[script] npc_rotate_to: index " << index << " angle " << angle << " degrees (" << rad << " radians)" << std::endl;
npcs[index]->state.targetFacingAngle = rad;
});
api.set_function("player_rotate_to",
[loc](float angle) {
const float rad = angle * static_cast<float>(M_PI) / 180.f;
std::cout << "[script] player_rotate_to: angle " << angle << " degrees (" << rad << " radians)" << std::endl;
logger() << "[script] player_rotate_to: angle " << angle << " degrees (" << rad << " radians)" << std::endl;
loc->player->state.targetFacingAngle = rad;
});
@ -172,12 +172,12 @@ namespace ZL {
const Item* item = ItemRegistry::instance().findById(itemId);
if (item) {
if (inventory->hasItem(itemId)) {
std::cout << "[script] has_item: " << item->name << " returns true" << std::endl;
logger() << "[script] has_item: " << item->name << " returns true" << std::endl;
return true;
}
else
{
std::cout << "[script] has_item: " << item->name << " returns false" << std::endl;
logger() << "[script] has_item: " << item->name << " returns false" << std::endl;
return false;
}
}
@ -192,7 +192,7 @@ namespace ZL {
const Item* item = ItemRegistry::instance().findById(itemId);
if (item) {
inventory->addItem(item->id);
std::cout << "[script] pickup_item: " << item->name << std::endl;
logger() << "[script] pickup_item: " << item->name << std::endl;
} else {
std::cerr << "[script] pickup_item: item '" << itemId << "' not found in ItemRegistry\n";
}
@ -200,7 +200,7 @@ namespace ZL {
// remove_item(item_id)
api.set_function("remove_item", [loc, inventory](const std::string& id) {
std::cout << "[script] remove_item: " << id << std::endl;
logger() << "[script] remove_item: " << id << std::endl;
inventory->removeItem(id);
});
@ -209,7 +209,7 @@ namespace ZL {
for (auto& intObj : loc->interactiveObjects) {
if (intObj.loadedObject.name == objectName) {
intObj.state.isActive = false;
std::cout << "[script] deactivate_interactive_object: " << objectName << std::endl;
logger() << "[script] deactivate_interactive_object: " << objectName << std::endl;
return;
}
}
@ -221,7 +221,7 @@ namespace ZL {
for (auto& intObj : loc->interactiveObjects) {
if (intObj.loadedObject.name == objectName) {
intObj.state.isActive = true;
std::cout << "[script] activate_interactive_object: " << objectName << std::endl;
logger() << "[script] activate_interactive_object: " << objectName << std::endl;
return;
}
}
@ -232,7 +232,7 @@ namespace ZL {
for (auto& intObj : loc->interactiveObjects) {
if (intObj.loadedObject.name == objectName) {
intObj.state.rotationY = value * static_cast<float>(M_PI) / 180.f;
std::cout << "[script] set_object_rotation: " << objectName << " " << value << std::endl;
logger() << "[script] set_object_rotation: " << objectName << " " << value << std::endl;
return;
}
}
@ -243,7 +243,7 @@ namespace ZL {
for (auto& intObj : loc->interactiveObjects) {
if (intObj.loadedObject.name == objectName) {
intObj.state.alpha = value;
std::cout << "[script] set_object_alpha: " <<objectName << " " << value << std::endl;
logger() << "[script] set_object_alpha: " <<objectName << " " << value << std::endl;
return;
}
}
@ -336,13 +336,13 @@ namespace ZL {
api.set_function("set_night",
[loc]() {
loc->requestNightDayTransition(true, false);
std::cout << "Set night called" << std::endl;
logger() << "Set night called" << std::endl;
});
api.set_function("set_dawn",
[loc]() {
loc->requestNightDayTransition(true, true);
std::cout << "Set dawn called" << std::endl;
logger() << "Set dawn called" << std::endl;
});
@ -857,7 +857,7 @@ namespace ZL {
std::cerr << "[SCRIPT] on_npc_interact error: " << err.what() << "\n";
}
else {
std::cout << "[SCRIPT] on_npc_interact called with index " << npcIndex << std::endl;
logger() << "[SCRIPT] on_npc_interact called with index " << npcIndex << std::endl;
}
}
else {
@ -883,7 +883,7 @@ namespace ZL {
}
sol::state& lua = impl->lua;
std::cout << "[SCRIPT] Looking for activate function: " << functionName << std::endl;
logger() << "[SCRIPT] Looking for activate function: " << functionName << std::endl;
sol::function activateFunc = lua[functionName];
@ -891,7 +891,7 @@ namespace ZL {
throw std::runtime_error("[SCRIPT] Lua function not found: " + functionName);
}
std::cout << "[SCRIPT] Found function! Calling: " << functionName << std::endl;
logger() << "[SCRIPT] Found function! Calling: " << functionName << std::endl;
auto result = activateFunc();
if (!result.valid()) {
@ -899,7 +899,7 @@ namespace ZL {
throw std::runtime_error("[SCRIPT] Error executing " + functionName + ": " + std::string(err.what()));
}
std::cout << "[SCRIPT] Function executed successfully!" << std::endl;
logger() << "[SCRIPT] Function executed successfully!" << std::endl;
}
void ScriptEngine::callItemPickupCallback(const std::string& objectName) {
@ -914,18 +914,18 @@ namespace ZL {
sol::function activateFunc = lua["on_item_pickup"];
if (activateFunc.valid()) {
std::cout << "[SCRIPT] Callback found! Calling with argument: " << objectName << std::endl;
logger() << "[SCRIPT] Callback found! Calling with argument: " << objectName << std::endl;
auto result = activateFunc(objectName);
if (!result.valid()) {
sol::error err = result;
std::cerr << "[SCRIPT] on_item_pickup callback error: " << err.what() << "\n";
}
else {
std::cout << "[SCRIPT] Callback executed successfully!" << std::endl;
logger() << "[SCRIPT] Callback executed successfully!" << std::endl;
}
}
else {
std::cout << "[SCRIPT] Fallback: on_item_pickup not found" << std::endl;
logger() << "[SCRIPT] Fallback: on_item_pickup not found" << std::endl;
}
}

View File

@ -474,7 +474,7 @@ namespace ZL {
}
bool SparkEmitter::loadFromJsonFile(const std::string& path, Renderer& renderer, const std::string& zipFile) {
std::cout << "Loading spark config from: " << path << std::endl;
logger() << "Loading spark config from: " << path << std::endl;
std::string content;
try {
@ -498,13 +498,13 @@ namespace ZL {
json j;
try {
j = json::parse(content);
std::cout << "JSON parsed successfully" << std::endl;
logger() << "JSON parsed successfully" << std::endl;
}
catch (const std::exception& e) {
std::cerr << "JSON parse error: " << e.what() << std::endl;
throw std::runtime_error("Failed to load spark emitter config file 9!");
}
std::cout << "JSON content: " << j.dump(2) << std::endl;
logger() << "JSON content: " << j.dump(2) << std::endl;
auto requireKey = [&](const std::string& key) {
if (!j.contains(key)) {
@ -531,13 +531,13 @@ namespace ZL {
particles.resize(maxParticles);
drawPositions.reserve(maxParticles * 6);
drawTexCoords.reserve(maxParticles * 6);
std::cout << "Max particles: " << maxParticles << std::endl;
logger() << "Max particles: " << maxParticles << std::endl;
particleSize = j["particleSize"].get<float>();
std::cout << "Particle size: " << particleSize << std::endl;
logger() << "Particle size: " << particleSize << std::endl;
biasX = j["biasX"].get<float>();
std::cout << "Bias X: " << biasX << std::endl;
logger() << "Bias X: " << biasX << std::endl;
// emissionPoints
std::vector<Vector3f> points;
@ -546,7 +546,7 @@ namespace ZL {
if (el.contains("position") && el["position"].is_array()) {
auto arr = el["position"];
points.push_back(Vector3f{ arr[0].get<float>(), arr[1].get<float>(), arr[2].get<float>() });
std::cout << "Fixed point: [" << arr[0] << ", " << arr[1] << ", " << arr[2] << "]" << std::endl;
logger() << "Fixed point: [" << arr[0] << ", " << arr[1] << ", " << arr[2] << "]" << std::endl;
}
else if (el.contains("positionRange") && el["positionRange"].is_object()) {
auto pr = el["positionRange"];
@ -564,18 +564,18 @@ namespace ZL {
for (int k = 0; k < count; ++k) {
Vector3f randomPoint{ dx(gen), dy(gen), dz(gen) };
points.push_back(randomPoint);
std::cout << "Random point " << k + 1 << ": [" << randomPoint(0)
logger() << "Random point " << k + 1 << ": [" << randomPoint(0)
<< ", " << randomPoint(1) << ", " << randomPoint(2) << "]" << std::endl;
}
}
}
if (!points.empty()) {
setEmissionPoints(points);
std::cout << "Total emission points: " << emissionPoints.size() << std::endl;
logger() << "Total emission points: " << emissionPoints.size() << std::endl;
}
else {
setEmissionPoints({});
std::cout << "Emission points parsed but empty" << std::endl;
logger() << "Emission points parsed but empty" << std::endl;
//throw std::runtime_error("Failed to load spark emitter config file 10!");
}
}
@ -589,7 +589,7 @@ namespace ZL {
auto a = j["speedRange"];
speedRange.min = a[0].get<float>();
speedRange.max = a[1].get<float>();
std::cout << "Speed range: [" << speedRange.min << ", " << speedRange.max << "]" << std::endl;
logger() << "Speed range: [" << speedRange.min << ", " << speedRange.max << "]" << std::endl;
}
else {
std::cerr << "speedRange missing or invalid" << std::endl;
@ -600,7 +600,7 @@ namespace ZL {
auto a = j["zSpeedRange"];
zSpeedRange.min = a[0].get<float>();
zSpeedRange.max = a[1].get<float>();
std::cout << "Z speed range: [" << zSpeedRange.min << ", " << zSpeedRange.max << "]" << std::endl;
logger() << "Z speed range: [" << zSpeedRange.min << ", " << zSpeedRange.max << "]" << std::endl;
}
else {
std::cerr << "zSpeedRange missing or invalid" << std::endl;
@ -611,7 +611,7 @@ namespace ZL {
auto a = j["scaleRange"];
scaleRange.min = a[0].get<float>();
scaleRange.max = a[1].get<float>();
std::cout << "Scale range: [" << scaleRange.min << ", " << scaleRange.max << "]" << std::endl;
logger() << "Scale range: [" << scaleRange.min << ", " << scaleRange.max << "]" << std::endl;
}
else {
std::cerr << "scaleRange missing or invalid" << std::endl;
@ -622,7 +622,7 @@ namespace ZL {
auto a = j["lifeTimeRange"];
lifeTimeRange.min = a[0].get<float>();
lifeTimeRange.max = a[1].get<float>();
std::cout << "Life time range: [" << lifeTimeRange.min << ", " << lifeTimeRange.max << "]" << std::endl;
logger() << "Life time range: [" << lifeTimeRange.min << ", " << lifeTimeRange.max << "]" << std::endl;
}
else {
std::cerr << "lifeTimeRange missing or invalid" << std::endl;
@ -632,17 +632,17 @@ namespace ZL {
// texture
if (j.contains("texture") && j["texture"].is_string()) {
std::string texPath = j["texture"].get<std::string>();
std::cout << "Loading texture: " << texPath << " From zip file: " << zipFile << std::endl;
logger() << "Loading texture: " << texPath << " From zip file: " << zipFile << std::endl;
try {
std::cout << "Loading texture step 1" << std::endl;
logger() << "Loading texture step 1" << std::endl;
auto texData = CreateTextureDataFromPng(texPath.c_str(), zipFile.c_str());
std::cout << "Loading texture step 2" << std::endl;
logger() << "Loading texture step 2" << std::endl;
texture = std::make_shared<Texture>(texData);
std::cout << "Texture loaded successfully, ID: " << texture->getTexID() << std::endl;
logger() << "Texture loaded successfully, ID: " << texture->getTexID() << std::endl;
}
catch (const std::exception& e) {
std::cout << "Texture load error: " << e.what() << std::endl;
logger() << "Texture load error: " << e.what() << std::endl;
std::cerr << "Texture load error: " << e.what() << std::endl;
throw std::runtime_error("Failed to load spark emitter config file 16!");
}
@ -652,11 +652,11 @@ namespace ZL {
throw std::runtime_error("Failed to load spark emitter config file 17!");
}
std::cout << "Working with shaders 1" << std::endl;
logger() << "Working with shaders 1" << std::endl;
// shaders
if (j.contains("shaderProgramName") && j["shaderProgramName"].is_string()) {
shaderProgramName = j["shaderProgramName"].get<std::string>();
std::cout << "Shader program name: " << shaderProgramName << std::endl;
logger() << "Shader program name: " << shaderProgramName << std::endl;
}
else {
std::cerr << "shaderProgramName missing or invalid" << std::endl;
@ -665,7 +665,7 @@ namespace ZL {
drawDataDirty = true;
configured = true;
std::cout << "SparkEmitter configuration loaded successfully!" << std::endl;
logger() << "SparkEmitter configuration loaded successfully!" << std::endl;
return true;
}

View File

@ -81,7 +81,7 @@ namespace ZL
numberVertices = std::stoi(match.str());
}
else {
std::cout << "Vertices header not found or invalid: " << tempLine << std::endl;
logger() << "Vertices header not found or invalid: " << tempLine << std::endl;
throw std::runtime_error("Vertices header not found or invalid.");
}
@ -116,7 +116,7 @@ namespace ZL
// UV - [7], [8]
if (floatValues.size() < 9) {
std::cout << "Malformed vertex line at index " << i << ": " << tempLine << std::endl;
logger() << "Malformed vertex line at index " << i << ": " << tempLine << std::endl;
throw std::runtime_error("Malformed vertex line at index " + std::to_string(i));
}
@ -137,7 +137,7 @@ namespace ZL
numberTriangles = std::stoi(match.str());
}
else {
std::cout << "Triangles header not found or invalid: " << tempLine << std::endl;
logger() << "Triangles header not found or invalid: " << tempLine << std::endl;
throw std::runtime_error("Triangles header not found.");
}
@ -162,7 +162,7 @@ namespace ZL
}
if (indices.size() != 3) {
std::cout << "Malformed triangle line at index " << i << ": " << tempLine << std::endl;
logger() << "Malformed triangle line at index " << i << ": " << tempLine << std::endl;
throw std::runtime_error("Malformed triangle line at index " + std::to_string(i));
}
@ -193,7 +193,7 @@ namespace ZL
result.NormalData[i](2) = originalNorm(0);
}
std::cout << "Model loaded: " << numberVertices << " verts, " << numberTriangles << " tris." << std::endl;
logger() << "Model loaded: " << numberVertices << " verts, " << numberTriangles << " tris." << std::endl;
s_meshCache[key] = result;
return result;
@ -266,7 +266,7 @@ namespace ZL
}
}
std::cout << "Binary model loaded: " << numVertices << " verts, " << numTriangles << " tris." << std::endl;
logger() << "Binary model loaded: " << numVertices << " verts, " << numTriangles << " tris." << std::endl;
s_meshCache[key] = result;
return result;

View File

@ -537,7 +537,7 @@ namespace ZL {
if (!t.contains(key) || !t[key].is_string()) return nullptr;
std::string path = t[key].get<std::string>();
try {
std::cout << "UiManager: loading texture for button '" << btn->name << "' : " << path << " Zip file: " << zipFile << std::endl;
logger() << "UiManager: loading texture for button '" << btn->name << "' : " << path << " Zip file: " << zipFile << std::endl;
return renderer.textureManager.LoadFromPng(path, zipFile, true);
}
catch (const std::exception& e) {
@ -571,7 +571,7 @@ namespace ZL {
if (!t.contains(key) || !t[key].is_string()) return nullptr;
std::string path = t[key].get<std::string>();
try {
std::cout << "UiManager: --loading texture for slider '" << s->name << "' : " << path << " Zip file: " << zipFile << std::endl;
logger() << "UiManager: --loading texture for slider '" << s->name << "' : " << path << " Zip file: " << zipFile << std::endl;
return renderer.textureManager.LoadFromPng(path, zipFile, true);
}
catch (const std::exception& e) {

View File

@ -3,6 +3,7 @@
#include <algorithm>
#include <cmath>
#include <iostream>
#include "utils/Utils.h"
namespace ZL::Cutscene {
@ -68,7 +69,7 @@ bool CutsceneRuntime::start(const std::string& cutsceneId) {
onLineStarted(firstLine.luaCallback);
}
std::cout << "[CUTSCENE] start id=" << cutsceneId
logger() << "[CUTSCENE] start id=" << cutsceneId
<< " lines=" << def->lines.size()
<< " totalDuration=" << cutsceneTotalDurationMs
<< std::endl;
@ -176,7 +177,7 @@ void CutsceneRuntime::skip() {
}
void CutsceneRuntime::finish() {
std::cout << "[CUTSCENE] finish id=" << activeCutsceneId << std::endl;
logger() << "[CUTSCENE] finish id=" << activeCutsceneId << std::endl;
const std::string finishedId = activeCutsceneId;
stop();
if (onFinished && !finishedId.empty()) {

View File

@ -73,7 +73,7 @@ namespace ZL {
objects.push_back(std::move(data));
}
std::cout << "Loaded " << objects.size() << " static objects from " << jsonPath << std::endl;
logger() << "Loaded " << objects.size() << " static objects from " << jsonPath << std::endl;
return objects;
}
@ -115,7 +115,7 @@ namespace ZL {
objects.push_back(std::move(data));
}
std::cout << "Loaded " << objects.size() << " interactive objects from " << jsonPath << std::endl;
logger() << "Loaded " << objects.size() << " interactive objects from " << jsonPath << std::endl;
return objects;
}
@ -199,7 +199,7 @@ namespace ZL {
// Service the OS message queue between loads so the window doesn't
// get flagged as "not responding" during long location loads.
SDL_PumpEvents();
std::cout << "Loading game object: " << data.name << std::endl;
logger() << "Loading game object: " << data.name << std::endl;
try {
LoadedGameObject obj = buildLoadedObject(data, renderer, zipPath);
@ -208,13 +208,13 @@ namespace ZL {
obj.mesh.RefreshVBO();
gameObjects[data.name] = std::move(obj);
std::cout << "Successfully loaded: " << data.name << std::endl;
logger() << "Successfully loaded: " << data.name << std::endl;
} catch (const std::exception& e) {
std::cerr << "GameObjectLoader: Failed to load '" << data.name << "': " << e.what() << std::endl;
}
}
std::cout << "Total game objects loaded: " << gameObjects.size() << std::endl;
logger() << "Total game objects loaded: " << gameObjects.size() << std::endl;
return gameObjects;
}
@ -230,17 +230,17 @@ namespace ZL {
for (const auto& data : loadInteractiveFromJson(jsonPath, zipPath)) {
SDL_PumpEvents();
std::cout << "Loading interactive object: " << data.base.name << std::endl;
logger() << "Loading interactive object: " << data.base.name << std::endl;
try {
InteractiveObject intObj = InteractiveObject::createFromState(
data.toInteractiveObjectState(), renderer, zipPath);
intObj.loadedObject.name = data.base.name;
if (!data.activateFunctionName.empty())
std::cout << "Successfully loaded interactive: " << data.base.name
logger() << "Successfully loaded interactive: " << data.base.name
<< " (function: " << data.activateFunctionName << ")" << std::endl;
else
std::cout << "Successfully loaded interactive: " << data.base.name << std::endl;
logger() << "Successfully loaded interactive: " << data.base.name << std::endl;
interactiveObjects.push_back(std::move(intObj));
} catch (const std::exception& e) {
@ -248,7 +248,7 @@ namespace ZL {
}
}
std::cout << "Total interactive objects loaded: " << interactiveObjects.size() << std::endl;
logger() << "Total interactive objects loaded: " << interactiveObjects.size() << std::endl;
return interactiveObjects;
}
@ -301,7 +301,7 @@ namespace ZL {
npcs.push_back(std::move(data));
}
std::cout << "Successfully loaded " << npcs.size() << " NPCs from " << jsonPath << std::endl;
logger() << "Successfully loaded " << npcs.size() << " NPCs from " << jsonPath << std::endl;
} catch (const std::exception& e) {
std::cerr << "Error loading NPCs from JSON: " << e.what() << std::endl;
}
@ -369,11 +369,11 @@ namespace ZL {
for (const auto& npcData : loadNpcsFromJson(jsonPath, zipPath)) {
SDL_PumpEvents();
std::cout << "Loading NPC: " << npcData.name << std::endl;
logger() << "Loading NPC: " << npcData.name << std::endl;
try {
auto npc = Character::createFromState(npcData.toCharacterState(), renderer, zipPath.c_str());
if (npc) {
std::cout << "Successfully loaded NPC: " << npcData.name << " at ("
logger() << "Successfully loaded NPC: " << npcData.name << " at ("
<< npcData.positionX << ", " << npcData.positionY << ", " << npcData.positionZ << ")" << std::endl;
npc->index = index;
npcs.push_back(std::move(npc));
@ -384,7 +384,7 @@ namespace ZL {
}
}
std::cout << "Total NPCs loaded: " << npcs.size() << std::endl;
logger() << "Total NPCs loaded: " << npcs.size() << std::endl;
return npcs;
}

View File

@ -3,19 +3,20 @@
#include "external/nlohmann/json.hpp"
#include <algorithm>
#include <iostream>
#include "../utils/Utils.h"
namespace ZL {
void Inventory::addItem(const std::string& itemId) {
itemIds.push_back(itemId);
std::cout << "Item added to inventory: " << itemId << std::endl;
logger() << "Item added to inventory: " << itemId << std::endl;
if (onItemAdded) onItemAdded(itemId);
}
void Inventory::removeItem(const std::string& itemId) {
auto it = std::find(itemIds.begin(), itemIds.end(), itemId);
if (it != itemIds.end()) {
std::cout << "Item removed from inventory: " << itemId << std::endl;
logger() << "Item removed from inventory: " << itemId << std::endl;
if (onItemRemoved) onItemRemoved(itemId);
itemIds.erase(it);
}

View File

@ -48,7 +48,7 @@ void ItemRegistry::loadFromJson(const std::string& jsonPath, const std::string&
items_[id] = std::move(item);
}
std::cout << "[ItemRegistry] Loaded " << items_.size() << " items from " << jsonPath << "\n";
logger() << "[ItemRegistry] Loaded " << items_.size() << " items from " << jsonPath << "\n";
}
const Item* ItemRegistry::findById(const std::string& id) const {

View File

@ -67,7 +67,7 @@ static void applyResize(int logicalW, int logicalH) {
e.window.data2 = physicalH;
SDL_PushEvent(&e);
std::cout << "Resized, new size: " << logicalW << "x" << logicalH
logger() << "Resized, new size: " << logicalW << "x" << logicalH
<< " (physical: " << physicalW << "x" << physicalH
<< ", DPR: " << dpr << ")" << std::endl;
}
@ -226,11 +226,46 @@ extern "C" int SDL_main(int argc, char* argv[]) {
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__linux__)
// Read the persisted fullscreen preference (if any) before creating the
// window, so it opens directly in the right mode instead of flashing
// windowed -> fullscreen once settings are loaded later during setupPart2().
void readSettings()
{
const std::string settingsContent = ZL::readSavedTextFile("settings.json");
if (!settingsContent.empty()) {
try {
const nlohmann::json settingsRoot = nlohmann::json::parse(settingsContent);
if (settingsRoot.contains("fullscreen")) {
ZL::Environment::isFullscreen = settingsRoot["fullscreen"].get<bool>();
}
if (settingsRoot.contains("isHighDPIEnabled")) {
ZL::Environment::isHighDPIEnabled = settingsRoot["isHighDPIEnabled"].get<bool>();
}
if (settingsRoot.contains("enableLogging")) {
ZL::Environment::enableLogging = settingsRoot["enableLogging"].get<bool>();
}
}
catch (const std::exception& e) {
std::cerr << "[settings] Failed to parse settings.json: " << e.what() << std::endl;
}
}
}
int main(int argc, char* argv[]) {
SDL_GLContext ctx = nullptr;
try
{
readSettings();
ZL::initLogger();
ZL::logger() << "Log started!" << std::endl;
#ifdef STEAMSDK
// Передаем явный App ID демо-версии
if (SteamAPI_RestartAppIfNecessary(4945840)) {
@ -259,31 +294,6 @@ int main(int argc, char* argv[]) {
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
// Read the persisted fullscreen preference (if any) before creating the
// window, so it opens directly in the right mode instead of flashing
// windowed -> fullscreen once settings are loaded later during setupPart2().
{
const std::string settingsContent = ZL::readSavedTextFile("settings.json");
if (!settingsContent.empty()) {
try {
const nlohmann::json settingsRoot = nlohmann::json::parse(settingsContent);
if (settingsRoot.contains("fullscreen")) {
ZL::Environment::isFullscreen = settingsRoot["fullscreen"].get<bool>();
}
if (settingsRoot.contains("isHighDPIEnabled")) {
ZL::Environment::isHighDPIEnabled = settingsRoot["isHighDPIEnabled"].get<bool>();
}
}
catch (const std::exception& e) {
std::cerr << "[settings] Failed to parse settings.json: " << e.what() << std::endl;
}
}
}
Uint32 windowFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_RESIZABLE;
if (ZL::Environment::isFullscreen) {
windowFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
@ -291,7 +301,7 @@ int main(int argc, char* argv[]) {
SDL_DisplayMode dm;
if (SDL_GetCurrentDisplayMode(0, &dm) == 0) {
std::cout << "Desktop resolution: " << dm.w << "x" << dm.h << " @ " << dm.refresh_rate << "Hz\n";
ZL::logger() << "Desktop resolution: " << dm.w << "x" << dm.h << " @ " << dm.refresh_rate << "Hz\n";
}
else {
SDL_Log("SDL_GetCurrentDisplayMode failed: %s", SDL_GetError());
@ -320,14 +330,14 @@ int main(int argc, char* argv[]) {
SDL_GL_GetDrawableSize(ZL::Environment::window, &drawW, &drawH);
ZL::Environment::width = drawW;
ZL::Environment::height = drawH;
std::cout << "HiDPI enabled, drawable size: " << drawW << "x" << drawH << std::endl;
ZL::logger() << "HiDPI enabled, drawable size: " << drawW << "x" << drawH << std::endl;
}
else {
int winW, winH;
SDL_GetWindowSize(ZL::Environment::window, &winW, &winH);
ZL::Environment::width = winW;
ZL::Environment::height = winH;
std::cout << "HiDPI disabled, window size: " << winW << "x" << winH << std::endl;
ZL::logger() << "HiDPI disabled, window size: " << winW << "x" << winH << std::endl;
}
// Динамическое создание объекта игры

View File

@ -100,7 +100,7 @@ void PathFinder::build(const std::string& configPath,
if (isTxt) {
if (loadGrid(configPath, zipPath)) {
ready = true;
std::cout << "[nav] Loaded precomputed grid: " << gridWidth << "x" << gridDepth
logger() << "[nav] Loaded precomputed grid: " << gridWidth << "x" << gridDepth
<< ", cell=" << cellSize << "\n";
} else {
std::cerr << "[nav] Failed to load precomputed grid: " << configPath << "\n";
@ -120,7 +120,7 @@ void PathFinder::build(const std::string& configPath,
rebuildWalkableGrid();
ready = true;
std::cout << "[nav] Polygon grid built: " << gridWidth << "x" << gridDepth
logger() << "[nav] Polygon grid built: " << gridWidth << "x" << gridDepth
<< ", cell=" << cellSize << ", areas=" << areas.size() << "\n";
}

View File

@ -329,7 +329,7 @@ namespace ZL {
size_t error = glGetError();
if (error != GL_NO_ERROR)
{
std::cout << "OpenGL error: " << error << std::endl;
logger() << "OpenGL error: " << error << std::endl;
throw std::runtime_error("Gl error");
}
}
@ -338,7 +338,7 @@ namespace ZL {
size_t error = glGetError();
if (error != GL_NO_ERROR)
{
std::cout << "OpenGL error: " << error << " happened in file: " << file << " at line: " << line << std::endl;
logger() << "OpenGL error: " << error << " happened in file: " << file << " at line: " << line << std::endl;
throw std::runtime_error("Gl error");
}
}

View File

@ -10,7 +10,7 @@ namespace ZL {
ShaderResource::ShaderResource(const std::string &vertexCode, const std::string &fragmentCode) {
std::cout << "Started creating shader resource" << std::endl;
logger() << "Started creating shader resource" << std::endl;
const int CONST_INFOLOG_LENGTH = 256;
@ -45,7 +45,7 @@ namespace ZL {
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &fragmentShaderCompiled);
glGetShaderInfoLog(fragmentShader, CONST_INFOLOG_LENGTH, &infoLogLength2, infoLog2);
std::cout << "Creating shader resource step 1" << std::endl;
//logger() << "Creating shader resource step 1" << std::endl;
if (!vertexShaderCompiled) {
@ -53,11 +53,11 @@ namespace ZL {
__android_log_print(ANDROID_LOG_ERROR, "ShaderManager",
"Failed to compile vertex shader: %s", infoLog);
#endif
std::cout << "Vertex shader compilation failed: " << infoLog << std::endl;
logger() << "Vertex shader compilation failed: " << infoLog << std::endl;
throw std::runtime_error("Failed to compile vertex shader code!");
}
std::cout << "Creating shader resource step 2" << std::endl;
//logger() << "Creating shader resource step 2" << std::endl;
if (!fragmentShaderCompiled) {
@ -65,12 +65,12 @@ namespace ZL {
__android_log_print(ANDROID_LOG_ERROR, "ShaderManager",
"Failed to compile fragment shader: %s", infoLog);
#endif
std::cout << "Fragment shader compilation failed: " << infoLog << std::endl;
logger() << "Fragment shader compilation failed: " << infoLog << std::endl;
throw std::runtime_error("Failed to compile fragment shader code!");
}
std::cout << "Creating shader resource step 4" << std::endl;
//logger() << "Creating shader resource step 4" << std::endl;
shaderProgram = glCreateProgram();
@ -86,7 +86,7 @@ namespace ZL {
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &programLinked);
glGetProgramInfoLog(shaderProgram, CONST_INFOLOG_LENGTH, &infoLogLength, infoLog);
std::cout << "Creating shader resource step 4" << std::endl;
//logger() << "Creating shader resource step 4" << std::endl;
if (!programLinked) {
shaderProgram = 0;
@ -94,11 +94,11 @@ namespace ZL {
__android_log_print(ANDROID_LOG_ERROR, "ShaderManager",
"Failed to link shader program: %s", infoLog);
#endif
std::cout << "Failed to link shader program: " << infoLog << std::endl;
logger() << "Failed to link shader program: " << infoLog << std::endl;
throw std::runtime_error("Failed to link shader program!");
}
std::cout << "Creating shader resource step 5" << std::endl;
//logger() << "Creating shader resource step 5" << std::endl;
//================= Parsing all uniforms ================
@ -121,7 +121,7 @@ namespace ZL {
uniformList[uniformName] = glGetUniformLocation(shaderProgram, uniformName);
}
std::cout << "Creating shader resource step 6" << std::endl;
//logger() << "Creating shader resource step 6" << std::endl;
//================= Parsing all attributes ================
@ -138,7 +138,7 @@ namespace ZL {
attribList[attribName] = glGetAttribLocation(shaderProgram, attribName);
}
std::cout << "Creating shader resource step 7" << std::endl;
//logger() << "Creating shader resource step 7" << std::endl;
#ifdef __ANDROID__
@ -173,7 +173,7 @@ namespace ZL {
"Fragment shader: %s", fragmentShaderFileName.c_str());
#endif
std::cout <<"Loading shader: " << shaderName << " " << vertexShaderFileName << " " << fragmentShaderFileName <<std::endl;
logger() <<"Loading shader: " << shaderName << " " << vertexShaderFileName << " " << fragmentShaderFileName <<std::endl;
std::string vertexShader;
std::string fragmentShader;
@ -204,7 +204,7 @@ namespace ZL {
}
if (shaderResourceMap.find(shaderName) == shaderResourceMap.end()) {
std::cout << "Shader does not exist: " << shaderName << std::endl;
logger() << "Shader does not exist: " << shaderName << std::endl;
throw std::runtime_error("Shader does not exist!");
}

View File

@ -62,7 +62,7 @@ namespace ZL
}
}
}
std::cout << "TextureManager: resized texture from "
logger() << "TextureManager: resized texture from "
<< src.width << "x" << src.height
<< " to " << newW << "x" << newH << " (POT)" << std::endl;
return dst;
@ -353,13 +353,13 @@ namespace ZL
}
void user_warning_fn(png_structp png_ptr, png_const_charp warning_msg) {
std::cout << "PNG Warning: " << warning_msg << std::endl;
logger() << "PNG Warning: " << warning_msg << std::endl;
}
void user_error_fn(png_structp png_ptr, png_const_charp error_msg) {
std::cout << "PNG Error: " << error_msg << std::endl;
logger() << "PNG Error: " << error_msg << std::endl;
longjmp(png_jmpbuf(png_ptr), 1);
}
@ -474,7 +474,7 @@ namespace ZL
fileArr = !ZIPFileName.empty() ? readFileFromZIP(fullFileName, ZIPFileName) : readFile(fullFileName);
if (fileArr.empty()) {
std::cout << "Could not read file data into memory: " << fullFileName << " zip file name: " << ZIPFileName << std::endl;
logger() << "Could not read file data into memory: " << fullFileName << " zip file name: " << ZIPFileName << std::endl;
throw std::runtime_error("Could not read file data into memory");
}
@ -539,7 +539,7 @@ namespace ZL
{
for (auto it = textureMap.begin(); it != textureMap.end(); ) {
if (it->first.substr(0, prefix.size()) == prefix) {
std::cout << "Unloading texture with prefix: " << it->first << std::endl;
logger() << "Unloading texture with prefix: " << it->first << std::endl;
it = textureMap.erase(it);
}
else {

View File

@ -11,6 +11,7 @@
#include <string>
#include <cctype>
#include <SDL.h>
#include "../Environment.h"
#ifdef __ANDROID__
#include <android/log.h>
@ -108,7 +109,7 @@ namespace ZL
int zipErr = 0;
zip_t* archive = zip_open(zipfilename.c_str(), ZIP_RDONLY, &zipErr);
if (!archive) {
std::cout << "Failed to open ZIP: " << zipfilename << " (error code " << zipErr << ")" << std::endl;
logger() << "Failed to open ZIP: " << zipfilename << " (error code " << zipErr << ")" << std::endl;
throw std::runtime_error("Failed to open ZIP: " + zipfilename);
}
@ -119,14 +120,14 @@ namespace ZL
zip_stat_init(&fileStat);
if (zip_stat(archive, cleanFilename.c_str(), 0, &fileStat) != 0 || !(fileStat.valid & ZIP_STAT_SIZE)) {
zip_close(archive);
std::cout << "Failed to stat file in ZIP: " << cleanFilename << " in " << zipfilename << std::endl;
logger() << "Failed to stat file in ZIP: " << cleanFilename << " in " << zipfilename << std::endl;
throw std::runtime_error("Can't stat file in ZIP: " + cleanFilename);
}
zip_file_t* zipFile = zip_fopen(archive, cleanFilename.c_str(), 0);
if (!zipFile) {
zip_close(archive);
std::cout << "Failed to open file in ZIP: " << cleanFilename << std::endl;
logger() << "Failed to open file in ZIP: " << cleanFilename << std::endl;
throw std::runtime_error("Can't open file in ZIP: " + cleanFilename);
}
@ -138,7 +139,7 @@ namespace ZL
zip_close(archive);
if (bytesRead < 0 || static_cast<zip_uint64_t>(bytesRead) != fileStat.size) {
std::cout << "Failed to read file from ZIP: " << cleanFilename << " (bytes read: " << bytesRead << ", expected: " << fileStat.size << ")" << std::endl;
logger() << "Failed to read file from ZIP: " << cleanFilename << " (bytes read: " << bytesRead << ", expected: " << fileStat.size << ")" << std::endl;
throw std::runtime_error("Error reading data from ZIP: " + cleanFilename);
}
@ -348,4 +349,90 @@ namespace ZL
#endif
}
// --- Инфраструктура для подавления вывода (когда лог выключен) ---
class NullBuffer : public std::streambuf {
protected:
int overflow(int c) override { return c; }
};
class NullStream : public std::ostream {
NullBuffer buf;
public:
NullStream() : std::ostream(&buf) {}
};
// --- Инфраструктура для дублирования вывода (Tee-поток) ---
class TeeBuffer : public std::streambuf {
std::streambuf* out1;
std::streambuf* out2;
protected:
int overflow(int c) override {
if (c != EOF) {
int r1 = out1->sputc(c);
int r2 = out2->sputc(c);
if (r1 == EOF || r2 == EOF) return EOF;
}
return c;
}
int sync() override {
int r1 = out1->pubsync();
int r2 = out2->pubsync();
return (r1 == -1 || r2 == -1) ? -1 : 0;
}
public:
TeeBuffer(std::streambuf* sb1, std::streambuf* sb2) : out1(sb1), out2(sb2) {}
};
// --- Глобальные переменные логгера ---
namespace {
std::ofstream g_logFile;
std::unique_ptr<TeeBuffer> g_teeBuffer;
std::unique_ptr<std::ostream> g_teeStream;
NullStream g_nullStream;
}
// --- Инициализация логгера ---
void initLogger() {
namespace fs = std::filesystem;
try {
fs::path dir = getSaveDirectory();
// Если директория не существует, ofstream не сможет создать файл,
// поэтому форсируем создание всей иерархии папок.
if (!fs::exists(dir)) {
fs::create_directories(dir);
}
fs::path logPath = dir / "log.txt";
// std::ios::trunc очищает файл при каждом новом запуске
g_logFile.open(logPath, std::ios::out | std::ios::trunc);
if (g_logFile.is_open()) {
g_teeBuffer = std::make_unique<TeeBuffer>(std::cout.rdbuf(), g_logFile.rdbuf());
g_teeStream = std::make_unique<std::ostream>(g_teeBuffer.get());
}
else {
std::cerr << "[logger] Could not open " << logPath << " for writing" << std::endl;
}
}
catch (const fs::filesystem_error& e) {
std::cerr << "[logger] Filesystem error during init: " << e.what() << std::endl;
}
}
// --- Сама функция логгера ---
std::ostream& logger() {
if (Environment::enableLogging) {
if (g_teeStream) {
return *g_teeStream;
}
// Фолбэк на стандартный вывод, если файл по какой-то причине не открылся
return std::cout;
}
// Если логирование отключено, возвращаем заглушку.
return g_nullStream;
}
};

View File

@ -35,4 +35,7 @@ namespace ZL
bool saveJsonToFile(const nlohmann::json& root, const std::string& filename);
void initLogger();
std::ostream& logger();
}