Mercurial > might-and-magic-trilogy
diff Game.cpp @ 0:8b8875f5b359
Initial commit
author | Nomad |
---|---|
date | Fri, 05 Oct 2012 16:07:14 +0200 |
parents | |
children | 2ca04ccb612a |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Game.cpp Fri Oct 05 16:07:14 2012 +0200 @@ -0,0 +1,1184 @@ +#include "Game.h" +#include "Party.h" +#include "IndoorCamera.h" +#include "Math.h" +#include "LightmapBuilder.h" +#include "Viewport.h" +#include "Time.h" +#include "Outdoor.h" +#include "Overlays.h" +#include "stru279.h" +#include "AudioPlayer.h" +#include "LOD.h" +#include "OSInfo.h" +#include "GUIWindow.h" +#include "Party.h" +#include "TurnEngine.h" +#include "stru157.h" +#include "VideoPlayer.h" +#include "Bink_Smacker.h" +#include "Events.h" +#include "Arcomage.h" + +//#include "MM7.h" + + + + + + +Game *pGame; + + + + + +//----- (00435694) -------------------------------------------------------- +void Game::ToggleFlags2(unsigned int uFlag) +{ + unsigned int v2; // eax@1 + + v2 = this->uFlags2; + if ( v2 & uFlag ) + this->uFlags2 = v2 & ~uFlag; + else + this->uFlags2 = uFlag | v2; +} + +//----- (0044103C) -------------------------------------------------------- +void Game::Draw() +{ + Render *v0; // esi@3 + int _null; // ebx@6 + float v2; // ST24_4@11 + double v3; // ST28_8@11 + int v4; // edi@26 + int v5; // eax@35 + + uFlags2 &= 0xFFFFFFFDu; + if ( pParty->_497FC5_check_party_perception_against_level() ) + uFlags2 |= 2u; + pIndoorCamera->sRotationX = pParty->sRotationX; + pIndoorCamera->sRotationY = pParty->sRotationY; + pIndoorCamera->pos.x = pParty->vPosition.x + - ((unsigned __int64)(stru_5C6E00->SinCos(pParty->sRotationY) + * (signed __int64)pParty->field_18) >> 16); + pIndoorCamera->pos.y = pParty->vPosition.z + - ((unsigned __int64)(stru_5C6E00->SinCos( + pParty->sRotationY - stru_5C6E00->uIntegerHalfPi) + * (signed __int64)pParty->field_18) >> 16); + pIndoorCamera->pos.z = pParty->vPosition.y + pParty->sEyelevel; + pIndoorCamera->Initialize2(); + pIndoorCameraD3D->CreateWorldMatrixAndSomeStuff(); + pIndoorCameraD3D->_4374E8_ProllyBuildFrustrum(); + //v0 = &pRenderer; + if ( pVideoPlayer->AnyMovieLoaded() ) + { + _null = 0; + if ( pRenderer->pRenderD3D ) + goto LABEL_22; + pRenderer->SetGameRenderStates(); + pMouse->_469E3B(); + } + else + { + if ( pParty->vPosition.x != pParty->vPrevPosition.x | pParty->sRotationY != pParty->sPrevRotationY | pParty->vPosition.z != pParty->vPrevPosition.z | pParty->sRotationX != pParty->sPrevRotationX | pParty->vPosition.y != pParty->vPrevPosition.y | pParty->sEyelevel != pParty->sPrevEyelevel ) + pParty->uFlags |= 2u; + pParty->vPrevPosition.x = pParty->vPosition.x; + pParty->vPrevPosition.y = pParty->vPosition.y; + //v0 = &pRenderer; + pParty->sPrevRotationY = pParty->sRotationY; + pParty->vPrevPosition.z = pParty->vPosition.z; + pParty->sPrevRotationX = pParty->sRotationX; + pParty->sPrevEyelevel = pParty->sEyelevel; + pRenderer->SetGameRenderStates(); + _null = 0; + if ( !pRenderer->pRenderD3D ) + pMouse->_469E3B(); + if ( !sub_4226C2() || viewparams->field_48 == 1 ) + { + if ( pRenderer->pRenderD3D ) + { + v2 = (double)(((signed int)pMiscTimer->uTotalGameTimeElapsed >> 2) & 0x1F) * 0.032258064 * 6.0; + v3 = v2 + 6.7553994e15; + pRenderer->field_1036A8_bitmapid = LODWORD(v3); + } + + if ( uCurrentlyLoadedLevelType == LEVEL_Indoor) + pIndoor->Draw(); + else if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor) + pOutdoor->Draw(); + + if ( pRenderer->pRenderD3D ) + { + pDecalBuilder->DrawBloodsplats(); + if ( pRenderer->pRenderD3D ) + pGame->pLightmapBuilder->DrawLightmaps(2); + } + } + } + pRenderer->DrawBillboards_And_MaybeRenderSpecialEffects_And_EndScene(); +LABEL_22: + pRenderer->BeginScene(); + if ( pRenderer->pRenderD3D != (RenderD3D *)_null ) + pMouse->_469E3B(); + if ( pOtherOverlayList->field_3EC != _null ) + viewparams->bRedrawGameUI = 1; + v4 = viewparams->bRedrawGameUI; + GameUI_DrawStatusBar(); + if ( viewparams->bRedrawGameUI == _null ) + { + //nullsub_1(); + GameUI_DrawRightPanelItems(); + } + else + { + GameUI_DrawRightPanelFrames(); + GameUI_DrawStatusBar_2(); + viewparams->bRedrawGameUI = _null; + } + if ( pVideoPlayer->pSmackerMovie == (_SMACK *)_null ) + { + GameUI_DrawMinimap(0x1E8u, 0x10u, 0x271u, 0x85u, viewparams->uMinimapZoom, pParty->uFlags & 2); + if ( v4 != _null ) + { + if ( !sub_4226C2() && pRenderer->pRenderD3D != (RenderD3D *)_null ) + pRenderer->FillRect2( + _null, + pViewport->uViewportX, + pViewport->uViewportY, + pViewport->uViewportZ - pViewport->uViewportX, + pViewport->uViewportW - pViewport->uViewportY + 1, + LOWORD(pRenderer->uTargetGMask) | LOWORD(pRenderer->uTargetBMask)); + viewparams->field_48 = _null; + } + } + v5 = pOtherOverlayList->field_3EC; + pOtherOverlayList->field_3EC = _null; + viewparams->bRedrawGameUI = v5; + GameUI_DrawPartySpells(); + if ( v4 != _null || pParty->pHirelings[0].evtc != _null || pParty->pHirelings[1].evtc != _null ) + DrawHiredNPCs(); + GameUI_DrawPortraits(v4); + GameUI_DrawLifeManaBars(); + GameUI_DrawCharacterSelectionFrame(); + if ( sub_44100D() ) + draw_right_panel(); + if ( !pVideoPlayer->AnyMovieLoaded() ) + { + pStru6Instance->DrawPlayerBuffAnims(); + pOtherOverlayList->_441964(v4); + GameUI_DrawTorchlightAndWizardEye(); + } + GUI_UpdateWindows(); + pParty->_4909F4(); + ++stru_51076C.field_8; + dword_5B5924 = _null; + if ( v4 != _null ) + pMouse->field_14 = 1; + pMouse->_469EA4(); + pMouse->DrawCursor(); + pMouse->_469E1C(); + pRenderer->EndScene(); + pRenderer->Present(); + pParty->uFlags &= 0xFFFFFFFDu; +} +// 5B5924: using guessed type int dword_5B5924; + + +//----- (0047A815) -------------------------------------------------------- +void Game::DrawParticles() +{ + pParticleEngine->Draw(); +} + +//----- (00463149) -------------------------------------------------------- +void Game::Loop() +{ + signed int v0; // ebp@3 + signed int v1; // esi@4 + Render *v2; // edi@7 + signed int v3; // esi@7 + signed int v4; // ecx@58 + char *v5; // eax@59 + Player *v6; // esi@65 + OtherOverlay *v7; // esi@67 + signed int v8; // edi@67 + int v9; // edi@69 + int *pHealth; // esi@71 + signed int v11; // esi@78 + int v12; // eax@83 + const char *v13; // [sp-4h] [bp-68h]@74 + bool bLoading; // [sp+10h] [bp-54h]@1 + signed int bLoadinga; // [sp+10h] [bp-54h]@19 + signed int v16; // [sp+14h] [bp-50h]@8 + int v17[4]; // [sp+18h] [bp-4Ch]@80 + MSG Msg; // [sp+28h] [bp-3Ch]@20 + char Source[64]; // [sp+44h] [bp-20h]@76 + + bLoading = uCurrentMenuID == MENU_LOAD; + SetCurrentMenuID(0xFFFFFFFFu); + if ( bLoading ) + { + pParty->Reset(); + dword_6BE340 = 0; + uGameState = 0; + LoadGame(uLoadGameUI_SelectedSlot); + } + v0 = 1; + do + { + v1 = 1; + do + { + sprintfex(pTmpBuf, "data\\lloyd%d%d.pcx", v0, v1); + remove(pTmpBuf); + ++v1; + } + while ( v1 < 6 ); + ++v0; + } + while ( v0 < 5 ); + LoadPlayerPortraintsAndVoices(); + pIcons_LOD->dword_11B84 = pIcons_LOD->uNumLoadedFiles; + pAudioPlayer->SetMusicVolume((signed __int64)(pSoundVolumeLevels[(char)uMusicVolimeMultiplier] * 64.0)); + v2 = pRenderer; + v3 = 1; + while ( 2 ) + { + v16 = v3; + if ( pMessageQueue_50CBD0->uNumMessages ) + pMessageQueue_50CBD0->uNumMessages = pMessageQueue_50CBD0->pMessages[0].field_8 != 0; + pPartyActionQueue->uNumActions = 0; + if ( pParty->bTurnBasedModeOn == v3 ) + { + pTurnEngine->End(0); + pParty->bTurnBasedModeOn = 0; + } + DoPrepareWorld(bLoading, v3); + pEventTimer->Resume(); + LOBYTE(dword_6BE364_game_settings_1) = dword_6BE364_game_settings_1 | 0x80; + dword_6BE340 = 2; + uGame_if_0_else_ui_id__11_save__else_load__8_drawSpellInfoPopup__22_final_window__26_keymapOptions__2_options__28_videoOptions = 0; + if ( pAsyncMouse ) + pAsyncMouse->Resume(); + if ( LOBYTE(pGame->pKeyboardInstance->bUsingAsynKeyboard) && pAsyncKeyboard ) + pAsyncKeyboard->Resume(); + if ( pRenderer->pRenderD3D ) + pGame->pVisInstance->_4C1A02(); + bLoadinga = 0; + do + { + while ( PeekMessageA(&Msg, 0, 0, 0, v3) ) + { + if ( Msg.message == WM_QUIT ) + Game_DeinitializeAndTerminate(0); + TranslateMessage(&Msg); + DispatchMessageA(&Msg); + } + if ( BYTE1(dword_6BE364_game_settings_1) & 1 ) + { + WaitMessage(); + continue; + } + pGame->_44EEA7(); + GameUI_WritePointedObjectStatusString(); + ProcessInputActions(); + GameUI_MsgProc(); + if ( pArcomageGame->bGameInProgress ) + { + ArcomageGame::Loop(); +LABEL_89: + v2->Present(); + continue; + } + if ( pAsyncMouse ) + pAsyncMouse->_46B736_consume_click_lists(v3); + if ( pVideoPlayer->pSmackerMovie && !SmackWait(pVideoPlayer->pSmackerMovie) ) + { + v2->BeginScene(); + pMouse->_469E3B(); + pVideoPlayer->SmackUpdatePalette(pVideoPlayer->hWindow); + pMouse->_469EA4(); + v2->EndScene(); + } + if ( pVideoPlayer->pBinkMovie && !BinkWait(pVideoPlayer->pBinkMovie) ) + { + v2->BeginScene(); + pMouse->_469E3B(); + pVideoPlayer->BinkUpdatePalette(pVideoPlayer->hWindow); + pMouse->_469EA4(); + v2->EndScene(); + } + pEventTimer->Update(); + pMiscTimer->Update(); + OnTimer(0); + GameUI_StatusBar_UpdateTimedString(0); + if ( pMiscTimer->bPaused && !pEventTimer->bPaused ) + pMiscTimer->Resume(); + if ( pEventTimer->bTackGameTime && !pParty->bTurnBasedModeOn ) + pEventTimer->bTackGameTime = 0; + if ( !pEventTimer->bPaused && !uGameState ) + { + if ( !pEventTimer->bTackGameTime ) + _494035_timed_effects__water_walking_damage__etc(); + if ( dword_6BE364_game_settings_1 & 1 ) + { + dword_6BE364_game_settings_1 &= 0xFFFFFFFEu; + } + else + { + sub_401A91_AI(); + sub_46BDC0_UpdateUserInput_and_MapSpecificStuff(); + } + } + if ( v16 ) + { + v16 = 0; + viewparams->bRedrawGameUI = v3; + } + pAudioPlayer->_4AAFCF(); + if ( uGameState == v3 ) + goto LABEL_96; + if ( uGameState == 2 ) + { + pAudioPlayer->StopChannels(-1, -1); + PrepareWorld(0); + uGameState = 0; + continue; + } + if ( (signed int)uGameState <= 2 ) + goto LABEL_85; + if ( (signed int)uGameState <= 5 || uGameState == 7 ) + { +LABEL_96: + bLoadinga = v3; + continue; + } + if ( uGameState != 8 ) + { + if ( uGameState != 9 ) + { +LABEL_85: + pGame->Draw(); + continue; + } + pRenderer->BeginScene(); + GUI_UpdateWindows(); + pRenderer->EndScene(); + goto LABEL_89; + } + pAudioPlayer->StopChannels(-1, -1); + memset(pParty->pHirelings, 0, 0x4Cu); + memset(&pParty->pHirelings[1], 0, 0x4Cu); + v4 = 0; + if ( (signed int)pNPCStats->uNumNewNPCs > 0 ) + { + v5 = (char *)&pNPCStats->pNewNPCData[0].uFlags; + do + { + if ( *((int *)v5 + 6) ) + *v5 &= 0x7Fu; + ++v4; + v5 += 76; + } + while ( v4 < (signed int)pNPCStats->uNumNewNPCs ); + } + pVideoPlayer->PlayDeathMovie(); + if ( pVideoPlayer->AnyMovieLoaded() ) + pVideoPlayer->Unload(); + SaveGame(0, 0); + ++pParty->uNumDeaths; + v6 = pParty->pPlayers; + do + { + v6->SetVariable(VAR_Award, 85); + ++v6; + } + while ( (signed int)v6 < (signed int)pParty->pHirelings ); + pParty->field_764 = 0; + pParty->uTimePlayed += 0x276000ui64; + LOWORD(pParty->uFlags) &= 0xFDFBu; + pParty->SetGold(0); + v7 = pOtherOverlayList->pOverlays; + v8 = 50; + do + { + v7->Reset(); + ++v7; + --v8; + } + while ( v8 ); + memset(pParty->pPartyBuffs, 0, 0x140u); + v9 = 1; + if ( pParty->bTurnBasedModeOn == 1 ) + { + pTurnEngine->End(1u); + pParty->bTurnBasedModeOn = 0; + } + pHealth = &pParty->pPlayers[0].sHealth; + do + { + memset(pHealth - 0x64F, 0, 0xA0u); + memset(pHealth - 0x67, 0, 0x180u); + *pHealth = 1; + pHealth += 1743; + uActiveCharacter = 1; + } + while ( (signed int)pHealth < (signed int)&pParty->field_871C[567] ); + if ( (unsigned __int16)_449B57_test_bit(pParty->_award_bits, 136) ) + { + pParty->vPosition.x = -17331; // respawn in harmondale + pParty->vPosition.z = 12547; + pParty->vPosition.y = 465; + pParty->sRotationY = 0; + v13 = "out02.odm"; + } + else + { + pParty->vPosition.x = 12552; // respawn on emerald isle + pParty->vPosition.z = 1816; + pParty->vPosition.y = 0; + pParty->sRotationY = 512; + v13 = "out01.odm"; + } + strcpy(Source, v13); + pParty->uFallStartY = pParty->vPosition.y; + pParty->sRotationX = 0; + pParty->uFallSpeed = 0; + pParty->field_6E4 = 0; + pParty->field_6E0 = 0; + if ( _strcmpi(Source, pCurrentMapName) ) + { + strcpy(pCurrentMapName, Source); + _5B65A8_npcdata_uflags_or_other = pParty->vPosition.x; + _5B65AC_npcdata_fame_or_other = pParty->vPosition.z; + _5B65B0_npcdata_rep_or_other = pParty->vPosition.y; + _5B65B4_npcdata_loword_house_or_other = pParty->sRotationY; + _5B65B8_npcdata_hiword_house_or_other = pParty->sRotationX; + dword_5B65C0 = 1; + PrepareWorld(1u); + } + UpdateActors(); + v11 = 0; + do + { + if ( pPlayers[v9]->CanAct() ) + v17[v11++] = v9; + ++v9; + } + while ( v9 <= 4 ); + if ( v11 ) + { + v12 = rand(); + pPlayers[v17[v12 % v11]]->PlaySound(99, 0); + } + ShowStatusBarString(pGlobalTXT_LocalizationStrings[524], 2u);// "Once again you've cheated death!.." + uGameState = 0; + v3 = 1; + } + while ( !bLoadinga ); + dword_6BE340 = 0; + pEventTimer->Pause(); + ResetCursor_Palettes_LODs_Level_Audio_SFT_Windows(); + if ( uGameState == 3 ) + { + sub_491E3A(); + LoadPlayerPortraintsAndVoices(); + uGameState = 0; + pIcons_LOD->dword_11B84 = pIcons_LOD->uNumLoadedFiles; + bLoading = v3; + continue; + } + break; + } + uGame_if_0_else_ui_id__11_save__else_load__8_drawSpellInfoPopup__22_final_window__26_keymapOptions__2_options__28_videoOptions = 16; + sub_491E3A(); +} +// 4D82B8: using guessed type int __stdcall BinkWait(int); +// 4D840C: using guessed type int __stdcall SmackWait(int); +// 4E28F8: using guessed type int uGame_if_0_else_ui_id__11_save__else_load__8_drawSpellInfoPopup__22_final_window__26_keymapOptions__2_options__28_videoOptions; +// 5B65A8: using guessed type int _5B65A8_npcdata_uflags_or_other; +// 5B65AC: using guessed type int _5B65AC_npcdata_fame_or_other; +// 5B65B0: using guessed type int _5B65B0_npcdata_rep_or_other; +// 5B65B4: using guessed type int _5B65B4_npcdata_loword_house_or_other; +// 5B65B8: using guessed type int _5B65B8_npcdata_hiword_house_or_other; +// 5B65C0: using guessed type int dword_5B65C0; +// 6BE340: using guessed type int dword_6BE340; +// 6BE364: using guessed type int dword_6BE364_game_settings_1; +// 463149: using guessed type int var_4C[4]; + + + +//----- (0044F192) -------------------------------------------------------- +void Game::PushStru165s() +{ + Game *v1; // edi@1 + int v2; // ebx@1 + float *v3; // esi@2 + + auto a1 = this; + v1 = a1; + v2 = 0; + if ( a1->array_708_size > 0 ) + { + v3 = &a1->array_708[0].flt_10; + do + { + pBloodsplatContainer->AddBloodsplat( + *(v3 - 4), + *(v3 - 3), + *(v3 - 2), + v3[2], + (signed __int64)*(v3 - 1), + (signed __int64)*v3, + (signed __int64)v3[1]); + ++v2; + v3 += 7; + } + while ( v2 < v1->array_708_size ); + } +} + + +//----- (0044F120) -------------------------------------------------------- +void Game::PushStationaryLights(int a2) +{ + signed int v3; // ebx@1 + char *v4; // esi@2 + + auto v2 = this; + v3 = 0; + if ( (signed int)this->uNumStationaryLights > 0 ) + { + v4 = (char *)&this->pStationaryLights[0].vRGBColor.y; + do + { + pStationaryLightsStack->AddLight( + (signed __int64)*((float *)v4 - 4), + (signed __int64)*((float *)v4 - 3), + (signed __int64)*((float *)v4 - 2), + (signed __int64)*((float *)v4 + 2), + (int *)(signed __int64)*((float *)v4 - 1), + (signed __int64)*(float *)v4, + (signed __int64)*((float *)v4 + 1), + byte_4E94D0); + ++v3; + v4 += 28; + } + while ( v3 < (signed int)v2->uNumStationaryLights ); + } +} +// 4E94D0: using guessed type char byte_4E94D0; + +//----- (0044F0FD) -------------------------------------------------------- +void Game::_44F0FD() +{ + ToggleFlags(0x40u); + + if ( !(uFlags & 0x40) ) + { + array_708_size = 0; + field_E0C = 0; + } +} + +//----- (0044F0D8) -------------------------------------------------------- +void Game::ToggleFlags(uint uMask) +{ + if (uFlags & uMask) + uFlags &= ~uMask; + else + uFlags |= uMask; +} + + +//----- (0044F07B) -------------------------------------------------------- +bool Game::_44F07B() +{ + if (!pKeyboardInstance->IsKeyBeingHeld(VK_SHIFT) && + !pKeyboardInstance->IsKeyBeingHeld(VK_LSHIFT) && + !pKeyboardInstance->IsKeyBeingHeld(VK_LSHIFT) || + + (pKeyboardInstance->WasKeyPressed(VK_F11) == 0 && + pKeyboardInstance->WasKeyPressed(VK_F11))) + return true; + return false; +} + +//----- (0044EEA7) -------------------------------------------------------- +bool Game::_44EEA7() +{ + Game *v1; // esi@1 + double v2; // st7@2 + float depth; // ST00_4@9 + bool result; // eax@9 + unsigned int v5; // eax@14 + __int64 v6; // kr00_8@21 + unsigned int y; // [sp+4h] [bp-24h]@2 + unsigned int x; // [sp+8h] [bp-20h]@2 + bool v9; // [sp+Ch] [bp-1Ch]@2 + stru157 *v10; // [sp+10h] [bp-18h]@2 + stru157 *v11; // [sp+14h] [bp-14h]@2 + POINT a2; // [sp+20h] [bp-8h]@1 + + v1 = this; + ++qword_5C6DF0; + pParticleEngine->UpdateParticles(); + pMouseInstance->GetCursorPos(&a2); + if ( sub_4637E0_is_there_popup_onscreen() ) + { + v11 = &a5; + v10 = &stru_F93E30; + v9 = 0; + x = a2.y; + y = a2.x; + v2 = GetPickDepth(); + } + else + { + if ( v1->uFlags2 & 0x10 ) + { + v11 = &a5; + v10 = &stru_F93E1C; + } + else + { + static bool __init_flag = false; + static stru157 static_sub_44EEA7_stru157; + if (!__init_flag) + { + __init_flag = true; + static_sub_44EEA7_stru157.field_8 = -1; + static_sub_44EEA7_stru157.field_0 = 0; + static_sub_44EEA7_stru157.field_4 = 2; + static_sub_44EEA7_stru157.field_C = 0; + static_sub_44EEA7_stru157.field_10 = 0; + } + v11 = &a5; + v10 = &static_sub_44EEA7_stru157; + } + v2 = 5120.0; + v9 = 0; + x = a2.y; + y = a2.x; + } + depth = v2; + + PickMouse(depth, y, x, v9, v10, v11); + v1->pLightmapBuilder->std__vector_000004_size = 0; + v1->pLightmapBuilder->std__vector_183808_size = 0; + pDecalBuilder->std__vector_pDecals_size = 0; + pDecalBuilder->field_308008 = 0; + result = _44F07B(); + if ( result ) + { + if ( uFlags & 8 ) + LOBYTE(pStru10Instance->field_4) = 0; + if ( pRenderer->pRenderD3D && uCurrentlyLoadedLevelType == LEVEL_Outdoor) + { + v5 = GetLevelFogColor(); + LODWORD(pRenderer->uFogColor) = v5 & 0xFFFFFF; + } + if (uFlags & 0x0400) + uFlags2 |= 0x01; + if ( !pRenderer->pRenderD3D && uCurrentlyLoadedLevelType == LEVEL_Outdoor && uNumMobileLightsApplied ) + { + uFlags2 |= 0x01; + field_E10 = qword_5C6DF0; + } + v6 = qword_5C6DF0 - v1->field_E10; + if ( qword_5C6DF0 - v1->field_E10 == 1 ) + v1->uFlags2 |= v6; + if ( v1->uNumStationaryLights_in_pStationaryLightsStack != uNumStationaryLightsApplied ) + { + v1->uFlags2 |= 1u; + v1->uNumStationaryLights_in_pStationaryLightsStack = uNumStationaryLightsApplied; + } + _44E904(); + LOBYTE(result) = 1; + } + return result; +} +// 519AB4: using guessed type int uNumStationaryLightsApplied; +// 5C6DEC: using guessed type char static_sub_44EEA7_byte_5C6DEC__init_flag; +// 5C6DF0: using guessed type __int64 qword_5C6DF0; +// F93E1C: using guessed type stru157 stru_F93E1C; +// F93E30: using guessed type stru157 stru_F93E30; + +//----- (0044EDE4) -------------------------------------------------------- +bool Game::_44EDE4(BLVFace *pFace, int *a3) +{ + bool result; // eax@1 + + result = (bool)pGame; + if ( pGame->uFlags2 & 2 && (result = (bool)pFace, pFace->uAttributes & 2) ) + { + result = sub_48A959(*a3, 1.0, this->_E28_timed_gamma_strength, -1.0); + *a3 = result; + LOBYTE(result) = 1; + } + else + { + LOBYTE(result) = 0; + } + return result; +} + +//----- (0044EE30) -------------------------------------------------------- +bool Game::_44EE30(ODMFace *a2, int a3) +{ + if (uFlags2 & 0x2 && a2->uFaceAttributes & 0x02) + { + *(int *)a3 = sub_48A959(*(int *)a3, 1.0, _E28_timed_gamma_strength, -1.0); + return true; + } + else + return false; +} + + +//----- (004645FA) -------------------------------------------------------- +void Game::Deinitialize() +{ + struct tagRECT Rect; // [sp+0h] [bp-10h]@6 + + if ( pAsyncMouse ) + pAsyncMouse->Suspend(); + if ( LOBYTE(pGame->pKeyboardInstance->bUsingAsynKeyboard) && pAsyncKeyboard ) + pAsyncKeyboard->Suspend(); + WriteWindowsRegistryInt("startinwindow", pRenderer->bWindowMode); + if ( GetWindowRect(hWnd, &Rect) && pRenderer->bWindowMode ) + { + WriteWindowsRegistryInt("window X", Rect.left); + WriteWindowsRegistryInt("window Y", Rect.top); + } + WriteWindowsRegistryInt("debug flags", stru_51076C.registry_debug_flags); + WriteWindowsRegistryInt("valAlwaysRun", bAlwaysRun); + pItemsTable->Release(); + pNPCStats->Release(); + pAsyncKeyboard->Release(); + pAsyncMouse->Release(); + if ( pMouse ) + pMouse->Deactivate(); + pAudioPlayer->Release(); + pNew_LOD->FreeSubIndexAndIO(); + pGames_LOD->FreeSubIndexAndIO(); + ClipCursor(0); + Game::Destroy(); +} + +//----- (0044EE7C) -------------------------------------------------------- +bool Game::draw_debug_outlines() +{ + if (uFlags & 0x04) + { + pLightmapBuilder->DrawDebugOutlines(-1); + pDecalBuilder->DrawDecalDebugOutlines(); + } + return true; +} + +//----- (0044EC23) -------------------------------------------------------- +int Game::_44EC23(stru148 *a2, int *a3, signed int a4) +{ + double v4; // st7@4 + double v5; // ST00_8@4 + signed int v6; // eax@5 + double v7; // ST00_8@6 + signed int result; // eax@8 + double v9; // ST00_8@9 + double v10; // ST00_8@11 + float a2a; // [sp+14h] [bp+8h]@4 + float a3a; // [sp+18h] [bp+Ch]@4 + float a3b; // [sp+18h] [bp+Ch]@6 + float a4a; // [sp+1Ch] [bp+10h]@9 + float a4b; // [sp+1Ch] [bp+10h]@11 + + if ( this->uFlags2 & 2 && a2->field_59 == 5 && a2->pODMFace->uFaceAttributes & 2 ) + { + v4 = (double)a4; + a2a = v4; + *a3 |= 2u; + a3a = (1.0 - this->_E28_timed_gamma_strength) * v4; + v5 = a3a + 6.7553994e15; + if ( SLODWORD(v5) >= 0 ) + { + a3b = (1.0 - this->_E28_timed_gamma_strength) * a2a; + v7 = a3b + 6.7553994e15; + v6 = LODWORD(v7); + } + else + { + v6 = 0; + } + if ( a4 >= v6 ) + { + a4a = (1.0 - this->_E28_timed_gamma_strength) * a2a; + v9 = a4a + 6.7553994e15; + if ( SLODWORD(v9) >= 0 ) + { + a4b = (1.0 - this->_E28_timed_gamma_strength) * a2a; + v10 = a4b + 6.7553994e15; + result = LODWORD(v10); + } + else + { + result = 0; + } + } + else + { + result = a4; + } + } + else + { + result = -1; + } + return result; +} + + + +//----- (00465C8B) -------------------------------------------------------- +Game *Game::Create() +{ + return new Game; +} + +//----- (00465CF3) -------------------------------------------------------- +void Game::Destroy() +{ + if (pGame) + delete pGame; + pGame = nullptr; +} + +//----- (0044ED0A) -------------------------------------------------------- +signed int Game::_44ED0A(BLVFace *a2, int *a3, signed int a4) +{ + double v4; // st7@3 + double v5; // ST00_8@3 + signed int v6; // eax@4 + double v7; // ST00_8@5 + signed int result; // eax@7 + double v9; // ST00_8@8 + double v10; // ST00_8@10 + float v11; // [sp+14h] [bp+8h]@3 + float v12; // [sp+18h] [bp+Ch]@3 + float v13; // [sp+18h] [bp+Ch]@5 + float v14; // [sp+1Ch] [bp+10h]@8 + float v15; // [sp+1Ch] [bp+10h]@10 + + if ( this->uFlags2 & 2 && a2->uAttributes & 2 ) + { + v4 = (double)a4; + v11 = v4; + *a3 |= 2u; + v12 = (1.0 - this->_E28_timed_gamma_strength) * v4; + v5 = v12 + 6.7553994e15; + if ( SLODWORD(v5) >= 0 ) + { + v13 = (1.0 - this->_E28_timed_gamma_strength) * v11; + v7 = v13 + 6.7553994e15; + v6 = LODWORD(v7); + } + else + { + v6 = 0; + } + if ( a4 >= v6 ) + { + v14 = (1.0 - this->_E28_timed_gamma_strength) * v11; + v9 = v14 + 6.7553994e15; + if ( SLODWORD(v9) >= 0 ) + { + v15 = (1.0 - this->_E28_timed_gamma_strength) * v11; + v10 = v15 + 6.7553994e15; + result = LODWORD(v10); + } + else + { + result = 0; + } + } + else + { + result = a4; + } + } + else + { + result = -1; + } + return result; +} + + +//----- (0044E4B7) -------------------------------------------------------- +Game::Game() +{ + uNumStationaryLights = 0; + array_708_size = 0; + field_E0C = 0; + field_E10 = 0; + uNumStationaryLights_in_pStationaryLightsStack = 0; + bGammaControlInitialized = false; + uFlags = 0; + uFlags2 = 0; + uSomeGammaStartTime = 0; + uSomeGammaDeltaTime = 0; + + pThreadWardInstance = new ThreadWard; + pParticleEngine = new ParticleEngine; + pMouseInstance = new Mouse(pThreadWardInstance); + pLightmapBuilder = new LightmapBuilder; + pVisInstance = new Vis; + pStru6Instance = new stru6; + pIndoorCameraD3D = new IndoorCameraD3D; + pStru9Instance = new stru9; + pStru10Instance = new stru10; + pStru11Instance = new stru11; + pStru12Instance = new stru12(pStru11Instance); + pCShow = new CShow; + pKeyboardInstance = new Keyboard; + pGammaController = new GammaController; + + uFlags |= 0x0800; + uFlags2 |= 0x24; + + _44F0FD(); + + bWinNT4_0 = false; + if (pVersion->pVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT && + pVersion->pVersionInfo.dwMajorVersion == 4) + bWinNT4_0 = true; +} + +//----- (0044E7F3) -------------------------------------------------------- +Game::~Game() +{ + if (pGammaController) + delete pGammaController; + if (pKeyboardInstance) + delete pKeyboardInstance; + if (pCShow) + delete pCShow; + if (pStru12Instance) + delete pStru12Instance; + if (pStru11Instance) + delete pStru11Instance; + if (pStru10Instance) + delete pStru10Instance; + if (pStru9Instance) + delete pStru9Instance; + if (pIndoorCameraD3D) + delete pIndoorCameraD3D; + if (pStru6Instance) + delete pStru6Instance; + if (pVisInstance) + delete pVisInstance; + if (pLightmapBuilder) + delete pLightmapBuilder; + if (pMouseInstance) + delete pMouseInstance; + if (pParticleEngine) + delete pParticleEngine; + if (pThreadWardInstance) + delete pThreadWardInstance; +} + +//----- (0044E904) -------------------------------------------------------- +void Game::_44E904() +{ + Game *v1; // esi@1 + unsigned __int64 v2; // qax@1 + unsigned int v3; // ecx@1 + int v4; // edi@1 + unsigned __int8 v5; // cf@7 + double v6; // st7@13 + double v7; // st7@15 + signed __int64 v8; // [sp+Ch] [bp-8h]@1 + + v1 = this; + v2 = pEventTimer->Time(); + v4 = (v2 - v1->uSomeGammaStartTime) >> 32; + v3 = v2 - LODWORD(v1->uSomeGammaStartTime); + v8 = v2 - v1->uSomeGammaStartTime; + if ( v4 < 0 + || SHIDWORD(v2) < ((unsigned int)v2 < LODWORD(v1->uSomeGammaStartTime)) + HIDWORD(v1->uSomeGammaStartTime) | v4 == 0 + && v3 <= 0x80 ) + { + if ( v4 > 0 || v4 >= 0 ) + goto LABEL_12; + v3 = 0; + v4 = 0; + } + else + { + if ( v1->uSomeGammaDeltaTime ) + { + LODWORD(v1->uSomeGammaDeltaTime) = 0; + HIDWORD(v1->uSomeGammaDeltaTime) = 0; + } + else + { + LODWORD(v1->uSomeGammaDeltaTime) = v3; + HIDWORD(v1->uSomeGammaDeltaTime) = v4; + } + v5 = __CFADD__(v3, -128); + v3 -= 128; + v4 = v5 + v4 - 1; + } + v1->uSomeGammaStartTime = v2; + v8 = __PAIR__(v4, v3); +LABEL_12: + if ( v1->uSomeGammaDeltaTime ) + v6 = (double)(signed __int64)(v1->uSomeGammaDeltaTime - __PAIR__(v4, v3)); + else + v6 = (double)v8; + v7 = v6 * 0.0078125; + if ( v7 < 0.0 || v7 <= 1.0 ) + { + if ( v7 < 0.0 ) + v7 = 0.0; + } + else + { + v7 = 1.0; + } + if ( pRenderer->pRenderD3D ) + v1->_E28_timed_gamma_strength = v7; + else + v1->_E28_timed_gamma_strength = (1.0 - 0.5) * v7 + 0.5; +} + +//----- (0044EA17) -------------------------------------------------------- +bool Game::InitializeGammaController() +{ + if (pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || + pVersion->pVersionInfo.dwMajorVersion != 4 ) + pGammaController->InitializeFromSurface(pRenderer->pFrontBuffer4); + + bGammaControlInitialized = true; + uSomeGammaStartTime = pEventTimer->Time(); + return true; +} + +//----- (0044EA5E) -------------------------------------------------------- +char Game::PickMouse(float fPickDepth, unsigned int uMouseX, unsigned int uMouseY, bool bOutline, stru157 *a5, stru157 *a6) +{ + char result; // al@3 + std::string v10; // [sp-4h] [bp-24h]@5 + float v11; // [sp+4h] [bp-1Ch]@10 + float v12; // [sp+8h] [bp-18h]@10 + const char *v13; // [sp+Ch] [bp-14h]@5 + int v14; // [sp+10h] [bp-10h]@5 + std::string *v15; // [sp+18h] [bp-8h]@5 + int a3; // [sp+1Fh] [bp-1h]@5 + + auto v7 = this; + if (!uGame_if_0_else_ui_id__11_save__else_load__8_drawSpellInfoPopup__22_final_window__26_keymapOptions__2_options__28_videoOptions + && pRenderer->pRenderD3D) + { + if (!pVisInstance) + { + MessageBoxW(nullptr, L"The 'Vis' object pointer has not been instatiated, but CGame::Pick() is trying to call through it.", nullptr, 0); + ExitProcess(0); + } + + if ( (signed int)uMouseX >= (signed int)pViewport->uScreenX + && (signed int)uMouseX <= (signed int)pViewport->uScreenZ + && (signed int)uMouseY >= (signed int)pViewport->uScreenY + && (signed int)uMouseY <= (signed int)pViewport->uScreenW ) + { + v14 = (int)a6; + v12 = (double)(signed int)uMouseY; + v11 = (double)(signed int)uMouseX; + pVisInstance->PickMouse(fPickDepth, v11, v12, a5, a6); + + if (bOutline) + OutlineSelection(); + } + return true; + } + return false; +} +// 4E28F8: using guessed type int uGame_if_0_else_ui_id__11_save__else_load__8_drawSpellInfoPopup__22_final_window__26_keymapOptions__2_options__28_videoOptions; + +//----- (0044EB12) -------------------------------------------------------- +bool Game::_44EB12(bool bOutline, stru157 *a3, stru157 *a4) +{ + if ( !uGame_if_0_else_ui_id__11_save__else_load__8_drawSpellInfoPopup__22_final_window__26_keymapOptions__2_options__28_videoOptions + && pVisInstance + && pRenderer->pRenderD3D ) + { + bool r = pVisInstance->_4C05CC(&pVisInstance->stru1, a3, a4); + + if (bOutline) + OutlineSelection(); + return r; + } + return false; +} +// 4E28F8: using guessed type int uGame_if_0_else_ui_id__11_save__else_load__8_drawSpellInfoPopup__22_final_window__26_keymapOptions__2_options__28_videoOptions; + +//----- (0044EB5A) -------------------------------------------------------- +void Game::OutlineSelection() +{ + Vis *v1; // eax@1 + Vis_stru1_stru0 *v2; // eax@3 + void *v3; // edx@9 + int v4; // eax@10 + int v5; // eax@11 + int v6; // eax@14 + int v7; // eax@15 + const char *v9; // [sp-8h] [bp-14h]@8 + int v10; // [sp-4h] [bp-10h]@8 + char v11; // [sp+0h] [bp-Ch]@18 + int a3; // [sp+Ah] [bp-2h]@8 + + v1 = this->pVisInstance; + if ( v1 ) + { + v2 = (Vis_stru1_stru0 *)((signed int)v1->stru1.uNumPointers <= 0 ? 0 : v1->stru1.array_1804[0]); + if ( v2 ) + { + if ( v2->uObjectType == 1 ) + { + MessageBoxW(nullptr, L"Sprite outline currently Unsupported", nullptr, 0); + ExitProcess(0); + } + + if ( v2->uObjectType == 2 ) + { + v3 = v2->pObjectInfo; // TODO 2 objects for indoor/outdoor + // some clues in header for Vis_stru1_stru0 + if (uCurrentlyLoadedLevelType == LEVEL_Outdoor) + { + v4 = *((int *)v3 + 11); + if ( v4 & 0x10000 ) + v5 = v4 & 0xFFFEFFFF; + else + v5 = v4 | 0x10000; + *((int *)v3 + 11) = v5; + } + else + { + v6 = *((int *)v3 + 7); + if ( v6 & 0x10000 ) + v7 = v6 & 0xFFFEFFFF; + else + v7 = v6 | 0x10000; + *((int *)v3 + 7) = v7; + } + } + else + { + MessageBoxW(nullptr, L"Undefined CObjectInfo type requested in CGame::outline_selection()", nullptr, 0); + ExitProcess(0); + } + } + } +} \ No newline at end of file