# HG changeset patch # User Ritor1 # Date 1411040334 -21600 # Node ID 5abd8fc8f1c607d351f579103f5a34849ce1cf38 # Parent 7b076fe64f233bdce4fa11fe680e0a369cb3e7a4 for ITEM_ARTIFACT_LADYS_ESCORT diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Actor.cpp --- a/Actor.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/Actor.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -4,22 +4,22 @@ #define _CRT_SECURE_NO_WARNINGS -#include "PaletteManager.h" +#include "Engine/Graphics/PaletteManager.h" #include "ErrorHandling.h" -#include "DecalBuilder.h" - -#include "Sprites.h" +#include "Engine/Graphics/DecalBuilder.h" + +#include "Engine/Graphics/Sprites.h" #include "stru6.h" #include "Actor.h" #include "OurMath.h" -#include "Outdoor.h" +#include "Engine/Graphics/Outdoor.h" #include "AudioPlayer.h" #include "Game.h" #include "ObjectList.h" -#include "Overlays.h" +#include "Engine/Graphics/Overlays.h" #include "FactionTable.h" #include "TurnEngine.h" #include "CastSpellInfo.h" @@ -33,9 +33,9 @@ #include "stru298.h" #include "Log.h" #include "Texts.h" -#include "Level/Decoration.h" -#include "Viewport.h" -#include "Vis.h" +#include "Engine/Graphics/Level/Decoration.h" +#include "Engine/Graphics/Viewport.h" +#include "Engine/Graphics/Vis.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Arcomage.cpp --- a/Arcomage.cpp Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3775 +0,0 @@ -#define _CRTDBG_MAP_ALLOC -#include -#include - -#define _CRT_SECURE_NO_WARNINGS -#include - - -#include "Render.h" -#include "Arcomage.h" -#include "AudioPlayer.h" -#include "Game.h" -#include "Viewport.h" -#include "Timer.h" -#include "GUIFont.h" -#include "Party.h" -#include "GUIWindow.h" -#include "texts.h" -#include -#include "mm7_data.h" -#include "UI/UIHouses.h" - - - -void SetStartConditions(); -void SetStartGameData(); -void FillPlayerDeck(); -void InitalHandsFill(); -void GetNextCardFromDeck(int player_num); -int GetEmptyCardSlotIndex(int player_num); -void IncreaseResourcesInTurn(int player_num); -void TurnChange(); -bool IsGameOver(); -int CalculateCardPower(ArcomagePlayer* player, ArcomagePlayer* enemy, ArcomageCard* pCard, int mastery); -char PlayerTurn(int player_num); -void DrawGameUI(int animation_stage); -void DrawSparks(); -void DrawRectanglesForText(); -void DrawPlayersText(); -void DrawPlayerLevels(int a1, char *text, POINT *pXY); -void DrawBricksCount(int a1, char* text, POINT *pXY); -void DrawGemsCount(int a1, char* text, POINT* pXY); -void DrawBeastsCount(int a1, char *text, POINT *pXY); -void DrawPlayersTowers(); -void DrawPlayersWall(); -void DrawCards(); -void DrawCardAnimation(int a1); -int GetPlayerHandCardCount(int player_num); -int DrawCardsRectangles(int player_num); -bool DiscardCard(int player_num, int card_slot_index); -bool PlayCard(int player_num, int card_slot_num); -bool CanCardBePlayed(int player_num, int hand_card_indx); -void ApplyCardToPlayer(int player_num, unsigned int uCardID); -int am_40D2B4(POINT* a1, int a2); // weak -int ApplyDamageToBuildings(int player_num, int damage); // weak -void GameResultsApply(); - -void am_DrawText(int a1, const char *pText, POINT *pXY); -void am_BeginScene(unsigned __int16 *pPcxPixels, int a2, int a3); // idb -void am_EndScene(); -void DrawRect(RECT *pXYZW, unsigned __int16 uColor, char bSolidFill); -void DrawSquare( POINT *pTargetXY, unsigned __int16 uColor ); -void DrawPixel(POINT *pTargetXY, unsigned __int16 uColor); -int rand_interval(int min, int max); // idb -void __fastcall am_IntToString(int val, char *pOut); - -//----- (0040DEDB) -------------------------------------------------------- -unsigned int R8G8B8_to_TargetFormat(int uColor) -{ - return Color16(LOBYTE(uColor), BYTE1(uColor), BYTE2(uColor)); -} - -/* 388 */ -#pragma pack(push, 1) -struct ArcomageStartConditions -{ - __int16 max_tower; - __int16 max_resources; - __int16 tower_height; - __int16 wall_height; - __int16 quarry_level; - __int16 magic_level; - __int16 zoo_level; - __int16 bricks_amount; - __int16 gems_amount; - __int16 beasts_amount; - int mastery_lvl; -}; -#pragma pack(pop) -const ArcomageStartConditions start_conditions[13] = -{ - { 30, 100, 15, 5, 2, 2, 2, 10, 10, 10, 0}, - { 50, 150, 20, 5, 2, 2, 2, 5, 5, 5, 1}, - { 50, 150, 20, 5, 2, 2, 2, 5, 5, 5, 2}, - { 75, 200, 25, 10, 3, 3, 3, 5, 5, 5, 2}, - { 75, 200, 20, 10, 3, 3, 3, 5, 5, 5, 1}, - {100, 300, 30, 15, 4, 4, 4, 10, 10, 10, 1}, - {100, 300, 30, 15, 4, 4, 4, 10, 10, 10, 2}, - {150, 400, 20, 10, 5, 5, 5, 25, 25, 25, 0}, - {200, 500, 20, 10, 1, 1, 1, 15, 15, 15, 2}, - {100, 300, 20, 50, 1, 1, 5, 5, 5, 25, 0}, - {125, 350, 10, 20, 3, 1, 2, 15, 5, 10, 2}, - {125, 350, 10, 20, 3, 1, 2, 15, 5, 10, 1}, - {100, 300, 50, 50, 5, 3, 5, 20, 10, 20, 0} -}; - -#define SIG_trpg 0x67707274 -#define SIG_xxxx 0x78787878 - -ArcomageGame *pArcomageGame = new ArcomageGame; - -ArcomagePlayer am_Players[2]; // 00505708 -AcromageCardOnTable shown_cards[10]; // 004FAA78 -stru272 array_4FABD0[10]; // 4FABD0 - - -ArcomageDeck playDeck; // 00505288 -ArcomageDeck deckMaster; // 005054C8 - -char Player2Name[] = "Enemy"; -char Player1Name[] = "Player"; - -/* 267 */ -#pragma pack(push, 1) -struct stru273 -{ - bool _40DD2F(); - bool Inside(RECT*pXYZW); - - int x; - int y; - char curr_mouse_left; - char mouse_left_state_changed; - char curr_mouse_right; - char mouse_right_state_changed; -}; -#pragma pack(pop) - - -#pragma pack(push, 1) -struct am_2 - { - int slot_index; - int card_power; - }; -#pragma pack(pop) - -am_2 cards_power[10]; -std::array<__int16, 12> am_sounds; - -char byte_4E185C = 1; // weak -char am_byte_4E185D = 1; // weak -char use_start_bonus = 1; // weak - -int start_tower_height; -int start_wall_height; -int start_quarry_level; -int start_magic_level; -int start_zoo_level; - - -int minimum_cards_at_hand = 5; // 004E1874 -int quarry_bonus = 1; -int magic_bonus = 1; -int zoo_bonus = 1; - -int max_tower_height = 50; -int max_resources_amount = 100 ; - -int opponent_mastery = 1 ; // weak - -bool am_gameover; // 004FAA2C -char byte_4FAA2D; // weak - -int am_default_starting_player = 0; // 505890 -int current_player_num; // 004FAA6C -char need_to_discard_card; // 04FAA77 - -int current_card_slot_index; // 004FABBC -int played_card_id; // 4FABC0 -int uCardID; // 4FAA50 - -int deck_walk_index; // 004FABC8 - -int start_bricks_amount; -int start_gems_amount; -int start_beasts_amount; - -POINT amuint_4FAA3C_blt_xy; -POINT am_uint_4FAA44_blt_xy; -POINT amuint_4FAA54_blt_xy; -POINT amuint_4FAA5C_blt_xy; - -int dword_4FAA64; // weak -int dword_4FAA68; // weak - -int dword_4FABB8; // weak - -char byte_4FAA00; // weak - -int amuint_4FAA34; // weak -int amuint_4FAA38; // weak -int amuint_4FAA4C; // weak - -char byte_4FAA2E; // weak - -int dword_4FAA70; // weak -char byte_4FAA74; // weak -char am_byte_4FAA75; // weak -char am_byte_4FAA76; // weak - -int amuint_4FABC4; // weak - - -char byte_505880; // weak -char byte_505881; // weak - -//----- (0040DD2F) -------------------------------------------------------- -bool stru273::_40DD2F() -{ - - this->x = pArcomageGame->mouse_x; - this->y = pArcomageGame->mouse_y; - this->curr_mouse_left = pArcomageGame->mouse_left; - this->mouse_left_state_changed = pArcomageGame->mouse_left == pArcomageGame->prev_mouse_left; - this->curr_mouse_right = pArcomageGame->mouse_right; - this->mouse_right_state_changed = pArcomageGame->mouse_right == pArcomageGame->prev_mouse_right; - pArcomageGame->prev_mouse_left = pArcomageGame->mouse_left; - pArcomageGame->prev_mouse_right = pArcomageGame->mouse_right; - return true; -} - -//----- (0040DD93) -------------------------------------------------------- -bool stru273::Inside(RECT*pXYZW ) - { - - return (x >= pXYZW->left) && (x <= pXYZW->right) && - (y>= pXYZW->top) && (y <= pXYZW->bottom); -} - -//----- (0040DFD1) -------------------------------------------------------- -stru272_stru0 *stru272_stru0::New() -{ - stru272_stru0 *v2 = (stru272_stru0 *)malloc(0x5Cu); - v2->signature = SIG_trpg; - v2->position_in_sparks_arr = 0; - v2->field_30 = 0.0; - v2->field_58 = 0; - v2->field_59 = 0; - - return v2; -} - -//----- (0040DFFE) -------------------------------------------------------- -int stru272_stru0::Free() -{ - if ( this->signature == SIG_trpg ) - { - this->signature = SIG_xxxx; - free(this); - return 0; - } - else - return 2; -} - -//----- (0040E01A) -------------------------------------------------------- -int stru272_stru0::StartFill( stru272_stru2* a2 ) -{ - //stru272_stru0* a1 = this; - if ( this->signature == SIG_trpg ) - { - this->field_4 = a2->field_20; - this->field_C = a2->effect_area.left << 16; - this->field_10 = a2->effect_area.top << 16; - this->field_14 = a2->effect_area.right << 16; - this->field_18 = a2->effect_area.bottom << 16; - this->field_1C = a2->field_10; - this->field_20 = a2->field_14; - this->field_24 = a2->field_18; - this->field_28 = (float)(a2->field_1Cf * 65536.0); - this->field_2C = a2->field_24f; - this->field_34 = (int)(a2->field_28f * 65536.0); - this->field_38 = (int)(a2->field_2Cf * 65536.0); - this->field_3C = a2->field_30; - this->field_40 = a2->field_34; - this->field_54 = a2->sparks_array; - this->field_59 = 1; - return 0; - } - else - return 2; -} - -//----- (0040E0F5) -------------------------------------------------------- -int stru272_stru0::Clear(char a2, char a3) - { - if ( signature == SIG_trpg) - { - if ( a2 ) - { - position_in_sparks_arr = 0; - field_30 = 0.0; - } - if ( field_59 && a3 ) - { - - for (int i=0; isignature != SIG_trpg ) - return 2; - v3 = this->position_in_sparks_arr; - v22 = this->field_30; - v4 = v3; - if ( v3 > 0 ) - { - v5 = v22 + this->field_2C; - v22 = v5; - if ( v5 > v4 ) - v22 = v4; - } - if ( v22 >= 1.0 || this->field_58 ) - { - v6 = 0; - v7 = this->field_54; - v20 = this->field_28; - - for ( v21 = this->field_4; v21; v21-- ) - { - if ( v7->have_spark > 0 ) - { - v8 = v7->field_14; - --v7->have_spark; - v9 = v8 + v7->field_C; - v10 = v20 + v7->field_18; - v7->field_C = v9; - v7->spark_position.x = v9 >> 16; - v11 = v10 + v7->field_10; - v7->field_18 = v10; - v7->field_10 = v11; - v7->spark_position.y = v11 >> 16; - v6 = 1; - //goto LABEL_14; - } - else - { - if ( v22 >= 1.0 ) - { - v12 = this->field_40; - v13 = this->field_3C; - v7->have_spark = rand_interval(v13,v12); - v7->field_14 = (rand() % 17 - 8) << 16; - v7->field_18 = (rand() % 17 - 8) << 16; - v14 = this->field_14 - 1; - v15 = this->field_C; - v16 = rand_interval(v15,v14); - v7->field_C = v16; - v7->spark_position.x = v16 >> 16; - v17 = this->field_18 - 1; - v18 = this->field_10; - v19 = rand_interval(v17, v18); - v7->field_10 = v19; - v7->spark_position.y = v19 >> 16; - --this->position_in_sparks_arr; - v22 = v22 - 1.0; - v6 = 1; - } - } -//LABEL_14: - ++v7; - //--v21; - //if ( !v21 ) - //{ - //this->field_58 = v6; - //this->field_30 = v22; - //return 0; - //} - } - this->field_58 = v6; - this->field_30 = v22; - } - return 0; -} - -//----- (0040E2A7) -------------------------------------------------------- -int stru272_stru0::_40E2A7() -{ - if (signature == SIG_trpg ) - { - if ( position_in_sparks_arr <= 0 ) - return field_58 != 0 ? 2 : 0; - else - return 1; - } - else - return 3; -} - -//----- (0040DFAF) -------------------------------------------------------- -void ArcomageGame::OnMouseClick(char right_left, bool bDown) -{ - if ( right_left ) - pArcomageGame->mouse_right = bDown; - else - pArcomageGame->mouse_left = bDown; -} - -//----- (0040DFC1) -------------------------------------------------------- -void ArcomageGame::OnMouseMove(int x, int y) -{ - pArcomageGame->mouse_x = x; - pArcomageGame->mouse_y = y; -} - -//----- (0040DF47) -------------------------------------------------------- -void DoBlt_Copy(unsigned __int16 *pPixels) -{ - RECT pSrcRect; - POINT pTargetPoint; // [sp+1Ch] [bp-8h]@1 - - pRenderer->Present(); - - pTargetPoint.x = 0; - pTargetPoint.y = 0; - - pSrcRect.left = 0; - pSrcRect.top = 0; - pSrcRect.right = window->GetWidth(); - pSrcRect.bottom = window->GetHeight(); - - pRenderer->BeginScene(); - pArcomageGame->pBlit_Copy_pixels = pPixels; - pRenderer->am_Blt_Copy(&pSrcRect, &pTargetPoint, 2); - pRenderer->EndScene(); - pArcomageGame->pBlit_Copy_pixels = nullptr; -} - -//----- (0040DDC9) -------------------------------------------------------- -void ArcomageGame::PlaySound( unsigned int event_id ) -{ - SoundID play_sound_id; // eax@10 - - switch ( event_id ) - { - case 40: - case 43: - case 46: - play_sound_id = SOUND_Arcomage_LoseResources; - break; - case 39: - case 41: - case 42: - case 44: - case 45: - case 47: - play_sound_id = SOUND_Arcomage_AddResources; - break; - case 0: - case 12: - case 14: - case 15: - case 16: - case 48: - case 50: - case 53: - play_sound_id = SOUND_Arcomage_TowerWallDamage; - break; - case 21: - case 22: - case 23: - play_sound_id = SOUND_Arcomage_DrawCard; - break; - case 56: - play_sound_id = SOUND_Arcomage_124; - break; - case 31: - case 34: - case 37: - play_sound_id = SOUND_Arcomage_ProductionDamage; - break; - case 1: - case 30: - case 32: - case 33: - case 35: - case 36: - case 38: - play_sound_id = SOUND_Arcomage_ProductionUpgrade; - break; - case 20: - play_sound_id = SOUND_Arcomage_127; - break; - case 3: - play_sound_id = SOUND_Arcomage_128; - break; - case 52: - case 54: - play_sound_id = SOUND_Arcomage_TowerUpgrade; - break; - case 10: - case 11: - case 13: - play_sound_id = SOUND_Arcomage_130; - break; - case 55u: - play_sound_id = SOUND_Arcomage_131; - break; - case 49: - case 51: - play_sound_id = SOUND_Arcomage_WallUpgrade; - break; - default: - return; - } - pAudioPlayer->PlaySound(play_sound_id, 0, 0, -1, 0, 0, 0, 0); -} - -//----- (0040DC2D) -------------------------------------------------------- -bool ArcomageGame::MsgLoop(int a1, ArcomageGame_stru1 *a2) -{ - void *v2; // ebp@1 - //BOOL v3; // eax@1 - - v2 = a2; - pArcomageGame->field_0 = 0; - pArcomageGame->stru1.field_0 = 0; - //v3 = PeekMessageA(&pArcomageGame->msg, 0, 0, 0, PM_REMOVE); - //if ( pArcomageGame->msg.message == WM_QUIT ) - //Game_DeinitializeAndTerminate(0); - if ( PeekMessageA(&pArcomageGame->msg, 0, 0, 0, PM_REMOVE) ) - { - if ( pArcomageGame->msg.message == WM_QUIT ) - Game_DeinitializeAndTerminate(0); - TranslateMessage(&pArcomageGame->msg); - DispatchMessageA(&pArcomageGame->msg); - } - /*if (pAsyncMouse) - { - EnterCriticalSection(&pGame->pThreadWardInstance->csAsyncMouse); - v4 = *((unsigned int *)pAsyncMouse + 7); - pArcomageGame->mouse_x = *((unsigned int *)pAsyncMouse + 6); - pArcomageGame->mouse_y = v4; - v5 = *((unsigned int *)pAsyncMouse + 27); - v6 = *(unsigned int *)v5; - if ( *(unsigned int *)v5 != v5 ) - { - do - { - v7 = *(unsigned int *)(v6 + 20); - if ( v7 & 1 ) - { - pArcomageGame->stru1.field_0 = 7; - } - else - { - if ( v7 & 2 ) - pArcomageGame->stru1.field_0 = 8; - } - v6 = *(unsigned int *)v6; - } - while ( v6 != *((unsigned int *)pAsyncMouse + 27) ); - } - pAsyncMouse->_46B944(); - if ( !*((unsigned char *)pAsyncMouse + 90) ) - pArcomageGame->field_F6 = 1; - LeaveCriticalSection(&pGame->pThreadWardInstance->csAsyncMouse); - }*/ - memcpy(v2, &pArcomageGame->stru1, 0xCu); - return pArcomageGame->stru1.field_0 != 0; -} - -//----- (0040D7D5) -------------------------------------------------------- -void am_BeginScene(unsigned __int16 *pPcxPixels, int a2, int a3) -{ - pRenderer->BeginScene(); - pArcomageGame->pBlit_Copy_pixels = pPcxPixels; -} - -//----- (0040D7EC) -------------------------------------------------------- -void Render::am_Blt_Chroma(RECT *pSrcRect, POINT *pTargetPoint, int a3, int blend_mode) -{ - unsigned __int16 *pSrc; // eax@2 - int uSrcTotalWidth; // ecx@4 - unsigned int v10; // esi@9 - int v21; // [sp+Ch] [bp-18h]@8 - unsigned __int16 *src_surf_pos; // [sp+10h] [bp-14h]@9 - __int32 src_width; // [sp+14h] [bp-10h]@3 - __int32 src_height; // [sp+18h] [bp-Ch]@3 - int uSrcPitch; // [sp+1Ch] [bp-8h]@5 - - if ( !uNumSceneBegins ) - return; - if ( !pArcomageGame->pBlit_Copy_pixels ) - return; - - //dest_surf_pos = &pRenderer->pTargetSurface[pTargetPoint->x + pTargetPoint->y * pRenderer->uTargetSurfacePitch]; - src_width = pSrcRect->right - pSrcRect->left; - src_height = pSrcRect->bottom - pSrcRect->top; - - if ( pArcomageGame->pBlit_Copy_pixels == pArcomageGame->pBackgroundPixels ) - uSrcTotalWidth = pArcomageGame->pGameBackground.uWidth; - else if ( pArcomageGame->pBlit_Copy_pixels == pArcomageGame->pSpritesPixels ) - uSrcTotalWidth = pArcomageGame->pSprites.uWidth; - - //v20 = 157; - //v19 = "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\am_nw.cpp"; - //v21 = &v18; - //std__string_char_40E2C8(&v18, "Problem in Blit_Chroma", &a3a); - //466D09_xcpt_string(&v21, v18, v19, v20); - //pSrc = pArcomageGame.pBlit_Copy_pixels; - //LABEL_9: - pSrc = pArcomageGame->pBlit_Copy_pixels; - uSrcPitch = uSrcTotalWidth; - src_surf_pos = &pSrc[pSrcRect->left + uSrcPitch * pSrcRect->top]; - v10 = 0x1F;//0xFF >> (8 - (unsigned __int8)uTargetBBits); - v21 = (uTargetGBits != 6 ? 0x31EF : 0x7BEF); - if ( blend_mode == 2 ) - { - uSrcPitch = (uSrcPitch - src_width); - for ( int i = 0; i < src_height; ++i ) - { - for ( int j = 0; j < src_width; ++j ) - { - if ( *src_surf_pos != v10 ) - { - if ( pTargetPoint->x + j >= 0 && pTargetPoint->x + j <= window->GetWidth() - 1 - && pTargetPoint->y + i >= 0 && pTargetPoint->y + i <= window->GetHeight() - 1) - WritePixel16(pTargetPoint->x + j, pTargetPoint->y + i, *src_surf_pos); - } - ++src_surf_pos; - } - src_surf_pos += uSrcPitch; - } - } - else - { - uSrcPitch = (uSrcPitch - src_width); - for ( int i = 0; i < src_height; ++i ) - { - for ( int j = 0; j < src_width; ++j ) - { - if ( *src_surf_pos != v10 ) - { - if ( pTargetPoint->x + j >= 0 && pTargetPoint->x + j <= window->GetWidth() - 1 - && pTargetPoint->y + i >= 0 && pTargetPoint->y + i <= window->GetHeight() - 1) - //WritePixel16(pTargetPoint->x + j, pTargetPoint->y + i, (v21 & (ReadPixel16(pTargetPoint->x + j, pTargetPoint->y + i) >> 1)) + (v21 & (*src_surf_pos >> 1))); - WritePixel16(pTargetPoint->x + j, pTargetPoint->y + i, (0x7BEF & (*src_surf_pos / 2))); - } - ++src_surf_pos; - } - src_surf_pos+=uSrcPitch; - } - } -} - -//----- (0040D9B1) -------------------------------------------------------- -void Render::am_Blt_Copy( RECT *pSrcRect, POINT *pTargetPoint, int blend_mode ) -{ - unsigned __int16 *pSrc; // eax@2 - int uSrcTotalWidth; // ecx@4 - int v21; // [sp+Ch] [bp-18h]@8 - unsigned __int16 *src_surf_pos; // [sp+10h] [bp-14h]@9 - __int32 src_width; // [sp+14h] [bp-10h]@3 - __int32 src_height; // [sp+18h] [bp-Ch]@3 - int uSrcPitch; // [sp+1Ch] [bp-8h]@5 - - if ( !uNumSceneBegins ) - return; - if ( !pArcomageGame->pBlit_Copy_pixels ) - return; - - //dest_surf_pos = &pRenderer->pTargetSurface[pTargetPoint->x + pTargetPoint->y * pRenderer->uTargetSurfacePitch]; - src_width = pSrcRect->right - pSrcRect->left; - src_height = pSrcRect->bottom - pSrcRect->top; - if ( pArcomageGame->pBlit_Copy_pixels == pArcomageGame->pBackgroundPixels ) - uSrcTotalWidth = pArcomageGame->pGameBackground.uWidth; - else if ( pArcomageGame->pBlit_Copy_pixels == pArcomageGame->pSpritesPixels ) - uSrcTotalWidth = pArcomageGame->pSprites.uWidth; - - //v20 = 157; - //v19 = "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\am_nw.cpp"; - //v21 = &v18; - //std__string_char_40E2C8(&v18, "Problem in Blit_Chroma", &a3a); - //466D09_xcpt_string(&v21, v18, v19, v20); - //pSrc = pArcomageGame.pBlit_Copy_pixels; - //LABEL_9: - pSrc = pArcomageGame->pBlit_Copy_pixels; - uSrcPitch = uSrcTotalWidth; - src_surf_pos = &pSrc[pSrcRect->left + uSrcPitch * pSrcRect->top]; - v21 = (uTargetGBits != 6 ? 0x31EF : 0x7BEF); - - if ( blend_mode == 2 ) - { - uSrcPitch = (uSrcPitch - src_width); - for ( int i = 0; i < src_height; ++i ) - { - for ( int j = 0; j < src_width; ++j ) - { - if ( *src_surf_pos != v21 ) - { - if ( pTargetPoint->x + j >= 0 && pTargetPoint->x + j <= window->GetWidth() - 1 - && pTargetPoint->y + i >= 0 && pTargetPoint->y + i <= window->GetHeight() - 1) - WritePixel16(pTargetPoint->x + j, pTargetPoint->y + i, *src_surf_pos); - } - ++src_surf_pos; - } - src_surf_pos += uSrcPitch; - } - } - else - { - uSrcPitch = (uSrcPitch - src_width); - for ( int i = 0; i < src_height; ++i ) - { - for ( int j = 0; j < src_width; ++j ) - { - if ( *src_surf_pos != v21 ) - { - if ( pTargetPoint->x + j >= 0 && pTargetPoint->x + j <= window->GetWidth() - 1 - && pTargetPoint->y + i >= 0 && pTargetPoint->y + i <= window->GetHeight() - 1) - //WritePixel16(pTargetPoint->x + j, pTargetPoint->y + i, (v21 & (ReadPixel16(pTargetPoint->x + j, pTargetPoint->y + i) / 2)) + (v21 & (*src_surf_pos / 2))); - WritePixel16(pTargetPoint->x + j, pTargetPoint->y + i, (0x7BEF & (*src_surf_pos / 2))); - } - ++src_surf_pos; - } - src_surf_pos += uSrcPitch; - } - } -} - -//----- (0040DB10) -------------------------------------------------------- -void am_EndScene() -{ - pRenderer->EndScene(); - pArcomageGame->pBlit_Copy_pixels = nullptr; -} - -//----- (0040D7B7) -------------------------------------------------------- -bool ArcomageGame::LoadSprites() -{ - pArcomageGame->pSprites.Load("sprites.pcx", 2); - pArcomageGame->pSpritesPixels = pArcomageGame->pSprites.pPixels; - return true; -} - -//----- (0040D799) -------------------------------------------------------- -bool ArcomageGame::LoadBackground() -{ - pArcomageGame->pGameBackground.Load("layout.pcx", 2); - pArcomageGame->pBackgroundPixels = pArcomageGame->pGameBackground.pPixels; - return true; -} - -int CalculateCardPower(ArcomagePlayer* player, ArcomagePlayer* enemy, ArcomageCard* pCard, int mastery) -{ - enum V_INDX{ - P_TOWER_M10, - P_WALL_M10, - E_TOWER, - E_WALL, - E_BUILDINGS, - E_QUARRY, - E_MAGIC, - E_ZOO, - E_RES, - V_INDEX_MAX - }; - - const int mastery_coeff[V_INDEX_MAX][2]= {{10, 5}, //P_TOWER_M10 - {2, 1}, //P_WALL_M10 - {1, 10}, //E_TOWER - {1, 3}, //E_WALL - {1, 7}, //E_BUILDINGS - {1, 5}, //E_QUARRY - {1, 40}, //E_MAGIC - {1, 40}, //E_ZOO - {1, 2} //E_RES - }; - int card_power= 0; - int element_power; - - if ( pCard->to_player_tower == 99 || pCard->to_pl_enm_tower == 99|| - pCard->to_player_tower2 == 99 || pCard->to_pl_enm_tower2 == 99 ) - element_power = enemy->tower_height - player->tower_height; - else - element_power = pCard->to_player_tower + pCard->to_pl_enm_tower + pCard->to_player_tower2 + pCard->to_pl_enm_tower2; - - if ( player->tower_height >= 10 ) - card_power += mastery_coeff[P_TOWER_M10][mastery]*element_power; - else - card_power += 20*element_power; - - - if ( pCard->to_player_wall == 99 || pCard->to_pl_enm_wall == 99 || - pCard->to_player_wall2 == 99 || pCard->to_pl_enm_wall2 == 99 ) - element_power = enemy->wall_height - player->wall_height; - else - element_power = pCard->to_player_wall + pCard->to_pl_enm_wall + - pCard->to_player_wall2 + pCard->to_pl_enm_wall2; - if ( player->wall_height >= 10 ) - card_power += mastery_coeff[P_WALL_M10][mastery]*element_power; //1 - else - card_power += 5*element_power; - - - card_power += 7 * (pCard->to_player_buildings + pCard->to_pl_enm_buildings + - pCard->to_player_buildings2 + pCard->to_pl_enm_buildings2); - - if ( pCard->to_player_quarry_lvl == 99 || pCard->to_pl_enm_quarry_lvl == 99 || - pCard->to_player_quarry_lvl2 == 99 || pCard->to_pl_enm_quarry_lvl2 == 99 ) - element_power = enemy->quarry_level - player->quarry_level; - else - element_power = pCard->to_player_quarry_lvl + pCard->to_pl_enm_quarry_lvl + - pCard->to_player_quarry_lvl2 + pCard->to_pl_enm_quarry_lvl; - - card_power += 40 * element_power; - - if ( pCard->to_player_magic_lvl == 99 || pCard->to_pl_enm_magic_lvl == 99 || - pCard->to_player_magic_lvl2 == 99 || pCard->to_pl_enm_magic_lvl2 == 99 ) - element_power = enemy->magic_level - player->magic_level; - else - element_power = pCard->to_player_magic_lvl + pCard->to_pl_enm_magic_lvl + - pCard->to_player_magic_lvl2 + pCard->to_pl_enm_magic_lvl2; - card_power += 40 *element_power; - - if ( pCard->to_player_zoo_lvl == 99 || pCard->to_pl_enm_zoo_lvl == 99 || - pCard->to_player_zoo_lvl2 == 99 || pCard->to_pl_enm_zoo_lvl2 == 99 ) - element_power = enemy->zoo_level - player->zoo_level; - else - element_power = pCard->to_player_zoo_lvl + pCard->to_pl_enm_zoo_lvl + - pCard->to_player_zoo_lvl2 + pCard->to_pl_enm_zoo_lvl2; - card_power += 40 *element_power; - - if ( pCard->to_player_bricks == 99 || pCard->to_pl_enm_bricks == 99 || - pCard->to_player_bricks2 == 99 || pCard->to_pl_enm_bricks2 == 99 ) - element_power = enemy->resource_bricks - player->resource_bricks; - else - element_power = pCard->to_player_bricks + pCard->to_pl_enm_bricks + - pCard->to_player_bricks2 + pCard->to_pl_enm_bricks2; - card_power += 2 *element_power; - - - if ( pCard->to_player_gems == 99 || pCard->to_pl_enm_gems == 99 || - pCard->to_player_gems2 == 99 || pCard->to_pl_enm_gems2 == 99 ) - element_power = enemy->resource_gems - player->resource_gems; - else - element_power = pCard->to_player_gems + pCard->to_pl_enm_gems + - pCard->to_player_gems2 + pCard->to_pl_enm_gems2; - card_power += 2 *element_power; - - if ( pCard->to_player_beasts == 99 || pCard->to_pl_enm_beasts == 99 || - pCard->to_player_beasts2 == 99 || pCard->to_pl_enm_beasts2 == 99 ) - element_power = enemy->resource_beasts - player->resource_beasts; - else - element_power = pCard->to_player_beasts + pCard->to_pl_enm_beasts + - pCard->to_player_beasts2 + pCard->to_pl_enm_beasts2; - card_power += 2 *element_power; - - if ( pCard->to_enemy_tower == 99 || pCard->to_enemy_tower2 == 99 ) - element_power = player->tower_height - enemy->tower_height; - else - element_power = -(pCard->to_enemy_tower + pCard->to_enemy_tower2); - card_power += mastery_coeff[E_TOWER][mastery]*element_power; - - if ( pCard->to_enemy_wall == 99 || pCard->to_enemy_wall2 == 99 ) - element_power = player->wall_height - enemy->wall_height; - else - element_power = -(pCard->to_enemy_wall + pCard->to_enemy_wall2); - card_power += mastery_coeff[E_WALL][mastery]*element_power; - - card_power -= mastery_coeff[E_BUILDINGS][mastery]*(pCard->to_enemy_buildings + pCard->to_enemy_buildings2); - - if ( pCard->to_enemy_quarry_lvl == 99 || pCard->to_enemy_quarry_lvl2 == 99 ) - element_power = player->quarry_level - enemy->quarry_level; //5 - else - element_power = -(pCard->to_enemy_quarry_lvl + pCard->to_enemy_quarry_lvl2); //5 - card_power += mastery_coeff[E_QUARRY][mastery]*element_power; - - if ( pCard->to_enemy_magic_lvl == 99 || pCard->to_enemy_magic_lvl2 == 99 ) - element_power = player->magic_level - enemy->magic_level; //40 - else - element_power = -(pCard->to_enemy_magic_lvl + pCard->to_enemy_magic_lvl2); - card_power += mastery_coeff[E_MAGIC][mastery]*element_power; - - if ( pCard->to_enemy_zoo_lvl == 99 || pCard->to_enemy_zoo_lvl2 == 99 ) - element_power = player->zoo_level - enemy->zoo_level; //40 - else - element_power = -(pCard->to_enemy_zoo_lvl + pCard->to_enemy_zoo_lvl2); - card_power += mastery_coeff[E_ZOO][mastery]*element_power; - - if ( pCard->to_enemy_bricks == 99 || pCard->to_enemy_bricks2 == 99 ) - element_power = player->resource_bricks - enemy->resource_bricks; //2 - else - element_power = -(pCard->to_enemy_bricks + pCard->to_enemy_bricks2); - card_power += mastery_coeff[E_RES][mastery]*element_power; - - if ( pCard->to_enemy_gems == 99 || pCard->to_enemy_gems2 == 99 ) - element_power = player->resource_gems - enemy->resource_gems; //2 - else - element_power = -(pCard->to_enemy_gems + pCard->to_enemy_gems2); - card_power += mastery_coeff[E_RES][mastery]*element_power; - - if ( pCard->to_enemy_beasts == 99 || pCard->to_enemy_beasts2 == 99 ) - element_power = player->resource_beasts - enemy->resource_beasts; //2 - else - element_power = -(pCard->to_enemy_beasts + pCard->to_enemy_beasts2); - card_power += mastery_coeff[E_RES][mastery]*element_power; - - if ( pCard->field_30 || pCard->field_4D ) - card_power *= 10; - - if ( pCard->field_24 == 1 ) - element_power = player->resource_bricks - pCard->needed_bricks; - else if ( pCard->field_24 == 2 ) - element_power = player->resource_gems - pCard->needed_gems; - else if (pCard->field_24 == 3) - element_power = player->resource_beasts - pCard->needed_beasts; - if ( element_power > 3 ) - element_power = 3; - card_power += 5 * element_power; - - if ( enemy->tower_height <= pCard->to_enemy_tower2 + pCard->to_enemy_tower ) - card_power += 9999; - - if (pCard->to_enemy_tower2 + pCard->to_enemy_tower + - pCard->to_enemy_wall + pCard->to_enemy_wall2 + - pCard->to_enemy_buildings + pCard->to_enemy_buildings2 >= enemy->wall_height + enemy->tower_height) - card_power += 9999; - - if ( (pCard->to_player_tower2 + pCard->to_pl_enm_tower2 + pCard->to_player_tower + pCard->to_pl_enm_tower + player->tower_height) - >= max_tower_height ) - card_power += 9999; - - return card_power; -} - -//----- (00408BB4) -------------------------------------------------------- -bool OpponentsAITurn(int player_num) -{ - int all_player_cards_count; // eax@9 - int random_card_slot; // edi@9 - ArcomageCard *v12; // ecx@20 - int v56; // ecx@141 - int v57; // edx@141 -// int v64; // eax@169 -// ArcomageCard *pCard; // ecx@169 -// char v66; // dl@169 -// char v67; // dl@173 -// int v68; // edx@174 - int v132; // [sp-14h] [bp-14h]@0 - ArcomagePlayer *enemy; // [sp-10h] [bp-10h]@5 - ArcomagePlayer *player; // [sp-Ch] [bp-Ch]@5 - - byte_4FAA00 = 1; - if ( opponent_mastery == 0) - { - if ( need_to_discard_card == 0 ) //am_byte_4FAA77 - { - for(int i = 0; i < 10; ++i ) - { - all_player_cards_count = GetPlayerHandCardCount(player_num); - random_card_slot = rand_interval(0, all_player_cards_count - 1); - if ( CanCardBePlayed(player_num, random_card_slot) ) - return PlayCard(player_num, random_card_slot); - } - } - all_player_cards_count = GetPlayerHandCardCount(player_num); - random_card_slot= rand_interval(0, all_player_cards_count - 1); - return DiscardCard(player_num, random_card_slot); - } - else if (( opponent_mastery == 1 )|| ( opponent_mastery == 2 )) - { - player = &am_Players[player_num]; - enemy = &am_Players[(player_num + 1) % 2]; - all_player_cards_count = GetPlayerHandCardCount(player_num); - for(int i = 0; i < 10 ; ++i ) - { - if ( i >= all_player_cards_count ) - { - cards_power[i].slot_index = -1; - cards_power[i].card_power = -9999; - } - else - { - cards_power[i].slot_index = i; - cards_power[i].card_power = 0; - } - } - for(int i = 0; i < all_player_cards_count ; ++i ) - { - v12 = &pCards[am_Players[player_num].cards_at_hand[cards_power[i].slot_index]]; - cards_power[i].card_power = CalculateCardPower(player, enemy, v12, opponent_mastery-1); - } - - for (int j = all_player_cards_count - 1; j >= 0; --j ) - { - for (int m = 0; m < j; ++m ) - { - if ( cards_power[m].card_power < cards_power[m + 1].card_power ) - { - v56 = cards_power[m].slot_index; - v57 = cards_power[m].card_power; - cards_power[m].slot_index = cards_power[m + 1].slot_index; - cards_power[m].card_power = cards_power[m + 1].card_power; - cards_power[m + 1].slot_index = cards_power[m].slot_index; - cards_power[m + 1].card_power = cards_power[m].card_power; - } - } - } - if ( need_to_discard_card ) - { - for ( int i = all_player_cards_count - 1; i; --i ) - { - if ( pCards[am_Players[player_num].cards_at_hand[cards_power[i].slot_index]].can_be_discarded ) - v132 = cards_power[i].slot_index; - } - } - else - { - for ( int i = all_player_cards_count - 1; i; --i ) - { - if ( pCards[am_Players[player_num].cards_at_hand[cards_power[i].slot_index]].can_be_discarded ) - v132 = cards_power[i].slot_index; - } - for ( int i = 0; i < all_player_cards_count - 1; ++i ) - { - if ( CanCardBePlayed(player_num, cards_power[i].slot_index) && cards_power[i].card_power ) - return PlayCard(player_num, cards_power[i].slot_index); - } - } - return DiscardCard(player_num, v132); - } - return true;//result != 0; -} - -//----- (00409E6A) -------------------------------------------------------- -void ArcomageGame::Loop() -{ - while ( !pArcomageGame->GameOver ) - { - pArcomageGame->field_F6 = 1; - byte_4FAA24 = 1; - IncreaseResourcesInTurn(current_player_num); -//LABEL_8: - while ( byte_4FAA24 ) - { - played_card_id = -1; - GetNextCardFromDeck(current_player_num); - while ( 1 ) - { - byte_4FAA24 = PlayerTurn(current_player_num); - if (GetPlayerHandCardCount(current_player_num) <= minimum_cards_at_hand) - { - need_to_discard_card = 0; - break; - } - need_to_discard_card = 1; - if (pArcomageGame->field_F4) - break; - } - } - pArcomageGame->GameOver = IsGameOver(); - if ( !pArcomageGame->GameOver ) - TurnChange(); - if ( pArcomageGame->field_F4 ) - pArcomageGame->GameOver = 1; - } - GameResultsApply(); - if ( am_gameover ) - dword_4FAA70 = 0; - else - dword_4FAA70 = -1; - - for( int i = 0; i < 10; ++i ) - { - array_4FABD0[i].field_40->Clear(1, 1); - array_4FABD0[i].field_40->Free(); - } - - pArcomageGame->pGameBackground.Release(); - pArcomageGame->pSprites.Release(); - pArcomageGame->bGameInProgress = false; - viewparams->bRedrawGameUI = true; - if ( pMovie_Track ) - BackToHouseMenu(); - for( int i = 0; i < 12; ++i ) - pSoundList->UnloadSound(am_sounds[i], 1); -} - -//----- (00409FE9) -------------------------------------------------------- -void SetStartGameData() -{ - signed int j; // edx@7 - int card_id_counter; // edx@13 - signed int i; // ecx@13 - signed int card_dispenser_counter; // eax@13 - - current_player_num = am_default_starting_player; - SetStartConditions(); - for( i = 0; i < 2; ++i ) - { - if ( i ) - { - strcpy(am_Players[1].pPlayerName, pArcomageGame->pPlayer2Name); - if ( byte_4E185C ) - am_Players[1].IsHisTurn = 0; - else - am_Players[1].IsHisTurn = 1; - } - else - { - strcpy(am_Players[0].pPlayerName, pArcomageGame->pPlayer1Name); - am_Players[0].IsHisTurn = 1; - } - am_Players[i].tower_height = start_tower_height; - am_Players[i].wall_height = start_wall_height; - am_Players[i].quarry_level = start_quarry_level; - am_Players[i].magic_level = start_magic_level; - am_Players[i].zoo_level = start_zoo_level; - am_Players[i].resource_bricks = start_bricks_amount; - am_Players[i].resource_gems = start_gems_amount; - am_Players[i].resource_beasts = start_beasts_amount; - - for ( j = 0; j < 10; ++j ) - { - am_Players[i].cards_at_hand[j] = -1; - if ( am_byte_4E185D ) - { - am_Players[i].card_shift[j].x = -1; - am_Players[i].card_shift[j].y = -1; - } - else - { - am_Players[i].card_shift[j].x = 0; - am_Players[i].card_shift[j].y = 0; - } - } - } - strcpy(deckMaster.name, "Master Deck"); - for ( i = 0, card_dispenser_counter = -2, card_id_counter = 0; i < DECK_SIZE; ++i, ++card_dispenser_counter) - { - deckMaster.cardsInUse[i] = 0; - deckMaster.cards_IDs[i] = card_id_counter; - switch ( card_dispenser_counter ) - { - case 0: - case 2: - case 6: - case 9: - case 13: - case 18: - case 23: - case 33: - case 36: - case 38: - case 44: - case 46: - case 52: - case 57: - case 69: - case 71: - case 75: - case 79: - case 81: - case 84: - case 89: - break; - default: - ++card_id_counter; - } - } - FillPlayerDeck(); -} - -//----- (0040A198) -------------------------------------------------------- -void FillPlayerDeck() - { - signed int m; - int rand_deck_pos; - char card_taken_flags[DECK_SIZE]; - int i,j; - - ArcomageGame::PlaySound(20); - memset(deckMaster.cardsInUse, 0,DECK_SIZE ); - memset(card_taken_flags, 0, DECK_SIZE); - - for ( i = 0; i < 2; ++i ) - { - for ( j = 0; j < 10; ++j ) - { - if ( am_Players[i].cards_at_hand[j] > -1 ) - { - for (m = 0; mfield_F6 = 1; - -} - -//----- (0040A255) -------------------------------------------------------- -void InitalHandsFill() -{ - for (int i = 0; i < minimum_cards_at_hand; ++i ) - { - GetNextCardFromDeck(0); - GetNextCardFromDeck(1); - } - pArcomageGame->field_F6 = 1; -} -// 4E1874: using guessed type int dword_4E1874; - -//----- (0040A283) -------------------------------------------------------- -void GetNextCardFromDeck( int player_num ) -{ - signed int deck_index; // eax@1 - int new_card_id; // edi@1 - signed int card_slot_indx; // eax@7 - - deck_index = deck_walk_index; - for(;;) - { - if ( deck_index >= DECK_SIZE ) - { - FillPlayerDeck(); - deck_index = deck_walk_index; - } - if ( !playDeck.cardsInUse[deck_index] ) - { - new_card_id = playDeck.cards_IDs[deck_index]; - ++deck_index; - deck_walk_index = deck_index; - break; - } - ++deck_index; - deck_walk_index = deck_index; - } - - ArcomageGame::PlaySound(21); - card_slot_indx = GetEmptyCardSlotIndex(player_num); - if ( card_slot_indx != -1 ) - { - amuint_4FAA4C = card_slot_indx; - am_Players[player_num].cards_at_hand[card_slot_indx] = new_card_id; - am_Players[player_num].card_shift[card_slot_indx].x = rand_interval(-4, 4); - am_Players[player_num].card_shift[card_slot_indx].y = rand_interval(-4, 4); - pArcomageGame->field_F6 = 1; - byte_4FAA2D = 1; - } -} - -//----- (0040A324) -------------------------------------------------------- -int GetEmptyCardSlotIndex( int player_num ) -{ - for ( int i = 0; i < 10; ++i ) - { - if (am_Players[player_num].cards_at_hand[i] == -1) - return i; - } - return -1; -} - -//----- (0040A346) -------------------------------------------------------- -void IncreaseResourcesInTurn(int player_num) -{ - am_Players[player_num].resource_bricks += quarry_bonus + am_Players[player_num].quarry_level; - am_Players[player_num].resource_gems += magic_bonus + am_Players[player_num].magic_level; - am_Players[player_num].resource_beasts += zoo_bonus + am_Players[player_num].zoo_level; -} - - -//----- (0040A383) -------------------------------------------------------- -void TurnChange() -{ - char player_name[64]; // [sp+4h] [bp-64h]@4 - // RECT v6; // [sp+44h] [bp-24h]@6 - ArcomageGame_stru1 v10; // [sp+54h] [bp-14h]@7 - POINT v11; // [sp+60h] [bp-8h]@4 - - if ( !pArcomageGame->field_F4 ) - { - if ( am_Players[0].IsHisTurn != 1 || am_Players[1].IsHisTurn != 1 ) - { - ++current_player_num; - am_byte_4FAA75 = 1; - if ( current_player_num >= 2 ) - current_player_num = 0; - } - else - { - //nullsub_1(); - // v11.x = 0; - // v11.y = 0; - strcpy(player_name, "The Next Player is: ");//"След" - // v0 = 0; - v11.y = 200; - v11.x = 320; // - 12 * v0 / 2; - am_DrawText(-1, player_name, &v11); - am_byte_4FAA75 = 1; - ++current_player_num; - if ( current_player_num >= 2 ) - current_player_num = 0; - strcpy(player_name, am_Players[current_player_num].pPlayerName); - // v4 = 0; - v11.y = 260; - v11.x = 320;// - 12 * v4 / 2; - am_DrawText(-1, player_name, &v11); - /* v6.left = 0; - v6.right = 640; - v6.top = 0; - v6.bottom = 480;*/ - //nullsub_1(); - pRenderer->Present(); - //nullsub_1(); - while ( 1 ) - { - while ( !ArcomageGame::MsgLoop(20, &v10) ) - ; - if ( v10.field_0 == 1 ) - { - if ( v10.field_4 ) - break; - //nullsub_1(); - continue; - } - if (( v10.field_0 > 4 ) && ( v10.field_0 <= 8 )) - break; - if ( v10.field_0 == 10 ) - { - pArcomageGame->field_F4 = 1; - byte_4FAA74 = 1; - break; - } - } - /* v11.x = 0; - v11.y = 0; - v6.left = 0; - v6.right = 640; - v6.top = 0; - v6.bottom = 480;*/ - //nullsub_1(); - pRenderer->Present(); - } - } -} - -//----- (0040A514) -------------------------------------------------------- -bool IsGameOver() -{ - bool result; // eax@1 - - result = false; - for( int i = 0; i < 2; ++i ) - { - if ( am_Players[i].tower_height <= 0 ) - result = true; - if ( am_Players[i].tower_height >= max_tower_height ) - result = true; - if ( am_Players[i].resource_bricks >= max_resources_amount - || am_Players[i].resource_gems >= max_resources_amount - || am_Players[i].resource_beasts >= max_resources_amount ) - result = true; - } - - return am_gameover = result; -} - -//----- (0040A560) -------------------------------------------------------- -char PlayerTurn( int player_num ) -{ -// int v1; // ebp@0 -// unsigned __int64 v2; // qax@3 - unsigned __int64 v3; // kr00_8@3 - -// int v5; // esi@67 -// char Dest[100]; // [sp+8h] [bp-A8h]@67 -// int v8; // [sp+6Ch] [bp-44h]@3 - RECT pSrcXYZW; // [sp+70h] [bp-40h]@75 -// int v10[4]; // [sp+80h] [bp-30h]@69 - POINT pTargetXY; // [sp+90h] [bp-20h]@75 - ArcomageGame_stru1 a2; // [sp+98h] [bp-18h]@8 - int animation_stage; // [sp+A4h] [bp-Ch]@1 -// char v15; // [sp+AEh] [bp-2h]@63 - bool break_loop; // [sp+AFh] [bp-1h]@1 - - uCardID = -1; - break_loop = false; - animation_stage = 20; - byte_4FAA00 = 0; - dword_4FAA68 = 0; - amuint_4FAA38 = 10; - amuint_4FAA34 = 5; - if ( amuint_4FAA4C != -1 ) - byte_4FAA2D = 1; - do - { - do - { - v3 = pEventTimer->Time() - pArcomageGame->event_timer_time; - } - while (v3 < 6); - pArcomageGame->event_timer_time = (unsigned int)pEventTimer->Time(); - if ( pArcomageGame->field_F4 ) - break_loop = true; - ArcomageGame::MsgLoop(0, &a2); - switch ( a2.field_0 ) - { - case 2: - if ( a2.field_4 == 129 && a2.field_8 == 1 ) - { - pAudioPlayer->StopChannels(-1, -1); - dword_4FAA68 = 0; - break_loop = true; - pArcomageGame->field_F4 = 1; - } - break; - case 9: - pArcomageGame->field_F6 = 1; - break; - case 10: - pAudioPlayer->StopChannels(-1, -1); - byte_4FAA74 = 1; - break_loop = true; - pArcomageGame->field_F4 = 1; - break; - } - - if (am_Players[current_player_num].IsHisTurn != 1 && - !byte_4FAA00 && !byte_4FAA2E && !byte_4FAA2D ) - { - if ( am_byte_4FAA75 ) - am_byte_4FAA76 = 1; - OpponentsAITurn(current_player_num); - byte_4FAA2E = 1; - } - if ( amuint_4FAA4C != -1 && amuint_4FAA38 > 10 ) - amuint_4FAA38 = 10; - if ( byte_4FAA2E || byte_4FAA2D ||am_Players[current_player_num].IsHisTurn != 1 ) - { - pArcomageGame->field_F6 = 1; - if ( byte_4FAA2D ) - { - --amuint_4FAA38; - if ( amuint_4FAA38 < 0 ) - { - byte_4FAA2D = 0; - amuint_4FAA38 = 10; - break_loop = false; - } - } - if ( byte_4FAA2E ) - { - --animation_stage; - if ( animation_stage < 0 ) - { - if ( dword_4FAA68 > 1 ) - { - --dword_4FAA68; - byte_4FAA00 = 0; - } - else - break_loop = true; - byte_4FAA2E = 0; - animation_stage = 20; - } - } - } - else - { - if ( need_to_discard_card ) - { - if ( a2.field_0 == 7 && DiscardCard(player_num, current_card_slot_index) ) - { - if ( am_byte_4FAA75 ) - am_byte_4FAA76 = 1; - if ( dword_4FAA64 > 0 ) - { - --dword_4FAA64; - need_to_discard_card = GetPlayerHandCardCount(player_num) > minimum_cards_at_hand; - } - byte_4FAA2E = 1; - } - if ( a2.field_0 == 8 && DiscardCard(player_num, current_card_slot_index) ) - { - if ( am_byte_4FAA75 ) - am_byte_4FAA76 = 1; - if ( dword_4FAA64 > 0 ) - { - --dword_4FAA64; - need_to_discard_card = GetPlayerHandCardCount(player_num) > minimum_cards_at_hand; - } - byte_4FAA2E = 1; - } - } - else - { - if ( a2.field_0 == 7 ) - { - if ( PlayCard(player_num, current_card_slot_index) ) - { - byte_4FAA2E = 1; - if ( am_byte_4FAA75 ) - am_byte_4FAA76 = 1; - } - } - if ( a2.field_0 == 8 ) - { - if ( DiscardCard(player_num, current_card_slot_index) ) - { - byte_4FAA2E = 1; - if ( am_byte_4FAA75 ) - am_byte_4FAA76 = 1; - } - } - } - } - //nullsub_1(); - //if ( false ) - //{ - // if ( !v15 ) - // { - // //nullsub_1(); - // v15 = 1; - // } - //} - //else - //{ - // v15 = 0; - // } - //if ( false ) - //{ - // //nullsub_1(); - // //nullsub_1(); - // // assert(false && "Invalid strcpy params"); - // // inv_strcpy(nullptr, Dest); - // v5 = 0;//unk::const_0(&unk_4E19FC, 0); - // //nullsub_1(); - // if ( v5 == 1 ) - // { - // pAudioPlayer->StopChannels(-1, -1); - // v16 = 1; - // pArcomageGame->field_F4 = 1; - // dword_4FAA68 = 0; - // } - // /*v10[0] = 0; - // v10[2] = 640; - // v10[1] = 0; - // v10[3] = 480;*/ - // //nullsub_1(); - //} - if ( dword_4FABB8 != DrawCardsRectangles(player_num) ) - { - dword_4FABB8 = DrawCardsRectangles(player_num); - pArcomageGame->field_F6 = 1; - } - if ( pArcomageGame->field_F6 ) - { - DrawGameUI(animation_stage); - DoBlt_Copy(pArcomageGame->pBackgroundPixels); - pArcomageGame->field_F6 = 0; - } - if ( pArcomageGame->field_F9 ) - { - pTargetXY.x = 0; - pTargetXY.y = 0; - pSrcXYZW.left = 0; - pSrcXYZW.right = window->GetWidth(); - pSrcXYZW.top = 0; - pSrcXYZW.bottom = window->GetHeight(); - am_BeginScene(pArcomageGame->pBackgroundPixels, -1, 1); - pRenderer->am_Blt_Copy(&pSrcXYZW, &pTargetXY, 2); - am_EndScene(); - DrawGameUI(animation_stage); - pRenderer->Present(); - pArcomageGame->field_F9 = 0; - } - } - while ( !break_loop ); - return dword_4FAA68 > 0; -} - - -//----- (0040A9AF) -------------------------------------------------------- -void DrawGameUI( int animation_stage ) -{ - am_BeginScene(pArcomageGame->pSpritesPixels, -1, 1); - DrawRectanglesForText(); - am_EndScene(); - - am_BeginScene(pArcomageGame->pSpritesPixels, -1, 1); - DrawCards();//рисуем карты - DrawPlayersTowers();//рисуем башню - DrawPlayersWall();//рисуем стену - DrawPlayersText();//рисуем текст - am_EndScene(); - - am_BeginScene(pArcomageGame->pSpritesPixels, -1, 1); - DrawCardAnimation(animation_stage); - - for( int i = 0; i < 10; ++i ) - { - if (array_4FABD0[i].have_effect) - array_4FABD0[i].field_40->DrawEffect(); - } - current_card_slot_index = DrawCardsRectangles(current_player_num); - DrawSparks(); - am_EndScene(); -} - -//----- (0040AA4E) -------------------------------------------------------- -void DrawSparks() -{ - int rgb_pixel_color; // [sp-4h] [bp-2Ch]@4 - unsigned int pixel_color; - - for ( int i = 0; i < 10; ++i ) - { - if(array_4FABD0[i].have_effect && (array_4FABD0[i].field_40->_40E2A7()==2)) - { - rgb_pixel_color = 0x0000FF00; - if ( !array_4FABD0[i].effect_sign ) - rgb_pixel_color = 0x000000FF; - pixel_color = R8G8B8_to_TargetFormat(rgb_pixel_color); - for( int j = 0; j < 150; ++j ) - { - if (array_4FABD0[i].effect_sparks[j].have_spark > 0) - { - if ( j%2 ) - DrawPixel(&array_4FABD0[i].effect_sparks[j].spark_position, pixel_color); - else - DrawSquare(&array_4FABD0[i].effect_sparks[j].spark_position, pixel_color); - } - } - } - } -} - -//----- (0040AB0A) -------------------------------------------------------- -void DrawRectanglesForText() -{ - RECT pSrcRect; // [sp+Ch] [bp-18h]@1 - POINT pTargetXY; // [sp+1Ch] [bp-8h]@1 - -//resources rectangles - pSrcRect.left = 765; - pSrcRect.top = 0; - pSrcRect.right = 843; - pSrcRect.bottom = 216; - - pTargetXY.x = 8; - pTargetXY.y = 56; - pRenderer->am_Blt_Copy(&pSrcRect, &pTargetXY, 2); - - pTargetXY.x = 555; - pTargetXY.y = 56; - pRenderer->am_Blt_Copy(&pSrcRect, &pTargetXY, 2); - - //players name rectangle - pSrcRect.left = 283; - pSrcRect.top = 166; - pSrcRect.right = 361; - pSrcRect.bottom = 190; - pTargetXY.x = 8; - pTargetXY.y = 13; - pRenderer->am_Blt_Chroma(&pSrcRect, &pTargetXY, pArcomageGame->field_54, 2); - - pTargetXY.x = 555; - pTargetXY.y = 13; - pRenderer->am_Blt_Chroma(&pSrcRect, &pTargetXY, pArcomageGame->field_54, 2); - - //tower height rectangle - pSrcRect.left = 234; - pSrcRect.top = 166; - pSrcRect.right = 283; - pSrcRect.bottom = 190; - pTargetXY.x = 100; - pTargetXY.y = 296; - pRenderer->am_Blt_Chroma(&pSrcRect, &pTargetXY, pArcomageGame->field_54, 2); - - pTargetXY.x = 492; - pTargetXY.y = 296; - pRenderer->am_Blt_Chroma(&pSrcRect, &pTargetXY, pArcomageGame->field_54, 2); - - //wall height rectangle - pSrcRect.left = 192; - pSrcRect.top = 166; - pSrcRect.right = 234; - pSrcRect.bottom = 190; - pTargetXY.x = 168; - pTargetXY.y = 296; - pRenderer->am_Blt_Chroma(&pSrcRect, &pTargetXY, pArcomageGame->field_54, 2); - - pTargetXY.x = 430; - pTargetXY.y = 296; - pRenderer->am_Blt_Chroma(&pSrcRect, &pTargetXY, pArcomageGame->field_54, 2); -} - -//----- (0040AC5F) -------------------------------------------------------- -void DrawPlayersText() -{ - int res_value; // ecx@18 - char text_buff[32]; // [sp+Ch] [bp-28h]@2 - POINT text_position; // [sp+2Ch] [bp-8h]@2 - - if ( need_to_discard_card ) - { - strcpy(text_buff, pGlobalTXT_LocalizationStrings[266]);// DISCARD A CARD - text_position.x = 320 - pArcomageGame->pfntArrus->GetLineWidth(text_buff) / 2; - text_position.y = 306; - am_DrawText(-1, text_buff, &text_position); - } - strcpy( text_buff, am_Players[0].pPlayerName); - if ( !current_player_num ) - strcat(text_buff, "***"); - text_position.x = 47 - pArcomageGame->pfntComic->GetLineWidth(text_buff) / 2; - text_position.y = 21; - am_DrawText(-1, text_buff, &text_position); - - strcpy(text_buff, am_Players[1].pPlayerName); - if ( current_player_num == 1 ) - strcat(text_buff, "***" ); - text_position.x = 595 - pArcomageGame->pfntComic->GetLineWidth(text_buff) / 2; - text_position.y = 21; - am_DrawText(-1, text_buff, &text_position); - - am_IntToString(am_Players[0].tower_height, text_buff); - text_position.x = 123 - pArcomageGame->pfntComic->GetLineWidth(text_buff) / 2; - text_position.y = 305; - am_DrawText(-1, text_buff, &text_position); - - am_IntToString(am_Players[1].tower_height, text_buff); - text_position.x = 515 - pArcomageGame->pfntComic->GetLineWidth(text_buff) / 2; - text_position.y = 305; - am_DrawText(-1, text_buff, &text_position); - - am_IntToString(am_Players[0].wall_height, text_buff); - text_position.x = 188 - pArcomageGame->pfntComic->GetLineWidth(text_buff) / 2; - text_position.y = 305; - am_DrawText(-1, text_buff, &text_position); - - am_IntToString(am_Players[1].wall_height, text_buff); - text_position.x = 451 - pArcomageGame->pfntComic->GetLineWidth(text_buff) / 2; - text_position.y = 305; - am_DrawText(-1, text_buff, &text_position); - - res_value = am_Players[0].quarry_level; - if ( use_start_bonus ) - res_value =am_Players[0].quarry_level + quarry_bonus; - am_IntToString(res_value, text_buff); - text_position.x = 14;// - 6 * 0 / 2; - text_position.y = 92; - DrawPlayerLevels(-1, text_buff, &text_position); - - res_value = am_Players[1].quarry_level; - if ( use_start_bonus ) - res_value = am_Players[1].quarry_level + quarry_bonus; - am_IntToString(res_value, text_buff); -// v2 = 0; - text_position.y = 92; - text_position.x = 561; //- 6 * v2 / 2; - DrawPlayerLevels(-1, text_buff, &text_position); - - res_value = am_Players[0].magic_level; - if ( use_start_bonus ) - res_value = am_Players[0].magic_level + magic_bonus; - am_IntToString(res_value, text_buff); - // v4 = 0; - text_position.y = 164; - text_position.x = 14; //- 6 * v4 / 2; - DrawPlayerLevels(-1, text_buff, &text_position); - - res_value = am_Players[1].magic_level; - if ( use_start_bonus ) - res_value = am_Players[1].magic_level + magic_bonus; - am_IntToString(res_value, text_buff); - // v6 = 0; - text_position.y = 164; - text_position.x = 561; //- 6 * v6 / 2; - DrawPlayerLevels(-1, text_buff, &text_position); - - res_value = am_Players[0].zoo_level; - if ( use_start_bonus ) - res_value = am_Players[0].zoo_level + zoo_bonus; - am_IntToString(res_value, text_buff); - // v8 = 0; - text_position.y = 236; - text_position.x = 14;// - 6 * v8 / 2; - DrawPlayerLevels(-1, text_buff, &text_position); - - res_value = am_Players[1].zoo_level; - if ( use_start_bonus ) - res_value = am_Players[1].zoo_level + zoo_bonus; - am_IntToString(res_value, text_buff); - // v10 = 0; - text_position.y = 236; - text_position.x = 561;// - 6 * v10 / 2; - DrawPlayerLevels(-1, text_buff, &text_position); - - am_IntToString(am_Players[0].resource_bricks, text_buff); - text_position.y = 114; - text_position.x = 10; - DrawBricksCount(-1, text_buff, &text_position); - - am_IntToString(am_Players[1].resource_bricks, text_buff); - text_position.x = 557; - text_position.y = 114; - DrawBricksCount(-1, text_buff, &text_position); - - am_IntToString(am_Players[0].resource_gems, text_buff); - text_position.x = 10; - text_position.y = 186; - DrawGemsCount(-1, text_buff, &text_position); - - am_IntToString(am_Players[1].resource_gems, text_buff); - text_position.x = 557; - text_position.y = 186; - DrawGemsCount(-1, text_buff, &text_position); - - am_IntToString(am_Players[0].resource_beasts, text_buff); - text_position.x = 10; - text_position.y = 258; - DrawBeastsCount(-1, text_buff, &text_position); - - am_IntToString(am_Players[1].resource_beasts, text_buff); - text_position.x = 557; - text_position.y = 258; - DrawBeastsCount(-1, text_buff, &text_position); -} - - -//----- (0040B102) -------------------------------------------------------- -void DrawPlayerLevels( int a1, char *text, POINT *pXY ) -{ - char *v3; // esi@1 - unsigned char test_char; // bl@2 - int v7; // eax@3 - RECT pSrcRect; - POINT pTargetPoint; - - v3 = text; - am_BeginScene(pArcomageGame->pSpritesPixels, -1, 1); - pTargetPoint.x = pXY->x; - pTargetPoint.y = pXY->y; - do - { - test_char = *v3; - ++v3; - if ( test_char ) - { - v7 = 22 * test_char; - pSrcRect.right = v7 - 842; - pSrcRect.left = v7 - 864; - pSrcRect.top = 190; - pSrcRect.bottom = 207; - pRenderer->am_Blt_Chroma(&pSrcRect, &pTargetPoint, pArcomageGame->field_54, 1); - pTargetPoint.x += 22; - } - } - while ( test_char!= 0 ); - am_EndScene(); -} - -//----- (0040B17E) -------------------------------------------------------- -void DrawBricksCount( int a1, char* text, POINT *pXY ) -{ - char *v3; // esi@1 - unsigned char test_char; // bl@2 - int v7; // eax@3 - RECT pSrcRect; - POINT pTargetPoint; - - v3 = text; - am_BeginScene(pArcomageGame->pSpritesPixels, -1, 1); - pTargetPoint.x = pXY->x; - pTargetPoint.y = pXY->y; - do - { - test_char = *v3; - ++v3; - if ( test_char ) - { - v7 = 13 * test_char; - pSrcRect.left = v7 - 370; - pSrcRect.right = v7 - 357; - pSrcRect.top = 128; - pSrcRect.bottom = 138; - pRenderer->am_Blt_Copy(&pSrcRect, &pTargetPoint, 2); - pTargetPoint.x += 13; - } - } - while ( test_char!= 0 ); - am_EndScene(); -} - -//----- (0040B1F3) -------------------------------------------------------- -void DrawGemsCount( int a1, char* text, POINT* pXY ) -{ - char *v3; // esi@1 - unsigned char test_char; // bl@2 - int v7; // eax@3 - RECT pSrcRect; - POINT pTargetPoint; - - v3 = text; - am_BeginScene(pArcomageGame->pSpritesPixels, -1, 1); - pTargetPoint.x = pXY->x; - pTargetPoint.y = pXY->y; - do - { - test_char = *v3; - ++v3; - if ( test_char ) - { - v7 = 13 * test_char; - pSrcRect.left = v7 - 370; - pSrcRect.right = v7 - 357; - pSrcRect.top = 138; - pSrcRect.bottom = 148; - pRenderer->am_Blt_Copy(&pSrcRect, &pTargetPoint, 2); - pTargetPoint.x += 13; - } - } - while ( test_char!= 0 ); - am_EndScene(); -} - -//----- (0040B268) -------------------------------------------------------- -void DrawBeastsCount( int a1, char *text, POINT *pXY ) -{ - char *v3; // esi@1 - unsigned char test_char; // bl@2 - int v7; // eax@3 - RECT pSrcRect; - POINT pTargetPoint; - - v3 = text; - am_BeginScene(pArcomageGame->pSpritesPixels, -1, 1); - pTargetPoint.x = pXY->x; - pTargetPoint.y = pXY->y; - do - { - test_char = *v3; - ++v3; - if ( test_char ) - { - v7 = 13 * test_char; - pSrcRect.left = v7 - 370; - pSrcRect.right = v7 - 357; - pSrcRect.top = 148; - pSrcRect.bottom = 158; - pRenderer->am_Blt_Copy(&pSrcRect, &pTargetPoint, 2); - pTargetPoint.x += 13; - } - } - while ( test_char!= 0 ); - am_EndScene(); -} - -//----- (0040B2DD) -------------------------------------------------------- -void DrawPlayersTowers() -{ - int tower_height; // eax@1 - int tower_top; // esi@3 - RECT pSrcXYZW; // [sp+0h] [bp-18h]@3 - POINT pTargetXY; // [sp+10h] [bp-8h]@3 - - tower_height= am_Players[0].tower_height; - if ( am_Players[0].tower_height > max_tower_height ) - tower_height = max_tower_height; - pSrcXYZW.top = 0; - pSrcXYZW.left = 892; - pSrcXYZW.right = 937; - tower_top = 200 * tower_height / max_tower_height; - pSrcXYZW.bottom = tower_top; - pTargetXY.x = 102; - pTargetXY.y = 297 - tower_top; - pRenderer->am_Blt_Copy(&pSrcXYZW, &pTargetXY, 2);//стена башни - - pSrcXYZW.top = 0; - pSrcXYZW.left = 384; - pSrcXYZW.right = 452; - pSrcXYZW.bottom = 94; - pTargetXY.y = 203 - tower_top; - pTargetXY.x = 91; - pRenderer->am_Blt_Chroma(&pSrcXYZW, &pTargetXY, pArcomageGame->field_54, 2);//верхушка башни - - tower_height = am_Players[1].tower_height; - if (am_Players[1].tower_height > max_tower_height ) - tower_height = max_tower_height; - tower_top = 200 * tower_height / max_tower_height; - pSrcXYZW.top = 0; - pSrcXYZW.left = 892; - pSrcXYZW.right = 937; - pSrcXYZW.bottom = tower_top; - - pTargetXY.x = 494; - pTargetXY.y = 297 - tower_top; - pRenderer->am_Blt_Copy(&pSrcXYZW, &pTargetXY, 2); - //draw tower up cone - pSrcXYZW.left = 384; - pSrcXYZW.right = 452; - pSrcXYZW.top = 94; - pSrcXYZW.bottom = 188; - - pTargetXY.x = 483; - pTargetXY.y = 203 - tower_top; - pRenderer->am_Blt_Chroma(&pSrcXYZW, &pTargetXY, pArcomageGame->field_54, 2); -} -// 4E1884: using guessed type int dword_4E1884; - -//----- (0040B400) -------------------------------------------------------- -void DrawPlayersWall() -{ - int v0; // eax@1 - int v1; // eax@4 -// LONG v2; // ecx@4 - int v3; // eax@5 - int v4; // eax@8 -// LONG v5; // esi@8 - RECT pSrcXYZW; // [sp+4h] [bp-18h]@4 - POINT pTargetXY; // [sp+14h] [bp-8h]@4 - - v0 = am_Players[0].wall_height; - - if ( am_Players[0].wall_height > 100 ) - v0 = 100; - - if ( am_Players[0].wall_height > 0 ) - { - pSrcXYZW.top = 0; - pSrcXYZW.left = 843; - v1 = 200 * v0 / 100; - pSrcXYZW.right = 867; - pSrcXYZW.bottom = v1; - pTargetXY.x = 177; - pTargetXY.y = 297 - v1; - pRenderer->am_Blt_Chroma(&pSrcXYZW, &pTargetXY, pArcomageGame->field_54, 2); - } - v3 = am_Players[1].wall_height; - if ( am_Players[1].wall_height > 100 ) - v3 = 100; - if ( am_Players[1].wall_height > 0 ) - { - pSrcXYZW.top = 0; - pSrcXYZW.left = 843; - v4 = 200 * v3 / 100; - pSrcXYZW.right = 867; - pSrcXYZW.bottom = v4; - pTargetXY.x = 439; - pTargetXY.y = 297 - v4; - pRenderer->am_Blt_Chroma(&pSrcXYZW, &pTargetXY, pArcomageGame->field_54, 2); - } -} - -//----- (0040B4B9) -------------------------------------------------------- -void DrawCards() -{ - int v0; // esi@1 -// char v1; // bl@1 - int v2; // edi@1 - //int v3; // edx@2 -// int v4; // eax@3 -// int v5; // ecx@3 -// int v6; // eax@3 - unsigned int v7; // ecx@4 -// int v8; // eax@16 -// int v9; // ecx@16 -// int v10; // eax@16 - signed int v11; // edi@18 -// signed int v12; // esi@20 -// int v13; // ecx@20 -// int v14; // eax@23 -// signed int v15; // eax@25 -// int v16; // ecx@25 -// POINT *v17; // esi@26 -// signed int v18; // eax@29 -// AcromageCardOnTable *v19; // ecx@29 -// int v20; // ecx@31 -// int v21; // [sp-4h] [bp-2Ch]@8 - RECT pSrcXYZW; // [sp+Ch] [bp-1Ch]@8 - POINT pTargetXY; // [sp+1Ch] [bp-Ch]@1 - int v24; // [sp+24h] [bp-4h]@1 - - v0 = GetPlayerHandCardCount(current_player_num); - pTargetXY.y = 327; - v24 = (window->GetWidth() - 96 * v0) / (v0 + 1); - pTargetXY.x = (window->GetWidth() - 96 * v0) / (v0 + 1); - for ( v2 = 0; v2 < v0; ++v2 ) - { - //v3 = current_player_num; - if ( am_byte_4E185D) - { - pTargetXY.x += am_Players[current_player_num].card_shift[v2].x; - pTargetXY.y += am_Players[current_player_num].card_shift[v2].y; - } - v7 = am_Players[current_player_num].cards_at_hand[v2]; - if ( am_Players[current_player_num].cards_at_hand[v2] == -1 ) - { - ++v0; - } - else if ( v2 != amuint_4FAA4C ) - { - if ( am_Players[current_player_num].IsHisTurn == 0 && byte_505881 == 0 ) - { - pSrcXYZW.left = 192; - pSrcXYZW.right = 288; - pSrcXYZW.top = 0; - pSrcXYZW.bottom = 128; - pRenderer->am_Blt_Copy(&pSrcXYZW, &pTargetXY, 2);//рисуется оборотные стороны карт противника - pTargetXY.x += v24 + 96; - } - else - { - - pArcomageGame->GetCardRect(v7, &pSrcXYZW); - if (!CanCardBePlayed(current_player_num, v2)) - { - pRenderer->am_Blt_Copy(&pSrcXYZW, &pTargetXY, 0);//рисуются неактивные карты - pTargetXY.x += v24 + 96; - } - else - { - pRenderer->am_Blt_Copy(&pSrcXYZW, &pTargetXY, 2);//рисуются активные карты - pTargetXY.x += v24 + 96; - } - } - } - else - pTargetXY.x += v24 + 96; -//LABEL_15: - if ( am_byte_4E185D ) - { - pTargetXY.x -= am_Players[current_player_num].card_shift[v2].x; - pTargetXY.y -= am_Players[current_player_num].card_shift[v2].y; - } - } - - for ( v11 = 0; v11 < 10; ++v11 ) - { - if ( am_byte_4FAA76 == 0 ) - { - if ( shown_cards[v11].uCardId != -1 ) - { - pArcomageGame->GetCardRect(shown_cards[v11].uCardId, &pSrcXYZW); - pRenderer->am_Blt_Copy(&pSrcXYZW, &shown_cards[v11].field_18_point, 0); - } - if ( shown_cards[v11].field_4 != 0 ) - { - pTargetXY.x = shown_cards[v11].field_18_point.x + 12; - pTargetXY.y = shown_cards[v11].field_18_point.y + 40; - pSrcXYZW.left = 843; - pSrcXYZW.right = 916; - pSrcXYZW.top = 200; - pSrcXYZW.bottom = 216; - pRenderer->am_Blt_Chroma(&pSrcXYZW, &pTargetXY, pArcomageGame->field_54, 2); - } - } - else if ( amuint_4FAA34 <= 0 ) - { - if ( v11 == 9 ) - { - am_byte_4FAA76 = 0; - am_byte_4FAA75 = 0; - amuint_4FAA34 = 5; - } - if ( shown_cards[v11].uCardId != -1 ) - amuint_4FABC4 = shown_cards[v11].uCardId; - shown_cards[v11].uCardId = -1; - shown_cards[v11].field_18_point.x = shown_cards[v11].field_8.x; - shown_cards[v11].field_18_point.y = shown_cards[v11].field_8.y; - shown_cards[v11].field_4 = 0; - } - else - { - if ( shown_cards[v11].uCardId != -1 ) - { - shown_cards[v11].field_18_point.x += shown_cards[v11].field_10_xplus; - shown_cards[v11].field_18_point.y += shown_cards[v11].field_14_y_plus; - pArcomageGame->GetCardRect(shown_cards[v11].uCardId, &pSrcXYZW); - pRenderer->am_Blt_Copy(&pSrcXYZW, &shown_cards[v11].field_18_point, 0); - } - } - } - if ( am_byte_4FAA76 != 0 ) - --amuint_4FAA34; - pSrcXYZW.left = 192; - pSrcXYZW.right = 288; - pSrcXYZW.top = 0; - pSrcXYZW.bottom = 128; - pTargetXY.x = 120; - pTargetXY.y = 18; - pRenderer->am_Blt_Copy(&pSrcXYZW, &pTargetXY, 0); -} - -//----- (0040B76F) -------------------------------------------------------- -void DrawCardAnimation( int animation_stage ) -{ - int v1; // eax@3 - int v2; // eax@3 -// int v3; // esi@4 - int v4; // eax@4 -// POINT *v5; // edx@6 -// RECT *v6; // ecx@6 - int v8; // eax@15 -// AcromageCardOnTable *v9; // ecx@15 -// int v10; // ecx@19 -// int v11; // eax@20 -// int v12; // ecx@20 -// int v13; // eax@20 -// unsigned int v14; // ecx@21 - double v15; // st7@22 -// POINT *v16; // edx@23 - int v17; // eax@32 - char v18; // zf@37 - int v19; // eax@41 -// int v20; // eax@46 -// int v21; // ecx@46 -// int v22; // eax@46 -// int v23; // [sp-4h] [bp-2Ch]@28 - RECT pSrcXYZW; // [sp+Ch] [bp-1Ch]@6 - POINT pTargetXY; // [sp+1Ch] [bp-Ch]@20 - int v26; // [sp+24h] [bp-4h]@1 - - v26 = animation_stage; - if ( amuint_4FAA4C != -1 ) - { - if ( amuint_4FAA38 >= 9 ) - { - am_uint_4FAA44_blt_xy.y = 18; - am_uint_4FAA44_blt_xy.x = 120; - v1 = GetPlayerHandCardCount(current_player_num); - v2 = (window->GetWidth() - 96 * v1) / v1 + 96; - if ( am_byte_4E185D ) - { - // v3 = 188 * current_player_num + 8 * amuint_4FAA4C; - // amuint_4FAA3C_blt_xy.x = (amuint_4FAA4C * v2 + *(am_Players[0].arr_6C[0] + v3) - 120) / 10; - amuint_4FAA3C_blt_xy.x=(amuint_4FAA4C * v2 + am_Players[current_player_num].card_shift[amuint_4FAA4C].x-120)/10; - v4 = (am_Players[current_player_num].card_shift[amuint_4FAA4C].y+309) /10;//(*(&am_Players[0].arr_6C[0][1] + v3) + 309) / 10; - } - else - { - amuint_4FAA3C_blt_xy.x = (amuint_4FAA4C * v2 - 120) / 10; - v4 = 30; - } - am_uint_4FAA44_blt_xy.y += v4; - am_uint_4FAA44_blt_xy.x += amuint_4FAA3C_blt_xy.x; - amuint_4FAA3C_blt_xy.y = v4; - pSrcXYZW.left = 192; - pSrcXYZW.top = 0; - pSrcXYZW.right = 288; - pSrcXYZW.bottom = 128; - pRenderer->am_Blt_Copy(&pSrcXYZW, &am_uint_4FAA44_blt_xy, 2); - } - else - { - pSrcXYZW.left = 192; - pSrcXYZW.top = 0; - pSrcXYZW.right = 288; - pSrcXYZW.bottom = 128; - am_uint_4FAA44_blt_xy.x += amuint_4FAA3C_blt_xy.x; - am_uint_4FAA44_blt_xy.y += amuint_4FAA3C_blt_xy.y; - pRenderer->am_Blt_Copy(&pSrcXYZW, &am_uint_4FAA44_blt_xy, 2); - if ( !amuint_4FAA38 ) - amuint_4FAA4C = -1; - } - } - if ( uCardID != -1 ) - { - if ( v26 <= 10 ) - { - if ( v26 == 10 ) - { - pArcomageGame->GetCardRect(uCardID, &pSrcXYZW); - // v8 = 0; - for ( v8 = 0; v8 < 10; ++v8 ) - { - if (shown_cards[v8].uCardId==-1) - { - shown_cards[v8].uCardId = uCardID; - shown_cards[v8].field_4 = 1; - break; - } - } - /* v9 = shown_cards; - while ( v9->uCardId != -1 ) - { - ++v9; - ++v8; - if ( v9 >= &dword_4FABB8 ) - goto LABEL_20; - } - v10 = v8; - shown_cards[v10].uCardId = uCardID; - shown_cards[v10].field_4 = 1;*/ -//LABEL_20: - pTargetXY.x = shown_cards[v8].field_8.x; - pTargetXY.y = shown_cards[v8].field_8.y; - pRenderer->am_Blt_Copy(&pSrcXYZW, &pTargetXY, 0); - uCardID = -1; - } - } - else - { - pArcomageGame->GetCardRect(uCardID, &pSrcXYZW); - amuint_4FAA5C_blt_xy.x += amuint_4FAA54_blt_xy.x; - amuint_4FAA5C_blt_xy.y += amuint_4FAA54_blt_xy.y; - pRenderer->am_Blt_Copy(&pSrcXYZW, &amuint_4FAA5C_blt_xy, 0); - } - } - if ( played_card_id != -1 ) - { - v15 = v26; - if ( v15 > 15.0 ) - { - pArcomageGame->GetCardRect(played_card_id, &pSrcXYZW); - amuint_4FAA5C_blt_xy.x += amuint_4FAA54_blt_xy.x; - amuint_4FAA5C_blt_xy.y += amuint_4FAA54_blt_xy.y; - pRenderer->am_Blt_Copy(&pSrcXYZW, &amuint_4FAA5C_blt_xy, 2); - return; - } - if ( v15 == 15.0 ) - { - ApplyCardToPlayer(current_player_num, played_card_id); - pArcomageGame->GetCardRect(played_card_id, &pSrcXYZW); - pTargetXY.x = 272; - pTargetXY.y = 173; - pRenderer->am_Blt_Copy(&pSrcXYZW, &pTargetXY, 2); - return; - } - if ( v15 == 5.0 ) - { - amuint_4FAA5C_blt_xy.x = 272; - amuint_4FAA5C_blt_xy.y = 173; - for ( v17 = 0; v17 < 10; ++v17 ) - { - if (shown_cards[v17].uCardId == -1) - break; - } - amuint_4FAA54_blt_xy.x = (shown_cards[v17].field_8.x - 272) / 5; - amuint_4FAA54_blt_xy.y = (shown_cards[v17].field_8.y - 173) / 5; - pArcomageGame->GetCardRect(played_card_id, &pSrcXYZW); - pTargetXY.x = 272; - pTargetXY.y = 173; - pRenderer->am_Blt_Copy(&pSrcXYZW, &pTargetXY, 2); - return; - } - if ( v15 >= 5.0 ) - v18 = v26 == 0; - else - { - v18 = v26 == 0; - if ( v26 > 0 ) - { - pArcomageGame->GetCardRect(played_card_id, &pSrcXYZW); - amuint_4FAA5C_blt_xy.x += amuint_4FAA54_blt_xy.x; - amuint_4FAA5C_blt_xy.y += amuint_4FAA54_blt_xy.y; - pRenderer->am_Blt_Copy(&pSrcXYZW, &amuint_4FAA5C_blt_xy, 0); - return; - } - } - if ( !v18 ) - { - pArcomageGame->GetCardRect(played_card_id, &pSrcXYZW); - pTargetXY.x = 272; - pTargetXY.y = 173; - pRenderer->am_Blt_Copy(&pSrcXYZW, &pTargetXY, 2); - return; - } - pArcomageGame->GetCardRect(played_card_id, &pSrcXYZW); - for ( v19 = 0; v19 < 10; ++v19 ) - { - if (shown_cards[v19].uCardId == -1) - { - shown_cards[v19].uCardId = played_card_id; - break; - } - } - pTargetXY.x = shown_cards[v19].field_8.x; - pTargetXY.y = shown_cards[v19].field_8.y; - pRenderer->am_Blt_Copy(&pSrcXYZW, &pTargetXY, 0); - played_card_id = -1; - } -} - -//----- (0040BB12) -------------------------------------------------------- -void ArcomageGame::GetCardRect(unsigned int uCardID, RECT *pCardRect) -{ - int v3; // edx@1 - int v4; // ecx@1 - - v3 = pCards[uCardID].slot % 10; - v4 = (pCards[uCardID].slot / 10 << 7) + 220; - pCardRect->top = v4; - pCardRect->left = 96 * v3; - pCardRect->bottom = v4 + 128; - pCardRect->right = 96 * v3 + 96; -} - -//----- (0040BB49) -------------------------------------------------------- -int GetPlayerHandCardCount( int player_num ) -{ - int card_count; // eax@1 - - card_count = 0; - for(int i=0; i<10; ++i) - { - if (am_Players[player_num].cards_at_hand[i]!=-1) - ++card_count; - } - return card_count; -} - -//----- (0040BB67) -------------------------------------------------------- -signed int DrawCardsRectangles( int player_num ) -{ - int v5; // eax@3 -// int i; // ecx@6 - int color; // ST00_4@19 - RECT pXYZW; // [sp+Ch] [bp-3Ch]@3 - stru273 v26; // [sp+1Ch] [bp-2Ch]@2 - __int32 var18; // [sp+30h] [bp-18h]@3 - int hand_index; // [sp+3Ch] [bp-Ch]@3 - -//__debugbreak(); // need do fix rectangle not fit to card - - if ( am_Players[player_num].IsHisTurn ) - { - if ( v26._40DD2F() ) - { - v5 = GetPlayerHandCardCount(player_num); - pXYZW.top = 327; - pXYZW.bottom = 455; - pXYZW.left = (window->GetWidth() - 96 * v5) / (v5 + 1); - var18 = pXYZW.left + 96; - pXYZW.right = pXYZW.left + 96; - for( hand_index = 0; hand_index < v5; hand_index++) - { - //for ( i = 0; i < 10; ++i ) - //{ - if (am_Players[player_num].cards_at_hand[hand_index] != -1 ) - { - //break; - //} - if ( am_byte_4E185D ) - { - pXYZW.left += am_Players[player_num].card_shift[hand_index].x; - pXYZW.right += am_Players[player_num].card_shift[hand_index].x; - pXYZW.top += am_Players[player_num].card_shift[hand_index].y; - pXYZW.bottom += am_Players[player_num].card_shift[hand_index].y; - } - if ( v26.Inside(&pXYZW) ) - { - if ( CanCardBePlayed(player_num, hand_index) ) - color = 0x00FFFFFF;//белый цвет - else - color = 0x000000FF;//красный цвет - DrawRect(&pXYZW, R8G8B8_to_TargetFormat(color), 0); - return hand_index; - } - DrawRect(&pXYZW, R8G8B8_to_TargetFormat(0), 0);//рамка чёрного цвета - if ( am_byte_4E185D ) - { - pXYZW.left -= am_Players[player_num].card_shift[hand_index].x; - pXYZW.right -= am_Players[player_num].card_shift[hand_index].x; - pXYZW.top -= am_Players[player_num].card_shift[hand_index].y; - pXYZW.bottom -= am_Players[player_num].card_shift[hand_index].y; - } - pXYZW.left += var18; - pXYZW.right += var18; - } - } - } - } - return -1; -} -// 4E185D: using guessed type char am_byte_4E185D; - -//----- (0040BCFB) -------------------------------------------------------- -bool DiscardCard( int player_num, signed int card_slot_index ) -{ - int v2; // esi@2 -// signed int v3; // edi@2 -// char *v4; // eax@2 -// int v5; // ecx@7 -// int v6; // ebx@7 -// int v7; // esi@8 - int v8; // eax@8 -// int v9; // esi@8 - int v10; // ecx@8 -// int v11; // eax@8 - int v12; // eax@8 -// signed int v13; // edx@9 -// unsigned int v14; // eax@12 -// char result; // al@12 - int i; - - if ( card_slot_index <= -1 ) - return false; - v2 = 0; - - for( i = 0; i < 10; ++i ) - { - if ( am_Players[player_num].cards_at_hand[i] != -1 ) - { - if ( card_slot_index == v2 ) - break; - ++v2; - } - } - - if ( pCards[am_Players[player_num].cards_at_hand[i]].can_be_discarded) - { - ArcomageGame::PlaySound(22); - v8 = GetPlayerHandCardCount(current_player_num); - v10 = am_Players[player_num].card_shift[i].x + (window->GetWidth() - 96 * v8) / (v8 + 1); - amuint_4FAA5C_blt_xy.x = v10; - amuint_4FAA5C_blt_xy.y = am_Players[player_num].card_shift[i].y + 327;//v11; - v12 = 0; - - if ( !am_byte_4FAA75 ) - { - for ( v12 = 0; v12 < 10; ++v12 ) - { - if (shown_cards[v12].uCardId == -1) - break; - } - } - pArcomageGame->field_F6 = 1; - amuint_4FAA54_blt_xy.x = (shown_cards[v12].field_8.x - v10) / 10; - amuint_4FAA54_blt_xy.y = (shown_cards[v12].field_8.y - 327) / 10; - uCardID = am_Players[player_num].cards_at_hand[i]; - am_Players[player_num].cards_at_hand[i] = -1; - need_to_discard_card = 0; - return true; - } - else - return false; -} - -//----- (0040BE0E) -------------------------------------------------------- -bool PlayCard( int player_num, int card_slot_num ) -{ -// int v3; // ebp@1 - int v4; // ecx@2 -// ArcomagePlayer *v5; // esi@2 - int card_index; // edi@2 -// int v7; // eax@2 -// int v8; // ebx@8 - int cards_at_hand; // eax@8 -// int v10; // ebx@8 -// int v11; // ebp@8 - int v12; // ecx@8 -// int v13; // eax@8 - ArcomageCard *pCard; // eax@8 -// int v15; // ecx@8 -// int v16; // ecx@8 - - if ( card_slot_num <= -1 ) - return false; - - v4 = 0; - for (card_index=0; card_index<10; ++card_index) - { - if ( am_Players[player_num].cards_at_hand[card_index] != -1 ) - { - if ( card_slot_num == v4 ) - break; - ++v4; - } - } - - if (CanCardBePlayed(player_num, card_index) ) - { - ArcomageGame::PlaySound(23); - cards_at_hand = GetPlayerHandCardCount(current_player_num); - pArcomageGame->field_F6 = 1; - v12 = am_Players[player_num].card_shift[card_index].x + - (window->GetWidth() - 96 * cards_at_hand) / (cards_at_hand + 1)+ - 96 * card_index ; - - // v13 = *(int *)((char *)&am_Players[0].arr_6C[0][1] + v10) + 327; - amuint_4FAA5C_blt_xy.x = v12;//v12; - amuint_4FAA5C_blt_xy.y = am_Players[player_num].card_shift[card_index].y + 327;//v13; - - amuint_4FAA54_blt_xy.x = (272 - v12) / 5; - amuint_4FAA54_blt_xy.y = -30; - - pCard = &pCards[am_Players[player_num].cards_at_hand[card_index]]; - am_Players[player_num].resource_bricks -= pCard->needed_bricks; - am_Players[player_num].resource_beasts -= pCard->needed_beasts; - am_Players[player_num].resource_gems -= pCard->needed_gems; - played_card_id = am_Players[player_num].cards_at_hand[card_index]; - am_Players[player_num].cards_at_hand[card_index] = -1; - return true; - } - else - return false; - -} - -//----- (0040BF15) -------------------------------------------------------- -bool CanCardBePlayed(int player_num, int hand_card_indx) -{ - bool result; // eax@1 - ArcomageCard *test_card; // ecx@1 - ArcomagePlayer *pPlayer; // esi@1 - - pPlayer = &am_Players[player_num]; - result = true; - test_card = &pCards[am_Players[player_num].cards_at_hand[hand_card_indx]]; - if ( test_card->needed_quarry_level > pPlayer->quarry_level ) - result = false; - if ( test_card->needed_magic_level > pPlayer->magic_level ) - result = false; - if ( test_card->needed_zoo_level > pPlayer->zoo_level ) - result = false; - if ( test_card->needed_bricks > pPlayer->resource_bricks ) - result = false; - if ( test_card->needed_gems > pPlayer->resource_gems ) - result = false; - if ( test_card->needed_beasts > pPlayer->resource_beasts ) - result = false; - return result; -} - -//----- (0040BF77) -------------------------------------------------------- -void ApplyCardToPlayer( int player_num, unsigned int uCardID ) - { - - -#define APPLY_TO_PLAYER( PLAYER, ENEMY,FIELD, VAL, RES )\ - if (VAL != 0) {\ - if (VAL == 99) {\ - if ( PLAYER->##FIELD < ENEMY->##FIELD ) {\ - PLAYER->##FIELD = ENEMY->##FIELD;\ - RES = ENEMY->##FIELD - PLAYER->##FIELD;\ - }\ - } else {\ - PLAYER->##FIELD += (signed int)(VAL);\ - if ( PLAYER->##FIELD<0 ) PLAYER->##FIELD= 0;\ - RES = (signed int)(VAL);\ - }\ - } - -#define APPLY_TO_ENEMY( PLAYER, ENEMY,FIELD, VAL, RES ) APPLY_TO_PLAYER(ENEMY, PLAYER, FIELD, VAL, RES) - -#define APPLY_TO_BOTH( PLAYER, ENEMY, FIELD, VAL, RES_P, RES_E ) \ - if ( VAL != 0) {\ - if ( VAL == 99 ) { \ - if ( PLAYER->##FIELD != ENEMY->##FIELD ) { \ - if ( PLAYER->##FIELD <= ENEMY->##FIELD ) { \ - PLAYER->##FIELD = ENEMY->##FIELD; \ - RES_P = ENEMY->##FIELD - PLAYER->##FIELD; \ - } else { \ - ENEMY->##FIELD = PLAYER->##FIELD; \ - RES_E = PLAYER->##FIELD - ENEMY->##FIELD; \ - } \ - }\ - } else { \ - PLAYER->##FIELD += (signed int)(VAL);\ - ENEMY->##FIELD += (signed int)(VAL); if (PLAYER->##FIELD < 0 ) {PLAYER->##FIELD = 0;} \ - if ( ENEMY->##FIELD < 0 ) {ENEMY->##FIELD = 0;} \ - RES_P = (signed int)(VAL); RES_E = (signed int)(VAL); \ - }\ - } - ArcomagePlayer *player; // esi@1 -// int v3; // eax@1 - ArcomagePlayer *enemy; // edi@1 -// int v5; // eax@2 -// char v6; // sf@2 -// unsigned __int8 v7; // of@2 -// int v8; // eax@3 -// int v9; // eax@4 -// char v10; // zf@5 -// int v11; // eax@8 -// unsigned __int8 v12; // zf@8 -// char v13; // sf@8 -// unsigned __int8 v14; // of@8 -// int v15; // eax@9 -// int v16; // eax@10 -// char v17; // zf@12 -// char v18; // al@15 -// int v19; // eax@16 -// int v20; // eax@17 -// int v21; // eax@22 -// int v22; // eax@23 - int v23; // eax@26 - signed int v24; // ebx@26 - int v103; - int v104; - - POINT v184; // [sp+Ch] [bp-64h]@488 - int enemy_num; // [sp+14h] [bp-5Ch]@1 - ArcomageCard *pCard; // [sp+18h] [bp-58h]@1 - int buildings_e; // [sp+1Ch] [bp-54h]@1 - int buildings_p; // [sp+20h] [bp-50h]@1 - int quarry_p; // [sp+28h] [bp-48h]@1 - int dmg_e; // [sp+2Ch] [bp-44h]@1 - int dmg_p; // [sp+30h] [bp-40h]@1 - int bricks_p; // [sp+34h] [bp-3Ch]@1 - int tower_e; // [sp+38h] [bp-38h]@1 - int tower_p; // [sp+3Ch] [bp-34h]@1 - int wall_e; // [sp+40h] [bp-30h]@1 - int wall_p; // [sp+44h] [bp-2Ch]@1 - int beasts_e; // [sp+48h] [bp-28h]@1 - int beasts_p; // [sp+4Ch] [bp-24h]@1 - int gems_e; // [sp+50h] [bp-20h]@1 - int gems_p; // [sp+54h] [bp-1Ch]@1 - int bricks_e; // [sp+58h] [bp-18h]@1 - int zoo_e; // [sp+5Ch] [bp-14h]@1 - int zoo_p; // [sp+60h] [bp-10h]@1 - int magic_e; // [sp+64h] [bp-Ch]@1 - int magic_p; // [sp+68h] [bp-8h]@1 - int quarry_e; // [sp+6Ch] [bp-4h]@1 - - quarry_p = 0; - magic_p = 0; - zoo_p = 0; - bricks_p = 0; - gems_p = 0; - beasts_p = 0; - wall_p = 0; - tower_p = 0; - buildings_p = 0; - dmg_p = 0; - quarry_e = 0; - magic_e = 0; - zoo_e = 0; - bricks_e = 0; - gems_e = 0; - beasts_e = 0; - wall_e = 0; - tower_e = 0; - buildings_e = 0; - dmg_e = 0; - - player = &am_Players[player_num]; - pCard = &pCards[uCardID]; - enemy_num = (player_num + 1) % 2; - enemy = &am_Players[enemy_num]; - switch ( pCard->compare_param ) - { - case 2: - if ( player->quarry_level < enemy->quarry_level )//если рудники < рудника врага - goto LABEL_26; - goto LABEL_231; - case 3: - if ( player->magic_level < enemy->magic_level ) - goto LABEL_26; - goto LABEL_231; - case 4: - if ( player->zoo_level < enemy->zoo_level )//если зверинец < зверинца врага - goto LABEL_26; - goto LABEL_231; - case 5: - if ( player->quarry_level == enemy->quarry_level ) - goto LABEL_26; - goto LABEL_231; - case 6: - if ( player->magic_level == enemy->magic_level ) - goto LABEL_26; - goto LABEL_231; - case 7: - if ( player->zoo_level == enemy->zoo_level ) - goto LABEL_26; - goto LABEL_231; - case 8: - if ( player->quarry_level < enemy->quarry_level ) - goto LABEL_26; - goto LABEL_231; - case 9: - if ( player->magic_level < enemy->magic_level ) - goto LABEL_26; - goto LABEL_231; - case 10: - if ( player->zoo_level < enemy->zoo_level ) - goto LABEL_26; - goto LABEL_231; - case 11: - if ( !player->wall_height ) - goto LABEL_26; - goto LABEL_231; - case 12: - if ( player->wall_height ) - goto LABEL_26; - goto LABEL_231; - case 13: - if ( !enemy->wall_height ) - goto LABEL_26; - goto LABEL_231; - case 14: - if ( enemy->wall_height ) - goto LABEL_26; - goto LABEL_231; - case 15: - if ( player->wall_height < enemy->wall_height ) - goto LABEL_26; - goto LABEL_231; - case 16: - if ( player->tower_height < enemy->tower_height ) - goto LABEL_26; - goto LABEL_231; - case 17: - if ( player->wall_height == enemy->wall_height ) - goto LABEL_26; - goto LABEL_231; - case 18: - if ( player->tower_height == enemy->tower_height ) - goto LABEL_26; - goto LABEL_231; - case 19: - if ( player->wall_height < enemy->wall_height ) - goto LABEL_26; - goto LABEL_231; - case 20: - if ( player->tower_height < enemy->tower_height ) - goto LABEL_26; - goto LABEL_231; - default: -LABEL_26: - v23 = pCard->draw_extra_card_count; - v24 = 0; - dword_4FAA68 = v23 + (pCard->field_30 == 1); - dword_4FAA64 = v23; - if ( v23 > 0 ) - { - do - { - GetNextCardFromDeck(player_num); - ++v24; - } - while ( v24 < pCard->draw_extra_card_count ); - } - - need_to_discard_card = GetPlayerHandCardCount(player_num) > minimum_cards_at_hand; - - APPLY_TO_PLAYER(player, enemy, quarry_level, pCard->to_player_quarry_lvl, quarry_p); - APPLY_TO_PLAYER(player, enemy, magic_level, pCard->to_player_magic_lvl, magic_p); - APPLY_TO_PLAYER(player, enemy, zoo_level, pCard->to_player_zoo_lvl, zoo_p); - APPLY_TO_PLAYER(player, enemy, resource_bricks, pCard->to_player_bricks, bricks_p); - APPLY_TO_PLAYER(player, enemy, resource_gems, pCard->to_player_gems, gems_p); - APPLY_TO_PLAYER(player, enemy, resource_beasts, pCard->to_player_beasts, beasts_p); - if ( pCard->to_player_buildings ) - { - dmg_p = ApplyDamageToBuildings(player_num, (signed int)pCard->to_player_buildings); - buildings_p = (signed int)pCard->to_player_buildings - dmg_p; - } - APPLY_TO_PLAYER(player, enemy, wall_height, pCard->to_player_wall, wall_p); - APPLY_TO_PLAYER(player, enemy, tower_height, pCard->to_player_tower, tower_p); - - APPLY_TO_ENEMY(player, enemy, quarry_level, pCard->to_enemy_quarry_lvl, quarry_e); - APPLY_TO_ENEMY(player, enemy, magic_level, pCard->to_enemy_magic_lvl, magic_e); - APPLY_TO_ENEMY(player, enemy, zoo_level, pCard->to_enemy_zoo_lvl, zoo_e); - APPLY_TO_ENEMY(player, enemy, resource_bricks, pCard->to_enemy_bricks, bricks_e); - APPLY_TO_ENEMY(player, enemy, resource_gems, pCard->to_enemy_gems, gems_e); - APPLY_TO_ENEMY(player, enemy, resource_beasts, pCard->to_enemy_beasts, beasts_e); - if ( pCard->to_enemy_buildings ) - { - dmg_e = ApplyDamageToBuildings(enemy_num, (signed int)pCard->to_enemy_buildings); - buildings_e = (signed int)pCard->to_enemy_buildings - dmg_e; - } - APPLY_TO_ENEMY(player, enemy, wall_height, pCard->to_enemy_wall, wall_e); - APPLY_TO_ENEMY(player, enemy, tower_height, pCard->to_enemy_tower, tower_e); - - APPLY_TO_BOTH(player, enemy, quarry_level, pCard->to_pl_enm_quarry_lvl, quarry_p, quarry_e); - APPLY_TO_BOTH(player, enemy, magic_level, pCard->to_pl_enm_magic_lvl, magic_p, magic_e); - APPLY_TO_BOTH(player, enemy, zoo_level, pCard->to_pl_enm_zoo_lvl, zoo_p, zoo_e); - APPLY_TO_BOTH(player, enemy, resource_bricks, pCard->to_pl_enm_bricks, bricks_p, bricks_e); - APPLY_TO_BOTH(player, enemy, resource_gems, pCard->to_pl_enm_gems, gems_p, gems_e); - APPLY_TO_BOTH(player, enemy, resource_beasts, pCard->to_pl_enm_beasts, beasts_p, beasts_e); - if ( pCard->to_pl_enm_buildings ) - { - dmg_p = ApplyDamageToBuildings(player_num, (signed int)pCard->to_pl_enm_buildings); - dmg_e = ApplyDamageToBuildings(enemy_num, (signed int)pCard->to_pl_enm_buildings); - buildings_p = (signed int)pCard->to_pl_enm_buildings - dmg_p; - buildings_e = (signed int)pCard->to_pl_enm_buildings - dmg_e; - } - APPLY_TO_BOTH(player, enemy, wall_height, pCard->to_pl_enm_wall, wall_p, wall_e); - APPLY_TO_BOTH(player, enemy, tower_height, pCard->to_pl_enm_tower, tower_p, tower_e); - break; - case 0: -LABEL_231: - v103 = pCard->can_draw_extra_card2; - v104 = 0; - dword_4FAA68 = v103 + (pCard->field_4D == 1); - dword_4FAA64 = v103; - if ( v103 > 0 ) - { - do - { - GetNextCardFromDeck(player_num); - ++v104; - } - while ( v104 < pCard->can_draw_extra_card2 ); - } - - need_to_discard_card = GetPlayerHandCardCount(player_num) > minimum_cards_at_hand; - - APPLY_TO_PLAYER(player, enemy, quarry_level, pCard->to_player_quarry_lvl2, quarry_p); - APPLY_TO_PLAYER(player, enemy, magic_level, pCard->to_player_magic_lvl2, magic_p); - APPLY_TO_PLAYER(player, enemy, zoo_level, pCard->to_player_zoo_lvl2, zoo_p); - APPLY_TO_PLAYER(player, enemy, resource_bricks, pCard->to_player_bricks2, bricks_p); - APPLY_TO_PLAYER(player, enemy, resource_gems, pCard->to_player_gems2, gems_p); - APPLY_TO_PLAYER(player, enemy, resource_beasts, pCard->to_player_beasts2, beasts_p); - if ( pCard->to_player_buildings2 ) - { - dmg_p = ApplyDamageToBuildings(player_num, (signed int)pCard->to_player_buildings2); - buildings_p = (signed int)pCard->to_player_buildings2 - dmg_p; - } - APPLY_TO_PLAYER(player, enemy, wall_height, pCard->to_player_wall2, wall_p); - APPLY_TO_PLAYER(player, enemy, tower_height, pCard->to_player_tower2, tower_p); - - APPLY_TO_ENEMY(player, enemy, quarry_level, pCard->to_enemy_quarry_lvl2, quarry_e); - APPLY_TO_ENEMY(player, enemy, magic_level, pCard->to_enemy_magic_lvl2, magic_e); - APPLY_TO_ENEMY(player, enemy, zoo_level, pCard->to_enemy_zoo_lvl2, zoo_e); - APPLY_TO_ENEMY(player, enemy, resource_bricks, pCard->to_enemy_bricks2, bricks_e); - APPLY_TO_ENEMY(player, enemy, resource_gems, pCard->to_enemy_gems2, gems_e); - APPLY_TO_ENEMY(player, enemy, resource_beasts, pCard->to_enemy_beasts2, beasts_e); - if ( pCard->to_enemy_buildings2 ) - { - dmg_e = ApplyDamageToBuildings(enemy_num, (signed int)pCard->to_enemy_buildings2); - buildings_e = (signed int)pCard->to_enemy_buildings2 - dmg_e; - } - APPLY_TO_ENEMY(player, enemy, wall_height, pCard->to_enemy_wall2, wall_e); - APPLY_TO_ENEMY(player, enemy, tower_height, pCard->to_enemy_tower2, tower_e); - - APPLY_TO_BOTH(player, enemy, quarry_level, pCard->to_pl_enm_quarry_lvl2, quarry_p, quarry_e); - APPLY_TO_BOTH(player, enemy, magic_level, pCard->to_pl_enm_magic_lvl2, magic_p, magic_e); - APPLY_TO_BOTH(player, enemy, zoo_level, pCard->to_pl_enm_zoo_lvl2, zoo_p, zoo_e); - APPLY_TO_BOTH(player, enemy, resource_bricks, pCard->to_pl_enm_bricks2, bricks_p, bricks_e); - APPLY_TO_BOTH(player, enemy, resource_gems, pCard->to_pl_enm_gems2, gems_p, gems_e); - APPLY_TO_BOTH(player, enemy, resource_beasts, pCard->to_pl_enm_beasts2, beasts_p, beasts_e); - - if ( pCard->to_pl_enm_buildings2 ) - { - dmg_p = ApplyDamageToBuildings(player_num, (signed int)pCard->to_pl_enm_buildings2); - dmg_e = ApplyDamageToBuildings(enemy_num, (signed int)pCard->to_pl_enm_buildings2); - buildings_p = (signed int)pCard->to_pl_enm_buildings2 - dmg_p; - buildings_e = (signed int)pCard->to_pl_enm_buildings2 - dmg_e; - } - APPLY_TO_BOTH(player, enemy, wall_height, pCard->to_pl_enm_wall2, wall_p, wall_e); - APPLY_TO_BOTH(player, enemy, tower_height, pCard->to_pl_enm_tower2, tower_p, tower_e); - break; - } - // } - if ( quarry_p > 0 || quarry_e > 0 ) - pArcomageGame->PlaySound(30); - if ( quarry_p < 0 || quarry_e < 0 ) - pArcomageGame->PlaySound(31); - if ( magic_p > 0 || magic_e > 0 ) - pArcomageGame->PlaySound(33); - if ( magic_p < 0 || magic_e < 0 ) - pArcomageGame->PlaySound(34); - if ( zoo_p > 0 || zoo_e > 0 ) - pArcomageGame->PlaySound(36); - if ( zoo_p < 0 || zoo_e < 0 ) - pArcomageGame->PlaySound(37); - if ( bricks_p > 0 || bricks_e > 0 ) - pArcomageGame->PlaySound(39); - if ( bricks_p < 0 || bricks_e < 0 ) - pArcomageGame->PlaySound(40); - if ( gems_p > 0 || gems_e > 0 ) - pArcomageGame->PlaySound(42); - if ( gems_p < 0 || gems_e < 0 ) - pArcomageGame->PlaySound(43); - if ( beasts_p > 0 || beasts_e > 0 ) - pArcomageGame->PlaySound(45u); - if ( beasts_p < 0 || beasts_e < 0 ) - pArcomageGame->PlaySound(46); - if ( buildings_p || buildings_e || dmg_p || dmg_e ) - pArcomageGame->PlaySound(48); - if ( wall_p > 0 || wall_e > 0 ) - pArcomageGame->PlaySound(49); - if ( wall_p < 0 || wall_e < 0 ) - pArcomageGame->PlaySound(50); - if ( tower_p > 0 || tower_e > 0 ) - pArcomageGame->PlaySound(52); - if ( tower_p < 0 || tower_e < 0 ) - pArcomageGame->PlaySound(53); - if ( player_num ) - { - if ( quarry_p ) - { - v184.x = 573; - v184.y = 92; - am_40D2B4(&v184, quarry_p); - } - if ( quarry_e ) - { - v184.x = 26; - v184.y = 92; - am_40D2B4(&v184, quarry_e); - } - if ( magic_p ) - { - v184.x = 573; - v184.y = 164; - am_40D2B4(&v184, magic_p); - } - if ( magic_e ) - { - v184.x = 26; - v184.y = 164; - am_40D2B4(&v184, magic_e); - } - if ( zoo_p ) - { - v184.x = 573; - v184.y = 236; - am_40D2B4(&v184, zoo_p); - } - if ( zoo_e ) - { - v184.x = 26; - v184.y = 236; - am_40D2B4(&v184, zoo_e); - } - if ( bricks_p ) - { - v184.x = 563; - v184.y = 114; - am_40D2B4(&v184, bricks_p); - } - if ( bricks_e ) - { - v184.x = 16; - v184.y = 114; - am_40D2B4(&v184, bricks_e); - } - if ( gems_p ) - { - v184.x = 563; - v184.y = 186; - am_40D2B4(&v184, gems_p); - } - if ( gems_e ) - { - v184.x = 16; - v184.y = 186; - am_40D2B4(&v184, gems_e); - } - if ( beasts_p ) - { - v184.x = 563; - v184.y = 258; - am_40D2B4(&v184, beasts_p); - } - if ( beasts_e ) - { - v184.x = 16; - v184.y = 258; - am_40D2B4(&v184, beasts_e); - } - if ( wall_p ) - { - v184.x = 442; - v184.y = 296; - am_40D2B4(&v184, wall_p); - } - if ( wall_e ) - { - v184.x = 180; - v184.y = 296; - am_40D2B4(&v184, wall_e); - } - if ( tower_p ) - { - v184.x = 514; - v184.y = 296; - am_40D2B4(&v184, tower_p); - } - if ( tower_e ) - { - v184.x = 122; - v184.y = 296; - am_40D2B4(&v184, tower_e); - } - if ( dmg_p ) - { - v184.x = 442; - v184.y = 296; - am_40D2B4(&v184, dmg_p); - } - if ( buildings_p ) - { - v184.x = 514; - v184.y = 296; - am_40D2B4(&v184, buildings_p); - } - if ( dmg_e ) - { - v184.x = 180; - v184.y = 296; - am_40D2B4(&v184, dmg_e); - } - if ( buildings_e ) - { - v184.x = 122; - v184.y = 296; - am_40D2B4(&v184, buildings_e); - } - } - else - { - if ( quarry_p ) - { - v184.x = 26; - v184.y = 92; - am_40D2B4(&v184, quarry_p); - } - if ( quarry_e ) - { - v184.x = 573; - v184.y = 92; - am_40D2B4(&v184, quarry_e); - } - if ( magic_p ) - { - v184.x = 26; - v184.y = 164; - am_40D2B4(&v184, magic_p); - } - if ( magic_e ) - { - v184.x = 573; - v184.y = 164; - am_40D2B4(&v184, magic_e); - } - if ( zoo_p ) - { - v184.x = 26; - v184.y = 236; - am_40D2B4(&v184, zoo_p); - } - if ( zoo_e ) - { - v184.x = 573; - v184.y = 236; - am_40D2B4(&v184, zoo_e); - } - if ( bricks_p ) - { - v184.x = 16; - v184.y = 114; - am_40D2B4(&v184, bricks_p); - } - if ( bricks_e ) - { - v184.x = 563; - v184.y = 114; - am_40D2B4(&v184, bricks_e); - } - if ( gems_p ) - { - v184.x = 16; - v184.y = 186; - am_40D2B4(&v184, gems_p); - } - if ( gems_e ) - { - v184.x = 563; - v184.y = 186; - am_40D2B4(&v184, gems_e); - } - if ( beasts_p ) - { - v184.x = 16; - v184.y = 258; - am_40D2B4(&v184, beasts_p); - } - if ( beasts_e ) - { - v184.x = 563; - v184.y = 258; - am_40D2B4(&v184, beasts_e); - } - if ( wall_p ) - { - v184.x = 180; - v184.y = 296; - am_40D2B4(&v184, wall_p); - } - if ( wall_e ) - { - v184.x = 442; - v184.y = 296; - am_40D2B4(&v184, wall_e); - } - if ( tower_p ) - { - v184.x = 122; - v184.y = 296; - am_40D2B4(&v184, tower_p); - } - if ( tower_e ) - { - v184.x = 514; - v184.y = 296; - am_40D2B4(&v184, tower_e); - } - if ( dmg_p ) - { - v184.x = 180; - v184.y = 296; - am_40D2B4(&v184, dmg_p); - } - if ( buildings_p ) - { - v184.x = 122; - v184.y = 296; - am_40D2B4(&v184, buildings_p); - } - if ( dmg_e ) - { - v184.x = 442; - v184.y = 296; - am_40D2B4(&v184, dmg_e); - } - if ( buildings_e ) - { - v184.x = 514; - v184.y = 296; - am_40D2B4(&v184, buildings_e); - } - } -#undef APPLY_TO_BOTH -#undef APPLY_TO_ENEMY -#undef APPLY_TO_PLAYER - -} - -//----- (0040D2B4) -------------------------------------------------------- -int am_40D2B4( POINT* startXY, int effect_value ) -{ - int v2; // ebp@1 -// POINT *v3; // edi@1 - int result; // eax@3 - int v6; - stru272_stru0 *v8; // ecx@12 - signed int v11; // [sp+10h] [bp-8h]@1 - - v11 = 0; - v2 = effect_value; - - while ( array_4FABD0[v11].have_effect )//Ritor1: needed refactoring - { - result = array_4FABD0[v11].field_40->_40E2A7(); - if ( !result ) - { - array_4FABD0[v11].have_effect = 0; - --v11; - } - ++v11; - if ( v11 >= 10 ) - return result; - } - v6 = v11; - array_4FABD0[v11].have_effect = 1; - if ( effect_value <= 0 ) - { - array_4FABD0[v6].effect_sign = 0; - effect_value = -effect_value; - } - else - array_4FABD0[v6].effect_sign = 1; - array_4FABD0[v6].field_4.effect_area.left = startXY->x - 20; - array_4FABD0[v6].field_4.effect_area.right = startXY->x + 20; - array_4FABD0[v6].field_4.effect_area.top = startXY->y - 20; - array_4FABD0[v6].field_4.effect_area.bottom = startXY->y + 20; - array_4FABD0[v6].field_4.field_10 = -60; - array_4FABD0[v6].field_4.field_14 = 60; - array_4FABD0[v6].field_4.field_18 = 180; - array_4FABD0[v6].field_4.field_1Cf = 0.5; - array_4FABD0[v6].field_4.field_20 = 150; - array_4FABD0[v6].field_4.field_24f= 50.0; - array_4FABD0[v6].field_4.field_28f = 3.0; - array_4FABD0[v6].field_4.field_2Cf = 8.0; - array_4FABD0[v6].field_4.field_30 = 5; - array_4FABD0[v6].field_4.field_34 = 15; - array_4FABD0[v6].field_4.sparks_array = &array_4FABD0[v6].effect_sparks[0]; - v8 = array_4FABD0[v6].field_40; - v8->StartFill(&array_4FABD0[v6].field_4); - if ( 10 * effect_value > 150 ) - effect_value = 15; - - if ( v8->signature != SIG_trpg ) - return 2; - if ( !v8->field_59 ) - return 3; - v8->position_in_sparks_arr = 10 * effect_value; - v8->field_30 = 0.0; - v8->field_58 = 0; - v8->field_44 = 0; - v8->field_4C = 0; - v8->field_48 = 0; - v8->field_50 = 0; - for (int i = 0; i < v8->field_4; ++i) - v8->field_54[i].have_spark = 0; - return 0; -} - -//----- (0040D402) -------------------------------------------------------- -int ApplyDamageToBuildings( int player_num, int damage ) -{ -// ArcomagePlayer *v2; // ecx@1 - int v3; // esi@1 - int result; // eax@3 - - v3 = am_Players[player_num].wall_height; - //if ( v3 <= 0 ) - result = 0; - //else - //{ - if ( v3 >= -damage ) - { - result = damage; - am_Players[player_num].wall_height += damage; - } - else - { - damage += v3; - result = -v3; - am_Players[player_num].wall_height = 0; - am_Players[player_num].tower_height += damage; - } - //} - if ( am_Players[player_num].tower_height < 0 ) - am_Players[player_num].tower_height = 0; - return result; -} -// 40D402: using guessed type int __fastcall am_40D402(uint, uint); - -//----- (0040D444) -------------------------------------------------------- -void GameResultsApply() -{ - int winner; // esi@1 - int victory_type; // edi@1 - int pl_resource; // edx@25 - int en_resource; // eax@28 - unsigned int tavern_num; // eax@54 -// char pText[64]; // [sp+Ch] [bp-48h]@1 -// POINT xy; // [sp+4Ch] [bp-8h]@1 - - winner = -1; - victory_type = -1; - //nullsub_1(); - /*strcpy(pText, "The Winner is: ");//"Победил: " Ritor1: архаизм - xy.y = 160; - xy.x = 320; //- 12 * v2 / 2; - am_DrawText(-1, pText, &xy);*/ - - //проверка построена ли башня - if ( am_Players[0].tower_height < max_tower_height && am_Players[1].tower_height >= max_tower_height )//наша башня не построена, а у врага построена - { - winner = 2;//победил игрок 2(враг) - victory_type = 0; - } - else if ( am_Players[0].tower_height >= max_tower_height && am_Players[1].tower_height < max_tower_height )//наша башня построена, а у врага нет - { - winner = 1;//победил игрок 1(мы) - victory_type = 0; - } - else if ( am_Players[0].tower_height >= max_tower_height && am_Players[1].tower_height >= max_tower_height )//и у нас, и у врага построена - { - if ( am_Players[0].tower_height == am_Players[1].tower_height )//наши башни равны - { - winner = 0;//никто не победил - victory_type = 4;//ничья - } - else//наши башни не равны - { - winner = (am_Players[0].tower_height <= am_Players[1].tower_height) + 1;//победил тот, у кого выше - victory_type = 0; - } - } - - //проверка разрушена ли башня - if ( am_Players[0].tower_height <= 0 && am_Players[1].tower_height > 0 )//наша башня разрушена, а у врага нет - { - winner = 2;// победил игрок 2(враг) - victory_type = 2;//победил разрушив башню врага - } - else if ( am_Players[0].tower_height > 0 && am_Players[1].tower_height <= 0 )//у врага башня разрушена, а у нас нет - { - winner = 1;//победил игрок 1(мы) - victory_type = 2;//победил разрушив башню врага - } - else if ( am_Players[0].tower_height <= 0 && am_Players[1].tower_height <= 0 )//наша башня разрушена, и у врага разрушена - { - if ( am_Players[0].tower_height == am_Players[1].tower_height )//если башни равны - { - if ( am_Players[0].wall_height == am_Players[1].wall_height )//если стены равны - { - winner = 0; - victory_type = 4; - } - else//если стены не равны - { - winner = (am_Players[0].wall_height <= am_Players[1].wall_height) + 1;//победил тот, у кого стена выше - victory_type = 1;//победа когда больше стена при ничье - } - } - else//башни не равны - { - winner = (am_Players[0].tower_height <= am_Players[1].tower_height) + 1;// побеждает тот у кого башня больше - victory_type = 2;//победил разрушив башню врага - } - } - - //проверка набраны ли ресурсы - //проверка какого ресурса больше всего у игрока 1(нас) - pl_resource = am_Players[0].resource_bricks;//кирпичей больше чем др. ресурсов - if ( am_Players[0].resource_gems > am_Players[0].resource_bricks - && am_Players[0].resource_gems > am_Players[0].resource_beasts )//драг.камней больше всего - pl_resource = am_Players[0].resource_gems; - else if ( am_Players[0].resource_beasts > am_Players[0].resource_gems - && am_Players[0].resource_beasts > am_Players[0].resource_bricks )//зверей больше всего - pl_resource = am_Players[0].resource_beasts; - - //проверка какого ресурса больше у игрока 2(врага) - en_resource = am_Players[1].resource_bricks;//кирпичей больше чем др. ресурсов - if ( am_Players[1].resource_gems > am_Players[1].resource_bricks - && am_Players[1].resource_gems > am_Players[1].resource_beasts )//драг.камней больше всего - en_resource = am_Players[1].resource_gems; - else if ( am_Players[1].resource_beasts > am_Players[1].resource_gems - && am_Players[1].resource_beasts > am_Players[1].resource_bricks )//зверей больше всего - en_resource = am_Players[1].resource_beasts; - - //сравнение ресурсов игроков - if ( winner == -1 && victory_type == -1 )//нет победителя по башням - { - if ( pl_resource < max_resources_amount && en_resource >= max_resources_amount )//враг набрал нужное количество - { - winner = 2;// враг победил - victory_type = 3;//победа собрав нужное количество ресурсов - } - else if ( pl_resource >= max_resources_amount && en_resource < max_resources_amount )//мы набрали нужное количество - { - winner = 1;// мы победили - victory_type = 3;//победа собрав нужное количество ресурсов - } - else if ( pl_resource >= max_resources_amount && en_resource >= max_resources_amount )//и у нас и у врага нужное количество ресурсов - { - if ( pl_resource == en_resource )// ресурсы равны - { - winner = 0;//ресурсы равны - victory_type = 4; //ничья - } - else - { - winner = (pl_resource <= en_resource) + 1;//ресурсы не равны, побеждает тот у кого больше - victory_type = 3;//победа собрав нужное количество ресурсов - } - } - } - else if ( winner == 0 && victory_type == 4 )// при ничье по башням и стене - { - if ( pl_resource != en_resource )//ресурсы не равны - { - winner = (pl_resource <= en_resource) + 1;//победил тот у кого больше - victory_type = 5;//победа когда при ничье большее количество ресурсов - } - else //ресурсы равны - { - winner = 0;//нет победителя - victory_type = 4; //ничья - } - } - - //подведение итогов - pArcomageGame->Victory_type = victory_type; - pArcomageGame->uGameWinner = winner; - if ( winner == 1 )//победитель игрок 1(мы) - { - if (( window_SpeakInHouse->par1C >= 108 ) && ( window_SpeakInHouse->par1C <= 120 ))//таверны - { - if ( !pParty->pArcomageWins[window_SpeakInHouse->par1C - 108] ) - { - pParty->pArcomageWins[window_SpeakInHouse->par1C - 108] = 1; - pParty->PartyFindsGold(p2DEvents[ window_SpeakInHouse->par1C - 1].fPriceMultiplier * 100.0, 0);//вознаграждение - } - } - //проверка выполнен ли квест по аркомагу - tavern_num = 0; - for ( uint i = 108; i <= 120; ++i ) - { - if ( !pParty->pArcomageWins[i - 108] ) - break; - tavern_num++; - } - if ( tavern_num == 13 ) - _449B7E_toggle_bit(pParty->_quest_bits, 238, 1);// 238 - Won all Arcomage games - - for ( int i = 0; i < 4; ++i )//внесение записи в Заслуги - { - if ( !_449B57_test_bit(pParty->pPlayers[i]._achieved_awards_bits, 1) ) - _449B7E_toggle_bit(pParty->pPlayers[i]._achieved_awards_bits, PLAYER_GUILD_BITS__ARCOMAGE_WIN, 1); - } - ++pParty->uNumArcomageWins; - if ( pParty->uNumArcomageWins > 1000000 )//ограничение количества побед - pParty->uNumArcomageWins = 1000000; - } - else//проигрыш - { - for ( int i = 0; i < 4; ++i )//внесение записи в Заслуги - { - if ( !_449B57_test_bit(pParty->pPlayers[i]._achieved_awards_bits, 1) ) - _449B7E_toggle_bit(pParty->pPlayers[i]._achieved_awards_bits, PLAYER_GUILD_BITS__ARCOMAGE_LOSE, 1); - } - ++pParty->uNumArcomageLoses; - if ( pParty->uNumArcomageLoses > 1000000 )//ограничение количества проигрышей - pParty->uNumArcomageLoses = 1000000; - } -} - -//----- (00409C8B) -------------------------------------------------------- -void ArcomageGame::PrepareArcomage() -{ -// signed __int64 v1; // qax@4 - int v2; // esi@4 - int v3; // esi@5 - signed int v4; // edi@5 -// int v6; // edx@9 - RECT pXYZW; // [sp+8h] [bp-1Ch]@5 - POINT pXY; // [sp+18h] [bp-Ch]@5 - - pAudioPlayer->StopChannels(-1, -1); - strcpy(pArcomageGame->pPlayer1Name, Player1Name); - strcpy(pArcomageGame->pPlayer2Name, Player2Name); - am_byte_4FAA76 = 0; - am_byte_4FAA75 = 0; - - for (int i = 0; i < 10; ++i) - { - v2 = (i+1) % 4; - v3 = (i+1) / 4; - shown_cards[i].uCardId = -1; - shown_cards[i].field_4 = 0; - shown_cards[i].field_8.x = 100 * v2 + 120; - shown_cards[i].field_8.y = 138 * v3 + 18; - shown_cards[i].field_10_xplus = -100 * v2 / 5; - shown_cards[i].field_14_y_plus = -138 * v3 / 5; - shown_cards[i].field_18_point.x = shown_cards[i].field_8.x; - shown_cards[i].field_18_point.y = shown_cards[i].field_8.y; - } - - pXY.x = 0; - pXY.y = 0; - ArcomageGame::LoadBackground(); - pXYZW.left = 0; - pXYZW.right = window->GetWidth(); - pXYZW.top = 0; - pXYZW.bottom = window->GetHeight(); - am_BeginScene(pArcomageGame->pBackgroundPixels, -1, 1); - pRenderer->am_Blt_Copy(&pXYZW, &pXY, 2); - am_EndScene(); - pRenderer->Present(); - ArcomageGame::LoadSprites(); - pRenderer->Present(); - - v4 = 120; - for ( int i = 0; i < 12; ++i ) - am_sounds[i] = pSoundList->LoadSound(v4++, 0); - - for (int i = 0; i < 10; ++i) - array_4FABD0[i].field_40 = stru272_stru0::New(); - - current_card_slot_index = -1; - amuint_4FAA4C = -1; - byte_4FAA74 = 0; - pArcomageGame->field_F4 = 0; - am_gameover = false; - byte_505880 = 0; - dword_4FAA70 = 0; - need_to_discard_card = 0; - SetStartGameData(); - InitalHandsFill(); - //nullsub_1(); - pArcomageGame->GameOver = 0; - pArcomageGame->pfntComic = pFontComic; - pArcomageGame->pfntArrus = pFontArrus; -} - -//----- (0040D711) -------------------------------------------------------- -ArcomageGame::ArcomageGame() -{ - field_4 = 0; - //RGBTexture::RGBTexture(&this->pGameBackground); - //RGBTexture::RGBTexture(&v1->pSprites); - bGameInProgress = 0; - field_F9 = 0; -} - -//----- (00409BE8) -------------------------------------------------------- -void SetStartConditions() -{ - const ArcomageStartConditions *st_cond; // eax@1 - - st_cond = &start_conditions[window_SpeakInHouse->par1C - 108]; - start_tower_height = st_cond->tower_height; - start_wall_height = st_cond->wall_height; - start_quarry_level = st_cond->quarry_level - 1; - start_magic_level = st_cond->magic_level - 1; - start_zoo_level = st_cond->zoo_level - 1; - minimum_cards_at_hand = 5; - quarry_bonus = 1; - magic_bonus = 1; - zoo_bonus = 1; - max_tower_height = st_cond->max_tower; - max_resources_amount = st_cond->max_resources; - - opponent_mastery = st_cond->mastery_lvl; - - start_bricks_amount = st_cond->bricks_amount; - start_gems_amount = st_cond->gems_amount; - start_beasts_amount = st_cond->beasts_amount; -} - -//----- (0040D75D) -------------------------------------------------------- -void am_DrawText( int a1, const char *pText, POINT *pXY ) -{ - pPrimaryWindow->DrawText( pFontComic, pXY->x, pXY->y - ((pFontComic->uFontHeight - 3) / 2) + 3, 0, pText, 0, 0, 0); -} - -//----- (0040DB27) -------------------------------------------------------- -void DrawRect( RECT *pXYZW, unsigned __int16 uColor, char bSolidFill ) -{ - pRenderer->BeginScene(); - pRenderer->SetRasterClipRect(0, 0, window->GetWidth() - 1, window->GetHeight() - 1); - if ( bSolidFill ) - { - for ( int i = pXYZW->top; i <= pXYZW->bottom; ++i ) - pRenderer->RasterLine2D(pXYZW->left, i, pXYZW->right, i, uColor); - } - else - { - pRenderer->RasterLine2D(pXYZW->left, pXYZW->top, pXYZW->right, pXYZW->top, uColor); - pRenderer->RasterLine2D(pXYZW->right, pXYZW->top, pXYZW->right, pXYZW->bottom, uColor); - pRenderer->RasterLine2D(pXYZW->right, pXYZW->bottom, pXYZW->left, pXYZW->bottom, uColor); - pRenderer->RasterLine2D(pXYZW->left, pXYZW->bottom, pXYZW->left, pXYZW->top, uColor); - } - pRenderer->EndScene(); -} - -void DrawSquare( POINT *pTargetXY, unsigned __int16 uColor ) -{ - pRenderer->BeginScene(); - //if ( uNumSceneBegins ) - { - if ( pTargetXY->x >= 0 && pTargetXY->x <= window->GetWidth() - 1 - && pTargetXY->y >= 0 && pTargetXY->y <= window->GetHeight() - 1) - { - pRenderer->WritePixel16(pTargetXY->x, pTargetXY->y, uColor); - pRenderer->WritePixel16(pTargetXY->x + 1, pTargetXY->y, uColor); - pRenderer->WritePixel16(pTargetXY->x, pTargetXY->y + 1, uColor); - pRenderer->WritePixel16(pTargetXY->x + 1, pTargetXY->y + 1, uColor); - } - pRenderer->EndScene(); - } -} - -//----- (0040DBD3) -------------------------------------------------------- -void DrawPixel( POINT *pTargetXY, unsigned __int16 uColor ) -{ - pRenderer->BeginScene(); - //if ( pRenderer->uNumSceneBegins ) - { - if ( pTargetXY->x >= 0 && pTargetXY->x <= window->GetWidth() - 1 - && pTargetXY->y >= 0 && pTargetXY->y <= window->GetHeight() - 1) - { - pRenderer->WritePixel16(pTargetXY->x, pTargetXY->y, uColor); - /*int xVal = pTargetXY->x; - int yVal = pTargetXY->y; - if ( xVal >= 0 && xVal <= 639 && yVal >= 0 && yVal <= 479) - { - pRenderer->pTargetSurface[xVal + pRenderer->uTargetSurfacePitch * yVal] = uColor; - }*/ - } - pRenderer->EndScene(); - } -} - -//----- (0040DDB1) -------------------------------------------------------- -int rand_interval( int min, int max ) -{ - return min + rand() % (max - min + 1); -} - -//----- (0040DEC8) -------------------------------------------------------- -void __fastcall am_IntToString(int val, char *pOut) -{ - sprintfex(pOut, "%d", val); -} - -void set_stru1_field_8_InArcomage(int inValue) -{ - switch(inValue) - { - case 91:LOBYTE(pArcomageGame->stru1.field_8) = 123;break; - case 92:LOBYTE(pArcomageGame->stru1.field_8) = 124;break; - case 93:LOBYTE(pArcomageGame->stru1.field_8) = 125;break; - case 96:LOBYTE(pArcomageGame->stru1.field_8) = 126;break; - case 61:LOBYTE(pArcomageGame->stru1.field_8) = 43;break; - case 55:LOBYTE(pArcomageGame->stru1.field_8) = 38;break; - case 56:LOBYTE(pArcomageGame->stru1.field_8) = 42;break; - case 57:LOBYTE(pArcomageGame->stru1.field_8) = 40;break; - case 59:LOBYTE(pArcomageGame->stru1.field_8) = 58;break; - case 54:LOBYTE(pArcomageGame->stru1.field_8) = 94;break; - case 50:LOBYTE(pArcomageGame->stru1.field_8) = 64;break; - case 51:LOBYTE(pArcomageGame->stru1.field_8) = 35;break; - case 52:LOBYTE(pArcomageGame->stru1.field_8) = 36;break; - case 53:LOBYTE(pArcomageGame->stru1.field_8) = 37;break; - case 49:LOBYTE(pArcomageGame->stru1.field_8) = 33;break; - case 39:LOBYTE(pArcomageGame->stru1.field_8) = 34;break; - case 44:LOBYTE(pArcomageGame->stru1.field_8) = 60;break; - case 46:LOBYTE(pArcomageGame->stru1.field_8) = 62;break; - case 47:LOBYTE(pArcomageGame->stru1.field_8) = 63;break; - case 48:LOBYTE(pArcomageGame->stru1.field_8) = 41;break; - default:LOBYTE(pArcomageGame->stru1.field_8) = inValue;break; - } -} \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Arcomage.h --- a/Arcomage.h Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,298 +0,0 @@ -#pragma once -#include "OSAPI.h" - -#include "Texture.h" - - - - -/* 272 */ -#pragma pack(push, 1) -struct ArcomageCard -{ - char pCardName[32]; - int slot; - char field_24; - char needed_quarry_level; - char needed_magic_level; - char needed_zoo_level; - char needed_bricks; - char needed_gems; - char needed_beasts; - bool can_be_discarded; - int compare_param; - char field_30; - char draw_extra_card_count; - char to_player_quarry_lvl; - char to_player_magic_lvl; - char to_player_zoo_lvl; - char to_player_bricks; - char to_player_gems; - char to_player_beasts; - char to_player_buildings; - char to_player_wall; - char to_player_tower; - char to_enemy_quarry_lvl; - char to_enemy_magic_lvl; - char to_enemy_zoo_lvl; - char to_enemy_bricks; - char to_enemy_gems; - char to_enemy_beasts; - char to_enemy_buildings; - char to_enemy_wall; - char to_enemy_tower; - char to_pl_enm_quarry_lvl; - char to_pl_enm_magic_lvl; - char to_pl_enm_zoo_lvl; - char to_pl_enm_bricks; - char to_pl_enm_gems; - char to_pl_enm_beasts; - char to_pl_enm_buildings; - char to_pl_enm_wall; - char to_pl_enm_tower; - char field_4D; - char can_draw_extra_card2; - char to_player_quarry_lvl2; - char to_player_magic_lvl2; - char to_player_zoo_lvl2; - char to_player_bricks2; - char to_player_gems2; - char to_player_beasts2; - char to_player_buildings2; - char to_player_wall2; - char to_player_tower2; - char to_enemy_quarry_lvl2; - char to_enemy_magic_lvl2; - char to_enemy_zoo_lvl2; - char to_enemy_bricks2; - char to_enemy_gems2; - char to_enemy_beasts2; - char to_enemy_buildings2; - char to_enemy_wall2; - char to_enemy_tower2; - char to_pl_enm_quarry_lvl2; - char to_pl_enm_magic_lvl2; - char to_pl_enm_zoo_lvl2; - char to_pl_enm_bricks2; - char to_pl_enm_gems2; - char to_pl_enm_beasts2; - char to_pl_enm_buildings2; - char to_pl_enm_wall2; - char to_pl_enm_tower2; - char field_6A; - char field_6B; -}; -#pragma pack(pop) - - -/* 401 */ -#pragma pack(push, 1) -struct AcromageCardOnTable -{ - int uCardId; - int field_4; - POINT field_8; - int field_10_xplus; - int field_14_y_plus; - POINT field_18_point; -}; -#pragma pack(pop) - - -#pragma pack(push, 1) -struct ArcomagePlayer -{ - char pPlayerName[32]; - int IsHisTurn; - int tower_height; - int wall_height; - int quarry_level; - int magic_level; - int zoo_level; - int resource_bricks; - int resource_gems; - int resource_beasts; - int cards_at_hand[10]; - POINT card_shift[10]; -}; -#pragma pack(pop) - - - -#pragma pack(push, 1) -struct ArcomageGame_stru1 -{ - int field_0; - int field_4; - int field_8; -}; -#pragma pack(pop) - - - - -#pragma pack(push, 1) -struct ArcomageGame -{ - ArcomageGame(); - - static bool LoadBackground(); - static bool LoadSprites(); - static bool MsgLoop(int a1, ArcomageGame_stru1 *a2); - static void PlaySound(unsigned int event_id); - static void OnMouseClick(char right_left, bool bDown); - static void OnMouseMove(int x, int y); - static void GetCardRect(unsigned int uCardID, RECT *pCardRect); - static void PrepareArcomage(); - static void DoBlt_Copy(unsigned __int16 *pPixels); // idb - - static void Loop(); - - char field_0; - char field_1; - char field_2; - char field_3; - int field_4; - ArcomageGame_stru1 stru1; - tagMSG msg; - int mouse_x; - int mouse_y; - char mouse_left; - char field_39; - char mouse_right; - char field_3B; - unsigned __int16 *pBackgroundPixels; - unsigned __int16 *pSpritesPixels; - unsigned __int16 *pBlit_Copy_pixels; - struct GUIFont *pfntComic;//ptr_48; - struct GUIFont *pfntArrus;//ptr_4C; - int field_50; - int field_54; - RGBTexture pGameBackground; - RGBTexture pSprites; - int event_timer_time; - int uGameWinner; - int Victory_type; - char pPlayer1Name[32]; - char pPlayer2Name[32]; - char field_F4; - char GameOver; - char field_F6; - char prev_mouse_left; - char prev_mouse_right; - char field_F9; - char bGameInProgress; -}; -#pragma pack(pop) - - - - -extern ArcomageGame *pArcomageGame; -extern ArcomageCard pCards[87]; -extern void set_stru1_field_8_InArcomage(int inValue); - - - -#pragma pack(push, 1) -struct stru272_stru1 -{ - int have_spark; - POINT spark_position; - int field_C; - int field_10; - int field_14; - int field_18; -}; -#pragma pack(pop) - -/* 404 */ -#pragma pack(push, 1) -struct stru272_stru2 -{ -/*int field_0; -int field_4; -int field_8; -int field_C;*/ - RECT effect_area; - int field_10; - int field_14; - int field_18; - float field_1Cf; - int field_20; - float field_24f; - float field_28f; - float field_2Cf; - int field_30; - int field_34; - stru272_stru1* sparks_array; -}; -#pragma pack(pop) - - -/* 270 */ -#pragma pack(push, 1) -struct stru272_stru0 // ARCOMAGE stuff -{ - static stru272_stru0 *New(); - - int Free(); - int StartFill(stru272_stru2* a2); - int Clear(char a2, char a3); - int DrawEffect(); - int _40E2A7(); - - int signature; - int field_4; - int position_in_sparks_arr; - int field_C; - int field_10; - int field_14; - int field_18; - int field_1C; - int field_20; - int field_24; - float field_28; - float field_2C; - float field_30; - int field_34; - int field_38; - int field_3C; - int field_40; - int field_44; - int field_48; - int field_4C; - int field_50; - stru272_stru1 * field_54; - char field_58; - char field_59; - char field_5A; - char field_5B; -}; -#pragma pack(pop) - -#define DECK_SIZE 108 - -#pragma pack(push, 1) -struct ArcomageDeck -{ - char name[32]; - char cardsInUse[DECK_SIZE]; - int cards_IDs[DECK_SIZE]; -}; - -#pragma pack(pop) - -#pragma pack(push, 1) -struct stru272 -{ - char have_effect; - char effect_sign; - char _pad_2; - char _pad_3; - stru272_stru2 field_4; - stru272_stru0 *field_40; - stru272_stru1 effect_sparks[150]; -}; -#pragma pack(pop) - diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Arcomage/Arcomage.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Arcomage/Arcomage.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,3775 @@ +#define _CRTDBG_MAP_ALLOC +#include +#include + +#define _CRT_SECURE_NO_WARNINGS +#include + + +#include "..\Engine/Graphics/Render.h" +#include "Arcomage.h" +#include "AudioPlayer.h" +#include "Game.h" +#include "..\Engine/Graphics/Viewport.h" +#include "Timer.h" +#include "GUIFont.h" +#include "Party.h" +#include "GUIWindow.h" +#include "texts.h" +#include +#include "mm7_data.h" +#include "UI/UIHouses.h" + + + +void SetStartConditions(); +void SetStartGameData(); +void FillPlayerDeck(); +void InitalHandsFill(); +void GetNextCardFromDeck(int player_num); +int GetEmptyCardSlotIndex(int player_num); +void IncreaseResourcesInTurn(int player_num); +void TurnChange(); +bool IsGameOver(); +int CalculateCardPower(ArcomagePlayer* player, ArcomagePlayer* enemy, ArcomageCard* pCard, int mastery); +char PlayerTurn(int player_num); +void DrawGameUI(int animation_stage); +void DrawSparks(); +void DrawRectanglesForText(); +void DrawPlayersText(); +void DrawPlayerLevels(int a1, char *text, POINT *pXY); +void DrawBricksCount(int a1, char* text, POINT *pXY); +void DrawGemsCount(int a1, char* text, POINT* pXY); +void DrawBeastsCount(int a1, char *text, POINT *pXY); +void DrawPlayersTowers(); +void DrawPlayersWall(); +void DrawCards(); +void DrawCardAnimation(int a1); +int GetPlayerHandCardCount(int player_num); +int DrawCardsRectangles(int player_num); +bool DiscardCard(int player_num, int card_slot_index); +bool PlayCard(int player_num, int card_slot_num); +bool CanCardBePlayed(int player_num, int hand_card_indx); +void ApplyCardToPlayer(int player_num, unsigned int uCardID); +int am_40D2B4(POINT* a1, int a2); // weak +int ApplyDamageToBuildings(int player_num, int damage); // weak +void GameResultsApply(); + +void am_DrawText(int a1, const char *pText, POINT *pXY); +void am_BeginScene(unsigned __int16 *pPcxPixels, int a2, int a3); // idb +void am_EndScene(); +void DrawRect(RECT *pXYZW, unsigned __int16 uColor, char bSolidFill); +void DrawSquare( POINT *pTargetXY, unsigned __int16 uColor ); +void DrawPixel(POINT *pTargetXY, unsigned __int16 uColor); +int rand_interval(int min, int max); // idb +void __fastcall am_IntToString(int val, char *pOut); + +//----- (0040DEDB) -------------------------------------------------------- +unsigned int R8G8B8_to_TargetFormat(int uColor) +{ + return Color16(LOBYTE(uColor), BYTE1(uColor), BYTE2(uColor)); +} + +/* 388 */ +#pragma pack(push, 1) +struct ArcomageStartConditions +{ + __int16 max_tower; + __int16 max_resources; + __int16 tower_height; + __int16 wall_height; + __int16 quarry_level; + __int16 magic_level; + __int16 zoo_level; + __int16 bricks_amount; + __int16 gems_amount; + __int16 beasts_amount; + int mastery_lvl; +}; +#pragma pack(pop) +const ArcomageStartConditions start_conditions[13] = +{ + { 30, 100, 15, 5, 2, 2, 2, 10, 10, 10, 0}, + { 50, 150, 20, 5, 2, 2, 2, 5, 5, 5, 1}, + { 50, 150, 20, 5, 2, 2, 2, 5, 5, 5, 2}, + { 75, 200, 25, 10, 3, 3, 3, 5, 5, 5, 2}, + { 75, 200, 20, 10, 3, 3, 3, 5, 5, 5, 1}, + {100, 300, 30, 15, 4, 4, 4, 10, 10, 10, 1}, + {100, 300, 30, 15, 4, 4, 4, 10, 10, 10, 2}, + {150, 400, 20, 10, 5, 5, 5, 25, 25, 25, 0}, + {200, 500, 20, 10, 1, 1, 1, 15, 15, 15, 2}, + {100, 300, 20, 50, 1, 1, 5, 5, 5, 25, 0}, + {125, 350, 10, 20, 3, 1, 2, 15, 5, 10, 2}, + {125, 350, 10, 20, 3, 1, 2, 15, 5, 10, 1}, + {100, 300, 50, 50, 5, 3, 5, 20, 10, 20, 0} +}; + +#define SIG_trpg 0x67707274 +#define SIG_xxxx 0x78787878 + +ArcomageGame *pArcomageGame = new ArcomageGame; + +ArcomagePlayer am_Players[2]; // 00505708 +AcromageCardOnTable shown_cards[10]; // 004FAA78 +stru272 array_4FABD0[10]; // 4FABD0 + + +ArcomageDeck playDeck; // 00505288 +ArcomageDeck deckMaster; // 005054C8 + +char Player2Name[] = "Enemy"; +char Player1Name[] = "Player"; + +/* 267 */ +#pragma pack(push, 1) +struct stru273 +{ + bool _40DD2F(); + bool Inside(RECT*pXYZW); + + int x; + int y; + char curr_mouse_left; + char mouse_left_state_changed; + char curr_mouse_right; + char mouse_right_state_changed; +}; +#pragma pack(pop) + + +#pragma pack(push, 1) +struct am_2 + { + int slot_index; + int card_power; + }; +#pragma pack(pop) + +am_2 cards_power[10]; +std::array<__int16, 12> am_sounds; + +char byte_4E185C = 1; // weak +char am_byte_4E185D = 1; // weak +char use_start_bonus = 1; // weak + +int start_tower_height; +int start_wall_height; +int start_quarry_level; +int start_magic_level; +int start_zoo_level; + + +int minimum_cards_at_hand = 5; // 004E1874 +int quarry_bonus = 1; +int magic_bonus = 1; +int zoo_bonus = 1; + +int max_tower_height = 50; +int max_resources_amount = 100 ; + +int opponent_mastery = 1 ; // weak + +bool am_gameover; // 004FAA2C +char byte_4FAA2D; // weak + +int am_default_starting_player = 0; // 505890 +int current_player_num; // 004FAA6C +char need_to_discard_card; // 04FAA77 + +int current_card_slot_index; // 004FABBC +int played_card_id; // 4FABC0 +int uCardID; // 4FAA50 + +int deck_walk_index; // 004FABC8 + +int start_bricks_amount; +int start_gems_amount; +int start_beasts_amount; + +POINT amuint_4FAA3C_blt_xy; +POINT am_uint_4FAA44_blt_xy; +POINT amuint_4FAA54_blt_xy; +POINT amuint_4FAA5C_blt_xy; + +int dword_4FAA64; // weak +int dword_4FAA68; // weak + +int dword_4FABB8; // weak + +char byte_4FAA00; // weak + +int amuint_4FAA34; // weak +int amuint_4FAA38; // weak +int amuint_4FAA4C; // weak + +char byte_4FAA2E; // weak + +int dword_4FAA70; // weak +char byte_4FAA74; // weak +char am_byte_4FAA75; // weak +char am_byte_4FAA76; // weak + +int amuint_4FABC4; // weak + + +char byte_505880; // weak +char byte_505881; // weak + +//----- (0040DD2F) -------------------------------------------------------- +bool stru273::_40DD2F() +{ + + this->x = pArcomageGame->mouse_x; + this->y = pArcomageGame->mouse_y; + this->curr_mouse_left = pArcomageGame->mouse_left; + this->mouse_left_state_changed = pArcomageGame->mouse_left == pArcomageGame->prev_mouse_left; + this->curr_mouse_right = pArcomageGame->mouse_right; + this->mouse_right_state_changed = pArcomageGame->mouse_right == pArcomageGame->prev_mouse_right; + pArcomageGame->prev_mouse_left = pArcomageGame->mouse_left; + pArcomageGame->prev_mouse_right = pArcomageGame->mouse_right; + return true; +} + +//----- (0040DD93) -------------------------------------------------------- +bool stru273::Inside(RECT*pXYZW ) + { + + return (x >= pXYZW->left) && (x <= pXYZW->right) && + (y>= pXYZW->top) && (y <= pXYZW->bottom); +} + +//----- (0040DFD1) -------------------------------------------------------- +stru272_stru0 *stru272_stru0::New() +{ + stru272_stru0 *v2 = (stru272_stru0 *)malloc(0x5Cu); + v2->signature = SIG_trpg; + v2->position_in_sparks_arr = 0; + v2->field_30 = 0.0; + v2->field_58 = 0; + v2->field_59 = 0; + + return v2; +} + +//----- (0040DFFE) -------------------------------------------------------- +int stru272_stru0::Free() +{ + if ( this->signature == SIG_trpg ) + { + this->signature = SIG_xxxx; + free(this); + return 0; + } + else + return 2; +} + +//----- (0040E01A) -------------------------------------------------------- +int stru272_stru0::StartFill( stru272_stru2* a2 ) +{ + //stru272_stru0* a1 = this; + if ( this->signature == SIG_trpg ) + { + this->field_4 = a2->field_20; + this->field_C = a2->effect_area.left << 16; + this->field_10 = a2->effect_area.top << 16; + this->field_14 = a2->effect_area.right << 16; + this->field_18 = a2->effect_area.bottom << 16; + this->field_1C = a2->field_10; + this->field_20 = a2->field_14; + this->field_24 = a2->field_18; + this->field_28 = (float)(a2->field_1Cf * 65536.0); + this->field_2C = a2->field_24f; + this->field_34 = (int)(a2->field_28f * 65536.0); + this->field_38 = (int)(a2->field_2Cf * 65536.0); + this->field_3C = a2->field_30; + this->field_40 = a2->field_34; + this->field_54 = a2->sparks_array; + this->field_59 = 1; + return 0; + } + else + return 2; +} + +//----- (0040E0F5) -------------------------------------------------------- +int stru272_stru0::Clear(char a2, char a3) + { + if ( signature == SIG_trpg) + { + if ( a2 ) + { + position_in_sparks_arr = 0; + field_30 = 0.0; + } + if ( field_59 && a3 ) + { + + for (int i=0; isignature != SIG_trpg ) + return 2; + v3 = this->position_in_sparks_arr; + v22 = this->field_30; + v4 = v3; + if ( v3 > 0 ) + { + v5 = v22 + this->field_2C; + v22 = v5; + if ( v5 > v4 ) + v22 = v4; + } + if ( v22 >= 1.0 || this->field_58 ) + { + v6 = 0; + v7 = this->field_54; + v20 = this->field_28; + + for ( v21 = this->field_4; v21; v21-- ) + { + if ( v7->have_spark > 0 ) + { + v8 = v7->field_14; + --v7->have_spark; + v9 = v8 + v7->field_C; + v10 = v20 + v7->field_18; + v7->field_C = v9; + v7->spark_position.x = v9 >> 16; + v11 = v10 + v7->field_10; + v7->field_18 = v10; + v7->field_10 = v11; + v7->spark_position.y = v11 >> 16; + v6 = 1; + //goto LABEL_14; + } + else + { + if ( v22 >= 1.0 ) + { + v12 = this->field_40; + v13 = this->field_3C; + v7->have_spark = rand_interval(v13,v12); + v7->field_14 = (rand() % 17 - 8) << 16; + v7->field_18 = (rand() % 17 - 8) << 16; + v14 = this->field_14 - 1; + v15 = this->field_C; + v16 = rand_interval(v15,v14); + v7->field_C = v16; + v7->spark_position.x = v16 >> 16; + v17 = this->field_18 - 1; + v18 = this->field_10; + v19 = rand_interval(v17, v18); + v7->field_10 = v19; + v7->spark_position.y = v19 >> 16; + --this->position_in_sparks_arr; + v22 = v22 - 1.0; + v6 = 1; + } + } +//LABEL_14: + ++v7; + //--v21; + //if ( !v21 ) + //{ + //this->field_58 = v6; + //this->field_30 = v22; + //return 0; + //} + } + this->field_58 = v6; + this->field_30 = v22; + } + return 0; +} + +//----- (0040E2A7) -------------------------------------------------------- +int stru272_stru0::_40E2A7() +{ + if (signature == SIG_trpg ) + { + if ( position_in_sparks_arr <= 0 ) + return field_58 != 0 ? 2 : 0; + else + return 1; + } + else + return 3; +} + +//----- (0040DFAF) -------------------------------------------------------- +void ArcomageGame::OnMouseClick(char right_left, bool bDown) +{ + if ( right_left ) + pArcomageGame->mouse_right = bDown; + else + pArcomageGame->mouse_left = bDown; +} + +//----- (0040DFC1) -------------------------------------------------------- +void ArcomageGame::OnMouseMove(int x, int y) +{ + pArcomageGame->mouse_x = x; + pArcomageGame->mouse_y = y; +} + +//----- (0040DF47) -------------------------------------------------------- +void DoBlt_Copy(unsigned __int16 *pPixels) +{ + RECT pSrcRect; + POINT pTargetPoint; // [sp+1Ch] [bp-8h]@1 + + pRenderer->Present(); + + pTargetPoint.x = 0; + pTargetPoint.y = 0; + + pSrcRect.left = 0; + pSrcRect.top = 0; + pSrcRect.right = window->GetWidth(); + pSrcRect.bottom = window->GetHeight(); + + pRenderer->BeginScene(); + pArcomageGame->pBlit_Copy_pixels = pPixels; + pRenderer->am_Blt_Copy(&pSrcRect, &pTargetPoint, 2); + pRenderer->EndScene(); + pArcomageGame->pBlit_Copy_pixels = nullptr; +} + +//----- (0040DDC9) -------------------------------------------------------- +void ArcomageGame::PlaySound( unsigned int event_id ) +{ + SoundID play_sound_id; // eax@10 + + switch ( event_id ) + { + case 40: + case 43: + case 46: + play_sound_id = SOUND_Arcomage_LoseResources; + break; + case 39: + case 41: + case 42: + case 44: + case 45: + case 47: + play_sound_id = SOUND_Arcomage_AddResources; + break; + case 0: + case 12: + case 14: + case 15: + case 16: + case 48: + case 50: + case 53: + play_sound_id = SOUND_Arcomage_TowerWallDamage; + break; + case 21: + case 22: + case 23: + play_sound_id = SOUND_Arcomage_DrawCard; + break; + case 56: + play_sound_id = SOUND_Arcomage_124; + break; + case 31: + case 34: + case 37: + play_sound_id = SOUND_Arcomage_ProductionDamage; + break; + case 1: + case 30: + case 32: + case 33: + case 35: + case 36: + case 38: + play_sound_id = SOUND_Arcomage_ProductionUpgrade; + break; + case 20: + play_sound_id = SOUND_Arcomage_127; + break; + case 3: + play_sound_id = SOUND_Arcomage_128; + break; + case 52: + case 54: + play_sound_id = SOUND_Arcomage_TowerUpgrade; + break; + case 10: + case 11: + case 13: + play_sound_id = SOUND_Arcomage_130; + break; + case 55u: + play_sound_id = SOUND_Arcomage_131; + break; + case 49: + case 51: + play_sound_id = SOUND_Arcomage_WallUpgrade; + break; + default: + return; + } + pAudioPlayer->PlaySound(play_sound_id, 0, 0, -1, 0, 0, 0, 0); +} + +//----- (0040DC2D) -------------------------------------------------------- +bool ArcomageGame::MsgLoop(int a1, ArcomageGame_stru1 *a2) +{ + void *v2; // ebp@1 + //BOOL v3; // eax@1 + + v2 = a2; + pArcomageGame->field_0 = 0; + pArcomageGame->stru1.field_0 = 0; + //v3 = PeekMessageA(&pArcomageGame->msg, 0, 0, 0, PM_REMOVE); + //if ( pArcomageGame->msg.message == WM_QUIT ) + //Game_DeinitializeAndTerminate(0); + if ( PeekMessageA(&pArcomageGame->msg, 0, 0, 0, PM_REMOVE) ) + { + if ( pArcomageGame->msg.message == WM_QUIT ) + Game_DeinitializeAndTerminate(0); + TranslateMessage(&pArcomageGame->msg); + DispatchMessageA(&pArcomageGame->msg); + } + /*if (pAsyncMouse) + { + EnterCriticalSection(&pGame->pThreadWardInstance->csAsyncMouse); + v4 = *((unsigned int *)pAsyncMouse + 7); + pArcomageGame->mouse_x = *((unsigned int *)pAsyncMouse + 6); + pArcomageGame->mouse_y = v4; + v5 = *((unsigned int *)pAsyncMouse + 27); + v6 = *(unsigned int *)v5; + if ( *(unsigned int *)v5 != v5 ) + { + do + { + v7 = *(unsigned int *)(v6 + 20); + if ( v7 & 1 ) + { + pArcomageGame->stru1.field_0 = 7; + } + else + { + if ( v7 & 2 ) + pArcomageGame->stru1.field_0 = 8; + } + v6 = *(unsigned int *)v6; + } + while ( v6 != *((unsigned int *)pAsyncMouse + 27) ); + } + pAsyncMouse->_46B944(); + if ( !*((unsigned char *)pAsyncMouse + 90) ) + pArcomageGame->field_F6 = 1; + LeaveCriticalSection(&pGame->pThreadWardInstance->csAsyncMouse); + }*/ + memcpy(v2, &pArcomageGame->stru1, 0xCu); + return pArcomageGame->stru1.field_0 != 0; +} + +//----- (0040D7D5) -------------------------------------------------------- +void am_BeginScene(unsigned __int16 *pPcxPixels, int a2, int a3) +{ + pRenderer->BeginScene(); + pArcomageGame->pBlit_Copy_pixels = pPcxPixels; +} + +//----- (0040D7EC) -------------------------------------------------------- +void Render::am_Blt_Chroma(RECT *pSrcRect, POINT *pTargetPoint, int a3, int blend_mode) +{ + unsigned __int16 *pSrc; // eax@2 + int uSrcTotalWidth; // ecx@4 + unsigned int v10; // esi@9 + int v21; // [sp+Ch] [bp-18h]@8 + unsigned __int16 *src_surf_pos; // [sp+10h] [bp-14h]@9 + __int32 src_width; // [sp+14h] [bp-10h]@3 + __int32 src_height; // [sp+18h] [bp-Ch]@3 + int uSrcPitch; // [sp+1Ch] [bp-8h]@5 + + if ( !uNumSceneBegins ) + return; + if ( !pArcomageGame->pBlit_Copy_pixels ) + return; + + //dest_surf_pos = &pRenderer->pTargetSurface[pTargetPoint->x + pTargetPoint->y * pRenderer->uTargetSurfacePitch]; + src_width = pSrcRect->right - pSrcRect->left; + src_height = pSrcRect->bottom - pSrcRect->top; + + if ( pArcomageGame->pBlit_Copy_pixels == pArcomageGame->pBackgroundPixels ) + uSrcTotalWidth = pArcomageGame->pGameBackground.uWidth; + else if ( pArcomageGame->pBlit_Copy_pixels == pArcomageGame->pSpritesPixels ) + uSrcTotalWidth = pArcomageGame->pSprites.uWidth; + + //v20 = 157; + //v19 = "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\am_nw.cpp"; + //v21 = &v18; + //std__string_char_40E2C8(&v18, "Problem in Blit_Chroma", &a3a); + //466D09_xcpt_string(&v21, v18, v19, v20); + //pSrc = pArcomageGame.pBlit_Copy_pixels; + //LABEL_9: + pSrc = pArcomageGame->pBlit_Copy_pixels; + uSrcPitch = uSrcTotalWidth; + src_surf_pos = &pSrc[pSrcRect->left + uSrcPitch * pSrcRect->top]; + v10 = 0x1F;//0xFF >> (8 - (unsigned __int8)uTargetBBits); + v21 = (uTargetGBits != 6 ? 0x31EF : 0x7BEF); + if ( blend_mode == 2 ) + { + uSrcPitch = (uSrcPitch - src_width); + for ( int i = 0; i < src_height; ++i ) + { + for ( int j = 0; j < src_width; ++j ) + { + if ( *src_surf_pos != v10 ) + { + if ( pTargetPoint->x + j >= 0 && pTargetPoint->x + j <= window->GetWidth() - 1 + && pTargetPoint->y + i >= 0 && pTargetPoint->y + i <= window->GetHeight() - 1) + WritePixel16(pTargetPoint->x + j, pTargetPoint->y + i, *src_surf_pos); + } + ++src_surf_pos; + } + src_surf_pos += uSrcPitch; + } + } + else + { + uSrcPitch = (uSrcPitch - src_width); + for ( int i = 0; i < src_height; ++i ) + { + for ( int j = 0; j < src_width; ++j ) + { + if ( *src_surf_pos != v10 ) + { + if ( pTargetPoint->x + j >= 0 && pTargetPoint->x + j <= window->GetWidth() - 1 + && pTargetPoint->y + i >= 0 && pTargetPoint->y + i <= window->GetHeight() - 1) + //WritePixel16(pTargetPoint->x + j, pTargetPoint->y + i, (v21 & (ReadPixel16(pTargetPoint->x + j, pTargetPoint->y + i) >> 1)) + (v21 & (*src_surf_pos >> 1))); + WritePixel16(pTargetPoint->x + j, pTargetPoint->y + i, (0x7BEF & (*src_surf_pos / 2))); + } + ++src_surf_pos; + } + src_surf_pos+=uSrcPitch; + } + } +} + +//----- (0040D9B1) -------------------------------------------------------- +void Render::am_Blt_Copy( RECT *pSrcRect, POINT *pTargetPoint, int blend_mode ) +{ + unsigned __int16 *pSrc; // eax@2 + int uSrcTotalWidth; // ecx@4 + int v21; // [sp+Ch] [bp-18h]@8 + unsigned __int16 *src_surf_pos; // [sp+10h] [bp-14h]@9 + __int32 src_width; // [sp+14h] [bp-10h]@3 + __int32 src_height; // [sp+18h] [bp-Ch]@3 + int uSrcPitch; // [sp+1Ch] [bp-8h]@5 + + if ( !uNumSceneBegins ) + return; + if ( !pArcomageGame->pBlit_Copy_pixels ) + return; + + //dest_surf_pos = &pRenderer->pTargetSurface[pTargetPoint->x + pTargetPoint->y * pRenderer->uTargetSurfacePitch]; + src_width = pSrcRect->right - pSrcRect->left; + src_height = pSrcRect->bottom - pSrcRect->top; + if ( pArcomageGame->pBlit_Copy_pixels == pArcomageGame->pBackgroundPixels ) + uSrcTotalWidth = pArcomageGame->pGameBackground.uWidth; + else if ( pArcomageGame->pBlit_Copy_pixels == pArcomageGame->pSpritesPixels ) + uSrcTotalWidth = pArcomageGame->pSprites.uWidth; + + //v20 = 157; + //v19 = "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\am_nw.cpp"; + //v21 = &v18; + //std__string_char_40E2C8(&v18, "Problem in Blit_Chroma", &a3a); + //466D09_xcpt_string(&v21, v18, v19, v20); + //pSrc = pArcomageGame.pBlit_Copy_pixels; + //LABEL_9: + pSrc = pArcomageGame->pBlit_Copy_pixels; + uSrcPitch = uSrcTotalWidth; + src_surf_pos = &pSrc[pSrcRect->left + uSrcPitch * pSrcRect->top]; + v21 = (uTargetGBits != 6 ? 0x31EF : 0x7BEF); + + if ( blend_mode == 2 ) + { + uSrcPitch = (uSrcPitch - src_width); + for ( int i = 0; i < src_height; ++i ) + { + for ( int j = 0; j < src_width; ++j ) + { + if ( *src_surf_pos != v21 ) + { + if ( pTargetPoint->x + j >= 0 && pTargetPoint->x + j <= window->GetWidth() - 1 + && pTargetPoint->y + i >= 0 && pTargetPoint->y + i <= window->GetHeight() - 1) + WritePixel16(pTargetPoint->x + j, pTargetPoint->y + i, *src_surf_pos); + } + ++src_surf_pos; + } + src_surf_pos += uSrcPitch; + } + } + else + { + uSrcPitch = (uSrcPitch - src_width); + for ( int i = 0; i < src_height; ++i ) + { + for ( int j = 0; j < src_width; ++j ) + { + if ( *src_surf_pos != v21 ) + { + if ( pTargetPoint->x + j >= 0 && pTargetPoint->x + j <= window->GetWidth() - 1 + && pTargetPoint->y + i >= 0 && pTargetPoint->y + i <= window->GetHeight() - 1) + //WritePixel16(pTargetPoint->x + j, pTargetPoint->y + i, (v21 & (ReadPixel16(pTargetPoint->x + j, pTargetPoint->y + i) / 2)) + (v21 & (*src_surf_pos / 2))); + WritePixel16(pTargetPoint->x + j, pTargetPoint->y + i, (0x7BEF & (*src_surf_pos / 2))); + } + ++src_surf_pos; + } + src_surf_pos += uSrcPitch; + } + } +} + +//----- (0040DB10) -------------------------------------------------------- +void am_EndScene() +{ + pRenderer->EndScene(); + pArcomageGame->pBlit_Copy_pixels = nullptr; +} + +//----- (0040D7B7) -------------------------------------------------------- +bool ArcomageGame::LoadSprites() +{ + pArcomageGame->pSprites.Load("sprites.pcx", 2); + pArcomageGame->pSpritesPixels = pArcomageGame->pSprites.pPixels; + return true; +} + +//----- (0040D799) -------------------------------------------------------- +bool ArcomageGame::LoadBackground() +{ + pArcomageGame->pGameBackground.Load("layout.pcx", 2); + pArcomageGame->pBackgroundPixels = pArcomageGame->pGameBackground.pPixels; + return true; +} + +int CalculateCardPower(ArcomagePlayer* player, ArcomagePlayer* enemy, ArcomageCard* pCard, int mastery) +{ + enum V_INDX{ + P_TOWER_M10, + P_WALL_M10, + E_TOWER, + E_WALL, + E_BUILDINGS, + E_QUARRY, + E_MAGIC, + E_ZOO, + E_RES, + V_INDEX_MAX + }; + + const int mastery_coeff[V_INDEX_MAX][2]= {{10, 5}, //P_TOWER_M10 + {2, 1}, //P_WALL_M10 + {1, 10}, //E_TOWER + {1, 3}, //E_WALL + {1, 7}, //E_BUILDINGS + {1, 5}, //E_QUARRY + {1, 40}, //E_MAGIC + {1, 40}, //E_ZOO + {1, 2} //E_RES + }; + int card_power= 0; + int element_power; + + if ( pCard->to_player_tower == 99 || pCard->to_pl_enm_tower == 99|| + pCard->to_player_tower2 == 99 || pCard->to_pl_enm_tower2 == 99 ) + element_power = enemy->tower_height - player->tower_height; + else + element_power = pCard->to_player_tower + pCard->to_pl_enm_tower + pCard->to_player_tower2 + pCard->to_pl_enm_tower2; + + if ( player->tower_height >= 10 ) + card_power += mastery_coeff[P_TOWER_M10][mastery]*element_power; + else + card_power += 20*element_power; + + + if ( pCard->to_player_wall == 99 || pCard->to_pl_enm_wall == 99 || + pCard->to_player_wall2 == 99 || pCard->to_pl_enm_wall2 == 99 ) + element_power = enemy->wall_height - player->wall_height; + else + element_power = pCard->to_player_wall + pCard->to_pl_enm_wall + + pCard->to_player_wall2 + pCard->to_pl_enm_wall2; + if ( player->wall_height >= 10 ) + card_power += mastery_coeff[P_WALL_M10][mastery]*element_power; //1 + else + card_power += 5*element_power; + + + card_power += 7 * (pCard->to_player_buildings + pCard->to_pl_enm_buildings + + pCard->to_player_buildings2 + pCard->to_pl_enm_buildings2); + + if ( pCard->to_player_quarry_lvl == 99 || pCard->to_pl_enm_quarry_lvl == 99 || + pCard->to_player_quarry_lvl2 == 99 || pCard->to_pl_enm_quarry_lvl2 == 99 ) + element_power = enemy->quarry_level - player->quarry_level; + else + element_power = pCard->to_player_quarry_lvl + pCard->to_pl_enm_quarry_lvl + + pCard->to_player_quarry_lvl2 + pCard->to_pl_enm_quarry_lvl; + + card_power += 40 * element_power; + + if ( pCard->to_player_magic_lvl == 99 || pCard->to_pl_enm_magic_lvl == 99 || + pCard->to_player_magic_lvl2 == 99 || pCard->to_pl_enm_magic_lvl2 == 99 ) + element_power = enemy->magic_level - player->magic_level; + else + element_power = pCard->to_player_magic_lvl + pCard->to_pl_enm_magic_lvl + + pCard->to_player_magic_lvl2 + pCard->to_pl_enm_magic_lvl2; + card_power += 40 *element_power; + + if ( pCard->to_player_zoo_lvl == 99 || pCard->to_pl_enm_zoo_lvl == 99 || + pCard->to_player_zoo_lvl2 == 99 || pCard->to_pl_enm_zoo_lvl2 == 99 ) + element_power = enemy->zoo_level - player->zoo_level; + else + element_power = pCard->to_player_zoo_lvl + pCard->to_pl_enm_zoo_lvl + + pCard->to_player_zoo_lvl2 + pCard->to_pl_enm_zoo_lvl2; + card_power += 40 *element_power; + + if ( pCard->to_player_bricks == 99 || pCard->to_pl_enm_bricks == 99 || + pCard->to_player_bricks2 == 99 || pCard->to_pl_enm_bricks2 == 99 ) + element_power = enemy->resource_bricks - player->resource_bricks; + else + element_power = pCard->to_player_bricks + pCard->to_pl_enm_bricks + + pCard->to_player_bricks2 + pCard->to_pl_enm_bricks2; + card_power += 2 *element_power; + + + if ( pCard->to_player_gems == 99 || pCard->to_pl_enm_gems == 99 || + pCard->to_player_gems2 == 99 || pCard->to_pl_enm_gems2 == 99 ) + element_power = enemy->resource_gems - player->resource_gems; + else + element_power = pCard->to_player_gems + pCard->to_pl_enm_gems + + pCard->to_player_gems2 + pCard->to_pl_enm_gems2; + card_power += 2 *element_power; + + if ( pCard->to_player_beasts == 99 || pCard->to_pl_enm_beasts == 99 || + pCard->to_player_beasts2 == 99 || pCard->to_pl_enm_beasts2 == 99 ) + element_power = enemy->resource_beasts - player->resource_beasts; + else + element_power = pCard->to_player_beasts + pCard->to_pl_enm_beasts + + pCard->to_player_beasts2 + pCard->to_pl_enm_beasts2; + card_power += 2 *element_power; + + if ( pCard->to_enemy_tower == 99 || pCard->to_enemy_tower2 == 99 ) + element_power = player->tower_height - enemy->tower_height; + else + element_power = -(pCard->to_enemy_tower + pCard->to_enemy_tower2); + card_power += mastery_coeff[E_TOWER][mastery]*element_power; + + if ( pCard->to_enemy_wall == 99 || pCard->to_enemy_wall2 == 99 ) + element_power = player->wall_height - enemy->wall_height; + else + element_power = -(pCard->to_enemy_wall + pCard->to_enemy_wall2); + card_power += mastery_coeff[E_WALL][mastery]*element_power; + + card_power -= mastery_coeff[E_BUILDINGS][mastery]*(pCard->to_enemy_buildings + pCard->to_enemy_buildings2); + + if ( pCard->to_enemy_quarry_lvl == 99 || pCard->to_enemy_quarry_lvl2 == 99 ) + element_power = player->quarry_level - enemy->quarry_level; //5 + else + element_power = -(pCard->to_enemy_quarry_lvl + pCard->to_enemy_quarry_lvl2); //5 + card_power += mastery_coeff[E_QUARRY][mastery]*element_power; + + if ( pCard->to_enemy_magic_lvl == 99 || pCard->to_enemy_magic_lvl2 == 99 ) + element_power = player->magic_level - enemy->magic_level; //40 + else + element_power = -(pCard->to_enemy_magic_lvl + pCard->to_enemy_magic_lvl2); + card_power += mastery_coeff[E_MAGIC][mastery]*element_power; + + if ( pCard->to_enemy_zoo_lvl == 99 || pCard->to_enemy_zoo_lvl2 == 99 ) + element_power = player->zoo_level - enemy->zoo_level; //40 + else + element_power = -(pCard->to_enemy_zoo_lvl + pCard->to_enemy_zoo_lvl2); + card_power += mastery_coeff[E_ZOO][mastery]*element_power; + + if ( pCard->to_enemy_bricks == 99 || pCard->to_enemy_bricks2 == 99 ) + element_power = player->resource_bricks - enemy->resource_bricks; //2 + else + element_power = -(pCard->to_enemy_bricks + pCard->to_enemy_bricks2); + card_power += mastery_coeff[E_RES][mastery]*element_power; + + if ( pCard->to_enemy_gems == 99 || pCard->to_enemy_gems2 == 99 ) + element_power = player->resource_gems - enemy->resource_gems; //2 + else + element_power = -(pCard->to_enemy_gems + pCard->to_enemy_gems2); + card_power += mastery_coeff[E_RES][mastery]*element_power; + + if ( pCard->to_enemy_beasts == 99 || pCard->to_enemy_beasts2 == 99 ) + element_power = player->resource_beasts - enemy->resource_beasts; //2 + else + element_power = -(pCard->to_enemy_beasts + pCard->to_enemy_beasts2); + card_power += mastery_coeff[E_RES][mastery]*element_power; + + if ( pCard->field_30 || pCard->field_4D ) + card_power *= 10; + + if ( pCard->field_24 == 1 ) + element_power = player->resource_bricks - pCard->needed_bricks; + else if ( pCard->field_24 == 2 ) + element_power = player->resource_gems - pCard->needed_gems; + else if (pCard->field_24 == 3) + element_power = player->resource_beasts - pCard->needed_beasts; + if ( element_power > 3 ) + element_power = 3; + card_power += 5 * element_power; + + if ( enemy->tower_height <= pCard->to_enemy_tower2 + pCard->to_enemy_tower ) + card_power += 9999; + + if (pCard->to_enemy_tower2 + pCard->to_enemy_tower + + pCard->to_enemy_wall + pCard->to_enemy_wall2 + + pCard->to_enemy_buildings + pCard->to_enemy_buildings2 >= enemy->wall_height + enemy->tower_height) + card_power += 9999; + + if ( (pCard->to_player_tower2 + pCard->to_pl_enm_tower2 + pCard->to_player_tower + pCard->to_pl_enm_tower + player->tower_height) + >= max_tower_height ) + card_power += 9999; + + return card_power; +} + +//----- (00408BB4) -------------------------------------------------------- +bool OpponentsAITurn(int player_num) +{ + int all_player_cards_count; // eax@9 + int random_card_slot; // edi@9 + ArcomageCard *v12; // ecx@20 + int v56; // ecx@141 + int v57; // edx@141 +// int v64; // eax@169 +// ArcomageCard *pCard; // ecx@169 +// char v66; // dl@169 +// char v67; // dl@173 +// int v68; // edx@174 + int v132; // [sp-14h] [bp-14h]@0 + ArcomagePlayer *enemy; // [sp-10h] [bp-10h]@5 + ArcomagePlayer *player; // [sp-Ch] [bp-Ch]@5 + + byte_4FAA00 = 1; + if ( opponent_mastery == 0) + { + if ( need_to_discard_card == 0 ) //am_byte_4FAA77 + { + for(int i = 0; i < 10; ++i ) + { + all_player_cards_count = GetPlayerHandCardCount(player_num); + random_card_slot = rand_interval(0, all_player_cards_count - 1); + if ( CanCardBePlayed(player_num, random_card_slot) ) + return PlayCard(player_num, random_card_slot); + } + } + all_player_cards_count = GetPlayerHandCardCount(player_num); + random_card_slot= rand_interval(0, all_player_cards_count - 1); + return DiscardCard(player_num, random_card_slot); + } + else if (( opponent_mastery == 1 )|| ( opponent_mastery == 2 )) + { + player = &am_Players[player_num]; + enemy = &am_Players[(player_num + 1) % 2]; + all_player_cards_count = GetPlayerHandCardCount(player_num); + for(int i = 0; i < 10 ; ++i ) + { + if ( i >= all_player_cards_count ) + { + cards_power[i].slot_index = -1; + cards_power[i].card_power = -9999; + } + else + { + cards_power[i].slot_index = i; + cards_power[i].card_power = 0; + } + } + for(int i = 0; i < all_player_cards_count ; ++i ) + { + v12 = &pCards[am_Players[player_num].cards_at_hand[cards_power[i].slot_index]]; + cards_power[i].card_power = CalculateCardPower(player, enemy, v12, opponent_mastery-1); + } + + for (int j = all_player_cards_count - 1; j >= 0; --j ) + { + for (int m = 0; m < j; ++m ) + { + if ( cards_power[m].card_power < cards_power[m + 1].card_power ) + { + v56 = cards_power[m].slot_index; + v57 = cards_power[m].card_power; + cards_power[m].slot_index = cards_power[m + 1].slot_index; + cards_power[m].card_power = cards_power[m + 1].card_power; + cards_power[m + 1].slot_index = cards_power[m].slot_index; + cards_power[m + 1].card_power = cards_power[m].card_power; + } + } + } + if ( need_to_discard_card ) + { + for ( int i = all_player_cards_count - 1; i; --i ) + { + if ( pCards[am_Players[player_num].cards_at_hand[cards_power[i].slot_index]].can_be_discarded ) + v132 = cards_power[i].slot_index; + } + } + else + { + for ( int i = all_player_cards_count - 1; i; --i ) + { + if ( pCards[am_Players[player_num].cards_at_hand[cards_power[i].slot_index]].can_be_discarded ) + v132 = cards_power[i].slot_index; + } + for ( int i = 0; i < all_player_cards_count - 1; ++i ) + { + if ( CanCardBePlayed(player_num, cards_power[i].slot_index) && cards_power[i].card_power ) + return PlayCard(player_num, cards_power[i].slot_index); + } + } + return DiscardCard(player_num, v132); + } + return true;//result != 0; +} + +//----- (00409E6A) -------------------------------------------------------- +void ArcomageGame::Loop() +{ + while ( !pArcomageGame->GameOver ) + { + pArcomageGame->field_F6 = 1; + byte_4FAA24 = 1; + IncreaseResourcesInTurn(current_player_num); +//LABEL_8: + while ( byte_4FAA24 ) + { + played_card_id = -1; + GetNextCardFromDeck(current_player_num); + while ( 1 ) + { + byte_4FAA24 = PlayerTurn(current_player_num); + if (GetPlayerHandCardCount(current_player_num) <= minimum_cards_at_hand) + { + need_to_discard_card = 0; + break; + } + need_to_discard_card = 1; + if (pArcomageGame->field_F4) + break; + } + } + pArcomageGame->GameOver = IsGameOver(); + if ( !pArcomageGame->GameOver ) + TurnChange(); + if ( pArcomageGame->field_F4 ) + pArcomageGame->GameOver = 1; + } + GameResultsApply(); + if ( am_gameover ) + dword_4FAA70 = 0; + else + dword_4FAA70 = -1; + + for( int i = 0; i < 10; ++i ) + { + array_4FABD0[i].field_40->Clear(1, 1); + array_4FABD0[i].field_40->Free(); + } + + pArcomageGame->pGameBackground.Release(); + pArcomageGame->pSprites.Release(); + pArcomageGame->bGameInProgress = false; + viewparams->bRedrawGameUI = true; + if ( pMovie_Track ) + BackToHouseMenu(); + for( int i = 0; i < 12; ++i ) + pSoundList->UnloadSound(am_sounds[i], 1); +} + +//----- (00409FE9) -------------------------------------------------------- +void SetStartGameData() +{ + signed int j; // edx@7 + int card_id_counter; // edx@13 + signed int i; // ecx@13 + signed int card_dispenser_counter; // eax@13 + + current_player_num = am_default_starting_player; + SetStartConditions(); + for( i = 0; i < 2; ++i ) + { + if ( i ) + { + strcpy(am_Players[1].pPlayerName, pArcomageGame->pPlayer2Name); + if ( byte_4E185C ) + am_Players[1].IsHisTurn = 0; + else + am_Players[1].IsHisTurn = 1; + } + else + { + strcpy(am_Players[0].pPlayerName, pArcomageGame->pPlayer1Name); + am_Players[0].IsHisTurn = 1; + } + am_Players[i].tower_height = start_tower_height; + am_Players[i].wall_height = start_wall_height; + am_Players[i].quarry_level = start_quarry_level; + am_Players[i].magic_level = start_magic_level; + am_Players[i].zoo_level = start_zoo_level; + am_Players[i].resource_bricks = start_bricks_amount; + am_Players[i].resource_gems = start_gems_amount; + am_Players[i].resource_beasts = start_beasts_amount; + + for ( j = 0; j < 10; ++j ) + { + am_Players[i].cards_at_hand[j] = -1; + if ( am_byte_4E185D ) + { + am_Players[i].card_shift[j].x = -1; + am_Players[i].card_shift[j].y = -1; + } + else + { + am_Players[i].card_shift[j].x = 0; + am_Players[i].card_shift[j].y = 0; + } + } + } + strcpy(deckMaster.name, "Master Deck"); + for ( i = 0, card_dispenser_counter = -2, card_id_counter = 0; i < DECK_SIZE; ++i, ++card_dispenser_counter) + { + deckMaster.cardsInUse[i] = 0; + deckMaster.cards_IDs[i] = card_id_counter; + switch ( card_dispenser_counter ) + { + case 0: + case 2: + case 6: + case 9: + case 13: + case 18: + case 23: + case 33: + case 36: + case 38: + case 44: + case 46: + case 52: + case 57: + case 69: + case 71: + case 75: + case 79: + case 81: + case 84: + case 89: + break; + default: + ++card_id_counter; + } + } + FillPlayerDeck(); +} + +//----- (0040A198) -------------------------------------------------------- +void FillPlayerDeck() + { + signed int m; + int rand_deck_pos; + char card_taken_flags[DECK_SIZE]; + int i,j; + + ArcomageGame::PlaySound(20); + memset(deckMaster.cardsInUse, 0,DECK_SIZE ); + memset(card_taken_flags, 0, DECK_SIZE); + + for ( i = 0; i < 2; ++i ) + { + for ( j = 0; j < 10; ++j ) + { + if ( am_Players[i].cards_at_hand[j] > -1 ) + { + for (m = 0; mfield_F6 = 1; + +} + +//----- (0040A255) -------------------------------------------------------- +void InitalHandsFill() +{ + for (int i = 0; i < minimum_cards_at_hand; ++i ) + { + GetNextCardFromDeck(0); + GetNextCardFromDeck(1); + } + pArcomageGame->field_F6 = 1; +} +// 4E1874: using guessed type int dword_4E1874; + +//----- (0040A283) -------------------------------------------------------- +void GetNextCardFromDeck( int player_num ) +{ + signed int deck_index; // eax@1 + int new_card_id; // edi@1 + signed int card_slot_indx; // eax@7 + + deck_index = deck_walk_index; + for(;;) + { + if ( deck_index >= DECK_SIZE ) + { + FillPlayerDeck(); + deck_index = deck_walk_index; + } + if ( !playDeck.cardsInUse[deck_index] ) + { + new_card_id = playDeck.cards_IDs[deck_index]; + ++deck_index; + deck_walk_index = deck_index; + break; + } + ++deck_index; + deck_walk_index = deck_index; + } + + ArcomageGame::PlaySound(21); + card_slot_indx = GetEmptyCardSlotIndex(player_num); + if ( card_slot_indx != -1 ) + { + amuint_4FAA4C = card_slot_indx; + am_Players[player_num].cards_at_hand[card_slot_indx] = new_card_id; + am_Players[player_num].card_shift[card_slot_indx].x = rand_interval(-4, 4); + am_Players[player_num].card_shift[card_slot_indx].y = rand_interval(-4, 4); + pArcomageGame->field_F6 = 1; + byte_4FAA2D = 1; + } +} + +//----- (0040A324) -------------------------------------------------------- +int GetEmptyCardSlotIndex( int player_num ) +{ + for ( int i = 0; i < 10; ++i ) + { + if (am_Players[player_num].cards_at_hand[i] == -1) + return i; + } + return -1; +} + +//----- (0040A346) -------------------------------------------------------- +void IncreaseResourcesInTurn(int player_num) +{ + am_Players[player_num].resource_bricks += quarry_bonus + am_Players[player_num].quarry_level; + am_Players[player_num].resource_gems += magic_bonus + am_Players[player_num].magic_level; + am_Players[player_num].resource_beasts += zoo_bonus + am_Players[player_num].zoo_level; +} + + +//----- (0040A383) -------------------------------------------------------- +void TurnChange() +{ + char player_name[64]; // [sp+4h] [bp-64h]@4 + // RECT v6; // [sp+44h] [bp-24h]@6 + ArcomageGame_stru1 v10; // [sp+54h] [bp-14h]@7 + POINT v11; // [sp+60h] [bp-8h]@4 + + if ( !pArcomageGame->field_F4 ) + { + if ( am_Players[0].IsHisTurn != 1 || am_Players[1].IsHisTurn != 1 ) + { + ++current_player_num; + am_byte_4FAA75 = 1; + if ( current_player_num >= 2 ) + current_player_num = 0; + } + else + { + //nullsub_1(); + // v11.x = 0; + // v11.y = 0; + strcpy(player_name, "The Next Player is: ");//"След" + // v0 = 0; + v11.y = 200; + v11.x = 320; // - 12 * v0 / 2; + am_DrawText(-1, player_name, &v11); + am_byte_4FAA75 = 1; + ++current_player_num; + if ( current_player_num >= 2 ) + current_player_num = 0; + strcpy(player_name, am_Players[current_player_num].pPlayerName); + // v4 = 0; + v11.y = 260; + v11.x = 320;// - 12 * v4 / 2; + am_DrawText(-1, player_name, &v11); + /* v6.left = 0; + v6.right = 640; + v6.top = 0; + v6.bottom = 480;*/ + //nullsub_1(); + pRenderer->Present(); + //nullsub_1(); + while ( 1 ) + { + while ( !ArcomageGame::MsgLoop(20, &v10) ) + ; + if ( v10.field_0 == 1 ) + { + if ( v10.field_4 ) + break; + //nullsub_1(); + continue; + } + if (( v10.field_0 > 4 ) && ( v10.field_0 <= 8 )) + break; + if ( v10.field_0 == 10 ) + { + pArcomageGame->field_F4 = 1; + byte_4FAA74 = 1; + break; + } + } + /* v11.x = 0; + v11.y = 0; + v6.left = 0; + v6.right = 640; + v6.top = 0; + v6.bottom = 480;*/ + //nullsub_1(); + pRenderer->Present(); + } + } +} + +//----- (0040A514) -------------------------------------------------------- +bool IsGameOver() +{ + bool result; // eax@1 + + result = false; + for( int i = 0; i < 2; ++i ) + { + if ( am_Players[i].tower_height <= 0 ) + result = true; + if ( am_Players[i].tower_height >= max_tower_height ) + result = true; + if ( am_Players[i].resource_bricks >= max_resources_amount + || am_Players[i].resource_gems >= max_resources_amount + || am_Players[i].resource_beasts >= max_resources_amount ) + result = true; + } + + return am_gameover = result; +} + +//----- (0040A560) -------------------------------------------------------- +char PlayerTurn( int player_num ) +{ +// int v1; // ebp@0 +// unsigned __int64 v2; // qax@3 + unsigned __int64 v3; // kr00_8@3 + +// int v5; // esi@67 +// char Dest[100]; // [sp+8h] [bp-A8h]@67 +// int v8; // [sp+6Ch] [bp-44h]@3 + RECT pSrcXYZW; // [sp+70h] [bp-40h]@75 +// int v10[4]; // [sp+80h] [bp-30h]@69 + POINT pTargetXY; // [sp+90h] [bp-20h]@75 + ArcomageGame_stru1 a2; // [sp+98h] [bp-18h]@8 + int animation_stage; // [sp+A4h] [bp-Ch]@1 +// char v15; // [sp+AEh] [bp-2h]@63 + bool break_loop; // [sp+AFh] [bp-1h]@1 + + uCardID = -1; + break_loop = false; + animation_stage = 20; + byte_4FAA00 = 0; + dword_4FAA68 = 0; + amuint_4FAA38 = 10; + amuint_4FAA34 = 5; + if ( amuint_4FAA4C != -1 ) + byte_4FAA2D = 1; + do + { + do + { + v3 = pEventTimer->Time() - pArcomageGame->event_timer_time; + } + while (v3 < 6); + pArcomageGame->event_timer_time = (unsigned int)pEventTimer->Time(); + if ( pArcomageGame->field_F4 ) + break_loop = true; + ArcomageGame::MsgLoop(0, &a2); + switch ( a2.field_0 ) + { + case 2: + if ( a2.field_4 == 129 && a2.field_8 == 1 ) + { + pAudioPlayer->StopChannels(-1, -1); + dword_4FAA68 = 0; + break_loop = true; + pArcomageGame->field_F4 = 1; + } + break; + case 9: + pArcomageGame->field_F6 = 1; + break; + case 10: + pAudioPlayer->StopChannels(-1, -1); + byte_4FAA74 = 1; + break_loop = true; + pArcomageGame->field_F4 = 1; + break; + } + + if (am_Players[current_player_num].IsHisTurn != 1 && + !byte_4FAA00 && !byte_4FAA2E && !byte_4FAA2D ) + { + if ( am_byte_4FAA75 ) + am_byte_4FAA76 = 1; + OpponentsAITurn(current_player_num); + byte_4FAA2E = 1; + } + if ( amuint_4FAA4C != -1 && amuint_4FAA38 > 10 ) + amuint_4FAA38 = 10; + if ( byte_4FAA2E || byte_4FAA2D ||am_Players[current_player_num].IsHisTurn != 1 ) + { + pArcomageGame->field_F6 = 1; + if ( byte_4FAA2D ) + { + --amuint_4FAA38; + if ( amuint_4FAA38 < 0 ) + { + byte_4FAA2D = 0; + amuint_4FAA38 = 10; + break_loop = false; + } + } + if ( byte_4FAA2E ) + { + --animation_stage; + if ( animation_stage < 0 ) + { + if ( dword_4FAA68 > 1 ) + { + --dword_4FAA68; + byte_4FAA00 = 0; + } + else + break_loop = true; + byte_4FAA2E = 0; + animation_stage = 20; + } + } + } + else + { + if ( need_to_discard_card ) + { + if ( a2.field_0 == 7 && DiscardCard(player_num, current_card_slot_index) ) + { + if ( am_byte_4FAA75 ) + am_byte_4FAA76 = 1; + if ( dword_4FAA64 > 0 ) + { + --dword_4FAA64; + need_to_discard_card = GetPlayerHandCardCount(player_num) > minimum_cards_at_hand; + } + byte_4FAA2E = 1; + } + if ( a2.field_0 == 8 && DiscardCard(player_num, current_card_slot_index) ) + { + if ( am_byte_4FAA75 ) + am_byte_4FAA76 = 1; + if ( dword_4FAA64 > 0 ) + { + --dword_4FAA64; + need_to_discard_card = GetPlayerHandCardCount(player_num) > minimum_cards_at_hand; + } + byte_4FAA2E = 1; + } + } + else + { + if ( a2.field_0 == 7 ) + { + if ( PlayCard(player_num, current_card_slot_index) ) + { + byte_4FAA2E = 1; + if ( am_byte_4FAA75 ) + am_byte_4FAA76 = 1; + } + } + if ( a2.field_0 == 8 ) + { + if ( DiscardCard(player_num, current_card_slot_index) ) + { + byte_4FAA2E = 1; + if ( am_byte_4FAA75 ) + am_byte_4FAA76 = 1; + } + } + } + } + //nullsub_1(); + //if ( false ) + //{ + // if ( !v15 ) + // { + // //nullsub_1(); + // v15 = 1; + // } + //} + //else + //{ + // v15 = 0; + // } + //if ( false ) + //{ + // //nullsub_1(); + // //nullsub_1(); + // // assert(false && "Invalid strcpy params"); + // // inv_strcpy(nullptr, Dest); + // v5 = 0;//unk::const_0(&unk_4E19FC, 0); + // //nullsub_1(); + // if ( v5 == 1 ) + // { + // pAudioPlayer->StopChannels(-1, -1); + // v16 = 1; + // pArcomageGame->field_F4 = 1; + // dword_4FAA68 = 0; + // } + // /*v10[0] = 0; + // v10[2] = 640; + // v10[1] = 0; + // v10[3] = 480;*/ + // //nullsub_1(); + //} + if ( dword_4FABB8 != DrawCardsRectangles(player_num) ) + { + dword_4FABB8 = DrawCardsRectangles(player_num); + pArcomageGame->field_F6 = 1; + } + if ( pArcomageGame->field_F6 ) + { + DrawGameUI(animation_stage); + DoBlt_Copy(pArcomageGame->pBackgroundPixels); + pArcomageGame->field_F6 = 0; + } + if ( pArcomageGame->field_F9 ) + { + pTargetXY.x = 0; + pTargetXY.y = 0; + pSrcXYZW.left = 0; + pSrcXYZW.right = window->GetWidth(); + pSrcXYZW.top = 0; + pSrcXYZW.bottom = window->GetHeight(); + am_BeginScene(pArcomageGame->pBackgroundPixels, -1, 1); + pRenderer->am_Blt_Copy(&pSrcXYZW, &pTargetXY, 2); + am_EndScene(); + DrawGameUI(animation_stage); + pRenderer->Present(); + pArcomageGame->field_F9 = 0; + } + } + while ( !break_loop ); + return dword_4FAA68 > 0; +} + + +//----- (0040A9AF) -------------------------------------------------------- +void DrawGameUI( int animation_stage ) +{ + am_BeginScene(pArcomageGame->pSpritesPixels, -1, 1); + DrawRectanglesForText(); + am_EndScene(); + + am_BeginScene(pArcomageGame->pSpritesPixels, -1, 1); + DrawCards();//рисуем карты + DrawPlayersTowers();//рисуем башню + DrawPlayersWall();//рисуем стену + DrawPlayersText();//рисуем текст + am_EndScene(); + + am_BeginScene(pArcomageGame->pSpritesPixels, -1, 1); + DrawCardAnimation(animation_stage); + + for( int i = 0; i < 10; ++i ) + { + if (array_4FABD0[i].have_effect) + array_4FABD0[i].field_40->DrawEffect(); + } + current_card_slot_index = DrawCardsRectangles(current_player_num); + DrawSparks(); + am_EndScene(); +} + +//----- (0040AA4E) -------------------------------------------------------- +void DrawSparks() +{ + int rgb_pixel_color; // [sp-4h] [bp-2Ch]@4 + unsigned int pixel_color; + + for ( int i = 0; i < 10; ++i ) + { + if(array_4FABD0[i].have_effect && (array_4FABD0[i].field_40->_40E2A7()==2)) + { + rgb_pixel_color = 0x0000FF00; + if ( !array_4FABD0[i].effect_sign ) + rgb_pixel_color = 0x000000FF; + pixel_color = R8G8B8_to_TargetFormat(rgb_pixel_color); + for( int j = 0; j < 150; ++j ) + { + if (array_4FABD0[i].effect_sparks[j].have_spark > 0) + { + if ( j%2 ) + DrawPixel(&array_4FABD0[i].effect_sparks[j].spark_position, pixel_color); + else + DrawSquare(&array_4FABD0[i].effect_sparks[j].spark_position, pixel_color); + } + } + } + } +} + +//----- (0040AB0A) -------------------------------------------------------- +void DrawRectanglesForText() +{ + RECT pSrcRect; // [sp+Ch] [bp-18h]@1 + POINT pTargetXY; // [sp+1Ch] [bp-8h]@1 + +//resources rectangles + pSrcRect.left = 765; + pSrcRect.top = 0; + pSrcRect.right = 843; + pSrcRect.bottom = 216; + + pTargetXY.x = 8; + pTargetXY.y = 56; + pRenderer->am_Blt_Copy(&pSrcRect, &pTargetXY, 2); + + pTargetXY.x = 555; + pTargetXY.y = 56; + pRenderer->am_Blt_Copy(&pSrcRect, &pTargetXY, 2); + + //players name rectangle + pSrcRect.left = 283; + pSrcRect.top = 166; + pSrcRect.right = 361; + pSrcRect.bottom = 190; + pTargetXY.x = 8; + pTargetXY.y = 13; + pRenderer->am_Blt_Chroma(&pSrcRect, &pTargetXY, pArcomageGame->field_54, 2); + + pTargetXY.x = 555; + pTargetXY.y = 13; + pRenderer->am_Blt_Chroma(&pSrcRect, &pTargetXY, pArcomageGame->field_54, 2); + + //tower height rectangle + pSrcRect.left = 234; + pSrcRect.top = 166; + pSrcRect.right = 283; + pSrcRect.bottom = 190; + pTargetXY.x = 100; + pTargetXY.y = 296; + pRenderer->am_Blt_Chroma(&pSrcRect, &pTargetXY, pArcomageGame->field_54, 2); + + pTargetXY.x = 492; + pTargetXY.y = 296; + pRenderer->am_Blt_Chroma(&pSrcRect, &pTargetXY, pArcomageGame->field_54, 2); + + //wall height rectangle + pSrcRect.left = 192; + pSrcRect.top = 166; + pSrcRect.right = 234; + pSrcRect.bottom = 190; + pTargetXY.x = 168; + pTargetXY.y = 296; + pRenderer->am_Blt_Chroma(&pSrcRect, &pTargetXY, pArcomageGame->field_54, 2); + + pTargetXY.x = 430; + pTargetXY.y = 296; + pRenderer->am_Blt_Chroma(&pSrcRect, &pTargetXY, pArcomageGame->field_54, 2); +} + +//----- (0040AC5F) -------------------------------------------------------- +void DrawPlayersText() +{ + int res_value; // ecx@18 + char text_buff[32]; // [sp+Ch] [bp-28h]@2 + POINT text_position; // [sp+2Ch] [bp-8h]@2 + + if ( need_to_discard_card ) + { + strcpy(text_buff, pGlobalTXT_LocalizationStrings[266]);// DISCARD A CARD + text_position.x = 320 - pArcomageGame->pfntArrus->GetLineWidth(text_buff) / 2; + text_position.y = 306; + am_DrawText(-1, text_buff, &text_position); + } + strcpy( text_buff, am_Players[0].pPlayerName); + if ( !current_player_num ) + strcat(text_buff, "***"); + text_position.x = 47 - pArcomageGame->pfntComic->GetLineWidth(text_buff) / 2; + text_position.y = 21; + am_DrawText(-1, text_buff, &text_position); + + strcpy(text_buff, am_Players[1].pPlayerName); + if ( current_player_num == 1 ) + strcat(text_buff, "***" ); + text_position.x = 595 - pArcomageGame->pfntComic->GetLineWidth(text_buff) / 2; + text_position.y = 21; + am_DrawText(-1, text_buff, &text_position); + + am_IntToString(am_Players[0].tower_height, text_buff); + text_position.x = 123 - pArcomageGame->pfntComic->GetLineWidth(text_buff) / 2; + text_position.y = 305; + am_DrawText(-1, text_buff, &text_position); + + am_IntToString(am_Players[1].tower_height, text_buff); + text_position.x = 515 - pArcomageGame->pfntComic->GetLineWidth(text_buff) / 2; + text_position.y = 305; + am_DrawText(-1, text_buff, &text_position); + + am_IntToString(am_Players[0].wall_height, text_buff); + text_position.x = 188 - pArcomageGame->pfntComic->GetLineWidth(text_buff) / 2; + text_position.y = 305; + am_DrawText(-1, text_buff, &text_position); + + am_IntToString(am_Players[1].wall_height, text_buff); + text_position.x = 451 - pArcomageGame->pfntComic->GetLineWidth(text_buff) / 2; + text_position.y = 305; + am_DrawText(-1, text_buff, &text_position); + + res_value = am_Players[0].quarry_level; + if ( use_start_bonus ) + res_value =am_Players[0].quarry_level + quarry_bonus; + am_IntToString(res_value, text_buff); + text_position.x = 14;// - 6 * 0 / 2; + text_position.y = 92; + DrawPlayerLevels(-1, text_buff, &text_position); + + res_value = am_Players[1].quarry_level; + if ( use_start_bonus ) + res_value = am_Players[1].quarry_level + quarry_bonus; + am_IntToString(res_value, text_buff); +// v2 = 0; + text_position.y = 92; + text_position.x = 561; //- 6 * v2 / 2; + DrawPlayerLevels(-1, text_buff, &text_position); + + res_value = am_Players[0].magic_level; + if ( use_start_bonus ) + res_value = am_Players[0].magic_level + magic_bonus; + am_IntToString(res_value, text_buff); + // v4 = 0; + text_position.y = 164; + text_position.x = 14; //- 6 * v4 / 2; + DrawPlayerLevels(-1, text_buff, &text_position); + + res_value = am_Players[1].magic_level; + if ( use_start_bonus ) + res_value = am_Players[1].magic_level + magic_bonus; + am_IntToString(res_value, text_buff); + // v6 = 0; + text_position.y = 164; + text_position.x = 561; //- 6 * v6 / 2; + DrawPlayerLevels(-1, text_buff, &text_position); + + res_value = am_Players[0].zoo_level; + if ( use_start_bonus ) + res_value = am_Players[0].zoo_level + zoo_bonus; + am_IntToString(res_value, text_buff); + // v8 = 0; + text_position.y = 236; + text_position.x = 14;// - 6 * v8 / 2; + DrawPlayerLevels(-1, text_buff, &text_position); + + res_value = am_Players[1].zoo_level; + if ( use_start_bonus ) + res_value = am_Players[1].zoo_level + zoo_bonus; + am_IntToString(res_value, text_buff); + // v10 = 0; + text_position.y = 236; + text_position.x = 561;// - 6 * v10 / 2; + DrawPlayerLevels(-1, text_buff, &text_position); + + am_IntToString(am_Players[0].resource_bricks, text_buff); + text_position.y = 114; + text_position.x = 10; + DrawBricksCount(-1, text_buff, &text_position); + + am_IntToString(am_Players[1].resource_bricks, text_buff); + text_position.x = 557; + text_position.y = 114; + DrawBricksCount(-1, text_buff, &text_position); + + am_IntToString(am_Players[0].resource_gems, text_buff); + text_position.x = 10; + text_position.y = 186; + DrawGemsCount(-1, text_buff, &text_position); + + am_IntToString(am_Players[1].resource_gems, text_buff); + text_position.x = 557; + text_position.y = 186; + DrawGemsCount(-1, text_buff, &text_position); + + am_IntToString(am_Players[0].resource_beasts, text_buff); + text_position.x = 10; + text_position.y = 258; + DrawBeastsCount(-1, text_buff, &text_position); + + am_IntToString(am_Players[1].resource_beasts, text_buff); + text_position.x = 557; + text_position.y = 258; + DrawBeastsCount(-1, text_buff, &text_position); +} + + +//----- (0040B102) -------------------------------------------------------- +void DrawPlayerLevels( int a1, char *text, POINT *pXY ) +{ + char *v3; // esi@1 + unsigned char test_char; // bl@2 + int v7; // eax@3 + RECT pSrcRect; + POINT pTargetPoint; + + v3 = text; + am_BeginScene(pArcomageGame->pSpritesPixels, -1, 1); + pTargetPoint.x = pXY->x; + pTargetPoint.y = pXY->y; + do + { + test_char = *v3; + ++v3; + if ( test_char ) + { + v7 = 22 * test_char; + pSrcRect.right = v7 - 842; + pSrcRect.left = v7 - 864; + pSrcRect.top = 190; + pSrcRect.bottom = 207; + pRenderer->am_Blt_Chroma(&pSrcRect, &pTargetPoint, pArcomageGame->field_54, 1); + pTargetPoint.x += 22; + } + } + while ( test_char!= 0 ); + am_EndScene(); +} + +//----- (0040B17E) -------------------------------------------------------- +void DrawBricksCount( int a1, char* text, POINT *pXY ) +{ + char *v3; // esi@1 + unsigned char test_char; // bl@2 + int v7; // eax@3 + RECT pSrcRect; + POINT pTargetPoint; + + v3 = text; + am_BeginScene(pArcomageGame->pSpritesPixels, -1, 1); + pTargetPoint.x = pXY->x; + pTargetPoint.y = pXY->y; + do + { + test_char = *v3; + ++v3; + if ( test_char ) + { + v7 = 13 * test_char; + pSrcRect.left = v7 - 370; + pSrcRect.right = v7 - 357; + pSrcRect.top = 128; + pSrcRect.bottom = 138; + pRenderer->am_Blt_Copy(&pSrcRect, &pTargetPoint, 2); + pTargetPoint.x += 13; + } + } + while ( test_char!= 0 ); + am_EndScene(); +} + +//----- (0040B1F3) -------------------------------------------------------- +void DrawGemsCount( int a1, char* text, POINT* pXY ) +{ + char *v3; // esi@1 + unsigned char test_char; // bl@2 + int v7; // eax@3 + RECT pSrcRect; + POINT pTargetPoint; + + v3 = text; + am_BeginScene(pArcomageGame->pSpritesPixels, -1, 1); + pTargetPoint.x = pXY->x; + pTargetPoint.y = pXY->y; + do + { + test_char = *v3; + ++v3; + if ( test_char ) + { + v7 = 13 * test_char; + pSrcRect.left = v7 - 370; + pSrcRect.right = v7 - 357; + pSrcRect.top = 138; + pSrcRect.bottom = 148; + pRenderer->am_Blt_Copy(&pSrcRect, &pTargetPoint, 2); + pTargetPoint.x += 13; + } + } + while ( test_char!= 0 ); + am_EndScene(); +} + +//----- (0040B268) -------------------------------------------------------- +void DrawBeastsCount( int a1, char *text, POINT *pXY ) +{ + char *v3; // esi@1 + unsigned char test_char; // bl@2 + int v7; // eax@3 + RECT pSrcRect; + POINT pTargetPoint; + + v3 = text; + am_BeginScene(pArcomageGame->pSpritesPixels, -1, 1); + pTargetPoint.x = pXY->x; + pTargetPoint.y = pXY->y; + do + { + test_char = *v3; + ++v3; + if ( test_char ) + { + v7 = 13 * test_char; + pSrcRect.left = v7 - 370; + pSrcRect.right = v7 - 357; + pSrcRect.top = 148; + pSrcRect.bottom = 158; + pRenderer->am_Blt_Copy(&pSrcRect, &pTargetPoint, 2); + pTargetPoint.x += 13; + } + } + while ( test_char!= 0 ); + am_EndScene(); +} + +//----- (0040B2DD) -------------------------------------------------------- +void DrawPlayersTowers() +{ + int tower_height; // eax@1 + int tower_top; // esi@3 + RECT pSrcXYZW; // [sp+0h] [bp-18h]@3 + POINT pTargetXY; // [sp+10h] [bp-8h]@3 + + tower_height= am_Players[0].tower_height; + if ( am_Players[0].tower_height > max_tower_height ) + tower_height = max_tower_height; + pSrcXYZW.top = 0; + pSrcXYZW.left = 892; + pSrcXYZW.right = 937; + tower_top = 200 * tower_height / max_tower_height; + pSrcXYZW.bottom = tower_top; + pTargetXY.x = 102; + pTargetXY.y = 297 - tower_top; + pRenderer->am_Blt_Copy(&pSrcXYZW, &pTargetXY, 2);//стена башни + + pSrcXYZW.top = 0; + pSrcXYZW.left = 384; + pSrcXYZW.right = 452; + pSrcXYZW.bottom = 94; + pTargetXY.y = 203 - tower_top; + pTargetXY.x = 91; + pRenderer->am_Blt_Chroma(&pSrcXYZW, &pTargetXY, pArcomageGame->field_54, 2);//верхушка башни + + tower_height = am_Players[1].tower_height; + if (am_Players[1].tower_height > max_tower_height ) + tower_height = max_tower_height; + tower_top = 200 * tower_height / max_tower_height; + pSrcXYZW.top = 0; + pSrcXYZW.left = 892; + pSrcXYZW.right = 937; + pSrcXYZW.bottom = tower_top; + + pTargetXY.x = 494; + pTargetXY.y = 297 - tower_top; + pRenderer->am_Blt_Copy(&pSrcXYZW, &pTargetXY, 2); + //draw tower up cone + pSrcXYZW.left = 384; + pSrcXYZW.right = 452; + pSrcXYZW.top = 94; + pSrcXYZW.bottom = 188; + + pTargetXY.x = 483; + pTargetXY.y = 203 - tower_top; + pRenderer->am_Blt_Chroma(&pSrcXYZW, &pTargetXY, pArcomageGame->field_54, 2); +} +// 4E1884: using guessed type int dword_4E1884; + +//----- (0040B400) -------------------------------------------------------- +void DrawPlayersWall() +{ + int v0; // eax@1 + int v1; // eax@4 +// LONG v2; // ecx@4 + int v3; // eax@5 + int v4; // eax@8 +// LONG v5; // esi@8 + RECT pSrcXYZW; // [sp+4h] [bp-18h]@4 + POINT pTargetXY; // [sp+14h] [bp-8h]@4 + + v0 = am_Players[0].wall_height; + + if ( am_Players[0].wall_height > 100 ) + v0 = 100; + + if ( am_Players[0].wall_height > 0 ) + { + pSrcXYZW.top = 0; + pSrcXYZW.left = 843; + v1 = 200 * v0 / 100; + pSrcXYZW.right = 867; + pSrcXYZW.bottom = v1; + pTargetXY.x = 177; + pTargetXY.y = 297 - v1; + pRenderer->am_Blt_Chroma(&pSrcXYZW, &pTargetXY, pArcomageGame->field_54, 2); + } + v3 = am_Players[1].wall_height; + if ( am_Players[1].wall_height > 100 ) + v3 = 100; + if ( am_Players[1].wall_height > 0 ) + { + pSrcXYZW.top = 0; + pSrcXYZW.left = 843; + v4 = 200 * v3 / 100; + pSrcXYZW.right = 867; + pSrcXYZW.bottom = v4; + pTargetXY.x = 439; + pTargetXY.y = 297 - v4; + pRenderer->am_Blt_Chroma(&pSrcXYZW, &pTargetXY, pArcomageGame->field_54, 2); + } +} + +//----- (0040B4B9) -------------------------------------------------------- +void DrawCards() +{ + int v0; // esi@1 +// char v1; // bl@1 + int v2; // edi@1 + //int v3; // edx@2 +// int v4; // eax@3 +// int v5; // ecx@3 +// int v6; // eax@3 + unsigned int v7; // ecx@4 +// int v8; // eax@16 +// int v9; // ecx@16 +// int v10; // eax@16 + signed int v11; // edi@18 +// signed int v12; // esi@20 +// int v13; // ecx@20 +// int v14; // eax@23 +// signed int v15; // eax@25 +// int v16; // ecx@25 +// POINT *v17; // esi@26 +// signed int v18; // eax@29 +// AcromageCardOnTable *v19; // ecx@29 +// int v20; // ecx@31 +// int v21; // [sp-4h] [bp-2Ch]@8 + RECT pSrcXYZW; // [sp+Ch] [bp-1Ch]@8 + POINT pTargetXY; // [sp+1Ch] [bp-Ch]@1 + int v24; // [sp+24h] [bp-4h]@1 + + v0 = GetPlayerHandCardCount(current_player_num); + pTargetXY.y = 327; + v24 = (window->GetWidth() - 96 * v0) / (v0 + 1); + pTargetXY.x = (window->GetWidth() - 96 * v0) / (v0 + 1); + for ( v2 = 0; v2 < v0; ++v2 ) + { + //v3 = current_player_num; + if ( am_byte_4E185D) + { + pTargetXY.x += am_Players[current_player_num].card_shift[v2].x; + pTargetXY.y += am_Players[current_player_num].card_shift[v2].y; + } + v7 = am_Players[current_player_num].cards_at_hand[v2]; + if ( am_Players[current_player_num].cards_at_hand[v2] == -1 ) + { + ++v0; + } + else if ( v2 != amuint_4FAA4C ) + { + if ( am_Players[current_player_num].IsHisTurn == 0 && byte_505881 == 0 ) + { + pSrcXYZW.left = 192; + pSrcXYZW.right = 288; + pSrcXYZW.top = 0; + pSrcXYZW.bottom = 128; + pRenderer->am_Blt_Copy(&pSrcXYZW, &pTargetXY, 2);//рисуется оборотные стороны карт противника + pTargetXY.x += v24 + 96; + } + else + { + + pArcomageGame->GetCardRect(v7, &pSrcXYZW); + if (!CanCardBePlayed(current_player_num, v2)) + { + pRenderer->am_Blt_Copy(&pSrcXYZW, &pTargetXY, 0);//рисуются неактивные карты + pTargetXY.x += v24 + 96; + } + else + { + pRenderer->am_Blt_Copy(&pSrcXYZW, &pTargetXY, 2);//рисуются активные карты + pTargetXY.x += v24 + 96; + } + } + } + else + pTargetXY.x += v24 + 96; +//LABEL_15: + if ( am_byte_4E185D ) + { + pTargetXY.x -= am_Players[current_player_num].card_shift[v2].x; + pTargetXY.y -= am_Players[current_player_num].card_shift[v2].y; + } + } + + for ( v11 = 0; v11 < 10; ++v11 ) + { + if ( am_byte_4FAA76 == 0 ) + { + if ( shown_cards[v11].uCardId != -1 ) + { + pArcomageGame->GetCardRect(shown_cards[v11].uCardId, &pSrcXYZW); + pRenderer->am_Blt_Copy(&pSrcXYZW, &shown_cards[v11].field_18_point, 0); + } + if ( shown_cards[v11].field_4 != 0 ) + { + pTargetXY.x = shown_cards[v11].field_18_point.x + 12; + pTargetXY.y = shown_cards[v11].field_18_point.y + 40; + pSrcXYZW.left = 843; + pSrcXYZW.right = 916; + pSrcXYZW.top = 200; + pSrcXYZW.bottom = 216; + pRenderer->am_Blt_Chroma(&pSrcXYZW, &pTargetXY, pArcomageGame->field_54, 2); + } + } + else if ( amuint_4FAA34 <= 0 ) + { + if ( v11 == 9 ) + { + am_byte_4FAA76 = 0; + am_byte_4FAA75 = 0; + amuint_4FAA34 = 5; + } + if ( shown_cards[v11].uCardId != -1 ) + amuint_4FABC4 = shown_cards[v11].uCardId; + shown_cards[v11].uCardId = -1; + shown_cards[v11].field_18_point.x = shown_cards[v11].field_8.x; + shown_cards[v11].field_18_point.y = shown_cards[v11].field_8.y; + shown_cards[v11].field_4 = 0; + } + else + { + if ( shown_cards[v11].uCardId != -1 ) + { + shown_cards[v11].field_18_point.x += shown_cards[v11].field_10_xplus; + shown_cards[v11].field_18_point.y += shown_cards[v11].field_14_y_plus; + pArcomageGame->GetCardRect(shown_cards[v11].uCardId, &pSrcXYZW); + pRenderer->am_Blt_Copy(&pSrcXYZW, &shown_cards[v11].field_18_point, 0); + } + } + } + if ( am_byte_4FAA76 != 0 ) + --amuint_4FAA34; + pSrcXYZW.left = 192; + pSrcXYZW.right = 288; + pSrcXYZW.top = 0; + pSrcXYZW.bottom = 128; + pTargetXY.x = 120; + pTargetXY.y = 18; + pRenderer->am_Blt_Copy(&pSrcXYZW, &pTargetXY, 0); +} + +//----- (0040B76F) -------------------------------------------------------- +void DrawCardAnimation( int animation_stage ) +{ + int v1; // eax@3 + int v2; // eax@3 +// int v3; // esi@4 + int v4; // eax@4 +// POINT *v5; // edx@6 +// RECT *v6; // ecx@6 + int v8; // eax@15 +// AcromageCardOnTable *v9; // ecx@15 +// int v10; // ecx@19 +// int v11; // eax@20 +// int v12; // ecx@20 +// int v13; // eax@20 +// unsigned int v14; // ecx@21 + double v15; // st7@22 +// POINT *v16; // edx@23 + int v17; // eax@32 + char v18; // zf@37 + int v19; // eax@41 +// int v20; // eax@46 +// int v21; // ecx@46 +// int v22; // eax@46 +// int v23; // [sp-4h] [bp-2Ch]@28 + RECT pSrcXYZW; // [sp+Ch] [bp-1Ch]@6 + POINT pTargetXY; // [sp+1Ch] [bp-Ch]@20 + int v26; // [sp+24h] [bp-4h]@1 + + v26 = animation_stage; + if ( amuint_4FAA4C != -1 ) + { + if ( amuint_4FAA38 >= 9 ) + { + am_uint_4FAA44_blt_xy.y = 18; + am_uint_4FAA44_blt_xy.x = 120; + v1 = GetPlayerHandCardCount(current_player_num); + v2 = (window->GetWidth() - 96 * v1) / v1 + 96; + if ( am_byte_4E185D ) + { + // v3 = 188 * current_player_num + 8 * amuint_4FAA4C; + // amuint_4FAA3C_blt_xy.x = (amuint_4FAA4C * v2 + *(am_Players[0].arr_6C[0] + v3) - 120) / 10; + amuint_4FAA3C_blt_xy.x=(amuint_4FAA4C * v2 + am_Players[current_player_num].card_shift[amuint_4FAA4C].x-120)/10; + v4 = (am_Players[current_player_num].card_shift[amuint_4FAA4C].y+309) /10;//(*(&am_Players[0].arr_6C[0][1] + v3) + 309) / 10; + } + else + { + amuint_4FAA3C_blt_xy.x = (amuint_4FAA4C * v2 - 120) / 10; + v4 = 30; + } + am_uint_4FAA44_blt_xy.y += v4; + am_uint_4FAA44_blt_xy.x += amuint_4FAA3C_blt_xy.x; + amuint_4FAA3C_blt_xy.y = v4; + pSrcXYZW.left = 192; + pSrcXYZW.top = 0; + pSrcXYZW.right = 288; + pSrcXYZW.bottom = 128; + pRenderer->am_Blt_Copy(&pSrcXYZW, &am_uint_4FAA44_blt_xy, 2); + } + else + { + pSrcXYZW.left = 192; + pSrcXYZW.top = 0; + pSrcXYZW.right = 288; + pSrcXYZW.bottom = 128; + am_uint_4FAA44_blt_xy.x += amuint_4FAA3C_blt_xy.x; + am_uint_4FAA44_blt_xy.y += amuint_4FAA3C_blt_xy.y; + pRenderer->am_Blt_Copy(&pSrcXYZW, &am_uint_4FAA44_blt_xy, 2); + if ( !amuint_4FAA38 ) + amuint_4FAA4C = -1; + } + } + if ( uCardID != -1 ) + { + if ( v26 <= 10 ) + { + if ( v26 == 10 ) + { + pArcomageGame->GetCardRect(uCardID, &pSrcXYZW); + // v8 = 0; + for ( v8 = 0; v8 < 10; ++v8 ) + { + if (shown_cards[v8].uCardId==-1) + { + shown_cards[v8].uCardId = uCardID; + shown_cards[v8].field_4 = 1; + break; + } + } + /* v9 = shown_cards; + while ( v9->uCardId != -1 ) + { + ++v9; + ++v8; + if ( v9 >= &dword_4FABB8 ) + goto LABEL_20; + } + v10 = v8; + shown_cards[v10].uCardId = uCardID; + shown_cards[v10].field_4 = 1;*/ +//LABEL_20: + pTargetXY.x = shown_cards[v8].field_8.x; + pTargetXY.y = shown_cards[v8].field_8.y; + pRenderer->am_Blt_Copy(&pSrcXYZW, &pTargetXY, 0); + uCardID = -1; + } + } + else + { + pArcomageGame->GetCardRect(uCardID, &pSrcXYZW); + amuint_4FAA5C_blt_xy.x += amuint_4FAA54_blt_xy.x; + amuint_4FAA5C_blt_xy.y += amuint_4FAA54_blt_xy.y; + pRenderer->am_Blt_Copy(&pSrcXYZW, &amuint_4FAA5C_blt_xy, 0); + } + } + if ( played_card_id != -1 ) + { + v15 = v26; + if ( v15 > 15.0 ) + { + pArcomageGame->GetCardRect(played_card_id, &pSrcXYZW); + amuint_4FAA5C_blt_xy.x += amuint_4FAA54_blt_xy.x; + amuint_4FAA5C_blt_xy.y += amuint_4FAA54_blt_xy.y; + pRenderer->am_Blt_Copy(&pSrcXYZW, &amuint_4FAA5C_blt_xy, 2); + return; + } + if ( v15 == 15.0 ) + { + ApplyCardToPlayer(current_player_num, played_card_id); + pArcomageGame->GetCardRect(played_card_id, &pSrcXYZW); + pTargetXY.x = 272; + pTargetXY.y = 173; + pRenderer->am_Blt_Copy(&pSrcXYZW, &pTargetXY, 2); + return; + } + if ( v15 == 5.0 ) + { + amuint_4FAA5C_blt_xy.x = 272; + amuint_4FAA5C_blt_xy.y = 173; + for ( v17 = 0; v17 < 10; ++v17 ) + { + if (shown_cards[v17].uCardId == -1) + break; + } + amuint_4FAA54_blt_xy.x = (shown_cards[v17].field_8.x - 272) / 5; + amuint_4FAA54_blt_xy.y = (shown_cards[v17].field_8.y - 173) / 5; + pArcomageGame->GetCardRect(played_card_id, &pSrcXYZW); + pTargetXY.x = 272; + pTargetXY.y = 173; + pRenderer->am_Blt_Copy(&pSrcXYZW, &pTargetXY, 2); + return; + } + if ( v15 >= 5.0 ) + v18 = v26 == 0; + else + { + v18 = v26 == 0; + if ( v26 > 0 ) + { + pArcomageGame->GetCardRect(played_card_id, &pSrcXYZW); + amuint_4FAA5C_blt_xy.x += amuint_4FAA54_blt_xy.x; + amuint_4FAA5C_blt_xy.y += amuint_4FAA54_blt_xy.y; + pRenderer->am_Blt_Copy(&pSrcXYZW, &amuint_4FAA5C_blt_xy, 0); + return; + } + } + if ( !v18 ) + { + pArcomageGame->GetCardRect(played_card_id, &pSrcXYZW); + pTargetXY.x = 272; + pTargetXY.y = 173; + pRenderer->am_Blt_Copy(&pSrcXYZW, &pTargetXY, 2); + return; + } + pArcomageGame->GetCardRect(played_card_id, &pSrcXYZW); + for ( v19 = 0; v19 < 10; ++v19 ) + { + if (shown_cards[v19].uCardId == -1) + { + shown_cards[v19].uCardId = played_card_id; + break; + } + } + pTargetXY.x = shown_cards[v19].field_8.x; + pTargetXY.y = shown_cards[v19].field_8.y; + pRenderer->am_Blt_Copy(&pSrcXYZW, &pTargetXY, 0); + played_card_id = -1; + } +} + +//----- (0040BB12) -------------------------------------------------------- +void ArcomageGame::GetCardRect(unsigned int uCardID, RECT *pCardRect) +{ + int v3; // edx@1 + int v4; // ecx@1 + + v3 = pCards[uCardID].slot % 10; + v4 = (pCards[uCardID].slot / 10 << 7) + 220; + pCardRect->top = v4; + pCardRect->left = 96 * v3; + pCardRect->bottom = v4 + 128; + pCardRect->right = 96 * v3 + 96; +} + +//----- (0040BB49) -------------------------------------------------------- +int GetPlayerHandCardCount( int player_num ) +{ + int card_count; // eax@1 + + card_count = 0; + for(int i=0; i<10; ++i) + { + if (am_Players[player_num].cards_at_hand[i]!=-1) + ++card_count; + } + return card_count; +} + +//----- (0040BB67) -------------------------------------------------------- +signed int DrawCardsRectangles( int player_num ) +{ + int v5; // eax@3 +// int i; // ecx@6 + int color; // ST00_4@19 + RECT pXYZW; // [sp+Ch] [bp-3Ch]@3 + stru273 v26; // [sp+1Ch] [bp-2Ch]@2 + __int32 var18; // [sp+30h] [bp-18h]@3 + int hand_index; // [sp+3Ch] [bp-Ch]@3 + +//__debugbreak(); // need do fix rectangle not fit to card + + if ( am_Players[player_num].IsHisTurn ) + { + if ( v26._40DD2F() ) + { + v5 = GetPlayerHandCardCount(player_num); + pXYZW.top = 327; + pXYZW.bottom = 455; + pXYZW.left = (window->GetWidth() - 96 * v5) / (v5 + 1); + var18 = pXYZW.left + 96; + pXYZW.right = pXYZW.left + 96; + for( hand_index = 0; hand_index < v5; hand_index++) + { + //for ( i = 0; i < 10; ++i ) + //{ + if (am_Players[player_num].cards_at_hand[hand_index] != -1 ) + { + //break; + //} + if ( am_byte_4E185D ) + { + pXYZW.left += am_Players[player_num].card_shift[hand_index].x; + pXYZW.right += am_Players[player_num].card_shift[hand_index].x; + pXYZW.top += am_Players[player_num].card_shift[hand_index].y; + pXYZW.bottom += am_Players[player_num].card_shift[hand_index].y; + } + if ( v26.Inside(&pXYZW) ) + { + if ( CanCardBePlayed(player_num, hand_index) ) + color = 0x00FFFFFF;//белый цвет + else + color = 0x000000FF;//красный цвет + DrawRect(&pXYZW, R8G8B8_to_TargetFormat(color), 0); + return hand_index; + } + DrawRect(&pXYZW, R8G8B8_to_TargetFormat(0), 0);//рамка чёрного цвета + if ( am_byte_4E185D ) + { + pXYZW.left -= am_Players[player_num].card_shift[hand_index].x; + pXYZW.right -= am_Players[player_num].card_shift[hand_index].x; + pXYZW.top -= am_Players[player_num].card_shift[hand_index].y; + pXYZW.bottom -= am_Players[player_num].card_shift[hand_index].y; + } + pXYZW.left += var18; + pXYZW.right += var18; + } + } + } + } + return -1; +} +// 4E185D: using guessed type char am_byte_4E185D; + +//----- (0040BCFB) -------------------------------------------------------- +bool DiscardCard( int player_num, signed int card_slot_index ) +{ + int v2; // esi@2 +// signed int v3; // edi@2 +// char *v4; // eax@2 +// int v5; // ecx@7 +// int v6; // ebx@7 +// int v7; // esi@8 + int v8; // eax@8 +// int v9; // esi@8 + int v10; // ecx@8 +// int v11; // eax@8 + int v12; // eax@8 +// signed int v13; // edx@9 +// unsigned int v14; // eax@12 +// char result; // al@12 + int i; + + if ( card_slot_index <= -1 ) + return false; + v2 = 0; + + for( i = 0; i < 10; ++i ) + { + if ( am_Players[player_num].cards_at_hand[i] != -1 ) + { + if ( card_slot_index == v2 ) + break; + ++v2; + } + } + + if ( pCards[am_Players[player_num].cards_at_hand[i]].can_be_discarded) + { + ArcomageGame::PlaySound(22); + v8 = GetPlayerHandCardCount(current_player_num); + v10 = am_Players[player_num].card_shift[i].x + (window->GetWidth() - 96 * v8) / (v8 + 1); + amuint_4FAA5C_blt_xy.x = v10; + amuint_4FAA5C_blt_xy.y = am_Players[player_num].card_shift[i].y + 327;//v11; + v12 = 0; + + if ( !am_byte_4FAA75 ) + { + for ( v12 = 0; v12 < 10; ++v12 ) + { + if (shown_cards[v12].uCardId == -1) + break; + } + } + pArcomageGame->field_F6 = 1; + amuint_4FAA54_blt_xy.x = (shown_cards[v12].field_8.x - v10) / 10; + amuint_4FAA54_blt_xy.y = (shown_cards[v12].field_8.y - 327) / 10; + uCardID = am_Players[player_num].cards_at_hand[i]; + am_Players[player_num].cards_at_hand[i] = -1; + need_to_discard_card = 0; + return true; + } + else + return false; +} + +//----- (0040BE0E) -------------------------------------------------------- +bool PlayCard( int player_num, int card_slot_num ) +{ +// int v3; // ebp@1 + int v4; // ecx@2 +// ArcomagePlayer *v5; // esi@2 + int card_index; // edi@2 +// int v7; // eax@2 +// int v8; // ebx@8 + int cards_at_hand; // eax@8 +// int v10; // ebx@8 +// int v11; // ebp@8 + int v12; // ecx@8 +// int v13; // eax@8 + ArcomageCard *pCard; // eax@8 +// int v15; // ecx@8 +// int v16; // ecx@8 + + if ( card_slot_num <= -1 ) + return false; + + v4 = 0; + for (card_index=0; card_index<10; ++card_index) + { + if ( am_Players[player_num].cards_at_hand[card_index] != -1 ) + { + if ( card_slot_num == v4 ) + break; + ++v4; + } + } + + if (CanCardBePlayed(player_num, card_index) ) + { + ArcomageGame::PlaySound(23); + cards_at_hand = GetPlayerHandCardCount(current_player_num); + pArcomageGame->field_F6 = 1; + v12 = am_Players[player_num].card_shift[card_index].x + + (window->GetWidth() - 96 * cards_at_hand) / (cards_at_hand + 1)+ + 96 * card_index ; + + // v13 = *(int *)((char *)&am_Players[0].arr_6C[0][1] + v10) + 327; + amuint_4FAA5C_blt_xy.x = v12;//v12; + amuint_4FAA5C_blt_xy.y = am_Players[player_num].card_shift[card_index].y + 327;//v13; + + amuint_4FAA54_blt_xy.x = (272 - v12) / 5; + amuint_4FAA54_blt_xy.y = -30; + + pCard = &pCards[am_Players[player_num].cards_at_hand[card_index]]; + am_Players[player_num].resource_bricks -= pCard->needed_bricks; + am_Players[player_num].resource_beasts -= pCard->needed_beasts; + am_Players[player_num].resource_gems -= pCard->needed_gems; + played_card_id = am_Players[player_num].cards_at_hand[card_index]; + am_Players[player_num].cards_at_hand[card_index] = -1; + return true; + } + else + return false; + +} + +//----- (0040BF15) -------------------------------------------------------- +bool CanCardBePlayed(int player_num, int hand_card_indx) +{ + bool result; // eax@1 + ArcomageCard *test_card; // ecx@1 + ArcomagePlayer *pPlayer; // esi@1 + + pPlayer = &am_Players[player_num]; + result = true; + test_card = &pCards[am_Players[player_num].cards_at_hand[hand_card_indx]]; + if ( test_card->needed_quarry_level > pPlayer->quarry_level ) + result = false; + if ( test_card->needed_magic_level > pPlayer->magic_level ) + result = false; + if ( test_card->needed_zoo_level > pPlayer->zoo_level ) + result = false; + if ( test_card->needed_bricks > pPlayer->resource_bricks ) + result = false; + if ( test_card->needed_gems > pPlayer->resource_gems ) + result = false; + if ( test_card->needed_beasts > pPlayer->resource_beasts ) + result = false; + return result; +} + +//----- (0040BF77) -------------------------------------------------------- +void ApplyCardToPlayer( int player_num, unsigned int uCardID ) + { + + +#define APPLY_TO_PLAYER( PLAYER, ENEMY,FIELD, VAL, RES )\ + if (VAL != 0) {\ + if (VAL == 99) {\ + if ( PLAYER->##FIELD < ENEMY->##FIELD ) {\ + PLAYER->##FIELD = ENEMY->##FIELD;\ + RES = ENEMY->##FIELD - PLAYER->##FIELD;\ + }\ + } else {\ + PLAYER->##FIELD += (signed int)(VAL);\ + if ( PLAYER->##FIELD<0 ) PLAYER->##FIELD= 0;\ + RES = (signed int)(VAL);\ + }\ + } + +#define APPLY_TO_ENEMY( PLAYER, ENEMY,FIELD, VAL, RES ) APPLY_TO_PLAYER(ENEMY, PLAYER, FIELD, VAL, RES) + +#define APPLY_TO_BOTH( PLAYER, ENEMY, FIELD, VAL, RES_P, RES_E ) \ + if ( VAL != 0) {\ + if ( VAL == 99 ) { \ + if ( PLAYER->##FIELD != ENEMY->##FIELD ) { \ + if ( PLAYER->##FIELD <= ENEMY->##FIELD ) { \ + PLAYER->##FIELD = ENEMY->##FIELD; \ + RES_P = ENEMY->##FIELD - PLAYER->##FIELD; \ + } else { \ + ENEMY->##FIELD = PLAYER->##FIELD; \ + RES_E = PLAYER->##FIELD - ENEMY->##FIELD; \ + } \ + }\ + } else { \ + PLAYER->##FIELD += (signed int)(VAL);\ + ENEMY->##FIELD += (signed int)(VAL); if (PLAYER->##FIELD < 0 ) {PLAYER->##FIELD = 0;} \ + if ( ENEMY->##FIELD < 0 ) {ENEMY->##FIELD = 0;} \ + RES_P = (signed int)(VAL); RES_E = (signed int)(VAL); \ + }\ + } + ArcomagePlayer *player; // esi@1 +// int v3; // eax@1 + ArcomagePlayer *enemy; // edi@1 +// int v5; // eax@2 +// char v6; // sf@2 +// unsigned __int8 v7; // of@2 +// int v8; // eax@3 +// int v9; // eax@4 +// char v10; // zf@5 +// int v11; // eax@8 +// unsigned __int8 v12; // zf@8 +// char v13; // sf@8 +// unsigned __int8 v14; // of@8 +// int v15; // eax@9 +// int v16; // eax@10 +// char v17; // zf@12 +// char v18; // al@15 +// int v19; // eax@16 +// int v20; // eax@17 +// int v21; // eax@22 +// int v22; // eax@23 + int v23; // eax@26 + signed int v24; // ebx@26 + int v103; + int v104; + + POINT v184; // [sp+Ch] [bp-64h]@488 + int enemy_num; // [sp+14h] [bp-5Ch]@1 + ArcomageCard *pCard; // [sp+18h] [bp-58h]@1 + int buildings_e; // [sp+1Ch] [bp-54h]@1 + int buildings_p; // [sp+20h] [bp-50h]@1 + int quarry_p; // [sp+28h] [bp-48h]@1 + int dmg_e; // [sp+2Ch] [bp-44h]@1 + int dmg_p; // [sp+30h] [bp-40h]@1 + int bricks_p; // [sp+34h] [bp-3Ch]@1 + int tower_e; // [sp+38h] [bp-38h]@1 + int tower_p; // [sp+3Ch] [bp-34h]@1 + int wall_e; // [sp+40h] [bp-30h]@1 + int wall_p; // [sp+44h] [bp-2Ch]@1 + int beasts_e; // [sp+48h] [bp-28h]@1 + int beasts_p; // [sp+4Ch] [bp-24h]@1 + int gems_e; // [sp+50h] [bp-20h]@1 + int gems_p; // [sp+54h] [bp-1Ch]@1 + int bricks_e; // [sp+58h] [bp-18h]@1 + int zoo_e; // [sp+5Ch] [bp-14h]@1 + int zoo_p; // [sp+60h] [bp-10h]@1 + int magic_e; // [sp+64h] [bp-Ch]@1 + int magic_p; // [sp+68h] [bp-8h]@1 + int quarry_e; // [sp+6Ch] [bp-4h]@1 + + quarry_p = 0; + magic_p = 0; + zoo_p = 0; + bricks_p = 0; + gems_p = 0; + beasts_p = 0; + wall_p = 0; + tower_p = 0; + buildings_p = 0; + dmg_p = 0; + quarry_e = 0; + magic_e = 0; + zoo_e = 0; + bricks_e = 0; + gems_e = 0; + beasts_e = 0; + wall_e = 0; + tower_e = 0; + buildings_e = 0; + dmg_e = 0; + + player = &am_Players[player_num]; + pCard = &pCards[uCardID]; + enemy_num = (player_num + 1) % 2; + enemy = &am_Players[enemy_num]; + switch ( pCard->compare_param ) + { + case 2: + if ( player->quarry_level < enemy->quarry_level )//если рудники < рудника врага + goto LABEL_26; + goto LABEL_231; + case 3: + if ( player->magic_level < enemy->magic_level ) + goto LABEL_26; + goto LABEL_231; + case 4: + if ( player->zoo_level < enemy->zoo_level )//если зверинец < зверинца врага + goto LABEL_26; + goto LABEL_231; + case 5: + if ( player->quarry_level == enemy->quarry_level ) + goto LABEL_26; + goto LABEL_231; + case 6: + if ( player->magic_level == enemy->magic_level ) + goto LABEL_26; + goto LABEL_231; + case 7: + if ( player->zoo_level == enemy->zoo_level ) + goto LABEL_26; + goto LABEL_231; + case 8: + if ( player->quarry_level < enemy->quarry_level ) + goto LABEL_26; + goto LABEL_231; + case 9: + if ( player->magic_level < enemy->magic_level ) + goto LABEL_26; + goto LABEL_231; + case 10: + if ( player->zoo_level < enemy->zoo_level ) + goto LABEL_26; + goto LABEL_231; + case 11: + if ( !player->wall_height ) + goto LABEL_26; + goto LABEL_231; + case 12: + if ( player->wall_height ) + goto LABEL_26; + goto LABEL_231; + case 13: + if ( !enemy->wall_height ) + goto LABEL_26; + goto LABEL_231; + case 14: + if ( enemy->wall_height ) + goto LABEL_26; + goto LABEL_231; + case 15: + if ( player->wall_height < enemy->wall_height ) + goto LABEL_26; + goto LABEL_231; + case 16: + if ( player->tower_height < enemy->tower_height ) + goto LABEL_26; + goto LABEL_231; + case 17: + if ( player->wall_height == enemy->wall_height ) + goto LABEL_26; + goto LABEL_231; + case 18: + if ( player->tower_height == enemy->tower_height ) + goto LABEL_26; + goto LABEL_231; + case 19: + if ( player->wall_height < enemy->wall_height ) + goto LABEL_26; + goto LABEL_231; + case 20: + if ( player->tower_height < enemy->tower_height ) + goto LABEL_26; + goto LABEL_231; + default: +LABEL_26: + v23 = pCard->draw_extra_card_count; + v24 = 0; + dword_4FAA68 = v23 + (pCard->field_30 == 1); + dword_4FAA64 = v23; + if ( v23 > 0 ) + { + do + { + GetNextCardFromDeck(player_num); + ++v24; + } + while ( v24 < pCard->draw_extra_card_count ); + } + + need_to_discard_card = GetPlayerHandCardCount(player_num) > minimum_cards_at_hand; + + APPLY_TO_PLAYER(player, enemy, quarry_level, pCard->to_player_quarry_lvl, quarry_p); + APPLY_TO_PLAYER(player, enemy, magic_level, pCard->to_player_magic_lvl, magic_p); + APPLY_TO_PLAYER(player, enemy, zoo_level, pCard->to_player_zoo_lvl, zoo_p); + APPLY_TO_PLAYER(player, enemy, resource_bricks, pCard->to_player_bricks, bricks_p); + APPLY_TO_PLAYER(player, enemy, resource_gems, pCard->to_player_gems, gems_p); + APPLY_TO_PLAYER(player, enemy, resource_beasts, pCard->to_player_beasts, beasts_p); + if ( pCard->to_player_buildings ) + { + dmg_p = ApplyDamageToBuildings(player_num, (signed int)pCard->to_player_buildings); + buildings_p = (signed int)pCard->to_player_buildings - dmg_p; + } + APPLY_TO_PLAYER(player, enemy, wall_height, pCard->to_player_wall, wall_p); + APPLY_TO_PLAYER(player, enemy, tower_height, pCard->to_player_tower, tower_p); + + APPLY_TO_ENEMY(player, enemy, quarry_level, pCard->to_enemy_quarry_lvl, quarry_e); + APPLY_TO_ENEMY(player, enemy, magic_level, pCard->to_enemy_magic_lvl, magic_e); + APPLY_TO_ENEMY(player, enemy, zoo_level, pCard->to_enemy_zoo_lvl, zoo_e); + APPLY_TO_ENEMY(player, enemy, resource_bricks, pCard->to_enemy_bricks, bricks_e); + APPLY_TO_ENEMY(player, enemy, resource_gems, pCard->to_enemy_gems, gems_e); + APPLY_TO_ENEMY(player, enemy, resource_beasts, pCard->to_enemy_beasts, beasts_e); + if ( pCard->to_enemy_buildings ) + { + dmg_e = ApplyDamageToBuildings(enemy_num, (signed int)pCard->to_enemy_buildings); + buildings_e = (signed int)pCard->to_enemy_buildings - dmg_e; + } + APPLY_TO_ENEMY(player, enemy, wall_height, pCard->to_enemy_wall, wall_e); + APPLY_TO_ENEMY(player, enemy, tower_height, pCard->to_enemy_tower, tower_e); + + APPLY_TO_BOTH(player, enemy, quarry_level, pCard->to_pl_enm_quarry_lvl, quarry_p, quarry_e); + APPLY_TO_BOTH(player, enemy, magic_level, pCard->to_pl_enm_magic_lvl, magic_p, magic_e); + APPLY_TO_BOTH(player, enemy, zoo_level, pCard->to_pl_enm_zoo_lvl, zoo_p, zoo_e); + APPLY_TO_BOTH(player, enemy, resource_bricks, pCard->to_pl_enm_bricks, bricks_p, bricks_e); + APPLY_TO_BOTH(player, enemy, resource_gems, pCard->to_pl_enm_gems, gems_p, gems_e); + APPLY_TO_BOTH(player, enemy, resource_beasts, pCard->to_pl_enm_beasts, beasts_p, beasts_e); + if ( pCard->to_pl_enm_buildings ) + { + dmg_p = ApplyDamageToBuildings(player_num, (signed int)pCard->to_pl_enm_buildings); + dmg_e = ApplyDamageToBuildings(enemy_num, (signed int)pCard->to_pl_enm_buildings); + buildings_p = (signed int)pCard->to_pl_enm_buildings - dmg_p; + buildings_e = (signed int)pCard->to_pl_enm_buildings - dmg_e; + } + APPLY_TO_BOTH(player, enemy, wall_height, pCard->to_pl_enm_wall, wall_p, wall_e); + APPLY_TO_BOTH(player, enemy, tower_height, pCard->to_pl_enm_tower, tower_p, tower_e); + break; + case 0: +LABEL_231: + v103 = pCard->can_draw_extra_card2; + v104 = 0; + dword_4FAA68 = v103 + (pCard->field_4D == 1); + dword_4FAA64 = v103; + if ( v103 > 0 ) + { + do + { + GetNextCardFromDeck(player_num); + ++v104; + } + while ( v104 < pCard->can_draw_extra_card2 ); + } + + need_to_discard_card = GetPlayerHandCardCount(player_num) > minimum_cards_at_hand; + + APPLY_TO_PLAYER(player, enemy, quarry_level, pCard->to_player_quarry_lvl2, quarry_p); + APPLY_TO_PLAYER(player, enemy, magic_level, pCard->to_player_magic_lvl2, magic_p); + APPLY_TO_PLAYER(player, enemy, zoo_level, pCard->to_player_zoo_lvl2, zoo_p); + APPLY_TO_PLAYER(player, enemy, resource_bricks, pCard->to_player_bricks2, bricks_p); + APPLY_TO_PLAYER(player, enemy, resource_gems, pCard->to_player_gems2, gems_p); + APPLY_TO_PLAYER(player, enemy, resource_beasts, pCard->to_player_beasts2, beasts_p); + if ( pCard->to_player_buildings2 ) + { + dmg_p = ApplyDamageToBuildings(player_num, (signed int)pCard->to_player_buildings2); + buildings_p = (signed int)pCard->to_player_buildings2 - dmg_p; + } + APPLY_TO_PLAYER(player, enemy, wall_height, pCard->to_player_wall2, wall_p); + APPLY_TO_PLAYER(player, enemy, tower_height, pCard->to_player_tower2, tower_p); + + APPLY_TO_ENEMY(player, enemy, quarry_level, pCard->to_enemy_quarry_lvl2, quarry_e); + APPLY_TO_ENEMY(player, enemy, magic_level, pCard->to_enemy_magic_lvl2, magic_e); + APPLY_TO_ENEMY(player, enemy, zoo_level, pCard->to_enemy_zoo_lvl2, zoo_e); + APPLY_TO_ENEMY(player, enemy, resource_bricks, pCard->to_enemy_bricks2, bricks_e); + APPLY_TO_ENEMY(player, enemy, resource_gems, pCard->to_enemy_gems2, gems_e); + APPLY_TO_ENEMY(player, enemy, resource_beasts, pCard->to_enemy_beasts2, beasts_e); + if ( pCard->to_enemy_buildings2 ) + { + dmg_e = ApplyDamageToBuildings(enemy_num, (signed int)pCard->to_enemy_buildings2); + buildings_e = (signed int)pCard->to_enemy_buildings2 - dmg_e; + } + APPLY_TO_ENEMY(player, enemy, wall_height, pCard->to_enemy_wall2, wall_e); + APPLY_TO_ENEMY(player, enemy, tower_height, pCard->to_enemy_tower2, tower_e); + + APPLY_TO_BOTH(player, enemy, quarry_level, pCard->to_pl_enm_quarry_lvl2, quarry_p, quarry_e); + APPLY_TO_BOTH(player, enemy, magic_level, pCard->to_pl_enm_magic_lvl2, magic_p, magic_e); + APPLY_TO_BOTH(player, enemy, zoo_level, pCard->to_pl_enm_zoo_lvl2, zoo_p, zoo_e); + APPLY_TO_BOTH(player, enemy, resource_bricks, pCard->to_pl_enm_bricks2, bricks_p, bricks_e); + APPLY_TO_BOTH(player, enemy, resource_gems, pCard->to_pl_enm_gems2, gems_p, gems_e); + APPLY_TO_BOTH(player, enemy, resource_beasts, pCard->to_pl_enm_beasts2, beasts_p, beasts_e); + + if ( pCard->to_pl_enm_buildings2 ) + { + dmg_p = ApplyDamageToBuildings(player_num, (signed int)pCard->to_pl_enm_buildings2); + dmg_e = ApplyDamageToBuildings(enemy_num, (signed int)pCard->to_pl_enm_buildings2); + buildings_p = (signed int)pCard->to_pl_enm_buildings2 - dmg_p; + buildings_e = (signed int)pCard->to_pl_enm_buildings2 - dmg_e; + } + APPLY_TO_BOTH(player, enemy, wall_height, pCard->to_pl_enm_wall2, wall_p, wall_e); + APPLY_TO_BOTH(player, enemy, tower_height, pCard->to_pl_enm_tower2, tower_p, tower_e); + break; + } + // } + if ( quarry_p > 0 || quarry_e > 0 ) + pArcomageGame->PlaySound(30); + if ( quarry_p < 0 || quarry_e < 0 ) + pArcomageGame->PlaySound(31); + if ( magic_p > 0 || magic_e > 0 ) + pArcomageGame->PlaySound(33); + if ( magic_p < 0 || magic_e < 0 ) + pArcomageGame->PlaySound(34); + if ( zoo_p > 0 || zoo_e > 0 ) + pArcomageGame->PlaySound(36); + if ( zoo_p < 0 || zoo_e < 0 ) + pArcomageGame->PlaySound(37); + if ( bricks_p > 0 || bricks_e > 0 ) + pArcomageGame->PlaySound(39); + if ( bricks_p < 0 || bricks_e < 0 ) + pArcomageGame->PlaySound(40); + if ( gems_p > 0 || gems_e > 0 ) + pArcomageGame->PlaySound(42); + if ( gems_p < 0 || gems_e < 0 ) + pArcomageGame->PlaySound(43); + if ( beasts_p > 0 || beasts_e > 0 ) + pArcomageGame->PlaySound(45u); + if ( beasts_p < 0 || beasts_e < 0 ) + pArcomageGame->PlaySound(46); + if ( buildings_p || buildings_e || dmg_p || dmg_e ) + pArcomageGame->PlaySound(48); + if ( wall_p > 0 || wall_e > 0 ) + pArcomageGame->PlaySound(49); + if ( wall_p < 0 || wall_e < 0 ) + pArcomageGame->PlaySound(50); + if ( tower_p > 0 || tower_e > 0 ) + pArcomageGame->PlaySound(52); + if ( tower_p < 0 || tower_e < 0 ) + pArcomageGame->PlaySound(53); + if ( player_num ) + { + if ( quarry_p ) + { + v184.x = 573; + v184.y = 92; + am_40D2B4(&v184, quarry_p); + } + if ( quarry_e ) + { + v184.x = 26; + v184.y = 92; + am_40D2B4(&v184, quarry_e); + } + if ( magic_p ) + { + v184.x = 573; + v184.y = 164; + am_40D2B4(&v184, magic_p); + } + if ( magic_e ) + { + v184.x = 26; + v184.y = 164; + am_40D2B4(&v184, magic_e); + } + if ( zoo_p ) + { + v184.x = 573; + v184.y = 236; + am_40D2B4(&v184, zoo_p); + } + if ( zoo_e ) + { + v184.x = 26; + v184.y = 236; + am_40D2B4(&v184, zoo_e); + } + if ( bricks_p ) + { + v184.x = 563; + v184.y = 114; + am_40D2B4(&v184, bricks_p); + } + if ( bricks_e ) + { + v184.x = 16; + v184.y = 114; + am_40D2B4(&v184, bricks_e); + } + if ( gems_p ) + { + v184.x = 563; + v184.y = 186; + am_40D2B4(&v184, gems_p); + } + if ( gems_e ) + { + v184.x = 16; + v184.y = 186; + am_40D2B4(&v184, gems_e); + } + if ( beasts_p ) + { + v184.x = 563; + v184.y = 258; + am_40D2B4(&v184, beasts_p); + } + if ( beasts_e ) + { + v184.x = 16; + v184.y = 258; + am_40D2B4(&v184, beasts_e); + } + if ( wall_p ) + { + v184.x = 442; + v184.y = 296; + am_40D2B4(&v184, wall_p); + } + if ( wall_e ) + { + v184.x = 180; + v184.y = 296; + am_40D2B4(&v184, wall_e); + } + if ( tower_p ) + { + v184.x = 514; + v184.y = 296; + am_40D2B4(&v184, tower_p); + } + if ( tower_e ) + { + v184.x = 122; + v184.y = 296; + am_40D2B4(&v184, tower_e); + } + if ( dmg_p ) + { + v184.x = 442; + v184.y = 296; + am_40D2B4(&v184, dmg_p); + } + if ( buildings_p ) + { + v184.x = 514; + v184.y = 296; + am_40D2B4(&v184, buildings_p); + } + if ( dmg_e ) + { + v184.x = 180; + v184.y = 296; + am_40D2B4(&v184, dmg_e); + } + if ( buildings_e ) + { + v184.x = 122; + v184.y = 296; + am_40D2B4(&v184, buildings_e); + } + } + else + { + if ( quarry_p ) + { + v184.x = 26; + v184.y = 92; + am_40D2B4(&v184, quarry_p); + } + if ( quarry_e ) + { + v184.x = 573; + v184.y = 92; + am_40D2B4(&v184, quarry_e); + } + if ( magic_p ) + { + v184.x = 26; + v184.y = 164; + am_40D2B4(&v184, magic_p); + } + if ( magic_e ) + { + v184.x = 573; + v184.y = 164; + am_40D2B4(&v184, magic_e); + } + if ( zoo_p ) + { + v184.x = 26; + v184.y = 236; + am_40D2B4(&v184, zoo_p); + } + if ( zoo_e ) + { + v184.x = 573; + v184.y = 236; + am_40D2B4(&v184, zoo_e); + } + if ( bricks_p ) + { + v184.x = 16; + v184.y = 114; + am_40D2B4(&v184, bricks_p); + } + if ( bricks_e ) + { + v184.x = 563; + v184.y = 114; + am_40D2B4(&v184, bricks_e); + } + if ( gems_p ) + { + v184.x = 16; + v184.y = 186; + am_40D2B4(&v184, gems_p); + } + if ( gems_e ) + { + v184.x = 563; + v184.y = 186; + am_40D2B4(&v184, gems_e); + } + if ( beasts_p ) + { + v184.x = 16; + v184.y = 258; + am_40D2B4(&v184, beasts_p); + } + if ( beasts_e ) + { + v184.x = 563; + v184.y = 258; + am_40D2B4(&v184, beasts_e); + } + if ( wall_p ) + { + v184.x = 180; + v184.y = 296; + am_40D2B4(&v184, wall_p); + } + if ( wall_e ) + { + v184.x = 442; + v184.y = 296; + am_40D2B4(&v184, wall_e); + } + if ( tower_p ) + { + v184.x = 122; + v184.y = 296; + am_40D2B4(&v184, tower_p); + } + if ( tower_e ) + { + v184.x = 514; + v184.y = 296; + am_40D2B4(&v184, tower_e); + } + if ( dmg_p ) + { + v184.x = 180; + v184.y = 296; + am_40D2B4(&v184, dmg_p); + } + if ( buildings_p ) + { + v184.x = 122; + v184.y = 296; + am_40D2B4(&v184, buildings_p); + } + if ( dmg_e ) + { + v184.x = 442; + v184.y = 296; + am_40D2B4(&v184, dmg_e); + } + if ( buildings_e ) + { + v184.x = 514; + v184.y = 296; + am_40D2B4(&v184, buildings_e); + } + } +#undef APPLY_TO_BOTH +#undef APPLY_TO_ENEMY +#undef APPLY_TO_PLAYER + +} + +//----- (0040D2B4) -------------------------------------------------------- +int am_40D2B4( POINT* startXY, int effect_value ) +{ + int v2; // ebp@1 +// POINT *v3; // edi@1 + int result; // eax@3 + int v6; + stru272_stru0 *v8; // ecx@12 + signed int v11; // [sp+10h] [bp-8h]@1 + + v11 = 0; + v2 = effect_value; + + while ( array_4FABD0[v11].have_effect )//Ritor1: needed refactoring + { + result = array_4FABD0[v11].field_40->_40E2A7(); + if ( !result ) + { + array_4FABD0[v11].have_effect = 0; + --v11; + } + ++v11; + if ( v11 >= 10 ) + return result; + } + v6 = v11; + array_4FABD0[v11].have_effect = 1; + if ( effect_value <= 0 ) + { + array_4FABD0[v6].effect_sign = 0; + effect_value = -effect_value; + } + else + array_4FABD0[v6].effect_sign = 1; + array_4FABD0[v6].field_4.effect_area.left = startXY->x - 20; + array_4FABD0[v6].field_4.effect_area.right = startXY->x + 20; + array_4FABD0[v6].field_4.effect_area.top = startXY->y - 20; + array_4FABD0[v6].field_4.effect_area.bottom = startXY->y + 20; + array_4FABD0[v6].field_4.field_10 = -60; + array_4FABD0[v6].field_4.field_14 = 60; + array_4FABD0[v6].field_4.field_18 = 180; + array_4FABD0[v6].field_4.field_1Cf = 0.5; + array_4FABD0[v6].field_4.field_20 = 150; + array_4FABD0[v6].field_4.field_24f= 50.0; + array_4FABD0[v6].field_4.field_28f = 3.0; + array_4FABD0[v6].field_4.field_2Cf = 8.0; + array_4FABD0[v6].field_4.field_30 = 5; + array_4FABD0[v6].field_4.field_34 = 15; + array_4FABD0[v6].field_4.sparks_array = &array_4FABD0[v6].effect_sparks[0]; + v8 = array_4FABD0[v6].field_40; + v8->StartFill(&array_4FABD0[v6].field_4); + if ( 10 * effect_value > 150 ) + effect_value = 15; + + if ( v8->signature != SIG_trpg ) + return 2; + if ( !v8->field_59 ) + return 3; + v8->position_in_sparks_arr = 10 * effect_value; + v8->field_30 = 0.0; + v8->field_58 = 0; + v8->field_44 = 0; + v8->field_4C = 0; + v8->field_48 = 0; + v8->field_50 = 0; + for (int i = 0; i < v8->field_4; ++i) + v8->field_54[i].have_spark = 0; + return 0; +} + +//----- (0040D402) -------------------------------------------------------- +int ApplyDamageToBuildings( int player_num, int damage ) +{ +// ArcomagePlayer *v2; // ecx@1 + int v3; // esi@1 + int result; // eax@3 + + v3 = am_Players[player_num].wall_height; + //if ( v3 <= 0 ) + result = 0; + //else + //{ + if ( v3 >= -damage ) + { + result = damage; + am_Players[player_num].wall_height += damage; + } + else + { + damage += v3; + result = -v3; + am_Players[player_num].wall_height = 0; + am_Players[player_num].tower_height += damage; + } + //} + if ( am_Players[player_num].tower_height < 0 ) + am_Players[player_num].tower_height = 0; + return result; +} +// 40D402: using guessed type int __fastcall am_40D402(uint, uint); + +//----- (0040D444) -------------------------------------------------------- +void GameResultsApply() +{ + int winner; // esi@1 + int victory_type; // edi@1 + int pl_resource; // edx@25 + int en_resource; // eax@28 + unsigned int tavern_num; // eax@54 +// char pText[64]; // [sp+Ch] [bp-48h]@1 +// POINT xy; // [sp+4Ch] [bp-8h]@1 + + winner = -1; + victory_type = -1; + //nullsub_1(); + /*strcpy(pText, "The Winner is: ");//"Победил: " Ritor1: архаизм + xy.y = 160; + xy.x = 320; //- 12 * v2 / 2; + am_DrawText(-1, pText, &xy);*/ + + //проверка построена ли башня + if ( am_Players[0].tower_height < max_tower_height && am_Players[1].tower_height >= max_tower_height )//наша башня не построена, а у врага построена + { + winner = 2;//победил игрок 2(враг) + victory_type = 0; + } + else if ( am_Players[0].tower_height >= max_tower_height && am_Players[1].tower_height < max_tower_height )//наша башня построена, а у врага нет + { + winner = 1;//победил игрок 1(мы) + victory_type = 0; + } + else if ( am_Players[0].tower_height >= max_tower_height && am_Players[1].tower_height >= max_tower_height )//и у нас, и у врага построена + { + if ( am_Players[0].tower_height == am_Players[1].tower_height )//наши башни равны + { + winner = 0;//никто не победил + victory_type = 4;//ничья + } + else//наши башни не равны + { + winner = (am_Players[0].tower_height <= am_Players[1].tower_height) + 1;//победил тот, у кого выше + victory_type = 0; + } + } + + //проверка разрушена ли башня + if ( am_Players[0].tower_height <= 0 && am_Players[1].tower_height > 0 )//наша башня разрушена, а у врага нет + { + winner = 2;// победил игрок 2(враг) + victory_type = 2;//победил разрушив башню врага + } + else if ( am_Players[0].tower_height > 0 && am_Players[1].tower_height <= 0 )//у врага башня разрушена, а у нас нет + { + winner = 1;//победил игрок 1(мы) + victory_type = 2;//победил разрушив башню врага + } + else if ( am_Players[0].tower_height <= 0 && am_Players[1].tower_height <= 0 )//наша башня разрушена, и у врага разрушена + { + if ( am_Players[0].tower_height == am_Players[1].tower_height )//если башни равны + { + if ( am_Players[0].wall_height == am_Players[1].wall_height )//если стены равны + { + winner = 0; + victory_type = 4; + } + else//если стены не равны + { + winner = (am_Players[0].wall_height <= am_Players[1].wall_height) + 1;//победил тот, у кого стена выше + victory_type = 1;//победа когда больше стена при ничье + } + } + else//башни не равны + { + winner = (am_Players[0].tower_height <= am_Players[1].tower_height) + 1;// побеждает тот у кого башня больше + victory_type = 2;//победил разрушив башню врага + } + } + + //проверка набраны ли ресурсы + //проверка какого ресурса больше всего у игрока 1(нас) + pl_resource = am_Players[0].resource_bricks;//кирпичей больше чем др. ресурсов + if ( am_Players[0].resource_gems > am_Players[0].resource_bricks + && am_Players[0].resource_gems > am_Players[0].resource_beasts )//драг.камней больше всего + pl_resource = am_Players[0].resource_gems; + else if ( am_Players[0].resource_beasts > am_Players[0].resource_gems + && am_Players[0].resource_beasts > am_Players[0].resource_bricks )//зверей больше всего + pl_resource = am_Players[0].resource_beasts; + + //проверка какого ресурса больше у игрока 2(врага) + en_resource = am_Players[1].resource_bricks;//кирпичей больше чем др. ресурсов + if ( am_Players[1].resource_gems > am_Players[1].resource_bricks + && am_Players[1].resource_gems > am_Players[1].resource_beasts )//драг.камней больше всего + en_resource = am_Players[1].resource_gems; + else if ( am_Players[1].resource_beasts > am_Players[1].resource_gems + && am_Players[1].resource_beasts > am_Players[1].resource_bricks )//зверей больше всего + en_resource = am_Players[1].resource_beasts; + + //сравнение ресурсов игроков + if ( winner == -1 && victory_type == -1 )//нет победителя по башням + { + if ( pl_resource < max_resources_amount && en_resource >= max_resources_amount )//враг набрал нужное количество + { + winner = 2;// враг победил + victory_type = 3;//победа собрав нужное количество ресурсов + } + else if ( pl_resource >= max_resources_amount && en_resource < max_resources_amount )//мы набрали нужное количество + { + winner = 1;// мы победили + victory_type = 3;//победа собрав нужное количество ресурсов + } + else if ( pl_resource >= max_resources_amount && en_resource >= max_resources_amount )//и у нас и у врага нужное количество ресурсов + { + if ( pl_resource == en_resource )// ресурсы равны + { + winner = 0;//ресурсы равны + victory_type = 4; //ничья + } + else + { + winner = (pl_resource <= en_resource) + 1;//ресурсы не равны, побеждает тот у кого больше + victory_type = 3;//победа собрав нужное количество ресурсов + } + } + } + else if ( winner == 0 && victory_type == 4 )// при ничье по башням и стене + { + if ( pl_resource != en_resource )//ресурсы не равны + { + winner = (pl_resource <= en_resource) + 1;//победил тот у кого больше + victory_type = 5;//победа когда при ничье большее количество ресурсов + } + else //ресурсы равны + { + winner = 0;//нет победителя + victory_type = 4; //ничья + } + } + + //подведение итогов + pArcomageGame->Victory_type = victory_type; + pArcomageGame->uGameWinner = winner; + if ( winner == 1 )//победитель игрок 1(мы) + { + if (( window_SpeakInHouse->par1C >= 108 ) && ( window_SpeakInHouse->par1C <= 120 ))//таверны + { + if ( !pParty->pArcomageWins[window_SpeakInHouse->par1C - 108] ) + { + pParty->pArcomageWins[window_SpeakInHouse->par1C - 108] = 1; + pParty->PartyFindsGold(p2DEvents[ window_SpeakInHouse->par1C - 1].fPriceMultiplier * 100.0, 0);//вознаграждение + } + } + //проверка выполнен ли квест по аркомагу + tavern_num = 0; + for ( uint i = 108; i <= 120; ++i ) + { + if ( !pParty->pArcomageWins[i - 108] ) + break; + tavern_num++; + } + if ( tavern_num == 13 ) + _449B7E_toggle_bit(pParty->_quest_bits, 238, 1);// 238 - Won all Arcomage games + + for ( int i = 0; i < 4; ++i )//внесение записи в Заслуги + { + if ( !_449B57_test_bit(pParty->pPlayers[i]._achieved_awards_bits, 1) ) + _449B7E_toggle_bit(pParty->pPlayers[i]._achieved_awards_bits, PLAYER_GUILD_BITS__ARCOMAGE_WIN, 1); + } + ++pParty->uNumArcomageWins; + if ( pParty->uNumArcomageWins > 1000000 )//ограничение количества побед + pParty->uNumArcomageWins = 1000000; + } + else//проигрыш + { + for ( int i = 0; i < 4; ++i )//внесение записи в Заслуги + { + if ( !_449B57_test_bit(pParty->pPlayers[i]._achieved_awards_bits, 1) ) + _449B7E_toggle_bit(pParty->pPlayers[i]._achieved_awards_bits, PLAYER_GUILD_BITS__ARCOMAGE_LOSE, 1); + } + ++pParty->uNumArcomageLoses; + if ( pParty->uNumArcomageLoses > 1000000 )//ограничение количества проигрышей + pParty->uNumArcomageLoses = 1000000; + } +} + +//----- (00409C8B) -------------------------------------------------------- +void ArcomageGame::PrepareArcomage() +{ +// signed __int64 v1; // qax@4 + int v2; // esi@4 + int v3; // esi@5 + signed int v4; // edi@5 +// int v6; // edx@9 + RECT pXYZW; // [sp+8h] [bp-1Ch]@5 + POINT pXY; // [sp+18h] [bp-Ch]@5 + + pAudioPlayer->StopChannels(-1, -1); + strcpy(pArcomageGame->pPlayer1Name, Player1Name); + strcpy(pArcomageGame->pPlayer2Name, Player2Name); + am_byte_4FAA76 = 0; + am_byte_4FAA75 = 0; + + for (int i = 0; i < 10; ++i) + { + v2 = (i+1) % 4; + v3 = (i+1) / 4; + shown_cards[i].uCardId = -1; + shown_cards[i].field_4 = 0; + shown_cards[i].field_8.x = 100 * v2 + 120; + shown_cards[i].field_8.y = 138 * v3 + 18; + shown_cards[i].field_10_xplus = -100 * v2 / 5; + shown_cards[i].field_14_y_plus = -138 * v3 / 5; + shown_cards[i].field_18_point.x = shown_cards[i].field_8.x; + shown_cards[i].field_18_point.y = shown_cards[i].field_8.y; + } + + pXY.x = 0; + pXY.y = 0; + ArcomageGame::LoadBackground(); + pXYZW.left = 0; + pXYZW.right = window->GetWidth(); + pXYZW.top = 0; + pXYZW.bottom = window->GetHeight(); + am_BeginScene(pArcomageGame->pBackgroundPixels, -1, 1); + pRenderer->am_Blt_Copy(&pXYZW, &pXY, 2); + am_EndScene(); + pRenderer->Present(); + ArcomageGame::LoadSprites(); + pRenderer->Present(); + + v4 = 120; + for ( int i = 0; i < 12; ++i ) + am_sounds[i] = pSoundList->LoadSound(v4++, 0); + + for (int i = 0; i < 10; ++i) + array_4FABD0[i].field_40 = stru272_stru0::New(); + + current_card_slot_index = -1; + amuint_4FAA4C = -1; + byte_4FAA74 = 0; + pArcomageGame->field_F4 = 0; + am_gameover = false; + byte_505880 = 0; + dword_4FAA70 = 0; + need_to_discard_card = 0; + SetStartGameData(); + InitalHandsFill(); + //nullsub_1(); + pArcomageGame->GameOver = 0; + pArcomageGame->pfntComic = pFontComic; + pArcomageGame->pfntArrus = pFontArrus; +} + +//----- (0040D711) -------------------------------------------------------- +ArcomageGame::ArcomageGame() +{ + field_4 = 0; + //RGBTexture::RGBTexture(&this->pGameBackground); + //RGBTexture::RGBTexture(&v1->pSprites); + bGameInProgress = 0; + field_F9 = 0; +} + +//----- (00409BE8) -------------------------------------------------------- +void SetStartConditions() +{ + const ArcomageStartConditions *st_cond; // eax@1 + + st_cond = &start_conditions[window_SpeakInHouse->par1C - 108]; + start_tower_height = st_cond->tower_height; + start_wall_height = st_cond->wall_height; + start_quarry_level = st_cond->quarry_level - 1; + start_magic_level = st_cond->magic_level - 1; + start_zoo_level = st_cond->zoo_level - 1; + minimum_cards_at_hand = 5; + quarry_bonus = 1; + magic_bonus = 1; + zoo_bonus = 1; + max_tower_height = st_cond->max_tower; + max_resources_amount = st_cond->max_resources; + + opponent_mastery = st_cond->mastery_lvl; + + start_bricks_amount = st_cond->bricks_amount; + start_gems_amount = st_cond->gems_amount; + start_beasts_amount = st_cond->beasts_amount; +} + +//----- (0040D75D) -------------------------------------------------------- +void am_DrawText( int a1, const char *pText, POINT *pXY ) +{ + pPrimaryWindow->DrawText( pFontComic, pXY->x, pXY->y - ((pFontComic->uFontHeight - 3) / 2) + 3, 0, pText, 0, 0, 0); +} + +//----- (0040DB27) -------------------------------------------------------- +void DrawRect( RECT *pXYZW, unsigned __int16 uColor, char bSolidFill ) +{ + pRenderer->BeginScene(); + pRenderer->SetRasterClipRect(0, 0, window->GetWidth() - 1, window->GetHeight() - 1); + if ( bSolidFill ) + { + for ( int i = pXYZW->top; i <= pXYZW->bottom; ++i ) + pRenderer->RasterLine2D(pXYZW->left, i, pXYZW->right, i, uColor); + } + else + { + pRenderer->RasterLine2D(pXYZW->left, pXYZW->top, pXYZW->right, pXYZW->top, uColor); + pRenderer->RasterLine2D(pXYZW->right, pXYZW->top, pXYZW->right, pXYZW->bottom, uColor); + pRenderer->RasterLine2D(pXYZW->right, pXYZW->bottom, pXYZW->left, pXYZW->bottom, uColor); + pRenderer->RasterLine2D(pXYZW->left, pXYZW->bottom, pXYZW->left, pXYZW->top, uColor); + } + pRenderer->EndScene(); +} + +void DrawSquare( POINT *pTargetXY, unsigned __int16 uColor ) +{ + pRenderer->BeginScene(); + //if ( uNumSceneBegins ) + { + if ( pTargetXY->x >= 0 && pTargetXY->x <= window->GetWidth() - 1 + && pTargetXY->y >= 0 && pTargetXY->y <= window->GetHeight() - 1) + { + pRenderer->WritePixel16(pTargetXY->x, pTargetXY->y, uColor); + pRenderer->WritePixel16(pTargetXY->x + 1, pTargetXY->y, uColor); + pRenderer->WritePixel16(pTargetXY->x, pTargetXY->y + 1, uColor); + pRenderer->WritePixel16(pTargetXY->x + 1, pTargetXY->y + 1, uColor); + } + pRenderer->EndScene(); + } +} + +//----- (0040DBD3) -------------------------------------------------------- +void DrawPixel( POINT *pTargetXY, unsigned __int16 uColor ) +{ + pRenderer->BeginScene(); + //if ( pRenderer->uNumSceneBegins ) + { + if ( pTargetXY->x >= 0 && pTargetXY->x <= window->GetWidth() - 1 + && pTargetXY->y >= 0 && pTargetXY->y <= window->GetHeight() - 1) + { + pRenderer->WritePixel16(pTargetXY->x, pTargetXY->y, uColor); + /*int xVal = pTargetXY->x; + int yVal = pTargetXY->y; + if ( xVal >= 0 && xVal <= 639 && yVal >= 0 && yVal <= 479) + { + pRenderer->pTargetSurface[xVal + pRenderer->uTargetSurfacePitch * yVal] = uColor; + }*/ + } + pRenderer->EndScene(); + } +} + +//----- (0040DDB1) -------------------------------------------------------- +int rand_interval( int min, int max ) +{ + return min + rand() % (max - min + 1); +} + +//----- (0040DEC8) -------------------------------------------------------- +void __fastcall am_IntToString(int val, char *pOut) +{ + sprintfex(pOut, "%d", val); +} + +void set_stru1_field_8_InArcomage(int inValue) +{ + switch(inValue) + { + case 91:LOBYTE(pArcomageGame->stru1.field_8) = 123;break; + case 92:LOBYTE(pArcomageGame->stru1.field_8) = 124;break; + case 93:LOBYTE(pArcomageGame->stru1.field_8) = 125;break; + case 96:LOBYTE(pArcomageGame->stru1.field_8) = 126;break; + case 61:LOBYTE(pArcomageGame->stru1.field_8) = 43;break; + case 55:LOBYTE(pArcomageGame->stru1.field_8) = 38;break; + case 56:LOBYTE(pArcomageGame->stru1.field_8) = 42;break; + case 57:LOBYTE(pArcomageGame->stru1.field_8) = 40;break; + case 59:LOBYTE(pArcomageGame->stru1.field_8) = 58;break; + case 54:LOBYTE(pArcomageGame->stru1.field_8) = 94;break; + case 50:LOBYTE(pArcomageGame->stru1.field_8) = 64;break; + case 51:LOBYTE(pArcomageGame->stru1.field_8) = 35;break; + case 52:LOBYTE(pArcomageGame->stru1.field_8) = 36;break; + case 53:LOBYTE(pArcomageGame->stru1.field_8) = 37;break; + case 49:LOBYTE(pArcomageGame->stru1.field_8) = 33;break; + case 39:LOBYTE(pArcomageGame->stru1.field_8) = 34;break; + case 44:LOBYTE(pArcomageGame->stru1.field_8) = 60;break; + case 46:LOBYTE(pArcomageGame->stru1.field_8) = 62;break; + case 47:LOBYTE(pArcomageGame->stru1.field_8) = 63;break; + case 48:LOBYTE(pArcomageGame->stru1.field_8) = 41;break; + default:LOBYTE(pArcomageGame->stru1.field_8) = inValue;break; + } +} \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Arcomage/Arcomage.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Arcomage/Arcomage.h Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,298 @@ +#pragma once +#include "OSAPI.h" + +#include "..\Engine/Graphics/Texture.h" + + + + +/* 272 */ +#pragma pack(push, 1) +struct ArcomageCard +{ + char pCardName[32]; + int slot; + char field_24; + char needed_quarry_level; + char needed_magic_level; + char needed_zoo_level; + char needed_bricks; + char needed_gems; + char needed_beasts; + bool can_be_discarded; + int compare_param; + char field_30; + char draw_extra_card_count; + char to_player_quarry_lvl; + char to_player_magic_lvl; + char to_player_zoo_lvl; + char to_player_bricks; + char to_player_gems; + char to_player_beasts; + char to_player_buildings; + char to_player_wall; + char to_player_tower; + char to_enemy_quarry_lvl; + char to_enemy_magic_lvl; + char to_enemy_zoo_lvl; + char to_enemy_bricks; + char to_enemy_gems; + char to_enemy_beasts; + char to_enemy_buildings; + char to_enemy_wall; + char to_enemy_tower; + char to_pl_enm_quarry_lvl; + char to_pl_enm_magic_lvl; + char to_pl_enm_zoo_lvl; + char to_pl_enm_bricks; + char to_pl_enm_gems; + char to_pl_enm_beasts; + char to_pl_enm_buildings; + char to_pl_enm_wall; + char to_pl_enm_tower; + char field_4D; + char can_draw_extra_card2; + char to_player_quarry_lvl2; + char to_player_magic_lvl2; + char to_player_zoo_lvl2; + char to_player_bricks2; + char to_player_gems2; + char to_player_beasts2; + char to_player_buildings2; + char to_player_wall2; + char to_player_tower2; + char to_enemy_quarry_lvl2; + char to_enemy_magic_lvl2; + char to_enemy_zoo_lvl2; + char to_enemy_bricks2; + char to_enemy_gems2; + char to_enemy_beasts2; + char to_enemy_buildings2; + char to_enemy_wall2; + char to_enemy_tower2; + char to_pl_enm_quarry_lvl2; + char to_pl_enm_magic_lvl2; + char to_pl_enm_zoo_lvl2; + char to_pl_enm_bricks2; + char to_pl_enm_gems2; + char to_pl_enm_beasts2; + char to_pl_enm_buildings2; + char to_pl_enm_wall2; + char to_pl_enm_tower2; + char field_6A; + char field_6B; +}; +#pragma pack(pop) + + +/* 401 */ +#pragma pack(push, 1) +struct AcromageCardOnTable +{ + int uCardId; + int field_4; + POINT field_8; + int field_10_xplus; + int field_14_y_plus; + POINT field_18_point; +}; +#pragma pack(pop) + + +#pragma pack(push, 1) +struct ArcomagePlayer +{ + char pPlayerName[32]; + int IsHisTurn; + int tower_height; + int wall_height; + int quarry_level; + int magic_level; + int zoo_level; + int resource_bricks; + int resource_gems; + int resource_beasts; + int cards_at_hand[10]; + POINT card_shift[10]; +}; +#pragma pack(pop) + + + +#pragma pack(push, 1) +struct ArcomageGame_stru1 +{ + int field_0; + int field_4; + int field_8; +}; +#pragma pack(pop) + + + + +#pragma pack(push, 1) +struct ArcomageGame +{ + ArcomageGame(); + + static bool LoadBackground(); + static bool LoadSprites(); + static bool MsgLoop(int a1, ArcomageGame_stru1 *a2); + static void PlaySound(unsigned int event_id); + static void OnMouseClick(char right_left, bool bDown); + static void OnMouseMove(int x, int y); + static void GetCardRect(unsigned int uCardID, RECT *pCardRect); + static void PrepareArcomage(); + static void DoBlt_Copy(unsigned __int16 *pPixels); // idb + + static void Loop(); + + char field_0; + char field_1; + char field_2; + char field_3; + int field_4; + ArcomageGame_stru1 stru1; + tagMSG msg; + int mouse_x; + int mouse_y; + char mouse_left; + char field_39; + char mouse_right; + char field_3B; + unsigned __int16 *pBackgroundPixels; + unsigned __int16 *pSpritesPixels; + unsigned __int16 *pBlit_Copy_pixels; + struct GUIFont *pfntComic;//ptr_48; + struct GUIFont *pfntArrus;//ptr_4C; + int field_50; + int field_54; + RGBTexture pGameBackground; + RGBTexture pSprites; + int event_timer_time; + int uGameWinner; + int Victory_type; + char pPlayer1Name[32]; + char pPlayer2Name[32]; + char field_F4; + char GameOver; + char field_F6; + char prev_mouse_left; + char prev_mouse_right; + char field_F9; + char bGameInProgress; +}; +#pragma pack(pop) + + + + +extern ArcomageGame *pArcomageGame; +extern ArcomageCard pCards[87]; +extern void set_stru1_field_8_InArcomage(int inValue); + + + +#pragma pack(push, 1) +struct stru272_stru1 +{ + int have_spark; + POINT spark_position; + int field_C; + int field_10; + int field_14; + int field_18; +}; +#pragma pack(pop) + +/* 404 */ +#pragma pack(push, 1) +struct stru272_stru2 +{ +/*int field_0; +int field_4; +int field_8; +int field_C;*/ + RECT effect_area; + int field_10; + int field_14; + int field_18; + float field_1Cf; + int field_20; + float field_24f; + float field_28f; + float field_2Cf; + int field_30; + int field_34; + stru272_stru1* sparks_array; +}; +#pragma pack(pop) + + +/* 270 */ +#pragma pack(push, 1) +struct stru272_stru0 // ARCOMAGE stuff +{ + static stru272_stru0 *New(); + + int Free(); + int StartFill(stru272_stru2* a2); + int Clear(char a2, char a3); + int DrawEffect(); + int _40E2A7(); + + int signature; + int field_4; + int position_in_sparks_arr; + int field_C; + int field_10; + int field_14; + int field_18; + int field_1C; + int field_20; + int field_24; + float field_28; + float field_2C; + float field_30; + int field_34; + int field_38; + int field_3C; + int field_40; + int field_44; + int field_48; + int field_4C; + int field_50; + stru272_stru1 * field_54; + char field_58; + char field_59; + char field_5A; + char field_5B; +}; +#pragma pack(pop) + +#define DECK_SIZE 108 + +#pragma pack(push, 1) +struct ArcomageDeck +{ + char name[32]; + char cardsInUse[DECK_SIZE]; + int cards_IDs[DECK_SIZE]; +}; + +#pragma pack(pop) + +#pragma pack(push, 1) +struct stru272 +{ + char have_effect; + char effect_sign; + char _pad_2; + char _pad_3; + stru272_stru2 field_4; + stru272_stru0 *field_40; + stru272_stru1 effect_sparks[150]; +}; +#pragma pack(pop) + diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Arcomage/ArcomageCards.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Arcomage/ArcomageCards.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,357 @@ +#define _CRTDBG_MAP_ALLOC +#include +#include + +#define _CRT_SECURE_NO_WARNINGS + +#include "Arcomage.h" +ArcomageCard pCards[87] = +{ + {"Brick Shortage", + 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Lucky Cache", + 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Friendly Terrain", + 2, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Miners", + 3, 1, 0, 0, 0, 3, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Mother Lode", + 4, 1, 0, 0, 0, 4, 0, 0, 1, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Dwarven Miners", + 5, 1, 0, 0, 0, 7, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Work Overtime", + 6, 1, 0, 0, 0, 2, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, -6, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Copping the Tech", + 7, 1, 0, 0, 0, 5, 0, 0, 1, 2, 0, 0, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Basic Wall", + 8, 1, 0, 0, 0, 2, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Sturdy Wall", + 9, 1, 0, 0, 0, 3, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Innovations", + 10, 1, 0, 0, 0, 2, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Foundations", + 11, 1, 0, 0, 0, 3, 0, 0, 1, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Tremors", + 12, 1, 0, 0, 0, 7, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Secret Room", + 13, 1, 0, 0, 0, 8, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Earthquake", + 14, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Big Wall", + 15, 1, 0, 0, 0, 5, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Collapse!", + 16, 1, 0, 0, 0, 4, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"New Equipment", + 17, 1, 0, 0, 0, 6, 0, 0, 1, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Strip Mine", + 18, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, -1, 0, 0, 0, 5, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Reinforced Wall", + 19, 1, 0, 0, 0, 8, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Porticulus", + 20, 1, 0, 0, 0, 9, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Crystal Rocks", + 21, 1, 0, 0, 0, 9, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Harmonic Ore", + 22, 1, 0, 0, 0, 11, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Mondo Wall", + 23, 1, 0, 0, 0, 13, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Focused Designs", + 24, 1, 0, 0, 0, 15, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Great Wall", + 25, 1, 0, 0, 0, 16, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Rock Launcer", + 26, 1, 0, 0, 0, 18, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, -10, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Dragon's Heart", + 27, 1, 0, 0, 0, 24, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Quartz", + 30, 2, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Smoky Quartz", + 31, 2, 0, 0, 0, 0, 2, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Amethyst", + 32, 2, 0, 0, 0, 0, 2, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Spell Weavers", + 33, 2, 0, 0, 0, 0, 3, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Prism", + 34, 2, 0, 0, 0, 0, 2, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Lodestone", + 35, 2, 0, 0, 0, 0, 5, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Solar Flare", + 36, 2, 0, 0, 0, 0, 4, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, + -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Crystal Matrix", + 37, 2, 0, 0, 0, 0, 6, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Gemstone Flaw", + 38, 2, 0, 0, 0, 0, 2, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Ruby", + 39, 2, 0, 0, 0, 0, 3, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Gem Spear", + 40, 2, 0, 0, 0, 0, 4, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Power Burn", + 41, 2, 0, 0, 0, 0, 3, 0, 1, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, -5, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Harmonic Vibe", + 42, 2, 0, 0, 0, 0, 7, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Parity", + 43, 2, 0, 0, 0, 0, 7, 0, 1, 3, 0, 0, 0, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Emerald", + 44, 2, 0, 0, 0, 0, 6, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Pearl of Wisdom", + 45, 2, 0, 0, 0, 0, 9, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Shatter", + 46, 2, 0, 0, 0, 0, 8, 0, 1, 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Crumblestone", + 47, 2, 0, 0, 0, 0, 7, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, -6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Sapphire", + 48, 2, 0, 0, 0, 0, 10, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Discord", + 49, 2, 0, 0, 0, 0, 5, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1, 0, 0, 0, 0, 0, 0, -7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Fire Ruby", + 50, 2, 0, 0, 0, 0, 13, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, + -4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Quarry's Help", + 51, 2, 0, 0, 0, 0, 4, 0, 1, 1, 0, 0, 0, 0, 0, -10, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Crystal Shield", + 52, 2, 0, 0, 0, 0, 12, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Empathy Gem", + 53, 2, 0, 0, 0, 0, 14, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Diamond", + 54, 2, 0, 0, 0, 0, 16, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Sanctuary", + 55, 2, 0, 0, 0, 0, 15, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 10, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Lava Jewel", + 56, 2, 0, 0, 0, 0, 17, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, -6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Dragon's Eye", + 57, 2, 0, 0, 0, 0, 21, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Mad Cow Disease", + 60, 3, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Faerie", + 61, 3, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Moody Goblins", + 62, 3, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Husbandry", + 63, 3, 0, 0, 0, 0, 0, 3, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Elvin Scout", + 64, 3, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Goblin Mob", + 65, 3, 0, 0, 0, 0, 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, 0, 0, 0, 0, -6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Goblin Archers", + 66, 3, 0, 0, 0, 0, 0, 4, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Shadow Faerie", + 67, 3, 0, 0, 0, 0, 0, 6, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Orc", + 68, 3, 0, 0, 0, 0, 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Dwarves", + 69, 3, 0, 0, 0, 0, 0, 5, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, -4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Little Snakes", + 70, 3, 0, 0, 0, 0, 0, 6, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Troll Keepers", + 71, 3, 0, 0, 0, 0, 0, 7, 1, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Tower Gremlins", + 72, 3, 0, 0, 0, 0, 0, 8, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 0, 0, 0, 0, 0, 0, + -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Full Moon", + 73, 3, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Slasher", + 74, 3, 0, 0, 0, 0, 0, 5, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Ogre", + 75, 3, 0, 0, 0, 0, 0, 6, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Rabid Sheep", + 76, 3, 0, 0, 0, 0, 0, 6, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, + -6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Imp", + 77, 3, 0, 0, 0, 0, 0, 5, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -6, 0, 0, 0, + 0, 0, -5, -5, -5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Spizzer", + 78, 3, 0, 0, 0, 0, 0, 8, 1, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -10, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Werewolf", + 79, 3, 0, 0, 0, 0, 0, 9, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Corrosion Cloud", + 80, 3, 0, 0, 0, 0, 0, 11, 1, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Unicorn", + 81, 3, 0, 0, 0, 0, 0, 9, 1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -12, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Elvin Archers", + 82, 3, 0, 0, 0, 0, 0, 10, 1, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, -6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Succubus", + 83, 3, 0, 0, 0, 0, 0, 14, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -8, 0, 0, + -5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Rock Stompers", + 84, 3, 0, 0, 0, 0, 0, 11, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, + -8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Thief", + 85, 3, 0, 0, 0, 0, 0, 12, 1, 1, 0, 0, 0, 0, 0, 3, 5, 0, 0, 0, 0, 0, 0, 0, -5, -10, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Stone Giant", + 86, 3, 0, 0, 0, 0, 0, 15, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, -10, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Vampire", + 87, 3, 0, 0, 0, 0, 0, 17, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, -5, -10, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Dragon", + 88, 3, 0, 0, 0, 0, 0, 25, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -10, 0, -20, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Forced Labor", + 28, 1, 0, 0, 0, 7, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, -5, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + {"Crystallize", + 58, 2, 0, 0, 0, 0, 8, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -6, 11, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + }; \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 ArcomageCards.cpp --- a/ArcomageCards.cpp Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,357 +0,0 @@ -#define _CRTDBG_MAP_ALLOC -#include -#include - -#define _CRT_SECURE_NO_WARNINGS - -#include "Arcomage.h" -ArcomageCard pCards[87] = -{ - {"Brick Shortage", - 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, -8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Lucky Cache", - 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Friendly Terrain", - 2, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Miners", - 3, 1, 0, 0, 0, 3, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Mother Lode", - 4, 1, 0, 0, 0, 4, 0, 0, 1, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Dwarven Miners", - 5, 1, 0, 0, 0, 7, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Work Overtime", - 6, 1, 0, 0, 0, 2, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, -6, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Copping the Tech", - 7, 1, 0, 0, 0, 5, 0, 0, 1, 2, 0, 0, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Basic Wall", - 8, 1, 0, 0, 0, 2, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Sturdy Wall", - 9, 1, 0, 0, 0, 3, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Innovations", - 10, 1, 0, 0, 0, 2, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Foundations", - 11, 1, 0, 0, 0, 3, 0, 0, 1, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Tremors", - 12, 1, 0, 0, 0, 7, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, -5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Secret Room", - 13, 1, 0, 0, 0, 8, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Earthquake", - 14, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Big Wall", - 15, 1, 0, 0, 0, 5, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Collapse!", - 16, 1, 0, 0, 0, 4, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"New Equipment", - 17, 1, 0, 0, 0, 6, 0, 0, 1, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Strip Mine", - 18, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, -1, 0, 0, 0, 5, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Reinforced Wall", - 19, 1, 0, 0, 0, 8, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Porticulus", - 20, 1, 0, 0, 0, 9, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Crystal Rocks", - 21, 1, 0, 0, 0, 9, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Harmonic Ore", - 22, 1, 0, 0, 0, 11, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Mondo Wall", - 23, 1, 0, 0, 0, 13, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Focused Designs", - 24, 1, 0, 0, 0, 15, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 5, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Great Wall", - 25, 1, 0, 0, 0, 16, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Rock Launcer", - 26, 1, 0, 0, 0, 18, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, -10, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Dragon's Heart", - 27, 1, 0, 0, 0, 24, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 8, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Quartz", - 30, 2, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Smoky Quartz", - 31, 2, 0, 0, 0, 0, 2, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Amethyst", - 32, 2, 0, 0, 0, 0, 2, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Spell Weavers", - 33, 2, 0, 0, 0, 0, 3, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Prism", - 34, 2, 0, 0, 0, 0, 2, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Lodestone", - 35, 2, 0, 0, 0, 0, 5, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Solar Flare", - 36, 2, 0, 0, 0, 0, 4, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, - -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Crystal Matrix", - 37, 2, 0, 0, 0, 0, 6, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Gemstone Flaw", - 38, 2, 0, 0, 0, 0, 2, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Ruby", - 39, 2, 0, 0, 0, 0, 3, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Gem Spear", - 40, 2, 0, 0, 0, 0, 4, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Power Burn", - 41, 2, 0, 0, 0, 0, 3, 0, 1, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, -5, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Harmonic Vibe", - 42, 2, 0, 0, 0, 0, 7, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Parity", - 43, 2, 0, 0, 0, 0, 7, 0, 1, 3, 0, 0, 0, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Emerald", - 44, 2, 0, 0, 0, 0, 6, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Pearl of Wisdom", - 45, 2, 0, 0, 0, 0, 9, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Shatter", - 46, 2, 0, 0, 0, 0, 8, 0, 1, 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Crumblestone", - 47, 2, 0, 0, 0, 0, 7, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, -6, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Sapphire", - 48, 2, 0, 0, 0, 0, 10, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Discord", - 49, 2, 0, 0, 0, 0, 5, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -1, 0, 0, 0, 0, 0, 0, -7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Fire Ruby", - 50, 2, 0, 0, 0, 0, 13, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, - -4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Quarry's Help", - 51, 2, 0, 0, 0, 0, 4, 0, 1, 1, 0, 0, 0, 0, 0, -10, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Crystal Shield", - 52, 2, 0, 0, 0, 0, 12, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 8, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Empathy Gem", - 53, 2, 0, 0, 0, 0, 14, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Diamond", - 54, 2, 0, 0, 0, 0, 16, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Sanctuary", - 55, 2, 0, 0, 0, 0, 15, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 10, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Lava Jewel", - 56, 2, 0, 0, 0, 0, 17, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, -6, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Dragon's Eye", - 57, 2, 0, 0, 0, 0, 21, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Mad Cow Disease", - 60, 3, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Faerie", - 61, 3, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Moody Goblins", - 62, 3, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Husbandry", - 63, 3, 0, 0, 0, 0, 0, 3, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Elvin Scout", - 64, 3, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Goblin Mob", - 65, 3, 0, 0, 0, 0, 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, 0, 0, 0, 0, -6, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Goblin Archers", - 66, 3, 0, 0, 0, 0, 0, 4, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, -3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Shadow Faerie", - 67, 3, 0, 0, 0, 0, 0, 6, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Orc", - 68, 3, 0, 0, 0, 0, 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -5, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Dwarves", - 69, 3, 0, 0, 0, 0, 0, 5, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, -4, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Little Snakes", - 70, 3, 0, 0, 0, 0, 0, 6, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Troll Keepers", - 71, 3, 0, 0, 0, 0, 0, 7, 1, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Tower Gremlins", - 72, 3, 0, 0, 0, 0, 0, 8, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 0, 0, 0, 0, 0, 0, - -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Full Moon", - 73, 3, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Slasher", - 74, 3, 0, 0, 0, 0, 0, 5, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -6, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Ogre", - 75, 3, 0, 0, 0, 0, 0, 6, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -7, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Rabid Sheep", - 76, 3, 0, 0, 0, 0, 0, 6, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, - -6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Imp", - 77, 3, 0, 0, 0, 0, 0, 5, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -6, 0, 0, 0, - 0, 0, -5, -5, -5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Spizzer", - 78, 3, 0, 0, 0, 0, 0, 8, 1, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -10, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Werewolf", - 79, 3, 0, 0, 0, 0, 0, 9, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -9, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Corrosion Cloud", - 80, 3, 0, 0, 0, 0, 0, 11, 1, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Unicorn", - 81, 3, 0, 0, 0, 0, 0, 9, 1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -12, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Elvin Archers", - 82, 3, 0, 0, 0, 0, 0, 10, 1, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, -6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Succubus", - 83, 3, 0, 0, 0, 0, 0, 14, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -8, 0, 0, - -5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Rock Stompers", - 84, 3, 0, 0, 0, 0, 0, 11, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, - -8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Thief", - 85, 3, 0, 0, 0, 0, 0, 12, 1, 1, 0, 0, 0, 0, 0, 3, 5, 0, 0, 0, 0, 0, 0, 0, -5, -10, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Stone Giant", - 86, 3, 0, 0, 0, 0, 0, 15, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, -10, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Vampire", - 87, 3, 0, 0, 0, 0, 0, 17, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, -5, -10, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Dragon", - 88, 3, 0, 0, 0, 0, 0, 25, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -10, 0, -20, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Forced Labor", - 28, 1, 0, 0, 0, 7, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, -5, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - - {"Crystallize", - 58, 2, 0, 0, 0, 0, 8, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -6, 11, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - }; \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 AudioPlayer.cpp --- a/AudioPlayer.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/AudioPlayer.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -10,19 +10,19 @@ #include "MediaPlayer.h" #include "AudioPlayer.h" #include "FrameTableInc.h" -#include "Indoor.h" +#include "Engine/Graphics/Indoor.h" #include "SpriteObject.h" #include "Party.h" #include "Actor.h" #include "Game.h" -#include "DecorationList.h" +#include "Engine/Graphics/DecorationList.h" #include "Timer.h" #include "OurMath.h" #include "MapInfo.h" #include "GUIWindow.h" #include "Log.h" #include "ErrorHandling.h" -#include "Level/Decoration.h" +#include "Engine/Graphics/Level/Decoration.h" #include "Registry.h" #include "Bink_Smacker.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 BSPModel.cpp --- a/BSPModel.cpp Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -#define _CRTDBG_MAP_ALLOC -#include -#include - -#define _CRT_SECURE_NO_WARNINGS -#include - -#include "BSPModel.h" - - - -//----- (00478389) -------------------------------------------------------- -void BSPModel::Release() -{ - free(this->pVertices.pVertices); - this->pVertices.pVertices = 0; - free(this->pFaces); - this->pFaces = nullptr; - free(this->pFacesOrdering); - this->pFacesOrdering = nullptr; - free(this->pNodes); - this->pNodes = nullptr; - this->uNumNodes = 0; - this->uNumFaces = 0; - this->pVertices.uNumVertices = 0; - this->uNumConvexFaces = 0; -} diff -r 7b076fe64f23 -r 5abd8fc8f1c6 BSPModel.h --- a/BSPModel.h Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -#pragma once -#include "VectorTypes.h" - - -#pragma pack(push, 1) -struct BSPNode //8 -{ - __int16 uFront; - __int16 uBack; - __int16 uCoplanarOffset; - __int16 uCoplanarSize; -}; -#pragma pack(pop) - - -#pragma pack(push, 1) -struct BSPVertexBuffer -{ - int uNumVertices; - Vec3_int_ *pVertices; -}; -#pragma pack(pop) - - - -/* 80 */ -#pragma pack(push, 1) -struct BSPModel -{ - void Release(); - - - char pModelName[32]; - char pModelName2[32]; - int field_40; - struct BSPVertexBuffer pVertices; - int uNumFaces; - unsigned int uNumConvexFaces; - struct ODMFace *pFaces; - unsigned __int16 *pFacesOrdering; - unsigned int uNumNodes; - struct BSPNode *pNodes; - unsigned int uNumDecorations; - int sCenterX; - int sCenterY; - Vec3_int_ vPosition; - int sMinX; - int sMinY; - int sMinZ; - int sMaxX; - int sMaxY; - int sMaxZ; - int sSomeOtherMinX; - int sSomeOtherMinY; - int sSomeOtherMinZ; - int sSomeOtherMaxX; - int sSomeOtherMaxY; - int sSomeOtherMaxZ; - Vec3_int_ vBoundingCenter; - int sBoundingRadius; -}; -#pragma pack(pop) diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Build/Visual Studio 2010/World of Might and Magic.vcxproj --- a/Build/Visual Studio 2010/World of Might and Magic.vcxproj Wed Sep 17 17:35:13 2014 +0600 +++ b/Build/Visual Studio 2010/World of Might and Magic.vcxproj Thu Sep 18 17:38:54 2014 +0600 @@ -88,31 +88,46 @@ - - + + - - - + + + + + + + + + + + + + + + + + + + + + + - - - - @@ -174,8 +189,6 @@ - - @@ -194,10 +207,6 @@ - - - - @@ -206,19 +215,13 @@ - - - - - - @@ -241,44 +244,57 @@ - - - - + - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - @@ -420,8 +436,6 @@ - - @@ -443,26 +457,17 @@ - - - - - - - - - @@ -470,10 +475,8 @@ - - @@ -481,9 +484,6 @@ - - - diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Build/Visual Studio 2010/World of Might and Magic.vcxproj.filters --- a/Build/Visual Studio 2010/World of Might and Magic.vcxproj.filters Wed Sep 17 17:35:13 2014 +0600 +++ b/Build/Visual Studio 2010/World of Might and Magic.vcxproj.filters Thu Sep 18 17:38:54 2014 +0600 @@ -291,72 +291,6 @@ - - Arcomage - - - Arcomage - - - Engine\Graphics\Level - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - Engine\TurnEngine @@ -564,13 +498,79 @@ GUI\UI\Books - + + + Arcomage + + + Arcomage + + + Engine\Graphics\Level + + + Engine\Graphics + + + Engine\Graphics + + + Engine\Graphics + + + Engine\Graphics + + + Engine\Graphics + + + Engine\Graphics + + + Engine\Graphics + + + Engine\Graphics + + Engine\Graphics - + + Engine\Graphics + + + Engine\Graphics + + + Engine\Graphics + + + Engine\Graphics + + + Engine\Graphics + + Engine\Graphics - + + Engine\Graphics + + + Engine\Graphics + + + Engine\Graphics + + + Engine\Graphics + + + Engine\Graphics + + + Engine\Graphics + @@ -999,75 +999,6 @@ - - Arcomage - - - Engine\Graphics\Level - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - - - Engine\Graphics - Engine\TurnEngine @@ -1266,14 +1197,83 @@ GUI\UI - + + + + Arcomage + + + Engine\Graphics\Level + + + Engine\Graphics + + + Engine\Graphics + + + Engine\Graphics + + + Engine\Graphics + + + Engine\Graphics + + + Engine\Graphics + + + Engine\Graphics + + + Engine\Graphics + + + Engine\Graphics + + Engine\Graphics - + + Engine\Graphics + + + Engine\Graphics + + + Engine\Graphics + + + Engine\Graphics + + + Engine\Graphics + + Engine\Graphics - - + + Engine\Graphics + + + Engine\Graphics + + + Engine\Graphics + + + Engine\Graphics + + + Engine\Graphics + + + Engine\Graphics + + + Engine\Graphics + diff -r 7b076fe64f23 -r 5abd8fc8f1c6 CastSpellInfo.cpp --- a/CastSpellInfo.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/CastSpellInfo.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -12,10 +12,10 @@ #include "Game.h" #include "GUIWindow.h" #include "AudioPlayer.h" -#include "Outdoor.h" -#include "Overlays.h" +#include "Engine/Graphics/Outdoor.h" +#include "Engine/Graphics/Overlays.h" #include "Events.h" -#include "Viewport.h" +#include "Engine/Graphics/Viewport.h" #include "OurMath.h" #include "SpriteObject.h" #include "ObjectList.h" @@ -26,7 +26,7 @@ #include "TurnEngine.h" #include "texts.h" #include "LOD.h" -#include "Level/Decoration.h" +#include "Engine/Graphics/Level/Decoration.h" #include "UI\UIPartyCreation.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Chest.cpp --- a/Chest.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/Chest.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -13,8 +13,8 @@ #include "LOD.h" #include "MapInfo.h" #include "Actor.h" -#include "Outdoor.h" -#include "DecorationList.h" +#include "Engine/Graphics/Outdoor.h" +#include "Engine/Graphics/DecorationList.h" #include "Party.h" #include "AudioPlayer.h" #include "OurMath.h" @@ -26,8 +26,8 @@ #include "MM7.h" #include "SpriteObject.h" #include "Mouse.h" -#include "Viewport.h" -#include "Level/Decoration.h" +#include "Engine/Graphics/Viewport.h" +#include "Engine/Graphics/Level/Decoration.h" size_t uNumChests; // idb struct ChestList *pChestList; diff -r 7b076fe64f23 -r 5abd8fc8f1c6 DecalBuilder.cpp --- a/DecalBuilder.cpp Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,656 +0,0 @@ -#define _CRTDBG_MAP_ALLOC -#include -#include - -#define _CRT_SECURE_NO_WARNINGS -#include "DecalBuilder.h" -#include "Game.h" -#include "Timer.h" -#include "stru314.h" -#include "Outdoor.h" -#include "Log.h" - -#include "stru9.h" - -#include "OurMath.h" - - -struct DecalBuilder *pDecalBuilder = new DecalBuilder; -struct BloodsplatContainer *pBloodsplatContainer = new BloodsplatContainer; - - -//----- (0043B570) -------------------------------------------------------- -double DecalBuilder_stru0::_43B570_get_color_mult_by_time() -{ - double result; // st7@3 - - if (field_1C_flags & 1) - { - if ((field_20_time - pEventTimer->Time() + 384) / 384.0 >= 0.0) - result = (field_20_time - pEventTimer->Time() + 384) / 384.0; - else - result = 0.0; - } - else - result = 1.0; - return result; -} - -//----- (0043B6EF) -------------------------------------------------------- -void BloodsplatContainer::AddBloodsplat(float x, float y, float z, float radius, unsigned char r, unsigned char g, unsigned char b) -{ - int i = this->uNumBloodsplats; - if ( this->uNumBloodsplats == 64 ) - i = 0; - this->std__vector_pBloodsplats[i].x = x; - this->std__vector_pBloodsplats[i].y = y; - this->std__vector_pBloodsplats[i].z = z; - this->std__vector_pBloodsplats[i].radius = radius; - this->std__vector_pBloodsplats[i].r = r; - this->std__vector_pBloodsplats[i].g = g; - this->std__vector_pBloodsplats[i].b = b; - this->std__vector_pBloodsplats_size = min(this->std__vector_pBloodsplats_size + 1, 64); -} - -//----- (0049B490) -------------------------------------------------------- -void DecalBuilder::AddBloodsplat(float x, float y, float z, float r, float g, float b, float radius, int a8, int a9) -{ - //double v10; // ST1C_8@1 -// char v11; // ST24_1@1 - //double v12; // ST1C_8@1 - //double v13; // ST1C_8@1 -// int a7a; // [sp+40h] [bp+18h]@1 - //float arg14a; // [sp+44h] [bp+1Ch]@1 - //float arg14b; // [sp+44h] [bp+1Ch]@1 - //float arg14c; // [sp+44h] [bp+1Ch]@1 - - /*arg14a = b * 255.0; - v10 = arg14a + 6.7553994e15; - v11 = LOBYTE(v10); - arg14b = g * 255.0; - v12 = arg14b + 6.7553994e15; - a7a = LODWORD(v12); - arg14c = r * 255.0; - v13 = arg14c + 6.7553994e15;*/ - pBloodsplatContainer->AddBloodsplat(x, y, z, radius, - //SLOBYTE(v13), a7a, v11); - bankersRounding(r * 255.0f), - bankersRounding(g * 255.0f), - bankersRounding(b * 255.0f)); -} - -//----- (0049B525) -------------------------------------------------------- -void DecalBuilder::Reset(unsigned int bPreserveBloodsplats) -{ - if ( !bPreserveBloodsplats ) - { - pBloodsplatContainer->std__vector_pBloodsplats_size = 0; - pBloodsplatContainer->uNumBloodsplats = 0; - } - std__vector_pDecals_size = 0; -} - -//----- (0049B540) -------------------------------------------------------- -char DecalBuilder::ApplyDecals(int light_level, char a3, stru154 *a4, int a5, RenderVertexSoft *a6, IndoorCameraD3D_Vec4 *a7, char a8, unsigned int uSectorID) -{ - //char *v9; // eax@3 - //signed int v10; // ecx@3 - //RenderVertexSoft *v11; // eax@10 - //unsigned int v12; // edx@10 - //RenderVertexSoft *v13; // esi@11 - //RenderVertexSoft *v14; // edi@11 - //char v15; // zf@11 - stru154 *v16; // esi@12 - //double v18; // st7@17 - //double v19; // st6@17 - //float v20; // eax@17 - //Bloodsplat *v21; // esi@21 - //int v22; // eax@21 - //int v23; // ecx@21 - //double v24; // st7@21 - int v25; // ebx@21 - //double v26; // st7@21 - //int v27; // edi@21 - //double v28; // st7@21 - //float v29; // ST10_4@21 -// int v30; // ST08_4@21 - //DecalBuilder *v31; // esi@21 - //int v32; // [sp+4h] [bp-44h]@18 - //float v33; // [sp+8h] [bp-40h]@21 - //stru314 *v34; // [sp+Ch] [bp-3Ch]@21 - //float v35; // [sp+10h] [bp-38h]@21 - //float v36; // [sp+14h] [bp-34h]@17 - //int v37; // [sp+18h] [bp-30h]@17 - //int a5a; // [sp+28h] [bp-20h]@21 - //int v39; // [sp+2Ch] [bp-1Ch]@21 - //int v40; // [sp+30h] [bp-18h]@21 - //int v41; // [sp+34h] [bp-14h]@22 - //int v42; // [sp+38h] [bp-10h]@21 - int v43; // [sp+3Ch] [bp-Ch]@21 - //DecalBuilder *thisa; // [sp+40h] [bp-8h]@1 - //RenderVertexSoft *a11; // [sp+44h] [bp-4h]@8 -// int a6a; - //int *a6b; - - -// __debugbreak(); - - //auto a2 = light_level; - //auto a9 = uSectorID; - - //thisa = this; - if ( !a5 ) - return 0; - - static RenderVertexSoft static_AE4F90[64]; - static bool __init_flag1 = false; - if (!__init_flag1) - { - __init_flag1 = true; - - for (uint i = 0; i < 64; ++i) - static_AE4F90[i].flt_2C = 0.0f; - } - - static stru314 static_AE4F60; // idb - /*static bool __init_flag2 = false; - if (!__init_flag2) - { - __init_flag2 = true; - - stru314::stru314(&static_AE4F60); - }*/ - - //a11 = a6; - if ( a7 ) - { - for(int i=0; i < a5;i++) - { - memcpy(&static_AE4F90[i], a6, 0x30u); - ++a6; - } - v16 = a4; - if ( pGame->pIndoorCameraD3D->_437376(a4, static_AE4F90, (unsigned int *)&a5) == 1 ) - { - if ( !a5 ) - return 0; - a6 = static_AE4F90; - } - } - else - v16 = a4; - //v18 = v16->face_plane.vNormal.z; - //v19 = v16->face_plane.vNormal.y; - //v20 = v16->face_plane.vNormal.x; - //v37 = (int)&static_AE4F60.field_1C; - static_AE4F60.field_4.y = v16->face_plane.vNormal.y; - static_AE4F60.field_4.x = v16->face_plane.vNormal.x; - //LODWORD(v36) = (DWORD)&static_AE4F60.field_10; - static_AE4F60.field_4.z = v16->face_plane.vNormal.z; - static_AE4F60.dist = v16->face_plane.dist; - if ( !pGame->pIndoorCameraD3D->GetFacetOrientation(v16->polygonType, &static_AE4F60.field_4, - &static_AE4F60.field_10, &static_AE4F60.field_1C) ) - MessageBoxW(nullptr, L"Error: Failed to get the facet orientation", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\PolyProjector.cpp:101", 0); - - if ( this->uNumDecals > 0 ) - { - //a6b = this->std__vector_30B00C; - for ( int i = 0; i < this->uNumDecals; ++i ) - { - //v21 = &pBloodsplatContainer->std__vector_pBloodsplats[*a6b]; - int point_light_level = _43F5C8_get_point_light_level_with_respect_to_lights(light_level, uSectorID, - pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].x, - pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].y, - pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].z); - //v23 = pBloodsplatContainer->std__vector_pBloodsplats[*a6b].b; - //v24 = pBloodsplatContainer->std__vector_pBloodsplats[*a6b].x; - //v42 = v22; - //BYTE3(v22) = 0; - //*(short *)((char *)&v22 + 1) = pBloodsplatContainer->std__vector_pBloodsplats[*a6b].r; - //LOBYTE(v22) = pBloodsplatContainer->std__vector_pBloodsplats[*a6b].g; - v43 = pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].b | - ((unsigned int)pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].g << 8) | - ((unsigned int)pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].r << 16); - v25 = (signed __int64)pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].x; - //v27 = (signed __int64)pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].y; - //v37 = a8; - //v40 = (signed __int64)pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].z; - //v28 = pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].dot_dist; - //LODWORD(v36) = (uint32)a6; - //a5a = v25; - //v39 = v27; - //LODWORD(v35) = a5; - //v34 = &static_AE4F60; - //v33 = v28; - //v32 = pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].b | (v22 << 8); - //v29 = pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].radius; - //v30 = (int)v21; - //v31 = thisa; - if ( !this->_49B790_build_decal_geometry(point_light_level, a3, - &pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]], - (int)&v25, - pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].radius, - v43, - pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].dot_dist, - &static_AE4F60, a5, a6, a8) ) - MessageBoxW(nullptr, L"Error: Failed to build decal geometry", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\PolyProjector.cpp:114", 0); - } - } - return 1; -} - -//----- (0049B790) -------------------------------------------------------- -char DecalBuilder::_49B790_build_decal_geometry(int a2, char a3, Bloodsplat *a4, int a5, float a6, unsigned int uColorMultiplier, float a8, stru314 *a9, signed int a10, RenderVertexSoft *a11, char uClipFlags) -{ - //DecalBuilder *v12; // esi@1 - Decal *v13; // edi@2 - //int *v14; // eax@2 - //double v15; // st7@4 - //double v16; // st7@4 - //int v17; // eax@4 - //stru314 *v18; // ebx@4 - //double v19; // st7@4 - //double v20; // st7@4 - //double v21; // st7@4 - //double v22; // st6@4 - //double v23; // st6@4 - //double v24; // st5@4 - //char *v25; // eax@4 - //signed int v26; // ecx@4 - //double v27; // st5@4 - double v28; // st7@5 - //double v29; // st7@6 - char result; // al@6 -// unsigned int *v31; // edi@7 -// RenderVertexSoft *v32; // ebx@8 -// std::string *v33; // ecx@15 - int v34; // eax@19 -// const char *v35; // [sp-Ch] [bp-2Ch]@15 -// int v36; // [sp-8h] [bp-28h]@15 - std::string v37; // [sp-4h] [bp-24h]@15 - //float v38; // [sp+8h] [bp-18h]@6 - //RenderVertexSoft *v39; // [sp+Ch] [bp-14h]@6 - //unsigned int v40; // [sp+10h] [bp-10h]@6 - - //int a6a; - //RenderVertexSoft *a8a; - unsigned int a8b = 0; - - //v12 = this; - if ( a6 == 0.0 ) - return 1; - v13 = &this->std__vector_pDecals[this->field_308008]; - //v14 = &this->std__vector_pDecals[this->field_308008].field_C1C; - this->std__vector_pDecals[this->field_308008].field_C18 = (DecalBuilder_stru0 *)a4; - this->std__vector_pDecals[this->field_308008].field_C1C = 0; - if ( a3 & 2 ) - this->std__vector_pDecals[this->field_308008].field_C1C = 1; - //v15 = a6 - a8; - this->field_30C028 = a6 - a8; - //v16 = sqrt((a6 + a6 - this->field_30C028) * this->field_30C028); - this->field_30C02C = sqrt((a6 + a6 - this->field_30C028) * this->field_30C028); - //v17 = a5; - //v18 = a9; - this->flt_30C030 = 1.0 - (a6 - this->field_30C02C) / a6; - v13->field_C08 = (signed __int64)(a4->x - a8 * a9->field_4.x); - v13->field_C0A = (signed __int64)(a4->y - a8 * a9->field_4.y); - //v19 = a6; - v13->field_C0C = (signed __int64)(a4->z - a8 * a9->field_4.z); - //v20 = a6 * this->flt_30C030; - //a8a = v13->pVertices; - this->field_30C034 = a6 * this->flt_30C030; - this->field_30C010 = this->field_30C034 * a9->field_10.x; - this->field_30C014 = this->field_30C034 * a9->field_10.y; - this->field_30C018 = this->field_30C034 * a9->field_10.z; - - this->field_30C01C = this->field_30C034 * a9->field_1C.x; - this->field_30C020 = this->field_30C034 * a9->field_1C.y; - this->field_30C024 = this->field_30C034 * a9->field_1C.z; - //a6a = v13->field_C08; - //v21 = (double)v13->field_C08; - //v22 = (double)v13->field_C08 - this->field_30C01C; - //a6a = v13->field_C0A; - v13->pVertices[0].vWorldPosition.x = (double)v13->field_C08 - this->field_30C01C + this->field_30C010; - v13->pVertices[0].vWorldPosition.y = (double)v13->field_C0A - this->field_30C020 + this->field_30C014; - v13->pVertices[0].vWorldPosition.z = (double)v13->field_C0A - this->field_30C024 + this->field_30C018; - v13->pVertices[0].u = 0.0; - v13->pVertices[0].v = 0.0; - - v13->pVertices[1].vWorldPosition.x = (double)v13->field_C08 - this->field_30C01C - this->field_30C010; - v13->pVertices[1].vWorldPosition.y = (double)v13->field_C0A - this->field_30C020 - this->field_30C014; - v13->pVertices[1].vWorldPosition.z = (double)v13->field_C0A - this->field_30C024 - this->field_30C018; - v13->pVertices[1].u = 0.0; - v13->pVertices[1].v = 1.0; - - v13->pVertices[2].vWorldPosition.x = (double)v13->field_C08 + this->field_30C01C - this->field_30C010; - v13->pVertices[2].vWorldPosition.y = (double)v13->field_C0A + this->field_30C020 - this->field_30C014; - v13->pVertices[2].vWorldPosition.z = (double)v13->field_C0A + this->field_30C024 - this->field_30C018; - v13->pVertices[2].u = 1.0; - v13->pVertices[2].v = 1.0; - - v13->pVertices[3].vWorldPosition.x = (double)v13->field_C08 + this->field_30C01C + this->field_30C010; - v13->pVertices[3].vWorldPosition.y = (double)v13->field_C0A + this->field_30C020 + this->field_30C014; - v13->pVertices[3].vWorldPosition.z = (double)v13->field_C0A + this->field_30C024 + this->field_30C018; - v13->pVertices[3].u = 1.0; - v13->pVertices[3].v = 0.0; - - for ( uint i = 0; i < 4; ++i ) - { - v28 = a9->field_4.x * v13->pVertices[i].vWorldPosition.x - + a9->field_4.y * v13->pVertices[i].vWorldPosition.y - + a9->field_4.z * v13->pVertices[i].vWorldPosition.z - + a9->dist; - v13->pVertices[i].vWorldPosition.x = v13->pVertices[i].vWorldPosition.x - v28 * a9->field_4.x; - v13->pVertices[i].vWorldPosition.y = v13->pVertices[i].vWorldPosition.y - v28 * a9->field_4.y; - v13->pVertices[i].vWorldPosition.z = v13->pVertices[i].vWorldPosition.z - v28 * a9->field_4.z; - //v25 += 48; - } - v13->uColorMultiplier = uColorMultiplier; - //v40 = (unsigned int *)&v13->uNumVertices; - //v39 = v13->pVertices; - v13->uNumVertices = 4; - v13->field_C14 = a2; - //v29 = a9->field_4.z; - //a6a = (unsigned int *)&v13->uNumVertices; - //v38 = a9->field_4.z; - result = pGame->pStru9Instance->_4980B9(a11, a10, a9->field_4.x, a9->field_4.y, a9->field_4.z, v13->pVertices, (unsigned int*)&v13->uNumVertices); - if ( result ) - { - //v31 = a6a; - if ( !v13->uNumVertices ) - return 1; - //v32 = a8a; - //v40 = *a6a; - //v39 = a8a; - pGame->pIndoorCameraD3D->ViewTransform(v13->pVertices, (unsigned int)v13->uNumVertices); - //v40 = 0; - pGame->pIndoorCameraD3D->Project(v13->pVertices, v13->uNumVertices, 0); - if ( !(uClipFlags & 1) ) - { - ++this->field_308008; - v34 = 1024; - if ( this->field_308008 == 1024 ) - this->field_308008 = 0; - if ( (signed int)(this->std__vector_pDecals_size + 1) <= 1024 ) - v34 = this->std__vector_pDecals_size + 1; - this->std__vector_pDecals_size = v34; - return 1; - } - if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor ) - { - if ( uClipFlags & 2 ) - { - //v40 = (int)&a8; - //v39 = this->pVertices; - //__debugbreak(); // warning C4700: uninitialized local variable 'v31' used - pGame->pIndoorCameraD3D->_436CDC_mess_with_lightmap__clipflag_2(v13->pVertices, v13->uNumVertices, this->pVertices, &a8b); - //v40 = (int)v31; - //v39 = this->pVertices; - pGame->pIndoorCameraD3D->_437143(a8b, v13->pVertices, this->pVertices, (unsigned int *)&v13->uNumVertices); - } - else if ( uClipFlags & 4 ) - { - //v40 = (int)&a8; - //v39 = this->pVertices; - pGame->pIndoorCameraD3D->_436F09_mess_with_lightmap__clipflag_4(v13->pVertices, v13->uNumVertices, this->pVertices, &a8b); - //v40 = (int)v31; - //v39 = this->pVertices; - pGame->pIndoorCameraD3D->_437143(a8b, v13->pVertices, this->pVertices, (unsigned int *)&v13->uNumVertices); - } - else - MessageBoxA(nullptr, "Undefined clip flag specified", "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\PolyProjector.cpp:258", 0); - } - else - MessageBoxA(nullptr, "Lightpoly builder native indoor clipping not implemented", "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\PolyProjector.cpp:263", 0); - if ( a8b != 0 ) - { - ++this->field_308008; - v34 = 1024; - if ( this->field_308008 == 1024 ) - this->field_308008 = 0; - if ( (signed int)(this->std__vector_pDecals_size + 1) <= 1024 ) - v34 = this->std__vector_pDecals_size + 1; - this->std__vector_pDecals_size = v34; - return 1; - } - result = 1; - } - return result; -} - -//----- (0049BBBD) -------------------------------------------------------- -bool DecalBuilder::ApplyBloodsplatDecals_IndoorFace(unsigned int uFaceID) -{ - double v7; // st7@12 - - uNumDecals = 0; - if (!pBloodsplatContainer->std__vector_pBloodsplats_size) - return true; - - BLVFace* pFace = &pIndoor->pFaces[uFaceID]; - - if ( pFace->Indoor_sky() || pFace->Fluid() ) - return true; - for (uint i = 0; i < pBloodsplatContainer->std__vector_pBloodsplats_size; ++i) - { - Bloodsplat* pBloodsplat = &pBloodsplatContainer->std__vector_pBloodsplats[i]; - if (pFace->pBounding.x1 - pBloodsplat->radius < pBloodsplat->x && - pFace->pBounding.x2 + pBloodsplat->radius > pBloodsplat->x && - pFace->pBounding.y1 - pBloodsplat->radius < pBloodsplat->y && - pFace->pBounding.y2 + pBloodsplat->radius > pBloodsplat->y && - pFace->pBounding.z1 - pBloodsplat->radius < pBloodsplat->z && - pFace->pBounding.z2 + pBloodsplat->radius > pBloodsplat->z) - { - v7 = pFace->pFacePlane.vNormal.z * pBloodsplat->z + - pFace->pFacePlane.vNormal.y * pBloodsplat->y + - pFace->pFacePlane.vNormal.x * pBloodsplat->x + - pFace->pFacePlane.dist; - if (v7 <= pBloodsplat->radius) - { - pBloodsplat->dot_dist = v7; - std__vector_30B00C[uNumDecals++] = i; - } - } - } - - return true; -} - -//----- (0049BCEB) -------------------------------------------------------- -char DecalBuilder::ApplyDecals_OutdoorFace(ODMFace *pFace) -{ - double v8; // st7@12 - //unsigned int v10; // [sp+20h] [bp-1Ch]@1 - - Bloodsplat *pBloodsplat; - - this->uNumDecals = 0; - //v10 = pBloodsplatContainer->std__vector_pBloodsplats_size; - if ( !pFace->Indoor_sky() && !pFace->Fluid() ) - { - for(int i = 0; i < pBloodsplatContainer->std__vector_pBloodsplats_size; i++ ) - { - pBloodsplat = &pBloodsplatContainer->std__vector_pBloodsplats[i]; - if ( (double)pFace->pBoundingBox.x1 - pBloodsplat->radius < pBloodsplat->x && - (double)pFace->pBoundingBox.x2 + pBloodsplat->radius > pBloodsplat->x && - (double)pFace->pBoundingBox.y1 - pBloodsplat->radius < pBloodsplat->y && - (double)pFace->pBoundingBox.y2 + pBloodsplat->radius > pBloodsplat->y && - (double)pFace->pBoundingBox.z1 - pBloodsplat->radius < pBloodsplat->z && - (double)pFace->pBoundingBox.z2 + pBloodsplat->radius > pBloodsplat->z ) - { - v8 = (double)((pFace->pFacePlane.dist - + round_to_int(pBloodsplat->x) * pFace->pFacePlane.vNormal.x - + round_to_int(pBloodsplat->y) * pFace->pFacePlane.vNormal.y - + round_to_int(pBloodsplat->z) * pFace->pFacePlane.vNormal.z) >> 16); - if ( v8 <= pBloodsplat->radius ) - { - pBloodsplat->dot_dist = v8; - this->std__vector_30B00C[this->uNumDecals++] = i; - } - } - } - } - return 1; -} - -//----- (0049BE8A) -------------------------------------------------------- -bool DecalBuilder::_49BE8A(struct Polygon *a2, Vec3_float_ *_a3, float *a4, RenderVertexSoft *a5, unsigned int uStripType, char a7) -{ - bool result; // eax@1 - //RenderVertexSoft *v8; // edi@3 - //Vec3_float_ *v9; // ebx@3 - //Bloodsplat *v10; // esi@3 - //float v11; // eax@5 - float v12; // eax@6 - //double v13; // st7@13 - double v14; // st7@19 - //short v15; // eax@20 - int v16; // eax@22 - //int v17; // edx@24 - //DecalBuilder *v18; // eax@24 - std::string v19; // [sp-18h] [bp-54h]@12 -// const char *v20; // [sp-8h] [bp-44h]@12 - //int v21; // [sp-4h] [bp-40h]@12 - double v22; // [sp+Ch] [bp-30h]@19 - unsigned int v23; // [sp+14h] [bp-28h]@1 - //DecalBuilder *v24; // [sp+18h] [bp-24h]@1 - //int v25; // [sp+1Ch] [bp-20h]@19 - float v26; // [sp+20h] [bp-1Ch]@12 -// int v27; // [sp+24h] [bp-18h]@12 - float v28; // [sp+28h] [bp-14h]@13 - //float v29; // [sp+2Ch] [bp-10h]@7 - float v30; // [sp+30h] [bp-Ch]@6 - float v31; // [sp+34h] [bp-8h]@6 - bool v32; // [sp+38h] [bp-4h]@2 - float a3; - - this->uNumDecals = 0; - result = pBloodsplatContainer->std__vector_pBloodsplats_size != 0; - // v24 = this; - v23 = pBloodsplatContainer->std__vector_pBloodsplats_size; - if ( pBloodsplatContainer->std__vector_pBloodsplats_size ) - { - - if ( (signed int)pBloodsplatContainer->std__vector_pBloodsplats_size > 0 ) - { - //v8 = a5; - //v9 = _a3; - for ( v32 = 0; v32 < (signed int)v23; ++v32 ) - { - if ( uStripType == 4 ) - { - a3 = a5->vWorldPosition.x; - //v11 = v8[3].vWorldPosition.x; - v31 = a5[3].vWorldPosition.x; - v30 = a5[1].vWorldPosition.y; - v12 = a5->vWorldPosition.y; - //v29 = v12; - } - else if ( uStripType == 3 ) - { - if ( a7 ) - { - a3 = a5->vWorldPosition.x; - v31 = a5[2].vWorldPosition.x; - v30 = a5[1].vWorldPosition.y; - v12 = a5[2].vWorldPosition.y; - //v29 = v12; - } - else - { - a3 = a5[1].vWorldPosition.x; - //v11 = v8[2].vWorldPosition.x; - v31 = a5[2].vWorldPosition.x; - v30 = a5[1].vWorldPosition.y; - v12 = a5->vWorldPosition.y; - //v29 = v12; - } - } - else - MessageBoxW(nullptr, L"Uknown strip type detected!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\PolyProjector.cpp:434", 0); - //v21 = uStripType; - //v13 = pGame->pIndoorCameraD3D->GetPolygonMinZ(v8, uStripType); - //v21 = uStripType; - v28 = pGame->pIndoorCameraD3D->GetPolygonMinZ(a5, uStripType); - v26 = pGame->pIndoorCameraD3D->GetPolygonMaxZ(a5, uStripType); - if ( a3 - pBloodsplatContainer->std__vector_pBloodsplats[v32].radius < pBloodsplatContainer->std__vector_pBloodsplats[v32].x && - v31 + pBloodsplatContainer->std__vector_pBloodsplats[v32].radius > pBloodsplatContainer->std__vector_pBloodsplats[v32].x && - v30 - pBloodsplatContainer->std__vector_pBloodsplats[v32].radius < pBloodsplatContainer->std__vector_pBloodsplats[v32].y && - v12 + pBloodsplatContainer->std__vector_pBloodsplats[v32].radius > pBloodsplatContainer->std__vector_pBloodsplats[v32].y && - v28 - pBloodsplatContainer->std__vector_pBloodsplats[v32].radius < pBloodsplatContainer->std__vector_pBloodsplats[v32].z && - v26 + pBloodsplatContainer->std__vector_pBloodsplats[v32].radius > pBloodsplatContainer->std__vector_pBloodsplats[v32].z ) - { - Vec3_float_::NegDot(&a5->vWorldPosition, _a3, a4); - v26 = _a3->y * pBloodsplatContainer->std__vector_pBloodsplats[v32].y - + _a3->z * pBloodsplatContainer->std__vector_pBloodsplats[v32].z - + _a3->x * pBloodsplatContainer->std__vector_pBloodsplats[v32].x - + *a4; - v22 = v26 + 6.7553994e15; - //v25 = LODWORD(v22); - v14 = (double)SLODWORD(v22); - v28 = v14; - if ( v14 <= pBloodsplatContainer->std__vector_pBloodsplats[v32].radius ) - { - //v15 = a2->flags; - if ( a2->flags & 2 || a2->flags & 0x100 ) - { - v16 = pBloodsplatContainer->std__vector_pBloodsplats[v32].field_1C; - if ( !(pBloodsplatContainer->std__vector_pBloodsplats[v32].field_1C & 1) ) - { - LOBYTE(v16) = v16 | 1; - pBloodsplatContainer->std__vector_pBloodsplats[v32].field_1C = v16; - pBloodsplatContainer->std__vector_pBloodsplats[v32].field_20 = pEventTimer->Time(); - } - } - //v17 = v32; - pBloodsplatContainer->std__vector_pBloodsplats[v32].dot_dist = LODWORD(v28); - //v18 = this; - this->std__vector_30B00C[this->uNumDecals] = v32; - ++this->uNumDecals; - } - } - //++v32; - //++v10; - result = v32; - } - } - } - LOBYTE(result) = 1; - return result; -} - - -//----- (0049C2CD) -------------------------------------------------------- -void DecalBuilder::DrawDecals(float z_bias) -{ - for (uint i = 0; i < std__vector_pDecals_size; ++i) - pRenderer->DrawDecal(std__vector_pDecals + i, z_bias); -} - -//----- (0049C304) -------------------------------------------------------- -void DecalBuilder::DrawBloodsplats() -{ - if (!std__vector_pDecals_size) - return; - - pRenderer->BeginDecals(); - - DrawDecals(0.00039999999); - - pRenderer->EndDecals(); -} - -//----- (0049C550) -------------------------------------------------------- -void DecalBuilder::DrawDecalDebugOutlines() -{ - for(int i = 0; i < std__vector_pDecals_size; i++) - pGame->pIndoorCameraD3D->debug_outline_sw(std__vector_pDecals[i].pVertices, std__vector_pDecals[i].uNumVertices, 0xC86400u, 0.0); -} - -//----- (0040E4C2) -------------------------------------------------------- -void Decal::Decal_base_ctor() -{ - uNumVertices = -1; - for (uint i = 0; i < 64; ++i) - pVertices[i].flt_2C = 0.0f; -} diff -r 7b076fe64f23 -r 5abd8fc8f1c6 DecalBuilder.h --- a/DecalBuilder.h Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,206 +0,0 @@ -#pragma once - -#include - -#include "Render.h" - -/* 158 */ -#pragma pack(push, 1) -struct Bloodsplat -{ - //----- (0043B538) -------------------------------------------------------- - inline Bloodsplat() - { - this->field_1C = 0; - this->field_20 = 0; - //this->field_24 = 0; - //this->vdestructor_ptr = &Bloodsplat_pvdtor; - } - - //----- (0043B54C) -------------------------------------------------------- - //void Bloodsplat::vdtor(Bloodsplat *this, char a2) - - //----- (0043B569) -------------------------------------------------------- - virtual ~Bloodsplat() - { - } - - //void ( ***vdestructor_ptr)(Bloodsplat *, bool); - float x; - float y; - float z; - float radius; - float dot_dist; - unsigned char r; - unsigned char g; - unsigned char b; - char field_1B; - int field_1C; - unsigned long long field_20; - //int field_24; -}; -#pragma pack(pop) - -/* 159 */ -#pragma pack(push, 1) -struct BloodsplatContainer -{ - //----- (0043B688) -------------------------------------------------------- - inline BloodsplatContainer() - { - /*_eh_vector_constructor_iterator_( - this->std__vector_pBloodsplats, - 40, - 64, - (void ( *)(void *))Bloodsplat::Bloodsplat, - (void ( *)(void *))Bloodsplat::dtor); - v1->std__vector_pBloodsplats_size = 0;*/ - uNumBloodsplats = 0; - } - //----- (0043B6D6) -------------------------------------------------------- - virtual ~BloodsplatContainer() - { - //this->vdestructor_ptr = &BloodsplatContainer_pvdtor; - //_eh_vector_destructor_iterator_(this->std__vector_pBloodsplats, 40, 64, Bloodsplat::dtor); - } - - - void AddBloodsplat(float x, float y, float z, float r, float g, float b, float radius, int a8, int a9); - void AddBloodsplat(float x, float y, float z, float radius, unsigned char r, unsigned char g, unsigned char b); - - - //void ( ***vdestructor_ptr)(BloodsplatContainer *, bool); - Bloodsplat std__vector_pBloodsplats[64]; - unsigned int std__vector_pBloodsplats_size; - int uNumBloodsplats; -}; -#pragma pack(pop) - -extern struct BloodsplatContainer *pBloodsplatContainer; // idb - -#pragma pack(push, 1) -struct DecalBuilder_stru0 -{ - double _43B570_get_color_mult_by_time(); - - int field_0; - int field_4; - int field_8; - int field_C; - int field_10; - int field_14; - int field_18; - int field_1C_flags; - __int64 field_20_time; -}; -#pragma pack(pop) - - - -/* 181 */ -#pragma pack(push, 1) -struct Decal -{ - void Decal_base_ctor(); - //----- (0043B60C) -------------------------------------------------------- - inline Decal() - { - Decal_base_ctor(); - field_C1C = 0; - } - - //----- (0043B625) -------------------------------------------------------- - //void Decal::vdtor(Decal *this, bool a2) - //----- (0043B641) -------------------------------------------------------- - virtual ~Decal() - { - } - - //void ( ***vdestructor_ptr)(Decal *, bool); - int uNumVertices; - RenderVertexSoft pVertices[64]; - __int16 field_C08; - __int16 field_C0A; - __int16 field_C0C; - __int16 field_C0E; - uint32_t uColorMultiplier; - int field_C14; - DecalBuilder_stru0 *field_C18; - int field_C1C; -}; -#pragma pack(pop) - -/* 180 */ -#pragma pack(push, 1) -struct DecalBuilder -{ - //----- (0049B408) -------------------------------------------------------- - DecalBuilder() - { - char *v2; // eax@1 - signed int v3; // ecx@1 - - DecalBuilder* v1 = this; - /*_eh_vector_constructor_iterator_( - this->std__vector_pDecals, - 3104, - 1024, - (void ( *)(void *))Decal::Decal, - (void ( *)(void *))Decal::dtor);*/ - v1->std__vector_pDecals_size = 0; - v1->field_308008 = 0; - v2 = (char *)&v1->pVertices[0].flt_2C; - v3 = 256; - do - { - *(float *)v2 = 0.0; - v2 += 48; - --v3; - } - while ( v3 ); - } - - //----- (0049B471) -------------------------------------------------------- - virtual ~DecalBuilder() - {} - - - void AddBloodsplat(float x, float y, float z, float r, float g, float b, float radius, int a8, int a9); - void Reset(unsigned int bPreserveBloodsplats); - char ApplyDecals(int light_level, char a3, struct stru154 *a4, int a5, struct RenderVertexSoft *a6, struct IndoorCameraD3D_Vec4 *a7, char a8, unsigned int uSectorID); - char _49B790_build_decal_geometry(int a2, char a3, Bloodsplat *a4, int a5, float a6, unsigned int uColorMultiplier, float a8, struct stru314 *a9, signed int a10, struct RenderVertexSoft *a11, char uClipFlags); - bool ApplyBloodsplatDecals_IndoorFace(unsigned int uFaceID); - char ApplyDecals_OutdoorFace(ODMFace *pFace); - bool _49BE8A(struct Polygon *a2, Vec3_float_ *a3, float *a4, struct RenderVertexSoft *a5, unsigned int uStripType, char a7); - void DrawDecals(float z_bias); - void DrawBloodsplats(); - void DrawDecalDebugOutlines(); - - - - //void ( ***vdestructor_ptr)(DecalBuilder *, bool); - Decal std__vector_pDecals[1024]; - unsigned int std__vector_pDecals_size; - int field_308008; - RenderVertexSoft pVertices[256]; - int std__vector_30B00C[1024]; - int uNumDecals; - float field_30C010; - float field_30C014; - float field_30C018; - float field_30C01C; - float field_30C020; - float field_30C024; - float field_30C028; - float field_30C02C; - float flt_30C030; - float field_30C034; -}; -#pragma pack(pop) - -extern struct DecalBuilder *pDecalBuilder; - - - - - diff -r 7b076fe64f23 -r 5abd8fc8f1c6 DecorationList.cpp --- a/DecorationList.cpp Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,294 +0,0 @@ -#define _CRTDBG_MAP_ALLOC -#include -#include - -#define _CRT_SECURE_NO_WARNINGS -#include "Sprites.h" -#include "DecorationList.h" -#include "FrameTableInc.h" -#include "mm7_data.h" -#include "ErrorHandling.h" -#include "stru123.h" -#include "Level\Decoration.h" - -struct DecorationList *pDecorationList; - -//----- (0045864C) -------------------------------------------------------- -void DecorationList::FromFile(void *data_mm6, void *data_mm7, void *data_mm8) -{ - uint num_mm6_decs = data_mm6 ? *(int *)data_mm6 : 0, - num_mm7_decs = data_mm7 ? *(int *)data_mm7 : 0, - num_mm8_decs = data_mm8 ? *(int *)data_mm8 : 0; - - uNumDecorations = num_mm6_decs + num_mm7_decs + num_mm8_decs; - Assert(uNumDecorations); - Assert(!num_mm8_decs); - - pDecorations = (DecorationDesc *)malloc(uNumDecorations * sizeof(DecorationDesc)); - memcpy(pDecorations, (char *)data_mm7 + 4, num_mm7_decs * sizeof(DecorationDesc)); - for (uint i = 0; i < num_mm6_decs; ++i) - { - memcpy(pDecorations + num_mm7_decs + i, (char *)data_mm6 + 4 + i * sizeof(DecorationDesc_mm6), sizeof(DecorationDesc_mm6)); - pDecorations[num_mm7_decs + i].uColoredLightRed = 255; - pDecorations[num_mm7_decs + i].uColoredLightGreen = 255; - pDecorations[num_mm7_decs + i].uColoredLightBlue = 255; - pDecorations[num_mm7_decs + i].__padding = 255; - } - memcpy(pDecorations + num_mm6_decs + num_mm7_decs, (char *)data_mm8 + 4, num_mm8_decs * sizeof(DecorationDesc)); -} - -//----- (00458693) -------------------------------------------------------- -void DecorationList::InitializeDecorationSprite(unsigned int uDecID) -{ - pSpriteFrameTable->InitializeSprite(this->pDecorations[uDecID].uSpriteID); -} - -//----- (004586B0) -------------------------------------------------------- -bool DecorationList::FromFileTxt(const char *Args) -{ - DecorationList *v2; // ebx@1 - FILE *v3; // eax@1 - unsigned int v4; // esi@3 - void *v5; // eax@10 - FILE *v6; // ST18_4@12 - char *i; // eax@12 - unsigned __int16 v8; // ax@16 - //const char *v9; // ST20_4@16 - //const char *v10; // ST18_4@16 - //__int16 v11; // ax@16 - //const char *v12; // ST14_4@16 - //unsigned __int16 v13; // ax@16 -// const char *v14; // ST10_4@16 - //__int16 v15; // ax@16 -// const char *v16; // ST0C_4@16 -// unsigned __int8 v17; // al@16 -// const char *v18; // ST08_4@16 -// unsigned __int8 v19; // al@16 -// const char *v20; // ST04_4@16 -// unsigned __int8 v21; // al@16 -// const char *v22; // ST00_4@16 - unsigned __int8 v23; // zf@16 - char v24; // sf@16 - unsigned __int8 v25; // of@16 - int j; // edi@17 - const char *v27; // esi@18 - int v29; // eax@21 - int v30; // eax@23 - int v31; // eax@25 - int v32; // eax@27 - int v33; // eax@29 - int v34; // eax@31 - int v35; // eax@33 - FrameTableTxtLine v37; // [sp+Ch] [bp-460h]@17 - FrameTableTxtLine v38; // [sp+88h] [bp-3E4h]@13 - char Dest; // [sp+104h] [bp-368h]@17 - char Buf; // [sp+17Ch] [bp-2F0h]@3 - FrameTableTxtLine v41; // [sp+370h] [bp-FCh]@4 - FrameTableTxtLine v42; // [sp+3ECh] [bp-80h]@4 - FILE *File; // [sp+468h] [bp-4h]@1 - unsigned int Argsa; // [sp+474h] [bp+8h]@3 - - v2 = this; - v3 = fopen(Args, "r"); - File = v3; - if ( !v3 ) - Error("DecorationDescriptionList::load - Unable to open file: %s."); - - v4 = 0; - Argsa = 0; - if ( fgets(&Buf, 490, v3) ) - { - do - { - *strchr(&Buf, 10) = 0; - memcpy(&v42, frame_table_txt_parser(&Buf, &v41), sizeof(v42)); - if ( v42.uPropCount && *v42.pProperties[0] != 47 && v42.uPropCount >= 3 ) - ++Argsa; - } - while ( fgets(&Buf, 490, File) ); - v4 = Argsa; - } - v2->uNumDecorations = v4; - v5 = malloc(84 * v4); - v2->pDecorations = (DecorationDesc *)v5; - if ( !v5 ) - Error("DecorationDescriptionList::load - Out of Memory!"); - - v6 = File; - v2->uNumDecorations = 0; - fseek(v6, 0, 0); - for ( i = fgets(&Buf, 490, File); i; i = fgets(&Buf, 490, File) ) - { - *strchr(&Buf, 10) = 0; - memcpy(&v42, frame_table_txt_parser(&Buf, &v38), sizeof(v42)); - if ( v42.uPropCount && *v42.pProperties[0] != 47 && v42.uPropCount >= 3 ) - { - strcpy(v2->pDecorations[v2->uNumDecorations].pName, v42.pProperties[1]); - v8 = pSpriteFrameTable->FastFindSprite(v2->pDecorations[v2->uNumDecorations].pName); - //v9 = v42.pProperties[2]; - v2->pDecorations[v2->uNumDecorations].uSpriteID = v8; - strcpy(v2->pDecorations[v2->uNumDecorations].field_20, v42.pProperties[2]); - //v10 = v42.pProperties[3]; - v2->pDecorations[v2->uNumDecorations].uType = 0; - //v11 = atoi(v42.pProperties[3]); - //v12 = v42.pProperties[4]; - v2->pDecorations[v2->uNumDecorations].uRadius = atoi(v42.pProperties[3]); - //v13 = atoi(v42.pProperties[4]); - //v14 = v42.pProperties[5]; - v2->pDecorations[v2->uNumDecorations].uDecorationHeight = atoi(v42.pProperties[4]); - //v15 = atoi(v42.pProperties[5]); - //v16 = v42.pProperties[6]; - v2->pDecorations[v2->uNumDecorations].uLightRadius = atoi(v42.pProperties[5]); - //v17 = atoi(v42.pProperties[6]); - //v18 = v42.pProperties[7]; - v2->pDecorations[v2->uNumDecorations].uColoredLightRed = atoi(v42.pProperties[6]); - //v19 = atoi(v42.pProperties[7]); - //v20 = v42.pProperties[8]; - v2->pDecorations[v2->uNumDecorations].uColoredLightGreen = atoi(v42.pProperties[7]); - //v21 = atoi(v42.pProperties[8]); - //v22 = v42.pProperties[9]; - v2->pDecorations[v2->uNumDecorations].uColoredLightBlue = atoi(v42.pProperties[8]); - v2->pDecorations[v2->uNumDecorations].uSoundID = atoi(v42.pProperties[9]); - __debugbreak();//Ritor1: need cleaning - v25 = __OFSUB__(v42.uPropCount, 10); - v23 = v42.uPropCount == 10; - v24 = v42.uPropCount - 10 < 0; - v2->pDecorations[v2->uNumDecorations].uFlags = 0; - if ( !((unsigned __int8)(v24 ^ v25) | v23) ) - { - strcpy(&Dest, v42.pProperties[10]); - memcpy(&v41, frame_table_txt_parser(&Dest, &v37), sizeof(v41)); - for ( j = 0; j < v41.uPropCount; ++j ) - { - v27 = v41.pProperties[j]; - if ( _stricmp(v41.pProperties[j], "NBM") ) - { - if ( _stricmp(v27, "Invisible") ) - { - if ( _stricmp(v27, "FS") ) - { - if ( _stricmp(v27, "FM") ) - { - if ( _stricmp(v27, "FF") ) - { - if ( _stricmp(v27, "Marker") ) - { - if ( _stricmp(v27, "LoopSlow") ) - { - if ( _stricmp(v27, "EmitFire") ) - { - if ( _stricmp(v27, "Dawn") ) - { - if ( !_stricmp(v27, "Dusk") ) - HIBYTE(v2->pDecorations[v2->uNumDecorations].uFlags) |= 2u; - } - else - { - HIBYTE(v2->pDecorations[v2->uNumDecorations].uFlags) |= 1u; - } - } - else - { - v35 = (int)&v2->pDecorations[v2->uNumDecorations].uFlags; - *(char *)v35 |= 0x80u; - } - } - else - { - v34 = (int)&v2->pDecorations[v2->uNumDecorations].uFlags; - *(char *)v34 |= 0x40u; - } - } - else - { - v33 = (int)&v2->pDecorations[v2->uNumDecorations].uFlags; - *(char *)v33 |= 0x20u; - } - } - else - { - v32 = (int)&v2->pDecorations[v2->uNumDecorations].uFlags; - *(char *)v32 |= 0x10u; - } - } - else - { - v31 = (int)&v2->pDecorations[v2->uNumDecorations].uFlags; - *(char *)v31 |= 8u; - } - } - else - { - v30 = (int)&v2->pDecorations[v2->uNumDecorations].uFlags; - *(char *)v30 |= 4u; - } - } - else - { - v29 = (int)&v2->pDecorations[v2->uNumDecorations].uFlags; - *(char *)v29 |= 2u; - } - } - else - v2->pDecorations[v2->uNumDecorations].uFlags |= 1; - } - } - ++v2->uNumDecorations; - } - } - fclose(File); - return 1; -} -//----- (00458600) -------------------------------------------------------- -void DecorationList::ToFile() -{ - FILE *v2; // eax@1 - FILE *v3; // edi@1 - - v2 = fopen("data\\ddeclist.bin", "wb"); - v3 = v2; - if ( !v2 ) - Error("Unable to save ddeclist.bin!"); - - fwrite(this, 4, 1, v2); - fwrite(this->pDecorations, 84, this->uNumDecorations, v3); - fclose(v3); -} -//----- (004488B6) -------------------------------------------------------- -unsigned __int16 DecorationList::GetDecorIdByName(const char *pName) -{ - if ( pName && (signed int)this->uNumDecorations > 1 ) - { - for ( uint uID = 1; uID < (signed int)this->uNumDecorations; ++uID ) - { - if ( !_stricmp(pName, this->pDecorations[uID].pName) ) - return uID; - } - } - return 0; -} - - -//----- (00450AAA) -------------------------------------------------------- -void RespawnGlobalDecorations() -{ - memset(stru_5E4C90_MapPersistVars._decor_events.data(), 0, 125); - - uint decorEventIdx = 0; - for (uint i = 0; i < uNumLevelDecorations; ++i) - { - LevelDecoration* decor = &pLevelDecorations[i]; - - if (!decor->uEventID) - { - if (decor->IsInteractive()) - { - if (decorEventIdx < 124) - { - decor->_idx_in_stru123 = decorEventIdx + 75; - stru_5E4C90_MapPersistVars._decor_events[decorEventIdx++] = decor->GetGlobalEvent(); - } - } - } - } -} \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 DecorationList.h --- a/DecorationList.h Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ -#pragma once - - - - -/* 321 */ -enum DECORATION_DESC_FLAGS -{ - DECORATION_DESC_MOVE_THROUGH = 0x0001, - DECORATION_DESC_DONT_DRAW = 0x0002, - DECORATION_DESC_FLICKER_SLOW = 0x0004, - DECORATION_DESC_FICKER_AVERAGE = 0x0008, - DECORATION_DESC_FICKER_FAST = 0x0010, - DECORATION_DESC_MARKER = 0x0020, - DECORATION_DESC_SLOW_LOOP = 0x0040, - DECORATION_DESC_EMITS_FIRE = 0x0080, - DECORATION_DESC_SOUND_ON_DAWN = 0x0100, - DECORATION_DESC_SOUND_ON_DUSK = 0x0200, - DECORATION_DESC_EMITS_SMOKE = 0x0400, -}; - - - -/* 54 */ -#pragma pack(push, 1) -struct DecorationDesc_mm6 -{ - inline bool CanMoveThrough() {return (uFlags & DECORATION_DESC_MOVE_THROUGH) != 0;} - inline bool DontDraw() {return (uFlags & DECORATION_DESC_DONT_DRAW) != 0;} - inline bool SoundOnDawn() {return (uFlags & DECORATION_DESC_SOUND_ON_DAWN) != 0;} - inline bool SoundOnDusk() {return (uFlags & DECORATION_DESC_SOUND_ON_DUSK) != 0;} - - char pName[32]; - char field_20[32]; - __int16 uType; - unsigned __int16 uDecorationHeight; - __int16 uRadius; - __int16 uLightRadius; - unsigned __int16 uSpriteID; - __int16 uFlags; - __int16 uSoundID; - __int16 _pad; - //unsigned __int8 uColoredLightRed; - //unsigned __int8 uColoredLightGreen; - //unsigned __int8 uColoredLightBlue; - //char __padding; -}; - -struct DecorationDesc: public DecorationDesc_mm6 -{ - unsigned __int8 uColoredLightRed; - unsigned __int8 uColoredLightGreen; - unsigned __int8 uColoredLightBlue; - char __padding; -}; -#pragma pack(pop) - -/* 55 */ -#pragma pack(push, 1) -struct DecorationList -{ - inline DecorationList(): //----- (00458380) - pDecorations(nullptr), uNumDecorations(0) - {} - - void ToFile(); - void FromFile(void *data_mm6, void *data_mm7, void *data_mm8); - bool FromFileTxt(const char *Args); - void InitializeDecorationSprite(unsigned int uDecID); - unsigned __int16 GetDecorIdByName(const char *pName); - - unsigned int uNumDecorations; - struct DecorationDesc *pDecorations; -}; -#pragma pack(pop) - - -extern struct DecorationList *pDecorationList; - -void RespawnGlobalDecorations(); \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/BSPModel.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/BSPModel.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,27 @@ +#define _CRTDBG_MAP_ALLOC +#include +#include + +#define _CRT_SECURE_NO_WARNINGS +#include + +#include "BSPModel.h" + + + +//----- (00478389) -------------------------------------------------------- +void BSPModel::Release() +{ + free(this->pVertices.pVertices); + this->pVertices.pVertices = 0; + free(this->pFaces); + this->pFaces = nullptr; + free(this->pFacesOrdering); + this->pFacesOrdering = nullptr; + free(this->pNodes); + this->pNodes = nullptr; + this->uNumNodes = 0; + this->uNumFaces = 0; + this->pVertices.uNumVertices = 0; + this->uNumConvexFaces = 0; +} diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/BSPModel.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/BSPModel.h Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,62 @@ +#pragma once +#include "VectorTypes.h" + + +#pragma pack(push, 1) +struct BSPNode //8 +{ + __int16 uFront; + __int16 uBack; + __int16 uCoplanarOffset; + __int16 uCoplanarSize; +}; +#pragma pack(pop) + + +#pragma pack(push, 1) +struct BSPVertexBuffer +{ + int uNumVertices; + Vec3_int_ *pVertices; +}; +#pragma pack(pop) + + + +/* 80 */ +#pragma pack(push, 1) +struct BSPModel +{ + void Release(); + + + char pModelName[32]; + char pModelName2[32]; + int field_40; + struct BSPVertexBuffer pVertices; + int uNumFaces; + unsigned int uNumConvexFaces; + struct ODMFace *pFaces; + unsigned __int16 *pFacesOrdering; + unsigned int uNumNodes; + struct BSPNode *pNodes; + unsigned int uNumDecorations; + int sCenterX; + int sCenterY; + Vec3_int_ vPosition; + int sMinX; + int sMinY; + int sMinZ; + int sMaxX; + int sMaxY; + int sMaxZ; + int sSomeOtherMinX; + int sSomeOtherMinY; + int sSomeOtherMinZ; + int sSomeOtherMaxX; + int sSomeOtherMaxY; + int sSomeOtherMaxZ; + Vec3_int_ vBoundingCenter; + int sBoundingRadius; +}; +#pragma pack(pop) diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/DecalBuilder.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/DecalBuilder.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,656 @@ +#define _CRTDBG_MAP_ALLOC +#include +#include + +#define _CRT_SECURE_NO_WARNINGS +#include "DecalBuilder.h" +#include "Game.h" +#include "Timer.h" +#include "stru314.h" +#include "Outdoor.h" +#include "Log.h" + +#include "stru9.h" + +#include "OurMath.h" + + +struct DecalBuilder *pDecalBuilder = new DecalBuilder; +struct BloodsplatContainer *pBloodsplatContainer = new BloodsplatContainer; + + +//----- (0043B570) -------------------------------------------------------- +double DecalBuilder_stru0::_43B570_get_color_mult_by_time() +{ + double result; // st7@3 + + if (field_1C_flags & 1) + { + if ((field_20_time - pEventTimer->Time() + 384) / 384.0 >= 0.0) + result = (field_20_time - pEventTimer->Time() + 384) / 384.0; + else + result = 0.0; + } + else + result = 1.0; + return result; +} + +//----- (0043B6EF) -------------------------------------------------------- +void BloodsplatContainer::AddBloodsplat(float x, float y, float z, float radius, unsigned char r, unsigned char g, unsigned char b) +{ + int i = this->uNumBloodsplats; + if ( this->uNumBloodsplats == 64 ) + i = 0; + this->std__vector_pBloodsplats[i].x = x; + this->std__vector_pBloodsplats[i].y = y; + this->std__vector_pBloodsplats[i].z = z; + this->std__vector_pBloodsplats[i].radius = radius; + this->std__vector_pBloodsplats[i].r = r; + this->std__vector_pBloodsplats[i].g = g; + this->std__vector_pBloodsplats[i].b = b; + this->std__vector_pBloodsplats_size = min(this->std__vector_pBloodsplats_size + 1, 64); +} + +//----- (0049B490) -------------------------------------------------------- +void DecalBuilder::AddBloodsplat(float x, float y, float z, float r, float g, float b, float radius, int a8, int a9) +{ + //double v10; // ST1C_8@1 +// char v11; // ST24_1@1 + //double v12; // ST1C_8@1 + //double v13; // ST1C_8@1 +// int a7a; // [sp+40h] [bp+18h]@1 + //float arg14a; // [sp+44h] [bp+1Ch]@1 + //float arg14b; // [sp+44h] [bp+1Ch]@1 + //float arg14c; // [sp+44h] [bp+1Ch]@1 + + /*arg14a = b * 255.0; + v10 = arg14a + 6.7553994e15; + v11 = LOBYTE(v10); + arg14b = g * 255.0; + v12 = arg14b + 6.7553994e15; + a7a = LODWORD(v12); + arg14c = r * 255.0; + v13 = arg14c + 6.7553994e15;*/ + pBloodsplatContainer->AddBloodsplat(x, y, z, radius, + //SLOBYTE(v13), a7a, v11); + bankersRounding(r * 255.0f), + bankersRounding(g * 255.0f), + bankersRounding(b * 255.0f)); +} + +//----- (0049B525) -------------------------------------------------------- +void DecalBuilder::Reset(unsigned int bPreserveBloodsplats) +{ + if ( !bPreserveBloodsplats ) + { + pBloodsplatContainer->std__vector_pBloodsplats_size = 0; + pBloodsplatContainer->uNumBloodsplats = 0; + } + std__vector_pDecals_size = 0; +} + +//----- (0049B540) -------------------------------------------------------- +char DecalBuilder::ApplyDecals(int light_level, char a3, stru154 *a4, int a5, RenderVertexSoft *a6, IndoorCameraD3D_Vec4 *a7, char a8, unsigned int uSectorID) +{ + //char *v9; // eax@3 + //signed int v10; // ecx@3 + //RenderVertexSoft *v11; // eax@10 + //unsigned int v12; // edx@10 + //RenderVertexSoft *v13; // esi@11 + //RenderVertexSoft *v14; // edi@11 + //char v15; // zf@11 + stru154 *v16; // esi@12 + //double v18; // st7@17 + //double v19; // st6@17 + //float v20; // eax@17 + //Bloodsplat *v21; // esi@21 + //int v22; // eax@21 + //int v23; // ecx@21 + //double v24; // st7@21 + int v25; // ebx@21 + //double v26; // st7@21 + //int v27; // edi@21 + //double v28; // st7@21 + //float v29; // ST10_4@21 +// int v30; // ST08_4@21 + //DecalBuilder *v31; // esi@21 + //int v32; // [sp+4h] [bp-44h]@18 + //float v33; // [sp+8h] [bp-40h]@21 + //stru314 *v34; // [sp+Ch] [bp-3Ch]@21 + //float v35; // [sp+10h] [bp-38h]@21 + //float v36; // [sp+14h] [bp-34h]@17 + //int v37; // [sp+18h] [bp-30h]@17 + //int a5a; // [sp+28h] [bp-20h]@21 + //int v39; // [sp+2Ch] [bp-1Ch]@21 + //int v40; // [sp+30h] [bp-18h]@21 + //int v41; // [sp+34h] [bp-14h]@22 + //int v42; // [sp+38h] [bp-10h]@21 + int v43; // [sp+3Ch] [bp-Ch]@21 + //DecalBuilder *thisa; // [sp+40h] [bp-8h]@1 + //RenderVertexSoft *a11; // [sp+44h] [bp-4h]@8 +// int a6a; + //int *a6b; + + +// __debugbreak(); + + //auto a2 = light_level; + //auto a9 = uSectorID; + + //thisa = this; + if ( !a5 ) + return 0; + + static RenderVertexSoft static_AE4F90[64]; + static bool __init_flag1 = false; + if (!__init_flag1) + { + __init_flag1 = true; + + for (uint i = 0; i < 64; ++i) + static_AE4F90[i].flt_2C = 0.0f; + } + + static stru314 static_AE4F60; // idb + /*static bool __init_flag2 = false; + if (!__init_flag2) + { + __init_flag2 = true; + + stru314::stru314(&static_AE4F60); + }*/ + + //a11 = a6; + if ( a7 ) + { + for(int i=0; i < a5;i++) + { + memcpy(&static_AE4F90[i], a6, 0x30u); + ++a6; + } + v16 = a4; + if ( pGame->pIndoorCameraD3D->_437376(a4, static_AE4F90, (unsigned int *)&a5) == 1 ) + { + if ( !a5 ) + return 0; + a6 = static_AE4F90; + } + } + else + v16 = a4; + //v18 = v16->face_plane.vNormal.z; + //v19 = v16->face_plane.vNormal.y; + //v20 = v16->face_plane.vNormal.x; + //v37 = (int)&static_AE4F60.field_1C; + static_AE4F60.field_4.y = v16->face_plane.vNormal.y; + static_AE4F60.field_4.x = v16->face_plane.vNormal.x; + //LODWORD(v36) = (DWORD)&static_AE4F60.field_10; + static_AE4F60.field_4.z = v16->face_plane.vNormal.z; + static_AE4F60.dist = v16->face_plane.dist; + if ( !pGame->pIndoorCameraD3D->GetFacetOrientation(v16->polygonType, &static_AE4F60.field_4, + &static_AE4F60.field_10, &static_AE4F60.field_1C) ) + MessageBoxW(nullptr, L"Error: Failed to get the facet orientation", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\PolyProjector.cpp:101", 0); + + if ( this->uNumDecals > 0 ) + { + //a6b = this->std__vector_30B00C; + for ( int i = 0; i < this->uNumDecals; ++i ) + { + //v21 = &pBloodsplatContainer->std__vector_pBloodsplats[*a6b]; + int point_light_level = _43F5C8_get_point_light_level_with_respect_to_lights(light_level, uSectorID, + pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].x, + pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].y, + pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].z); + //v23 = pBloodsplatContainer->std__vector_pBloodsplats[*a6b].b; + //v24 = pBloodsplatContainer->std__vector_pBloodsplats[*a6b].x; + //v42 = v22; + //BYTE3(v22) = 0; + //*(short *)((char *)&v22 + 1) = pBloodsplatContainer->std__vector_pBloodsplats[*a6b].r; + //LOBYTE(v22) = pBloodsplatContainer->std__vector_pBloodsplats[*a6b].g; + v43 = pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].b | + ((unsigned int)pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].g << 8) | + ((unsigned int)pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].r << 16); + v25 = (signed __int64)pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].x; + //v27 = (signed __int64)pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].y; + //v37 = a8; + //v40 = (signed __int64)pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].z; + //v28 = pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].dot_dist; + //LODWORD(v36) = (uint32)a6; + //a5a = v25; + //v39 = v27; + //LODWORD(v35) = a5; + //v34 = &static_AE4F60; + //v33 = v28; + //v32 = pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].b | (v22 << 8); + //v29 = pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].radius; + //v30 = (int)v21; + //v31 = thisa; + if ( !this->_49B790_build_decal_geometry(point_light_level, a3, + &pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]], + (int)&v25, + pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].radius, + v43, + pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].dot_dist, + &static_AE4F60, a5, a6, a8) ) + MessageBoxW(nullptr, L"Error: Failed to build decal geometry", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\PolyProjector.cpp:114", 0); + } + } + return 1; +} + +//----- (0049B790) -------------------------------------------------------- +char DecalBuilder::_49B790_build_decal_geometry(int a2, char a3, Bloodsplat *a4, int a5, float a6, unsigned int uColorMultiplier, float a8, stru314 *a9, signed int a10, RenderVertexSoft *a11, char uClipFlags) +{ + //DecalBuilder *v12; // esi@1 + Decal *v13; // edi@2 + //int *v14; // eax@2 + //double v15; // st7@4 + //double v16; // st7@4 + //int v17; // eax@4 + //stru314 *v18; // ebx@4 + //double v19; // st7@4 + //double v20; // st7@4 + //double v21; // st7@4 + //double v22; // st6@4 + //double v23; // st6@4 + //double v24; // st5@4 + //char *v25; // eax@4 + //signed int v26; // ecx@4 + //double v27; // st5@4 + double v28; // st7@5 + //double v29; // st7@6 + char result; // al@6 +// unsigned int *v31; // edi@7 +// RenderVertexSoft *v32; // ebx@8 +// std::string *v33; // ecx@15 + int v34; // eax@19 +// const char *v35; // [sp-Ch] [bp-2Ch]@15 +// int v36; // [sp-8h] [bp-28h]@15 + std::string v37; // [sp-4h] [bp-24h]@15 + //float v38; // [sp+8h] [bp-18h]@6 + //RenderVertexSoft *v39; // [sp+Ch] [bp-14h]@6 + //unsigned int v40; // [sp+10h] [bp-10h]@6 + + //int a6a; + //RenderVertexSoft *a8a; + unsigned int a8b = 0; + + //v12 = this; + if ( a6 == 0.0 ) + return 1; + v13 = &this->std__vector_pDecals[this->field_308008]; + //v14 = &this->std__vector_pDecals[this->field_308008].field_C1C; + this->std__vector_pDecals[this->field_308008].field_C18 = (DecalBuilder_stru0 *)a4; + this->std__vector_pDecals[this->field_308008].field_C1C = 0; + if ( a3 & 2 ) + this->std__vector_pDecals[this->field_308008].field_C1C = 1; + //v15 = a6 - a8; + this->field_30C028 = a6 - a8; + //v16 = sqrt((a6 + a6 - this->field_30C028) * this->field_30C028); + this->field_30C02C = sqrt((a6 + a6 - this->field_30C028) * this->field_30C028); + //v17 = a5; + //v18 = a9; + this->flt_30C030 = 1.0 - (a6 - this->field_30C02C) / a6; + v13->field_C08 = (signed __int64)(a4->x - a8 * a9->field_4.x); + v13->field_C0A = (signed __int64)(a4->y - a8 * a9->field_4.y); + //v19 = a6; + v13->field_C0C = (signed __int64)(a4->z - a8 * a9->field_4.z); + //v20 = a6 * this->flt_30C030; + //a8a = v13->pVertices; + this->field_30C034 = a6 * this->flt_30C030; + this->field_30C010 = this->field_30C034 * a9->field_10.x; + this->field_30C014 = this->field_30C034 * a9->field_10.y; + this->field_30C018 = this->field_30C034 * a9->field_10.z; + + this->field_30C01C = this->field_30C034 * a9->field_1C.x; + this->field_30C020 = this->field_30C034 * a9->field_1C.y; + this->field_30C024 = this->field_30C034 * a9->field_1C.z; + //a6a = v13->field_C08; + //v21 = (double)v13->field_C08; + //v22 = (double)v13->field_C08 - this->field_30C01C; + //a6a = v13->field_C0A; + v13->pVertices[0].vWorldPosition.x = (double)v13->field_C08 - this->field_30C01C + this->field_30C010; + v13->pVertices[0].vWorldPosition.y = (double)v13->field_C0A - this->field_30C020 + this->field_30C014; + v13->pVertices[0].vWorldPosition.z = (double)v13->field_C0A - this->field_30C024 + this->field_30C018; + v13->pVertices[0].u = 0.0; + v13->pVertices[0].v = 0.0; + + v13->pVertices[1].vWorldPosition.x = (double)v13->field_C08 - this->field_30C01C - this->field_30C010; + v13->pVertices[1].vWorldPosition.y = (double)v13->field_C0A - this->field_30C020 - this->field_30C014; + v13->pVertices[1].vWorldPosition.z = (double)v13->field_C0A - this->field_30C024 - this->field_30C018; + v13->pVertices[1].u = 0.0; + v13->pVertices[1].v = 1.0; + + v13->pVertices[2].vWorldPosition.x = (double)v13->field_C08 + this->field_30C01C - this->field_30C010; + v13->pVertices[2].vWorldPosition.y = (double)v13->field_C0A + this->field_30C020 - this->field_30C014; + v13->pVertices[2].vWorldPosition.z = (double)v13->field_C0A + this->field_30C024 - this->field_30C018; + v13->pVertices[2].u = 1.0; + v13->pVertices[2].v = 1.0; + + v13->pVertices[3].vWorldPosition.x = (double)v13->field_C08 + this->field_30C01C + this->field_30C010; + v13->pVertices[3].vWorldPosition.y = (double)v13->field_C0A + this->field_30C020 + this->field_30C014; + v13->pVertices[3].vWorldPosition.z = (double)v13->field_C0A + this->field_30C024 + this->field_30C018; + v13->pVertices[3].u = 1.0; + v13->pVertices[3].v = 0.0; + + for ( uint i = 0; i < 4; ++i ) + { + v28 = a9->field_4.x * v13->pVertices[i].vWorldPosition.x + + a9->field_4.y * v13->pVertices[i].vWorldPosition.y + + a9->field_4.z * v13->pVertices[i].vWorldPosition.z + + a9->dist; + v13->pVertices[i].vWorldPosition.x = v13->pVertices[i].vWorldPosition.x - v28 * a9->field_4.x; + v13->pVertices[i].vWorldPosition.y = v13->pVertices[i].vWorldPosition.y - v28 * a9->field_4.y; + v13->pVertices[i].vWorldPosition.z = v13->pVertices[i].vWorldPosition.z - v28 * a9->field_4.z; + //v25 += 48; + } + v13->uColorMultiplier = uColorMultiplier; + //v40 = (unsigned int *)&v13->uNumVertices; + //v39 = v13->pVertices; + v13->uNumVertices = 4; + v13->field_C14 = a2; + //v29 = a9->field_4.z; + //a6a = (unsigned int *)&v13->uNumVertices; + //v38 = a9->field_4.z; + result = pGame->pStru9Instance->_4980B9(a11, a10, a9->field_4.x, a9->field_4.y, a9->field_4.z, v13->pVertices, (unsigned int*)&v13->uNumVertices); + if ( result ) + { + //v31 = a6a; + if ( !v13->uNumVertices ) + return 1; + //v32 = a8a; + //v40 = *a6a; + //v39 = a8a; + pGame->pIndoorCameraD3D->ViewTransform(v13->pVertices, (unsigned int)v13->uNumVertices); + //v40 = 0; + pGame->pIndoorCameraD3D->Project(v13->pVertices, v13->uNumVertices, 0); + if ( !(uClipFlags & 1) ) + { + ++this->field_308008; + v34 = 1024; + if ( this->field_308008 == 1024 ) + this->field_308008 = 0; + if ( (signed int)(this->std__vector_pDecals_size + 1) <= 1024 ) + v34 = this->std__vector_pDecals_size + 1; + this->std__vector_pDecals_size = v34; + return 1; + } + if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor ) + { + if ( uClipFlags & 2 ) + { + //v40 = (int)&a8; + //v39 = this->pVertices; + //__debugbreak(); // warning C4700: uninitialized local variable 'v31' used + pGame->pIndoorCameraD3D->_436CDC_mess_with_lightmap__clipflag_2(v13->pVertices, v13->uNumVertices, this->pVertices, &a8b); + //v40 = (int)v31; + //v39 = this->pVertices; + pGame->pIndoorCameraD3D->_437143(a8b, v13->pVertices, this->pVertices, (unsigned int *)&v13->uNumVertices); + } + else if ( uClipFlags & 4 ) + { + //v40 = (int)&a8; + //v39 = this->pVertices; + pGame->pIndoorCameraD3D->_436F09_mess_with_lightmap__clipflag_4(v13->pVertices, v13->uNumVertices, this->pVertices, &a8b); + //v40 = (int)v31; + //v39 = this->pVertices; + pGame->pIndoorCameraD3D->_437143(a8b, v13->pVertices, this->pVertices, (unsigned int *)&v13->uNumVertices); + } + else + MessageBoxA(nullptr, "Undefined clip flag specified", "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\PolyProjector.cpp:258", 0); + } + else + MessageBoxA(nullptr, "Lightpoly builder native indoor clipping not implemented", "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\PolyProjector.cpp:263", 0); + if ( a8b != 0 ) + { + ++this->field_308008; + v34 = 1024; + if ( this->field_308008 == 1024 ) + this->field_308008 = 0; + if ( (signed int)(this->std__vector_pDecals_size + 1) <= 1024 ) + v34 = this->std__vector_pDecals_size + 1; + this->std__vector_pDecals_size = v34; + return 1; + } + result = 1; + } + return result; +} + +//----- (0049BBBD) -------------------------------------------------------- +bool DecalBuilder::ApplyBloodsplatDecals_IndoorFace(unsigned int uFaceID) +{ + double v7; // st7@12 + + uNumDecals = 0; + if (!pBloodsplatContainer->std__vector_pBloodsplats_size) + return true; + + BLVFace* pFace = &pIndoor->pFaces[uFaceID]; + + if ( pFace->Indoor_sky() || pFace->Fluid() ) + return true; + for (uint i = 0; i < pBloodsplatContainer->std__vector_pBloodsplats_size; ++i) + { + Bloodsplat* pBloodsplat = &pBloodsplatContainer->std__vector_pBloodsplats[i]; + if (pFace->pBounding.x1 - pBloodsplat->radius < pBloodsplat->x && + pFace->pBounding.x2 + pBloodsplat->radius > pBloodsplat->x && + pFace->pBounding.y1 - pBloodsplat->radius < pBloodsplat->y && + pFace->pBounding.y2 + pBloodsplat->radius > pBloodsplat->y && + pFace->pBounding.z1 - pBloodsplat->radius < pBloodsplat->z && + pFace->pBounding.z2 + pBloodsplat->radius > pBloodsplat->z) + { + v7 = pFace->pFacePlane.vNormal.z * pBloodsplat->z + + pFace->pFacePlane.vNormal.y * pBloodsplat->y + + pFace->pFacePlane.vNormal.x * pBloodsplat->x + + pFace->pFacePlane.dist; + if (v7 <= pBloodsplat->radius) + { + pBloodsplat->dot_dist = v7; + std__vector_30B00C[uNumDecals++] = i; + } + } + } + + return true; +} + +//----- (0049BCEB) -------------------------------------------------------- +char DecalBuilder::ApplyDecals_OutdoorFace(ODMFace *pFace) +{ + double v8; // st7@12 + //unsigned int v10; // [sp+20h] [bp-1Ch]@1 + + Bloodsplat *pBloodsplat; + + this->uNumDecals = 0; + //v10 = pBloodsplatContainer->std__vector_pBloodsplats_size; + if ( !pFace->Indoor_sky() && !pFace->Fluid() ) + { + for(int i = 0; i < pBloodsplatContainer->std__vector_pBloodsplats_size; i++ ) + { + pBloodsplat = &pBloodsplatContainer->std__vector_pBloodsplats[i]; + if ( (double)pFace->pBoundingBox.x1 - pBloodsplat->radius < pBloodsplat->x && + (double)pFace->pBoundingBox.x2 + pBloodsplat->radius > pBloodsplat->x && + (double)pFace->pBoundingBox.y1 - pBloodsplat->radius < pBloodsplat->y && + (double)pFace->pBoundingBox.y2 + pBloodsplat->radius > pBloodsplat->y && + (double)pFace->pBoundingBox.z1 - pBloodsplat->radius < pBloodsplat->z && + (double)pFace->pBoundingBox.z2 + pBloodsplat->radius > pBloodsplat->z ) + { + v8 = (double)((pFace->pFacePlane.dist + + round_to_int(pBloodsplat->x) * pFace->pFacePlane.vNormal.x + + round_to_int(pBloodsplat->y) * pFace->pFacePlane.vNormal.y + + round_to_int(pBloodsplat->z) * pFace->pFacePlane.vNormal.z) >> 16); + if ( v8 <= pBloodsplat->radius ) + { + pBloodsplat->dot_dist = v8; + this->std__vector_30B00C[this->uNumDecals++] = i; + } + } + } + } + return 1; +} + +//----- (0049BE8A) -------------------------------------------------------- +bool DecalBuilder::_49BE8A(struct Polygon *a2, Vec3_float_ *_a3, float *a4, RenderVertexSoft *a5, unsigned int uStripType, char a7) +{ + bool result; // eax@1 + //RenderVertexSoft *v8; // edi@3 + //Vec3_float_ *v9; // ebx@3 + //Bloodsplat *v10; // esi@3 + //float v11; // eax@5 + float v12; // eax@6 + //double v13; // st7@13 + double v14; // st7@19 + //short v15; // eax@20 + int v16; // eax@22 + //int v17; // edx@24 + //DecalBuilder *v18; // eax@24 + std::string v19; // [sp-18h] [bp-54h]@12 +// const char *v20; // [sp-8h] [bp-44h]@12 + //int v21; // [sp-4h] [bp-40h]@12 + double v22; // [sp+Ch] [bp-30h]@19 + unsigned int v23; // [sp+14h] [bp-28h]@1 + //DecalBuilder *v24; // [sp+18h] [bp-24h]@1 + //int v25; // [sp+1Ch] [bp-20h]@19 + float v26; // [sp+20h] [bp-1Ch]@12 +// int v27; // [sp+24h] [bp-18h]@12 + float v28; // [sp+28h] [bp-14h]@13 + //float v29; // [sp+2Ch] [bp-10h]@7 + float v30; // [sp+30h] [bp-Ch]@6 + float v31; // [sp+34h] [bp-8h]@6 + bool v32; // [sp+38h] [bp-4h]@2 + float a3; + + this->uNumDecals = 0; + result = pBloodsplatContainer->std__vector_pBloodsplats_size != 0; + // v24 = this; + v23 = pBloodsplatContainer->std__vector_pBloodsplats_size; + if ( pBloodsplatContainer->std__vector_pBloodsplats_size ) + { + + if ( (signed int)pBloodsplatContainer->std__vector_pBloodsplats_size > 0 ) + { + //v8 = a5; + //v9 = _a3; + for ( v32 = 0; v32 < (signed int)v23; ++v32 ) + { + if ( uStripType == 4 ) + { + a3 = a5->vWorldPosition.x; + //v11 = v8[3].vWorldPosition.x; + v31 = a5[3].vWorldPosition.x; + v30 = a5[1].vWorldPosition.y; + v12 = a5->vWorldPosition.y; + //v29 = v12; + } + else if ( uStripType == 3 ) + { + if ( a7 ) + { + a3 = a5->vWorldPosition.x; + v31 = a5[2].vWorldPosition.x; + v30 = a5[1].vWorldPosition.y; + v12 = a5[2].vWorldPosition.y; + //v29 = v12; + } + else + { + a3 = a5[1].vWorldPosition.x; + //v11 = v8[2].vWorldPosition.x; + v31 = a5[2].vWorldPosition.x; + v30 = a5[1].vWorldPosition.y; + v12 = a5->vWorldPosition.y; + //v29 = v12; + } + } + else + MessageBoxW(nullptr, L"Uknown strip type detected!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\PolyProjector.cpp:434", 0); + //v21 = uStripType; + //v13 = pGame->pIndoorCameraD3D->GetPolygonMinZ(v8, uStripType); + //v21 = uStripType; + v28 = pGame->pIndoorCameraD3D->GetPolygonMinZ(a5, uStripType); + v26 = pGame->pIndoorCameraD3D->GetPolygonMaxZ(a5, uStripType); + if ( a3 - pBloodsplatContainer->std__vector_pBloodsplats[v32].radius < pBloodsplatContainer->std__vector_pBloodsplats[v32].x && + v31 + pBloodsplatContainer->std__vector_pBloodsplats[v32].radius > pBloodsplatContainer->std__vector_pBloodsplats[v32].x && + v30 - pBloodsplatContainer->std__vector_pBloodsplats[v32].radius < pBloodsplatContainer->std__vector_pBloodsplats[v32].y && + v12 + pBloodsplatContainer->std__vector_pBloodsplats[v32].radius > pBloodsplatContainer->std__vector_pBloodsplats[v32].y && + v28 - pBloodsplatContainer->std__vector_pBloodsplats[v32].radius < pBloodsplatContainer->std__vector_pBloodsplats[v32].z && + v26 + pBloodsplatContainer->std__vector_pBloodsplats[v32].radius > pBloodsplatContainer->std__vector_pBloodsplats[v32].z ) + { + Vec3_float_::NegDot(&a5->vWorldPosition, _a3, a4); + v26 = _a3->y * pBloodsplatContainer->std__vector_pBloodsplats[v32].y + + _a3->z * pBloodsplatContainer->std__vector_pBloodsplats[v32].z + + _a3->x * pBloodsplatContainer->std__vector_pBloodsplats[v32].x + + *a4; + v22 = v26 + 6.7553994e15; + //v25 = LODWORD(v22); + v14 = (double)SLODWORD(v22); + v28 = v14; + if ( v14 <= pBloodsplatContainer->std__vector_pBloodsplats[v32].radius ) + { + //v15 = a2->flags; + if ( a2->flags & 2 || a2->flags & 0x100 ) + { + v16 = pBloodsplatContainer->std__vector_pBloodsplats[v32].field_1C; + if ( !(pBloodsplatContainer->std__vector_pBloodsplats[v32].field_1C & 1) ) + { + LOBYTE(v16) = v16 | 1; + pBloodsplatContainer->std__vector_pBloodsplats[v32].field_1C = v16; + pBloodsplatContainer->std__vector_pBloodsplats[v32].field_20 = pEventTimer->Time(); + } + } + //v17 = v32; + pBloodsplatContainer->std__vector_pBloodsplats[v32].dot_dist = LODWORD(v28); + //v18 = this; + this->std__vector_30B00C[this->uNumDecals] = v32; + ++this->uNumDecals; + } + } + //++v32; + //++v10; + result = v32; + } + } + } + LOBYTE(result) = 1; + return result; +} + + +//----- (0049C2CD) -------------------------------------------------------- +void DecalBuilder::DrawDecals(float z_bias) +{ + for (uint i = 0; i < std__vector_pDecals_size; ++i) + pRenderer->DrawDecal(std__vector_pDecals + i, z_bias); +} + +//----- (0049C304) -------------------------------------------------------- +void DecalBuilder::DrawBloodsplats() +{ + if (!std__vector_pDecals_size) + return; + + pRenderer->BeginDecals(); + + DrawDecals(0.00039999999); + + pRenderer->EndDecals(); +} + +//----- (0049C550) -------------------------------------------------------- +void DecalBuilder::DrawDecalDebugOutlines() +{ + for(int i = 0; i < std__vector_pDecals_size; i++) + pGame->pIndoorCameraD3D->debug_outline_sw(std__vector_pDecals[i].pVertices, std__vector_pDecals[i].uNumVertices, 0xC86400u, 0.0); +} + +//----- (0040E4C2) -------------------------------------------------------- +void Decal::Decal_base_ctor() +{ + uNumVertices = -1; + for (uint i = 0; i < 64; ++i) + pVertices[i].flt_2C = 0.0f; +} diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/DecalBuilder.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/DecalBuilder.h Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,206 @@ +#pragma once + +#include + +#include "Render.h" + +/* 158 */ +#pragma pack(push, 1) +struct Bloodsplat +{ + //----- (0043B538) -------------------------------------------------------- + inline Bloodsplat() + { + this->field_1C = 0; + this->field_20 = 0; + //this->field_24 = 0; + //this->vdestructor_ptr = &Bloodsplat_pvdtor; + } + + //----- (0043B54C) -------------------------------------------------------- + //void Bloodsplat::vdtor(Bloodsplat *this, char a2) + + //----- (0043B569) -------------------------------------------------------- + virtual ~Bloodsplat() + { + } + + //void ( ***vdestructor_ptr)(Bloodsplat *, bool); + float x; + float y; + float z; + float radius; + float dot_dist; + unsigned char r; + unsigned char g; + unsigned char b; + char field_1B; + int field_1C; + unsigned long long field_20; + //int field_24; +}; +#pragma pack(pop) + +/* 159 */ +#pragma pack(push, 1) +struct BloodsplatContainer +{ + //----- (0043B688) -------------------------------------------------------- + inline BloodsplatContainer() + { + /*_eh_vector_constructor_iterator_( + this->std__vector_pBloodsplats, + 40, + 64, + (void ( *)(void *))Bloodsplat::Bloodsplat, + (void ( *)(void *))Bloodsplat::dtor); + v1->std__vector_pBloodsplats_size = 0;*/ + uNumBloodsplats = 0; + } + //----- (0043B6D6) -------------------------------------------------------- + virtual ~BloodsplatContainer() + { + //this->vdestructor_ptr = &BloodsplatContainer_pvdtor; + //_eh_vector_destructor_iterator_(this->std__vector_pBloodsplats, 40, 64, Bloodsplat::dtor); + } + + + void AddBloodsplat(float x, float y, float z, float r, float g, float b, float radius, int a8, int a9); + void AddBloodsplat(float x, float y, float z, float radius, unsigned char r, unsigned char g, unsigned char b); + + + //void ( ***vdestructor_ptr)(BloodsplatContainer *, bool); + Bloodsplat std__vector_pBloodsplats[64]; + unsigned int std__vector_pBloodsplats_size; + int uNumBloodsplats; +}; +#pragma pack(pop) + +extern struct BloodsplatContainer *pBloodsplatContainer; // idb + +#pragma pack(push, 1) +struct DecalBuilder_stru0 +{ + double _43B570_get_color_mult_by_time(); + + int field_0; + int field_4; + int field_8; + int field_C; + int field_10; + int field_14; + int field_18; + int field_1C_flags; + __int64 field_20_time; +}; +#pragma pack(pop) + + + +/* 181 */ +#pragma pack(push, 1) +struct Decal +{ + void Decal_base_ctor(); + //----- (0043B60C) -------------------------------------------------------- + inline Decal() + { + Decal_base_ctor(); + field_C1C = 0; + } + + //----- (0043B625) -------------------------------------------------------- + //void Decal::vdtor(Decal *this, bool a2) + //----- (0043B641) -------------------------------------------------------- + virtual ~Decal() + { + } + + //void ( ***vdestructor_ptr)(Decal *, bool); + int uNumVertices; + RenderVertexSoft pVertices[64]; + __int16 field_C08; + __int16 field_C0A; + __int16 field_C0C; + __int16 field_C0E; + uint32_t uColorMultiplier; + int field_C14; + DecalBuilder_stru0 *field_C18; + int field_C1C; +}; +#pragma pack(pop) + +/* 180 */ +#pragma pack(push, 1) +struct DecalBuilder +{ + //----- (0049B408) -------------------------------------------------------- + DecalBuilder() + { + char *v2; // eax@1 + signed int v3; // ecx@1 + + DecalBuilder* v1 = this; + /*_eh_vector_constructor_iterator_( + this->std__vector_pDecals, + 3104, + 1024, + (void ( *)(void *))Decal::Decal, + (void ( *)(void *))Decal::dtor);*/ + v1->std__vector_pDecals_size = 0; + v1->field_308008 = 0; + v2 = (char *)&v1->pVertices[0].flt_2C; + v3 = 256; + do + { + *(float *)v2 = 0.0; + v2 += 48; + --v3; + } + while ( v3 ); + } + + //----- (0049B471) -------------------------------------------------------- + virtual ~DecalBuilder() + {} + + + void AddBloodsplat(float x, float y, float z, float r, float g, float b, float radius, int a8, int a9); + void Reset(unsigned int bPreserveBloodsplats); + char ApplyDecals(int light_level, char a3, struct stru154 *a4, int a5, struct RenderVertexSoft *a6, struct IndoorCameraD3D_Vec4 *a7, char a8, unsigned int uSectorID); + char _49B790_build_decal_geometry(int a2, char a3, Bloodsplat *a4, int a5, float a6, unsigned int uColorMultiplier, float a8, struct stru314 *a9, signed int a10, struct RenderVertexSoft *a11, char uClipFlags); + bool ApplyBloodsplatDecals_IndoorFace(unsigned int uFaceID); + char ApplyDecals_OutdoorFace(ODMFace *pFace); + bool _49BE8A(struct Polygon *a2, Vec3_float_ *a3, float *a4, struct RenderVertexSoft *a5, unsigned int uStripType, char a7); + void DrawDecals(float z_bias); + void DrawBloodsplats(); + void DrawDecalDebugOutlines(); + + + + //void ( ***vdestructor_ptr)(DecalBuilder *, bool); + Decal std__vector_pDecals[1024]; + unsigned int std__vector_pDecals_size; + int field_308008; + RenderVertexSoft pVertices[256]; + int std__vector_30B00C[1024]; + int uNumDecals; + float field_30C010; + float field_30C014; + float field_30C018; + float field_30C01C; + float field_30C020; + float field_30C024; + float field_30C028; + float field_30C02C; + float flt_30C030; + float field_30C034; +}; +#pragma pack(pop) + +extern struct DecalBuilder *pDecalBuilder; + + + + + diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/DecorationList.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/DecorationList.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,294 @@ +#define _CRTDBG_MAP_ALLOC +#include +#include + +#define _CRT_SECURE_NO_WARNINGS +#include "Sprites.h" +#include "DecorationList.h" +#include "FrameTableInc.h" +#include "mm7_data.h" +#include "ErrorHandling.h" +#include "stru123.h" +#include "Engine/Graphics/Level\Decoration.h" + +struct DecorationList *pDecorationList; + +//----- (0045864C) -------------------------------------------------------- +void DecorationList::FromFile(void *data_mm6, void *data_mm7, void *data_mm8) +{ + uint num_mm6_decs = data_mm6 ? *(int *)data_mm6 : 0, + num_mm7_decs = data_mm7 ? *(int *)data_mm7 : 0, + num_mm8_decs = data_mm8 ? *(int *)data_mm8 : 0; + + uNumDecorations = num_mm6_decs + num_mm7_decs + num_mm8_decs; + Assert(uNumDecorations); + Assert(!num_mm8_decs); + + pDecorations = (DecorationDesc *)malloc(uNumDecorations * sizeof(DecorationDesc)); + memcpy(pDecorations, (char *)data_mm7 + 4, num_mm7_decs * sizeof(DecorationDesc)); + for (uint i = 0; i < num_mm6_decs; ++i) + { + memcpy(pDecorations + num_mm7_decs + i, (char *)data_mm6 + 4 + i * sizeof(DecorationDesc_mm6), sizeof(DecorationDesc_mm6)); + pDecorations[num_mm7_decs + i].uColoredLightRed = 255; + pDecorations[num_mm7_decs + i].uColoredLightGreen = 255; + pDecorations[num_mm7_decs + i].uColoredLightBlue = 255; + pDecorations[num_mm7_decs + i].__padding = 255; + } + memcpy(pDecorations + num_mm6_decs + num_mm7_decs, (char *)data_mm8 + 4, num_mm8_decs * sizeof(DecorationDesc)); +} + +//----- (00458693) -------------------------------------------------------- +void DecorationList::InitializeDecorationSprite(unsigned int uDecID) +{ + pSpriteFrameTable->InitializeSprite(this->pDecorations[uDecID].uSpriteID); +} + +//----- (004586B0) -------------------------------------------------------- +bool DecorationList::FromFileTxt(const char *Args) +{ + DecorationList *v2; // ebx@1 + FILE *v3; // eax@1 + unsigned int v4; // esi@3 + void *v5; // eax@10 + FILE *v6; // ST18_4@12 + char *i; // eax@12 + unsigned __int16 v8; // ax@16 + //const char *v9; // ST20_4@16 + //const char *v10; // ST18_4@16 + //__int16 v11; // ax@16 + //const char *v12; // ST14_4@16 + //unsigned __int16 v13; // ax@16 +// const char *v14; // ST10_4@16 + //__int16 v15; // ax@16 +// const char *v16; // ST0C_4@16 +// unsigned __int8 v17; // al@16 +// const char *v18; // ST08_4@16 +// unsigned __int8 v19; // al@16 +// const char *v20; // ST04_4@16 +// unsigned __int8 v21; // al@16 +// const char *v22; // ST00_4@16 + unsigned __int8 v23; // zf@16 + char v24; // sf@16 + unsigned __int8 v25; // of@16 + int j; // edi@17 + const char *v27; // esi@18 + int v29; // eax@21 + int v30; // eax@23 + int v31; // eax@25 + int v32; // eax@27 + int v33; // eax@29 + int v34; // eax@31 + int v35; // eax@33 + FrameTableTxtLine v37; // [sp+Ch] [bp-460h]@17 + FrameTableTxtLine v38; // [sp+88h] [bp-3E4h]@13 + char Dest; // [sp+104h] [bp-368h]@17 + char Buf; // [sp+17Ch] [bp-2F0h]@3 + FrameTableTxtLine v41; // [sp+370h] [bp-FCh]@4 + FrameTableTxtLine v42; // [sp+3ECh] [bp-80h]@4 + FILE *File; // [sp+468h] [bp-4h]@1 + unsigned int Argsa; // [sp+474h] [bp+8h]@3 + + v2 = this; + v3 = fopen(Args, "r"); + File = v3; + if ( !v3 ) + Error("DecorationDescriptionList::load - Unable to open file: %s."); + + v4 = 0; + Argsa = 0; + if ( fgets(&Buf, 490, v3) ) + { + do + { + *strchr(&Buf, 10) = 0; + memcpy(&v42, frame_table_txt_parser(&Buf, &v41), sizeof(v42)); + if ( v42.uPropCount && *v42.pProperties[0] != 47 && v42.uPropCount >= 3 ) + ++Argsa; + } + while ( fgets(&Buf, 490, File) ); + v4 = Argsa; + } + v2->uNumDecorations = v4; + v5 = malloc(84 * v4); + v2->pDecorations = (DecorationDesc *)v5; + if ( !v5 ) + Error("DecorationDescriptionList::load - Out of Memory!"); + + v6 = File; + v2->uNumDecorations = 0; + fseek(v6, 0, 0); + for ( i = fgets(&Buf, 490, File); i; i = fgets(&Buf, 490, File) ) + { + *strchr(&Buf, 10) = 0; + memcpy(&v42, frame_table_txt_parser(&Buf, &v38), sizeof(v42)); + if ( v42.uPropCount && *v42.pProperties[0] != 47 && v42.uPropCount >= 3 ) + { + strcpy(v2->pDecorations[v2->uNumDecorations].pName, v42.pProperties[1]); + v8 = pSpriteFrameTable->FastFindSprite(v2->pDecorations[v2->uNumDecorations].pName); + //v9 = v42.pProperties[2]; + v2->pDecorations[v2->uNumDecorations].uSpriteID = v8; + strcpy(v2->pDecorations[v2->uNumDecorations].field_20, v42.pProperties[2]); + //v10 = v42.pProperties[3]; + v2->pDecorations[v2->uNumDecorations].uType = 0; + //v11 = atoi(v42.pProperties[3]); + //v12 = v42.pProperties[4]; + v2->pDecorations[v2->uNumDecorations].uRadius = atoi(v42.pProperties[3]); + //v13 = atoi(v42.pProperties[4]); + //v14 = v42.pProperties[5]; + v2->pDecorations[v2->uNumDecorations].uDecorationHeight = atoi(v42.pProperties[4]); + //v15 = atoi(v42.pProperties[5]); + //v16 = v42.pProperties[6]; + v2->pDecorations[v2->uNumDecorations].uLightRadius = atoi(v42.pProperties[5]); + //v17 = atoi(v42.pProperties[6]); + //v18 = v42.pProperties[7]; + v2->pDecorations[v2->uNumDecorations].uColoredLightRed = atoi(v42.pProperties[6]); + //v19 = atoi(v42.pProperties[7]); + //v20 = v42.pProperties[8]; + v2->pDecorations[v2->uNumDecorations].uColoredLightGreen = atoi(v42.pProperties[7]); + //v21 = atoi(v42.pProperties[8]); + //v22 = v42.pProperties[9]; + v2->pDecorations[v2->uNumDecorations].uColoredLightBlue = atoi(v42.pProperties[8]); + v2->pDecorations[v2->uNumDecorations].uSoundID = atoi(v42.pProperties[9]); + __debugbreak();//Ritor1: need cleaning + v25 = __OFSUB__(v42.uPropCount, 10); + v23 = v42.uPropCount == 10; + v24 = v42.uPropCount - 10 < 0; + v2->pDecorations[v2->uNumDecorations].uFlags = 0; + if ( !((unsigned __int8)(v24 ^ v25) | v23) ) + { + strcpy(&Dest, v42.pProperties[10]); + memcpy(&v41, frame_table_txt_parser(&Dest, &v37), sizeof(v41)); + for ( j = 0; j < v41.uPropCount; ++j ) + { + v27 = v41.pProperties[j]; + if ( _stricmp(v41.pProperties[j], "NBM") ) + { + if ( _stricmp(v27, "Invisible") ) + { + if ( _stricmp(v27, "FS") ) + { + if ( _stricmp(v27, "FM") ) + { + if ( _stricmp(v27, "FF") ) + { + if ( _stricmp(v27, "Marker") ) + { + if ( _stricmp(v27, "LoopSlow") ) + { + if ( _stricmp(v27, "EmitFire") ) + { + if ( _stricmp(v27, "Dawn") ) + { + if ( !_stricmp(v27, "Dusk") ) + HIBYTE(v2->pDecorations[v2->uNumDecorations].uFlags) |= 2u; + } + else + { + HIBYTE(v2->pDecorations[v2->uNumDecorations].uFlags) |= 1u; + } + } + else + { + v35 = (int)&v2->pDecorations[v2->uNumDecorations].uFlags; + *(char *)v35 |= 0x80u; + } + } + else + { + v34 = (int)&v2->pDecorations[v2->uNumDecorations].uFlags; + *(char *)v34 |= 0x40u; + } + } + else + { + v33 = (int)&v2->pDecorations[v2->uNumDecorations].uFlags; + *(char *)v33 |= 0x20u; + } + } + else + { + v32 = (int)&v2->pDecorations[v2->uNumDecorations].uFlags; + *(char *)v32 |= 0x10u; + } + } + else + { + v31 = (int)&v2->pDecorations[v2->uNumDecorations].uFlags; + *(char *)v31 |= 8u; + } + } + else + { + v30 = (int)&v2->pDecorations[v2->uNumDecorations].uFlags; + *(char *)v30 |= 4u; + } + } + else + { + v29 = (int)&v2->pDecorations[v2->uNumDecorations].uFlags; + *(char *)v29 |= 2u; + } + } + else + v2->pDecorations[v2->uNumDecorations].uFlags |= 1; + } + } + ++v2->uNumDecorations; + } + } + fclose(File); + return 1; +} +//----- (00458600) -------------------------------------------------------- +void DecorationList::ToFile() +{ + FILE *v2; // eax@1 + FILE *v3; // edi@1 + + v2 = fopen("data\\ddeclist.bin", "wb"); + v3 = v2; + if ( !v2 ) + Error("Unable to save ddeclist.bin!"); + + fwrite(this, 4, 1, v2); + fwrite(this->pDecorations, 84, this->uNumDecorations, v3); + fclose(v3); +} +//----- (004488B6) -------------------------------------------------------- +unsigned __int16 DecorationList::GetDecorIdByName(const char *pName) +{ + if ( pName && (signed int)this->uNumDecorations > 1 ) + { + for ( uint uID = 1; uID < (signed int)this->uNumDecorations; ++uID ) + { + if ( !_stricmp(pName, this->pDecorations[uID].pName) ) + return uID; + } + } + return 0; +} + + +//----- (00450AAA) -------------------------------------------------------- +void RespawnGlobalDecorations() +{ + memset(stru_5E4C90_MapPersistVars._decor_events.data(), 0, 125); + + uint decorEventIdx = 0; + for (uint i = 0; i < uNumLevelDecorations; ++i) + { + LevelDecoration* decor = &pLevelDecorations[i]; + + if (!decor->uEventID) + { + if (decor->IsInteractive()) + { + if (decorEventIdx < 124) + { + decor->_idx_in_stru123 = decorEventIdx + 75; + stru_5E4C90_MapPersistVars._decor_events[decorEventIdx++] = decor->GetGlobalEvent(); + } + } + } + } +} \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/DecorationList.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/DecorationList.h Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,80 @@ +#pragma once + + + + +/* 321 */ +enum DECORATION_DESC_FLAGS +{ + DECORATION_DESC_MOVE_THROUGH = 0x0001, + DECORATION_DESC_DONT_DRAW = 0x0002, + DECORATION_DESC_FLICKER_SLOW = 0x0004, + DECORATION_DESC_FICKER_AVERAGE = 0x0008, + DECORATION_DESC_FICKER_FAST = 0x0010, + DECORATION_DESC_MARKER = 0x0020, + DECORATION_DESC_SLOW_LOOP = 0x0040, + DECORATION_DESC_EMITS_FIRE = 0x0080, + DECORATION_DESC_SOUND_ON_DAWN = 0x0100, + DECORATION_DESC_SOUND_ON_DUSK = 0x0200, + DECORATION_DESC_EMITS_SMOKE = 0x0400, +}; + + + +/* 54 */ +#pragma pack(push, 1) +struct DecorationDesc_mm6 +{ + inline bool CanMoveThrough() {return (uFlags & DECORATION_DESC_MOVE_THROUGH) != 0;} + inline bool DontDraw() {return (uFlags & DECORATION_DESC_DONT_DRAW) != 0;} + inline bool SoundOnDawn() {return (uFlags & DECORATION_DESC_SOUND_ON_DAWN) != 0;} + inline bool SoundOnDusk() {return (uFlags & DECORATION_DESC_SOUND_ON_DUSK) != 0;} + + char pName[32]; + char field_20[32]; + __int16 uType; + unsigned __int16 uDecorationHeight; + __int16 uRadius; + __int16 uLightRadius; + unsigned __int16 uSpriteID; + __int16 uFlags; + __int16 uSoundID; + __int16 _pad; + //unsigned __int8 uColoredLightRed; + //unsigned __int8 uColoredLightGreen; + //unsigned __int8 uColoredLightBlue; + //char __padding; +}; + +struct DecorationDesc: public DecorationDesc_mm6 +{ + unsigned __int8 uColoredLightRed; + unsigned __int8 uColoredLightGreen; + unsigned __int8 uColoredLightBlue; + char __padding; +}; +#pragma pack(pop) + +/* 55 */ +#pragma pack(push, 1) +struct DecorationList +{ + inline DecorationList(): //----- (00458380) + pDecorations(nullptr), uNumDecorations(0) + {} + + void ToFile(); + void FromFile(void *data_mm6, void *data_mm7, void *data_mm8); + bool FromFileTxt(const char *Args); + void InitializeDecorationSprite(unsigned int uDecID); + unsigned __int16 GetDecorIdByName(const char *pName); + + unsigned int uNumDecorations; + struct DecorationDesc *pDecorations; +}; +#pragma pack(pop) + + +extern struct DecorationList *pDecorationList; + +void RespawnGlobalDecorations(); \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/GammaControl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/GammaControl.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,142 @@ +#define _CRTDBG_MAP_ALLOC +#include +#include + +#define _CRT_SECURE_NO_WARNINGS +#include + +#include "GammaControl.h" +#include "Render.h" + +#include "mm7_data.h" + + + +//----- (0044F324) -------------------------------------------------------- +void GammaController::GetRamp() +{ + if (pGammaControl) + ErrD3D(pGammaControl->GetGammaRamp(0, &pDefaultRamp)); + else + MessageBoxW(nullptr, L"Gamma control not active", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\GammaControl.cpp:83", 0); +} + +//----- (0044F377) -------------------------------------------------------- +double GammaController::_44F377(DDGAMMARAMP *a1) +{ + double v2; // st7@1 + unsigned __int16 *v3; // ecx@1 + double v4; // st6@2 + signed int v6; // [sp+0h] [bp-8h]@1 + signed int v7; // [sp+4h] [bp-4h]@1 + + v2 = 0.0; + v6 = 256; + v3 = a1->green; + for ( v7 = 0; v7 < 256; ++v7 ) + { + v4 = ((double)*(v3 - 256) + (double)v3[256] + (double)*v3) * 0.000015259022 * 0.33333334; + if ( v4 == 0.0 ) + --v6; + else + v2 = v2 + (double)v7 * 0.0039215689 / v4; + ++v3; + } + if ( v6 ) + return v2 / (double)v6; + else + return 1.0; +} + +//----- (0044F408) -------------------------------------------------------- +void GammaController::SetGammaRamp(DDGAMMARAMP *pRamp) +{ + if (pGammaControl) + ErrD3D(pGammaControl->SetGammaRamp(0, pRamp)); + else + MessageBoxW(nullptr, L"Gamma control not active", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\GammaControl.cpp:120", 0); +} + +//----- (0044F45B) -------------------------------------------------------- +int GammaController::InitGammaRamp(DDGAMMARAMP *pRamp) +{ + unsigned __int16 *v2; // esi@1 + double v3; // st7@2 + signed __int64 v4; // qax@3 + signed int v6; // [sp+Ch] [bp-4h]@1 + + v2 = pRamp->green; + for ( v6 = 0; v6 < 256; ++v6 ) + { + v3 = (double)v6 * 0.0039215689 * this->fGamma; + if ( v3 >= 1.0 || (v4 = (signed __int64)(v3 * 65535.0), (signed int)v4 > 65535) ) + LODWORD(v4) = 65535; + else if ( (signed int)v4 < 0 ) + LODWORD(v4) = 0; + else + { + if ( (signed int)v4 > 65535 ) + LODWORD(v4) = 65535; + } + v2[256] = v4; + *v2 = v4; + *(v2 - 256) = v4; + ++v2; + } + return v4; +} + +//----- (0044F4D9) -------------------------------------------------------- +void GammaController::Initialize(float gamma) +{ + double v3; // st7@3 + double v4; // st6@4 + + //if (pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || + //pVersion->pVersionInfo.dwMajorVersion != 4) + { + InitializeFromSurface(pRenderer->pFrontBuffer4); + v3 = 2.8; + if ( gamma <= 2.8f ) + v4 = gamma; + else + v4 = 2.8; + if ( v4 >= 0.1f ) + { + if ( gamma <= 2.8f ) + v3 = gamma; + } + else + v3 = 0.1; + this->fGamma = v3; + InitGammaRamp(&this->field_60C); + SetGammaRamp(&this->field_60C); + } +} + +//----- (0044F215) -------------------------------------------------------- +GammaController::GammaController() +{ + static float flt_4D8670_default_gamma = 1.0f; + + pGammaControl = nullptr; + fGamma = flt_4D8670_default_gamma; +} + +//----- (0044F24B) -------------------------------------------------------- +void GammaController::InitializeFromSurface(IDirectDrawSurface4 *a2) +{ + this->pSurface = a2; + if ( this->pGammaControl ) + { + this->pGammaControl->Release(); + this->pGammaControl = 0; + } + if ( pRenderer->IsGammaSupported() ) + { + ErrD3D(a2->QueryInterface(IID_IDirectDrawGammaControl, (LPVOID *)&this->pGammaControl)); + GetRamp(); + memcpy(&this->field_60C, &this->pDefaultRamp, 0x600u); + fGamma = _44F377(&this->field_60C); + } +} \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/GammaControl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/GammaControl.h Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,29 @@ +#pragma once +#include "lib\legacy_dx\d3d.h" + +#pragma pack(push, 1) +class GammaController +{ +public: + GammaController(); + inline ~GammaController() {} //----- (0044F22E) + + void Initialize/*_44F4D9*/(float gamma); + + void GetRamp(); + double _44F377(DDGAMMARAMP *a1); + void SetGammaRamp(DDGAMMARAMP *pRamp); + int InitGammaRamp(DDGAMMARAMP *pRamp); + + /*protected*/void InitializeFromSurface(struct IDirectDrawSurface4 *a2); + + + + void ( ***vdestructor_ptr)(GammaController *, bool); + IDirectDrawSurface4 *pSurface; + IDirectDrawGammaControl *pGammaControl; + DDGAMMARAMP pDefaultRamp; + DDGAMMARAMP field_60C; + float fGamma;//field_C0C; +}; +#pragma pack(pop) diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/IRender.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/IRender.h Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,169 @@ +#pragma once + +#include "lib\legacy_dx\d3d.h" +#include "OSWindow.h" +#include "RenderStruct.h" +#include "VectorTypes.h" + +struct IRender +{ + public: + virtual ~IRender() {} + + virtual bool Initialize(OSWindow *window) = 0; + + virtual void ClearBlack() = 0; + virtual void PresentBlackScreen() = 0; + + virtual void SaveWinnersCertificate(const char *a1) = 0; + virtual void ClearTarget(unsigned int uColor) = 0; + virtual void Present() = 0; + + virtual void _49FD3A_fullscreen() = 0; + virtual bool InitializeFullscreen() = 0; + + virtual void CreateZBuffer() = 0; + virtual void Release() = 0; + + virtual bool SwitchToWindow() = 0; + virtual void RasterLine2D(signed int uX, signed int uY, signed int uZ, signed int uW, unsigned __int16 uColor) = 0; + virtual void ClearZBuffer(int a2, int a3) = 0; + virtual void SetRasterClipRect(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW) = 0; + virtual bool LockSurface_DDraw4(IDirectDrawSurface4 *pSurface, DDSURFACEDESC2 *pDesc, unsigned int uLockFlags) = 0; + virtual void GetTargetPixelFormat(DDPIXELFORMAT *pOut) = 0; + virtual void LockRenderSurface(void **pOutSurfacePtr, unsigned int *pOutPixelsPerRow) = 0; + virtual void UnlockBackBuffer() = 0; + virtual void LockFrontBuffer(void **pOutSurface, unsigned int *pOutPixelsPerRow) = 0; + virtual void UnlockFrontBuffer() = 0; + virtual void RestoreFrontBuffer() = 0; + virtual void RestoreBackBuffer() = 0; + virtual void BltToFront(RECT *pDstRect, IDirectDrawSurface *pSrcSurface, RECT *pSrcRect, unsigned int uBltFlags) = 0; + virtual void BltBackToFontFast(int a2, int a3, RECT *a4) = 0; + virtual void BeginSceneD3D() = 0; + + virtual unsigned int GetActorTintColor(float a2, int tint, int a4, int a5, RenderBillboard *a6) = 0; + + virtual void DrawPolygon(unsigned int uNumVertices, struct Polygon *a3, ODMFace *a4, IDirect3DTexture2 *pTexture) = 0; + virtual void DrawTerrainPolygon(unsigned int uNumVertices, struct Polygon *a4, IDirect3DTexture2 *a5, bool transparent, bool clampAtTextureBorders) = 0; + virtual void DrawIndoorPolygon(unsigned int uNumVertices, struct BLVFace *a3, IDirect3DTexture2 *pHwTex, struct Texture *pTex, int uPackedID, unsigned int uColor, int a8) = 0; + + virtual void MakeParticleBillboardAndPush_BLV(RenderBillboardTransform_local0 *a2, IDirect3DTexture2 *a3, unsigned int uDiffuse, int angle) = 0; + virtual void MakeParticleBillboardAndPush_ODM(RenderBillboardTransform_local0 *a2, IDirect3DTexture2 *a3, unsigned int uDiffuse, int angle) = 0; + + virtual void DrawBillboards_And_MaybeRenderSpecialEffects_And_EndScene() = 0; + virtual void DrawBillboard_Indoor(RenderBillboardTransform_local0 *pSoftBillboard, Sprite *pSprite, int dimming_level) = 0; + virtual void _4A4CC9_AddSomeBillboard(struct stru6_stru1_indoor_sw_billboard *a1, int diffuse) = 0; + virtual void TransformBillboardsAndSetPalettesODM() = 0; + virtual void DrawBillboardList_BLV() = 0; + + virtual void DrawProjectile(float srcX, float srcY, float a3, float a4, float dstX, float dstY, float a7, float a8, IDirect3DTexture2 *a9) = 0; + virtual bool LoadTexture(const char *pName, unsigned int bMipMaps, IDirectDrawSurface4 **pOutSurface, IDirect3DTexture2 **pOutTexture) = 0; + virtual bool MoveSpriteToDevice(Sprite *pSprite) = 0; + + virtual void BeginScene() = 0; + virtual void EndScene() = 0; + virtual void ScreenFade(unsigned int color, float t) = 0; + + virtual void SetTextureClipRect(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW) = 0; + virtual void ResetTextureClipRect() = 0; + virtual void DrawTextureRGB(unsigned int uOutX, unsigned int uOutY, RGBTexture *a4) = 0; + virtual void CreditsTextureScroll(unsigned int pX, unsigned int pY, int move_X, int move_Y, RGBTexture *pTexture) = 0; + virtual void DrawTextureIndexed(unsigned int uX, unsigned int uY, struct Texture *a4) = 0; + + virtual void ZBuffer_Fill_2(signed int a2, signed int a3, struct Texture *pTexture, int a5) = 0; + virtual void DrawMaskToZBuffer(signed int uOutX, unsigned int uOutY, struct Texture *pTexture, int zVal) = 0; + virtual void DrawTextureTransparent(unsigned int uX, unsigned int uY, struct Texture *pTexture) = 0; + virtual void DrawAura(unsigned int a2, unsigned int a3, struct Texture *a4, struct Texture *a5, int a6, int a7, int a8) = 0; + virtual void _4A65CC(unsigned int x, unsigned int y, struct Texture *a4, struct Texture *a5, int a6, int a7, int a8) = 0; + + virtual void DrawTransparentRedShade(unsigned int a2, unsigned int a3, struct Texture *a4) = 0; + virtual void DrawTransparentGreenShade(signed int a2, signed int a3, struct Texture *pTexture) = 0; + virtual void DrawFansTransparent(const RenderVertexD3D3 *vertices, unsigned int num_vertices) = 0; + + virtual void DrawMasked(signed int a2, signed int a3, struct Texture *pTexture, unsigned __int16 mask) = 0; + virtual void GetLeather(unsigned int a2, unsigned int a3, struct Texture *a4, __int16 height) = 0; + + virtual void DrawTextPalette(int x, int y, unsigned char* font_pixels, int a5, unsigned int uFontHeight, unsigned __int16 *pPalette, int a8) = 0; + virtual void DrawText(signed int uOutX, signed int uOutY, unsigned __int8 *pFontPixels, unsigned int uCharWidth, unsigned int uCharHeight, unsigned __int16 *pFontPalette, unsigned __int16 uFaceColor, unsigned __int16 uShadowColor) = 0; + + virtual void FillRectFast(unsigned int uX, unsigned int uY, unsigned int uWidth, unsigned int uHeight, unsigned int uColor16) = 0; + virtual void _4A6DF5(unsigned __int16 *pBitmap, unsigned int uBitmapPitch, struct Vec2_int_ *pBitmapXY, void *pTarget, unsigned int uTargetPitch, Vec4_int_ *a7) = 0; + virtual void DrawTranslucent(unsigned int a2, unsigned int a3, struct Texture *a4) = 0; + + virtual void DrawBuildingsD3D() = 0; + + virtual void DrawIndoorSky(unsigned int uNumVertices, unsigned int uFaceID = 0) = 0; + virtual void DrawOutdoorSkyD3D() = 0; + virtual void DrawOutdoorSkyPolygon(unsigned int uNumVertices, struct Polygon *pSkyPolygon, IDirect3DTexture2 *pTexture) = 0; + virtual void DrawIndoorSkyPolygon(signed int uNumVertices, struct Polygon *pSkyPolygon, IDirect3DTexture2 *pTexture) = 0; + + virtual void PrepareDecorationsRenderList_ODM() = 0; + virtual void DrawSpriteObjects_ODM() = 0; + + virtual void RenderTerrainD3D() = 0; + + virtual void ChangeBetweenWinFullscreenModes() = 0; + virtual bool AreRenderSurfacesOk() = 0; + virtual bool IsGammaSupported() = 0; + + virtual void SaveScreenshot(const char *pFilename, unsigned int width, unsigned int height) = 0; + virtual void PackScreenshot(unsigned int width, unsigned int height, void *out_data, unsigned int data_size, unsigned int *screenshot_size) = 0; + virtual void SavePCXScreenshot() = 0; + + virtual int _46А6АС_GetActorsInViewport(int pDepth) = 0; + + virtual void BeginLightmaps() = 0; + virtual void EndLightmaps() = 0; + virtual void BeginLightmaps2() = 0; + virtual void EndLightmaps2() = 0; + virtual bool DrawLightmap(struct Lightmap *pLightmap, struct Vec3_float_ *pColorMult, float z_bias) = 0; + + virtual void BeginDecals() = 0; + virtual void EndDecals() = 0; + virtual void DrawDecal(struct Decal *pDecal, float z_bias) = 0; + + virtual void do_draw_debug_line_d3d(const RenderVertexD3D3 *pLineBegin, signed int sDiffuseBegin, const RenderVertexD3D3 *pLineEnd, signed int sDiffuseEnd, float z_stuff) = 0; + virtual void DrawLines(const RenderVertexD3D3 *vertices, unsigned int num_vertices) = 0; + + virtual void DrawSpecialEffectsQuad(const RenderVertexD3D3 *vertices, IDirect3DTexture2 *texture) = 0; + + virtual void am_Blt_Copy(RECT *pSrcRect, POINT *pTargetXY, int a3) = 0; + virtual void am_Blt_Chroma(RECT *pSrcRect, POINT *pTargetPoint, int a3, int blend_mode) = 0; + + + + + + + + + + int *pActiveZBuffer; + IDirectDraw4 *pDirectDraw4; + IDirectDrawSurface4 *pFrontBuffer4; + IDirectDrawSurface4 *pBackBuffer4; + void *pTargetSurface; + unsigned int uTargetSurfacePitch; + unsigned int bUseColoredLights; + unsigned int bTinting; + unsigned int bUsingSpecular; + uint32_t uFogColor; + unsigned int pHDWaterBitmapIDs[7]; + int hd_water_current_frame; + int hd_water_tile_id; + void (*pBeforePresentFunction)(); + uint32_t bFogEnabled; + RenderBillboardD3D pBillboardRenderListD3D[1000]; + unsigned int uNumBillboardsToDraw; + + virtual void WritePixel16(int x, int y, unsigned __int16 color) = 0; + virtual unsigned __int16 ReadPixel16(int x, int y) = 0; + + virtual void ToggleTint() = 0; + virtual void ToggleColoredLights() = 0; + + virtual unsigned int GetRenderWidth() = 0; + virtual unsigned int GetRenderHeight() = 0; + + virtual void Sub01() = 0; +}; \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/Indoor.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/Indoor.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,6446 @@ +#define _CRTDBG_MAP_ALLOC +#include +#include + +#define _CRT_SECURE_NO_WARNINGS +#include "ErrorHandling.h" +#include "ZlibWrapper.h" + +#include "LightmapBuilder.h" +#include "DecalBuilder.h" +#include "stru9.h" +#include "stru10.h" +#include "stru367.h" + +#include "Outdoor.h" +#include "SpriteObject.h" +#include "Events.h" +#include "Game.h" +#include "Viewport.h" +#include "Timer.h" +#include "Party.h" +#include "OurMath.h" +#include "LOD.h" +#include "DecorationList.h" +#include "ObjectList.h" +#include "Actor.h" +#include "Chest.h" +#include "GUIProgressBar.h" +#include "stru123.h" +#include "AudioPlayer.h" +#include "Log.h" +#include "TurnEngine.h" +#include "PaletteManager.h" +#include "Lights.h" + +#include "MM7.h" +#include "Sprites.h" +#include "stru6.h" +#include "ParticleEngine.h" +#include "texts.h" +#include "GUIWindow.h" +#include "Engine/Graphics/Level/Decoration.h" +#include "Overlays.h" + + + +IndoorLocation *pIndoor = new IndoorLocation; +BLVRenderParams *pBLVRenderParams = new BLVRenderParams; + + +LEVEL_TYPE uCurrentlyLoadedLevelType = LEVEL_null; + +stru320 stru_F8AD28; // idb +stru337 stru_F81018; +BspRenderer_PortalViewportData stru_F8A590; +BspRenderer *pBspRenderer = new BspRenderer; // idb +stru141_actor_collision_object stru_721530; +std::array stru_F83B80; + + + +unsigned __int16 pDoorSoundIDsByLocationID[78] = +{ + 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, + 300, 300, 300, 404, 302, 306, 308, 304, 308, 302, 400, 302, 300, + 308, 308, 306, 308, 308, 304, 300, 404, 406, 300, 400, 406, 404, + 306, 302, 408, 304, 300, 300, 300, 300, 300, 300, 300, 300, 300, + 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 404, 304, + 400, 300, 300, 404, 304, 400, 300, 300, 404, 304, 400, 300, 300 +}; + + +std::array _4E6BDC_loc_names= + { + "mdt12.blv", + "d18.blv", + "mdt14.blv", + "d37.blv", + "mdk01.blv", + "mdt01.blv", + "mdr01.blv", + "mdt10.blv", + "mdt09.blv", + "mdt15.blv", + "mdt11.blv" + }; + + +//----- (0043F39E) -------------------------------------------------------- +void __fastcall PrepareDrawLists_BLV() +{ + int v5; // eax@4 + unsigned int v7; // ebx@8 + BLVSector *v8; // esi@8 + + pBLVRenderParams->Reset(); + pMobileLightsStack->uNumLightsActive = 0; + //uNumMobileLightsApplied = 0; + uNumDecorationsDrawnThisFrame = 0; + uNumSpritesDrawnThisFrame = 0; + uNumBillboardsToDraw = 0; + + if ( !byte_4D864C || !(pGame->uFlags & 0x1000) ) // lightspot around party + { + //v2 = pParty->flt_TorchlightColorB + 6.7553994e15; + //v11 = LOBYTE(v2); + v5 = 800; + if (pParty->TorchlightActive()) + v5 *= pParty->pPartyBuffs[PARTY_BUFF_TORCHLIGHT].uPower; + //LOBYTE(v1) = _4E94D0_light_type; + //v4 = pParty->flt_TorchlightColorR + 6.7553994e15; + //v3 = pParty->flt_TorchlightColorG + 6.7553994e15; + pMobileLightsStack->AddLight(pGame->pIndoorCameraD3D->vPartyPos.x, + pGame->pIndoorCameraD3D->vPartyPos.y, + pGame->pIndoorCameraD3D->vPartyPos.z, + pBLVRenderParams->uPartySectorID, + v5, + floorf(pParty->flt_TorchlightColorR + 0.5f), + floorf(pParty->flt_TorchlightColorG + 0.5f), + floorf(pParty->flt_TorchlightColorB + 0.5f), + _4E94D0_light_type); + } + PrepareBspRenderList_BLV(); + PrepareItemsRenderList_BLV(); + PrepareActorRenderList_BLV(); + + for (uint i = 0; i < pBspRenderer->uNumVisibleNotEmptySectors; ++i) + { + v7 = pBspRenderer->pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[i]; + v8 = &pIndoor->pSectors[pBspRenderer->pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[i]]; + + for (uint j = 0; j < v8->uNumDecorations; ++j) + PrepareDecorationsRenderList_BLV(v8->pDecorationIDs[j], v7); + } + FindBillboardsLightLevels_BLV(); + pGame->PrepareBloodsplats(); +} + +//----- (004407D9) -------------------------------------------------------- +void BLVRenderParams::Reset() +{ + int v7; // eax@1 + + this->field_0_timer_ = pEventTimer->uTotalGameTimeElapsed; + + pGame->pIndoorCameraD3D->debug_flags = 0; + if (viewparams->draw_sw_outlines) + pGame->pIndoorCameraD3D->debug_flags |= BLV_RENDER_DRAW_SW_OUTLINES; + if (viewparams->draw_d3d_outlines) + pGame->pIndoorCameraD3D->debug_flags |= BLV_RENDER_DRAW_D3D_OUTLINES; + + //v2 = a2; + //this->field_0_timer_ = a2->field_0_timer; + //this->uFlags = a2->uFlags; + //this->vPartyPos.x = a2->vPosition.x; + //this->vPartyPos.y = a2->vPosition.y; + //this->vPartyPos.z = a2->vPosition.z; + //v4 = this->vPartyPos.z; + //v5 = this->vPartyPos.y; + //this->sPartyRotY = a2->sRotationY; + //v6 = this->vPartyPos.x; + //this->sPartyRotX = a2->sRotationX; + v7 = pIndoor->GetSector(pGame->pIndoorCameraD3D->vPartyPos.x, + pGame->pIndoorCameraD3D->vPartyPos.y, + pGame->pIndoorCameraD3D->vPartyPos.z); + this->uPartySectorID = v7; + if ( !v7 ) + { + //__debugbreak(); // shouldnt happen, please provide savegame + /*v8 = this->vPartyPos.z; + this->vPartyPos.x = pParty->vPosition.x; + v9 = pParty->vPosition.y; + v10 = this->vPartyPos.x; + this->vPartyPos.y = pParty->vPosition.y;*/ + this->uPartySectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z); + } + //if ( pRenderer->pRenderD3D ) + { + //this->sCosineY = stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationY); + //this->sSineY = stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationY); + //this->sCosineNegX = stru_5C6E00->Cos(-pGame->pIndoorCameraD3D->sRotationX); + //this->sSineNegX = stru_5C6E00->Sin(-pGame->pIndoorCameraD3D->sRotationX); + //this->fCosineY = cos((3.141592653589793 + 3.141592653589793) * (double)pGame->pIndoorCameraD3D->sRotationY * 0.00048828125); + //this->fSineY = sin((3.141592653589793 + 3.141592653589793) * (double)pGame->pIndoorCameraD3D->sRotationY * 0.00048828125); + //this->fCosineNegX = cos((3.141592653589793 + 3.141592653589793) * (double)-pGame->pIndoorCameraD3D->sRotationX * 0.00048828125); + //this->fSineNegX = sin((3.141592653589793 + 3.141592653589793) * (double)-pGame->pIndoorCameraD3D->sRotationX * 0.00048828125); + this->field_64 = pViewport->field_of_view; + + this->uViewportX = pViewport->uScreen_TL_X; + this->uViewportY = pViewport->uScreen_TL_Y; + this->uViewportZ = pViewport->uScreen_BR_X; + this->uViewportW = pViewport->uScreen_BR_Y; + + this->uViewportWidth = uViewportZ - uViewportX + 1; + this->uViewportHeight = uViewportW - uViewportY + 1; + this->uViewportCenterX = (uViewportZ + uViewportX) / 2; + this->uViewportCenterY = (uViewportY + uViewportW) / 2; + } + /*else + { + __debugbreak(); // no sw + this->sCosineY = stru_5C6E00->Cos(-this->sPartyRotY); + this->sSineY = stru_5C6E00->Sin(-this->sPartyRotY); + this->sCosineNegX = stru_5C6E00->Cos(-this->sPartyRotX); + this->sSineNegX = stru_5C6E00->Sin(-this->sPartyRotX); + v17 = cos((double)-this->sPartyRotY * 0.0030664064); + v18 = this->sPartyRotY; + this->fCosineY = v17; + v19 = sin((double)-v18 * 0.0030664064); + v20 = this->sPartyRotX; + this->fSineY = v19; + v21 = cos((double)-v20 * 0.0030664064); + v22 = this->sPartyRotX; + this->fCosineNegX = v21; + this->fSineNegX = sin((double)-v22 * 0.0030664064); + v23 = this->uViewportX; + this->field_64 = a2->field_3C; + v24 = this->uViewportZ; + this->field_70 = this->uViewportZ - v23 + 1; + v25 = this->uViewportW - this->uViewportY + 1; + this->uViewportHeight = v25; + v29 = v25; + v26 = this->field_64; + this->uViewportCenterX = (signed int)(v24 + v23) >> 1; + this->uViewportCenterY = this->uViewportW - ((unsigned __int64)(v26 * (signed __int64)v29) >> 16); + }*/ + //v27 = (unsigned int)(signed __int64)((double)this->uViewportWidth * 0.5 + // / tan((double)(v2->fov_deg >> 1) * 0.01745329) + // + 0.5) << 16; + extern float _calc_fov(int viewport_width, int angle_degree); + this->fov_rad_fixpoint = fixpoint_from_int(_calc_fov(uViewportWidth, 65), 0); + this->fov_rad_inv_fixpoint = 0x100000000i64 / this->fov_rad_fixpoint; + this->pRenderTarget = pRenderer->pTargetSurface; + this->uTargetWidth = window->GetWidth(); + this->uTargetHeight = window->GetHeight(); + this->pTargetZBuffer = pRenderer->pActiveZBuffer; + this->field_8C = 0; + this->field_84 = 0; + this->uNumFacesRenderedThisFrame = 0; + this->field_88 = 0; + pBLVRenderParams->field_90 = 64; + pBLVRenderParams->field_94 = 6; +} + +//----- (00440B44) -------------------------------------------------------- +void IndoorLocation::ExecDraw(bool bD3D) +{ + if (bD3D) + { + pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z); + for (uint i = 0; i < pBspRenderer->num_faces; ++i) + { + if (pBspRenderer->nodes[pBspRenderer->faces[i].uNodeID].viewing_portal_id == -1) + IndoorLocation::ExecDraw_d3d(pBspRenderer->faces[i].uFaceID, nullptr, 4, nullptr); + else + IndoorLocation::ExecDraw_d3d(pBspRenderer->faces[i].uFaceID, + pBspRenderer->nodes[pBspRenderer->faces[i].uNodeID].std__vector_0007AC, 4, + pBspRenderer->nodes[pBspRenderer->faces[i].uNodeID].pPortalBounding); + } + } + else for (uint j = 0; j < pBspRenderer->num_faces; ++j ) + { + __debugbreak(); // no SW + //pBLVRenderParams->field_7C = &pBspRenderer->nodes[pBspRenderer->faces[j].uNodeID].PortalScreenData; + //IndoorLocation::ExecDraw_sw(pBspRenderer->faces[j].uFaceID); + } +} + + +/* +//----- (00440BED) -------------------------------------------------------- +void __fastcall sub_440BED(IndoorLocation_drawstru *_this) +{ + unsigned __int16 *v1; // edi@7 + BspRenderer_stru0 *v2; // esi@8 + int v3; // ecx@9 + unsigned int v4; // edx@9 + short *v5; // eax@10 + signed int v6; // [sp+8h] [bp-8h]@7 + int v7; // [sp+Ch] [bp-4h]@8 + short *v8; + + PrepareDrawLists_BLV(_this); + if (pBLVRenderParams->uPartySectorID) + IndoorLocation::ExecDraw(pRenderer->pRenderD3D != 0); + pRenderer->DrawBillboardList_BLV(); + + if ( !pRenderer->pRenderD3D ) + { + if (pBLVRenderParams->uFlags & INDOOR_CAMERA_DRAW_D3D_OUTLINES) + pBspRenderer->DrawFaceOutlines(); + if (pBLVRenderParams->uFlags & INDOOR_CAMERA_DRAW_SW_OUTLINES) + { + v1 = pBLVRenderParams->pRenderTarget; + v7 = 0; + for(int i=0; i < pBspRenderer->num_nodes; i++) + { + BspRenderer_stru0 *pNode = &pBspRenderer->nodes[i]; + v4 = pRenderer->uTargetSurfacePitch * pNode->PortalScreenData._viewport_space_y; + if ( pNode->PortalScreenData._viewport_space_y <= pNode->PortalScreenData._viewport_space_w ) + { + //v5 = (char *)&pBspRenderer->nodes[0].field_C.array_3D8[pNode->field_C._viewport_space_y + v7]; + v5 = &pNode->PortalScreenData.viewport_right_side[pNode->PortalScreenData._viewport_space_y]; + v8 = &pNode->PortalScreenData.viewport_left_side[pNode->PortalScreenData._viewport_space_y]; + do + { + v1[v4 + *v8] = 255; + ++pNode->PortalScreenData._viewport_space_y; + v1[v4 + *v5] = 255; + v4 += pRenderer->uTargetSurfacePitch; + ++v5; + ++v8; + } + while ( pNode->PortalScreenData._viewport_space_y <= pNode->PortalScreenData._viewport_space_w ); + } + } + } + } +} +*/ + +//----- (00441BD4) -------------------------------------------------------- +void IndoorLocation::Draw() +{ + //int v0; // eax@1 + //IndoorLocation_drawstru _this; // [sp+0h] [bp-4Ch]@5 +// int v2; // [sp+44h] [bp-8h]@5 +// int v3; // [sp+48h] [bp-4h]@5 + + /*_this.uFlags = 0; + if (viewparams->draw_sw_outlines) + _this.uFlags |= BLV_RENDER_DRAW_SW_OUTLINES; + if (viewparams->draw_d3d_outlines) + _this.uFlags |= BLV_RENDER_DRAW_D3D_OUTLINES; + + _this.uFlags |= BLV_RENDER_DRAW_SW_OUTLINES; + _this.uFlags |= BLV_RENDER_DRAW_D3D_OUTLINES; + + _this.field_0_timer = pEventTimer->uTotalGameTimeElapsed; + //_this.fov_deg = 65; + //_this.vPosition.x = pParty->vPosition.x - fixpoint_mul(stru_5C6E00->Cos(pParty->sRotationY), pParty->y_rotation_granularity); + //_this.vPosition.y = pParty->vPosition.y - fixpoint_mul(stru_5C6E00->Sin(pParty->sRotationY), pParty->y_rotation_granularity); + //_this.vPosition.z = pParty->vPosition.z + pParty->sEyelevel; + //_this.sRotationX = pParty->sRotationX; + //_this.sRotationY = pParty->sRotationY; + _this.pRenderTarget = pRenderer->pTargetSurface; + _this.uViewportX = pViewport->uScreen_TL_X; + _this.uViewportY = pViewport->uScreen_TL_Y; + _this.uViewportZ = pViewport->uScreen_BR_X; + _this.uViewportW = pViewport->uScreen_BR_Y; + _this.field_3C = pViewport->field_30; + + _this.uTargetWidth = 640; + _this.uTargetHeight = 480; + _this.pTargetZ = pRenderer->pActiveZBuffer;*/ + + //sub_440BED(&_this); -- inlined + //{ + PrepareDrawLists_BLV(); + if (pBLVRenderParams->uPartySectorID) + IndoorLocation::ExecDraw(true/*pRenderer->pRenderD3D != 0*/); + pRenderer->DrawBillboardList_BLV(); + //} + + pParty->uFlags &= ~2; + pGame->DrawParticles(); + trail_particle_generator.UpdateParticles(); +} + +//----- (004C0EF2) -------------------------------------------------------- +void BLVFace::FromODM(ODMFace *face) +{ + this->pFacePlane_old.vNormal.x = face->pFacePlane.vNormal.x; + this->pFacePlane_old.vNormal.y = face->pFacePlane.vNormal.y; + this->pFacePlane_old.vNormal.z = face->pFacePlane.vNormal.z; + this->pFacePlane_old.dist = face->pFacePlane.dist; + this->pFacePlane.vNormal.x = (double)(face->pFacePlane.vNormal.x & 0xFFFF) * 0.000015259022 + + (double)(face->pFacePlane.vNormal.x >> 16); + this->pFacePlane.vNormal.y = (double)(face->pFacePlane.vNormal.y & 0xFFFF) * 0.000015259022 + + (double)(face->pFacePlane.vNormal.y >> 16); + this->pFacePlane.vNormal.z = (double)(face->pFacePlane.vNormal.z & 0xFFFF) * 0.000015259022 + + (double)(face->pFacePlane.vNormal.z >> 16); + this->pFacePlane.dist = (double)(face->pFacePlane.dist & 0xFFFF) * 0.000015259022 + (double)(face->pFacePlane.dist >> 16); + this->uAttributes = face->uAttributes; + this->pBounding.x1 = face->pBoundingBox.x1; + this->pBounding.y1 = face->pBoundingBox.y1; + this->pBounding.z1 = face->pBoundingBox.z1; + this->pBounding.x2 = face->pBoundingBox.x2; + this->pBounding.y2 = face->pBoundingBox.y2; + this->pBounding.z2 = face->pBoundingBox.z2; + this->zCalc1 = face->zCalc1; + this->zCalc2 = face->zCalc2; + this->zCalc3 = face->zCalc3; + this->pXInterceptDisplacements = face->pXInterceptDisplacements; + this->pYInterceptDisplacements = face->pYInterceptDisplacements; + this->pZInterceptDisplacements = face->pZInterceptDisplacements; + this->uPolygonType = (PolygonType)face->uPolygonType; + this->uNumVertices = face->uNumVertices; + this->uBitmapID = face->uTextureID; + this->pVertexIDs = face->pVertexIDs; +} + +//----- (004B0A25) -------------------------------------------------------- +void IndoorLocation::ExecDraw_d3d(unsigned int uFaceID, IndoorCameraD3D_Vec4 *pVertices, unsigned int uNumVertices, RenderVertexSoft *pPortalBounding) +{ + int v17; // ebx@25 + IDirect3DTexture2 *v27; // eax@42 + unsigned int uNumVerticesa; // [sp+24h] [bp-4h]@17 + int a4a; // [sp+34h] [bp+Ch]@25 + + if (uFaceID >= pIndoor->uNumFaces) + return; + + static RenderVertexSoft static_vertices_F7C228[64]; + static RenderVertexSoft static_vertices_F7B628[64]; + static stru154 stru_F7B60C; // idb + + BLVFace* pFace = &pIndoor->pFaces[uFaceID]; + if (pFace->uNumVertices < 3) + return; + + + if (pFace->Invisible()) + return; + + ++pBLVRenderParams->uNumFacesRenderedThisFrame; + pFace->uAttributes |= FACE_UNKNOW4; + + if (!pFace->GetTexture()) + return; + + if (!pGame->pIndoorCameraD3D->IsCulled(pFace)) + { + uNumVerticesa = pFace->uNumVertices; + for (uint i = 0; i < pFace->uNumVertices; ++i) + { + static_vertices_F7C228[i].vWorldPosition.x = pIndoor->pVertices[pFace->pVertexIDs[i]].x; + static_vertices_F7C228[i].vWorldPosition.y = pIndoor->pVertices[pFace->pVertexIDs[i]].y; + static_vertices_F7C228[i].vWorldPosition.z = pIndoor->pVertices[pFace->pVertexIDs[i]].z; + static_vertices_F7C228[i].u = (signed short)pFace->pVertexUIDs[i]; + static_vertices_F7C228[i].v = (signed short)pFace->pVertexVIDs[i]; + } + + if (!pVertices || + (pGame->pStru9Instance->_498377(pPortalBounding, 4, pVertices, static_vertices_F7C228, &uNumVerticesa), uNumVerticesa) ) + { + if (pGame->pIndoorCameraD3D->CalcPortalShape(static_vertices_F7C228, &uNumVerticesa, + static_vertices_F7B628, pGame->pIndoorCameraD3D->std__vector_000034_prolly_frustrum, 4, false, 0) != 1 || uNumVerticesa ) + { + a4a = SHIWORD(stru_F8AD28.uCurrentAmbientLightLevel); + v17 = (248 - 8 * SHIWORD(stru_F8AD28.uCurrentAmbientLightLevel)) | (((248 - 8 * SHIWORD(stru_F8AD28.uCurrentAmbientLightLevel)) + | ((248 - 8 * SHIWORD(stru_F8AD28.uCurrentAmbientLightLevel)) << 8)) << 8); + sub_4B0E07(uFaceID); + pGame->pLightmapBuilder->ApplyLights_IndoorFace(uFaceID); + pDecalBuilder->ApplyBloodsplatDecals_IndoorFace(uFaceID); + pGame->pIndoorCameraD3D->ViewTransfrom_OffsetUV(static_vertices_F7B628, uNumVerticesa, array_507D30, &stru_F8AD28); + pGame->pIndoorCameraD3D->Project(array_507D30, uNumVerticesa, 0); + pGame->pLightmapBuilder->std__vector_000004_size = 0; + if (stru_F8AD28.uNumLightsApplied > 0 || pDecalBuilder->uNumDecals > 0) + { + stru_F7B60C.face_plane.vNormal.x = pFace->pFacePlane.vNormal.x; + stru_F7B60C.polygonType = pFace->uPolygonType; + stru_F7B60C.face_plane.vNormal.y = pFace->pFacePlane.vNormal.y; + stru_F7B60C.face_plane.vNormal.z = pFace->pFacePlane.vNormal.z; + stru_F7B60C.face_plane.dist = pFace->pFacePlane.dist; + } + + if (stru_F8AD28.uNumLightsApplied > 0 && !pFace->Indoor_sky()) + pGame->pLightmapBuilder->ApplyLights(&stru_F8AD28, &stru_F7B60C, uNumVerticesa, array_507D30, pVertices, 0); + + if (pDecalBuilder->uNumDecals > 0)//отрисовка пятен крови + pDecalBuilder->ApplyDecals(a4a, 1, &stru_F7B60C, uNumVerticesa, array_507D30, pVertices, 0, pFace->uSectorID); + + if (pFace->Fluid()) + { + if (pFace->uBitmapID == pRenderer->hd_water_tile_id) + v27 = pBitmaps_LOD->pHardwareTextures[pRenderer->pHDWaterBitmapIDs[pRenderer->hd_water_current_frame]]; + else + { + //auto v24 = GetTickCount() / 4; + //auto v25 = v24 - stru_5C6E00->uIntegerHalfPi; + uint eightSeconds = GetTickCount() % 8000; + float angle = (eightSeconds / 8000.0f) * 2 * 3.1415f; + + //animte lava back and forth + for (uint i = 0; i < uNumVerticesa; ++i) + //array_507D30[i].v += (double)(pBitmaps_LOD->pTextures[pFace->uBitmapID].uHeightMinus1 & (unsigned int)(stru_5C6E00->SinCos(v25) >> 8)); + array_507D30[i].v += pBitmaps_LOD->pTextures[pFace->uBitmapID].uHeightMinus1 * cosf(angle); + v27 = pBitmaps_LOD->pHardwareTextures[pFace->uBitmapID]; + } + } + else if (pFace->uAttributes & FACE_TEXTURE_FRAME) + v27 = pBitmaps_LOD->pHardwareTextures[pTextureFrameTable->GetFrameTexture(pFace->uBitmapID, pBLVRenderParams->field_0_timer_)]; + else + { + v17 = 0xFF808080; + v27 = pBitmaps_LOD->pHardwareTextures[pFace->uBitmapID]; + } + + if (pFace->Indoor_sky()) + pRenderer->DrawIndoorSky(uNumVerticesa, uFaceID); + else + pRenderer->DrawIndoorPolygon(uNumVerticesa, pFace, v27, pFace->GetTexture(), PID(OBJECT_BModel, uFaceID), v17, 0); + return; + } + } + } +} + +//----- (004B0E07) -------------------------------------------------------- +unsigned int __fastcall sub_4B0E07(unsigned int uFaceID) +{ + unsigned int result; // eax@1 + + stru_F8AD28.pDeltaUV[0] = pIndoor->pFaceExtras[pIndoor->pFaces[uFaceID].uFaceExtraID].sTextureDeltaU; + stru_F8AD28.pDeltaUV[1] = pIndoor->pFaceExtras[pIndoor->pFaces[uFaceID].uFaceExtraID].sTextureDeltaV; + result = GetTickCount() >> 3; + if ( pIndoor->pFaces[uFaceID].uAttributes & FACE_FLOW_DIAGONAL ) + stru_F8AD28.pDeltaUV[1] -= result & pBitmaps_LOD->GetTexture(pIndoor->pFaces[uFaceID].uBitmapID)->uHeightMinus1; + else + { + if ( pIndoor->pFaces[uFaceID].uAttributes & FACE_FLOW_VERTICAL ) + stru_F8AD28.pDeltaUV[1] += result & pBitmaps_LOD->GetTexture(pIndoor->pFaces[uFaceID].uBitmapID)->uHeightMinus1; + } + if ( pIndoor->pFaces[uFaceID].uAttributes & FACE_FLOW_HORIZONTAL ) + stru_F8AD28.pDeltaUV[0] -= result & pBitmaps_LOD->GetTexture(pIndoor->pFaces[uFaceID].uBitmapID)->uWidthMinus1; + else + { + if ( pIndoor->pFaces[uFaceID].uAttributes & FACE_DONT_CACHE_TEXTURE ) + stru_F8AD28.pDeltaUV[0] += result & pBitmaps_LOD->GetTexture(pIndoor->pFaces[uFaceID].uBitmapID)->uWidthMinus1; + } + return result; +} + +//----- (004B0EA8) -------------------------------------------------------- +void BspRenderer::AddFaceToRenderList_d3d(unsigned int node_id, unsigned int uFaceID) +{ + unsigned __int16 pTransitionSector; // ax@11 + int v9; // edx@15 + char v29; // al@48 + + nodes[num_nodes].viewing_portal_id = -1; + //v39 = &pIndoor->pFaces[uFaceID]; + + BLVFace* pFace = &pIndoor->pFaces[uFaceID]; + + if (!pFace->Portal()) + { + if (num_faces < 1000) + { + faces[num_faces].uFaceID = uFaceID; + faces[num_faces++].uNodeID = node_id; + } + return; + } + + if (nodes[node_id].uFaceID == uFaceID) + return; + if (!node_id && + pGame->pIndoorCameraD3D->vPartyPos.x >= pFace->pBounding.x1 - 16 && // we are probably standing at the portal plane + pGame->pIndoorCameraD3D->vPartyPos.x <= pFace->pBounding.x2 + 16 && + pGame->pIndoorCameraD3D->vPartyPos.y >= pFace->pBounding.y1 - 16 && + pGame->pIndoorCameraD3D->vPartyPos.y <= pFace->pBounding.y2 + 16 && + pGame->pIndoorCameraD3D->vPartyPos.z >= pFace->pBounding.z1 - 16 && + pGame->pIndoorCameraD3D->vPartyPos.z <= pFace->pBounding.z2 + 16 ) + { + if ( abs(pFace->pFacePlane_old.dist + pGame->pIndoorCameraD3D->vPartyPos.x * pFace->pFacePlane_old.vNormal.x + + pGame->pIndoorCameraD3D->vPartyPos.y * pFace->pFacePlane_old.vNormal.y + + pGame->pIndoorCameraD3D->vPartyPos.z * pFace->pFacePlane_old.vNormal.z) <= 589824 ) // we sure are standing at the portal plane + { + pTransitionSector = pFace->uSectorID; + if ( nodes[0].uSectorID == pTransitionSector ) // draw back sector + pTransitionSector = pFace->uBackSectorID; + nodes[num_nodes].uSectorID = pTransitionSector; + nodes[num_nodes].uFaceID = uFaceID; + nodes[num_nodes].uViewportX = pBLVRenderParams->uViewportX; + nodes[num_nodes].uViewportZ = pBLVRenderParams->uViewportZ; + nodes[num_nodes].uViewportY = pBLVRenderParams->uViewportY; + nodes[num_nodes].uViewportW = pBLVRenderParams->uViewportW; + nodes[num_nodes].PortalScreenData.GetViewportData(pBLVRenderParams->uViewportX, pBLVRenderParams->uViewportY, + pBLVRenderParams->uViewportZ, pBLVRenderParams->uViewportW); + AddBspNodeToRenderList(++num_nodes - 1); + return; + } + } + + v9 = pFace->pFacePlane_old.vNormal.x * (pIndoor->pVertices[pFace->pVertexIDs[0]].x - pGame->pIndoorCameraD3D->vPartyPos.x) + + pFace->pFacePlane_old.vNormal.y * (pIndoor->pVertices[pFace->pVertexIDs[0]].y - pGame->pIndoorCameraD3D->vPartyPos.y) + + pFace->pFacePlane_old.vNormal.z * (pIndoor->pVertices[pFace->pVertexIDs[0]].z - pGame->pIndoorCameraD3D->vPartyPos.z); + if (nodes[node_id].uSectorID != pFace->uSectorID) + v9 = -v9; + if (v9 >= 0) + return; + + int num_vertices = GetPortalScreenCoord(uFaceID); + if (num_vertices < 2) + return; + + int face_min_screenspace_x = PortalFace._screen_space_x[0], + face_max_screenspace_x = PortalFace._screen_space_x[0]; + int face_min_screenspace_y = PortalFace._screen_space_y[0], + face_max_screenspace_y = PortalFace._screen_space_y[0]; + for (uint i = 1; i < num_vertices; ++i) + { + if (face_min_screenspace_x > PortalFace._screen_space_x[i]) + face_min_screenspace_x = PortalFace._screen_space_x[i]; + if (face_max_screenspace_x < PortalFace._screen_space_x[i]) + face_max_screenspace_x = PortalFace._screen_space_x[i]; + + if (face_min_screenspace_y > PortalFace._screen_space_y[i]) + face_min_screenspace_y = PortalFace._screen_space_y[i]; + if (face_max_screenspace_y < PortalFace._screen_space_y[i]) + face_max_screenspace_y = PortalFace._screen_space_y[i]; + } + //_screen_space_x = 719, 568, 493 + //savegame: qw , 0Bh and 0x1D4h + //problem here when standing near/on portal, condition is false because of face_min_screenspace_x > p->uViewportZ + if (face_max_screenspace_x >= nodes[node_id].uViewportX && + face_min_screenspace_x <= nodes[node_id].uViewportZ && + face_max_screenspace_y >= nodes[node_id].uViewportY && + face_min_screenspace_y <= nodes[node_id].uViewportW && + PortalFrustrum(num_vertices, &nodes[num_nodes].PortalScreenData, &nodes[node_id].PortalScreenData, uFaceID)) + { + pTransitionSector = pFace->uSectorID; + if (nodes[node_id].uSectorID == pTransitionSector ) + pTransitionSector = pFace->uBackSectorID; + nodes[num_nodes].uSectorID = pTransitionSector; + nodes[num_nodes].uFaceID = uFaceID; + nodes[num_nodes].uViewportX = pBLVRenderParams->uViewportX; + nodes[num_nodes].uViewportZ = pBLVRenderParams->uViewportZ; + nodes[num_nodes].uViewportY = pBLVRenderParams->uViewportY; + nodes[num_nodes].uViewportW = pBLVRenderParams->uViewportW; + v29 = false; + if (nodes[node_id].viewing_portal_id == -1)//for first portal + v29 = pGame->pStru10Instance->CalcPortalShape(pFace, nodes[num_nodes].std__vector_0007AC, nodes[num_nodes].pPortalBounding); + else//for next portals + { + static RenderVertexSoft static_subAddFaceToRenderList_d3d_stru_F7AA08[64]; + static RenderVertexSoft static_subAddFaceToRenderList_d3d_stru_F79E08[64]; + + for (uint k = 0; k < pFace->uNumVertices; ++k) + { + static_subAddFaceToRenderList_d3d_stru_F7AA08[k].vWorldPosition.x = pIndoor->pVertices[pFace->pVertexIDs[k]].x; + static_subAddFaceToRenderList_d3d_stru_F7AA08[k].vWorldPosition.y = pIndoor->pVertices[pFace->pVertexIDs[k]].y; + static_subAddFaceToRenderList_d3d_stru_F7AA08[k].vWorldPosition.z = pIndoor->pVertices[pFace->pVertexIDs[k]].z; + } + + unsigned int pNewNumVertices = pFace->uNumVertices; + pGame->pIndoorCameraD3D->CalcPortalShape(static_subAddFaceToRenderList_d3d_stru_F7AA08, &pNewNumVertices, + static_subAddFaceToRenderList_d3d_stru_F79E08, nodes[node_id].std__vector_0007AC, 4, 0, 0); + + v29 = pGame->pStru10Instance->_49C5DA(pFace, static_subAddFaceToRenderList_d3d_stru_F79E08, &pNewNumVertices, + nodes[num_nodes].std__vector_0007AC, nodes[num_nodes].pPortalBounding); + } + if ( 1 ) + { + assert(num_nodes < 150); + + nodes[num_nodes].viewing_portal_id = uFaceID; + AddBspNodeToRenderList(++num_nodes - 1); + } + if (pGame->pIndoorCameraD3D->debug_flags & BLV_RENDER_DRAW_SW_OUTLINES) + pGame->pIndoorCameraD3D->PrepareAndDrawDebugOutline(pFace, 0x1E1EFF); + //pGame->pIndoorCameraD3D->DebugDrawPortal(pFace); + } +} + +//----- (004AE5BA) -------------------------------------------------------- +Texture *BLVFace::GetTexture() +{ + unsigned int v1; // ecx@2 + + if ( uAttributes & FACE_TEXTURE_FRAME ) + v1 = pTextureFrameTable->GetFrameTexture(this->uBitmapID, pBLVRenderParams->field_0_timer_); + else + v1 = uBitmapID; + return pBitmaps_LOD->GetTexture(v1); +} + + +//----- (00498B15) -------------------------------------------------------- +void IndoorLocation::Release() +{ + free(this->ptr_0002B4_doors_ddata); + this->ptr_0002B4_doors_ddata = NULL; + + free(this->ptr_0002B0_sector_rdata); + this->ptr_0002B0_sector_rdata = NULL; + + free(this->ptr_0002B8_sector_lrdata); + this->ptr_0002B8_sector_lrdata = NULL; + + free(this->pLFaces); + this->pLFaces = NULL; + + free(this->pSpawnPoints); + this->pSpawnPoints = NULL; + + this->uNumSectors = 0; + this->uNumFaces = 0; + this->uNumVertices = 0; + this->uNumNodes = 0; + this->uNumDoors = 0; + this->uNumLights = 0; + + free(this->pVertices); + this->pVertices = NULL; + + free(this->pFaces); + this->pFaces = NULL; + + free(this->pFaceExtras); + this->pFaceExtras = NULL; + + free(this->pSectors); + this->pSectors = NULL; + + free(this->pLights); + this->pLights = NULL; + + free(this->pDoors); + this->pDoors = NULL; + + free(this->pNodes); + this->pNodes = NULL; + + free(this->pMapOutlines); + this->pMapOutlines = NULL; + + this->bLoaded = 0; +} + +//----- (00498C45) -------------------------------------------------------- +bool IndoorLocation::Alloc() + { + pVertices = (Vec3_short_ *) malloc(15000 * sizeof(Vec3_short_));//0x15F90u + pFaces = (BLVFace *) malloc(10000 * sizeof(BLVFace));//0xEA600u + pFaceExtras = (BLVFaceExtra *) malloc(5000 * sizeof(BLVFaceExtra)); //0x2BF20u + pSectors = (BLVSector *) malloc(512 * sizeof(BLVSector));//0xE800u + pLights = (BLVLightMM7 *) malloc(400 * sizeof(BLVLightMM7));//0x1900u + pDoors = (BLVDoor *) malloc(200 * sizeof(BLVDoor));//0x3E80u + pNodes = (BSPNode *) malloc(5000 * sizeof(BSPNode));//0x9C40u + pMapOutlines =(BLVMapOutlines *)malloc(sizeof(BLVMapOutlines));//0x14824u + if (pVertices && pFaces && pFaceExtras && pSectors && pLights && pDoors && pNodes && pMapOutlines ) + { + memset(pVertices, 0, 15000*sizeof(Vec3_short_)); + memset(pFaces, 0, 10000*sizeof(BLVFace)); + memset(pFaceExtras,0, 5000*sizeof(BLVFaceExtra)); + memset(pSectors, 0, 512*sizeof(BLVSector)); + memset(pLights, 0, 400*sizeof(BLVLightMM7)); + memset(pDoors, 0, 200*sizeof(BLVDoor)); + memset(pNodes, 0, 5000*sizeof(BSPNode)); + memset(pMapOutlines,0, sizeof(BLVMapOutlines)); + return true; + } + else + return false; +} + +//----- (00444810) -------------------------------------------------------- +unsigned int IndoorLocation::GetLocationIndex(const char *Str1) +{ + for (uint i = 0; i < 11; ++i) + if (!_stricmp(Str1, _4E6BDC_loc_names[i])) + return i + 1; + return 0; +} + +//----- (004488F7) -------------------------------------------------------- +void IndoorLocation::ToggleLight(signed int sLightID, unsigned int bToggle) +{ + if ( uCurrentlyLoadedLevelType == LEVEL_Indoor && (sLightID <= pIndoor->uNumLights - 1) && (sLightID >= 0) ) + { + if ( bToggle ) + pIndoor->pLights[sLightID].uAtributes &= 0xFFFFFFF7; + else + pIndoor->pLights[sLightID].uAtributes |= 8; + pParty->uFlags |= 2; + } +} + +//----- (00498E0A) -------------------------------------------------------- +bool IndoorLocation::Load(char *pFilename, int a3, size_t _i, char *pDest) +{ + /*unsigned int v5; // ebx@1 + //IndoorLocation *v6; // esi@1 + FILE *v7; // edi@3 + bool result; // eax@3 + char *v9; // ecx@4 + void *v10; // eax@4 + //unsigned __int8 v11; // zf@4 + //unsigned __int8 v12; // sf@4 + int v13; // eax@5 + size_t v14; // ecx@6 + char *v15; // ecx@6 + int v16; // edx@6 + size_t v17; // ecx@6 + char *v18; // ecx@6 + int v19; // edx@6 + unsigned __int16 *v20; // edx@6 + unsigned __int16 *v21; // edx@6 + unsigned __int16 *v22; // edx@6 + __int16 v23; // ax@10 + char *v24; // ecx@10 + __int16 v25; // cx@10 + __int16 v26; // ax@11 + char *v27; // ecx@11 + unsigned __int16 v28; // ax@17 + BLVFaceExtra *v29; // ecx@17 + char *v30; // edx@17 + int v31; // ecx@20 + void *v32; // eax@25 + int v33; // eax@26 + unsigned __int16 *v34; // edx@27 + size_t v35; // ecx@27 + char *v36; // ecx@27 + int v37; // edx@27 + size_t v38; // ecx@27 + char *v39; // ecx@27 + int v40; // edx@27 + unsigned __int16 *v41; // edx@27 + unsigned __int16 *v42; // edx@27 + unsigned __int16 *v43; // edx@27 + unsigned __int16 *v44; // edx@27 + size_t v45; // ecx@27 + unsigned __int16 *v46; // edx@27 + void *v47; // eax@28 + BLVSector *v48; // eax@29 + size_t v49; // ecx@29 + unsigned __int16 *v50; // edx@31 + void *v51; // eax@32 + int v52; // eax@33 + unsigned __int16 *v53; // edx@34 + size_t v54; // ecx@34 + char *v55; // ecx@34 + int v56; // edx@34 + size_t v57; // ecx@34 + char *v58; // ecx@34 + int v59; // edx@34 + unsigned __int16 *v60; // edx@34 + unsigned __int16 *v61; // edx@34 + unsigned __int16 *v62; // edx@34 + unsigned __int16 *v63; // edx@34 + int v64; // ecx@34 + BLVDoor *v65; // ecx@36 + char *v66; // eax@37 + int v67; // edx@38 + int v68; // ecx@38 + BLVFace *v69; // edx@38 + int v70; // ecx@38 + int v71; // edx@38 + int v72; // eax@38 + unsigned __int16 v73; // ax@42 + char *v74; // ecx@42 + SpriteObject *v75; // ecx@44 + size_t v76; // eax@45 + int j; // edx@46 + unsigned __int16 v78; // ax@50 + void *v79; // eax@52 + void **v80; // esi@52 + unsigned int v145; // eax@103 + void *v146; // eax@103 + unsigned int v147; // ecx@103 + int v148; // ebx@103 + unsigned int *v149; // ecx@103*/ + //size_t v150; // eax@103 + //unsigned int v151; // ebx@109 + //unsigned int v152; // ecx@116 + //unsigned int v153; // eax@117 + //size_t v154; // ebx@126 + //unsigned int v155; // ebx@134 + //size_t v156; // eax@140 + //signed int v157; // ebx@142 + //int v158; // ebx@148 + //BLVFace *v159; // eax@149 +// BLVFaceExtra *v160; // ecx@149 + //BLVFaceExtra *v161; // ecx@149 + //signed int v162; // ebx@154 + //unsigned int outz; // ebx@157 + //unsigned int v164; // ebx@157 + //unsigned int v165; // edx@158 + //char *v166; // ecx@158 + //unsigned __int16 v167; // ax@161 + //__int16 v168; // ax@165 + //unsigned int v169; // ebx@168 + //void *v170; // eax@168 + //size_t v171; // ebx@168 + //int v172; // edx@168 + //BLVDoor *v173; // ecx@169 + //int k; // eax@169 + //BLVDoor *v175; // ecx@172 + //int v176; // edx@172 + //BLVDoor *v177; // ecx@172 + //int v178; // edx@172 + //BLVDoor *v179; // ecx@172 + //int v180; // edx@172 + //BLVDoor *v181; // ecx@172 + //int v182; // edx@172 + //BLVDoor *v183; // ecx@172 + //int v184; // edx@172 + //BLVDoor *v185; // ecx@172 + //int v186; // edx@172 + //BLVDoor *v187; // ecx@172 + //int v188; // edx@172 + //unsigned __int16 *v189; // ebx@172 + //char *v190; // edx@173 + //BLVDoor *v191; // ecx@174 + //BLVDoor *l; // eax@175 + //signed int v193; // ebx@176 + //int v194; // ecx@176 + //BLVFaceExtra *v195; // ecx@176 + //BLVFace *v196; // ebx@178 + //std::string v197; // [sp-18h] [bp-680h]@66 + //void *v198; // [sp-14h] [bp-67Ch]@72 + //size_t v199; // [sp-10h] [bp-678h]@72 + //size_t v200; // [sp-Ch] [bp-674h]@72 + //const char *v201; // [sp-8h] [bp-670h]@4 + //int v202; // [sp-4h] [bp-66Ch]@4 + char v203[875]; // [sp+Ch] [bp-65Ch]@130 +// char FileName[260]; // [sp+378h] [bp-2F0h]@1 + //char DstBuf; // [sp+47Ch] [bp-1ECh]@4 +// __int32 Offset; // [sp+480h] [bp-1E8h]@4 +// __int32 v207; // [sp+48Ch] [bp-1DCh]@4 +// __int32 v208; // [sp+498h] [bp-1D0h]@4 +// __int32 v209; // [sp+4A4h] [bp-1C4h]@4 +// __int32 v210; // [sp+4B0h] [bp-1B8h]@4 +// __int32 v211; // [sp+4BCh] [bp-1ACh]@15 +// __int32 v212; // [sp+4C8h] [bp-1A0h]@15 +// __int32 v213; // [sp+4D4h] [bp-194h]@25 +// __int32 v214; // [sp+4E0h] [bp-188h]@25 +// __int32 v215; // [sp+4ECh] [bp-17Ch]@32 +// __int32 v216; // [sp+4F8h] [bp-170h]@32 +// __int32 v217; // [sp+504h] [bp-164h]@40 +// __int32 v218; // [sp+510h] [bp-158h]@40 +// __int32 v219; // [sp+51Ch] [bp-14Ch]@43 +// __int32 v220; // [sp+528h] [bp-140h]@43 +// __int32 v221; // [sp+534h] [bp-134h]@52 +// __int32 v222; // [sp+540h] [bp-128h]@52 +// __int32 v223; // [sp+54Ch] [bp-11Ch]@52 +// __int32 v224; // [sp+558h] [bp-110h]@52 +// __int32 v225; // [sp+564h] [bp-104h]@52 +// __int32 v226; // [sp+570h] [bp-F8h]@52 +// __int32 v227; // [sp+57Ch] [bp-ECh]@52 +// __int32 v228; // [sp+588h] [bp-E0h]@52 +// __int32 v229; // [sp+594h] [bp-D4h]@52 +// __int32 v230; // [sp+5A0h] [bp-C8h]@52 +// __int32 v231; // [sp+5ACh] [bp-BCh]@52 +// __int32 v232; // [sp+5B8h] [bp-B0h]@52 +// __int32 v233; // [sp+5C4h] [bp-A4h]@52 +// __int32 v234; // [sp+5D0h] [bp-98h]@52 + //char pName[40]; // [sp+5FCh] [bp-6Ch]@42 + //size_t pSource; // [sp+624h] [bp-44h]@67 + //char Dst[12]; // [sp+628h] [bp-40h]@9 + //char *v238; // [sp+634h] [bp-34h]@38 + ODMHeader header; // [sp+638h] [bp-30h]@61 + //void *ptr; // [sp+648h] [bp-20h]@66 + //size_t Count; // [sp+64Ch] [bp-1Ch]@109 + //int uSourceLen; // [sp+653h] [bp-15h]@66 + FILE *File; // [sp+658h] [bp-10h]@56 + //BLVSector *v244; // [sp+65Ch] [bp-Ch]@72 + //int v245; // [sp+660h] [bp-8h]@72 + //BLVFace *Src; // [sp+664h] [bp-4h]@73 +// signed int Argsa; // [sp+670h] [bp+8h]@4 +// signed int Argsb; // [sp+670h] [bp+8h]@7 +// signed int Argsc; // [sp+670h] [bp+8h]@15 +// signed int Argsd; // [sp+670h] [bp+8h]@18 +// int Argse; // [sp+670h] [bp+8h]@25 +// int Argsf; // [sp+670h] [bp+8h]@28 +// int Argsg; // [sp+670h] [bp+8h]@32 +// int Argsh; // [sp+670h] [bp+8h]@35 +// signed int Argsi; // [sp+670h] [bp+8h]@40 +// signed int Argsj; // [sp+670h] [bp+8h]@45 + //int Argsk; // [sp+670h] [bp+8h]@143 + //void *Argsl; // [sp+670h] [bp+8h]@155 + //signed int Argsm; // [sp+670h] [bp+8h]@161 + //signed int Argsn; // [sp+670h] [bp+8h]@175 + + //v5 = 0; + //v6 = this; + _6807E0_num_decorations_with_sounds_6807B8 = 0; + + #pragma region "loading from txt" + /*sprintf(FileName, "levels\\%s", pFilename); + if ( GetFileAttributesA(FileName) != -1 ) + { + Release(); + if ( Alloc() ) + { + v7 = fopen(FileName, "rb"); + result = 1; + if ( !v7 ) + return result; + v9 = pDest; + bLoaded = 1; + v202 = (int)v7; + v201 = (const char *)1; + *(int *)v9 = 1; + fread(&DstBuf, 0x180u, (size_t)v201, (FILE *)v202); + fseek(v7, Offset, 0); + fread(&blv, 0x88u, 1u, v7); + fseek(v7, v207, 0); + fread(&uNumVertices, 1u, 4u, v7); + fseek(v7, v208, 0); + fread(pVertices, 6u, uNumVertices, v7); + fseek(v7, v209, 0); + fread(&uNumFaces, 4u, 1u, v7); + fseek(v7, v210, 0); + fread(pFaces, 0x60u, uNumFaces, v7); + v10 = malloc(ptr_2AC, blv.uFaces_fdata_Size, "L.FData"); + v202 = (int)v7; + ptr_2AC = (unsigned __int16 *)v10; + fread(v10, 1u, blv.uFaces_fdata_Size, (FILE *)v202); + v11 = uNumFaces == 0; + v12 = (uNumFaces & 0x80000000u) != 0; + pDest = 0; + Argsa = 0; + if ( !(v12 | v11) ) + { + v13 = 0; + do + { + pFaces[v13].pVertexIDs = (unsigned __int16 *)&pDest[(unsigned int)ptr_2AC]; + v14 = (size_t)&pFaces[v13]; + i = v14; + v15 = &pDest[2 * *(char *)(v14 + 93) + 2]; + v16 = (int)&v15[(unsigned int)ptr_2AC]; + pDest = v15; + *(int *)(i + 52) = v16; + v17 = (size_t)&pFaces[v13]; + i = v17; + v18 = &pDest[2 * *(char *)(v17 + 93) + 2]; + v19 = (int)&v18[(unsigned int)ptr_2AC]; + pDest = v18; + *(int *)(i + 56) = v19; + i = (size_t)&pFaces[v13]; + v20 = ptr_2AC; + pDest += 2 * *(char *)(i + 93) + 2; + *(int *)(i + 60) = (int)(char *)v20 + (int)pDest; + i = (size_t)&pFaces[v13]; + v21 = ptr_2AC; + pDest += 2 * *(char *)(i + 93) + 2; + *(int *)(i + 64) = (int)(char *)v21 + (int)pDest; + i = (size_t)&pFaces[v13]; + ++v13; + v22 = ptr_2AC; + pDest += 2 * *(char *)(i + 93) + 2; + ++Argsa; + *(int *)(i + 68) = (int)(char *)v22 + (int)pDest; + pDest += 2 * *((char *)&pFaces[v13] - 3) + 2; + } + while ( Argsa < (signed int)uNumFaces ); + } + Argsb = 0; + if ( (signed int)uNumFaces > 0 ) + { + pDest = 0; + do + { + fread(Dst, 1u, 0xAu, v7); + if ( pDest[(unsigned int)pFaces + 45] & 0x40 ) + { + v23 = pTextureFrameTable->FindTextureByName(Dst); + v24 = pDest; + *(short *)&pDest[(unsigned int)pFaces + 74] = v23; + v25 = *(short *)&v24[(unsigned int)pFaces + 74]; + if ( v25 ) + { + pTextureFrameTable->LoadAnimationSequenceAndPalettes(v25); + } + else + { + v26 = pBitmaps_LOD->LoadTexture(Dst); + v27 = pDest; + *(short *)&pDest[(unsigned int)pFaces + 74] = v26; + v27[(unsigned int)pFaces + 45] &= 0xBFu; + } + } + else + { + *(short *)&pDest[(unsigned int)pFaces + 74] = pBitmaps_LOD->LoadTexture(Dst); + } + ++Argsb; + pDest += 96; + } + while ( Argsb < (signed int)uNumFaces ); + } + fseek(v7, v211, 0); + fread(&uNumFaceExtras, 4u, 1u, v7); + fseek(v7, v212, 0); + fread(pFaceExtras, 0x24u, uNumFaceExtras, v7); + Argsc = 0; + if ( (signed int)uNumFaceExtras > 0 ) + { + pDest = 0; + do + { + fread(Dst, 1u, 0xAu, v7); + v28 = pBitmaps_LOD->LoadTexture(Dst); + v29 = pFaceExtras; + v30 = pDest; + ++Argsc; + pDest += 36; + *(unsigned __int16 *)((char *)&v29->uAdditionalBitmapID + (int)v30) = v28; + } + while ( Argsc < (signed int)uNumFaceExtras ); + } + Argsd = 0; + if ( (signed int)uNumFaces > 0 ) + { + pDest = 0; + do + { + v31 = (int)&pFaceExtras[*(short *)&pDest[(unsigned int)pFaces + 72]]; + if ( *(short *)(v31 + 26) ) + { + if ( ((BLVFaceExtra *)v31)->HasEventint() ) + pDest[(unsigned int)pFaces + 46] |= 0x10u; + else + pDest[(unsigned int)pFaces + 46] &= 0xEFu; + } + ++Argsd; + pDest += 96; + } + while ( Argsd < (signed int)uNumFaces ); + } + fseek(v7, v213, 0); + fread(&uNumSectors, 4u, 1u, v7); + fseek(v7, v214, 0); + fread(pSectors, 0x74u, uNumSectors, v7); + v32 = malloc(ptr_0002B0_sector_rdata, blv.uSector_rdata_Size, "L.RData"); + v202 = (int)v7; + ptr_0002B0_sector_rdata = (unsigned __int16 *)v32; + fread(v32, 1u, blv.uSector_rdata_Size, (FILE *)v202); + v11 = uNumSectors == 0; + v12 = uNumSectors < 0; + pDest = 0; + Argse = 0; + if ( !(v12 | v11) ) + { + v33 = 0; + do + { + pSectors[v33].pFloors = (unsigned __int16 *)&pDest[(unsigned int)ptr_0002B0_sector_rdata]; + i = (size_t)&pSectors[v33]; + v34 = ptr_0002B0_sector_rdata; + pDest += 2 * *(short *)(i + 4); + *(int *)(i + 16) = (int)(char *)v34 + (int)pDest; + v35 = (size_t)&pSectors[v33]; + i = v35; + v36 = &pDest[2 * *(short *)(v35 + 12)]; + v37 = (int)&v36[(unsigned int)ptr_0002B0_sector_rdata]; + pDest = v36; + *(int *)(i + 24) = v37; + v38 = (size_t)&pSectors[v33]; + i = v38; + v39 = &pDest[2 * *(short *)(v38 + 20)]; + v40 = (int)&v39[(unsigned int)ptr_0002B0_sector_rdata]; + pDest = v39; + *(int *)(i + 32) = v40; + i = (size_t)&pSectors[v33]; + v41 = ptr_0002B0_sector_rdata; + pDest += 2 * *(short *)(i + 28); + *(int *)(i + 40) = (int)(char *)v41 + (int)pDest; + i = (size_t)&pSectors[v33]; + v42 = ptr_0002B0_sector_rdata; + pDest += 2 * *(short *)(i + 36); + *(int *)(i + 48) = (int)(char *)v42 + (int)pDest; + i = (size_t)&pSectors[v33]; + v43 = ptr_0002B0_sector_rdata; + pDest += 2 * *(short *)(i + 44); + *(int *)(i + 64) = (int)(char *)v43 + (int)pDest; + i = (size_t)&pSectors[v33]; + v44 = ptr_0002B0_sector_rdata; + pDest += 2 * *(short *)(i + 60); + *(int *)(i + 72) = (int)(char *)v44 + (int)pDest; + v45 = (size_t)&pSectors[v33]; + ++v33; + i = v45; + v46 = ptr_0002B0_sector_rdata; + pDest += 2 * *(short *)(v45 + 68); + ++Argse; + *(int *)(v45 + 80) = (int)(char *)v46 + (int)pDest; + pDest += 2 * *((short *)&pSectors[v33] - 20); + } + while ( Argse < uNumSectors ); + } + v47 = malloc( + ptr_0002B8_sector_lrdata, + blv.uSector_lrdata_Size, + "L.RLData"); + v202 = (int)v7; + ptr_0002B8_sector_lrdata = (unsigned __int16 *)v47; + fread(v47, 1u, blv.uSector_lrdata_Size, (FILE *)v202); + v11 = uNumSectors == 0; + v12 = uNumSectors < 0; + pDest = 0; + Argsf = 0; + if ( !(v12 | v11) ) + { + v48 = pSectors; + v49 = 0; + for ( i = 0; ; v49 = i ) + { + v50 = ptr_0002B8_sector_lrdata; + i += 116; + ++Argsf; + *(BLVLightMM7 **)((char *)&v48->pLights + v49) = (BLVLightMM7 *)((char *)v50 + (int)pDest); + v48 = pSectors; + pDest += 2 * *(__int16 *)((char *)&v48->uNumLights + v49); + if ( Argsf >= uNumSectors ) + break; + } + } + fseek(v7, v215, 0); + fread(&uNumDoors, 4u, 1u, v7); + fseek(v7, v216, 0); + fread(pDoors, 0x50u, 0xC8u, v7); + v51 = malloc(ptr_0002B4_doors_ddata, blv.uDoors_ddata_Size, "L.DData"); + v202 = (int)v7; + ptr_0002B4_doors_ddata = (unsigned __int16 *)v51; + fread(v51, 1u, blv.uDoors_ddata_Size, (FILE *)v202); + v11 = uNumDoors == 0; + v12 = uNumDoors < 0; + pDest = 0; + Argsg = 0; + if ( !(v12 | v11) ) + { + v52 = 0; + do + { + pDoors[v52].pVertexIDs = (unsigned __int16 *)&pDest[(unsigned int)ptr_0002B4_doors_ddata]; + i = (size_t)&pDoors[v52]; + v53 = ptr_0002B4_doors_ddata; + pDest += 2 * *(short *)(i + 68); + *(int *)(i + 40) = (int)(char *)v53 + (int)pDest; + v54 = (size_t)&pDoors[v52]; + i = v54; + v55 = &pDest[2 * *(short *)(v54 + 70)]; + v56 = (int)&v55[(unsigned int)ptr_0002B4_doors_ddata]; + pDest = v55; + *(int *)(i + 44) = v56; + v57 = (size_t)&pDoors[v52]; + i = v57; + v58 = &pDest[2 * *(short *)(v57 + 72)]; + v59 = (int)&v58[(unsigned int)ptr_0002B4_doors_ddata]; + pDest = v58; + *(int *)(i + 48) = v59; + i = (size_t)&pDoors[v52]; + v60 = ptr_0002B4_doors_ddata; + pDest += 2 * *(short *)(i + 70); + *(int *)(i + 52) = (int)(char *)v60 + (int)pDest; + i = (size_t)&pDoors[v52]; + v61 = ptr_0002B4_doors_ddata; + pDest += 2 * *(short *)(i + 70); + *(int *)(i + 56) = (int)(char *)v61 + (int)pDest; + i = (size_t)&pDoors[v52]; + v62 = ptr_0002B4_doors_ddata; + pDest += 2 * *(short *)(i + 74); + *(int *)(i + 60) = (int)(char *)v62 + (int)pDest; + i = (size_t)&pDoors[v52]; + v63 = ptr_0002B4_doors_ddata; + pDest += 2 * *(short *)(i + 74); + *(int *)(i + 64) = (int)(char *)v63 + (int)pDest; + ++Argsg; + v64 = pDoors[v52].uNumOffsets; + ++v52; + pDest += 2 * v64; + } + while ( Argsg < uNumDoors ); + } + Argsh = 0; + if ( uNumDoors > 0 ) + { + v65 = pDoors; + pDest = 0; + do + { + i = 0; + v66 = &pDest[(int)v65]; + if ( *(short *)&pDest[(int)v65 + 70] > 0 ) + { + do + { + v67 = *((int *)v66 + 10); + a3 = 2 * i; + v68 = *(short *)(v67 + 2 * i); + v69 = pFaces; + ++i; + v70 = (int)&pFaceExtras[v69[v68].uFaceExtraID]; + v71 = *((int *)v66 + 12); + v72 = a3; + v238 = (char *)v70; + *(short *)(a3 + v71) = *(short *)(v70 + 20); + *(__int16 *)(*(char **)((char *)&pDoors->pDeltaVs + (unsigned int)pDest) + v72) = *((short *)v238 + 11); + v65 = pDoors; + v66 = &pDest[(int)v65]; + } + while ( (signed int)i < *(short *)&pDest[(int)v65 + 70] ); + } + ++Argsh; + pDest += 80; + } + while ( Argsh < uNumDoors ); + } + fseek(v7, v217, 0); + fread(&uNumLevelDecorations, 4u, 1u, v7); + fseek(v7, v218, 0); + fread(pLevelDecorations, 0x20u, uNumLevelDecorations, v7); + Argsi = 0; + if ( (signed int)uNumLevelDecorations > 0 ) + { + pDest = (char *)pLevelDecorations; + do + { + fread(pName, 1u, 0x20u, v7); + v73 = pDecorationList->GetDecorIdByName(pName); + v74 = pDest; + ++Argsi; + pDest += 32; + *(short *)v74 = v73; + } + while ( Argsi < (signed int)uNumLevelDecorations ); + } + fseek(v7, v219, 0); + fread(&uNumSpriteObjects, 4u, 1u, v7); + fseek(v7, v220, 0); + fread(pSpriteObjects, 0x70u, uNumSpriteObjects, v7); + if ( (signed int)uNumSpriteObjects > 0 ) + { + v75 = pSpriteObjects; + pDest = (char *)uNumSpriteObjects; + do + { + Argsj = 0; + v76 = 48 * v75->stru_24.uItemID; + v11 = pObjectList->uNumObjects == 0; + v12 = (pObjectList->uNumObjects & 0x80000000u) != 0; + LOWORD(v76) = *(unsigned __int16 *)((char *)&pItemsTable->pItems[0].uSpriteID + v76); + i = v76; + v75->uItemType = v76; + if ( v12 | v11 ) + { +LABEL_50: + v78 = 0; + } + else + { + for ( j = (int)&pObjectList->pObjects->uObjectID; (short)v76 != *(short *)j; j = a3 ) + { + ++Argsj; + a3 = j + 56; + if ( Argsj >= (signed int)pObjectList->uNumObjects ) + goto LABEL_50; + LOWORD(v76) = i; + } + v78 = Argsj; + } + v75->uObjectDescID = v78; + ++v75; + --pDest; + } + while ( pDest ); + } + fseek(v7, v221, 0); + fread(&uNumActors, 4u, 1u, v7); + fseek(v7, v222, 0); + fread(pActors, 0x344u, uNumActors, v7); + fseek(v7, v228, 0); + fread(&uNumChests, 4u, 1u, v7); + fseek(v7, v229, 0); + fread(pChests, 0x14CCu, uNumChests, v7); + fseek(v7, v224, 0); + fread(&uNumLights, 4u, 1u, v7); + fseek(v7, v225, 0); + fread(pLights, 0x10u, uNumLights, v7); + fseek(v7, v226, 0); + fread(&uNumNodes, 4u, 1u, v7); + fseek(v7, v227, 0); + fread(pNodes, 8u, uNumNodes, v7); + fseek(v7, v230, 0); + fread(&uNumSpawnPoints, 4u, 1u, v7); + v79 = malloc(pSpawnPoints, 24 * uNumSpawnPoints, "Spawn"); + v202 = 0; + pSpawnPoints = (SpawnPointMM7 *)v79; + fseek(v7, v231, v202); + fread(pSpawnPoints, 0x18u, uNumSpawnPoints, v7); + fseek(v7, v232, 0); + fread(&dlv, 0x28u, 1u, v7); + fseek(v7, v233, 0); + fread(&stru_5E4C90, 1u, 0xC8u, v7); + fseek(v7, v234, 0); + fread(&uLastVisitDay, 1u, 0x38u, v7); + fseek(v7, v223, 0); + v80 = (void **)&pMapOutlines; + fread(*v80, 4u, 1u, v7); + fread((char *)*v80 + 4, 0xCu, *(int *)*v80, v7); + fclose(v7); + goto LABEL_179; + } + return 4; + }*/ + #pragma endregion + + if (bLoaded) + { + Log::Warning(L"BLV is already loaded"); + return 3; + } + + if ( !pGames_LOD->DoesContainerExist(pFilename) ) + Error("Unable to find %s in Games.LOD", pFilename); + + //v238 = pFilename - 4; + //v81 = strlen(pFilename); + strcpy(this->pFilename, pFilename); + strcpy(&pFilename[strlen(pFilename) - 4], ".blv"); + File = pGames_LOD->FindContainer(pFilename, 1); + //File = v82; + + Release(); + if ( !Alloc() ) + return 4; + + header.uVersion = 91969; + header.pMagic[0] = 'm'; + header.pMagic[1] = 'v'; + header.pMagic[2] = 'i'; + header.pMagic[3] = 'i'; + header.uCompressedSize = 0; + header.uDecompressedSize = 0; + fread(&header, sizeof(ODMHeader), 1, File); + if (header.uVersion != 91969 || + header.pMagic[0] != 'm' || + header.pMagic[1] != 'v' || + header.pMagic[2] != 'i' || + header.pMagic[3] != 'i' ) + { + MessageBoxW(nullptr, L"Can't load file!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Polydata.cpp:792", 0); + } + //v83 = header.uCompressedSize; + //pSource = header.uDecompressedSize; + //v84 = malloc(header.uDecompressedSize); + //v85 = v84; + //ptr = v84; + void* pRawBLV = malloc(header.uDecompressedSize); + memset(pRawBLV, 0, header.uDecompressedSize); + + if (header.uCompressedSize == header.uDecompressedSize) + fread(pRawBLV, header.uDecompressedSize, 1, File); + else if (header.uCompressedSize < header.uDecompressedSize) + { + void* pTmpMem = malloc(header.uCompressedSize); + { + fread(pTmpMem, header.uCompressedSize, 1, File); + + uint uDecompressedSize = header.uDecompressedSize; + zlib::MemUnzip(pRawBLV, &uDecompressedSize, pTmpMem, header.uCompressedSize); + + if (uDecompressedSize != header.uDecompressedSize) + Log::Warning(L"uDecompressedSize != header.uDecompressedSize in BLV"); + } + free(pTmpMem); + } + else + { + MessageBoxW(nullptr, L"Can't load file!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Polydata.cpp:803", 0); + return 0; + } + + bLoaded = true; + + char* pData = (char *)pRawBLV; + + pGameLoadingUI_ProgressBar->Progress(); + + memcpy(&blv, pData, 136); + memcpy(&uNumVertices, pData += 136, 4); + memcpy(pVertices, pData += 4, uNumVertices * sizeof(Vec3_short_)); + + pGameLoadingUI_ProgressBar->Progress(); + + memcpy(&uNumFaces, pData += uNumVertices * sizeof(Vec3_short_), 4); + + pGameLoadingUI_ProgressBar->Progress(); + + memcpy(pFaces, pData += 4, uNumFaces * sizeof (BLVFace)); + pLFaces = (unsigned __int16 *)malloc(blv.uFaces_fdata_Size); + + memcpy(pLFaces, pData += uNumFaces * sizeof (BLVFace), blv.uFaces_fdata_Size); + + for (uint i = 0, j = 0; i < uNumFaces; ++i) + { + BLVFace* pFace = &pFaces[i]; + + pFace->pVertexIDs = &pLFaces[j]; + + j += pFace->uNumVertices + 1; + pFace->pXInterceptDisplacements = (short *)(&pLFaces[j]); + + j += pFace->uNumVertices + 1; + pFace->pYInterceptDisplacements = (short *)(&pLFaces[j]); + + j += pFace->uNumVertices + 1; + pFace->pZInterceptDisplacements = (short *)(&pLFaces[j]); + + j += pFace->uNumVertices + 1; + pFace->pVertexUIDs = (__int16 *)(&pLFaces[j]); + + j += pFace->uNumVertices + 1; + pFace->pVertexVIDs = (__int16 *)(&pLFaces[j]); + + j += pFace->uNumVertices + 1; + /*v93 = &pFaces[v92]; + Src = v93; + v94 = (BLVSector *)((char *)v244 + 2 * v93->uNumVertices + 2); + v95 = (unsigned __int16 *)((char *)v94 + (unsigned int)ptr_2AC); + v244 = v94; + Src->pXInterceptDisplacements = v95; + v96 = (int)&pFaces[v92]; + Src = (BLVFace *)v96; + v97 = (BLVSector *)((char *)v244 + 2 * *(char *)(v96 + 93) + 2); + v98 = (unsigned __int16 *)((char *)v97 + (unsigned int)ptr_2AC); + v244 = v97; + Src->pYInterceptDisplacements = v98; + Src = &pFaces[v92]; + v99 = ptr_2AC; + v244 = (BLVSector *)((char *)v244 + 2 * Src->uNumVertices + 2); + Src->pZInterceptDisplacements = (unsigned __int16 *)((char *)v99 + (int)v244); + Src = &pFaces[v92]; + v100 = ptr_2AC; + v244 = (BLVSector *)((char *)v244 + 2 * Src->uNumVertices + 2); + Src->pVertexUIDs = (unsigned __int16 *)((char *)v100 + (int)v244); + Src = &pFaces[v92]; + ++v92; + v101 = ptr_2AC; + v244 = (BLVSector *)((char *)v244 + 2 * Src->uNumVertices + 2); + ++v245; + Src->pVertexVIDs = (unsigned __int16 *)((char *)v101 + (int)v244); + v244 = (BLVSector *)((char *)v244 + 2 * *((char *)&pFaces[v92] - 3) + 2);*/ + } + + pGameLoadingUI_ProgressBar->Progress(); + + pData += blv.uFaces_fdata_Size; + + for (uint i = 0; i < uNumFaces; ++i) + { + BLVFace* pFace = &pFaces[i]; + + char pTexName[16]; + strncpy(pTexName, pData, 10); + pData += 10; + + if (pFace->uAttributes & FACE_TEXTURE_FRAME) + { + pFace->uBitmapID = pTextureFrameTable->FindTextureByName(pTexName); + if (pFace->uBitmapID) + pTextureFrameTable->LoadAnimationSequenceAndPalettes(pFace->uBitmapID); + else + { + pFace->uBitmapID = pBitmaps_LOD->LoadTexture(pTexName); + pFace->uAttributes &= ~FACE_TEXTURE_FRAME; + } + } + else + pFace->uBitmapID = pBitmaps_LOD->LoadTexture(pTexName); + } + + pGameLoadingUI_ProgressBar->Progress(); + + memcpy(&uNumFaceExtras, pData, 4); + memcpy(pFaceExtras, pData += 4, uNumFaceExtras * sizeof(BLVFaceExtra)); + pData += uNumFaceExtras * sizeof(BLVFaceExtra); + + pGameLoadingUI_ProgressBar->Progress(); + + //v108 = (char *)v107 + 36 * uNumFaceExtras; + //v245 = 0; + //*(int *)((char *)&uSourceLen + 1) = 0; + for (uint i = 0; i < uNumFaceExtras; ++i) + { + char pTexName[32]; + strncpy(pTexName, pData, 10); + pData += 10; + + if (!strcmp(pTexName, "")) + pFaceExtras[i].uAdditionalBitmapID = -1; + else + pFaceExtras[i].uAdditionalBitmapID = pBitmaps_LOD->LoadTexture(pTexName); + } + + + for (uint i = 0; i < uNumFaces; ++i) + { + BLVFace* pFace = &pFaces[i]; + BLVFaceExtra* pFaceExtra = &pFaceExtras[pFace->uFaceExtraID]; + + if (pFaceExtra->uEventID) + { + if (pFaceExtra->HasEventint()) + pFace->uAttributes |= FACE_HAS_EVENT; + else + pFace->uAttributes &= ~FACE_HAS_EVENT; + } + } + + pGameLoadingUI_ProgressBar->Progress(); + + memcpy(&uNumSectors, pData, 4); + memcpy(pSectors, pData + 4, uNumSectors * sizeof(BLVSector)); + pData += 4 + uNumSectors * sizeof(BLVSector); + + pGameLoadingUI_ProgressBar->Progress(); + + ptr_0002B0_sector_rdata = (unsigned short *)malloc(blv.uSector_rdata_Size);//, "L.RData"); + memcpy(ptr_0002B0_sector_rdata, pData, blv.uSector_rdata_Size); + pData += blv.uSector_rdata_Size; + + for (uint i = 0, j = 0; i < uNumSectors; ++i) + { + BLVSector* pSector = &pSectors[i]; + + pSector->pFloors = &ptr_0002B0_sector_rdata[j]; + j += pSector->uNumFloors; + + pSector->pWalls = &ptr_0002B0_sector_rdata[j]; + j += pSector->uNumWalls; + + pSector->pCeilings = &ptr_0002B0_sector_rdata[j]; + j += pSector->uNumCeilings; + + pSector->pFluids = &ptr_0002B0_sector_rdata[j]; + j += pSector->uNumFluids; + + pSector->pPortals = &ptr_0002B0_sector_rdata[j]; + j += pSector->uNumPortals; + + pSector->pFaceIDs = &ptr_0002B0_sector_rdata[j]; + j += pSector->uNumFaces; + + pSector->pCogs = &ptr_0002B0_sector_rdata[j]; + j += pSector->uNumCogs; + + pSector->pDecorationIDs = &ptr_0002B0_sector_rdata[j]; + j += pSector->uNumDecorations; + + pSector->pMarkers = &ptr_0002B0_sector_rdata[j]; + j += pSector->uNumMarkers; + + + //do + //{ + /*pSectors[v118].pFloors = (unsigned __int16 *)((char *)Src + (unsigned int)ptr_0002B0_sector_rdata); + v244 = &pSectors[v118]; + v119 = ptr_0002B0_sector_rdata; + Src = (BLVFace *)((char *)Src + 2 * v244->field_4); + v244->pWalls = (unsigned __int16 *)((char *)v119 + (int)Src); + v120 = (int)&pSectors[v118]; + v244 = (BLVSector *)v120; + v121 = (BLVFace *)((char *)Src + 2 * *(short *)(v120 + 12)); + v122 = (unsigned __int16 *)((char *)v121 + (unsigned int)ptr_0002B0_sector_rdata); + Src = v121; + v244->pCeilings = v122; + v123 = (int)&pSectors[v118]; + v244 = (BLVSector *)v123; + v124 = (BLVFace *)((char *)Src + 2 * *(short *)(v123 + 20)); + v125 = (unsigned __int16 *)((char *)v124 + (unsigned int)ptr_0002B0_sector_rdata); + Src = v124; + v244->pFluids = v125; + v244 = &pSectors[v118]; + v126 = ptr_0002B0_sector_rdata; + Src = (BLVFace *)((char *)Src + 2 * v244->field_1C); + v244->pPortals = (unsigned __int16 *)((char *)v126 + (int)Src); + v244 = &pSectors[v118]; + v127 = ptr_0002B0_sector_rdata; + Src = (BLVFace *)((char *)Src + 2 * v244->uNumPortals); + v244->pFaceIDs = (unsigned __int16 *)((char *)v127 + (int)Src); + v244 = &pSectors[v118]; + v128 = ptr_0002B0_sector_rdata; + Src = (BLVFace *)((char *)Src + 2 * v244->field_2C); + v244->pCogs = (unsigned __int16 *)((char *)v128 + (int)Src); + v244 = &pSectors[v118]; + v129 = ptr_0002B0_sector_rdata; + Src = (BLVFace *)((char *)Src + 2 * v244->field_3C); + v244->pDecorationIDs = (unsigned __int16 *)((char *)v129 + (int)Src); + v130 = (int)&pSectors[v118]; + ++v118; + v244 = (BLVSector *)v130; + v131 = ptr_0002B0_sector_rdata; + Src = (BLVFace *)((char *)Src + 2 * *(short *)(v130 + 68)); + ++v245; + *(int *)(v130 + 80) = (int)(char *)v131 + (int)Src; + Src = (BLVFace *)((char *)Src + 2 * *((short *)&pSectors[v118] - 20));*/ + //} + //while ( v245 < uNumSectors ); + } + + ptr_0002B8_sector_lrdata = (unsigned __int16 *)malloc(blv.uSector_lrdata_Size);//, "L.RLData"); + memcpy(ptr_0002B8_sector_lrdata, pData, blv.uSector_lrdata_Size); + pData += blv.uSector_lrdata_Size; + + pGameLoadingUI_ProgressBar->Progress(); + + for (uint i = 0, j = 0; i < uNumSectors; ++i) + { + pSectors[i].pLights = ptr_0002B8_sector_lrdata + j; + j += pSectors[i].uNumLights; + } + + pGameLoadingUI_ProgressBar->Progress(); + + memcpy(&uNumDoors, pData, 4); + pData += 4; + + pGameLoadingUI_ProgressBar->Progress(); + pGameLoadingUI_ProgressBar->Progress(); + + memcpy(&uNumLevelDecorations, pData, 4); + memcpy(pLevelDecorations.data(), pData + 4, uNumLevelDecorations * sizeof(LevelDecoration)); + pData += 4 + uNumLevelDecorations * sizeof(LevelDecoration); + + for (uint i = 0; i < uNumLevelDecorations; ++i) + { + pLevelDecorations[i].uDecorationDescID = pDecorationList->GetDecorIdByName(pData); + + pData += 32; + } + + pGameLoadingUI_ProgressBar->Progress(); + + memcpy(&uNumLights, pData, 4); + memcpy(pLights, pData + 4, uNumLights * sizeof(BLVLightMM7)); + pData += 4 + uNumLights * sizeof(BLVLightMM7); + + pGameLoadingUI_ProgressBar->Progress(); + pGameLoadingUI_ProgressBar->Progress(); + + memcpy(&uNumNodes, pData, 4); + memcpy(pNodes, pData + 4, uNumNodes * sizeof(BSPNode)); + pData += 4 + uNumNodes * sizeof(BSPNode); + + pGameLoadingUI_ProgressBar->Progress(); + pGameLoadingUI_ProgressBar->Progress(); + + memcpy(&uNumSpawnPoints, pData, 4); + pSpawnPoints = (SpawnPointMM7 *)malloc(uNumSpawnPoints * sizeof(SpawnPointMM7)); + memcpy(pSpawnPoints, pData + 4, uNumSpawnPoints * sizeof(SpawnPointMM7)); + pData += 4 + uNumSpawnPoints * sizeof(SpawnPointMM7); + + pGameLoadingUI_ProgressBar->Progress(); + pGameLoadingUI_ProgressBar->Progress(); + + //v201 = (const char *)v148; + //v200 = (size_t)pMapOutlines; + memcpy(&pMapOutlines->uNumOutlines, pData, 4); + memcpy(pMapOutlines->pOutlines, pData + 4, pMapOutlines->uNumOutlines * sizeof(BLVMapOutline)); + //v149 = pMapOutlines; + //v199 = 12 * *v149; + //memcpy(v149 + 1, (const void *)(v148 + 4), v199); + free(pRawBLV); + pRawBLV = nullptr; + + void *pRawDLV = nullptr; + strcpy(&pFilename[strlen(pFilename) - 4], ".dlv"); + File = pNew_LOD->FindContainer(pFilename, 1);//error on D28.dlv + fread(&header, 0x10, 1, File);//(FILE *)v245); + bool _v244 = false; + if (header.uVersion != 91969 || + header.pMagic[0] != 'm' || + header.pMagic[1] != 'v' || + header.pMagic[2] != 'i' || + header.pMagic[3] != 'i' ) + { + MessageBoxW(nullptr, L"Can't load file!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Polydata.cpp:1090", 0); + _v244 = true; + } + else + { + pRawDLV = malloc(header.uDecompressedSize); + if (header.uCompressedSize == header.uDecompressedSize) + fread(pRawDLV, 1, header.uCompressedSize, File); + else if (header.uCompressedSize < header.uDecompressedSize) + { + void* pTmpMem = malloc(header.uCompressedSize); + { + fread(pTmpMem, header.uCompressedSize, 1, File); + + uint uDecompressedSize = header.uDecompressedSize; + zlib::MemUnzip(pRawDLV, &uDecompressedSize, pTmpMem, header.uCompressedSize); + + if (uDecompressedSize != header.uDecompressedSize) + Log::Warning(L"uDecompressedSize != header.uDecompressedSize in DLV"); + } + free(pTmpMem); + } + else + MessageBoxW(nullptr, L"Can't load file!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Polydata.cpp:1108", 0); + + pData = (char *)pRawDLV; + } + + memcpy(&dlv, pData, 40); + pData += 40; + + //v152 = dlv.uNumFacesInBModels; + if (dlv.uNumFacesInBModels) + { + //v153 = dlv.uNumDecorations; + if (dlv.uNumDecorations) + { + if (dlv.uNumFacesInBModels != uNumFaces || + dlv.uNumDecorations != uNumLevelDecorations) + _v244 = true; + } + } + + if (dword_6BE364_game_settings_1 & GAME_SETTINGS_2000 ) + _i = 0x1BAF800; + bool _a = false; + if ( a3 - dlv.uLastRepawnDay >= _i && _stricmp(pCurrentMapName, "d29.dlv") ) + _a = true; + + //v154 = 875; + if (_v244 || (_a || !dlv.uLastRepawnDay)) + { + if (_v244) + { + memset(v203, 0, 0x36B); + } + else if (_a || !dlv.uLastRepawnDay) + { + memcpy(v203, pData, 0x36B); + } + + free(pRawDLV); + dlv.uLastRepawnDay = a3; + if (_v244) + ++dlv.uNumRespawns; + //v201 = pFilename; + *(int *)pDest = 1; + File = pGames_LOD->FindContainer(pFilename, 0); + fread(&header, 0x10u, 1, File); + uint v155 = header.uCompressedSize; + uint Count = header.uDecompressedSize; + BLVFace* Src = (BLVFace *)malloc(header.uDecompressedSize); + pRawDLV = Src; + if (v155 <= Count) + { + if (v155 == Count) + fread(Src, 1, Count, File); + else + { + void* _uSourceLen = malloc(v155); + fread(_uSourceLen, v155, 1, File); + zlib::MemUnzip(Src, &Count, _uSourceLen, v155); + free(_uSourceLen); + } + } + else + MessageBoxW(nullptr, L"Can't load file!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Polydata.cpp:1195", 0); + pData = ((char *)Src + 40); + //v154 = 875; + } + else + { + *(int *)pDest = 0; + } + + +//LABEL_140: + //v202 = (int)".blv"; + //v156 = strlen(pFilename); + strcpy(&pFilename[strlen(pFilename) - 4], ".blv"); + memcpy(_visible_outlines, pData, 875); + pData += 875; + + if ( *(int *)pDest ) + memcpy(_visible_outlines, v203, 875); + + for (uint i = 0; i < pMapOutlines->uNumOutlines; ++i) + { + BLVMapOutline* pVertex = &pMapOutlines->pOutlines[i]; + if ((unsigned __int8)(1 << (7 - i % 8)) & _visible_outlines[i / 8]) + pVertex->uFlags |= 1; + } + + + for (uint i = 0; i < uNumFaces; ++i) + { + BLVFace* pFace = &pFaces[i]; + BLVFaceExtra* pFaceExtra = &pFaceExtras[pFace->uFaceExtraID]; + + memcpy(&pFace->uAttributes, pData, 4); + pData += 4; + + if (pFaceExtra->uEventID) + { + if (pFaceExtra->HasEventint()) + pFace->uAttributes |= FACE_HAS_EVENT; + else + pFace->uAttributes &= ~FACE_HAS_EVENT; + } + } + + pGameLoadingUI_ProgressBar->Progress(); + + for (uint i = 0; i < uNumLevelDecorations; ++i) + { + memcpy(&pLevelDecorations[i].uFlags, pData, 2); + pData += 2; + } + + pGameLoadingUI_ProgressBar->Progress(); + + memcpy(&uNumActors, pData, 4); + memcpy(&pActors, pData + 4, uNumActors * sizeof(Actor)); + pData += 4 + uNumActors * sizeof(Actor); + + pGameLoadingUI_ProgressBar->Progress(); + pGameLoadingUI_ProgressBar->Progress(); + + memcpy(&uNumSpriteObjects, pData, 4); + memcpy(pSpriteObjects.data(), pData + 4, uNumSpriteObjects * sizeof(SpriteObject)); + pData += 4 + uNumSpriteObjects * sizeof(SpriteObject); + + pGameLoadingUI_ProgressBar->Progress(); + + for ( uint i = 0; i < uNumSpriteObjects; ++i ) + { + if (pSpriteObjects[i].stru_24.uItemID && !(pSpriteObjects[i].uAttributes & 0x0100)) + { + pSpriteObjects[i].uType = pItemsTable->pItems[pSpriteObjects[i].stru_24.uItemID].uSpriteID; + + //uint uObjectID = 0; + for ( uint j = 0; j < pObjectList->uNumObjects; ++j ) + if ( pSpriteObjects[i].uType == pObjectList->pObjects[j].uObjectID ) + { + pSpriteObjects[i].uObjectDescID = j; + break; + } + } + } + + pGameLoadingUI_ProgressBar->Progress(); + + memcpy(&uNumChests, pData, 4); + memcpy(pChests.data(), pData + 4, uNumChests * sizeof(Chest)); + pData += 4 + uNumChests * sizeof(Chest); + + pGameLoadingUI_ProgressBar->Progress(); + pGameLoadingUI_ProgressBar->Progress(); + + memcpy(pDoors, pData, 0x3E80); + pData += 0x3E80; + + //v201 = (const char *)blv.uDoors_ddata_Size; + //v200 = (size_t)ptr_0002B4_doors_ddata; + //v170 = malloc(ptr_0002B4_doors_ddata, blv.uDoors_ddata_Size, "L.DData"); + //v171 = blv.uDoors_ddata_Size; + ptr_0002B4_doors_ddata = (unsigned __int16 *)malloc(blv.uDoors_ddata_Size);//, "L.DData"); + memcpy(ptr_0002B4_doors_ddata, pData, blv.uDoors_ddata_Size); + pData += blv.uDoors_ddata_Size; + + //Src = (BLVFace *)((char *)Src + v171); + //v172 = 0; + //v245 = 0; + //if (uNumDoors > 0) + for (uint i = 0, j = 0; i < uNumDoors; ++i) + { + BLVDoor* pDoor = &pDoors[i]; + + pDoor->pVertexIDs = &ptr_0002B4_doors_ddata[j]; + j += pDoor->uNumVertices; + + pDoor->pFaceIDs = &ptr_0002B4_doors_ddata[j]; + j += pDoor->uNumFaces; + + pDoor->pSectorIDs = &ptr_0002B4_doors_ddata[j]; + j += pDoor->field_48; + + pDoor->pDeltaUs = (short *)(&ptr_0002B4_doors_ddata[j]); + j += pDoor->uNumFaces; + + pDoor->pDeltaVs = (short *)(&ptr_0002B4_doors_ddata[j]); + j += pDoor->uNumFaces; + + pDoor->pXOffsets = &ptr_0002B4_doors_ddata[j]; + j += pDoor->uNumOffsets; + + pDoor->pYOffsets = &ptr_0002B4_doors_ddata[j]; + j += pDoor->uNumOffsets; + + pDoor->pZOffsets = &ptr_0002B4_doors_ddata[j]; + j += pDoor->uNumOffsets; + /*v173 = pDoors; + for ( k = 0; ; v172 = v188 + 2 * *((short *)&v173[k] - 3) ) + { + v173[k].pVertexIDs = (unsigned __int16 *)((char *)ptr_0002B4_doors_ddata + v172); + v175 = &pDoors[k]; + v176 = v172 + 2 * v175->uNumVertices; + v175->pFaceIDs = (unsigned __int16 *)((char *)ptr_0002B4_doors_ddata + v176); + v177 = &pDoors[k]; + v178 = v176 + 2 * v177->uNumFaces; + v177->pSectorIDs = (unsigned __int16 *)((char *)ptr_0002B4_doors_ddata + v178); + v179 = &pDoors[k]; + v180 = v178 + 2 * v179->field_48; + v179->pDeltaUs = (__int16 *)((char *)ptr_0002B4_doors_ddata + v180); + v181 = &pDoors[k]; + v182 = v180 + 2 * v181->uNumFaces; + v181->pDeltaVs = (__int16 *)((char *)ptr_0002B4_doors_ddata + v182); + v183 = &pDoors[k]; + v184 = v182 + 2 * v183->uNumFaces; + v183->pXOffsets = (unsigned __int16 *)((char *)ptr_0002B4_doors_ddata + v184); + v185 = &pDoors[k]; + v186 = v184 + 2 * v185->uNumOffsets; + v185->pYOffsets = (unsigned __int16 *)((char *)ptr_0002B4_doors_ddata + v186); + v187 = &pDoors[k]; + ++k; + v188 = v186 + 2 * v187->uNumOffsets; + v189 = (unsigned __int16 *)((char *)ptr_0002B4_doors_ddata + v188); + ++v245; + v187->pZOffsets = v189; + v173 = pDoors; + if ( v245 >= uNumDoors ) + break; + }*/ + } + //v190 = 0; + //v245 = 0; + for (uint i = 0; i < uNumDoors; ++i) + { + BLVDoor* pDoor = &pDoors[i]; + + for (uint j = 0; j < pDoor->uNumFaces; ++j) + { + BLVFace* pFace = &pFaces[pDoor->pFaceIDs[j]]; + BLVFaceExtra* pFaceExtra = &pFaceExtras[pFace->uFaceExtraID]; + + pDoor->pDeltaUs[j] = pFaceExtra->sTextureDeltaU; + pDoor->pDeltaVs[j] = pFaceExtra->sTextureDeltaV; + } + //v191 = pDoors; + //pDest = 0; + //do + // { + /*Argsn = 0; + for ( l = (BLVDoor *)&v190[(int)v191]; + Argsn < *(short *)&v190[(int)v191 + 70]; + l = (BLVDoor *)&v190[(int)v191] ) + { + v193 = Argsn; + v194 = l->pFaceIDs[Argsn++]; + v195 = &pFaceExtras[pFaces[v194].uFaceExtraID]; + l->pDeltaUs[v193] = v195->sTextureDeltaU; + v190 = pDest; + *(short *)(v193 * 2 + *(int *)&pDest[(unsigned int)pDoors + 52]) = v195->sTextureDeltaV; + v191 = pDoors; + } + ++v245; + v190 += 80; + pDest = v190;*/ + //} + //while ( v245 < uNumDoors ); + } + + + pGameLoadingUI_ProgressBar->Progress(); + + memcpy(&stru_5E4C90_MapPersistVars, pData, 0xC8); + pData += 0xC8; + + pGameLoadingUI_ProgressBar->Progress(); + + memcpy(&stru1, pData, 0x38u); + pData += 0x38; + + free(pRawDLV); + //v5 = 0; + + pSoundList->LoadSound(64, 0); + pSoundList->LoadSound(103, 0); + pSoundList->LoadSound(63, 0); + pSoundList->LoadSound(102, 0); + pSoundList->LoadSound(50, 0); + pSoundList->LoadSound(89, 0); + + return 0; +} + + +//----- (0049AC17) -------------------------------------------------------- +int IndoorLocation::GetSector(int sX, int sY, int sZ) +{ + int v4; // esi@1 + signed int v25; // edx@21 + int v26; // ebx@23 + int v37; // edi@38 + int pSectorID; // ebx@40 + int v39; // eax@41 + int v43[50]; // [sp+Ch] [bp-108h]@1 + bool v50; // [sp+ECh] [bp-28h]@19 + int v51; // [sp+F0h] [bp-24h]@9 + int v53; // [sp+F8h] [bp-1Ch]@10 + int v54; // [sp+FCh] [bp-18h]@16 + int v55; // [sp+100h] [bp-14h]@1 + int v59; // [sp+110h] [bp-4h]@16 + + v4 = 0; + v43[0] = 0; + + v55 = 0; + + if (uNumSectors < 2) + return 0; + + for (uint i = 1; i < uNumSectors; ++i) + { + BLVSector* pSector = &pSectors[i]; + + if (pSector->pBounding.x1 > sX || pSector->pBounding.x2 < sX || + pSector->pBounding.y1 > sY || pSector->pBounding.y2 < sY || + pSector->pBounding.z1 - 64 > sZ || pSector->pBounding.z2 + 64 < sZ) + continue; + + //Log::Warning(L"Sector[%u]", i); + v51 = pSector->uNumFloors + pSector->uNumPortals; + if (!v51) + continue; + + + for (uint j = 0; j < v51; ++j) + { + uint uFaceID; + if (j < pSector->uNumFloors) + uFaceID = pSector->pFloors[j]; + else + uFaceID = pSector->pPortals[j - pSector->uNumFloors]; + + BLVFace* pFace = &pFaces[uFaceID]; + if (pFace->uPolygonType != POLYGON_Floor && + pFace->uPolygonType != POLYGON_InBetweenFloorAndWall) + continue; + + v54 = 0; + v50 = pVertices[pFace->pVertexIDs[0]].y >= sY; + + for (uint k = 1; k <= pFace->uNumVertices; k++) + { + v59 = v50; + + if (v54 >= 2) + break; + + Vec3* v2 = &pVertices[pFace->pVertexIDs[k]]; + v50 = v2->y >= sY; + + if (v59 == v50) + continue; + + Vec3* v1 = &pVertices[pFace->pVertexIDs[k - 1]]; + v25 = v2->x >= sX ? 0 : 2; + v26 = v25 | (v1->x < sX); + + if (v26 == 3) + continue; + + if (!v26) + ++v54; + else + { + if (v1->x >= v2->x) + { + /*int _a58; + int _a59; + + v32 = v1->x - v2->x; + LODWORD(v33) = v32 << 16; + HIDWORD(v33) = v32 >> 16;*/ + //fixpoint_div(v1->x - v2->x, v1->y - v2->y); + //_a58 = v33 / (v1->y - v2->y); + //_a59 = fixpoint_mul(_a58, sY - v2->y); + long long x_div_y = fixpoint_div(v1->x - v2->x, v1->y - v2->y); + long long res = fixpoint_mul(x_div_y, sY - v2->y); // a / b * c - looks like projection + if (res + v2->x > sX) + ++v54; + } + else + { + long long x_div_y = fixpoint_div(v2->x - v1->x, v2->y - v1->y); + long long res = fixpoint_mul(x_div_y, sY - v1->y); + + if (res + v1->x > sX) + ++v54; + + /*int _a58; + int _a59; + auto v32 = v2->x - v1->x; + LODWORD(v33) = v32 << 16; + HIDWORD(v33) = v32 >> 16; + _a58 = v33 / (v2->y - v1->y); + _a59 = fixpoint_mul(_a58, sY - v1->y); + + if (_a59 + pVertices[k].x > sX) + ++v54;*/ + } + } + } + + if (pFace->uNumVertices && v54 == 1) + v43[v55++] = uFaceID; + } + } + + v4 = v43[0]; + if ( v55 == 1 ) + return this->pFaces[v4].uSectorID; + if ( !v55 ) + return 0; + pSectorID = 0; + v53 = 0xFFFFFFu; + if ( v55 > 0 ) + { + v39 = sY; + for ( v37 = 0; v37 < v55; ++v37 ) + { + if ( this->pFaces[v43[v37]].uPolygonType == POLYGON_Floor ) + v39 = sZ - this->pVertices[*this->pFaces[v43[v37]].pVertexIDs].z; + if ( this->pFaces[v43[v37]].uPolygonType == POLYGON_InBetweenFloorAndWall ) + { + v39 = sZ - ((fixpoint_mul(this->pFaces[v43[v37]].zCalc1, (sX << 16)) + + fixpoint_mul(this->pFaces[v43[v37]].zCalc2, (sY << 16)) + + this->pFaces[v43[v37]].zCalc3 + + 0x8000) >> 16); + } + if ( v39 >= 0 ) + { + if ( v39 < v53 ) + { + pSectorID = this->pFaces[v43[v37]].uSectorID; + v53 = v39; + } + } + } + } + return pSectorID; +} +// 49AC17: using guessed type int var_108[50]; + + +//----- (00498A41) -------------------------------------------------------- +void BLVFace::_get_normals(Vec3_int_ *a2, Vec3_int_ *a3) +{ + Vec3_float_ a1; // [sp+Ch] [bp-Ch]@8 + + if ( this->uPolygonType == POLYGON_VerticalWall ) + { + a2->x = -this->pFacePlane_old.vNormal.y; + a2->y = this->pFacePlane_old.vNormal.x; + a2->z = 0; + + a3->x = 0; + a3->y = 0; + a3->z = 0xFFFF0000u; + + } + else if ( this->uPolygonType == POLYGON_Floor || this->uPolygonType == POLYGON_Ceiling ) + { + a2->x = 0x10000u; + a2->y = 0; + a2->z = 0; + + a3->x = 0; + a3->y = 0xFFFF0000u; + a3->z = 0; + + } + else if ( this->uPolygonType == POLYGON_InBetweenFloorAndWall || this->uPolygonType == POLYGON_InBetweenCeilingAndWall ) + { + if ( abs(this->pFacePlane_old.vNormal.z) < 46441 ) + { + a1.x = (double)-this->pFacePlane_old.vNormal.y; + a1.y = (double)this->pFacePlane_old.vNormal.x; + a1.z = 0.0; + a1.Normalize(); + + a2->x = (signed __int64)(a1.x * 65536.0); + a2->y = (signed __int64)(a1.y * 65536.0); + a2->z = 0; + + a3->y = 0; + a3->z = 0xFFFF0000u; + a3->x = 0; + + } + else + { + a2->x = 0x10000u; + a2->y = 0; + a2->z = 0; + + a3->x = 0; + a3->y = 0xFFFF0000u; + a3->z = 0; + } + + } +//LABEL_12: + if ( this->uAttributes & FACE_UNKNOW3 ) + { + a2->x = -a2->x; + a2->y = -a2->y; + a2->z = -a2->z; + } + if ( this->uAttributes & FACE_UNKNOW4 ) + { + a3->x = -a3->x; + a3->y = -a3->y; + a3->z = -a3->z; + } + return; +} + +//----- (0044C23B) -------------------------------------------------------- +bool BLVFaceExtra::HasEventint() +{ + signed int event_index; // eax@1 + _evt_raw* start_evt; + _evt_raw* end_evt; + + event_index = 0; + if ( (uLevelEVT_NumEvents - 1) <= 0 ) + return false; + while ( pLevelEVT_Index[event_index].uEventID != this->uEventID ) + { + ++event_index; + if ( event_index >= (signed int)(uLevelEVT_NumEvents - 1) ) + return false; + } + end_evt=(_evt_raw*)&pLevelEVT[pLevelEVT_Index[event_index+1].uEventOffsetInEVT]; + start_evt=(_evt_raw*)&pLevelEVT[pLevelEVT_Index[event_index].uEventOffsetInEVT]; + if ( (end_evt->_e_type != EVENT_Exit) || (start_evt->_e_type!= EVENT_MouseOver) ) + return false; + else + return true; +} + +//----- (0046F228) -------------------------------------------------------- +void BLV_UpdateDoors() +{ + BLVFace *face; // ebx@24 + Vec3_short_ *v17; // esi@24 + int v18; // eax@24 + int v19; // edx@24 + signed int v20; // eax@24 + int v24; // esi@25 + int v25; // eax@25 + signed __int64 v27; // qtt@27 + BLVFaceExtra *v28; // esi@32 + int v32; // eax@34 + Vec3_short_ *v34; // eax@35 + int v35; // ecx@35 + int v36; // edx@35 + signed int v37; // eax@35 + signed int v38; // edx@35 + int v39; // eax@35 + int v40; // edx@35 + Vec3_short_ *v43; // edi@36 + int v57; // eax@58 + Vec3_int_ v67; + Vec3_int_ v70; + int v73; // [sp+20h] [bp-44h]@24 + int v75; // [sp+28h] [bp-3Ch]@36 + int v76; // [sp+2Ch] [bp-38h]@36 + int v77; // [sp+30h] [bp-34h]@36 + int v82; // [sp+44h] [bp-20h]@35 + int v83; // [sp+48h] [bp-1Ch]@34 + int v84; // [sp+4Ch] [bp-18h]@34 + SoundID eDoorSoundID; // [sp+54h] [bp-10h]@1 + int v88; // [sp+5Ch] [bp-8h]@18 + int v89; // [sp+60h] [bp-4h]@6 + + eDoorSoundID = (SoundID)pDoorSoundIDsByLocationID[dword_6BE13C_uCurrentlyLoadedLocationID]; + for (uint i = 0; i < pIndoor->uNumDoors; ++i) + { + BLVDoor* door = &pIndoor->pDoors[i]; + if (door->uState == BLVDoor::Closed || door->uState == BLVDoor::Open) + { + door->uAttributes &= 0xFFFFFFFDu;//~0x2 + continue; + } + door->uTimeSinceTriggered += pEventTimer->uTimeElapsed; + if (door->uState == BLVDoor::Opening) + { + v89 = (signed int)(door->uTimeSinceTriggered * door->uCloseSpeed) / 128; + if ( v89 >= door->uMoveLength ) + { + v89 = door->uMoveLength; + door->uState = BLVDoor::Open; + if ( !(door->uAttributes & FACE_UNKNOW5) && door->uNumVertices != 0) + pAudioPlayer->PlaySound((SoundID)((int)eDoorSoundID + 1), PID(OBJECT_BLVDoor,i), 0, -1, 0, 0, 0, 0); + //goto LABEL_18; + } + else if (!(door->uAttributes & FACE_UNKNOW5) && door->uNumVertices) + pAudioPlayer->PlaySound(eDoorSoundID, PID(OBJECT_BLVDoor, i), 1, -1, 0, 0, 0, 0); + } + else + { + signed int v5 = (signed int)(door->uTimeSinceTriggered * door->uOpenSpeed) / 128; + if ( v5 >= door->uMoveLength) + { + v89 = 0; + door->uState = BLVDoor::Closed; + if ( !(door->uAttributes & FACE_UNKNOW5) && door->uNumVertices != 0) + pAudioPlayer->PlaySound((SoundID)((int)eDoorSoundID + 1), PID(OBJECT_BLVDoor,i), 0, -1, 0, 0, 0, 0); + //goto LABEL_18; + } + else + { + v89 = door->uMoveLength - v5; + if (!(door->uAttributes & FACE_UNKNOW5) && door->uNumVertices) + pAudioPlayer->PlaySound(eDoorSoundID, PID(OBJECT_BLVDoor, i), 1, -1, 0, 0, 0, 0); + } + } + +//LABEL_18: + for (uint j = 0; j < door->uNumVertices; ++j) + { + pIndoor->pVertices[door->pVertexIDs[j]].x = fixpoint_mul(door->vDirection.x, v89) + door->pXOffsets[j]; + pIndoor->pVertices[door->pVertexIDs[j]].y = fixpoint_mul(door->vDirection.y, v89) + door->pYOffsets[j]; + pIndoor->pVertices[door->pVertexIDs[j]].z = fixpoint_mul(door->vDirection.z, v89) + door->pZOffsets[j]; + } + for ( v88 = 0; v88 < door->uNumFaces; ++v88 ) + { + face = &pIndoor->pFaces[door->pFaceIDs[v88]]; + v17 = &pIndoor->pVertices[face->pVertexIDs[0]]; + v18 = face->pFacePlane_old.vNormal.y; + v73 = *(int *)&v17->x; + v19 = face->pFacePlane_old.vNormal.z; + v20 = -(v19 * (int)v17->z + (signed __int16)v73 * face->pFacePlane_old.vNormal.x + SHIWORD(v73) * v18); + face->pFacePlane_old.dist = v20; + face->pFacePlane.dist = -((double)v17->z * face->pFacePlane.vNormal.z + + (double)v17->y * face->pFacePlane.vNormal.y + + (double)v17->x * face->pFacePlane.vNormal.x); + if ( v19 ) + { + v24 = abs(v20 >> 15); + v25 = abs(face->pFacePlane_old.vNormal.z); + if ( v24 > v25 ) + Error("Door Error\ndoor id: %i\nfacet no: %i\n\nOverflow dividing facet->d [%i] by facet->nz [%i]", + door->uDoorID, door->pFaceIDs[v88], face->pFacePlane_old.dist, face->pFacePlane_old.vNormal.z); + LODWORD(v27) = face->pFacePlane_old.dist << 16; + HIDWORD(v27) = face->pFacePlane_old.dist >> 16; + face->zCalc3 = -v27 / face->pFacePlane_old.vNormal.z; + } + //if ( face->uAttributes & FACE_TEXTURE_FLOW || pRenderer->pRenderD3D ) + face->_get_normals(&v70, &v67); + v28 = &pIndoor->pFaceExtras[face->uFaceExtraID]; + /*if ( !pRenderer->pRenderD3D ) + { + if ( !(face->uAttributes & FACE_TEXTURE_FLOW) ) + continue; + v83 = (unsigned __int64)(door->vDirection.x * (signed __int64)v70.x) >> 16; + v85 = (unsigned __int64)(door->vDirection.y * (signed __int64)v70.y) >> 16; + v84 = (unsigned __int64)(door->vDirection.z * (signed __int64)v70.z) >> 16; + v29 = v89; + v28->sTextureDeltaU = -((v83 + v85 + v84) * (signed __int64)v89) >> 16; + v85 = (unsigned __int64)(door->vDirection.x * (signed __int64)v67.x) >> 16; + v83 = (unsigned __int64)(door->vDirection.y * (signed __int64)v67.y) >> 16; + v84 = (unsigned __int64)(door->vDirection.z * (signed __int64)v67.z) >> 16; + v31 = (v85 + v83 + v84) * (signed __int64)v29; + v32 = v31 >> 16; + v57 = -v32; + v28->sTextureDeltaV = v57; + v28->sTextureDeltaU += door->pDeltaUs[v88]; + v28->sTextureDeltaV = v57 + door->pDeltaVs[v88]; + continue; + }*/ + v28->sTextureDeltaU = 0; + v28->sTextureDeltaV = 0; + v34 = &pIndoor->pVertices[face->pVertexIDs[0]]; + v35 = v34->z; + v36 = v34->y; + v82 = v34->x; + v37 = v70.x * v82 + v70.y * v36 + v70.z * v35; + v38 = v67.x * v82 + v67.y * v36 + v67.z * v35; + v39 = v37 >> 16; + *face->pVertexUIDs = v39; + v40 = v38 >> 16; + *face->pVertexVIDs = v40; + v84 = v39; + v82 = v40; + for (uint j = 1; j < face->uNumVertices; ++j) + { + v43 = &pIndoor->pVertices[face->pVertexIDs[j]]; + v76 = ((__int64)v70.z * v43->z + (__int64)v70.x * v43->x + (__int64)v70.y * v43->y) >> 16; + v77 = ((__int64)v67.x * v43->x + (__int64)v67.y * v43->y + (__int64)v43->z * v67.z) >> 16; + if ( v76 < v39 ) + v39 = v76; + if ( v77 < v40 ) + v40 = v77; + if ( v76 > v84 ) + v84 = v76; + if ( v77 > v82 ) + v82 = v77; + face->pVertexUIDs[j] = v76; + face->pVertexVIDs[j] = v77; + } + if ( face->uAttributes & 0x00001000 ) + v28->sTextureDeltaU -= v39; + else + { + if ( SBYTE1(face->uAttributes) < 0 ) + { + if ( face->uBitmapID != -1 ) + v28->sTextureDeltaU -= v84 + pBitmaps_LOD->pTextures[face->uBitmapID].uTextureWidth; + } + } + if ( face->uAttributes & FACE_UNKNOW6 ) + v28->sTextureDeltaV -= v40; + else + { + if ( face->uAttributes & FACE_INDOOR_DOOR ) + { + if ( face->uBitmapID != -1 ) + v28->sTextureDeltaV -= v82 + pBitmaps_LOD->GetTexture(face->uBitmapID)->uTextureHeight; + } + } + if ( face->uAttributes & FACE_TEXTURE_FLOW ) + { + v84 = fixpoint_mul(door->vDirection.x, v70.x); + v82 = fixpoint_mul(door->vDirection.y, v70.y); + v83 = fixpoint_mul(door->vDirection.z, v70.z); + v75 = v84 + v82 + v83; + v82 = fixpoint_mul(v75, v89); + v28->sTextureDeltaU = -v82; + v84 = fixpoint_mul(door->vDirection.x, v67.x); + v82 = fixpoint_mul(door->vDirection.y, v67.y); + v83 = fixpoint_mul(door->vDirection.z, v67.z); + v75 = v84 + v82 + v83; + v32 = fixpoint_mul(v75, v89); + v57 = -v32; + v28->sTextureDeltaV = v57; + v28->sTextureDeltaU += door->pDeltaUs[v88]; + v28->sTextureDeltaV = v57 + door->pDeltaVs[v88]; + } + } + } +} +// 6BE13C: using guessed type int dword_6BE13C_uCurrentlyLoadedLocationID; + +//----- (0046F90C) -------------------------------------------------------- +void UpdateActors_BLV() +{ + int v2; // edi@6 + int v3; // eax@6 + int v4; // eax@8 + __int16 v5; // ax@11 + signed int v6; // ebx@14 + signed __int64 v10; // qax@18 + int v22; // edi@46 + unsigned int v24; // eax@51 + int v27; // ST08_4@54 + int v28; // edi@54 + int v29; // eax@54 + int v30; // ecx@62 + int v31; // ebx@62 + int v32; // eax@62 + int v33; // eax@64 + signed int v37; // ebx@85 + int v44; // ecx@96 + int v45; // edi@101 + AIDirection v52; // [sp+0h] [bp-60h]@75 + AIDirection v53; // [sp+1Ch] [bp-44h]@116 + unsigned int uSectorID; // [sp+3Ch] [bp-24h]@6 + int v56; // [sp+40h] [bp-20h]@6 + unsigned int _this; // [sp+44h] [bp-1Ch]@51 + int v58; // [sp+48h] [bp-18h]@51 + int v59; // [sp+4Ch] [bp-14h]@8 + unsigned int uFaceID; // [sp+50h] [bp-10h]@6 + int v61; // [sp+54h] [bp-Ch]@14 + int v62; // [sp+58h] [bp-8h]@6 + unsigned int actor_id; // [sp+5Ch] [bp-4h]@1 + + for ( actor_id = 0; actor_id < uNumActors; actor_id++ ) + { + if ( pActors[actor_id].uAIState == Removed || pActors[actor_id].uAIState == Disabled + || pActors[actor_id].uAIState == Summoned || !pActors[actor_id].uMovementSpeed ) + continue; + uSectorID = pActors[actor_id].uSectorID; + v2 = collide_against_floor(pActors[actor_id].vPosition.x, pActors[actor_id].vPosition.y, pActors[actor_id].vPosition.z, &uSectorID, &uFaceID); + pActors[actor_id].uSectorID = uSectorID; + v3 = pActors[actor_id].pMonsterInfo.uFlying; + v56 = v2; + v62 = v3; + if ( !pActors[actor_id].CanAct() ) + v62 = 0; + v4 = pActors[actor_id].vPosition.z; + v59 = 0; + if ( pActors[actor_id].vPosition.z > v2 + 1 ) + v59 = 1; + if ( v2 <= -30000 ) + { + v5 = pIndoor->GetSector(pActors[actor_id].vPosition.x, pActors[actor_id].vPosition.y, v4); + pActors[actor_id].uSectorID = v5; + v56 = BLV_GetFloorLevel(pActors[actor_id].vPosition.x, pActors[actor_id].vPosition.y, pActors[actor_id].vPosition.z, v5, &uFaceID); + if ( !v5 || v56 == -30000 ) + continue; + } + if ( pActors[actor_id].uCurrentActionAnimation == ANIM_Walking)//монстр двигается + { + v6 = pActors[actor_id].uMovementSpeed; + if ( pActors[actor_id].pActorBuffs[ACTOR_BUFF_SLOWED].uExpireTime > 0 ) + { + if ( pActors[actor_id].pActorBuffs[ACTOR_BUFF_SLOWED].uPower ) + LODWORD(v10) = pActors[actor_id].uMovementSpeed / (unsigned __int16)pActors[actor_id].pActorBuffs[ACTOR_BUFF_SLOWED].uPower; + else + v10 = (signed __int64)((double)pActors[actor_id].uMovementSpeed * 0.5); + v6 = v10; + } + if ( pActors[actor_id].uAIState == Pursuing || pActors[actor_id].uAIState == Fleeing ) + v6 *= 2; + if ( pParty->bTurnBasedModeOn == true && pTurnEngine->turn_stage == TE_WAIT ) + v6 = (signed __int64)((double)v6 * flt_6BE3AC_debug_recmod1_x_1_6); + if ( v6 > 1000 ) + v6 = 1000; + pActors[actor_id].vVelocity.x = fixpoint_mul(stru_5C6E00->Cos(pActors[actor_id].uYawAngle), v6); + pActors[actor_id].vVelocity.y = fixpoint_mul(stru_5C6E00->Sin(pActors[actor_id].uYawAngle), v6); + if ( v62 ) + pActors[actor_id].vVelocity.z = fixpoint_mul(stru_5C6E00->Sin(pActors[actor_id].uPitchAngle), v6); + } + else//actor is not moving(актор не двигается) + { + pActors[actor_id].vVelocity.x = fixpoint_mul(55000, pActors[actor_id].vVelocity.x); + pActors[actor_id].vVelocity.y = fixpoint_mul(55000, pActors[actor_id].vVelocity.y); + if ( v62 ) + pActors[actor_id].vVelocity.z = fixpoint_mul(55000, pActors[actor_id].vVelocity.z); + } + if ( pActors[actor_id].vPosition.z <= v56 ) + { + pActors[actor_id].vPosition.z = v56 + 1; + if ( pIndoor->pFaces[uFaceID].uPolygonType == 3 ) + { + if ( pActors[actor_id].vVelocity.z < 0 ) + pActors[actor_id].vVelocity.z = 0; + } + else + { + if ( pIndoor->pFaces[uFaceID].pFacePlane_old.vNormal.z < 45000 ) + pActors[actor_id].vVelocity.z -= LOWORD(pEventTimer->uTimeElapsed) * GetGravityStrength(); + } + } + else + { + if ( v59 && !v62 ) + pActors[actor_id].vVelocity.z += -8 * LOWORD(pEventTimer->uTimeElapsed) * GetGravityStrength(); + } + if ( pActors[actor_id].vVelocity.x * pActors[actor_id].vVelocity.x + + pActors[actor_id].vVelocity.y * pActors[actor_id].vVelocity.y + + pActors[actor_id].vVelocity.z * pActors[actor_id].vVelocity.z >= 400 ) + { + stru_721530.field_84 = -1; + stru_721530.field_70 = 0; + stru_721530.field_0 = 1; + stru_721530.field_8_radius = pActors[actor_id].uActorRadius; + stru_721530.prolly_normal_d = pActors[actor_id].uActorRadius; + stru_721530.height = pActors[actor_id].uActorHeight; + v22 = 0; + for ( uSectorID = 0; uSectorID < 100; uSectorID++ ) + { + stru_721530.position.x = pActors[actor_id].vPosition.x; + stru_721530.normal.x = stru_721530.position.x; + stru_721530.position.y = pActors[actor_id].vPosition.y; + stru_721530.normal.y = stru_721530.position.y; + stru_721530.normal.z = pActors[actor_id].vPosition.z + pActors[actor_id].uActorRadius + 1; + stru_721530.position.z = pActors[actor_id].vPosition.z - pActors[actor_id].uActorRadius + stru_721530.height - 1; + if ( stru_721530.position.z < stru_721530.normal.z ) + stru_721530.position.z = pActors[actor_id].vPosition.z + pActors[actor_id].uActorRadius + 1; + stru_721530.velocity.x = pActors[actor_id].vVelocity.x; + stru_721530.velocity.y = pActors[actor_id].vVelocity.y; + stru_721530.velocity.z = pActors[actor_id].vVelocity.z; + stru_721530.uSectorID = pActors[actor_id].uSectorID; + if ( !stru_721530._47050A(v22) ) + { + v58 = 0; + v24 = 8 * actor_id; + LOBYTE(v24) = PID(OBJECT_Actor,actor_id); + for ( v61 = 0; v61 < 100; ++v61 ) + { + _46E44E_collide_against_faces_and_portals(1); + _46E0B2_collide_against_decorations(); + _46EF01_collision_chech_player(0); + _46ED8A_collide_against_sprite_objects(v24); + for ( uint j = 0; j < ai_arrays_size; j++ ) + { + if ( ai_near_actors_ids[j] != actor_id ) + { + v27 = abs(pActors[ai_near_actors_ids[j]].vPosition.z - pActors[actor_id].vPosition.z); + v28 = abs(pActors[ai_near_actors_ids[j]].vPosition.y - pActors[actor_id].vPosition.y); + v29 = abs(pActors[ai_near_actors_ids[j]].vPosition.x - pActors[actor_id].vPosition.x); + if ( int_get_vector_length(v29, v28, v27) >= pActors[actor_id].uActorRadius + (signed int)pActors[ai_near_actors_ids[j]].uActorRadius + && Actor::_46DF1A_collide_against_actor(ai_near_actors_ids[j], 40) ) + ++v58; + } + } + if ( _46F04E_collide_against_portals() ) + break; + } + v56 = v58 > 1; + if ( stru_721530.field_7C >= stru_721530.field_6C ) + { + v30 = stru_721530.normal2.x; + v31 = stru_721530.normal2.y; + v32 = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1; + } + else + { + v30 = pActors[actor_id].vPosition.x + fixpoint_mul(stru_721530.field_7C, stru_721530.direction.x); + v31 = pActors[actor_id].vPosition.y + fixpoint_mul(stru_721530.field_7C, stru_721530.direction.y); + v32 = pActors[actor_id].vPosition.z + fixpoint_mul(stru_721530.field_7C, stru_721530.direction.z); + } + v33 = collide_against_floor(v30, v31, v32, &stru_721530.uSectorID, &uFaceID); + if (pIndoor->pFaces[uFaceID].uAttributes & FACE_INDOOR_SKY && pActors[actor_id].uAIState == Dead) + { + pActors[actor_id].uAIState = Removed; + continue; + } + if ( v59 || v62 || !(pIndoor->pFaces[uFaceID].uAttributes & FACE_INDOOR_SKY) ) + { + if ( v33 == -30000 ) + continue; + if ( pActors[actor_id].uCurrentActionAnimation != 1 || v33 >= pActors[actor_id].vPosition.z - 100 || v59 || v62 ) + { + if ( stru_721530.field_7C < stru_721530.field_6C ) + { + pActors[actor_id].vPosition.x += fixpoint_mul(stru_721530.field_7C, stru_721530.direction.x); + pActors[actor_id].vPosition.y += fixpoint_mul(stru_721530.field_7C, stru_721530.direction.y); + pActors[actor_id].vPosition.z += fixpoint_mul(stru_721530.field_7C, stru_721530.direction.z); + pActors[actor_id].uSectorID = LOWORD(stru_721530.uSectorID); + stru_721530.field_70 += stru_721530.field_7C; + v37 = PID_ID(stru_721530.uFaceID); + if (PID_TYPE(stru_721530.uFaceID) == OBJECT_Actor) + { + if (pParty->bTurnBasedModeOn == 1 && (pTurnEngine->turn_stage == TE_ATTACK || pTurnEngine->turn_stage == TE_MOVEMENT)) + { + pActors[actor_id].vVelocity.x = fixpoint_mul(58500, pActors[actor_id].vVelocity.x); + pActors[actor_id].vVelocity.y = fixpoint_mul(58500, pActors[actor_id].vVelocity.y); + pActors[actor_id].vVelocity.z = fixpoint_mul(58500, pActors[actor_id].vVelocity.z); + v22 = 0; + continue; + } + if (pActors[actor_id].pMonsterInfo.uHostilityType) + { + if (!v56) + { + Actor::AI_Flee(actor_id, stru_721530.uFaceID, v22, (AIDirection *)v22); + pActors[actor_id].vVelocity.x = fixpoint_mul(58500, pActors[actor_id].vVelocity.x); + pActors[actor_id].vVelocity.y = fixpoint_mul(58500, pActors[actor_id].vVelocity.y); + pActors[actor_id].vVelocity.z = fixpoint_mul(58500, pActors[actor_id].vVelocity.z); + v22 = 0; + continue; + } + } + else + { + if (!v56) + { + if (!pActors[v37].pMonsterInfo.uHostilityType) + { + Actor::AI_FaceObject(actor_id, stru_721530.uFaceID, v22, (AIDirection *)v22); + pActors[actor_id].vVelocity.x = fixpoint_mul(58500, pActors[actor_id].vVelocity.x); + pActors[actor_id].vVelocity.y = fixpoint_mul(58500, pActors[actor_id].vVelocity.y); + pActors[actor_id].vVelocity.z = fixpoint_mul(58500, pActors[actor_id].vVelocity.z); + v22 = 0; + continue; + } + Actor::AI_Flee(actor_id, stru_721530.uFaceID, v22, (AIDirection *)v22); + pActors[actor_id].vVelocity.x = fixpoint_mul(58500, pActors[actor_id].vVelocity.x); + pActors[actor_id].vVelocity.y = fixpoint_mul(58500, pActors[actor_id].vVelocity.y); + pActors[actor_id].vVelocity.z = fixpoint_mul(58500, pActors[actor_id].vVelocity.z); + v22 = 0; + continue; + } + } + Actor::AI_StandOrBored(actor_id, 4, v22, &v53); + pActors[actor_id].vVelocity.x = fixpoint_mul(58500, pActors[actor_id].vVelocity.x); + pActors[actor_id].vVelocity.y = fixpoint_mul(58500, pActors[actor_id].vVelocity.y); + pActors[actor_id].vVelocity.z = fixpoint_mul(58500, pActors[actor_id].vVelocity.z); + v22 = 0; + continue; + } + if (PID_TYPE(stru_721530.uFaceID) == OBJECT_Player) + { + if (pActors[actor_id].GetActorsRelation(0)) + { + //v51 = __OFSUB__(HIDWORD(pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime), v22); + //v49 = HIDWORD(pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime) == v22; + //v50 = HIDWORD(pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime) - v22 < 0; + pActors[actor_id].vVelocity.y = v22; + pActors[actor_id].vVelocity.x = v22; + if (pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime > v22) + pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].Reset(); + viewparams->bRedrawGameUI = 1; + pActors[actor_id].vVelocity.x = fixpoint_mul(58500, pActors[actor_id].vVelocity.x); + pActors[actor_id].vVelocity.y = fixpoint_mul(58500, pActors[actor_id].vVelocity.y); + pActors[actor_id].vVelocity.z = fixpoint_mul(58500, pActors[actor_id].vVelocity.z); + v22 = 0; + continue; + } + Actor::AI_FaceObject(actor_id, stru_721530.uFaceID, v22, (AIDirection *)v22); + pActors[actor_id].vVelocity.x = fixpoint_mul(58500, pActors[actor_id].vVelocity.x); + pActors[actor_id].vVelocity.y = fixpoint_mul(58500, pActors[actor_id].vVelocity.y); + pActors[actor_id].vVelocity.z = fixpoint_mul(58500, pActors[actor_id].vVelocity.z); + v22 = 0; + continue; + } + if (PID_TYPE(stru_721530.uFaceID) == OBJECT_Decoration) + { + _this = integer_sqrt(pActors[actor_id].vVelocity.x * pActors[actor_id].vVelocity.x + pActors[actor_id].vVelocity.y * pActors[actor_id].vVelocity.y); + v45 = stru_5C6E00->Atan2(pActors[actor_id].vPosition.x - pLevelDecorations[v37].vPosition.x, + pActors[actor_id].vPosition.y - pLevelDecorations[v37].vPosition.y); + pActors[actor_id].vVelocity.x = fixpoint_mul(stru_5C6E00->Cos(v45), _this); + pActors[actor_id].vVelocity.y = fixpoint_mul(stru_5C6E00->Sin(v45), _this); + pActors[actor_id].vVelocity.x = fixpoint_mul(58500, pActors[actor_id].vVelocity.x); + pActors[actor_id].vVelocity.y = fixpoint_mul(58500, pActors[actor_id].vVelocity.y); + pActors[actor_id].vVelocity.z = fixpoint_mul(58500, pActors[actor_id].vVelocity.z); + v22 = 0; + continue; + } + if (PID_TYPE(stru_721530.uFaceID) == OBJECT_BModel) + { + stru_721530.field_84 = stru_721530.uFaceID >> 3; + if (pIndoor->pFaces[v37].uPolygonType == 3) + { + pActors[actor_id].vVelocity.z = 0; + pActors[actor_id].vPosition.z = pIndoor->pVertices[*pIndoor->pFaces[v37].pVertexIDs].z + 1; + if (pActors[actor_id].vVelocity.x * pActors[actor_id].vVelocity.x + + pActors[actor_id].vVelocity.y * pActors[actor_id].vVelocity.y < 400) + { + pActors[actor_id].vVelocity.y = 0; + pActors[actor_id].vVelocity.x = 0; + pActors[actor_id].vVelocity.x = fixpoint_mul(58500, pActors[actor_id].vVelocity.x); + pActors[actor_id].vVelocity.y = fixpoint_mul(58500, pActors[actor_id].vVelocity.y); + pActors[actor_id].vVelocity.z = fixpoint_mul(58500, pActors[actor_id].vVelocity.z); + v22 = 0; + continue; + } + } + else + { + v61 = abs(pIndoor->pFaces[v37].pFacePlane_old.vNormal.x * pActors[actor_id].vVelocity.x + pIndoor->pFaces[v37].pFacePlane_old.vNormal.y + * pActors[actor_id].vVelocity.y + + pIndoor->pFaces[v37].pFacePlane_old.vNormal.z + * pActors[actor_id].vVelocity.z) >> 16; + if ((stru_721530.speed >> 3) > v61) + v61 = stru_721530.speed >> 3; + pActors[actor_id].vVelocity.x += fixpoint_mul(v61, pIndoor->pFaces[v37].pFacePlane_old.vNormal.x); + pActors[actor_id].vVelocity.y += fixpoint_mul(v61, pIndoor->pFaces[v37].pFacePlane_old.vNormal.y); + pActors[actor_id].vVelocity.z += fixpoint_mul(v61, pIndoor->pFaces[v37].pFacePlane_old.vNormal.z); + if (pIndoor->pFaces[v37].uPolygonType != 4 && pIndoor->pFaces[v37].uPolygonType != 3) + { + v44 = stru_721530.prolly_normal_d + - ((pIndoor->pFaces[v37].pFacePlane_old.dist + + pIndoor->pFaces[v37].pFacePlane_old.vNormal.z * pActors[actor_id].vPosition.z + + pIndoor->pFaces[v37].pFacePlane_old.vNormal.y * pActors[actor_id].vPosition.y + + pIndoor->pFaces[v37].pFacePlane_old.vNormal.x * pActors[actor_id].vPosition.x) >> 16); + if (v44 > 0) + { + pActors[actor_id].vPosition.x += fixpoint_mul(v44, pIndoor->pFaces[v37].pFacePlane_old.vNormal.x); + pActors[actor_id].vPosition.y += fixpoint_mul(v44, pIndoor->pFaces[v37].pFacePlane_old.vNormal.y); + pActors[actor_id].vPosition.z += fixpoint_mul(v44, pIndoor->pFaces[v37].pFacePlane_old.vNormal.z); + } + pActors[actor_id].uYawAngle = stru_5C6E00->Atan2(pActors[actor_id].vVelocity.x, pActors[actor_id].vVelocity.y); + } + } + if (pIndoor->pFaces[v37].uAttributes & FACE_UNKNOW1) + EventProcessor(pIndoor->pFaceExtras[pIndoor->pFaces[v37].uFaceExtraID].uEventID, 0, 1); + } + pActors[actor_id].vVelocity.x = fixpoint_mul(58500, pActors[actor_id].vVelocity.x); + pActors[actor_id].vVelocity.y = fixpoint_mul(58500, pActors[actor_id].vVelocity.y); + pActors[actor_id].vVelocity.z = fixpoint_mul(58500, pActors[actor_id].vVelocity.z); + v22 = 0; + continue; + } + else + { + pActors[actor_id].vPosition.x = LOWORD(stru_721530.normal2.x); + pActors[actor_id].vPosition.y = LOWORD(stru_721530.normal2.y); + pActors[actor_id].vPosition.z = LOWORD(stru_721530.normal2.z) - LOWORD(stru_721530.prolly_normal_d) - 1; + pActors[actor_id].uSectorID = LOWORD(stru_721530.uSectorID); + //goto LABEL_123; + break; + } + + } + else if ( pActors[actor_id].vPosition.x & 1 ) + pActors[actor_id].uYawAngle += 100; + else + pActors[actor_id].uYawAngle -= 100; + } + else + { + if (pParty->bTurnBasedModeOn == 1 && (pTurnEngine->turn_stage == TE_ATTACK || pTurnEngine->turn_stage == TE_MOVEMENT)) + continue; + if ( !pActors[actor_id].pMonsterInfo.uHostilityType || v56 != v22 ) + { + Actor::AI_StandOrBored(actor_id, 4, v22, &v52); + continue; + } + } + } + } + } + else + { + pActors[actor_id].vVelocity.z = 0; + pActors[actor_id].vVelocity.y = 0; + pActors[actor_id].vVelocity.x = 0; + if ( pIndoor->pFaces[uFaceID].uAttributes & FACE_INDOOR_SKY ) + { + if (pActors[actor_id].uAIState == Dead) + pActors[actor_id].uAIState = Removed; + } + } +//LABEL_123: + ; + } +} + + +//----- (00460A78) -------------------------------------------------------- +void PrepareToLoadBLV(unsigned int bLoading) +{ + unsigned int respawn; // ebx@1 + unsigned int map_id; // eax@8 + MapInfo *map_info; // edi@9 + int v4; // eax@11 + DecorationDesc *decoration; // eax@54 + char v28; // zf@81 + signed int v30; // edi@94 + int v34[4]; // [sp+3E8h] [bp-2Ch]@96 + int v35; // [sp+3F8h] [bp-1Ch]@1 + int v38; // [sp+404h] [bp-10h]@1 + int pDest; // [sp+40Ch] [bp-8h]@1 + + respawn = 0; + pGameLoadingUI_ProgressBar->Reset(0x20u); + bUnderwater = false; + bNoNPCHiring = false; + pDest = 1; + uCurrentlyLoadedLevelType = LEVEL_Indoor; + pGame->uFlags2 &= 0xFFFFFFF7u; + if ( Is_out15odm_underwater() ) + { + bUnderwater = true; + pGame->uFlags2 |= 8; + } + if ( !_stricmp(pCurrentMapName, "out15.odm") || !_stricmp(pCurrentMapName, "d23.blv") ) + bNoNPCHiring = true; + pPaletteManager->pPalette_tintColor[0] = 0; + pPaletteManager->pPalette_tintColor[1] = 0; + pPaletteManager->pPalette_tintColor[2] = 0; + pPaletteManager->RecalculateAll(); + if ( _A750D8_player_speech_timer ) + _A750D8_player_speech_timer = 0i64; + map_id = pMapStats->GetMapInfo(pCurrentMapName); + if ( map_id ) + { + map_info = &pMapStats->pInfos[map_id]; + respawn = pMapStats->pInfos[map_id].uRespawnIntervalDays; + v38 = GetAlertStatus(); + } + else + map_info = (MapInfo *)bLoading; + dword_6BE13C_uCurrentlyLoadedLocationID = map_id; + + pStationaryLightsStack->uNumLightsActive = 0; + v4 = pIndoor->Load(pCurrentMapName, (unsigned int)(signed __int64)((double)pParty->uTimePlayed * 0.234375) / 60 / 60 / 24 + 1, respawn, (char *)&pDest) - 1; + if ( !v4 ) + Error("Unable to open %s", pCurrentMapName); + + if ( v4 == 1 ) + Error("File %s is not a BLV File", pCurrentMapName); + + if ( v4 == 2 ) + Error("Attempt to open new level before clearing old"); + if ( v4 == 3 ) + Error("Out of memory loading indoor level"); + if ( !(dword_6BE364_game_settings_1 & GAME_SETTINGS_2000) ) + { + Actor::InitializeActors(); + SpriteObject::InitializeSpriteObjects(); + } + dword_6BE364_game_settings_1 &= ~GAME_SETTINGS_2000; + if ( !map_id ) + pDest = 0; + if ( pDest == 1 ) + { + for (uint i = 0; i < pIndoor->uNumSpawnPoints; ++i ) + { + if ( pIndoor->pSpawnPoints[i].uKind == 3 ) + SpawnEncounter(map_info, &pIndoor->pSpawnPoints[i], 0, 0, 0); + else + map_info->SpawnRandomTreasure(&pIndoor->pSpawnPoints[i]); + } + RespawnGlobalDecorations(); + } + + pSoundList->LoadSound(pDoorSoundIDsByLocationID[map_id], 0); + pSoundList->LoadSound(pDoorSoundIDsByLocationID[map_id] + 1, 0); + + for (uint i = 0; i < pIndoor->uNumDoors; ++i) + { + if (pIndoor->pDoors[i].uAttributes & 0x01) + { + pIndoor->pDoors[i].uState = BLVDoor::Opening; + pIndoor->pDoors[i].uTimeSinceTriggered = 15360; + pIndoor->pDoors[i].uAttributes = 2; + } + + if (pIndoor->pDoors[i].uState == BLVDoor::Closed) + { + pIndoor->pDoors[i].uState = BLVDoor::Closing; + pIndoor->pDoors[i].uTimeSinceTriggered = 15360; + pIndoor->pDoors[i].uAttributes = 2; + } + else if (pIndoor->pDoors[i].uState == BLVDoor::Open) + { + pIndoor->pDoors[i].uState = BLVDoor::Opening; + pIndoor->pDoors[i].uTimeSinceTriggered = 15360; + pIndoor->pDoors[i].uAttributes = 2; + } + } + + for (uint i = 0; i < pIndoor->uNumFaces; ++i) + { + if (pIndoor->pFaces[i].uBitmapID != -1) + pBitmaps_LOD->pTextures[pIndoor->pFaces[i].uBitmapID].palette_id2 = pPaletteManager->LoadPalette(pBitmaps_LOD->pTextures[pIndoor->pFaces[i].uBitmapID].palette_id1); + } + + pGameLoadingUI_ProgressBar->Progress(); + + v35 = 0; + for (uint i = 0; i < uNumLevelDecorations; ++i) + { + pDecorationList->InitializeDecorationSprite(pLevelDecorations[i].uDecorationDescID); + + if (pDecorationList->pDecorations[pLevelDecorations[i].uDecorationDescID].uSoundID && _6807E0_num_decorations_with_sounds_6807B8 < 9) + { + pSoundList->LoadSound(pDecorationList->pDecorations[pLevelDecorations[i].uDecorationDescID].uSoundID, 0); + _6807B8_level_decorations_ids[_6807E0_num_decorations_with_sounds_6807B8++] = i; + } + + if (!(pLevelDecorations[i].uFlags & LEVEL_DECORATION_INVISIBLE)) + { + decoration = &pDecorationList->pDecorations[pLevelDecorations[i].uDecorationDescID]; + if (!decoration->DontDraw()) + { + if ( decoration->uLightRadius ) + { + unsigned char r = 255, + g = 255, + b = 255; + if (/*pRenderer->pRenderD3D*/true && pRenderer->bUseColoredLights) + { + r = decoration->uColoredLightRed; + g = decoration->uColoredLightGreen; + b = decoration->uColoredLightBlue; + } + pStationaryLightsStack->AddLight(pLevelDecorations[i].vPosition.x, + pLevelDecorations[i].vPosition.y, + pLevelDecorations[i].vPosition.z + decoration->uDecorationHeight, decoration->uLightRadius, r, g, b, _4E94D0_light_type); + } + } + } + + if (!pLevelDecorations[i].uEventID) + { + if (pLevelDecorations[i].IsInteractive()) + { + if ( v35 < 124 ) + { + pLevelDecorations[i]._idx_in_stru123 = v35 + 75; + if ( !stru_5E4C90_MapPersistVars._decor_events[v35] ) + pLevelDecorations[i].uFlags |= LEVEL_DECORATION_INVISIBLE; + v35++; + } + } + } + } + + pGameLoadingUI_ProgressBar->Progress(); + + for (uint i = 0; i < uNumSpriteObjects; ++i) + { + if (pSpriteObjects[i].uObjectDescID) + { + if ( pSpriteObjects[i].stru_24.uItemID ) + { + if ( pSpriteObjects[i].stru_24.uItemID != 220 && pItemsTable->pItems[ pSpriteObjects[i].stru_24.uItemID].uEquipType == EQUIP_POTION && + !pSpriteObjects[i].stru_24.uEnchantmentType) + pSpriteObjects[i].stru_24.uEnchantmentType = rand() % 15 + 5; + pItemsTable->SetSpecialBonus(&pSpriteObjects[i].stru_24); + } + } + } + + // INDOOR initialize actors + v38 = 0; + for (uint i = 0; i < uNumActors; ++i) + { + if (pActors[i].uAttributes & ACTOR_UNKNOW7) + { + if ( !map_id ) + { + pActors[i].pMonsterInfo.field_3E = 19; + pActors[i].uAttributes |= ACTOR_UNKNOW11; + continue; + } + v28 = v38 == 0; + } + else + v28 = v38 == 1; + + if ( !v28 ) + { + pActors[i].PrepareSprites(0); + pActors[i].pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly; + if ( pActors[i].pMonsterInfo.field_3E != 11 && pActors[i].pMonsterInfo.field_3E != 19 && (!pActors[i].sCurrentHP || !pActors[i].pMonsterInfo.uHP) ) + { + pActors[i].pMonsterInfo.field_3E = 5; + pActors[i].UpdateAnimation(); + } + } + else + { + pActors[i].pMonsterInfo.field_3E = 19; + pActors[i].uAttributes |= ACTOR_UNKNOW11; + } + } + + pGameLoadingUI_ProgressBar->Progress(); + + //Party to start position + Actor this_; + this_.pMonsterInfo.uID = 45; + this_.PrepareSprites(0); + if ( !bLoading ) + { + pParty->sRotationX = 0; + pParty->sRotationY = 0; + pParty->vPosition.z = 0; + pParty->vPosition.y = 0; + pParty->vPosition.x = 0; + pParty->uFallStartY = 0; + pParty->uFallSpeed = 0; + TeleportToStartingPoint(uLevel_StartingPointType); + } + viewparams->_443365(); + PlayLevelMusic(); + if ( !bLoading ) + { + v30 = 0; + for ( uint pl_id = 1; pl_id <= 4; ++pl_id ) + { + if ( pPlayers[pl_id]->CanAct() ) + v34[v30++] = pl_id; + } + if ( v30 ) + { + if ( pDest ) + { + _A750D8_player_speech_timer = 256i64; + PlayerSpeechID = SPEECH_46; + uSpeakingCharacter = v34[rand() % v30]; + } + } + } +} +//----- (0046CEC3) -------------------------------------------------------- +int BLV_GetFloorLevel(int x, int y, int z, unsigned int uSectorID, unsigned int *pFaceID) +{ + int v13; // ecx@13 + signed int v14; // ebx@14 + int v15; // eax@16 + int v21; // eax@27 + signed int v28; // eax@45 + int v29; // ebx@47 + int v38; // edx@62 + bool v47; // [sp+24h] [bp-1Ch]@43 + bool current_vertices_Y; // [sp+28h] [bp-18h]@10 + bool v49; // [sp+28h] [bp-18h]@41 + bool next_vertices_Y; // [sp+2Ch] [bp-14h]@12 + signed int number_hits; // [sp+30h] [bp-10h]@10 + signed int v54; // [sp+30h] [bp-10h]@41 + signed int v55; // [sp+34h] [bp-Ch]@1 + + //LOG_DECOMPILATION_WARNING(); + + static int blv_floor_id[50]; // 00721200 + static int blv_floor_level[50]; // 007212C8 + + static __int16 blv_floor_face_vert_coord_Y[104]; // word_721390_ys + static __int16 blv_floor_face_vert_coord_X[104]; // word_721460_xs + + BLVSector* pSector = &pIndoor->pSectors[uSectorID]; + v55 = 0; + for (uint i = 0; i < pSector->uNumFloors; ++i) + { + BLVFace* pFloor = &pIndoor->pFaces[pSector->pFloors[i]]; + if (pFloor->Ethereal()) + continue; + + assert(pFloor->uNumVertices); + if (x <= pFloor->pBounding.x2 && x >= pFloor->pBounding.x1 && + y <= pFloor->pBounding.y2 && y >= pFloor->pBounding.y1) + { + for (uint j = 0; j < pFloor->uNumVertices; ++j) + { + blv_floor_face_vert_coord_X[2 * j] = pFloor->pXInterceptDisplacements[j] + pIndoor->pVertices[pFloor->pVertexIDs[j]].x; + blv_floor_face_vert_coord_X[2 * j + 1] = pFloor->pXInterceptDisplacements[j] + pIndoor->pVertices[pFloor->pVertexIDs[j + 1]].x; + blv_floor_face_vert_coord_Y[2 * j] = pFloor->pYInterceptDisplacements[j] + pIndoor->pVertices[pFloor->pVertexIDs[j]].y; + blv_floor_face_vert_coord_Y[2 * j + 1] = pFloor->pYInterceptDisplacements[j] + pIndoor->pVertices[pFloor->pVertexIDs[j + 1]].y; + } + blv_floor_face_vert_coord_X[2 * pFloor->uNumVertices] = blv_floor_face_vert_coord_X[0]; + blv_floor_face_vert_coord_Y[2 * pFloor->uNumVertices] = blv_floor_face_vert_coord_Y[0]; + + next_vertices_Y = blv_floor_face_vert_coord_Y[0] >= y; + number_hits = 0; + + for (uint j = 0; j < 2 * pFloor->uNumVertices; ++j) + { + if (number_hits >= 2) + break; + + current_vertices_Y = next_vertices_Y; + next_vertices_Y = blv_floor_face_vert_coord_Y[j + 1] >= y; + + v13 = i; + if (current_vertices_Y == next_vertices_Y) + continue; + + v14 = blv_floor_face_vert_coord_X[j + 1] >= x ? 0 : 2; + v15 = v14 | (blv_floor_face_vert_coord_X[j] < x); + + if (v15 == 3) + continue; + else if (!v15) + ++number_hits; + else + { + long long a_div_b = fixpoint_div(y - blv_floor_face_vert_coord_Y[j], blv_floor_face_vert_coord_Y[j + 1] - blv_floor_face_vert_coord_Y[j]); + long long res = fixpoint_mul((signed int)blv_floor_face_vert_coord_X[j + 1] - (signed int)blv_floor_face_vert_coord_X[j], a_div_b); + + if (res + blv_floor_face_vert_coord_X[j] >= x) + ++number_hits; + } + } + + + if ( number_hits == 1 ) + { + if ( v55 >= 50 ) + break; + if ( pFloor->uPolygonType == POLYGON_Floor || pFloor->uPolygonType == POLYGON_Ceiling ) + v21 = pIndoor->pVertices[pFloor->pVertexIDs[0]].z; + else + v21 = fixpoint_mul(pFloor->zCalc1, x) + fixpoint_mul(pFloor->zCalc2, y) + (short)(pFloor->zCalc3 >> 16); + blv_floor_level[v55] = v21; + blv_floor_id[v55] = pSector->pFloors[i]; + v55++; + } + } + } + + if ( pSector->field_0 & 8 ) + { + for (uint i = 0; i < pSector->uNumPortals; ++i) + { + BLVFace* portal = &pIndoor->pFaces[pSector->pPortals[i]]; + if (portal->uPolygonType != POLYGON_Floor) + continue; + + if (!portal->uNumVertices) + continue; + + if (x <= portal->pBounding.x2 && x >= portal->pBounding.x1 && + y <= portal->pBounding.y2 && y >= portal->pBounding.y1 ) + { + for (uint j = 0; j < portal->uNumVertices; ++j) + { + blv_floor_face_vert_coord_X[2 * j] = portal->pXInterceptDisplacements[j] + pIndoor->pVertices[portal->pVertexIDs[j]].x; + blv_floor_face_vert_coord_X[2 * j + 1] = portal->pXInterceptDisplacements[j + 1] + pIndoor->pVertices[portal->pVertexIDs[j + 1]].x; + blv_floor_face_vert_coord_Y[2 * j] = portal->pYInterceptDisplacements[j] + pIndoor->pVertices[portal->pVertexIDs[j]].y; + blv_floor_face_vert_coord_Y[2 * j + 1] = portal->pYInterceptDisplacements[j + 1] + pIndoor->pVertices[portal->pVertexIDs[j + 1]].y; + } + blv_floor_face_vert_coord_X[2 * portal->uNumVertices] = blv_floor_face_vert_coord_X[0]; + blv_floor_face_vert_coord_Y[2 * portal->uNumVertices] = blv_floor_face_vert_coord_Y[0]; + v54 = 0; + v47 = blv_floor_face_vert_coord_Y[0] >= y; + + for (uint j = 0; j < 2 * portal->uNumVertices; ++j) + { + v49 = v47; + if ( v54 >= 2 ) + break; + v47 = blv_floor_face_vert_coord_Y[j + 1] >= y; + if ( v49 != v47 ) + { + v28 = blv_floor_face_vert_coord_X[j + 1] >= x ? 0 : 2; + v29 = v28 | (blv_floor_face_vert_coord_X[j] < x); + if ( v29 != 3 ) + { + if ( !v29 ) + ++v54; + else + { + long long a_div_b = fixpoint_div(y - blv_floor_face_vert_coord_Y[j], blv_floor_face_vert_coord_Y[j + 1] - blv_floor_face_vert_coord_Y[j]); + long long res = fixpoint_mul(blv_floor_face_vert_coord_X[j + 1] - blv_floor_face_vert_coord_X[j], a_div_b); + if (res + blv_floor_face_vert_coord_X[j] >= x) + ++v54; + } + } + } + } + if ( v54 == 1 ) + { + if ( v55 >= 50 ) + break; + blv_floor_level[v55] = -29000; + blv_floor_id[v55] = pSector->pPortals[i]; + v55++; + } + } + } + } + if ( v55 == 1 ) + { + *pFaceID = blv_floor_id[0]; + if ( blv_floor_level[0] <= -29000 ) + __debugbreak(); + return blv_floor_level[0]; + } + if ( !v55 ) + return -30000; + *pFaceID = blv_floor_id[0]; + //result = blv_floor_level[0]; + + /*for ( v35 = 1; v35 < v55; ++v35 ) + { + if ( blv_floor_level[0] <= z + 5 ) + { + if ( blv_floor_level[v35] >= blv_floor_level[0] || blv_floor_level[v35] > z + 5 ) + continue; + blv_floor_level[0] = blv_floor_level[v35]; + *pFaceID = blv_floor_id[v35]; + continue; + } + if ( blv_floor_level[v35] < blv_floor_level[0] ) + { + blv_floor_level[0] = blv_floor_level[v35]; + *pFaceID = blv_floor_id[v35]; + } + }*/ + + + int result = blv_floor_level[0]; + for (uint i = 1; i < v55; ++i) + { + v38 = blv_floor_level[i]; + if ( result <= z + 5 ) + { + if ( v38 > result && v38 <= z + 5 ) + { + result = blv_floor_level[i]; + if ( blv_floor_level[i] <= -29000 ) + __debugbreak(); + *pFaceID = blv_floor_id[i]; + } + } + else if ( v38 < result ) + { + result = blv_floor_level[i]; + if ( blv_floor_level[i] <= -29000 ) + __debugbreak(); + *pFaceID = blv_floor_id[i]; + } + } + + return result; +} +//----- (0043FDED) -------------------------------------------------------- +void PrepareActorRenderList_BLV() +{ + unsigned int v4; // eax@5 + int v6; // esi@5 + int v8; // eax@10 + SpriteFrame *v9; // eax@16 + int v12; // ecx@28 + signed __int64 v18; // qtt@36 + int v25; // edx@44 + __int16 v26; // ax@44 + int a5a; // [sp+2Ch] [bp-28h]@36 + __int16 v41; // [sp+3Ch] [bp-18h]@18 + int a6; // [sp+40h] [bp-14h]@34 + int v43; // [sp+44h] [bp-10h]@34 + int z; // [sp+48h] [bp-Ch]@32 + signed int y; // [sp+4Ch] [bp-8h]@32 + int x; // [sp+50h] [bp-4h]@32 + + for (uint i = 0; i < uNumActors; ++i) + { + if (pActors[i].uAIState == Removed || pActors[i].uAIState == Disabled) + continue; + + v4 = stru_5C6E00->Atan2(pActors[i].vPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x, pActors[i].vPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y); + v6 = ((signed int)(pActors[i].uYawAngle + ((signed int)stru_5C6E00->uIntegerPi >> 3) - v4 + stru_5C6E00->uIntegerPi) >> 8) & 7; + v8 = pActors[i].uCurrentActionTime; + if ( pParty->bTurnBasedModeOn ) + { + if ( pActors[i].uCurrentActionAnimation == 1 ) + v8 = i * 32 + pMiscTimer->uTotalGameTimeElapsed; + } + else + { + if ( pActors[i].uCurrentActionAnimation == 1 ) + v8 = i * 32 + pBLVRenderParams->field_0_timer_; + } + if (pActors[i].pActorBuffs[ACTOR_BUFF_STONED].uExpireTime > 0 || pActors[i].pActorBuffs[ACTOR_BUFF_PARALYZED].uExpireTime > 0 ) + v8 = 0; + + if (pActors[i].uAIState == Resurrected) + v9 = pSpriteFrameTable->GetFrameBy_x(pActors[i].pSpriteIDs[pActors[i].uCurrentActionAnimation], v8); + else + v9 = pSpriteFrameTable->GetFrame(pActors[i].pSpriteIDs[pActors[i].uCurrentActionAnimation], v8); + + v41 = 0; + if (v9->uFlags & 2) + v41 = 2; + if (v9->uFlags & 0x40000) + v41 |= 0x40u; + if (v9->uFlags & 0x20000) + LOBYTE(v41) = v41 | 0x80; + if ( (256 << v6) & v9->uFlags) + v41 |= 4; + if ( v9->uGlowRadius ) + { + //LOBYTE(v11) = _4E94D3_light_type; + pMobileLightsStack->AddLight(pActors[i].vPosition.x, pActors[i].vPosition.y, pActors[i].vPosition.z, pActors[i].uSectorID, v9->uGlowRadius, 0xFFu, 0xFFu, 0xFFu, _4E94D3_light_type); + } + for ( v12 = 0; v12 < pBspRenderer->uNumVisibleNotEmptySectors; ++v12 ) + { + if ( pBspRenderer->pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[v12] == pActors[i].uSectorID ) + { + if ( !pGame->pIndoorCameraD3D->ApplyViewTransform_TrueIfStillVisible_BLV(pActors[i].vPosition.x, pActors[i].vPosition.y, pActors[i].vPosition.z, &x, &y, &z, 1) + || abs(x) < abs(y) ) + continue; + pGame->pIndoorCameraD3D->Project(x, y, z, &v43, &a6); + if (uNumBillboardsToDraw >= 500) + break; + ++uNumBillboardsToDraw; + ++uNumSpritesDrawnThisFrame; + pActors[i].uAttributes |= ACTOR_UNKNOW2; + pBillboardRenderList[uNumBillboardsToDraw - 1].HwSpriteID = v9->pHwSpriteIDs[v6]; + pBillboardRenderList[uNumBillboardsToDraw - 1].uPalette = v9->uPaletteIndex; + pBillboardRenderList[uNumBillboardsToDraw - 1].uIndoorSectorID = pActors[i].uSectorID; + /*if ( !pRenderer->pRenderD3D ) + { + LODWORD(v20) = pBLVRenderParams->fov_rad_fixpoint << 16; + HIDWORD(v20) = pBLVRenderParams->fov_rad_fixpoint >> 16; + v0->_screenspace_x_scaler_packedfloat = fixpoint_mul(v10->scale, v20 / x); + a5a = fixpoint_mul(v10->scale, v20 / x); + } + else + {*/ + pBillboardRenderList[uNumBillboardsToDraw - 1].fov_x = pGame->pIndoorCameraD3D->fov_x; + pBillboardRenderList[uNumBillboardsToDraw - 1].fov_y = pGame->pIndoorCameraD3D->fov_y; + LODWORD(v18) = 0; + HIDWORD(v18) = floorf(pBillboardRenderList[uNumBillboardsToDraw - 1].fov_x + 0.5f); + pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_x_scaler_packedfloat = fixpoint_mul(v9->scale, v18 / x); + a5a = fixpoint_mul(v9->scale, v18 / x); + //} + pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_y_scaler_packedfloat = a5a; + if ( pActors[i].pActorBuffs[ACTOR_BUFF_SHRINK].uExpireTime <= 0 ) + { + if ( pActors[i].pActorBuffs[ACTOR_BUFF_MASS_DISTORTION].uExpireTime > 0 ) + pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_y_scaler_packedfloat = fixpoint_mul(pGame->pStru6Instance->_4A806F(&pActors[i]), + pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_y_scaler_packedfloat); + } + else + { + if ( pActors[i].pActorBuffs[ACTOR_BUFF_SHRINK].uPower > 0 ) + pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_x_scaler_packedfloat = fixpoint_mul(65536 / pActors[i].pActorBuffs[ACTOR_BUFF_SHRINK].uPower, pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_x_scaler_packedfloat); + } + HIWORD(v25) = HIWORD(x); + pBillboardRenderList[uNumBillboardsToDraw - 1].world_x = pActors[i].vPosition.x; + pBillboardRenderList[uNumBillboardsToDraw - 1].world_y = pActors[i].vPosition.y; + pBillboardRenderList[uNumBillboardsToDraw - 1].world_z = pActors[i].vPosition.z; + pBillboardRenderList[uNumBillboardsToDraw - 1].uScreenSpaceX = v43; + pBillboardRenderList[uNumBillboardsToDraw - 1].uScreenSpaceY = a6; + LOWORD(v25) = 0; + LOBYTE(v26) = v41; + + //v0->sZValue = v25 + (PID(OBJECT_Actor,i)); + pBillboardRenderList[uNumBillboardsToDraw - 1].actual_z = HIWORD(x); + pBillboardRenderList[uNumBillboardsToDraw - 1].object_pid = PID(OBJECT_Actor,i); + + //v29 = HIDWORD(p->pActorBuffs[ACTOR_BUFF_STONED].uExpireTime) == 0; + //v30 = HIDWORD(p->pActorBuffs[ACTOR_BUFF_STONED].uExpireTime) < 0; + pBillboardRenderList[uNumBillboardsToDraw - 1].field_1E = v41; + pBillboardRenderList[uNumBillboardsToDraw - 1].pSpriteFrame = v9; + pBillboardRenderList[uNumBillboardsToDraw - 1].sTintColor = pMonsterList->pMonsters[pActors[i].pMonsterInfo.uID - 1].sTintColor; + if ( pActors[i].pActorBuffs[ACTOR_BUFF_STONED].uExpireTime > 0 ) + { + HIBYTE(v26) = HIBYTE(v41) | 1; + pBillboardRenderList[uNumBillboardsToDraw - 1].field_1E = v26; + } + } + } + } +} +//----- (0044028F) -------------------------------------------------------- +void PrepareItemsRenderList_BLV() +{ + SpriteFrame *v4; // eax@12 + unsigned int v6; // eax@12 + int v7; // ecx@12 + int v9; // ecx@12 + __int64 v18; // ST5C_4@27 + int a6; // [sp+2Ch] [bp-30h]@12 + int v31; // [sp+38h] [bp-24h]@27 + signed __int16 v34; // [sp+44h] [bp-18h]@14 + int v35; // [sp+48h] [bp-14h]@25 + int v36; // [sp+4Ch] [bp-10h]@25 + signed int z; // [sp+50h] [bp-Ch]@24 + signed int y; // [sp+54h] [bp-8h]@24 + signed int x; // [sp+58h] [bp-4h]@24 + + for (uint i = 0; i < uNumSpriteObjects; ++i) + { + if (pSpriteObjects[i].uObjectDescID) + { + if ( !(pObjectList->pObjects[pSpriteObjects[i].uObjectDescID].uFlags & 1) ) + { + if ( ( pSpriteObjects[i].uType < 1000 || pSpriteObjects[i].uType >= 10000) + && (pSpriteObjects[i].uType < 500 || pSpriteObjects[i].uType >= 600) + && (pSpriteObjects[i].uType < 811 || pSpriteObjects[i].uType >= 815) + || pGame->pStru6Instance->_4A81CA(&pSpriteObjects[i])) + { + v4 = pSpriteFrameTable->GetFrame(pObjectList->pObjects[pSpriteObjects[i].uObjectDescID].uSpriteID, pSpriteObjects[i].uSpriteFrameID); + a6 = v4->uGlowRadius * pSpriteObjects[i].field_22_glow_radius_multiplier; + v6 = stru_5C6E00->Atan2(pSpriteObjects[i].vPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x, + pSpriteObjects[i].vPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y); + LOWORD(v7) = pSpriteObjects[i].uFacing; + v9 = ((signed int)(stru_5C6E00->uIntegerPi + ((signed int)stru_5C6E00->uIntegerPi >> 3) + v7 - v6) >> 8) & 7; + pBillboardRenderList[uNumBillboardsToDraw].HwSpriteID = v4->pHwSpriteIDs[v9]; + if ( v4->uFlags & 0x20 ) + pSpriteObjects[i].vPosition.z -= (signed int)(fixpoint_mul(v4->scale, pSprites_LOD->pSpriteHeaders[pBillboardRenderList[uNumBillboardsToDraw].HwSpriteID].uHeight) / 2); + + v34 = 0; + if ( v4->uFlags & 2 ) + v34 = 2; + if ( v4->uFlags & 0x40000 ) + v34 |= 0x40u; + if ( v4->uFlags & 0x20000 ) + LOBYTE(v34) = v34 | 0x80; + //v11 = (int *)(256 << v9); + if ( (256 << v9) & v4->uFlags ) + v34 |= 4; + if ( a6 ) + { + //LOBYTE(v11) = _4E94D3_light_type; + pMobileLightsStack->AddLight(pSpriteObjects[i].vPosition.x, pSpriteObjects[i].vPosition.y, pSpriteObjects[i].vPosition.z, + pSpriteObjects[i].uSectorID, a6, pObjectList->pObjects[pSpriteObjects[i].uObjectDescID].uParticleTrailColorR, + pObjectList->pObjects[pSpriteObjects[i].uObjectDescID].uParticleTrailColorG, + pObjectList->pObjects[pSpriteObjects[i].uObjectDescID].uParticleTrailColorB, _4E94D3_light_type); + } + if ( pGame->pIndoorCameraD3D->ApplyViewTransform_TrueIfStillVisible_BLV(pSpriteObjects[i].vPosition.x, pSpriteObjects[i].vPosition.y, + pSpriteObjects[i].vPosition.z, &x, &y, &z, 1) ) + { + pGame->pIndoorCameraD3D->Project(x, y, z, &v36, &v35); + + assert(uNumBillboardsToDraw < 500); + //if ( (signed int)uNumBillboardsToDraw >= 500 ) + // return; + ++uNumBillboardsToDraw; + ++uNumSpritesDrawnThisFrame; + pSpriteObjects[i].uAttributes |= 1; + pBillboardRenderList[uNumBillboardsToDraw - 1].uPalette = v4->uPaletteIndex; + pBillboardRenderList[uNumBillboardsToDraw - 1].uIndoorSectorID = pSpriteObjects[i].uSectorID; + //if ( pRenderer->pRenderD3D ) + { + pBillboardRenderList[uNumBillboardsToDraw - 1].fov_x = pGame->pIndoorCameraD3D->fov_x; + pBillboardRenderList[uNumBillboardsToDraw - 1].fov_y = pGame->pIndoorCameraD3D->fov_y; + LODWORD(v18) = 0; + HIDWORD(v18) = (int)floorf(pBillboardRenderList[uNumBillboardsToDraw - 1].fov_x + 0.5f); + pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_x_scaler_packedfloat = fixpoint_mul(v4->scale, v18 / x); + v31 = fixpoint_mul(v4->scale, v18 / x); + } + /*else + { + __debugbreak(); // sw rendering + LODWORD(v19) = pBLVRenderParams->field_40 << 16; + HIDWORD(v19) = pBLVRenderParams->field_40 >> 16; + v20 = v19 / x; + pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_x_scaler_packedfloat = fixpoint_mul(v24->scale, v19 / x); + v31 = fixpoint_mul(v24->scale, v20); + }*/ + //HIWORD(v21) = HIWORD(x); + //LOWORD(v21) = 0; + pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_y_scaler_packedfloat = v31; + pBillboardRenderList[uNumBillboardsToDraw - 1].field_1E = v34; + pBillboardRenderList[uNumBillboardsToDraw - 1].world_x = pSpriteObjects[i].vPosition.x; + pBillboardRenderList[uNumBillboardsToDraw - 1].world_y = pSpriteObjects[i].vPosition.y; + pBillboardRenderList[uNumBillboardsToDraw - 1].world_z = pSpriteObjects[i].vPosition.z; + pBillboardRenderList[uNumBillboardsToDraw - 1].uScreenSpaceX = v36; + pBillboardRenderList[uNumBillboardsToDraw - 1].sTintColor = 0; + pBillboardRenderList[uNumBillboardsToDraw - 1].uScreenSpaceY = v35; + //v23 = 8 * i; + //LOBYTE(v23) = PID(OBJECT_Item,i); + pBillboardRenderList[uNumBillboardsToDraw - 1].pSpriteFrame = v4; + //v12 = (p->uAttributes & 0x20) == 0; + //pBillboardRenderList[uNumBillboardsToDraw - 1].sZValue = v21 + v23; + pBillboardRenderList[uNumBillboardsToDraw - 1].actual_z = HIWORD(x); + pBillboardRenderList[uNumBillboardsToDraw - 1].object_pid = PID(OBJECT_Item,i); + /*if (pSpriteObjects[i].uAttributes & 0x20) + { + if ( !pRenderer->pRenderD3D ) + pBillboardRenderList[uNumBillboardsToDraw - 1].sZValue = 0; + }*/ + } + } + } + } + } +} + +//----- (00440639) -------------------------------------------------------- +void AddBspNodeToRenderList(unsigned int node_id) +{ + BLVSector *pSector; // esi@1 + + pSector = &pIndoor->pSectors[pBspRenderer->nodes[node_id].uSectorID]; + //if ( pRenderer->pRenderD3D ) + { + for (uint i = 0; i < pSector->uNumNonBSPFaces; ++i) + //Log::Warning(L"Non-BSP face: %X", v3->pFaceIDs[v2]); + pBspRenderer->AddFaceToRenderList_d3d(node_id, pSector->pFaceIDs[i]);//рекурсия\recursion + } + /*else + { + for (uint i = 0; i < pSector->uNumNonBSPFaces; ++i) + pBspRenderer->AddFaceToRenderList_sw(node_id, pSector->pFaceIDs[i]); + }*/ + if ( pSector->field_0 & 0x10 ) + sub_4406BC(node_id, pSector->uFirstBSPNode); +} + +//----- (004406BC) -------------------------------------------------------- +void __fastcall sub_4406BC(unsigned int node_id, unsigned int uFirstNode) +{ + BLVSector *pSector; // esi@2 + BSPNode *pNode; // edi@2 + BLVFace *pFace; // eax@2 + int v5; // ecx@2 + __int16 v6; // ax@6 + int v7; // ebp@10 + int v8; // ebx@10 + __int16 v9; // di@18 + BspRenderer_stru0 *node; // [sp+18h] [bp-4h]@1 + + //Log::Warning(L"sub_4406BC(%u, %u)", a1, uFirstNode); + + //v10 = a1; + node = &pBspRenderer->nodes[node_id]; + while ( 1 ) + { + pSector = &pIndoor->pSectors[node->uSectorID]; + pNode = &pIndoor->pNodes[uFirstNode]; + pFace = &pIndoor->pFaces[pSector->pFaceIDs[pNode->uCoplanarOffset]]; + v5 = pFace->pFacePlane_old.dist + + pGame->pIndoorCameraD3D->vPartyPos.x * pFace->pFacePlane_old.vNormal.x + + pGame->pIndoorCameraD3D->vPartyPos.y * pFace->pFacePlane_old.vNormal.y + + pGame->pIndoorCameraD3D->vPartyPos.z * pFace->pFacePlane_old.vNormal.z;//plane equation + if (pFace->Portal() && pFace->uSectorID != node->uSectorID ) + v5 = -v5; + //v11 = v5 > 0; + if ( v5 <= 0 ) + v6 = pNode->uFront; + else + v6 = pNode->uBack; + if ( v6 != -1 ) + sub_4406BC(node_id, v6); + v7 = pNode->uCoplanarOffset; + v8 = v7 + pNode->uCoplanarSize; + + //Log::Warning(L"Node %u: %X to %X (%hX)", uFirstNode, v7, v8, v2->pFaceIDs[v7]); + + //if ( pRenderer->pRenderD3D ) + { + while ( v7 < v8 ) + pBspRenderer->AddFaceToRenderList_d3d(node_id, pSector->pFaceIDs[v7++]); + } + /*else + { + while ( v7 < v8 ) + pBspRenderer->AddFaceToRenderList_sw(node_id, pSector->pFaceIDs[v7++]); + }*/ + v9 = v5 > 0 ? pNode->uFront : pNode->uBack; + if ( v9 == -1 ) + break; + uFirstNode = v9; + } +} +//----- (0043FA33) -------------------------------------------------------- +void PrepareDecorationsRenderList_BLV(unsigned int uDecorationID, unsigned int uSectorID) +{ + unsigned int v8; // edi@5 + int v9; // edi@5 + int v10; // eax@7 + SpriteFrame *v11; // eax@7 + signed __int64 v20; // qtt@19 + Particle_sw particle; // [sp+Ch] [bp-A0h]@3 + int v30; // [sp+8Ch] [bp-20h]@7 + int a5; // [sp+94h] [bp-18h]@17 + int z; // [sp+98h] [bp-14h]@15 + int a6; // [sp+9Ch] [bp-10h]@17 + int y; // [sp+A0h] [bp-Ch]@15 + int x; // [sp+A4h] [bp-8h]@15 + int v37; // [sp+A8h] [bp-4h]@5 + + if (pLevelDecorations[uDecorationID].uFlags & LEVEL_DECORATION_INVISIBLE) + return; + + if (pDecorationList->pDecorations[pLevelDecorations[uDecorationID].uDecorationDescID].uFlags & DECORATION_DESC_EMITS_FIRE) + { + memset(&particle, 0, sizeof(particle)); // fire, like at the Pit's tavern + particle.type = ParticleType_Bitmap | ParticleType_Rotating | ParticleType_8; + particle.uDiffuse = 0xFF3C1E; + particle.x = (double)pLevelDecorations[uDecorationID].vPosition.x; + particle.y = (double)pLevelDecorations[uDecorationID].vPosition.y; + particle.z = (double)pLevelDecorations[uDecorationID].vPosition.z; + particle.r = 0.0; + particle.g = 0.0; + particle.b = 0.0; + particle.flt_28 = 1.0; + particle.timeToLive = (rand() & 0x80) + 128; + particle.uTextureID = pBitmaps_LOD->LoadTexture("effpar01"); + pGame->pParticleEngine->AddParticle(&particle); + return; + } + + if (pDecorationList->pDecorations[pLevelDecorations[uDecorationID].uDecorationDescID].uFlags & DECORATION_DESC_DONT_DRAW) + return; + + v8 = pLevelDecorations[uDecorationID].field_10_y_rot + ((signed int)stru_5C6E00->uIntegerPi >> 3) + - stru_5C6E00->Atan2(pLevelDecorations[uDecorationID].vPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x, + pLevelDecorations[uDecorationID].vPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y); + v9 = ((signed int)(stru_5C6E00->uIntegerPi + v8) >> 8) & 7; + v37 = pBLVRenderParams->field_0_timer_; + if (pParty->bTurnBasedModeOn) + v37 = pMiscTimer->uTotalGameTimeElapsed; + v10 = abs(pLevelDecorations[uDecorationID].vPosition.x + pLevelDecorations[uDecorationID].vPosition.y); + v11 = pSpriteFrameTable->GetFrame(pDecorationList->pDecorations[pLevelDecorations[uDecorationID].uDecorationDescID].uSpriteID, v37 + v10); + v30 = 0; + if ( v11->uFlags & 2 ) + v30 = 2; + if ( v11->uFlags & 0x40000 ) + v30 |= 0x40u; + if ( v11->uFlags & 0x20000 ) + LOBYTE(v30) = v30 | 0x80; + if ( (256 << v9) & v11->uFlags ) + v30 |= 4; + if ( pGame->pIndoorCameraD3D->ApplyViewTransform_TrueIfStillVisible_BLV(pLevelDecorations[uDecorationID].vPosition.x, + pLevelDecorations[uDecorationID].vPosition.y, + pLevelDecorations[uDecorationID].vPosition.z, &x, &y, &z, 1) ) + { + if ( abs(x) >= abs(y) ) + { + pGame->pIndoorCameraD3D->Project(x, y, z, &a5, &a6); + + assert(uNumBillboardsToDraw < 500); + + ++uNumBillboardsToDraw; + ++uNumDecorationsDrawnThisFrame; + pBillboardRenderList[uNumBillboardsToDraw - 1].HwSpriteID = v11->pHwSpriteIDs[v9]; + pBillboardRenderList[uNumBillboardsToDraw - 1].uPalette = v11->uPaletteIndex; + pBillboardRenderList[uNumBillboardsToDraw - 1].uIndoorSectorID = uSectorID; + /*if ( !pRenderer->pRenderD3D ) + { + LODWORD(v21) = pBLVRenderParams->fov_rad_fixpoint << 16; + HIDWORD(v21) = pBLVRenderParams->fov_rad_fixpoint >> 16; + //LODWORD(v31) = v12->scale; + pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_x_scaler_packedfloat = fixpoint_mul(v12->scale, v21 / x); + v37 = fixpoint_mul(v12->scale, v21 / x); + } + else + {*/ + pBillboardRenderList[uNumBillboardsToDraw - 1].fov_x = pGame->pIndoorCameraD3D->fov_x; + pBillboardRenderList[uNumBillboardsToDraw - 1].fov_y = pGame->pIndoorCameraD3D->fov_y; + LODWORD(v20) = 0; + HIDWORD(v20) = floorf(pBillboardRenderList[uNumBillboardsToDraw - 1].fov_x + 0.5f); + pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_x_scaler_packedfloat = fixpoint_mul(v11->scale, v20 / x); + LODWORD(v20) = 0; + HIDWORD(v20) = floorf(pBillboardRenderList[uNumBillboardsToDraw - 1].fov_y + 0.5f); + v37 = fixpoint_mul(v11->scale, v20 / x); + //} + //HIWORD(v22) = HIWORD(x); + //LOWORD(v22) = 0; + pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_y_scaler_packedfloat = v37; + pBillboardRenderList[uNumBillboardsToDraw - 1].field_1E = v30; + pBillboardRenderList[uNumBillboardsToDraw - 1].world_x = pLevelDecorations[uDecorationID].vPosition.x; + pBillboardRenderList[uNumBillboardsToDraw - 1].world_y = pLevelDecorations[uDecorationID].vPosition.y; + pBillboardRenderList[uNumBillboardsToDraw - 1].world_z = pLevelDecorations[uDecorationID].vPosition.z; + pBillboardRenderList[uNumBillboardsToDraw - 1].uScreenSpaceX = a5; + pBillboardRenderList[uNumBillboardsToDraw - 1].uScreenSpaceY = a6; + //v23 = 8 * uDecorationID; + //LOBYTE(v23) = PID(OBJECT_Decoration,uDecorationID); + + //pBillboardRenderList[uNumBillboardsToDraw - 1].sZValue = v22 + v23; + pBillboardRenderList[uNumBillboardsToDraw - 1].actual_z = HIWORD(x); + pBillboardRenderList[uNumBillboardsToDraw - 1].object_pid = PID(OBJECT_Decoration,uDecorationID); + + pBillboardRenderList[uNumBillboardsToDraw - 1].sTintColor = 0; + pBillboardRenderList[uNumBillboardsToDraw - 1].pSpriteFrame = v11; + } + } +} +//----- (0043F953) -------------------------------------------------------- +void PrepareBspRenderList_BLV() +{ + pBspRenderer->num_faces = 0; + + if (pBLVRenderParams->uPartySectorID) + { + pBspRenderer->nodes[0].uSectorID = pBLVRenderParams->uPartySectorID; + pBspRenderer->nodes[0].uViewportW = pBLVRenderParams->uViewportW; + pBspRenderer->nodes[0].uViewportZ = pBLVRenderParams->uViewportZ; + pBspRenderer->nodes[0].uViewportY = pBLVRenderParams->uViewportY; + pBspRenderer->nodes[0].uViewportX = pBLVRenderParams->uViewportX; + pBspRenderer->nodes[0].PortalScreenData.GetViewportData(pBLVRenderParams->uViewportX, pBLVRenderParams->uViewportY, + pBLVRenderParams->uViewportZ, pBLVRenderParams->uViewportW); + pBspRenderer->nodes[0].uFaceID = -1; + pBspRenderer->nodes[0].viewing_portal_id = -1; + pBspRenderer->num_nodes = 1; + AddBspNodeToRenderList(0); + } + + pBspRenderer->MakeVisibleSectorList(); +} + +//----- (0043F9E1) -------------------------------------------------------- +void BspRenderer_PortalViewportData::GetViewportData(__int16 x, int y, __int16 z, int w) +{ + _viewport_space_y = y; + _viewport_space_w = w; + + for (uint i = 0; i < window->GetHeight(); ++i) + { + if ( i < y || i > w ) + { + viewport_left_side[i] = window->GetWidth(); + viewport_right_side[i] = -1; + } + else + { + viewport_left_side[i] = x; + viewport_right_side[i] = z; + } + } +} +//----- (0048653D) -------------------------------------------------------- +void stru149::_48653D_frustum_blv(int a2, int a3, int a4, int a5, int a6, int a7)//portal frustum culling +{ + int v8; // edi@1 + int v9; // eax@1 + int v16; // ST14_4@3 + int v17; // ST10_4@3 + int v19; // ST10_4@6 + int v21; // ST10_4@9 + int v28; // [sp+1Ch] [bp-Ch]@1 + int v29; // [sp+24h] [bp-4h]@1 + + v8 = stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationY); + v29 = stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationY); + v28 = stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationX); + v9 = stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationX); + //v11 = -pBLVRenderParams->vPartyPos.y; + //v26 = -pBLVRenderParams->vPartyPos.x; + //v27 = v9; + //v12 = -pBLVRenderParams->vPartyPos.z; + if (pGame->pIndoorCameraD3D->sRotationX) + { + v16 = v8 * -pGame->pIndoorCameraD3D->vPartyPos.x + v29 * -pGame->pIndoorCameraD3D->vPartyPos.y; + v17 = -65536 * pGame->pIndoorCameraD3D->vPartyPos.z; + this->field_0_party_dir_x = fixpoint_mul(v16, v28) + fixpoint_mul((-pGame->pIndoorCameraD3D->vPartyPos.z) << 16, v9); + this->field_4_party_dir_y = v8 * -pGame->pIndoorCameraD3D->vPartyPos.y - v29 * -pGame->pIndoorCameraD3D->vPartyPos.x; + this->field_8_party_dir_z = fixpoint_mul(v17, v28) - fixpoint_mul(v16, v9); + } + else + { + this->field_0_party_dir_x = v8 * -pGame->pIndoorCameraD3D->vPartyPos.x + v29 * -pGame->pIndoorCameraD3D->vPartyPos.y; + this->field_4_party_dir_y = v8 * -pGame->pIndoorCameraD3D->vPartyPos.y - v29 * -pGame->pIndoorCameraD3D->vPartyPos.x; + this->field_8_party_dir_z = (-pGame->pIndoorCameraD3D->vPartyPos.z) << 16; + } + + if (pGame->pIndoorCameraD3D->sRotationX) + { + v19 = fixpoint_mul(a2, v8) + fixpoint_mul(a3, v29); + + this->angle_from_north = fixpoint_mul(v19, v28) + fixpoint_mul(a4, v9); + this->angle_from_west = fixpoint_mul(a3, v8) - fixpoint_mul(a2, v29); + this->viewing_angle_from_west_east = fixpoint_mul(a4, v28) - fixpoint_mul(v19, v9); + } + else + { + this->angle_from_north = fixpoint_mul(a2, v8) + fixpoint_mul(a3, v29); + this->angle_from_west = fixpoint_mul(a3, v8) - fixpoint_mul(a2, v29); + this->viewing_angle_from_west_east = a4; + } + + if (pGame->pIndoorCameraD3D->sRotationX) + { + v21 = fixpoint_mul(a5, v8) + fixpoint_mul(a6, v29); + + this->angle_from_east = fixpoint_mul(v21, v28) + fixpoint_mul(a7, v9); + this->angle_from_south = fixpoint_mul(a6, v8) - fixpoint_mul(a5, v29); + this->viewing_angle_from_north_south = fixpoint_mul(a7, v28) - fixpoint_mul(v21, v9); + } + else + { + this->angle_from_east = fixpoint_mul(a5, v8) + fixpoint_mul(a6, v29); + this->angle_from_south = fixpoint_mul(a6, v8) - fixpoint_mul(a5, v29); + this->viewing_angle_from_north_south = a7; + } + + this->angle_from_east = -this->angle_from_east; + this->angle_from_south = -this->angle_from_south; + this->viewing_angle_from_north_south = -this->viewing_angle_from_north_south; + + this->field_24 = fixpoint_dot(this->angle_from_north, this->field_0_party_dir_x, + this->angle_from_west, this->field_4_party_dir_y, + this->viewing_angle_from_west_east, this->field_8_party_dir_z); + this->field_28 = fixpoint_dot(this->angle_from_east, this->field_0_party_dir_x, + this->angle_from_south, this->field_4_party_dir_y, + this->viewing_angle_from_north_south, this->field_8_party_dir_z); +} +//----- (00407A1C) -------------------------------------------------------- +bool __fastcall sub_407A1C(int x, int y, int z, Vec3_int_ v) +{ + unsigned int v4; // esi@1 + int dist_y; // edi@2 + int dist_z; // ebx@2 + int dist_x; // esi@2 + signed int v9; // ecx@2 + int v10; // eax@2 + int v12; // eax@4 + int v17; // ST34_4@25 + int v18; // ST38_4@25 + int v19; // eax@25 + char v20; // zf@25 + signed int v21; // ebx@25 + signed int v23; // edi@26 + int v24; // ST34_4@30 + signed int v32; // ecx@37 + int v33; // eax@37 + int v35; // eax@39 + ODMFace *odm_face; // esi@54 + signed int v40; // ebx@60 + signed int v42; // edi@61 + signed int v49; // ecx@73 + int v50; // eax@73 + int v51; // edx@75 + int v52; // ecx@75 + int v53; // eax@75 + int v59; // eax@90 + BLVFace *face; // esi@91 + int v63; // ST34_4@98 + int v64; // ST30_4@98 + int v65; // eax@98 + signed int v66; // ebx@98 + signed int v68; // edi@99 + int v69; // ST2C_4@103 + signed int v77; // ecx@111 + int v78; // eax@111 + int v79; // edx@113 + int v80; // ecx@113 + int v81; // eax@113 + int v87; // ecx@128 + signed int v91; // ebx@136 + signed int v93; // edi@137 + Vec3_int_ v97; // [sp-18h] [bp-94h]@1 + int v107; // [sp+10h] [bp-6Ch]@98 + int v108; // [sp+10h] [bp-6Ch]@104 + int v109; // [sp+18h] [bp-64h]@25 + int v110; // [sp+18h] [bp-64h]@31 + signed int v113; // [sp+20h] [bp-5Ch]@1 + signed int v114; // [sp+24h] [bp-58h]@1 + int v119; // [sp+34h] [bp-48h]@75 + int v120; // [sp+34h] [bp-48h]@113 + int v121; // [sp+38h] [bp-44h]@4 + int v122; // [sp+38h] [bp-44h]@39 + int v123; // [sp+38h] [bp-44h]@76 + int v124; // [sp+38h] [bp-44h]@114 + int v125; // [sp+3Ch] [bp-40h]@4 + int v126; // [sp+3Ch] [bp-40h]@39 + int v127; // [sp+3Ch] [bp-40h]@77 + int v128; // [sp+3Ch] [bp-40h]@115 + int v129; // [sp+40h] [bp-3Ch]@11 + int v130; // [sp+40h] [bp-3Ch]@46 + int v131; // [sp+40h] [bp-3Ch]@78 + int v132; // [sp+40h] [bp-3Ch]@116 + int v133; // [sp+44h] [bp-38h]@10 + int v134; // [sp+44h] [bp-38h]@45 + int v135; // [sp+44h] [bp-38h]@81 + int v136; // [sp+44h] [bp-38h]@119 + int v137; // [sp+48h] [bp-34h]@7 + int v138; // [sp+48h] [bp-34h]@42 + int v139; // [sp+48h] [bp-34h]@82 + int v140; // [sp+48h] [bp-34h]@120 + int v141; // [sp+4Ch] [bp-30h]@6 + int v142; // [sp+4Ch] [bp-30h]@41 + int v143; // [sp+4Ch] [bp-30h]@75 + int v144; // [sp+4Ch] [bp-30h]@113 + int v145; // [sp+50h] [bp-2Ch]@5 + int v146; // [sp+50h] [bp-2Ch]@40 + int v149; // [sp+54h] [bp-28h]@4 + int v150; // [sp+54h] [bp-28h]@39 + int sDepthb; // [sp+58h] [bp-24h]@90 + signed int a5b; // [sp+5Ch] [bp-20h]@83 + signed int a5c; // [sp+5Ch] [bp-20h]@121 + int v162; // [sp+60h] [bp-1Ch]@128 + int outz; // [sp+64h] [bp-18h]@2 + int outx; // [sp+68h] [bp-14h]@2 + int outy; // [sp+6Ch] [bp-10h]@2 + int sZ; // [sp+70h] [bp-Ch]@2 + int sX; // [sp+74h] [bp-8h]@2 + int sY; // [sp+78h] [bp-4h]@2 + //8bytes unused + int ya; // [sp+84h] [bp+8h]@60 + int yb; // [sp+84h] [bp+8h]@136 + int ve; // [sp+88h] [bp+Ch]@60 + int va; // [sp+88h] [bp+Ch]@60 + int vb; // [sp+88h] [bp+Ch]@66 + int vf; // [sp+88h] [bp+Ch]@136 + int vc; // [sp+88h] [bp+Ch]@136 + int vd; // [sp+88h] [bp+Ch]@142 + int v_4; // [sp+8Ch] [bp+10h]@60 + int v_4a; // [sp+8Ch] [bp+10h]@65 + int v_4b; // [sp+8Ch] [bp+10h]@136 + int v_4c; // [sp+8Ch] [bp+10h]@141 + + //__debugbreak();срабатывает при стрельбе огненным шаром + + v4 = stru_5C6E00->Atan2(v.x - x, v.y - y); + + v113 = 0; + v114 = 0; + + v97.z = z; + v97.x = x; + v97.y = y; + + if ( uCurrentlyLoadedLevelType == LEVEL_Indoor) + { + Vec3_int_::Rotate(32, stru_5C6E00->uIntegerHalfPi + v4, 0, v97, &sX, &sY, &sZ); + Vec3_int_::Rotate(32, stru_5C6E00->uIntegerHalfPi + v4, 0, v, &outx, &outy, &outz); + dist_y = outy - sY; + dist_z = outz - sZ; + dist_x = outx - sX; + v49 = integer_sqrt(dist_x * dist_x + dist_y * dist_y + dist_z * dist_z); + v50 = 65536; + if ( v49 ) + v50 = 65536 / v49; + v51 = outx; + v143 = dist_x * v50; + v52 = dist_y * v50; + v53 = dist_z * v50; + + v123 = max(outx, sX); + v119 = min(outx, sX); + + v131 = max(outy, sY); + v127 = min(outy, sY); + + v139 = max(outz, sZ); + v135 = min(outz, sZ); + + for ( a5b = 0; a5b < 2; a5b++ ) + { + if ( a5b ) + v59 = pIndoor->GetSector(sX, sY, sZ); + else + v59 = pIndoor->GetSector(outx, outy, outz); + //v60 = pIndoor->pSectors; + //v61 = 116 * v59; + //i = 116 * v59; + //for (sDepthb = 0; *(__int16 *)((char *)&pIndoor->pSectors->uNumWalls + v61) + //+ 2 * *(__int16 *)((char *)&pIndoor->pSectors->uNumFloors + v61); ++sDepthb) + for ( sDepthb = 0; sDepthb < pIndoor->pSectors[v59].uNumFaces; ++sDepthb ) + { + face = &pIndoor->pFaces[pIndoor->pSectors[v59].pFaceIDs[sDepthb]];// face = &pIndoor->pFaces[*(__int16 *)((char *)&pIndoor->pSectors->pWalls + v61)[sDepthb]] + v63 = fixpoint_mul(v143, face->pFacePlane_old.vNormal.x); + v64 = fixpoint_mul(v53, face->pFacePlane_old.vNormal.z); + v65 = fixpoint_mul(v52, face->pFacePlane_old.vNormal.y); + v20 = v63 + v64 + v65 == 0; + v66 = v63 + v64 + v65; + v107 = v63 + v64 + v65; + if ( face->Portal() + || v119 > face->pBounding.x2 || v123 < face->pBounding.x1 + || v127 > face->pBounding.y2 || v131 < face->pBounding.y1 + || v135 > face->pBounding.z2 || v139 < face->pBounding.z1 + || v20 ) + continue; + v68 = -(face->pFacePlane_old.dist + sX * face->pFacePlane_old.vNormal.x + + sY * face->pFacePlane_old.vNormal.y + + sZ * face->pFacePlane_old.vNormal.z); + if ( v66 <= 0 ) + { + if ( face->pFacePlane_old.dist + sX * face->pFacePlane_old.vNormal.x + + sY * face->pFacePlane_old.vNormal.y + + sZ * face->pFacePlane_old.vNormal.z < 0 ) + continue; + } + else + { + if ( face->pFacePlane_old.dist + sX * face->pFacePlane_old.vNormal.x + + sY * face->pFacePlane_old.vNormal.y + + sZ * face->pFacePlane_old.vNormal.z > 0 ) + continue; + } + v69 = abs(-(face->pFacePlane_old.dist + sX * face->pFacePlane_old.vNormal.x + + sY * face->pFacePlane_old.vNormal.y + + sZ * face->pFacePlane_old.vNormal.z )) >> 14; + if ( v69 <= abs(v66) ) + { + //LODWORD(v70) = v68 << 16; + //HIDWORD(v70) = v68 >> 16; + //v71 = v70 / v107; + //v108 = v70 / v107; + v108 = fixpoint_div(v68, v107); + if ( v108 >= 0 ) + { + if ( sub_4075DB(sX + ((signed int)(fixpoint_mul(v108, v143) + 0x8000) >> 16), + sY + ((signed int)(fixpoint_mul(v108, v52) + 0x8000) >> 16), + sZ + ((signed int)(fixpoint_mul(v108, v53) + 0x8000) >> 16), + face) ) + { + v114 = 1; + break; + } + } + } + } + } + + Vec3_int_::Rotate(32, v4 - stru_5C6E00->uIntegerHalfPi, 0, v97, &sX, &sY, &sZ); + Vec3_int_::Rotate(32, v4 - stru_5C6E00->uIntegerHalfPi, 0, v, &outx, &outy, &outz); + dist_y = outy - sY; + dist_z = outz - sZ; + dist_x = outx - sX; + v77 = integer_sqrt(dist_x * dist_x + dist_y * dist_y + dist_z * dist_z); + v78 = 65536; + if ( v77 ) + v78 = 65536 / v77; + v79 = outx; + v144 = dist_x * v78; + v80 = dist_y * v78; + v81 = dist_z * v78; + + v120 = max(outx, sX); + v124 = min(outx, sX); + + v132 = max(outy, sY); + v128 = min(outy, sY); + + v140 = max(outz, sZ); + v136 = min(outz, sZ); + + for ( a5c = 0; a5c < 2; a5c++ ) + { + if ( v113 ) + return !v114 || !v113; + if ( a5c ) + { + v87 = pIndoor->GetSector(sX, sY, sZ); + } + else + { + v87 = pIndoor->GetSector(outx, outy, outz); + } + for ( v162 = 0; v162 < pIndoor->pSectors[v87].uNumFaces; v162++) + { + face = &pIndoor->pFaces[pIndoor->pSectors[v87].pFaceIDs[v162]]; + yb = fixpoint_mul(v144, face->pFacePlane_old.vNormal.x); + v_4b = fixpoint_mul(v80, face->pFacePlane_old.vNormal.y); + vf = fixpoint_mul(v81, face->pFacePlane_old.vNormal.z); + v20 = yb + vf + v_4b == 0; + v91 = yb + vf + v_4b; + vc = yb + vf + v_4b; + if ( face->Portal() + || v120 > face->pBounding.x2 || v124 < face->pBounding.x1 + || v128 > face->pBounding.y2 || v132 < face->pBounding.y1 + || v136 > face->pBounding.z2 || v140 < face->pBounding.z1 + || v20 ) + continue; + v93 = -(face->pFacePlane_old.dist + sX * face->pFacePlane_old.vNormal.x + + sY * face->pFacePlane_old.vNormal.y + + sZ * face->pFacePlane_old.vNormal.z); + if ( v91 <= 0 ) + { + if ( face->pFacePlane_old.dist + sX * face->pFacePlane_old.vNormal.x + + sY * face->pFacePlane_old.vNormal.y + + sZ * face->pFacePlane_old.vNormal.z < 0 ) + continue; + } + else + { + if ( face->pFacePlane_old.dist + sX * face->pFacePlane_old.vNormal.x + + sY * face->pFacePlane_old.vNormal.y + + sZ * face->pFacePlane_old.vNormal.z > 0 ) + continue; + } + v_4c = abs(-(face->pFacePlane_old.dist + sX * face->pFacePlane_old.vNormal.x + + sY * face->pFacePlane_old.vNormal.y + + sZ * face->pFacePlane_old.vNormal.z)) >> 14; + if ( v_4c <= abs(v91) ) + { + vd = fixpoint_div(v93, vc); + if ( vd >= 0 ) + { + if ( sub_4075DB(sX + ((signed int)(fixpoint_mul(vd, v144) + 0x8000) >> 16), + sY + ((signed int)(fixpoint_mul(vd, v80) + 0x8000) >> 16), + sZ + ((signed int)(fixpoint_mul(vd, v81) + 0x8000) >> 16), + face) ) + { + v113 = 1; + break; + } + } + } + } + } + } + else if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor ) + { + Vec3_int_::Rotate(32, stru_5C6E00->uIntegerHalfPi + v4, 0, v97, &sX, &sY, &sZ); + Vec3_int_::Rotate(32, stru_5C6E00->uIntegerHalfPi + v4, 0, v, &outx, &outy, &outz); + dist_y = outy - sY; + dist_z = outz - sZ; + dist_x = outx - sX; + v9 = integer_sqrt(dist_x* dist_x+ dist_y* dist_y+ dist_z* dist_z); + v10 = 65536; + if ( v9 ) + v10 = 65536 / v9; + v125 = dist_x* v10; + v12 = dist_z* v10; + v121 = dist_y* v10; + + v145 = max(outx, sX); + v149 = min(outx, sX); + + v137 = max(outy, sY); + v141 = min(outy, sY); + + v129 = max(outz, sZ); + v133 = min(outz, sZ); + + for ( uint model_id = 0; model_id < pOutdoor->uNumBModels; model_id++) + { + if ( sub_4088E9(sX, sY, outx, outy, pOutdoor->pBModels[model_id].vPosition.x, pOutdoor->pBModels[model_id].vPosition.y) + <= pOutdoor->pBModels[model_id].sBoundingRadius + 128 ) + { + for ( uint face_id = 0; face_id < pOutdoor->pBModels[model_id].uNumFaces; ++face_id ) + { + odm_face = &pOutdoor->pBModels[model_id].pFaces[face_id]; + v17 = fixpoint_mul(v125, odm_face->pFacePlane.vNormal.x); + v18 = fixpoint_mul(v121, odm_face->pFacePlane.vNormal.y); + v19 = fixpoint_mul(v12, odm_face->pFacePlane.vNormal.z); + v20 = v17 + v18 + v19 == 0; + v21 = v17 + v18 + v19; + v109 = v17 + v18 + v19; + if ( v149 > odm_face->pBoundingBox.x2 || v145 < odm_face->pBoundingBox.x1 + || v141 > odm_face->pBoundingBox.y2 || v137 < odm_face->pBoundingBox.y1 + || v133 > odm_face->pBoundingBox.z2 || v129 < odm_face->pBoundingBox.z1 + || v20 ) + continue; + v23 = -(odm_face->pFacePlane.dist + sX * odm_face->pFacePlane.vNormal.x + + sY * odm_face->pFacePlane.vNormal.y + + sZ * odm_face->pFacePlane.vNormal.z); + if ( v21 <= 0 ) + { + if ( odm_face->pFacePlane.dist + sX * odm_face->pFacePlane.vNormal.x + + sY * odm_face->pFacePlane.vNormal.y + + sZ * odm_face->pFacePlane.vNormal.z < 0 ) + continue; + } + else + { + if ( odm_face->pFacePlane.dist + sX * odm_face->pFacePlane.vNormal.x + + sY * odm_face->pFacePlane.vNormal.y + + sZ * odm_face->pFacePlane.vNormal.z > 0 ) + continue; + } + v24 = abs(-(odm_face->pFacePlane.dist + sX * odm_face->pFacePlane.vNormal.x + + sY * odm_face->pFacePlane.vNormal.y + + sZ * odm_face->pFacePlane.vNormal.z)) >> 14; + if ( v24 <= abs(v21) ) + { + v110 = fixpoint_div(v23, v109); + if ( v110 >= 0 ) + { + if ( sub_4077F1(sX + ((signed int)(fixpoint_mul(v110, v125) + 0x8000) >> 16), + sY + ((signed int)(fixpoint_mul(v110, v121) + 0x8000) >> 16), + sZ + ((signed int)(fixpoint_mul(v110, v12) + 0x8000) >> 16), + odm_face, + &pOutdoor->pBModels[model_id].pVertices) ) + { + v114 = 1; + break; + } + } + } + } + } + } + + Vec3_int_::Rotate(32, v4 - stru_5C6E00->uIntegerHalfPi, 0, v97, &sX, &sY, &sZ); + Vec3_int_::Rotate(32, v4 - stru_5C6E00->uIntegerHalfPi, 0, v, &outx, &outy, &outz); + dist_y = outy - sY; + dist_z = outz - sZ; + dist_x = outx - sX; + v32 = integer_sqrt(dist_x * dist_x + dist_y * dist_y + dist_z * dist_z); + v33 = 65536; + if ( v32 ) + v33 = 65536 / v32; + v126 = dist_x * v33; + v35 = dist_z * v33; + v122 = dist_y * v33; + + v146 = max(outx, sX); + v150 = min(outx, sX); + + v138 = max(outy, sY); + v142 = min(outy, sY); + + v130 = max(outz, sZ); + v134 = min(outz, sZ); + + for ( uint model_id = 0; model_id < (signed int)pOutdoor->uNumBModels; ++model_id ) + { + if ( sub_4088E9(sX, sY, outx, outy, pOutdoor->pBModels[model_id].vPosition.x, pOutdoor->pBModels[model_id].vPosition.y) + <= pOutdoor->pBModels[model_id].sBoundingRadius + 128 ) + { + for ( uint face_id = 0; face_id < pOutdoor->pBModels[model_id].uNumFaces; ++face_id ) + { + odm_face = &pOutdoor->pBModels[model_id].pFaces[face_id]; + ya = fixpoint_mul(v126, odm_face->pFacePlane.vNormal.x); + ve = fixpoint_mul(v122, odm_face->pFacePlane.vNormal.y); + v_4 = fixpoint_mul(v35, odm_face->pFacePlane.vNormal.z); + v20 = ya + ve + v_4 == 0; + v40 = ya + ve + v_4; + va = ya + ve + v_4; + if ( v150 > odm_face->pBoundingBox.x2 || v146 < odm_face->pBoundingBox.x1 + || v142 > odm_face->pBoundingBox.y2 || v138 < odm_face->pBoundingBox.y1 + || v134 > odm_face->pBoundingBox.z2 || v130 < odm_face->pBoundingBox.z1 + || v20 ) + continue; + v42 = -(odm_face->pFacePlane.dist + sX * odm_face->pFacePlane.vNormal.x + + sY * odm_face->pFacePlane.vNormal.y + + sZ * odm_face->pFacePlane.vNormal.z); + if ( v40 <= 0 ) + { + if ( odm_face->pFacePlane.dist + sX * odm_face->pFacePlane.vNormal.x + + sY * odm_face->pFacePlane.vNormal.y + + sZ * odm_face->pFacePlane.vNormal.z < 0 ) + continue; + } + else + { + if ( odm_face->pFacePlane.dist + sX * odm_face->pFacePlane.vNormal.x + + sY * odm_face->pFacePlane.vNormal.y + + sZ * odm_face->pFacePlane.vNormal.z > 0 ) + continue; + } + v_4a = abs(-(odm_face->pFacePlane.dist + sX * odm_face->pFacePlane.vNormal.x + + sY * odm_face->pFacePlane.vNormal.y + + sZ * odm_face->pFacePlane.vNormal.z )) >> 14; + if ( v_4a <= abs(v40) ) + { + //LODWORD(v43) = v42 << 16; + //HIDWORD(v43) = v42 >> 16; + //vb = v43 / va; + vb = fixpoint_div(v42, va); + if ( vb >= 0 ) + { + if ( sub_4077F1(sX + ((signed int)(fixpoint_mul(vb, v126) + 0x8000) >> 16), + sY + ((signed int)(fixpoint_mul(vb, v122) + 0x8000) >> 16), + sZ + ((signed int)(fixpoint_mul(vb, v35) + 0x8000) >> 16), + odm_face, + &pOutdoor->pBModels[model_id].pVertices) ) + { + v113 = 1; + break; + } + } + } + } + } + } + + } + return !v114 || !v113; +} +//----- (0043F333) -------------------------------------------------------- +void BspRenderer::MakeVisibleSectorList() +{ +// int v6; // ebx@3 + + uNumVisibleNotEmptySectors = 0; + for (uint i = 0; i < num_nodes; ++i) + { + //if (!uNumVisibleNotEmptySectors) + //{ + //pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[uNumVisibleNotEmptySectors++] = nodes[i].uSectorID; + //continue; + //} + //v6 = 0; + //while (pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[v6] != nodes[i].uSectorID ) + for ( uint j = 0; j < uNumVisibleNotEmptySectors; j++ ) + { + //++v6; + if ( pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[j] == nodes[i].uSectorID) + break; + } + pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[uNumVisibleNotEmptySectors++] = nodes[i].uSectorID; + } +} +//----- (0046A334) -------------------------------------------------------- +char __fastcall DoInteractionWithTopmostZObject(int a1, int a2) +{ + int v17; // edi@36 + + v17 = PID_ID(a1); + switch ( PID_TYPE(a1) ) + { + case OBJECT_Item: // take the item + if ( pObjectList->pObjects[pSpriteObjects[v17].uObjectDescID].uFlags & 0x10 || v17 >= 1000 || !pSpriteObjects[v17].uObjectDescID ) + return 1; + if ( pItemsTable->pItems[pSpriteObjects[v17].stru_24.uItemID].uEquipType == EQUIP_GOLD) + { + pParty->PartyFindsGold(pSpriteObjects[v17].stru_24.uSpecEnchantmentType, 0); + viewparams->bRedrawGameUI = 1; + } + else + { + if ( pParty->pPickedItem.uItemID ) + return 1; + sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[471], pItemsTable->pItems[pSpriteObjects[v17].stru_24.uItemID].pUnidentifiedName);//You found an item (%s)! + ShowStatusBarString(pTmpBuf2.data(), 2); + if ( pSpriteObjects[v17].stru_24.uItemID == 506 )//artefact + _449B7E_toggle_bit(pParty->_quest_bits, 184, 1); + if ( pSpriteObjects[v17].stru_24.uItemID == 455 ) + _449B7E_toggle_bit(pParty->_quest_bits, 185, 1); + if ( !pParty->AddItemToParty(&pSpriteObjects[v17].stru_24) ) + pParty->SetHoldingItem(&pSpriteObjects[v17].stru_24); + } + SpriteObject::OnInteraction(v17); + break; + + case OBJECT_Actor: + if ( pActors[v17].uAIState == Dying || pActors[v17].uAIState == Summoned ) + return 1; + if ( pActors[v17].uAIState == Dead ) + pActors[v17].LootActor(); + else + { + if ( !pActors[v17].GetActorsRelation(0) && pActors[v17].ActorFriend() && pActors[v17].CanAct() ) + { + Actor::AI_FaceObject(v17, 4, 0, 0); + if ( pActors[v17].sNPC_ID ) + pMessageQueue_50CBD0->AddGUIMessage(UIMSG_StartNPCDialogue, v17, 0); + else + { + if ( pNPCStats->pGroups_copy[pActors[v17].uGroup] ) + { + if ( pNPCStats->pCatchPhrases[pNPCStats->pGroups_copy[pActors[v17].uGroup]] ) + { + pParty->uFlags |= 2; + strcpy(byte_5B0938.data(), pNPCStats->pCatchPhrases[pNPCStats->pGroups_copy[pActors[v17].uGroup]]); + sub_4451A8_press_any_key(0, 0, 0); + } + } + } + } + } + break; + + case OBJECT_Decoration: + if ( pLevelDecorations[v17].uEventID ) + { + EventProcessor(pLevelDecorations[v17].uEventID, a1, 1); + pLevelDecorations[v17].uFlags |= LEVEL_DECORATION_VISIBLE_ON_MAP; + } + else + { + if ( !pLevelDecorations[v17].IsInteractive() ) + return 1; + activeLevelDecoration = &pLevelDecorations[v17]; + EventProcessor(stru_5E4C90_MapPersistVars._decor_events[pLevelDecorations[v17]._idx_in_stru123 - 75] + 380, 0, 1); + activeLevelDecoration = nullptr; + } + break; + + default: + MessageBoxW(nullptr, L"Warning: Invalid ID reached!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Mouse.cpp:2020", 0); + return 1; + + case OBJECT_BModel: + if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor ) + { + int bmodel_id = a1 >> 9, + face_id = v17 & 0x3F; + if (bmodel_id >= pOutdoor->uNumBModels) + return 1; + if (pOutdoor->pBModels[bmodel_id].pFaces[face_id].uAttributes & FACE_HAS_EVENT + || pOutdoor->pBModels[bmodel_id].pFaces[face_id].sCogTriggeredID == 0 ) + return 1; + EventProcessor((signed __int16)pOutdoor->pBModels[bmodel_id].pFaces[face_id].sCogTriggeredID, a1, 1); + } + else + { + if ( !(pIndoor->pFaces[v17].uAttributes & FACE_CLICKABLE) ) + { + ShowNothingHereStatus(); + return 1; + } + if ( pIndoor->pFaces[v17].uAttributes & FACE_HAS_EVENT || !pIndoor->pFaceExtras[pIndoor->pFaces[v17].uFaceExtraID].uEventID ) + return 1; + if ( pCurrentScreen != SCREEN_BRANCHLESS_NPC_DIALOG ) + EventProcessor((signed __int16)pIndoor->pFaceExtras[pIndoor->pFaces[v17].uFaceExtraID].uEventID, a1, 1); + } + return 0; + break; + } + return 0; +} +//----- (0046BDF1) -------------------------------------------------------- +void BLV_UpdateUserInputAndOther() +{ + UpdateObjects(); + BLV_ProcessPartyActions(); + UpdateActors_BLV(); + BLV_UpdateDoors(); + check_event_triggers(); +} +//----- (00424829) -------------------------------------------------------- +// Finds out if current portal can be seen through the previous portal +bool PortalFrustrum(int pNumVertices, BspRenderer_PortalViewportData *far_portal, BspRenderer_PortalViewportData *near_portal, int uFaceID) +{ + int min_y; // esi@5 + int max_y; // edx@5 + int current_ID; // eax@12 + int v13; // eax@22 + int v15; // ecx@29 + int v18; // eax@39 + int v19; // eax@44 + int v20; // ecx@44 + int v22; // edi@46 + int v24; // edx@48 + int v26; // eax@55 + int v29; // edx@57 + int v31; // eax@64 + __int16 v36; // dx@67 + __int16 v38; // dx@67 + int v46; // edx@87 + int v49; // esi@93 + int v53; // [sp+Ch] [bp-34h]@44 + int v54; // [sp+10h] [bp-30h]@0 + int min_y_ID2; // [sp+14h] [bp-2Ch]@12 + int v59; // [sp+14h] [bp-2Ch]@87 + int v61; // [sp+1Ch] [bp-24h]@29 + int v62; // [sp+20h] [bp-20h]@0 + signed int direction1; // [sp+24h] [bp-1Ch]@3 + signed int direction2; // [sp+28h] [bp-18h]@3 + int min_y_ID; // [sp+2Ch] [bp-14h]@5 + int v69; // [sp+34h] [bp-Ch]@29 + int v70; // [sp+34h] [bp-Ch]@46 + + if ( pNumVertices <= 1 ) + return false; + min_y = PortalFace._screen_space_y[0]; + min_y_ID = 0; + max_y = PortalFace._screen_space_y[0]; + //face direction(направление фейса) + if ( !PortalFace.direction ) + { + direction1 = 1; + direction2 = -1; + } + else + { + direction1 = -1; + direction2 = 1; + } + + //get min and max y for portal(дать минимальное и максимальное значение y для портала) + for ( uint i = 1; i < pNumVertices; ++i ) + { + if (PortalFace._screen_space_y[i] < min_y) + { + min_y_ID = i; + min_y = PortalFace._screen_space_y[i]; + } + else if (PortalFace._screen_space_y[i] > max_y) + { + max_y = PortalFace._screen_space_y[i]; + } + } + if ( max_y == min_y ) + return false; + + //***************************************************************************************************************************** + far_portal->_viewport_space_y = min_y; + far_portal->_viewport_space_w = max_y; + current_ID = min_y_ID; + min_y_ID2 = min_y_ID; + + for ( uint i = 0; i < pNumVertices; ++i ) + { + current_ID += direction2; + if ( current_ID < pNumVertices ) + { + if ( current_ID < 0 ) + current_ID += pNumVertices; + } + else + current_ID -= pNumVertices; + if ( PortalFace._screen_space_y[current_ID] <= PortalFace._screen_space_y[min_y_ID] )//определение минимальной у + { + min_y_ID2 = current_ID; + min_y_ID = current_ID; + } + if ( PortalFace._screen_space_y[current_ID] == max_y ) + break; + } + + v13 = min_y_ID2 + direction2; + if ( v13 < pNumVertices ) + { + if ( v13 < 0 ) + v13 += pNumVertices; + } + else + v13 -= pNumVertices; + if ( PortalFace._screen_space_y[v13] != PortalFace._screen_space_y[min_y_ID2] ) + { + v62 = PortalFace._screen_space_x[min_y_ID2] << 16; + v54 = ((PortalFace._screen_space_x[v13] - PortalFace._screen_space_x[min_y_ID2]) << 16) / + (PortalFace._screen_space_y[v13] - PortalFace._screen_space_y[min_y_ID2]); + far_portal->viewport_left_side[min_y] = (short)PortalFace._screen_space_x[min_y_ID2]; + } + //**************************************************************************************************************************************** + // + v15 = min_y_ID; + v61 = min_y_ID; + for ( v69 = 0; v69 < pNumVertices; ++v69 ) + { + v15 += direction1; + if ( v15 < pNumVertices ) + { + if ( v15 < 0 ) + v15 += pNumVertices; + } + else + v15 -= pNumVertices; + if ( PortalFace._screen_space_y[v15] <= PortalFace._screen_space_y[min_y_ID] ) + { + v61 = v15; + min_y_ID = v15; + } + if ( PortalFace._screen_space_y[v15] == max_y ) + break; + } + v18 = direction1 + v61; + if ( v18 < pNumVertices ) + { + if ( v18 < 0 ) + v18 += pNumVertices; + } + else + v18 -= pNumVertices; + v19 = v18; + v20 = v61; + if ( PortalFace._screen_space_y[v19] != PortalFace._screen_space_y[v61] ) + { + v61 = PortalFace._screen_space_x[v20] << 16; + v53 = ((PortalFace._screen_space_x[v19] - PortalFace._screen_space_x[v20]) << 16) / + (PortalFace._screen_space_y[v19] - PortalFace._screen_space_y[v20]); + far_portal->viewport_right_side[max_y] = (short)PortalFace._screen_space_x[v20]; + } + //**************************************************************************************************************************************** + v22 = min_y; + if ( min_y <= max_y ) + { + for ( v70 = min_y; v70 <= max_y; ++v70 ) + { + v24 = v13; + if ( v22 >= PortalFace._screen_space_y[v13] && v22 != max_y ) + { + v13 = direction2 + v13; + if ( v13 < pNumVertices ) + { + if ( v13 < 0 ) + v13 += pNumVertices; + } + else + v13 -= pNumVertices; + v26 = v13; + if ( PortalFace._screen_space_y[v26] - PortalFace._screen_space_y[v24] > 0 ) + { + v54 = ((PortalFace._screen_space_x[v26] - PortalFace._screen_space_x[v24]) << 16) / (PortalFace._screen_space_y[v26] - PortalFace._screen_space_y[v24]); + v62 = PortalFace._screen_space_x[v24] << 16; + } + } + v29 = v18; + if ( v70 >= PortalFace._screen_space_y[v18] && v70 != max_y ) + { + v18 += direction1; + if ( v18 < pNumVertices ) + { + if ( v18 < 0 ) + v18 += pNumVertices; + } + else + v18 -= pNumVertices; + v31 = v18; + if ( PortalFace._screen_space_y[v31] - PortalFace._screen_space_y[v29] > 0 ) + { + v53 = ((PortalFace._screen_space_x[v31] - PortalFace._screen_space_x[v29]) << 16) / (PortalFace._screen_space_y[v31] - PortalFace._screen_space_y[v29]); + v61 = PortalFace._screen_space_x[v29] << 16; + } + } + far_portal->viewport_left_side[v70] = HIWORD(v62); + far_portal->viewport_right_side[v70] = HIWORD(v61); + if ( far_portal->viewport_left_side[v70] > far_portal->viewport_right_side[v70] ) + { + v36 = far_portal->viewport_left_side[v70] ^ far_portal->viewport_right_side[v70]; + //v37 = far_portal->viewport_right_side[v70]; + far_portal->viewport_left_side[v70] = v36; + v38 = far_portal->viewport_right_side[v70] ^ v36; + far_portal->viewport_left_side[v70] ^= v38; + far_portal->viewport_right_side[v70] = v38; + } + v62 += v54; + v22 = v70 + 1; + v61 += v53; + } + } + //***************************************************************************************************************************** + // check portals coordinates and determine max, min(проверка координат порталов и определение макс, мин-ой у) + if ( max_y < near_portal->_viewport_space_y ) + return false; + if ( min_y > near_portal->_viewport_space_w ) + return false; + if ( min_y < near_portal->_viewport_space_y ) + min_y = near_portal->_viewport_space_y; + if ( max_y > near_portal->_viewport_space_w ) + max_y = near_portal->_viewport_space_w; + if ( min_y <= max_y ) + { + for ( min_y; min_y <= max_y; ++min_y ) + { + if ( far_portal->viewport_right_side[min_y] >= near_portal->viewport_left_side[min_y] + && far_portal->viewport_left_side[min_y] <= near_portal->viewport_right_side[min_y] ) + break; + } + } + if ( max_y < min_y ) + return false; + for ( max_y; max_y >= min_y; --max_y ) + { + if ( far_portal->viewport_right_side[max_y] >= near_portal->viewport_left_side[max_y] + && far_portal->viewport_left_side[max_y] <= near_portal->viewport_right_side[max_y] ) + break; + } + if ( min_y >= max_y ) + return false; + //************************************************************************************************************************************* + v59 = min_y; + for ( v46 = max_y - min_y + 1; v46; --v46 ) + { + if ( far_portal->viewport_left_side[v59] < near_portal->viewport_left_side[v59] ) + far_portal->viewport_left_side[v59] = near_portal->viewport_left_side[v59]; + if ( far_portal->viewport_right_side[v59] > near_portal->viewport_right_side[v59] ) + far_portal->viewport_right_side[v59] = near_portal->viewport_right_side[v59]; + ++v59; + } + far_portal->_viewport_space_y = min_y; + far_portal->_viewport_space_w = max_y; + far_portal->_viewport_space_x = far_portal->viewport_left_side[min_y]; + far_portal->_viewport_space_z = far_portal->viewport_right_side[min_y]; + far_portal->_viewport_x_minID = min_y; + far_portal->_viewport_z_maxID = min_y; + v49 = min_y + 1; + if ( v49 <= max_y ) + { + for ( v49; v49 <= max_y; ++v49 ) + { + if ( far_portal->viewport_left_side[v49] < far_portal->_viewport_space_x ) + { + far_portal->_viewport_space_x = far_portal->viewport_left_side[v49]; + far_portal->_viewport_x_minID = v49; + } + if ( far_portal->viewport_right_side[v49] > far_portal->_viewport_space_z ) + { + far_portal->_viewport_space_z = far_portal->viewport_right_side[v49]; + far_portal->_viewport_z_maxID = v49; + } + } + } + return true; +} +//----- (00423B5D) -------------------------------------------------------- +int __fastcall GetPortalScreenCoord(unsigned int uFaceID) +{ + BLVFace *pFace; // ebx@1 + int pNextVertices; // edx@11 + int t; // ST28_4@12 + int pScreenX; // eax@22 + int pScreenY; // eax@27 + signed int left_num_vertices; // edi@31 + signed int right_num_vertices; // ebx@41 + signed int top_num_vertices; // edi@51 + int bottom_num_vertices; // ebx@61 + bool current_vertices_flag; // [sp+18h] [bp-10h]@9 + signed int depth_num_vertices; // [sp+1Ch] [bp-Ch]@9 + bool next_vertices_flag; // [sp+20h] [bp-8h]@10 + + //Доп инфо "Программирование трёхмерных игр для windows" Ламот стр 910 + + pFace = &pIndoor->pFaces[uFaceID]; + memset(&PortalFace, 0, sizeof(stru367)); + + //get direction the face(определение направленности фейса)********************************************************************************* + if ( pFace->pFacePlane_old.vNormal.x * (pIndoor->pVertices[pIndoor->pFaces[uFaceID].pVertexIDs[0]].x - pGame->pIndoorCameraD3D->vPartyPos.x) + + pFace->pFacePlane_old.vNormal.y * (pIndoor->pVertices[pIndoor->pFaces[uFaceID].pVertexIDs[0]].y - pGame->pIndoorCameraD3D->vPartyPos.y) + + pFace->pFacePlane_old.vNormal.z * (pIndoor->pVertices[pIndoor->pFaces[uFaceID].pVertexIDs[0]].z - pGame->pIndoorCameraD3D->vPartyPos.z) < 0 ) + { + PortalFace.direction = true; + } + else + { + PortalFace.direction = false; + if ( !(pFace->Portal()) ) + return 0; + } + //***************************************************************************************************************************************** + //generate/cinvertetion in camera location coordinates(генерация/конвертирование в координаты пространства камеры) + + //for new coordinates: + //int x = 0x AAAA BBBB; + //AAAA - integer(целая часть), BBBB - fractional(дробная) + //float v = HIWORD(x) + LOWORD(x) / 65535.0f; + //0x0351A281 это 849(351 в шестнадцатиричной) в целой части и A281 в дробной(хотя как точно BBBB считалась не помню) + //if in HIWORD: FFFF = -1 + //FFFE = -2 + //FFFD = -3 + //.... + //8000 = -32767 + //7FFF = 32767 + //7FFE = 32766 + //если в LOWORD например лежит FFFF то не совсем понятно, что это + //потому что если и hiword и loword равны FFFF FFFF то двойное отрицание как бы, нужно тестировать что конкретно получается чтобы понять что это значит + //всё что больше 7FFF для верхнего слова это идёт уже с минусом/Nomad/ + + if ( (signed int)pFace->uNumVertices > 0 ) + { + for (uint i = 0; i < pFace->uNumVertices; ++i) + { + pGame->pIndoorCameraD3D->ApplyViewTransform_TrueIfStillVisible_BLV(pIndoor->pVertices[pFace->pVertexIDs[i]].x, + pIndoor->pVertices[pFace->pVertexIDs[i]].y, + pIndoor->pVertices[pFace->pVertexIDs[i]].z, + &PortalFace._view_transformed_z[i + 3], &PortalFace._view_transformed_x[i + 3], &PortalFace._view_transformed_y[i + 3], 0); + } + } + //***************************************************************************************************************************************** + //check vertices for the nearest plane(проверка вершин есть ли в области за ближайшей плоскостью) + if ( pFace->uNumVertices <= 0 ) + return 0; + bool bFound = false; + for (uint i = 0; i < pFace->uNumVertices; ++i) + { + if ( PortalFace._view_transformed_z[i + 3] >= 524288 )// 8.0(0x80000) + { + bFound = true; + break; + } + } + if ( !bFound ) + return 0; + //***************************************************************************************************************************************** + //check for near clip plane(проверка по ближней границе) + // + // v0 v1 + // ._________________. + // / \ + // / \ + // v5. . v2 + // | | + // | | + // | | + // ---------------------------- 8.0(near_clip) + // | | + // ._______________________. + // v4 v3 + depth_num_vertices = 0; + PortalFace._view_transformed_z[pFace->uNumVertices + 3] = PortalFace._view_transformed_z[3]; + PortalFace._view_transformed_x[pFace->uNumVertices + 3] = PortalFace._view_transformed_x[3]; + PortalFace._view_transformed_y[pFace->uNumVertices + 3] = PortalFace._view_transformed_y[3]; + current_vertices_flag = PortalFace._view_transformed_z[3] >= 0x80000; //524288 + if ( pFace->uNumVertices >= 1 ) + { + for ( uint i = 1; i <= pFace->uNumVertices; ++i) + { + next_vertices_flag = PortalFace._view_transformed_z[i + 3] >= 0x80000; //524288;// 8.0 + if ( current_vertices_flag ^ next_vertices_flag )//или текущая или следующая вершина за ближней границей - v5 + { + if ( next_vertices_flag )//следующая вершина за ближней границей + { + //t = near_clip - v4.z / v5.z - v4.z + t = fixpoint_div(0x80000 - PortalFace._view_transformed_z[i + 2], PortalFace._view_transformed_z[i + 3] - PortalFace._view_transformed_z[i + 2]); + //New_x = (v5.x - v4.x)*t + v4.x + PortalFace._view_transformed_x[depth_num_vertices] = fixpoint_mul((PortalFace._view_transformed_x[i + 3] - PortalFace._view_transformed_x[i + 2]), t) + + PortalFace._view_transformed_x[i + 2]; + //New_y = (v5.y - v4.y)*t + v4.y + PortalFace._view_transformed_y[depth_num_vertices] = fixpoint_mul((PortalFace._view_transformed_y[i + 3] - PortalFace._view_transformed_y[i + 2]), t) + + PortalFace._view_transformed_y[i + 2]; + //New_z = 8.0(0x80000) + PortalFace._view_transformed_z[depth_num_vertices] = 0x80000; //524288 + } + else// текущая вершина за ближней границей + { + //t = near_clip - v1.z / v0.z - v1.z + t = fixpoint_div(524288 - PortalFace._view_transformed_z[i + 3], PortalFace._view_transformed_z[i + 2] - PortalFace._view_transformed_z[i + 3]); + //New_x = (v0.x - v1.x)*t + v1.x + PortalFace._view_transformed_x[depth_num_vertices] = fixpoint_mul((PortalFace._view_transformed_x[i + 2] - PortalFace._view_transformed_x[i + 3]), t) + + PortalFace._view_transformed_x[i + 3]; + //New_y = (v0.x - v1.y)*t + v1.y + PortalFace._view_transformed_y[depth_num_vertices] = fixpoint_mul((PortalFace._view_transformed_y[i + 2] - PortalFace._view_transformed_y[i + 3]), t) + + PortalFace._view_transformed_y[i + 3]; + //New_z = 8.0(0x80000) + PortalFace._view_transformed_z[depth_num_vertices] = 0x80000; //524288 + } + depth_num_vertices++; + } + if ( next_vertices_flag )//если следующая вершина за ближней границей + { + pNextVertices = depth_num_vertices++; + PortalFace._view_transformed_z[pNextVertices] = PortalFace._view_transformed_z[i + 3]; + PortalFace._view_transformed_x[pNextVertices] = PortalFace._view_transformed_x[i + 3]; + PortalFace._view_transformed_y[pNextVertices] = PortalFace._view_transformed_y[i + 3]; + } + current_vertices_flag = next_vertices_flag; + } + } + //результат: нет моргания на границе портала(когда проходим сквозь портал) + //************************************************************************************************************************************ + //convertion in screen coordinates(конвертирование в координаты экрана) + PortalFace._view_transformed_z[depth_num_vertices] = PortalFace._view_transformed_z[0]; + PortalFace._view_transformed_x[depth_num_vertices] = PortalFace._view_transformed_x[0]; + PortalFace._view_transformed_y[depth_num_vertices] = PortalFace._view_transformed_y[0]; + for ( uint i = 0; i < depth_num_vertices; ++i ) + { + if ( (abs(PortalFace._view_transformed_x[i]) >> 13) <= abs(PortalFace._view_transformed_z[i]) ) + pScreenX = fixpoint_div(PortalFace._view_transformed_x[i], PortalFace._view_transformed_z[i]); + else + { + if ( PortalFace._view_transformed_x[i] >= 0 ) + { + if (PortalFace._view_transformed_z[i] >= 0) + pScreenX = 0x400000; // 64.0 + else + pScreenX = 0xFFC00000; // -63.0 + } + else + { + if (PortalFace._view_transformed_z[i] >= 0) + pScreenX = 0xFFC00000; // -63.0 + else + pScreenX = 0x400000; // 64.0 + } + } + + if ( (abs(PortalFace._view_transformed_y[i]) >> 13) <= abs(PortalFace._view_transformed_z[i]) ) + pScreenY = fixpoint_div(PortalFace._view_transformed_y[i], PortalFace._view_transformed_z[i]); + else + { + if ( PortalFace._view_transformed_y[i] >= 0 ) + { + if (PortalFace._view_transformed_z[i] >= 0) + pScreenY = 0x400000; // 64.0 + else + pScreenY = 0xFFC00000; // -63.0 + } + else + { + if (PortalFace._view_transformed_z[i] >= 0) + pScreenY = 0xFFC00000; // -63.0 + else + pScreenY = 0x400000; // 64.0 + } + } + PortalFace._screen_space_x[i + 12] = pBLVRenderParams->uViewportCenterX - fixpoint_mul(SHIWORD(pBLVRenderParams->fov_rad_fixpoint), pScreenX); + PortalFace._screen_space_y[i + 12] = pBLVRenderParams->uViewportCenterY - fixpoint_mul(SHIWORD(pBLVRenderParams->fov_rad_fixpoint), pScreenY); + } + // результат: при повороте камеры, когда граница портала сдвигается к краю экрана, портал остается прозрачным(видимым) + //****************************************************************************************************************************************** + //координаты как в Ида-базе игры так и в данном проекте перевёрнутые,т.е. портал который в правой части экрана имеет экранные координаты + //которые для левой части экрана. Например, x(оригинал) = 8, у нас х = 468(противоположный край экрана), точно также и с у. + // + //check for left_clip plane(порверка по левой границе) + left_num_vertices = 0; + PortalFace._screen_space_x[depth_num_vertices + 12] = PortalFace._screen_space_x[12]; + PortalFace._screen_space_y[depth_num_vertices + 12] = PortalFace._screen_space_y[12]; + current_vertices_flag = PortalFace._screen_space_x[12] >= (signed int)pBLVRenderParams->uViewportX;//8.0 + if ( depth_num_vertices < 1 ) + return 0; + for ( uint i = 1; i <= depth_num_vertices; ++i ) + { + next_vertices_flag = PortalFace._screen_space_x[i + 12] >= (signed int)pBLVRenderParams->uViewportX; + if ( current_vertices_flag ^ next_vertices_flag ) + { + if ( next_vertices_flag ) + { + //t = left_clip - v0.x / v1.x - v0.x + t = fixpoint_div(pBLVRenderParams->uViewportX - PortalFace._screen_space_x[i + 11], PortalFace._screen_space_x[i + 12] - PortalFace._screen_space_x[i + 11]); + //New_y = (v1.y - v0.y)*t + v0.y + PortalFace._screen_space_y[left_num_vertices + 9] = fixpoint_mul((PortalFace._screen_space_y[i + 12]- PortalFace._screen_space_y[i + 11]), t) + + PortalFace._screen_space_y[i + 11]; + //New_x = left_clip + PortalFace._screen_space_x[left_num_vertices + 9] = pBLVRenderParams->uViewportX; + } + else + { + //t = left_clip - v1.x / v0.x - v1.x + t = fixpoint_div(pBLVRenderParams->uViewportX - PortalFace._screen_space_x[i + 12], PortalFace._screen_space_x[i + 11] - PortalFace._screen_space_x[i + 12]); + //New_y = (v0.y - v1.y)*t + v1.y + PortalFace._screen_space_y[left_num_vertices + 9] = fixpoint_mul((PortalFace._screen_space_y[i + 11] - PortalFace._screen_space_y[i + 12]), t) + + PortalFace._screen_space_y[i + 12]; + //New_x = left_clip + PortalFace._screen_space_x[left_num_vertices + 9] = pBLVRenderParams->uViewportX; + } + left_num_vertices++; + } + if ( next_vertices_flag ) + { + pNextVertices = left_num_vertices++; + PortalFace._screen_space_x[pNextVertices + 9] = PortalFace._screen_space_x[i + 12]; + PortalFace._screen_space_y[pNextVertices + 9] = PortalFace._screen_space_y[i + 12]; + } + current_vertices_flag = next_vertices_flag; + } +//********************************************************************************************************************************* +//for right_clip plane(проверка по правой плоскости) + right_num_vertices = 0; + PortalFace._screen_space_x[left_num_vertices + 9] = PortalFace._screen_space_x[9]; + PortalFace._screen_space_y[left_num_vertices + 9] = PortalFace._screen_space_y[9]; + current_vertices_flag = PortalFace._screen_space_x[9] <= (signed int)pBLVRenderParams->uViewportZ;//468.0 + if (left_num_vertices < 1) + return 0; + for ( uint i = 1; i <= left_num_vertices; ++i ) + { + next_vertices_flag = PortalFace._screen_space_x[i + 9] <= (signed int)pBLVRenderParams->uViewportZ; + if ( current_vertices_flag ^ next_vertices_flag ) + { + if ( next_vertices_flag ) + { + //t = right_clip - v1.x / v0.x - v1.x + t = fixpoint_div(pBLVRenderParams->uViewportZ - PortalFace._screen_space_x[i + 8], PortalFace._screen_space_x[i + 9] - PortalFace._screen_space_x[i + 8]); + //New_y = (v0.y - v1.y)*t + v1.y + PortalFace._screen_space_y[right_num_vertices + 6] = fixpoint_mul((PortalFace._screen_space_y[i + 9] - PortalFace._screen_space_y[i + 8]), t) + + PortalFace._screen_space_y[i + 8]; + //New_x = right_clip + PortalFace._screen_space_x[right_num_vertices + 6] = pBLVRenderParams->uViewportZ; + } + else + { + //t = right_clip - v0.x / v1.x - v0.x + t = fixpoint_div(pBLVRenderParams->uViewportZ - PortalFace._screen_space_x[i + 9], PortalFace._screen_space_x[i + 8] - PortalFace._screen_space_x[i + 9]); + //New_y = (v1.y - v0.y)*t + v0.y + PortalFace._screen_space_y[right_num_vertices + 6] = fixpoint_mul((PortalFace._screen_space_y[i + 8] - PortalFace._screen_space_y[i + 9]), t) + + PortalFace._screen_space_y[i + 9]; + //New_x = right_clip + PortalFace._screen_space_x[right_num_vertices + 6] = pBLVRenderParams->uViewportZ; + } + right_num_vertices++; + } + if ( next_vertices_flag ) + { + pNextVertices = right_num_vertices++; + PortalFace._screen_space_x[pNextVertices + 6] = PortalFace._screen_space_x[i + 9]; + PortalFace._screen_space_y[pNextVertices + 6] = PortalFace._screen_space_y[i + 9]; + } + current_vertices_flag = next_vertices_flag; + } + //************************************************************************************************************************************ + // for top clip plane + top_num_vertices = 0; + PortalFace._screen_space_x[right_num_vertices + 6] = PortalFace._screen_space_x[6]; + PortalFace._screen_space_y[right_num_vertices + 6] = PortalFace._screen_space_y[6]; + + current_vertices_flag = PortalFace._screen_space_y[6] >= (signed int)pBLVRenderParams->uViewportY;//8.0 + if ( right_num_vertices < 1 ) + return 0; + for ( uint i = 1; i <= right_num_vertices; ++i ) + { + next_vertices_flag = PortalFace._screen_space_y[i + 6] >= (signed int)pBLVRenderParams->uViewportY; + if ( current_vertices_flag ^ next_vertices_flag ) + { + if ( next_vertices_flag ) + { + t = fixpoint_div(pBLVRenderParams->uViewportY - PortalFace._screen_space_y[i + 5], PortalFace._screen_space_y[i + 6] - PortalFace._screen_space_y[i + 5]); + PortalFace._screen_space_x[top_num_vertices + 3] = ((signed int)((PortalFace._screen_space_x[i + 6] - PortalFace._screen_space_x[i + 5]) + * t) >> 16) + PortalFace._screen_space_x[i + 5]; + PortalFace._screen_space_y[top_num_vertices + 3] = pBLVRenderParams->uViewportY; + } + else + { + t = fixpoint_div(pBLVRenderParams->uViewportY - PortalFace._screen_space_y[i + 6], PortalFace._screen_space_y[i + 5] - PortalFace._screen_space_y[i + 6]); + PortalFace._screen_space_x[top_num_vertices + 3] = fixpoint_mul((PortalFace._screen_space_x[i + 5]- PortalFace._screen_space_x[i + 6]), t) + + PortalFace._screen_space_x[i + 6]; + PortalFace._screen_space_y[top_num_vertices + 3] = pBLVRenderParams->uViewportY; + } + top_num_vertices++; + } + current_vertices_flag = next_vertices_flag; + if ( next_vertices_flag ) + { + pNextVertices = top_num_vertices++; + PortalFace._screen_space_x[pNextVertices + 3] = PortalFace._screen_space_x[i + 6]; + PortalFace._screen_space_y[pNextVertices + 3] = PortalFace._screen_space_y[i + 6]; + } + } +//********************************************************************************************************************************** +//for bottom_clip plane(проверка по нижней плоскости) + bottom_num_vertices = 0; + PortalFace._screen_space_x[top_num_vertices + 3] = PortalFace._screen_space_x[3]; + PortalFace._screen_space_y[top_num_vertices + 3] = PortalFace._screen_space_y[3]; + current_vertices_flag = PortalFace._screen_space_y[3] <= (signed int)pBLVRenderParams->uViewportW;//351.0 + if ( top_num_vertices < 1 ) + return 0; + for ( uint i =1; i <= top_num_vertices; ++i ) + { + next_vertices_flag = PortalFace._screen_space_y[i + 3] <= (signed int)pBLVRenderParams->uViewportW; + if ( current_vertices_flag ^ next_vertices_flag ) + { + if ( next_vertices_flag ) + { + t = fixpoint_div(pBLVRenderParams->uViewportW - PortalFace._screen_space_y[i + 2], PortalFace._screen_space_y[i + 3] - PortalFace._screen_space_y[i + 2]); + PortalFace._screen_space_x[bottom_num_vertices] = fixpoint_mul((PortalFace._screen_space_x[i + 3] - PortalFace._screen_space_x[i + 2]), t) + + PortalFace._screen_space_x[i + 2]; + PortalFace._screen_space_y[bottom_num_vertices] = pBLVRenderParams->uViewportW; + } + else + { + t = fixpoint_div(pBLVRenderParams->uViewportW - PortalFace._screen_space_y[i + 3], PortalFace._screen_space_y[i + 2] - PortalFace._screen_space_y[i + 3]); + PortalFace._screen_space_x[bottom_num_vertices] = fixpoint_mul((PortalFace._screen_space_x[i + 2] - PortalFace._screen_space_x[i + 3]), t) + + PortalFace._screen_space_x[i + 3]; + PortalFace._screen_space_y[bottom_num_vertices] = pBLVRenderParams->uViewportW; + } + bottom_num_vertices++; + } + if ( next_vertices_flag ) + { + pNextVertices = bottom_num_vertices++; + PortalFace._screen_space_x[pNextVertices] = PortalFace._screen_space_x[i + 3]; + PortalFace._screen_space_y[pNextVertices] = PortalFace._screen_space_y[i + 3]; + } + current_vertices_flag = next_vertices_flag; + } +//*************************************************************************************************************************************** + + if ( !bottom_num_vertices ) + return 0; + PortalFace._screen_space_x[bottom_num_vertices] = PortalFace._screen_space_x[0]; + PortalFace._screen_space_y[bottom_num_vertices] = PortalFace._screen_space_y[0]; +//check for software(проверка для софтвар) + /*if ( !pRenderer->pRenderD3D && bottom_num_vertices > 3 ) + { + PortalFace._screen_space_x[bottom_num_vertices + 1] = PortalFace._screen_space_x[1]; + PortalFace._screen_space_y[bottom_num_vertices + 1] = PortalFace._screen_space_y[1]; + thisf = PortalFace.direction == true ? 1 : - 1; + if ( bottom_num_vertices > 0 ) + { + v62 = 1; + v71 = 1; + do + { + v63 = v62 - 1; + v64 = v62 + 1; + v80 = v62 + 1; + if ( v62 - 1 >= bottom_num_vertices ) + v63 -= bottom_num_vertices; + if ( v62 >= bottom_num_vertices ) + v62 -= bottom_num_vertices; + if ( v64 >= bottom_num_vertices ) + v64 -= bottom_num_vertices; + if ( thisf * ((PortalFace._screen_space_y[v64] - PortalFace._screen_space_y[v63]) + * (PortalFace._screen_space_x[v62] - PortalFace._screen_space_x[v63]) + - (PortalFace._screen_space_y[v62] - PortalFace._screen_space_y[v63]) + * (PortalFace._screen_space_x[v64] - PortalFace._screen_space_x[v63])) < 0 ) + { + v62 = v80; + v71 = v80; + } + else + { + v62 = v71; + v65 = v71; + if ( v71 < bottom_num_vertices || (v65 = v71 - bottom_num_vertices, v71 - bottom_num_vertices < bottom_num_vertices) ) + { + memcpy(&PortalFace._screen_space_y[v65], &PortalFace._screen_space_y[v65 + 1], + 4 * ((unsigned int)(4 * (bottom_num_vertices - v65)) >> 2)); + memcpy(&PortalFace._screen_space_x[v65], &PortalFace._screen_space_x[v65 + 1], + 4 * ((unsigned int)(4 * (bottom_num_vertices - v65)) >> 2)); + } + --bottom_num_vertices; + } + } + while ( v62 - 1 < bottom_num_vertices ); + } + PortalFace._screen_space_x[bottom_num_vertices] = PortalFace._screen_space_x[0]; + PortalFace._screen_space_y[bottom_num_vertices] = PortalFace._screen_space_y[0]; + }*/ + return bottom_num_vertices; +} + +//----- (004AAEA6) -------------------------------------------------------- +int __fastcall sub_4AAEA6_transform(RenderVertexSoft *a1) +{ + double v4; // st5@2 + double v5; // st4@3 + float v11; // [sp+8h] [bp-8h]@2 + float v12; // [sp+8h] [bp-8h]@6 + float v13; // [sp+Ch] [bp-4h]@2 + float v14; // [sp+Ch] [bp-4h]@6 + + if (pGame->pIndoorCameraD3D->sRotationX) + { + v13 = a1->vWorldPosition.x - (double)pParty->vPosition.x; + v11 = a1->vWorldPosition.y - (double)pParty->vPosition.y; + v4 = a1->vWorldPosition.z - (double)pParty->vPosition.z; + //if ( pRenderer->pRenderD3D ) + //{ + v5 = v11 * pGame->pIndoorCameraD3D->fRotationYSine + v13 * pGame->pIndoorCameraD3D->fRotationYCosine; + a1->vWorldViewPosition.y = v13 * pGame->pIndoorCameraD3D->fRotationYSine - v11 * pGame->pIndoorCameraD3D->fRotationYCosine; + /*} + else + { + v5 = v13 * pBLVRenderParams->fCosineY - v11 * pBLVRenderParams->fSineY; + a1->vWorldViewPosition.y = v13 * pBLVRenderParams->fSineY + v11 * pBLVRenderParams->fCosineY; + }*/ + a1->vWorldViewPosition.x = v5 * pGame->pIndoorCameraD3D->fRotationXCosine - v4 * pGame->pIndoorCameraD3D->fRotationXSine; + a1->vWorldViewPosition.z = v5 * pGame->pIndoorCameraD3D->fRotationXSine + v4 * pGame->pIndoorCameraD3D->fRotationXCosine; + } + else + { + v14 = a1->vWorldPosition.x - (double)pParty->vPosition.x; + v12 = a1->vWorldPosition.y - (double)pParty->vPosition.y; + a1->vWorldViewPosition.z = a1->vWorldPosition.z - (double)pParty->vPosition.z; + //if ( pRenderer->pRenderD3D ) + //{ + a1->vWorldViewPosition.x = v12 * pGame->pIndoorCameraD3D->fRotationYSine + v14 * pGame->pIndoorCameraD3D->fRotationYCosine; + a1->vWorldViewPosition.y = v14 * pGame->pIndoorCameraD3D->fRotationYSine - v12 * pGame->pIndoorCameraD3D->fRotationYCosine; + /*} + else + { + a1->vWorldViewPosition.x = v14 * pBLVRenderParams->fCosineY - v12 * pBLVRenderParams->fSineY; + a1->vWorldViewPosition.y = v14 * pBLVRenderParams->fSineY + v12 * pBLVRenderParams->fCosineY; + }*/ + } + return 0; +} +//----- (00472866) -------------------------------------------------------- +void BLV_ProcessPartyActions() +{ + int v1; // ebx@1 + int v2; // edi@1 + double v10; // st7@27 + int new_party_z; // esi@96 + int v38; // eax@96 + int v39; // ecx@106 + int v40; // eax@106 + int v42; // eax@120 + BLVFace *pFace; // esi@126 + int v46; // ecx@133 + int v52; // eax@140 + int v54; // ebx@146 + unsigned int uFaceEvent; // [sp+14h] [bp-4Ch]@1 + bool party_running_flag; // [sp+1Ch] [bp-44h]@1 + bool bFeatherFall; // [sp+24h] [bp-3Ch]@15 + unsigned int uSectorID; // [sp+28h] [bp-38h]@1 + bool party_walking_flag; // [sp+2Ch] [bp-34h]@1 + unsigned int uFaceID; // [sp+30h] [bp-30h]@1 + int v80; // [sp+34h] [bp-2Ch]@1 + int v82; // [sp+3Ch] [bp-24h]@47 + int _view_angle; // [sp+40h] [bp-20h]@47 + bool hovering; // [sp+44h] [bp-1Ch]@1 + int new_party_y; // [sp+48h] [bp-18h]@1 + int new_party_x; // [sp+4Ch] [bp-14h]@1 + int party_z; // [sp+50h] [bp-10h]@1 + int angle; // [sp+5Ch] [bp-4h]@47 + + uFaceEvent = 0; + //v89 = pParty->uFallSpeed; + v1 = 0; + v2 = 0; + new_party_x = pParty->vPosition.x; + new_party_y = pParty->vPosition.y; + party_z = pParty->vPosition.z; + uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z); + party_running_flag = false; + party_walking_flag = false; + hovering = false; + + uFaceID = -1; + int floor_level = collide_against_floor(new_party_x, new_party_y, party_z + 40, &uSectorID, &uFaceID);//получить высоту пола + + if ( pParty->bFlying )//отключить полёт + { + pParty->bFlying = false; + if (pParty->FlyActive()) + pOtherOverlayList->pOverlays[pParty->pPartyBuffs[PARTY_BUFF_FLY].uOverlayID - 1].field_E |= 1; + } + + if ( floor_level == -30000 || uFaceID == -1) + { + floor_level = collide_against_floor_approximate(new_party_x, new_party_y, party_z + 40, &uSectorID, &uFaceID); + if ( floor_level == -30000 || uFaceID == -1) + { + __debugbreak(); // level built with errors + pParty->vPosition.x = blv_prev_party_x; + pParty->vPosition.y = blv_prev_party_z; + pParty->vPosition.z = blv_prev_party_y; + pParty->uFallStartY = blv_prev_party_y; + return; + } + } + + blv_prev_party_x = pParty->vPosition.x; + blv_prev_party_z = pParty->vPosition.y; + blv_prev_party_y = pParty->vPosition.z; + if (!pParty->bTurnBasedModeOn) + { + static int dword_720CDC = 0; + + int v67 = GetTickCount() / 500; + if (dword_720CDC != v67 ) + { + dword_4F8580[3 * dword_4F8580[1]] = pParty->vPosition.x; + dword_4F8580[3 * dword_4F8580[2]] = pParty->vPosition.y; + dword_4F8580[3 * dword_4F8580[3]] = pParty->vPosition.z; + if ( dword_4F8580[0] > 60 ) + dword_4F8580[0] = 1; + + dword_720CDC = v67; + } + } + + int fall_start; + /* + if (!pParty->FeatherFallActive())// не активно падение пера + { + bFeatherFall = false; + if (!pParty->pPlayers[0].WearsItemAnyWhere(ITEM_ARTIFACT_LADYS_ESCORT) && // grants feather fall + !pParty->pPlayers[1].WearsItemAnyWhere(ITEM_ARTIFACT_LADYS_ESCORT) && + !pParty->pPlayers[2].WearsItemAnyWhere(ITEM_ARTIFACT_LADYS_ESCORT) && + !pParty->pPlayers[3].WearsItemAnyWhere(ITEM_ARTIFACT_LADYS_ESCORT)) + { + fall_start = pParty->uFallStartY; + } + else// was missing + { + fall_start = floor_level; + bFeatherFall = true; + pParty->uFallStartY = floor_level; + } + } + else// активно падение пера + { + fall_start = floor_level; + bFeatherFall = true; + pParty->uFallStartY = floor_level; + } + + Reworked condition below + */ + if (pParty->FeatherFallActive() + || pParty->pPlayers[0].WearsItemAnyWhere(ITEM_ARTIFACT_LADYS_ESCORT) + || pParty->pPlayers[1].WearsItemAnyWhere(ITEM_ARTIFACT_LADYS_ESCORT) + || pParty->pPlayers[2].WearsItemAnyWhere(ITEM_ARTIFACT_LADYS_ESCORT) + || pParty->pPlayers[3].WearsItemAnyWhere(ITEM_ARTIFACT_LADYS_ESCORT)) + { + fall_start = floor_level; + bFeatherFall = true; + pParty->uFallStartY = floor_level; + } + else + { + bFeatherFall = false; + fall_start = pParty->uFallStartY; + } + + if (fall_start - party_z > 512 && !bFeatherFall && party_z <= floor_level + 1)//повреждение от падения с высоты + { + assert(~pParty->uFlags & PARTY_FLAGS_1_LANDING); // why land in indoor? + if (pParty->uFlags & PARTY_FLAGS_1_LANDING) + pParty->uFlags &= ~PARTY_FLAGS_1_LANDING; + else for (uint i = 0; i < 4; ++i) + { // receive falling damage + if (!pParty->pPlayers[i].HasEnchantedItemEquipped(72) && !pParty->pPlayers[i].WearsItem(ITEM_ARTIFACT_HERMES_SANDALS, EQUIP_BOOTS)) + { + pParty->pPlayers[i].ReceiveDamage((pParty->uFallStartY - party_z) * (0.1f * pParty->pPlayers[i].GetMaxHealth()) / 256, DMGT_PHISYCAL); + v10 = (double)(20 - pParty->pPlayers[i].GetParameterBonus(pParty->pPlayers[i].GetActualEndurance())) * flt_6BE3A4_debug_recmod1 * 2.133333333333333; + pParty->pPlayers[i].SetRecoveryTime((signed __int64)v10); + } + } + } + + if ( party_z > floor_level + 1 ) + hovering = true; + + bool not_high_fall = false; + + if ( party_z - floor_level <= 32 ) + { + pParty->uFallStartY = party_z; + not_high_fall = true; + } + + if (bWalkSound && pParty->walk_sound_timer)//таймеры для звуков передвижения + { + if (pParty->walk_sound_timer > pEventTimer->uTimeElapsed) + pParty->walk_sound_timer -= pEventTimer->uTimeElapsed; + else pParty->walk_sound_timer = 0; + } + + if (party_z <= floor_level + 1)// группа ниже уровня пола + { + party_z = floor_level + 1; + pParty->uFallStartY = floor_level + 1; + + if (!hovering && pParty->floor_face_pid != uFaceID)// не парящие и + { + if (pIndoor->pFaces[uFaceID].uAttributes & FACE_PRESSURE_PLATE) + uFaceEvent = pIndoor->pFaceExtras[pIndoor->pFaces[uFaceID].uFaceExtraID].uEventID; + } + } + if (!hovering) + pParty->floor_face_pid = uFaceID; + + bool on_water = false; + if ( pIndoor->pFaces[uFaceID].Fluid())// на воде + on_water = true; + + //v81 = pParty->uWalkSpeed; + angle = pParty->sRotationY; + _view_angle = pParty->sRotationX; + v82 = (unsigned __int64)(pEventTimer->dt_in_some_format * (signed __int64)((signed int)(pParty->y_rotation_speed * stru_5C6E00->uIntegerPi) + / 180)) >> 16; + while ( pPartyActionQueue->uNumActions ) + { + switch ( pPartyActionQueue->Next() ) + { + case PARTY_TurnLeft: + if (uTurnSpeed) + angle = stru_5C6E00->uDoublePiMask & (angle + uTurnSpeed); + else + angle = stru_5C6E00->uDoublePiMask & (angle + (int)(v82 * fTurnSpeedMultiplier)); + break; + case PARTY_TurnRight: + if (uTurnSpeed) + angle = stru_5C6E00->uDoublePiMask & (angle - uTurnSpeed); + else + angle = stru_5C6E00->uDoublePiMask & (angle - (int)(v82 * fTurnSpeedMultiplier)); + break; + + case PARTY_FastTurnLeft: + if (uTurnSpeed) + angle = stru_5C6E00->uDoublePiMask & (angle + uTurnSpeed); + else + angle = stru_5C6E00->uDoublePiMask & (angle + (int)(2.0f * fTurnSpeedMultiplier * (double)v82)); + break; + + case PARTY_FastTurnRight: + if (uTurnSpeed) + angle = stru_5C6E00->uDoublePiMask & (angle - uTurnSpeed); + else + angle = stru_5C6E00->uDoublePiMask & (angle - (int)(2.0f * fTurnSpeedMultiplier * (double)v82)); + break; + + case PARTY_StrafeLeft: + v2 -= fixpoint_mul(stru_5C6E00->Sin(angle), pParty->uWalkSpeed * fWalkSpeedMultiplier / 2); + v1 += fixpoint_mul(stru_5C6E00->Cos(angle), pParty->uWalkSpeed * fWalkSpeedMultiplier / 2); + party_walking_flag = true; + break; + case PARTY_StrafeRight: + v2 += fixpoint_mul(stru_5C6E00->Sin(angle), pParty->uWalkSpeed * fWalkSpeedMultiplier / 2); + v1 -= fixpoint_mul(stru_5C6E00->Cos(angle), pParty->uWalkSpeed * fWalkSpeedMultiplier / 2); + party_walking_flag = true; + break; + case PARTY_WalkForward: + v2 += fixpoint_mul(stru_5C6E00->Cos(angle), 5 * pParty->uWalkSpeed * fWalkSpeedMultiplier); + v1 += fixpoint_mul(stru_5C6E00->Sin(angle), 5 * pParty->uWalkSpeed * fWalkSpeedMultiplier); + party_walking_flag = true; + break; + case PARTY_WalkBackward: + v2 -= fixpoint_mul(stru_5C6E00->Cos(angle), pParty->uWalkSpeed * fBackwardWalkSpeedMultiplier); + v1 -= fixpoint_mul(stru_5C6E00->Sin(angle), pParty->uWalkSpeed * fBackwardWalkSpeedMultiplier); + party_walking_flag = true; + break; + case PARTY_RunForward://Бег вперёд + v2 += fixpoint_mul(stru_5C6E00->Cos(angle), 2 * pParty->uWalkSpeed * fWalkSpeedMultiplier); + v1 += fixpoint_mul(stru_5C6E00->Sin(angle), 2 * pParty->uWalkSpeed * fWalkSpeedMultiplier); + party_running_flag = true; + break; + case PARTY_RunBackward: + //v32 = stru_5C6E00->SinCos(angle); + //v33 = (double)v81; + //v88 = (double)v81; + v2 -= fixpoint_mul(stru_5C6E00->Cos(angle), pParty->uWalkSpeed * fBackwardWalkSpeedMultiplier); + //v34 = stru_5C6E00->SinCos(angle - stru_5C6E00->uIntegerHalfPi); + v1 -= fixpoint_mul(stru_5C6E00->Sin(angle), pParty->uWalkSpeed * fBackwardWalkSpeedMultiplier); + party_running_flag = true; + break; + case PARTY_LookUp: + _view_angle += (signed __int64)(flt_6BE150_look_up_down_dangle * 25.0); + if ( _view_angle > 128 ) + _view_angle = 128; + if ( uActiveCharacter ) + pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)SPEECH_63, 0); + break; + case PARTY_LookDown: + _view_angle += (signed __int64)(flt_6BE150_look_up_down_dangle * -25.0); + if ( _view_angle < -128 ) + _view_angle = -128; + if ( uActiveCharacter ) + pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)SPEECH_64, 0); + break; + case PARTY_CenterView: + _view_angle = 0; + break; + case PARTY_Jump: + if ( (!hovering || party_z <= floor_level + 6 && pParty->uFallSpeed <= 0) && pParty->field_24 ) + { + hovering = true; + pParty->uFallSpeed = (signed __int64)((double)(pParty->field_24 << 6) * 1.5 + (double)pParty->uFallSpeed); + } + break; + default: + break; + } + } + pParty->sRotationY = angle; + pParty->sRotationX = _view_angle; + if ( hovering )//парящие + { + pParty->uFallSpeed += -2 * pEventTimer->uTimeElapsed * GetGravityStrength();// расчёт скорости падения + if ( hovering && pParty->uFallSpeed <= 0 ) + { + if ( pParty->uFallSpeed < -500 && !pParty->bFlying ) + { + for ( uint pl = 1; pl <= 4; pl++ ) + { + if ( !pPlayers[pl]->HasEnchantedItemEquipped(72) && !pPlayers[pl]->WearsItem(ITEM_ARTIFACT_HERMES_SANDALS, EQUIP_BOOTS) ) //was 8 + pPlayers[pl]->PlayEmotion(CHARACTER_EXPRESSION_SCARED, 0); + } + } + } + else + pParty->uFallStartY = party_z; + } + else// не парящие + { + if ( pIndoor->pFaces[uFaceID].pFacePlane_old.vNormal.z < 0x8000 ) + { + pParty->uFallSpeed -= pEventTimer->uTimeElapsed * GetGravityStrength(); + pParty->uFallStartY = party_z; + } + else + { + if (! (pParty->uFlags & PARTY_FLAGS_1_LANDING) ) + pParty->uFallSpeed = 0; + pParty->uFallStartY = party_z; + } + } + if ( v2 * v2 + v1 * v1 < 400 ) + { + v1 = 0; + v2 = 0; + } + + stru_721530.field_84 = -1; + stru_721530.field_70 = 0; + stru_721530.prolly_normal_d = pParty->field_14_radius; + stru_721530.field_8_radius = pParty->field_14_radius / 2; + stru_721530.field_0 = 1; + stru_721530.height = pParty->uPartyHeight - 32; + for ( uint i = 0; i < 100; i++ ) + { + new_party_z = party_z; + stru_721530.position.x = new_party_x; + stru_721530.position.y = new_party_y; + stru_721530.position.z = stru_721530.height + party_z + 1; + + stru_721530.normal.x = new_party_x; + stru_721530.normal.y = new_party_y; + stru_721530.normal.z = stru_721530.prolly_normal_d + party_z + 1; + + stru_721530.velocity.x = v2; + stru_721530.velocity.y = v1; + stru_721530.velocity.z = pParty->uFallSpeed; + + stru_721530.uSectorID = uSectorID; + v38 = 0; + if ( pParty->bTurnBasedModeOn == true && pTurnEngine->turn_stage == TE_MOVEMENT ) + v38 = 13312; + if ( stru_721530._47050A(v38) ) + break; + for ( uint j = 0; j < 100; ++j ) + { + _46E44E_collide_against_faces_and_portals(1); + _46E0B2_collide_against_decorations();//столкновения с декором + for ( v80 = 0; v80 < (signed int)uNumActors; ++v80 ) + Actor::_46DF1A_collide_against_actor(v80, 0);//столкновения с монстрами + if ( _46F04E_collide_against_portals() )//столкновения с порталами + break; + } + if ( stru_721530.field_7C >= stru_721530.field_6C ) + { + v39 = stru_721530.normal2.x; + uSectorID = stru_721530.normal2.y; + v40 = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1; + } + else + { + v39 = new_party_x + fixpoint_mul(stru_721530.field_7C, stru_721530.direction.x); + uSectorID = new_party_y + fixpoint_mul(stru_721530.field_7C, stru_721530.direction.y); + v40 = new_party_z + fixpoint_mul(stru_721530.field_7C, stru_721530.direction.z); + } + v42 = collide_against_floor(v39, uSectorID, v40 + 40, &stru_721530.uSectorID, &uFaceID); + if ( v42 == -30000 || v42 - new_party_z > 128 ) + return; + if ( stru_721530.field_7C >= stru_721530.field_6C )//??? + { + new_party_x = stru_721530.normal2.x; + new_party_y = stru_721530.normal2.y; + new_party_z = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1; + break; + } + new_party_x += fixpoint_mul(stru_721530.field_7C, stru_721530.direction.x); + new_party_y += fixpoint_mul(stru_721530.field_7C, stru_721530.direction.y); + uSectorID = stru_721530.uSectorID; + stru_721530.field_70 += stru_721530.field_7C; + unsigned long long v87 = new_party_z + fixpoint_mul(stru_721530.field_7C, stru_721530.direction.z); + if ( PID_TYPE(stru_721530.uFaceID) == OBJECT_Actor)//при столкновении с монстром + { + if ( pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime > 0 ) + pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].Reset(); + viewparams->bRedrawGameUI = true; + } + else if ( PID_TYPE(stru_721530.uFaceID) == OBJECT_Decoration)//при столкновении с декорацией + { + v54 = stru_5C6E00->Atan2(new_party_x - pLevelDecorations[stru_721530.uFaceID >> 3].vPosition.x, + new_party_y - pLevelDecorations[stru_721530.uFaceID >> 3].vPosition.y); + v2 = fixpoint_mul(stru_5C6E00->Cos(v54), integer_sqrt(v2 * v2 + v1 * v1)); + v1 = fixpoint_mul(stru_5C6E00->Sin(v54), integer_sqrt(v2 * v2 + v1 * v1)); + } + else if ( PID_TYPE(stru_721530.uFaceID) == OBJECT_BModel)//при столкновении с bmodel + { + pFace = &pIndoor->pFaces[(signed int)stru_721530.uFaceID >> 3]; + if ( pFace->uPolygonType == POLYGON_Floor )// если bmodel - пол + { + if ( pParty->uFallSpeed < 0 ) + pParty->uFallSpeed = 0; + v87 = pIndoor->pVertices[*pFace->pVertexIDs].z + 1; + if ( pParty->uFallStartY - v87 < 512 ) + pParty->uFallStartY = v87; + if ( v2 * v2 + v1 * v1 < 400 ) + { + v1 = 0; + v2 = 0; + } + if ( pParty->floor_face_pid != PID_ID(stru_721530.uFaceID) && pFace->Pressure_Plate() ) + uFaceEvent = pIndoor->pFaceExtras[pFace->uFaceExtraID].uEventID; + } + else// если не пол + { + v46 = pParty->uFallSpeed * pFace->pFacePlane_old.vNormal.z; + if ( pFace->uPolygonType != POLYGON_InBetweenFloorAndWall )//полез на холм + { + v80 = abs(v1 * pFace->pFacePlane_old.vNormal.y + v46 + v2 * pFace->pFacePlane_old.vNormal.x) >> 16; + if ((stru_721530.speed >> 3) > v80 ) + v80 = stru_721530.speed >> 3; + v2 += fixpoint_mul(v80, pFace->pFacePlane_old.vNormal.x); + v1 += fixpoint_mul(v80, pFace->pFacePlane_old.vNormal.y); + pParty->uFallSpeed += fixpoint_mul(v80, pFace->pFacePlane_old.vNormal.z); + //v80 = pFace->pFacePlane_old.vNormal.y; + v52 = stru_721530.prolly_normal_d - ((pFace->pFacePlane_old.dist + + v87 * pFace->pFacePlane_old.vNormal.z + + new_party_y * pFace->pFacePlane_old.vNormal.y + + new_party_x * pFace->pFacePlane_old.vNormal.x) >> 16); + if ( v52 > 0 ) + { + new_party_x += fixpoint_mul(v52, pFace->pFacePlane_old.vNormal.x); + new_party_y += fixpoint_mul(v52, pFace->pFacePlane_old.vNormal.y); + v87 += fixpoint_mul(v52, pFace->pFacePlane_old.vNormal.z); + } + if ( pParty->floor_face_pid != PID_ID(stru_721530.uFaceID) && pFace->Pressure_Plate() ) + uFaceEvent = pIndoor->pFaceExtras[pFace->uFaceExtraID].uEventID; + } + if ( pFace->uPolygonType == POLYGON_InBetweenFloorAndWall ) + { + v80 = abs(v1 * pFace->pFacePlane_old.vNormal.y + v46 + v2 * pFace->pFacePlane_old.vNormal.x) >> 16; + if ((stru_721530.speed >> 3) > v80 ) + v80 = stru_721530.speed >> 3; + v2 += fixpoint_mul(v80, pFace->pFacePlane_old.vNormal.x); + v1 += fixpoint_mul(v80, pFace->pFacePlane_old.vNormal.y); + pParty->uFallSpeed += fixpoint_mul(v80, pFace->pFacePlane_old.vNormal.z); + if ( v2 * v2 + v1 * v1 >= 400 ) + { + if ( pParty->floor_face_pid != PID_ID(stru_721530.uFaceID) && pFace->Pressure_Plate() ) + uFaceEvent = pIndoor->pFaceExtras[pFace->uFaceExtraID].uEventID; + } + else + { + v2 = 0; + v1 = 0; + pParty->uFallSpeed = 0; + } + } + } + } + v2 = fixpoint_mul(58500, v2); + v1 = fixpoint_mul(58500, v1); + pParty->uFallSpeed = fixpoint_mul(58500, pParty->uFallSpeed); + } + + // //Воспроизведение звуков ходьбы/бега------------------------- + uint pX_ = abs(pParty->vPosition.x - new_party_x); + uint pY_ = abs(pParty->vPosition.y - new_party_y); + uint pZ_ = abs(pParty->vPosition.z - new_party_z); + if ( bWalkSound && pParty->walk_sound_timer <= 0 ) + { + pAudioPlayer->_4AA258(804);//stop sound + if ( party_running_flag && (!hovering || not_high_fall) ) //Бег и (не прыжок или не высокое падение ) + { + if ( integer_sqrt(pX_ * pX_ + pY_ * pY_ + pZ_ * pZ_) >= 16 ) + { + if ( on_water ) + pAudioPlayer->PlaySound(SOUND_RunAlongWater, 804, 1, -1, 0, 0, 0, 0); + else if ( pIndoor->pFaces[uFaceID].uAttributes & FACE_INDOOR_CARPET )//по ковру + pAudioPlayer->PlaySound((SoundID)50, 804, 1, -1, 0, 0, 0, 0); + else + pAudioPlayer->PlaySound(SOUND_RunAlong3DModel, 804, 1, -1, 0, 0, 0, 0); + pParty->walk_sound_timer = 96;//64 + } + } + else if ( party_walking_flag && (!hovering || not_high_fall) )//Ходьба и (не прыжок или не высокое падение) + { + if ( integer_sqrt(pX_ * pX_ + pY_ * pY_ + pZ_ * pZ_) >= 8 ) + { + if ( on_water ) + pAudioPlayer->PlaySound(SOUND_WalkAlongWater, 804, 1, -1, 0, 0, 0, 0); + else if ( pIndoor->pFaces[uFaceID].uAttributes & FACE_INDOOR_CARPET )//по ковру + pAudioPlayer->PlaySound((SoundID)89, 804, 1, -1, 0, 0, 0, 0); + else + pAudioPlayer->PlaySound(SOUND_WalkAlong3DModel, 804, 1, -1, 0, 0, 0, 0); + pParty->walk_sound_timer = 144;//64 + } + } + } + if ( integer_sqrt(pX_ * pX_ + pY_ * pY_ + pZ_ * pZ_) < 8 )//отключить звук ходьбы при остановке + pAudioPlayer->_4AA258(804); + //------------------------------------------------------------- + if ( !hovering || !not_high_fall ) + pParty->uFlags &= ~PARTY_FLAGS_1_FALLING; + else + pParty->uFlags |= PARTY_FLAGS_1_FALLING; + pParty->uFlags &= ~PARTY_FLAGS_1_BURNING; + pParty->vPosition.x = new_party_x; + pParty->vPosition.z = new_party_z; + pParty->vPosition.y = new_party_y; + //pParty->uFallSpeed = v89; + if ( !hovering && pIndoor->pFaces[uFaceID].uAttributes & FACE_INDOOR_LAVA ) + pParty->uFlags |= PARTY_FLAGS_1_BURNING;//0x200 + if (uFaceEvent) + EventProcessor(uFaceEvent, 0, 1); +} + +//----- (00449A49) -------------------------------------------------------- +void Door_switch_animation(unsigned int uDoorID, int a2) +{ + int old_state; // eax@1 + signed int door_id; // esi@2 + + if ( !pIndoor->pDoors ) + return; + for ( door_id = 0; door_id < 200; ++door_id ) + { + if ( pIndoor->pDoors[door_id].uDoorID == uDoorID ) + break; + } + if ( door_id >= 200 ) + { + Error("Unable to find Door ID: %i!", uDoorID); + } + old_state = pIndoor->pDoors[door_id].uState; + //old_state: 0 - в нижнем положении/закрыто + // 2 - в верхнем положении/открыто, + //a2: 1 - открыть + // 2 - опустить/поднять + if ( a2 == 2 ) + { + if ( pIndoor->pDoors[door_id].uState == BLVDoor::Closing || pIndoor->pDoors[door_id].uState == BLVDoor::Opening ) + return; + if ( pIndoor->pDoors[door_id].uState ) + { + if ( pIndoor->pDoors[door_id].uState != BLVDoor::Closed && pIndoor->pDoors[door_id].uState != BLVDoor::Closing ) + { + pIndoor->pDoors[door_id].uState = BLVDoor::Closing; + if ( old_state == BLVDoor::Open ) + { + pIndoor->pDoors[door_id].uTimeSinceTriggered = 0; + return; + } + if ( pIndoor->pDoors[door_id].uTimeSinceTriggered != 15360 ) + { + pIndoor->pDoors[door_id].uTimeSinceTriggered = (pIndoor->pDoors[door_id].uMoveLength << 7) / pIndoor->pDoors[door_id].uOpenSpeed + - ((signed int)(pIndoor->pDoors[door_id].uTimeSinceTriggered * pIndoor->pDoors[door_id].uCloseSpeed) + / 128 << 7) / pIndoor->pDoors[door_id].uOpenSpeed; + return; + } + pIndoor->pDoors[door_id].uTimeSinceTriggered = 15360; + } + return; + } + } + else + { + if ( a2 == 0 ) + { + if ( pIndoor->pDoors[door_id].uState != BLVDoor::Closed && pIndoor->pDoors[door_id].uState != BLVDoor::Closing ) + { + pIndoor->pDoors[door_id].uState = BLVDoor::Closing; + if ( old_state == BLVDoor::Open ) + { + pIndoor->pDoors[door_id].uTimeSinceTriggered = 0; + return; + } + if ( pIndoor->pDoors[door_id].uTimeSinceTriggered != 15360 ) + { + pIndoor->pDoors[door_id].uTimeSinceTriggered = (pIndoor->pDoors[door_id].uMoveLength << 7) / pIndoor->pDoors[door_id].uOpenSpeed + - ((signed int)(pIndoor->pDoors[door_id].uTimeSinceTriggered * pIndoor->pDoors[door_id].uCloseSpeed) + / 128 << 7) / pIndoor->pDoors[door_id].uOpenSpeed; + return; + } + pIndoor->pDoors[door_id].uTimeSinceTriggered = 15360; + } + return; + } + if ( a2 != 1 ) + return; + } + if ( old_state != BLVDoor::Open && old_state != BLVDoor::Opening ) + { + pIndoor->pDoors[door_id].uState = BLVDoor::Opening; + if ( old_state == BLVDoor::Closed ) + { + pIndoor->pDoors[door_id].uTimeSinceTriggered = 0; + return; + } + if ( pIndoor->pDoors[door_id].uTimeSinceTriggered != 15360 ) + { + pIndoor->pDoors[door_id].uTimeSinceTriggered = (pIndoor->pDoors[door_id].uMoveLength << 7) / pIndoor->pDoors[door_id].uCloseSpeed + - ((signed int)(pIndoor->pDoors[door_id].uTimeSinceTriggered * pIndoor->pDoors[door_id].uOpenSpeed) + / 128 << 7) / pIndoor->pDoors[door_id].uCloseSpeed; + return; + } + pIndoor->pDoors[door_id].uTimeSinceTriggered = 15360; + } + return; +} + + +//----- (004088E9) -------------------------------------------------------- +int __fastcall sub_4088E9(int x1, int y1, int x2, int y2, int x3, int y3) +{ + signed int result; // eax@1 + + result = integer_sqrt(abs(x2 - x1) * abs(x2 - x1) + abs(y2 - y1) * abs(y2 - y1)); + if ( result ) + result = abs(((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / result); + return result; +} + +//----- (00450DA3) -------------------------------------------------------- +int GetAlertStatus() +{ + int result; // eax@2 + + if ( uCurrentlyLoadedLevelType == LEVEL_Indoor ) + result = pOutdoor->ddm.field_C_alert; + else + result = uCurrentlyLoadedLevelType == LEVEL_Outdoor ? pIndoor->dlv.field_C_alert : 0; + return result; +} + + +//----- (0045063B) -------------------------------------------------------- +int __fastcall _45063B_spawn_some_monster(MapInfo *a1, int a2) +{ + int result; // eax@8 + int v6; // edi@11 + int v7; // ebx@11 + int v8; // edi@11 + int v9; // ebx@12 + int v10; // eax@12 + char v11; // zf@16 + int v12; // edi@20 + int v13; // eax@20 + int v14; // ebx@20 + int v15; // eax@20 + int v16; // eax@20 + int v17; // eax@20 + int v18; // eax@21 + SpawnPointMM7 v19; // [sp+Ch] [bp-38h]@1 + int v22; // [sp+2Ch] [bp-18h]@3 + unsigned int uFaceID; // [sp+38h] [bp-Ch]@10 + int v26; // [sp+3Ch] [bp-8h]@11 + int v27; // [sp+40h] [bp-4h]@11 + + if (!uNumActors) + return 0; + + for ( uint mon_id = 0; mon_id < uNumActors; ++mon_id ) + { + if ((pActors[mon_id].pMonsterInfo.uID < 121 || pActors[mon_id].pMonsterInfo.uID > 123) && // Dwarf FemaleC A-C + (pActors[mon_id].pMonsterInfo.uID < 124 || pActors[mon_id].pMonsterInfo.uID > 126) && // Dwarf MaleA A-C + (pActors[mon_id].pMonsterInfo.uID < 133 || pActors[mon_id].pMonsterInfo.uID > 135) && // Peasant Elf FemaleA A-C + pActors[mon_id].CanAct()) + { + if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor ) + { + v22 = 0; + uint face_id = 0; + for ( face_id; face_id < 100; ++face_id ) + { + v6 = rand() % 1024 + 512; + v7 = rand() % (signed int)stru_5C6E00->uIntegerDoublePi; + v19.vPosition.x = pParty->vPosition.x + fixpoint_mul(stru_5C6E00->Cos(v7), v6); + v8 = 0; + v19.uIndex = a2; + v19.vPosition.y = fixpoint_mul(stru_5C6E00->Sin(v7), v6) + pParty->vPosition.y; + v19.vPosition.z = pParty->vPosition.z; + v26 = 0; + v27 = 0; + v19.vPosition.z = ODM_GetFloorLevel(v19.vPosition.x, v19.vPosition.y, pParty->vPosition.z, 0, &v26, &v27, 0); + for( int i = 0; i < pOutdoor->uNumBModels; i++ ) + { + v9 = abs(v19.vPosition.y - pOutdoor->pBModels[i].vBoundingCenter.y); + v10 = abs(v19.vPosition.x - pOutdoor->pBModels[i].vBoundingCenter.x); + if ( int_get_vector_length(v10, v9, 0) < pOutdoor->pBModels[i].sBoundingRadius + 256 ) + { + v22 = 1; + break; + } + } + if ( v22 ) + { + v11 = face_id == 100; + break; + } + } + v11 = face_id == 100; + } + else if ( uCurrentlyLoadedLevelType == LEVEL_Indoor ) + { + v22 = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z); + for ( uint i = 0; i < 100; ++i ) + { + v12 = rand() % 512 + 256; + v13 = rand(); + v14 = v13 % (signed int)stru_5C6E00->uIntegerDoublePi; + v15 = stru_5C6E00->Cos(v13 % (signed int)stru_5C6E00->uIntegerDoublePi); + v19.vPosition.x = pParty->vPosition.x + fixpoint_mul(v15, v12); + v16 = stru_5C6E00->Sin(v13 % (signed int)stru_5C6E00->uIntegerDoublePi); + v19.vPosition.y = fixpoint_mul(v16, v12) + pParty->vPosition.y; + v19.vPosition.z = pParty->vPosition.z; + v19.uIndex = a2; + v17 = pIndoor->GetSector(v19.vPosition.x, v19.vPosition.y, pParty->vPosition.z); + if ( v17 == v22 ) + { + v18 = BLV_GetFloorLevel(v19.vPosition.x, v19.vPosition.y, v19.vPosition.z, v17, &uFaceID); + v19.vPosition.z = v18; + if ( v18 != -30000 ) + { + if ( abs(v18 - pParty->vPosition.z) <= 1024 ) + break; + } + } + } + v11 = v26 == 100; + } + if ( v11 ) + result = 0; + else + { + SpawnEncounter(a1, &v19, 0, 0, 1); + result = a2; + } + } + + //break; + //v22 = v3->pMonsterInfo.uID - 1; + //v4 = (signed __int64)((double)v22 * 0.3333333333333333); + //if ( (int)v4 != 40 ) + //{ + // if ( (int)v4 != 41 && (int)v4 != 44 && v3->CanAct() ) + // break; + //} + //++v2; + //++v3; + //if ( v2 >= (signed int)uNumActors ) + // goto LABEL_8; + } + return result; +} + +//----- (00450521) -------------------------------------------------------- +int __fastcall sub_450521_ProllyDropItemAt(int ecx0, signed int a2, int a3, int a4, int a5, unsigned __int16 a6) +{ + int v6; // edi@1 + int v7; // esi@1 + signed int v8; // edi@1 + unsigned __int16 v9; // cx@1 + // char *v10; // edx@2 + unsigned __int16 v11; // ax@5 + SpriteObject a1; // [sp+8h] [bp-70h]@1 + + v6 = ecx0; + v7 = a2; + pItemsTable->GenerateItem(v6, v7, &a1.stru_24); + v8 = 0; + v9 = pItemsTable->pItems[a1.stru_24.uItemID].uSpriteID; + a1.uType = pItemsTable->pItems[a1.stru_24.uItemID].uSpriteID; + v11 = 0; + for( int i = 0; i < pObjectList->uNumObjects; i++ ) + { + if( v9 == pObjectList->pObjects[i].uObjectID ) + { + v11 = i; + break; + } + } + a1.uObjectDescID = v11; + a1.vPosition.y = a4; + a1.vPosition.x = a3; + a1.vPosition.z = a5; + a1.uFacing = a6; + a1.uAttributes = 0; + a1.uSectorID = pIndoor->GetSector(a3, a4, a5); + a1.uSpriteFrameID = 0; + return a1.Create(0, 0, 0, 0); +} + +//----- (004075DB) -------------------------------------------------------- +bool __fastcall sub_4075DB(int x, int y, int z, BLVFace *face) +{ + int v8; // edi@2 + signed int v25; // eax@22 + bool result; // eax@25 + signed int a3a; // [sp+24h] [bp+8h]@14 + int a4a; // [sp+28h] [bp+Ch]@2 + + std::array dword_4F5CC8_ys; // idb + std::array dword_4F5D98_xs; // idb + + //__debugbreak(); + + if (face->uAttributes & FACE_XY_PLANE) + { + a4a = x; + v8 = y; + for (int i = 0; i < face->uNumVertices; i++) + { + dword_4F5D98_xs[i] = pIndoor->pVertices[face->pVertexIDs[i]].x; + dword_4F5CC8_ys[i] = pIndoor->pVertices[face->pVertexIDs[i]].y; + } + } + else + { + v8 = z; + if (face->uAttributes & FACE_XZ_PLANE) + { + a4a = x; + for (int i = 0; i < face->uNumVertices; i++) + { + dword_4F5D98_xs[i] = pIndoor->pVertices[face->pVertexIDs[i]].x; + dword_4F5CC8_ys[i] = pIndoor->pVertices[face->pVertexIDs[i]].z; + } + } + else + { + a4a = y; + for (int i = 0; i < face->uNumVertices; i++) + { + dword_4F5D98_xs[i] = pIndoor->pVertices[face->pVertexIDs[i]].y; + dword_4F5CC8_ys[i] = pIndoor->pVertices[face->pVertexIDs[i]].z; + } + } + } + a3a = 0; + dword_4F5D98_xs[face->uNumVertices] = dword_4F5D98_xs[0]; + dword_4F5CC8_ys[face->uNumVertices] = dword_4F5CC8_ys[0]; + for (int i = 0; i < face->uNumVertices && a3a < 2; i++) + { + if (dword_4F5CC8_ys[i] >= v8 ^ (dword_4F5CC8_ys[i + 1] >= v8)) + { + //if( dword_4F5D98_xs[i + 1] >= a4a || dword_4F5D98_xs[i] >= a4a) + if (!(dword_4F5D98_xs[i + 1] >= a4a && dword_4F5D98_xs[i] < a4a)) + { + if ((dword_4F5D98_xs[i + 1] < a4a && dword_4F5D98_xs[i] >= a4a)) + ++a3a; + //|| (v25 = dword_4F5D98_xs[i + 1] - dword_4F5D98_xs[i],LODWORD(v26) = v25 << 16, HIDWORD(v26) = v25 >> 16, + //dword_4F5D98_xs[i] + ((signed int)(((unsigned __int64)(v26 / (dword_4F5CC4_ys[i + 2] - dword_4F5CC4_ys[i + 1])* ((v8 - dword_4F5CC4_ys[i + 1]) << 16)) >> 16) + // + 32768) >> 16) >= a4a) ) + else + { + v25 = fixpoint_div(dword_4F5D98_xs[i + 1] - dword_4F5D98_xs[i], dword_4F5CC8_ys[i + 1] - dword_4F5CC8_ys[i]); + if (dword_4F5D98_xs[i] + (fixpoint_mul(v25, (v8 - dword_4F5CC8_ys[i]) << 16) + 0x8000 >> 16) >= a4a) + ++a3a; + } + } + } + } + result = 1; + if (a3a != 1) + result = 0; + return result; +} + +//----- (004077F1) -------------------------------------------------------- +bool __fastcall sub_4077F1(int a1, int a2, int a3, ODMFace *face, BSPVertexBuffer *a5) +{ + int a4a; // [sp+28h] [bp+Ch]@2 + signed int a5a; // [sp+2Ch] [bp+10h]@14 + + std::array dword_4F5B24_ys; // idb + std::array dword_4F5BF4_xs; // idb + + //__debugbreak(); //срабатывает при нападении стрекозавров с огнём + + if (face->uAttributes & FACE_XY_PLANE) + { + a4a = a1; + a3 = a2; + for (int i = 0; i < face->uNumVertices; i++) + { + dword_4F5BF4_xs[i + 1] = a5->pVertices[face->pVertexIDs[i]].x; + dword_4F5B24_ys[i + 1] = a5->pVertices[face->pVertexIDs[i]].y; + } + } + else + { + if (face->uAttributes & FACE_XY_PLANE) + { + a4a = a1; + for (int i = 0; i < face->uNumVertices; i++) + { + dword_4F5BF4_xs[i + 1] = a5->pVertices[face->pVertexIDs[i]].x; + dword_4F5B24_ys[i + 1] = a5->pVertices[face->pVertexIDs[i]].z; + } + } + else + { + a4a = a2; + for (int i = 0; i < face->uNumVertices; i++) + { + dword_4F5BF4_xs[i + 1] = a5->pVertices[face->pVertexIDs[i]].y; + dword_4F5B24_ys[i + 1] = a5->pVertices[face->pVertexIDs[i]].z; + } + } + } + a5a = 0; + dword_4F5BF4_xs[face->uNumVertices + 1] = dword_4F5BF4_xs[1]; + dword_4F5B24_ys[face->uNumVertices + 1] = dword_4F5B24_ys[1]; + for (int i = 0; i < face->uNumVertices; i++) + { + if (a5a >= 2) + break; + if (dword_4F5B24_ys[i + 1] >= a3 ^ (dword_4F5B24_ys[i + 2] >= a3)) + { + if (dword_4F5BF4_xs[i + 2] >= a4a || dword_4F5BF4_xs[i] >= a4a) + { + if (dword_4F5BF4_xs[i + 2] >= a4a && dword_4F5BF4_xs[i + 1] >= a4a) + ++a5a; + else + { + //v23 = (__int64)(dword_4F5BF4_xs[i + 2] - dword_4F5BF4_xs[i + 1]) << 16; + __int64 _a = dword_4F5B24_ys[i + 2] - dword_4F5B24_ys[i + 1]; + __int64 _b = (__int64)(a3 - dword_4F5B24_ys[i + 1]) << 16; + + if (dword_4F5BF4_xs[i + 1] + ((((((__int64)(dword_4F5BF4_xs[i + 2] - dword_4F5BF4_xs[i + 1]) << 16) / _a * _b) >> 16) + 0x8000) >> 16) >= a4a) + ++a5a; + } + } + } + } + + if (a5a != 1) + return false; + return true; + +} + +//----- (0049B04D) -------------------------------------------------------- +void stru154::GetFacePlaneAndClassify(ODMFace *a2, BSPVertexBuffer *a3) +{ + Vec3_float_ v; // [sp+4h] [bp-Ch]@1 + float v7; + + v.x = 0.0; + v.y = 0.0; + v.z = 0.0; + GetFacePlane(a2, a3, &v, &v7); + + if (fabsf(a2->pFacePlane.vNormal.z) < 1e-6f) + polygonType = POLYGON_VerticalWall; + else if (fabsf(a2->pFacePlane.vNormal.x) < 1e-6f && + fabsf(a2->pFacePlane.vNormal.y) < 1e-6f) + polygonType = POLYGON_Floor; + else + polygonType = POLYGON_InBetweenFloorAndWall; + + face_plane.vNormal.x = v.x; + face_plane.vNormal.y = v.y; + face_plane.vNormal.z = v.z; + face_plane.dist = v7; +} + +//----- (0049B0C9) -------------------------------------------------------- +void stru154::ClassifyPolygon(Vec3_float_ *pNormal, float dist) +{ + if (fabsf(pNormal->z) < 1e-6f) + polygonType = POLYGON_VerticalWall; + else if (fabsf(pNormal->x) < 1e-6f && + fabsf(pNormal->y) < 1e-6f) + polygonType = POLYGON_Floor; + else + polygonType = POLYGON_InBetweenFloorAndWall; + + face_plane.vNormal.x = pNormal->x; + face_plane.dist = dist; + face_plane.vNormal.y = pNormal->y; + face_plane.vNormal.z = pNormal->z; +} + +//----- (0049B13D) -------------------------------------------------------- +void stru154::GetFacePlane(ODMFace *pFace, BSPVertexBuffer *pVertices, Vec3_float_ *pOutNormal, float *pOutDist) +{ + Vec3_float_ *v19; // eax@3 + Vec3_float_ v2; // [sp+4h] [bp-64h]@3 + float v26; // [sp+1Ch] [bp-4Ch]@3 + float v27; // [sp+20h] [bp-48h]@3 + float v28; // [sp+24h] [bp-44h]@3 + Vec3_float_ v1; // [sp+40h] [bp-28h]@1 + Vec3_float_ v38; // [sp+58h] [bp-10h]@3 + + v1.x = 0.0; + v1.y = 0.0; + v1.z = 0.0; + + if (pFace->uNumVertices >= 2) + { + for (int i = 0; i < pFace->uNumVertices - 2; i++) + { + v1.x = pVertices->pVertices[pFace->pVertexIDs[i + 1]].x - pVertices->pVertices[pFace->pVertexIDs[i]].x; + v1.y = pVertices->pVertices[pFace->pVertexIDs[i + 1]].y - pVertices->pVertices[pFace->pVertexIDs[i]].y; + v1.z = pVertices->pVertices[pFace->pVertexIDs[i + 1]].z - pVertices->pVertices[pFace->pVertexIDs[i]].z; + + v26 = pVertices->pVertices[pFace->pVertexIDs[i + 2]].x - pVertices->pVertices[pFace->pVertexIDs[i + 1]].x; + v27 = pVertices->pVertices[pFace->pVertexIDs[i + 2]].y - pVertices->pVertices[pFace->pVertexIDs[i + 1]].y; + v28 = pVertices->pVertices[pFace->pVertexIDs[i + 2]].z - pVertices->pVertices[pFace->pVertexIDs[i + 1]].z; + + v19 = Vec3_float_::Cross(&v1, &v2, v26, v27, v28); + v38.x = v19->x; + v38.y = v19->y; + v38.z = v19->z; + if (v38.x != 0.0 || v38.y != 0.0 || v38.z != 0.0) + { + v38.Normalize(); + + pOutNormal->x = v38.x; + pOutNormal->y = v38.y; + pOutNormal->z = v38.z; + + *pOutDist = -(pVertices->pVertices[pFace->pVertexIDs[i]].x * v38.x + + pVertices->pVertices[pFace->pVertexIDs[i]].y * v38.y + + pVertices->pVertices[pFace->pVertexIDs[i]].z * v38.z); + return; + } + } + } + + pOutNormal->x = (double)(pFace->pFacePlane.vNormal.x & 0xFFFF) / 65535.0f + (double)(pFace->pFacePlane.vNormal.x >> 16); + pOutNormal->y = (double)(pFace->pFacePlane.vNormal.y & 0xFFFF) / 65535.0f + (double)(pFace->pFacePlane.vNormal.y >> 16); + pOutNormal->z = (double)(pFace->pFacePlane.vNormal.z & 0xFFFF) / 65535.0f + (double)(pFace->pFacePlane.vNormal.z >> 16); + *pOutDist = (double)(pFace->pFacePlane.dist & 0xFFFF) / 65535.0f + (double)(pFace->pFacePlane.dist >> 16); +} + +//----- (0043F515) -------------------------------------------------------- +void FindBillboardsLightLevels_BLV() +{ + for (uint i = 0; i < uNumBillboardsToDraw; ++i) + { + if (pBillboardRenderList[i].field_1E & 2 || uCurrentlyLoadedLevelType == LEVEL_Indoor && !pBillboardRenderList[i].uIndoorSectorID) + pBillboardRenderList[i].dimming_level = 0; + else + pBillboardRenderList[i].dimming_level = _43F55F_get_billboard_light_level(&pBillboardRenderList[i], -1); + } +} + +//----- (0047272C) -------------------------------------------------------- +int collide_against_floor_approximate(int x, int y, int z, unsigned int *pSectorID, unsigned int *pFaceID) +{ + int result; // eax@1 + + *pSectorID = pIndoor->GetSector(x - 2, y, z + 40); + result = collide_against_floor(x - 2, y, z + 40, pSectorID, pFaceID); + if (result == -30000 || !*pSectorID) + { + *pSectorID = pIndoor->GetSector(x + 2, y, z + 40); + result = collide_against_floor(x + 2, y, z + 40, pSectorID, pFaceID); + if (result == -30000 || !*pSectorID) + { + *pSectorID = pIndoor->GetSector(x, y - 2, z + 40); + result = collide_against_floor(x, y - 2, z + 40, pSectorID, pFaceID); + if (result == -30000 || !*pSectorID) + { + *pSectorID = pIndoor->GetSector(x, y + 2, z + 40); + result = collide_against_floor(x, y + 2, z + 40, pSectorID, pFaceID); + if (result == -30000 || !*pSectorID) + { + *pSectorID = pIndoor->GetSector(x, y, z + 140); + result = collide_against_floor(x, y, z + 140, pSectorID, pFaceID); + } + } + } + } + return result; +} + +//----- (0047050A) -------------------------------------------------------- +int stru141_actor_collision_object::_47050A(int dt) +{ + int v7; // eax@1 + signed int result; // eax@4 + int v17; // eax@5 + int v18; // eax@7 + int v21; // eax@9 + int v22; // eax@11 + + int speed = 1 | integer_sqrt(this->velocity.z * this->velocity.z + this->velocity.y * this->velocity.y + this->velocity.x * this->velocity.x); + + this->direction.x = 65536 / speed * this->velocity.x; + this->direction.y = 65536 / speed * this->velocity.y; + this->direction.z = 65536 / speed * this->velocity.z; + + this->speed = speed; + this->inv_speed = 65536 / speed; + + if (dt) + v7 = dt; + else + v7 = pEventTimer->dt_in_some_format; + + //v8 = fixpoint_mul(v7, speed) - this->field_70; // speed * dt - something + this->field_6C = fixpoint_mul(v7, speed) - this->field_70; + if (this->field_6C > 0) + { + //v10 = fixpoint_mul(v8, this->direction.x) + this->normal.x; + this->field_4C = fixpoint_mul(this->field_6C, this->direction.x) + this->normal.x; + this->normal2.x = fixpoint_mul(this->field_6C, this->direction.x) + this->normal.x; + //v11 = fixpoint_mul(this->field_6C, this->direction.y) + this->normal.y; + this->field_50 = fixpoint_mul(this->field_6C, this->direction.y) + this->normal.y; + this->normal2.y = fixpoint_mul(this->field_6C, this->direction.y) + this->normal.y; + this->normal2.z = fixpoint_mul(this->field_6C, this->direction.z) + this->normal.z; + //v12 = this->position.z; + //v13 = this->normal.x; + //v14 = this->normal2.x; + //v15 = this->prolly_normal_d; + //v16 = this->position.z + fixpoint_mul(this->field_6C, this->direction.z); + //v28 = this->position.z + fixpoint_mul(this->field_6C, this->direction.z); + this->field_54 = this->position.z + fixpoint_mul(this->field_6C, this->direction.z); + v17 = this->normal.x; + if (v17 >= this->normal2.x) + v17 = this->normal2.x; + this->sMaxX = v17 - this->prolly_normal_d; + v18 = this->prolly_normal_d + this->normal.x; + if (this->normal.x <= this->normal2.x) + v18 = this->prolly_normal_d + this->normal2.x; + //v19 = this->normal.y; + //v20 = this->normal2.y; + this->sMinX = v18; + v21 = this->normal.y; + if (v21 >= this->normal2.y) + v21 = this->normal2.y; + this->sMaxY = v21 - this->prolly_normal_d; + v22 = this->prolly_normal_d + this->normal.y; + if (this->normal.y <= this->normal2.y) + v22 = this->normal2.y + this->prolly_normal_d; + //v23 = this->normal2.z; + this->sMinY = v22; + //v24 = this->normal.z; + if (this->normal.z >= this->normal2.z) + this->sMaxZ = this->normal2.z - this->prolly_normal_d; + else + this->sMaxZ = this->normal.z - this->prolly_normal_d; + //this->sMaxZ = v25; + //v26 = this->field_8_radius; + if (this->position.z <= this->position.z + fixpoint_mul(this->field_6C, this->direction.z)) + this->sMinZ = (this->position.z + fixpoint_mul(this->field_6C, this->direction.z)) + this->field_8_radius; + else + this->sMinZ = this->position.z + this->field_8_radius; + this->uFaceID = 0; + this->field_80 = -1; + this->field_88 = -1; + //this->sMinZ = v27; + this->field_7C = 0xFFFFFFu; + result = 0; + } + else + result = 1; + return result; +} diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/Indoor.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/Indoor.h Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,921 @@ +#pragma once +#include + +#include "Render.h" +#include "IndoorCameraD3D.h" +#include "mm7_data.h" + +/* 358 */ +#pragma pack(push, 1) +struct stru320 +{ + int field_0; + Plane_int_ plane_4; + Vec3_int_ vec_14; + Vec3_int_ vec_20; + unsigned int uCurrentAmbientLightLevel; + int field_30; + int field_34; + int field_38; + int pDeltaUV[2]; + int field_44; + int field_48; + char field_4C[8]; + Vec3_int_ rotated_normal; + Vec3_int_ vec_60; + int field_6C; + Vec3_int_ vec_70; + int field_7C; + Vec3_int_ vec_80; + Vec3_int_ vec_8C; + int field_98; + Vec3_int_ vec_9C; + int field_A8; + unsigned int uNumLightsApplied; + int _blv_lights_radii[20]; + int _blv_lights_inv_radii[20]; + int _blv_lights_xs[20]; + int _blv_lights_ys[20]; + int _blv_lights_light_dot_faces[20]; + int field_240; + int field_244; + int field_248; + int field_24C; + int field_250; + int field_254; + int field_258; + int field_25C; + int field_260; + int field_264; + int field_268; + int field_26C; + int field_270; + int field_274; + int field_278; + int field_27C; + int field_280; + int field_284; + int field_288; + int field_28C; + int _blv_lights_zs[20]; + float _blv_lights_rs[20]; + float _blv_lights_gs[20]; + float _blv_lights_bs[20]; + char _blv_lights_types[20]; + int field_3E4; + int field_3E8; + int field_3EC; + int field_3F0; + int field_3F4; + unsigned int uDefaultAmbientLightLevel; +}; +#pragma pack(pop) + +extern stru320 stru_F8AD28; // idb + + + + + + + + +/* 345 */ +#pragma pack(push, 1) +struct stru315 +{ + int field_0; + int field_4; + int field_8; + int field_C; + int field_10; + int field_14; + int field_18; + int field_1C; + int field_20; + int field_24; + int field_28; + int field_2C; + int field_30; + unsigned __int16 *field_34_palette; + unsigned __int16 *pTextureLOD; + unsigned int *pDepthBuffer; + unsigned __int16 *pColorBuffer; +}; +#pragma pack(pop) + + + + + +/* 346 */ +#pragma pack(push, 1) +struct stru316 +{ + int field_0; + int field_4; + int field_8; + int field_C; + int field_10; + int field_14; + int field_18; + int field_1C; + int field_20; + unsigned __int16 *field_24_palette; +}; +#pragma pack(pop) + + + + + + +/* 134 */ +#pragma pack(push, 1) +struct stru141_actor_collision_object +{ + int _47050A(int a2); + + int field_0; + int prolly_normal_d; + int field_8_radius; + int height; + int field_10; + int field_14; + int field_18; + Vec3_int_ velocity; + Vec3_int_ normal; + Vec3_int_ position; + Vec3_int_ normal2; + int field_4C; + int field_50; + int field_54; + Vec3_int_ direction; // velocity's unit vector + int speed; + int inv_speed; + int field_6C; + int field_70; + unsigned int uSectorID; + unsigned int uFaceID; + int field_7C; + int field_80; + int field_84; + int field_88; + int sMaxX; + int sMinX; + int sMaxY; + int sMinY; + int sMaxZ; + int sMinZ; + int field_A4; +}; +#pragma pack(pop) +extern stru141_actor_collision_object stru_721530; + + + + + + +/* 378 */ +#pragma pack(push, 1) +struct stru337_stru0 +{ + int field_0; + int field_4; + int field_8; + int field_C; + int field_10; +}; +#pragma pack(pop) + + + +/* 377 */ +#pragma pack(push, 1) +struct stru337 +{ + stru337_stru0 field_0; + int field_14; + int field_18; + int field_1C; + int field_20; + int field_24; + int field_28; + int field_2C; + int field_30; + stru337_stru0 field_34; +}; +#pragma pack(pop) +extern stru337 stru_F81018; + + +/* 291 */ +enum PolygonType : __int8 +{ + POLYGON_Invalid = 0x0, + POLYGON_VerticalWall = 0x1, + POLYGON_unk = 0x2, + POLYGON_Floor = 0x3, + POLYGON_InBetweenFloorAndWall = 0x4, + POLYGON_Ceiling = 0x5, + POLYGON_InBetweenCeilingAndWall = 0x6, +}; + + +/* 147 */ +#pragma pack(push, 1) + +struct stru154 +{ + //----- (0049B001) -------------------------------------------------------- + inline stru154() + {} + + //----- (0049B027) -------------------------------------------------------- + inline ~stru154() + {} + + void GetFacePlaneAndClassify(struct ODMFace *a2, struct BSPVertexBuffer *a3); + void ClassifyPolygon(struct Vec3_float_ *pNormal, float dist); + void GetFacePlane(struct ODMFace *pFace, struct BSPVertexBuffer *pVertices, struct Vec3_float_ *pOutNormal, float *pOutDist); + + + void(***vdestructor_ptr)(stru154 *, bool); + Plane_float_ face_plane; + PolygonType polygonType; + char field_15; + char field_16; + char field_17; +}; +#pragma pack(pop) + + + + + +/* 392 */ +#pragma pack(push, 1) +struct stru352 +{ + int field_0; + int field_4; + int field_8; + int field_C; + int field_10; + int field_14; + int field_18; + int field_1C; + int field_20; + int field_24; + int field_28; + int field_2C; + int field_30; + int field_34; +}; +#pragma pack(pop) +//extern std::array stru_F83B80; + +#pragma pack(push, 1) +struct LocationTime_stru1 +{ + unsigned __int64 uLastVisitDay; + char sky_texture_name[12]; + int day_attrib; + int day_fogrange_1; + int day_fogrange_2; + char field_2F4[24]; +}; +#pragma pack(pop) + +/* 319 */ +enum LEVEL_TYPE +{ + LEVEL_null = 0, + LEVEL_Indoor = 0x1, + LEVEL_Outdoor = 0x2, +}; +extern LEVEL_TYPE uCurrentlyLoadedLevelType; + + + + + + + + + + + + + +/* 86 */ +#pragma pack(push, 1) +struct SpawnPointMM6 +{ + Vec3_int_ vPosition; + unsigned __int16 uRadius; + unsigned __int16 uKind; + unsigned __int16 uIndex; + unsigned __int16 uAttributes; +}; +#pragma pack(pop) + + + +/* 102 */ +#pragma pack(push, 1) +struct SpawnPointMM7 +{ + //----- (00448DD6) -------------------------------------------------------- + SpawnPointMM7() + { + uRadius = 32; + uAttributes = 0; + uIndex = 0; + uKind = 0; + uGroup = 0; + } + + + Vec3_int_ vPosition; + unsigned __int16 uRadius; + unsigned __int16 uKind; + unsigned __int16 uIndex; + unsigned __int16 uAttributes; + unsigned int uGroup; +}; +#pragma pack(pop) + + + + + + +/* 90 */ +#pragma pack(push, 1) +struct BLVHeader +{ + char field_0[104]; + unsigned int uFaces_fdata_Size; + unsigned int uSector_rdata_Size; + unsigned int uSector_lrdata_Size; + unsigned int uDoors_ddata_Size; + char field_78[16]; +}; +#pragma pack(pop) + + + +/* 96 */ +#pragma pack(push, 1) +struct BLVSectorMM8 +{ + int dword_000074; +}; +#pragma pack(pop) + +/* 97 */ +#pragma pack(push, 1) +struct BLVLightMM6 +{ + Vec3_short_ vPosition; + __int16 uRadius; + __int16 uAttributes; + unsigned __int16 uBrightness; +}; +#pragma pack(pop) + +/* 98 */ +#pragma pack(push, 1) +struct BLVLightMM7 //10h +{ + struct Vec3_short_ vPosition; + __int16 uRadius; + char uRed; + char uGreen; + char uBlue; + char uType; + __int16 uAtributes; // & 0x08 doesn't light faces + __int16 uBrightness; +}; +#pragma pack(pop) + +/* 99 */ +#pragma pack(push, 1) +struct BLVLightMM8 +{ + int uID; +}; +#pragma pack(pop) + + + +/* 100 */ +#pragma pack(push, 1) +struct BLVDoor //50h +{ + enum State: unsigned __int16 + { + Closed = 0, + Opening = 1, + Open = 2, + Closing = 3 + }; + + unsigned int uAttributes; + unsigned int uDoorID; + unsigned int uTimeSinceTriggered; + Vec3_int_ vDirection; + int uMoveLength; + int uOpenSpeed; + int uCloseSpeed; + unsigned __int16 *pVertexIDs; + unsigned __int16 *pFaceIDs; + unsigned __int16 *pSectorIDs; + __int16 *pDeltaUs; + __int16 *pDeltaVs; + unsigned __int16 *pXOffsets; + unsigned __int16 *pYOffsets; + unsigned __int16 *pZOffsets; + unsigned __int16 uNumVertices; + unsigned __int16 uNumFaces; + __int16 field_48; + unsigned __int16 uNumOffsets; + State uState; + __int16 field_4E; +}; +#pragma pack(pop) + +/* 101 */ +#pragma pack(push, 1) +struct BLVMapOutline //0C +{ + unsigned __int16 uVertex1ID; + unsigned __int16 uVertex2ID; + unsigned __int16 uFace1ID; + unsigned __int16 uFace2ID; + __int16 sZ; + unsigned __int16 uFlags; +}; +#pragma pack(pop) + + +#define FACE_PORTAL 0x00000001 // portal/two-sided +#define FACE_CAN_SATURATE_COLOR 0x00000002 +#define FACE_FLOW_DIAGONAL 0x00000004 // Diagonal flow of the lava or water +#define FACE_UNKNOW5 0x00000006 +#define FACE_UNKNOW6 0x00000008 +#define FACE_FLUID 0x00000010 // wavy animated water or lava +#define FACE_FLOW_VERTICAL 0x00000020 // Vertical flow of the lava or water +#define FACE_DONT_CACHE_TEXTURE 0x00000040 // do not load face texture if it isn't loaded already +#define FACE_UNKNOW4 0x00000080 +#define FACE_XY_PLANE 0x00000100 +#define FACE_XZ_PLANE 0x00000200 +#define FACE_YZ_PLANE 0x00000400 +#define FACE_FLOW_HORIZONTAL 0x00000800 // Horizontal flow of the lava or water +#define FACE_HAS_EVENT_HINT 0x00001000 +#define FACE_INVISIBLE 0x00002000 +#define FACE_TEXTURE_FRAME 0x00004000 // Texture ID is a frameset from TextureFrameTable, otherwise BitmapID +#define FACE_OUTLINED 0x00010000 // outline face edges +#define FACE_INDOOR_DOOR 0x00020000 +#define FACE_TEXTURE_FLOW 0x00040000 // The texture moves slowly. For horizontal facets only. +#define FACE_HAS_EVENT 0x00100000 +#define FACE_INDOOR_CARPET 0x00200000 +#define FACE_INDOOR_SKY 0x00400000 +#define FACE_UNKNOW3 0x00800000 +#define FACE_UNKNOW4 0x01000000 +#define FACE_CLICKABLE 0x02000000 // Event can be triggered by clicking on the facet. +#define FACE_PRESSURE_PLATE 0x04000000 // Event can be triggered by stepping on the facet. +#define FACE_INDICATE 0x06000000 // Event can be triggered by indicating on the facet. +#define FACE_UNKNOW1 0x08000000 +#define FACE_UNKNOW2 0x10000000 +#define FACE_ETHEREAL 0x20000000 // Untouchable. You can pass through it. +#define FACE_INDOOR_LAVA 0x40000000 +#define FACE_PICKED 0x80000000 + +/* 93 */ +#pragma pack(push, 1) +struct BLVFace //60h +{ + //----- (0046ED02) -------------------------------------------------------- + inline BLVFace() + { + this->uNumVertices = 0; + this->uAttributes = 0; + this->uFaceExtraID = 0; + this->pVertexIDs = nullptr; + this->pZInterceptDisplacements = nullptr; + this->pYInterceptDisplacements = nullptr; + this->pXInterceptDisplacements = nullptr; + } + + void _get_normals(Vec3_int_ *a2, Vec3_int_ *a3); + struct Texture *GetTexture(); + void FromODM(struct ODMFace *face); + + inline bool Invisible() const {return (uAttributes & FACE_INVISIBLE) != 0;} + inline bool Visible() const {return !Invisible();} + inline bool Portal() const {return (uAttributes & FACE_PORTAL) != 0;} + inline bool Fluid() const {return (uAttributes & FACE_FLUID) != 0;} + inline bool Indoor_sky() const {return (uAttributes & FACE_INDOOR_SKY) != 0;} + inline bool Clickable() const {return (uAttributes & FACE_CLICKABLE) != 0;} + inline bool Pressure_Plate() const {return (uAttributes & FACE_PRESSURE_PLATE) != 0;} + inline bool Ethereal() const {return (uAttributes & FACE_ETHEREAL) != 0;} + + struct Plane_float_ pFacePlane; + struct Plane_int_ pFacePlane_old; + int zCalc1; + int zCalc2; + int zCalc3; + unsigned int uAttributes; + unsigned __int16 *pVertexIDs; + signed __int16 *pXInterceptDisplacements; + signed __int16 *pYInterceptDisplacements; + signed __int16 *pZInterceptDisplacements; + signed __int16 *pVertexUIDs; + signed __int16 *pVertexVIDs; + unsigned __int16 uFaceExtraID; + unsigned __int16 uBitmapID; + unsigned __int16 uSectorID; + __int16 uBackSectorID; + struct BBox_short_ pBounding; + PolygonType uPolygonType; + unsigned __int8 uNumVertices; + char field_5E; + char field_5F; +}; +#pragma pack(pop) + +/* 94 */ +#pragma pack(push, 1) +struct BLVFaceExtra //24h +{ +bool HasEventint(); + + __int16 field_0; + __int16 field_2; + __int16 field_4; + __int16 field_6; + __int16 field_8; + __int16 field_A; + __int16 field_C; + unsigned __int16 uAdditionalBitmapID; + __int16 field_10; + __int16 field_12; + __int16 sTextureDeltaU; + __int16 sTextureDeltaV; + __int16 sCogNumber; + unsigned __int16 uEventID; + __int16 field_1C; + __int16 field_1E; + __int16 field_20; + __int16 field_22; +}; +#pragma pack(pop) + +/* 95 */ +#pragma pack(push, 1) +struct BLVSector //0x74 +{ + int field_0; + unsigned __int16 uNumFloors; + __int16 field_6; + unsigned __int16 *pFloors; + unsigned __int16 uNumWalls; + __int16 field_E; + unsigned __int16 *pWalls; + unsigned __int16 uNumCeilings; + __int16 field_16; + unsigned __int16 *pCeilings; + unsigned __int16 uNumFluids; + __int16 field_1E; + unsigned __int16 *pFluids; + __int16 uNumPortals; + __int16 field_26; + unsigned __int16 *pPortals; + unsigned __int16 uNumFaces; + unsigned __int16 uNumNonBSPFaces; + unsigned __int16 *pFaceIDs; + unsigned __int16 uNumCylinderFaces; + __int16 field_36; + int pCylinderFaces; + unsigned __int16 uNumCogs; + __int16 field_3E; + unsigned __int16 *pCogs; + unsigned __int16 uNumDecorations; + __int16 field_46; + unsigned __int16 *pDecorationIDs; + unsigned __int16 uNumMarkers; + __int16 field_4E; + unsigned __int16 *pMarkers; + unsigned __int16 uNumLights; + __int16 field_56; + unsigned __int16 *pLights; + __int16 uWaterLevel; + __int16 uMistLevel; + __int16 uLightDistanceMultiplier; + __int16 uMinAmbientLightLevel; + __int16 uFirstBSPNode; + __int16 exit_tag; + BBox_short_ pBounding; +}; +#pragma pack(pop) + + +#pragma pack(push, 1) +struct BLVMapOutlines +{ + int uNumOutlines; + BLVMapOutline pOutlines[7000]; +}; +#pragma pack(pop) + + + + + + + +/* 89 */ +#pragma pack(push, 1) +struct IndoorLocation +{ + //----- (00462592) -------------------------------------------------------- + inline IndoorLocation() + { + bLoaded = 0; + ptr_0002B8_sector_lrdata = 0; + ptr_0002B4_doors_ddata = 0; + ptr_0002B0_sector_rdata = 0; + pLFaces = 0; + pVertices = 0; + pFaces = 0; + pFaceExtras = 0; + pSectors = 0; + pLights = 0; + pDoors = 0; + pNodes = 0; + pMapOutlines = 0; + uNumSpawnPoints = 0; + pSpawnPoints = 0; + uNumSectors = 0; + } + + int GetSector(int sX, int sY, int sZ); + void Release(); + bool Alloc(); + bool Load(char *pFilename, int a3, size_t i, char *pDest); + void Draw(); + void ToggleLight(signed int uLightID, unsigned int bToggle); + + static unsigned int GetLocationIndex(const char *Str1); + static void ExecDraw(bool bD3D); + //static void ExecDraw_sw(unsigned int uFaceID); + static void ExecDraw_d3d(unsigned int uFaceID, struct IndoorCameraD3D_Vec4 *pVertices, unsigned int uNumVertices, struct RenderVertexSoft *pPortalBounding); + + char pFilename[32]; + char field_20[48]; + unsigned int bLoaded; + char field_54[404]; + struct BLVHeader blv; + unsigned int uNumVertices; + struct Vec3_short_ *pVertices; + unsigned int uNumFaces; + struct BLVFace *pFaces; + unsigned int uNumFaceExtras; + struct BLVFaceExtra *pFaceExtras; + int uNumSectors; + struct BLVSector *pSectors; + int uNumLights; + struct BLVLightMM7 *pLights; + int uNumDoors; + struct BLVDoor *pDoors; + unsigned int uNumNodes; + struct BSPNode *pNodes; + BLVMapOutlines *pMapOutlines; + unsigned __int16 *pLFaces; + unsigned __int16 *ptr_0002B0_sector_rdata; + unsigned __int16 *ptr_0002B4_doors_ddata; + unsigned __int16 *ptr_0002B8_sector_lrdata; + unsigned int uNumSpawnPoints; + struct SpawnPointMM7 *pSpawnPoints; + struct DDM_DLV_Header dlv; + LocationTime_stru1 stru1; + char _visible_outlines[875]; + char padding; +}; +#pragma pack(pop) + +extern IndoorLocation *pIndoor; + + + + + + + + + + + + + +/* 162 */ +#pragma pack(push, 1) +struct BLVRenderParams +{ + inline BLVRenderParams() + { + uViewportX = 0; + uViewportY = 0; + uViewportZ = 0; + uViewportW = 0; + } + + void Reset(); + + int field_0_timer_; + int _unused_uFlags; // & INDOOR_CAMERA_DRAW_D3D_OUTLINES: render d3d outlines + Vec3_int_ _unused_vPartyPos; + int _unused_sPartyRotY; + int _unused_sPartyRotX; + int uPartySectorID; + int _unused_sCosineY; // matches ODMRenderParams::int sines and cosines + int _unused_sSineY; // computed in 0048600E + int _unused_sCosineNegX; // merged into IndoorCameraD3D + int _unused_sSineNegX; // --//-- + float _unused_fCosineY; // matches old IndoorCamera::fRotationCosineY (new IndoorCameraD3D::fRotationCosineY) + float _unused_fSineY; // matches old IndoorCamera::fRotationSineY (new IndoorCameraD3D::fRotationSineY) + float _unused_fCosineNegX; // the same + float _unused_fSineNegX; // the same + int fov_rad_fixpoint; + int fov_rad_inv_fixpoint;//float + void *pRenderTarget; + unsigned int uTargetWidth; + unsigned int uTargetHeight; + unsigned int uViewportX; + unsigned int uViewportY; + unsigned int uViewportZ; + unsigned int uViewportW; + int field_64; + int *pTargetZBuffer; + int uViewportHeight; + int uViewportWidth; + int uViewportCenterX; + int uViewportCenterY; + struct BspRenderer_PortalViewportData *field_7C; + unsigned int uNumFacesRenderedThisFrame; + int field_84; + int field_88; + int field_8C; + int field_90; + int field_94; +}; +#pragma pack(pop) +extern BLVRenderParams *pBLVRenderParams; + + + + + +int __fastcall GetPortalScreenCoord(unsigned int uFaceID); +bool PortalFrustrum(int pNumVertices, struct BspRenderer_PortalViewportData *a2, struct BspRenderer_PortalViewportData *near_portal, int uFaceID); +void PrepareBspRenderList_BLV(); +void PrepareDecorationsRenderList_BLV(unsigned int uDecorationID, unsigned int uSectorID); +void PrepareActorRenderList_BLV(); +void PrepareItemsRenderList_BLV(); +void AddBspNodeToRenderList(unsigned int node_id); +void __fastcall sub_4406BC(unsigned int node_id, unsigned int uFirstNode); // idb +char __fastcall DoInteractionWithTopmostZObject(int a1, int a2); +int __fastcall sub_4AAEA6_transform(struct RenderVertexSoft *a1); +unsigned int __fastcall sub_4B0E07(unsigned int uFaceID); // idb +void BLV_UpdateUserInputAndOther(); +int BLV_GetFloorLevel(int x, int y, int z, unsigned int uSectorID, unsigned int *pFaceID); +void BLV_UpdateDoors(); +void UpdateActors_BLV(); +void BLV_ProcessPartyActions(); +void Door_switch_animation(unsigned int uDoorID, int a2); // idb: sub_449A49 +int __fastcall sub_4088E9(int a1, int a2, int a3, int a4, int a5, int a6); +void __fastcall PrepareDrawLists_BLV(); +void PrepareToLoadBLV(unsigned int bLoading); +int GetAlertStatus(); +int __fastcall _45063B_spawn_some_monster(struct MapInfo *a1, int a2); +int __fastcall sub_450521_ProllyDropItemAt(int ecx0, signed int a2, int a3, int a4, int a5, unsigned __int16 a6); + +bool __fastcall sub_4075DB(int a1, int a2, int a3, struct BLVFace *face); +bool __fastcall sub_4077F1(int a1, int a2, int a3, struct ODMFace *face, struct BSPVertexBuffer *a5); + +#pragma once + + + + + +/* 165 */ +#pragma pack(push, 1) +struct BspRenderer_PortalViewportData +{ + void GetViewportData(__int16 x, int y, __int16 z, int w); + + int _viewport_space_y; + int _viewport_space_w; + int _viewport_space_x; + int _viewport_space_z; + int _viewport_x_minID; + int _viewport_z_maxID; + __int16 viewport_left_side[480]; + __int16 viewport_right_side[480]; +}; +#pragma pack(pop) +extern BspRenderer_PortalViewportData stru_F8A590; + + + + +/* 164 */ +#pragma pack(push, 1) +struct BspRenderer_stru0 +{ + //----- (0043F2BF) -------------------------------------------------------- + inline BspRenderer_stru0() + { + //_eh_vector_constructor_iterator_(std__vector_0007AC, 24, 4, + // (void ( *)(void *))IndoorCameraD3D_Vec4::IndoorCameraD3D_Vec4, + // (void ( *)(void *))IndoorCameraD3D_Vec4::dtor); + //for (int i = 0; i < 4; ++i) + // pVertices[i].flt_2C = 0.0f; + } + + //----- (0043F2A9) -------------------------------------------------------- + ~BspRenderer_stru0() + { + //_eh_vector_destructor_iterator_(this->std__vector_0007AC, 24, 4, IndoorCameraD3D_Vec4::dtor); + } + + unsigned __int16 uSectorID; + unsigned __int16 uViewportX; + unsigned __int16 uViewportY; + unsigned __int16 uViewportZ; + unsigned __int16 uViewportW; + __int16 field_A; + BspRenderer_PortalViewportData PortalScreenData; + unsigned __int16 uFaceID; + __int16 field_7A6; + unsigned int viewing_portal_id; // portal through which we're seeing this node + IndoorCameraD3D_Vec4 std__vector_0007AC[4]; + RenderVertexSoft pPortalBounding[4]; +}; +#pragma pack(pop) + + + + +#pragma pack(push, 1) +struct BspFace +{ + unsigned __int16 uFaceID; + unsigned __int16 uNodeID; +}; +#pragma pack(pop) + + +/* 163 */ +#pragma pack(push, 1) +struct BspRenderer // stru170 +{ + //----- (0043F282) -------------------------------------------------------- + inline BspRenderer() + { + // _eh_vector_constructor_iterator_(field_FA8, 2252, 150, + // (void ( *)(void *))stru170_stru0::stru170_stru0, + // (void ( *)(void *))stru170_stru0::dtor); + num_faces = 0; + num_nodes = 0; + uNumVisibleNotEmptySectors = 0; + } + + //void AddFaceToRenderList_sw(unsigned int node_id, unsigned int uFaceID); + void AddFaceToRenderList_d3d(unsigned int node_id, unsigned int uFaceID); + void MakeVisibleSectorList(); + //void DrawFaceOutlines(); + + unsigned int num_faces; + //__int16 pFaceIDs[2000]; + BspFace faces[1000]; + //char field_130[3700]; + unsigned int num_nodes; + BspRenderer_stru0 nodes[150]; + unsigned int uNumVisibleNotEmptySectors; + unsigned __int16 pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[6]; +}; +#pragma pack(pop) + + +extern struct BspRenderer *pBspRenderer; // idb + +void FindBillboardsLightLevels_BLV(); + +int collide_against_floor_approximate(int x, int y, int z, unsigned int *pSectorID, unsigned int *pFaceID); // idb + +bool __fastcall sub_407A1C(int x, int z, int y, struct Vec3_int_ v); // idb diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/IndoorCameraD3D.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/IndoorCameraD3D.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,1466 @@ +#define _CRTDBG_MAP_ALLOC +#include +#include + +#define _CRT_SECURE_NO_WARNINGS +#include "ErrorHandling.h" +#include "IndoorCameraD3D.h" +#include "Game.h" +#include "Indoor.h" +#include "Viewport.h" +#include "LOD.h" +#include "OurMath.h" + +#include "stru9.h" + + +// calculates FOV (Field of View) angle in radians for IndoorCamera::Initialize and BLVRenderParams::Reset +float _calc_fov(int viewport_width, int angle_degree) +{ + return viewport_width * 0.5 / tan(angle_degree / 2 * 0.01745329) + 0.5; +} + + + +//----- (004361EF) -------------------------------------------------------- +IndoorCameraD3D::IndoorCameraD3D() +{ + this->field_108 = 0.0; + this->field_138 = 0.0; + this->field_168 = 0.0; + this->field_198 = 0.0; + this->field_1C8 = 0.0; + this->field_1F8 = 0.0; + this->field_228 = 0.0; + this->field_258 = 0.0; + this->field_288 = 0.0; + this->field_2B8 = 0.0; + this->field_2E8 = 0.0; + this->field_2BC = 0.0; + this->field_2C0 = 0.0; + this->field_2C4 = 0.0; + this->field_318 = 0.0; + this->field_2EC = 0.0; + this->field_2F0 = 0.0; + this->field_2F4 = 0.0; + this->field_348 = 0.0; + this->field_31C = 0.0; + this->field_320 = 0.0; + this->field_324 = 0.0; + this->field_378 = 0.0; + this->field_34C = 0.0; + this->field_350 = 0.0; + this->field_354 = 0.0; + for (uint i = 0; i < 16384; ++i) + { + list_0037C[i].field_0 = 0; + list_0037C[i].flt_30 = 0.0f; + } + list_0037C_size = 0; + for (uint i = 0; i < 256; ++i) + list_E0380[i].mm7__vector_000004_size = 0; + list_E0380_size = 0; +} + + +//----- (0043643E) -------------------------------------------------------- +float IndoorCameraD3D::GetPickDepth() +{ + if (uCurrentlyLoadedLevelType == LEVEL_Outdoor) + return pODMRenderParams->uPickDepth; + else + return 16192.0; +} + +//----- (00436427) -------------------------------------------------------- +float IndoorCameraD3D::GetShadingDistMist() +{ + if (uCurrentlyLoadedLevelType == LEVEL_Outdoor) + return (double)pODMRenderParams->shading_dist_mist; + else + return 16192.0; +} + +//----- (004364C5) -------------------------------------------------------- +void IndoorCameraD3D::ViewTransfrom_OffsetUV(RenderVertexSoft *pVertices, unsigned int uNumVertices, RenderVertexSoft *pOutVertices, stru320 *a5) +{ + for (uint i = 0; i < uNumVertices; ++i) + { + pOutVertices[i].vWorldPosition.x = pVertices[i].vWorldPosition.x; + pOutVertices[i].vWorldPosition.y = pVertices[i].vWorldPosition.y; + pOutVertices[i].vWorldPosition.z = pVertices[i].vWorldPosition.z; + + pOutVertices[i].u = pVertices[i].u + a5->pDeltaUV[0]; + pOutVertices[i].v = pVertices[i].v + a5->pDeltaUV[1]; + } + ViewTransform(pOutVertices, uNumVertices); +} + +//----- (0043669D) -------------------------------------------------------- +bool IndoorCameraD3D::ApplyViewTransform_TrueIfStillVisible_BLV(int x, int y, int z, signed int *pOutX, int *pOutZ, int *pOutY, char bDoNotShow) +{ + int to_z; // esi@2 + int v9; // ecx@3 + //signed int *v10; // esi@5 + //int pOutY_; // ecx@5 + //signed int v12; // esi@7 + int v14; // [sp+8h] [bp-4h]@3 + int to_x; // [sp+14h] [bp+8h]@1 + int to_y; // [sp+18h] [bp+Ch]@1 +// int a2b; // [sp+18h] [bp+Ch]@5 + int a3a; // [sp+1Ch] [bp+10h]@5 + + to_x = x - pGame->pIndoorCameraD3D->vPartyPos.x; + to_y = y - pGame->pIndoorCameraD3D->vPartyPos.y; + if (pGame->pIndoorCameraD3D->sRotationX) + { + to_z = (z - pGame->pIndoorCameraD3D->vPartyPos.z) << 16; + //if ( pRenderer->pRenderD3D ) + //{ + v14 = (unsigned __int64)(to_x * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) + + (unsigned __int64)(to_y * (signed __int64)pGame->pIndoorCameraD3D->int_sine_y); + v9 = (unsigned __int64)(to_x * (signed __int64)pGame->pIndoorCameraD3D->int_sine_y) + - (unsigned __int64)(to_y * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y); + //} + a3a = (z - pGame->pIndoorCameraD3D->vPartyPos.z) << 16; + *pOutX = fixpoint_mul(v14, pGame->pIndoorCameraD3D->int_cosine_x) - fixpoint_mul(to_z, pGame->pIndoorCameraD3D->int_sine_x); + *pOutZ = v9; + *pOutY = fixpoint_mul(v14, pGame->pIndoorCameraD3D->int_sine_x) + fixpoint_mul(a3a, pGame->pIndoorCameraD3D->int_cosine_x); + } + else + { + *pOutY = (z - pGame->pIndoorCameraD3D->vPartyPos.z) << 16; + //if ( pRenderer->pRenderD3D ) + //{ + //v10 = pOutX; + *pOutX = (unsigned __int64)(to_x * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) + + (unsigned __int64)(to_y * (signed __int64)pGame->pIndoorCameraD3D->int_sine_y); + *pOutZ = (unsigned __int64)(to_x * (signed __int64)pGame->pIndoorCameraD3D->int_sine_y) + - (unsigned __int64)(to_y * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y); + //} + } + if (!bDoNotShow) + return false; + + return *pOutX >= fixpoint_from_int(4, 0) && + *pOutX <= fixpoint_from_int(8000, 0); +} + +//----- (00436455) -------------------------------------------------------- +bool IndoorCameraD3D::IsCulled(BLVFace *pFace) +{ + RenderVertexSoft v; // [sp+8h] [bp-30h]@1 + + //----- (0043648F) -------------------------------------------------------- + auto Vec3_short__to_RenderVertexSoft = [](RenderVertexSoft *_this, Vec3_short_ *a2) -> void + { + _this->flt_2C = 0.0; + + _this->vWorldPosition.x = a2->x; + _this->vWorldPosition.y = a2->y; + _this->vWorldPosition.z = a2->z; + }; + + + Vec3_short__to_RenderVertexSoft(&v, &pIndoor->pVertices[*pFace->pVertexIDs]); + return is_face_faced_to_camera(pFace, &v); +} + + +//----- (00436523) -------------------------------------------------------- +void IndoorCameraD3D::ViewTransform(RenderVertexSoft *a1a, unsigned int uNumVertices) +{ + if (byte_4D864C && pGame->uFlags & 0x80 || + uCurrentlyLoadedLevelType == LEVEL_Indoor) + { + float sin_x = fRotationXSine, + cos_x = fRotationXCosine; + float sin_y = fRotationYSine, + cos_y = fRotationYCosine; + + //v4 = uNumVertices; + //v7 = pIndoorCamera->fRotationXSine; + if (pGame->pIndoorCameraD3D->sRotationX) + { + + //_EAX = a1a; + for (uint i = 0; i < uNumVertices; ++i) + { + float st0, st1, st2; + //if ( pRenderer->pRenderD3D ) + { + /*__asm + { + fld [ebp+uNumVertices] // [(a1a[i].y - pIndoorCamera->pos.y)] [(a1a[i].z - pIndoorCamera->pos.z)] [pIndoorCamera->fRotationXCosine] [pIndoorCamera->fRotationYSine] [pIndoorCamera->fRotationYCosine] + fmul st, st(3) // [pIndoorCamera->fRotationYSine * (a1a[i].y - pIndoorCamera->pos.y)] [(a1a[i].z - pIndoorCamera->pos.z)] [pIndoorCamera->fRotationXCosine] [pIndoorCamera->fRotationYSine] [pIndoorCamera->fRotationYCosine] + fld [ebp+a1] // [(a1a[i].x - pIndoorCamera->pos.x)] [pIndoorCamera->fRotationYSine * (a1a[i].y - pIndoorCamera->pos.y)] [(a1a[i].z - pIndoorCamera->pos.z)] [pIndoorCamera->fRotationXCosine] [pIndoorCamera->fRotationYSine] [pIndoorCamera->fRotationYCosine] + fmul st, st(5) // 0[pIndoorCamera->fRotationYCosine * (a1a[i].x - pIndoorCamera->pos.x)] + // 1[pIndoorCamera->fRotationYSine * (a1a[i].y - pIndoorCamera->pos.y)] + // 2[(a1a[i].z - pIndoorCamera->pos.z)] + // 3[pIndoorCamera->fRotationXCosine] + // 4[pIndoorCamera->fRotationYSine] + // 5[pIndoorCamera->fRotationYCosine] + faddp st(1), st // [pIndoorCamera->fRotationYCosine * (a1a[i].x - pIndoorCamera->pos.x) + pIndoorCamera->fRotationYSine * (a1a[i].y - pIndoorCamera->pos.y)] [(a1a[i].z - pIndoorCamera->pos.z)] [pIndoorCamera->fRotationXCosine] [pIndoorCamera->fRotationYSine] [pIndoorCamera->fRotationYCosine] + fld [ebp+a1] // [(a1a[i].x - pIndoorCamera->pos.x)] [pIndoorCamera->fRotationYCosine * (a1a[i].x - pIndoorCamera->pos.x) + pIndoorCamera->fRotationYSine * (a1a[i].y - pIndoorCamera->pos.y)] [(a1a[i].z - pIndoorCamera->pos.z)] [pIndoorCamera->fRotationXCosine] [pIndoorCamera->fRotationYSine] [pIndoorCamera->fRotationYCosine] + fmul st, st(4) // [pIndoorCamera->fRotationYSine * (a1a[i].x - pIndoorCamera->pos.x)] [pIndoorCamera->fRotationYCosine * (a1a[i].x - pIndoorCamera->pos.x) + pIndoorCamera->fRotationYSine * (a1a[i].y - pIndoorCamera->pos.y)] [(a1a[i].z - pIndoorCamera->pos.z)] [pIndoorCamera->fRotationXCosine] [pIndoorCamera->fRotationYSine] [pIndoorCamera->fRotationYCosine] + + fld [ebp+uNumVertices] // 0[a1a[i].y - pIndoorCamera->pos.y] + // 1[pIndoorCamera->fRotationYSine * (a1a[i].x - pIndoorCamera->pos.x)] + // 2[pIndoorCamera->fRotationYCosine * (a1a[i].x - pIndoorCamera->pos.x) + pIndoorCamera->fRotationYSine * (a1a[i].y - pIndoorCamera->pos.y)] + // 3[(a1a[i].z - pIndoorCamera->pos.z)] + // 4[pIndoorCamera->fRotationXCosine] + // 5[pIndoorCamera->fRotationYSine] + // 6[pIndoorCamera->fRotationYCosine] + + fmul st, st(6) // 0[pIndoorCamera->fRotationYCosine * (a1a[i].y - pIndoorCamera->pos.y)] + // 1[pIndoorCamera->fRotationYSine * (a1a[i].x - pIndoorCamera->pos.x)] + // 2[pIndoorCamera->fRotationYCosine * (a1a[i].x - pIndoorCamera->pos.x) + pIndoorCamera->fRotationYSine * (a1a[i].y - pIndoorCamera->pos.y)] + // 3[(a1a[i].z - pIndoorCamera->pos.z)] + // 4[pIndoorCamera->fRotationXCosine] + // 5[pIndoorCamera->fRotationYSine] + // 6[pIndoorCamera->fRotationYCosine] + + fsubp st(1), st // 0[pIndoorCamera->fRotationYSine * (a1a[i].x - pIndoorCamera->pos.x) - pIndoorCamera->fRotationYCosine * (a1a[i].y - pIndoorCamera->pos.y)] + // 1[pIndoorCamera->fRotationYCosine * (a1a[i].x - pIndoorCamera->pos.x) + pIndoorCamera->fRotationYSine * (a1a[i].y - pIndoorCamera->pos.y)] + // 2[(a1a[i].z - pIndoorCamera->pos.z)] + // 3[pIndoorCamera->fRotationXCosine] + // 4[pIndoorCamera->fRotationYSine] + // 5[pIndoorCamera->fRotationYCosine] + }*/ + st0 = sin_y * (a1a[i].vWorldPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x) - cos_y * (a1a[i].vWorldPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y); + st1 = cos_y * (a1a[i].vWorldPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x) + sin_y * (a1a[i].vWorldPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y); + st2 = (a1a[i].vWorldPosition.z - pGame->pIndoorCameraD3D->vPartyPos.z); + } + if (false)//else + { + /*__asm + { + fld [ebp+a1] // 0[(a1a[i].x - pIndoorCamera->pos.x)] + // 1[(a1a[i].z - pIndoorCamera->pos.z)] + // 2[pIndoorCamera->fRotationXCosine] + // 3[pIndoorCamera->fRotationYSine] + // 4[pIndoorCamera->fRotationYCosine] + fmul st, st(4) // 0[pIndoorCamera->fRotationYCosine * (a1a[i].x - pIndoorCamera->pos.x)] + // 1[(a1a[i].z - pIndoorCamera->pos.z)] + // 2[pIndoorCamera->fRotationXCosine] + // 3[pIndoorCamera->fRotationYSine] + // 4[pIndoorCamera->fRotationYCosine] + fld [ebp+uNumVertices] // 0[(a1a[i].y - pIndoorCamera->pos.y)] + // 1[pIndoorCamera->fRotationYCosine * (a1a[i].x - pIndoorCamera->pos.x)] + // 2[(a1a[i].z - pIndoorCamera->pos.z)] + // 3[pIndoorCamera->fRotationXCosine] + // 4[pIndoorCamera->fRotationYSine] + // 5[pIndoorCamera->fRotationYCosine] + fmul st, st(4) // 0[pIndoorCamera->fRotationYSine * (a1a[i].y - pIndoorCamera->pos.y)] + // 1[pIndoorCamera->fRotationYCosine * (a1a[i].x - pIndoorCamera->pos.x)] + // 2[(a1a[i].z - pIndoorCamera->pos.z)] + // 3[pIndoorCamera->fRotationXCosine] + // 4[pIndoorCamera->fRotationYSine] + // 5[pIndoorCamera->fRotationYCosine] + fsubp st(1), st // 0[pIndoorCamera->fRotationYCosine * (a1a[i].x - pIndoorCamera->pos.x) - pIndoorCamera->fRotationYSine * (a1a[i].y - pIndoorCamera->pos.y)] + // 1[(a1a[i].z - pIndoorCamera->pos.z)] + // 2[pIndoorCamera->fRotationXCosine] + // 3[pIndoorCamera->fRotationYSine] + // 4[pIndoorCamera->fRotationYCosine] + fld [ebp+a1] // 0[(a1a[i].x - pIndoorCamera->pos.x)] + // 1[pIndoorCamera->fRotationYCosine * (a1a[i].x - pIndoorCamera->pos.x) - pIndoorCamera->fRotationYSine * (a1a[i].y - pIndoorCamera->pos.y)] + // 2[(a1a[i].z - pIndoorCamera->pos.z)] + // 3[pIndoorCamera->fRotationXCosine] + // 4[pIndoorCamera->fRotationYSine] + // 5[pIndoorCamera->fRotationYCosine] + fmul st, st(4) // 0[pIndoorCamera->fRotationYSine * (a1a[i].x - pIndoorCamera->pos.x)] + // 1[pIndoorCamera->fRotationYCosine * (a1a[i].x - pIndoorCamera->pos.x) - pIndoorCamera->fRotationYSine * (a1a[i].y - pIndoorCamera->pos.y)] + // 2[(a1a[i].z - pIndoorCamera->pos.z)] + // 3[pIndoorCamera->fRotationXCosine] + // 4[pIndoorCamera->fRotationYSine] + // 5[pIndoorCamera->fRotationYCosine] + fld [ebp+uNumVertices] // 0[(a1a[i].y - pIndoorCamera->pos.y)] + // 1[pIndoorCamera->fRotationYSine * (a1a[i].x - pIndoorCamera->pos.x)] + // 2[pIndoorCamera->fRotationYCosine * (a1a[i].x - pIndoorCamera->pos.x) - pIndoorCamera->fRotationYSine * (a1a[i].y - pIndoorCamera->pos.y)] + // 3[(a1a[i].z - pIndoorCamera->pos.z)] + // 4[pIndoorCamera->fRotationXCosine] + // 5[pIndoorCamera->fRotationYSine] + // 6[pIndoorCamera->fRotationYCosine] + fmul st, st(6) // 0[pIndoorCamera->fRotationYCosine * (a1a[i].y - pIndoorCamera->pos.y)] + // 1[pIndoorCamera->fRotationYSine * (a1a[i].x - pIndoorCamera->pos.x)] + // 2[pIndoorCamera->fRotationYCosine * (a1a[i].x - pIndoorCamera->pos.x) - pIndoorCamera->fRotationYSine * (a1a[i].y - pIndoorCamera->pos.y)] + // 3[(a1a[i].z - pIndoorCamera->pos.z)] + // 4[pIndoorCamera->fRotationXCosine] + // 5[pIndoorCamera->fRotationYSine] + // 6[pIndoorCamera->fRotationYCosine] + faddp st(1), st // 0[pIndoorCamera->fRotationYCosine * (a1a[i].y - pIndoorCamera->pos.y) + pIndoorCamera->fRotationYSine * (a1a[i].x - pIndoorCamera->pos.x)] + // 1[pIndoorCamera->fRotationYCosine * (a1a[i].x - pIndoorCamera->pos.x) - pIndoorCamera->fRotationYSine * (a1a[i].y - pIndoorCamera->pos.y)] + // 2[(a1a[i].z - pIndoorCamera->pos.z)] + // 3[pIndoorCamera->fRotationXCosine] + // 4[pIndoorCamera->fRotationYSine] + // 5[pIndoorCamera->fRotationYCosine] + }*/ + st0 = cos_y * (a1a[i].vWorldPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y) + sin_y * (a1a[i].vWorldPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x); + st1 = cos_y * (a1a[i].vWorldPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x) - sin_y * (a1a[i].vWorldPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y); + st2 = (a1a[i].vWorldPosition.z - pGame->pIndoorCameraD3D->vPartyPos.z); + } + + a1a[i].vWorldViewPosition.x = st1*cos_x - st2*sin_x; + a1a[i].vWorldViewPosition.y = st0; + a1a[i].vWorldViewPosition.z = st2*cos_x + st1*sin_x; + } + } + else + { + for (uint i = 0; i < uNumVertices; ++i) + { + //if ( pRenderer->pRenderD3D ) + { + /*__asm + { + fld [ebp+uNumVertices] // 0[(a1a[i].y - pIndoorCamera->pos.y)] + // 1[(a1a[i].z - pIndoorCamera->pos.z)] + // 2[sin_y] + // 3[cos_y] + fmul st, st(2) // 0[sin_y * (a1a[i].y - pIndoorCamera->pos.y)] + // 1[(a1a[i].z - pIndoorCamera->pos.z)] + // 2[sin_y] + // 3[cos_y] + fld [ebp+a1] // 0[(a1a[i].x - pIndoorCamera->pos.x)] + // 1[sin_y * (a1a[i].y - pIndoorCamera->pos.y)] + // 2[(a1a[i].z - pIndoorCamera->pos.z)] + // 3[sin_y] + // 4[cos_y] + fmul st, st(4) // 0[cos_y * (a1a[i].x - pIndoorCamera->pos.x)] + // 1[sin_y * (a1a[i].y - pIndoorCamera->pos.y)] + // 2[(a1a[i].z - pIndoorCamera->pos.z)] + // 3[sin_y] + // 4[cos_y] + faddp st(1), st // 0[cos_y * (a1a[i].x - pIndoorCamera->pos.x) + sin_y * (a1a[i].y - pIndoorCamera->pos.y)] + // 1[(a1a[i].z - pIndoorCamera->pos.z)] + // 2[sin_y] + // 3[cos_y] + fstp dword ptr [eax+0Ch] + fld [ebp+a1] // 0[(a1a[i].x - pIndoorCamera->pos.x)] + // 1[(a1a[i].z - pIndoorCamera->pos.z)] + // 2[sin_y] + // 3[cos_y] + fmul st, st(2) // 0[sin_y * (a1a[i].x - pIndoorCamera->pos.x)] + // 1[(a1a[i].z - pIndoorCamera->pos.z)] + // 2[sin_y] + // 3[cos_y] + fld [ebp+uNumVertices] // 0[(a1a[i].y - pIndoorCamera->pos.y)] + // 1[sin_y * (a1a[i].x - pIndoorCamera->pos.x)] + // 2[(a1a[i].z - pIndoorCamera->pos.z)] + // 3[sin_y] + // 4[cos_y] + fmul st, st(4) // 0[cos_y * (a1a[i].y - pIndoorCamera->pos.y)] + // 1[sin_y * (a1a[i].x - pIndoorCamera->pos.x)] + // 2[(a1a[i].z - pIndoorCamera->pos.z)] + // 3[sin_y] + // 4[cos_y] + fsubp st(1), st // 0[sin_y * (a1a[i].x - pIndoorCamera->pos.x) - cos_y * (a1a[i].y - pIndoorCamera->pos.y)] + // 1[(a1a[i].z - pIndoorCamera->pos.z)] + // 2[sin_y] + // 3[cos_y] + fstp dword ptr [eax+10h] + fstp dword ptr [eax+14h] + }*/ + a1a[i].vWorldViewPosition.x = cos_y * (a1a[i].vWorldPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x) + sin_y * (a1a[i].vWorldPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y); + a1a[i].vWorldViewPosition.y = sin_y * (a1a[i].vWorldPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x) - cos_y * (a1a[i].vWorldPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y); + a1a[i].vWorldViewPosition.z = (a1a[i].vWorldPosition.z - pGame->pIndoorCameraD3D->vPartyPos.z); + } + if (false)//else + { + __debugbreak(); + /*__asm + { + fld [ebp+a1] + fmul st, st(3) + fld [ebp+uNumVertices] + fmul st, st(3) + fsubp st(1), st + fstp dword ptr [eax+0Ch] + fld [ebp+a1] + fmul st, st(2) + fld [ebp+uNumVertices] + fmul st, st(4) + faddp st(1), st + + fstp dword ptr [eax+10h] + fstp dword ptr [eax+14h] + }*/ + } + } + } + } + else for (uint i = 0; i < uNumVertices; ++i) + //pIndoorCamera->ViewTransform_ODM(a1a + i); + { + //ViewTransform_ODM(a1a + i); + + RenderVertexSoft* a1 = &a1a[i]; + //----- (00481CCE) -------------------------------------------------------- + //void ViewTransform_ODM(RenderVertexSoft *a1) + { + float result; // eax@1 + double vCamToVertexZ; // st7@1 + double v3; // st6@1 + double v4; // st5@1 + double v5; // st4@1 + float v6; // ST04_4@3 + float v7; // [sp+0h] [bp-14h]@1 + float v8; // [sp+8h] [bp-Ch]@1 + float vCamToVertexX; // [sp+Ch] [bp-8h]@1 + float vCamToVertexY; // [sp+10h] [bp-4h]@1 + + v8 = fRotationXCosine; + result = fRotationXSine; + v7 = fRotationXSine; + vCamToVertexX = a1->vWorldPosition.x - (double)pGame->pIndoorCameraD3D->vPartyPos.x; + vCamToVertexY = a1->vWorldPosition.y - (double)pGame->pIndoorCameraD3D->vPartyPos.y; + vCamToVertexZ = a1->vWorldPosition.z - (double)pGame->pIndoorCameraD3D->vPartyPos.z; + v3 = fRotationYCosine; + v4 = fRotationYSine; + v5 = vCamToVertexY * fRotationYSine + fRotationYCosine * vCamToVertexX; + if (pGame->pIndoorCameraD3D->sRotationX) + { + v6 = vCamToVertexY * fRotationYSine + fRotationYCosine * vCamToVertexX; + a1->vWorldViewPosition.x = v5 * fRotationXCosine + fRotationXSine * vCamToVertexZ; + a1->vWorldViewPosition.y = v3 * vCamToVertexY - v4 * vCamToVertexX; + a1->vWorldViewPosition.z = v8 * vCamToVertexZ - v6 * v7; + } + else + { + a1->vWorldViewPosition.x = vCamToVertexY * fRotationYSine + fRotationYCosine * vCamToVertexX; + a1->vWorldViewPosition.y = v3 * vCamToVertexY - v4 * vCamToVertexX; + a1->vWorldViewPosition.z = vCamToVertexZ; + } + } + } +} + + +//----- (00436932) -------------------------------------------------------- +bool IndoorCameraD3D::GetFacetOrientation(char polyType, Vec3_float_ *a2, Vec3_float_ *a3, Vec3_float_ *a4) +{ + switch ((PolygonType)polyType) + { + case POLYGON_VerticalWall: + { + a4->x = -a2->y; + a4->y = a2->x; + a4->z = 0.0; + + a3->x = 0.0; + a3->y = 0.0; + a3->z = 1.0f; + } + return true; + + case POLYGON_Floor: + case POLYGON_Ceiling: + { + a4->x = 1.0; + a4->y = 0.0; + a4->z = 0.0; + + a3->x = 0.0; + a3->y = 1.0; + a3->z = 0.0; + } + return true; + + case POLYGON_InBetweenFloorAndWall: + case POLYGON_InBetweenCeilingAndWall: + { + if (fabs(a2->z) < 0.70811361) + { + a4->x = -a2->y; + a4->y = a2->x; + a4->z = 0.0; + a4->Normalize(); + + a3->x = 0.0; + a3->y = 0.0; + a3->z = 1.0; + } + else + { + a4->x = 1.0; + a4->y = 0.0; + a4->z = 0.0; + + a3->x = 0.0; + a3->y = 1.0; + a3->z = 0.0; + } + } + return true; + + default: + return false; + } +} + +//----- (00438258) -------------------------------------------------------- +bool IndoorCameraD3D::is_face_faced_to_camera(BLVFace *pFace, RenderVertexSoft *a2) +{ + if (pFace->Portal()) + return false; + + //really strange cull; dot(to_cam, normal) < 0 means we see the BACK face, not font %_% + if ( (a2->vWorldPosition.z - (double)pGame->pIndoorCameraD3D->vPartyPos.z) * (double)pFace->pFacePlane_old.vNormal.z + + (a2->vWorldPosition.y - (double)pGame->pIndoorCameraD3D->vPartyPos.y) * (double)pFace->pFacePlane_old.vNormal.y + + (a2->vWorldPosition.x - (double)pGame->pIndoorCameraD3D->vPartyPos.x) * (double)pFace->pFacePlane_old.vNormal.x < 0.0) + return false; + + return true; +} + + +//----- (00437AB5) -------------------------------------------------------- +void IndoorCameraD3D::do_draw_debug_line_sw(RenderVertexSoft *pLineBegin, signed int sStartDiffuse, RenderVertexSoft *pLineEnd, signed int sEndDiffuse, unsigned int uOutNumVertices, float z_stuff) +{ + RenderVertexSoft a1[20]; // [sp+8h] [bp-7C4h]@6 + RenderVertexSoft pVertices[20]; // [sp+3C8h] [bp-404h]@2 + RenderVertexD3D3 v24[2]; // [sp+788h] [bp-44h]@11 + + //if ( pRenderer->pRenderD3D ) + //{ + for ( uint i = 0; i < 20; i++ ) + pVertices[i].flt_2C = 0.0; + if ( (char)uOutNumVertices ) + { + pVertices[0].vWorldViewProjX = pLineBegin->vWorldViewProjX; + pVertices[0].vWorldViewProjY = pLineBegin->vWorldViewProjY; + + pVertices[1].vWorldViewProjX = pLineEnd->vWorldViewProjX; + pVertices[1].vWorldViewProjY = pLineEnd->vWorldViewProjY; + v24[0].specular = 0; + v24[0].pos.x = pVertices[0].vWorldViewProjX; + v24[0].pos.y = pVertices[0].vWorldViewProjY; + v24[0].pos.z = 0.001 - z_stuff; + v24[0].diffuse = sStartDiffuse; + v24[0].rhw = 0.001; + v24[0].texcoord.x = 0.0; + v24[0].texcoord.y = 0.0; + + v24[1].pos.x = pVertices[1].vWorldViewProjX; + v24[1].pos.y = pVertices[1].vWorldViewProjY; + v24[1].diffuse = sEndDiffuse; + v24[1].pos.z = 0.001 - z_stuff; + v24[1].specular = 0; + v24[1].rhw = 0.001; + v24[1].texcoord.x = 0.0; + v24[1].texcoord.y = 0.0; + //v19 = pRenderer->pRenderD3D->pDevice; + pRenderer->DrawLines(v24, 2); + return; + } + for ( uint i = 0; i < 20; i++ ) + a1[i].flt_2C = 0.0; + uOutNumVertices = 2; + a1[0].vWorldPosition.x = pLineBegin->vWorldPosition.x; + a1[0].vWorldPosition.y = pLineBegin->vWorldPosition.y; + a1[0].vWorldPosition.z = pLineBegin->vWorldPosition.z; + a1[1].vWorldPosition.x = pLineEnd->vWorldPosition.x; + a1[1].vWorldPosition.y = pLineEnd->vWorldPosition.y; + a1[1].vWorldPosition.z = pLineEnd->vWorldPosition.z; + if ( CalcPortalShape(a1, &uOutNumVertices, pVertices, this->std__vector_000034_prolly_frustrum, 4, 1, 0) != 1 || (signed int)uOutNumVertices >= 2 ) + { + ViewTransform(pVertices, 2); + Project(pVertices, 2, 0); + v24[0].specular = 0; + v24[0].pos.x = pVertices[0].vWorldViewProjX; + v24[0].pos.y = pVertices[0].vWorldViewProjY; + v24[0].pos.z = 0.001 - z_stuff; + v24[0].diffuse = sStartDiffuse; + v24[0].rhw = 0.001; + v24[0].texcoord.x = 0.0; + v24[0].texcoord.y = 0.0; + + v24[1].pos.x = pVertices[1].vWorldViewProjX; + v24[1].pos.y = pVertices[1].vWorldViewProjY; + v24[1].diffuse = sEndDiffuse; + v24[1].pos.z = 0.001 - z_stuff; + v24[1].specular = 0; + v24[1].rhw = 0.001; + v24[1].texcoord.x = 0.0; + v24[1].texcoord.y = 0.0; + //v19 = pRenderer->pRenderD3D->pDevice; + pRenderer->DrawLines(v24, 2); + return; + } + //} +} + +//----- (00437A55) -------------------------------------------------------- +void IndoorCameraD3D::debug_outline_d3d(const RenderVertexD3D3 *pLineVertices, unsigned int uNumLines, int uDiffuse, float z_stuff) +{ + unsigned int v5; // esi@1 + const RenderVertexD3D3 *v6; // ecx@2 + unsigned int v7; // ebx@2 + const RenderVertexD3D3 *v8; // edi@3 + + v5 = 0; + if ( (signed int)(uNumLines - 1) > 0 ) + { + v6 = pLineVertices; + v5 = uNumLines - 1; + for ( v7 = uNumLines - 1; v7; --v7 ) + { + v8 = v6 + 1; + pRenderer->do_draw_debug_line_d3d(v6, uDiffuse, v6 + 1, uDiffuse, z_stuff); + v6 = v8; + } + } + pRenderer->do_draw_debug_line_d3d(&pLineVertices[v5], uDiffuse, pLineVertices, uDiffuse, z_stuff); +} + +//----- (004379EE) -------------------------------------------------------- +void IndoorCameraD3D::debug_outline_sw(RenderVertexSoft *a2, unsigned int uNumVertices, unsigned int uDiffuse, float a5) +{ + if ( !uNumVertices ) + return; + if ( (signed int)(uNumVertices - 1) > 0 ) + { + for ( uint i = 0; i < uNumVertices - 1; i++ ) + do_draw_debug_line_sw(&a2[i], uDiffuse, &a2[i + 1], uDiffuse, 0, a5); + } + do_draw_debug_line_sw(&a2[uNumVertices - 1], uDiffuse, a2, uDiffuse, 0, a5); +} + + +void IndoorCameraD3D::DebugDrawPortal(BLVFace *pFace) +{ + Assert(pFace->uNumVertices <= 32); + + RenderVertexSoft sw[32]; + for (uint i = 0; i < pFace->uNumVertices; ++i) + { + sw[i].vWorldPosition.x = pIndoor->pVertices[pFace->pVertexIDs[i]].x; + sw[i].vWorldPosition.y = pIndoor->pVertices[pFace->pVertexIDs[i]].y; + sw[i].vWorldPosition.z = pIndoor->pVertices[pFace->pVertexIDs[i]].z; + } + ViewTransform(sw, pFace->uNumVertices); + Project(sw, pFace->uNumVertices, 0); + + + + RenderVertexD3D3 v[32]; + for (uint i = 0; i < pFace->uNumVertices; ++i) + { + v[i].pos.x = sw[i].vWorldViewProjX; + v[i].pos.y = sw[i].vWorldViewProjY; + v[i].pos.z = 1.0 - 1.0 / (sw[i].vWorldViewPosition.x * 0.061758894); + v[i].rhw = 1.0 / sw[i].vWorldViewPosition.x; + v[i].diffuse = 0x80F020F0; + v[i].specular = 0; + //v[i].texcoord.x = pFace->pVertexUIDs[i] / (double)pTex->uTextureWidth; + //v[i].texcoord.y = pFace->pVertexUIDs[i] / (double)pTex->uTextureHeight; + v[i].texcoord.x = 0; + v[i].texcoord.y = 0; + } + + pRenderer->DrawFansTransparent(v, pFace->uNumVertices); +} + +//----- (00437906) -------------------------------------------------------- +void IndoorCameraD3D::PrepareAndDrawDebugOutline(BLVFace *pFace, unsigned int uDiffuse) +{ + static RenderVertexSoft static_sub_437906_array_50CDD0[64]; + static bool __init_flag1 = false; + if (!__init_flag1) + { + __init_flag1 = true; + + for (uint i = 0; i < 64; ++i) + static_sub_437906_array_50CDD0[i].flt_2C = 0.0f; + } + if ( pFace->uNumVertices ) + { + for ( uint i = 0; i < pFace->uNumVertices; i++ ) + { + static_sub_437906_array_50CDD0[i].vWorldPosition.x = (double)pIndoor->pVertices[pFace->pVertexIDs[i]].x; + static_sub_437906_array_50CDD0[i].vWorldPosition.y = (double)pIndoor->pVertices[pFace->pVertexIDs[i]].y; + static_sub_437906_array_50CDD0[i].vWorldPosition.z = (double)pIndoor->pVertices[pFace->pVertexIDs[i]].z; + static_sub_437906_array_50CDD0[i].u = (double)pFace->pVertexUIDs[i]; + static_sub_437906_array_50CDD0[i].v = (double)pFace->pVertexVIDs[i]; + } + } + if ( draw_portals_loops ) + debug_outline_sw(static_sub_437906_array_50CDD0, pFace->uNumVertices, uDiffuse, 0.0); +} +// 50D9D0: using guessed type char static_sub_437906_byte_50D9D0_init_flag; + +//----- (004378BA) -------------------------------------------------------- +void IndoorCameraD3D::MatrixMultiply(Matrix3x3_float_ *ma, Matrix3x3_float_ *mb, Matrix3x3_float_ *m_out) +{ + float sum; + + for ( uint row = 0; row < 3; row++ ) + { + for ( uint col = 0; col < 3; col++ ) + { + sum = 0; + for ( int index = 0; index < 3; index++ ) + sum += ma->v[row][index]*mb->v[index][col]; + m_out->v[row][col] = sum; + } + } +} + +//----- (004376E7) -------------------------------------------------------- +void IndoorCameraD3D::CreateWorldMatrixAndSomeStuff() +{ + Matrix3x3_float_ m1; // [sp+10h] [bp-B8h]@1 + Matrix3x3_float_ m2; // [sp+34h] [bp-94h]@1 + Matrix3x3_float_ m3; // [sp+58h] [bp-70h]@1 + Matrix3x3_float_ m4; // [sp+7Ch] [bp-4Ch]@1 + Matrix3x3_float_ m5; // [sp+A0h] [bp-28h]@1 + + //RotationZ(0) + m5._11 = cosf(0); m5._12 = sinf(0); m5._13 = 0; + m5._21 = -sinf(0); m5._22 = cosf(0); m5._23 = 0; + m5._31 = 0; m5._32 = 0; m5._33 = 1; + + float cos_x1 = fRotationXCosine, + sin_x1 = fRotationXSine; + //RotationX(x) + m4._11 = 1; m4._12 = 0; m4._13 = 0; + m4._21 = 0; m4._22 = cos_x1; m4._23 = sin_x1; + m4._31 = 0; m4._32 = -sin_x1; m4._33 = cos_x1; + + float cos_y1 = fRotationYCosine, + sin_y1 = fRotationYSine; + //RotationY(some_angle) + m3._11 = cos_y1; m3._12 = 0; m3._13 = -sin_y1; + m3._21 = 0; m3._22 = 1; m3._23 = 0; + m3._31 = sin_y1; m3._32 = 0; m3._33 = cos_y1; + + MatrixMultiply(&m5, &m3, &m1); + MatrixMultiply(&m4, &m1, &m2); + + for (uint i = 0; i < 3; ++i) + { + field_4[0].v[i] = m2.v[1][i]; + field_4[1].v[i] = m2.v[0][i]; + field_4[2].v[i] = m2.v[2][i]; + } + + inv_fov = 1.1344639; + fov_x = (double)pViewport->uScreenWidth * 0.8814736; + + fov_y = 0.8814736 * (double)pViewport->uScreenHeight; + fov = fov_y; + if ( fov_x > fov ) + fov = fov_x; + screenCenterX = (double)pViewport->uScreenCenterX; + screenCenterY = (double)(pViewport->uScreenCenterY - pViewport->uScreen_TL_Y); +} + +//----- (00437691) -------------------------------------------------------- +void IndoorCameraD3D::Vec3Transform(const IndoorCameraD3D_Vec3 *pVector, IndoorCameraD3D_Vec3 *pOut) +{ + pOut->y = field_4[1].x * pVector->x + field_4[0].x * pVector->y + field_4[2].x * pVector->z; + pOut->z = field_4[1].y * pVector->x + field_4[0].y * pVector->y + field_4[2].y * pVector->z; + pOut->x = field_4[1].z * pVector->x + field_4[0].z * pVector->y + field_4[2].z * pVector->z; +} + +//----- (00437607) -------------------------------------------------------- +void IndoorCameraD3D::_437607(IndoorCameraD3D_Vec3 *a1, IndoorCameraD3D_Vec4 *a2) +{ + double v4; // st7@1 + IndoorCameraD3D_Vec3 v8; // [sp+8h] [bp-1Ch]@1 + + v8.x = (double)pGame->pIndoorCameraD3D->vPartyPos.x; + v8.y = (double)pGame->pIndoorCameraD3D->vPartyPos.y; + v8.z = (double)pGame->pIndoorCameraD3D->vPartyPos.z; + Vec3Transform(a1, a2); + + v4 = v8.x * a2->x + v8.y * a2->y + v8.z * a2->z; + a2->dot = v4 + 0.000099999997; +} + +//----- (004374E8) -------------------------------------------------------- +void IndoorCameraD3D::_4374E8_ProllyBuildFrustrum() +{ + //IndoorCameraD3D *v1; // esi@1 + //double v2; // st7@1 + double v3; // st7@1 + //double v4; // st7@1 + double v5; // st7@1 + //double v6; // st7@1 + IndoorCameraD3D_Vec3 v7; // [sp+Ch] [bp-24h]@1 + //float v8; // [sp+10h] [bp-20h]@1 + //float v9; // [sp+14h] [bp-1Ch]@1 + //float v10; // [sp+18h] [bp-18h]@1 + //float v11; // [sp+1Ch] [bp-14h]@1 + //float v12; // [sp+20h] [bp-10h]@1 + //int v13; // [sp+2Ch] [bp-4h]@1 + + //v1 = this; + //IndoorCameraD3D_Vec3::IndoorCameraD3D_Vec3(&v7); + //v2 = 2.0 / inv_fov; + //v13 = 0; + v3 = atan(2.0 / inv_fov * fov / fov_x); + //v12 = v3; + //v11 = sin(v3); + //v4 = cos(v3); + v7.x = -sin(v3); + v7.y = 0.0; + v7.z = cos(v3); + _437607(&v7, std__vector_000034_prolly_frustrum + 0); + v7.x = sin(v3); + _437607(&v7, std__vector_000034_prolly_frustrum + 1); + v5 = atan(2.0 / inv_fov * fov / (fov_y + 0.5)); + //v12 = v5; + //v11 = sin(v5); + //v6 = cos(v5); + v7.y = sin(v5); + v7.x = 0.0; + v7.z = cos(v5); + _437607(&v7, &std__vector_000034_prolly_frustrum[2]); + v7.y = -sin(v5); + _437607(&v7, &std__vector_000034_prolly_frustrum[3]); + //v13 = -1; + //IndoorCameraD3D_Vec3::dtor(&v7); +} + +//----- (00437376) -------------------------------------------------------- +char IndoorCameraD3D::_437376(stru154 *thisa, RenderVertexSoft *a2, unsigned int *pOutNumVertices) +{ + //unsigned int v4; // ebx@1 + //RenderVertexSoft *v5; // edx@2 + double v6; // st7@3 + //unsigned int v7; // edi@5 + signed int v8; // esi@6 + int v9; // ebx@8 + int v10; // eax@8 + //int v11; // ecx@14 + //int v12; // eax@14 + int v13; // eax@15 + signed int v14; // ebx@17 + //RenderVertexSoft *v15; // eax@18 + unsigned int *v16; // eax@20 +// char result; // al@24 + RenderVertexSoft v18; // [sp+Ch] [bp-34h]@2 + int v19; // [sp+3Ch] [bp-4h]@8 + signed int thisb; // [sp+48h] [bp+8h]@6 + bool a2_3; // [sp+4Fh] [bp+Fh]@5 + + //v4 = *pOutNumVertices; + //v5 = a2; + memcpy(&v18, a2, sizeof(v18)); + a2_3 = false; + memcpy(&a2[*pOutNumVertices], a2, sizeof(a2[*pOutNumVertices])); + memcpy(&a2[*pOutNumVertices + 1], &a2[1], sizeof(a2[*pOutNumVertices + 1])); + //v7 = *pOutNumVertices; + + if ( (signed int)*pOutNumVertices <= 3 + || (((v18.vWorldPosition.z - (double)pGame->pIndoorCameraD3D->vPartyPos.z) * thisa->face_plane.vNormal.z + + (v18.vWorldPosition.y - (double)pGame->pIndoorCameraD3D->vPartyPos.y) * thisa->face_plane.vNormal.y + + (v18.vWorldPosition.x - (double)pGame->pIndoorCameraD3D->vPartyPos.x) * thisa->face_plane.vNormal.x < 0.0) ? (v6 = 1.0) : (v6 = -1.0), + (signed int)*pOutNumVertices <= 0) ) + return 0; + v8 = 1; + for ( thisb = 1; thisb - 1 < (signed int)*pOutNumVertices; v8 = thisb ) + { + v9 = v8 - 1; + v10 = v8 + 1; + v19 = v8 + 1; + if ( v8 - 1 >= (signed int)*pOutNumVertices ) + v9 -= *pOutNumVertices; + if ( v8 >= (signed int)*pOutNumVertices ) + v8 -= *pOutNumVertices; + if ( v19 >= (signed int)*pOutNumVertices ) + v10 = v19 - *pOutNumVertices; + //v11 = (int)&a2[v10]; + //v12 = (int)&a2[v9]; + if ( -0.009999999776482582 > ((a2[v8].vWorldViewProjX - a2[v9].vWorldViewProjX) + * (a2[v10].vWorldViewProjY - a2[v9].vWorldViewProjY) + - (a2[v8].vWorldViewProjY - a2[v9].vWorldViewProjY) + * (a2[v10].vWorldViewProjX - a2[v9].vWorldViewProjX)) + * v6 ) + { + thisb = v19; + v16 = pOutNumVertices; + } + else + { + v13 = thisb; + if ( thisb >= (signed int)*pOutNumVertices ) + v13 = thisb - *pOutNumVertices; + if ( v13 < (signed int)*pOutNumVertices ) + { + for ( v14 = v13; v14 < (signed int)*pOutNumVertices; ++v14 ) + memcpy(&a2[v14], &a2[v14 + 1], sizeof(a2[v14])); + } + v16 = pOutNumVertices; + a2_3 = true; + --*v16; + } + *pOutNumVertices = *v16; + //if ( thisb - 1 >= (signed int)*v16 ) + //break; + } + if ( a2_3 ) + return true; + else + return false; +} + +//----- (00437285) -------------------------------------------------------- +bool IndoorCameraD3D::CalcPortalShape(RenderVertexSoft *a1, unsigned int *pOutNumVertices, RenderVertexSoft *pVertices, IndoorCameraD3D_Vec4 *a4, signed int uNumVertices, char a6, int _unused) +{ +// char *v8; // eax@2 +// signed int v9; // ecx@2 + //bool result; // eax@5 + int v11; // ecx@5 + //signed int v12; // ecx@6 + //char *v13; // esi@6 + RenderVertexSoft *v14; // eax@8 + RenderVertexSoft *v15; // edx@8 + Vec3_float_ a5; // [sp+18h] [bp-3Ch]@12 + //float v17; // [sp+44h] [bp-10h]@1 + //int v18; // [sp+48h] [bp-Ch]@5 + //stru9 *thisa; // [sp+4Ch] [bp-8h]@1 + int a7a; // [sp+53h] [bp-1h]@5 + //bool a6a; // [sp+70h] [bp+1Ch]@5 + + //v17 = 0.0; + //thisa = pGame->pStru9Instance; + + static RenderVertexSoft sr_vertices_50D9D8[64]; + + //result = 0; + a7a = 0; + v11 = 2 * (a6 == 0) + 1; + //a6a = 0; + //v18 = v11; + if (uNumVertices <= 0) + return false; + + //v12 = *pOutNumVertices; + //v13 = (char *)&a4->y; + + //while ( 1 ) + for ( uint i = 0; i < uNumVertices; ++i ) + { + if (i % 2) + { + v14 = a1; + v15 = sr_vertices_50D9D8; + } + else + { + v15 = a1; + v14 = sr_vertices_50D9D8; + } + if (i == uNumVertices - 1) + v14 = pVertices; + a5.x = a4[i].x; + a5.y = a4[i].y; + a5.z = a4[i].z; + pGame->pStru9Instance->CalcPortalShape(v15, *pOutNumVertices, v14, pOutNumVertices, &a5, a4[i].dot, (char *)&a7a, _unused); + //v12 = *pOutNumVertices; + if (*pOutNumVertices < v11) + { + *pOutNumVertices = 0; + return true; + } + //result = a6a; + //v13 += 24; + //if (++i >= uNumVertices) + // + } + return a7a; +} + +//----- (004371C3) -------------------------------------------------------- +bool IndoorCameraD3D::_4371C3(RenderVertexSoft *pVertices, unsigned int *pOutNumVertices, int _unused) +{ +// char *v4; // eax@2 +// signed int v5; // ecx@2 + RenderVertexSoft *v6; // esi@5 + unsigned int *v7; // edi@5 + char *v8; // ecx@6 + int v9; // eax@6 + IndoorCameraD3D *thisa; // [sp+0h] [bp-Ch]@1 + signed int v12; // [sp+4h] [bp-8h]@5 + unsigned int pVerticesa; // [sp+14h] [bp+8h]@6 + unsigned int pOutNumVerticesa; // [sp+18h] [bp+Ch]@6 + + thisa = this; + + + static RenderVertexSoft static_4371C3_array_50E5E0[64]; + static bool __init_flag1 = false; + if (!__init_flag1) + { + __init_flag1 = true; + + for (uint i = 0; i < 64; ++i) + static_4371C3_array_50E5E0[i].flt_2C = 0.0f; + } + + v12 = 0; + v6 = pVertices; + v7 = pOutNumVertices; + if ( (signed int)*pOutNumVertices > 0 ) + { + pOutNumVerticesa = (char *)static_4371C3_array_50E5E0 - (char *)pVertices; + pVerticesa = (char *)&static_4371C3_array_50E5E0[0].vWorldViewProjY - (char *)pVertices; + v8 = (char *)&static_4371C3_array_50E5E0[0].vWorldPosition.y; + v9 = (int)&v6->vWorldPosition.z; + do + { + ++v12; + *((int *)v8 - 1) = *(int *)(v9 - 8); + *(int *)v8 = *(int *)(v9 - 4); + v8 += 48; + *(float *)(pOutNumVerticesa + v9) = *(float *)v9; + *(float *)(pVerticesa + v9) = *(float *)(v9 + 28); + *(float *)((char *)&static_4371C3_array_50E5E0[0]._rhw - (char *)v6 + v9) = *(float *)(v9 + 32); + v9 += 48; + } + while ( v12 < (signed int)*v7 ); + } + return CalcPortalShape( + static_4371C3_array_50E5E0, + v7, + v6, + thisa->std__vector_000034_prolly_frustrum, + 4, + 0, + _unused); +} +// 50F1E0: using guessed type char static_sub_4371C3_byte_50F1E0_init_flags; + +//----- (00437143) -------------------------------------------------------- +void IndoorCameraD3D::_437143(unsigned int uNumInVertices, RenderVertexSoft *pOutVertices, RenderVertexSoft *pInVertices, unsigned int *pOutNumVertices) +{ + double v9; // st7@3 + + uint i = 0; + + for ( i; i < uNumInVertices; ++i ) + { + pInVertices[i]._rhw = 1.0 / (pInVertices[i].vWorldViewPosition.x + 0.0000001); + memcpy(&pOutVertices[i], &pInVertices[i], sizeof(pOutVertices[i])); + v9 = (double)pODMRenderParams->int_fov_rad * pInVertices[i]._rhw; + pOutVertices[i].vWorldViewProjX = (double)pViewport->uScreenCenterX - v9 * pInVertices[i].vWorldViewPosition.y; + pOutVertices[i].vWorldViewProjY = (double)pViewport->uScreenCenterY - v9 * pInVertices[i].vWorldViewPosition.z; + } + *pOutNumVertices = i; + return; +} + +//----- (00436F09) -------------------------------------------------------- +void IndoorCameraD3D::_436F09_mess_with_lightmap__clipflag_4(RenderVertexSoft *pInVertices, int uNumInVertices, RenderVertexSoft *pOutVertices, unsigned int *pOutNumVertices) +{ + unsigned int *pOutNumVertices_; // ebx@1 + double v6; // st7@2 + signed int v7; // esi@2 + char *v8; // edx@5 + unsigned int v9; // eax@10 + RenderVertexSoft *v10; // ecx@11 + double v11; // st6@11 + double v12; // st6@12 + unsigned int v13; // edi@14 + unsigned __int8 v14; // c2@16 + unsigned __int8 v15; // c3@16 + unsigned int v16; // edi@17 + bool a1a; // [sp+Ch] [bp+8h]@7 + int a4a; // [sp+18h] [bp+14h]@5 + + pOutNumVertices_ = pOutNumVertices; + *pOutNumVertices = 0; + if ( uNumInVertices ) + { + memcpy(&pInVertices[uNumInVertices], pInVertices, sizeof(pInVertices[uNumInVertices])); + v6 = (double)pODMRenderParams->shading_dist_mist; + v7 = 0; + if ( v6 >= pInVertices->vWorldViewPosition.x ) + v7 = 1; + if ( uNumInVertices + 1 > 1 ) + { + a4a = uNumInVertices; + v8 = (char *)&pInVertices[1].u; + do + { + a1a = v6 >= *((float *)v8 - 6); + if ( v7 == a1a ) + { + v10 = pOutVertices; + //goto LABEL_23; + } + else + { + + v9 = *pOutNumVertices_; + if (a1a) + { + v10 = pOutVertices; + v11 = (v6 - *((float *)v8 - 18)) / (*((float *)v8 - 6) - *((float *)v8 - 18)); + pOutVertices[v9].vWorldViewPosition.y = (*((float *)v8 - 5) - *((float *)v8 - 17)) * v11 + *((float *)v8 - 17); + pOutVertices[*pOutNumVertices_].vWorldViewPosition.z = (*((float *)v8 - 4) - *((float *)v8 - 16)) * v11 + + *((float *)v8 - 16); + pOutVertices[*pOutNumVertices_].u = (*(float *)v8 - *((float *)v8 - 12)) * v11 + *((float *)v8 - 12); + pOutVertices[*pOutNumVertices_].v = (*((float *)v8 + 1) - *((float *)v8 - 11)) * v11 + *((float *)v8 - 11); + } + else + { + v12 = (v6 - *((float *)v8 - 6)) / (*((float *)v8 - 18) - *((float *)v8 - 6)); + pOutVertices[v9].vWorldViewPosition.y = (*((float *)v8 - 17) - *((float *)v8 - 5)) * v12 + *((float *)v8 - 5); + pOutVertices[*pOutNumVertices_].vWorldViewPosition.z = (*((float *)v8 - 16) - *((float *)v8 - 4)) * v12 + + *((float *)v8 - 4); + pOutVertices[*pOutNumVertices_].u = (*((float *)v8 - 12) - *(float *)v8) * v12 + *(float *)v8; + pOutVertices[*pOutNumVertices_].v = (*((float *)v8 - 11) - *((float *)v8 + 1)) * v12 + *((float *)v8 + 1); + v10 = pOutVertices; + } + v10[*pOutNumVertices_].vWorldViewPosition.x = v6; + v10[*pOutNumVertices_]._rhw = 1.0 / v6; + if (v7) + { + v13 = (unsigned int)&v10[*pOutNumVertices_]; + if (*(float *)(v13 + 12) != *((float *)v8 - 18) || *(float *)(v13 + 16) != *((float *)v8 - 17)) + { + ++*pOutNumVertices_; + //goto LABEL_23; + } + else + { + v14 = 0; + v15 = *(float *)(v13 + 20) == *((float *)v8 - 16); + if (!(v15 | v14)) + { + //goto LABEL_21; + ++*pOutNumVertices_; + //goto LABEL_23; + } + } + } + else + { + v16 = (unsigned int)&v10[*pOutNumVertices_]; + if (*(float *)(v16 + 12) != *((float *)v8 - 6) || *(float *)(v16 + 16) != *((float *)v8 - 5)) + { + //LABEL_21: + ++*pOutNumVertices_; + //goto LABEL_23; + } + else + { + v14 = 0; + v15 = *(float *)(v16 + 20) == *((float *)v8 - 4); + if (!(v15 | v14)) + { + //goto LABEL_21; + ++*pOutNumVertices_; + //goto LABEL_23; + } + } + } + } + //LABEL_23: + if ( a1a ) + { + memcpy(&v10[*pOutNumVertices_], v8 - 36, sizeof(v10[*pOutNumVertices_])); + pOutVertices[*pOutNumVertices_]._rhw = 1.0 / (*((float *)v8 - 6) + 0.0000001); + pOutVertices[(*pOutNumVertices_)++].flt_2C = *((float *)v8 + 2); + } + v7 = a1a; + v8 += 48; + --a4a; + } + while ( a4a ); + } + if ( (signed int)*pOutNumVertices_ < 3 ) + *pOutNumVertices_ = 0; + } +} + +//----- (00436CDC) -------------------------------------------------------- +void IndoorCameraD3D::_436CDC_mess_with_lightmap__clipflag_2(RenderVertexSoft *pInVertices, int uNumInVertices, RenderVertexSoft *pOutVertices, unsigned int *pOutNumVertices) +{ + signed int v5; // esi@2 + char *v6; // edx@5 + unsigned int v7; // eax@10 + RenderVertexSoft *v8; // ecx@11 + double v9; // st6@11 + double v10; // st6@12 + unsigned int v11; // edi@14 + unsigned __int8 v12; // c2@16 + unsigned __int8 v13; // c3@16 + unsigned int v14; // edi@17 + bool a1a; // [sp+Ch] [bp+8h]@7 + + if ( uNumInVertices ) + { + *pOutNumVertices = 0; + memcpy(&pInVertices[uNumInVertices], pInVertices, sizeof(pInVertices[uNumInVertices])); + v5 = 0; + if ( pInVertices->vWorldViewPosition.x >= 8.0 ) + v5 = 1; + if ( uNumInVertices + 1 > 1 ) + { + v6 = (char *)&pInVertices[1].u; + do + { + a1a = *((float *)v6 - 6) >= 8.0; + if ( v5 == a1a ) + { + v8 = pOutVertices; + goto LABEL_23; + } + v7 = *pOutNumVertices; + if ( a1a ) + { + v8 = pOutVertices; + v9 = (8.0 - *((float *)v6 - 18)) / (*((float *)v6 - 6) - *((float *)v6 - 18)); + pOutVertices[v7].vWorldViewPosition.y = (*((float *)v6 - 5) - *((float *)v6 - 17)) * v9 + *((float *)v6 - 17); + pOutVertices[*pOutNumVertices].vWorldViewPosition.z = (*((float *)v6 - 4) - *((float *)v6 - 16)) * v9 + + *((float *)v6 - 16); + pOutVertices[*pOutNumVertices].u = (*(float *)v6 - *((float *)v6 - 12)) * v9 + *((float *)v6 - 12); + pOutVertices[*pOutNumVertices].v = (*((float *)v6 + 1) - *((float *)v6 - 11)) * v9 + *((float *)v6 - 11); + } + else + { + v10 = (8.0 - *((float *)v6 - 6)) / (*((float *)v6 - 18) - *((float *)v6 - 6)); + pOutVertices[v7].vWorldViewPosition.y = (*((float *)v6 - 17) - *((float *)v6 - 5)) * v10 + *((float *)v6 - 5); + pOutVertices[*pOutNumVertices].vWorldViewPosition.z = (*((float *)v6 - 16) - *((float *)v6 - 4)) * v10 + + *((float *)v6 - 4); + pOutVertices[*pOutNumVertices].u = (*((float *)v6 - 12) - *(float *)v6) * v10 + *(float *)v6; + pOutVertices[*pOutNumVertices].v = (*((float *)v6 - 11) - *((float *)v6 + 1)) * v10 + *((float *)v6 + 1); + v8 = pOutVertices; + } + v8[*pOutNumVertices].vWorldViewPosition.x = 8.0; + v8[*pOutNumVertices]._rhw = 0.125; + if ( v5 ) + { + v11 = (unsigned int)&v8[*pOutNumVertices]; + if ( *(float *)(v11 + 12) != *((float *)v6 - 18) || *(float *)(v11 + 16) != *((float *)v6 - 17) ) + goto LABEL_21; + v12 = 0; + v13 = *(float *)(v11 + 20) == *((float *)v6 - 16); + } + else + { + v14 = (unsigned int)&v8[*pOutNumVertices]; + if ( *(float *)(v14 + 12) != *((float *)v6 - 6) || *(float *)(v14 + 16) != *((float *)v6 - 5) ) + { +LABEL_21: + ++*pOutNumVertices; + goto LABEL_23; + } + v12 = 0; + v13 = *(float *)(v14 + 20) == *((float *)v6 - 4); + } + if ( !(v13 | v12) ) + goto LABEL_21; +LABEL_23: + if ( a1a ) + { + memcpy(&v8[*pOutNumVertices], v6 - 36, sizeof(v8[*pOutNumVertices])); + pOutVertices[(*pOutNumVertices)++]._rhw = 1.0 / (*((float *)v6 - 6) + 0.0000001); + } + v5 = a1a; + v6 += 48; + --uNumInVertices; + } + while ( uNumInVertices ); + } + if ( (signed int)*pOutNumVertices < 3 ) + *pOutNumVertices = 0; + } +} + +//----- (00481D77) -------------------------------------------------------- +void _outdoor_project(RenderVertexSoft *v) +{ + double v1; // st7@1 + double v2; // st7@1 + + v1 = 1.0 / (v->vWorldViewPosition.x + 0.0000001); + v->_rhw = v1; + v2 = v1 * (double)pODMRenderParams->int_fov_rad; + v->vWorldViewProjX = (double)pViewport->uScreenCenterX - v2 * v->vWorldViewPosition.y; + v->vWorldViewProjY = (double)pViewport->uScreenCenterY - v2 * v->vWorldViewPosition.z; +} + +//----- (00436BB7) -------------------------------------------------------- +void IndoorCameraD3D::Project(RenderVertexSoft *pVertices, unsigned int uNumVertices, char a4) +{ + double v7; // st7@7 + double v8; // st7@9 + double v9; // st6@10 + double v10; // st5@12 + double v11; // st7@16 + double v12; // st6@17 + double v13; // st5@19 + float uNumVerticesa; // [sp+14h] [bp+Ch]@13 + float uNumVerticesb; // [sp+14h] [bp+Ch]@20 + + for (uint i = 0; i < uNumVertices; ++i) + { + if (byte_4D864C && pGame->uFlags & 0x80 || uCurrentlyLoadedLevelType == LEVEL_Indoor) + { + v7 = 1.0 / pVertices[i].vWorldViewPosition.x; + + pVertices[i].vWorldViewProjX = pVertices[i].vWorldViewPosition.y * fov * v7 + screenCenterX; + pVertices[i].vWorldViewProjY = (signed int)pViewport->uViewportBR_Y - (pVertices[i].vWorldViewPosition.z * fov * v7 + screenCenterY); + } + else + { + extern void _outdoor_project(RenderVertexSoft *v); + _outdoor_project(pVertices + i); + } + + if ( a4 ) + { +// __debugbreak(); + v8 = (double)(signed int)pViewport->uViewportBR_X; + if ( v8 >= pVertices[i].vWorldViewProjX ) + v9 = pVertices[i].vWorldViewProjX; + else + v9 = v8; + v10 = (double)(signed int)pViewport->uViewportTL_X; + if ( v10 <= v9 ) + { + if ( v8 >= pVertices[i].vWorldViewProjX) + v8 = pVertices[i].vWorldViewProjX; + } + else + { + uNumVerticesa = v10; + v8 = uNumVerticesa; + } + pVertices[i].vWorldViewProjX = v8; + v11 = (double)(signed int)pViewport->uViewportBR_Y; + if ( v11 >= pVertices[i].vWorldViewProjY) + v12 = pVertices[i].vWorldViewProjY; + else + v12 = v11; + v13 = (double)(signed int)pViewport->uViewportTL_Y; + if ( v13 <= v12 ) + { + if ( v11 >= pVertices[i].vWorldViewProjY) + v11 = pVertices[i].vWorldViewProjY; + } + else + { + uNumVerticesb = v13; + v11 = uNumVerticesb; + } + pVertices[i].vWorldViewProjY = v11; + } + } +} + +//----- (00436A9A) -------------------------------------------------------- +void IndoorCameraD3D::Project(signed int x, signed int y, signed int z, int *a5, int *a6) +{ + double v6; // ST00_8@2 + //double v7; // ST08_8@2 + //double v8; // ST00_8@2 +// signed __int64 v9; // qtt@3 +// int v10; // ST04_4@3 + float a2a; // [sp+18h] [bp+8h]@2 + float a2b; // [sp+18h] [bp+8h]@2 + + //if ( pRenderer->pRenderD3D ) + { + v6 = 1.0 / (double)x; + a2a = (double)y * fov * v6 + screenCenterX; + //v7 = a2a + 6.7553994e15; + *a5 = floorf(a2a + 0.5f); + a2b = (double)z * fov * v6 + screenCenterY; + //v8 = a2b + 6.7553994e15; + *a6 = pViewport->uViewportBR_Y - floorf(a2b + 0.5f); + } + /*else + { + LODWORD(v9) = pBLVRenderParams->fov_rad_fixpoint << 16; + HIDWORD(v9) = pBLVRenderParams->fov_rad_fixpoint >> 16; + v10 = v9 / x; + LODWORD(v9) = pBLVRenderParams->fov_rad_fixpoint << 16; + HIDWORD(v9) = pBLVRenderParams->fov_rad_fixpoint >> 16; + *a5 = pBLVRenderParams->uViewportCenterX + - ((signed int)(((unsigned __int64)(v10 * (signed __int64)y) >> 16) + 32768) >> 16); + *a6 = pBLVRenderParams->uViewportCenterY - ((signed int)(((unsigned __int64)(v9 / x * z) >> 16) + 32768) >> 16); + }*/ +} + +//----- (00436A6D) -------------------------------------------------------- +double IndoorCameraD3D::GetPolygonMinZ(RenderVertexSoft *pVertices, unsigned int uStripType) +{ + unsigned int v3; // edx@1 + double result; // st7@1 + float *v5; // ecx@2 + + v3 = uStripType; + result = 3.402823466385289e38; + if ( (signed int)uStripType > 0 ) + { + v5 = &pVertices->vWorldPosition.z; + do + { + if ( *v5 < result ) + result = *v5; + v5 += 12; + --v3; + } + while ( v3 ); + } + return result; +} + +//----- (00436A24) -------------------------------------------------------- +struct IDirect3DTexture2 *IndoorCameraD3D::LoadTextureAndGetHardwarePtr(char *Str1) +{ + return pBitmaps_LOD->pHardwareTextures[pBitmaps_LOD->LoadTexture(Str1)]; +} + +//----- (00436A40) -------------------------------------------------------- +double IndoorCameraD3D::GetPolygonMaxZ(RenderVertexSoft *pVertex, unsigned int uStripType) +{ + double result; // st7@1 + + result = 1.1754944e-38; + for ( uint i = 0; i < uStripType; i++ ) + { + if ( pVertex[i].vWorldPosition.z > result ) + result = pVertex[i].vWorldPosition.z; + } + return result; +} + +// -- new +// merged from IndoorCamera::Initialize2 +// and ODMRenderParams::RotationToInts +// and BLVRenderParams::Reset +void IndoorCameraD3D::CalculateRotations(int camera_rot_x, int camera_rot_y) +{ + sRotationX = camera_rot_x; + sRotationY = camera_rot_y; + + fRotationYSine = sin((3.141592653589793 + 3.141592653589793) * (double)sRotationY / 2048.0); + fRotationYCosine = cos((3.141592653589793 + 3.141592653589793) * (double)sRotationY / 2048.0); + if (byte_4D864C && pGame->uFlags & 0x80 || uCurrentlyLoadedLevelType == LEVEL_Indoor) + { + fRotationXSine = sin((3.141592653589793 + 3.141592653589793) * (double)-sRotationX / 2048.0); + fRotationXCosine = cos((3.141592653589793 + 3.141592653589793) * (double)-sRotationX / 2048.0); + + int_sine_y = stru_5C6E00->Sin( pGame->pIndoorCameraD3D->sRotationY); + int_cosine_y = stru_5C6E00->Cos( pGame->pIndoorCameraD3D->sRotationY); + int_sine_x = stru_5C6E00->Sin(-pGame->pIndoorCameraD3D->sRotationX); + int_cosine_x = stru_5C6E00->Cos(-pGame->pIndoorCameraD3D->sRotationX); + } + else + { + fRotationXSine = sin((3.141592653589793 + 3.141592653589793) * (double)sRotationX / 2048.0); + fRotationXCosine = cos((3.141592653589793 + 3.141592653589793) * (double)sRotationX / 2048.0); + + int_sine_y = stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationY); + int_cosine_y = stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationY); + int_sine_x = stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationX); + int_cosine_x = stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationX); + } +} \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/IndoorCameraD3D.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/IndoorCameraD3D.h Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,254 @@ +#pragma once +#include "VectorTypes.h" + + + +/* 124 */ +#pragma pack(push, 1) +struct IndoorCameraD3D_Vec3 +{ + //----- (004C0376) -------------------------------------------------------- + inline IndoorCameraD3D_Vec3() {} + //----- (004C037F) -------------------------------------------------------- + virtual ~IndoorCameraD3D_Vec3() {} + //----- (004C039C) -------------------------------------------------------- + //void ~IndoorCameraD3D_Vec3() {} + + //void ( ***vdestructor_ptr)(IndoorCameraD3D_Vec3 *, bool); + + union + { + struct + { + float x; + float y; + float z; + }; + float v[3]; + }; +}; +#pragma pack(pop) + +/* 125 */ +#pragma pack(push, 1) +struct IndoorCameraD3D_Vec4: public IndoorCameraD3D_Vec3 +{ + //----- (00498038) -------------------------------------------------------- + inline IndoorCameraD3D_Vec4(): + IndoorCameraD3D_Vec3() + {} + + //----- (00498069) -------------------------------------------------------- + virtual ~IndoorCameraD3D_Vec4() + {} + + float dot; + int _wtf; // sizeof vec4 is 18 and first member is vdtor, but vdtor is already included in vec3 so very weird +}; +#pragma pack(pop) + + + +/* 199 */ +#pragma pack(push, 1) +struct IndoorCameraD3D_stru3 +{ + int field_0; + int field_4; + int field_8; + int field_C; + int field_10; + int field_14; + int field_18; + int field_1C; + int field_20; + int field_24; + int field_28; + int field_2C; + float flt_30; + int field_34; +}; +#pragma pack(pop) + + + +/* 197 */ +#pragma pack(push, 1) +struct IndoorCameraD3D_stru1 +{ + //----- (004363A2) -------------------------------------------------------- + IndoorCameraD3D_stru1() + { + this->flt_2C = 0.0; + } + + + int field_0; + int field_4; + int field_8; + int field_C; + int field_10; + int field_14; + int field_18; + int field_1C; + int field_20; + int field_24; + int field_28; + float flt_2C; +}; +#pragma pack(pop) + +/* 198 */ +#pragma pack(push, 1) +struct IndoorCameraD3D_stru2 +{ + unsigned int mm7__vector_000004_size; + IndoorCameraD3D_stru1 mm7__vector_000004[64]; + int field_C04; + int field_C08; + int field_C0C; +}; +#pragma pack(pop) + + + +#define BLV_RENDER_DRAW_SW_OUTLINES (1 << 0) // 1 +#define BLV_RENDER_DRAW_D3D_OUTLINES (1 << 1) // 2 +#define ODM_RENDER_DRAW_D3D_OUTLINES (1 << 2) // 4 +#define ODM_RENDER_DRAW_TERRAIN_OUTLINES (1 << 3) // 8 + +/* 123 */ +#pragma pack(push, 1) +struct IndoorCameraD3D +{ + IndoorCameraD3D(); + + //----- (004363C6) -------------------------------------------------------- + virtual ~IndoorCameraD3D() + { + //this->vdestructor_ptr = &stru8_pvdtor; + //_eh_vector_destructor_iterator_(this->std__vector_000034_prolly_frustrum, 24, 6, IndoorCameraD3D_Vec4::dtor); + //IndoorCameraD3D_Vec3::dtor(&v1->field_24); + //IndoorCameraD3D_Vec3::dtor(&v1->field_14); + //IndoorCameraD3D_Vec3::dtor(&v1->field_4); + } + + double GetPolygonMaxZ(struct RenderVertexSoft *pVertex, unsigned int uStripType); + double GetPolygonMinZ(struct RenderVertexSoft *pVertices, unsigned int uStripType); + struct IDirect3DTexture2 *LoadTextureAndGetHardwarePtr(char *Str1); + void Project(signed int x, signed int y, signed int z, int *a5, int *a6); + void Project(struct RenderVertexSoft *pVertices, unsigned int uNumVertices, char a4); + void _436CDC_mess_with_lightmap__clipflag_2(struct RenderVertexSoft *pInVertices, int uNumInVertices, struct RenderVertexSoft *pOutVertices, unsigned int *pOutNumVertices); + void _436F09_mess_with_lightmap__clipflag_4(struct RenderVertexSoft *pInVertices, int uNumInVertices, struct RenderVertexSoft *pOutVertices, unsigned int *pOutNumVertices); + void _437143(unsigned int uNumInVertices, struct RenderVertexSoft *pOutVertices, struct RenderVertexSoft *pInVertices, unsigned int *pOutNumVertices); + bool _4371C3(struct RenderVertexSoft *pVertices, unsigned int *pOutNumVertices, int _unused); + bool CalcPortalShape(struct RenderVertexSoft *a1, unsigned int *pOutNumVertices, struct RenderVertexSoft *pVertices, IndoorCameraD3D_Vec4 *a4, signed int uNumVertices, char a6, int _unused); + char _437376(struct stru154 *thisa, struct RenderVertexSoft *a2, unsigned int *pOutNumVertices); + void _4374E8_ProllyBuildFrustrum(); + void _437607(IndoorCameraD3D_Vec3 *a1, IndoorCameraD3D_Vec4 *a2); + void Vec3Transform(const IndoorCameraD3D_Vec3 *pVector, IndoorCameraD3D_Vec3 *pOut); + void CreateWorldMatrixAndSomeStuff(); + void MatrixMultiply(struct Matrix3x3_float_ *a1, struct Matrix3x3_float_ *a2, struct Matrix3x3_float_ *a3); + void PrepareAndDrawDebugOutline(struct BLVFace *pFace, unsigned int uDiffuse); + void debug_outline_sw(struct RenderVertexSoft *a2, unsigned int uNumVertices, unsigned int uDiffuse, float a5); + void debug_outline_d3d(const struct RenderVertexD3D3 *pLineVertices, unsigned int uNumLines, int uDiffuse, float z_stuff); + void do_draw_debug_line_sw(struct RenderVertexSoft *pLineBegin, signed int sStartDiffuse, struct RenderVertexSoft *pLineEnd, signed int sEndDiffuse, unsigned int uOutNumVertices, float z_stuff); + //void sr_437D4A_draw_some_vertices(float x, float y, float z, unsigned int a5, char a6, float a7); + //void sr_438141_draw_list_0037C(); + //void sr_438240_draw_lits(); + //void sr_Reset_list_0037C(); + bool is_face_faced_to_camera(struct BLVFace *pFace, struct RenderVertexSoft *a2); + bool GetFacetOrientation(char polyType, struct Vec3_float_ *a2, struct Vec3_float_ *a3, struct Vec3_float_ *a4); + void ViewTransform(struct RenderVertexSoft *a1a, unsigned int uNumVertices); + bool IsCulled(struct BLVFace *pFace); + void ViewTransfrom_OffsetUV(struct RenderVertexSoft *pVertices, unsigned int uNumVertices, struct RenderVertexSoft *pOutVertices, struct stru320 *a5); + bool ApplyViewTransform_TrueIfStillVisible_BLV(int x, int y, int z, signed int *pOutX, int *pOutZ, int *pOutY, char bDoNotShow); + float GetPickDepth(); + float GetShadingDistMist(); + + void DebugDrawPortal(struct BLVFace *pFace); + + //void ( ***vdestructor_ptr)(IndoorCameraD3D *, bool); + IndoorCameraD3D_Vec3 field_4[3]; + //IndoorCameraD3D_Vec3 field_14; + //IndoorCameraD3D_Vec3 field_24; + IndoorCameraD3D_Vec4 std__vector_000034_prolly_frustrum[6]; + float fov; + float screenCenterX; + float screenCenterY; + float fov_x; + float fov_y; + float inv_fov; + float _unused_blv_party_x; + float _unused_blv_party_y; + float _unused_blv_party_z; + char field_E8[32]; + float field_108; + float _unused_blv_party_x_2; + float _unused_blv_party_y_2; + float _unused_blv_party_z_2; + char field_118[32]; + float field_138; + char field_13C[44]; + float field_168; + char field_16C[44]; + float field_198; + char field_19C[44]; + float field_1C8; + char field_1CC[44]; + float field_1F8; + char field_1FC[44]; + float field_228; + char field_22C[44]; + float field_258; + char field_25C[44]; + float field_288; + char field_28C[44]; + float field_2B8; + float field_2BC; + float field_2C0; + float field_2C4; + char field_2C8[32]; + float field_2E8; + float field_2EC; + float field_2F0; + float field_2F4; + char field_2F8[32]; + float field_318; + float field_31C; + float field_320; + float field_324; + char field_328[32]; + float field_348; + float field_34C; + float field_350; + float field_354; + char field_358[32]; + float field_378; + IndoorCameraD3D_stru3 list_0037C[16384]; + unsigned int list_0037C_size; + IndoorCameraD3D_stru2 list_E0380[256]; + int list_E0380_size; + + + void CalculateRotations(int camera_rot_x, int camera_rot_y); + int sRotationY; // moved from 157 struct IndoorCamera::18 + int sRotationX; // moved from 157 struct IndoorCamera::14 + float fRotationYSine; // moved from 157 struct IndoorCamera::2C + float fRotationYCosine; // moved from 157 struct IndoorCamera::30 + float fRotationXSine; // moved from 157 struct IndoorCamera::34 + float fRotationXCosine; // moved from 157 struct IndoorCamera::38 + Vec3 vPartyPos; // moved from 157 struct IndoorCamera::00 + // merged from 162 struct BLVRenderParams::08 + int debug_flags; // moved from 157 struct IndoorCamera::4C + // merged from 162 struct BLVRenderParams::04 + int int_sine_y; // moved from 157 struct ODMRenderParams::1C + // merged from 162 struct BLVRenderParams::24 + int int_cosine_y; // moved from 157 struct ODMRenderParams::20 + // merged from 162 struct BLVRenderParams::20 + int int_sine_x; // moved from 157 struct ODMRenderParams::24 + // merged from 162 struct BLVRenderParams::2C + int int_cosine_x; // moved from 157 struct ODMRenderParams::28 + // merged from 162 struct BLVRenderParams::28 +}; +#pragma pack(pop) \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/Level/Decoration.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/Level/Decoration.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,184 @@ +#define _CRTDBG_MAP_ALLOC +#include +#include + +#define _CRT_SECURE_NO_WARNINGS +#include "Decoration.h" +#include "../../../Party.h" +#include "../../../ErrorHandling.h" + +std::array pLevelDecorations; +size_t uNumLevelDecorations; +LevelDecoration* activeLevelDecoration; + +//----- (004583B0) -------------------------------------------------------- +LevelDecoration::LevelDecoration() +{ + memset(this, 0, sizeof(*this)); +} + +//----- (00450929) -------------------------------------------------------- +int LevelDecoration::GetGlobalEvent() +{ + //LevelDecoration *v1; // esi@1 + //signed int v2; // eax@1 + //int v3; // eax@5 + //int v4; // eax@6 + //int v5; // eax@7 + //int v6; // eax@8 + //int v7; // eax@9 + //int result; // eax@14 + //int v9; // eax@18 + //int v10; // eax@19 + //int v11; // eax@20 + //int v12; // eax@21 + //int v13; // eax@22 + + switch (uDecorationDescID) + { + case 0: case 1: + case 2: case 3: + return 0; + + case 4: return 16; // dec01 "Trash Pile" + case 5: return 32; // dec02 "Campfire" + case 6: return 12 + rand() % 4; // dec03 "Cauldron" + case 7: case 8: + case 9: case 10: + return 0; + + case 11: return 34; // dec08 "Fruit plate" + case 12: + return 0; + + case 13: return 17; // dec10 "Trash Pile" + case 14: return 18; // dec11 "Filth" + case 15: case 16: case 17: + case 18: case 19: case 20: + case 21: case 22: case 23: + return 0; + + case 24: return 36; // dec21 "Keg" + case 25: case 26: case 27: case 28: case 29: + case 30: case 31: case 32: case 33: + return 0; + + case 34: return 4 + rand() % 6; // dec32 "Barrel" + case 35: case 36: case 37: case 38: case 39: + case 40: case 41: case 42: case 43: case 44: case 45: case 46: case 47: case 48: case 49: + case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: case 58: case 59: + case 60: case 61: case 62: case 63: case 64: case 65: case 66: case 67: case 68: case 69: + case 70: case 71: case 72: case 73: case 74: case 75: case 76: case 77: case 78: case 79: + case 80: case 81: case 82: case 83: case 84: case 85: case 86: case 87: case 88: case 89: + case 90: case 91: case 92: case 93: case 94: case 95: case 96: case 97: case 98: case 99: + case 100: case 101: case 102: case 103: case 104: case 105: case 106: case 107: case 108: case 109: + case 110: case 111: case 112: case 113: case 114: case 115: case 116: case 117: case 118: case 119: + case 120: case 121: case 122: case 123: case 124: case 125: case 126: case 127: case 128: case 129: + case 130: case 131: case 132: case 133: case 134: case 135: case 136: case 137: case 138: case 139: + case 140: case 141: case 142: case 143: case 144: case 145: case 146: case 147: case 148: case 149: + case 150: case 151: case 152: case 153: case 154: case 155: case 156: case 157: case 158: case 159: + case 160: case 161: case 162: case 163: case 164: case 165: case 166: case 167: case 168: case 169: + case 170: case 171: case 172: case 173: case 174: case 175: case 176: case 177: case 178: case 179: + case 180: case 181: case 182: case 183: + + case 184: return 33; // dec24 "Campfire" + case 185: case 186: + return 0; + + case 187: // dec88 "Mushroom" + case 190: // dec91 "Mushroom" + return 37; + + case 188: case 189: + case 191: case 192: case 193: case 194: case 195: case 196: + case 197: case 198: case 199: case 200: case 201: case 202: + case 203: case 204: case 205: + return 0; + + case 206: return 162 + rand() % 7; // dec60 + case 207: return 169 + rand() % 7; // dec61 + case 208: return 176 + rand() % 7; // dec62 + case 209: return 183 + rand() % 7; // dec63 + case 210: return 150; // dec64 "Magic pedestal" + case 211: return 151; // dec65 "Magic pedestal" + case 212: return 152; // dec66 "Magic pedestal" + case 213: return 153; // dec67 "Magic pedestal" + case 214: return 154; // dec68 "Magic pedestal" + case 215: return 155; // dec69 "Magic pedestal" + case 216: return 156; // dec70 "Magic pedestal" + case 217: return 157; // dec71 "Magic pedestal" + case 218: return 158; // dec72 "Magic pedestal" + case 219: return 159; // dec73 "Magic pedestal" + case 220: return 160; // dec74 "Magic pedestal" + case 221: return 161; // dec75 "Magic pedestal" + + case 222: case 223: case 224: + case 225: case 226: case 227: + return 0; + + default: Error("Invalid DecorationDescID: %u", uDecorationDescID); + } +} + +//----- (0047A825) -------------------------------------------------------- +bool LevelDecoration::IsObeliskChestActive() +{ + //bool v1; // ebx@1 + //LevelDecoration *v2; // edi@1 + + static const std::array aObeliskQuests = { + PARTY_QUEST_OBELISK_HARMONDALE, + PARTY_QUEST_OBELISK_ERATHIA, + PARTY_QUEST_OBELISK_TULAREAN_FOREST, + PARTY_QUEST_OBELISK_DEYJA, + PARTY_QUEST_OBELISK_BRACADA_DESERT, + PARTY_QUEST_OBELISK_CELESTE, + PARTY_QUEST_OBELISK_THE_PIT, + PARTY_QUEST_OBELISK_EVENMORN_ISLAND, + PARTY_QUEST_OBELISK_MOUNT_NIGHON, + PARTY_QUEST_OBELISK_BARROW_DOWNS, + PARTY_QUEST_OBELISK_LAND_OF_THE_GIANTS, + PARTY_QUEST_OBELISK_TATALIA, + PARTY_QUEST_OBELISK_AVLEE, + PARTY_QUEST_OBELISK_STONE_CITY + }; + + if (pParty->uCurrentHour == 0 + && !TestPartyQuestBit(PARTY_QUEST_OBELISK_TREASURE_FOUND) + && std::all_of(aObeliskQuests.begin(), aObeliskQuests.end(), TestPartyQuestBit)) + { + this->uFlags &= ~LEVEL_DECORATION_INVISIBLE; + return true; + } + + this->uFlags |= LEVEL_DECORATION_INVISIBLE; + return false; +} + +//----- (0044C2F4) -------------------------------------------------------- +bool LevelDecoration::IsInteractive() +{ + switch (uDecorationDescID) + { + case 4: // trash pile + case 5: // campfire + case 6: // cauldron + case 11: // fruit plate + case 13: // trash pile + case 14: // dirt + case 24: // keg + case 184: // fire + case 187: // fire + case 190: // fire + return true; + } + + if (uDecorationDescID >= 206 && uDecorationDescID <= 209) // lighthouse fire + return true; + if (uDecorationDescID >= 210 && uDecorationDescID <= 221) // magic pedestal + return true; + + return false; +} + + diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/Level/Decoration.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/Level/Decoration.h Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,46 @@ +#pragma once + +#include +#include + +#include "../../../VectorTypes.h" + + +enum LEVEL_DECORATION_FLAGS: uint16_t +{ + LEVEL_DECORATION_TRIGGERED_BY_TOUCH = 0x01, + LEVEL_DECORATION_TRIGGERED_BY_MONSTER = 0x02, + LEVEL_DECORATION_TRIGGERED_BY_OBJECT = 0x04, + LEVEL_DECORATION_VISIBLE_ON_MAP = 0x08, + LEVEL_DECORATION_CHEST = 0x10, + LEVEL_DECORATION_INVISIBLE = 0x20, + LEVEL_DECORATION_OBELISK_CHEST = 0x40, +}; + +/* 74 */ +#pragma pack(push, 1) +struct LevelDecoration +{ + LevelDecoration(); + int GetGlobalEvent(); + bool IsInteractive(); + bool IsObeliskChestActive(); + + uint16_t uDecorationDescID; + uint16_t uFlags; + Vec3_int_ vPosition; + int32_t field_10_y_rot; + uint16_t uCog; + uint16_t uEventID; + uint16_t uTriggerRange; + int16_t field_1A; + int16_t _idx_in_stru123; + int16_t field_1E; +}; + + + +extern std::array pLevelDecorations; +extern size_t uNumLevelDecorations; +extern LevelDecoration* activeLevelDecoration; // 5C3420 +#pragma pack(pop) diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/LightmapBuilder.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/LightmapBuilder.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,1444 @@ +#define _CRTDBG_MAP_ALLOC +#include +#include + +#define _CRT_SECURE_NO_WARNINGS +#include "LightmapBuilder.h" +#include "Game.h" +#include "stru314.h" +#include "Outdoor.h" +#include "Log.h" +#include "ErrorHandling.h" + +#include "Lights.h" + +#include "stru9.h" + + + + +LightsStack_StationaryLight_ *pStationaryLightsStack = new LightsStack_StationaryLight_; +//StationaryLight pStationaryLights[400]; +//int uNumStationaryLightsApplied; // weak +LightsStack_MobileLight_ *pMobileLightsStack = new LightsStack_MobileLight_; +//MobileLight pMobileLights[400]; +//int uNumMobileLightsApplied; + + + + + +//----- (0045DF13) -------------------------------------------------------- +Lightmap::Lightmap() +{ + field_C18 = 0; +} + +//----- (0045BB06) -------------------------------------------------------- +LightmapBuilder::LightmapBuilder() +{ +} + +//----- (0045BC07) -------------------------------------------------------- +bool LightmapBuilder::ApplyLights(stru320 *a2, stru154 *a3, unsigned int uNumVertices, RenderVertexSoft *a5, IndoorCameraD3D_Vec4 *a6, char uClipFlag) +{ + Vec3_int_ pos; // [sp+2Ch] [bp-40h]@21 + RenderVertexSoft *a9; // [sp+68h] [bp-4h]@8 + + if (!uNumVertices) + return false; + + static RenderVertexSoft static_69B140[64]; + + a9 = a5; + if (a6) + { + for (uint i = 0; i < uNumVertices; ++i) + memcpy(static_69B140 + i, a5 + i, sizeof(RenderVertexSoft)); + + //__debugbreak(); + if (pGame->pIndoorCameraD3D->_437376(a3, static_69B140, &uNumVertices) == 1) + { + if ( !uNumVertices ) + return false; + a9 = static_69B140; + } + } + + static stru314 static_69B110; + static_69B110.field_4.x = a3->face_plane.vNormal.x; + static_69B110.field_4.y = a3->face_plane.vNormal.y; + static_69B110.field_4.z = a3->face_plane.vNormal.z; + static_69B110.dist = a3->face_plane.dist; + if (!pGame->pIndoorCameraD3D->GetFacetOrientation(a3->polygonType, &static_69B110.field_4, + &static_69B110.field_10, &static_69B110.field_1C)) + { + MessageBoxW(nullptr, L"Error: Failed to get the facet orientation", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Light.cpp:119", 0); + ExitProcess(0); + } + + for (uint i = 0; i < a2->uNumLightsApplied; ++i) + { + pos.x = a2->_blv_lights_xs[i]; + pos.y = a2->_blv_lights_ys[i]; + pos.z = a2->_blv_lights_zs[i]; + + uint uColorR = (uint)floorf(a2->_blv_lights_rs[i] * 255.0 + 0.5f) & 0xFF, + uColorG = (uint)floorf(a2->_blv_lights_gs[i] * 255.0 + 0.5f) & 0xFF, + uColorB = (uint)floorf(a2->_blv_lights_bs[i] * 255.0 + 0.5f) & 0xFF; + uint uColor = (uColorR << 16) | (uColorG << 8) | uColorB; + if (!uColor) + uColor = 0x00FFFFF; + + if (!_45BE86_build_light_polygon(&pos, a2->_blv_lights_radii[i], uColor, a2->_blv_lights_light_dot_faces[i], + a2->_blv_lights_types[i], &static_69B110, uNumVertices, a9, uClipFlag) ) + { + MessageBoxW(nullptr, L"Error: Failed to build light polygon", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Light.cpp:138", 0); + } + } + return true; +} + +//----- (0045BE86) -------------------------------------------------------- +bool LightmapBuilder::_45BE86_build_light_polygon(Vec3_int_ *pos, float radius, unsigned int uColorMask, float dot_dist, int uLightType, stru314 *a7, unsigned int uNumVertices, RenderVertexSoft *a9, char uClipFlag) +{ + Lightmap *v11; // edi@3 + double v17; // st7@5 + double v24; // st7@6 + double v38; // st7@14 + double v39; // st7@16 + double v40; // st7@16 + int v45; // eax@24 + + if (fabsf(radius) < 1e-6f) + return true; + + v11 = uLightType & 1 ? &std__vector_000004[std__vector_000004_size] : + &std__vector_183808[std__vector_183808_size]; + flt_3C8C24 = radius - dot_dist; + flt_3C8C28 = sqrt((radius + dot_dist) * (radius - dot_dist)); + flt_3C8C2C_lightmaps_brightness = 1.0 - (radius - flt_3C8C28) / radius; + v11->field_C08 = (double)pos->x - dot_dist * a7->field_4.x; + v11->field_C0A = (double)pos->y - dot_dist * a7->field_4.y; + v11->field_C0C = (double)pos->z - dot_dist * a7->field_4.z; + + v17 = radius * flt_3C8C2C_lightmaps_brightness; + flt_3C8C30 = v17; + flt_3C8C0C = v17 * a7->field_10.x; + flt_3C8C10 = v17 * a7->field_10.y; + flt_3C8C14 = v17 * a7->field_10.z; + flt_3C8C18 = v17 * a7->field_1C.x; + flt_3C8C1C = v17 * a7->field_1C.y; + flt_3C8C20 = v17 * a7->field_1C.z; + + /* + v11->pVertices[0].vWorldPosition.x = v11->field_C08 - flt_3C8C18 + flt_3C8C0C; + v11->pVertices[0].vWorldPosition.y = v11->field_C0A - flt_3C8C1C + flt_3C8C10; + v11->pVertices[0].vWorldPosition.z = v11->field_C0C - flt_3C8C20 + flt_3C8C14; + v11->pVertices[0].u = 0.0; + v11->pVertices[0].v = 0.0; + + v11->pVertices[1].vWorldPosition.x = v11->field_C08 - flt_3C8C18 - flt_3C8C0C; + v11->pVertices[1].vWorldPosition.y = v11->field_C0A - flt_3C8C1C - flt_3C8C10; + v11->pVertices[1].vWorldPosition.z = v11->field_C0C - flt_3C8C20 - flt_3C8C14; + v11->pVertices[1].u = 0.0; + v11->pVertices[1].v = 1.0; + + v11->pVertices[2].vWorldPosition.x = v11->field_C08 + flt_3C8C18 - flt_3C8C0C; + v11->pVertices[2].vWorldPosition.y = v11->field_C0A + flt_3C8C1C - flt_3C8C10; + v11->pVertices[2].vWorldPosition.z = v11->field_C0C + flt_3C8C20 - flt_3C8C14; + v11->pVertices[2].u = 1.0; + v11->pVertices[2].v = 1.0; + + v11->pVertices[3].vWorldPosition.x = v11->field_C08 + flt_3C8C18 + flt_3C8C0C; + v11->pVertices[3].vWorldPosition.y = v11->field_C0A + flt_3C8C1C + flt_3C8C10; + v11->pVertices[3].vWorldPosition.z = v11->field_C0C + flt_3C8C20 + flt_3C8C14; + v11->pVertices[3].u = 1.0; + v11->pVertices[3].v = 0.0; + */ + + for (uint i = 0; i < 4; ++i) + { + v11->pVertices[i].vWorldPosition.x = v11->field_C08 - flt_3C8C18 + flt_3C8C0C; + v11->pVertices[i].vWorldPosition.y = v11->field_C0A - flt_3C8C1C + flt_3C8C10; + v11->pVertices[i].vWorldPosition.z = v11->field_C0C - flt_3C8C20 + flt_3C8C14; + v11->pVertices[i].u = 0.0; + v11->pVertices[i].v = 0.0; + + v24 = a7->field_4.y * v11->pVertices[i].vWorldPosition.y + + a7->field_4.z * v11->pVertices[i].vWorldPosition.z + + a7->field_4.x * v11->pVertices[i].vWorldPosition.x + + a7->dist; + + v11->pVertices[i].vWorldPosition.x -= v24 * a7->field_4.x; + v11->pVertices[i].vWorldPosition.y -= v24 * a7->field_4.y; + v11->pVertices[i].vWorldPosition.z -= v24 * a7->field_4.z; + } + + v11->uColorMask = uColorMask; + v11->uNumVertices = 4; + + if (~pGame->uFlags2 & 4) + v11->fBrightness = flt_3C8C2C_lightmaps_brightness; + else + { + Vec3_float_ a1; // [sp+2Ch] [bp-20h]@8 + a1.x = (double)pos->x - v11->field_C08; + a1.y = (double)pos->y - v11->field_C0A; + a1.z = (double)pos->z - v11->field_C0C; + a1.Normalize(); + + auto dist_x = abs(pos->x - v11->field_C08), //v31 + dist_y = abs(pos->y - v11->field_C0A), //v32 arg0a + dist_z = abs(pos->z - v11->field_C0C); //v33 _v64 + v38 = int_get_vector_length(dist_x, dist_y, dist_z); + if (v38 > radius) + return true; + //radius = (1 / radius) * v38; + if ( uLightType & 4 ) + { + //v59 = (void *)v37; + //uLightType = flt_4D86CC; + //v58 = v37; + v39 = fabs(a1.x * a7->field_4.x + a1.z * a7->field_4.z + a1.y * a7->field_4.y); + v40 = v39 * 1.0 * flt_4D86CC; + + v11->fBrightness = v40 - (1 / radius) * v38 * v40; + } + else if ( uLightType & 8 ) + { + v40 = 1.0 * 1.0; + v11->fBrightness = v40 - (1 / radius) * v38; + } + else + MessageBoxW(nullptr, L"Invalid light type!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Light.cpp:277", 0); + } + + if (!pGame->pStru9Instance->_4980B9(a9, uNumVertices, + a7->field_4.x, a7->field_4.y, a7->field_4.z, + v11->pVertices, &v11->uNumVertices)) + return false; + + //v44 = &v11->uNumVertices; + if (!v11->uNumVertices) + return true; + + v45 = _45C6D6(uNumVertices, a9, v11); + if ( v45 != uNumVertices && v45 > 0 ) + _45C4B9(uNumVertices, a9, v11); + //v59 = v11->uNumVertices; + //v46 = (RenderVertexSoft *)pLightmapVertices_; + pGame->pIndoorCameraD3D->ViewTransform(v11->pVertices, v11->uNumVertices); + //v59 = 0; + //v58 = v11->uNumVertices; + pGame->pIndoorCameraD3D->Project(v11->pVertices, v11->uNumVertices, 0); + + unsigned int _a4 = 0; + if ( !(uClipFlag & 1) ) + _a4 = 1; + else if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor) + { + if ( uClipFlag & 2 ) + { + //v59 = &a4; + //v58 = (unsigned int)field_3C8C34; + //v57 = *v44; + pGame->pIndoorCameraD3D->_436CDC_mess_with_lightmap__clipflag_2(v11->pVertices, v11->uNumVertices, field_3C8C34, &_a4); + + //v59 = v44; + //v58 = (unsigned int)field_3C8C34; + //v57 = (int)v46; + //v56 = a4; + pGame->pIndoorCameraD3D->_437143(_a4, v11->pVertices, field_3C8C34, &v11->uNumVertices); + } + else if ( uClipFlag & 4 ) + { + //v59 = &a4; + //v58 = (unsigned int)field_3C8C34; + //v57 = *v44; + pGame->pIndoorCameraD3D->_436F09_mess_with_lightmap__clipflag_4(v11->pVertices, v11->uNumVertices, field_3C8C34, &_a4); + + //v59 = v44; + //v58 = (unsigned int)field_3C8C34; + //v57 = (int)v46; + //v56 = a4; + pGame->pIndoorCameraD3D->_437143(_a4, v11->pVertices, field_3C8C34, &v11->uNumVertices); + } + else + MessageBoxW(nullptr, L"Undefined clip flag specified", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Light.cpp:330", 0); + } + else + MessageBoxW(nullptr, L"Lightpoly builder native indoor clipping not implemented", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Light.cpp:335", 0); + + if (_a4) + { + if (uLightType & 1) + { + //v48 = (char *)&std__vector_000004_size; + //v49 = std__vector_000004_size; + //v51 = __OFSUB__(std__vector_000004_size, 511); + //v50 = std__vector_000004_size - 511 < 0; + if (std__vector_000004_size < 512 - 1) + ++std__vector_000004_size; + } + else + { + //v48 = (char *)&std__vector_183808_size; + //v49 = std__vector_183808_size; + //v51 = __OFSUB__(std__vector_183808_size, 767); + //v50 = std__vector_183808_size - 767 < 0; + if (std__vector_183808_size < 768 - 1) + ++std__vector_183808_size; + } + //if ( v50 ^ v51 ) + // *(unsigned int *)v48 = v49 + 1; + } + return true; +} + +//----- (0045C4B9) -------------------------------------------------------- +int LightmapBuilder::_45C4B9(int a2, RenderVertexSoft *a3, Lightmap *pLightmap) +{ + Lightmap *v4; // edi@1 + int v5; // eax@1 + signed int v6; // ecx@1 + RenderVertexSoft *v7; // ebx@2 + int v8; // edx@3 + RenderVertexSoft *v9; // esi@3 + int v10; // eax@6 +// char *v11; // edi@7 + RenderVertexSoft *v12; // ecx@8 + char v13; // bl@17 + signed int v14; // edx@17 + double v15; // st6@18 + double v16; // st6@21 + double v17; // st6@24 + signed int v18; // edx@33 + int v20; // [sp+4h] [bp-1Ch]@3 + //int v21; // [sp+8h] [bp-18h]@8 + float v22; // [sp+Ch] [bp-14h]@23 + float v23; // [sp+10h] [bp-10h]@20 + int v24; // [sp+14h] [bp-Ch]@1 + RenderVertexSoft *v25; // [sp+18h] [bp-8h]@2 + char v26; // [sp+1Eh] [bp-2h]@17 + char v27; // [sp+1Fh] [bp-1h]@17 + + //__debugbreak();//Ritor1: needed cleaning + + v4 = pLightmap; + v5 = 0; + v6 = pLightmap->uNumVertices; + v24 = 0; + if ( v6 > 0 ) + { + v7 = pLightmap->pVertices; + v25 = pLightmap->pVertices; + do + { + v20 = v5 + 1; + v8 = (v5 + 1) % v6; + v9 = &v4->pVertices[v8]; + if ( v7->vWorldPosition.x != v9->vWorldPosition.x + || v7->vWorldPosition.y != v4->pVertices[v8].vWorldPosition.y + || v7->vWorldPosition.z != v4->pVertices[v8].vWorldPosition.z ) + { + //v10 = 0; + if ( a2 > 0 ) + { + //v11 = (char *)&a3->vWorldPosition.z; + for ( v10 = 1; v10 <= a2; ++v10 ) + { + //v21 = v10 + 1; + v12 = &a3[v10 % a2]; + if ((a3[v10].vWorldPosition.x != v12->vWorldPosition.x + || a3[v10].vWorldPosition.y != v12->vWorldPosition.y || a3[v10].vWorldPosition.z != v12->vWorldPosition.z) + && v7->vWorldPosition.x == a3[v10].vWorldPosition.x + && v7->vWorldPosition.y == a3[v10].vWorldPosition.y && v7->vWorldPosition.z == a3[v10].vWorldPosition.z + && (v9->vWorldPosition.x != v12->vWorldPosition.x + || v9->vWorldPosition.y != v12->vWorldPosition.y || v9->vWorldPosition.z != v12->vWorldPosition.z) ) + { + v13 = 0; + v14 = 0; + v27 = 0; + v26 = 0; + if ( v9->vWorldPosition.x <= (double)v12->vWorldPosition.x ) + v15 = v12->vWorldPosition.x - v9->vWorldPosition.x; + else + v15 = v9->vWorldPosition.x - v12->vWorldPosition.x; + v23 = v15; + + if ( v9->vWorldPosition.y <= (double)v12->vWorldPosition.y ) + v16 = v12->vWorldPosition.y - v9->vWorldPosition.y; + else + v16 = v9->vWorldPosition.y - v12->vWorldPosition.y; + v22 = v16; + + if ( v9->vWorldPosition.z <= (double)v12->vWorldPosition.z ) + v17 = v12->vWorldPosition.z - v9->vWorldPosition.z; + else + v17 = v9->vWorldPosition.z - v12->vWorldPosition.z; + if ( v23 < 1.0 ) + { + v13 = 1; + v14 = 1; + } + if ( v22 < 1.0 ) + { + v27 = 1; + ++v14; + } + if ( v17 < 1.0 ) + { + v26 = 1; + ++v14; + } + if ( v14 > 1 ) + { + v18 = 0; + if ( v13 && v9->vWorldPosition.x != v12->vWorldPosition.x ) + { + v18 = 1; + v9->vWorldPosition.x = v12->vWorldPosition.x; + } + if ( v27 && v9->vWorldPosition.y != v12->vWorldPosition.y ) + { + ++v18; + v9->vWorldPosition.y = v12->vWorldPosition.y; + } + if ( v26 && v9->vWorldPosition.z != v12->vWorldPosition.z ) + { + ++v18; + v9->vWorldPosition.z = v12->vWorldPosition.z; + } + if ( v18 > 0 ) + ++v24; + } + v7 = v25; + } + //++v10; + //v11 += 48; + } + //while ( v21 < a2 ); + v4 = pLightmap; + } + } + v5 = v20; + v6 = v4->uNumVertices; + ++v7; + v25 = v7; + } + while ( v20 < v6 ); + } + return v24; +} + +//----- (0045C6D6) -------------------------------------------------------- +int LightmapBuilder::_45C6D6(int a2, RenderVertexSoft *a3, Lightmap *pLightmap) +{ + signed int v6; // esi@1 + double v9; // st7@6 + double v10; // st6@10 + double v11; // st5@14 + double v12; // st7@17 + int v15; // [sp+Ch] [bp-8h]@1 + float v16; // [sp+10h] [bp-4h]@1 + + v6 = -1; + v16 = 3.4028235e38; + v15 = 0; + if ( (signed int)pLightmap->uNumVertices > 0 ) + { + for ( uint i = 0; i < (signed int)pLightmap->uNumVertices; ++i ) + { + if ( a2 > 0 ) + { + for ( uint j = 0; j < a2; ++j ) + { + if ( pLightmap->pVertices[i].vWorldPosition.x <= (double)a3[j].vWorldPosition.x ) + v9 = a3[j].vWorldPosition.x - pLightmap->pVertices[i].vWorldPosition.x; + else + v9 = pLightmap->pVertices[i].vWorldPosition.x - a3[j].vWorldPosition.x; + if ( v9 < 2.0 ) + { + v10 = pLightmap->pVertices[i].vWorldPosition.y <= (double)a3[j].vWorldPosition.y + ? a3[j].vWorldPosition.y - pLightmap->pVertices[i].vWorldPosition.y + : pLightmap->pVertices[i].vWorldPosition.y - a3[j].vWorldPosition.y; + if ( v10 < 2.0 ) + { + v11 = pLightmap->pVertices[i].vWorldPosition.z <= (double)a3[j].vWorldPosition.z + ? a3[j].vWorldPosition.z - pLightmap->pVertices[i].vWorldPosition.z + : pLightmap->pVertices[i].vWorldPosition.z - a3[j].vWorldPosition.z; + if ( v11 < 2.0 ) + { + v12 = v9 + v11 + v10; + if ( v12 < v16 ) + { + v16 = v12; + v6 = j; + } + } + } + } + } + if ( v6 != -1 ) + { + ++v15; + pLightmap->pVertices[i].vWorldPosition.x = a3[v6].vWorldPosition.x; + pLightmap->pVertices[i].vWorldPosition.y = a3[v6].vWorldPosition.y; + pLightmap->pVertices[i].vWorldPosition.z = a3[v6].vWorldPosition.z; + } + } + v6 = -1; + v16 = 3.4028235e38; + } + } + return v15; +} + +//----- (0045C7F6) -------------------------------------------------------- +bool LightmapBuilder::ApplyLights_IndoorFace(unsigned int uFaceID) +{ + BLVFace* pFace = &pIndoor->pFaces[uFaceID]; + BLVSector* pSector = &pIndoor->pSectors[pFace->uSectorID]; + + stru_F8AD28.uCurrentAmbientLightLevel = (stru_F8AD28.uDefaultAmbientLightLevel + pSector->uMinAmbientLightLevel) << 16; + + uint uNumLightsApplied = 0; + for (uint i = 0; i < pMobileLightsStack->uNumLightsActive; ++i) + { + if (uNumLightsApplied >= 20) + break; + + ApplyLight_BLV((StationaryLight *)(pMobileLightsStack->pLights + i), pFace, &uNumLightsApplied, true, 0); + } + + for (uint i = 0; i < pSector->uNumLights; ++i) + { + if (uNumLightsApplied >= 20 ) + break; + + BLVLightMM7* pLight = &pIndoor->pLights[pSector->pLights[i]]; + if (~pLight->uAtributes & 0x08) + ApplyLight_BLV((StationaryLight *)pLight, pFace, &uFaceID, false, &_4E94D0_light_type); + } + + for (uint i = 0; i < pStationaryLightsStack->uNumLightsActive; ++i) + { + if (uNumLightsApplied >= 20) + break; + + ApplyLight_BLV(pStationaryLightsStack->pLights + i, pFace, &uNumLightsApplied, false, &_4E94D0_light_type); + } + + stru_F8AD28.uNumLightsApplied = uNumLightsApplied; + return true; +} + +//----- (0045C911) -------------------------------------------------------- +bool LightmapBuilder::ApplyLight_BLV(StationaryLight *pLight, BLVFace *a2, unsigned int *pSlot, bool bLightBackfaces, char *a5) +{ + double v13; // st7@8 + + if (!pLight->uRadius) + return false; + + if (pLight->vPosition.x > a2->pBounding.x1 - pLight->uRadius && + pLight->vPosition.x < a2->pBounding.x2 + pLight->uRadius && + pLight->vPosition.y > a2->pBounding.y1 - pLight->uRadius && + pLight->vPosition.y < a2->pBounding.y2 + pLight->uRadius && + pLight->vPosition.z > a2->pBounding.z1 - pLight->uRadius && + pLight->vPosition.z < a2->pBounding.z2 + pLight->uRadius) + { + v13 = (double)pLight->vPosition.z * a2->pFacePlane.vNormal.z + + (double)pLight->vPosition.y * a2->pFacePlane.vNormal.y + + (double)pLight->vPosition.x * a2->pFacePlane.vNormal.x + + a2->pFacePlane.dist; + if ((bLightBackfaces || v13 >= 0.0f) && fabsf(v13) <= pLight->uRadius) + { + unsigned int slot = *pSlot; + + stru_F8AD28._blv_lights_radii[slot] = pLight->uRadius; + stru_F8AD28._blv_lights_inv_radii[slot] = 65536 / pLight->uRadius; + stru_F8AD28._blv_lights_xs[slot] = pLight->vPosition.x; + stru_F8AD28._blv_lights_ys[slot] = pLight->vPosition.y; + stru_F8AD28._blv_lights_zs[slot] = pLight->vPosition.z; + stru_F8AD28._blv_lights_rs[slot] = (double)pLight->uLightColorR / 255.0f; + stru_F8AD28._blv_lights_gs[slot] = (double)pLight->uLightColorG / 255.0f; + stru_F8AD28._blv_lights_bs[slot] = (double)pLight->uLightColorB / 255.0f; + stru_F8AD28._blv_lights_light_dot_faces[slot] = abs((int)floorf(v13 + 0.5f)); + stru_F8AD28._blv_lights_types[slot] = pLight->uLightType; + + *pSlot += 1; + return true; + } + } + + return false; +} + +//----- (0045CA88) -------------------------------------------------------- +int LightmapBuilder::_45CA88(stru320 *a2, RenderVertexSoft *a3, int a4, Vec3_float_ *pNormal) +{ + int result; // eax@1 + stru320 *v6; // ecx@2 + RenderVertexSoft *v7; // ebx@2 + double v8; // st7@2 + double v9; // st6@2 + char *v10; // eax@3 + double v11; // st7@5 + __int64 v12; // ST2C_8@5 + float v13; // edx@5 + int v14; // eax@5 + float v15; // ST10_4@5 + Vec3_float_ v16; // ST00_12@5 + double v17; // st7@5 + int a5; // [sp+2Ch] [bp-1Ch]@1 + float v19; // [sp+30h] [bp-18h]@1 + float v20; // [sp+34h] [bp-14h]@1 + //LightmapBuilder *thisa; // [sp+38h] [bp-10h]@1 + int v22; // [sp+3Ch] [bp-Ch]@1 + int *j; // [sp+40h] [bp-8h]@3 + int i; // [sp+44h] [bp-4h]@1 + int a3a; // [sp+58h] [bp+10h]@2 + + __debugbreak();//Ritor1: needed cleaning + + *(float *)&a5 = 0.0; + v19 = 0.0; + //thisa = this; + v20 = 0.0; + result = _45CBD4(a3, a4, dword_69B010.data(), &v22); + for ( i = 0; i < v22; result = i ) + { + v6 = a2; + a3a = 0; + v7 = &a3[dword_69B010[i]]; + v8 = v7->vWorldPosition.z; + v9 = v7->vWorldPosition.y; + *(float *)&a5 = v7->vWorldPosition.x; + v19 = v9; + v20 = v8; + v7->flt_2C = 0.0; + if ( a2->uNumLightsApplied > 0 ) + { + v10 = (char *)a2->_blv_lights_ys; + for ( j = a2->_blv_lights_ys; ; v10 = (char *)j ) + { + v11 = (double)*((signed int *)v10 - 60); + LODWORD(v12) = *((unsigned int *)v10 - 20); + HIDWORD(v12) = *(unsigned int *)v10; + LODWORD(v13) = *((unsigned int *)v10 + 60); + v14 = a3a; + LOBYTE(v14) = v6->_blv_lights_types[a3a]; + v15 = v11; + *(_QWORD *)&v16.x = v12; + v16.z = v13; + v17 = _45CC0C_light(v16/*COERCE_VEC3_FLOAT_(v16.x)*/, 1.0, v15, pNormal, *(float *)&a5/*COERCE_FLOAT(&a5)*/, v14) + + v7->flt_2C; + ++a3a; + ++j; + v7->flt_2C = v17; + if ( a3a >= a2->uNumLightsApplied ) + break; + v6 = a2; + } + } + ++i; + } + return result; +} + +//----- (0045CB89) -------------------------------------------------------- +int LightmapBuilder::_45CB89(RenderVertexSoft *a1, int a2) +{ + int v3; // edx@1 + int result; // eax@2 + char *v5; // ecx@2 + double v6; // st7@4 + __int16 v7; // fps@4 + char v8; // c0@4 + char v9; // c2@4 + char v10; // c3@4 + double v11; // st7@5 + double v12; // st7@6 + __int16 v13; // fps@6 + char v14; // c0@6 + char v15; // c2@6 + char v16; // c3@6 + + v3 = a2; + if ( a2 > 0 ) + { + HIWORD(result) = HIWORD(a1); + v5 = (char *)&a1->flt_2C; + do + { + __debugbreak(); // warning C4700: uninitialized local variable 'v7' used + if ( *(float *)v5 < 0.0 + || (v6 = *(float *)v5, /*UNDEF(v7),*/ v8 = 1.0 < v6, v9 = 0, v10 = 1.0 == v6, LOWORD(result) = v7, v6 <= 1.0) ) + { + v12 = *(float *)v5; + //UNDEF(v13); + v14 = 0.0 < v12; + v15 = 0; + v16 = 0.0 == v12; + __debugbreak(); // warning C4700: uninitialized local variable 'v13' used + LOWORD(result) = v13; + if ( v12 >= 0.0 ) + v11 = *(float *)v5; + else + v11 = 0.0; + } + else + { + v11 = 1.0; + } + *(float *)v5 = v11; + v5 += 48; + --v3; + } + while ( v3 ); + } + return result; +} + +//----- (0045CBD4) -------------------------------------------------------- +int LightmapBuilder::_45CBD4(RenderVertexSoft *a2, int a3, int *a4, int *a5) +{ + int result; // eax@1 + int v6; // edx@1 + int v7; // ecx@2 + int v8; // esi@2 + + result = (int)a5; + v6 = 0; + for ( *a5 = 0; v6 < a3; ++v6 ) + { + v7 = *a5; + v8 = 0; + if ( *a5 <= 0 ) + { +//LABEL_5: + a4[v7] = v6; + ++*a5; + } + else + { + while ( a4[v8] != v6 ) + { + ++v8; + if (v8 >= v7) + { + a4[v7] = v6; + ++*a5; + break; + //goto LABEL_5; + } + } + } + } + return result; +} + +//----- (0045CC0C) -------------------------------------------------------- +double LightmapBuilder::_45CC0C_light(Vec3_float_ a1, float a2, float a3, Vec3_float_ *pNormal, float a5, int uLightType) +{ + float v7; // esi@1 + int v8; // eax@1 +// int v9; // ebx@1 +// unsigned int v10; // ecx@1 +// int v11; // edx@2 +// int v12; // edx@4 +// unsigned int v13; // edx@6 + double v14; // st7@7 + double result; // st7@8 + double v16; // st7@9 + int v17; // esi@9 + const char *v18; // ecx@9 + double v19; // st7@10 + double v20; // st7@10 + std::string v21; // [sp-10h] [bp-40h]@13 + const char *v22[6]; // [sp+0h] [bp-30h]@10 + double v23; // [sp+18h] [bp-18h]@1 +// double v24; // [sp+20h] [bp-10h]@1 + int v25; // [sp+28h] [bp-8h]@1 + int v26; // [sp+2Ch] [bp-4h]@1 + + v7 = a5; + LODWORD(a5) = *(unsigned int *)(LODWORD(a5) + 8); + //v24 = a5 + 6.7553994e15; + v26 = floorf(a5 + 0.5f);//LODWORD(v24); + LODWORD(a5) = *(unsigned int *)(LODWORD(v7) + 4); + //v24 = a5 + 6.7553994e15; + auto _v24 = floorf(a5 + 0.5f); + LODWORD(a5) = *(unsigned int *)LODWORD(v7); + //v23 = a5 + 6.7553994e15; + auto _v23 = floorf(a5 + 0.5f); + //*(_QWORD *)((char *)&v24 + 4) = __PAIR__(LODWORD(v24), LODWORD(v23)); + v26 = abs((signed)LODWORD(a1.z) - v26); + //v25 = abs((signed)LODWORD(a1.y) - (signed)LODWORD(v24)); + //v8 = abs((int)a1.x - (signed)LODWORD(v23)); + v25 = abs((signed)LODWORD(a1.y) - (signed)_v24); + v8 = abs((int)a1.x - (signed)_v23); + v14 = int_get_vector_length(v26, v25, v8); + if ( v14 <= a3 ) + { + a5 = v14 / a3; + v16 = (double)(signed int)a1.x; + *(float *)&v23 = (double)SLODWORD(a1.y); + LODWORD(a1.x) = *(unsigned int *)LODWORD(v7); + v17 = LODWORD(v7) + 4; + *((float *)&v23 + 1) = (double)SLODWORD(a1.z); + LODWORD(a1.y) = *(unsigned int *)v17; + LODWORD(a1.z) = *(unsigned int *)(v17 + 4); + a3 = *((float *)&v23 + 1) - a1.z; + a1.z = a3; + a1.x = v16 - a1.x; + a1.y = (float)v23 - a1.y; + a1.Normalize(); + if ( uLightType & 4 ) + { + __debugbreak(); // warning C4700: uninitialized local variable 'v18' used + v22[1] = v18; + uLightType = dword_4D86D8; + v22[0] = v18; + v19 = fabs(a1.z * pNormal->z + a1.y * pNormal->y + a1.x * pNormal->x); + v20 = v19 * *(float *)&uLightType * a2; + } + else + { + if ( uLightType & 8 ) + { + v20 = 1.3 * a2; + } + else + { + MessageBoxW(nullptr, L"Invalid light type detected!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Light.cpp:783", 0); + v20 = *(float *)&uLightType; + } + } + result = v20 - a5 * v20; + } + else + { + result = 0.0; + } + return result; +} +// 4D86D8: using guessed type int dword_4D86D8; + +//----- (0045CDB7) -------------------------------------------------------- +bool LightmapBuilder::ApplyLights_OutdoorFace(ODMFace *pFace) +{ + int v3; // eax@1 + bool result; // eax@9 + int pSlot; // [sp+10h] [bp-4h]@1 + + v3 = stru_F8AD28.uDefaultAmbientLightLevel + pFace->uShadeType; + pSlot = 0; + stru_F8AD28.uCurrentAmbientLightLevel = v3 << 16; + for ( uint i = 0; i < pMobileLightsStack->uNumLightsActive; ++i ) + { + if ( pSlot >= 20 ) + break; + ApplyLight_ODM((StationaryLight *)pMobileLightsStack[i].pLights, pFace, (unsigned int *)&pSlot, 1); + } + for ( uint i = 0; i < pStationaryLightsStack->uNumLightsActive; ++i ) + { + if ( pSlot >= 20 ) + break; + ApplyLight_ODM(&pStationaryLightsStack->pLights[i], pFace, (unsigned int *)&pSlot, 0); + } + result = pSlot; + stru_F8AD28.uNumLightsApplied = pSlot; + return true; +} + +//----- (0045CE50) -------------------------------------------------------- +bool LightmapBuilder::ApplyLight_ODM(StationaryLight *pLight, ODMFace *pFace, unsigned int *pSlot, char a4) +{ + int result; // eax@0 + int v10; // ecx@8 + //unsigned int v12; // ebx@11 + //RenderD3D *v13; // ecx@11 + char v14; // dl@11 + + //__debugbreak(); + + result = (int)pFace; + v10 = (pFace->pFacePlane.dist + + pLight->vPosition.x * pFace->pFacePlane.vNormal.x + + pLight->vPosition.y * pFace->pFacePlane.vNormal.y + + pLight->vPosition.z * pFace->pFacePlane.vNormal.z) >> 16; + if ( pLight->uRadius > 0 + && (pLight->vPosition.x > pFace->pBoundingBox.x1 - pLight->uRadius) && pLight->vPosition.x < pLight->uRadius + pFace->pBoundingBox.x2 + && (pLight->vPosition.y > pFace->pBoundingBox.y1 - pLight->uRadius) && pLight->vPosition.y < pLight->uRadius + pFace->pBoundingBox.y2 + && (pLight->vPosition.z > pFace->pBoundingBox.z1 - pLight->uRadius) && pLight->vPosition.z < pLight->uRadius + pFace->pBoundingBox.z2 + && ((a4) || v10 >= 0) && v10 <= pLight->uRadius ) + { + stru_F8AD28._blv_lights_radii[*pSlot] = pLight->uRadius; + stru_F8AD28._blv_lights_inv_radii[*pSlot] = 65536 / pLight->uRadius; + stru_F8AD28._blv_lights_xs[*pSlot] = pLight->vPosition.x; + stru_F8AD28._blv_lights_ys[*pSlot] = pLight->vPosition.y; + stru_F8AD28._blv_lights_zs[*pSlot] = pLight->vPosition.z; + stru_F8AD28._blv_lights_rs[*pSlot] = (double)pLight->uLightColorR * 0.0039215689; + stru_F8AD28._blv_lights_gs[*pSlot] = (double)pLight->uLightColorG * 0.0039215689; + stru_F8AD28._blv_lights_bs[*pSlot] = (double)pLight->uLightColorB * 0.0039215689; + //v11 = abs(v10); + //v12 = pRenderer->bUsingSpecular; + stru_F8AD28._blv_lights_light_dot_faces[*pSlot] = abs(v10); + stru_F8AD28._blv_lights_types[*pSlot] = pLight->uLightType; + //v13 = pRenderer->pRenderD3D; + v14 = stru_F8AD28._blv_lights_types[*pSlot]; + if ( /*pRenderer->pRenderD3D &&*/ pRenderer->bUsingSpecular && v14 & 4 ) + v14 = _4E94D2_light_type; + stru_F8AD28._blv_lights_types[*pSlot] = v14; + result = 4 * *pSlot; + if ( /*v13*/true && pRenderer->bUsingSpecular ) + { + if ( stru_F8AD28._blv_lights_types[*pSlot] & 4 ) + { + *(float *)((char *)stru_F8AD28._blv_lights_rs + result) = *(float *)((char *)stru_F8AD28._blv_lights_rs + result) + * 0.33000001; + *(float *)((char *)stru_F8AD28._blv_lights_gs + result) = *(float *)((char *)stru_F8AD28._blv_lights_gs + result) + * 0.33000001; + *(float *)((char *)stru_F8AD28._blv_lights_bs + result) = *(float *)((char *)stru_F8AD28._blv_lights_bs + result) + * 0.33000001; + } + } + ++*pSlot; + LOBYTE(result) = 1; + } + else + LOBYTE(result) = 0; + return result; +} +// 4E94D2: using guessed type char _4E94D2_light_type; + +//----- (0045D036) -------------------------------------------------------- +bool LightmapBuilder::StackLights_TerrainFace(Vec3_float_ *pNormal, float *a2, RenderVertexSoft *a3, unsigned int uStripType, bool bLightBackfaces) +{ + /*int v6; // esi@1 + //LightmapBuilder *v7; // edi@1 + MobileLight *v8; // ebx@2 + int v9; // esi@5 + StationaryLight *v10; // ebx@6 + //bool result; // eax@9 + unsigned int a7; // [sp+Ch] [bp-4h]@1 + + v6 = 0; + //v7 = this; + a7 = 0; + stru_F8AD28.uCurrentAmbientLightLevel = pOutdoor->field_CBC_terrain_triangles_shade_type; + if ( pMobileLightsStack->uNumLightsActive > 0 ) + { + v8 = pMobileLightsStack->pLights; + do + { + if ( (signed int)a7 >= 20 ) + break; + StackLight_TerrainFace((StationaryLight *)v8, pNormal, a3, a1, uStripType, bLightBackfaces, &a7); + ++v6; + ++v8; + } + while ( v6 < pMobileLightsStack->uNumLightsActive ); + } + v9 = 0; + if ( pStationaryLightsStack->uNumLightsActive > 0 ) + { + v10 = pStationaryLightsStack->pLights; + do + { + if ( (signed int)a7 >= 20 ) + break; + StackLight_TerrainFace(v10, pNormal, a3, a1, uStripType, bLightBackfaces, &a7); + ++v9; + ++v10; + } + while ( v9 < pStationaryLightsStack->uNumLightsActive ); + } + + stru_F8AD28.uNumLightsApplied = a7; + return true;*/ +// bool __stdcall sub_45D036(struct Vec3 *pNormal, int a2, struct RenderVertex *a3, int a4, signed int X) +//{ +// float v6; // ebx@2 + unsigned int v10; // [sp+Ch] [bp-4h]@1 + int i; + + v10 = 0; + stru_F8AD28.uCurrentAmbientLightLevel = pOutdoor->max_terrain_dimming_level; + for (i = 0; i < pMobileLightsStack->uNumLightsActive; ++i) + { + if ( v10 >= 20 ) + break; + StackLight_TerrainFace((StationaryLight *)&pMobileLightsStack->pLights[i], pNormal, a2, a3, uStripType, bLightBackfaces, &v10); + } + + for (i = 0; i < pStationaryLightsStack->uNumLightsActive; ++i) + { + if ( v10 >= 20 ) + break; + StackLight_TerrainFace(&pStationaryLightsStack->pLights[i], pNormal, a2, a3, uStripType, bLightBackfaces, &v10); + } + + stru_F8AD28.uNumLightsApplied = v10; + return true; + +} +// 519AB4: using guessed type int uNumStationaryLightsApplied; + +//----- (0045D0D5) -------------------------------------------------------- +bool LightmapBuilder::StackLight_TerrainFace(StationaryLight *pLight, Vec3_float_ *pNormal, float *a3, RenderVertexSoft *a1, unsigned int uStripType, int X, unsigned int *pSlot) +{ + StationaryLight *v8; // edi@1 + bool result; // eax@1 +// unsigned int v10; // esi@2 + RenderVertexSoft *v11; // ebx@2 + float v12; // eax@3 + float v13; // eax@4 +// double v14; // st7@11 + double maxz; // st7@11 + double v16; // st7@11 + double v17; // st6@11 +// __int16 v18; // fps@11 +// char v19; // c0@11 + char v20; // c2@11 +// char v21; // c3@11 +// double v22; // st6@12 +// __int16 v23; // fps@12 +// char v24; // c0@12 +// char v25; // c2@12 +// char v26; // c3@12 +// double v27; // st7@13 +// double v28; // st6@13 +// __int16 v29; // fps@13 +// char v30; // c0@13 +// char v31; // c2@13 +// char v32; // c3@13 +// double v33; // st6@14 +// __int16 v34; // fps@14 +// char v35; // c0@14 +// char v36; // c2@14 +// char v37; // c3@14 +// double v38; // st7@15 +// double v39; // st6@15 +// __int16 v40; // fps@15 +// char v41; // c0@15 +// char v42; // c2@15 +// char v43; // c3@15 +// double v44; // st6@16 +// __int16 v45; // fps@16 +// char v46; // c0@16 +// char v47; // c2@16 +// char v48; // c3@16 + Vec3_float_ *v49; // esi@17 +// double v50; // st7@17 +// double v51; // st6@17 + signed int v52; // ecx@17 + unsigned int *v53; // esi@18 + int v54; // eax@18 + unsigned int v55; // ebx@18 + //RenderD3D *v56; // ecx@18 + char v57; // dl@18 + std::string v58; // [sp-18h] [bp-38h]@10 + const char *v59; // [sp-8h] [bp-28h]@10 + signed int v60; // [sp-4h] [bp-24h]@10 + double v61; // [sp+Ch] [bp-14h]@11 + float minz; // [sp+14h] [bp-Ch]@11 + int v63; // [sp+18h] [bp-8h]@1 + float v64; // [sp+1Ch] [bp-4h]@5 + + v8 = pLight; + result = pLight->uRadius; + v63 = pLight->uRadius; + if ( result <= 0 ) + return 0; + //v10 = uStripType; + v11 = a1; + if ( uStripType == 4 ) + { + pLight = (StationaryLight *)LODWORD(a1->vWorldPosition.x); + v12 = a1[3].vWorldPosition.x; + //uStripType = LODWORD(v12); + a1 = (RenderVertexSoft *)LODWORD(a1[1].vWorldPosition.y); + v13 = v11->vWorldPosition.y; + } + else + { + if ( uStripType != 3 ) + { + MessageBoxW(nullptr, L"Uknown strip type detected!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Light.cpp:981", 0); + //goto LABEL_11; + } + else if ((unsigned char)X) + { + pLight = (StationaryLight *)LODWORD(a1->vWorldPosition.x); + uStripType = LODWORD(a1[2].vWorldPosition.x); + a1 = (RenderVertexSoft *)LODWORD(a1[1].vWorldPosition.y); + v13 = v11[2].vWorldPosition.y; + v64 = v13; + //goto LABEL_11; + //goto LABEL_5; + } + else + { + pLight = (StationaryLight *)LODWORD(a1[1].vWorldPosition.x); + v12 = a1[2].vWorldPosition.x; + a1 = (RenderVertexSoft *)LODWORD(a1[1].vWorldPosition.y); + v13 = v11->vWorldPosition.y; + v64 = v13; + //uStripType = LODWORD(v12); + a1 = (RenderVertexSoft *)LODWORD(a1[1].vWorldPosition.y); + v13 = v11->vWorldPosition.y; + } + } + +//LABEL_11: + //v60 = v10; + v59 = (const char *)v11; + v60 = v12;//uStripType; + minz = pGame->pIndoorCameraD3D->GetPolygonMinZ(v11, uStripType); + maxz = pGame->pIndoorCameraD3D->GetPolygonMaxZ(v11, uStripType); + result = v8->vPosition.x; + *((float *)&v61 + 1) = maxz; + v16 = (double)result; + *(float *)&X = (double)v63; + v17 = *(float *)&pLight - *(float *)&X; + //UNDEF(v18); + //v19 = v16 < v17; + v20 = 0; + //v21 = v16 == v17; +/* BYTE1(result) = HIBYTE(v18); + if ( v16 <= v17 + || (v22 = *(float *)&X + *(float *)&uStripType, + //UNDEF(v23), + v24 = v16 < v22, + v25 = 0, + v26 = v16 == v22, + BYTE1(result) = HIBYTE(v23), + v16 >= v22) + || (result = v8->vPosition.y, + pLight = (StationaryLight *)v8->vPosition.y, + v27 = (double)(signed int)pLight, + v28 = *(float *)&a1 - *(float *)&X, + //UNDEF(v29), + v30 = v27 < v28, + v31 = 0, + v32 = v27 == v28, + BYTE1(result) = HIBYTE(v29), + v27 <= v28) + || (v33 = *(float *)&X + v64, + //UNDEF(v34), + v35 = v27 < v33, + v36 = 0, + v37 = v27 == v33, + BYTE1(result) = HIBYTE(v34), + v27 >= v33) + || (result = v8->vPosition.z, + pLight = (StationaryLight *)v8->vPosition.z, + v38 = (double)(signed int)pLight, + v39 = minz - *(float *)&X, + //UNDEF(v40), + v41 = v38 < v39, + v42 = 0, + v43 = v38 == v39, + BYTE1(result) = HIBYTE(v40), + v38 <= v39) + || (v44 = *(float *)&X + *((float *)&v61 + 1), + //UNDEF(v45), + v46 = v38 < v44, + v47 = 0, + v48 = v38 == v44, + BYTE1(result) = HIBYTE(v45), + v38 >= v44) + || (v49 = pNormal, + Vec3_float_::NegDot(&v11->vWorldPosition, pNormal, a3), + X = v8->vPosition.y, + v50 = (double)X * v49->y, + X = v8->vPosition.z, + v51 = (double)X * v49->z, + X = v8->vPosition.x, + *(float *)&a3 = v50 + v51 + (double)X * v49->x + *a3, + v61 = *(float *)&a3 + 6.7553994e15, + result = LODWORD(v61), + X = LODWORD(v61), + v52 = v63, + SLODWORD(v61) > v63) )*/ + v49 = pNormal; + Vec3_float_::NegDot(&v11->vWorldPosition, pNormal, a3); + *(float *)a3 = (double)v8->vPosition.x * v49->x + + (double)v8->vPosition.y * v49->y + + (double)v8->vPosition.z * v49->z + *a3; + v61 = *(float *)a3 + 6.7553994e15; + result = LODWORD(v61); + X = LODWORD(v61); + v52 = v63; + if ( SLODWORD(v61) > v63) + return 0; + v53 = pSlot; + v60 = X; + stru_F8AD28._blv_lights_radii[*pSlot] = v63; + stru_F8AD28._blv_lights_inv_radii[*v53] = 65536 / v63; + stru_F8AD28._blv_lights_xs[*v53] = v8->vPosition.x; + stru_F8AD28._blv_lights_ys[*v53] = v8->vPosition.y; + stru_F8AD28._blv_lights_zs[*v53] = v8->vPosition.z; + //a3 = (float *)v8->uLightColorR; + stru_F8AD28._blv_lights_rs[*v53] = v8->uLightColorR / 255.0f; + //a3 = (float *)v8->uLightColorG; + stru_F8AD28._blv_lights_gs[*v53] = v8->uLightColorG / 255.0f; + //a3 = (float *)v8->uLightColorB; + stru_F8AD28._blv_lights_bs[*v53] = v8->uLightColorB / 255.0f; + v54 = abs(v63); + v55 = pRenderer->bUsingSpecular; + stru_F8AD28._blv_lights_light_dot_faces[*v53] = v54; + stru_F8AD28._blv_lights_types[*v53] = v8->uLightType; + //v56 = pRenderer->pRenderD3D; + v57 = stru_F8AD28._blv_lights_types[*v53]; + if ( /*pRenderer->pRenderD3D &&*/ v55 && v57 & 4 ) + v57 = _4E94D2_light_type; + stru_F8AD28._blv_lights_types[*v53] = v57; + result = 4 * *v53; + if ( /*v56 &&*/ v55 ) + { + if ( stru_F8AD28._blv_lights_types[*v53] & 4 ) + { + stru_F8AD28._blv_lights_rs[result] = stru_F8AD28._blv_lights_rs[result] * 0.3300000131130219; + stru_F8AD28._blv_lights_gs[result] = stru_F8AD28._blv_lights_gs[result] * 0.3300000131130219; + stru_F8AD28._blv_lights_bs[result] = stru_F8AD28._blv_lights_bs[result] * 0.3300000131130219; + } + } + ++*v53; + return 1; +} + +//----- (0045D698) -------------------------------------------------------- +bool LightmapBuilder::DrawDebugOutlines(char bit_one_for_list1__bit_two_for_list2) +{ + bool result; // eax@1 + LightmapBuilder *v3; // esi@1 + RenderVertexSoft *v4; // edi@3 + RenderVertexSoft *v5; // edi@7 + IndoorCameraD3D *thisa; // [sp+10h] [bp-8h]@1 + bool v7; // [sp+14h] [bp-4h]@2 + bool a2a; // [sp+20h] [bp+8h]@6 + + result = (bool)pGame->pIndoorCameraD3D; + v3 = this; + thisa = pGame->pIndoorCameraD3D; + if ( bit_one_for_list1__bit_two_for_list2 & 1 ) + { + v7 = 0; + if ( (signed int)this->std__vector_000004_size > 0 ) + { + v4 = this->std__vector_000004[0].pVertices; + do + { + pGame->pIndoorCameraD3D->debug_outline_sw(v4, *((unsigned int *)v4 - 1), 0xFF00u, 0.0); + ++v7; + v4 = (RenderVertexSoft *)((char *)v4 + 3100); + result = v7; + } + while ( v7 < (signed int)v3->std__vector_000004_size ); + } + } + if ( bit_one_for_list1__bit_two_for_list2 & 2 ) + { + a2a = 0; + if ( (signed int)v3->std__vector_183808_size > 0 ) + { + v5 = v3->std__vector_183808[0].pVertices; + do + { + pGame->pIndoorCameraD3D->debug_outline_sw(v5, *((unsigned int *)v5 - 1), 0xC04000u, 0.00019999999); + ++a2a; + v5 = (RenderVertexSoft *)((char *)v5 + 3100); + result = a2a; + } + while ( a2a < (signed int)v3->std__vector_183808_size ); + } + } + LOBYTE(result) = 1; + return result; +} + +//----- (0045D73F) -------------------------------------------------------- +void LightmapBuilder::DrawLightmapsType(int type) +{ + if (type == 2) + Draw_183808_Lightmaps(); +} + +//----- (0045D74F) -------------------------------------------------------- +bool LightmapBuilder::DrawLightmaps(int *indices) +{ + //char v3; // zf@1 +// IDirect3DDevice3 *v4; // eax@2 +// HRESULT v5; // eax@2 + //char *v6; // eax@2 + //struct IDirect3DTexture2 *v7; // edi@4 +// HRESULT v8; // eax@8 +// HRESULT v9; // eax@8 +// HRESULT v10; // eax@8 +// HRESULT v11; // eax@8 +// HRESULT v12; // eax@8 + //int *v13; // eax@8 + //float v14; // ecx@15 + //IDirect3DDevice3 *v15; // eax@21 + //HRESULT v16; // eax@21 + //IDirect3DDevice3 *v17; // eax@21 + //HRESULT v18; // eax@21 + //IDirect3DDevice3 *v19; // eax@21 + //HRESULT v20; // eax@21 + //IDirect3DDevice3 *v21; // eax@21 + //HRESULT v22; // eax@21 + //IDirect3DDevice3 *v23; // eax@23 + std::string v25; // [sp+44h] [bp-44h]@12 +// signed int v26; // [sp+48h] [bp-40h]@21 +// signed int v27; // [sp+4Ch] [bp-3Ch]@21 + Lightmap *v28; // [sp+50h] [bp-38h]@2 +// int v29; // [sp+54h] [bp-34h]@2 + //float v30; // [sp+58h] [bp-30h]@2 + Vec3_float_ arg4; + //int arg4; // [sp+68h] [bp-20h]@8 + //float v32; // [sp+6Ch] [bp-1Ch]@8 + //float v33; // [sp+70h] [bp-18h]@8 +// int v34; // [sp+74h] [bp-14h]@19 +// int v35; // [sp+78h] [bp-10h]@2 + //int *v36; // [sp+7Ch] [bp-Ch]@10 + //int a1; // [sp+80h] [bp-8h]@12 + //float v38; // [sp+84h] [bp-4h]@1 + + if (std__vector_000004_size == 0) + return true; + + if (byte_4D864C && pGame->uFlags & GAME_FLAGS_1_01_lightmap_related) + return true; + + pRenderer->BeginLightmaps(); + + arg4.x = 1.0f; + arg4.y = 1.0f; + arg4.z = 1.0f; + if (indices) + { + for (int* i = indices; *i != -1; ++i) + { + v28 = &std__vector_000004[*i]; + if ( !pRenderer->DrawLightmap(v28, &arg4, 0.0) ) + Error("Invalid lightmap detected! (%u)", *i); + } + } + else + { + for (unsigned int i = 0; i < std__vector_000004_size; ++i) + { + Lightmap* _a1 = &std__vector_000004[(int)i]; + if ( !pRenderer->DrawLightmap(_a1, &arg4, 0.0) ) + Error("Invalid lightmap detected! (%u)", i); + } + } + + pRenderer->EndLightmaps(); + + return true; +} + + +//----- (0045DA56) -------------------------------------------------------- +bool LightmapBuilder::DoDraw_183808_Lightmaps(float z_bias) +{ + Vec3_float_ v; // [sp+Ch] [bp-1Ch]@2 + v.z = 1.0; + v.y = 1.0; + v.x = 1.0; + + for (uint i = 0; i < std__vector_183808_size; ++i) + if (!pRenderer->DrawLightmap(std__vector_183808 + i, &v, z_bias)) + Error("Invalid lightmap detected! (%u)", i); + + return true; +} + +//----- (0045DAE8) -------------------------------------------------------- +bool Render::DrawLightmap(Lightmap *pLightmap, Vec3_float_ *pColorMult, float z_bias) +{ + double v10; // st7@4 + double v14; // st7@7 +// __int16 v15; // fps@8 + double v18; // st3@8 + signed int v24; // [sp-1Ch] [bp-670h]@13 +// const char *v25; // [sp-18h] [bp-66Ch]@13 +// int v26; // [sp-14h] [bp-668h]@13 + RenderVertexD3D3 a2[32]; // [sp+0h] [bp-654h]@7 + + + if (pLightmap->uNumVertices < 3) + { + Log::Warning(L"Lightmap uNumVertices < 3"); + return false; + } + + uint uLightmapColorMaskR = (pLightmap->uColorMask >> 16) & 0xFF; + uint uLightmapColorR = floorf(uLightmapColorMaskR * pLightmap->fBrightness * pColorMult->x + 0.5f); + + uint uLightmapColorMaskG = (pLightmap->uColorMask >> 8) & 0xFF; + uint uLightmapColorG = floorf(uLightmapColorMaskG * pLightmap->fBrightness * pColorMult->y + 0.5f); + + uint uLightmapColorMaskB = pLightmap->uColorMask & 0xFF; + uint uLightmapColorB = floorf(uLightmapColorMaskB * pLightmap->fBrightness * pColorMult->z + 0.5f); + + uint uLightmapColor = uLightmapColorB | (uLightmapColorMaskG << 8) | (uLightmapColorMaskR << 16); + + if (uCurrentlyLoadedLevelType == LEVEL_Outdoor) + v10 = (double)pODMRenderParams->shading_dist_mist; + else + v10 = 16192.0; + v14 = 1.0 / v10; + + for (uint i = 0; i < pLightmap->uNumVertices; ++i) + { + v18 = 1.0 - 1.0 / (v14 * pLightmap->pVertices[i].vWorldViewPosition.x * 1000.0); + if (fabsf(z_bias) < 1e-5f) + { + v18 = v18 - z_bias; + if (v18 < 0.000099999997) + v18 = 0.000099999997; + } + + a2[i].pos.x = pLightmap->pVertices[i].vWorldViewProjX; + a2[i].pos.z = v18; + a2[i].pos.y = pLightmap->pVertices[i].vWorldViewProjY; + a2[i].rhw = 1.0 / pLightmap->pVertices[i].vWorldViewPosition.x; + a2[i].diffuse = uLightmapColor; + a2[i].specular = 0; + a2[i].texcoord.x = pLightmap->pVertices[i].u; + a2[i].texcoord.y = pLightmap->pVertices[i].v; + } + + if (uCurrentlyLoadedLevelType == LEVEL_Indoor) + v24 = D3DDP_DONOTLIGHT | D3DDP_DONOTCLIP | D3DDP_DONOTUPDATEEXTENTS; + else + v24 = D3DDP_DONOTLIGHT; + + ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + a2, + pLightmap->uNumVertices, + v24)); + + return true; +} + +//----- (0045DCA9) -------------------------------------------------------- +void LightmapBuilder::Draw_183808_Lightmaps() +{ + if (!std__vector_183808_size) + return; + + pRenderer->BeginLightmaps2(); + + DoDraw_183808_Lightmaps(0.00050000002); + + pRenderer->EndLightmaps2(); +} \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/LightmapBuilder.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/LightmapBuilder.h Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,93 @@ +#pragma once +#include +#include "Render.h" + +struct LightsStack_StationaryLight_; +struct LightsStack_MobileLight_; + +/* 115 */ +#pragma pack(push, 1) +struct Lightmap +{ + Lightmap(); + virtual ~Lightmap() {} + + //void ( ***vdestructor_ptr)(Lightmap *, bool); + unsigned int uNumVertices; + RenderVertexSoft pVertices[64]; + __int16 field_C08; + __int16 field_C0A; + __int16 field_C0C; + __int16 field_C0E; + unsigned int uColorMask; + float fBrightness; + int field_C18; +}; +#pragma pack(pop) + + +/* 114 */ +#pragma pack(push, 1) +class LightmapBuilder +{ +public: + LightmapBuilder(); + virtual ~LightmapBuilder() //----- (0045BBAA) + {} + + void Draw_183808_Lightmaps(); + //bool DrawLightmap(Lightmap *a1, Vec3_float_ *pColorMult, float z_bias); + bool DoDraw_183808_Lightmaps(float a2); + bool DrawLightmaps(int *indices = nullptr); + void DrawLightmapsType(int type); + bool DrawDebugOutlines(char bit_one_for_list1__bit_two_for_list2); + double _45D643_sw(struct Edge *a1, float a2); + //int _45D426_sw(struct Span *a1, struct Edge **a2, unsigned int a3, struct Edge *a4, int a5); + //bool _45D3C7_sw(struct Polygon *a1); + bool StackLight_TerrainFace(struct StationaryLight *pLight, struct Vec3_float_ *pNormal, float *a3, struct RenderVertexSoft *a1, unsigned int uStripType, int X, unsigned int *pSlot); + bool StackLights_TerrainFace(struct Vec3_float_ *pNormal, float *a3, struct RenderVertexSoft *a1, unsigned int uStripType, bool bLightBackfaces); + bool ApplyLight_ODM(struct StationaryLight *pLight, struct ODMFace *pFace, unsigned int *pSlot, char a4); + bool ApplyLights_OutdoorFace(struct ODMFace *pFace); + double _45CC0C_light(struct Vec3_float_ a1, float a2, float a3, struct Vec3_float_ *pNormal, float a5, int uLightType); + int _45CBD4(struct RenderVertexSoft *a2, int a3, int *a4, int *a5); + int _45CB89(struct RenderVertexSoft *a1, int a2); + int _45CA88(struct stru320 *a2, struct RenderVertexSoft *a3, int a4, struct Vec3_float_ *pNormal); + bool ApplyLight_BLV(struct StationaryLight *pLight, struct BLVFace *a2, unsigned int *pSlot, bool bLightBackfaces, char *a5); + bool ApplyLights_IndoorFace(unsigned int uFaceID); + int _45C6D6(int a2, struct RenderVertexSoft *a3, Lightmap *pLightmap); + int _45C4B9(int a2, struct RenderVertexSoft *a3, Lightmap *pLightmap); + bool _45BE86_build_light_polygon(Vec3_int_ *pos, float radius, unsigned int uColorMask, float dot_dist, int uLightType, struct stru314 *a7, unsigned int uNumVertices, RenderVertexSoft *a9, char uClipFlag); + bool ApplyLights(struct stru320 *a2, struct stru154 *a3, unsigned int uNumVertices, struct RenderVertexSoft *a5, struct IndoorCameraD3D_Vec4 *, char uClipFlag); + + + //void ( ***vdestructor_ptr)(LightmapBuilder *, bool); + //std::vector std__vector_000004; + //std::vector std__vector_183808; + Lightmap std__vector_000004[512]; + unsigned int std__vector_000004_size; + Lightmap std__vector_183808[768]; + unsigned int std__vector_183808_size; + float flt_3C8C0C; + float flt_3C8C10; + float flt_3C8C14; + float flt_3C8C18; + float flt_3C8C1C; + float flt_3C8C20; + float flt_3C8C24; + float flt_3C8C28; + float flt_3C8C2C_lightmaps_brightness; + float flt_3C8C30; + RenderVertexSoft field_3C8C34[256]; + int uFlags; +}; +#pragma pack(pop) + + + + +extern LightsStack_StationaryLight_ *pStationaryLightsStack; +//extern StationaryLight pStationaryLights[400]; +//extern int uNumStationaryLightsApplied; // weak +extern LightsStack_MobileLight_ *pMobileLightsStack; +//extern MobileLight pMobileLights[400]; +//extern int uNumMobileLightsApplied; \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/Lights.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/Lights.h Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,111 @@ +#pragma once + +#include "VectorTypes.h" + + +/* 257 */ +#pragma pack(push, 1) +struct StationaryLight +{ + Vec3_short_ vPosition; + __int16 uRadius; + unsigned __int8 uLightColorR; + unsigned __int8 uLightColorG; + unsigned __int8 uLightColorB; + char uLightType; +}; +#pragma pack(pop) + + + + +#pragma pack(push, 1) +struct MobileLight +{ + Vec3_short_ vPosition; + __int16 uRadius; + unsigned __int8 uLightColorR; + unsigned __int8 uLightColorG; + unsigned __int8 uLightColorB; + char uLightType; + __int16 field_C; + __int16 uSectorID; + __int16 field_10; +}; +#pragma pack(pop) + + + +/* +#pragma pack(push, 1) +struct LightStack +{ + int field_0; + char T[400]; + unsigned int uNumLightsActive; +}; +#pragma pack(pop)*/ + + + +/* 260 */ +#pragma pack(push, 1) +struct LightsStack_StationaryLight_ +{ + //----- (004AD385) -------------------------------------------------------- + LightsStack_StationaryLight_() + { + uNumLightsActive = 0; + } + + //----- (004AD395) -------------------------------------------------------- + virtual ~LightsStack_StationaryLight_() + { + uNumLightsActive = 0; + } + + //----- (004AD39D) -------------------------------------------------------- + inline unsigned int GetNumLights() + { + return uNumLightsActive; + } + + //----- (004AD3C8) -------------------------------------------------------- + bool AddLight(__int16 x, __int16 y, __int16 z, __int16 a5, unsigned char r, unsigned char g, unsigned char b, char uLightType); + + + + //void ( ***vdestructor_ptr)(LightsStack_StationaryLight_ *, bool); + StationaryLight pLights[400]; + unsigned int uNumLightsActive; +}; +#pragma pack(pop) + + + + +/* 261 */ +#pragma pack(push, 1) +struct LightsStack_MobileLight_ +{ + //----- (00467D45) -------------------------------------------------------- + inline LightsStack_MobileLight_() + { + this->uNumLightsActive = 0; + //this->vdestructor_ptr = &pLightsStack_MobileLight__pvdtor; + } + //----- (00467D55) -------------------------------------------------------- + virtual ~LightsStack_MobileLight_() + { + this->uNumLightsActive = 0; + } + + bool AddLight(__int16 x, __int16 y, __int16 z, __int16 uSectorID, int uRadius, unsigned __int8 r, unsigned __int8 g, unsigned __int8 b, char a10); + + + + //void ( ***vdestructor_ptr)(LightsStack_MobileLight_ *, bool); + MobileLight pLights[400]; + unsigned int uNumLightsActive; +}; +#pragma pack(pop) \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/LightsStack.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/LightsStack.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,57 @@ +#define _CRTDBG_MAP_ALLOC +#include +#include + +#define _CRT_SECURE_NO_WARNINGS +#include +#include "Lights.h" +#include "OSAPI.h" + + +//----- (00467D88) -------------------------------------------------------- +bool LightsStack_MobileLight_::AddLight(__int16 x, __int16 y, __int16 z, __int16 uSectorID, int uRadius, unsigned __int8 r, unsigned __int8 g, unsigned __int8 b, char uLightType) +{ + if (uNumLightsActive >= 400) + { + MessageBoxW(nullptr, L"Too many mobile lights!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\MobileLightStack.cpp:51", 0); + return false; + } + + pLights[uNumLightsActive].vPosition.x = x; + pLights[uNumLightsActive].vPosition.y = y; + pLights[uNumLightsActive].vPosition.z = z; + pLights[uNumLightsActive].uRadius = uRadius; + pLights[uNumLightsActive].field_C = (((uRadius < 0) - 1) & 0x3E) - 31; + pLights[uNumLightsActive].uSectorID = uSectorID; + pLights[uNumLightsActive].field_10 = uRadius * uRadius >> 5; + pLights[uNumLightsActive].uLightColorR = r; + pLights[uNumLightsActive].uLightColorG = g; + pLights[uNumLightsActive].uLightColorB = b; + pLights[uNumLightsActive++].uLightType = uLightType; + + return true; +} + +bool LightsStack_StationaryLight_::AddLight( __int16 x, __int16 y, __int16 z, __int16 a5, unsigned char r, unsigned char g, unsigned char b, char uLightType ) +{ + //unsigned int v9; // eax@1 + //std::string v11; // [sp-18h] [bp-18h]@3 + + //v9 = this->uNumLightsActive; + if ( (signed int)this->uNumLightsActive >= 400 ) + { + MessageBoxW(nullptr, L"Too many stationary lights!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\StationaryLightStack.cpp:45", 0); + return false; + } + + StationaryLight* pLight = &pLights[uNumLightsActive++]; + pLight->vPosition.x = x; + pLight->vPosition.y = y; + pLight->vPosition.z = z; + pLight->uRadius = a5; + pLight->uLightColorR = (unsigned __int8)r; + pLight->uLightColorG = g; + pLight->uLightColorB = b; + pLight->uLightType = uLightType; + return true; +} diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/Outdoor.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/Outdoor.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,5000 @@ +#define _CRTDBG_MAP_ALLOC +#include +#include + +#define _CRT_SECURE_NO_WARNINGS +#include "ErrorHandling.h" + +#include "stru6.h" +#include "Weather.h" +#include "Sprites.h" +#include "LightmapBuilder.h" +#include "Outdoor.h" +#include "Party.h" +#include "SpriteObject.h" +#include "LOD.h" +#include "PaletteManager.h" +#include "GUIProgressBar.h" +#include "AudioPlayer.h" +#include "DecorationList.h" +#include "OurMath.h" +#include "ObjectList.h" +#include "Game.h" +#include "Actor.h" +#include "Chest.h" +#include "stru123.h" +#include "Timer.h" +#include "Viewport.h" +#include "Events.h" +#include "ParticleEngine.h" +#include "TurnEngine.h" + +#include "MM7.h" +#include "Lights.h" + +#include "GUIWindow.h" +#include "Engine/Graphics/Level/Decoration.h" +#include "ZlibWrapper.h" +#include "MMT.h" + +MapStartPoint uLevel_StartingPointType; // weak + +OutdoorLocation *pOutdoor = new OutdoorLocation; +ODMRenderParams *pODMRenderParams; + + +stru149 stru_8019C8; +std::array array_77EC08; + + +struct FogProbabilityTableEntry +{ + unsigned char small_fog_chance; + unsigned char average_fog_chance; + unsigned char dense_fog_chance; + unsigned char __unused; +} fog_probability_table[15] = +{ + { 20, 10, 5, 0}, // MAP_EMERALD_ISLE + { 20, 10, 5, 0}, // MAP_HARMONDALE + { 20, 10, 5, 0}, // MAP_STEADWICK + { 20, 10, 5, 0}, // MAP_PIERPONT + { 20, 10, 5, 0}, // MAP_DEYJA + { 10, 5, 0, 0}, // MAP_BRAKADA_DESERT + { 0, 0, 0, 0}, // MAP_CELESTIA + { 0, 0, 0, 0}, // MAP_THE_PIT + { 20, 30, 50, 0}, // MAP_EVENMORN_ISLE + { 30, 20, 10, 0}, // MAP_MOUNT_NIGHON + { 10, 5, 0, 0}, // MAP_BARROW_DOWNS + { 20, 10, 5, 0}, // MAP_LAND_OF_GIANTS + { 20, 10, 5, 0}, // MAP_TATALIA + { 20, 10, 5, 0}, // MAP_AVLEE + { 0, 100, 0, 0} // MAP_SHOALS +}; + +//for future sky textures? +std::array dword_4EC268={{3,3,3,3,3,3,3,3,3}}; // weak +std::array dword_4EC28C={{3,3,3,3,3,3,3}}; // weak +int dword_4EC2A8=9; // weak +int dword_4EC2AC=7; // weak + + + +//----- (0047A59E) -------------------------------------------------------- +void OutdoorLocation::ExecDraw(unsigned int bRedraw) +{ + + pGame->pIndoorCameraD3D->debug_flags = 0; + if (viewparams->draw_d3d_outlines) + pGame->pIndoorCameraD3D->debug_flags |= ODM_RENDER_DRAW_D3D_OUTLINES; + + if (bRedraw || true/*pRenderer->pRenderD3D*/) + { + //pODMRenderParams->RotationToInts(); + sub_481ED9_MessWithODMRenderParams(); + } + + pODMRenderParams->uMapGridCellX = WorldPosToGridCellX(pParty->vPosition.x); + pODMRenderParams->uMapGridCellZ = WorldPosToGridCellZ(pParty->vPosition.y); + assert(pODMRenderParams->uMapGridCellX <= 127 && pODMRenderParams->uMapGridCellZ <= 127); + + if (bRedraw) + { + sub_487DA9(); + } + if ( pParty->uCurrentMinute != pOutdoor->uLastSunlightUpdateMinute ) + pOutdoor->UpdateSunlightVectors(); + pOutdoor->UpdateFog(); + //pGame->pIndoorCameraD3D->sr_Reset_list_0037C(); + + //if (pRenderer->pRenderD3D) // d3d - redraw always + { + pRenderer->DrawOutdoorSkyD3D(); + pRenderer->DrawBuildingsD3D(); + pRenderer->RenderTerrainD3D(); + //pRenderer->DrawBezierTerrain(); + } + /*else + { + if (!bRedraw) + pRenderer->OnOutdoorRedrawSW(); + else + { + pRenderer->DrawBuildingsSW(); + pRenderer->DrawBezierTerrain(); + sr_sub_486F92_MessWithEdgesAndSpans(); + pODMRenderParams->ApplyLightmapsSW(); + } + }*/ + + + pMobileLightsStack->uNumLightsActive = 0; + pStationaryLightsStack->uNumLightsActive = 0; + /*if ( !pRenderer->pRenderD3D ) + { + pRenderer->ExecOutdoorDrawSW(); + pGame->pIndoorCameraD3D->sr_438240_draw_lits(); + }*/ + pGame->PushStationaryLights(-1); + pGame->PrepareBloodsplats(); + if (bRedraw) + pOutdoor->UpdateDiscoveredArea(WorldPosToGridCellX(pParty->vPosition.x), WorldPosToGridCellZ(pParty->vPosition.y), 1); + pGame->uFlags2 &= 0xFFFFFFFEu; + if (/*pRenderer->pRenderD3D*/true && pRenderer->bUsingSpecular) + pGame->pLightmapBuilder->uFlags |= 1; + else + pGame->pLightmapBuilder->uFlags &= 0xFFFFFFFEu; + + uNumDecorationsDrawnThisFrame = 0; + uNumSpritesDrawnThisFrame = 0; + uNumBillboardsToDraw = 0; + + PrepareActorsDrawList(); + if (!pODMRenderParams->bDoNotRenderDecorations) + pRenderer->PrepareDecorationsRenderList_ODM(); + + pRenderer->DrawSpriteObjects_ODM(); + pRenderer->TransformBillboardsAndSetPalettesODM(); +} + + +//----- (00441CFF) -------------------------------------------------------- +void OutdoorLocation::Draw() +{ + bool redrawWorld = true; + if ( !(pParty->uFlags & 2) && !(pGame->uFlags2 & 1) ) + redrawWorld = false; + pOutdoor->ExecDraw(redrawWorld); + + pGame->DrawParticles(); + //pWeather->Draw();//если раскомментировать скорость снега быстрее + trail_particle_generator.UpdateParticles(); +} + +//----- (00488E23) -------------------------------------------------------- +double OutdoorLocation::GetFogDensityByTime() +{ + if ( pParty->uCurrentHour < 5 )//ночь + { + pWeather->bNight = true; + return 60.0 * 0.016666668; + } + else if ( pParty->uCurrentHour >= 5 && pParty->uCurrentHour < 6 )//рассвет + { + pWeather->bNight = false; + return (60.0 - (double)(60 * pParty->uCurrentHour + pParty->uCurrentMinute - 300)) * 0.016666668; + } + else if ( pParty->uCurrentHour >= 6 && pParty->uCurrentHour < 20 )//день + { + pWeather->bNight = false; + return 0.0; + } + else if ( pParty->uCurrentHour >= 20 && pParty->uCurrentHour < 21 )//сумерки + { + pWeather->bNight = false; + return ((double)(pParty->uCurrentHour - 20) * 60.0 + (double)(signed int)pParty->uCurrentMinute) * 0.016666668; + } + else//ночь + { + pWeather->bNight = true; + return 60.0 * 0.016666668; + } +} + +//----- (00488EB1) -------------------------------------------------------- +int OutdoorLocation::GetSomeOtherTileInfo(int sX, int sY) +{ + //OutdoorLocation *v3; // esi@1 + unsigned int v4; // edi@1 + unsigned int v5; // eax@1 +// int result; // eax@5 + +/* v3 = this; + v4 = WorldPosToGridCellZ(sY); + v5 = WorldPosToGridCellX(sX); + if ( (v5 & 0x80000000u) != 0 || (signed int)v5 > 127 || (v4 & 0x80000000u) != 0 || (signed int)v4 > 127 ) + result = 0; + else + result = ActuallyGetSomeOtherTileInfo(v5, v4); + return result;*/ + v4 = WorldPosToGridCellZ(sY); + v5 = WorldPosToGridCellX(sX); + if ( v5 < 0 || v5 > 127 || v4 < 0 || v4 > 127 ) + return 0; + return ActuallyGetSomeOtherTileInfo(v5, v4); +} +// 47F44B: using guessed type int __stdcall WorldPosToGridCellX(int); +// 47F458: using guessed type int __stdcall WorldPosToGridCellZ(int); + +//----- (00488EEF) -------------------------------------------------------- +unsigned int OutdoorLocation::GetTileTexture(signed int sX, signed int sY) +{ + //OutdoorLocation *v3; // esi@1 + signed int v4; // edi@1 + signed int v5; // eax@1 +// unsigned int result; // eax@5 + + /*v3 = this; + v4 = WorldPosToGridCellZ(sZ); + v5 = WorldPosToGridCellX(sX); + if ( v5< 0 || (signed int)v5 > 127 || v4 < 0 || (signed int)v4 > 127 )//if ( (v5 & 0x80000000u) != 0 || (signed int)v5 > 127 || (v4 & 0x80000000u) != 0 || (signed int)v4 > 127 ) + result = -1; + else + result = DoGetTileTexture(v5, v4); + return result;*/ + v4 = WorldPosToGridCellZ(sY); + v5 = WorldPosToGridCellX(sX); + if ( v5 < 0 || v5 > 127 || v4 < 0 || v4 > 127 ) + return -1; + return DoGetTileTexture(v5, v4); +} +// 47F44B: using guessed type int __stdcall WorldPosToGridCellX(int); +// 47F458: using guessed type int __stdcall WorldPosToGridCellZ(int); + +//----- (00488F2E) -------------------------------------------------------- +int OutdoorLocation::GetHeightOnTerrain(int sX, int sZ) + /* Функция предоставляет возможность перемещать камеру таким образом, чтобы она имитировала ходьбу по ландшафту. + То есть нам надо менять высоту камеры (координату Y) в зависимости от того, в каком месте ландшафта мы находимся. + Для этого мы сначала должны определить по координатам X и Z камеры квадрат ландшафта в котором мы находимся. + Все это делает функция Terrain::getHeight; в своих параметрах она получает координаты X и Z камеры и возвращает высоту, + на которой должна быть расположена камера, чтобы она оказалась над ландшафтом.*/ +{ + int result; // eax@5 + + if ( sX < 0 || sX > 127 || sZ < 0 || sZ > 127 ) + result = 0; + else + result = DoGetHeightOnTerrain(sX, sZ); + return result; +} + +//----- (00488F5C) -------------------------------------------------------- +bool OutdoorLocation::Initialize(const char *pFilename, int File, size_t uRespawnInterval, int *thisa) +{ + OutdoorLocation *v5; // esi@1 + bool result; // eax@2 + + v5 = this; + if ( pFilename ) + { + Release(); + pBitmaps_LOD->ReleaseAll2(); + pSprites_LOD->DeleteSomeOtherSprites(); + pSpriteFrameTable->ResetSomeSpriteFlags(); + pIcons_LOD->ReleaseAll2(); + + if ( !Load(pFilename, (ODMFace *)File, uRespawnInterval, thisa) ) + { + MessageBoxA(0, "Error!", "Couldn't Load Map!", 0); + CreateDebugLocation(); + } + ::day_attrib = v5->loc_time.day_attrib; + ::day_fogrange_1 = v5->loc_time.day_fogrange_1; + ::day_fogrange_2 = v5->loc_time.day_fogrange_2; + if ( Is_out15odm_underwater() ) + SetUnderwaterFog(); + _6BE134_odm_main_tile_group = v5->pTileTypes[0].tileset; + result = 1; + } + else + { + result = 0; + } + return result; +} + + + +char foot_travel_destinations[15][4] = +{ +// north south east west from + {MAP_INVALID, MAP_INVALID, MAP_INVALID, MAP_INVALID}, // MAP_EMERALD_ISLE + {MAP_PIERPONT, MAP_BARROW_DOWNS, MAP_PIERPONT, MAP_STEADWICK}, // MAP_HARMONDALE + {MAP_DEYJA, MAP_BRAKADA_DESERT, MAP_HARMONDALE, MAP_TATALIA}, // MAP_STEADWICK + {MAP_AVLEE, MAP_HARMONDALE, MAP_INVALID, MAP_DEYJA}, // MAP_PIERPONT + {MAP_PIERPONT, MAP_STEADWICK, MAP_PIERPONT, MAP_STEADWICK}, // MAP_DEYJA + {MAP_STEADWICK, MAP_INVALID, MAP_BARROW_DOWNS, MAP_INVALID}, // MAP_BRAKADA_DESERT + {MAP_INVALID, MAP_INVALID, MAP_INVALID, MAP_INVALID}, // MAP_CELESTIA + {MAP_INVALID, MAP_INVALID, MAP_INVALID, MAP_INVALID}, // MAP_THE_PIT + {MAP_INVALID, MAP_INVALID, MAP_INVALID, MAP_INVALID}, // MAP_EVENMORN_ISLE + {MAP_INVALID, MAP_INVALID, MAP_INVALID, MAP_INVALID}, // MAP_MOUNT_NIGHON + {MAP_HARMONDALE, MAP_BRAKADA_DESERT, MAP_HARMONDALE, MAP_BRAKADA_DESERT}, // MAP_BARROW_DOWNS + {MAP_INVALID, MAP_INVALID, MAP_INVALID, MAP_INVALID}, // MAP_LAND_OF_GIANTS + {MAP_INVALID, MAP_INVALID, MAP_STEADWICK, MAP_INVALID}, // MAP_TATALIA + {MAP_INVALID, MAP_PIERPONT, MAP_PIERPONT, MAP_INVALID}, // MAP_AVLEE + {MAP_INVALID, MAP_INVALID, MAP_INVALID, MAP_INVALID} // MAP_SHOALS +}; +unsigned char foot_travel_times[15][4] = +{ +// north south east west from + {0, 0, 0, 0}, // MAP_EMERALD_ISLE + {5, 5, 7, 5}, // MAP_HARMONDALE + {5, 5, 5, 5}, // MAP_STEADWICK + {5, 5, 0, 5}, // MAP_PIERPONT + {7, 5, 5, 4}, // MAP_DEYJA + {5, 0, 5, 0}, // MAP_BRAKADA_DESERT + {0, 0, 0, 0}, // MAP_CELESTIA + {0, 0, 0, 0}, // MAP_THE_PIT + {0, 0, 0, 0}, // MAP_EVENMORN_ISLE + {0, 0, 0, 0}, // MAP_MOUNT_NIGHON + {5, 7, 7, 5}, // MAP_BARROW_DOWNS + {0, 0, 0, 0}, // MAP_LAND_OF_GIANTS + {0, 0, 5, 0}, // MAP_TATALIA + {0, 7, 5, 0}, // MAP_AVLEE + {0, 0, 0, 0}, // MAP_SHOALS +}; + + +MapStartPoint foot_travel_arrival_points[15][4] = +{ +// north south east west from + {MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party}, // MAP_EMERALD_ISLE + {MapStartPoint_South, MapStartPoint_North, MapStartPoint_South, MapStartPoint_East}, // MAP_HARMONDALE + {MapStartPoint_South, MapStartPoint_North, MapStartPoint_West, MapStartPoint_East}, // MAP_STEADWICK + {MapStartPoint_East, MapStartPoint_North, MapStartPoint_Party, MapStartPoint_East}, // MAP_PIERPONT + {MapStartPoint_West, MapStartPoint_North, MapStartPoint_West, MapStartPoint_North}, // MAP_DEYJA + {MapStartPoint_South, MapStartPoint_Party, MapStartPoint_West, MapStartPoint_Party}, // MAP_BRAKADA_DESERT + {MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party}, // MAP_CELESTIA + {MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party}, // MAP_THE_PIT + {MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party}, // MAP_EVENMORN_ISLE + {MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party}, // MAP_MOUNT_NIGHON + {MapStartPoint_South, MapStartPoint_East, MapStartPoint_South, MapStartPoint_East}, // MAP_BARROW_DOWNS + {MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party}, // MAP_LAND_OF_GIANTS + {MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_West, MapStartPoint_Party}, // MAP_TATALIA + {MapStartPoint_Party, MapStartPoint_North, MapStartPoint_North, MapStartPoint_Party}, // MAP_AVLEE + {MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party}, // MAP_SHOALS +}; + + +//----- (0048902E) -------------------------------------------------------- +bool OutdoorLocation::GetTravelDestination(signed int sPartyX, signed int sPartyZ, char *pOut, signed int a5) +{ + char *mapNumberAsStr; // eax@3 + int mapNumberAsInt; // eax@3 + signed int direction; // esi@7 + signed int destinationMap; // eax@23 + char Str[140]; // [sp+8h] [bp-78h]@3 + + strcpy(Str, this->pLevelFilename);//настоящая локация + _strlwr(Str); + mapNumberAsStr = strtok(Str, "out"); + mapNumberAsStr[2] = 0; + mapNumberAsInt = atoi(mapNumberAsStr); + if ( a5 < 10 || strlen(this->pLevelFilename) != 9 || mapNumberAsInt < 1 || mapNumberAsInt > 15 ) //длина .odm и количество локаций + return 0; + if ( sPartyX < -22528 )//граница карты + direction = 4; + else if ( sPartyX > 22528 ) + direction = 3; + else if ( sPartyZ < -22528 ) + direction = 2; + else if ( sPartyZ > 22528 ) + direction = 1; + else + return false; + + if ( mapNumberAsInt == MAP_AVLEE && direction == 4) // to Shoals + { + if ( pPlayers[1]->HasUnderwaterSuitEquipped() && + pPlayers[2]->HasUnderwaterSuitEquipped() && + pPlayers[3]->HasUnderwaterSuitEquipped() && + pPlayers[4]->HasUnderwaterSuitEquipped()) + { + uDefaultTravelTime_ByFoot = 1; + strcpy(pOut, "out15.odm"); + uLevel_StartingPointType = MapStartPoint_East; + LOWORD(pParty->uFlags) &= 0xFD7Bu; + return true; + } + } + else if ( mapNumberAsInt == MAP_SHOALS && direction == 3 ) //from Shoals + { + uDefaultTravelTime_ByFoot = 1; + strcpy(pOut, "out14.odm");//Авли + uLevel_StartingPointType = MapStartPoint_West; + LOWORD(pParty->uFlags) &= 0xFD7Bu; + return true; + } + destinationMap = foot_travel_destinations[mapNumberAsInt - 1][direction - 1]; + if (destinationMap == MAP_INVALID) + return false; + + assert(destinationMap <= MAP_SHOALS); + + uDefaultTravelTime_ByFoot = foot_travel_times[mapNumberAsInt - 1][direction - 1]; + uLevel_StartingPointType = foot_travel_arrival_points[mapNumberAsInt - 1][direction - 1]; + sprintf(pOut, "out%02d.odm", destinationMap); //локация направления + return true; +} +// 6BD07C: using guessed type int uDefaultTravelTime_ByFoot; +// 6BE35C: using guessed type int uLevel_StartingPointType; + +//----- (0048917E) -------------------------------------------------------- +void OutdoorLocation::MessWithLUN() +{ + this->pSpriteIDs_LUN[0] = -1; + this->pSpriteIDs_LUN[1] = 0; + this->pSpriteIDs_LUN[2] = pSpriteFrameTable->FastFindSprite("LUN1-4"); + this->pSpriteIDs_LUN[3] = 0; + this->pSpriteIDs_LUN[4] = pSpriteFrameTable->FastFindSprite("LUN1-2"); + this->pSpriteIDs_LUN[5] = 0; + this->pSpriteIDs_LUN[6] = pSpriteFrameTable->FastFindSprite("LUN3-4"); + this->pSpriteIDs_LUN[7] = 0; + this->uSpriteID_LUNFULL = pSpriteFrameTable->FastFindSprite("LUNFULL"); + this->uSpriteID_LUN1_2_cp = pSpriteFrameTable->FastFindSprite("LUN1-2"); + this->uSpriteID_LUN1_4_cp = pSpriteFrameTable->FastFindSprite("LUN1-4"); + this->uSpriteID_LUN3_4_cp = pSpriteFrameTable->FastFindSprite("LUN3-4"); + this->field_D60 = -1; + this->field_CF0 = 4; + this->field_CF8 = 4; + this->field_D00 = 4; + this->field_CE8 = 0; + this->field_D3C = (int)this->pSpriteIDs_LUN; + this->field_D40 = 0; + this->field_D44 = 0; + this->field_D48 = 0; + this->field_D4C = 131072; + this->field_D5C = 0; + this->field_D64 = 0; + this->field_D28 = -1; + this->field_D08 = 0; + this->field_D0C = 0; + this->field_D10 = 0; + this->field_D24 = 0; + this->field_D2C = 0; + this->uSpriteID_LUN_SUN = pSpriteFrameTable->FastFindSprite("LUN-SUN"); + this->field_D14 = -131072; + for ( uint i = 0; i < 8; i++ ) + pSpriteFrameTable->InitializeSprite(this->pSpriteIDs_LUN[i]);//v2 += 2; + pSpriteFrameTable->InitializeSprite(this->uSpriteID_LUN_SUN); +} + +//----- (004892E6) -------------------------------------------------------- +void OutdoorLocation::UpdateSunlightVectors() +{ + unsigned int v3; // edi@3 + double v8; // st7@4 + + if ( pParty->uCurrentHour >= 5 && pParty->uCurrentHour < 21 ) + { + v3 = pParty->uCurrentMinute + 60 * (pParty->uCurrentHour - 5); + this->inv_sunlight_y = 0; + this->inv_sunlight_x = stru_5C6E00->Cos((v3 * stru_5C6E00->uIntegerPi) / 960); + this->inv_sunlight_z = stru_5C6E00->Sin((v3 * stru_5C6E00->uIntegerPi) / 960); + this->vSunlight.x = -this->inv_sunlight_x; + this->vSunlight.y = -this->inv_sunlight_y; + this->vSunlight.z = -this->inv_sunlight_z; + if ( v3 >= 480 ) + v8 = 960 - v3; + else + v8 = v3; + this->max_terrain_dimming_level = (int)(20.0 - v8 / 480.0 * 20.0); + this->uLastSunlightUpdateMinute = pParty->uCurrentMinute; + } +} + +//----- (004893C1) -------------------------------------------------------- +void OutdoorLocation::UpdateFog() +{ + fFogDensity = GetFogDensityByTime(); +} + +//----- (004893CF) -------------------------------------------------------- +int OutdoorLocation::GetNumFoodRequiredToRestInCurrentPos(int x, signed int y, int z) +{ + int v7; // eax@4 + int is_on_water; // [sp+8h] [bp-8h]@2 + int bmodel_standing_on_pid; // [sp+Ch] [bp-4h]@2 + + is_on_water = 0; + bmodel_standing_on_pid = 0; + ODM_GetFloorLevel(x, y, z, pParty->uDefaultPartyHeight, &is_on_water, &bmodel_standing_on_pid, 0); + if ( pParty->uFlags & 8 || bmodel_standing_on_pid || is_on_water )//на bmodel,и или на воде + return 2; + v7 = _47ED83(WorldPosToGridCellX(pParty->vPosition.x), WorldPosToGridCellZ(pParty->vPosition.y) - 1); + switch ( pTileTable->pTiles[GetTileIdByTileMapId(v7)].tileset ) + { + case Tileset_Grass://на траве + return 1; + case Tileset_Snow://на снегу + return 3; + case Tilset_Desert://на песке + return 5; + case Tileset_3: + case Tileset_Dirt:// на грязи + return 4; + case Tileset_Water:// on water(на воде) + return 3;//еденицы еды + default: + return 2; + } +} + +//----- (00489487) -------------------------------------------------------- +void OutdoorLocation::SetFog() +{ + strcpy(pOutdoor->pLevelFilename, pCurrentMapName); + + MAP_TYPE map_id = pMapStats->GetMapInfo(pCurrentMapName); + if (map_id == MAP_INVALID || map_id == MAP_CELESTIA || map_id == MAP_THE_PIT || map_id > MAP_SHOALS) + return; + + uint chance = rand() % 100; + + if (chance < fog_probability_table[map_id - 1].small_fog_chance) + { + ::day_fogrange_1 = 4096; + ::day_fogrange_2 = 8192; + ::day_attrib |= DAY_ATTRIB_FOG; + } + else if (chance < fog_probability_table[map_id - 1].small_fog_chance + + fog_probability_table[map_id - 1].average_fog_chance) + { + ::day_fogrange_2 = 4096; + ::day_fogrange_1 = 0; + ::day_attrib |= DAY_ATTRIB_FOG; + } + else if (fog_probability_table[map_id - 1].dense_fog_chance && + chance < fog_probability_table[map_id - 1].small_fog_chance + + fog_probability_table[map_id - 1].average_fog_chance + + fog_probability_table[map_id - 1].dense_fog_chance) + { + ::day_fogrange_2 = 2048; + ::day_fogrange_1 = 0; + ::day_attrib |= DAY_ATTRIB_FOG; + } + else + ::day_attrib &= ~DAY_ATTRIB_FOG; + + if ( Is_out15odm_underwater() ) + SetUnderwaterFog(); + pOutdoor->loc_time.day_fogrange_1 = ::day_fogrange_1; + pOutdoor->loc_time.day_fogrange_2 = ::day_fogrange_2; + pOutdoor->loc_time.day_attrib = ::day_attrib; +} + +//----- (00482170) -------------------------------------------------------- +bool ODMFace::IsBackfaceNotCulled(RenderVertexSoft *a2, struct Polygon *polygon) +{ + unsigned int numOfVertices; // edx@1 + RenderVertexSoft *currVertex; // ecx@2 + double v7; // st7@5 + double v8; // st6@5 + double v9; // st5@5 + float v18; // [sp+8h] [bp-38h]@5 + float v19; // [sp+10h] [bp-30h]@5 + float v20; // [sp+14h] [bp-2Ch]@5 + float v21; // [sp+18h] [bp-28h]@5 + float v22; // [sp+1Ch] [bp-24h]@5 + float v23; // [sp+24h] [bp-1Ch]@5 + float v24; // [sp+28h] [bp-18h]@5 + float v25; // [sp+30h] [bp-10h]@5 + float v26; // [sp+34h] [bp-Ch]@5 + float v27; // [sp+38h] [bp-8h]@5 + float v28; // [sp+3Ch] [bp-4h]@5 + float a3a; // [sp+48h] [bp+8h]@5 + float a3b; // [sp+48h] [bp+8h]@17 + float a3c; // [sp+48h] [bp+8h]@17 + float a3d; // [sp+48h] [bp+8h]@17 + float a3e; // [sp+48h] [bp+8h]@17 + + numOfVertices = polygon->uNumVertices; + if ( numOfVertices < 3 ) + return false; + currVertex = &a2[numOfVertices - 1]; + if ( a2->vWorldPosition.z == a2[1].vWorldPosition.z && a2[1].vWorldPosition.z == currVertex->vWorldPosition.z ) + polygon->flags |= 0x10u; + + v28 = a2[1].vWorldPosition.x - a2->vWorldPosition.x; + v27 = a2[1].vWorldPosition.y - a2->vWorldPosition.y; + a3a = a2[1].vWorldPosition.z - a2->vWorldPosition.z; + + + for (int i = 0; i < numOfVertices; i++) + { + v7 = currVertex->vWorldPosition.x - a2->vWorldPosition.x; + v8 = currVertex->vWorldPosition.y - a2->vWorldPosition.y; + v9 = currVertex->vWorldPosition.z - a2->vWorldPosition.z; + v26 = v27 * v9 - v8 * a3a; + v24 = v7 * a3a - v9 * v28; + v25 = v8 * v28 - v7 * v27; + if ( v24 != 0.0 || v25 != 0.0 || v26 != 0.0 ) + break; + currVertex--; + } + + if ( ((double)pGame->pIndoorCameraD3D->vPartyPos.x - a2->vWorldPosition.x) * v26 + + ((double)pGame->pIndoorCameraD3D->vPartyPos.z - a2->vWorldPosition.z) * v25 + + ((double)pGame->pIndoorCameraD3D->vPartyPos.y - a2->vWorldPosition.y) * v24 > 0.0 ) + { + + v19 = a2[1].vWorldViewPosition.x - a2->vWorldViewPosition.x; + v18 = a2[1].vWorldViewPosition.y - a2->vWorldViewPosition.y; + v20 = a2[1].vWorldViewPosition.z - a2->vWorldViewPosition.z; + v21 = currVertex->vWorldViewPosition.x - a2->vWorldViewPosition.x; + v22 = currVertex->vWorldViewPosition.y - a2->vWorldViewPosition.y; + v23 = currVertex->vWorldViewPosition.z - a2->vWorldViewPosition.z; + + a3b = v23 * v18 - v22 * v20; + polygon->v_18.x = bankersRounding(a3b); + a3c = v21 * v20 - v23 * v19; + polygon->v_18.y = bankersRounding(a3c); + a3d = v22 * v19 - v21 * v18; + polygon->v_18.z = bankersRounding(a3d); + polygon->_normalize_v_18(); + a3e = -((double)polygon->v_18.x * a2->vWorldViewPosition.x) + - (double)polygon->v_18.y * a2->vWorldViewPosition.y + - (double)polygon->v_18.z * a2->vWorldViewPosition.z; + polygon->field_24 = bankersRounding(a3e); + return true; + } + else + return false; +} + +//----- (0047C7A9) -------------------------------------------------------- +void OutdoorLocationTerrain::_47C7A9() +{ + this->field_10 = 0; + this->field_12 = 0; + this->field_16 = 0; + this->field_14 = 0; + this->field_1C = 0; + this->field_18 = 0; +} + +//----- (0047C7C2) -------------------------------------------------------- +void OutdoorLocationTerrain::Release()//очистить локацию +{ + free(this->pHeightmap); + pHeightmap = nullptr; + free(pTilemap); + pTilemap = nullptr; + free(pAttributemap); + pAttributemap = nullptr; + free(pDmap); + pDmap = nullptr; + + _47C7A9(); +} + +//----- (0047C80A) -------------------------------------------------------- +void OutdoorLocationTerrain::FillDMap( int X, int Y, int W, int Z ) +{ + double v6; // st7@1 + double v7; // st7@2 + double v8; // st7@2 + int result; // eax@3 + int v10; // eax@4 + int v11; // ecx@5 + int v12; // ecx@6 + int v13; // edi@7 + int v14; // edx@9 +// int v15; // eax@15 + unsigned __int8 *pMapHeight; // ebx@15 + int v17; // eax@15 + int v18; // ecx@15 + int v19; // esi@15 + int v20; // edi@15 + int v21; // edx@15 + int v22; // ecx@15 + int v23; // ebx@15 + int v24; // ecx@15 + int v25; // ST28_4@15 + double v26; // st7@15 + double v27; // st6@15 + double v28; // st5@15 + double v29; // st7@15 + double v30; // st7@16 + double v31; // st7@17 + int v32; // eax@21 + double v33; // st7@21 + double v34; // st6@21 + double v35; // st5@21 + double v36; // st7@21 + double v37; // st7@22 + double v38; // st7@23 + int v39; // [sp+14h] [bp-34h]@8 + int v40; // [sp+18h] [bp-30h]@15 + int v41; // [sp+1Ch] [bp-2Ch]@15 + int v42; // [sp+20h] [bp-28h]@15 + int v44; // [sp+28h] [bp-20h]@21 + float v45; // [sp+2Ch] [bp-1Ch]@1 + float v46; // [sp+30h] [bp-18h]@1 + float v47; // [sp+34h] [bp-14h]@1 + //int v48; // [sp+38h] [bp-10h]@7 + int v49; // [sp+3Ch] [bp-Ch]@10 + int v50; // [sp+40h] [bp-8h]@9 + float v51; // [sp+44h] [bp-4h]@15 + float v52; // [sp+44h] [bp-4h]@21 + float v53; // [sp+50h] [bp+8h]@15 + float v54; // [sp+50h] [bp+8h]@21 +// int v55; // [sp+54h] [bp+Ch]@15 + float v56; // [sp+54h] [bp+Ch]@15 + float v57; // [sp+54h] [bp+Ch]@21 + + v46 = -64.0; + v47 = -64.0; + v45 = 64.0; + v6 = sqrt(12288.0); + if ( v6 != 0.0 ) + { + v7 = 1.0 / v6; + v45 = 64.0 * v7; + v8 = v7 * -64.0; + v46 = v8; + v47 = v8; + } + result = Y; + if ( Y > Z ) + { + v10 = Z ^ Y; + Z ^= Y ^ Z; + result = Z ^ v10; + } + v11 = X; + if ( X > W ) + { + v12 = W ^ X; + W ^= X ^ W; + v11 = W ^ v12; + } + //v48 = result - 1; + if ( result - 1 <= Z ) + { + v39 = v11 - 1; + for ( v13 = result - 1; v13 <= Z; v13++ ) + { + v50 = v39; + if ( v39 <= W ) + { + result = (v39 - 63) << 9; + v49 = (v39 - 63) << 9; + for ( v14 = v39; v14 <= W; v14++ ) + { + if ( v13 >= 0 && result >= -32256 && v13 <= 127 && result <= 32768 ) + { + //v15 = pOutLocTerrain->field_10; + //v55 = pOutLocTerrain->field_10; + pMapHeight = this->pHeightmap; + v17 = (int)(&pMapHeight[v13 * this->field_10] + v14); + v18 = -v13; + v19 = (64 - v13) << 9; + v20 = 32 * *(char *)v17; + v21 = 32 * *(char *)(v17 + 1); + + v22 = (v18 + 63) << 9; + v41 = v22; + v23 = (int)(&pMapHeight[this->field_10 * (v13 + 1)] + v14); + v24 = v22 - v19; + v40 = 32 * *(char *)v23; + v42 = 32 * *(char *)(v23 + 1); + + v25 = v49 - 512 - v49; + v26 = (double)-((v20 - v21) * v24); + v51 = v26; + v27 = (double)-(v25 * (v42 - v21)); + v53 = v27; + v28 = (double)(v25 * v24); + v56 = v28; + v29 = sqrt(v28 * v28 + v27 * v27 + v26 * v26); + if ( v29 != 0.0 ) + { + v30 = 1.0 / v29; + v51 = v51 * v30; + v53 = v53 * v30; + v56 = v30 * v56; + } + v31 = (v56 * v47 + v53 * v46 + v51 * v45) * 31.0; + if ( v31 < 0.0 ) + v31 = 0.0; + if ( v31 > 31.0 ) + v31 = 31.0; + v44 = 2 * (v14 + v13 * this->field_10); + //pOutLocTerrain = pOutLocTerrain2; + *((char *)this->pDmap + v44 + 1) = (signed __int64)v31; + + v32 = v49 - (v49 - 512); + v33 = (double)-((v42 - v40) * (v19 - v41)); + v52 = v33; + v34 = (double)-(v32 * (v20 - v40)); + v54 = v34; + v35 = (double)(v32 * (v19 - v41)); + v57 = v35; + v36 = sqrt(v35 * v35 + v34 * v34 + v33 * v33); + if ( v36 != 0.0 ) + { + v37 = 1.0 / v36; + v52 = v52 * v37; + v54 = v54 * v37; + v57 = v37 * v57; + } + v38 = (v57 * v47 + v54 * v46 + v52 * v45) * 31.0; + if ( v38 < 0.0 ) + v38 = 0.0; + if ( v38 > 31.0 ) + v38 = 31.0; + //v13 = v48; + *((char *)this->pDmap + v44) = (signed __int64)v38; + //v14 = v50; + result = v49; + } + //++v14; + result += 512; + //v50 = v14; + v49 = result; + } + } + //++v13; + //v48 = v13; + } + //while ( v13 <= Z ); + } +} + +//----- (0047CB57) -------------------------------------------------------- +int OutdoorLocationTerrain::_47CB57(int a1, int a2, int a3) +{ + signed int result; // eax@2 +// unsigned __int16 *v5; // edx@3 +// double v6; // st7@3 +// int v8; // eax@3 +// int v9; // eax@4 +// int v10; // eax@5 +// double v11; // st6@7 +// signed int v12; // edi@7 +// int v13; // esi@9 +// char *v14; // esi@10 +// signed int v15; // ecx@10 +// char v16[256]; // [sp+4h] [bp-124h]@9 +// unsigned __int16 *v17; // [sp+104h] [bp-24h]@3 +// float v22; // [sp+118h] [bp-10h]@3 +// float v23; // [sp+11Ch] [bp-Ch]@3 +// int i; // [sp+120h] [bp-8h]@3 +// unsigned int v25; // [sp+124h] [bp-4h]@5 +// signed int a2a; // [sp+134h] [bp+Ch]@3 +// unsigned int a2b; // [sp+134h] [bp+Ch]@7 +// float a3a; // [sp+138h] [bp+10h]@7 +// int a3b; // [sp+138h] [bp+10h]@9 + + int num_r_bits = 5; + int num_g_bits = 6; + int num_b_bits = 5; + + int r_mask = 0xF800; + int g_mask = 0x7E0; + int b_mask = 0x1F; + + //if ( pRenderer->pRenderD3D ) + result = 0; + /*else + { + __debugbreak(); + v5 = PaletteManager::Get_Dark_or_Red_LUT(a2, 0, 1); + v6 = 0.0; + v22 = 0.0; + v8 = 0; + v17 = v5; + v23 = 0.0; + a2a = 0; + for ( i = 0; i < a3; ++i ) + { + v9 = *(char *)(v8 + a1); + if ( v9 ) + { + v10 = v5[v9]; + v6 = v6 + (double)((signed int)(r_mask & v10) >> (num_b_bits + num_g_bits)); + ++a2a; + v25 = b_mask & v10; + v22 = (double)((signed int)(g_mask & v10) >> num_b_bits) + v22; + v23 = (double)(signed int)(b_mask & v10) + v23; + } + v8 = i + 1; + } + v11 = 1.0 / (double)a2a; + a3a = v11; + v25 = (signed __int64)(a3a * v22); + i = (signed __int64)(a3a * v23); + v12 = 0; + a2b = num_b_bits + num_g_bits; + while ( 1 ) + { + v13 = v17[v12]; + a3b = abs((__int64)(signed __int64)(v11 * v6) - ((signed int)(r_mask & v17[v12]) >> a2b)); + BYTE3(a3b) = abs((signed)v25 - ((signed int)(g_mask & v13) >> num_b_bits)) + a3b; + v16[v12++] = abs((signed)i - (signed)(b_mask & v13)) + BYTE3(a3b); + if ( v12 >= 256 ) + break; + } + result = 0; + v14 = (char *)&pPaletteManager->field_D1600[42][23][116]; + v15 = 0; + do + { + if ( (unsigned __int8)v16[v15] < (signed int)v14 ) + { + v14 = (char *)(unsigned __int8)v16[v15]; + result = v15; + } + ++v15; + } + while ( v15 < 256 ); + }*/ + return result; +} + +//----- (0047CCE2) -------------------------------------------------------- +bool OutdoorLocationTerrain::ZeroLandscape() +{ + memset(this->pHeightmap, 0, 0x4000u); + memset(this->pTilemap, 90, 0x4000u); + memset(this->pAttributemap, 0, 0x4000u); + memset(this->pDmap, 0, 0x8000u); + this->field_12 = 128; + this->field_10 = 128; + this->field_16 = 7; + this->field_14 = 7; + this->field_1C = 127; + this->field_18 = 127; + return true; +} + +//----- (0047CD44) -------------------------------------------------------- +bool OutdoorLocationTerrain::Initialize() +{ + pHeightmap = (unsigned __int8 *)malloc(0x4000u);//height map + pTilemap = (unsigned __int8 *)malloc(0x4000u);//tile map + pAttributemap = (unsigned __int8 *)malloc(0x4000u);//карта атрибутов + pDmap = (struct DMap *)malloc(0x8000u); + if (pHeightmap && pTilemap && pAttributemap && pDmap ) + return true; + else + return false; +} + +//----- (0047CDE2) -------------------------------------------------------- +void OutdoorLocation::CreateDebugLocation() +{ + //OutdoorLocation *v1; // esi@1 + void *v2; // eax@1 + void *v3; // ST14_4@1 + void *v4; // eax@1 + void *v5; // ST14_4@1 + void *v6; // eax@1 + //unsigned int v7; // eax@1 + //char v8; // zf@1 + + //v1 = this; + strcpy(this->pLevelFilename, "blank"); + strcpy(this->pLocationFileName, "i6.odm"); + strcpy(this->pLocationFileDescription, "MM6 Outdoor v1.00"); + this->uNumBModels = 0; + this->pTileTypes[0].tileset = Tileset_Grass; + this->pTileTypes[1].tileset = Tileset_Water; + this->pTileTypes[2].tileset = Tileset_6; + this->pTileTypes[3].tileset = Tileset_RoadGrassCobble; + this->LoadTileGroupIds(); + this->LoadRoadTileset(); + free(this->pBModels); + free(this->pSpawnPoints); + this->pBModels = 0; + this->pSpawnPoints = 0; + this->pTerrain.Initialize(); + this->pTerrain.ZeroLandscape(); + this->pTerrain.FillDMap(0, 0, 128, 128); + free(this->pCmap); + this->pCmap = 0; + v2 = malloc(0x8000u); + v3 = this->pOMAP; + this->pCmap = v2; + free(v3); + this->pOMAP = 0; + v4 = malloc(0x10000u); + this->pOMAP = (unsigned int *)v4; + memset(v4, 0, 0x10000u); + v5 = this->pFaceIDLIST; + this->numFaceIDListElems = 0; + free(v5); + this->pFaceIDLIST = 0; + v6 = malloc(2); + this->pFaceIDLIST = (unsigned __int16 *)v6; + *(short *)v6 = 0; + strcpy(this->pSkyTextureName, pDefaultSkyTexture.data()); + this->sSky_TextureID = pBitmaps_LOD->LoadTexture(this->pSkyTextureName); + strcpy(this->pGroundTileset, byte_6BE124_cfg_textures_DefaultGroundTexture.data()); + //v7 = pBitmaps_LOD->LoadTexture(this->pGroundTileset); + this->sMainTile_BitmapID = pBitmaps_LOD->LoadTexture(this->pGroundTileset); + + if ( this->sSky_TextureID == -1 ) + Error("Invalid Sky Tex Handle"); + + if ( this->sMainTile_BitmapID == -1 ) + Error("Invalid Ground Tex Handle"); +} + +//----- (0047CF9C) -------------------------------------------------------- +void OutdoorLocation::Release() +{ + strcpy(pLevelFilename, "blank"); + strcpy(pLocationFileName, "default.odm"); + strcpy(pLocationFileDescription, "MM6 Outdoor v1.00"); + strcpy(pSkyTextureName, "sky043"); + strcpy(pGroundTileset, "hm005"); + + if (pBModels) + { + for (uint i = 0; i < uNumBModels; ++i) + pBModels[i].Release(); + + free(pBModels); + pBModels = nullptr; + uNumBModels = 0; + } + + free(pSpawnPoints); + pSpawnPoints = nullptr; + uNumSpawnPoints = 0; + + pTerrain.Release(); + + free(pCmap); + pCmap = nullptr; + free(pOMAP); + pOMAP = nullptr; + free(pFaceIDLIST); + pFaceIDLIST = nullptr; + free(pTerrainNormals); + pTerrainNormals = nullptr; +} + +//----- (0047D0A6) -------------------------------------------------------- +bool OutdoorLocation::Load(const char *pFilename, ODMFace *File, size_t pNumItems, int *thisa)//загрузка локации +{ + //OutdoorLocation *pOutdoorLocation; // esi@1 + /*bool result; // eax@9 + bool v7; // ebx@9 + size_t v8; // eax@10 + void *v9; // eax@10 + void *v10; // eax@10 + void *v11; // eax@10 + int v12; // ebx@11 + BSPModel *v13; // eax@12 + void *v14; // eax@12 + BSPModel *v15; // ecx@12 + void *v16; // eax@12 + BSPModel *v17; // ecx@12 + BSPModel *v18; // eax@12 + __int16 v19; // ax@15 + __int16 v20; // ax@16 + int v21; // ecx@16 + ODMFace *v22; // ebx@26 + SpriteObject *pItems; // ecx@27 + unsigned int v24; // eax@28 + //unsigned __int8 v25; // zf@28 + //unsigned __int8 v26; // sf@28 + ODMFace *v27; // eax@28 + const char *i; // edx@29 + unsigned __int16 v29; // ax@33 + unsigned __int16 v30; // ax@37 + int v31; // ecx@37 + int v32; // eax@38 + void *v33; // eax@38 + TileDesc *v34; // eax@43 + unsigned int v35; // eax@43 + unsigned int v36; // edi@43 + unsigned int v37; // edi@45*/ + //size_t v38; // eax@50 + FILE *v39; // eax@50 + //unsigned int v40; // edi@56 + //void *v41; // eax@56 + //void *v42; // ebx@56 + //const void *v43; // ebx@59 + //const void *v44; // ebx@59 + //unsigned int v45; // eax@59 + //BSPModel *v46; // eax@59 + //unsigned int v47; // ecx@59 + //int v48; // ebx@60 + //BSPModel *v49; // eax@61 + //BSPModel *v50; // eax@61 + //BSPModel *v51; // eax@61 + //BSPModel *v52; // eax@61 + //BSPModel *v53; // eax@61 + //BSPModel *v54; // ecx@61 + //BSPModel *v55; // ecx@61 + //BSPModel *v56; // ecx@61 + //void *v57; // ST24_4@61 + //BSPModel *v58; // ecx@61 + //void *v59; // ST18_4@61 + //BSPModel *v60; // eax@61 + //__int16 v61; // ax@64 + unsigned __int16 v62; // ax@65 + //ODMFace *v63; // ecx@65 + //unsigned __int16 v64; // ax@80 + //const char *v65; // ecx@80 + //int v66; // eax@81 + //void *v67; // eax@81 + //int v68; // ecx@81 + //void *v69; // eax@81 + //unsigned int v70; // eax@81 + //SpawnPointMM7 *v71; // eax@81 + //unsigned int v72; // ecx@81 + //size_t v73; // eax@81 + //int v74; // edi@87 + //void *v75; // edi@88 + //unsigned int v76; // edx@94 + //int v77; // ecx@94 + //char *v78; // eax@95 + //unsigned int v79; // edx@97 + //unsigned int v80; // eax@99 + //int v81; // eax@107 + //void *v82; // edi@114 + //size_t v83; // eax@120 + //const void *v84; // edi@120 + //const void *v85; // edi@120 + //BSPModel *v86; // eax@124 + //unsigned int v87; // eax@124 + //BSPModel *v88; // eax@126 + //BSPModel *v89; // eax@127 + //ODMFace *v90; // eax@129 + //const void *v91; // edi@138 + //const void *v92; // edi@141 + //const void *v93; // edi@141 + //const void *v94; // edi@144 + //const void *v95; // edi@144 + //const char *v96; // edi@147 + //unsigned int v97; // eax@147 + //TileDesc *v98; // eax@147 + //unsigned int v99; // eax@147 + //int v100; // ecx@150 + //unsigned int v101; // eax@157 +// int v102; // edi@159 + //void *v103; // [sp-14h] [bp-B94h]@55 + //void *v104; // [sp-10h] [bp-B90h]@59 + //size_t v105; // [sp-Ch] [bp-B8Ch]@59 + //char *v106; // [sp-8h] [bp-B88h]@59 +// int v107; // [sp-4h] [bp-B84h]@12 + int v108; // [sp+0h] [bp-B80h]@10 + char Src[968]; // [sp+10h] [bp-B70h]@110 + char Dst[968]; // [sp+3D8h] [bp-7A8h]@50 + char Str[256]; // [sp+7A0h] [bp-3E0h]@50 + /*char DstBuf; // [sp+8A0h] [bp-2E0h]@10 + __int32 Offset; // [sp+8A4h] [bp-2DCh]@10 + __int32 v114; // [sp+8B0h] [bp-2D0h]@10 + __int32 v115; // [sp+8BCh] [bp-2C4h]@10 + __int32 v116; // [sp+8C8h] [bp-2B8h]@10 + __int32 v117; // [sp+8D4h] [bp-2ACh]@10 + __int32 v118; // [sp+8E0h] [bp-2A0h]@10 + __int32 v119; // [sp+8ECh] [bp-294h]@10 + __int32 v120; // [sp+8F8h] [bp-288h]@10 + __int32 v121; // [sp+904h] [bp-27Ch]@10 + __int32 v122; // [sp+910h] [bp-270h]@10 + __int32 v123; // [sp+91Ch] [bp-264h]@10 + __int32 v124; // [sp+928h] [bp-258h]@26 + __int32 v125; // [sp+934h] [bp-24Ch]@35 + __int32 v126; // [sp+940h] [bp-240h]@38 + __int32 v127; // [sp+94Ch] [bp-234h]@38 + __int32 v128; // [sp+958h] [bp-228h]@38 + __int32 v129; // [sp+964h] [bp-21Ch]@38 + __int32 v130; // [sp+970h] [bp-210h]@38 + __int32 v131; // [sp+97Ch] [bp-204h]@38 + __int32 v132; // [sp+988h] [bp-1F8h]@38 + __int32 v133; // [sp+994h] [bp-1ECh]@38 + __int32 v134; // [sp+9A0h] [bp-1E0h]@38 + __int32 v135; // [sp+9ACh] [bp-1D4h]@38 + __int32 v136; // [sp+9D0h] [bp-1B0h]@10*/ + //char FileName[8]; // [sp+A20h] [bp-160h]@8 + //char v138; // [sp+A28h] [bp-158h]@12 + //int v139; // [sp+B1Ch] [bp-64h]@10 + //char pContainer[32]; // [sp+B20h] [bp-60h]@1 + //int *v141; // [sp+B40h] [bp-40h]@50 + //__int64 v142; // [sp+B44h] [bp-3Ch]@55 + //size_t pSource; // [sp+B4Ch] [bp-34h]@56 + //int v144; // [sp+B50h] [bp-30h]@61 + //int v145; // [sp+B54h] [bp-2Ch]@68 + ODMHeader header; // [sp+B58h] [bp-28h]@50 + //unsigned int pDestLen; // [sp+B68h] [bp-18h]@13 + //FILE *ptr; // [sp+B6Ch] [bp-14h]@12 + //void *v149; // [sp+B70h] [bp-10h]@19 + char *Str2; // [sp+B74h] [bp-Ch]@12 + //int v151; // [sp+B78h] [bp-8h]@59 + //void *uSourceLen; // [sp+B7Ch] [bp-4h]@59 + + //pOutdoorLocation = this; + //strcpy(pContainer, pFilename); + + if (bUnderwater) + { + pPaletteManager->pPalette_tintColor[0] = 0x10; + pPaletteManager->pPalette_tintColor[1] = 0xC2; + pPaletteManager->pPalette_tintColor[2] = 0x99; + pPaletteManager->SetMistColor(37, 143, 92); + } + else + { + pPaletteManager->pPalette_tintColor[0] = 0; + pPaletteManager->pPalette_tintColor[1] = 0; + pPaletteManager->pPalette_tintColor[2] = 0; + if (pPaletteManager->pPalette_mistColor[0] != 0x80 || + pPaletteManager->pPalette_mistColor[1] != 0x80 || + pPaletteManager->pPalette_mistColor[2] != 0x80) + { + pPaletteManager->SetMistColor(128, 128, 128); + pPaletteManager->RecalculateAll(); + } + } + + _6807E0_num_decorations_with_sounds_6807B8 = 0; + /*sprintf(FileName, "levels\\%s", pContainer); + if ( GetFileAttributesA(FileName) != -1 ) + { + result = (bool)fopen(FileName, "rb"); + v7 = result; + File = (ODMFace *)result; + if ( !result ) + return result; + *(int *)thisa = 1; + v8 = strlen(pContainer); + v108 = 2; + *((char *)&v139 + v8) = 0; + viewparams->uTextureID_LocationMap = pIcons_LOD->LoadTexture(pContainer, (enum TEXTURE_TYPE)v108); + fread(&DstBuf, 0x180u, 1u, (FILE *)v7); + fseek((FILE *)v7, Offset, 0); + fread(this, 0xB0u, 1u, (FILE *)v7); + LoadTileGroupIds(); + LoadRoadTileset(); + strcpy(pGroundTileset, "grastyl"); + fseek((FILE *)v7, v114, 0); + fread(&uNumBModels, 4u, 1u, (FILE *)v7); + fseek((FILE *)v7, v115, 0); + fread(&uNumSpriteObjects, 4u, 1u, (FILE *)v7); + fseek((FILE *)v7, v116, 0); + fread(&uNumLevelDecorations, 4u, 1u, (FILE *)v7); + fseek((FILE *)v7, v117, 0); + fread(&uNumActors, 4u, 1u, (FILE *)v7); + fseek((FILE *)v7, v118, 0); + fread(&uNumChests, 4u, 1u, (FILE *)v7); + pTerrain.Initialize(); + fseek((FILE *)v7, v119, 0); + fread(pTerrain.pHeightmap, 1u, 0x4000u, (FILE *)v7); + fseek((FILE *)v7, v120, 0); + fread(pTerrain.pTilemap, 1u, 0x4000u, (FILE *)v7); + fseek((FILE *)v7, v121, 0); + fread(pTerrain.pAttributemap, 1u, 0x4000u, (FILE *)v7); + pTerrain._47C80A(0, 0, 128, 128); + free(ptr_D4); + ptr_D4 = 0; + v9 = malloc(0, 0x8000u, "CMAP"); + v108 = (int)pOMAP; + ptr_D4 = v9; + free((void *)v108); + pOMAP = 0; + v10 = malloc(0, 0x10000u, "OMAP"); + v108 = 0; + pOMAP = (unsigned int *)v10; + fseek((FILE *)v7, v136, v108); + fread(&uNumTerrainNormals, 4u, 1u, (FILE *)v7); + fread(pTerrainSomeOtherData, 1u, 0x20000u, (FILE *)v7); + fread(pTerrainNormalIndices, 1u, 0x10000u, (FILE *)v7); + pTerrainNormals = (Vec3_float_ *)malloc(pTerrainNormals, 12 * uNumTerrainNormals, "TerNorm"); + fread(pTerrainNormals, 1u, 12 * uNumTerrainNormals, (FILE *)v7); + v11 = malloc(pBModels, 188 * uNumBModels, "BDdata"); + v108 = 0; + pBModels = (BSPModel *)v11; + fseek((FILE *)v7, v122, v108); + fread(pBModels, 0xBCu, uNumBModels, (FILE *)v7); + fseek((FILE *)v7, v123, 0); + pNumItems = 0; + if ( (signed int)uNumBModels > 0 ) + { + v12 = 0; + while ( 1 ) + { + pBModels[v12].pVertices.pVertices = 0; + pBModels[v12].pFaces = 0; + pBModels[v12].pFacesOrdering = 0; + pBModels[v12].pNodes = 0; + FileName[0] = 0; + v108 = (int)&pBModels[v12]; + sprintfex(FileName, "%s", v108); + v13 = pBModels; + v138 = 0; + pBModels[v12].pVertices.pVertices = (Vec3_int_ *)malloc(v13[v12].pVertices.pVertices, 12 * v13[v12].pVertices.uNumVertices, + FileName); + pBModels[v12].pFaces = (ODMFace *)malloc(pBModels[v12].pFaces, 308 * pBModels[v12].uNumFaces, + FileName); + pBModels[v12].pFacesOrdering = (unsigned __int16 *)malloc(pBModels[v12].pFacesOrdering, + 2 * pBModels[v12].uNumFaces, FileName); + v14 = malloc(pBModels[v12].pNodes, 8 * pBModels[v12].uNumNodes, FileName); + v15 = pBModels; + v108 = (int)File; + v15[v12].pNodes = (BSPNode *)v14; + fread(pBModels[v12].pVertices.pVertices, 0xCu, pBModels[v12].pVertices.uNumVertices, (FILE *)v108); + fread(pBModels[v12].pFaces, 0x134u, pBModels[v12].uNumFaces, (FILE *)File); + fread(pBModels[v12].pFacesOrdering, 2u, pBModels[v12].uNumFaces, (FILE *)File); + fread(pBModels[v12].pNodes, 8u, pBModels[v12].uNumNodes, (FILE *)File); + v16 = malloc(10 * pBModels[v12].uNumFaces); + v107 = (int)File; + v17 = pBModels; + ptr = (FILE *)v16; + fread(v16, 0xAu, v17[v12].uNumFaces, (FILE *)File); + v18 = pBModels; + Str2 = 0; + if ( (signed int)v18[v12].uNumFaces > 0 ) + break; +LABEL_25: + free(ptr); + ++pNumItems; + ++v12; + if ( (signed int)pNumItems >= (signed int)uNumBModels ) + goto LABEL_26; + } + pDestLen = 0; + pFilename = (char *)ptr; + while ( 1 ) + { + thisa = (int)((char *)v18[v12].pFaces + pDestLen); + if ( !(*(char *)(thisa + 29) & 0x40) ) + break; + v19 = pTextureFrameTable->FindTextureByName(pFilename); + *(short *)(thisa + 272) = v19; + if ( !v19 ) + { + v20 = pBitmaps_LOD->LoadTexture(pFilename); + v21 = thisa; + *(char *)(v21 + 29) &= 0xBFu; +LABEL_19: + *(short *)(v21 + 272) = v20; + v149 = (void *)(v20 != -1 ? &pBitmaps_LOD->pTextures[v20] : 0); + auto pTex = (Texture *)v149; + if (pTex) + pTex->palette_id2 = pPaletteManager->LoadPalette(pTex->palette_id1); + goto LABEL_20; + } + pTextureFrameTable->LoadAnimationSequenceAndPalettes(*(unsigned __int16 *)((char *)&pBModels[v12].pFaces->uTextureID + pDestLen)); +LABEL_20: + if ( *(short *)(thisa + 292) ) + { + if ( ((ODMFace *)thisa)->HasEventHint() ) + *(char *)(thisa + 30) |= 0x10u; + else + *(char *)(thisa + 30) &= 0xEFu; + } + ++Str2; + v18 = pBModels; + pDestLen += 308; + pFilename += 10; + if ( (signed int)Str2 >= (signed int)v18[v12].uNumFaces ) + goto LABEL_25; + } + v20 = pBitmaps_LOD->LoadTexture(pFilename); + v21 = thisa; + goto LABEL_19; + } +LABEL_26: + v22 = File; + fseek((FILE *)File, v124, 0); + fread(pSpriteObjects, 0x70u, uNumSpriteObjects, (FILE *)v22); + if ( (signed int)uNumSpriteObjects > 0 ) + { + pItems = pSpriteObjects; + pNumItems = uNumSpriteObjects; + do + { + v24 = pItems->stru_24.uItemID; + thisa = 0; + v27 = (ODMFace *)(48 * v24); + v25 = pObjectList->uNumObjects == 0; + v26 = (pObjectList->uNumObjects & 0x80000000u) != 0; + LOWORD(v27) = *(short *)((char *)&v27->pFacePlane.vNormal.x + (int)((char *)&pItemsTable + 24)); + File = v27; + pItems->uItemType = (unsigned __int16)v27; + if ( v26 | v25 ) + { +LABEL_33: + v29 = 0; + } + else + { + for ( i = (const char *)&pObjectList->pObjects->uObjectID; (short)v27 != *(short *)i; i = pFilename ) + { + ++thisa; + pFilename = (char *)i + 56; + if ( thisa >= (signed int)pObjectList->uNumObjects ) + goto LABEL_33; + LOWORD(v27) = (short)File; + } + v29 = thisa; + } + pItems->uObjectDescID = v29; + ++pItems; + --pNumItems; + } + while ( pNumItems ); + } + fseek((FILE *)v22, v125, 0); + fread(pLevelDecorations, 0x20u, uNumLevelDecorations, (FILE *)v22); + pNumItems = 0; + if ( (signed int)uNumLevelDecorations > 0 ) + { + thisa = (int)pLevelDecorations; + do + { + fread(FileName, 1u, 0x20u, (FILE *)v22); + v30 = pDecorationList->GetDecorIdByName(FileName); + v31 = thisa; + ++pNumItems; + thisa += 32; + *(short *)v31 = v30; + } + while ( (signed int)pNumItems < (signed int)uNumLevelDecorations ); + } + fseek((FILE *)v22, v126, 0); + fread(pActors, 0x344u, uNumActors, (FILE *)v22); + fseek((FILE *)v22, v127, 0); + fread(pChests, 0x14CCu, uNumChests, (FILE *)v22); + fseek((FILE *)v22, v128, 0); + fread(&field_DC, 4u, 1u, (FILE *)v22); + free(pFaceIDLIST); + v32 = field_DC; + pFaceIDLIST = 0; + v33 = malloc(0, 2 * v32, "IDLIST"); + v108 = (int)v22; + pFaceIDLIST = (unsigned __int16 *)v33; + fread(v33, 2u, field_DC, (FILE *)v108); + fseek((FILE *)v22, v129, 0); + fread(pOMAP, 4u, 0x4000u, (FILE *)v22); + fseek((FILE *)v22, v130, 0); + fread(&uNumSpawnPoints, 4u, 1u, (FILE *)v22); + pSpawnPoints = (SpawnPointMM7 *)malloc(pSpawnPoints, 24 * uNumSpawnPoints, "Spawn"); + fseek((FILE *)v22, v131, 0); + fread(pSpawnPoints, 0x18u, uNumSpawnPoints, (FILE *)v22); + fseek((FILE *)v22, v132, 0); + fread(&ddm, 0x28u, 1u, (FILE *)v22); + fseek((FILE *)v22, v133, 0); + fread(&stru_5E4C90, 1u, 0xC8u, (FILE *)v22); + fseek((FILE *)v22, v134, 0); + fread(&uLastVisitDay, 1u, 0x38u, (FILE *)v22); + fseek((FILE *)v22, v135, 0); + fread(&uLastVisitDay, 1u, 4u, (FILE *)v22); + thisa = (int)pTileTypes; + pTileTable->InitializeTileset(4); + pTileTable->InitializeTileset(pTileTypes[0].uTileGroup); + pTileTable->InitializeTileset(pTileTypes[1].uTileGroup); + pTileTable->InitializeTileset(pTileTypes[2].uTileGroup); + pTileTable->InitializeTileset(pTileTypes[3].uTileGroup); + if ( this != (OutdoorLocation *)-96 && pSkyTextureName[0] ) + { + v108 = 0; + v107 = (int)pSkyTextureName; + } + else + { + v108 = 0; + v107 = (int)pDefaultSkyTexture; + } + sSky_TextureID = pBitmaps_LOD->LoadTexture((const char *)v107, (enum TEXTURE_TYPE)v108); + strcpy(pGroundTileset, byte_6BE124_cfg_textures_DefaultGroundTexture); + v34 = pTileTable->GetTileById(pTileTypes[0].uTileID); + v35 = pBitmaps_LOD->LoadTexture(v34->pTileName); + v36 = sSky_TextureID; + sMainTile_BitmapID = v35; + if ( v36 != -1 ) + pBitmaps_LOD->pTextures[v36].palette_id2 = pPaletteManager->LoadPalette(pBitmaps_LOD->pTextures[v36].palette_id1); + + v37 = sMainTile_BitmapID; + if ( v37 != -1 ) + pBitmaps_LOD->pTextures[v37].palette_id2 = pPaletteManager->LoadPalette(pBitmaps_LOD->pTextures[v37].palette_id1); + + _47F0E2(); + pGameLoadingUI_ProgressBar->Progress(); + fclose((FILE *)v22); + goto LABEL_150; + }*/ + + assert(sizeof(BSPModel) == 188); + + if (!pGames_LOD->DoesContainerExist(pFilename)) + Error("Unable to find %s in Games.LOD", pFilename); + + + char pMinimapTextureFilename[1024]; + strcpy(pMinimapTextureFilename, pFilename); + pMinimapTextureFilename[strlen(pMinimapTextureFilename) - 4] = 0; + viewparams->uTextureID_LocationMap = pIcons_LOD->LoadTexture(pMinimapTextureFilename, TEXTURE_16BIT_PALETTE); + + //strcpy(FileName, pContainer); + strcpy(Str, pFilename); + strcpy(Str + strlen(Str) - 4, ".odm"); + //v141 = &v139; + //v38 = strlen(pFilename); + //strcpy((char *)&v139 + v38, ".odm"); + v39 = pGames_LOD->FindContainer(Str, 1); + //Str[strlen(Str) - 4] = 0; + + header.uCompressedSize = 0; + header.uDecompressedSize = 0; + //ptr = v39; + header.uVersion = 91969; + header.pMagic[0] = 'm'; + header.pMagic[1] = 'v'; + header.pMagic[2] = 'i'; + header.pMagic[3] = 'i'; + fread(&header, 0x10u, 1u, v39); + if (header.uVersion != 91969 || + header.pMagic[0] != 'm' || + header.pMagic[1] != 'v' || + header.pMagic[2] != 'i' || + header.pMagic[3] != 'i') + { + MessageBoxW(nullptr, L"Can't load file!", + L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Odmap.cpp:507", 0); + } + //v40 = header.uCompressedSize; + //pSource = header.uDecompressedSize; + //v41 = malloc(header.uDecompressedSize); + uchar* pSrcMem = (unsigned char *)malloc(header.uDecompressedSize); + uchar* pSrc = pSrcMem; + //v42 = v41; + //HIDWORD(v142) = (uint32)pSrc; + if (header.uCompressedSize < header.uDecompressedSize) + { + char* pComressedSrc = (char *)malloc(header.uCompressedSize); + fread(pComressedSrc, header.uCompressedSize, 1, v39); + + uint actualDecompressedSize = header.uDecompressedSize; + zlib::MemUnzip(pSrc, &actualDecompressedSize, pComressedSrc, header.uCompressedSize); + free(pComressedSrc); + } + else + { + fread(pSrc, header.uDecompressedSize, 1, v39); + } + + memcpy(pLevelFilename, pSrc, 0x20); + memcpy(pLocationFileName, pSrc + 0x20, 0x20); + memcpy(pLocationFileDescription, pSrc + 0x40, 0x20); + memcpy(pSkyTextureName, pSrc + 3 * 32, 32); + memcpy(pGroundTileset, pSrc + 0x80, 0x20); + memcpy(pTileTypes, pSrc + 0xA0, 0x10); + pSrc += 0xB0; + + //v43 = (char *)pSrc + 176; + LoadTileGroupIds(); + LoadRoadTileset(); + strcpy(pGroundTileset, "grastyl"); + pGameLoadingUI_ProgressBar->Progress(); + pTerrain.Initialize(); + //v108 = 16384; + //v107 = (int)v43; + //v106 = (char *)pTerrain.pHeightmap; + memcpy(pTerrain.pHeightmap, pSrc, 0x4000); + pSrc += 0x4000; + + //v43 = (char *)v43 + 16384; + //v105 = 16384; + //v104 = (void *)v43; + //v103 = pTerrain.pTilemap; + memcpy(pTerrain.pTilemap, pSrc, 0x4000); + pSrc += 0x4000; + + //v43 = (char *)v43 + 16384; + memcpy(pTerrain.pAttributemap, pSrc, 0x4000); + pSrc += 0x4000; + + //v43 = (char *)v43 + 16384; + //v108 = (int)ptr_D4; + free(pCmap); + pCmap = malloc(0x8000); + pTerrain.FillDMap(0, 0, 128, 128); + + pGameLoadingUI_ProgressBar->Progress(); + memcpy(&uNumTerrainNormals, pSrc, 4); + //v43 = (char *)v43 + 4; + memcpy(pTerrainSomeOtherData.data(), pSrc + 4, 0x20000); + pSrc += 4 + 0x20000; + //v43 = (char *)v43 + 131072; + memcpy(pTerrainNormalIndices.data(), pSrc, 0x10000); + pSrc += 0x10000; + //v43 = (char *)v43 + 65536; + + //pFilename = (char *)(12 * uNumTerrainNormals); + pTerrainNormals = (Vec3_float_ *)malloc(sizeof(Vec3_float_) * uNumTerrainNormals); + memcpy(pTerrainNormals, pSrc, 12 * uNumTerrainNormals); + pSrc += 12 * uNumTerrainNormals; + //v44 = (char *)v43 + (int)pFilename; + //v44 = (char *)v44 + 4; + //v45 = uNumBModels; + //v108 = (int)"BDdata"; + + pGameLoadingUI_ProgressBar->Progress(); + + //v107 = 188 * v45; + //v106 = (char *)pBModels; + //v46 = (BSPModel *)malloc(v106, 188 * v45, "BDdata"); + //v47 = uNumBModels; + memcpy(&uNumBModels, pSrc, 4); + pBModels = (BSPModel *)malloc(188 * uNumBModels); + //pFilename = (char *)(188 * v47); + memcpy(pBModels, pSrc + 4, 188 * uNumBModels); + pSrc += 4 + 188 * uNumBModels; + + pGameLoadingUI_ProgressBar->Progress(); + + //uSourceLen = (char *)v44 + (int)pFilename; + //v151 = 0; + for (uint i = 0; i < uNumBModels; ++i) + { + //v48 = 0; + //BSPModel* model = &pBModels[i]; + + pBModels[i].pVertices.pVertices = nullptr; + pBModels[i].pFaces = nullptr; + pBModels[i].pFacesOrdering = nullptr; + pBModels[i].pNodes = nullptr; + //FileName[0] = 0; + //v108 = (int)&pBModels[i]; + //sprintf(FileName, "%s", v108); + //v49 = pBModels; + //v138 = 0; + //v50 = &pBModels[v48]; + //v108 = (int)FileName; + //v107 = 12 * v50->pVertices.uNumVertices; + //v106 = (char *)v50->pVertices.pVertices; + assert(sizeof(Vec3_int_) == 12); + uint verticesSize = pBModels[i].pVertices.uNumVertices * sizeof(Vec3_int_); + pBModels[i].pVertices.pVertices = (Vec3_int_ *)malloc(verticesSize); + memcpy(pBModels[i].pVertices.pVertices, pSrc, verticesSize); + pSrc += verticesSize; + //v51 = &pBModels[v48]; + //v108 = (int)FileName; + //v107 = 308 * v51->uNumFaces; + //v106 = (char *)v51->pFaces; + assert(sizeof(ODMFace) == 308); + uint facesSize = pBModels[i].uNumFaces * sizeof(ODMFace); + pBModels[i].pFaces = (ODMFace *)malloc(facesSize); + memcpy(pBModels[i].pFaces, pSrc, facesSize); + pSrc += facesSize; + //v52 = &pBModels[v48]; + //v108 = (int)FileName; + //v107 = 2 * v52->uNumFaces; + //v106 = (char *)v52->pFacesOrdering; + uint facesOrderingSize = pBModels[i].uNumFaces * sizeof(short); + pBModels[i].pFacesOrdering = (unsigned __int16 *)malloc(facesOrderingSize); + memcpy(pBModels[i].pFacesOrdering, pSrc, facesOrderingSize); + pSrc += facesOrderingSize; + //v53 = &pBModels[v48]; + //v108 = (int)FileName; + //v107 = 8 * v53->uNumNodes; + //v106 = (char *)v53->pNodes; + assert(sizeof(BSPNode) == 8); + uint nodesSize = pBModels[i].uNumNodes * sizeof(BSPNode); + pBModels[i].pNodes = (BSPNode *)malloc(nodesSize); + memcpy(pBModels[i].pNodes, pSrc, nodesSize); + pSrc += nodesSize; + //v54 = &pBModels[v48]; + //v108 = 12 * v54->pVertices.uNumVertices; + //pFilename = (char *)v108; + //v107 = (int)uSourceLen; + //v106 = (char *)v54->pVertices.pVertices; + //memcpy(v106, uSourceLen, v108); + //uSourceLen = (char *)uSourceLen + (int)pFilename; + //v55 = &pBModels[v48]; + //v105 = 308 * v55->uNumFaces; + //v104 = uSourceLen; + //v103 = v55->pFaces; + //pFilename = (char *)v105; + //memcpy(v103, uSourceLen, v105); + //v56 = &pBModels[v48]; + //uSourceLen = (char *)uSourceLen + (int)pFilename; + //v57 = v56->pFacesOrdering; + //pFilename = (char *)(2 * v56->uNumFaces); + //memcpy(v57, uSourceLen, (size_t)pFilename); + //v58 = &pBModels[v48]; + //uSourceLen = (char *)uSourceLen + (int)pFilename; + //v59 = v58->pNodes; + //pFilename = (char *)(8 * v58->uNumNodes); + //memcpy(v59, uSourceLen, (size_t)pFilename); + //uSourceLen = (char *)uSourceLen + (int)pFilename; + //ptr = (FILE *)malloc(10 * model->uNumFaces); + const char* textureFilenames = (const char *)malloc(10 * pBModels[i].uNumFaces); + //pFilename = (char *)(10 * pBModels[v48].uNumFaces); + memcpy((char *)textureFilenames, pSrc, 10 * pBModels[i].uNumFaces); + pSrc += 10 * pBModels[i].uNumFaces; + //v144 = 0; + //uSourceLen = (char *)uSourceLen + (int)pFilename; + //v60 = pBModels; + for (uint j = 0; j < pBModels[i].uNumFaces; ++j) + { + const char* texFilename = &textureFilenames[j * 10]; + //v149 = 0; + //Str2 = (char *)ptr; + + //ODMFace* face = &pBModels[i].pFaces[j]; + //pFilename = (char *)v149 + (unsigned int)v60[v48].pFaces; + if ( !(pBModels[i].pFaces[j].uAttributes & FACE_DONT_CACHE_TEXTURE)) + { + v62 = pBitmaps_LOD->LoadTexture(texFilename); +// v63 = (ODMFace *)pFilename; + pBModels[i].pFaces[j].uTextureID = v62; + //v145 = (signed __int16)v62 != -1 ? &pBitmaps_LOD->pTextures[(signed __int16)v62] : 0; + //v108 = ((signed __int16)v62 != -1 ? pBitmaps_LOD->pTextures[(signed __int16)v62].palette_id1 : 36); + if ((signed __int16)v62 != -1) + pBitmaps_LOD->pTextures[v62].palette_id2 = pPaletteManager->LoadPalette(pBitmaps_LOD->pTextures[v62].palette_id1); + //goto LABEL_69; + //goto LABEL_68; + } + else + { + //v61 = pTextureFrameTable->FindTextureByName(texFilename); + pBModels[i].pFaces[j].uTextureID = pTextureFrameTable->FindTextureByName(texFilename); + if (!pBModels[i].pFaces[j].uTextureID) + { + v62 = pBitmaps_LOD->LoadTexture(texFilename); + //v63 = (ODMFace *)pFilename; + pBModels[i].pFaces[j].uAttributes &= ~FACE_DONT_CACHE_TEXTURE; + //LABEL_68: + pBModels[i].pFaces[j].uTextureID = v62; + //v145 = (signed __int16)v62 != -1 ? &pBitmaps_LOD->pTextures[(signed __int16)v62] : 0; + //v108 = ((signed __int16)v62 != -1 ? pBitmaps_LOD->pTextures[(signed __int16)v62].palette_id1 : 36); + if ((signed __int16)v62 != -1) + pBitmaps_LOD->pTextures[v62].palette_id2 = pPaletteManager->LoadPalette(pBitmaps_LOD->pTextures[v62].palette_id1); + //goto LABEL_69; + } + else + pTextureFrameTable->LoadAnimationSequenceAndPalettes(pBModels[i].pFaces[j].uTextureID); + } +//LABEL_69: + if (pBModels[i].pFaces[j].sCogTriggeredID) + { + if (pBModels[i].pFaces[j].HasEventHint()) + pBModels[i].pFaces[j].uAttributes |= FACE_HAS_EVENT; + else + pBModels[i].pFaces[j].uAttributes &= ~FACE_HAS_EVENT; + } + //++v144; + //v60 = pBModels; + //v149 = (char *)v149 + 308; + //Str2 += 10; + //if ( v144 >= (signed int)v60[v48].uNumFaces ) + //goto LABEL_74; + } + +//LABEL_74: + free((void *)textureFilenames); +// ++v151; +// ++v48; +// if ( v151 >= (signed int)uNumBModels ) +// goto LABEL_75; + } +//LABEL_75: + pGameLoadingUI_ProgressBar->Progress(); + + memcpy(&uNumLevelDecorations, pSrc, 4); + //uSourceLen = (char *)uSourceLen + 4; + if (uNumLevelDecorations > 3000) + MessageBoxW(nullptr, L"Can't load file!", + L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Odmap.cpp:678", 0); + + assert(sizeof(LevelDecoration) == 32); + //pFilename = (char *)(32 * uNumLevelDecorations); + memcpy(pLevelDecorations.data(), pSrc + 4, uNumLevelDecorations * sizeof(LevelDecoration)); + pSrc += 4 + sizeof(LevelDecoration) * uNumLevelDecorations; + + pGameLoadingUI_ProgressBar->Progress(); + + //v151 = 0; + //uSourceLen = (char *)uSourceLen + (int)pFilename; + for (uint i = 0; i < uNumLevelDecorations; ++i) + { + char name[256]; + memcpy(name, pSrc, sizeof(LevelDecoration)); + pSrc += sizeof(LevelDecoration); + + pLevelDecorations[i].uDecorationDescID = pDecorationList->GetDecorIdByName(name); + } + + pGameLoadingUI_ProgressBar->Progress(); + + memcpy(&numFaceIDListElems, pSrc, 4); + + //uSourceLen = (char *)uSourceLen + 4; + //v108 = (int)pFaceIDLIST; + free(pFaceIDLIST); + pFaceIDLIST = nullptr; + //v66 = field_DC; + //pFaceIDLIST = 0; + //v67 = malloc(0, 2 * v66, "IDLIST"); + uint faceIDListSize = 2 * numFaceIDListElems; + pFaceIDLIST = (unsigned short *)malloc(faceIDListSize); + //v68 = field_DC; + //pFaceIDLIST = (unsigned __int16 *)v67; + //pFilename = (char *)(2 * v68); + memcpy(pFaceIDLIST, pSrc + 4, faceIDListSize); + pSrc += 4 + faceIDListSize; + + //uSourceLen = (char *)uSourceLen + (int)pFilename; + pGameLoadingUI_ProgressBar->Progress(); + + //v108 = (int)pOMAP; + //free((void *)v108); + //pOMAP = 0; + free(pOMAP); + //v69 = malloc(0, 0x10000u, "OMAP"); + pOMAP = (unsigned int *)malloc(0x10000); + //v108 = 65536; + //pOMAP = (unsigned int *)v69; + memcpy(pOMAP, pSrc, 65536); + pSrc += 65536; + + //uSourceLen = (char *)uSourceLen + 65536; + pGameLoadingUI_ProgressBar->Progress(); + + memcpy(&uNumSpawnPoints, pSrc, 4); + //uSourceLen = (char *)uSourceLen + 4; + pGameLoadingUI_ProgressBar->Progress(); + //v70 = uNumSpawnPoints; + //v108 = (int)"Spawn"; + //v107 = 24 * v70; + //v106 = (char *)pSpawnPoints; + assert(sizeof(SpawnPointMM7) == 24); + uint spawnPointsSize = uNumSpawnPoints * sizeof(SpawnPointMM7); + pSpawnPoints = (SpawnPointMM7 *)malloc(spawnPointsSize); + //v72 = uNumSpawnPoints; + //pSpawnPoints = v71; + memcpy(pSpawnPoints, pSrc + 4, spawnPointsSize); + pSrc += 4 + spawnPointsSize; + + pGameLoadingUI_ProgressBar->Progress(); + + free(pSrcMem); + + //v108 = (int)".ddm"; + //v73 = strlen(pContainer); + strcpy(Str + strlen(Str) - 4, ".ddm"); + //strcpy((char *)v141 + v73, (const char *)v108); + v39 = pNew_LOD->FindContainer(Str, 1);//error + fread(&header, 0x10u, 1, v39); + Str2 = 0; + if (header.uVersion != 91969 || + header.pMagic[0] != 'm' || + header.pMagic[1] != 'v' || + header.pMagic[2] != 'i' || + header.pMagic[3] != 'i' ) + { + MessageBoxW(nullptr, L"Can't load file!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Odmap.cpp:746", 0); + Str2 = (char *)1; + } + //v74 = 0; + //pFilename = (char *)header.uCompressedSize; + //v149 = 0; + //pDestLen = header.uDecompressedSize; + if ( !Str2 ) + { + pSrcMem = (unsigned char *)malloc(header.uDecompressedSize); + pSrc = pSrcMem; + //v149 = v75; + if (header.uCompressedSize == header.uDecompressedSize) + fread(pSrc, header.uDecompressedSize, 1u, v39); + else if (header.uCompressedSize < header.uDecompressedSize) + { + void* compressedMem = malloc(header.uCompressedSize); + fread(compressedMem, header.uCompressedSize, 1, v39); + + uint actualDecompressedSize = header.uDecompressedSize; + zlib::MemUnzip(pSrc, &actualDecompressedSize, compressedMem, header.uCompressedSize); + free(compressedMem); + } + else + MessageBoxW(nullptr, L"Can't load file!", + L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Odmap.cpp:765", 0); + + assert(sizeof(DDM_DLV_Header) == 0x28); + memcpy(&ddm, pSrc, sizeof(DDM_DLV_Header)); + pSrc += sizeof(DDM_DLV_Header); + //v74 = (int)((char *)v75 + 40); + } + uint actualNumFacesInLevel = 0; + for (uint i = 0; i < uNumBModels; ++i) + actualNumFacesInLevel += pBModels[i].uNumFaces; + + //v79 = ddm.uNumFacesInBModels; + if (ddm.uNumFacesInBModels) + { + if ( ddm.uNumBModels ) + { + //v80 = ddm.uNumDecorations; + if (ddm.uNumDecorations) + { + if (ddm.uNumFacesInBModels != actualNumFacesInLevel || + ddm.uNumBModels != uNumBModels || + ddm.uNumDecorations != uNumLevelDecorations ) + Str2 = (char *)1; + } + } + } + + if (dword_6BE364_game_settings_1 & GAME_SETTINGS_2000) + pNumItems = 0x1BAF800; + + if (Str2 || ((unsigned int)((char *)File - ddm.uLastRepawnDay) >= pNumItems || !ddm.uLastRepawnDay)) + { + + if (Str2) + { + memset(Dst, 0, 0x3C8u); + memset(Src, 0, 0x3C8u); + //goto LABEL_112; + } + //v81 = ddm.uLastRepawnDay; + if ((unsigned int)((char *)File - ddm.uLastRepawnDay) >= pNumItems || !ddm.uLastRepawnDay) + { + memcpy(Dst, pSrc, 0x3C8u); + memcpy(Src, pSrc + 968, 0x3C8u); + } + //LABEL_112: + free(pSrcMem); + + ddm.uLastRepawnDay = (int)File; + if (Str2 == 0) + ++ddm.uNumRespawns; + v108 = 0; + *thisa = 1; + v39 = pGames_LOD->FindContainer(Str, 0); + fread(&header, 0x10, 1u, v39); + //pFilename = (char *)header.uCompressedSize; + //pDestLen = header.uDecompressedSize; + //v82 = malloc(header.uDecompressedSize); + pSrcMem = (unsigned char *)malloc(header.uDecompressedSize); + //v149 = v82; + if (header.uCompressedSize == header.uDecompressedSize) + fread(pSrcMem, header.uDecompressedSize, 1, v39); + else if (header.uCompressedSize < header.uDecompressedSize) + { + void* compressedMem = malloc(header.uCompressedSize); + fread(compressedMem, header.uCompressedSize, 1u, v39); + + uint actualDecompressedSize = header.uDecompressedSize; + zlib::MemUnzip(pSrcMem, &actualDecompressedSize, compressedMem, header.uCompressedSize); + free(compressedMem); + } + else + MessageBoxW(nullptr, L"Can't load file!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Odmap.cpp:857", 0); + + pSrc = pSrcMem + 40; + //goto LABEL_120; + } + else + *thisa = 0; +//LABEL_120: + //v108 = (int)".odm"; + //v83 = strlen(pContainer); + //strcpy((char *)v141 + v83, (const char *)v108); + memcpy(uFullyRevealedCellOnMap, pSrc, 0x3C8); + //v84 = (const void *)(v74 + 968); + memcpy(uPartiallyRevealedCellOnMap, pSrc + 0x3C8, 0x3C8); + pSrc += 2 * 0x3C8; + //v85 = (char *)v84 + 968; + + pGameLoadingUI_ProgressBar->Progress(); + + if ( *thisa ) + { + memcpy(uFullyRevealedCellOnMap, Dst, 0x3C8u); + memcpy(uPartiallyRevealedCellOnMap, Src, 0x3C8u); + } + + for (uint i = 0; i < uNumBModels; ++i) + { + BSPModel model = pBModels[i]; + for (uint j = 0; j < model.uNumFaces; ++j) + { + ODMFace face = model.pFaces[j]; + memcpy(&face.uAttributes, pSrc, 4); + pSrc += 4; + } + + for (uint j = 0; j < model.uNumFaces; ++j) + { + ODMFace face = model.pFaces[j]; + if (face.sCogTriggeredID) + { + if (face.HasEventHint()) + face.uAttributes |= FACE_HAS_EVENT_HINT; + else + face.uAttributes &= ~FACE_HAS_EVENT_HINT;//~0x00001000 + } + } + } + + pGameLoadingUI_ProgressBar->Progress(); + + for (uint i = 0; i < uNumLevelDecorations; ++i) + { + memcpy(&pLevelDecorations[i].uFlags, pSrc, 2); + pSrc += 2; + } + + pGameLoadingUI_ProgressBar->Progress(); + + memcpy(&uNumActors, pSrc, 4); + if (uNumActors > 500) + MessageBoxW(nullptr, L"Can't load file!", + L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Odmap.cpp:939", 0); + + pGameLoadingUI_ProgressBar->Progress(); + + assert(sizeof(Actor) == 836); + //pFilename = (char *)(836 * uNumActors); + memcpy(pActors.data(), pSrc + 4, uNumActors * sizeof(Actor)); + pSrc += 4 + uNumActors * sizeof(Actor); + //v92 = (char *)v91 + (int)pFilename; + pGameLoadingUI_ProgressBar->Progress(); + + memcpy(&uNumSpriteObjects, pSrc, 4); + assert(uNumSpriteObjects <= 1000 && "Too many objects"); + assert(sizeof(SpriteObject) == 112); + + pGameLoadingUI_ProgressBar->Progress(); + + //pFilename = (char *)(112 * uNumSpriteObjects); + memcpy(pSpriteObjects.data(), pSrc + 4, uNumSpriteObjects * sizeof(SpriteObject)); + pSrc += 4 + uNumSpriteObjects * sizeof(SpriteObject); + + //v94 = (char *)v93 + (int)pFilename; + pGameLoadingUI_ProgressBar->Progress(); + + memcpy(&uNumChests, pSrc, 4); + //v95 = (char *)v94 + 4; + if (uNumChests > 20) + MessageBoxW(nullptr, L"Can't load file!", + L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Odmap.cpp:968", 0); + + pGameLoadingUI_ProgressBar->Progress(); + + assert(sizeof(Chest) == 5324); + //pFilename = (char *)(5324 * uNumChests); + memcpy(pChests.data(), pSrc + 4 , uNumChests * sizeof(Chest)); + pSrc += 4 + uNumChests * sizeof(Chest); + //v96 = (char *)v95 + (int)pFilename; + pGameLoadingUI_ProgressBar->Progress(); + + memcpy(&stru_5E4C90_MapPersistVars, pSrc, 0xC8); + pSrc += 0xC8; + + pGameLoadingUI_ProgressBar->Progress(); + memcpy(&loc_time, pSrc, 0x38u); + + free(pSrcMem); + + pTileTable->InitializeTileset(Tileset_Dirt); + pTileTable->InitializeTileset(Tileset_Snow); + pTileTable->InitializeTileset(pTileTypes[0].tileset); + pTileTable->InitializeTileset(pTileTypes[1].tileset); + pTileTable->InitializeTileset(pTileTypes[2].tileset); + pTileTable->InitializeTileset(pTileTypes[3].tileset); + strcpy(pGroundTileset, byte_6BE124_cfg_textures_DefaultGroundTexture.data()); + TileDesc* v98 = pTileTable->GetTileById(pTileTypes[0].uTileID); + sMainTile_BitmapID = pBitmaps_LOD->LoadTexture(v98->pTileName, TEXTURE_DEFAULT); + if (sMainTile_BitmapID != -1) + pBitmaps_LOD->pTextures[sMainTile_BitmapID].palette_id2 = pPaletteManager->LoadPalette(pBitmaps_LOD->pTextures[sMainTile_BitmapID].palette_id1); + + _47F0E2(); + +//LABEL_150: + if ( pWeather->bRenderSnow ) //Ritor1: it's include for snow + strcpy(loc_time.sky_texture_name, "sky19"); + else if (loc_time.uLastVisitDay) + { + if ( (signed int)((signed int)(signed __int64)((double)loc_time.uLastVisitDay * 0.234375) / 60 / 60 / 24) % 28 != pParty->uDaysPlayed ) + { + if ( rand() % 100 >= 20 ) + v108 = dword_4EC268[rand() % dword_4EC2A8]; + else + v108 = dword_4EC28C[rand() % dword_4EC2AC]; + sprintf(loc_time.sky_texture_name, "plansky%d", v108); + } + } + else + strcpy(loc_time.sky_texture_name, "plansky3"); + + //v101 = pBitmaps_LOD->LoadTexture(field_4F8); + sSky_TextureID = pBitmaps_LOD->LoadTexture(loc_time.sky_texture_name); + if (sSky_TextureID != -1) + pBitmaps_LOD->pTextures[sSky_TextureID].palette_id2 = pPaletteManager->LoadPalette(pBitmaps_LOD->pTextures[sSky_TextureID].palette_id1); + + pPaletteManager->RecalculateAll(); + pSoundList->LoadSound(53, 0); + pSoundList->LoadSound(92, 0); + pSoundList->LoadSound(57, 0); + pSoundList->LoadSound(96, 0); + pSoundList->LoadSound(64, 0); + pSoundList->LoadSound(103, 0); + for (int i=0; i < 3;++i) + { + switch ( pTileTypes[i].tileset ) + { + case Tileset_Grass: + pSoundList->LoadSound(54, 0); + pSoundList->LoadSound(93, 0); + break; + case Tileset_Snow: + pSoundList->LoadSound(58, 0); + pSoundList->LoadSound(97, 0); + break; + case Tilset_Desert: + pSoundList->LoadSound(52, 0); + pSoundList->LoadSound(91, 0); + break; + case Tileset_3: + pSoundList->LoadSound(51, 0); + pSoundList->LoadSound(90, 0); + break; + case Tileset_Water: + pSoundList->LoadSound(62, 0); + pSoundList->LoadSound(101, 0); + break; + case Tileset_6: + pSoundList->LoadSound(49, 0); + pSoundList->LoadSound(88, 0); + break; + case Tileset_Swamp: + pSoundList->LoadSound(61, 0); + pSoundList->LoadSound(100, 0); + break; + } + } + return true; +} + +//----- (0047ECC1) -------------------------------------------------------- +int OutdoorLocation::GetTileIdByTileMapId(signed int a2) +{ + signed int result; // eax@2 + int v3; // eax@3 + + if ( a2 >= 90 ) + { + v3 = (a2 - 90) / 36; + if ( v3 && v3 != 1 && v3 != 2 ) + { + if ( v3 == Tileset_3 ) + result = this->pTileTypes[3].uTileID; + else + result = a2; + } + else + result = this->pTileTypes[v3].uTileID; + } + else + result = 0; + return result; +} + +//----- (0047ED08) -------------------------------------------------------- +unsigned int OutdoorLocation::DoGetTileTexture(signed int sX, signed int sY) +{ + int v3; // esi@5 +// unsigned int result; // eax@9 + + assert(sX < 128 && sY < 128); + + v3 = this->pTerrain.pTilemap[sY * 128 + sX]; + if (v3 < 198) // < Tileset_3 + { + if (v3 >= 90) + v3 = v3 + this->pTileTypes[(v3 - 90) / 36].uTileID - 36 * ((v3 - 90) / 36) - 90; + } + else + v3 = v3 + this->pTileTypes[3].uTileID - 198; + + #pragma region "New: seasons change" + + if (change_seasons) + switch (pParty->uCurrentMonth) + { + case 11: case 0: case 1: // winter + if (v3 >= 90) // Tileset_Grass begins at TileID = 90 + { + if (v3 <= 95) // some grastyl entries + v3 = 348; + else if (v3 <= 113) // rest of grastyl & all grdrt* + v3 = 348 + (v3 - 96); + } + /*switch (v3) + { + case 102: v3 = 354; break; // grdrtNE -> SNdrtne + case 104: v3 = 356; break; // grdrtNW -> SNdrtnw + case 108: v3 = 360; break; // grdrtN -> SNdrtn + }*/ + break; + + case 2: case 3: case 4: // spring + case 8: case 9: case 10: // autumn + if (v3 >= 90 && v3 <= 113) // just convert all Tileset_Grass to dirt + v3 = 1; + break; + + case 5: case 6: case 7: // summer + //all tiles are green grass by default + break; + + default: assert(pParty->uCurrentMonth >= 0 && pParty->uCurrentMonth < 12); + } + #pragma endregion + + return pTileTable->pTiles[v3].uBitmapID; +} + +//----- (0047ED83) -------------------------------------------------------- +int OutdoorLocation::_47ED83(signed int a2, signed int a3) +{ + assert(a2 < 128 && a3 < 128); + + return *(&this->pTerrain.pTilemap[128 * a3] + a2); +} + +//----- (0047EDB3) -------------------------------------------------------- +int OutdoorLocation::ActuallyGetSomeOtherTileInfo(signed int sX, signed int sY) +{ + assert(sX < 128 && sY < 128); + int v3; // esi@5 + + v3 = this->pTerrain.pTilemap[sY * 128 + sX]; + if ( v3 >= 90 ) + v3 = v3 + this->pTileTypes[(v3 - 90) / 36].uTileID - 36 * ((v3 - 90) / 36) - 90; + return pTileTable->pTiles[v3].uAttributes; +} + +//----- (0047EE16) -------------------------------------------------------- +int OutdoorLocation::DoGetHeightOnTerrain(signed int sX, signed int sZ) +{ + assert(sX < 128 && sZ < 128); + + return 32 * pTerrain.pHeightmap[sZ * 128 + sX]; +} + +//----- (0047EE49) -------------------------------------------------------- +int OutdoorLocation::GetSoundIdByPosition( signed int X_pos, signed int Y_pos, int running ) + { + signed int v4; // eax@5 + signed int v5; // eax@7 +// int v6; // eax@8 + signed int v8; // eax@9 + int modif=0; + + if ( X_pos < 0 || X_pos > 127 || Y_pos < 0 || Y_pos > 127 ) + v4 = 0; + else + v4 = this->pTerrain.pTilemap[128 * Y_pos + X_pos]; + v5 = GetTileIdByTileMapId(v4); + if (running) + modif=-39; + if ( !v5 ) + return 92+modif; + + switch (pTileTable->pTiles[v5].tileset) + { + case 0: return 93+ modif; + case 1: return 97+ modif; + case 2: return 91+ modif; + case 3: return 90+ modif; + case 4: return 101+ modif; + case 5: return 95+ modif; + case 6: return 88+ modif; + case 7: return 100+ modif; + case 8: return 93+ modif; + default: + v8=pTileTable->pTiles[v5].tileset; + if ( (v8 > 9 && v8 <= 17) || (v8 > 21 && v8 <= 27) ) + return 96+ modif; + else + return 95+ modif; + } + +} + +//----- (0047EF60) -------------------------------------------------------- +int OutdoorLocation::UpdateDiscoveredArea(int X_grid_pos, int Y_grid_poa, int a4) +{ + for (int i = -10; i < 10; i++) + { + int currYpos = Y_grid_poa + i - 20; + for (int j = -10; j < 10; j++) + { + int currXpos = X_grid_pos + j - 20; + int distanceSquared = i * i + j * j; + if ( distanceSquared <= 100 && currYpos >= 0 && currYpos <= 87 && currXpos >= 0 && currXpos <= 87 ) + { + unsigned char v13 = 1 << (7 - currXpos % 8); + this->uPartiallyRevealedCellOnMap[currYpos][currXpos / 8] |= v13; + if ( distanceSquared <= 49 ) + this->uFullyRevealedCellOnMap[currYpos][currXpos / 8] |= v13; + } + } + } + return 1; +} + + +//----- (0047F04C) -------------------------------------------------------- +bool OutdoorLocation::IsMapCellFullyRevealed(signed int x_pos, signed int y_pos) +{ + if ( x_pos < 0 || x_pos >= 88 || y_pos < 0 || y_pos >= 88 ) + return false; + else + return (uFullyRevealedCellOnMap[y_pos][x_pos/8] & (1 << (7 - (x_pos) % 8))) != 0; +} + +//----- (0047F097) -------------------------------------------------------- +bool OutdoorLocation::IsMapCellPartiallyRevealed(signed int x_pos, signed int y_pos) +{ + if ( x_pos < 0 || x_pos >= 88 || y_pos < 0 || y_pos >= 88 ) + return false; + else + return (uPartiallyRevealedCellOnMap[y_pos][x_pos/8] & (1 << (7 - (x_pos) % 8))) != 0; +} + +//----- (0047F0E2) -------------------------------------------------------- +bool OutdoorLocation::_47F0E2() +{ + for ( uint i = 0; i < (signed int)pBitmaps_LOD->uNumLoadedFiles; ++i ) + { + //if ( i != -1 ? (int)&pBitmaps_LOD->pTextures[i] : 0 ) + pBitmaps_LOD->pTextures[i].uDecompressedSize = this->pTerrain._47CB57((int)pBitmaps_LOD->pTextures[i].pLevelOfDetail0_prolly_alpha_mask, + pBitmaps_LOD->pTextures[i].palette_id2, + pBitmaps_LOD->pTextures[i].uTextureWidth * pBitmaps_LOD->pTextures[i].uTextureHeight); + } + return 1; +} + +//----- (0047F138) -------------------------------------------------------- +bool OutdoorLocation::PrepareDecorations() +{ + signed int v1; // ebx@1 + signed int v8; // [sp+Ch] [bp-4h]@1 + + v1 = 0; + v8 = 0; + if ( !_stricmp(pCurrentMapName, "out09.odm") ) + v8 = 1; + + for (uint i = 0; i < uNumLevelDecorations; ++i) + { + LevelDecoration* decor = &pLevelDecorations[i]; + + pDecorationList->InitializeDecorationSprite(decor->uDecorationDescID); + if ( pDecorationList->pDecorations[decor->uDecorationDescID].uSoundID && _6807E0_num_decorations_with_sounds_6807B8 < 9 ) + { + pSoundList->LoadSound(pDecorationList->pDecorations[decor->uDecorationDescID].uSoundID, 0); + _6807B8_level_decorations_ids[_6807E0_num_decorations_with_sounds_6807B8++] = i; + } + if ( v8 && decor->uCog == 20 ) + decor->uFlags |= LEVEL_DECORATION_OBELISK_CHEST; + if ( !decor->uEventID ) + { + if ( decor->IsInteractive() ) + { + if ( v1 < 124 ) + { + decor->_idx_in_stru123 = v1 + 75; + if ( !stru_5E4C90_MapPersistVars._decor_events[v1++] ) + decor->uFlags |= LEVEL_DECORATION_INVISIBLE; + } + } + } + } + + pGameLoadingUI_ProgressBar->Progress(); + return true; +} +// 6807E0: using guessed type int _6807E0_num_decorations_6807B8; + +//----- (0047F223) -------------------------------------------------------- +void OutdoorLocation::ArrangeSpriteObjects() +{ + OutdoorLocation *v5; // [sp+0h] [bp-4h]@1 + + v5 = this; + if ( (signed int)uNumSpriteObjects > 0 ) + { + for ( int i = 0; i < (signed int)uNumSpriteObjects; ++i ) + { + if ( pSpriteObjects[i].uObjectDescID ) + { + if ( !(pSpriteObjects[i].uAttributes & 8) && !(pObjectList->pObjects[pSpriteObjects[i].uObjectDescID].uFlags & 0x10) ) + pSpriteObjects[i].vPosition.z = GetTerrainHeightsAroundParty2(pSpriteObjects[i].vPosition.x, pSpriteObjects[i].vPosition.y, (int *)&v5, 0); + if ( pSpriteObjects[i].stru_24.uItemID ) + { + if ( pSpriteObjects[i].stru_24.uItemID != 220 + && pItemsTable->pItems[pSpriteObjects[i].stru_24.uItemID].uEquipType == EQUIP_POTION + && !pSpriteObjects[i].stru_24.uEnchantmentType ) + pSpriteObjects[i].stru_24.uEnchantmentType = rand() % 15 + 5; + pItemsTable->SetSpecialBonus(&pSpriteObjects[i].stru_24); + } + } + } + } + pGameLoadingUI_ProgressBar->Progress(); +} + +//----- (0047F2D3) -------------------------------------------------------- +bool OutdoorLocation::InitalizeActors(int a1) +{ + int alert_status; // [sp+348h] [bp-8h]@1 +// int v9; // [sp+34Ch] [bp-4h]@1 + + alert_status = 0; + for( int i = 0; i < uNumActors; ++i ) + { + if ( !(pActors[i].uAttributes & ACTOR_UNKNOW7) ) + { + if ( alert_status != 1 ) + { + pActors[i].uCurrentActionTime = 0; + pActors[i].uCurrentActionLength = 0; + if ( pActors[i].uAttributes & ACTOR_UNKNOW11 ) + pActors[i].uAIState = AIState::Disabled; + if ( pActors[i].uAIState != AIState::Removed && pActors[i].uAIState != AIState::Disabled && + (pActors[i].sCurrentHP == 0 || pActors[i].pMonsterInfo.uHP == 0) ) + pActors[i].uAIState = AIState::Dead; + pActors[i].vVelocity.x = 0; + pActors[i].vVelocity.y = 0; + pActors[i].vVelocity.z = 0; + pActors[i].UpdateAnimation(); + pActors[i].pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly; + pActors[i].PrepareSprites(0); + } + else + { + pActors[i].uAIState = AIState::Disabled; + pActors[i].uAttributes |= ACTOR_UNKNOW11; + } + } + else if ( a1 == 0 ) + { + pActors[i].uAIState = AIState::Disabled; + pActors[i].uAttributes |= ACTOR_UNKNOW11; + } + else if ( alert_status != 0 ) + { + pActors[i].uCurrentActionTime = 0; + pActors[i].uCurrentActionLength = 0; + if ( pActors[i].uAttributes & ACTOR_UNKNOW11 ) + pActors[i].uAIState = AIState::Disabled; + if ( pActors[i].uAIState != AIState::Removed && pActors[i].uAIState != AIState::Disabled && + (pActors[i].sCurrentHP == 0 || pActors[i].pMonsterInfo.uHP == 0) ) + pActors[i].uAIState = AIState::Dead; + pActors[i].vVelocity.x = 0; + pActors[i].vVelocity.y = 0; + pActors[i].vVelocity.z = 0; + pActors[i].UpdateAnimation(); + pActors[i].pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly; + pActors[i].PrepareSprites(0); + } + else + { + pActors[i].uAIState = AIState::Disabled; + pActors[i].uAttributes |= ACTOR_UNKNOW11; + alert_status = GetAlertStatus(); + } + } + + pGameLoadingUI_ProgressBar->Progress(); + //no use for this +// Actor thisa; +// thisa.pMonsterInfo.uID = 45; +// thisa.PrepareSprites(0); + return 1; +} + +//----- (0047F3EA) -------------------------------------------------------- +bool OutdoorLocation::LoadRoadTileset() +{ + pTileTypes[3].uTileID = pTileTable->GetTileForTerrainType(pTileTypes[3].tileset, 1); + pTileTable->InitializeTileset(pTileTypes[3].tileset); + return 1; +} + +//----- (0047F420) -------------------------------------------------------- +bool OutdoorLocation::LoadTileGroupIds() +{ + for (uint i = 0; i < 3; ++i) + pTileTypes[i].uTileID = pTileTable->GetTileForTerrainType(pTileTypes[i].tileset, 1); + + return true; +} + +//----- (0047B42C) -------------------------------------------------------- +void OutdoorLocation::PrepareActorsDrawList() +{ + unsigned int result; // eax@1 + int z; // esi@5 + float v4; // ST48_4@8 + unsigned int v8; // eax@11 + int v9; // edx@11 + signed int v12; // eax@16 + SpriteFrame *v14; // eax@24 + SpriteFrame *v15; // ebx@25 + int v17; // eax@35 + int v18; // ST78_4@36 + int v19; // eax@36 + int v20; // ecx@38 + int v21; // eax@38 + int v22; // ecx@41 + int v23; // ST5C_4@43 + int v24; // esi@44 + signed __int64 v25; // qtt@45 + int v26; // ST54_4@45 + int v27; // ecx@45 + int v34; // ecx@54 + int v41; // [sp+24h] [bp-3Ch]@11 + int v42; // [sp+28h] [bp-38h]@38 + int v43; // [sp+28h] [bp-38h]@45 + int v44; // [sp+2Ch] [bp-34h]@36 + int v45; // [sp+2Ch] [bp-34h]@44 + int v46; // [sp+2Ch] [bp-34h]@45 + int v47; // [sp+30h] [bp-30h]@36 + int v48; // [sp+30h] [bp-30h]@41 + signed int v49; // [sp+34h] [bp-2Ch]@5 + int v50; // [sp+34h] [bp-2Ch]@36 + int v51; // [sp+34h] [bp-2Ch]@41 + int v53; // [sp+38h] [bp-28h]@36 + int y; // [sp+40h] [bp-20h]@5 + int x; // [sp+44h] [bp-1Ch]@5 + int v57; // [sp+48h] [bp-18h]@45 + int v58; // [sp+4Ch] [bp-14h]@45 + int X; // [sp+54h] [bp-Ch]@36 + signed __int16 v62; // [sp+5Ch] [bp-4h]@25 + + //result = 0; + //v59 = 0; + for (int i = 0; i < uNumActors; ++i) + { + //v54 = 0; + //v1 = pActors;//[0].vPosition.z; + //do + //{ + //Actor* actor = &pActors[i]; + //v2 = actor->uAIState; + + pActors[i].uAttributes &= 0xFFFFFFF7;//~0x8 + if (pActors[i].uAIState == Removed || pActors[i].uAIState == Disabled) + continue; + + z = pActors[i].vPosition.z; + v49 = 0; + x = pActors[i].vPosition.x; + y = pActors[i].vPosition.y; + if (pActors[i].uAIState == Summoned) + { + if (PID_TYPE(pActors[i].uSummonerID) != OBJECT_Actor || + pActors[PID_ID(pActors[i].uSummonerID)].pMonsterInfo.uSpecialAbilityDamageDiceSides != 1 ) + { + z += floorf(pActors[i].uActorHeight * 0.5f + 0.5f); + } + else + { + v49 = 1; + pGame->pStru6Instance->_4A7F74(pActors[i].vPosition.x, pActors[i].vPosition.y, z); + v4 = (1.0 - (double)pActors[i].uCurrentActionTime / (double)pActors[i].uCurrentActionLength) * + (double)(2 * pActors[i].uActorHeight); + z -= floorf(v4 + 0.5f); + if ( z > pActors[i].vPosition.z ) + z = pActors[i].vPosition.z; + } + } + v8 = stru_5C6E00->Atan2(pActors[i].vPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x, + pActors[i].vPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y); + LOWORD(v9) = pActors[i].uYawAngle; + v41 = ((signed int)(stru_5C6E00->uIntegerPi + ((signed int)stru_5C6E00->uIntegerPi >> 3) + v9 - v8) >> 8) & 7; + if ( pParty->bTurnBasedModeOn ) + { + v12 = pActors[i].uCurrentActionTime; + if ( pActors[i].uCurrentActionAnimation == 1 ) + v12 = 32 * i + pMiscTimer->uTotalGameTimeElapsed; + } + else + { + v12 = pActors[i].uCurrentActionTime; + if ( pActors[i].uCurrentActionAnimation == 1 ) + v12 = 32 * i + pEventTimer->uTotalGameTimeElapsed; + } + if ( (signed __int64)pActors[i].pActorBuffs[ACTOR_BUFF_STONED].uExpireTime > 0 || (signed __int64)pActors[i].pActorBuffs[ACTOR_BUFF_PARALYZED].uExpireTime > 0 ) + v12 = 0; + if ( pActors[i].uAIState == 17 && !v49 ) + v14 = pSpriteFrameTable->GetFrame(uSpriteID_Spell11, v12); + else if ( pActors[i].uAIState == 16 ) + v14 = pSpriteFrameTable->GetFrameBy_x(pActors[i].pSpriteIDs[pActors[i].uCurrentActionAnimation], v12); + else + v14 = pSpriteFrameTable->GetFrame(pActors[i].pSpriteIDs[pActors[i].uCurrentActionAnimation], v12); + v62 = 0; + v15 = v14; + //v16 = (int *)v14->uFlags; + if (v14->uFlags & 2) + v62 = 2; + if (v14->uFlags & 0x40000) + v62 |= 0x40; + if (v14->uFlags & 0x20000) + LOBYTE(v62) = v62 | 0x80; + if ((256 << v41) & v14->uFlags) + v62 |= 4; + if ( v15->uGlowRadius ) + { + //LOBYTE(v16) = _4E94D3_light_type; + pMobileLightsStack->AddLight(x, y, z, 0, v15->uGlowRadius, 0xFFu, 0xFFu, 0xFFu, _4E94D3_light_type); + } + v17 = (x - pGame->pIndoorCameraD3D->vPartyPos.x) << 16; + if (pGame->pIndoorCameraD3D->sRotationX) + { + v18 = (y - pGame->pIndoorCameraD3D->vPartyPos.y) << 16; + v47 = (fixpoint_mul(v17, pGame->pIndoorCameraD3D->int_cosine_y) + fixpoint_mul(v18, pGame->pIndoorCameraD3D->int_sine_y)); + v50 = fixpoint_mul(v17, pGame->pIndoorCameraD3D->int_sine_y); + v53 = fixpoint_mul(v18, pGame->pIndoorCameraD3D->int_cosine_y); + v44 = (z - pGame->pIndoorCameraD3D->vPartyPos.z) << 16; + v19 = (fixpoint_mul(v44, pGame->pIndoorCameraD3D->int_sine_x) + fixpoint_mul(v47, pGame->pIndoorCameraD3D->int_cosine_x)); + X = fixpoint_mul(v44, pGame->pIndoorCameraD3D->int_sine_x) + fixpoint_mul(v47, pGame->pIndoorCameraD3D->int_cosine_x); + if ( v19 < 262144 || v19 > pODMRenderParams->shading_dist_mist << 16 ) + continue; + v20 = v53 - v50; + v42 = v53 - v50; + v21 = (fixpoint_mul(v44, pGame->pIndoorCameraD3D->int_cosine_x) - fixpoint_mul(v47, pGame->pIndoorCameraD3D->int_sine_x)); + } + else + { + v48 = (y - pGame->pIndoorCameraD3D->vPartyPos.y) << 16; + v51 = fixpoint_mul(v17, pGame->pIndoorCameraD3D->int_cosine_y); + v22 = fixpoint_mul(v48, pGame->pIndoorCameraD3D->int_sine_y); + X = v22 + v51; + if ( v22 + v51 < 262144 || v22 + v51 > pODMRenderParams->shading_dist_mist << 16 ) + continue; + v23 = fixpoint_mul(((x - pGame->pIndoorCameraD3D->vPartyPos.x) << 16), pGame->pIndoorCameraD3D->int_sine_y); + v20 = fixpoint_mul(v48, pGame->pIndoorCameraD3D->int_cosine_y) - v23; + v42 = fixpoint_mul(v48, pGame->pIndoorCameraD3D->int_cosine_y) - v23; + v21 = (z - pGame->pIndoorCameraD3D->vPartyPos.z) << 16; + } + v45 = v21; + v24 = abs(v20); + if ( abs(X) >= v24 ) + { + LODWORD(v25) = 0; + HIDWORD(v25) = SLOWORD(pODMRenderParams->int_fov_rad); + v58 = v25 / X; + v26 = v25 / X; + LODWORD(v25) = 0; + HIDWORD(v25) = SLOWORD(pODMRenderParams->int_fov_rad); + v57 = v25 / X; + v27 = pViewport->uScreenCenterX - ((signed int)(fixpoint_mul(v26, v42) + 0x8000) >> 16); + v43 = pViewport->uScreenCenterX - ((signed int)(fixpoint_mul(v26, v42) + 0x8000) >> 16); + v46 = pViewport->uScreenCenterY - ((signed int)(fixpoint_mul(v25 / X, v45) + 0x8000) >> 16); + result = uNumBillboardsToDraw; + //v28 = &pBillboardRenderList[uNumBillboardsToDraw]; + if (uNumBillboardsToDraw >= 500) + return; + ++uNumBillboardsToDraw; + ++uNumSpritesDrawnThisFrame; + pActors[i].uAttributes |= ACTOR_UNKNOW2; + pBillboardRenderList[uNumBillboardsToDraw - 1].HwSpriteID = v15->pHwSpriteIDs[v41]; + pBillboardRenderList[uNumBillboardsToDraw - 1].uIndoorSectorID = 0; + pBillboardRenderList[uNumBillboardsToDraw - 1].uPalette = v15->uPaletteIndex; + pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_x_scaler_packedfloat = fixpoint_mul(v15->scale, v58); + pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_y_scaler_packedfloat = fixpoint_mul(v15->scale, v57); + if ( pActors[i].pActorBuffs[ACTOR_BUFF_SHRINK].uExpireTime <= 0 ) + { + if ( pActors[i].pActorBuffs[ACTOR_BUFF_MASS_DISTORTION].uExpireTime > 0 ) + { + pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_y_scaler_packedfloat = fixpoint_mul(pGame->pStru6Instance->_4A806F(&pActors[i]), + pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_y_scaler_packedfloat); + LOWORD(v27) = v43; + } + } + else + { + if ( pActors[i].pActorBuffs[ACTOR_BUFF_SHRINK].uPower ) + { + pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_y_scaler_packedfloat = fixpoint_mul(65536 / pActors[i].pActorBuffs[ACTOR_BUFF_SHRINK].uPower, + pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_y_scaler_packedfloat); + LOWORD(v27) = v43; + } + } + pBillboardRenderList[uNumBillboardsToDraw - 1].uScreenSpaceX = v27; + pBillboardRenderList[uNumBillboardsToDraw - 1].uScreenSpaceY = v46; + pBillboardRenderList[uNumBillboardsToDraw - 1].world_x = x; + pBillboardRenderList[uNumBillboardsToDraw - 1].world_y = y; + pBillboardRenderList[uNumBillboardsToDraw - 1].world_z = z; + HIWORD(v34) = HIWORD(X); + LOWORD(v34) = 0; + pBillboardRenderList[uNumBillboardsToDraw - 1].dimming_level = 0; + pBillboardRenderList[uNumBillboardsToDraw - 1].sZValue = v34 + PID(OBJECT_Actor, i); + pBillboardRenderList[uNumBillboardsToDraw - 1].field_14_actor_id = i; + //v35 = pMonsterList->pMonsters; + //v36 = pActors[i].pMonsterInfo.uID; + pBillboardRenderList[uNumBillboardsToDraw - 1].field_1E = v62 | 0x200; + pBillboardRenderList[uNumBillboardsToDraw - 1].pSpriteFrame = v15; + pBillboardRenderList[uNumBillboardsToDraw - 1].sTintColor = pMonsterList->pMonsters[pActors[i].pMonsterInfo.uID - 1].sTintColor;//*((int *)&v35[v36] - 36); + if (pActors[i].pActorBuffs[ACTOR_BUFF_STONED].uExpireTime) + pBillboardRenderList[uNumBillboardsToDraw - 1].field_1E = v62 | 0x200; + } +//LABEL_58: + //++v59; + //v54 += 32; + //result = v59; + //++v1; + //} + //while ( v59 < (signed int)uNumActors ); + } + //return result; +} + +//----- (0044C1E8) -------------------------------------------------------- +bool ODMFace::HasEventHint() +{ + signed int event_index; // eax@1 + _evt_raw* start_evt; + _evt_raw* end_evt; + + event_index = 0; + if ( (uLevelEVT_NumEvents - 1) <= 0 ) + return false; + while ( pLevelEVT_Index[event_index].uEventID != this->sCogTriggeredID ) + { + ++event_index; + if ( event_index >= (signed int)(uLevelEVT_NumEvents - 1) ) + return false; + } + end_evt=(_evt_raw*)&pLevelEVT[pLevelEVT_Index[event_index+1].uEventOffsetInEVT]; + start_evt=(_evt_raw*)&pLevelEVT[pLevelEVT_Index[event_index].uEventOffsetInEVT]; + if ( (end_evt->_e_type != EVENT_Exit) || (start_evt->_e_type!= EVENT_MouseOver) ) + return false; + else + return true; +} +//----- (0046D49E) -------------------------------------------------------- +int ODM_GetFloorLevel(int X, signed int Y, int Z, int __unused, int *pIsOnWater, int *bmodel_pid, int bWaterWalk) +{ + BSPModel *pBModel; // esi@4 + ODMFace *pFace; // ecx@11 +// int v14; // edx@20 + signed int v18; // edx@26 + int v19; // eax@28 +// int v20; // edx@30 +// int v21; // ST1C_4@30 + signed int v22; // edx@30 + signed __int64 v23; // qtt@30 + int v24; // eax@36 + signed int v25; // ecx@38 +// int result; // eax@42 + signed int current_floor_level; // ecx@43 +// int v28; // edi@44 + signed int v29; // edx@44 +// int v30; // esi@45 +// int v31; // eax@45 +// int v33; // ecx@59 +// int v36; // [sp+14h] [bp-2Ch]@24 +// int v38; // [sp+1Ch] [bp-24h]@2 + int v39; // [sp+20h] [bp-20h]@9 + signed int pBModelNum; // [sp+28h] [bp-18h]@1 + int pFaceNum; // [sp+2Ch] [bp-14h]@8 + bool current_vertices_Y; // [sp+30h] [bp-10h]@22 + bool next_vertices_Y; // [sp+34h] [bp-Ch]@24 + signed int v46; // [sp+3Ch] [bp-4h]@1 + signed int number_hits; // [sp+58h] [bp+18h]@22 + signed int next_floor_level; // [sp+58h] [bp+18h]@43 + + v46 = 1; + current_BModel_id[0] = -1; + current_Face_id[0] = -1; + odm_floor_level[0] = GetTerrainHeightsAroundParty2(X, Y, pIsOnWater, bWaterWalk); + + for ( pBModelNum = 0; pBModelNum < pOutdoor->uNumBModels; ++pBModelNum ) + { + pBModel = &pOutdoor->pBModels[pBModelNum]; + if ( X <= pBModel->sMaxX && X >= pBModel->sMinX && + Y <= pBModel->sMaxY && Y >= pBModel->sMinY ) + { + if ( pBModel->uNumFaces > 0 ) + { + v39 = 0; + for ( pFaceNum = 0; pFaceNum < pBModel->uNumFaces; ++pFaceNum ) + { + pFace = &pBModel->pFaces[pFaceNum]; + if ( pFace->Ethereal() ) + continue; + if ( (pFace->uPolygonType == POLYGON_Floor || pFace->uPolygonType == POLYGON_InBetweenFloorAndWall) + && X <= pFace->pBoundingBox.x2 && X >= pFace->pBoundingBox.x1 + && Y <= pFace->pBoundingBox.y2 && Y >= pFace->pBoundingBox.y1 ) + { + for ( uint i = 0; i < pFace->uNumVertices; ++i) + { + odm_floor_face_vert_coord_X[2 * i] = pFace->pXInterceptDisplacements[i] + pBModel->pVertices.pVertices[pFace->pVertexIDs[i]].x; + odm_floor_face_vert_coord_Y[2 * i] = pFace->pYInterceptDisplacements[i] + pBModel->pVertices.pVertices[pFace->pVertexIDs[i]].y; + odm_floor_face_vert_coord_X[2 * i + 1] = pFace->pXInterceptDisplacements[i] + pBModel->pVertices.pVertices[pFace->pVertexIDs[i + 1]].x; + odm_floor_face_vert_coord_Y[2 * i + 1] = pFace->pYInterceptDisplacements[i] + pBModel->pVertices.pVertices[pFace->pVertexIDs[i + 1]].y; + } + odm_floor_face_vert_coord_X[2 * pFace->uNumVertices] = odm_floor_face_vert_coord_X[0]; + odm_floor_face_vert_coord_Y[2 * pFace->uNumVertices] = odm_floor_face_vert_coord_Y[0]; + + current_vertices_Y = odm_floor_face_vert_coord_Y[0] >= Y; + number_hits = 0; + if ( 2 * pFace->uNumVertices > 0 ) + { + for ( int i = 0; i < 2 * pFace->uNumVertices; ++i ) + { + if ( number_hits >= 2 ) + break; + //v36 = odm_floor_face_vert_coord_Y[i + 1]; + next_vertices_Y = odm_floor_face_vert_coord_Y[i + 1] >= Y; + if ( current_vertices_Y != next_vertices_Y )//проверка по Y + { + v18 = odm_floor_face_vert_coord_X[i + 1] >= X ? 0 : 2; + v19 = v18 | (odm_floor_face_vert_coord_X[i] < X); + if ( v19 != 3 ) + { + if ( !v19 ) + ++number_hits; + else + { + LODWORD(v23) = (Y - odm_floor_face_vert_coord_Y[i]) << 16; + HIDWORD(v23) = (Y - odm_floor_face_vert_coord_Y[i]) >> 16; + v22 = ((((odm_floor_face_vert_coord_X[i + 1] - odm_floor_face_vert_coord_X[i]) * v23 / (odm_floor_face_vert_coord_Y[i + 1] + - odm_floor_face_vert_coord_Y[i])) >> 16) + odm_floor_face_vert_coord_X[i]); + if ( v22 >= X) + ++number_hits; + } + } + } + current_vertices_Y = next_vertices_Y; + } + if ( number_hits == 1 ) + { + if ( v46 >= 20 ) + break; + if ( pFace->uPolygonType == POLYGON_Floor ) + v24 = pBModel->pVertices.pVertices[pFace->pVertexIDs[0]].z; + else + { + int a = fixpoint_mul(pFace->zCalc1, X); + int b = fixpoint_mul(pFace->zCalc2, Y); + int c = ((signed __int64)pFace->zCalc3 >> 16); + v24 = a + b + c; + } + v25 = v46++; + odm_floor_level[v25] = v24; + current_BModel_id[v25] = pBModelNum; + current_Face_id[v25] = pFaceNum; + } + } + } + + } + } + } + } + if ( v46 == 1 ) + { + *bmodel_pid = 0; + return odm_floor_level[0]; + } + current_floor_level = 0; + v29 = 0; + if ( v46 <= 1 ) + *bmodel_pid = 0; + else + { + current_floor_level = odm_floor_level[0]; + for ( uint i = 1; i < v46; ++i ) + { + next_floor_level = odm_floor_level[i]; + if ( current_floor_level <= Z + 5 ) + { + if ( next_floor_level > current_floor_level && next_floor_level <= Z + 5 ) + { + current_floor_level = next_floor_level; + v29 = i; + } + } + else if ( next_floor_level < current_floor_level ) + { + current_floor_level = next_floor_level; + v29 = i; + } + } + if ( !v29 ) + *bmodel_pid = 0; + else + *bmodel_pid = current_Face_id[v29] | (current_BModel_id[v29] << 6); + } + if ( v29 ) + { + *pIsOnWater = false; + if ( pOutdoor->pBModels[current_BModel_id[v29]].pFaces[current_Face_id[v29]].Fluid()) + *pIsOnWater = true; + } + if ( odm_floor_level[v29] >= odm_floor_level[0] ) + odm_floor_level[0] = odm_floor_level[v29]; + return odm_floor_level[0]; +} + +//not sure if right- or left-handed coordinate space assumed, so this could be normal of inverse normal +// for a right-handed system, that would be an inverse normal +//----- (0046DCC8) -------------------------------------------------------- +void ODM_GetTerrainNormalAt(int pos_x, int pos_z, Vec3_int_ *out) +{ + uint grid_x = WorldPosToGridCellX(pos_x); + uint grid_z = WorldPosToGridCellZ(pos_z) - 1; + + int grid_pos_x1 = GridCellToWorldPosX(grid_x); + int grid_pos_x2 = GridCellToWorldPosX(grid_x + 1); + int grid_pos_z1 = GridCellToWorldPosZ(grid_z); + int grid_pos_z2 = GridCellToWorldPosZ(grid_z + 1); + + int x1z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z); + int x2z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z); + int x2z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z + 1); + int x1z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z + 1); + + float side1_dx, side1_dy, side1_dz, + side2_dx, side2_dy, side2_dz; + + int dx = abs(pos_x - grid_pos_x1), + dz = abs(grid_pos_z1 - pos_z); + if (dz >= dx) + { + side2_dx = (double)(grid_pos_x2 - grid_pos_x1); + side2_dz = 0.0;//(double)(grid_pos_z2 - grid_pos_z2); // bug? z2 - z2 + side2_dy = (double)(x2z2_y - x1z2_y); + + side1_dx = 0.0;//(double)(grid_pos_x1 - grid_pos_x1); + side1_dz = (double)(grid_pos_z1 - grid_pos_z2); // z1 - z2 yes + side1_dy = (double)(x1z1_y - x1z2_y); + //Log::Warning(L"%S %S %u\n", __FILE__, __FUNCTION__, __LINE__); + /* |\ + side1 | \ + |____\ + side 2 */ + } + else + { + side2_dx = (double)(grid_pos_x1 - grid_pos_x2); + side2_dz = 0.0;//(double)(grid_pos_z1 - grid_pos_z1); + side2_dy = (double)(x1z1_y - x2z1_y); + + side1_dx = 0.0;//(double)(grid_pos_x2 - grid_pos_x1); + side1_dz = (double)(grid_pos_z2 - grid_pos_z1); + side1_dy = (double)(x2z2_y - x2z1_y); + /* side 2 + _____ + \ | + \ | side 1 + \| */ + } + + float nx = side1_dy * side2_dz - side1_dz * side2_dy; + float ny = side1_dx * side2_dy - side1_dy * side2_dx; + float nz = side1_dz * side2_dx - side1_dx * side2_dz; + + float mag = sqrt(nx * nx + ny * ny + nz * nz); + if (fabsf(mag) < 1e-6f) + { + out->y = 0; + out->x = 0; + out->z = 65536; + } + else + { + float invmag = 1.0 / mag; + out->x = invmag * nx * 65536.0; + out->y = invmag * ny * 65536.0; + out->z = invmag * nz * 65536.0; + } +} +//----- (0046BE0A) -------------------------------------------------------- +void ODM_UpdateUserInputAndOther() +{ + bool v0; // eax@5 + char pOut[32]; // [sp+8h] [bp-20h]@5 + + UpdateObjects(); + ODM_ProcessPartyActions(); + if ( pParty->vPosition.x < -22528 + || pParty->vPosition.x > 22528 + || pParty->vPosition.y < -22528 + || pParty->vPosition.y > 22528 ) + { + strcpy(pOutdoor->pLevelFilename, pCurrentMapName); + v0 = pOutdoor->GetTravelDestination(pParty->vPosition.x, pParty->vPosition.y, pOut, 32); + if ( !bUnderwater && (pParty->uFlags & (PARTY_FLAGS_1_STANDING_ON_WATER | PARTY_FLAGS_1_FALLING | 0x04) || pParty->uFlags & 0x0200 || pParty->bFlying) || !v0 ) + { + if ( pParty->vPosition.x < -22528 ) + pParty->vPosition.x = -22528; + if ( pParty->vPosition.x > 22528 ) + pParty->vPosition.x = 22528; + if ( pParty->vPosition.y < -22528 ) + pParty->vPosition.y = -22528; + if ( pParty->vPosition.y > 22528 ) + pParty->vPosition.y = 22528; + } + else + { + pAudioPlayer->StopChannels(-1, -1); + TravelUI_Load(); + } + } + UpdateActors_ODM(); + check_event_triggers(); +} +//----- (0041F54A) -------------------------------------------------------- +void OutdoorLocation::LoadActualSkyFrame() +{ + if ( pTexture_RestUI_CurrentSkyFrame ) + pTexture_RestUI_CurrentSkyFrame->Release(); + if ( pTexture_RestUI_CurrentHourglassFrame ) + pTexture_RestUI_CurrentHourglassFrame->Release(); + pIcons_LOD->SyncLoadedFilesCount(); + sprintf(pTmpBuf.data(), "TERRA%03d", pParty->uCurrentMinute / 6 + 10 * pParty->uCurrentHour); + pTexture_RestUI_CurrentSkyFrame = pIcons_LOD->LoadTexturePtr(pTmpBuf.data(), TEXTURE_16BIT_PALETTE); +} + + +//----- (004626BA) -------------------------------------------------------- +OutdoorLocation::OutdoorLocation() +{ + subconstuctor(); + uLastSunlightUpdateMinute = 0; + + uNumBModels = 0; + pBModels = nullptr; +} + +//----- (004626CD) -------------------------------------------------------- +void OutdoorLocation::subconstuctor() +{ + //OutdoorLocationTerrain::OutdoorLocationTerrain(&this->pTerrain); + field_F0 = 0; + field_F4 = 0x40000000u; + //DLVHeader::DLVHeader(&v1->ddm); + pSpawnPoints = 0; + pBModels = 0; + pCmap = 0; + pFaceIDLIST = 0; + pOMAP = 0; +} + +//----- (00481E55) -------------------------------------------------------- +void ODM_Project(unsigned int uNumVertices) +{ + for ( uint i = 0; i < uNumVertices; i++ ) + { + memcpy(&array_50AC10[i], &array_507D30[i], sizeof(array_50AC10[i])); + array_50AC10[i].vWorldViewProjX = (double)pViewport->uScreenCenterX + - ((double)pODMRenderParams->int_fov_rad * array_507D30[i]._rhw) * array_507D30[i].vWorldViewPosition.y; + array_50AC10[i].vWorldViewProjY = (double)pViewport->uScreenCenterY + - ((double)pODMRenderParams->int_fov_rad * array_507D30[i]._rhw) * array_507D30[i].vWorldViewPosition.z; + } + } +//----- (00485F64) -------------------------------------------------------- +void ODMRenderParams::Initialize() +{ + int v1; // eax@1 + int v2; // eax@2 + signed __int64 v3; // qtt@4 + int v4; // eax@4 + + this->uCameraFovInDegrees = 75; + v1 = stru_5C6E00->uPiMask & 0xD5; + if ( v1 >= (signed int)stru_5C6E00->uIntegerHalfPi ) + v2 = -stru_5C6E00->pTanTable[stru_5C6E00->uIntegerPi - v1]; + else + v2 = stru_5C6E00->pTanTable[v1]; + LODWORD(v3) = (viewparams->uSomeZ - viewparams->uSomeX) << 31; + HIDWORD(v3) = (viewparams->uSomeZ - viewparams->uSomeX) << 15 >> 16; + v4 = (signed int)(v3 / v2) >> 16; + this->int_fov_rad = v4; + this->field_4C = 360000; + this->int_fov_rad_inv = 65536 / v4; + this->field_50 = 115; + //sr_6BE060[1] = 1; + //RotationToInts(); +} +//----- (00473893) -------------------------------------------------------- +void ODM_ProcessPartyActions() +{ + int v1; // edi@1 + int v2; // ebx@1 + int floor_level; // eax@14 + int v6; // esi@45 + ODMFace *face; // ecx@45 + //signed int v33; // eax@143 + int v34; // esi@143 + int v35; // esi@147 + int v36; // eax@155 +// signed int v37; // esi@159 +// signed int v38; // eax@159 +// signed int i; // esi@159 + int v40; // esi@162 + bool v42; // eax@180 + signed int v43; // ecx@184 + signed int v44; // edx@184 + int v45; // ecx@200 + BSPModel *pModel; // eax@203 + bool pModel_; + ODMFace *pODMFace; // esi@203 + int v48; // eax@203 + int v54; // eax@215 + int v55; // eax@217 + unsigned int v66; // esi@263 + signed int v68; // ecx@263 + int v69; // eax@263 +// unsigned int v76; // edi@293 + bool v77; // edx@297 + bool v78; // ecx@303 + int v79; // ecx@314 + __int16 v80; // dx@317 + //int v81; // ebx@318 + //int v82; // ecx@318 + int pTerrainHeight; // eax@321 +// int v86; // [sp-20h] [bp-B4h]@246 + int v87; // [sp-20h] [bp-B4h]@248 + int v97; // [sp+Ch] [bp-88h]@180 + Vec3_int_ v98; + bool not_high_fall; // [sp+1Ch] [bp-78h]@33 + int v102; // [sp+20h] [bp-74h]@1 + int trigger_id; // [sp+24h] [bp-70h]@1 + bool bFeatherFall; // [sp+28h] [bp-6Ch]@4 + int bonus; + int on_ground; // [sp+2Ch] [bp-68h]@24 + bool bWaterWalk; // [sp+30h] [bp-64h]@1 + int ceiling_height; // [sp+3Ch] [bp-58h]@28 + int v110; // [sp+40h] [bp-54h]@180 + int v111; // [sp+44h] [bp-50h]@14 + bool hovering; // [sp+48h] [bp-4Ch]@1 + int v113; // [sp+4Ch] [bp-48h]@1 + bool party_running_flag; // [sp+50h] [bp-44h]@1 + int _walk_speed; // [sp+54h] [bp-40h]@48 + int pX; // [sp+58h] [bp-3Ch]@1 + int pY; // [sp+5Ch] [bp-38h]@1 + int v118; // [sp+60h] [bp-34h]@1 + int _angle_x; // [sp+68h] [bp-2Ch]@48 + unsigned int v122; // [sp+70h] [bp-24h]@180 + int pZ; // [sp+74h] [bp-20h]@1 + bool party_walking_flag; // [sp+78h] [bp-1Ch]@1 + int _angle_y; // [sp+7Ch] [bp-18h]@48 + int v128; // [sp+88h] [bp-Ch]@1 + int v129; // [sp+8Ch] [bp-8h]@92 + + v1 = 0; + trigger_id = 0; + v2 = 0; + //*(float *)&v128 = 0.0; + int fall_speed = pParty->uFallSpeed; + v128 = 0; + v129 = 0; + pX = pParty->vPosition.x; + pY = pParty->vPosition.y; + pZ = pParty->vPosition.z; + v113 = pParty->field_6F0; + hovering = false; + bool partyAtHighSlope = IsTerrainSlopeTooHigh(pParty->vPosition.x, pParty->vPosition.y); + party_running_flag = false; + party_walking_flag = false; + v102 = 0; + pModel_ = false; + bWaterWalk = false; + + if (!pParty->FeatherFallActive())//Проверка падение пера + { + bFeatherFall = false; + for (int i = 0; i < 4; ++i) + if (pParty->pPlayers[i].WearsItemAnyWhere(ITEM_ARTIFACT_LADYS_ESCORT)) // seems like flying boots + { + bFeatherFall = true; + break; + } + } + else + bFeatherFall = true; + + pParty->uFlags &= ~PARTY_FLAGS_1_STANDING_ON_WATER; + if (pParty->WaterWalkActive())//Проверка хождения по воде + { + //LOBYTE(pParty->uFlags) &= 0x7Fu; + bWaterWalk = true; + *(short *)&stru_5E4C90_MapPersistVars._decor_events[20 * pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uOverlayID + 119] |= 1u; + if (!(pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uFlags & 1) && + pParty->pPlayers[pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uCaster - 1].sMana <= 0 ) + bWaterWalk = false; + } + + int bmodel_standing_on_pid; + int is_on_water = false; + floor_level = ODM_GetFloorLevel(pX, pY, pZ, pParty->uPartyHeight, &is_on_water, &bmodel_standing_on_pid, bWaterWalk); + int is_not_on_bmodel = bmodel_standing_on_pid == 0; + + v111 = floor_level; + if ( bFeatherFall ) + pParty->uFallStartY = floor_level; + else + floor_level = pParty->uFallStartY; + + if ( floor_level - pZ > 512 && !bFeatherFall && pZ <= v111 + 1 )//падение на 3D Model + { + if (pParty->uFlags & PARTY_FLAGS_1_LANDING) + pParty->uFlags &= ~PARTY_FLAGS_1_LANDING; + else for (int i = 0; i < 4; ++i) // receive falling damage + { + if ( !pParty->pPlayers[i].HasEnchantedItemEquipped(72) && !pParty->pPlayers[i].WearsItem(ITEM_ARTIFACT_HERMES_SANDALS, EQUIP_BOOTS) ) + { + pParty->pPlayers[i].ReceiveDamage( + (signed int)((pParty->uFallStartY - pZ) * (unsigned __int64)(pParty->pPlayers[i].GetMaxHealth() / 10)) / 256, DMGT_PHISYCAL); + bonus = 20 - pParty->pPlayers[i].GetParameterBonus(pParty->pPlayers[i].GetActualEndurance()); + pParty->pPlayers[i].SetRecoveryTime((signed __int64)((double)bonus * flt_6BE3A4_debug_recmod1 * 2.133333333333333)); + } + } + } + + ceiling_height = -1; + if ( pParty->bFlying ) + ceiling_height = GetCeilingHeight(pX, pY, pZ + pParty->uPartyHeight, (int)&v102);//высота потолка + //v107 = bmodel_standing_on_pid == 0; + on_ground = v111 + 1; + if ( pZ <= on_ground )//полёт: посадка + { + ceiling_height = -1; + pParty->bFlying = false; + } + else + hovering = true; + not_high_fall = pZ - v111 <= 32; + + if ( bWalkSound && pParty->walk_sound_timer)//timer update + { + if (pParty->walk_sound_timer >= pEventTimer->uTimeElapsed) + pParty->walk_sound_timer -= pEventTimer->uTimeElapsed; + else + pParty->walk_sound_timer = 0; + } + + if (!bUnderwater && pParty->pPartyBuffs[PARTY_BUFF_FLY].uExpireTime <= 0)// конец действия полёта + pParty->bFlying = false; + + if (!hovering)// + { + if ( pParty->floor_face_pid != PID(OBJECT_BModel, bmodel_standing_on_pid) ) + { + if (bmodel_standing_on_pid) + { + if ( (bmodel_standing_on_pid >> 6) < pOutdoor->uNumBModels ) + { + face = pOutdoor->pBModels[bmodel_standing_on_pid >> 6].pFaces; + v6 = bmodel_standing_on_pid & 0x3F; + /*if ( *(char *)(v7->pFacePlane.vNormal.x + 308 * v6 + 31) & 4 ) + { + pParty->field_6F4_packedid = PID(OBJECT_BModel,v108); + v103 = *(short *)(v7->pFacePlane.vNormal.x + 308 * v6 + 292); + }*/ + if ( face[v6].uAttributes & FACE_PRESSURE_PLATE ) + { + pParty->floor_face_pid = PID(OBJECT_BModel, bmodel_standing_on_pid); + trigger_id = face[v6].sCogTriggeredID; // + } + } + } + } + pParty->floor_face_pid = PID(OBJECT_BModel, bmodel_standing_on_pid); + } + + _walk_speed = pParty->uWalkSpeed; + _angle_y = pParty->sRotationY; + _angle_x = pParty->sRotationX; + //v126 = pEventTimer->dt_in_some_format; + /*v119 = (Player **)((unsigned __int64)(pEventTimer->dt_in_some_format + * (signed __int64)((signed int)(pParty->field_20_prolly_turn_speed + * stru_5C6E00->uIntegerPi) + / 180)) >> 16);*/ + __int64 dturn = (unsigned __int64)(pEventTimer->dt_in_some_format * (signed __int64)((signed int)(pParty->y_rotation_speed * stru_5C6E00->uIntegerPi) / 180)) >> 16; + while (pPartyActionQueue->uNumActions) + { + switch (pPartyActionQueue->Next()) + { + case PARTY_FlyUp://полёт вверх + { + if (!pParty->FlyActive() && !bUnderwater) + break; + + pParty->bFlying = false; + if (bUnderwater || + pParty->pPartyBuffs[PARTY_BUFF_FLY].uFlags & 1 || + pParty->pPlayers[pParty->pPartyBuffs[PARTY_BUFF_FLY].uCaster - 1].sMana > 0 ) + { + extern int max_flight_height; + if ( pParty->vPosition.z < max_flight_height || hovering ) + { + pZ += 30; + v113 += 30; + pParty->bFlying = true; + if ( pZ > max_flight_height ) + { + pZ = max_flight_height; + v113 = max_flight_height; + } + v1 = 0; + v2 = 0; + fall_speed = 0; + *(float *)&v128 = 0.0; + if ( v102 && pZ < ceiling_height && (signed int)(pParty->uPartyHeight + pZ) >= ceiling_height )//столкновение с потолком + { + pParty->field_6E0 = 0; + pParty->field_6E4 = 0; + pPartyActionQueue->uNumActions = 0; + pParty->uFlags |= PARTY_FLAGS_1_LANDING; + pParty->vPosition.z = ceiling_height - pParty->uPartyHeight - 31; + pParty->field_6F0 = pZ; + pParty->bFlying = false; + pZ = ceiling_height - pParty->uPartyHeight - 31; + v113 = pParty->field_6F0; + } + pParty->uFallSpeed = 0; + pModel_ = true; + } + } + } + break; + + case PARTY_FlyDown://полёт вниз + if (pParty->FlyActive() || bUnderwater) + { + pParty->bFlying = false; + if ( bUnderwater + || pParty->pPartyBuffs[PARTY_BUFF_FLY].uFlags & 1 + || pParty->pPlayers[pParty->pPartyBuffs[PARTY_BUFF_FLY].uCaster - 1].sMana > 0 )//*(int *)&pParty->pArtifactsFound[6972 * pParty->pPartyBuffs[PARTY_BUFF_FLY].uCaster + 10] > 0 ) + { + pZ -= 30; + v113 -= 30; + pParty->uFallSpeed = 0; + fall_speed = 0; + pParty->bFlying = true; + pModel_ = true; + if ( pZ <= v111 ) + { + pParty->bFlying = false; + pPartyActionQueue->uNumActions = 0; + } + } + } + break; + + case PARTY_TurnLeft: + if (uTurnSpeed) + _angle_y += uTurnSpeed; //descrete turn + else + _angle_y += dturn * fTurnSpeedMultiplier; // time-based smooth turn + + _angle_y &= stru_5C6E00->uDoublePiMask; + break; + + case PARTY_TurnRight: + if (uTurnSpeed) + _angle_y -= uTurnSpeed; + else + _angle_y -= dturn * fTurnSpeedMultiplier; + + _angle_y &= stru_5C6E00->uDoublePiMask; + break; + + case PARTY_FastTurnLeft: + if (uTurnSpeed) + _angle_y += uTurnSpeed; + else + _angle_y += 2.0f * fTurnSpeedMultiplier * (double)dturn; + + _angle_y &= stru_5C6E00->uDoublePiMask; + break; + + case PARTY_FastTurnRight: + if (!uTurnSpeed) + _angle_y -= 2.0f * fTurnSpeedMultiplier * (double)dturn; + else + _angle_y -= uTurnSpeed; + + _angle_y &= stru_5C6E00->uDoublePiMask; + break; + + case PARTY_StrafeLeft://хождение боком в влево + { + *(float *)&v128 = pParty->uWalkSpeed; + + float sin_y = sinf(2 * 3.141592653589 * _angle_y / 2048.0); + int dx = sin_y * pParty->uWalkSpeed * fWalkSpeedMultiplier; + v2 -= 3 * dx / 4; + + float cos_y = cosf(2 * 3.141592653589 * _angle_y / 2048.0); + int dy = cos_y * pParty->uWalkSpeed * fWalkSpeedMultiplier; + v1 += 3 * dy / 4; + + v128 = v1; + party_walking_flag = true; + } + break; + + case PARTY_StrafeRight://хождение боком в вправо + { + *(float *)&v128 = pParty->uWalkSpeed; + + float sin_y = sinf(2 * 3.141592653589 * _angle_y / 2048.0); + int dx = sin_y * pParty->uWalkSpeed * fWalkSpeedMultiplier; + v2 += 3 * dx / 4; + + float cos_y = cosf(2 * 3.141592653589 * _angle_y / 2048.0); + int dy = cos_y * pParty->uWalkSpeed * fWalkSpeedMultiplier; + v1 -= 3 * dy / 4; + + v128 = v1; + party_walking_flag = true; + } + break; + + case PARTY_WalkForward:// идти вперёд + { + *(float *)&v128 = _walk_speed; + + float sin_y = sinf(2 * 3.141592653589 * _angle_y / 2048.0), + cos_y = cosf(2 * 3.141592653589 * _angle_y / 2048.0); + + int dx = cos_y * pParty->uWalkSpeed * fWalkSpeedMultiplier; + int dy = sin_y * pParty->uWalkSpeed * fWalkSpeedMultiplier; + + if ( new_speed ) + { + v2 += dx * 12; + v1 += dy * 12; + } + else + { + v2 += dx; + v1 += dy; + } + + v128 = v1; + party_walking_flag = true; + } + break; + + case PARTY_RunForward://бежать вперёд + { + *(float *)&v128 = _walk_speed; + + float sin_y = sinf(2 * 3.141592653589 * _angle_y / 2048.0); + float cos_y = cosf(2 * 3.141592653589 * _angle_y / 2048.0); + + int dx = cos_y * pParty->uWalkSpeed * fWalkSpeedMultiplier; + int dy = sin_y * pParty->uWalkSpeed * fWalkSpeedMultiplier; + + if (pParty->bFlying)//лететь вперёд + { + v2 += 4 * dx; + v1 += 4 * dy; + + v128 = v1; + } + else if (partyAtHighSlope && !bmodel_standing_on_pid)//сбегание со склона + { + v2 += dx; + v1 += dy; + + v128 = v1; + party_walking_flag = true; + } + else + { + /*v2 += (unsigned __int64)(stru_5C6E00->Cos(_angle_y) + * (signed __int64)(signed int)(2 * (unsigned __int64)(signed __int64)((double)_walk_speed * fWalkSpeedMultiplier))) >> 16; + v1 += (unsigned __int64)((signed int)stru_5C6E00->Sin(_angle_y) + * (signed __int64)(signed int)(2 * (unsigned __int64)(signed __int64)((double)_walk_speed * fWalkSpeedMultiplier))) >> 16;*/ + + v2 += 2 * dx; + v1 += 2 * dy; + + v128 = v1; + party_running_flag = true; + } + } + break; + + + case PARTY_WalkBackward://идти назад + { + *(float *)&v128 = _walk_speed; + + float sin_y = sinf(2 * 3.141592653589 * _angle_y / 2048.0), + cos_y = cosf(2 * 3.141592653589 * _angle_y / 2048.0); + + int dx = cos_y * pParty->uWalkSpeed * fBackwardWalkSpeedMultiplier; + v2 -= dx; + + int dy = sin_y * pParty->uWalkSpeed * fBackwardWalkSpeedMultiplier; + v1 -= dy; + + v128 = v1; + party_walking_flag = true; + } + break; + + + case PARTY_RunBackward://бежать назад + { + float sin_y = sinf(2 * 3.141592653589 * _angle_y / 2048.0), + cos_y = cosf(2 * 3.141592653589 * _angle_y / 2048.0); + + int dx = cos_y * pParty->uWalkSpeed * fBackwardWalkSpeedMultiplier; + int dy = sin_y * pParty->uWalkSpeed * fBackwardWalkSpeedMultiplier; + + if (pParty->bFlying) + { + v2 -= 4 * dx; + v1 -= 4 * dy; + v128 = v1; + } + else + { + v2 -= dx; + v1 -= dy; + + v128 = v1; + party_walking_flag = true; + } + } + break; + + case PARTY_CenterView://смотреть прямо + _angle_x = 0; + break; + + case PARTY_LookUp://смотреть вверх + _angle_x += (signed __int64)(flt_6BE150_look_up_down_dangle * 25.0); + if ( _angle_x > 128 ) + _angle_x = 128; + if (uActiveCharacter) + pPlayers[uActiveCharacter]->PlaySound(SPEECH_63, 0); + break; + + case PARTY_LookDown://смотреть вниз + _angle_x += (signed __int64)(flt_6BE150_look_up_down_dangle * -25.0); + if ( _angle_x < -128 ) + _angle_x = -128; + if (uActiveCharacter) + pPlayers[uActiveCharacter]->PlaySound(SPEECH_64, 0); + break; + + case PARTY_Jump://прыжок + if ( (!partyAtHighSlope || bmodel_standing_on_pid) && !hovering && pParty->field_24 && !(pParty->uFlags & 4) && !(pParty->uFlags & 0x200) ) + { + //v126 = pParty->field_24 << 6; + hovering = true; + fall_speed = (signed __int64)((double)(pParty->field_24 << 6) * 1.5 + (double)fall_speed); + } + break; + + case PARTY_Land://приземление(клавиша Home) + if (pParty->bFlying) + { + pParty->uFlags |= PARTY_FLAGS_1_LANDING; + pParty->uFallSpeed = 0; + } + pParty->bFlying = false; + pPartyActionQueue->uNumActions = 0; + break; + + default: + assert(false); + + + } + } + + pParty->sRotationY = _angle_y; + pParty->sRotationX = _angle_x; + //------------------------------------------- + if ( pParty->bFlying ) + { + v129 = fixpoint_mul(4, stru_5C6E00->Cos(GetTickCount())); + pZ = v113 + v129; + if ( pModel_ ) + pZ = v113; + if (pParty->FlyActive()) + stru_5E4C90_MapPersistVars._decor_events[20 * pParty->pPartyBuffs[PARTY_BUFF_FLY].uOverlayID + 119] &= 0xFE; + pParty->uFallStartY = pZ; + } + else if ( pZ < v111 ) + { + if ( is_on_water && fall_speed ) + SpriteObject::sub_42F960_create_object(pX, pY, v111); + fall_speed = 0; + pZ = v111; + pParty->uFallStartY = v111; + v113 = pZ; + if (pParty->FlyActive()) + stru_5E4C90_MapPersistVars._decor_events[20 * pParty->pPartyBuffs[PARTY_BUFF_FLY].uOverlayID + 119] |= 1; + } + else + { + v113 = pZ; + if (pParty->FlyActive()) + stru_5E4C90_MapPersistVars._decor_events[20 * pParty->pPartyBuffs[PARTY_BUFF_FLY].uOverlayID + 119] |= 1; + } + //------------------------------------------ + if (hovering && !pParty->bFlying)//расчёт скорости падения + { + //v33 = -(pEventTimer->uTimeElapsed * GetGravityStrength()); + v34 = fall_speed + (-(pEventTimer->uTimeElapsed * GetGravityStrength()) << 1); + fall_speed += (-(pEventTimer->uTimeElapsed * GetGravityStrength()) << 1 ); //y(t) = 2*gt + } + else if (!partyAtHighSlope) + v34 = fall_speed; + else if (!hovering) + { + if ( !bmodel_standing_on_pid ) + { + // rolling down the hill + // how it's done: you get a little bit pushed in the air along terrain normal, getting in the air + // and falling to the gravity, gradually sliding downwards. nice trick + pZ = v111; + ODM_GetTerrainNormalAt(pX, pY, &v98); + v35 = fall_speed + (8 * -(pEventTimer->uTimeElapsed * GetGravityStrength())); + v129 = abs(v2 * v98.x + v1 * v98.y + v35 * v98.z) >> 16; + v2 += fixpoint_mul(v129, v98.x); + v1 += fixpoint_mul(v129, v98.y); + v34 = v35 + fixpoint_mul(v129, v98.z); + v128 = v1; + fall_speed = v34; + } + } + else + v34 = fall_speed; + + if ( hovering )//блок для крика падения + { + if ( !bUnderwater && v34 <= 0) + { + if ( v34 < -500 && !pParty->bFlying && pParty->vPosition.z - v111 > 1000 && !pParty->FeatherFallActive()) + { // falling scream + for (int i = 0; i < 4; ++i) + { + if (!pParty->pPlayers[i].HasEnchantedItemEquipped(72) + && !pParty->pPlayers[i].WearsItem(ITEM_ARTIFACT_HERMES_SANDALS, EQUIP_BOOTS) + && pParty->pPlayers[i].CanAct()) + pParty->pPlayers[i].PlaySound(SPEECH_Falling_scream, 0);//крик падения + } + } + } + } + else + pParty->uFallStartY = pZ; + + if ( v2 * v2 + v1 * v1 < 400 && !partyAtHighSlope ) + { + *(float *)&v128 = 0.0; + v2 = 0; + } +//--(столкновения)------------------------------------------------------------------- + stru_721530.field_84 = -1; + stru_721530.field_70 = 0; + stru_721530.prolly_normal_d = pParty->field_14_radius; + stru_721530.field_8_radius = pParty->field_14_radius / 2; + stru_721530.field_0 = 1; + stru_721530.height = pParty->uPartyHeight - 32; + for ( uint i = 0; i < 100; i++ ) + { + stru_721530.position.x = pX; + stru_721530.position.y = pY; + stru_721530.position.z = stru_721530.height + pZ + 1; + + stru_721530.normal.x = pX; + stru_721530.normal.y = pY; + stru_721530.normal.z = stru_721530.prolly_normal_d + pZ + 1; + + stru_721530.velocity.x = v2; + stru_721530.velocity.y = v128; + stru_721530.velocity.z = fall_speed; + + stru_721530.uSectorID = 0; + v36 = 0; + if ( pParty->bTurnBasedModeOn == true && pTurnEngine->turn_stage == TE_MOVEMENT ) + v36 = 13312; + if ( stru_721530._47050A(v36) ) + break; + _46E889_collide_against_bmodels(1); + //v37 = WorldPosToGridCellZ(pParty->vPosition.y); + //v38 = WorldPosToGridCellX(pParty->vPosition.x); + _46E26D_collide_against_sprites(WorldPosToGridCellX(pParty->vPosition.x), WorldPosToGridCellZ(pParty->vPosition.y)); + _46ED8A_collide_against_sprite_objects(4); + for ( uint actor_id = 0; actor_id < (signed int)uNumActors; ++actor_id ) + Actor::_46DF1A_collide_against_actor(actor_id, 0); + if ( stru_721530.field_7C >= stru_721530.field_6C ) + { + _angle_x = stru_721530.normal2.x; + _angle_y = stru_721530.normal2.y; + v40 = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1; + } + else + { + _angle_x = pX + fixpoint_mul(stru_721530.field_7C, stru_721530.direction.x); + _angle_y = pY + fixpoint_mul(stru_721530.field_7C, stru_721530.direction.y); + //pModel = (BSPModel *)fixpoint_mul(stru_721530.field_7C, stru_721530.direction.z); + v40 = fixpoint_mul(stru_721530.field_7C, stru_721530.direction.z) + pZ; + } + v122 = v40; + ODM_GetFloorLevel(_angle_x, _angle_y, v40, pParty->uPartyHeight, &is_on_water, &bmodel_standing_on_pid, 0); + v129 = ODM_GetFloorLevel(_angle_x, pY, v40, pParty->uPartyHeight, &is_on_water, &v97, 0); + int v119 = ODM_GetFloorLevel(pX, _angle_y, v40, pParty->uPartyHeight, &is_on_water, &v110, 0); + bool v42_ = (BSPModel *)IsTerrainSlopeTooHigh(_angle_x, pY); + v42 = IsTerrainSlopeTooHigh(pX, _angle_y); + is_not_on_bmodel = false; + //v118 = v42; + if ( !v97 && !v110 && !bmodel_standing_on_pid ) + is_not_on_bmodel = true; + v43 = 1; + v44 = 1; + if ( bUnderwater || !is_not_on_bmodel ) + { + pX = _angle_x; + if ( v43 ) + pY = _angle_y; + } + else + { + if ( v42_ && v129 > pZ ) + v44 = 0; + if ( v42 && v119 > pZ ) + v43 = 0; + if ( v44 ) + { + pX = _angle_x; + if ( v43 ) + pY = _angle_y; + } + else if ( v43 ) + pY = _angle_y; + else + { + int new_ = ODM_GetFloorLevel(_angle_x, _angle_y, v40, pParty->uPartyHeight, &is_on_water, &bmodel_standing_on_pid, 0); + if ( IsTerrainSlopeTooHigh(_angle_x, _angle_y) && new_ <= pZ ) + { + v43 = 1; + pX = _angle_x; + if ( v43 ) + pY = _angle_y; + } + } + } + if ( stru_721530.field_7C >= stru_721530.field_6C ) + { + if ( !is_not_on_bmodel ) + { + pX = stru_721530.normal2.x; + pY = stru_721530.normal2.y; + } + pZ = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1; + break; + } + stru_721530.field_70 += stru_721530.field_7C; + pX = _angle_x; + pY = _angle_y; + v45 = stru_721530.uFaceID; + pZ = v40; + + if ( PID_TYPE(stru_721530.uFaceID) == OBJECT_Actor) + { + if (pParty->Invisible()) + pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].Reset(); + viewparams->bRedrawGameUI = true; + } + + if ( PID_TYPE(stru_721530.uFaceID) == OBJECT_Decoration) + { + v129 = stru_5C6E00->Atan2(_angle_x - pLevelDecorations[(signed int)stru_721530.uFaceID >> 3].vPosition.x, + _angle_y - pLevelDecorations[(signed int)stru_721530.uFaceID >> 3].vPosition.y); + v2 = fixpoint_mul(stru_5C6E00->Cos(v129), integer_sqrt(v2 * v2 + v128 * v128)); + v122 = fixpoint_mul(stru_5C6E00->Sin(v129), integer_sqrt(v2 * v2 + v128 * v128)); + v128 = fixpoint_mul(stru_5C6E00->Sin(v129), integer_sqrt(v2 * v2 + v128 * v128)); + } + + if ( PID_TYPE(stru_721530.uFaceID) == OBJECT_BModel) + { + pParty->bFlying = false; + pModel = &pOutdoor->pBModels[(signed int)stru_721530.uFaceID >> 9]; + pODMFace = &pModel->pFaces[((signed int)stru_721530.uFaceID >> 3) & 0x3F]; + v48 = pODMFace->pBoundingBox.z2 - pODMFace->pBoundingBox.z1; + v129 = v48 <= 32; + v119 = pODMFace->pFacePlane.vNormal.z < 46378; + if ( bUnderwater == 1 ) + v119 = 0; + if ( pODMFace->uPolygonType == POLYGON_Floor ) + { + if ( fall_speed < 0 ) + fall_speed = 0; + pZ = pModel->pVertices.pVertices[pODMFace->pVertexIDs[0]].z + 1; + if ( v2 * v2 + v128 * v128 < 400 ) + { + v2 = 0; + *(float *)&v128 = 0.0; + } + if ( pParty->floor_face_pid != v45 && pODMFace->Pressure_Plate() ) + { + pParty->floor_face_pid = v45; + trigger_id = pODMFace->sCogTriggeredID; + } + } + if ( !v129 && (pODMFace->uPolygonType != POLYGON_InBetweenFloorAndWall || v119) )// упёрся в столб + { + v118 = abs(v128 * pODMFace->pFacePlane.vNormal.y + fall_speed * pODMFace->pFacePlane.vNormal.z + + v2 * pODMFace->pFacePlane.vNormal.x) >> 16; + if ((stru_721530.speed >> 3) > v118 ) + v118 = stru_721530.speed >> 3; + v2 += fixpoint_mul(v118, pODMFace->pFacePlane.vNormal.x); + v128 += fixpoint_mul(v118, pODMFace->pFacePlane.vNormal.y); + v54 = 0; + if ( !v119 ) + v54 = fixpoint_mul(v118, pODMFace->pFacePlane.vNormal.z); + pParty->uFallSpeed += v54; + v55 = stru_721530.prolly_normal_d - ((signed int)(pODMFace->pFacePlane.dist + v122 * pODMFace->pFacePlane.vNormal.z + + _angle_y * pODMFace->pFacePlane.vNormal.y + _angle_x * pODMFace->pFacePlane.vNormal.x) >> 16); + if ( v55 > 0 ) + { + pX = _angle_x + fixpoint_mul(pODMFace->pFacePlane.vNormal.x, v55); + pY = _angle_y + fixpoint_mul(pODMFace->pFacePlane.vNormal.y, v55); + if ( !v119 ) + pZ = v122 + fixpoint_mul(pODMFace->pFacePlane.vNormal.z, v55); + } + if ( pParty->floor_face_pid != stru_721530.uFaceID && pODMFace->Pressure_Plate() ) + { + pParty->floor_face_pid = stru_721530.uFaceID; + trigger_id = pODMFace->sCogTriggeredID; // + } + } + if ( pODMFace->uPolygonType == POLYGON_InBetweenFloorAndWall ) + { + v118 = abs(v128 * pODMFace->pFacePlane.vNormal.y + + fall_speed * pODMFace->pFacePlane.vNormal.z + v2 * pODMFace->pFacePlane.vNormal.x) >> 16; + if ((stru_721530.speed >> 3) > v118 ) + v118 = stru_721530.speed >> 3; + v2 += fixpoint_mul(v118, pODMFace->pFacePlane.vNormal.x); + v128 += fixpoint_mul(v118, pODMFace->pFacePlane.vNormal.y); + fall_speed += fixpoint_mul(v118, pODMFace->pFacePlane.vNormal.z); + if ( v2 * v2 + v128 * v128 >= 400 ) + { + if ( pParty->floor_face_pid != stru_721530.uFaceID && pODMFace->Pressure_Plate() ) + { + pParty->floor_face_pid = stru_721530.uFaceID; + trigger_id = pODMFace->sCogTriggeredID; // + } + } + else + { + v2 = 0; + fall_speed = 0; + *(float *)&v128 = 0.0; + } + } + } + v2 = fixpoint_mul(58500, v2); + v128 = fixpoint_mul(58500, v128); + v122 = fixpoint_mul(58500, v122); + fall_speed = fixpoint_mul(58500, fall_speed); + } + + //Воспроизведение звуков ходьбы/бега------------------------ + uint pX_ = abs(pParty->vPosition.x - pX); + uint pY_ = abs(pParty->vPosition.y - pY); + uint pZ_ = abs(pParty->vPosition.z - pZ); + if ( bWalkSound && pParty->walk_sound_timer <= 0 ) + { + pAudioPlayer->_4AA258(804);//stop sound + if ( party_running_flag && (!hovering || not_high_fall) ) + { + if ( integer_sqrt(pX_ * pX_ + pY_ * pY_ + pZ_ * pZ_) >= 16 ) + { + if ( !is_not_on_bmodel && pOutdoor->pBModels[pParty->floor_face_pid >> 9].pFaces[(pParty->floor_face_pid >> 3) & 0x3F].Visible() ) + pAudioPlayer->PlaySound(SOUND_RunAlong3DModel, 804, 1, -1, 0, 0, 0, 0);//бег на 3D Modelи + else + { + v87 = pOutdoor->GetSoundIdByPosition(WorldPosToGridCellX(pParty->vPosition.x), WorldPosToGridCellZ(pParty->vPosition.y) - 1, 1); + pAudioPlayer->PlaySound((SoundID)v87, 804, 1, -1, 0, 0, 0, 0);//бег по земле 56 + } + pParty->walk_sound_timer = 96;//таймер для бега + } + } + else if( party_walking_flag && (!hovering || not_high_fall) ) + { + if ( integer_sqrt(pX_ * pX_ + pY_ * pY_ + pZ_ * pZ_) >= 8 ) + { + if ( !is_not_on_bmodel && pOutdoor->pBModels[pParty->floor_face_pid >> 9].pFaces[(pParty->floor_face_pid >> 3) & 0x3F].Visible() ) + pAudioPlayer->PlaySound(SOUND_WalkAlong3DModel, 804, 1, -1, 0, 0, 0, 0);// хождение на 3D Modelи + else + { + v87 = pOutdoor->GetSoundIdByPosition(WorldPosToGridCellX(pParty->vPosition.x), WorldPosToGridCellZ(pParty->vPosition.y) - 1, 0); + pAudioPlayer->PlaySound((SoundID)v87, 804, 1, -1, 0, 0, 0, 0);// хождение по земле + } + pParty->walk_sound_timer = 144;//таймер для ходьбы + } + } + } + if ( integer_sqrt(pX_ * pX_ + pY_ * pY_ + pZ_ * pZ_) < 8 )//отключить звук ходьбы при остановке + pAudioPlayer->_4AA258(804); +//------------------------------------------------------------------------ + if ( !hovering || !not_high_fall )// или не высокое падение + pParty->uFlags &= ~PARTY_FLAGS_1_FALLING; + else + pParty->uFlags |= PARTY_FLAGS_1_FALLING; + int pMap_X = WorldPosToGridCellX(pParty->vPosition.x); + int pMap_Y = WorldPosToGridCellZ(pParty->vPosition.y) - 1; + unsigned int v114_a = WorldPosToGridCellX(pX); + v66 = WorldPosToGridCellZ(pY) - 1; + unsigned int v122_a = (~(unsigned int)pOutdoor->ActuallyGetSomeOtherTileInfo(pMap_X, pMap_Y) / 2) & 1; + v122 = (~(unsigned int)pOutdoor->ActuallyGetSomeOtherTileInfo(v114_a, pMap_Y) / 2) & 1; + v69 = (~(unsigned int)pOutdoor->ActuallyGetSomeOtherTileInfo(pMap_X, v66) / 2) & 1; + + //-(обновление координат группы)--------------------------------------- + v68 = 0; + if ( v114_a == pMap_X && v66 == pMap_Y && v122 && v69 ) + v68 = 1; + if ( !is_not_on_bmodel ) // на bmodel,и + v68 = 1; + if ( v68 ) + { + pParty->vPosition.x = pX; + pParty->vPosition.y = pY; + pParty->vPosition.z = pZ; + pParty->field_6F0 = v113; + pParty->uFallSpeed = fall_speed; + if ( pZ > 8160 ) //ограничение высоты + { + pZ = 8160; + pParty->uFallStartY = 8160; + pParty->vPosition.z = 8160; + } + + if ( !trigger_id //падение на землю + || (EventProcessor(trigger_id, 0, 1), + pParty->vPosition.x == pX) + && pParty->vPosition.y == pY + && pParty->vPosition.z == pZ ) + { + if ( pParty->vPosition.z < v111 ) + { + pParty->uFallSpeed = 0; + //v73 = v105; + pParty->vPosition.z = on_ground; + if ( pParty->uFallStartY - pZ > 512 && !bFeatherFall && pZ <= on_ground && !bUnderwater )//Fall to the ground(падение на землю с высоты) + { + if ( pParty->uFlags & PARTY_FLAGS_1_LANDING ) + pParty->uFlags &= ~PARTY_FLAGS_1_LANDING; + else + { + for ( uint i = 1; i <= 4; ++i ) + { + pPlayers[i]->ReceiveDamage((signed int)((pParty->uFallStartY - pZ) * (unsigned __int64)(signed __int64)((double)pPlayers[i]->GetMaxHealth() * 0.1)) / 256, + DMGT_PHISYCAL); + v110 = 20 - pPlayers[i]->GetParameterBonus(pPlayers[i]->GetActualEndurance()); + pPlayers[i]->SetRecoveryTime((signed __int64)((double)v110 * flt_6BE3A4_debug_recmod1 * 2.133333333333333)); + } + //v73 = pParty->vPosition.z; + } + } + pParty->uFallStartY = pZ; + } + if ( v102 && pParty->vPosition.z < ceiling_height ) + { + if ( (signed int)(pParty->uPartyHeight + pParty->vPosition.z) >= ceiling_height ) + { + pParty->vPosition.z = ceiling_height - pParty->uPartyHeight - 1; + pParty->field_6F0 = ceiling_height - pParty->uPartyHeight - 1; + } + } + pParty->uFlags &= ~0x204; + } + return; + } +//----------------------------------------------------------------- + //v76 = pParty->bFlying; + if ( pParty->bFlying || !not_high_fall || bWaterWalk || !v122_a )// полёт или высокое падение или хождение по воде или + v77 = 1; + else + v77 = v122 != 0; + bool party_drowning_flag = false; + if ( !pParty->bFlying && not_high_fall && !bWaterWalk ) //не полёт и не высокое падение и не хождение по воде + { + if ( v122_a ) + v78 = v69 != 0; + else + { + party_drowning_flag = true;//утопление + v78 = true; + } + } + else + v78 = true; + + if ( v77 ) + pParty->vPosition.x = pX; + if ( v78 ) + pParty->vPosition.y = pY; + + if ( v78 || v77) + { + if ( bWaterWalk ) + { + pParty->uFlags &= ~PARTY_FLAGS_1_STANDING_ON_WATER; + //v79 = 20 * pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uOverlayID + 6180178; + //*(short *)&stru_5E4C90._decor_events[20 * pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uOverlayID + 119] |= 1u; + v79 = (int)&stru_5E4C90_MapPersistVars._decor_events[20 * pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uOverlayID + 119]; + *(short *)v79 |= 1; + if ( !v122 || !v69 ) + { + if ( !pParty->bFlying ) + { + v80 = *(short *)v79; + pParty->uFlags |= PARTY_FLAGS_1_STANDING_ON_WATER; + *(short *)v79 = v80 & 0xFFFE; + } + } + } + } + else if ( bWalkSound && pParty->walk_sound_timer <= 0 ) + { + pAudioPlayer->_4AA258(804); + pParty->walk_sound_timer = 64; + } + + //v81 = pZ; + //v82 = pZ; + pParty->vPosition.z = pZ; + if ( pZ > 8160 )//опять ограничение высоты + { + //v82 = 8160; + pParty->uFallStartY = 8160; + pParty->vPosition.z = 8160; + } + LOWORD(pParty->uFlags) &= 0xFDFBu; + pParty->uFallSpeed = fall_speed; + pParty->field_6F0 = v113; + if ( party_drowning_flag )//группа тонет + { + pTerrainHeight = GetTerrainHeightsAroundParty2(pParty->vPosition.x, pParty->vPosition.y, &v110, 1); + if ( pParty->vPosition.z <= pTerrainHeight + 1 )//положение группы всегда +1 + pParty->uFlags |= PARTY_FLAGS_1_WATER_DAMAGE; + } + + if ( !trigger_id//падение на воду + || (EventProcessor(trigger_id, 0, 1), + pParty->vPosition.x == pX) + && pParty->vPosition.y == pY + && pParty->vPosition.z == pZ ) + { + if ( pParty->vPosition.z < v111 ) + { + //v82 = on_ground; + pParty->uFallSpeed = 0; + pParty->vPosition.z = on_ground; + if ( pParty->uFallStartY - pZ > 512 && !bFeatherFall && pZ <= on_ground && !bUnderwater )//Fall to the water(падение на воду с высоты) + { + if ( pParty->uFlags & PARTY_FLAGS_1_LANDING ) + pParty->uFlags &= ~PARTY_FLAGS_1_LANDING; + else + { + for ( uint i = 1; i <= 4; ++i ) + { + v110 = pPlayers[i]->GetMaxHealth(); + pPlayers[i]->ReceiveDamage((signed int)((pParty->uFallStartY - pZ) * (unsigned __int64)(signed __int64)((double)v110 * 0.1)) / 256, + DMGT_PHISYCAL); + v110 = 20 - pPlayers[i]->GetParameterBonus(pPlayers[i]->GetActualEndurance()); + pPlayers[i]->SetRecoveryTime((signed __int64)((double)v110 * flt_6BE3A4_debug_recmod1 * 2.133333333333333)); + } + //v82 = pParty->vPosition.z; + } + } + pParty->uFallStartY = pZ; + } + if ( v102 && pParty->vPosition.z < ceiling_height && (signed int)(pParty->uPartyHeight + pParty->vPosition.z) >= ceiling_height ) + { + pParty->vPosition.z = pParty->vPosition.z + pParty->uPartyHeight - ceiling_height + 1; + pParty->field_6F0 = pParty->vPosition.z + pParty->uPartyHeight - ceiling_height + 1; + } + } +} + +//----- (0046D8E3) -------------------------------------------------------- +int GetCeilingHeight(int Party_X, signed int Party_Y, int Party_ZHeight, int pFaceID) +{ + signed int v13; // eax@25 + int v14; // edx@27 + int v16; // ST18_4@29 + signed int v17; // edx@29 + signed __int64 v18; // qtt@29 + int v19; // eax@35 + signed int v20; // ecx@37 + signed int v22; // ebx@42 +// int v24; // edx@44 +// int v25; // eax@44 + int v27; // [sp+10h] [bp-34h]@21 + bool v34; // [sp+30h] [bp-14h]@21 + bool v35; // [sp+34h] [bp-10h]@23 + signed int v37; // [sp+38h] [bp-Ch]@21 + signed int v38; // [sp+38h] [bp-Ch]@42 + signed int v39; // [sp+3Ch] [bp-8h]@1 + + dword_720ED0[0] = -1; + dword_720E80[0] = -1; + v39 = 1; + ceiling_height_level[0] = 10000;//нет потолка + for ( uint i = 0; i < (signed int)pOutdoor->uNumBModels; ++i ) + { + if ( Party_X <= pOutdoor->pBModels[i].sMaxX && Party_X >= pOutdoor->pBModels[i].sMinX + && Party_Y <= pOutdoor->pBModels[i].sMaxY && Party_Y >= pOutdoor->pBModels[i].sMinY ) + { + for ( uint j = 0; j < pOutdoor->pBModels[i].uNumFaces; ++j ) + { + if ( (pOutdoor->pBModels[i].pFaces[j].uPolygonType == POLYGON_Ceiling + || pOutdoor->pBModels[i].pFaces[j].uPolygonType == POLYGON_InBetweenCeilingAndWall) + && !pOutdoor->pBModels[i].pFaces[j].Ethereal() + && Party_X <= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.x2 && Party_X >= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.x1 + && Party_Y <= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.y2 && Party_Y >= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.y1 ) + { + for ( uint v = 0; v < pOutdoor->pBModels[i].pFaces[j].uNumVertices; v++ ) + { + word_720DB0_xs[2 * v] = pOutdoor->pBModels[i].pFaces[j].pXInterceptDisplacements[v] + LOWORD(pOutdoor->pBModels[i].pVertices.pVertices[pOutdoor->pBModels[i].pFaces[j].pVertexIDs[v]].x); + word_720CE0_ys[2 * v] = pOutdoor->pBModels[i].pFaces[j].pXInterceptDisplacements[v] + LOWORD(pOutdoor->pBModels[i].pVertices.pVertices[pOutdoor->pBModels[i].pFaces[j].pVertexIDs[v]].y); + word_720DB0_xs[2 * v + 1] = pOutdoor->pBModels[i].pFaces[j].pXInterceptDisplacements[v] + LOWORD(pOutdoor->pBModels[i].pVertices.pVertices[pOutdoor->pBModels[i].pFaces[j].pVertexIDs[v + 1]].x); + word_720CE0_ys[2 * v + 1] = pOutdoor->pBModels[i].pFaces[j].pXInterceptDisplacements[v] + LOWORD(pOutdoor->pBModels[i].pVertices.pVertices[pOutdoor->pBModels[i].pFaces[j].pVertexIDs[v + 1]].y); + } + v27 = 2 * pOutdoor->pBModels[i].pFaces[j].uNumVertices; + word_720DB0_xs[2 * pOutdoor->pBModels[i].pFaces[j].uNumVertices] = word_720DB0_xs[0]; + word_720CE0_ys[2 * pOutdoor->pBModels[i].pFaces[j].uNumVertices] = word_720CE0_ys[0]; + v34 = word_720CE0_ys[0] >= Party_Y; + v37 = 0; + for ( uint v = 0; v < v27; ++v ) + { + if ( v37 >= 2 ) + break; + v35 = word_720CE0_ys[v + 1] >= Party_Y; + if ( v34 != v35 ) + { + v13 = word_720DB0_xs[v + 1] >= Party_X ? 0 : 2; + v14 = v13 | (word_720DB0_xs[v] < Party_X); + if ( v14 != 3 ) + { + if ( !v14 || ( v16 = word_720CE0_ys[v + 1] - word_720CE0_ys[v], + v17 = Party_Y - word_720CE0_ys[v], + LODWORD(v18) = v17 << 16, + HIDWORD(v18) = v17 >> 16, + (signed int)(((unsigned __int64)(((signed int)word_720DB0_xs[v + 1] + - (signed int)word_720DB0_xs[v]) * v18 / v16) >> 16) + word_720DB0_xs[v]) >= Party_X) ) + ++v37; + } + } + v34 = v35; + } + if ( v37 == 1 ) + { + if ( v39 >= 20 ) + break; + if ( pOutdoor->pBModels[i].pFaces[j].uPolygonType == POLYGON_Ceiling ) + v19 = pOutdoor->pBModels[i].pVertices.pVertices[pOutdoor->pBModels[i].pFaces[j].pVertexIDs[0]].z; + else + v19 = fixpoint_mul(pOutdoor->pBModels[i].pFaces[j].zCalc1, Party_X) + fixpoint_mul(pOutdoor->pBModels[i].pFaces[j].zCalc2, Party_Y) + + HIWORD(pOutdoor->pBModels[i].pFaces[j].zCalc3); + v20 = v39++; + ceiling_height_level[v20] = v19; + dword_720ED0[v20] = i; + dword_720E80[v20] = j; + } + } + } + } + } + if ( !v39 ) + { + pFaceID = 0; + return ceiling_height_level[0]; + } + v22 = 0; + for ( v38 = 0; v38 < v39; ++v38 ) + { + if ( ceiling_height_level[v38] == ceiling_height_level[0] ) + v22 = v38; + else if ( ceiling_height_level[v38] < ceiling_height_level[0] && ceiling_height_level[0] > Party_ZHeight + 15 ) + v22 = v38; + else if ( ceiling_height_level[v38] > ceiling_height_level[0] && ceiling_height_level[v38] <= Party_ZHeight + 15 ) + v22 = v38; + } + if ( v22 ) + { + *(int *)pFaceID = dword_720E80[v22] | (dword_720ED0[v22] << 6); + return ceiling_height_level[v22];//если есть преграда + } + pFaceID = 0; + return ceiling_height_level[v22];// нет никакой преграды +} + + +//----- (00464839) -------------------------------------------------------- +char Is_out15odm_underwater() +{ + return _stricmp(pCurrentMapName, "out15.odm") == 0; +} + +//----- (00464851) -------------------------------------------------------- +void SetUnderwaterFog() +{ + day_fogrange_1 = 50; + day_fogrange_2 = 5000; +} + +//----- (00487DA9) -------------------------------------------------------- +void sub_487DA9() +{ + for (int i = 0; i < 20000; ++i) + array_77EC08[i].field_108 = 0; +} + +//----- (004706C6) -------------------------------------------------------- +void UpdateActors_ODM() +{ + int v3; // ebx@6 + int v5; // eax@10 + //int v6; // ecx@10 + signed int v8; // ebx@17 + // unsigned __int8 v10; // sf@17 + // unsigned __int16 v11; // ax@21 + __int16 v20; // ax@42 + int v25; // eax@45 + signed int v26; // ecx@50 + int v28; // eax@54 + signed int v29; // ebx@57 + signed int v30; // eax@57 + int v31; // edi@57 + signed int i; // ebx@57 + unsigned int v33; // ecx@58 + int v35; // edi@64 + int v36; // eax@64 + unsigned int v39; // edi@71 + ODMFace *face; // edi@75 + int v46; // ecx@82 + signed int v47; // ebx@85 + int v48; // edi@85 + // int v55; // eax@107 + // unsigned int v56; // edi@107 + // int v57; // ST10_4@107 + unsigned int v58; // edi@107 + unsigned int v59; // ebx@107 + // signed int v60; // eax@107 + int v61; // eax@124 + Vec3_int_ v62; // [sp+Ch] [bp-44h]@42 + int v63; // [sp+18h] [bp-38h]@64 + int v64; // [sp+1Ch] [bp-34h]@64 + bool v67; // [sp+28h] [bp-28h]@10 + unsigned int v69; // [sp+30h] [bp-20h]@6 + unsigned int v70; // [sp+34h] [bp-1Ch]@10 + int v71; // [sp+38h] [bp-18h]@62 + int uIsAboveFloor; // [sp+3Ch] [bp-14h]@10 + int v72b; + int uIsFlying; // [sp+44h] [bp-Ch]@8 + unsigned int v75; // [sp+48h] [bp-8h]@1 + int uIsOnWater; // [sp+4Ch] [bp-4h]@10 + + for (v75 = 0; v75 < uNumActors; ++v75) + { + if (pActors[v75].uAIState == Removed + || pActors[v75].uAIState == Disabled + || pActors[v75].uAIState == Summoned + || !pActors[v75].uMovementSpeed) + continue; + v3 = 0; + v69 = 0; + if (MonsterStats::BelongsToSupertype(pActors[v75].pMonsterInfo.uID, MONSTER_SUPERTYPE_WATER_ELEMENTAL)) + v3 = 1; + pActors[v75].uSectorID = 0; + uIsFlying = pActors[v75].pMonsterInfo.uFlying; + if (!pActors[v75].CanAct()) + uIsFlying = 0; + v70 = IsTerrainSlopeTooHigh(pActors[v75].vPosition.x, pActors[v75].vPosition.y); + v5 = ODM_GetFloorLevel(pActors[v75].vPosition.x, pActors[v75].vPosition.y, pActors[v75].vPosition.z, + pActors[v75].uActorHeight, &uIsOnWater, (int *)&v69, v3); + //v6 = pActors[v75].vPosition.z; + uIsAboveFloor = 0; + v67 = v69 == 0; + if (pActors[v75].vPosition.z > v5 + 1) + uIsAboveFloor = 1; + if (pActors[v75].uAIState == Dead && uIsOnWater && !uIsAboveFloor) + { + pActors[v75].uAIState = Removed; + continue; + } + if (pActors[v75].uCurrentActionAnimation == ANIM_Walking) + { + v8 = pActors[v75].uMovementSpeed; + if ((signed __int64)pActors[v75].pActorBuffs[ACTOR_BUFF_SLOWED].uExpireTime > 0) + v8 = (signed __int64)((double)v8 * 0.5); + if (pActors[v75].uAIState == Fleeing || pActors[v75].uAIState == Pursuing) + v8 *= 2; + if (pParty->bTurnBasedModeOn == true && pTurnEngine->turn_stage == TE_WAIT) + v8 *= flt_6BE3AC_debug_recmod1_x_1_6; + if (v8 > 1000) + v8 = 1000; + + pActors[v75].vVelocity.x = fixpoint_mul(stru_5C6E00->Cos(pActors[v75].uYawAngle), v8); + pActors[v75].vVelocity.y = fixpoint_mul(stru_5C6E00->Sin(pActors[v75].uYawAngle), v8); + if (uIsFlying) + { + pActors[v75].vVelocity.z = fixpoint_mul(stru_5C6E00->Sin(pActors[v75].uPitchAngle), v8); + } + //v7 = v68; + } + else + { + pActors[v75].vVelocity.x = fixpoint_mul(55000, pActors[v75].vVelocity.x); + pActors[v75].vVelocity.y = fixpoint_mul(55000, pActors[v75].vVelocity.y); + if (uIsFlying) + pActors[v75].vVelocity.z = fixpoint_mul(55000, pActors[v75].vVelocity.z); + } + if (pActors[v75].vPosition.z < v5) + { + pActors[v75].vPosition.z = v5; + pActors[v75].vVelocity.z = uIsFlying != 0 ? 0x14 : 0; + } + //v17 = 0; + if (!uIsAboveFloor || uIsFlying) + { + if (v70 && !uIsAboveFloor && v67) + { + pActors[v75].vPosition.z = v5; + ODM_GetTerrainNormalAt(pActors[v75].vPosition.x, pActors[v75].vPosition.y, &v62); + v20 = GetGravityStrength(); + //v21 = v62.y; + //v22 = v62.z; + //v23 = v62.y * v0->vVelocity.y; + pActors[v75].vVelocity.z += -8 * LOWORD(pEventTimer->uTimeElapsed) * v20; + int v73 = abs(v62.x * pActors[v75].vVelocity.x + v62.z * pActors[v75].vVelocity.z + v62.y * pActors[v75].vVelocity.y) >> 16; + //v72b = v21; + pActors[v75].vVelocity.x += fixpoint_mul(v73, v62.x); + pActors[v75].vVelocity.y += fixpoint_mul(v73, v62.y); + pActors[v75].vVelocity.z += fixpoint_mul(v73, v62.z); + //v17 = 0; + } + } + else + { + pActors[v75].vVelocity.z -= LOWORD(pEventTimer->uTimeElapsed) * GetGravityStrength(); + } + if (pParty->armageddon_timer != 0 && pActors[v75].CanAct()) + { + pActors[v75].vVelocity.x += rand() % 100 - 50; + pActors[v75].vVelocity.y += rand() % 100 - 50; + pActors[v75].vVelocity.z += rand() % 100 - 20; + v25 = rand(); + pActors[v75].uAIState = Stunned; + pActors[v75].uYawAngle += v25 % 32 - 16; + pActors[v75].UpdateAnimation(); + } + if (pActors[v75].vVelocity.x * pActors[v75].vVelocity.x + pActors[v75].vVelocity.y * pActors[v75].vVelocity.y < 400 && v70 == 0) + { + pActors[v75].vVelocity.y = 0; + pActors[v75].vVelocity.x = 0; + } + stru_721530.field_0 = 1; + if (!uIsFlying) + v26 = 40; + else + v26 = pActors[v75].uActorRadius; + + stru_721530.field_84 = -1; + stru_721530.field_8_radius = v26; + stru_721530.prolly_normal_d = v26; + stru_721530.height = pActors[v75].uActorHeight; + stru_721530.field_70 = 0; + + for (v69 = 0; v69 < 100; ++v69) + { + stru_721530.position.x = pActors[v75].vPosition.x; + stru_721530.normal.x = stru_721530.position.x; + stru_721530.position.y = pActors[v75].vPosition.y; + stru_721530.normal.y = stru_721530.position.y; + v28 = pActors[v75].vPosition.z; + stru_721530.normal.z = v28 + v26 + 1; + stru_721530.position.z = v28 - v26 + stru_721530.height - 1; + if (stru_721530.position.z < stru_721530.normal.z) + stru_721530.position.z = v28 + v26 + 1; + stru_721530.velocity.x = pActors[v75].vVelocity.x; + stru_721530.uSectorID = 0; + stru_721530.velocity.y = pActors[v75].vVelocity.y; + stru_721530.velocity.z = pActors[v75].vVelocity.z; + if (stru_721530._47050A(0)) + break; + _46E889_collide_against_bmodels(1); + v29 = WorldPosToGridCellZ(pActors[v75].vPosition.y); + v30 = WorldPosToGridCellX(pActors[v75].vPosition.x); + _46E26D_collide_against_sprites(v30, v29); + _46EF01_collision_chech_player(0); + _46ED8A_collide_against_sprite_objects(PID(OBJECT_Actor, v75)); + v31 = 0; + for (i = 0; v31 < ai_arrays_size; ++v31) + { + v33 = ai_near_actors_ids[v31]; + if (v33 != v75 && Actor::_46DF1A_collide_against_actor(v33, 40)) + ++i; + } + v71 = i > 1; + if (stru_721530.field_7C < stru_721530.field_6C) + v70 = fixpoint_mul(stru_721530.field_7C, stru_721530.direction.z); + //v34 = 0; + v35 = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1; + v36 = ODM_GetFloorLevel(stru_721530.normal2.x, stru_721530.normal2.y, + stru_721530.normal2.z - stru_721530.prolly_normal_d - 1, + pActors[v75].uActorHeight, (int *)&v63, &v64, 0); + if (uIsOnWater) + { + if (v35 < v36 + 60) + { + if (pActors[v75].uAIState == Dead || pActors[v75].uAIState == Dying || pActors[v75].uAIState == Removed + || pActors[v75].uAIState == Disabled) + { + if (v64) + v61 = v36 + 30; + else + v61 = v5 + 60; + SpriteObject::sub_42F960_create_object(pActors[v75].vPosition.x, pActors[v75].vPosition.y, v61); + pActors[v75].uAIState = Removed; + return; + } + } + } + if (stru_721530.field_7C >= stru_721530.field_6C) + { + pActors[v75].vPosition.x = LOWORD(stru_721530.normal2.x); + pActors[v75].vPosition.y = LOWORD(stru_721530.normal2.y); + pActors[v75].vPosition.z = LOWORD(stru_721530.normal2.z) - LOWORD(stru_721530.prolly_normal_d) - 1; + break; + } + //v72b = fixpoint_mul(stru_721530.field_7C, stru_721530.field_58.x); + pActors[v75].vPosition.x += fixpoint_mul(stru_721530.field_7C, stru_721530.direction.x); + //v72b = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.y) >> 16; + pActors[v75].vPosition.y += fixpoint_mul(stru_721530.field_7C, stru_721530.direction.y); + //v72b = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.z) >> 16; + pActors[v75].vPosition.z += fixpoint_mul(stru_721530.field_7C, stru_721530.direction.z); + stru_721530.field_70 += stru_721530.field_7C; + v39 = PID_ID(stru_721530.uFaceID); + switch (PID_TYPE(stru_721530.uFaceID)) + { + case OBJECT_Actor: + if (pTurnEngine->turn_stage != TE_ATTACK && pTurnEngine->turn_stage != TE_MOVEMENT || pParty->bTurnBasedModeOn != TE_WAIT) + { + //if(pParty->bTurnBasedModeOn == 1) + //v34 = 0; + if (pActors[v75].pMonsterInfo.uHostilityType) + { + if (v71 == 0) + Actor::AI_Flee(v75, stru_721530.uFaceID, 0, (AIDirection *)0); + else + Actor::AI_StandOrBored(v75, 4, 0, (AIDirection *)0); + } + else if (v71) + Actor::AI_StandOrBored(v75, 4, 0, (AIDirection *)0); + else if (pActors[v39].pMonsterInfo.uHostilityType == MonsterInfo::Hostility_Friendly) + Actor::AI_Flee(v75, stru_721530.uFaceID, 0, (AIDirection *)0); + else + Actor::AI_FaceObject(v75, stru_721530.uFaceID, 0, (AIDirection *)0); + } + break; + case OBJECT_Player: + if (!pActors[v75].GetActorsRelation(0)) + { + Actor::AI_FaceObject(v75, stru_721530.uFaceID, 0, (AIDirection *)0); + break; + } + //v52 = HIDWORD(pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime) == 0; + //v53 = SHIDWORD(pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime) < 0; + pActors[v75].vVelocity.y = 0; + pActors[v75].vVelocity.x = 0; + //if ( !v53 && (!(v53 | v52) || LODWORD(pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime) > 0) ) + if ((signed __int64)pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime < 0) + pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].Reset(); + viewparams->bRedrawGameUI = 1; + break; + case OBJECT_Decoration: + v47 = integer_sqrt(pActors[v75].vVelocity.x * pActors[v75].vVelocity.x + pActors[v75].vVelocity.y * pActors[v75].vVelocity.y); + v48 = stru_5C6E00->Atan2(pActors[v75].vPosition.x - pLevelDecorations[v39].vPosition.x, + pActors[v75].vPosition.y - pLevelDecorations[v39].vPosition.y); + //v49 = v48; + pActors[v75].vVelocity.x = fixpoint_mul(stru_5C6E00->Cos(v48), v47); + pActors[v75].vVelocity.y = fixpoint_mul(stru_5C6E00->Sin(v48), v47); + break; + case OBJECT_BModel: + face = &pOutdoor->pBModels[stru_721530.uFaceID >> 9].pFaces[v39 & 0x3F]; + if (!face->Ethereal()) + { + if (face->uPolygonType == 3) + { + pActors[v75].vVelocity.z = 0; + pActors[v75].vPosition.z = LOWORD(pOutdoor->pBModels[stru_721530.uFaceID >> 9].pVertices.pVertices[face->pVertexIDs[0]].z) + 1; + if (pActors[v75].vVelocity.x * pActors[v75].vVelocity.x + + pActors[v75].vVelocity.y * pActors[v75].vVelocity.y < 400) + { + pActors[v75].vVelocity.y = 0; + pActors[v75].vVelocity.x = 0; + } + } + else + { + v72b = abs(face->pFacePlane.vNormal.y * pActors[v75].vVelocity.y + face->pFacePlane.vNormal.z * pActors[v75].vVelocity.z + + face->pFacePlane.vNormal.x * pActors[v75].vVelocity.x) >> 16; + if ((stru_721530.speed >> 3) > v72b) + v72b = stru_721530.speed >> 3; + + pActors[v75].vVelocity.x += fixpoint_mul(v72b, face->pFacePlane.vNormal.x); + pActors[v75].vVelocity.y += fixpoint_mul(v72b, face->pFacePlane.vNormal.y); + pActors[v75].vVelocity.z += fixpoint_mul(v72b, face->pFacePlane.vNormal.z); + if (face->uPolygonType != 4) + { + v46 = stru_721530.prolly_normal_d + - ((face->pFacePlane.dist + + face->pFacePlane.vNormal.x * pActors[v75].vPosition.x + + face->pFacePlane.vNormal.y * pActors[v75].vPosition.y + + face->pFacePlane.vNormal.z * pActors[v75].vPosition.z) >> 16); + if (v46 > 0) + { + pActors[v75].vPosition.x += fixpoint_mul(v46, face->pFacePlane.vNormal.x); + pActors[v75].vPosition.y += fixpoint_mul(v46, face->pFacePlane.vNormal.y); + pActors[v75].vPosition.z += fixpoint_mul(v46, face->pFacePlane.vNormal.z); + } + pActors[v75].uYawAngle = stru_5C6E00->Atan2(pActors[v75].vVelocity.x, pActors[v75].vVelocity.y); + } + } + } + break; + } + + pActors[v75].vVelocity.x = fixpoint_mul(58500, pActors[v75].vVelocity.x); + pActors[v75].vVelocity.y = fixpoint_mul(58500, pActors[v75].vVelocity.y); + pActors[v75].vVelocity.z = fixpoint_mul(58500, pActors[v75].vVelocity.z); + + v26 = stru_721530.prolly_normal_d; + } + + v58 = ((unsigned int)~pOutdoor->ActuallyGetSomeOtherTileInfo(WorldPosToGridCellX(pActors[v75].vPosition.x), WorldPosToGridCellZ(pActors[v75].vPosition.y) - 1) >> 1) & 1; + v59 = ((unsigned int)~pOutdoor->ActuallyGetSomeOtherTileInfo(WorldPosToGridCellX(pActors[v75].vPosition.x), WorldPosToGridCellZ(pActors[v75].vPosition.y) - 1) >> 1) & 1; + if (WorldPosToGridCellX(pActors[v75].vPosition.x) == WorldPosToGridCellX(pActors[v75].vPosition.x) + && WorldPosToGridCellZ(pActors[v75].vPosition.y) == WorldPosToGridCellZ(pActors[v75].vPosition.y) + && v58 || v67 != 0) + { + if (MonsterStats::BelongsToSupertype(pActors[v75].pMonsterInfo.uID, MONSTER_SUPERTYPE_WATER_ELEMENTAL)) + { + v58 = v58 == 0; + v59 = v59 == 0; + } + if (!uIsFlying && v58 && !v59) + { + pActors[v75].vPosition.x = pActors[v75].vPosition.x; + pActors[v75].vPosition.y = pActors[v75].vPosition.y; + if (pActors[v75].CanAct()) + { + pActors[v75].uYawAngle -= 32; + pActors[v75].uCurrentActionTime = 0; + pActors[v75].uCurrentActionLength = 128; + pActors[v75].uAIState = Fleeing; + } + } + } + } +} + +//----- (0047A384) -------------------------------------------------------- +void ODM_LoadAndInitialize(const char *pLevelFilename, ODMRenderParams *thisa) +{ + int v2; // ebx@3 + unsigned int v3; // eax@3 + MapInfo *v4; // edi@4 + //int v5; // eax@8 + //SpawnPointMM7 *v6; // edx@14 + size_t v7; // eax@19 + //char *v8; // eax@19 + //char *v9; // eax@21 + char Source[120]; // [sp+Ch] [bp-84h]@19 + const char *pFilename; // [sp+84h] [bp-Ch]@1 + //unsigned int v12; // [sp+88h] [bp-8h]@12 + //int v13; // [sp+8Ch] [bp-4h]@11 + int v; + + pFilename = pLevelFilename; + //thisa->AllocSoftwareDrawBuffers(); + pODMRenderParams->Initialize(); + pWeather->bRenderSnow = false; + pRenderer->ClearZBuffer(0, 479); + //thisa = (ODMRenderParams *)1; + GetAlertStatus(); + if (_A750D8_player_speech_timer) + _A750D8_player_speech_timer = 0; + v2 = pMapStats->GetMapInfo(pCurrentMapName); + v3 = 0; + if (v2) + { + v4 = &pMapStats->pInfos[v2]; + v3 = v4->uRespawnIntervalDays; + } + else + v4 = (MapInfo *)1; + day_attrib &= ~DAY_ATTRIB_FOG; + dword_6BE13C_uCurrentlyLoadedLocationID = v2; + pOutdoor->Initialize( + pFilename, + (unsigned int)(signed __int64)((double)(signed __int64)pParty->uTimePlayed * 0.234375) / 0x3C / 0x3C / 0x18 + 1, + v3, + &v); + if (!(dword_6BE364_game_settings_1 & GAME_SETTINGS_2000)) + { + Actor::InitializeActors(); + SpriteObject::InitializeSpriteObjects(); + } + dword_6BE364_game_settings_1 &= ~GAME_SETTINGS_2000; + //v5 = 0; + if (!v2) + v = 0; + if (v == 1) + { + //v13 = 0; + for (uint i = 0; i < pOutdoor->uNumSpawnPoints; ++i) + { + //v12 = 0; + //while ( 1 ) + //{ + SpawnPointMM7* spawn = pOutdoor->pSpawnPoints + i; + //v6 = &pOutdoor->pSpawnPoints[v12 / 0x18]; + if (spawn->uKind == 3) + SpawnEncounter(v4, spawn, 0, 0, 0); + else + v4->SpawnRandomTreasure(spawn); + //++v13; + //v12 += 24; + //if ( v13 >= (signed int)pOutdoor->uNumSpawnPoints ) + // break; + //v5 = 0; + //} + } + RespawnGlobalDecorations(); + } + pOutdoor->PrepareDecorations(); + pOutdoor->ArrangeSpriteObjects(); + pOutdoor->InitalizeActors(v2); + pOutdoor->MessWithLUN(); + v7 = strlen("levels\\"); + strcpy(Source, &pFilename[v7]); + strcpy(pOutdoor->pLevelFilename, Source); + pWeather->Initialize(); + pGame->pIndoorCameraD3D->sRotationY = pParty->sRotationY; + pGame->pIndoorCameraD3D->sRotationX = pParty->sRotationX; + //pODMRenderParams->RotationToInts(); + pOutdoor->UpdateSunlightVectors(); + + float fov_rad; + float fov_rad_inv; + //----- (0042394D) -------------------------------------------------------- + //void IndoorCamera::Initialize(int degFov, unsigned int uViewportWidth, unsigned int uViewportHeight) + { + //pIndoorCamera->Initialize(65, viewparams->uScreen_BttmR_X - viewparams->uScreen_topL_X + 1, + // viewparams->uScreen_BttmR_Y - viewparams->uScreen_topL_Y + 1); + + int uViewportWidth = viewparams->uScreen_BttmR_X - viewparams->uScreen_topL_X + 1; + + extern float _calc_fov(int viewport_width, int angle_degree); + fov_rad = _calc_fov(uViewportWidth, 65); + fov_rad_inv = 65536.0 / fov_rad; + } + pODMRenderParams->int_fov_rad = (signed __int64)fov_rad; + pODMRenderParams->int_fov_rad_inv = (signed __int64)fov_rad_inv; + + for (int i = 0; i < 20000; ++i) + { + array_77EC08[i].ptr_38 = &stru_8019C8; + + array_77EC08[i].ptr_48 = nullptr; + } + + MM7Initialization(); +} + +//----- (0047C370) -------------------------------------------------------- +unsigned int GetLevelFogColor() +{ + signed __int64 v1; // qax@5 + int v2; // eax@6 + + if (bUnderwater) + return 0xFF258F5C; + + if (day_attrib & DAY_ATTRIB_FOG) + { + if (pWeather->bNight) // night-time fog + { + if (for_refactoring) + { + MessageBoxA(nullptr, "Nomad: decompilation can be inaccurate, please send savegame to Nomad", "", 0); + __debugbreak(); + } + v2 = -(pWeather->bNight != 1); + return (v2 & 0xE0E0E1) - 0xE0E0E1; + } + else + { + v1 = (signed __int64)((1.0 - pOutdoor->fFogDensity) * 200.0 + pOutdoor->fFogDensity * 31.0); + return v1 | (((unsigned int)v1 | (((unsigned int)v1 | 0xFFFFFF00) << 8)) << 8); + } + } + + return 0; +} + +//----- (0047C3D7) -------------------------------------------------------- +int __fastcall sub_47C3D7_get_fog_specular(int a1, int a2, float a3) +{ + int v3; // ecx@1 + signed int v7; // ecx@11 + + v3 = pWeather->bNight; + if (bUnderwater == 1) + v3 = 0; + if (pParty->armageddon_timer || !(day_attrib & DAY_ATTRIB_FOG) && !bUnderwater) + return 0xFF000000; + if (v3) + { + if (a3 < (double)day_fogrange_1) + { + v7 = 0; + if (a3 == 0.0) + v7 = 216; + if (a2) + v7 = 248; + return (-1 - v7) << 24; + } + else + { + if (a3 > (double)day_fogrange_2) + { + v7 = 216; + if (a3 == 0.0) + v7 = 216; + if (a2) + v7 = 248; + return (-1 - v7) << 24; + } + v7 = (signed __int64)((a3 - (double)day_fogrange_1) / ((double)day_fogrange_2 - (double)day_fogrange_1) * 216.0); + } + } + else + { + if (a3 < (double)day_fogrange_1) + { + v7 = 0; + if (a3 == 0.0) + v7 = 216; + if (a2) + v7 = 248; + return (-1 - v7) << 24; + } + else + { + if (a3 > (double)day_fogrange_2) + { + v7 = 216; + if (a3 == 0.0) + v7 = 216; + if (a2) + v7 = 248; + return (-1 - v7) << 24; + } + else + v7 = floorf(((a3 - (double)day_fogrange_1) * 216.0 / ((double)day_fogrange_2 - (double)day_fogrange_1)) + 0.5f); + } + } + if (v7 > 216) + v7 = 216; + else + { + if (a3 == 0.0) + v7 = 216; + } + if (a2) + v7 = 248; + return (-1 - v7) << 24; +} + + +//----- (0047F44B) -------------------------------------------------------- +unsigned int WorldPosToGridCellX(int sWorldPosX) +{ + return (sWorldPosX >> 9) + 64; // sar is in original exe, resulting -880 / 512 = -1 + // and -880 sar 9 = -2 +} + +//----- (0047F458) -------------------------------------------------------- +unsigned int WorldPosToGridCellZ(int sWorldPosZ) +{ + return 64 - (sWorldPosZ >> 9); // sar is in original exe, resulting -880 / 512 = -1 + // and -880 sar 9 = -2 +} + +//----- (0047F469) -------------------------------------------------------- +int GridCellToWorldPosX(int a1) +{ + return (a1 - 64) << 9; +} + +//----- (0047F476) -------------------------------------------------------- +int GridCellToWorldPosZ(int a1) +{ + return (64 - a1) << 9; +} + + + +//----- (00481ED9) -------------------------------------------------------- +void sub_481ED9_MessWithODMRenderParams() +{ + stru_8019C8._48616B_frustum_odm(65536, 0, 0, 0, 65536, 0); + pODMRenderParams->uNumPolygons = 0; + //pODMRenderParams->uNumEdges = 0; + //pODMRenderParams->uNumSpans = 0; + //pODMRenderParams->uNumSurfs = 0; + pODMRenderParams->uNumBillboards = 0; + pODMRenderParams->field_44 = 0; +} + +//----- (004823F4) -------------------------------------------------------- +bool IsTerrainSlopeTooHigh(int pos_x, int pos_z) +{ + //unsigned int v2; // ebx@1 + //unsigned int v3; // edi@1 + //int v4; // eax@1 + //int v6; // esi@5 + //int v7; // ecx@6 + //int v8; // edx@6 + //int v9; // eax@6 + //int y_min; // esi@10 + //int v11; // [sp+14h] [bp-8h]@1 + //int v12; // [sp+18h] [bp-4h]@1 + + //v12 = a1; + //v11 = a2; + unsigned int grid_x = WorldPosToGridCellX(pos_x); + unsigned int grid_z = WorldPosToGridCellZ(pos_z) - 1; + + int party_grid_x1 = GridCellToWorldPosX(grid_x); + //dword_76D56C_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(grid_x + 1); + //dword_76D570_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(grid_x + 1); + //dword_76D574_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(grid_x); + int party_grid_z1 = GridCellToWorldPosZ(grid_z); + //dword_76D55C_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(grid_z); + //dword_76D560_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(grid_z + 1); + //dword_76D564_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(grid_z + 1); + int party_x1z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z); + int party_x2z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z); + int party_x2z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z + 1); + int party_x1z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z + 1); + //dword_76D554_terrain_cell_world_pos_around_party_y = v4; + if (party_x1z1_y == party_x2z1_y && + party_x2z1_y == party_x2z2_y && + party_x2z2_y == party_x1z2_y) + return false; + + int dx = abs(pos_x - party_grid_x1), + dz = abs(party_grid_z1 - pos_z); + + int y1, y2, y3; + if (dz >= dx) + { + y1 = party_x1z2_y; // lower-left triangle + y2 = party_x2z2_y; // y3 | \ + y3 = party_x1z1_y; // | \ + /* | \ + |______ \ + y1 y2 */ + } + else + { + y1 = party_x2z1_y; // upper-right + y2 = party_x1z1_y; // y2_______ y1 + y3 = party_x2z2_y; // \ | + /* \ | + \ | + y3 */ + } + + int y_min = min(y1, min(y2, y3));// не верно при подъёме на склон + int y_max = max(y1, max(y2, y3)); + return (y_max - y_min) > 512; +} + +//----- (0048257A) -------------------------------------------------------- +int __fastcall GetTerrainHeightsAroundParty2(int a1, int a2, int *pIsOnWater, int bFloatAboveWater) +{ + // int result; // eax@9 + int v8; // ebx@11 + int v9; // eax@11 + int v10; // ecx@11 + int v13; // [sp+10h] [bp-8h]@11 + signed int v14; // [sp+14h] [bp-4h]@3 + int v15; // [sp+24h] [bp+Ch]@11 + + unsigned int grid_x = WorldPosToGridCellX(a1); + unsigned int grid_z = WorldPosToGridCellZ(a2) - 1; + + int grid_x1 = GridCellToWorldPosX(grid_x), + grid_x2 = GridCellToWorldPosX(grid_x + 1); + int grid_z1 = GridCellToWorldPosZ(grid_z), + grid_z2 = GridCellToWorldPosZ(grid_z + 1); + + int y_x1z1 = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z), + y_x2z1 = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z), + y_x2z2 = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z + 1), + y_x1z2 = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z + 1); + //v4 = WorldPosToGridCellX(a1); + //v5 = WorldPosToGridCellZ(v12) - 1; + //dword_76D538_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v4); + //dword_76D53C_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v4 + 1); + //dword_76D540_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v4 + 1); + //dword_76D544_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v4); + //dword_76D528_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v5); + //dword_76D52C_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v5); + //dword_76D530_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v5 + 1); + //dword_76D534_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v5 + 1); + //dword_76D518_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4, v5); + //dword_76D51C_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4 + 1, v5); + //dword_76D520_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4 + 1, v5 + 1); + //dword_76D524_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4, v5 + 1); + *pIsOnWater = false; + if (pOutdoor->ActuallyGetSomeOtherTileInfo(grid_x, grid_z) & 2) + *pIsOnWater = true; + v14 = 0; + if (!bFloatAboveWater && *pIsOnWater) + v14 = -60; + if (y_x1z1 != y_x2z1 || + y_x2z1 != y_x2z2 || + y_x2z2 != y_x1z2) + { + if (abs(grid_z1 - a2) >= abs(a1 - grid_x1)) + { + v8 = y_x1z2; + v9 = y_x2z2; + v10 = y_x1z1; + v15 = a1 - grid_x1; + v13 = a2 - grid_z2; + } + else + { + v8 = y_x2z1; + v9 = y_x1z1; + v10 = y_x2z2; + v15 = grid_x2 - a1; + v13 = grid_z1 - a2; + } + return v14 + v8 + fixpoint_mul(v13, (v10 - v8) * 128) + fixpoint_mul(v15, (v9 - v8) * 128); + } + else + return y_x1z1; +} diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/Outdoor.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/Outdoor.h Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,278 @@ +#pragma + +#include "Indoor.h" +#include "TileFrameTable.h" +#include "Engine/Graphics/BSPModel.h" + +#define DAY_ATTRIB_FOG 1 + +/* 256 */ +#pragma pack(push, 1) +struct ODMHeader +{ + int uVersion; + char pMagic[4]; + unsigned int uCompressedSize; + unsigned int uDecompressedSize; +}; +#pragma pack(pop) + + + +/* 78 */ +#pragma pack(push, 1) +struct OutdoorLocationTileType +{ + Tileset tileset; + unsigned __int16 uTileID; +}; +#pragma pack(pop) + +#pragma pack(push, 1) +struct DMap + { + unsigned __int8 field0; + unsigned __int8 field1; + }; +#pragma pack(pop) + +/* 79 */ +#pragma pack(push, 1) +struct OutdoorLocationTerrain +{ + //----- (0047C794) -------------------------------------------------------- + inline OutdoorLocationTerrain() + { + pHeightmap = nullptr; + pTilemap = nullptr; + pAttributemap = nullptr; + pDmap = nullptr;; + this->field_10 = 0; + this->field_12 = 0; + + + } + + void _47C7A9(); + void Release(); + void FillDMap(int X, int Y, int W, int Z); + int _47CB57(int a1, int a2, int a3); + bool ZeroLandscape(); + bool Initialize(); + + + unsigned __int8 *pHeightmap; + unsigned __int8 *pTilemap; + unsigned __int8 *pAttributemap; + struct DMap *pDmap; + __int16 field_10; + __int16 field_12; + __int16 field_14; + __int16 field_16; + int field_18; + int field_1C; +}; +#pragma pack(pop) + + +/* 81 */ +#pragma pack(push, 1) +struct ODMFace +{ + bool HasEventHint(); + + + static bool IsBackfaceNotCulled(struct RenderVertexSoft *a2, struct Polygon *polygon); + + inline bool Invisible() const {return (uAttributes & FACE_INVISIBLE) != 0;} + inline bool Visible() const {return !Invisible();} + inline bool Portal() const {return (uAttributes & FACE_PORTAL) != 0;} + inline bool Fluid() const {return (uAttributes & FACE_FLUID) != 0;} + inline bool Indoor_sky() const {return (uAttributes & FACE_INDOOR_SKY) != 0;} + inline bool Clickable() const {return (uAttributes & FACE_CLICKABLE) != 0;} + inline bool Pressure_Plate() const {return (uAttributes & FACE_PRESSURE_PLATE) != 0;} + inline bool Ethereal() const {return (uAttributes & FACE_ETHEREAL) != 0;} + + struct Plane_int_ pFacePlane; + int zCalc1; + int zCalc2; + int zCalc3; + unsigned int uAttributes; + unsigned __int16 pVertexIDs[20]; + unsigned __int16 pTextureUIDs[20]; + unsigned __int16 pTextureVIDs[20]; + signed __int16 pXInterceptDisplacements[20]; + signed __int16 pYInterceptDisplacements[20]; + signed __int16 pZInterceptDisplacements[20]; + __int16 uTextureID; + __int16 sTextureDeltaU; + __int16 sTextureDeltaV; + struct BBox_short_ pBoundingBox; + __int16 sCogNumber; + __int16 sCogTriggeredID; + __int16 sCogTriggerType; + char field_128; + char field_129; + unsigned __int8 uGradientVertex1; + unsigned __int8 uGradientVertex2; + unsigned __int8 uGradientVertex3; + unsigned __int8 uGradientVertex4; + unsigned __int8 uNumVertices; + unsigned __int8 uPolygonType; + unsigned __int8 uShadeType; + unsigned __int8 bVisible; + char field_132; + char field_133; +}; +#pragma pack(pop) + + + +#pragma pack(push, 1) +struct OutdoorLocation +{ + OutdoorLocation(); + void subconstuctor(); + + void ExecDraw(unsigned int bRedraw); + void PrepareActorsDrawList(); + void CreateDebugLocation(); + void Release(); + bool Load(const char *pFilename, ODMFace *File, size_t a4, int *thisa); + int GetTileIdByTileMapId(signed int a2); + unsigned int DoGetTileTexture(signed int uX, signed int uZ); + int _47ED83(signed int a2, signed int a3); + int ActuallyGetSomeOtherTileInfo(signed int uX, signed int uY); + int DoGetHeightOnTerrain(signed int sX, signed int sZ); + int GetSoundIdByPosition(signed int X_pos, signed int Y_pos, int a4); + int UpdateDiscoveredArea(int a2, int a3, int a4); + bool IsMapCellFullyRevealed(signed int a2, signed int a3); + bool IsMapCellPartiallyRevealed(signed int a2, signed int a3); + bool _47F0E2(); + bool PrepareDecorations(); + void ArrangeSpriteObjects(); + bool InitalizeActors(int a1); + bool LoadRoadTileset(); + bool LoadTileGroupIds(); + double GetFogDensityByTime(); + int GetSomeOtherTileInfo(int sX, int sY); + unsigned int GetTileTexture(int sX, int sZ); + int GetHeightOnTerrain(int sX, int sZ); + bool Initialize(const char *pFilename, int File, size_t uRespawnInterval, int *thisa); + //bool Release2(); + bool GetTravelDestination(signed int sPartyX, signed int sPartyZ, char *pOut, signed int a5); + void MessWithLUN(); + void UpdateSunlightVectors(); + void UpdateFog(); + int GetNumFoodRequiredToRestInCurrentPos(int x, signed int y, int z); + void SetFog(); + void Draw(); + + static void LoadActualSkyFrame(); + + + char pLevelFilename[32]; + char pLocationFileName[32]; + char pLocationFileDescription[32]; + char pSkyTextureName[32]; + char pGroundTileset[32]; + OutdoorLocationTileType pTileTypes[4]; // [3] road tileset + int uNumBModels; + struct OutdoorLocationTerrain pTerrain; + void *pCmap; + BSPModel *pBModels; + unsigned int numFaceIDListElems; + unsigned __int16 *pFaceIDLIST; + unsigned int *pOMAP; + signed int sSky_TextureID; + signed int sMainTile_BitmapID; + __int16 field_F0; + __int16 field_F2; + int field_F4; + char field_F8[968]; + unsigned int uNumSpawnPoints; + struct SpawnPointMM7 *pSpawnPoints; + struct DDM_DLV_Header ddm; + LocationTime_stru1 loc_time; + //unsigned __int64 uLastVisitDay; + //char sky_texture_name[12]; + //int day_attrib; + //int day_fogrange_1; + //int day_fogrange_2; + // char field_510[24]; + unsigned char uFullyRevealedCellOnMap[88][11];//968 the inner array is 11 bytes long, because every bit is used for a separate cell, so in the end it's 11 * 8 bits = 88 values + unsigned char uPartiallyRevealedCellOnMap[88][11];//[968] + int field_CB8; + int max_terrain_dimming_level; + int field_CC0; + unsigned int pSpriteIDs_LUN[8]; + unsigned int uSpriteID_LUNFULL; + int field_CE8; + unsigned int uSpriteID_LUN3_4_cp; + int field_CF0; + unsigned int uSpriteID_LUN1_2_cp; + int field_CF8; + unsigned int uSpriteID_LUN1_4_cp; + int field_D00; + unsigned __int16 uSpriteID_LUN_SUN; + __int16 field_D06; + int field_D08; + int field_D0C; + int field_D10; + int field_D14; + int inv_sunlight_x; + int inv_sunlight_y; + int inv_sunlight_z; + int field_D24; + int field_D28; + int field_D2C; + Vec3_int_ vSunlight; + int field_D3C; + int field_D40; + int field_D44; + int field_D48; + int field_D4C; + float field_D50; + int field_D54; + int field_D58; + int field_D5C; + int field_D60; + int field_D64; + char field_D68[111900]; + float fFogDensity; + int uLastSunlightUpdateMinute; +}; +#pragma pack(pop) + + +extern struct OutdoorLocation *pOutdoor; + +void ODM_UpdateUserInputAndOther(); +int ODM_GetFloorLevel(int X, signed int Y, int Z, int, int *pOnWater, int *bmodel_pid, int bWaterWalk); +int GetCeilingHeight(int Party_X, signed int Party_Y, int Party_ZHeight, int pFaceID); +void ODM_GetTerrainNormalAt(int pos_x, int pos_z, Vec3_int_ *out); +void UpdateActors_ODM(); +void ODM_ProcessPartyActions(); +char Is_out15odm_underwater(); +void SetUnderwaterFog(); +void ODM_Project(unsigned int uNumVertices); +void sub_487DA9(); +void ODM_LoadAndInitialize(const char *pLevelFilename, struct ODMRenderParams *thisa); +unsigned int GetLevelFogColor(); +int __fastcall sub_47C3D7_get_fog_specular(int a1, int a2, float a3); +unsigned int WorldPosToGridCellX(int); // weak +unsigned int WorldPosToGridCellZ(int); // weak +int GridCellToWorldPosX(int); // weak +int GridCellToWorldPosZ(int); // weak +void sub_481ED9_MessWithODMRenderParams(); +bool IsTerrainSlopeTooHigh(int pos_x, int pos_y); +int __fastcall GetTerrainHeightsAroundParty2(int a1, int a2, int *a3, int a4); + + + + + + + + + diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/Overlays.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/Overlays.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,259 @@ +#define _CRTDBG_MAP_ALLOC +#include +#include + + +#define _CRT_SECURE_NO_WARNINGS +#include +#include "ErrorHandling.h" + +#include "Overlays.h" +#include "Sprites.h" +#include "FrameTableInc.h" +#include "IconFrameTable.h" +#include "Timer.h" +#include "Party.h" +#include "TurnEngine.h" +#include "LOD.h" +#include "Render.h" +#include "GUIWindow.h" + +#include "mm7_data.h" + + + + + +struct OtherOverlayList *pOtherOverlayList = new OtherOverlayList; // idb +struct OverlayList *pOverlayList = new OverlayList; + + + + + + +// inlined +//----- (mm6c::0045BD50) -------------------------------------------------- +void OtherOverlayList::Reset() +{ + for (uint i = 0; i < 50; ++i) + pOverlays[i].Reset(); +} + +//----- (004418B1) -------------------------------------------------------- +int OtherOverlayList::_4418B1(int a2, int a3, int a4, int a5) +{ + return 0; +} + +//----- (004418B6) -------------------------------------------------------- +int OtherOverlayList::_4418B6(int uOverlayID, __int16 a3, int a4, int a5, __int16 a6) +{ + signed int v9; // esi@6 + __int16 v11; // dx@11 + + for ( uint i = 0; i < 50; ++i ) + { + if ( this->pOverlays[i].field_6 <= 0 ) + { + this->pOverlays[i].field_0 = 0; + this->pOverlays[i].field_A = 0; + this->pOverlays[i].field_8 = 0; + this->pOverlays[i].field_C = a3; + v9 = 0; + for ( v9; v9 < (signed int)pOverlayList->uNumOverlays; ++v9 ) + { + if ( uOverlayID == pOverlayList->pOverlays[v9].uOverlayID ) + break; + } + this->pOverlays[i].field_2 = v9; + this->pOverlays[i].field_4 = 0; + if ( a4 ) + v11 = a4; + else + v11 = 8 * pSpriteFrameTable->pSpriteSFrames[pOverlayList->pOverlays[v9].uSpriteFramesetID].uAnimLength; + this->pOverlays[i].field_6 = v11; + this->pOverlays[i].field_10 = a5; + this->pOverlays[i].field_E = a6; + bRedraw = true; + return true; + } + } + return 0; +} + +//----- (00441964) -------------------------------------------------------- +void OtherOverlayList::DrawTurnBasedIcon(int a2) +{ + IconFrame *frame; // eax@12 + unsigned int v5; // [sp-8h] [bp-Ch]@4 + + if ( pCurrentScreen != SCREEN_GAME || !pParty->bTurnBasedModeOn) + return; + + if ( pTurnEngine->turn_stage == TE_MOVEMENT )//все персы отстрелялись(сжатый кулак) + frame = pIconsFrameTable->GetFrame(pIconIDs_Turn[5 - pTurnEngine->uActionPointsLeft / 26], pEventTimer->uStartTime); + else if ( pTurnEngine->turn_stage == TE_WAIT ) + { + if ( dword_50C998_turnbased_icon_1A ) + v5 = uIconID_TurnStart;//анимация руки(запуск пошагового режима) + else + v5 = uIconID_TurnHour; //группа ожидает(часы) + frame = pIconsFrameTable->GetFrame(v5, dword_50C994); + } + else if ( pTurnEngine->turn_stage == TE_ATTACK )//группа атакует(ладонь) + frame = pIconsFrameTable->GetFrame(uIconID_TurnStop, pEventTimer->uStartTime); + //if ( pRenderer->pRenderD3D ) + pRenderer->DrawTextureIndexed(394, 288, &pIcons_LOD->pTextures[frame->uTextureID]); + /*else + pRenderer->DrawTextureTransparent(0x18Au, 0x120u, v7);*/ + if ( dword_50C994 < dword_50C998_turnbased_icon_1A ) + { + dword_50C994 += pEventTimer->uTimeElapsed; + if ( (signed int)dword_50C994 >= dword_50C998_turnbased_icon_1A ) + dword_50C998_turnbased_icon_1A = 0; + } +} +// 4E28F8: using guessed type int pCurrentScreen; +// 50C994: using guessed type int dword_50C994; +// 50C998: using guessed type int dword_50C998_turnbased_icon_1A; + + +//----- (00458D97) -------------------------------------------------------- +void OverlayList::InitializeSprites() +{ + for (uint i = 0; i < uNumOverlays; ++i) + pSpriteFrameTable->InitializeSprite(pOverlays[i].uSpriteFramesetID); +} + +//----- (00458DBC) -------------------------------------------------------- +void OverlayList::ToFile() +{ + FILE *v2; // eax@1 + //FILE *v3; // edi@1 + + v2 = fopen("data\\doverlay.bin", "wb"); + //v3 = v2; + if ( !v2 ) + Error("Unable to save doverlay.bin!"); + fwrite(this, 4, 1, v2); + fwrite(this->pOverlays, 8, this->uNumOverlays, v2); + fclose(v2); +} + +//----- (00458E08) -------------------------------------------------------- +void OverlayList::FromFile(void *data_mm6, void *data_mm7, void *data_mm8) +{ + uint num_mm6_overlays = data_mm6 ? *(int *)data_mm6 : 0, + num_mm7_overlays = data_mm7 ? *(int *)data_mm7 : 0, + num_mm8_overlays = data_mm8 ? *(int *)data_mm8 : 0; + + uNumOverlays = num_mm6_overlays + num_mm7_overlays + num_mm8_overlays; + Assert(uNumOverlays); + Assert(!num_mm8_overlays); + + pOverlays = (OverlayDesc *)malloc(uNumOverlays * sizeof(OverlayDesc)); + memcpy(pOverlays, (char *)data_mm7 + 4, num_mm7_overlays * sizeof(OverlayDesc)); + memcpy(pOverlays + num_mm7_overlays, (char *)data_mm6 + 4, num_mm6_overlays * sizeof(OverlayDesc)); + memcpy(pOverlays + num_mm6_overlays + num_mm7_overlays, (char *)data_mm8 + 4, num_mm8_overlays * sizeof(OverlayDesc)); +} + +//----- (00458E4F) -------------------------------------------------------- +bool OverlayList::FromFileTxt(const char *Args) +{ + __int32 v3; // edi@1 + FILE *v4; // eax@1 + unsigned int v5; // esi@3 + void *v7; // eax@9 + //FILE *v8; // ST0C_4@11 + char *i; // eax@11 + char Buf; // [sp+10h] [bp-2F0h]@3 + FrameTableTxtLine v18; // [sp+204h] [bp-FCh]@4 + FrameTableTxtLine v19; // [sp+280h] [bp-80h]@4 + FILE *File; // [sp+2FCh] [bp-4h]@1 + unsigned int Argsa; // [sp+308h] [bp+8h]@3 + + free(this->pOverlays); + v3 = 0; + this->pOverlays = nullptr; + this->uNumOverlays = 0; + v4 = fopen(Args, "r"); + File = v4; + if ( !v4 ) + Error("ObjectDescriptionList::load - Unable to open file: %s."); + + v5 = 0; + Argsa = 0; + if ( fgets(&Buf, 490, v4) ) + { + do + { + *strchr(&Buf, 10) = 0; + memcpy(&v19, txt_file_frametable_parser(&Buf, &v18), sizeof(v19)); + if ( v19.uPropCount && *v19.pProperties[0] != 47 ) + ++Argsa; + } + while ( fgets(&Buf, 490, File) ); + v5 = Argsa; + v3 = 0; + } + this->uNumOverlays = v5; + v7 = malloc(8 * v5); + this->pOverlays = (OverlayDesc *)v7; + if ( v7 == (void *)v3 ) + Error("OverlayDescriptionList::load - Out of Memory!"); + + memset(v7, v3, 8 * this->uNumOverlays); + //v8 = File; + this->uNumOverlays = v3; + fseek(File, v3, v3); + for ( i = fgets(&Buf, 490, File); i; i = fgets(&Buf, 490, File) ) + { + *strchr(&Buf, 10) = 0; + memcpy(&v19, txt_file_frametable_parser(&Buf, &v18), sizeof(v19)); + if ( v19.uPropCount && *v19.pProperties[0] != 47 ) + { + this->pOverlays[this->uNumOverlays].uOverlayID = atoi(v19.pProperties[0]); + if ( _stricmp(v19.pProperties[1], "center") ) + { + if ( !_stricmp(v19.pProperties[1], "transparent") ) + this->pOverlays[this->uNumOverlays].uOverlayType = 2; + else + this->pOverlays[this->uNumOverlays].uOverlayType = 1; + } + else + this->pOverlays[this->uNumOverlays].uOverlayType = 0; + this->pOverlays[this->uNumOverlays++].uSpriteFramesetID = pSpriteFrameTable->FastFindSprite((char *)v19.pProperties[2]); + } + } + fclose(File); + return 1; +} + +//----- (0045855F) -------------------------------------------------------- +void OtherOverlay::Reset() +{ + this->field_0 = 0; + this->field_2 = 0; + this->field_4 = 0; + this->field_6 = 0; + this->field_8 = 0; + this->field_A = 0; + this->field_C = 0; + this->field_E = 0; + this->field_10 = 65536; +} + +//----- (004584B8) -------------------------------------------------------- +OtherOverlay::OtherOverlay() +{ + this->field_0 = 0; + this->field_2 = 0; + this->field_4 = 0; + this->field_6 = 0; + this->field_8 = 0; + this->field_A = 0; + this->field_C = 0; + this->field_E = 0; + this->field_10 = 65536; +} \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/Overlays.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/Overlays.h Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,80 @@ +#pragma once + + +/* 282 */ +#pragma pack(push, 1) +struct OtherOverlay +{ + OtherOverlay(); + void Reset(); + + __int16 field_0; + __int16 field_2; + __int16 field_4; + __int16 field_6; + __int16 field_8; + __int16 field_A; + __int16 field_C; + __int16 field_E; + int field_10; +}; +#pragma pack(pop) + +/* 63 */ +#pragma pack(push, 1) +struct OtherOverlayList +{ + inline OtherOverlayList(): //----- (0045848D) + field_3E8(0), bRedraw(false) + {} + + void Reset(); + int _4418B1(int a2, int a3, int a4, int a5); + int _4418B6(int uOverlayID, __int16 a3, int a4, int a5, __int16 a6); + void DrawTurnBasedIcon(int a2); + + OtherOverlay pOverlays[50]; + int field_3E8; + int bRedraw; +}; +#pragma pack(pop) + + + + +/* 52 */ +#pragma pack(push, 1) +struct OverlayDesc +{ + unsigned __int16 uOverlayID; + unsigned __int16 uOverlayType; + unsigned __int16 uSpriteFramesetID; + __int16 field_6; +}; +#pragma pack(pop) + + + +#pragma pack(push, 1) +struct OverlayList +{ + inline OverlayList(): //----- (00458474) + uNumOverlays(0), pOverlays(nullptr) + {} + + void ToFile(); + void FromFile(void *data_mm6, void *data_mm7, void *data_mm8); + bool FromFileTxt(const char *Args); + void InitializeSprites(); + + + unsigned int uNumOverlays; + struct OverlayDesc *pOverlays; +}; +#pragma pack(pop) + + + + +extern struct OtherOverlayList *pOtherOverlayList; // idb +extern struct OverlayList *pOverlayList; \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/PaletteManager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/PaletteManager.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,986 @@ +#define _CRTDBG_MAP_ALLOC +#include +#include + +#define _CRT_SECURE_NO_WARNINGS +#include "ErrorHandling.h" +#include "PaletteManager.h" +#include "Game.h" +#include "LOD.h" +#include "Log.h" +#include "OurMath.h" + +#include "mm7_data.h" + + + + +PaletteManager *pPaletteManager = new PaletteManager; + + + +//----- (00452AE2) -------------------------------------------------------- +int __fastcall MakeColorMaskFromBitDepth(int a1) +{ + signed __int64 v1; // qax@1 + + v1 = 4294967296i64; + if ( a1 > 0 ) + { + do + { + LODWORD(v1) = HIDWORD(v1) + v1; + HIDWORD(v1) *= 2; + --a1; + } + while ( a1 ); + } + return v1; +} + +//----- (0048A643) -------------------------------------------------------- +bool __fastcall HSV2RGB(float *a1, float *a2, float *a3, float a4, float a5, float a6) +{ + float *v6; // ebx@1 + float *v7; // edi@1 + float *v8; // esi@1 + double v9; // st7@5 + signed __int64 v10; // qax@5 + double v11; // st7@5 + double v12; // st5@5 + int v13; // eax@6 + int v14; // eax@7 + int v15; // eax@8 + int v16; // eax@9 + float v17; // eax@11 + float a3a; // [sp+1Ch] [bp+8h]@14 + float a4b; // [sp+20h] [bp+Ch]@5 + float a4c; // [sp+20h] [bp+Ch]@5 + float a4a; // [sp+20h] [bp+Ch]@5 + + v6 = a3; + v7 = a2; + v8 = a1; + if ( a5 == 0.0 ) + { + *a3 = a6; + *a2 = a6; + *a1 = a6; + goto LABEL_20; + } + if ( a4 == 360.0 ) + a4 = 0.0; + v9 = a4 * 0.01666666666666667; + a4b = v9; + floor(v9); + v10 = (signed __int64)v9; + a4c = a4b - (double)(signed int)(signed __int64)v9; + v11 = (1.0 - a5) * a6; + v12 = (1.0 - a4c * a5) * a6; + a4a = (1.0 - (1.0 - a4c) * a5) * a6; + if ( (int)v10 ) + { + v13 = v10 - 1; + if ( v13 ) + { + v14 = v13 - 1; + if ( v14 ) + { + v15 = v14 - 1; + if ( v15 ) + { + v16 = v15 - 1; + if ( v16 ) + { + if ( v16 != 1 ) + goto LABEL_20; + *v8 = a6; + v17 = v12; + *v7 = v11; + goto LABEL_12; + } + *(int *)v8 = LODWORD(a4a); + *v7 = v11; + } + else + { + *v8 = v11; + a3a = v12; + *(int *)v7 = LODWORD(a3a); + } + v17 = a6; + } + else + { + *v8 = v11; + *(int *)v7 = LODWORD(a6); + v17 = a4a; + } +LABEL_12: + *(int *)v6 = LODWORD(v17); + goto LABEL_20; + } + *v8 = v12; + *v7 = a6; + } + else + { + *v8 = a6; + *(int *)v7 = LODWORD(a4a); + } + *a3 = v11; +LABEL_20: + if ( *v8 > 1.0 ) + *v8 = 1.0; + if ( *v7 > 1.0 ) + *v7 = 1.0; + if ( *v6 > 1.0 ) + *v6 = 1.0; + if ( *v8 < 0.0 ) + *v8 = 0.0; + if ( *v7 < 0.0 ) + *v7 = 0.0; + if ( *v6 < 0.0 ) + *v6 = 0.0; + return 1; +} + +//----- (0048A7AA) -------------------------------------------------------- +void __fastcall RGB2HSV(float *a1, float *a2, float a3, float a4, float a5, float *a6) +{ + double v6; // st7@2 + double v7; // st6@7 + double v8; // st5@12 + double v9; // st7@15 + double v10; // st7@17 +// double v11; // st7@21 +// __int16 v12; // fps@21 +// unsigned __int8 v13; // c0@21 +// unsigned __int8 v14; // c2@21 + float a6a; // [sp+14h] [bp+14h]@16 + + if ( a3 <= (double)a4 ) + v6 = a4; + else + v6 = a3; + if ( v6 < a5 ) + v6 = a5; + if ( a3 <= (double)a4 ) + v7 = a3; + else + v7 = a4; + if ( v7 > a5 ) + v7 = a5; + *a6 = v6; + if ( v6 == 0.0 ) + v8 = 0.0; + else + v8 = (v6 - v7) / v6; + *a2 = v8; + if ( v8 == 0.0 ) + { + v9 = 0.0; +//LABEL_23: + *a1 = v9; + return; + } + a6a = v6 - v7; + if ( a3 == v6 ) + { + v10 = (a4 - a5) / a6a; + } + else + { + if ( a4 == v6 ) + v10 = (a5 - a3) / a6a + 2.0; + else + v10 = (a3 - a4) / a6a + 4.0; + } + //*a1 = v10; + //v11 = *a1 * 60.0; + //UNDEF(v12); + *a1 = v10 * 60.0; + if (*a1 < 0) + { + *a1 += 360.0; + } +} + + + +//----- (0048A8A3) -------------------------------------------------------- +int PaletteManager::LockAll() +{ + int *v1; // edx@1 + signed int v2; // eax@1 + + v1 = &this->pPaletteIDs[1]; + v2 = 1; + do + { + if ( *v1 ) + this->_num_locked = v2 + 1; + ++v2; + ++v1; + } + while ( v2 < 50 ); + return this->_num_locked; +} + +//----- (0048A8CC) -------------------------------------------------------- +int PaletteManager::LockTestAll() +{ + char *v1; // edx@1 + signed int v2; // eax@1 + + v1 = (char *)&this->pPaletteIDs[1]; + v2 = 1; + do + { + if ( *(int *)v1 ) + this->_pal_lock_test = v2 + 1; + ++v2; + v1 += 4; + } + while ( v2 < 50 ); + return this->_pal_lock_test; +} + + +//----- (0048A8F5) -------------------------------------------------------- +void PaletteManager::SetColorChannelInfo(int uNumRBits, int uNumGBits, int uNumBBits) +{ + PaletteManager *v4; // esi@1 + int v5; // edi@1 + int v6; // eax@1 + int v7; // ebx@1 + + v4 = this; + this->uNumTargetRBits = uNumRBits; + this->uNumTargetGBits = uNumGBits; + v5 = this->uNumTargetGBits; + this->uNumTargetBBits = uNumBBits; + v6 = MakeColorMaskFromBitDepth(uNumRBits); + v7 = v4->uNumTargetBBits; + v4->uTargetRMask = v6 << (v5 + v4->uNumTargetBBits); + v4->uTargetGMask = MakeColorMaskFromBitDepth(v5) << v7; + v4->uTargetBMask = MakeColorMaskFromBitDepth(v7); +} + + +//----- (00489BE0) -------------------------------------------------------- +void PaletteManager::CalcPalettes_LUT(int a2) +{ + PaletteManager *v2; // esi@1 + //char *v3; // edi@1 + //signed int v4; // ebx@4 + //float v5; // ST08_4@5 + //float v6; // ST04_4@5 + //float v7; // ST00_4@5 + //int v8; // eax@7 + //float *v9; // edx@8 + //float *v10; // ST0C_4@8 + //float *v11; // ecx@8 + //int v12; // ebx@8 + //int v13; // eax@8 + //float v14; // ebx@8 +// float v15; // ST08_4@8 +// float v16; // ST04_4@8 +// float v17; // ST00_4@8 + //unsigned __int8 v18; // sf@8 + //unsigned __int8 v19; // of@8 + //int v20; // eax@10 + double v21; // st5@11 + //float v22; // ST0C_4@13 + unsigned int v23; // eax@13 + //__int16 v24; // bx@16 + //int v25; // eax@16 + double v26; // st7@20 + //float v27; // ST0C_4@22 + unsigned int v28; // eax@22 + //__int16 v29; // bx@25 + //__int16 *v30; // eax@25 + //int v31; // eax@27 + double v32; // st5@28 + //float v33; // ST0C_4@30 + //float v34; // ST08_4@30 + unsigned int v35; // ebx@30 + signed __int64 v36; // qax@33 + signed int v37; // edx@33 + char v38; // cl@33 + unsigned int v39; // ebx@33 + signed int v40; // edi@33 + unsigned int v41; // ecx@33 + unsigned int v42; // ecx@35 + //int v43; // eax@39 + signed int v44; // edx@39 + //unsigned __int8 v45; // al@40 + //double v46; // st6@43 + //signed int v47; // eax@43 + //int v48; // eax@45 + double v49; // st6@47 + //float v50; // ST08_4@49 + //unsigned int v51; // ebx@49 + int v52; // edi@55 + int v53; // ebx@55 + signed __int64 v54; // qax@55 + double v55; // st7@56 + unsigned int v56; // ecx@57 + unsigned int v57; // ecx@59 + //int v58; // edx@61 + unsigned int v59; // ecx@61 + unsigned int v60; // eax@63 + char v61; // cl@63 + //int result; // eax@63 + float v63[256]; // [sp+1Ch] [bp-C38h]@5 + float v64[256]; // [sp+41Ch] [bp-838h]@5 + float a6[256]; // [sp+81Ch] [bp-438h]@5 +// int v66; // [sp+C1Ch] [bp-38h]@43 + float v67; // [sp+C20h] [bp-34h]@43 + float v68; // [sp+C24h] [bp-30h]@43 + //PaletteManager *v69; // [sp+C28h] [bp-2Ch]@9 + //float v70; // [sp+C2Ch] [bp-28h]@43 + //double v71; // [sp+C30h] [bp-24h]@10 + //int v72; // [sp+C38h] [bp-1Ch]@9 + //int v73; // [sp+C3Ch] [bp-18h]@9 + //int i; // [sp+C40h] [bp-14h]@7 + //float v75; // [sp+C44h] [bp-10h]@5 + float a2a; // [sp+C48h] [bp-Ch]@13 + float a1; // [sp+C4Ch] [bp-8h]@13 + float a3; // [sp+C50h] [bp-4h]@13 + signed int v79; // [sp+C5Ch] [bp+8h]@33 + //signed int v80; // [sp+C5Ch] [bp+8h]@43 + int v81; // [sp+C5Ch] [bp+8h]@57 + + v2 = this; + //v3 = (char *)pBaseColors[a2]; + if (pPalette_tintColor[0] || pPalette_tintColor[1] || pPalette_tintColor[2]) + { + //v8 = 0; + //i = 0; + + for (uint i = 0; i < 256; ++i) + RGB2HSV(&v64[i], &v63[i], (pBaseColors[a2][i][0] + pPalette_tintColor[0]) / (255.0f + 255.0f), //Uninitialized memory access + (pBaseColors[a2][i][1] + pPalette_tintColor[1]) / (255.0f + 255.0f), + (pBaseColors[a2][i][2] + pPalette_tintColor[2]) / (255.0f + 255.0f), &a6[i]); + //do + //{ + //v9 = (float *)((char *)v63 + v8); + //v10 = (float *)((char *)a6 + v8); + //v11 = (float *)((char *)v64 + v8); + //v12 = pPalette_tintColor[1]; + //LODWORD(v75) = pPalette_tintColor[2] + (unsigned __int8)v3[2]; + //v13 = pPalette_tintColor[1] + (unsigned __int8)v3[1]; + //LODWORD(v14) = (unsigned __int8)*v3; + //v15 = (double)((unsigned __int8)v3[2] + pPalette_tintColor[2]) / (2.0f * 255.0f); + //LODWORD(v75) = v13; + //LODWORD(v75) = (unsigned __int8)*v3 + pPalette_tintColor[0]; + //v16 = (double)((unsigned __int8)v3[1] + pPalette_tintColor[1]) / 510.0f; + //v17 = (double)((unsigned __int8)*v3 + pPalette_tintColor[0]) / 510.0f; + //RGB2HSV(&v64[i], &v63[i], v17, v16, v15, &a6[i]); + //v3 += 3; + //v8 = i + 4; + //v19 = __OFSUB__(i + 4, 1024); + //v18 = i - 1020 < 0; + //i += 4; + //} + //while ( i < ); + } + else + { + for (uint i = 0; i < 256; ++i) + RGB2HSV(&v64[i], &v63[i], pBaseColors[a2][i][0] / 255.0f, + pBaseColors[a2][i][1] / 255.0f, + pBaseColors[a2][i][2] / 255.0f, &a6[i]); + /*v4 = 0; + do + { + LODWORD(v75) = (unsigned __int8)v3[2]; + v5 = (double)SLODWORD(v75) * 0.00392156862745098; + LODWORD(v75) = (unsigned __int8)v3[1]; + v6 = (double)SLODWORD(v75) * 0.00392156862745098; + LODWORD(v75) = (unsigned __int8)*v3; + v7 = (double)SLODWORD(v75) * 0.00392156862745098; + RGB2HSV(&v64[v4], &v63[v4], v7, v6, v5, &a6[v4]); + ++v4; + v3 += 3; + } + while ( v4 < 256 );*/ + } + + //v69 = (PaletteManager *)((char *)v2 + 16384 * a2); + //v72 = 0; + //v73 = (int)pPalette1[a2]; + for (uint i = 0; i < 32; ++i) + //do + { + //v20 = 0; + //i = 0; + //v71 = 1.0 - (double)v72 / 31.0f; + //do + for (uint j = 0; j < 256; ++j) + { + v21 = a6[j] * (1.0f - i / 32.0f); + if ( v21 < 0.0 ) + v21 = 0.0; + + //v22 = v21; + HSV2RGB(&a1, &a2a, &a3, v64[j], v63[j], v21); + v23 = v2->uNumTargetGBits; + if ( v23 == 6 ) // r5g6b5 + { + a1 = a1 * 31.0; + a2a = a2a * 62.0; + a3 = a3 * 31.0; + } + else if (v23 == 5) // r5g5b5 + { + a1 = a1 * 31.0; + a2a = a2a * 31.0; + a3 = a3 * 31.0; + } + else if (v23 == 0) + Log::Warning(L"Calling palette manager with num_target_bits == 0"); + else Error("(%u)", v23); + //v24 = (unsigned __int32)a3 | ((unsigned __int32)a2a << v2->uNumTargetBBits) | ((unsigned __int32)a1 << (v2->uNumTargetBBits + v2->uNumTargetGBits)); + //v25 = v73; + //v73 += 2; + //*(short *)v25 = v24; + pPalette1[a2][i][j] = (unsigned __int32)a3 | + ((unsigned __int32)a2a << v2->uNumTargetBBits) | + ((unsigned __int32)a1 << (v2->uNumTargetBBits + v2->uNumTargetGBits)); + //v20 = i + 4; + //v19 = __OFSUB__(i + 4, 1024); + //v18 = i - 1020 < 0; + //i += 4; + } + //while ( v18 ^ v19 ); + //++v72; + } + //while ( v72 < 32 ); + + //v72 = 0; + //v73 = (int)v69->field_199600_palettes; + //do + for (uint i = 0; i < 32; ++i) + { + //i = 0; + //v71 = 1.0 - (double)v72 / 31.0f; + //do + for (uint j = 0; j < 256; ++j) + { + v26 = a6[j] * (1.0 - i / 31.0f); + if ( v26 < 0.0 ) + v26 = 0.0; + + //v27 = v26; + HSV2RGB(&a1, &a2a, &a3, 1.0, 1.0, v26); + v28 = v2->uNumTargetGBits; + if ( v28 == 6 ) + { + a1 = a1 * 31.0; + a2a = a2a * 62.0; + a3 = a3 * 31.0; + } + else if (v28 == 5) + { + a1 = a1 * 31.0; + a2a = a2a * 31.0; + a3 = a3 * 31.0; + } + else if (v23 == 0) + Log::Warning(L"Calling palette manager with num_target_bits == 0"); + else Error("(%u)", v23); + + //v29 = (unsigned __int64)(signed __int64)a3 | ((unsigned __int16)(signed __int64)a2a << v2->uNumTargetBBits) | (unsigned __int16)((unsigned __int16)(signed __int64)a1 << (v2->uNumTargetBBits + v28)); + //v30 = (__int16 *)v73; + //++i; + //v73 += 2; + //v19 = __OFSUB__(i, 256); + //v18 = i - 256 < 0; + //*v30 = v29; + field_199600_palettes[a2][i][j] = (unsigned __int64)(signed __int64)a3 | ((unsigned __int16)(signed __int64)a2a << v2->uNumTargetBBits) | (unsigned __int16)((unsigned __int16)(signed __int64)a1 << (v2->uNumTargetBBits + v28)); + } + //while ( v18 ^ v19 ); + //++v72; + } + //while ( v72 < 32 ); + + //v73 = (int)((char *)v2 + 512 * (a2 + 4875)); // field_261600[a2] + //v31 = 0; + //i = 0; + for (uint i = 0; i < 256; ++i) + //do + { + //v32 = (*(float *)((char *)a6 + v31) - 0.8) * 0.8387096774193549 + 0.8; + v32 = (a6[i] - 0.8f) * 0.8387096774193549 + 0.8; + if ( v32 < 0.0 ) + v32 = 0.0; + + //v33 = v32; + //v34 = v63[i] * 0.7034339229968783; + HSV2RGB(&a1, &a2a, &a3, v64[i], v63[i] * 0.7034339229968783, v32); + v35 = v2->uNumTargetGBits; + if ( v35 == 6 ) + { + a1 = a1 * 31.0; + a2a = a2a * 62.0; + a3 = a3 * 31.0; + } + else if (v35 == 5) + { + a1 = a1 * 31.0; + a2a = a2a * 31.0; + a3 = a3 * 31.0; + } + else if (v23 == 0) + Log::Warning(L"Calling palette manager with num_target_bits == 0"); + else Error("(%u)", v23); + + v36 = (signed __int64)((a1 + a2a + a3) * 0.3333333333333333 * 8.0); + v37 = (signed int)v36 >> (8 - v2->uNumTargetRBits); + v38 = 8 - v35; + v39 = v2->uNumTargetBBits; + v40 = (signed int)v36 >> v38; + v41 = v2->uNumTargetRBits; + v79 = (signed int)v36 >> (8 - v39); + if ( v37 > (1 << v41) - 1 ) + v37 = (1 << v41) - 1; + v42 = v2->uNumTargetGBits; + if ( v40 > (1 << v42) - 1 ) + v40 = (1 << v42) - 1; + if ( v79 > (1 << v39) - 1 ) + v79 = (1 << v39) - 1; + //v43 = v73; + v44 = v37 << (v39 + v2->uNumTargetGBits); + //v73 += 2; + //*(short *)v43 = v79 | ((short)v40 << v39) | (unsigned __int16)v44; + field_261600[a2][i] = v79 | ((unsigned short)v40 << v39) | (unsigned __int16)v44; + //v31 = i + 4; + //v19 = __OFSUB__(i + 4, 1024); + //v18 = i - 1020 < 0; + //i += 4; + } + //while ( v18 ^ v19 ); + + //v45 = pPalette_mistColor[0]; + float mist_a, mist_b, mist_c; + if (pPalette_mistColor[0] || pPalette_mistColor[1] || pPalette_mistColor[2]) + { + //v46 = (double)v45; + //v80 = pPalette_mistColor[1]; + //v47 = pPalette_mistColor[2]; + //v70 = v46 * 0.00392156862745098; + //*((float *)&v71 + 1) = (double)v80 * 0.00392156862745098; + //v75 = (double)v47 * 0.00392156862745098; + mist_a = pPalette_mistColor[0] / 255.0f; + mist_b = pPalette_mistColor[1] / 255.0f; + mist_c = pPalette_mistColor[2] / 255.0f; + + float unused; + RGB2HSV(&v68, &v67, mist_a, mist_b, mist_c, &unused); + } + + //v72 = 0; + //v73 = (int)v69->field_D1600; + //do + for (uint i = 0; i < 32; ++i) + { + //v48 = 0; + //for ( i = 0; ; v48 = i ) + for (uint j = 0; j < 256; ++j) + { + v49 = v63[j]; + if ( v49 < 0.0 ) + v49 = 0.0; + + //v50 = v49; + HSV2RGB(&a1, &a2a, &a3, v64[j], v49, a6[j]); + //v51 = v2->uNumTargetGBits; + if ( v2->uNumTargetGBits == 6 ) + { + a1 = a1 * 31.0; + a2a = a2a * 62.0; + a3 = a3 * 31.0; + } + else if (v2->uNumTargetGBits == 5) + { + a1 = a1 * 31.0; + a2a = a2a * 31.0; + a3 = a3 * 31.0; + } + else if (v23 == 0) + Log::Warning(L"Calling palette manager with num_target_bits == 0"); + else Error("(%u)", v23); + + if (pPalette_mistColor[0] || pPalette_mistColor[1] || pPalette_mistColor[2]) + { + v55 = (double)i / 31.0f; + v52 = (signed __int64)((double)(1 << v2->uNumTargetRBits) * mist_a * v55 + a1 * (1.0 - v55)); + v53 = (signed __int64)((double)(1 << v2->uNumTargetGBits) * mist_b * v55 + a2a * (1.0 - v55)); + v54 = (signed __int64)((double)(1 << v2->uNumTargetBBits) * mist_c * v55 + a3 * (1.0 - v55)); + } + else + { + v52 = (signed __int64)a1; + v53 = (signed __int64)a2a; + v54 = (signed __int64)a3; + } + + v56 = v2->uNumTargetRBits; + v81 = v54; + if ( v52 > (1 << v56) - 1 ) + v52 = (1 << v56) - 1; + v57 = v2->uNumTargetGBits; + if ( v53 > (1 << v57) - 1 ) + v53 = (1 << v57) - 1; + HIDWORD(v54) = v2->uNumTargetBBits; + v59 = v2->uNumTargetBBits; + if ( (signed int)v54 > (1 << v59) - 1 ) + v81 = (1 << v59) - 1; + v60 = v2->uNumTargetGBits; + //i += 4; + v61 = uNumTargetBBits + v60; + //result = v73; + //v73 += 2; + //v19 = __OFSUB__(i, 1024); + //v18 = i - 1024 < 0; + //*(short *)result = v81 | ((short)v53 << uNumTargetBBits) | (v52 << v61); + field_D1600[a2][i][j] = v81 | ((short)v53 << uNumTargetBBits) | (v52 << v61); + //if ( !(v18 ^ v19) ) + // break; + } + //++v72; + } + //while ( v72 < 32 ); +} + + +//----- (0048A300) -------------------------------------------------------- +PaletteManager::PaletteManager(): + uNumTargetRBits(0), uNumTargetGBits(0),uNumTargetBBits(0),_num_locked(0) +{ + for (uint i = 0; i < 256; ++i) + { + pBaseColors[0][i][0] = i; + pBaseColors[0][i][1] = i; + pBaseColors[0][i][2] = i; + } + + memset(pPaletteIDs, 0, sizeof(pPaletteIDs)); + memset(pPalette_tintColor, 0, sizeof(pPalette_tintColor)); + memset(pPalette_mistColor, 0, sizeof(pPalette_mistColor)); + CalcPalettes_LUT(0); +} + +//----- (0048A336) -------------------------------------------------------- +// make grayscale palette at 0, clear all palettes ids that aren't locked +int PaletteManager::ResetNonLocked() +{ + PaletteManager *v1; // esi@1 + signed int v2; // ecx@1 + int v3; // eax@1 + signed int result; // eax@3 + void *v5; // edi@4 + int v6; // ecx@4 + + v1 = this; + v2 = 0; + v3 = (int)&v1->pBaseColors[0][0][1]; + do + { + *(char *)(v3 + 1) = v2; + *(char *)v3 = v2; + *(char *)(v3 - 1) = v2++; + v3 += 3; + } + while ( v2 < 256 ); + CalcPalettes_LUT(0); + result = v1->_num_locked; + if ( result < 50 ) + { + v5 = &v1->pPaletteIDs[result]; + v6 = 50 - result; + result = 0; + memset(v5, 0, 4 * v6); + } + return result; +} + +//----- (0048A379) -------------------------------------------------------- +// make grayscale palette at 0, clear all palettes ids that aren't in "lock_test" +int PaletteManager::ResetNonTestLocked() +{ + PaletteManager *v1; // esi@1 + signed int v2; // ecx@1 + int v3; // eax@1 + signed int result; // eax@3 + void *v5; // edi@4 + int v6; // ecx@4 + + v1 = this; + v2 = 0; + v3 = (int)&v1->pBaseColors[0][0][1]; + do + { + *(char *)(v3 + 1) = v2; + *(char *)v3 = v2; + *(char *)(v3 - 1) = v2++; + v3 += 3; + } + while ( v2 < 256 ); + CalcPalettes_LUT(0); + result = v1->_pal_lock_test; + if ( result < 50 ) + { + v5 = &v1->pPaletteIDs[result]; + v6 = 50 - result; + result = 0; + memset(v5, 0, 4 * v6); + } + return result; +} + +//----- (0048A3BC) -------------------------------------------------------- +int PaletteManager::LoadPalette(unsigned int uPaletteID) +{ + unsigned int *v2; // ecx@1 + signed int result; // eax@1 + signed int v4; // esi@6 + double v5; // st7@7 + double v6; // st7@12 + double v7; // st6@17 + signed __int64 v8; // qax@17 + double v9; // st6@17 + char v10[768]; // [sp+18h] [bp-388h]@6 + //char v11; // [sp+19h] [bp-387h]@17 + //char v12[766]; // [sp+1Ah] [bp-386h]@17 + char Source[32]; // [sp+360h] [bp-40h]@4 + //PaletteManager *v15; // [sp+380h] [bp-20h]@1 + float v16; // [sp+384h] [bp-1Ch]@7 + int v17; // [sp+388h] [bp-18h]@6 + float v18; // [sp+38Ch] [bp-14h]@7 + float a2a; // [sp+390h] [bp-10h]@7 + float a1; // [sp+394h] [bp-Ch]@7 + float a6; // [sp+398h] [bp-8h]@7 + float a3; // [sp+39Ch] [bp-4h]@7 + + //v15 = this; + v2 = (unsigned int *)&this->pPaletteIDs[1]; + result = 1; + while ( *v2 != uPaletteID ) + { + ++result; + ++v2; + if ( result >= 50 ) + { + sprintf(Source, "pal%03i", uPaletteID); + + Texture tex; // [sp+318h] [bp-88h]@4 + //Texture::Texture(&tex); + + if ( pBitmaps_LOD->LoadTextureFromLOD(&tex, Source, TEXTURE_24BIT_PALETTE) == 1 ) + { + v4 = 0; + v17 = 1 - (int)&v10; + do + { + //LODWORD(a1) = tex.pPalette24[v4]; + a1 = (double)tex.pPalette24[v4] / 255.0f; + LODWORD(a2a) = (unsigned __int8)*(&v10 + v4 + v17 + (unsigned int)tex.pPalette24); + a2a = (double)tex.pPalette24[v4 + 1] / 255.0f; + //a3 = tex.pPalette24[v4 + 2]; + a3 = (double)tex.pPalette24[v4 + 2] / 255.0f; + RGB2HSV(&v16, &v18, a1, a2a, a3, &a6); + v5 = a6 * 1.1; + if ( v5 >= 0.0 && v5 >= 1.0 ) + v5 = 1.0; + else + { + if ( v5 < 0.0 ) + v5 = 0.0; + } + a6 = v5; + v6 = v18 * 0.64999998; + if ( v6 >= 0.0 && v6 >= 1.0 ) + v6 = 1.0; + else + { + if ( v6 < 0.0 ) + v6 = 0.0; + } + v18 = v6; + HSV2RGB(&a1, &a2a, &a3, v16, v18, a6); + v7 = a2a * 255.0; + v10[v4] = (signed __int64)(a1 * 255.0); + v8 = (signed __int64)v7; + v9 = a3 * 255.0; + v10[v4 + 1] = v8; + v10[v4 + 2] = (signed __int64)v9; + v4 += 3; + } + while ( v4 < 768 ); + tex.Release(); + result = this->MakeBasePaletteLut(uPaletteID, v10); + } + else + result = 0; + return result; + } + } + return result; +} +// 48A3BC: using guessed type char var_386[766]; + +//----- (0048A5A4) -------------------------------------------------------- +int PaletteManager::MakeBasePaletteLut(int idx, char *entries) +{ + //PaletteManager *v3; // edi@1 + //signed int result; // eax@1 + //int *v5; // ecx@1 + int v6; // eax@4 + int v7; // esi@4 + //int v8; // eax@9 + //signed int v9; // ecx@9 + //int v10; // edx@9 + + //v3 = this; + //result = 0; + //v5 = this->pPaletteIDs; + + for (uint i = 0; i < 50; ++i) + if (pPaletteIDs[i] == idx) + return i; + + v6 = (int)&pPaletteIDs[1]; + v7 = 1; + while ( *(int *)v6 ) + { + ++v7; + v6 += 4; + if ( v7 >= 50 ) + return 0; + } + /*v8 = (int)pBaseColors[v7];//(int)((char *)v3 + 768 * v7); + v9 = 768; + v10 = (int)(entries - v8); + do + { + *(char *)v8 = *(char *)(v10 + v8); + ++v8; + --v9; + } + while ( v9 );*/ + unsigned __int8 *dst = (unsigned __int8 *)pBaseColors[v7]; + for (uint i = 0; i < 768; ++i) + dst[i] = entries[i]; + + pPaletteIDs[v7] = idx; + CalcPalettes_LUT(v7); + return v7; + +} + +// inlined +//----- (mm6c::0045C610) --------------------------------------------------- +void PaletteManager::SetMistColor(unsigned char r, unsigned char g, unsigned char b) +{ + pPalette_mistColor[0] = r; + pPalette_mistColor[1] = g; + pPalette_mistColor[2] = b; +} + +//----- (0048A614) -------------------------------------------------------- +void PaletteManager::RecalculateAll() +{ + CalcPalettes_LUT(0); + + for (uint i = 1; i < 50; ++i) + if (pPaletteIDs[i]) + CalcPalettes_LUT(i); +} + + +//----- (0047BE67) -------------------------------------------------------- +unsigned __int16 *PaletteManager::Get(int a1) +{ + return (unsigned __int16 *)pPaletteManager->field_199600_palettes[a1]; +} + +//----- (0047BE72) -------------------------------------------------------- +unsigned __int16 *PaletteManager::Get_Mist_or_Red_LUT(int a1, int a2, char a3) +{ + int v3; // eax@4 + + if ( a3 & 2 || byte_4D864C && BYTE2(pGame->uFlags) & 4 ) + v3 = 32 * a1 + a2 + 3275; + else + v3 = 32 * a1 + a2 + 1675; + return (unsigned __int16 *)((char *)&pPaletteManager + 512 * v3); +} +// 4D864C: using guessed type char byte_4D864C; + + +//----- (0041F50D) -------------------------------------------------------- +unsigned __int16 *PaletteManager::Get_Dark_or_Red_LUT(int a1, int a2, char a3) +{ + int v3; // eax@4 + + if ( a3 & 2 || byte_4D864C && BYTE2(pGame->uFlags) & 4 ) + v3 = 32 * a1 + a2 + 3275; + else + v3 = 32 * a1 + a2 + 75; + return (unsigned __int16 *)((char *)&pPaletteManager + 512 * v3); +} +// 4D864C: using guessed type char byte_4D864C; + + +//----- (0047C30E) -------------------------------------------------------- +unsigned __int16 *PaletteManager::_47C30E_get_palette(int a1, char a2) +{ + char *result; // eax@4 + + if ( a2 & 2 || byte_4D864C && BYTE2(pGame->uFlags) & 4 ) + result = (char *)pPaletteManager->field_199600_palettes[a1]; + else + result = (char *)pPaletteManager->field_D1600[a1]; + return (unsigned __int16 *)result; +} + + +//----- (0047C33F) -------------------------------------------------------- +unsigned __int16 *PaletteManager::_47C33F_get_palette(int a1, char a2) +{ + unsigned __int16 *result; // eax@4 + + if ( a2 & 2 || byte_4D864C && BYTE2(pGame->uFlags) & 4 ) + result = (unsigned __int16 *)pPaletteManager->field_199600_palettes[a1]; + else + result = (unsigned __int16 *)pPaletteManager->pPalette1[a1]; + return result; +} +// 4D864C: using guessed type char byte_4D864C; + + +//----- (0048A959) -------------------------------------------------------- +signed int ReplaceHSV(unsigned int uColor, float h_replace, float s_replace, float v_replace) +{ + float r = ((uColor & 0x00FF0000) >> 16) / 255.0f, + g = ((uColor & 0x0000FF00) >> 8) / 255.0f, + b = (uColor & 0x000000FF) / 255.0f; + + float h, s, v; + RGB2HSV(&h, &s, r, g, b, &v); + + if ( h_replace != -1.0 ) + h = h_replace; + if ( s_replace != -1.0 ) + s = s_replace; + if ( v_replace != -1.0 ) + v = v_replace; + HSV2RGB(&r, &g, &b, h, s, v); + + return (((uint)round_to_int(r * 255.0f) & 0xFF) << 16) | + (((uint)round_to_int(g * 255.0f) & 0xFF) << 8) | + (((uint)round_to_int(b * 255.0f) & 0xFF)); +} \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/PaletteManager.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/PaletteManager.h Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,53 @@ +#pragma once + + +/* 148 */ +#pragma pack(push, 1) +struct PaletteManager +{ + PaletteManager(); + + void SetMistColor(unsigned char r, unsigned char g, unsigned char b); + int ResetNonTestLocked(); + void CalcPalettes_LUT(int a2); + int ResetNonLocked(); + int LoadPalette(unsigned int uPaletteID); + int MakeBasePaletteLut(int a2, char *entries); + void RecalculateAll(); + int LockAll(); + int LockTestAll(); + void SetColorChannelInfo(int uNumRBits, int uNumGBits, int uNumBBits); + + static unsigned __int16 *Get(int a1); + static unsigned __int16 *Get_Mist_or_Red_LUT(int paletteIdx, int a2, char a3); + static unsigned __int16 *Get_Dark_or_Red_LUT(int paletteIdx, int a2, char a3); + static unsigned __int16 *_47C30E_get_palette(int a1, char a2); + static unsigned __int16 *_47C33F_get_palette(int a1, char a2); + + unsigned __int8 pBaseColors[50][256][3]; + unsigned __int16 pPalette1[50][32][256]; + unsigned __int16 field_D1600[50][32][256]; + unsigned __int16 field_199600_palettes[50][32][256]; + unsigned __int16 field_261600[50][256]; + int pPaletteIDs[50]; + int _num_locked; + int _pal_lock_test; + unsigned __int8 pPalette_mistColor[3]; + unsigned char pPalette_tintColor[3]; + char field_267AD6; + char field_267AD7; + unsigned int uNumTargetRBits; + unsigned int uNumTargetGBits; + unsigned int uNumTargetBBits; + unsigned int uTargetRMask; + unsigned int uTargetGMask; + unsigned int uTargetBMask; +}; +#pragma pack(pop) + + + +bool __fastcall HSV2RGB(float *a1, float *a2, float *a3, float a4, float a5, float a6); +void __fastcall RGB2HSV(float *a1, float *a2, float a3, float a4, float a5, float *a6); +signed int ReplaceHSV(unsigned int uColor, float a2, float gamma, float a4); +extern PaletteManager *pPaletteManager; \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/ParticleEngine.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/ParticleEngine.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,768 @@ +#define _CRTDBG_MAP_ALLOC +#include +#include + +#define _CRT_SECURE_NO_WARNINGS +#include "ParticleEngine.h" +#include "Timer.h" +#include "Viewport.h" +#include "Outdoor.h" +#include "Game.h" +#include "OurMath.h" +#include "LOD.h" + +#include "Sprites.h" + +TrailParticleGenerator trail_particle_generator; + + +//----- (00440DF5) -------------------------------------------------------- +void TrailParticleGenerator::AddParticle(int x, int y, int z, int bgr16) +{ + particles[num_particles].x = x; + particles[num_particles].y = y; + particles[num_particles].z = z; + particles[num_particles].time_to_live = rand() % 64 + 256; + particles[num_particles].time_left = particles[num_particles].time_to_live; + particles[num_particles].bgr16 = bgr16; + + num_particles++; + assert(num_particles < 100); +} + +//----- (00440E91) -------------------------------------------------------- +void TrailParticleGenerator::GenerateTrailParticles(int x, int y, int z, int bgr16) +{ + for (int i = 0; i < 5 + rand() % 6; ++i) + AddParticle(rand() % 33 + x - 16, + rand() % 33 + y - 16, + rand() % 33 + z, bgr16); +} + +//----- (00440F07) -------------------------------------------------------- +void TrailParticleGenerator::UpdateParticles() +{ + for (uint i = 0; i < 100; ++i) + { + if (particles[i].time_left > 0) + { + particles[i].x += rand() % 5 + 4; + particles[i].y += rand() % 5 - 2; + particles[i].z += rand() % 5 - 2; + particles[i].time_left -= pEventTimer->uTimeElapsed; + } + } +} + +//----- (0048AAC5) -------------------------------------------------------- +ParticleEngine::ParticleEngine() +{ + for (uint i = 0; i < 500; ++i) + memset(&pParticles[i], 0, sizeof(pParticles[i])); + + ResetParticles(); +} + +//----- (0048AAF6) -------------------------------------------------------- +void ParticleEngine::ResetParticles() +{ + memset(pParticles, 0, 500 * sizeof(*pParticles)); + uStartParticle = 500; + uEndParticle = 0; + uTimeElapsed = 0; +} + +//----- (0048AB23) -------------------------------------------------------- +void ParticleEngine::AddParticle(Particle_sw *a2) +{ + signed int v2; // eax@2 + Particle *v3; // edx@2 + Particle *v4; // esi@10 + int v5; // ecx@10 + //char v6; // zf@10 + + if ( !pMiscTimer->bPaused ) + { + v2 = 0; + v3 = (Particle *)this; + do + { + if (v3->type == ParticleType_Invalid) + break; + ++v2; + ++v3; + } + while ( v2 < 500 ); + if ( v2 < 500 ) + { + if ( v2 < this->uStartParticle ) + this->uStartParticle = v2; + if ( v2 > this->uEndParticle ) + this->uEndParticle = v2; + v4 = &this->pParticles[v2]; + v4->type = a2->type; + v4->x = a2->x; + v4->y = a2->y; + v4->z = a2->z; + v4->_x = a2->x; + v4->_y = a2->y; + v4->_z = a2->z; + v4->flt_10 = a2->r; + v4->flt_14 = a2->g; + v4->flt_18 = a2->b; + v5 = a2->uDiffuse; + v4->uParticleColor = v5; + v4->uLightColor_bgr = v5; + //v6 = (v4->uType & 4) == 0; + v4->timeToLive = a2->timeToLive; + v4->uTextureID = a2->uTextureID; + v4->flt_28 = a2->flt_28; + if (v4->type & ParticleType_Rotating) + { + v4->rotation_speed = (rand() % 256) - 128; + v4->angle = rand(); + } + else + { + v4->rotation_speed = 0; + v4->angle = 0; + } + } + } +} + +//----- (0048ABF3) -------------------------------------------------------- +void ParticleEngine::Draw() +{ + uTimeElapsed += pEventTimer->uTimeElapsed; + pLines.uNumLines = 0; + + if (uCurrentlyLoadedLevelType == LEVEL_Indoor) + DrawParticles_BLV(); + else + DrawParticles_ODM(); + + //if (pRenderer->pRenderD3D) + { + if (pLines.uNumLines) + { + pRenderer->DrawLines(pLines.pLineVertices, pLines.uNumLines); + /*pRenderer->pRenderD3D->pDevice->SetTexture(0, 0); + pRenderer->pRenderD3D->pDevice->DrawPrimitive( + D3DPT_LINELIST, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + pLines.pLineVertices, + pLines.uNumLines, + D3DDP_DONOTLIGHT);*/ + } + } +} + +//----- (0048AC65) -------------------------------------------------------- +void ParticleEngine::UpdateParticles() +{ + unsigned int time; // edi@1 + //int v5; // eax@3 + //char v6; // sf@4 + float v7; // ST4C_4@11 + double v8; // st7@12 + //int v9; // eax@12 + //double v10; // st7@14 + signed int v19; // [sp+38h] [bp-14h]@1 + int v20; // [sp+3Ch] [bp-10h]@1 + unsigned int time_; // [sp+40h] [bp-Ch]@1 + int v22; // [sp+44h] [bp-8h]@12 + + v20 = 0; + time = pMiscTimer->bPaused == 0 ? pEventTimer->uTimeElapsed : 0; + v19 = 500; + time_ = pMiscTimer->bPaused == 0 ? pEventTimer->uTimeElapsed : 0; + + for (uint i = uStartParticle; i <= uEndParticle; ++i) + { + Particle* p = &pParticles[i]; + + if (p->type == ParticleType_Invalid) + continue; + + if (p->timeToLive <= time) + { + p->timeToLive = 0; + p->type = ParticleType_Invalid; + continue; + } + p->timeToLive -= time; + + if (p->type & ParticleType_Line) + { + p->_x = p->x; + p->_y = p->y; + p->_z = p->z; + } + + if (p->type & ParticleType_1) + p->flt_18 = p->flt_18 - (double)(signed int)time_ * 5.0; + + if (p->type & ParticleType_8) + { + v7 = (double)(signed int)time_; + *(float *)&p->x += (double)(rand() % 5 - 2) * v7 / 16.0f; + *(float *)&p->y += (double)(rand() % 5 - 2) * v7 / 16.0f; + *(float *)&p->z += (double)(rand() % 5 + 4) * v7 / 16.0f; + } + v8 = (double)(signed int)time_ / 128.0f; + //v9 = (signed int)(time * p->rotation_speed) / 16; + + p->x += v8 * p->flt_10; + p->y += v8 * p->flt_14; + p->z += v8 * p->flt_18; + + p->angle += time * p->rotation_speed / 16; + v22 = 2 * p->timeToLive; + if (v22 >= 255 ) + v22 = 255; + //v10 = (double)v22 * 0.0039215689; + p->uLightColor_bgr = ((uint)floorf(p->b * (v22 / 255.0f) + 0.5) << 16) | + ((uint)floorf(p->g * (v22 / 255.0f) + 0.5) << 8) | + ((uint)floorf(p->r * (v22 / 255.0f) + 0.5) << 0); + if ( i < v19 ) + v19 = i; + if ( i > v20 ) + v20 = i; + } + + uEndParticle = v20; + uStartParticle = v19; +} + +//----- (0048AE74) -------------------------------------------------------- +bool ParticleEngine::ViewProject_TrueIfStillVisible_BLV(unsigned int uParticleID) +{ + Particle *pParticle; // esi@1 + //double v56; // ST28_8@2 + //float v4; // eax@4 + //double v5; // ST34_8@4 + signed __int64 v6; // qtt@4 + //double v7; // st7@4 + //float v8; // ST18_4@4 +// int v9; // ecx@4 + //int v10; // eax@4 + //double v11; // ST44_8@7 + //double v12; // ST4C_8@7 +// double v13; // ST4C_8@7 +// int v14; // ecx@7 + //signed __int64 v15; // qtt@7 +// int v16; // eax@7 +// int v17; // edx@7 +// float v18; // edx@7 +// int v19; // eax@7 +// int v20; // edx@7 +// int v21; // ST50_4@8 +// int v22; // ebx@8 +// int v23; // ecx@10 +// int v24; // edi@10 + //double v25; // ST44_8@12 + //double v26; // ST4C_8@12 +// int v27; // edi@12 +// int v28; // ST40_4@12 +// int v29; // ecx@12 + //signed __int64 v30; // qtt@12 +// int v31; // eax@12 +// int v32; // edx@12 +// float v33; // edx@12 + //int v34; // eax@12 +// int v35; // ecx@12 +// int v36; // ST38_4@13 +// int v37; // ST30_4@15 +// int v38; // eax@16 + //signed __int64 v40; // qtt@18 +// int v41; // eax@18 +// int v42; // ecx@18 +// int v43; // eax@18 +// unsigned __int64 v44; // qax@18 + //double v45; // st7@18 + //int v46; // ecx@18 + //float v47; // ST18_4@18 + //unsigned __int64 v48; // qax@18 + int y_int_; // [sp+10h] [bp-40h]@2 +// int a2; // [sp+18h] [bp-38h]@10 + int x_int; // [sp+20h] [bp-30h]@2 + int z_int_; // [sp+24h] [bp-2Ch]@2 +// int z_int_4; // [sp+28h] [bp-28h]@8 + int z; // [sp+3Ch] [bp-14h]@3 +// double a5; // [sp+40h] [bp-10h]@4 +// int a6; // [sp+48h] [bp-8h]@4 + int y; // [sp+4Ch] [bp-4h]@3 + + pParticle = &this->pParticles[uParticleID]; + if (pParticle->type == ParticleType_Invalid) + return 0; + //uParticleID = LODWORD(pParticle->x); + //v56 = *(float *)&uParticleID + 6.7553994e15; + x_int = floorf(pParticle->x + 0.5f); + //uParticleID = LODWORD(pParticle->y); + //y_int_ = *(float *)&uParticleID + 6.7553994e15; + y_int_ = floorf(pParticle->y + 0.5f); + //uParticleID = LODWORD(pParticle->z); + //z_int_ = *(float *)&uParticleID + 6.7553994e15; + z_int_ = floorf(pParticle->z + 0.5f); + /*if ( !pRenderer->pRenderD3D ) + { + if (pGame->pIndoorCameraD3D->sRotationX) + { + if (pParticle->type & ParticleType_Line) + { + //v11 = pParticle->_x + 6.7553994e15; + int _uParticleID = (int)(floorf(pParticle->_x + 0.5f) - pBLVRenderParams->vPartyPos.x) << 16; + //v12 = pParticle->_y + 6.7553994e15; + y = (int)(floorf(pParticle->_y + 0.5f) - pBLVRenderParams->vPartyPos.y) << 16; + z = (unsigned __int64)(y * (signed __int64)pGame->pIndoorCameraD3D->int_sine_y) >> 16; + HIDWORD(a5) = ((unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16) + - z; + a6 = (unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_sine_y) >> 16; + //v13 = pParticle->_z + 6.7553994e15; + _uParticleID = (int)(floorf(pParticle->_z + 0.5f) - pBLVRenderParams->vPartyPos.z) << 16; + z = ((unsigned __int64)(SHIDWORD(a5) * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_x) >> 16) + - ((unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_sine_x) >> 16); + v14 = z; + HIDWORD(v13) = (unsigned __int64)(SHIDWORD(a5) * (signed __int64)pGame->pIndoorCameraD3D->int_sine_x) >> 16; + HIDWORD(a5) = (unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_x) >> 16; + //LODWORD(v15) = pBLVRenderParams->field_40 << 16; + //HIDWORD(v15) = pBLVRenderParams->field_40 >> 16; + //v16 = v15 / z; + v16 = fixpoint_div(pBLVRenderParams->field_40, z); + v17 = (unsigned __int64)(y * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16; + pParticle->_screenspace_scale = v16; + _uParticleID = (unsigned __int64)(v16 * (signed __int64)(a6 + v17)) >> 16; + LODWORD(v18) = pBLVRenderParams->uViewportCenterX + - ((signed int)((unsigned __int64)(v16 * (signed __int64)(a6 + v17)) >> 16) >> 16); + v19 = pParticle->_screenspace_scale; + pParticle->uScreenSpaceZ = v18; + _uParticleID = (unsigned __int64)(v19 * (signed __int64)(HIDWORD(v13) + HIDWORD(a5))) >> 16; + v20 = pBLVRenderParams->uViewportCenterY + - ((signed int)((unsigned __int64)(v19 * (signed __int64)(HIDWORD(v13) + HIDWORD(a5))) >> 16) >> 16); + pParticle->sZValue2 = v14; + pParticle->uScreenSpaceW = v20; + } + int _uParticleID = (x_int - pBLVRenderParams->vPartyPos.x) << 16; + y = (y_int_ - pBLVRenderParams->vPartyPos.y) << 16; + HIDWORD(a5) = ((unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16) + - ((unsigned __int64)(y * (signed __int64)pGame->pIndoorCameraD3D->int_sine_y) >> 16); + a6 = (unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_sine_y) >> 16; + z_int_4 = (unsigned __int64)(y * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16; + _uParticleID = (z_int_ - pBLVRenderParams->vPartyPos.z) << 16; + v21 = (unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_sine_x) >> 16; + v22 = ((unsigned __int64)(SHIDWORD(a5) * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_x) >> 16) - v21; + z = ((unsigned __int64)(SHIDWORD(a5) * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_x) >> 16) - v21; + if ( v22 < (signed int)0x40000u || v22 > (signed int)0x1F400000u ) + return 0; + v23 = a6 + z_int_4; + a2 = a6 + z_int_4; + v24 = ((unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_x) >> 16) + + ((unsigned __int64)(SHIDWORD(a5) * (signed __int64)pGame->pIndoorCameraD3D->int_sine_x) >> 16); + } + else + { + if (pParticle->type & ParticleType_Line) + { + //v25 = pParticle->_x + 6.7553994e15; + int _uParticleID = ((int)floorf(pParticle->_x + 0.5f) - pBLVRenderParams->vPartyPos.x) << 16; + //v26 = pParticle->_y + 6.7553994e15; + y = ((int)floorf(pParticle->_y + 0.5f) - pBLVRenderParams->vPartyPos.y) << 16; + auto _hiword_v25 = (__int64)(y * (signed __int64)pGame->pIndoorCameraD3D->int_sine_y) >> 16; + v27 = ((unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16) - _hiword_v25; + z = ((unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16) - _hiword_v25; + v28 = (unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_sine_y) >> 16; + //a5 = pParticle->_z + 6.7553994e15; + v29 = ((int)floorf(pParticle->_z + 0.5f) - pBLVRenderParams->vPartyPos.z) << 16; + //LODWORD(v30) = pBLVRenderParams->field_40 << 16; + //HIDWORD(v30) = pBLVRenderParams->field_40 >> 16; + //v31 = v30 / z; + v31 = fixpoint_div(pBLVRenderParams->field_40, z); + v32 = (unsigned __int64)(y * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16; + pParticle->_screenspace_scale = v31; + _uParticleID = (unsigned __int64)(v31 * (signed __int64)(v28 + v32)) >> 16; + LODWORD(v33) = pBLVRenderParams->uViewportCenterX - ((signed int)((unsigned __int64)(v31 * (signed __int64)(v28 + v32)) >> 16) >> 16); + //v34 = pParticle->_screenspace_scale; + pParticle->uScreenSpaceZ = v33; + v35 = pBLVRenderParams->uViewportCenterY - ((signed int)((unsigned __int64)(pParticle->_screenspace_scale * (signed __int64)v29) >> 16) >> 16); + pParticle->sZValue2 = v27; + pParticle->uScreenSpaceW = v35; + } + int _uParticleID = (x_int - pBLVRenderParams->vPartyPos.x) << 16; + y = (y_int_ - pBLVRenderParams->vPartyPos.y) << 16; + v36 = (unsigned __int64)(y * (signed __int64)pGame->pIndoorCameraD3D->int_sine_y) >> 16; + v22 = ((unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16) - v36; + z = ((unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16) - v36; + if ( v22 < 262144 || v22 > 524288000 ) + return 0; + v37 = (unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_sine_y) >> 16; + _uParticleID = (unsigned __int64)(y * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16; + v23 = v37 + ((unsigned __int64)(y * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16); + a2 = v37 + ((unsigned __int64)(y * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16); + v24 = (z_int_ - pBLVRenderParams->vPartyPos.z) << 16; + } + int _uParticleID = abs(v23); + v38 = abs(v22); + if ( v38 >= (signed int)_uParticleID ) + { + //LODWORD(v40) = pBLVRenderParams->field_40 << 16; + //HIDWORD(v40) = pBLVRenderParams->field_40 >> 16; + v41 = fixpoint_div(pBLVRenderParams->field_40, z); + pParticle->_screenspace_scale = v41; + _uParticleID = (unsigned __int64)(v41 * (signed __int64)a2) >> 16; + v42 = pBLVRenderParams->uViewportCenterX - ((signed int)((unsigned __int64)(v41 * (signed __int64)a2) >> 16) >> 16); + v43 = pParticle->_screenspace_scale; + pParticle->uScreenSpaceX = v42; + v44 = v43 * (signed __int64)v24; + //uParticleID = v44 >> 16; + LODWORD(v44) = (signed int)(v44 >> 16) >> 16; + pParticle->uScreenSpaceY = pBLVRenderParams->uViewportCenterY - v44; + pParticle->_screenspace_scale = fixpoint_mul(fixpoint_from_float(pParticle->flt_28), pParticle->_screenspace_scale); + pParticle->sZValue = z; + return true; + } + return false; + }*/ + + int x; + if ( !pGame->pIndoorCameraD3D->ApplyViewTransform_TrueIfStillVisible_BLV( + x_int, + y_int_, + z_int_, + &x, + &y, + &z, + 1) ) + return false; + pGame->pIndoorCameraD3D->Project(x, y, z, &pParticle->uScreenSpaceX, &pParticle->uScreenSpaceY); + pParticle->flt_5C = pGame->pIndoorCameraD3D->fov_x; + //v4 = pParticle->flt_5C; + pParticle->flt_60 = pGame->pIndoorCameraD3D->fov_y; + //v5 = v4 + 6.7553994e15; + LODWORD(v6) = 0; + HIDWORD(v6) = floorf(pParticle->flt_5C + 0.5f); + //v7 = pParticle->flt_28; + //pParticle->_screenspace_scale = v6 / x; + //v8 = v7; + pParticle->_screenspace_scale = fixpoint_mul(fixpoint_from_float(pParticle->flt_28), v6 / x); + pParticle->sZValue = x; + return true; +} + + + + +//----- (0048B5B3) -------------------------------------------------------- +bool ParticleEngine::ViewProject_TrueIfStillVisible_ODM(unsigned int uID) +{ + int v3; // ebx@1 + int v4; // edi@1 + int v5; // ecx@1 + int v11; // ST44_4@4 + signed __int64 v13; // qtt@4 + int v16; // edi@6 + int v17; // eax@6 + signed __int64 v22; // qtt@8 + int v26; // edx@9 + int v28; // ebx@12 + signed __int64 v29; // qtt@13 + int v40; // [sp+14h] [bp-3Ch]@12 + int v44; // [sp+2Ch] [bp-24h]@1 + int v45; // [sp+40h] [bp-10h]@5 + int X_4; // [sp+48h] [bp-8h]@5 + + v3 = stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationX); + v44 = stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationX); + v4 = stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationY); + v5 = stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationY); + + if (pParticles[uID].type == ParticleType_Invalid) + return false; + + if ( v3 ) + { + if (pParticles[uID].type & ParticleType_Line) + { + v11 = fixpoint_sub_unknown(pParticles[uID].x - pGame->pIndoorCameraD3D->vPartyPos.x, v4) + + fixpoint_sub_unknown(pParticles[uID].y - pGame->pIndoorCameraD3D->vPartyPos.y, v5); + long long _hidword_v12 = fixpoint_mul(v11, v3) + fixpoint_sub_unknown(pParticles[uID].z - pGame->pIndoorCameraD3D->vPartyPos.z, v44); + LODWORD(v13) = 0; + HIDWORD(v13) = SLOWORD(pODMRenderParams->int_fov_rad); + pParticles[uID]._screenspace_scale = v13 / _hidword_v12; + pParticles[uID].uScreenSpaceX = pViewport->uScreenCenterX + - ((signed int)fixpoint_mul(pParticles[uID]._screenspace_scale, (fixpoint_sub_unknown(pParticles[uID].y + - pGame->pIndoorCameraD3D->vPartyPos.y, v4) + - fixpoint_sub_unknown(pParticles[uID].x - pGame->pIndoorCameraD3D->vPartyPos.x, v5))) >> 16); + pParticles[uID].uScreenSpaceY = pViewport->uScreenCenterY + - ((signed int)fixpoint_mul(pParticles[uID]._screenspace_scale, (fixpoint_sub_unknown(pParticles[uID].z + - pGame->pIndoorCameraD3D->vPartyPos.z, v3) + - fixpoint_mul(v11, v44))) >> 16); + pParticles[uID].sZValue = _hidword_v12; + } + v45 = fixpoint_sub_unknown(pParticles[uID].x - pGame->pIndoorCameraD3D->vPartyPos.x, v4) + fixpoint_sub_unknown(pParticles[uID].y + - pGame->pIndoorCameraD3D->vPartyPos.y, v5); + X_4 = fixpoint_sub_unknown(pParticles[uID].z - pGame->pIndoorCameraD3D->vPartyPos.z, v44) + fixpoint_mul(v45, v3); + if ( X_4 < 0x40000 ) + return 0; + v16 = fixpoint_sub_unknown(pParticles[uID].y - pGame->pIndoorCameraD3D->vPartyPos.y, v4) + - fixpoint_sub_unknown(pParticles[uID].x - pGame->pIndoorCameraD3D->vPartyPos.x, v5); + v17 = fixpoint_sub_unknown(pParticles[uID].z - pGame->pIndoorCameraD3D->vPartyPos.z, v3) - fixpoint_mul(v45, v44); + } + else + { + if (pParticles[uID].type & ParticleType_Line) + { + LODWORD(v22) = 0; + HIDWORD(v22) = SLOWORD(pODMRenderParams->int_fov_rad); + long long _var_123 = fixpoint_sub_unknown(pParticles[uID].x - pGame->pIndoorCameraD3D->vPartyPos.x, v4) + + fixpoint_sub_unknown(pParticles[uID].y - pGame->pIndoorCameraD3D->vPartyPos.y, v5); + pParticles[uID]._screenspace_scale = v22 / _var_123; + pParticles[uID].uScreenSpaceX = pViewport->uScreenCenterX + - ((signed int)fixpoint_mul(pParticles[uID]._screenspace_scale, (fixpoint_sub_unknown(pParticles[uID].y + - pGame->pIndoorCameraD3D->vPartyPos.y, v4) + - fixpoint_sub_unknown(pParticles[uID].x - pGame->pIndoorCameraD3D->vPartyPos.x, v5))) >> 16); + pParticles[uID].uScreenSpaceY = pViewport->uScreenCenterY - (fixpoint_sub_unknown(pParticles[uID].z, pParticles[uID]._screenspace_scale) >> 16); + pParticles[uID].sZValue = _var_123; + } + v26 = fixpoint_sub_unknown(pParticles[uID].y - pGame->pIndoorCameraD3D->vPartyPos.y, v5); + X_4 = v26 + fixpoint_sub_unknown(pParticles[uID].x - pGame->pIndoorCameraD3D->vPartyPos.x, v4); + if ( X_4 < 0x40000 || X_4 > (pODMRenderParams->uPickDepth - 1000) << 16 ) + return 0; + v17 = pParticles[uID].z; + v16 = fixpoint_sub_unknown(pParticles[uID].y - pGame->pIndoorCameraD3D->vPartyPos.y, v4) + - fixpoint_sub_unknown(pParticles[uID].x - pGame->pIndoorCameraD3D->vPartyPos.x, v5); + } + v40 = v17; + v28 = abs(v16); + if ( abs(X_4) >= v28 ) + { + LODWORD(v29) = 0; + HIDWORD(v29) = SLOWORD(pODMRenderParams->int_fov_rad); + pParticles[uID]._screenspace_scale = v29 / X_4; + pParticles[uID].uScreenSpaceX = pViewport->uScreenCenterX - ((signed int)fixpoint_mul(pParticles[uID]._screenspace_scale, v16) >> 16); + pParticles[uID].uScreenSpaceY = pViewport->uScreenCenterY - ((signed int)fixpoint_mul(pParticles[uID]._screenspace_scale, v40) >> 16); + pParticles[uID]._screenspace_scale = fixpoint_mul(fixpoint_from_float(pParticles[uID].flt_28), pParticles[uID]._screenspace_scale); + pParticles[uID].sZValue = X_4; + if ( pParticles[uID].uScreenSpaceX >= (signed int)pViewport->uViewportTL_X + && pParticles[uID].uScreenSpaceX < (signed int)pViewport->uViewportBR_X + && pParticles[uID].uScreenSpaceY >= (signed int)pViewport->uViewportTL_Y + && pParticles[uID].uScreenSpaceY < (signed int)pViewport->uViewportBR_Y ) + return true; + } + return false; +} + +//----- (0048BBA6) -------------------------------------------------------- +void ParticleEngine::DrawParticles_BLV() +{ +// int v11; // eax@18 +// int v12; // ecx@20 +// int v13; // edx@20 + //Particle *v14; // eax@28 + RenderBillboardTransform_local0 v15; // [sp+Ch] [bp-58h]@1 + + v15.sParentBillboardID = -1; + + for (uint i = uStartParticle; i < uEndParticle; ++i) + { + Particle* p = &pParticles[i]; + + if (p->type == ParticleType_Invalid) + continue; + + if (!ViewProject_TrueIfStillVisible_BLV(i)) + continue; + + if (p->uScreenSpaceX >= pBLVRenderParams->uViewportX && + p->uScreenSpaceX < pBLVRenderParams->uViewportZ && + p->uScreenSpaceY >= pBLVRenderParams->uViewportY && + p->uScreenSpaceY < pBLVRenderParams->uViewportW) + { + /*if (!pRenderer->pRenderD3D) + { + __debugbreak(); + v11 = 13 * p->_screenspace_scale >> 16; + if ( v11 > 30 ) + v11 = 30; + v12 = p->uScreenSpaceY - v11; + v13 = p->uScreenSpaceX - (v11 >> 1); + if ( v13 + v11 < (signed int)pViewport->uViewportTL_X + || v13 >= (signed int)pViewport->uViewportBR_X + || v12 + v11 < (signed int)pViewport->uViewportTL_Y + || v12 >= (signed int)pViewport->uViewportBR_Y ) + { + ; + } + else + { + pRenderer->MakeParticleBillboardAndPush_BLV_Software(v13, v12, p->sZValue, p->uLightColor_bgr, v11); + } + } + else*/ + + if (p->type & ParticleType_Diffuse) + { + //v14 = &pParticles[i]; + v15._screenspace_x_scaler_packedfloat = p->_screenspace_scale / 4; + v15._screenspace_y_scaler_packedfloat = p->_screenspace_scale / 4; + v15.uScreenSpaceX = p->uScreenSpaceX; + v15.uScreenSpaceY = p->uScreenSpaceY; + v15.sZValue = p->sZValue; + pRenderer->MakeParticleBillboardAndPush_BLV(&v15, 0, p->uLightColor_bgr, p->angle); + return; + } + if (p->type & ParticleType_Line) + { + if (pLines.uNumLines < 100) + { + pLines.pLineVertices[2 * pLines.uNumLines].pos.x = p->uScreenSpaceX; + pLines.pLineVertices[2 * pLines.uNumLines].pos.y = p->uScreenSpaceY; + pLines.pLineVertices[2 * pLines.uNumLines].pos.z = 1.0 - 1.0 / ((short)p->sZValue * 0.061758894); + pLines.pLineVertices[2 * pLines.uNumLines].rhw = 1.0; + pLines.pLineVertices[2 * pLines.uNumLines].diffuse = p->uLightColor_bgr; + pLines.pLineVertices[2 * pLines.uNumLines].specular = 0; + pLines.pLineVertices[2 * pLines.uNumLines].texcoord.x = 0.0; + pLines.pLineVertices[2 * pLines.uNumLines].texcoord.y = 0.0; + + pLines.pLineVertices[2 * pLines.uNumLines + 1].pos.x = p->uScreenSpaceZ; + pLines.pLineVertices[2 * pLines.uNumLines + 1].pos.y = p->uScreenSpaceW; + pLines.pLineVertices[2 * pLines.uNumLines + 1].pos.z = 1.0 - 1.0 / ((short)p->sZValue2 * 0.061758894); + pLines.pLineVertices[2 * pLines.uNumLines + 1].rhw = 1.0; + pLines.pLineVertices[2 * pLines.uNumLines + 1].diffuse = p->uLightColor_bgr; + pLines.pLineVertices[2 * pLines.uNumLines + 1].specular = 0; + pLines.pLineVertices[2 * pLines.uNumLines + 1].texcoord.x = 0.0; + pLines.pLineVertices[2 * pLines.uNumLines++ + 1].texcoord.y = 0.0; + } + } + if (p->type & ParticleType_Bitmap) + { + v15._screenspace_x_scaler_packedfloat = p->_screenspace_scale; + v15._screenspace_y_scaler_packedfloat = p->_screenspace_scale; + v15.uScreenSpaceX = p->uScreenSpaceX; + v15.uScreenSpaceY = p->uScreenSpaceY; + v15.sZValue = p->sZValue; + pRenderer->MakeParticleBillboardAndPush_BLV(&v15, pBitmaps_LOD->pHardwareTextures[p->uTextureID], p->uLightColor_bgr, p->angle); + } + if (p->type & ParticleType_Sprite) + { + v15._screenspace_x_scaler_packedfloat = p->_screenspace_scale; + v15._screenspace_y_scaler_packedfloat = p->_screenspace_scale; + v15.uScreenSpaceX = p->uScreenSpaceX; + v15.uScreenSpaceY = p->uScreenSpaceY; + v15.sZValue = p->sZValue; + pRenderer->MakeParticleBillboardAndPush_BLV(&v15, pSprites_LOD->pHardwareSprites[p->uTextureID].pTexture, p->uLightColor_bgr, p->angle); + } + } + } +} + +//----- (0048BEEF) -------------------------------------------------------- +void ParticleEngine::DrawParticles_ODM() +{ + ParticleEngine *pParticleEngine; // esi@1 + //int pParticleNum; // eax@1 +// unsigned __int8 v3; // zf@1 +// char v4; // sf@1 +// unsigned __int8 v5; // of@1 + //char *v7; // edi@2 + //int v8; // eax@6 + //signed int pNumLines; // eax@8 +// int v10; // eax@14 +// int v11; // ecx@16 +// int v12; // edx@16 + //Particle *pParticle; // eax@24 + RenderBillboardTransform_local0 pBillboard; // [sp+Ch] [bp-58h]@1 + //int v15; // [sp+5Ch] [bp-8h]@9 +// int v16; // [sp+60h] [bp-4h]@1 + + pBillboard.sParentBillboardID = -1; + pParticleEngine = this; + //v2 = this->uStartParticle; + //v5 = v2 > this->uEndParticle;// v5 = __OFSUB__(v2, this->uEndParticle); + //v3 = v2 == this->uEndParticle; + //v4 = v2 - this->uEndParticle < 0; + //v16 = this->uStartParticle; + for (uint i = uStartParticle; i <= uEndParticle; ++i) + { + Particle* particle = &pParticles[i]; + if (particle->type == ParticleType_Invalid || !ViewProject_TrueIfStillVisible_ODM(i)) + continue; + + /*if ( !pRenderer->pRenderD3D ) + { + __debugbreak(); + v10 = 13 * particle->_screenspace_scale >> 16; + if ( v10 > 30 ) + v10 = 30; + v11 = particle->uScreenSpaceX - (v10 >> 1); + v12 = particle->uScreenSpaceY - v10; + if ( v11 + v10 < pViewport->uViewportTL_X + || v11 >= pViewport->uViewportBR_X + || particle->uScreenSpaceY < pViewport->uViewportTL_Y + || v12 >= (signed int)pViewport->uViewportBR_Y ) + { + ; + } + else + { + pRenderer->MakeParticleBillboardAndPush_BLV_Software(v11, v12, particle->sZValue, particle->uLightColor_bgr, v10); + } + } + else*/ + + //v8 = *(_DWORD *)(v7 - 82); + if (particle->type & ParticleType_Diffuse) + { + pBillboard._screenspace_x_scaler_packedfloat = particle->_screenspace_scale / 4; + pBillboard._screenspace_y_scaler_packedfloat = particle->_screenspace_scale / 4; + pBillboard.uScreenSpaceX = particle->uScreenSpaceX; + pBillboard.uScreenSpaceY = particle->uScreenSpaceY; + pBillboard.sZValue = particle->sZValue; + pRenderer->MakeParticleBillboardAndPush_ODM(&pBillboard, 0, particle->uLightColor_bgr, particle->angle); + return; + } + if (particle->type & ParticleType_Line) + { + if (pLines.uNumLines < 100) + { + pLines.pLineVertices[2 * pLines.uNumLines].pos.x = particle->uScreenSpaceX; + pLines.pLineVertices[2 * pLines.uNumLines].pos.y = particle->uScreenSpaceY; + pLines.pLineVertices[2 * pLines.uNumLines].pos.z = 1.0 - 1.0 / ((double)particle->zbuffer_depth * 1000.0 / (double)pODMRenderParams->shading_dist_mist); + pLines.pLineVertices[2 * pLines.uNumLines].rhw = 1.0; + pLines.pLineVertices[2 * pLines.uNumLines].diffuse = particle->uLightColor_bgr; + pLines.pLineVertices[2 * pLines.uNumLines].specular = 0; + pLines.pLineVertices[2 * pLines.uNumLines].texcoord.x = 0.0; + pLines.pLineVertices[2 * pLines.uNumLines].texcoord.y = 0.0; + + pLines.pLineVertices[2 * pLines.uNumLines + 1].pos.x = particle->uScreenSpaceZ; + pLines.pLineVertices[2 * pLines.uNumLines + 1].pos.y = particle->uScreenSpaceW; + pLines.pLineVertices[2 * pLines.uNumLines + 1].pos.z = 1.0 - 1.0 / ((double)particle->zbuffer_depth * 1000.0 / (double)pODMRenderParams->shading_dist_mist); + pLines.pLineVertices[2 * pLines.uNumLines + 1].rhw = 1.0; + pLines.pLineVertices[2 * pLines.uNumLines + 1].diffuse = particle->uLightColor_bgr; + pLines.pLineVertices[2 * pLines.uNumLines + 1].specular = 0; + pLines.pLineVertices[2 * pLines.uNumLines + 1].texcoord.x = 0.0; + pLines.pLineVertices[2 * pLines.uNumLines + 1].texcoord.y = 0.0; + pLines.uNumLines++; + } + } + if (particle->type & ParticleType_Bitmap) + { + pBillboard._screenspace_x_scaler_packedfloat = particle->_screenspace_scale; + pBillboard._screenspace_y_scaler_packedfloat = particle->_screenspace_scale; + pBillboard.uScreenSpaceX = particle->uScreenSpaceX; + pBillboard.uScreenSpaceY = particle->uScreenSpaceY; + pBillboard.sZValue = particle->sZValue; + pRenderer->MakeParticleBillboardAndPush_ODM(&pBillboard, pBitmaps_LOD->pHardwareTextures[particle->uTextureID], particle->uLightColor_bgr, particle->angle); + } + if (particle->type & ParticleType_Sprite) + { + pBillboard._screenspace_x_scaler_packedfloat = particle->_screenspace_scale; + pBillboard._screenspace_y_scaler_packedfloat = particle->_screenspace_scale; + pBillboard.uScreenSpaceX = particle->uScreenSpaceX; + pBillboard.uScreenSpaceY = particle->uScreenSpaceY; + pBillboard.sZValue = particle->sZValue; + pRenderer->MakeParticleBillboardAndPush_ODM(&pBillboard, pSprites_LOD->pHardwareSprites[particle->uTextureID].pTexture, particle->uLightColor_bgr, particle->angle); + } + } +} \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/ParticleEngine.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/ParticleEngine.h Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,199 @@ +#pragma once +#include "Render.h" + + + +enum ParticleType: unsigned __int32 +{ + ParticleType_Invalid = 0, + ParticleType_1 = 0x0001, + ParticleType_Rotating = 0x0004, + ParticleType_8 = 0x0008, + ParticleType_Diffuse = 0x0100, // colored plane + ParticleType_Line = 0x0200, // line + ParticleType_Bitmap = 0x0400, // textured planed + ParticleType_Sprite = 0x0800 +}; + +/* 305 */ +#pragma pack(push, 1) +struct Particle_sw +{ + unsigned int type; + float x; + float y; + float z; + float r; + float g; + float b; + unsigned int uDiffuse; + int timeToLive; + unsigned int uTextureID; + float flt_28; + int field_2C; + int field_30; + int field_34; + int field_38[12]; +}; +#pragma pack(pop) + + + +/* 109 */ +#pragma pack(push, 1) +struct Particle +{ + unsigned int type; + float x; + float y; + float z; + float flt_10; + float flt_14; + float flt_18; + union + { + struct + { + unsigned char r, g, b, a; + }; + unsigned int uParticleColor; + }; + int timeToLive; + unsigned int uTextureID; + float flt_28; + float _x; + float _y; + float _z; + int rotation_speed; + int angle; + int uScreenSpaceX; + int uScreenSpaceY; + int uScreenSpaceZ; // line end x + int uScreenSpaceW; // line end y + union + { + int sZValue; + struct + { + unsigned short object_pid; + short zbuffer_depth; + }; + }; + int sZValue2; // line end z + int _screenspace_scale; + float flt_5C; + float flt_60; + int uLightColor_bgr; +}; +#pragma pack(pop) + + + +/* 111 */ +#pragma pack(push, 1) +struct stru2_LineList +{ + unsigned int uNumLines; + RenderVertexD3D3 pLineVertices[48]; + char field_604[60]; +}; +#pragma pack(pop) + + + + + +/* 110 */ +#pragma pack(push, 1) +class ParticleEngine +{ +public: + ParticleEngine(); + + void ResetParticles(); + void AddParticle(Particle_sw *a2); + void Draw(); + void UpdateParticles(); + bool ViewProject_TrueIfStillVisible_BLV(unsigned int uParticleID); + bool ViewProject_TrueIfStillVisible_ODM(unsigned int uID); + void DrawParticles_BLV(); + void DrawParticles_ODM(); + + Particle pParticles[500]; + stru2_LineList pLines; + char field_D160[4800]; + float field_E420; + int uStartParticle; + int uEndParticle; + int uTimeElapsed; +}; +#pragma pack(pop) + + + + + + + + + + + +/* 160 */ +#pragma pack(push, 1) +struct TrailParticle // stru167 +{ + inline TrailParticle() + { + x = 0; + y = 0; + z = 0; + time_left = 0; + time_to_live = 0; + bgr16 = 0; + } + + char field_0; + char field_1; + char field_2; + char field_3; + char field_4; + char field_5; + __int16 x; + __int16 y; + __int16 z; + __int16 time_left; + __int16 time_to_live; + char field_10; + char field_11; + char field_12; + char field_13; + __int16 bgr16; + char field_16; + char field_17; +}; +#pragma pack(pop) + + +/* 363 */ +#pragma pack(push, 1) +struct TrailParticleGenerator // stru167_wrap +{ + public: + inline TrailParticleGenerator() + { + num_particles = 0; + } + + void GenerateTrailParticles(int x, int y, int z, int bgr16); + void UpdateParticles(); + + protected: + void AddParticle(int x, int y, int z, int bgr16); + + TrailParticle particles[100]; + int num_particles; + int field_964; +}; +#pragma pack(pop) +extern TrailParticleGenerator trail_particle_generator; // 005118E8 \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/Render.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/Render.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,11264 @@ +#define _CRTDBG_MAP_ALLOC +#include +#include + +#define _CRT_SECURE_NO_WARNINGS + +#include "ZlibWrapper.h" +#include "ErrorHandling.h" + +#include "Render.h" +#include "MediaPlayer.h" +#include "Sprites.h" +#include "Mouse.h" +#include "Engine/Graphics/GammaControl.h" +#include "stru6.h" +#include "GUIWindow.h" +#include "DecalBuilder.h" +#include "ParticleEngine.h" +#include "Outdoor.h" +#include "Party.h" +#include "LOD.h" +#include "Viewport.h" +#include "OurMath.h" +#include "PaletteManager.h" +#include "Timer.h" +#include "Game.h" +#include "LightmapBuilder.h" +#include "ObjectList.h" +#include "SpriteObject.h" +#include "DecorationList.h" +#include "Actor.h" +#include "Log.h" +#include "MM7.h" +#include "Lights.h" +#include "Engine/Graphics/Level/Decoration.h" +#include "Vis.h" +#include "Registry.h" +#include "Weather.h" +#include "MMT.h" + + +//#pragma comment(lib, "lib\\legacy_dx\\lib\\ddraw.lib") +//#pragma comment(lib, "lib\\legacy_dx\\lib\\dxguid.lib") + +struct IDirectDrawClipper *pDDrawClipper; +struct IRender *pRenderer; // idb +struct RenderVertexD3D3 pVertices[50]; +int uNumDecorationsDrawnThisFrame; // weak +RenderBillboard pBillboardRenderList[500]; +unsigned int uNumBillboardsToDraw; +int uNumSpritesDrawnThisFrame; // weak + +RenderVertexSoft array_507D30[50]; +RenderVertexSoft array_50AC10[50]; +RenderVertexSoft array_73D150[20]; + +RenderVertexD3D3 d3d_vertex_buffer[50]; + +/* 384 */ +#pragma pack(push, 1) +struct PCXHeader_1 +{ + char manufacturer; + char version; + char encoding; + char bpp; + __int16 left; + __int16 up; + __int16 right; + __int16 bottom; + __int16 hdpi; + __int16 vdpi; +}; +#pragma pack(pop) + +/* 385 */ +#pragma pack(push, 1) +struct PCXHeader_2 +{ + char reserved; + char planes; + __int16 pitch; + __int16 palette_info; +}; +#pragma pack(pop) + +HRESULT __stdcall D3DZBufferFormatEnumerator(DDPIXELFORMAT *Src, DDPIXELFORMAT *Dst); +HRESULT __stdcall DDrawDisplayModesEnumerator(DDSURFACEDESC2 *pSurfaceDesc, __int16 *a2); +HRESULT __stdcall D3DDeviceEnumerator(const GUID *lpGUID, const char *lpDeviceDesc, const char *lpDeviceName, D3DDEVICEDESC *pHWDesc, D3DDEVICEDESC *pSWDesc, struct RenderD3D_aux *a6); +signed int __stdcall RenderD3D__DeviceEnumerator(GUID *lpGUID, const char *lpDevDesc, const char *lpDriverName, RenderD3D__DevInfo *pOut); // idb + +//----- (0049E79F) -------------------------------------------------------- +bool Render::CheckTextureStages() +{ + bool v0; // edi@1 + IDirectDrawSurface4 *pSurface2; // [sp+Ch] [bp-14h]@1 + IDirectDrawSurface4 *pSurface1; // [sp+10h] [bp-10h]@1 + DWORD v4; // [sp+14h] [bp-Ch]@1 + IDirect3DTexture2 *pTexture2; // [sp+18h] [bp-8h]@1 + IDirect3DTexture2 *pTexture1; // [sp+1Ch] [bp-4h]@1 + + v0 = false; + pRenderD3D->CreateTexture(64, 64, &pSurface1, &pTexture1, true, false, 32); + pRenderD3D->CreateTexture(64, 64, &pSurface2, &pTexture2, true, false, 32); + + ErrD3D(pRenderD3D->pDevice->SetTexture(0, pTexture1)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLOROP, 2)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, 2)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, 2)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MINFILTER, 2)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, 1)); + + ErrD3D(pRenderD3D->pDevice->SetTexture(0, pTexture2)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_COLOROP, 7)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_COLORARG1, 2)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_COLORARG2, 1)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_MAGFILTER, 2)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_MINFILTER, 2)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_MIPFILTER, 1)); + + if ( !pRenderD3D->pDevice->ValidateDevice(&v4) && v4 == 1 ) + v0 = true; + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_COLOROP, 1)); + pTexture1->Release(); + pTexture2->Release(); + pSurface1->Release(); + pSurface2->Release(); + return v0; +} + + +//----- (00440CB8) -------------------------------------------------------- +void Render::DrawBillboardList_BLV() +{ + RenderBillboardTransform_local0 soft_billboard; // [sp+4h] [bp-50h]@1 + + soft_billboard.sParentBillboardID = -1; + soft_billboard.pTarget = pBLVRenderParams->pRenderTarget; + soft_billboard.pTargetZ = pBLVRenderParams->pTargetZBuffer; + soft_billboard.uTargetPitch = uTargetSurfacePitch; + soft_billboard.uViewportX = pBLVRenderParams->uViewportX; + soft_billboard.uViewportY = pBLVRenderParams->uViewportY; + soft_billboard.uViewportZ = pBLVRenderParams->uViewportZ - 1; + soft_billboard.uViewportW = pBLVRenderParams->uViewportW; + + pODMRenderParams->uNumBillboards = ::uNumBillboardsToDraw; + for (uint i = 0; i < ::uNumBillboardsToDraw; ++i) + { + RenderBillboard* p = &pBillboardRenderList[i]; + + soft_billboard.uScreenSpaceX = p->uScreenSpaceX; + soft_billboard.sParentBillboardID = i; + soft_billboard.uScreenSpaceY = p->uScreenSpaceY; + soft_billboard._screenspace_x_scaler_packedfloat = p->_screenspace_x_scaler_packedfloat; + soft_billboard._screenspace_y_scaler_packedfloat = p->_screenspace_y_scaler_packedfloat; + soft_billboard.sZValue = p->sZValue; + soft_billboard.uFlags = p->field_1E; + soft_billboard.sTintColor = p->sTintColor; + if ( p->HwSpriteID != -1 ) + { + if ( pRenderD3D ) + DrawBillboard_Indoor(&soft_billboard, &pSprites_LOD->pHardwareSprites[p->HwSpriteID], p->dimming_level); + else + { + soft_billboard.pPalette = PaletteManager::Get_Dark_or_Red_LUT(p->uPalette, p->dimming_level, 1); + if (p->field_1E & 0x0100) + soft_billboard.pPalette = pPaletteManager->field_261600[p->uPalette]; + if ( !(soft_billboard.uFlags & 0x40) && soft_billboard.uFlags & 0x80 ) + soft_billboard.pPalette2 = PaletteManager::Get_Dark_or_Red_LUT(p->uPalette, 0, 1); + if ( p->HwSpriteID >= 0 ) + pSprites_LOD->pSpriteHeaders[p->HwSpriteID].DrawSprite_sw(&soft_billboard, 1); + } + } + } +} + +//----- (004A16A5) -------------------------------------------------------- +bool Render::AreRenderSurfacesOk() +{ + return pFrontBuffer4 && pBackBuffer4; +} + + +//----- (004A19D8) -------------------------------------------------------- +unsigned int BlendColors(unsigned int a1, unsigned int a2) +{ + /*signed __int64 v2; // ST10_8@1 + double v3; // st7@1 + float v4; // ST24_4@1 + double v5; // ST10_8@1 + int v6; // ST1C_4@1 + float v7; // ST24_4@1 + double v8; // ST10_8@1 + unsigned __int8 v9; // ST20_1@1 + float v10; // ST24_4@1 + double v11; // ST10_8@1 + float v12; // ST24_4@1 + double v13; // ST08_8@1*/ + + uint alpha = (uint)floorf(0.5f + (a1 >> 24) / 255.0f * + (a2 >> 24) / 255.0f * 255.0f), + red = (uint)floorf(0.5f + ((a1 >> 16) & 0xFF) / 255.0f * + ((a2 >> 16) & 0xFF) / 255.0f * 255.0f), + green = (uint)floorf(0.5f + ((a1 >> 8) & 0xFF) / 255.0f * + ((a2 >> 8) & 0xFF) / 255.0f * 255.0f), + blue = (uint)floorf(0.5f + ((a1 >> 0) & 0xFF) / 255.0f * + ((a2 >> 0) & 0xFF) / 255.0f * 255.0f); + return (alpha << 24) | (red << 16) | (green << 8) | blue; + /*v2 = a1 >> 24; + v3 = (double)v2 / 255.0f; + HIDWORD(v2) = 0; + LODWORD(v2) = a2 >> 24; + v4 = v3 * (double)v2 / 255.0f * 255.0; + v5 = v4 + 6.7553994e15; + v6 = LODWORD(v5); + v7 = (double)((a1 >> 16) & 0xFFi64) / 255.0f * (double)((a2 >> 16) & 0xFF) * 0.0039215689 * 255.0; + v8 = v7 + 6.7553994e15; + v9 = LOBYTE(v8); + v10 = (double)((unsigned __int16)a1 >> 8) / 255.0f * (double)((unsigned __int16)a2 >> 8) / 255.0f * 255.0; + v11 = v10 + 6.7553994e15; + v12 = (double)(a1 & 0xFFi64) / 255.0f * (double)(unsigned __int8)a2 / 255.0f * 255.0; + v13 = v12 + 6.7553994e15; + return LOBYTE(v13) | ((LOBYTE(v11) | (((v6 << 8) | v9) << 8)) << 8);*/ +} + + +void Render::RenderTerrainD3D() // New function +{ + int v6; // ecx@8 + struct Polygon *pTilePolygon; // ebx@8 + float Light_tile_dist; + + //warning: the game uses CW culling by default, ccw is incosistent + pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CCW); + + static RenderVertexSoft pTerrainVertices[128 * 128];//vertexCountX and vertexCountZ + + //Генерация местоположения вершин------------------------------------------------------------------------- + //решётка вершин делится на две части от -64 до 0 и от 0 до 64 + // + // -64 X 0 64 + // --------------- 64 + // | | | + // | | | + // | | | + // 0|------+------| Z + // | | | + // | | | + // | | | + // --------------- + // -64 + + int blockScale = 512; + int heightScale = 32; + for (unsigned int z = 0; z < 128; ++z) + { + for (unsigned int x = 0; x < 128; ++x) + { + pTerrainVertices[z * 128 + x].vWorldPosition.x = (-64 + (signed)x) * blockScale; + pTerrainVertices[z * 128 + x].vWorldPosition.y = (64 - (signed)z) * blockScale; + pTerrainVertices[z * 128 + x].vWorldPosition.z = heightScale * pOutdoor->pTerrain.pHeightmap[z * 128 + x]; + pGame->pIndoorCameraD3D->ViewTransform(&pTerrainVertices[z * 128 + x], 1); + pGame->pIndoorCameraD3D->Project(&pTerrainVertices[z * 128 + x], 1, 0); + } + } +//-------(Отсечение невидимой части карты)------------------------------------------------------------------------------------------ + float direction = (float)(pGame->pIndoorCameraD3D->sRotationY / 256);//direction of the camera(напрвление камеры) + //0-East(B) + //1-NorthEast(CB) + //2-North(C) + //3-WestNorth(CЗ) + //4-West(З) + //5-SouthWest(ЮЗ) + //6-South(Ю) + //7-SouthEast(ЮВ) + unsigned int Start_X, End_X, Start_Z, End_Z; + if ( direction >= 0 && direction < 1.0 )//East(B) - NorthEast(CB) + { + Start_X = pODMRenderParams->uMapGridCellX - 2, End_X = 127; + Start_Z = 0, End_Z = 127; + } + else if (direction >= 1.0 && direction < 3.0)//NorthEast(CB) - WestNorth(CЗ) + { + Start_X = 0, End_X = 127; + Start_Z = 0, End_Z = pODMRenderParams->uMapGridCellZ + 1; + } + else if (direction >= 3.0 && direction < 5.0)//WestNorth(CЗ) - SouthWest(ЮЗ) + { + Start_X = 0, End_X = pODMRenderParams->uMapGridCellX + 2; + Start_Z = 0, End_Z = 127; + } + else if ( direction >= 5.0 && direction < 7.0 )//SouthWest(ЮЗ) - //SouthEast(ЮВ) + { + Start_X = 0, End_X = 127; + Start_Z = pODMRenderParams->uMapGridCellZ - 2, End_Z = 127; + } + else//SouthEast(ЮВ) - East(B) + { + Start_X = pODMRenderParams->uMapGridCellX - 2, End_X = 127; + Start_Z = 0, End_Z = 127; + } + for (unsigned int z = Start_Z; z < End_Z; ++z) + { + for (unsigned int x = Start_X; x < End_X; ++x) + { + pTilePolygon = &array_77EC08[pODMRenderParams->uNumPolygons]; + pTilePolygon->flags = 0; + pTilePolygon->field_32 = 0; + pTilePolygon->uTileBitmapID = pOutdoor->DoGetTileTexture(x, z); + pTilePolygon->pTexture = (Texture *)&pBitmaps_LOD->pHardwareTextures[pTilePolygon->uTileBitmapID]; + if (pTilePolygon->uTileBitmapID == 0xFFFF) + continue; + + //pTile->flags = 0x8010 |pOutdoor->GetSomeOtherTileInfo(x, z); + pTilePolygon->flags = pOutdoor->GetSomeOtherTileInfo(x, z); + pTilePolygon->field_32 = 0; + pTilePolygon->field_59 = 1; + pTilePolygon->sTextureDeltaU = 0; + pTilePolygon->sTextureDeltaV = 0; +// x,z x+1,z +// .____________. +// | | +// | | +// | | +// | | +// | | +// .____________. +// x,z+1 x+1,z+1 + memcpy(&array_73D150[0], &pTerrainVertices[z * 128 + x], sizeof(RenderVertexSoft));//x, z + array_73D150[0].u = 0; + array_73D150[0].v = 0; + memcpy(&array_73D150[1], &pTerrainVertices[z * 128 + x + 1], sizeof(RenderVertexSoft));//x + 1, z + array_73D150[1].u = 1; + array_73D150[1].v = 0; + memcpy(&array_73D150[2], &pTerrainVertices[(z + 1) * 128 + x + 1], sizeof(RenderVertexSoft));//x + 1, z + 1 + array_73D150[2].u = 1; + array_73D150[2].v = 1; + memcpy(&array_73D150[3], &pTerrainVertices[(z + 1) * 128 + x], sizeof(RenderVertexSoft));//x, z + 1 + array_73D150[3].u = 0; + array_73D150[3].v = 1; + //v58 = 0; + //if (v58 == 4) // if all y == first y; primitive in xz plane + //pTile->field_32 |= 0x0001; + pTilePolygon->pODMFace = nullptr; + pTilePolygon->uNumVertices = 4; + pTilePolygon->field_59 = 5; + +//shading (затенение)---------------------------------------------------------------------------- + //uint norm_idx = pTerrainNormalIndices[2 * (z * 128 + x) + 1]; + uint norm_idx = pTerrainNormalIndices[2 * (x * 128 + z) + 2]; + assert(norm_idx < uNumTerrainNormals); + + Vec3_float_* norm = &pTerrainNormals[norm_idx]; + float _f = ((norm->x * (float)pOutdoor->vSunlight.x / 65536.0) - + (norm->y * (float)pOutdoor->vSunlight.y / 65536.0) - + (norm->z * (float)pOutdoor->vSunlight.z / 65536.0)); + pTilePolygon->dimming_level = 20.0 - floorf(20.0 * _f + 0.5f); + if ( norm_idx < 0 || norm_idx > uNumTerrainNormals - 1 ) + norm = 0; + else + norm = &pTerrainNormals[norm_idx]; + if (for_refactoring) + { + MessageBoxA(nullptr, "Ritor1: function StackLights_TerrainFace needed refactoring and result - slows", "", 0); + __debugbreak(); + } + //pGame->pLightmapBuilder->StackLights_TerrainFace(norm, &Light_tile_dist, array_50AC10, 4, 1);//Ritor1: slows + //pDecalBuilder->_49BE8A(pTilePolygon, norm, &Light_tile_dist, array_50AC10, 4, 1); + //unsigned int a5 = 4; +//---------------------------------------------------------------------------- + + ++pODMRenderParams->uNumPolygons; + ++pODMRenderParams->field_44; + assert(pODMRenderParams->uNumPolygons < 20000); + + pTilePolygon->uBModelID = 0; + pTilePolygon->uBModelFaceID = 0; + pTilePolygon->field_50 = (8 * (0 | (0 << 6))) | 6; + for (unsigned int k = 0; k < pTilePolygon->uNumVertices; ++k) + { + memcpy(&array_50AC10[k], &array_73D150[k], sizeof(struct RenderVertexSoft)); + array_50AC10[k]._rhw = 1.0 / (array_73D150[k].vWorldViewPosition.x + 0.0000001000000011686097); + } +//---------Draw distance(Дальность отрисовки)------------------------------- + int temp = pODMRenderParams->shading_dist_mist; + if ( draw_terrain_dist_mist ) + pODMRenderParams->shading_dist_mist = 0x5000; + bool neer_clip = array_73D150[0].vWorldViewPosition.x < 8.0 + || array_73D150[1].vWorldViewPosition.x < 8.0 + || array_73D150[2].vWorldViewPosition.x < 8.0 + || array_73D150[3].vWorldViewPosition.x < 8.0; + bool far_clip = (double)pODMRenderParams->shading_dist_mist < array_73D150[0].vWorldViewPosition.x + || (double)pODMRenderParams->shading_dist_mist < array_73D150[1].vWorldViewPosition.x + || (double)pODMRenderParams->shading_dist_mist < array_73D150[2].vWorldViewPosition.x + || (double)pODMRenderParams->shading_dist_mist < array_73D150[3].vWorldViewPosition.x; + + /* int v33 = 0; + static stru154 static_sub_0048034E_stru_154; + pGame->pLightmapBuilder->std__vector_000004_size = 0; + if ( stru_F8AD28.uNumLightsApplied > 0 || pDecalBuilder->uNumDecals > 0 ) + { + if ( neer_clip ) + v33 = 3; + else + v33 = far_clip != 0 ? 5 : 0; + static_sub_0048034E_stru_154.ClassifyPolygon(norm, Light_tile_dist); + if ( pDecalBuilder->uNumDecals > 0 ) + pDecalBuilder->ApplyDecals(31 - pTilePolygon->dimming_level, 4, &static_sub_0048034E_stru_154, a5, array_50AC10, 0, *(float *)&v33, -1); + } + if ( stru_F8AD28.uNumLightsApplied > 0 ) + pGame->pLightmapBuilder->ApplyLights(&stru_F8AD28, &static_sub_0048034E_stru_154, a5, array_50AC10, 0, v33);*/ + + if ( !byte_4D864C || ~pGame->uFlags & 0x80 ) + { + //if ( neer_clip ) //Ritor1: Даёт искажения на подъёме, возможно требуется ф-ция Безье + //{ + // pTilePolygon->uNumVertices = ODM_NearClip(pTilePolygon->uNumVertices); + // ODM_Project(pTilePolygon->uNumVertices); + //} + if ( far_clip ) + { + pTilePolygon->uNumVertices = ODM_FarClip(pTilePolygon->uNumVertices); + ODM_Project(pTilePolygon->uNumVertices); + } + } + pODMRenderParams->shading_dist_mist = temp; + +// check the transparency and texture (tiles) mapping (проверка прозрачности и наложение текстур (тайлов))---------------------- + bool transparent = false; + if ( !( pTilePolygon->flags & 1 ) ) // не поддерживается TextureFrameTable + { + if ( /*pTile->flags & 2 && */pTilePolygon->uTileBitmapID == pRenderer->hd_water_tile_id) + { + //transparent = false; + v6 = pRenderer->pHDWaterBitmapIDs[pRenderer->hd_water_current_frame]; + } + else + { + v6 = pTilePolygon->uTileBitmapID; + if ( !_strnicmp(pBitmaps_LOD->pTextures[pTilePolygon->uTileBitmapID].pName, "wtrdr", 5) ) + transparent = true; + } + + assert(v6 < 1000); // many random crashes here + + // for all shore tiles - draw a tile water under them since they're half-empty + if (!_strnicmp(pBitmaps_LOD->pTextures[pTilePolygon->uTileBitmapID].pName, "wtrdr", 5)) // all shore tile filenames are wtrdrXXX + DrawBorderTiles(pTilePolygon); + + pRenderer->DrawTerrainPolygon(pTilePolygon->uNumVertices, pTilePolygon, pBitmaps_LOD->pHardwareTextures[v6], transparent, true); + } + //else //здесь уже пограничные тайлы воды + //pTile->DrawBorderTiles(); +//-------------------------------------------------------------------------------------------------------------------------------- + + --pODMRenderParams->uNumPolygons; + --pODMRenderParams->field_44; + } + } +} + +//----- (004811A3) -------------------------------------------------------- +void Render::DrawBorderTiles(struct Polygon *poly) +{ + pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false); + DrawTerrainPolygon(poly->uNumVertices, poly, + pBitmaps_LOD->pHardwareTextures[pHDWaterBitmapIDs[hd_water_current_frame]], false, true); + + pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, true); + //DrawTerrainPolygon(poly->uNumVertices, poly, pBitmaps_LOD->pHardwareTextures[poly->uTileBitmapID], true, true); +} + + +//----- (0047BACF) -------------------------------------------------------- +void Render::TransformBillboardsAndSetPalettesODM() +{ + //int v0; // edi@1 + //char *v1; // esi@2 + //unsigned int v2; // edx@3 + //int v3; // eax@3 + //int v4; // edi@3 + //int v5; // eax@3 + //__int16 v6; // di@3 + //int v7; // eax@3 + //int v8; // ebx@4 +// unsigned __int16 *v9; // eax@7 +// char v10; // zf@9 + //DWORD v11; // eax@13 +// int v12; // eax@13 +// int v13; // eax@14 + RenderBillboardTransform_local0 billboard; // [sp+4h] [bp-60h]@1 +// int v15; // [sp+54h] [bp-10h]@13 + //int v16; // [sp+58h] [bp-Ch]@1 + //int v17; // [sp+5Ch] [bp-8h]@2 +// int v18; // [sp+60h] [bp-4h]@13 + + billboard.sParentBillboardID = -1; + billboard.pTarget = pRenderer->pTargetSurface; + billboard.pTargetZ = pRenderer->pActiveZBuffer; + billboard.uTargetPitch = pRenderer->uTargetSurfacePitch; + billboard.uViewportX = pViewport->uViewportTL_X; + billboard.uViewportY = pViewport->uViewportTL_Y; + billboard.uViewportZ = pViewport->uViewportBR_X - 1; + billboard.uViewportW = pViewport->uViewportBR_Y; + pODMRenderParams->uNumBillboards = uNumBillboardsToDraw; + + for (unsigned int i = 0; i < ::uNumBillboardsToDraw; ++i) + { + billboard.uScreenSpaceX = pBillboardRenderList[i].uScreenSpaceX; + billboard.uScreenSpaceY = pBillboardRenderList[i].uScreenSpaceY; + billboard.sParentBillboardID = i; + billboard._screenspace_x_scaler_packedfloat = pBillboardRenderList[i]._screenspace_x_scaler_packedfloat; + billboard.sTintColor = pBillboardRenderList[i].sTintColor; + billboard._screenspace_y_scaler_packedfloat = pBillboardRenderList[i]._screenspace_y_scaler_packedfloat; + billboard.sZValue = pBillboardRenderList[i].sZValue; + billboard.uFlags = pBillboardRenderList[i].field_1E; + if (pBillboardRenderList[i].HwSpriteID != -1) + { + if (!pRenderD3D) __debugbreak(); // no sw rendering + //if (pRenderer->pRenderD3D) + TransformBillboard(&billboard, + &pSprites_LOD->pHardwareSprites[pBillboardRenderList[i].HwSpriteID], + pBillboardRenderList[i].dimming_level, &pBillboardRenderList[i]); + /*else + { + assert(false); + + auto v1 = (char *)&pBillboard->uScreenSpaceY; + if ( *(v1 - 10) & 2 ) + v9 = PaletteManager::Get_Dark_or_Red_LUT(*((short *)v1 - 7), 0, 1); + else + v9 = sr_GetBillboardPalette((RenderBillboard *)(v1 - 40), *((short *)v1 - 7), pBillboard->sZValue, *((short *)v1 + 1)); + v10 = (*(v1 - 9) & 1) == 0; + billboard.pPalette = v9; + if ( !v10 ) + billboard.pPalette = pPaletteManager->field_261600[*((short *)v1 - 7)]; + if ( !(billboard.uFlags & 0x40) && billboard.uFlags & 0x80 ) + { + v12 = stru_5C6E00->Cos(i * 5 + GetTickCount()); + v15 = abs(v12); + v18 = (unsigned __int64)(15i64 * v15) >> 16; + billboard.pPalette2 = PaletteManager::Get_Dark_or_Red_LUT(*((short *)v1 - 7), 15 - v18, 1); + } + v13 = *((short *)v1 - 8); + if ( v13 >= 0 ) + pSprites_LOD->pSpriteHeaders[v13].DrawSprite_sw(&billboard, 1); + }*/ + } + } +} + +//----- (0047AF11) -------------------------------------------------------- +void Render::DrawSpriteObjects_ODM() +{ + SpriteFrame *frame; // eax@10 + unsigned int v6; // eax@10 + int v9; // ecx@10 + int v17; // ecx@25 + int v18; // eax@25 +// int v22; // ST3C_4@29 + signed __int64 v23; // qtt@30 + int v26; // eax@31 +// char v27; // zf@31 + int v30; // [sp+14h] [bp-2Ch]@23 + int v37; // [sp+1Ch] [bp-24h]@23 + int a6; // [sp+20h] [bp-20h]@10 + int v42; // [sp+2Ch] [bp-14h]@23 + int y; // [sp+30h] [bp-10h]@10 + int x; // [sp+34h] [bp-Ch]@10 + int z; // [sp+38h] [bp-8h]@10 + signed __int16 v46; // [sp+3Ch] [bp-4h]@12 + + //v41 = 0; + for (unsigned int i = 0; i < uNumSpriteObjects; ++i) + { + SpriteObject* object = &pSpriteObjects[i]; + //auto v0 = (char *)&pSpriteObjects[i].uSectorID; + //v0 = (char *)&pSpriteObjects[0].uSectorID; + //do + //{ + if (!object->uObjectDescID) // item probably pciked up + continue; + + assert(object->uObjectDescID < pObjectList->uNumObjects); + ObjectDesc* object_desc = &pObjectList->pObjects[object->uObjectDescID]; + if (object_desc->NoSprite()) + continue; + + //v1 = &pObjectList->pObjects[*((short *)v0 - 13)]; + //if ( !(v1->uFlags & 1) ) + //{ + //v2 = *((short *)v0 - 14) + //v2 = object->uType; + if ( (object->uType < 1000 || object->uType >= 10000) && (object->uType < 500 || object->uType >= 600) + || pGame->pStru6Instance->_4A81CA(object) ) + { + //a5 = *(short *)v0; + x = object->vPosition.x; + y = object->vPosition.y; + z = object->vPosition.z; + frame = pSpriteFrameTable->GetFrame(object_desc->uSpriteID, object->uSpriteFrameID); + a6 = frame->uGlowRadius * object->field_22_glow_radius_multiplier; + v6 = stru_5C6E00->Atan2(object->vPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x, object->vPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y); + //LOWORD(v7) = object->uFacing; + //v8 = v36; + v9 = ((signed int)(stru_5C6E00->uIntegerPi + ((signed int)stru_5C6E00->uIntegerPi >> 3) + object->uFacing - v6) >> 8) & 7; + pBillboardRenderList[::uNumBillboardsToDraw].HwSpriteID = frame->pHwSpriteIDs[v9]; + if ( frame->uFlags & 0x20 ) + { + //v8 = v36; + z -= fixpoint_mul(frame->scale, pSprites_LOD->pSpriteHeaders[(signed __int16)frame->pHwSpriteIDs[v9]].uHeight) / 2; + } + v46 = 0; + if ( frame->uFlags & 2 ) + v46 = 2; + //v11 = (int *)(256 << v9); + if ( (256 << v9) & frame->uFlags ) + v46 |= 4; + if ( frame->uFlags & 0x40000 ) + v46 |= 0x40; + if ( frame->uFlags & 0x20000 ) + LOBYTE(v46) = v46 | 0x80; + if ( a6 ) + { + //LOBYTE(v11) = _4E94D3_light_type; + pMobileLightsStack->AddLight(x, y, z, object->uSectorID, a6, 0xFF, 0xFF, 0xFF, _4E94D3_light_type); + } + if (pGame->pIndoorCameraD3D->sRotationX) + { + v30 = fixpoint_mul((x - pGame->pIndoorCameraD3D->vPartyPos.x) << 16, pGame->pIndoorCameraD3D->int_cosine_y) + + fixpoint_mul((y - pGame->pIndoorCameraD3D->vPartyPos.y) << 16, pGame->pIndoorCameraD3D->int_sine_y); + v37 = fixpoint_mul((x - pGame->pIndoorCameraD3D->vPartyPos.x) << 16, pGame->pIndoorCameraD3D->int_sine_y); + v42 = fixpoint_mul((z - pGame->pIndoorCameraD3D->vPartyPos.z) << 16, pGame->pIndoorCameraD3D->int_sine_x) + + fixpoint_mul(v30, pGame->pIndoorCameraD3D->int_cosine_x); + if ( v42 >= 0x40000 && v42 <= pODMRenderParams->shading_dist_mist << 16 ) + { + v17 = fixpoint_mul((y - pGame->pIndoorCameraD3D->vPartyPos.y) << 16, pGame->pIndoorCameraD3D->int_cosine_y) - v37; + v18 = fixpoint_mul((z - pGame->pIndoorCameraD3D->vPartyPos.z) << 16, pGame->pIndoorCameraD3D->int_cosine_x) + - fixpoint_mul(v30, pGame->pIndoorCameraD3D->int_sine_x); + if ( abs(v42) >= abs(v17) ) + { + LODWORD(v23) = 0; + HIDWORD(v23) = SLOWORD(pODMRenderParams->int_fov_rad); + + object->uAttributes |= 1; + pBillboardRenderList[::uNumBillboardsToDraw].uPalette = frame->uPaletteIndex; + pBillboardRenderList[::uNumBillboardsToDraw].uIndoorSectorID = object->uSectorID; + pBillboardRenderList[::uNumBillboardsToDraw]._screenspace_x_scaler_packedfloat = fixpoint_mul(frame->scale, v23 / v42); + pBillboardRenderList[::uNumBillboardsToDraw].pSpriteFrame = frame; + pBillboardRenderList[::uNumBillboardsToDraw]._screenspace_y_scaler_packedfloat = fixpoint_mul(frame->scale, v23 / v42); + pBillboardRenderList[::uNumBillboardsToDraw].field_1E = v46; + pBillboardRenderList[::uNumBillboardsToDraw].world_x = x; + pBillboardRenderList[::uNumBillboardsToDraw].world_y = y; + pBillboardRenderList[::uNumBillboardsToDraw].world_z = z; + pBillboardRenderList[::uNumBillboardsToDraw].uScreenSpaceX = pViewport->uScreenCenterX - ((signed int)(fixpoint_mul(v23 / v42, v17) + 0x8000) >> 16); + pBillboardRenderList[::uNumBillboardsToDraw].uScreenSpaceY = pViewport->uScreenCenterY - (((unsigned int)fixpoint_mul(v23 / v42, v18) + 0x8000) >> 16); + HIWORD(v26) = HIWORD(v42); + LOWORD(v26) = 0; + pBillboardRenderList[::uNumBillboardsToDraw].sZValue = v26 + (PID(OBJECT_Item,i)); + pBillboardRenderList[::uNumBillboardsToDraw].dimming_level = 0; + pBillboardRenderList[::uNumBillboardsToDraw].sTintColor = 0; + if ( !(object->uAttributes & 0x20) ) + { + if ( !pRenderD3D ) + { + __debugbreak(); + pBillboardRenderList[::uNumBillboardsToDraw].sZValue = 0; + } + } + //if (::uNumBillboardsToDraw >= 500) + // return; + assert(::uNumBillboardsToDraw < 500); + ++::uNumBillboardsToDraw; + ++uNumSpritesDrawnThisFrame; + } + } + } + else + { + v42 = fixpoint_mul((y - pGame->pIndoorCameraD3D->vPartyPos.y) << 16, pGame->pIndoorCameraD3D->int_sine_y) + + fixpoint_mul((x - pGame->pIndoorCameraD3D->vPartyPos.x) << 16, pGame->pIndoorCameraD3D->int_cosine_y); + if ( v42 >= 0x40000 && v42 <= pODMRenderParams->shading_dist_mist << 16 ) + { + v17 = fixpoint_mul((y - pGame->pIndoorCameraD3D->vPartyPos.y) << 16, pGame->pIndoorCameraD3D->int_cosine_y) + - fixpoint_mul(((x - pGame->pIndoorCameraD3D->vPartyPos.x) << 16), pGame->pIndoorCameraD3D->int_sine_y); + v18 = (z - pGame->pIndoorCameraD3D->vPartyPos.z) << 16; + if ( abs(v42) >= abs(v17) ) + { + LODWORD(v23) = 0; + HIDWORD(v23) = SLOWORD(pODMRenderParams->int_fov_rad); + + object->uAttributes |= 1; + pBillboardRenderList[::uNumBillboardsToDraw].uPalette = frame->uPaletteIndex; + pBillboardRenderList[::uNumBillboardsToDraw].uIndoorSectorID = object->uSectorID; + pBillboardRenderList[::uNumBillboardsToDraw]._screenspace_x_scaler_packedfloat = fixpoint_mul(frame->scale, v23 / v42); + pBillboardRenderList[::uNumBillboardsToDraw].pSpriteFrame = frame; + pBillboardRenderList[::uNumBillboardsToDraw]._screenspace_y_scaler_packedfloat = fixpoint_mul(frame->scale, v23 / v42); + pBillboardRenderList[::uNumBillboardsToDraw].field_1E = v46; + pBillboardRenderList[::uNumBillboardsToDraw].world_x = x; + pBillboardRenderList[::uNumBillboardsToDraw].world_y = y; + pBillboardRenderList[::uNumBillboardsToDraw].world_z = z; + pBillboardRenderList[::uNumBillboardsToDraw].uScreenSpaceX = pViewport->uScreenCenterX - ((signed int)(fixpoint_mul(v23 / v42, v17) + 0x8000) >> 16); + pBillboardRenderList[::uNumBillboardsToDraw].uScreenSpaceY = pViewport->uScreenCenterY - (((unsigned int)fixpoint_mul(v23 / v42, v18) + 0x8000) >> 16); + HIWORD(v26) = HIWORD(v42); + LOWORD(v26) = 0; + pBillboardRenderList[::uNumBillboardsToDraw].sZValue = v26 + (PID(OBJECT_Item,i)); + pBillboardRenderList[::uNumBillboardsToDraw].dimming_level = 0; + pBillboardRenderList[::uNumBillboardsToDraw].sTintColor = 0; + if ( !(object->uAttributes & 0x20) ) + { + if ( !pRenderD3D ) + { + __debugbreak(); + pBillboardRenderList[::uNumBillboardsToDraw].sZValue = 0; + } + } + //if (::uNumBillboardsToDraw >= 500) + // return; + assert(::uNumBillboardsToDraw < 500); + ++::uNumBillboardsToDraw; + ++uNumSpritesDrawnThisFrame; + } + } + } + } + } +} + +//----- (0049D9BC) -------------------------------------------------------- +signed int __stdcall RenderD3D__DeviceEnumerator(GUID *lpGUID, const char *lpDevDesc, const char *lpDriverName, RenderD3D__DevInfo *pOut) +{ + size_t v4; // eax@1 + size_t v5; // eax@1 + size_t v7; // eax@13 + DDDEVICEIDENTIFIER ddDevId; // [sp+4h] [bp-4F8h]@11 + DDSURFACEDESC2 v10;/*int v10; // [sp+42Ch] [bp-D0h]@16*/ + DDSCAPS2 ddsCaps; // [sp+4A8h] [bp-54h]@14 + unsigned int uFreeVideoMem; // [sp+4B8h] [bp-44h]@14 + RenderD3D_aux aux; // [sp+4BCh] [bp-40h]@19 + IDirect3D3 *pDirect3D3; // [sp+4C4h] [bp-38h]@18 + int is_there_a_compatible_screen_mode; // [sp+4C8h] [bp-34h]@16 + RenderD3D_D3DDevDesc v20; // [sp+4CCh] [bp-30h]@1 + LPDIRECTDRAW pDirectDraw = nullptr; // [sp+4F4h] [bp-8h]@4 + IDirectDraw4 *pDirectDraw4; // [sp+4F8h] [bp-4h]@7 + + v4 = strlen(lpDriverName); + v20.pDriverName = new char[v4 + 1]; + v5 = strlen(lpDevDesc); + v20.pDeviceDesc = new char[v5 + 1]; + strcpy(v20.pDriverName, lpDriverName); + strcpy(v20.pDeviceDesc, lpDevDesc); + if ( lpGUID ) + { + v20.pGUID = new GUID; + memcpy(v20.pGUID, lpGUID, 0x10); + } + else + v20.pGUID = 0; + + if (FAILED(DirectDrawCreate(v20.pGUID, &pDirectDraw, 0))) + { + delete [] v20.pDriverName; + delete [] v20.pDeviceDesc; + delete v20.pGUID; + } + else + { + if (FAILED(pDirectDraw->QueryInterface(IID_IDirectDraw4, (LPVOID *)&pDirectDraw4))) + { + delete [] v20.pDriverName; + delete [] v20.pDeviceDesc; + delete v20.pGUID; + pDirectDraw->Release(); + } + else + { + pDirectDraw->Release(); + if (FAILED( pDirectDraw4->GetDeviceIdentifier(&ddDevId, 1))) + v20.pDDraw4DevDesc = 0; + else + { + v7 = strlen(ddDevId.szDescription); + v20.pDDraw4DevDesc = new char[v7 + 1]; + strcpy(v20.pDDraw4DevDesc, ddDevId.szDescription); + } + memset(&ddsCaps, 0, sizeof(ddsCaps)); + if (FAILED(pDirectDraw4->GetAvailableVidMem(&ddsCaps, (LPDWORD)&v20.uVideoMem, (LPDWORD)&uFreeVideoMem))) + v20.uVideoMem = 0; + memset(&v10, 0, sizeof(v10)); + v10.dwSize = 124; + v10.dwFlags = 6; + v10.dwHeight = window->GetWidth(); + v10.dwWidth = window->GetHeight(); + v10.ddpfPixelFormat.dwSize = 32; + + is_there_a_compatible_screen_mode = false; + if ( FAILED(pDirectDraw4->EnumDisplayModes(0, 0, &is_there_a_compatible_screen_mode, (LPDDENUMMODESCALLBACK2)DDrawDisplayModesEnumerator)) + || !is_there_a_compatible_screen_mode + || FAILED(pDirectDraw4->QueryInterface(IID_IDirect3D3, (LPVOID *)&pDirect3D3))) + { + delete [] v20.pDriverName; + delete [] v20.pDeviceDesc; + //free(v20.pDDraw4DevDesc); + delete [] v20.pDDraw4DevDesc; + delete v20.pGUID; + pDirectDraw4->Release(); + } + else + { + aux.pInfo = pOut; + aux.ptr_4 = &v20; + pDirect3D3->EnumDevices((LPD3DENUMDEVICESCALLBACK)D3DDeviceEnumerator, &aux); + delete [] v20.pDriverName; + delete [] v20.pDeviceDesc; + delete [] v20.pDDraw4DevDesc; + delete v20.pGUID; + pDirectDraw4->Release(); + pDirectDraw4 = 0; + pDirect3D3->Release(); + } + } + } + return 1; +} + +//----- (0049D784) -------------------------------------------------------- +HRESULT __stdcall D3DDeviceEnumerator(const GUID *lpGUID, const char *lpDeviceDesc, const char *lpDeviceName, D3DDEVICEDESC *pHWDesc, D3DDEVICEDESC *pSWDesc, RenderD3D_aux *a6) +{ + signed int v7; // edi@1 + + v7 = -1; + if ( pHWDesc->dwFlags ) + { + if ( !a6->ptr_4->pGUID ) + v7 = 0; + if ( pHWDesc->dwFlags && a6->ptr_4->pGUID ) + v7 = 1; + } + if ( !strcmp(lpDeviceName, "RGB Emulation") && !a6->ptr_4->pGUID ) + v7 = 2; + if ( !strcmp(lpDeviceName, "Reference Rasterizer") && !a6->ptr_4->pGUID ) + v7 = 3; + if ( v7 != -1 ) + { + a6->pInfo[v7].bIsDeviceCompatible = 1; + a6->pInfo[v7].uCaps = 0; + if ( !(pHWDesc->dpcTriCaps.dwSrcBlendCaps & 0x10) ) + a6->pInfo[v7].uCaps |= 2; + if ( !(pHWDesc->dpcTriCaps.dwSrcBlendCaps & 2) ) + a6->pInfo[v7].uCaps |= 4; + if ( !(pHWDesc->dpcTriCaps.dwSrcBlendCaps & 1) ) + a6->pInfo[v7].uCaps |= 8; + if ( !(pHWDesc->dpcTriCaps.dwDestBlendCaps & 0x20) ) + a6->pInfo[v7].uCaps |= 16; + if ( !(pHWDesc->dpcTriCaps.dwDestBlendCaps & 2) ) + a6->pInfo[v7].uCaps |= 32; + if ( !(pHWDesc->dpcTriCaps.dwDestBlendCaps & 4) ) + a6->pInfo[v7].uCaps |= 64; + if ( !(BYTE1(pHWDesc->dwDevCaps) & 0x10) ) + BYTE1(a6->pInfo[v7].uCaps) |= 1; + if ( pHWDesc->dpcTriCaps.dwTextureCaps & 0x20 ) + LOBYTE(a6->pInfo[v7].uCaps) |= 0x80; + + a6->pInfo[v7].pName = new char[strlen(lpDeviceName) + 1]; + strcpy(a6->pInfo[v7].pName, lpDeviceName); + + a6->pInfo[v7].pDescription = new char[strlen(lpDeviceDesc) + 1]; + strcpy(a6->pInfo[v7].pDescription, lpDeviceDesc); + + a6->pInfo[v7].pGUID = new GUID; + memcpy(a6->pInfo[v7].pGUID, lpGUID, 0x10); + + a6->pInfo[v7].pDriverName = new char[strlen(a6->ptr_4->pDriverName) + 1]; + strcpy(a6->pInfo[v7].pDriverName, a6->ptr_4->pDriverName); + + a6->pInfo[v7].pDeviceDesc = new char[strlen(a6->ptr_4->pDeviceDesc) + 1]; + strcpy(a6->pInfo[v7].pDeviceDesc, a6->ptr_4->pDeviceDesc); + + a6->pInfo[v7].pDDraw4DevDesc = new char[strlen(a6->ptr_4->pDDraw4DevDesc) + 1]; + strcpy(a6->pInfo[v7].pDDraw4DevDesc, a6->ptr_4->pDDraw4DevDesc); + + if ( a6->ptr_4->pGUID ) + { + a6->pInfo[v7].pDirectDrawGUID = new GUID; + memcpy(a6->pInfo[v7].pDirectDrawGUID, a6->ptr_4->pGUID, 0x10); + } + else + a6->pInfo[v7].pDirectDrawGUID = 0; + a6->pInfo[v7].uVideoMem = a6->ptr_4->uVideoMem; + } + return 1; +} + +//----- (0049D75C) -------------------------------------------------------- +HRESULT __stdcall DDrawDisplayModesEnumerator(DDSURFACEDESC2 *pSurfaceDesc, __int16 *found_compatible_mode) +{ + if ( pSurfaceDesc->ddsCaps.dwCaps | DDSCAPS_3DDEVICE /*&& pSurfaceDesc->ddpfPixelFormat.dwRGBBitCount == 16*/ ) + { + *found_compatible_mode = 1; + return S_OK; + } + return 1; +} + +//----- (0047A95E) -------------------------------------------------------- +void Render::PrepareDecorationsRenderList_ODM() +{ + unsigned int v6; // edi@9 + int v7; // eax@9 + SpriteFrame *v8; // eax@9 + unsigned __int16 *v10; // eax@9 + int v13; // ecx@9 + int v14; // ecx@20 + char v15; // dl@20 + signed int v16; // eax@20 + int v17; // eax@23 + int v18; // ecx@24 + int v19; // eax@24 + int v20; // ecx@24 + int v21; // ebx@26 + int v22; // eax@26 + signed __int64 v24; // qtt@31 + int v25; // ebx@31 + __int16 v29; // cx@37 + int v30; // ecx@37 + int v31; // ebx@37 + Particle_sw local_0; // [sp+Ch] [bp-98h]@7 + unsigned __int16 *v37; // [sp+84h] [bp-20h]@9 + int v38; // [sp+88h] [bp-1Ch]@9 + int v40; // [sp+90h] [bp-14h]@24 + int v41; // [sp+94h] [bp-10h]@24 + int v42; // [sp+98h] [bp-Ch]@9 + int b; // [sp+A0h] [bp-4h]@22 + + for (unsigned int i = 0; i < uNumLevelDecorations; ++i) + { + //LevelDecoration* decor = &pLevelDecorations[i]; + if ((!(pLevelDecorations[i].uFlags & LEVEL_DECORATION_OBELISK_CHEST) + || pLevelDecorations[i].IsObeliskChestActive()) && !(pLevelDecorations[i].uFlags & LEVEL_DECORATION_INVISIBLE)) + { + DecorationDesc* decor_desc = &pDecorationList->pDecorations[pLevelDecorations[i].uDecorationDescID]; + if ( (char)decor_desc->uFlags >= 0 ) + { + if ( !(decor_desc->uFlags & 0x22) ) + { + v6 = pMiscTimer->uTotalGameTimeElapsed; + v7 = abs(pLevelDecorations[i].vPosition.x + pLevelDecorations[i].vPosition.y); + + #pragma region "New: seasons change" + extern bool change_seasons; + if (change_seasons) + switch (pParty->uCurrentMonth) + { + // case 531 (tree60), 536 (tree65), 537 (tree66) have no autumn/winter sprites + case 11: case 0: case 1: // winter + switch (decor_desc->uSpriteID) + { + //case 468: //bush02 grows on swamps, which are evergreeen actually + case 548: // flower10 + case 547: // flower09 + case 541: // flower03 + case 539: continue; // flower01 + + case 483: // tree01 + case 486: // tree04 + case 492: // tree10 + pSpriteFrameTable->InitializeSprite(decor_desc->uSpriteID + 2); + v8 = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID + 2, v6 + v7); + break; + + default: + v8 = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID, v6 + v7); + } + break; + + case 2: case 3: case 4: // spring + switch (decor_desc->uSpriteID) + { + } + v8 = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID, v6 + v7); + break; + + case 8: case 9: case 10: // autumn + switch (decor_desc->uSpriteID) + { + //case 468: //bush02 grows on swamps, which are evergreeen actually + case 548: // flower10 + case 547: // flower09 + case 541: // flower03 + case 539: continue; // flower01 + + case 483: // tree01 + case 486: // tree04 + case 492: // tree10 + pSpriteFrameTable->InitializeSprite(decor_desc->uSpriteID + 1); + v8 = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID + 1, v6 + v7); + break; + + default: + v8 = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID, v6 + v7); + } + break; + + case 5: case 6: case 7: // summer + //all green by default + v8 = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID, v6 + v7); + break; + + default: assert(pParty->uCurrentMonth >= 0 && pParty->uCurrentMonth < 12); + } + else + v8 = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID, v6 + v7); + #pragma endregion + //v8 = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID, v6 + v7); + + v10 = (unsigned __int16 *)stru_5C6E00->Atan2(pLevelDecorations[i].vPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x, + pLevelDecorations[i].vPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y); + v38 = 0; + v13 = ((signed int)(stru_5C6E00->uIntegerPi + ((signed int)stru_5C6E00->uIntegerPi >> 3) + pLevelDecorations[i].field_10_y_rot - (signed int)v10) >> 8) & 7; + v37 = (unsigned __int16 *)v13; + if ( v8->uFlags & 2 ) + v38 = 2; + if ( (256 << v13) & v8->uFlags ) + v38 |= 4; + if ( v8->uFlags & 0x40000 ) + v38 |= 0x40; + if ( v8->uFlags & 0x20000 ) + LOBYTE(v38) = v38 | 0x80; + if ( v8->uGlowRadius ) + { + if ( pRenderD3D && bUseColoredLights ) + { + v14 = /*255;//*/decor_desc->uColoredLightRed; + v15 = /*255;//*/decor_desc->uColoredLightGreen; + v16 = /*255;//*/decor_desc->uColoredLightBlue; + } + else + { + v16 = 255; + v14 = 255; + v15 = 255; + } + pStationaryLightsStack->AddLight(pLevelDecorations[i].vPosition.x, pLevelDecorations[i].vPosition.y, pLevelDecorations[i].vPosition.z + decor_desc->uDecorationHeight / 2, + v8->uGlowRadius, v14, v15, v16, _4E94D0_light_type); + } + v17 = (pLevelDecorations[i].vPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x) << 16; + if (pGame->pIndoorCameraD3D->sRotationX) + { + v40 = (pLevelDecorations[i].vPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y) << 16; + v18 = fixpoint_mul(v17, pGame->pIndoorCameraD3D->int_cosine_y) + fixpoint_mul(v40, pGame->pIndoorCameraD3D->int_sine_y); + v41 = fixpoint_mul((pLevelDecorations[i].vPosition.z - pGame->pIndoorCameraD3D->vPartyPos.z) << 16, pGame->pIndoorCameraD3D->int_sine_x); + v19 = fixpoint_mul(v18, pGame->pIndoorCameraD3D->int_cosine_x); + v20 = v19 + fixpoint_mul((pLevelDecorations[i].vPosition.z - pGame->pIndoorCameraD3D->vPartyPos.z) << 16, pGame->pIndoorCameraD3D->int_sine_x); + if ( v20 >= 0x40000 && v20 <= pODMRenderParams->shading_dist_mist << 16 ) + { + v21 = fixpoint_mul(v40, pGame->pIndoorCameraD3D->int_cosine_y) - fixpoint_mul(v17, pGame->pIndoorCameraD3D->int_sine_y); + v22 = fixpoint_mul((pLevelDecorations[i].vPosition.z - pGame->pIndoorCameraD3D->vPartyPos.z) << 16, pGame->pIndoorCameraD3D->int_cosine_x) - fixpoint_mul(v18, pGame->pIndoorCameraD3D->int_sine_x); + if ( 2 * abs(v20) >= abs(v21) ) + { + LODWORD(v24) = 0; + HIDWORD(v24) = SLOWORD(pODMRenderParams->int_fov_rad); + v25 = pViewport->uScreenCenterX - ((signed int)(fixpoint_mul(v24 / v20, v21) + 0x8000) >> 16); + v40 = pViewport->uScreenCenterY - ((signed int)(fixpoint_mul(v24 / v20, v22) + 0x8000) >> 16); + v41 = fixpoint_mul(v8->scale, v24 / v20); + if ( pRenderD3D ) + b = fixpoint_mul(pSprites_LOD->pHardwareSprites[v8->pHwSpriteIDs[(int)v37]].uBufferWidth / 2, v41); + else + { + __debugbreak(); + b = fixpoint_mul(pSprites_LOD->pSpriteHeaders[v8->pHwSpriteIDs[(int)v37]].uWidth / 2, v41); + } + if ( b + v25 >= (signed int)pViewport->uViewportTL_X && v25 - b <= (signed int)pViewport->uViewportBR_X ) + { + if (::uNumBillboardsToDraw >= 500) + return; + pBillboardRenderList[::uNumBillboardsToDraw].HwSpriteID = v8->pHwSpriteIDs[(int)v37]; + pBillboardRenderList[::uNumBillboardsToDraw]._screenspace_x_scaler_packedfloat = v41; + pBillboardRenderList[::uNumBillboardsToDraw]._screenspace_y_scaler_packedfloat = v41; + v29 = v38; + pBillboardRenderList[::uNumBillboardsToDraw].uScreenSpaceX = v25; + HIBYTE(v29) |= 2; + pBillboardRenderList[::uNumBillboardsToDraw].uPalette = v8->uPaletteIndex; + pBillboardRenderList[::uNumBillboardsToDraw].field_1E = v29; + pBillboardRenderList[::uNumBillboardsToDraw].world_x = pLevelDecorations[i].vPosition.x; + pBillboardRenderList[::uNumBillboardsToDraw].world_y = pLevelDecorations[i].vPosition.y; + pBillboardRenderList[::uNumBillboardsToDraw].world_z = pLevelDecorations[i].vPosition.z; + pBillboardRenderList[::uNumBillboardsToDraw].uScreenSpaceY = v40; + HIWORD(v30) = HIWORD(v20); + v31 = PID(OBJECT_Decoration,i); + LOWORD(v30) = 0; + pBillboardRenderList[::uNumBillboardsToDraw].uIndoorSectorID = 0; + pBillboardRenderList[::uNumBillboardsToDraw].sZValue = v30 + v31; + pBillboardRenderList[::uNumBillboardsToDraw].dimming_level = 0; + pBillboardRenderList[::uNumBillboardsToDraw].pSpriteFrame = v8; + pBillboardRenderList[::uNumBillboardsToDraw].sTintColor = 0; + ::uNumBillboardsToDraw++; + ++uNumDecorationsDrawnThisFrame; + } + } + continue; + } + } + else + { + v42 = (pLevelDecorations[i].vPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x) << 16; + v40 = (pLevelDecorations[i].vPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y) << 16; + v20 = fixpoint_mul(v17, pGame->pIndoorCameraD3D->int_cosine_y) + fixpoint_mul(v40, pGame->pIndoorCameraD3D->int_sine_y); + if ( v20 >= 0x40000 && v20 <= pODMRenderParams->shading_dist_mist << 16 ) + { + v21 = fixpoint_mul(v40, pGame->pIndoorCameraD3D->int_cosine_y) - fixpoint_mul(v42, pGame->pIndoorCameraD3D->int_sine_y); + v22 = (pLevelDecorations[i].vPosition.z - pGame->pIndoorCameraD3D->vPartyPos.z) << 16; + v42 = v22; + if ( 2 * abs(v20) >= abs(v21) ) + { + LODWORD(v24) = 0; + HIDWORD(v24) = SLOWORD(pODMRenderParams->int_fov_rad); + v25 = pViewport->uScreenCenterX - ((signed int)(fixpoint_mul(v24 / v20, v21) + 0x8000) >> 16); + v40 = pViewport->uScreenCenterY - ((signed int)(fixpoint_mul(v24 / v20, v42) + 0x8000) >> 16); + v41 = fixpoint_mul(v8->scale, v24 / v20); + if ( pRenderD3D ) + b = fixpoint_mul(pSprites_LOD->pHardwareSprites[v8->pHwSpriteIDs[(int)v37]].uBufferWidth / 2, v41); + else + { + __debugbreak(); + b = fixpoint_mul(pSprites_LOD->pSpriteHeaders[v8->pHwSpriteIDs[(int)v37]].uWidth / 2, v41); + } + if ( b + v25 >= (signed int)pViewport->uViewportTL_X && v25 - b <= (signed int)pViewport->uViewportBR_X ) + { + if (::uNumBillboardsToDraw >= 500) + return; + pBillboardRenderList[::uNumBillboardsToDraw].HwSpriteID = v8->pHwSpriteIDs[(int)v37]; + pBillboardRenderList[::uNumBillboardsToDraw]._screenspace_x_scaler_packedfloat = v41; + pBillboardRenderList[::uNumBillboardsToDraw]._screenspace_y_scaler_packedfloat = v41; + v29 = v38; + pBillboardRenderList[::uNumBillboardsToDraw].uScreenSpaceX = v25; + HIBYTE(v29) |= 2; + pBillboardRenderList[::uNumBillboardsToDraw].uPalette = v8->uPaletteIndex; + pBillboardRenderList[::uNumBillboardsToDraw].field_1E = v29; + pBillboardRenderList[::uNumBillboardsToDraw].world_x = pLevelDecorations[i].vPosition.x; + pBillboardRenderList[::uNumBillboardsToDraw].world_y = pLevelDecorations[i].vPosition.y; + pBillboardRenderList[::uNumBillboardsToDraw].world_z = pLevelDecorations[i].vPosition.z; + pBillboardRenderList[::uNumBillboardsToDraw].uScreenSpaceY = v40; + HIWORD(v30) = HIWORD(v20); + v31 = PID(OBJECT_Decoration,i); + LOWORD(v30) = 0; + pBillboardRenderList[::uNumBillboardsToDraw].uIndoorSectorID = 0; + pBillboardRenderList[::uNumBillboardsToDraw].sZValue = v30 + v31; + pBillboardRenderList[::uNumBillboardsToDraw].dimming_level = 0; + pBillboardRenderList[::uNumBillboardsToDraw].pSpriteFrame = v8; + pBillboardRenderList[::uNumBillboardsToDraw].sTintColor = 0; + ::uNumBillboardsToDraw++; + ++uNumDecorationsDrawnThisFrame; + } + } + continue; + } + } + } + } + else + { + memset(&local_0, 0, 0x68); + local_0.type = ParticleType_Bitmap | ParticleType_Rotating | ParticleType_8; + local_0.uDiffuse = 0xFF3C1E; + local_0.x = (double)pLevelDecorations[i].vPosition.x; + local_0.y = (double)pLevelDecorations[i].vPosition.y; + local_0.z = (double)pLevelDecorations[i].vPosition.z; + local_0.r = 0.0; + local_0.g = 0.0; + local_0.b = 0.0; + local_0.flt_28 = 1.0; + local_0.timeToLive = (rand() & 0x80) + 128; + local_0.uTextureID = pBitmaps_LOD->LoadTexture("effpar01"); + pGame->pParticleEngine->AddParticle(&local_0); + } + } + } +} + +//----- (0049D717) -------------------------------------------------------- +HRESULT __stdcall D3DZBufferFormatEnumerator(DDPIXELFORMAT *Src, DDPIXELFORMAT *Dst) +{ + if ( Src->dwFlags & (0x400 | 0x2000)) + { + if ( Src->dwRGBBitCount == 16 && !Src->dwRBitMask ) + { + memcpy(Dst, Src, sizeof(DDPIXELFORMAT)); + return 0; + } + if ( !Dst->dwSize ) + { + memcpy(Dst, Src, sizeof(DDPIXELFORMAT)); + return 1; + } + } + return 1; +} + +//----- (0049DC28) -------------------------------------------------------- +void RenderD3D::GetAvailableDevices(RenderD3D__DevInfo **pOutDevices) +{ + RenderD3D__DevInfo *v2; // eax@1 + + v2 = new RenderD3D__DevInfo[4];// 4 items + *pOutDevices = v2; + memset(v2, 0, sizeof(v2)); + DirectDrawEnumerateExA((LPDDENUMCALLBACKEXA)RenderD3D__DeviceEnumerator, *pOutDevices, DDENUM_ATTACHEDSECONDARYDEVICES); +} + +//----- (0049DC58) -------------------------------------------------------- +RenderD3D::RenderD3D() +{ + this->pHost = nullptr; + this->pDirect3D = nullptr; + this->pUnk = nullptr; + this->pBackBuffer = nullptr; + this->pFrontBuffer = nullptr; + this->pZBuffer = nullptr; + this->pDevice = nullptr; + this->pViewport = nullptr; + this->field_40 = 1; + this->field_44 = 10; + GetAvailableDevices(&this->pAvailableDevices); +} + +//----- (0049DC90) -------------------------------------------------------- +void RenderD3D::Release() +{ + if ( !this->bWindowed ) + { + if ( this->pHost ) + { + this->pHost->RestoreDisplayMode(); + this->pHost->SetCooperativeLevel(this->hWindow, DDSCL_NORMAL); + this->pHost->FlipToGDISurface(); + } + } + + for (int i = 0; i < 4; i++) + { + delete[] this->pAvailableDevices[i].pDriverName; + this->pAvailableDevices[i].pDriverName = nullptr; + + delete[] this->pAvailableDevices[i].pDeviceDesc; + this->pAvailableDevices[i].pDeviceDesc = nullptr; + + delete[] this->pAvailableDevices[i].pDDraw4DevDesc; + this->pAvailableDevices[i].pDDraw4DevDesc = nullptr; + + delete this->pAvailableDevices[i].pDirectDrawGUID; + this->pAvailableDevices[i].pDirectDrawGUID = nullptr; + + delete[] this->pAvailableDevices[i].pName; + this->pAvailableDevices[i].pName = nullptr; + + delete[] this->pAvailableDevices[i].pDescription; + this->pAvailableDevices[i].pDescription = nullptr; + + delete this->pAvailableDevices[i].pGUID; + this->pAvailableDevices[i].pGUID = nullptr; + } + + delete[] this->pAvailableDevices; + this->pAvailableDevices = NULL; + + if ( this->pViewport ) + { + this->pViewport->Release(); + this->pViewport = NULL; + } + + if ( this->pUnk ) + { + this->pUnk->Release(); + this->pUnk = NULL; + } + + if ( this->pZBuffer ) + { + this->pZBuffer->Release(); + this->pZBuffer = NULL; + } + + if ( this->pDevice ) + { + this->pDevice->Release(); + this->pDevice = NULL; + } + + if ( this->pDirect3D ) + { + this->pDirect3D->Release(); + this->pDirect3D = NULL; + } + + if ( this->pBackBuffer ) + { + this->pBackBuffer->Release(); + this->pBackBuffer = NULL; + } + + if ( this->pFrontBuffer ) + { + this->pFrontBuffer->Release(); + this->pFrontBuffer = NULL; + } + + if ( this->pHost ) + { + this->pHost->Release(); + this->pHost = NULL; + } +} + +//----- (0049DE14) -------------------------------------------------------- +bool RenderD3D::CreateDevice(unsigned int uDeviceID, int bWindowed, OSWindow *window) +{ + DWORD v26; // [sp-4h] [bp-DCh]@30 + DDSCAPS2 v27; // [sp+Ch] [bp-CCh]@37 + DDSURFACEDESC2 ddsd2; // [sp+1Ch] [bp-BCh]@11 + D3DVIEWPORT2 d3dvp2; // [sp+98h] [bp-40h]@28 + IDirectDrawClipper *lpddclipper; // [sp+C4h] [bp-14h]@18 + LPDIRECTDRAW lpDD; // [sp+C8h] [bp-10h]@1 + + auto hWnd = window->GetApiHandle(); + int game_width = window->GetWidth(); + int game_height = window->GetHeight(); + + this->bWindowed = bWindowed; + this->hWindow = hWnd; + + //Создание объекта DirectDraw + if (FAILED(DirectDrawCreate(pAvailableDevices[uDeviceID].pDirectDrawGUID, &lpDD, NULL))) + { + sprintf(pErrorMessage, "Init - Failed to create DirectDraw interface.\n"); + return 0; + } + + //Запрос интерфейса IDirectDraw4 + if (FAILED(lpDD->QueryInterface(IID_IDirectDraw4, (LPVOID *)&pHost))) + { + sprintf(pErrorMessage, "Init - Failed to create DirectDraw4 interface.\n"); + if (lpDD) + lpDD->Release(); + return 0; + } + lpDD->Release(); + lpDD = NULL; + + //Задаём уровень совместного доступа для приложения DirectDraw в оконном режиме + if (bWindowed && !pAvailableDevices[uDeviceID].pDirectDrawGUID) + { + if (FAILED(pHost->SetCooperativeLevel(hWnd, DDSCL_MULTITHREADED | DDSCL_NORMAL))) + { + sprintf(pErrorMessage, "Init - Failed to set cooperative level.\n"); + if (pHost) + { + pHost->Release(); + pHost = NULL; + } + return 0; + } + + // + memset(&ddsd2, 0, sizeof(DDSURFACEDESC2)); + ddsd2.dwSize = sizeof(DDSURFACEDESC2); + ddsd2.dwFlags = DDSD_CAPS; + ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + //Создаём первичную поверхность + if ( FAILED(pHost->CreateSurface(&ddsd2, &pFrontBuffer, NULL)) ) + { + sprintf(pErrorMessage, "Init - Failed to create front buffer.\n"); + if (pHost) + { + pHost->Release(); + pHost = NULL; + } + return 0; + } + ddsd2.dwSize = sizeof(DDSURFACEDESC2); + pHost->GetDisplayMode(&ddsd2); + if ( FORCE_16_BITS && ddsd2.ddpfPixelFormat.dwRGBBitCount != 16 ) + { + sprintf(pErrorMessage, "Init - Desktop isn't in 16 bit mode.\n"); + if (pFrontBuffer) + { + pFrontBuffer->Release(); + pFrontBuffer = NULL; + } + if (pHost) + { + pHost->Release(); + pHost = NULL; + } + return 0; + } + + ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + ddsd2.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE; + ddsd2.dwWidth = game_width; + ddsd2.dwHeight = game_height; + if (pHost->CreateSurface(&ddsd2, &pBackBuffer, NULL) ) + { + sprintf(pErrorMessage, "Init - Failed to create back buffer.\n"); + if (pFrontBuffer) + { + pFrontBuffer->Release(); + pFrontBuffer = NULL; + } + if (pHost) + { + pHost->Release(); + pHost = NULL; + } + return 0; + } + //Создание отсекателя DirectDraw + if ( pHost->CreateClipper(0, &lpddclipper, NULL) ) + { + sprintf(pErrorMessage, "Init - Failed to create clipper.\n"); + if (pBackBuffer) + { + pBackBuffer->Release(); + pBackBuffer = NULL; + } + if (pFrontBuffer) + { + pFrontBuffer->Release(); + pFrontBuffer= NULL; + } + if (pHost) + { + pHost->Release(); + pHost = NULL; + } + return 0; + } + lpddclipper->SetHWnd(0, hWnd); + pFrontBuffer->SetClipper(lpddclipper); + + lpddclipper->Release(); + lpddclipper = NULL; + // + + pHost->QueryInterface(IID_IDirect3D3, (LPVOID *)&pDirect3D); + + ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; + ddsd2.ddsCaps.dwCaps = DDSCAPS_ZBUFFER; + ddsd2.dwWidth = game_width; + ddsd2.dwHeight = game_height; + + if ( pDirect3D->EnumZBufferFormats(*pAvailableDevices[uDeviceID].pGUID, + (HRESULT (__stdcall *)(DDPIXELFORMAT *, void *))D3DZBufferFormatEnumerator, + &ddsd2.ddpfPixelFormat) ) + { + sprintf(pErrorMessage, "Init - Failed to enumerate Z buffer formats.\n"); + if (pBackBuffer) + { + pBackBuffer->Release(); + pBackBuffer = NULL; + } + if (pFrontBuffer) + { + pFrontBuffer->Release(); + pFrontBuffer= NULL; + } + if (pHost) + { + pHost->Release(); + pHost = NULL; + } + return 0; + } + if ( uDeviceID == 2 || uDeviceID == 3 ) + ddsd2.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; + + if ( !pHost->CreateSurface(&ddsd2, &pZBuffer, NULL) ) + { + if ( !pBackBuffer->AddAttachedSurface(pZBuffer) ) + { + if ( !pDirect3D->CreateDevice(*pAvailableDevices[uDeviceID].pGUID, pBackBuffer, &pDevice, 0) ) + { + memset(&d3dvp2, 0, sizeof(D3DVIEWPORT2)); + d3dvp2.dvClipWidth = 2.0; + d3dvp2.dvClipY = 1.0; + d3dvp2.dvClipHeight = 2.0; + d3dvp2.dvMaxZ = 1.0; + d3dvp2.dvMinZ = 0.0; + goto LABEL_54; + } + sprintf(pErrorMessage, "Init - Failed to create D3D device.\n"); + if (pDirect3D) + { + pDirect3D->Release(); + pDirect3D = NULL; + } + if (pZBuffer) + { + pZBuffer->Release(); + pZBuffer = NULL; + } + if (pBackBuffer) + { + pBackBuffer->Release(); + pBackBuffer = NULL; + } + if (pFrontBuffer) + { + pFrontBuffer->Release(); + pFrontBuffer= NULL; + } + if (pHost) + { + pHost->Release(); + pHost = NULL; + } + return 0; + } + sprintf(pErrorMessage, "Init - Failed to attach z-buffer to back buffer.\n"); + if (pZBuffer) + { + pZBuffer->Release(); + pZBuffer = NULL; + } + if (pBackBuffer) + { + pBackBuffer->Release(); + pBackBuffer = NULL; + } + if (pFrontBuffer) + { + pFrontBuffer->Release(); + pFrontBuffer= NULL; + } + if (pHost) + { + pHost->Release(); + pHost = NULL; + } + return 0; + } + sprintf(pErrorMessage, "Init - Failed to create z-buffer.\n"); + if (pBackBuffer) + { + pBackBuffer->Release(); + pBackBuffer = NULL; + } + if (pFrontBuffer) + { + pFrontBuffer->Release(); + pFrontBuffer= NULL; + } + if (pHost) + { + pHost->Release(); + pHost = NULL; + } + return 0; + } + if ( uDeviceID == 1 ) + v26 = 1045; + else + v26 = 1041; + if (pHost->SetCooperativeLevel(hWnd, v26) ) + { + sprintf(pErrorMessage, "Init - Failed to set cooperative level.\n"); + if (pHost) + { + pHost->Release(); + pHost = NULL; + } + return 0; + } + if (pHost->SetDisplayMode(window->GetWidth(), window->GetHeight(), 16, 0, 0) ) + { + sprintf(pErrorMessage, "Init - Failed to set display mode.\n"); + if (pHost) + { + pHost->Release(); + pHost = NULL; + } + return 0; + } + + memset(&ddsd2, 0, sizeof(DDSURFACEDESC2)); + ddsd2.dwSize = sizeof(DDSURFACEDESC2); + //Подключение полей с достоверными данными + ddsd2.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; + //Запрос сложной структуры с возможностью переключения + ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; + //Присвоение полю счётчика задних буферов значения 1 + ddsd2.dwBackBufferCount = 1; + if ( pHost->CreateSurface(&ddsd2, &pFrontBuffer, NULL) ) + { + sprintf(pErrorMessage, "Init - Failed to create front buffer.\n"); + if (pHost) + { + pHost->Release(); + pHost = NULL; + } + return 0; + } + //a3a = &pBackBuffer; + //v14 = *v34; + memset(&v27, 0, sizeof(DDSCAPS2)); + + v27.dwCaps = DDSCAPS_BACKBUFFER; + //v33 = (IDirect3DDevice3 **)v14->GetAttachedSurface(&v27, &pBackBuffer); + //hWnda = &pDirect3D; + pHost->QueryInterface(IID_IDirect3D3, (LPVOID *)&pDirect3D); + + if (FAILED(pFrontBuffer->GetAttachedSurface(&v27, &pBackBuffer))) + { + sprintf(pErrorMessage, "Init - Failed to get D3D interface.\n"); + if (pBackBuffer) + { + pBackBuffer->Release(); + pBackBuffer = NULL; + } + if (pFrontBuffer) + { + pFrontBuffer->Release(); + pFrontBuffer= NULL; + } + if (pHost) + { + pHost->Release(); + pHost = NULL; + } + return 0; + } + + ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; + ddsd2.ddsCaps.dwCaps = DDSCAPS_ZBUFFER; + ddsd2.dwWidth = 640; + ddsd2.dwHeight = 480; + if ( pDirect3D->EnumZBufferFormats(*pAvailableDevices[uDeviceID].pGUID, + (HRESULT (__stdcall *)(DDPIXELFORMAT *, void *))D3DZBufferFormatEnumerator, + &ddsd2.ddpfPixelFormat) ) + { + sprintf(pErrorMessage, "Init - Failed to enumerate Z buffer formats.\n"); + if (pBackBuffer) + { + pBackBuffer->Release(); + pBackBuffer = 0; + } + if (pFrontBuffer) + { + pFrontBuffer->Release(); + pFrontBuffer= 0; + } + if (pHost) + { + pHost->Release(); + pHost = 0; + } + return 0; + } + if ( uDeviceID == 2 || uDeviceID == 3 ) + BYTE1(ddsd2.ddsCaps.dwCaps) |= 8; + //uDeviceIDa = &pZBuffer; + if (pHost->CreateSurface(&ddsd2, &pZBuffer, NULL) ) + { + sprintf(pErrorMessage, "Init - Failed to create z-buffer.\n"); + if (pBackBuffer) + { + pBackBuffer->Release(); + pBackBuffer = 0; + } + if (pFrontBuffer) + { + pFrontBuffer->Release(); + pFrontBuffer= 0; + } + if (pHost) + { + pHost->Release(); + pHost = 0; + } + return 0; + } + if (pBackBuffer->AddAttachedSurface(pZBuffer)) + { + sprintf(pErrorMessage, "Init - Failed to attach z-buffer to back buffer.\n"); + if (pZBuffer) + { + pZBuffer->Release(); + pZBuffer = 0; + } + if (pBackBuffer) + { + pBackBuffer->Release(); + pBackBuffer = 0; + } + if (pFrontBuffer) + { + pFrontBuffer->Release(); + pFrontBuffer= 0; + } + if (pHost) + { + pHost->Release(); + pHost = 0; + } + return 0; + } + //v33 = &pDevice; + if (pDirect3D->CreateDevice(*pAvailableDevices[uDeviceID].pGUID, pBackBuffer, &pDevice, 0) ) + { + sprintf(pErrorMessage, "Init - Failed to create D3D device.\n"); + if (pDirect3D) + { + pDirect3D->Release(); + pDirect3D = 0; + } + if (pZBuffer) + { + pZBuffer->Release(); + pZBuffer = 0; + } + if (pBackBuffer) + { + pBackBuffer->Release(); + pBackBuffer = 0; + } + if (pFrontBuffer) + { + pFrontBuffer->Release(); + pFrontBuffer= 0; + } + if (pHost) + { + pHost->Release(); + pHost = 0; + } + return 0; + } + memset(&d3dvp2, 0, sizeof(D3DVIEWPORT2)); + d3dvp2.dvClipWidth = 2.0; + d3dvp2.dvClipY = 1.0; + d3dvp2.dvClipHeight = 2.0; + d3dvp2.dvMaxZ = 1.0; + +LABEL_54: + d3dvp2.dwSize = sizeof(D3DVIEWPORT2); + //v17 = *hWnda; + d3dvp2.dwWidth = game_width; + d3dvp2.dwHeight = game_height; + d3dvp2.dvClipX = -1.0; + //v18 = v17->lpVtbl; + //v32 = &v4->pViewport; + if (pDirect3D->CreateViewport(&pViewport, 0)) + { + sprintf(pErrorMessage, "Init - Failed to create viewport.\n"); + if (pDevice) + { + pDevice->Release(); + pDevice = 0; + } + if (pDirect3D) + { + pDirect3D->Release(); + pDirect3D = 0; + } + if (pZBuffer) + { + pZBuffer->Release(); + pZBuffer = 0; + } + if (pBackBuffer) + { + pBackBuffer->Release(); + pBackBuffer = 0; + } + if (pFrontBuffer) + { + pFrontBuffer->Release(); + pFrontBuffer= 0; + } + if (pHost) + { + pHost->Release(); + pHost = 0; + } + return 0; + } + + pDevice->AddViewport(pViewport); + pViewport->SetViewport2(&d3dvp2); + pDevice->SetCurrentViewport(pViewport); + return 1; +} + +//----- (0049E444) -------------------------------------------------------- +unsigned int RenderD3D::GetDeviceCaps() +{ + unsigned int v1; // ebx@1 + unsigned int result; // eax@2 + D3DDEVICEDESC refCaps; // [sp+Ch] [bp-1F8h]@1 + D3DDEVICEDESC halCaps; // [sp+108h] [bp-FCh]@1 + + v1 = 0; + + memset(&halCaps, 0, sizeof(halCaps)); + halCaps.dwSize = sizeof(halCaps); + + memset(&refCaps, 0, sizeof(refCaps)); + refCaps.dwSize = sizeof(refCaps); + + if ( this->pDevice->GetCaps(&halCaps, &refCaps) ) + result = 1; + else + { + if ( !(halCaps.dpcTriCaps.dwSrcBlendCaps & D3DPBLENDCAPS_SRCALPHA) ) + v1 = 2; + if ( !(halCaps.dpcTriCaps.dwSrcBlendCaps & D3DPBLENDCAPS_ONE) ) + v1 |= 4; + if ( !(halCaps.dpcTriCaps.dwSrcBlendCaps & D3DPBLENDCAPS_ZERO) ) + v1 |= 8; + if ( !(halCaps.dpcTriCaps.dwDestBlendCaps & D3DPBLENDCAPS_INVSRCALPHA) ) + v1 |= 16; + if ( !(halCaps.dpcTriCaps.dwDestBlendCaps & D3DPBLENDCAPS_ONE) ) + v1 |= 32; + if ( !(halCaps.dpcTriCaps.dwDestBlendCaps & D3DPBLENDCAPS_SRCCOLOR) ) + v1 |= 64; + if ( halCaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_SQUAREONLY ) + v1 |= 128; + result = v1; + } + return result; +} + +//----- (0049E4FC) -------------------------------------------------------- +void RenderD3D::ClearTarget(unsigned int bClearColor, unsigned int uClearColor, unsigned int bClearDepth, float z_clear) +{ + uint uClearFlags = 0; + + if (bClearColor) + uClearFlags |= D3DCLEAR_TARGET; + if (bClearDepth) + uClearFlags |= D3DCLEAR_ZBUFFER; + + D3DRECT rects[] = {{0, 0, window->GetWidth(), window->GetHeight()}}; + if (uClearFlags) + pViewport->Clear2(1, rects, uClearFlags, uClearColor, z_clear, 0); +} + +//----- (0049E54D) -------------------------------------------------------- +void RenderD3D::Present(bool bForceBlit) +{ + RECT source_rect; // [sp+18h] [bp-18h]@1 + struct tagPOINT Point; // [sp+28h] [bp-8h]@4 + + source_rect.left = 0; + source_rect.top = 0; + source_rect.bottom = 480;//window->GetHeight(); //Ritor1: проблема с кнопкой "развернуть" + source_rect.right = 640; //window->GetWidth(); + + if (bWindowed || bForceBlit) + { + RECT dest_rect; + GetClientRect(hWindow, &dest_rect); + Point.y = 0; + Point.x = 0; + ClientToScreen(hWindow, &Point); + OffsetRect(&dest_rect, Point.x, Point.y); + pFrontBuffer->Blt(&dest_rect, pBackBuffer, &source_rect, DDBLT_WAIT, NULL); + } + else + pFrontBuffer->Flip(NULL, DDFLIP_WAIT); +} + +//----- (0049E5D4) -------------------------------------------------------- +bool RenderD3D::CreateTexture(unsigned int uTextureWidth, unsigned int uTextureHeight, IDirectDrawSurface4 **pOutSurface, IDirect3DTexture2 **pOutTexture, bool bAlphaChannel, bool bMipmaps, unsigned int uMinDeviceTexDim) +{ + unsigned int v9; // ebx@5 + unsigned int v10; // eax@5 + DWORD v11; // edx@5 + DDSURFACEDESC2 ddsd2; // [sp+Ch] [bp-80h]@1 + + memset(&ddsd2, 0, sizeof(ddsd2)); + ddsd2.dwSize = sizeof(ddsd2); + ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; + ddsd2.ddsCaps.dwCaps = DDSCAPS_TEXTURE; + ddsd2.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE; + ddsd2.dwHeight = uTextureHeight; + ddsd2.dwWidth = uTextureWidth; + if ( bMipmaps ) + { + if ( (signed int)uTextureHeight <= (signed int)uTextureWidth ) + { + ddsd2.dwMipMapCount = GetMaxMipLevels(uTextureHeight) - GetMaxMipLevels(uMinDeviceTexDim); + if ( ddsd2.dwMipMapCount ) + { + ddsd2.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT; + ddsd2.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP; + } + goto LABEL_12; + } + if ( (signed int)uTextureWidth < (signed int)uMinDeviceTexDim ) + { + ddsd2.dwMipMapCount = GetMaxMipLevels(uMinDeviceTexDim); + if ( ddsd2.dwMipMapCount ) + { + ddsd2.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT; + ddsd2.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP; + } + goto LABEL_12; + } + v9 = GetMaxMipLevels(uTextureWidth); + v10 = GetMaxMipLevels(uMinDeviceTexDim); + ddsd2.dwMipMapCount = v9 - v10; + if ( v9 == v10 ) + { + ddsd2.dwFlags = 0x1007; + __debugbreak(); // warning C4700: uninitialized local variable 'v11' used + ddsd2.ddsCaps.dwCaps = v11; + goto LABEL_12; + } + } + else + ddsd2.dwMipMapCount = 1; + ddsd2.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT; + ddsd2.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP; +LABEL_12: + ddsd2.ddpfPixelFormat.dwRGBBitCount = 16; + ddsd2.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); + if (bAlphaChannel) + { + ddsd2.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS; + ddsd2.ddpfPixelFormat.dwRBitMask = 0x7C00; + ddsd2.ddpfPixelFormat.dwGBitMask = 0x03E0; + ddsd2.ddpfPixelFormat.dwBBitMask = 0x001F; + ddsd2.ddpfPixelFormat.dwRGBAlphaBitMask = 0x8000; + } + else + { + ddsd2.ddpfPixelFormat.dwFlags = DDPF_RGB; + ddsd2.ddpfPixelFormat.dwRBitMask = 0xF800; + ddsd2.ddpfPixelFormat.dwGBitMask = 0x07E0; + ddsd2.ddpfPixelFormat.dwBBitMask = 0x001F; + ddsd2.ddpfPixelFormat.dwRGBAlphaBitMask = 0; + } + if (FAILED(pHost->CreateSurface(&ddsd2, pOutSurface, NULL))) + return false; + if (FAILED((*pOutSurface)->QueryInterface(IID_IDirect3DTexture2, (void **)pOutTexture))) + { + (*pOutSurface)->Release(); + *pOutSurface = 0; + return false; + } + return true; +} + +//----- (004A5190) -------------------------------------------------------- +void RenderD3D::HandleLostResources() +{ + pBitmaps_LOD->ReleaseLostHardwareTextures(); + pBitmaps_LOD->_410423_move_textures_to_device(); + pSprites_LOD->ReleaseLostHardwareSprites(); +} + +//----- (004A2050) -------------------------------------------------------- +void Render::DrawPolygon(unsigned int uNumVertices, struct Polygon *a3, ODMFace *a4, IDirect3DTexture2 *pTexture) +{ + unsigned int v6; // ebx@1 + int v8; // eax@7 + unsigned int v41; // eax@29 + //unsigned int v54; // [sp+5Ch] [bp-Ch]@3 + signed int a2; // [sp+64h] [bp-4h]@4 + + v6 = 0; + if ( this->uNumD3DSceneBegins && (signed int)uNumVertices >= 3 ) + { + //v54 = pGame->pLightmapBuilder->std__vector_000004_size; + if ( pGame->pLightmapBuilder->std__vector_000004_size) + a2 = -1; + pGame->AlterGamma_ODM(a4, &a2); + if ( byte_4D864C && pGame->uFlags & GAME_FLAGS_1_01_lightmap_related) + { + v8 = ::GetActorTintColor(a3->dimming_level, 0, array_50AC10[0].vWorldViewPosition.x, 0, 0); + pGame->pLightmapBuilder->DrawLightmaps(/*v8, 0*/); + } + else + { + if ( !pGame->pLightmapBuilder->std__vector_000004_size || byte_4D864C && pGame->uFlags & 2 ) + { + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CW)); + if (bUsingSpecular) + { + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); + } + for (uint i = 0; i < uNumVertices; ++i) + { + + d3d_vertex_buffer[i].pos.x = array_50AC10[i].vWorldViewProjX; + d3d_vertex_buffer[i].pos.y = array_50AC10[i].vWorldViewProjY; + d3d_vertex_buffer[i].pos.z = 1.0 - 1.0 / ((array_50AC10[i].vWorldViewPosition.x * 1000) / (double)pODMRenderParams->shading_dist_mist); + d3d_vertex_buffer[i].rhw = 1.0 / (array_50AC10[i].vWorldViewPosition.x + 0.0000001); + d3d_vertex_buffer[i].diffuse = ::GetActorTintColor(a3->dimming_level, 0, array_50AC10[i].vWorldViewPosition.x, 0, 0); + pGame->AlterGamma_ODM(a4, &d3d_vertex_buffer[i].diffuse); + + if ( this->bUsingSpecular ) + d3d_vertex_buffer[i].specular = sub_47C3D7_get_fog_specular(0, 0, array_50AC10[i].vWorldViewPosition.x); + else + d3d_vertex_buffer[i].specular = 0; + d3d_vertex_buffer[i].texcoord.x = array_50AC10[i].u; + d3d_vertex_buffer[i].texcoord.y = array_50AC10[i].v; + + } + + if (a4->uAttributes & FACE_OUTLINED) + { + int color; + if (GetTickCount() % 300 >= 150) + color = 0xFFFF2020; + else color = 0xFF901010; + + for (uint i = 0; i < uNumVertices; ++i) + d3d_vertex_buffer[i].diffuse = color; + } + + pRenderD3D->pDevice->SetTexture(0, pTexture); + pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + d3d_vertex_buffer, + uNumVertices, + D3DDP_DONOTLIGHT); + } + else + { + for (uint i = 0; i < uNumVertices; ++i) + { + + d3d_vertex_buffer[i].pos.x = array_50AC10[i].vWorldViewProjX; + d3d_vertex_buffer[i].pos.y = array_50AC10[i].vWorldViewProjY; + d3d_vertex_buffer[i].pos.z = 1.0 - 1.0 / ((array_50AC10[i].vWorldViewPosition.x * 1000) / (double)pODMRenderParams->shading_dist_mist); + d3d_vertex_buffer[i].rhw = 1.0 / (array_50AC10[i].vWorldViewPosition.x + 0.0000001); + d3d_vertex_buffer[i].diffuse = GetActorTintColor(a3->dimming_level, 0, array_50AC10[i].vWorldViewPosition.x, 0, 0); + if ( this->bUsingSpecular ) + d3d_vertex_buffer[i].specular = sub_47C3D7_get_fog_specular(0, 0, array_50AC10[i].vWorldViewPosition.x); + else + d3d_vertex_buffer[i].specular = 0; + d3d_vertex_buffer[i].texcoord.x = array_50AC10[i].u; + d3d_vertex_buffer[i].texcoord.y = array_50AC10[i].v; + + } + + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); + if (bUsingSpecular) + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE)); + + ErrD3D(pRenderD3D->pDevice->SetTexture(0, nullptr)); + ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_TEX1 | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, + d3d_vertex_buffer, + uNumVertices, + D3DDP_DONOTLIGHT)); + //v50 = (const char *)v5->pRenderD3D->pDevice; + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE)); + //(*(void (**)(void))(*(int *)v50 + 88))(); + pGame->pLightmapBuilder->DrawLightmaps(/*-1, 0*/); + for (uint i = 0; i < uNumVertices; ++i) + { + d3d_vertex_buffer[i].diffuse = a2; + } + ErrD3D(pRenderD3D->pDevice->SetTexture(0, pTexture)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); + if ( !pRenderer->bUsingSpecular ) + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); + + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ZERO)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_SRCCOLOR)); + ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_TEX1 | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, + d3d_vertex_buffer, + uNumVertices, + D3DDP_DONOTLIGHT)); + if (bUsingSpecular) + { + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); + + for (uint i = 0; i < uNumVertices; ++i) + { + d3d_vertex_buffer[i].diffuse = pRenderer->uFogColor | d3d_vertex_buffer[i].specular & 0xFF000000; + d3d_vertex_buffer[i].specular = 0; + } + + ErrD3D(pRenderD3D->pDevice->SetTexture(0, nullptr)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_INVSRCALPHA)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_SRCALPHA)); + ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_TEX1 | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, + d3d_vertex_buffer, + uNumVertices, + D3DDP_DONOTLIGHT)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE)); + //v40 = pRenderer->pRenderD3D->pDevice->lpVtbl; + v41 = GetLevelFogColor(); + pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, GetLevelFogColor() & 0xFFFFFF); + v6 = 0; + pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, 0); + } + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, v6)); + } + } + } +} +// 4D864C: using guessed type char byte_4D864C; + +//----- (0049EB79) -------------------------------------------------------- +Render::~Render() +{ + free(this->pDefaultZBuffer); + this->pD3DBitmaps.Release(); + this->pD3DSprites.Release(); + Release(); + this->bWindowMode = 1; + //nullsub_1(); + //nullsub_1(); +} + + +//----- (0049E992) -------------------------------------------------------- +Render::Render() +{ + //Render *v1; // esi@1 +// int v2; // eax@1 +// char v3; // zf@1 + + //v1 = this; + this->pDirectDraw4 = nullptr; + this->pFrontBuffer4 = nullptr; + this->pBackBuffer4 = nullptr; + //this->pColorKeySurface4 = 0; + //this->pDirectDraw2 = 0; + //this->pFrontBuffer2 = 0; + //this->pBackBuffer2 = 0; + //this->pSomeSurface2 = 0; + //RenderHWLContainer::RenderHWLContainer(&this->pD3DBitmaps); + //RenderHWLContainer::RenderHWLContainer(&v1->pD3DSprites); + this->bWindowMode = 1; + //this->field_40054 = 0; + //this->field_10 = 640; + //this->field_14 = 480; + //this->field_40030 = 0; + //this->field_4002C = 0; + this->pActiveZBuffer = nullptr; + this->pDefaultZBuffer = nullptr; + this->raster_clip_y = 0; + this->raster_clip_x = 0; + this->raster_clip_z = 639; + this->raster_clip_w = 479; + //this->field_4003C = 0x004EED80; + //this->field_40040 = dword_4EED78; + this->uClipZ = 640; + //this->field_40044 = 2; + //this->field_40048 = 6; + this->pFrontBuffer4 = nullptr; + this->pBackBuffer4 = nullptr; + //this->pColorKeySurface4 = 0; + this->pDirectDraw4 = nullptr; + this->pRenderD3D = 0; + this->uNumSceneBegins = 0; + this->uNumD3DSceneBegins = 0; + this->using_software_screen_buffer = 0; + this->pTargetSurface = nullptr; + this->uTargetSurfacePitch = 0; + this->uClipY = 0; + this->uClipX = 0; + this->uClipW = 480; + this->bClip = 1; + //this->bColorKeySupported = 0; + this->bRequiredTextureStagesAvailable = 0; + this->bTinting = 1; + //LOBYTE(this->field_103668) = 0; + uNumBillboardsToDraw = 0; + bFogEnabled = false; + + hd_water_tile_id = -1; + hd_water_current_frame = 0; +} + +bool Render::Initialize(OSWindow *window/*, bool bColoredLights, uint32_t uDetailLevel, bool bTinting*/) +{ + //bUserDirect3D = true;//ReadWindowsRegistryInt("Use D3D", 0); + + this->window = window; + //bStartInWindow = true; + //windowed_mode_width = windowed_width; + //windowed_mode_height = windowed_height; + + uDesiredDirect3DDevice = ReadWindowsRegistryInt("D3D Device", 0); + + bUseColoredLights = ReadWindowsRegistryInt("Colored Lights", false); + uLevelOfDetail = ReadWindowsRegistryInt("Detail Level", 1); + bTinting = ReadWindowsRegistryInt("Tinting", 1) != 0; + + bool r1 = pD3DBitmaps.Load(L"data\\d3dbitmap.hwl"); + bool r2 = pD3DSprites.Load(L"data\\d3dsprite.hwl"); + + return r1 && r2; +} + + +//----- (0049ECC4) -------------------------------------------------------- +void Render::ClearBlack() +{ + //if (pRenderD3D) + { + if (using_software_screen_buffer) + pRenderD3D->ClearTarget(true, 0, false, 0.0); + } + //else + //memset(pRenderer->pTargetSurface, 0, 4 * (field_10 * field_14 / 2)); +} + +//----- (0049ED18) -------------------------------------------------------- +void Render::PresentBlackScreen() +{ + IDirectDrawSurface *lpddsback; // eax@3 + DDBLTFX lpDDBltFx; // [sp+4h] [bp-74h]@5 + RECT dest_rect; // [sp+68h] [bp-10h]@3 + + memset(&lpDDBltFx, 0, sizeof(DDBLTFX)); + lpDDBltFx.dwSize = sizeof(DDBLTFX); + + GetWindowRect(window->GetApiHandle(), &dest_rect); + lpddsback = (IDirectDrawSurface *)this->pBackBuffer4; + + lpDDBltFx.dwFillColor = 0; + lpddsback->Blt(&dest_rect, NULL, NULL, DDBLT_COLORFILL, &lpDDBltFx); + pRenderer->Present(); +} + +//----- (0049EDB6) -------------------------------------------------------- +void Render::SavePCXScreenshot() +{ + int v5; // eax@8 + FILE *pOutFile; // edi@10 + unsigned short *v8; // eax@11 + signed int v12; // eax@18 + char v15[56]; // [sp+Ch] [bp-158h]@10 + DDSURFACEDESC2 Dst; // [sp+48h] [bp-11Ch]@7 + char color_map[48]; // [sp+C4h] [bp-A0h]@10 + char Filename[40]; // [sp+F4h] [bp-70h]@3 + char *lineB; // [sp+11Ch] [bp-48h]@14 + char *lineG; // [sp+120h] [bp-44h]@14 + FILE *File; // [sp+128h] [bp-3Ch]@3 + PCXHeader_1 header1; // [sp+130h] [bp-34h]@10 + PCXHeader_2 header2; // [sp+140h] [bp-24h]@10 + char *lineRGB; // [sp+148h] [bp-1Ch]@10 + void *surface; // [sp+14Ch] [bp-18h]@8 + unsigned int image_width; // [sp+150h] [bp-14h]@4 + int pitch; // [sp+154h] [bp-10h]@4 + char v31; // [sp+15Ah] [bp-Ah]@25 + unsigned char pict_byte; // [sp+15Bh] [bp-9h]@17 + unsigned short *line_picture_data; // [sp+15Ch] [bp-8h]@10 + byte test_byte; // [sp+163h] [bp-1h]@17 + + int num_r_bits = 5; + int num_g_bits = 6; + int num_b_bits = 5; + + int r_mask = 0xF800; + int g_mask = 0x7E0; + int b_mask = 0x1F; + + if ( !this->pRenderD3D || this->using_software_screen_buffer ) + { + sprintf(Filename, "screen%0.2i.pcx", ScreenshotFileNumber++ % 100); + File = fopen(Filename, "wb"); + if ( File ) + { + pitch = this->GetRenderWidth(); + if ( pitch & 1 ) + pitch = pitch + 1; + if ( this->pRenderD3D ) + { + memset(&Dst, 0, sizeof(Dst)); + Dst.dwSize = sizeof(Dst); + if ( !pRenderer->LockSurface_DDraw4(pRenderer->pBackBuffer4, &Dst, DDLOCK_WAIT) ) + return; + surface = Dst.lpSurface; + v5 = Dst.lPitch / 2; + } + else + { + pRenderer->BeginScene(); + surface = pRenderer->pTargetSurface; + v5 = pRenderer->uTargetSurfacePitch; + } + header1.right = GetRenderWidth() - 1; + header1.left = 0; + header1.bottom = this->GetRenderHeight() - 1; + header1.up = 0; + header2.pitch = pitch; + memset(color_map, 0, sizeof(color_map)); + memset(v15, 0, sizeof(v15)); + header2.reserved = 0; + header1.manufacturer = 10; + pOutFile = File; + header1.version = 5; + header1.encoding = 1; + header1.bpp = 8; + header1.hdpi = 75; + header1.vdpi = 75; + header2.planes = 3; + header2.palette_info = 1; + fwrite(&header1, 1, 1, File); + fwrite(&header1.version, 1, 1, pOutFile); + fwrite(&header1.encoding, 1, 1, pOutFile); + fwrite(&header1.bpp, 1, 1, pOutFile); + fwrite(&header1.left, 2, 1, pOutFile); + fwrite(&header1.up, 2, 1, pOutFile); + fwrite(&header1.right, 2, 1, pOutFile); + fwrite(&header1.bottom, 2, 1, pOutFile); + fwrite(&header1.hdpi, 2, 1, pOutFile); + fwrite(&header1.vdpi, 2, 1, pOutFile); + fwrite(color_map, 0x30, 1, pOutFile); + fwrite(&header2, 1, 1, pOutFile); + fwrite(&header2.planes, 1, 1, pOutFile); + fwrite(&header2.pitch, 2, 1, pOutFile); + fwrite(&header2.palette_info, 2, 1, pOutFile); + fwrite(v15, 0x3Au, 1, pOutFile); + lineRGB = (char *)malloc(3 * GetRenderWidth() + 6); + if ( this->GetRenderHeight() > 0 ) + { + image_width = 3 * pitch; + //v24 = 2 * v5; + v8 = (unsigned short *)surface; + for ( unsigned int y = 0; y < this->GetRenderHeight(); y++ ) + { + line_picture_data = v8; + if ( GetRenderWidth() > 0 ) + { + lineG = (char *)lineRGB + pitch; + lineB = (char *)lineRGB + 2 * pitch; + for ( uint x = 0; x < this->GetRenderWidth(); x++ ) + { + //int p = *line_picture_data; //0x2818 + //int for_rad = (pRenderer->uTargetGBits + pRenderer->uTargetBBits );//16 = 8 + 8 + //int value = (pRenderer->uTargetRMask & *line_picture_data);//0 = 0xFF0000 & 0x2818 + //int result = (pRenderer->uTargetRMask & *line_picture_data) >> (pRenderer->uTargetGBits + pRenderer->uTargetBBits ); + lineRGB[x] = (uTargetRMask & *line_picture_data) >> (uTargetGBits + uTargetBBits );// + pRenderer->uTargetRBits - 8); + lineG[x] = (uTargetGMask & *line_picture_data) >> (uTargetBBits);// + pRenderer->uTargetGBits - 8); + //int value2 = (pRenderer->uTargetGMask & *line_picture_data); //10240 = 0xFF00 & 0x2818 + //int result2 = (pRenderer->uTargetGMask & *line_picture_data) >> (pRenderer->uTargetBBits); + lineB[x] = (uTargetBMask & *line_picture_data);// << (8 - pRenderer->uTargetBBits); + //int value3 = (pRenderer->uTargetBMask & *line_picture_data);//24 = 0xFF & 0x2818 + line_picture_data += 2; + } + } + for ( uint i = 0; i < image_width; i += test_byte ) + { + pict_byte = lineRGB[i]; + for ( test_byte = 1; test_byte < 0x3F; ++test_byte ) + { + v12 = i + test_byte; + if ( lineRGB[v12] != pict_byte ) + break; + if ( !(v12 % pitch) ) + break; + } + if ( i + test_byte > image_width ) + test_byte = 3 * pitch - i; + if ( test_byte > 1 || pict_byte >= 0xC0 ) + { + v31 = test_byte | 0xC0; + fwrite(&v31, 1, 1, pOutFile); + } + fwrite(&pict_byte, 1, 1, pOutFile); + } + v8 += v5; + } + } + if ( this->pRenderD3D ) + ErrD3D(pRenderer->pBackBuffer4->Unlock(NULL)); + else + pRenderer->EndScene(); + + free(lineRGB); + fclose(pOutFile); + } + } +} + +//----- (0049F1BC) -------------------------------------------------------- +void Render::SaveWinnersCertificate(const char *a1) +{ + unsigned int v6; // eax@8 + //FILE *v7; // edi@10 +// int v8; // ecx@11 + unsigned short *v9; // eax@11 + int v10; // eax@13 + signed int v13; // eax@18 +// char v14; // zf@27 +// HRESULT v15; // eax@29 + char v16[56]; // [sp+Ch] [bp-12Ch]@10 + __int16 v17; // [sp+44h] [bp-F4h]@10 + DDSURFACEDESC2 Dst; // [sp+48h] [bp-F0h]@7 +// int v19; // [sp+58h] [bp-E0h]@8 +// unsigned __int16 *v20; // [sp+6Ch] [bp-CCh]@8 + char color_map[48]; // [sp+C4h] [bp-74h]@10 +// unsigned int v22; // [sp+F4h] [bp-44h]@11 + char *lineB; // [sp+F8h] [bp-40h]@14 + int image_width; // [sp+FCh] [bp-3Ch]@11 + int v25; // [sp+100h] [bp-38h]@4 + FILE *File; // [sp+104h] [bp-34h]@3 + char Str; // [sp+108h] [bp-30h]@10 + char v28; // [sp+109h] [bp-2Fh]@10 + char v29; // [sp+10Ah] [bp-2Eh]@10 + char v30; // [sp+10Bh] [bp-2Dh]@10 + __int16 v31; // [sp+10Ch] [bp-2Ch]@10 + __int16 v32; // [sp+10Eh] [bp-2Ah]@10 + __int16 v33; // [sp+110h] [bp-28h]@10 + __int16 v34; // [sp+112h] [bp-26h]@10 + __int16 v35; // [sp+114h] [bp-24h]@10 + __int16 v36; // [sp+116h] [bp-22h]@10 + char v37; // [sp+118h] [bp-20h]@10 + char v38; // [sp+119h] [bp-1Fh]@10 + __int16 v39; // [sp+11Ah] [bp-1Eh]@10 + __int16 v40; // [sp+11Ch] [bp-1Ch]@10 + char *lineRGB; // [sp+120h] [bp-18h]@10 + void *surface; // [sp+124h] [bp-14h]@8 + int pitch; // [sp+128h] [bp-10h]@4 + char v44; // [sp+12Fh] [bp-9h]@25 + char *lineG; // [sp+130h] [bp-8h]@10 + unsigned char pict_byte; // [sp+137h] [bp-1h]@17 + byte test_byte; + + int num_r_bits = 5; + int num_g_bits = 6; + int num_b_bits = 5; + + int r_mask = 0xF800; + int g_mask = 0x7E0; + int b_mask = 0x1F; + + if ( !this->pRenderD3D || this->using_software_screen_buffer ) + { + static int _4EFA84_num_winners_certificates = 0; + ++_4EFA84_num_winners_certificates; + + File = fopen(a1, "wb"); + if ( File ) + { + v25 = this->GetRenderWidth(); + pitch = v25; + if ( pitch & 1 ) + pitch = pitch + 1; + if ( this->pRenderD3D ) + { + memset(&Dst, 0, 0x7C); + Dst.dwSize = 124; + if ( !pRenderer->LockSurface_DDraw4(pRenderer->pBackBuffer4, (DDSURFACEDESC2 *)&Dst, DDLOCK_WAIT) ) + return; + surface = Dst.lpSurface; + v6 = Dst.lPitch / 2; + } + else + { + pRenderer->BeginScene(); + surface = pRenderer->pTargetSurface; + v6 = pRenderer->uTargetSurfacePitch; + } + v33 = this->GetRenderWidth() - 1; + v31 = 0; + v34 = (short)this->GetRenderHeight() - 1; + v32 = 0; + v39 = pitch; + memset(&color_map, 0, sizeof(color_map)); + memset(&v16, 0, sizeof(v16)); + v37 = 0; + Str = 10; + v17 = 0; + v28 = 5; + v29 = 1; + v30 = 8; + v35 = 75; + v36 = 75; + v38 = 3; + v40 = 1; + fwrite(&Str, 1, 1, File); + fwrite(&v28, 1, 1, File); + fwrite(&v29, 1, 1, File); + fwrite(&v30, 1, 1, File); + fwrite(&v31, 2, 1, File); + fwrite(&v32, 2, 1, File); + fwrite(&v33, 2, 1, File); + fwrite(&v34, 2, 1, File); + fwrite(&v35, 2, 1, File); + fwrite(&v36, 2, 1, File); + fwrite(&color_map, 0x30, 1, File); + fwrite(&v37, 1, 1, File); + fwrite(&v38, 1, 1, File); + fwrite(&v39, 2, 1, File); + fwrite(&v40, 2, 1, File); + fwrite(&v16, 0x3A, 1, File); + lineRGB = (char *)malloc(3 * (v25 + 2)); + if ( (signed int)this->GetRenderHeight() > 0 ) + { + image_width = 3 * pitch; + v9 = (unsigned short *)surface; + for ( uint j = 0; j < this->GetRenderHeight(); j++) + { + a1 = (const char *)v9; + if ( v25 > 0 ) + { + lineG = (char *)lineRGB + pitch; + lineB = (char *)lineRGB + 2 * pitch; + for ( v10 = 0; v10 < v25; v10++ ) + { + lineRGB[v10] = (signed int)(r_mask & *(short *)a1) >> (num_g_bits + num_b_bits + num_r_bits - 8); + lineG[v10] = (signed int)(g_mask & *(short *)a1) >> (num_b_bits + num_g_bits - 8); + lineB[v10] = (b_mask & *(short *)a1) << (8 - num_b_bits); + a1 += 2; + } + } + for ( uint i = 0; i < image_width; i += test_byte ) + { + pict_byte = lineRGB[i]; + for ( test_byte = 1; test_byte < 0x3F; test_byte ) + { + v13 = i + test_byte; + if ( lineRGB[v13] != pict_byte ) + break; + if ( !(v13 % pitch) ) + break; + } + if ( i + test_byte > image_width ) + test_byte = 3 * pitch - i; + if ( test_byte > 1 || pict_byte >= 0xC0 ) + { + v44 = test_byte | 0xC0; + fwrite(&v44, 1, 1, File); + } + fwrite(&pict_byte, 1, 1, File); + } + v9 += pitch; + } + } + if ( this->pRenderD3D ) + ErrD3D(pRenderer->pBackBuffer4->Unlock(NULL)); + else + pRenderer->EndScene(); + free(lineRGB); + fclose(File); + } + } +} + +//----- (0049F5A2) -------------------------------------------------------- +void Render::PackPCXpicture( unsigned short* picture_data, int wight, int heidth, void *data_buff, int max_buff_size,unsigned int* packed_size ) +{ + void *v8; // esi@3 + void *v9; // esi@3 + unsigned short* v11; // eax@4 +// int v13; // eax@8 +// int v14; // ecx@8 + signed int v15; // eax@11 +// char v16; // zf@20 +// int result; // eax@21 + char v18[58]; // [sp+Ch] [bp-ACh]@3 + char v20[48]; // [sp+48h] [bp-70h]@3 + char *lineG; // [sp+78h] [bp-40h]@7 + char *lineB; // [sp+7Ch] [bp-3Ch]@7 + int v23; // [sp+80h] [bp-38h]@4 + int v24; // [sp+84h] [bp-34h]@4 + int v25; // [sp+88h] [bp-30h]@4 + int v26; // [sp+8Ch] [bp-2Ch]@4 + PCXHeader_1 Src; // [sp+90h] [bp-28h]@3 + PCXHeader_2 v27; // [sp+A0h] [bp-18h]@3 + char *lineRGB; // [sp+A8h] [bp-10h]@3 + int pitch; // [sp+ACh] [bp-Ch]@1 + char v43; // [sp+B3h] [bp-5h]@18 + int i; // [sp+B4h] [bp-4h]@6 + unsigned short* line_picture_data; + byte test_byte; + unsigned char pict_byte; + + int num_r_bits = 5; + int num_g_bits = 6; + int num_b_bits = 5; + + int r_mask = 0xF800; + int g_mask = 0x7E0; + int b_mask = 0x1F; + + pitch = wight; + if ( wight & 1 ) + pitch = wight + 1; + Src.left = 0; + Src.up = 0; + Src.right = wight - 1; + Src.bottom = heidth - 1; + v27.pitch = pitch; + memset(&v20, 0, 0x30u); + memset(&v18, 0, 0x38u); + v8 = data_buff; + v27.reserved = 0; + *(_WORD *)&v18[56] = 0; + Src.manufacturer = 10; + Src.version = 5; + Src.encoding = 1; + Src.bpp = 8; + Src.hdpi = 75; + Src.vdpi = 75; + v27.planes = 3; + v27.palette_info = 1; + memcpy(data_buff, &Src, 1); + v8 = (char *)v8 + 1; + memcpy(v8, &Src.version, 1); + v8 = (char *)v8 + 1; + memcpy(v8, &Src.encoding, 1); + v8 = (char *)v8 + 1; + memcpy(v8, &Src.bpp, 1); + v8 = (char *)v8 + 1; + memcpy(v8, &Src.left, 2); + v8 = (char *)v8 + 2; + memcpy(v8, &Src.up, 2); + v8 = (char *)v8 + 2; + memcpy(v8, &Src.right, 2); + v8 = (char *)v8 + 2; + memcpy(v8, &Src.bottom, 2); + v8 = (char *)v8 + 2; + memcpy(v8, &Src.hdpi, 2); + v8 = (char *)v8 + 2; + memcpy(v8, &Src.vdpi, 2); + v8 = (char *)v8 + 2; + memcpy(v8, &v20, 0x30u); + v8 = (char *)v8 + 48; + memcpy(v8, &v27, 1u); + v8 = (char *)v8 + 1; + memcpy(v8, &v27.planes, 1); + v8 = (char *)v8 + 1; + memcpy(v8, &v27.pitch, 2); + v8 = (char *)v8 + 2; + memcpy(v8, &v27.palette_info, 2); + v8 = (char *)v8 + 2; + memcpy(v8, &v18, 0x3Au); + v9 = (char *)v8 + 58; + + lineRGB = (char*)malloc(3 * (wight + 2)); + if ( heidth > 0 ) + { + v26 = 3 * pitch; + v23 = 2 * wight; + v11 = picture_data; + v24 = (int)picture_data; + for ( v25 = heidth; v25; v25-- ) + { + line_picture_data = v11; + if ( wight > 0 ) + { + lineG = (char *)lineRGB + pitch; + lineB = (char *)lineRGB + 2 * pitch; + for ( uint i = 0; i < wight; i++ ) + { + lineRGB[i] = (signed int)(r_mask & *line_picture_data) >> (num_g_bits + num_b_bits + num_r_bits - 8); + lineG[i] = (signed int)(g_mask & *line_picture_data) >> ( num_b_bits + num_g_bits- 8); + lineB[i] = (b_mask & *line_picture_data) << (8 - num_b_bits); + line_picture_data += 1; + } + } + for ( i = 0; i < v26; v9 = (char *)v9 + 1 ) + { + pict_byte = lineRGB[i]; + for ( test_byte = 1; test_byte < 63; ++test_byte ) + { + v15 = i + test_byte; + if ( lineRGB[v15] != pict_byte )//Uninitialized memory access + break; + if ( !(v15 % pitch) ) + break; + } + if ( i + test_byte > v26 ) + test_byte = 3 * pitch - i; + if ( test_byte > 1 || pict_byte >= 192 ) + { + v43 = test_byte | 0xC0; + memcpy(v9, &v43, 1); + v9 = (char *)v9 + 1; + } + memcpy(v9, &pict_byte, 1); + i += test_byte; + } + v11 += wight; + } + } + free(lineRGB); + *(int *)packed_size = (char *)v9 - data_buff; +} + +//----- (0049F8B5) -------------------------------------------------------- +void Render::SavePCXImage(const char *Filename, unsigned short* picture_data, int width, int height) +{ + FILE *result; // eax@1 + FILE *pOutFile; // edi@4 + unsigned short* v9; // eax@5 +// int v10; // eax@7 + signed int v12; // eax@12 +// char v13; // zf@21 + char v14[56]; // [sp+4h] [bp-A0h]@4 + __int16 v15; // [sp+3Ch] [bp-68h]@4 + char color_map[48]; // [sp+40h] [bp-64h]@4 + int v18; // [sp+74h] [bp-30h]@5 +// char *v19; // [sp+78h] [bp-2Ch]@5 + int image_width; // [sp+7Ch] [bp-28h]@5 + PCXHeader_1 header1; // [sp+80h] [bp-24h]@4 + PCXHeader_2 header2; // [sp+90h] [bp-14h]@4 + char *lineRGB; // [sp+98h] [bp-Ch]@4 + int pitch; // [sp+9Ch] [bp-8h]@2 + char *lineB; // [sp+A0h] [bp-4h]@8 + char *lineG; + unsigned short* line_pictute_data; + byte test_byte; + char v43; + + int num_r_bits = 5; + int num_g_bits = 6; + int num_b_bits = 5; + + int r_mask = 0xF800; + int g_mask = 0x7E0; + int b_mask = 0x1F; + + result = fopen(Filename, "wb"); + Filename = (const char *)result; + if ( result ) + { + pitch = width; + if ( width & 1 ) + pitch = width + 1; + header1.left = 0; + header1.up = 0; + header1.right = width - 1; + header1.bottom = height - 1; + header2.pitch = pitch; + memset(color_map, 0, sizeof(color_map)); + header2.reserved = 0; + memset(v14, 0, sizeof(v14)); + v15 = 0; + header1.manufacturer = 10; + header1.version = 5; + header1.encoding = 1; + header1.bpp = 8; + header1.hdpi = 75; + header1.vdpi = 75; + header2.planes = 3; + header2.palette_info = 1; + fwrite(&header1, 1, 1, (FILE *)Filename); + pOutFile = (FILE *)Filename; + fwrite(&header1.version, 1, 1, (FILE *)Filename); + fwrite(&header1.encoding, 1, 1, pOutFile); + fwrite(&header1.bpp, 1, 1, pOutFile); + fwrite(&header1.left, 2, 1, pOutFile); + fwrite(&header1.up, 2, 1, pOutFile); + fwrite(&header1.right, 2, 1, pOutFile); + fwrite(&header1.bottom, 2, 1, pOutFile); + fwrite(&header1.hdpi, 2, 1, pOutFile); + fwrite(&header1.vdpi, 2, 1, pOutFile); + fwrite(color_map, 0x30u, 1, pOutFile); + fwrite(&header2, 1, 1, pOutFile); + fwrite(&header2.planes, 1, 1, pOutFile); + fwrite(&header2.pitch, 2, 1, pOutFile); + fwrite(&header2.palette_info, 2, 1, pOutFile); + fwrite(v14, 0x3Au, 1, pOutFile); + + lineRGB = (char *)malloc(3 * (width + 2)); + //При сохранении изображения подряд идущие пиксели одинакового цвета объединяются и вместо указания цвета для каждого пикселя + //указывается цвет группы пикселей и их количество. + image_width = 3 * pitch; + v9 = picture_data; + for ( v18 = 0; v18 < height; v18++ )//столбец + { + line_pictute_data = v9; + lineG = (char *)lineRGB + pitch; + lineB = (char *)lineRGB + 2 * pitch; + + for ( int i = 0; i < width; i++ )//строка + { + lineRGB[i] = (signed int)(r_mask & *line_pictute_data) >> (num_g_bits + num_b_bits + num_r_bits - 8); + lineG[i] = (signed int)(g_mask & *line_pictute_data) >> (num_b_bits + num_g_bits - 8); + lineB[i] = (b_mask & *line_pictute_data) << (8 - num_b_bits); + line_pictute_data += 1; + } + test_byte = 1; + for ( int i = 0; (signed int)i < image_width; i += test_byte ) + { + unsigned char pic_byte = lineRGB[i]; + for ( test_byte; test_byte < 63; ++test_byte )// расчёт количества одинаковых цветов + { + v12 = i + test_byte; + if ( lineRGB[v12] != pic_byte ) + break; + if ( !(v12 % pitch) ) + break; + } + if ( i + test_byte > image_width ) + test_byte = 3 * pitch - i; + if ( test_byte > 1 || pic_byte >= 0xC0 ) + { + v43 = test_byte | 0xC0;//тест-байт объединения + fwrite(&v43, 1, 1, pOutFile); + } + fwrite(&pic_byte, 1, 1, pOutFile); + } + v9 += width; + } + free(lineRGB); + fclose(pOutFile); + } +} + +//----- (0049FBCD) -------------------------------------------------------- +void Render::ClearTarget(unsigned int uColor) +{ + //if (pRenderD3D) + { + if (using_software_screen_buffer) + pRenderD3D->ClearTarget(true, uColor, false, 0.0); + } + //else + //memset32(pTargetSurface, uColor, field_10 * field_14 / 2); +} + + +//----- (0049FC37) -------------------------------------------------------- +void Render::Present() +{ + //struct tagRECT Rect; // [sp+8h] [bp-28h]@11 + //RECT a4; // [sp+18h] [bp-18h]@11 + //struct tagPOINT Point; // [sp+28h] [bp-8h]@11 + + if ( !pRenderD3D || this->using_software_screen_buffer ) + { + this->pBeforePresentFunction(); + if ( this->pRenderD3D ) + { + if ( this->using_software_screen_buffer ) + pRenderD3D->Present(false); + } + else + __debugbreak(); // no sr + /*{ + if ( this->bWindowMode ) + { + RestoreFrontBuffer(); + GetClientRect(this->hWnd, &Rect); + Point.y = 0; + Point.x = 0; + ClientToScreen(this->hWnd, &Point); + OffsetRect(&Rect, Point.x, Point.y); + a4.top = 0; + a4.bottom = 480; + a4.left = 0; + a4.right = 640; + PresentRect(&Rect, &a4); + } + else + { + RestoreFrontBuffer(); + a4.top = 0; + a4.bottom = 480; + a4.left = 0; + a4.right = 640; + BltBackToFontFast(0, 0, &a4); + } + }*/ + } +} + +//----- (0049FD3A) -------------------------------------------------------- +void Render::_49FD3A_fullscreen() +{ + RECT src_rect; // [sp+8h] [bp-10h]@6 + + if ( this->pRenderD3D ) + { + if (pFrontBuffer4->IsLost() == DDERR_SURFACELOST) + pFrontBuffer4->Restore(); + if (pBackBuffer4->IsLost() == DDERR_SURFACELOST) + pBackBuffer4->Restore(); + src_rect.top = 0; + src_rect.bottom = window->GetHeight(); + src_rect.left = 0; + src_rect.right = window->GetWidth(); + this->pBackBuffer4->BltFast(NULL, NULL, this->pFrontBuffer4, &src_rect, DDBLTFAST_WAIT); + } +} + +//----- (0049FDBF) -------------------------------------------------------- +void Render::CreateZBuffer() +{ + if (!pDefaultZBuffer) + { + pDefaultZBuffer = pActiveZBuffer = (int *)malloc(0x12C000); + memset32(pActiveZBuffer, 0xFFFF0000, 0x4B000u); // // inlined Render::ClearActiveZBuffer (mm8::004A085B) + } +} + +//----- (0049FE05) -------------------------------------------------------- +void Render::Release() +{ + //Render *v1; // esi@1 + //RenderD3D *v2; // ecx@1 + //char v3; // zf@4 + //void *v4; // ebx@6 +// IDirectDraw *v5; // eax@10 +// IDirectDrawSurface2 *v6; // eax@11 +// IDirectDrawSurface2 *v7; // eax@13 +// IDirectDrawSurface2 *v8; // eax@15 +// IDirectDraw2 *v9; // eax@17 +// IDirectDraw4 *v10; // eax@19 +// IDirectDrawSurface4 *v11; // eax@20 +// IDirectDrawSurface4 *v12; // eax@22 +// IDirectDrawSurface4 *v13; // eax@24 +// IDirectDraw4 *v14; // eax@26 +// unsigned __int16 **v15; // ebx@28 +// void **v16; // esi@29 + + // v1 = this; + if (pRenderD3D) + { + if ( this->using_software_screen_buffer ) + { + pRenderD3D->ClearTarget(true, 0, false, 1.0); + pRenderD3D->Present(0); + pRenderD3D->ClearTarget(true, 0, false, 1.0); + } + //this->pColorKeySurface4 = 0; + this->pBackBuffer4 = nullptr; + this->pFrontBuffer4 = nullptr; + this->pDirectDraw4 = nullptr; + delete [] this->pTargetSurface_unaligned; + this->pTargetSurface = nullptr; + this->pTargetSurface_unaligned = nullptr; + if (pRenderD3D) + { + pRenderD3D->Release(); + delete pRenderD3D; + } + pRenderD3D = nullptr; + } + else + ;//__debugbreak(); // no sr + /*{ + if ( bWinNT4_0 == 1 ) + { + v5 = (IDirectDraw *)this->pDirectDraw2; + if ( !v5 ) + return; + v5->SetCooperativeLevel(this->hWnd, 8u); + this->pDirectDraw2->FlipToGDISurface(); + v6 = this->pSomeSurface2; + if ( v6 ) + { + v6->Release(); + this->pSomeSurface2 = 0; + } + v7 = this->pBackBuffer2; + if ( v7 ) + { + v7->Release(); + this->pBackBuffer2 = 0; + } + v8 = this->pFrontBuffer2; + if ( v8 ) + { + v8->Release(); + this->pFrontBuffer2 = 0; + } + v9 = this->pDirectDraw2; + if ( v9 ) + { + v9->Release(); + this->pDirectDraw2 = 0; + } + } + else + { + v10 = this->pDirectDraw4; + if ( !v10 ) + return; + v10->SetCooperativeLevel(this->hWnd, 1032u); + this->pDirectDraw4->FlipToGDISurface(); + v11 = this->pColorKeySurface4; + if ( v11 ) + { + v11->Release(); + this->pColorKeySurface4 = 0; + } + v12 = this->pBackBuffer4; + if ( v12 ) + { + v12->Release(); + this->pBackBuffer4 = 0; + } + v13 = this->pFrontBuffer4; + if ( v13 ) + { + v13->Release(); + this->pFrontBuffer4 = 0; + } + v14 = this->pDirectDraw4; + if ( v14 ) + { + v14->Release(); + this->pDirectDraw4 = 0; + } + } + v15 = &this->pTargetSurface; + if ( this->pTargetSurface ) + { + v16 = (void **)&this->ptr_400E8; + free(*v16); + *v15 = 0; + *v16 = 0; + } + }*/ +} + +void Present32(unsigned __int32 *src, unsigned int src_pitch, + unsigned __int32 *dst, unsigned int dst_pitch) +{ + for (uint y = 0; y < 8; ++y) + memcpy(dst + y * dst_pitch, + src + y * src_pitch, src_pitch * sizeof(__int32)); + + for (uint y = 8; y < 352; ++y) + { + memcpy(dst + y * dst_pitch, + src + y * src_pitch, 8 * sizeof(__int32)); + memcpy(dst + 8 + game_viewport_width + y * dst_pitch, + src + 8 + game_viewport_width + y * src_pitch, 174/*172*/ * sizeof(__int32)); + } + + for (uint y = 352; y < 480; ++y) + memcpy(dst + y * dst_pitch, + src + y * src_pitch, src_pitch * sizeof(__int32)); + + for (uint y = pViewport->uViewportTL_Y; y < pViewport->uViewportBR_Y + 1; ++y) + { + for (uint x = pViewport->uViewportTL_X; x < pViewport->uViewportBR_X; ++x) + { + //if (src[x + y * src_pitch] != (pRenderer->uTargetGMask | pRenderer->uTargetBMask)) + if (src[x + y * src_pitch] != 0xFF00FCF8) // FFF8FCF8 = Color32(Color16(g_mask | b_mask)) + dst[x + y * dst_pitch] = src[x + y * src_pitch]; + } + } +} + +//----- (004A597D) -------------------------------------------------------- +void Present_NoColorKey() +{ + void *v2; // edi@4 + int v9; // eax@10 + unsigned int v10; // esi@10 + unsigned __int32 v11; // edi@10 + unsigned int v13; // ebx@10 + DDSURFACEDESC2 Dst; // [sp+Ch] [bp-98h]@3 + int v21; // [sp+8Ch] [bp-18h]@10 + __int32 v22; // [sp+90h] [bp-14h]@10 + unsigned int v24; // [sp+98h] [bp-Ch]@4 + + int r_mask = 0xF800; + int g_mask = 0x7E0; + int b_mask = 0x1F; + + //if ( !pRenderer->uNumSceneBegins ) + { + //if ( pRenderer->using_software_screen_buffer ) + //{ + memset(&Dst, 0, sizeof(Dst)); + Dst.dwSize = sizeof(Dst); + if ( pRenderer->LockSurface_DDraw4(pRenderer->pBackBuffer4, &Dst, DDLOCK_WAIT) ) + { + //v26 = Dst.lpSurface; + //pRenderer->pCurrentlyLockedSurfaceDataPtr = (unsigned __int16 *)Dst.lpSurface; + v24 = g_mask | b_mask | ((g_mask | b_mask) << 16); + //pRenderer->pCurrentlyLockedSoftSurface = pRenderer->pTargetSurface; + //pRenderer->uCurrentlyLockedSurfacePitch = Dst.lPitch; + //v1 = pRenderer->pTargetSurface; + v2 = Dst.lpSurface; + + + /*for (uint y = 0; y < 480; ++y) + { + auto pDst = (unsigned short *)((char *)Dst.lpSurface + y * Dst.lPitch); + for (uint x = 0; x < 640; ++x) + pDst[x] = pRenderer->uTargetRMask | pRenderer->uTargetBMask; + }*/ + + if (!FORCE_16_BITS) + Present32((unsigned __int32 *)pRenderer->pTargetSurface, pRenderer->uTargetSurfacePitch, (unsigned __int32 *)Dst.lpSurface, Dst.lPitch / 4); + else + { + ushort* pSrc = (unsigned short *)pRenderer->pTargetSurface; + short* pDst = (__int16 *)Dst.lpSurface; + + for (uint y = 0; y < 8; ++y) + memcpy(pDst + y * Dst.lPitch / 2, + + pSrc + y * window->GetWidth(), window->GetWidth() * sizeof(__int16)); + + for (uint y = 8; y < 352; ++y) + { + memcpy(pDst + y * Dst.lPitch / 2, + pSrc + y * window->GetWidth(), 8 * sizeof(__int16)); + memcpy(pDst + 8 + game_viewport_width/*462*/ + y * Dst.lPitch / 2, + pSrc + 8 + game_viewport_width/*462*/ + y * window->GetWidth(), 174/*172*/ * sizeof(__int16)); + } + + for (uint y = 352; y < window->GetHeight(); ++y) + memcpy(pDst + y * Dst.lPitch / 2, + pSrc + y * window->GetWidth(), window->GetWidth() * sizeof(__int16)); + + + ushort* pSrc_x1y1 = pSrc + window->GetWidth() * pViewport->uViewportTL_Y + pViewport->uViewportTL_X; + //_this = (unsigned int)&pSrc[2 * (((signed int)pViewport->uViewportX >> 1) + 320 * pViewport->uViewportY)]; + short* pDst_x1y1 = pDst + Dst.lPitch * pViewport->uViewportTL_Y + pViewport->uViewportTL_X; + //v23 = (unsigned __int32)((char *)v26 + 4 * (((signed int)pViewport->uViewportX >> 1) + (Dst.lPitch >> 2) * pViewport->uViewportY)); + v9 = ((signed int)pViewport->uViewportTL_X >> 1) - ((signed int)pViewport->uViewportBR_X >> 1); + //v20 = ((signed int)pViewport->uViewportZ >> 1) - ((signed int)pViewport->uViewportX >> 1); + v22 = 4 * ((Dst.lPitch / 4) + v9); + v21 = 4 * v9 + 1280; + + //auto uNumLines = pViewport->uViewportW - pViewport->uViewportY + 1; + //v26 = (LPVOID)(pViewport->uViewportW - pViewport->uViewportY + 1); + v10 = (int)pSrc_x1y1; + v11 = (int)pDst_x1y1; + int uHalfWidth = (pViewport->uViewportBR_X - pViewport->uViewportTL_X) / 2; + v13 = v24; + + for (uint y = pViewport->uViewportTL_Y; y < pViewport->uViewportBR_Y + 1; ++y) + { + //memcpy(pDst + pViewport->uViewportX + y * Dst.lPitch / 2, + // pSrc + pViewport->uViewportX + y * 640, (pViewport->uViewportZ - pViewport->uViewportX) * sizeof(__int16)); + for (uint x = pViewport->uViewportTL_X; x < pViewport->uViewportBR_X; ++x) + { + if (pSrc[y * window->GetWidth() + x] != (g_mask | b_mask)) + pDst[y * Dst.lPitch / 2 + x] = pSrc[y * window->GetWidth() + x]; + } + } + } + + ErrD3D(pRenderer->pBackBuffer4->Unlock(NULL)); + + /* while ( 1 ) + { + while ( 1 ) + { + v14 = *(int *)v10; + v10 += 4; + if ( v14 == v13 ) + break; + if ( (short)v14 == (short)v13 ) + { + *(int *)v11 = *(int *)v11 & 0xFFFF | v14 & 0xFFFF0000; + v11 += 4; + --uHalfWidth; + if ( !uHalfWidth ) + goto LABEL_21; + } + else + { + v15 = __ROL__(v14, 16); + if ( (short)v15 == (short)v13 ) + { + v17 = __ROR__(v15, 16); + *(int *)v11 = *(int *)v11 & 0xFFFF0000 | (unsigned __int16)v17; + v11 += 4; + --uHalfWidth; + if ( !uHalfWidth ) + goto LABEL_21; + } + else + { + v16 = __ROR__(v15, 16); + *(int *)v11 = v16; + v11 += 4; + --uHalfWidth; + if ( !uHalfWidth ) + goto LABEL_21; + } + } + } + v11 += 4; + --uHalfWidth; + if ( !uHalfWidth ) + { +LABEL_21: + v10 += v21; + v11 += v22; + uHalfWidth = v20; + if ( !--uNumLines ) + { + ErrD3D(pRenderer->pBackBuffer4->Unlock(NULL)); + return; + } + } + }*/ + } + //} + } +} + + +//----- (0049FFFB) -------------------------------------------------------- +bool Render::InitializeFullscreen() +{ + RenderD3D__DevInfo *v7; // ecx@5 + bool v8; // eax@6 + unsigned int v10; // eax@13 + signed int v15; // ebx@31 + int *v22; // eax@42 + int v23; // ecx@42 + D3DDEVICEDESC refCaps; // [sp+Ch] [bp-300h]@25 + DDSURFACEDESC2 pDesc; // [sp+108h] [bp-204h]@40 + D3DDEVICEDESC halCaps; // [sp+184h] [bp-188h]@25 + int v29; // [sp+308h] [bp-4h]@2 + + //__debugbreak(); // Nomad + + this->using_software_screen_buffer = 0; + //this->pColorKeySurface4 = 0; + this->pBackBuffer4 = nullptr; + this->pFrontBuffer4 = nullptr; + this->pDirectDraw4 = nullptr; + //this->bColorKeySupported = 0; + Release(); + //v3 = hWnd; + this->window = window; + CreateZBuffer(); + + /*if (!bUserDirect3D) + { + CreateDirectDraw(); + SetDirectDrawCooperationMode(hWnd, 1); + SetDirectDrawDisplayMode(640u, 480u, 16u); + CreateDirectDrawPrimarySurface(); + v15 = 1; + } + else + {*/ + pRenderD3D = new RenderD3D; + //v28 = pRenderD3D; + //v6 = uDesiredDirect3DDevice; + v29 = -1; + v7 = pRenderD3D->pAvailableDevices; + if ( pRenderD3D->pAvailableDevices[uDesiredDirect3DDevice].bIsDeviceCompatible ) + v8 = pRenderD3D->CreateDevice(uDesiredDirect3DDevice, /*0*/true, window); + else + { + if ( v7[1].bIsDeviceCompatible ) + v8 = pRenderD3D->CreateDevice(1, /*0*/true, window); + else + { + if ( !v7->bIsDeviceCompatible ) + Error("There aren't any D3D devices to create."); + + v8 = pRenderD3D->CreateDevice(0, /*0*/true, window); + } + } + if ( !v8 ) + Error("D3Drend->Init failed."); + + //v9 = pRenderD3D; + pBackBuffer4 = pRenderD3D->pBackBuffer; + pFrontBuffer4 = pRenderD3D->pFrontBuffer; + pDirectDraw4 = pRenderD3D->pHost; + v10 = pRenderD3D->GetDeviceCaps(); + if ( v10 & 1 ) + { + if ( pRenderD3D ) + { + pRenderD3D->Release(); + delete pRenderD3D; + } + pRenderD3D = nullptr; + pBackBuffer4 = nullptr; + pFrontBuffer4 = nullptr; + pDirectDraw4 = nullptr; + Error("Direct3D renderer: The device failed to return capabilities."); + } + if ( v10 & 0x3E ) + { + if ( pRenderD3D ) + { + pRenderD3D->Release(); + delete pRenderD3D; + } + //pColorKeySurface4 = 0; + pRenderD3D = nullptr; + pBackBuffer4 = nullptr; + pFrontBuffer4 = nullptr; + pDirectDraw4 = nullptr; + Error("Direct3D renderer: The device doesn't support the necessary alpha blending modes."); + } + if ( (v10 & 0x80) != 0 ) + { + if ( pRenderD3D ) + { + pRenderD3D->Release(); + delete pRenderD3D; + } + pRenderD3D = nullptr; + pBackBuffer4 = nullptr; + pFrontBuffer4 = nullptr; + pDirectDraw4 = nullptr; + Error("Direct3D renderer: The device doesn't support non-square textures."); + } + //LOBYTE(field_10365C) = ~(unsigned __int8)(v10 >> 6) & 1; + bRequiredTextureStagesAvailable = CheckTextureStages(); + + memset(&halCaps, 0, sizeof(halCaps)); + halCaps.dwSize = sizeof(halCaps); + + memset(&refCaps, 0, sizeof(refCaps)); + refCaps.dwSize = sizeof(refCaps); + + ErrD3D(pRenderD3D->pDevice->GetCaps(&halCaps, &refCaps)); + + uMinDeviceTextureDim = halCaps.dwMinTextureWidth; + if ( (unsigned int)halCaps.dwMinTextureWidth >= halCaps.dwMinTextureHeight ) + uMinDeviceTextureDim = halCaps.dwMinTextureHeight; + uMinDeviceTextureDim = halCaps.dwMaxTextureWidth; + if ( (unsigned int)halCaps.dwMaxTextureWidth < halCaps.dwMaxTextureHeight ) + uMinDeviceTextureDim = halCaps.dwMaxTextureHeight; + if ( (unsigned int)uMinDeviceTextureDim < 4 ) + uMinDeviceTextureDim = 4; + v15 = 1; + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, true)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, true)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, 2)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SPECULARENABLE, false)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_COLORKEYENABLE, false)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, false)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, 1)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, 2)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MINFILTER, 2)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, 3)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, 2)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, 0)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, 2)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, 2)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, 0)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLOROP, 4)); + //} + ddpfPrimarySuface.dwSize = 32; + GetTargetPixelFormat(&ddpfPrimarySuface); + ParseTargetPixelFormat(); + + if (!pRenderD3D) + { + __debugbreak(); + pBeforePresentFunction = 0;//nullsub_1; + } + //else + //{ + /*v16 = IsColorKeySupported(pDirectDraw4); + v17 = uAcquiredDirect3DDevice == v15; + bColorKeySupported = v16; + if ( !v17 ) + bColorKeySupported = 0; + if ( bColorKeySupported ) + { + memset(&ddsd2, 0, sizeof(ddsd2)); + ddsd2.dwSize = sizeof(ddsd2); + ddsd2.ddckCKSrcBlt.dwColorSpaceLowValue = uTargetGMask | uTargetBMask; + ddsd2.ddckCKSrcBlt.dwColorSpaceHighValue = ddsd2.ddckCKSrcBlt.dwColorSpaceLowValue; + ddsd2.dwFlags = 65543; + ddsd2.ddsCaps.dwCaps = 2112; + ddsd2.dwWidth = 640; + ddsd2.dwHeight = 480; + ErrD3D(pDirectDraw4->CreateSurface(&ddsd2, &pColorKeySurface4, NULL)); + pBeforePresentFunction = Present_ColorKey; + } + else*/ + { + pTargetSurface = nullptr; + pTargetSurface_unaligned = (unsigned int *)malloc(window->GetWidth() * window->GetHeight() * 2 + 32); + if ( !pTargetSurface_unaligned ) + return 0; + memset(&pDesc, 0, sizeof(pDesc)); + pDesc.dwSize = sizeof(pDesc); + if ( !pRenderer->LockSurface_DDraw4(pRenderer->pBackBuffer4, &pDesc, v15) ) + return 0; + pBackBuffer4->Unlock(NULL); + v22 = (int *)pTargetSurface_unaligned + 4; + v23 = (unsigned int)pDesc.lpSurface & 7; + LOBYTE(v22) = (unsigned __int8)v22 & 0xF8; + uTargetSurfacePitch = window->GetWidth(); + pBeforePresentFunction = Present_NoColorKey; + v15 = 1; + pTargetSurface = (unsigned __int32 *)((char *)v22 + 2 * v23); + } + using_software_screen_buffer = v15; + //} + bWindowMode = 0; + pParty->uFlags |= 2; + pViewport->SetFOV(flt_6BE3A0 * 65536.0f); + return v15 != 0; +} + +//----- (004A05F3) -------------------------------------------------------- +bool Render::SwitchToWindow() +{ + bool v7; // eax@7 + unsigned int v9; // eax@12 + int v12; // eax@24 + int v13; // eax@26 + D3DDEVICEDESC refCaps; // [sp+Ch] [bp-300h]@24 + DDSURFACEDESC2 pDesc; // [sp+108h] [bp-204h]@37 + D3DDEVICEDESC halCaps; // [sp+184h] [bp-188h]@24 + int v29; // [sp+308h] [bp-4h]@2 + + pParty->uFlags |= PARTY_FLAGS_1_0002; + pViewport->SetFOV(flt_6BE3A0 * 65536.0f); + using_software_screen_buffer = 0; + Release(); + //pColorKeySurface4 = 0; + pBackBuffer4 = nullptr; + pFrontBuffer4 = nullptr; + pDirectDraw4 = nullptr; + //bColorKeySupported = 0; + CreateZBuffer(); + /*if (!bUserDirect3D) + { + CreateDirectDraw(); + SetDirectDrawCooperationMode(hWnd, 0); + field_4004C = 1; + CreateFrontBuffer(); + CreateClipper(hWnd); + CreateBackBuffer(); + field_40030 = 0; + field_18_locked_pitch = 0; + } + else + {*/ + /*v3 = malloc(0x148u); + thisa = (RenderD3D *)v3; + v29 = 0; + if ( v3 ) + v4 = RenderD3D::RenderD3D((RenderD3D *)v3); + else + v4 = 0;*/ + pRenderD3D = new RenderD3D; + //v4 = pRenderD3D; + //v5 = uDesiredDirect3DDevice; + v29 = -1; + //v6 = pRenderD3D->pAvailableDevices; + if (pRenderD3D->pAvailableDevices[uDesiredDirect3DDevice].bIsDeviceCompatible && + uDesiredDirect3DDevice != 1 ) + { + v7 = pRenderD3D->CreateDevice(uDesiredDirect3DDevice, true, window); + } + else + { + if ( !pRenderD3D->pAvailableDevices[0].bIsDeviceCompatible ) + Error("There aren't any D3D devices to init."); + + v7 = pRenderD3D->CreateDevice(0, true, window); + } + if ( !v7 ) + Error("D3Drend->Init failed."); + + //v8 = pRenderD3D; + //pColorKeySurface4 = 0; + pBackBuffer4 = pRenderD3D->pBackBuffer; + pFrontBuffer4 = pRenderD3D->pFrontBuffer; + pDirectDraw4 = pRenderD3D->pHost; + v9 = pRenderD3D->GetDeviceCaps(); + if ( v9 & 1 ) + { + if (pRenderD3D) + { + pRenderD3D->Release(); + delete pRenderD3D; + } + pRenderD3D = nullptr; + pBackBuffer4 = nullptr; + pFrontBuffer4 = nullptr; + pDirectDraw4 = nullptr; + Error("Direct3D renderer: The device failed to return capabilities."); + } + if ( v9 & 0x3E ) + { + if (pRenderD3D) + { + pRenderD3D->Release(); + delete pRenderD3D; + } + //pColorKeySurface4 = 0; + pRenderD3D = nullptr; + pBackBuffer4 = nullptr; + pFrontBuffer4 = nullptr; + pDirectDraw4 = nullptr; + Error("Direct3D renderer: The device doesn't support the necessary alpha blending modes."); + } + if (v9 & 0x80) + { + if (pRenderD3D) + { + pRenderD3D->Release(); + delete pRenderD3D; + } + pRenderD3D = nullptr; + pBackBuffer4 = nullptr; + pFrontBuffer4 = nullptr; + pDirectDraw4 = nullptr; + Error("Direct3D renderer: The device doesn't support non-square textures."); + } + //LOBYTE(field_10365C) = ~(unsigned __int8)(v9 >> 6) & 1; + bRequiredTextureStagesAvailable = CheckTextureStages(); + + memset(&halCaps, 0, sizeof(halCaps)); + halCaps.dwSize = sizeof(halCaps); + + memset(&refCaps, 0, sizeof(refCaps)); + refCaps.dwSize = sizeof(refCaps); + + ErrD3D(pRenderD3D->pDevice->GetCaps(&halCaps, &refCaps)); + v12 = halCaps.dwMinTextureWidth; + if ( (unsigned int)halCaps.dwMinTextureWidth > halCaps.dwMinTextureHeight ) + v12 = halCaps.dwMinTextureHeight; + uMinDeviceTextureDim = v12; + v13 = halCaps.dwMaxTextureWidth; + if ( (unsigned int)halCaps.dwMaxTextureWidth < halCaps.dwMaxTextureHeight ) + v13 = halCaps.dwMaxTextureHeight; + uMaxDeviceTextureDim = v13; + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, 1)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, 1)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, 2)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SPECULARENABLE, 0)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_COLORKEYENABLE, 0)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, 1)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, 2)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MINFILTER, 2)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, 3)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, 2)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, 0)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, 2)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, 2)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, 0)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLOROP, 4)); + //} + + ddpfPrimarySuface.dwSize = 32; + GetTargetPixelFormat(&ddpfPrimarySuface); + ParseTargetPixelFormat(); + + if ( !pRenderD3D ) + { + __debugbreak(); + //pBeforePresentFunction = 0;//nullsub_1; + //goto LABEL_47; + } + /*v14 = IsColorKeySupported(pDirectDraw4); + v15 = uAcquiredDirect3DDevice == 1; + bColorKeySupported = v14; + if ( !v15 ) + bColorKeySupported = 0;*/ + //if ( bColorKeySupported ) + if (false) + { + /*memset(&ddsd2, 0, 0x7Cu); + ddsd2.ddckCKSrcBlt.dwColorSpaceLowValue = uTargetGMask | uTargetBMask; + ddsd2.ddckCKSrcBlt.dwColorSpaceHighValue = ddsd2.ddckCKSrcBlt.dwColorSpaceLowValue; + v16 = pDirectDraw4; + ddsd2.dwSize = 124; + ddsd2.dwFlags = 65543; + ddsd2.ddsCaps.dwCaps = 2112; + ddsd2.dwWidth = 640; + ddsd2.dwHeight = 480; + ErrD3D(v16->CreateSurface(&ddsd2, &pColorKeySurface4, NULL)); + pBeforePresentFunction = Present_ColorKey;*/ + using_software_screen_buffer = 1; +//LABEL_47: + bWindowMode = 1; + //hWnd = hWnd; + return 0; + } + pTargetSurface = 0; + pTargetSurface_unaligned = 0; + + uint num_pixels = window->GetWidth() * window->GetHeight(); + pTargetSurface_unaligned = new unsigned int[num_pixels]; + + if (!pTargetSurface_unaligned) + return false; + + memset(&pDesc, 0, sizeof(pDesc)); + pDesc.dwSize = sizeof(pDesc); + if (!pRenderer->LockSurface_DDraw4(pRenderer->pBackBuffer4, &pDesc, DDLOCK_WAIT)) + { + delete [] pTargetSurface_unaligned; + return false; + } + + memset32(pTargetSurface_unaligned, -1, num_pixels); + + pRenderer->pBackBuffer4->Unlock(NULL); + /*v19 = pTargetSurface_unaligned; + v20 = (unsigned int)pDesc.lpSurface & 7; + v21 = (unsigned int)ptr_400E8 & 7; + if ( v21 == v20 ) + pTargetSurface = (unsigned __int16 *)v19; + else + { + if ( (signed int)v21 >= v20 ) + v22 = (int)((char *)v19 + 2 * (v21 - v20) + 16); + else + v22 = (int)((char *)v19 + 2 * (v20 - v21) + 16); + pTargetSurface = (unsigned __int16 *)v22; + }*/ + pTargetSurface = pTargetSurface_unaligned; + uTargetSurfacePitch = window->GetWidth(); + pBeforePresentFunction = Present_NoColorKey; + using_software_screen_buffer = 1; + bWindowMode = 1; + return 0; +} + + +//----- (0044F2B2) -------------------------------------------------------- +bool Render::IsGammaSupported() +{ +// bool result; // eax@3 +// HRESULT v1; // eax@4 + + //if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 ) + { + DDCAPS halCaps; // [sp+0h] [bp-180h]@4 + memset(&halCaps, 0, sizeof(DDCAPS)); + halCaps.dwSize = sizeof(DDCAPS); + + ErrD3D(pDirectDraw4->GetCaps(&halCaps, 0)); + return (halCaps.dwCaps2 >> 17) & 1; + } + /*else + return false;*/ +} + +//----- (004A0BEE) -------------------------------------------------------- +void Render::RasterLine2D(signed int uX, signed int uY, signed int uZ, signed int uW, unsigned __int16 uColor) +{ + signed int lower_bound; // eax@17 +// signed int left_bound; + unsigned int v21; // edi@46 + int v22; // esi@47 + int v23; // ebx@47 + signed int v24; // edx@50 + signed int v25; // esi@52 + unsigned __int16 *v26; // ecx@52 + int v27; // ebx@54 + int v28; // edi@55 + int v29; // edx@55 + int v30; // ebx@60 + int v31; // edx@61 + int v32; // edi@61 + signed int upper_bound; // [sp+18h] [bp-4h]@28 + unsigned int uXa; // [sp+24h] [bp+8h]@49 + int uYb; // [sp+28h] [bp+Ch]@47 + bool left_border_x = false; + bool right_border_x = false; + bool left_border_z = false; + bool right_border_z = false; + bool upper_border_y = false; + bool bottom_border_y = false; + bool upper_border_w = false; + bool bottom_border_w = false; + + if ( uX < this->raster_clip_x )// x выходит за рамки левой границы + left_border_x = true; + if ( uX > this->raster_clip_z )// x выходит за рамки правой границы + right_border_x = true; + + if ( uZ < this->raster_clip_x )// z выходит за рамки левой границы + left_border_z = true; + if ( uZ > this->raster_clip_z )// z выходит за рамки правой границы + right_border_z = true; + + if ( uY < this->raster_clip_y )// y выходит за рамки верхней границы + upper_border_y = true; + if ( uY > this->raster_clip_w )// y выходит за рамки нижней границы + bottom_border_y = true; + + if ( uW < this->raster_clip_y )// w выходит за рамки верхней границы + upper_border_w = true; + if ( uW > this->raster_clip_w )// w выходит за рамки нижней границы + bottom_border_w = true; + + if ( (left_border_x && left_border_z) || (right_border_x && right_border_z ) + || (upper_border_y && upper_border_w) || (bottom_border_y && bottom_border_w)) + return; + + if ( left_border_x || left_border_z || right_border_x || right_border_z + || upper_border_y || upper_border_w || bottom_border_y || bottom_border_w) + { + if ( left_border_x || left_border_z )//if ( (BYTE4(v36) ^ (unsigned __int8)v36) & 8 )//for left (левая граница) + { + if ( left_border_x )//left_border = true; х меньше левой границы + { + uY += (uW - uY) * ((this->raster_clip_x - uX) / (uZ - uX));//t = near_clip - v0.x / v1.x - v0.x (формула получения точки пересечения отрезка с плоскостью) + uX = this->raster_clip_x; + } + else if ( left_border_z )//z меньше левой границы + { + uZ = this->raster_clip_x; + uW += (uY - uW) * ((this->raster_clip_x - uZ) / (uX - uZ)); + } + } + + if ( right_border_x || right_border_z )//if ( (BYTE4(v36) ^ (unsigned __int8)v36) & 4 )//for right (правая граница) + { + if ( right_border_x ) //right_border = true; х больше правой границы + { + uY += (uY - uW) * ((this->raster_clip_z - uX) / (uZ - uX)); + uX = this->raster_clip_z; + } + else if ( right_border_z )//z больше правой границы + { + uW += (uW - uY) * ((this->raster_clip_z - uZ) / (uX - uZ)); + uZ = this->raster_clip_z; + } + } + + upper_bound = 0; + if ( uY < this->raster_clip_y ) + upper_bound = 2; + if ( uY > this->raster_clip_w ) + upper_bound |= 1; + + lower_bound = 0; + if ( uW < this->raster_clip_y ) + lower_bound = 2; + if ( uW > this->raster_clip_w ) + lower_bound |= 1; + + if ( !(lower_bound & upper_bound) )//for up and down(для верха и низа) + { + lower_bound ^= upper_bound; + if ( lower_bound & 2 ) + { + if ( upper_bound & 2 ) + { + uX += (uZ - uX) * ((this->raster_clip_y - uY) / (uW - uY)); + uY = this->raster_clip_y; + } + else + { + uZ += (uX - uZ) * ((this->raster_clip_y - uW) / (uY - uW)); + uW = this->raster_clip_y; + } + } + if ( lower_bound & 1 ) + { + if ( upper_bound & 1 ) + { + uX += (uZ - uX) * ((this->raster_clip_w - uY) / (uW - uY)); + uY = this->raster_clip_w; + } + else + { + uZ += (uX - uZ) * ((this->raster_clip_w - uW) / (uY - uW)); + uW = this->raster_clip_w; + } + } + } + } + v21 = pRenderer->uTargetSurfacePitch; + if ( pRenderer->uTargetSurfacePitch ) + { + //v12 = uX + uY * pRenderer->uTargetSurfacePitch; + v22 = uW - uY; + v23 = v22; + uYb = v22; + if ( v22 < 0 ) + { + v23 = -v22; + uYb = -v22; + v21 = -pRenderer->uTargetSurfacePitch; + } + uXa = uZ - uX; + if ((signed)(uZ - uX) >= 0) + v24 = 1; + else + { + uXa = -uXa; + v24 = -1; + } + v25 = 0; + + v26 = (unsigned __int16 *)this->pTargetSurface; + if ( v26 ) + { + if ( (signed int)uXa <= v23 )//рисуем вертикальную линию + { + v30 = v23 + 1; + if ( v30 > 0 ) + { + v31 = 2 * v24; + v32 = 2 * v21; + //v12 = (int)&v26[v12]; + int y = 0; + int x = 0; + for ( v30; v30; --v30 ) + { + v25 += uXa; + //*(short *)v12 = uColor; + //v12 += v32; + WritePixel16(uX + x, uY + y, uColor); + if ( v32 >= 0 ) + y += 1; + else + y -= 1; + if ( v25 > 0 ) + { + v25 -= uYb; + //v12 += v31; + if ( v31 >= 0 ) + x += 1; + else + x -= 1; + } + } + } + } + else//рисуем горизонтальную линию + { + v27 = uXa + 1; + if ( (signed int)(uXa + 1) > 0 ) + { + v28 = 2 * v21; + v29 = 2 * v24; + int y = 0; + int x = 0; + //v12 = (int)&v26[v12]; + for ( v27; v27; --v27 ) + { + v25 += uYb; + //*(short *)v12 = uColor; + //v12 += v29; + WritePixel16(uX + x, uY + y, uColor); + if ( v29 >= 0 ) + x += 1; + else + x -= 1; + if ( v25 > (signed int)uXa ) + { + v25 -= uXa; + //v12 += v28; + if ( v28 >= 0 ) + y += 1; + else + y -= 1; + } + } + } + } + } + } + return; +} + +//----- (004A0E80) -------------------------------------------------------- +void Render::ClearZBuffer(int a2, int a3) +{ + memset32(this->pActiveZBuffer, -65536, 0x4B000); +} + +//----- (004A0E97) -------------------------------------------------------- +void Render::SetRasterClipRect(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW) +{ + this->raster_clip_x = uX; + this->raster_clip_y = uY; + this->raster_clip_z = uZ; + this->raster_clip_w = uW; +} + +//----- (004A0EB6) -------------------------------------------------------- +void Render::ParseTargetPixelFormat() +{ + signed int v2; // ecx@1 + DWORD uRedMask; // edx@1 + unsigned int uGreenMask; // esi@5 + signed int v5; // ecx@5 + unsigned int uBlueMask; // edx@9 + signed int v7; // ecx@9 + //unsigned int v8; // ecx@13 + + v2 = 0; + uRedMask = this->ddpfPrimarySuface.dwRBitMask; + this->uTargetBBits = 0; + this->uTargetGBits = 0; + this->uTargetRBits = 0; + do + { + if ( (1 << v2) & uRedMask ) + ++this->uTargetRBits; + ++v2; + } + while ( v2 < 32 ); + uGreenMask = this->ddpfPrimarySuface.dwGBitMask; + v5 = 0; + do + { + if ( (1 << v5) & uGreenMask ) + ++this->uTargetGBits; + ++v5; + } + while ( v5 < 32 ); + uBlueMask = this->ddpfPrimarySuface.dwBBitMask; + v7 = 0; + do + { + if ( (1 << v7) & uBlueMask ) + ++this->uTargetBBits; + ++v7; + } + while ( v7 < 32 ); + this->uTargetGMask = uGreenMask; + this->uTargetRMask = this->ddpfPrimarySuface.dwRBitMask; + this->uTargetBMask = uBlueMask; +} + +//----- (004A0F40) -------------------------------------------------------- +bool Render::LockSurface_DDraw4(IDirectDrawSurface4 *pSurface, DDSURFACEDESC2 *pDesc, unsigned int uLockFlags) +{ + HRESULT result; // eax@1 + HRESULT v6; // eax@4 + char v9; // [sp+Bh] [bp-1h]@1 + + v9 = 1; + result = pSurface->Lock(NULL, pDesc, uLockFlags, NULL); + /* + Когда объект DirectDrawSurface теряет поверхностную память, методы возвратят DDERR_SURFACELOST + и не выполнят никакую другую функцию. Метод IDirectDrawSurface::Restore перераспределит поверхностную память + и повторно присоединит ее к объекту DirectDrawSurface. + */ + if ( result == DDERR_SURFACELOST ) + { + v6 = pSurface->Restore();//Восстанавливает потерянную поверхность. Это происходит, когда поверхностная память, + //связанная с объектом DirectDrawSurface была освобождена. + if ( v6 ) + { + if ( v6 != DDERR_IMPLICITLYCREATED )//DDERR_IMPLICITLYCREATED - Поверхность не может быть восстановлена, + //потому что она - неявно созданная поверхность. + { + v9 = 0; + result = (bool)memset(pDesc, 0, 4); + LOBYTE(result) = v9; + return 0; + } + pRenderer->pFrontBuffer4->Restore(); + pSurface->Restore(); + } + result = pSurface->Lock(NULL, pDesc, DDLOCK_WAIT, NULL); + if ( result == DDERR_INVALIDRECT || result == DDERR_SURFACEBUSY )//DDERR_SURFACEBUSY - Доступ к этой поверхности отказан, + //потому что поверхность блокирована другой нитью. DDERR_INVALIDRECT - Обеспечиваемый прямоугольник недопустим. + { + v9 = 0; + result = (bool)memset(pDesc, 0, 4); + LOBYTE(result) = v9; + return result; + } + ErrD3D(result); + if ( result ) + { + //v8 = 0; + //v7 = 2161; +//LABEL_19: + //CheckHRESULT((CheckHRESULT_stru0 *)&pSurface, result, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Screen16.cpp", v7, v8); + v9 = 0; + result = (bool)memset(pDesc, 0, 4); + LOBYTE(result) = v9; + return result; + } + if ( pRenderD3D ) + pRenderD3D->HandleLostResources(); + result = pRenderer->pDirectDraw4->RestoreAllSurfaces(); + } + else + { + if ( result ) + { + if ( result == DDERR_INVALIDRECT || result == DDERR_SURFACEBUSY ) + { + v9 = 0; + result = (bool)memset(pDesc, 0, 4); + LOBYTE(result) = v9; + return result; + } + ErrD3D(result); + //v8 = 0; + //v7 = 2199; + //goto LABEL_19; + } + } + return true; +} + + +//----- (004A10E4) -------------------------------------------------------- +void Render::CreateDirectDraw() +{ + //Render *v1; // edi@1 +// HRESULT v2; // eax@1 +// HRESULT v3; // eax@5 +// int v6; // [sp-Ch] [bp-20h]@3 +// unsigned int v9; // [sp+0h] [bp-14h]@0 + IDirectDraw *lpDD; // [sp+10h] [bp-4h]@1 + + //v1 = this; + ErrD3D(DirectDrawCreate(0, &lpDD, 0)); + + pDirectDraw4 = nullptr; + + ErrD3D(lpDD->QueryInterface(IID_IDirectDraw4, (void **)&pDirectDraw4)); + + lpDD->Release(); + lpDD = nullptr; +} + +//----- (004A1169) -------------------------------------------------------- +void Render::SetDirectDrawCooperationMode(HWND hWnd, bool bFullscreen) +{ + DWORD flags; // eax@1 + + //Установка взаимодействия для полноэкранного и оконного режимов + flags = bFullscreen ? DDSCL_NORMAL | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN : DDSCL_NORMAL; + + ErrD3D(pDirectDraw4->SetCooperativeLevel(hWnd, flags | DDSCL_MULTITHREADED)); +} + +//----- (004A11C6) -------------------------------------------------------- +void Render::SetDirectDrawDisplayMode(unsigned int uWidth, unsigned int uHeight, unsigned int uBPP) +{ + ErrD3D(pDirectDraw4->SetDisplayMode(uWidth, uHeight, uBPP, 0, 0)); +} + +//----- (004A121C) -------------------------------------------------------- +void Render::CreateFrontBuffer() +{ + //Render *v1; // esi@1 + IDirectDraw *pDD; // eax@3 + IDirectDrawSurface **pOutSurf; // esi@3 + struct _DDSURFACEDESC *v4; // edx@3 +//// HRESULT v5; // eax@5 + int v6; // [sp-8h] [bp-8Ch]@3 + DDSURFACEDESC2 a2; // [sp+4h] [bp-80h]@3 + + //v1 = this; + //if (pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || + //pVersion->pVersionInfo.dwMajorVersion != 4 ) + { + memset(&a2, 0, sizeof(a2)); + a2.dwSize = sizeof(a2); + + pDD = (IDirectDraw *)this->pDirectDraw4; + a2.dwFlags = 1; + a2.ddsCaps.dwCaps = 512;//DDSCAPS_PRIMARYSURFACE = 0x200 + + v6 = 2357; + pOutSurf = (IDirectDrawSurface **)&this->pFrontBuffer4; + v4 = (struct _DDSURFACEDESC *)&a2; + } + /*else + { + memset(&a2.lPitch, 0, 0x6Cu); // DDSURFACEDESC here + pDD = (IDirectDraw *)v1->pDirectDraw2; + a2.lPitch = 108; + a2.dwBackBufferCount = 1; + a2.dwTextureStage = 512; + v6 = 2346; + pOutSurf = (IDirectDrawSurface **)&v1->pFrontBuffer2; + v4 = (struct _DDSURFACEDESC *)&a2.lPitch; + }*/ + ErrD3D(pDD->CreateSurface(v4, pOutSurf, NULL)); +} + +//----- (004A12CD) -------------------------------------------------------- +void Render::CreateBackBuffer() +{ + //Render *v1; // esi@1 + IDirectDraw *v2; // eax@3 + IDirectDrawSurface **ppBackBuffer; // esi@3 + struct _DDSURFACEDESC *v4; // edx@3 +// HRESULT v5; // eax@5 + int v6; // [sp-8h] [bp-8Ch]@3 + unsigned int v7; // [sp-4h] [bp-88h]@3 + DDSURFACEDESC2 a2; // [sp+4h] [bp-80h]@3 + + //v1 = this; + //if (pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || + // pVersion->pVersionInfo.dwMajorVersion != 4 ) + { + memset(&a2, 0, sizeof(a2)); + a2.dwSize = sizeof(a2); + + v2 = (IDirectDraw *)this->pDirectDraw4; + a2.dwFlags = 7; + a2.ddsCaps.dwCaps = 2112;//0x840 = DDSCAPS_SYSTEMMEMORY = 0x800 | DDSCAPS_OFFSCREENPLAIN = 0x40 + a2.dwWidth = window->GetWidth(); + a2.dwHeight = window->GetHeight(); + + v7 = 0; + v6 = 2387; + ppBackBuffer = (IDirectDrawSurface **)&this->pBackBuffer4; + v4 = (struct _DDSURFACEDESC *)&a2; + } + /*else + { + memset(&a2.lPitch, 0, 0x6Cu); + v2 = (IDirectDraw *)v1->pDirectDraw2; + a2.lPitch = 108; + a2.dwBackBufferCount = 7; + v7 = 0; + a2.dwTextureStage = 2112; + a2.dwAlphaBitDepth = 640; + a2.dwMipMapCount = 480; + v6 = 2374; + ppBackBuffer = (IDirectDrawSurface **)&v1->pBackBuffer2; + v4 = (struct _DDSURFACEDESC *)&a2.lPitch; // //DDSURFACEDESC here fo ddraw2 + }*/ + ErrD3D(v2->CreateSurface(v4, ppBackBuffer, NULL)); +} + +//----- (004A139A) -------------------------------------------------------- +void Render::CreateDirectDrawPrimarySurface() +{ + IDirectDrawSurface *pFrontBuffer; // eax@3 + DDSCAPS2 *v6; // edx@3 + IDirectDraw4 *v7; // eax@4 + int v9; // ST14_4@5 + IDirectDrawSurface *v10; // ST10_4@5 + IDirectDrawSurface **ppBackBuffer; // [sp-4h] [bp-A4h]@3 + DDSURFACEDESC2 ddsd2; // [sp+Ch] [bp-94h]@3 + DDSCAPS2 v17; // [sp+88h] [bp-18h]@4 + + //v1 = this; + //if (pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || + //pVersion->pVersionInfo.dwMajorVersion != 4 ) + { + //v2 = 0; + //this->field_4004C = 1; + memset(&ddsd2, 0, sizeof(ddsd2)); + ddsd2.dwSize = sizeof(ddsd2); + + ddsd2.dwBackBufferCount = 1; + ddsd2.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; + ddsd2.ddsCaps.dwCaps = DDSCAPS_COMPLEX | DDSCAPS_FLIP | DDSCAPS_3DDEVICE | DDSCAPS_PRIMARYSURFACE; + ErrD3D(this->pDirectDraw4->CreateSurface(&ddsd2, &pFrontBuffer4, NULL)); + pFrontBuffer = (IDirectDrawSurface *)this->pFrontBuffer4; + ppBackBuffer = (IDirectDrawSurface **)&this->pBackBuffer4; + } + /*else + { + v2 = 0; + this->field_4004C = 1; + + DDSURFACEDESC ddsd; + memset(&ddsd, 0, sizeof(DDSURFACEDESC)); + + ddsd.lpSurface = (LPVOID)1; + ddsd.lPitch = 108; + ddsd.dwBackBufferCount = 33; + ddsd.ddsCaps.dwCaps = 8728; + ErrD3D(pDirectDraw2->CreateSurface(&ddsd, (IDirectDrawSurface **)&pFrontBuffer2, NULL)); + + pFrontBuffer = (IDirectDrawSurface *)v1->pFrontBuffer2; + ppBackBuffer = (IDirectDrawSurface **)&v1->pBackBuffer2; + }*/ + __debugbreak(); // warning C4700: uninitialized local variable 'v6' used + v9 = (int)v6; + v10 = pFrontBuffer; // BUG + + v17.dwCaps = 4; + ErrD3D(pFrontBuffer->GetAttachedSurface((DDSCAPS *)&v17, ppBackBuffer));// hr = this->pFrontBuffer->GetAttachedSurface(&ddsCaps2, ppBackBuffer); + //CheckHRESULT(&thisa, v11, (const char *)v10, v9, (unsigned int)ppBackBuffer); + //v1->field_40030 = v2; + //v1->field_18_locked_pitch = v2; +} + +//----- (004A14F4) -------------------------------------------------------- +void Render::CreateClipper(HWND a2) +{ + ErrD3D(pDirectDraw4->CreateClipper(0, &pDDrawClipper, NULL)); + ErrD3D(pDDrawClipper->SetHWnd(0, a2)); + ErrD3D(pFrontBuffer4->SetClipper(pDDrawClipper)); +} + +//----- (004A15D8) -------------------------------------------------------- +void Render::GetTargetPixelFormat(DDPIXELFORMAT *pOut) +{ + pFrontBuffer4->GetPixelFormat(pOut); +} + +//----- (004A1605) -------------------------------------------------------- +void Render::LockRenderSurface(void **pOutSurfacePtr, unsigned int *pOutPixelsPerRow) +{ + signed int v4; // eax@3 + + //if (pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || + //pVersion->pVersionInfo.dwMajorVersion != 4 ) + { + DDSURFACEDESC2 pDesc; // [sp+4h] [bp-7Ch]@3 + + memset(&pDesc, 0, sizeof(pDesc)); + pDesc.dwSize = sizeof(pDesc); + + LockSurface_DDraw4(this->pBackBuffer4, &pDesc, DDLOCK_WAIT); + *pOutSurfacePtr = pDesc.lpSurface; + v4 = pDesc.lPitch; + } + /*else + { + DDSURFACEDESC pDesc; // [sp+4h] [bp-7Ch]@3 + memset(&pDesc.lPitch, 0, 0x6Cu); + pDesc.lPitch = 108; + LockSurface_DDraw2(this->pBackBuffer2, &pDesc, 1); + *pOutSurfacePtr = (void *)pDesc.lpSurface; + v4 = pDesc.dwReserved; + }*/ + *pOutPixelsPerRow = v4 >> 1; +} + +//----- (004A16E1) -------------------------------------------------------- +void Render::UnlockBackBuffer() +{ + ErrD3D(pBackBuffer4->Unlock(NULL)); +} + +//----- (004A172E) -------------------------------------------------------- +void Render::LockFrontBuffer(void **pOutSurface, unsigned int *pOutPixelsPerRow) +{ + signed int v4; // eax@3 + + //if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 ) + { + DDSURFACEDESC2 pDesc; // [sp+4h] [bp-7Ch]@3 + + memset(&pDesc, 0, sizeof(pDesc)); + pDesc.dwSize = sizeof(pDesc); + + LockSurface_DDraw4(this->pFrontBuffer4, &pDesc, DDLOCK_WAIT); + *pOutSurface = pDesc.lpSurface; + v4 = pDesc.lPitch; + } + /*else + { + DDSURFACEDESC pDesc; // [sp+4h] [bp-7Ch]@3 + memset(&pDesc.lPitch, 0, 0x6Cu); + pDesc.lPitch = 108; + LockSurface_DDraw2(this->pFrontBuffer2, &pDesc, 1); + *pOutSurface = (void *)pDesc.lpSurface; + v4 = pDesc.dwReserved; + }*/ + *pOutPixelsPerRow = v4 >> 1; +} + +//----- (004A17C7) -------------------------------------------------------- +void Render::UnlockFrontBuffer() +{ + ErrD3D(pFrontBuffer4->Unlock(NULL)); +} + +//----- (004A1814) -------------------------------------------------------- +void Render::RestoreFrontBuffer() +{ + if (pFrontBuffer4->IsLost() == DDERR_SURFACELOST ) + pFrontBuffer4->Restore(); +} + +//----- (004A184C) -------------------------------------------------------- +void Render::RestoreBackBuffer() +{ + if ( pBackBuffer4->IsLost() == DDERR_SURFACELOST ) + pBackBuffer4->Restore(); +} + +//----- (004A18F5) -------------------------------------------------------- +void Render::BltToFront(RECT *pDstRect, IDirectDrawSurface *pSrcSurface, RECT *pSrcRect, unsigned int uBltFlags) +{ + ErrD3D(pFrontBuffer4->Blt(pDstRect, (IDirectDrawSurface4 *)pSrcSurface, pSrcRect, uBltFlags, nullptr)); +} + +//----- (004A194A) -------------------------------------------------------- +void Render::BltBackToFontFast(int a2, int a3, RECT *pSrcRect) +{ + IDirectDrawSurface *pFront; // eax@3 + IDirectDrawSurface *pBack; // [sp-Ch] [bp-Ch]@3 + + //if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 ) + { + pFront = (IDirectDrawSurface *)this->pFrontBuffer4; + pBack = (IDirectDrawSurface *)this->pBackBuffer4; + } + /*else + { + pFront = (IDirectDrawSurface *)this->pFrontBuffer2; + pBack = (IDirectDrawSurface *)this->pBackBuffer2; + }*/ + pFront->BltFast(NULL, NULL, pBack, pSrcRect, DDBLTFAST_WAIT); +} + +//----- (004A1B22) -------------------------------------------------------- +unsigned int Render::Billboard_ProbablyAddToListAndSortByZOrder(float z) +{ + unsigned int v7; // edx@6 + + if (uNumBillboardsToDraw >= 999 ) + return 0; + if (!uNumBillboardsToDraw) + { + uNumBillboardsToDraw = 1; + return 0; + } + + for (int left = 0, right = uNumBillboardsToDraw; left < right; ) // binsearch + { + v7 = left + (right - left) / 2; + if (z <= pRenderer->pBillboardRenderListD3D[v7].z_order) + right = v7; + else + left = v7 + 1; + } + + if (z > pRenderer->pBillboardRenderListD3D[v7].z_order ) + { + if ( v7 == pRenderer->uNumBillboardsToDraw - 1 ) + v7 = pRenderer->uNumBillboardsToDraw; + else + { + if ( (signed int)pRenderer->uNumBillboardsToDraw > (signed int)v7 ) + { + for ( uint i = 0; i < pRenderer->uNumBillboardsToDraw - v7; i++ ) + { + memcpy(&pRenderer->pBillboardRenderListD3D[pRenderer->uNumBillboardsToDraw - i], + &pRenderer->pBillboardRenderListD3D[pRenderer->uNumBillboardsToDraw - (i + 1)], + sizeof(pRenderer->pBillboardRenderListD3D[pRenderer->uNumBillboardsToDraw - i])); + } + } + ++v7; + } + uNumBillboardsToDraw++; + return v7; + } + if (z <= pRenderer->pBillboardRenderListD3D[v7].z_order ) + { + if ( (signed int)pRenderer->uNumBillboardsToDraw > (signed int)v7 ) + { + for ( uint i = 0; i < pRenderer->uNumBillboardsToDraw - v7; i++ ) + { + memcpy(&pRenderer->pBillboardRenderListD3D[pRenderer->uNumBillboardsToDraw - i], + &pRenderer->pBillboardRenderListD3D[pRenderer->uNumBillboardsToDraw -(i + 1)], + sizeof(pRenderer->pBillboardRenderListD3D[pRenderer->uNumBillboardsToDraw - i])); + } + } + uNumBillboardsToDraw++; + return v7; + } + return v7; +} + +//----- (004A1E9D) -------------------------------------------------------- +unsigned int Render::GetBillboardDrawListSize() +{ + return pRenderer->uNumBillboardsToDraw; +} + +//----- (004A1EA3) -------------------------------------------------------- +unsigned int Render::GetParentBillboardID(unsigned int uBillboardID) +{ + return pRenderer->pBillboardRenderListD3D[uBillboardID].sParentBillboardID; +} + +//----- (004A1EB6) -------------------------------------------------------- +void Render::BeginSceneD3D() +{ + if (!uNumD3DSceneBegins++) + { + //if (pRenderD3D) + { + pRenderD3D->ClearTarget(true, 0x00F08020, true, 1.0); + pRenderer->uNumBillboardsToDraw = 0; + pRenderD3D->pDevice->BeginScene(); + + if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor ) + uFogColor = GetLevelFogColor(); + else + uFogColor = 0; + + if ( uFogColor & 0xFF000000 ) + { + pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 1); + pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, uFogColor & 0xFFFFFF); + pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, 0); + bUsingSpecular = true; + } + else + { + pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 0); + bUsingSpecular = 0; + } + } + /*else + { + LockRenderSurface((void **)&pTargetSurface, &uTargetSurfacePitch); + if (pTargetSurface) + field_18_locked_pitch = uTargetSurfacePitch; + else + --uNumD3DSceneBegins; + }*/ + } +} + +//----- (004A1FE1) -------------------------------------------------------- +void Render::DrawBillboards_And_MaybeRenderSpecialEffects_And_EndScene() +{ + --uNumD3DSceneBegins; + if (uNumD3DSceneBegins) + return; + + if (pRenderD3D) + { + pGame->draw_debug_outlines(); + DoRenderBillboards_D3D(); + pGame->pStru6Instance->RenderSpecialEffects(); + pRenderD3D->pDevice->EndScene(); + } + else + pGame->pStru6Instance->RenderSpecialEffects(); +} + +//----- (004A2031) -------------------------------------------------------- +unsigned int Render::GetActorTintColor(float a2, int tint, int a4, int a5, RenderBillboard *a6) +{ +// __debugbreak(); // should not fire outside decal builder + return ::GetActorTintColor(tint, a4, a2, a5, a6); +} + +/*void Render::DrawTerrainPolygon_new(Polygon *a3, IDirect3DTexture2 *pTexture)//new function +{ + int v5; // ebx@1 + int v6; // edi@1 + int v8; // eax@7 + float v9; // eax@12 + float *v10; // esi@12 + float v11; // ecx@14 + double v12; // st7@14 + double v13; // st7@14 + double v14; // st7@14 + signed int v15; // eax@14 + int v16; // eax@15 + float v17; // ST48_4@15 + char v18; // zf@17 + int v19; // eax@18 + int v20; // eax@18 + int v21; // edx@20 + signed int v22; // ecx@20 + int v23; // eax@20 + const char *v24; // ST4C_4@20 + unsigned int v25; // ST50_4@20 + int v26; // ST54_4@20 + int v27; // eax@20 + _UNKNOWN *v28; // eax@21 + int v29; // ecx@23 + int v30; // eax@23 + int v31; // eax@23 + int v32; // eax@24 + int v33; // eax@25 + int v34; // eax@25 + int v35; // eax@25 + int v36; // eax@25 + signed int v37; // ecx@26 + int v38; // eax@26 + _UNKNOWN *v39; // eax@27 + int v40; // edx@28 + int v41; // eax@29 + int v42; // eax@29 + int v43; // eax@29 + int v44; // eax@29 + unsigned int v46; // eax@29 + int v47; // eax@30 + int v48; // eax@30 + int v49; // eax@30 + double v52; // st6@35 + const char *v55; // [sp+4Ch] [bp-1Ch]@20 + int v57; // [sp+5Ch] [bp-Ch]@3 + signed int v59; // [sp+60h] [bp-8h]@12 + int v61; // [sp+64h] [bp-4h]@4 + int i; + + v6 = (int)this; + v5 = 0; + if (!this->uNumD3DSceneBegins) + return; + + + + + this->pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP); + this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE); + if (this->bUsingSpecular) + { + this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE); + this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE); + this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO); + } + + pVertices[0].pos.x = array_50AC10[0].vWorldViewProjX; + pVertices[0].pos.y = array_50AC10[0].vWorldViewProjY; + pVertices[0].pos.z = 1.0 - 1.0 / (1000 * array_50AC10[0].vWorldViewPosition.x / (double)pODMRenderParams->shading_dist_mist); + pVertices[0].rhw = 1.0 / (array_50AC10[0].vWorldViewPosition.x + 0.0000001000000011686097); + pVertices[0].diffuse = GetActorTintColor(a3->field_58, 0, array_50AC10[0].vWorldViewPosition.x, 0, 0); + pVertices[0].specular = 0; + pVertices[0].texcoord.x = array_50AC10[0].u; + pVertices[0].texcoord.y = array_50AC10[0].v; + + pVertices[1].pos.x = array_50AC10[3].vWorldViewProjX; + pVertices[1].pos.y = array_50AC10[3].vWorldViewProjY; + pVertices[1].pos.z = 1.0 - 1.0 / (1000 * array_50AC10[3].vWorldViewPosition.x / (double)pODMRenderParams->shading_dist_mist); + pVertices[1].rhw = 1.0 / (array_50AC10[3].vWorldViewPosition.x + 0.0000001000000011686097); + pVertices[1].diffuse = GetActorTintColor(a3->field_58, 0, array_50AC10[3].vWorldViewPosition.x, 0, 0); + pVertices[1].specular = 0; + pVertices[1].texcoord.x = array_50AC10[3].u; + pVertices[1].texcoord.y = array_50AC10[3].v; + + pVertices[2].pos.x = array_50AC10[1].vWorldViewProjX; + pVertices[2].pos.y = array_50AC10[1].vWorldViewProjY; + pVertices[2].pos.z = 1.0 - 1.0 / (1000 * array_50AC10[1].vWorldViewPosition.x / (double)pODMRenderParams->shading_dist_mist); + pVertices[2].rhw = 1.0 / (array_50AC10[1].vWorldViewPosition.x + 0.0000001000000011686097); + pVertices[2].diffuse = GetActorTintColor(a3->field_58, 0, array_50AC10[1].vWorldViewPosition.x, 0, 0); + pVertices[2].specular = 0; + pVertices[2].texcoord.x = array_50AC10[1].u; + pVertices[2].texcoord.y = array_50AC10[1].v; + + memcpy(pVertices + 3, pVertices + 2, sizeof(RenderVertexD3D3)); + memcpy(pVertices + 4, pVertices + 1, sizeof(RenderVertexD3D3)); + + pVertices[5].pos.x = array_50AC10[2].vWorldViewProjX; + pVertices[5].pos.y = array_50AC10[2].vWorldViewProjY; + pVertices[5].pos.z = 1.0 - 1.0 / (1000 * array_50AC10[2].vWorldViewPosition.x / (double)pODMRenderParams->shading_dist_mist); + pVertices[5].rhw = 1.0 / (array_50AC10[2].vWorldViewPosition.x + 0.0000001000000011686097); + pVertices[5].diffuse = GetActorTintColor(a3->field_58, 0, array_50AC10[2].vWorldViewPosition.x, 0, 0); + pVertices[5].specular = 0; + pVertices[5].texcoord.x = array_50AC10[2].u; + pVertices[5].texcoord.y = array_50AC10[2].v; + + + this->pRenderD3D->pDevice->SetTexture(0, pTexture); + this->pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, pVertices, 6, D3DDP_DONOTLIGHT); + +}*/ + +//----- (004A26BC) -------------------------------------------------------- +void Render::DrawTerrainPolygon(unsigned int uNumVertices, struct Polygon *a4, IDirect3DTexture2 *a5, bool transparent, bool clampAtTextureBorders) +{ + unsigned int v8; // ebx@1 + int v11; // eax@5 + int v20; // eax@14 + unsigned int v45; // eax@28 + + v8 = 0; + if (!this->uNumD3DSceneBegins) + return; + if ( uNumVertices < 3) + return; + + //v61 = pVertices; + + /* v9 = pGame->pLightmapBuilder; + v65 = v9; + v10 = v9->std__vector_000004_size;*/ + if ( byte_4D864C && pGame->uFlags & GAME_FLAGS_1_01_lightmap_related) + { + v11 = ::GetActorTintColor(a4->dimming_level, 0, array_50AC10[0].vWorldViewPosition.x, 0, 0); + pGame->pLightmapBuilder->DrawLightmaps(/*v11, 0*/); + } + else + { + if (transparent || !pGame->pLightmapBuilder->std__vector_000004_size || + byte_4D864C && pGame->uFlags & 2 ) + { + if (clampAtTextureBorders) + this->pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP); + else + this->pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP); + + if (transparent || this->bUsingSpecular) + { + this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE); + if (transparent) + { + this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA); + this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA); + //this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ZERO); + //this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE); + } + else + { + this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE); + this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO); + } + } + + for (uint i = 0; i < uNumVertices; ++i) + { + + d3d_vertex_buffer[i].pos.x = array_50AC10[i].vWorldViewProjX; + d3d_vertex_buffer[i].pos.y = array_50AC10[i].vWorldViewProjY; + d3d_vertex_buffer[i].pos.z = 1.0 - 1.0 / ((array_50AC10[i].vWorldViewPosition.x * 1000) / (double)pODMRenderParams->shading_dist_mist); + d3d_vertex_buffer[i].rhw = 1.0 / (array_50AC10[i].vWorldViewPosition.x + 0.0000001); + d3d_vertex_buffer[i].diffuse = ::GetActorTintColor(a4->dimming_level, 0, array_50AC10[i].vWorldViewPosition.x, 0, 0); + if ( this->bUsingSpecular ) + { + d3d_vertex_buffer[i].specular = sub_47C3D7_get_fog_specular(0, 0, array_50AC10[i].vWorldViewPosition.x); + } + else + { + d3d_vertex_buffer[i].specular = 0; + } + d3d_vertex_buffer[i].texcoord.x = array_50AC10[i].u; + d3d_vertex_buffer[i].texcoord.y = array_50AC10[i].v; + } + + this->pRenderD3D->pDevice->SetTexture(0, a5); + this->pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, d3d_vertex_buffer, uNumVertices, 16); + if (transparent) + { + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); + } + } + else + { + for (uint i = 0; i < uNumVertices; ++i) + { + + d3d_vertex_buffer[i].pos.x = array_50AC10[i].vWorldViewProjX; + d3d_vertex_buffer[i].pos.y = array_50AC10[i].vWorldViewProjY; + d3d_vertex_buffer[i].pos.z = 1.0 - 1.0 / ((array_50AC10[i].vWorldViewPosition.x * 1000) / (double)pODMRenderParams->shading_dist_mist); + d3d_vertex_buffer[i].rhw = 1.0 / (array_50AC10[i].vWorldViewPosition.x + 0.0000001); + d3d_vertex_buffer[i].diffuse = GetActorTintColor(a4->dimming_level, 0, array_50AC10[i].vWorldViewPosition.x, 0, 0); + if ( this->bUsingSpecular ) + { + d3d_vertex_buffer[i].specular = sub_47C3D7_get_fog_specular(0, 0, array_50AC10[i].vWorldViewPosition.x); + } + else + { + d3d_vertex_buffer[i].specular = 0; + } + __debugbreak(); // warning C4700: uninitialized local variable 'v20' used + d3d_vertex_buffer[i].specular = v20; + d3d_vertex_buffer[i].texcoord.x = array_50AC10[i].u; + d3d_vertex_buffer[i].texcoord.y = array_50AC10[i].v; + } + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); + if (pRenderer->bUsingSpecular) + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE)); + + ErrD3D(pRenderD3D->pDevice->SetTexture(0, 0)); + ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + d3d_vertex_buffer, + uNumVertices, + 16)); + //v63 = (const char *)v7->pRenderD3D->pDevice; + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE)); + //(*(void (**)(void))(*(int *)v63 + 88))(); + pGame->pLightmapBuilder->DrawLightmaps(/*-1, 0*/); + for (uint i = 0; i < uNumVertices; ++i) + { + d3d_vertex_buffer[i].diffuse = -1; + } + ErrD3D(pRenderD3D->pDevice->SetTexture(0, a5)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); + if ( !pRenderer->bUsingSpecular ) + { + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); + } + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ZERO)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_SRCCOLOR)); + ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + d3d_vertex_buffer, + uNumVertices, + 16)); + if ( pRenderer->bUsingSpecular ) + { + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); + ErrD3D(pRenderD3D->pDevice->SetTexture(0, 0)); + for (uint i = 0; i < uNumVertices; ++i) + { + d3d_vertex_buffer[i].diffuse = pRenderer->uFogColor | d3d_vertex_buffer[i].specular & 0xFF000000; + d3d_vertex_buffer[i].specular = 0; + } + + ErrD3D(pRenderD3D->pDevice->SetTexture(0, 0));//problem + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_INVSRCALPHA)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_SRCALPHA)); + ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + d3d_vertex_buffer, + uNumVertices, + 16)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE)); + //v44 = pRenderer->pRenderD3D->pDevice; + v45 = GetLevelFogColor(); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, v45 & 0xFFFFFF)); + v8 = 0; + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, 0)); + } + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, v8)); + } + } + + //if (pIndoorCamera->flags & INDOOR_CAMERA_DRAW_TERRAIN_OUTLINES || pBLVRenderParams->uFlags & INDOOR_CAMERA_DRAW_TERRAIN_OUTLINES) + if (pGame->pIndoorCameraD3D->debug_flags & ODM_RENDER_DRAW_TERRAIN_OUTLINES) + pGame->pIndoorCameraD3D->debug_outline_d3d(d3d_vertex_buffer, uNumVertices, 0x00FFFFFF, 0.0); + } +// 4A26BC: could not find valid save-restore pair for esi +// 4D864C: using guessed type char byte_4D864C; + +//----- (004A2DA3) -------------------------------------------------------- +void Render::DrawOutdoorSkyPolygon(unsigned int uNumVertices, struct Polygon *pSkyPolygon, IDirect3DTexture2 *pTexture) +{ + int v7; // eax@7 + + if ( !this->uNumD3DSceneBegins ) + return; + if ( uNumVertices >= 3 ) + { + this->pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP); + if ( this->bUsingSpecular ) + { + this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE); + this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE); + this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO); + } + for ( uint i = 0; i < uNumVertices; ++i ) + { + pVertices[i].pos.x = array_50AC10[i].vWorldViewProjX; + pVertices[i].pos.y = array_50AC10[i].vWorldViewProjY; + pVertices[i].pos.z = 0.99989998; + pVertices[i].rhw = array_50AC10[i]._rhw; + + pVertices[i].diffuse = ::GetActorTintColor(31, 0, array_50AC10[i].vWorldViewPosition.x, 1, 0); + v7 = 0; + if (this->bUsingSpecular) + v7 = sub_47C3D7_get_fog_specular(0, 1, array_50AC10[i].vWorldViewPosition.x); + pVertices[i].specular = v7; + pVertices[i].texcoord.x = array_50AC10[i].u; + pVertices[i].texcoord.y = array_50AC10[i].v; + } + pRenderD3D->pDevice->SetTexture(0, pTexture); + pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + pVertices, uNumVertices, D3DDP_DONOTUPDATEEXTENTS | D3DDP_DONOTLIGHT); + } +} + +//----- (004A2ED5) -------------------------------------------------------- +void Render::DrawIndoorSkyPolygon(signed int uNumVertices, struct Polygon *pSkyPolygon, IDirect3DTexture2 *pTexture) +{ + int v5; // eax@3 + + if ( this->uNumD3DSceneBegins ) + { + if ( uNumVertices >= 3 ) + { + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); + v5 = 31 - (pSkyPolygon->dimming_level & 0x1F); + if ( v5 < pOutdoor->max_terrain_dimming_level ) + v5 = pOutdoor->max_terrain_dimming_level; + for (uint i = 0; i < (unsigned int)uNumVertices; ++i) + { + d3d_vertex_buffer[i].pos.x = array_507D30[i].vWorldViewProjX; + d3d_vertex_buffer[i].pos.y = array_507D30[i].vWorldViewProjY; + d3d_vertex_buffer[i].pos.z = 1.0 - 1.0 / (array_507D30[i].vWorldViewPosition.x * 0.061758894); + d3d_vertex_buffer[i].rhw = array_507D30[i]._rhw; + d3d_vertex_buffer[i].diffuse = 8 * v5 | ((8 * v5 | (v5 << 11)) << 8); + d3d_vertex_buffer[i].specular = 0; + d3d_vertex_buffer[i].texcoord.x = array_507D30[i].u; + d3d_vertex_buffer[i].texcoord.y = array_507D30[i].v; + } + ErrD3D(pRenderD3D->pDevice->SetTexture(0, pTexture)); + ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + d3d_vertex_buffer, uNumVertices, 28)); + } + } +} + +//----- (00479A53) -------------------------------------------------------- +void Render::DrawIndoorSky(unsigned int uNumVertices, unsigned int uFaceID) +{ + BLVFace *pFace; // esi@1 + double v5; // st7@3 + signed __int64 v6; // qax@3 + int v12; // edx@7 + int v13; // eax@7 + int v17; // edi@9 + double v18; // st7@9 + signed int v19; // ebx@9 + void *v20; // ecx@9 + int v21; // ebx@11 + int v22; // eax@14 + signed __int64 v23; // qtt@16 + double v28; // st7@20 + double v33; // st6@23 + const void *v35; // ecx@31 + int v36; // eax@31 + const void *v37; // edi@31 + signed __int64 v38; // qax@31 + int v39; // ecx@31 + int v40; // ebx@33 + int v41; // eax@36 + signed __int64 v42; // qtt@39 + int v43; // eax@39 + double v48; // st7@41 + double v51; // st7@46 + struct Polygon pSkyPolygon; // [sp+14h] [bp-160h]@6 + unsigned int v63; // [sp+120h] [bp-54h]@7 + unsigned int v65; // [sp+128h] [bp-4Ch]@1 + unsigned int v66; // [sp+12Ch] [bp-48h]@7 + __int64 v69; // [sp+13Ch] [bp-38h]@3 + int v70; // [sp+144h] [bp-30h]@3 + int X; // [sp+148h] [bp-2Ch]@9 + int v72; // [sp+14Ch] [bp-28h]@7 + float v73; // [sp+150h] [bp-24h]@16 + unsigned int v74; // [sp+154h] [bp-20h]@3 + unsigned int v74_; // [sp+154h] [bp-20h]@3 + RenderVertexSoft *v75; // [sp+158h] [bp-1Ch]@3 + float v76; // [sp+15Ch] [bp-18h]@9 + int v77; // [sp+160h] [bp-14h]@9 + int v78; // [sp+164h] [bp-10h]@7 + void *v79; // [sp+168h] [bp-Ch]@9 + float v80; // [sp+16Ch] [bp-8h]@3 + const void *v81; // [sp+170h] [bp-4h]@7 + + pFace = &pIndoor->pFaces[uFaceID]; + //for floor and wall(for example Selesta)------------------- + if (pFace->uPolygonType == POLYGON_InBetweenFloorAndWall || pFace->uPolygonType == POLYGON_Floor) + { + int v69 = (GetTickCount() / 32) - pGame->pIndoorCameraD3D->vPartyPos.x; + int v55 = (GetTickCount() / 32) + pGame->pIndoorCameraD3D->vPartyPos.y; + for (uint i = 0; i < uNumVertices; ++i) + { + array_507D30[i].u = (v69 + array_507D30[i].u) * 0.25f; + array_507D30[i].v = (v55 + array_507D30[i].v) * 0.25f; + } + pRenderer->DrawIndoorPolygon(uNumVertices, pFace, pBitmaps_LOD->pHardwareTextures[pFace->uBitmapID], pFace->GetTexture(), PID(OBJECT_BModel, uFaceID), -1, 0); + return; + } +//--------------------------------------- + v70 = (signed __int64)((double)(pBLVRenderParams->fov_rad_fixpoint * pGame->pIndoorCameraD3D->vPartyPos.z)//179 + / (((double)pBLVRenderParams->fov_rad_fixpoint + 16192.0) + * 65536.0) + + (double)pBLVRenderParams->uViewportCenterY); + v5 = (double)pGame->pIndoorCameraD3D->sRotationX * 0.0030664064;//0 + v6 = (signed __int64)((double)pBLVRenderParams->uViewportCenterY//183 + - (double)pBLVRenderParams->fov_rad_fixpoint + / ((cos(v5) * 16192.0 + 0.0000001) + * 65535.0) + * (sin(v5) * -16192.0 - (double)pGame->pIndoorCameraD3D->vPartyPos.z)); + + stru_8019C8._48653D_frustum_blv(65536, 0, 0, 0, 65536, 0); + pSkyPolygon.Create_48607B(&stru_8019C8); + pSkyPolygon.uTileBitmapID = pFace->uBitmapID; + + pSkyPolygon.pTexture = pBitmaps_LOD->GetTexture(pSkyPolygon.uTileBitmapID); + if ( !pSkyPolygon.pTexture ) + return; + + pSkyPolygon.dimming_level = 0; + pSkyPolygon.uNumVertices = uNumVertices; + + pSkyPolygon.v_18.x = -stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationX + 16); + pSkyPolygon.v_18.y = 0; + pSkyPolygon.v_18.z = -stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationX + 16); + + memcpy(&array_507D30[uNumVertices], array_507D30, sizeof(array_507D30[uNumVertices])); + pSkyPolygon.field_24 = 0x2000000; + + extern float _calc_fov(int viewport_width, int angle_degree); + //v64 = (double)(signed int)(pBLVRenderParams->uViewportZ - pBLVRenderParams->uViewportX) * 0.5; + //v72 = 65536 / (signed int)(signed __int64)(v64 / tan(0.6457717418670654) + 0.5); + v72 = 65536.0f / _calc_fov(pBLVRenderParams->uViewportZ - pBLVRenderParams->uViewportX, 74); + v12 = pSkyPolygon.pTexture->uWidthMinus1; + v13 = pSkyPolygon.pTexture->uHeightMinus1; + //v67 = 1.0 / (double)pSkyPolygon.pTexture->uTextureWidth; + v63 = 224 * pMiscTimer->uTotalGameTimeElapsed & v13; + v66 = 224 * pMiscTimer->uTotalGameTimeElapsed & v12; + v78 = 0; + //v81 = 0; + float v68 = 1.0 / (double)pSkyPolygon.pTexture->uTextureHeight; + if ( (signed int)pSkyPolygon.uNumVertices <= 0 ) + return; + + int _507D30_idx = 0; + for ( _507D30_idx; _507D30_idx < pSkyPolygon.uNumVertices; _507D30_idx++ ) + { + //v15 = (void *)(v72 * (v70 - (int)array_507D30[_507D30_idx].vWorldViewProjY)); + v77 = fixpoint_mul(pSkyPolygon.ptr_38->viewing_angle_from_west_east, v72 * (v70 - array_507D30[_507D30_idx].vWorldViewProjY)); + v74 = v77 + pSkyPolygon.ptr_38->angle_from_north; + + v77 = fixpoint_mul(pSkyPolygon.ptr_38->viewing_angle_from_north_south, v72 * (v70 - array_507D30[_507D30_idx].vWorldViewProjY)); + v74_ = v77 + pSkyPolygon.ptr_38->angle_from_east; + + v79 = (void *)(fixpoint_mul(pSkyPolygon.v_18.z, v72 * (v70 - (int)array_507D30[_507D30_idx].vWorldViewProjY))); + v17 = v72 * (pBLVRenderParams->uViewportCenterX - (int)array_507D30[_507D30_idx].vWorldViewProjX); + v18 = array_507D30[_507D30_idx].vWorldViewProjY - 1.0; + v19 = -pSkyPolygon.field_24; + v77 = -pSkyPolygon.field_24; + X = (int)((char *)v79 + pSkyPolygon.v_18.x); + LODWORD(v76) = (signed __int64)v18; + v20 = (void *)(v72 * (v70 - LODWORD(v76))); + while ( 1 ) + { + v79 = v20; + if ( !X ) + goto LABEL_14; + v21 = abs(v19 >> 14); + if ( v21 <= abs(X) )//0x800 <= 0x28652 + break; + if ( SLODWORD(v76) <= (signed int)pViewport->uViewportTL_Y ) + break; + v19 = v77; + v20 = v79; +LABEL_14: + v79 = (void *)fixpoint_mul(pSkyPolygon.v_18.z, (int)v20); + v22 = fixpoint_mul(pSkyPolygon.v_18.z, (int)v20); + --LODWORD(v76); + v20 = (char *)v20 + v72; + X = v22 + pSkyPolygon.v_18.x; + v78 = 1; + } + if ( !v78 ) + { + LODWORD(v23) = v77 << 16; + HIDWORD(v23) = v77 >> 16;//v23 = 0xfffffe0000000000 + v79 = (void *)(v23 / X);//X = FFFF9014(-28652) + v77 = v17; + signed __int64 s = v74 + fixpoint_mul(pSkyPolygon.ptr_38->angle_from_west, v17);// s = 0xFFFFFFFF FFFF3EE6 + LODWORD(v80) = v66 + ((signed int)fixpoint_mul(SLODWORD(s), v23 / X) >> 4); + array_507D30[_507D30_idx].u = ((double)SLODWORD(v80) * 0.000015259022) * (1.0 / (double)pSkyPolygon.pTexture->uTextureWidth); + + signed __int64 s2 = v74_ + fixpoint_mul(pSkyPolygon.ptr_38->angle_from_south, v17); + LODWORD(v80) = v63 + ((signed int)fixpoint_mul(SLODWORD(s2), v23 / X) >> 4); + array_507D30[_507D30_idx].v = ((double)SLODWORD(v80) * 0.000015259022) * v68; + + v77 = fixpoint_mul(SLODWORD(s), v23 / X); + LODWORD(v73) = fixpoint_mul(SLODWORD(s2), v23 / X); + array_507D30[_507D30_idx]._rhw = 65536.0 / (double)(signed int)v79; + + //if ( (int)v81 >= pSkyPolygon.uNumVertices ) + //{ + // pRenderer->DrawIndoorSkyPolygon(pSkyPolygon.uNumVertices, &pSkyPolygon, + // pBitmaps_LOD->pHardwareTextures[(signed __int16)pSkyPolygon.uTileBitmapID]); + // return; + //} + continue; + } + break; + } + if ( _507D30_idx >= pSkyPolygon.uNumVertices ) + { + pRenderer->DrawIndoorSkyPolygon(pSkyPolygon.uNumVertices, &pSkyPolygon, + pBitmaps_LOD->pHardwareTextures[(signed __int16)pSkyPolygon.uTileBitmapID]); + return; + } + LODWORD(v73) = 0; + v80 = v76; + if ( (signed int)pSkyPolygon.uNumVertices > 0 ) + { + v28 = (double)SLODWORD(v76); + LODWORD(v76) = (int)(char *)array_50AC10 + 28; + uint i = 0; + for ( v78 = pSkyPolygon.uNumVertices; v78; --v78 ) + { + ++LODWORD(v73); + memcpy(&array_50AC10[i], &array_507D30[i], 0x30u); + LODWORD(v76) += 48; + if ( v28 < array_507D30[i].vWorldViewProjY | v28 == array_507D30[i].vWorldViewProjY + || v28 >= array_507D30[i + 1].vWorldViewProjY ) + { + if ( v28 >= array_507D30[i].vWorldViewProjY || v28 <= array_507D30[i + 1].vWorldViewProjY ) + { + i++; + continue; + } + v33 = (array_507D30[i + 1].vWorldViewProjX - array_507D30[i].vWorldViewProjX) * v28 / (array_507D30[i + 1].vWorldViewProjY - array_507D30[i].vWorldViewProjY) + + array_507D30[i + 1].vWorldViewProjX; + } + else + { + v33 = (array_507D30[i].vWorldViewProjX - array_507D30[i + 1].vWorldViewProjX) * v28 / (array_507D30[i].vWorldViewProjY - array_507D30[i + 1].vWorldViewProjY) + + array_507D30[i].vWorldViewProjX; + } + array_50AC10[i + 1].vWorldViewProjX = v33; + ++LODWORD(v73); + *(unsigned int *)LODWORD(v76) = v28; + LODWORD(v76) += 48; + i++; + } + } + if ( SLODWORD(v73) <= 0 ) + goto LABEL_40; + //v34 = (char *)&array_50AC10[0].vWorldViewProjY; + uint j = 0; + v65 = v77 >> 14; + //HIDWORD(v69) = LODWORD(v73); + for ( int t = (int)LODWORD(v73); t > 1; t-- ) + { + v35 = (const void *)(v72 * (v70 - (unsigned __int64)(signed __int64)array_50AC10[j].vWorldViewProjY)); + + //v78 = pSkyPolygon.ptr_38->viewing_angle_from_west_east; + //v81 = (const void *)fixpoint_mul(pSkyPolygon.ptr_38->viewing_angle_from_west_east, v35); + v36 = (int)(fixpoint_mul(pSkyPolygon.ptr_38->viewing_angle_from_west_east, (int)v35) + pSkyPolygon.ptr_38->angle_from_north); + + v81 = v35; + v74 = v36; + //v78 = pSkyPolygon.ptr_38->viewing_angle_from_north_south; + v81 = (const void *)fixpoint_mul(pSkyPolygon.ptr_38->viewing_angle_from_north_south, (int)v35); + v78 = (int)v35; + v75 = (RenderVertexSoft *)((char *)v81 + pSkyPolygon.ptr_38->angle_from_east); + //v81 = (const void *)pSkyPolygon.v_18.z; + v78 = fixpoint_mul(pSkyPolygon.v_18.z, (int)v35); + v37 = (const void *)(v72 * (pBLVRenderParams->uViewportCenterX - (unsigned __int64)(signed __int64)array_50AC10[j].vWorldViewProjX)); + v38 = (signed __int64)(array_50AC10[j].vWorldViewProjY - 1.0); + v81 = 0; + LODWORD(v76) = v38; + v39 = v72 * (v70 - v38); + while ( 1 ) + { + v78 = v39; + if ( !X ) + goto LABEL_36; + v40 = abs(X); + if ( abs((signed __int64)v65) <= v40 ) + break; + if ( SLODWORD(v76) <= (signed int)pViewport->uViewportTL_Y ) + break; + v39 = v78; +LABEL_36: + v78 = pSkyPolygon.v_18.z; + v41 = fixpoint_mul(pSkyPolygon.v_18.z, v39); + --LODWORD(v76); + v39 += v72; + X = v41 + pSkyPolygon.v_18.x; + v81 = (const void *)1; + } + if ( v81 ) + { + v79 = (void *)pSkyPolygon.v_18.z; + v78 = 2 * LODWORD(v76); + v81 = (const void *)fixpoint_mul(pSkyPolygon.v_18.z, (((double)v70 - ((double)(2 * LODWORD(v76)) - array_50AC10[j].vWorldViewProjY)) + * (double)v72)); + X = (int)((char *)v81 + pSkyPolygon.v_18.x); + } + LODWORD(v42) = v77 << 16; + HIDWORD(v42) = v77 >> 16; + v79 = (void *)(v42 / X); + v81 = v37; + + //v78 = pSkyPolygon.ptr_38->angle_from_west; + v81 = (const void *)fixpoint_mul(pSkyPolygon.ptr_38->angle_from_west, (int)v37); + v43 = v74 + fixpoint_mul(pSkyPolygon.ptr_38->angle_from_west, (int)v37); + v74 = (unsigned int)v37; + LODWORD(v76) = v43; + + //v78 = pSkyPolygon.ptr_38->angle_from_south; + v75 = (RenderVertexSoft *)((char *)v75 + fixpoint_mul(pSkyPolygon.ptr_38->angle_from_south, (int)v37)); + //v74 = fixpoint_mul(v43, v42 / X); + v81 = (const void *)fixpoint_mul((int)v75, v42 / X); + + //v34 += 48; + //v78 = v66 + ((signed int)fixpoint_mul(v43, v42 / X) >> 4); + //v44 = HIDWORD(v69)-- == 1; + //v45 = (double)(v66 + ((signed int)fixpoint_mul(v43, v42 / X) >> 4)) * 0.000015259022; + //v78 = v63 + ((signed int)fixpoint_mul((int)v75, v42 / X) >> 4); + array_50AC10[j].u = ((double)(v66 + ((signed int)fixpoint_mul(v43, v42 / X) >> 4)) * 0.000015259022) * (1.0 / (double)pSkyPolygon.pTexture->uTextureWidth); + array_50AC10[j].v = ((double)(v66 + ((signed int)fixpoint_mul(v43, v42 / X) >> 4)) * 0.000015259022) * v68; + //v46 = (double)(signed int)v79; + array_50AC10[j].vWorldViewPosition.x = 0.000015258789 * (double)(signed int)v79; + array_50AC10[j]._rhw = 65536.0 / (double)(signed int)v79; + ++j; + } + //while ( !v44 ); +LABEL_40: + uint i = 0; + if ( SLODWORD(v73) > 0 ) + { + v48 = (double)SLODWORD(v80); + for ( HIDWORD(v69) = LODWORD(v73); HIDWORD(v69); --HIDWORD(v69) ) + { + if ( v48 >= array_50AC10[i].vWorldViewProjY ) + { + ++i; + memcpy(&array_507D30[i], &array_50AC10[i], 0x30u); + } + } + } + pSkyPolygon.uNumVertices = i; + pRenderer->DrawIndoorSkyPolygon(pSkyPolygon.uNumVertices, &pSkyPolygon, pBitmaps_LOD->pHardwareTextures[(signed __int16)pSkyPolygon.uTileBitmapID]); + int pNumVertices = 0; + if ( SLODWORD(v73) > 0 ) + { + v51 = (double)SLODWORD(v80); + for ( v80 = v73; v80 != 0.0; --LODWORD(v80) ) + { + if ( v51 <= array_50AC10[pNumVertices].vWorldViewProjY ) + { + ++pNumVertices; + memcpy(&array_507D30[pNumVertices], &array_50AC10[pNumVertices], 0x30u); + } + } + } + pRenderer->DrawIndoorSkyPolygon(pNumVertices, &pSkyPolygon, pBitmaps_LOD->pHardwareTextures[(signed __int16)pSkyPolygon.uTileBitmapID]); +} + + +//----- (004A2FC0) -------------------------------------------------------- +void Render::DrawIndoorPolygon(unsigned int uNumVertices, BLVFace *pFace, IDirect3DTexture2 *pHwTex, Texture *pTex, int uPackedID, unsigned int uColor, int a8) +{ + if (!uNumD3DSceneBegins || uNumVertices < 3) + return; + + //auto a3 = pFace; + //auto a6 = uPackedID; + //v59 = pGame->pLightmapBuilder; + //v9 = v59->std__vector_000004_size; + + int sCorrectedColor = uColor; + if (pGame->pLightmapBuilder->std__vector_000004_size) + sCorrectedColor = -1; + pGame->AlterGamma_BLV(pFace, &sCorrectedColor); + + + if (pFace->uAttributes & FACE_OUTLINED) + { +// int color; + if (GetTickCount() % 300 >= 150) + uColor = sCorrectedColor = 0xFF20FF20; + else uColor = sCorrectedColor = 0xFF109010; + } + + if (byte_4D864C && pGame->uFlags & GAME_FLAGS_1_01_lightmap_related) + { + __debugbreak(); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); + for (uint i = 0; i < uNumVertices; ++i) + { + d3d_vertex_buffer[i].pos.x = array_507D30[i].vWorldViewProjX; + d3d_vertex_buffer[i].pos.y = array_507D30[i].vWorldViewProjY; + d3d_vertex_buffer[i].pos.z = 1.0 - 1.0 / (array_507D30[i].vWorldViewPosition.x * 0.061758894); + d3d_vertex_buffer[i].rhw = 1.0 / array_507D30[i].vWorldViewPosition.x; + d3d_vertex_buffer[i].diffuse = sCorrectedColor; + d3d_vertex_buffer[i].specular = 0; + d3d_vertex_buffer[i].texcoord.x = array_507D30[i].u / (double)pTex->uTextureWidth; + d3d_vertex_buffer[i].texcoord.y = array_507D30[i].v / (double)pTex->uTextureHeight; + } + + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); + ErrD3D(pRenderD3D->pDevice->SetTexture(0, nullptr)); + ErrD3D(pRenderD3D->pDevice->DrawPrimitive( + D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + d3d_vertex_buffer, + uNumVertices, + 28)); + pGame->pLightmapBuilder->DrawLightmaps(/*-1, 0*/); + } + else + { + if (!pGame->pLightmapBuilder->std__vector_000004_size || + byte_4D864C && pGame->uFlags & 2) + { + for (uint i = 0; i < uNumVertices; ++i) + { + d3d_vertex_buffer[i].pos.x = array_507D30[i].vWorldViewProjX; + d3d_vertex_buffer[i].pos.y = array_507D30[i].vWorldViewProjY; + d3d_vertex_buffer[i].pos.z = 1.0 - 1.0 / (array_507D30[i].vWorldViewPosition.x * 0.061758894); + d3d_vertex_buffer[i].rhw = 1.0 / array_507D30[i].vWorldViewPosition.x; + d3d_vertex_buffer[i].diffuse = sCorrectedColor; + d3d_vertex_buffer[i].specular = 0; + d3d_vertex_buffer[i].texcoord.x = array_507D30[i].u / (double)pTex->uTextureWidth; + d3d_vertex_buffer[i].texcoord.y = array_507D30[i].v / (double)pTex->uTextureHeight; + } + + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); + ErrD3D(pRenderD3D->pDevice->SetTexture(0, pHwTex)); + ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + d3d_vertex_buffer, + uNumVertices, + 28)); + } + else + { + for (uint i = 0; i < uNumVertices; ++i) + { + d3d_vertex_buffer[i].pos.x = array_507D30[i].vWorldViewProjX; + d3d_vertex_buffer[i].pos.y = array_507D30[i].vWorldViewProjY; + d3d_vertex_buffer[i].pos.z = 1.0 - 1.0 / (array_507D30[i].vWorldViewPosition.x * 0.061758894); + d3d_vertex_buffer[i].rhw = 1.0 / array_507D30[i].vWorldViewPosition.x; + d3d_vertex_buffer[i].diffuse = uColor; + d3d_vertex_buffer[i].specular = 0; + d3d_vertex_buffer[i].texcoord.x = array_507D30[i].u / (double)pTex->uTextureWidth; + d3d_vertex_buffer[i].texcoord.y = array_507D30[i].v / (double)pTex->uTextureHeight; + } + //__debugbreak(); + //if ( (signed int)uNumVertices > 0 ) + //{ + //v23 = pTex; + //v24 = (char *)&array_507D30[0].vWorldViewPosition; + //v25 = (char *)&d3d_vertex_buffer[0].pos.y; + //pTex = (Texture *)uNumVertices; + //uint v18; + //do + //{ + //v26 = *(float *)v24 * 0.061758894; + //v27 = *((int *)v24 + 3); + //*((int *)v25 + 4) = 0; + //*((int *)v25 - 1) = v27; + //*(int *)v25 = *((int *)v24 + 4); + //*((int *)v25 + 3) = uColor; + //v25 += 32; + //*((float *)v25 - 7) = 1.0 - 1.0 / v26; + //v28 = 1.0 / *(float *)v24; + //v24 += 48; + //v18 = pTex == (Texture *)1; + //pTex = (Texture *)((char *)pTex - 1); + //*((float *)v25 - 6) = v28; + //a3 = (BLVFace *)v23->uTextureWidth; + //*((float *)v25 - 3) = *((float *)v24 - 6) / (double)(signed int)v23->uTextureWidth; + //a3 = (BLVFace *)v23->uTextureHeight; + //*((float *)v25 - 2) = *((float *)v24 - 5) / (double)(signed int)v23->uTextureHeight; + //} + //while ( !v18 ); + //} + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); + ErrD3D(pRenderD3D->pDevice->SetTexture(0, nullptr)); + ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + d3d_vertex_buffer, + uNumVertices, + 28)); + + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE)); + pGame->pLightmapBuilder->DrawLightmaps(/*-1, 0*/); + + for (uint i = 0; i < uNumVertices; ++i) + d3d_vertex_buffer[i].diffuse = sCorrectedColor; + /*v33 = uNumVertices; + if ( (signed int)uNumVertices > 0 ) + { + v34 = (char *)&d3d_vertex_buffer[0].diffuse; + do + { + *(int *)v34 = uCorrectedColor; + v34 += 32; + --v33; + } + while ( v33 ); + }*/ + ErrD3D(pRenderD3D->pDevice->SetTexture(0, pHwTex)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ZERO)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_SRCCOLOR)); + ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + d3d_vertex_buffer, + uNumVertices, + 28)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE)); + } + } +} +// 4D864C: using guessed type char byte_4D864C; + +//----- (004A43B1) -------------------------------------------------------- +void Render::DrawBillboard_Indoor(RenderBillboardTransform_local0 *pSoftBillboard, Sprite *pSprite, int dimming_level) +{ + unsigned int v7; // eax@2 + signed int v11; // eax@9 + signed int v12; // eax@9 + double v15; // st5@12 + double v16; // st4@12 + double v17; // st3@12 + double v18; // st2@12 + int v19; // ecx@14 + double v20; // st3@14 + int v21; // ecx@16 + double v22; // st3@16 + float v27; // [sp+24h] [bp-Ch]@5 + int v28; // [sp+28h] [bp-8h]@2 + float v29; // [sp+2Ch] [bp-4h]@5 + float v31; // [sp+3Ch] [bp+Ch]@5 + float a1; // [sp+40h] [bp+10h]@5 + + if ( this->uNumD3DSceneBegins ) + { + //v4 = pSoftBillboard; + //v5 = (double)pSoftBillboard->zbuffer_depth; + //pSoftBillboarda = pSoftBillboard->zbuffer_depth; + //v6 = pSoftBillboard->zbuffer_depth; + v7 = Billboard_ProbablyAddToListAndSortByZOrder(pSoftBillboard->zbuffer_depth); + //v8 = dimming_level; + //v9 = v7; + v28 = dimming_level & 0xFF000000; + if ( dimming_level & 0xFF000000 ) + pBillboardRenderListD3D[v7].opacity = RenderBillboardD3D::Opaque_3; + else + pBillboardRenderListD3D[v7].opacity = RenderBillboardD3D::Transparent; + //v10 = a3; + pBillboardRenderListD3D[v7].field_90 = pSoftBillboard->field_44; + pBillboardRenderListD3D[v7].sZValue = pSoftBillboard->sZValue; + pBillboardRenderListD3D[v7].sParentBillboardID = pSoftBillboard->sParentBillboardID; + //v25 = pSoftBillboard->uScreenSpaceX; + //v24 = pSoftBillboard->uScreenSpaceY; + a1 = (pSoftBillboard->_screenspace_x_scaler_packedfloat & 0xFFFF) * 0.000015260186 + HIWORD(pSoftBillboard->_screenspace_x_scaler_packedfloat); + v29 = (pSoftBillboard->_screenspace_y_scaler_packedfloat & 0xFFFF) * 0.000015260186 + HIWORD(pSoftBillboard->_screenspace_y_scaler_packedfloat); + v31 = (double)((pSprite->uBufferWidth >> 1) - pSprite->uAreaX); + v27 = (double)(pSprite->uBufferHeight - pSprite->uAreaY); + if ( pSoftBillboard->uFlags & 4 ) + v31 = v31 * -1.0; + if ( pSoftBillboard->sTintColor && this->bTinting ) + { + v11 = ::GetActorTintColor(dimming_level, 0, pSoftBillboard->zbuffer_depth, 0, 0); + v12 = BlendColors(pSoftBillboard->sTintColor, v11); + if ( v28 ) + v12 = (unsigned int)((char *)&array_77EC08[1852].pEdgeList1[17] + 3) & ((unsigned int)v12 >> 1); + } + else + { + v12 = ::GetActorTintColor(dimming_level, 0, pSoftBillboard->zbuffer_depth, 0, 0); + } + //v13 = (double)v25; + pBillboardRenderListD3D[v7].pQuads[0].specular = 0; + pBillboardRenderListD3D[v7].pQuads[0].diffuse = v12; + pBillboardRenderListD3D[v7].pQuads[0].pos.x = pSoftBillboard->uScreenSpaceX - v31 * a1; + //v14 = (double)v24; + //v32 = v14; + pBillboardRenderListD3D[v7].pQuads[0].pos.y = pSoftBillboard->uScreenSpaceY - v27 * v29; + v15 = 1.0 - 1.0 / (pSoftBillboard->zbuffer_depth * 0.061758894); + pBillboardRenderListD3D[v7].pQuads[0].pos.z = v15; + v16 = 1.0 / pSoftBillboard->zbuffer_depth; + pBillboardRenderListD3D[v7].pQuads[0].rhw = 1.0 / pSoftBillboard->zbuffer_depth; + pBillboardRenderListD3D[v7].pQuads[0].texcoord.x = 0.0; + pBillboardRenderListD3D[v7].pQuads[0].texcoord.y = 0.0; + v17 = (double)((pSprite->uBufferWidth >> 1) - pSprite->uAreaX); + v18 = (double)(pSprite->uBufferHeight - pSprite->uAreaY - pSprite->uAreaHeight); + if ( pSoftBillboard->uFlags & 4 ) + v17 = v17 * -1.0; + pBillboardRenderListD3D[v7].pQuads[1].specular = 0; + pBillboardRenderListD3D[v7].pQuads[1].diffuse = v12; + pBillboardRenderListD3D[v7].pQuads[1].pos.x = pSoftBillboard->uScreenSpaceX - v17 * a1; + pBillboardRenderListD3D[v7].pQuads[1].pos.y = pSoftBillboard->uScreenSpaceY - v18 * v29; + pBillboardRenderListD3D[v7].pQuads[1].pos.z = v15; + pBillboardRenderListD3D[v7].pQuads[1].rhw = v16; + pBillboardRenderListD3D[v7].pQuads[1].texcoord.x = 0.0; + pBillboardRenderListD3D[v7].pQuads[1].texcoord.y = 1.0; + v19 = pSprite->uBufferHeight - pSprite->uAreaY - pSprite->uAreaHeight; + v20 = (double)(pSprite->uAreaX + pSprite->uAreaWidth + (pSprite->uBufferWidth >> 1) - pSprite->uBufferWidth); + if ( pSoftBillboard->uFlags & 4 ) + v20 = v20 * -1.0; + pBillboardRenderListD3D[v7].pQuads[2].specular = 0; + pBillboardRenderListD3D[v7].pQuads[2].diffuse = v12; + pBillboardRenderListD3D[v7].pQuads[2].pos.x = v20 * a1 + pSoftBillboard->uScreenSpaceX; + pBillboardRenderListD3D[v7].pQuads[2].pos.y = pSoftBillboard->uScreenSpaceY - (double)v19 * v29; + pBillboardRenderListD3D[v7].pQuads[2].pos.z = v15; + pBillboardRenderListD3D[v7].pQuads[2].rhw = v16; + pBillboardRenderListD3D[v7].pQuads[2].texcoord.x = 1.0; + pBillboardRenderListD3D[v7].pQuads[2].texcoord.y = 1.0; + v21 = pSprite->uBufferHeight - pSprite->uAreaY; + v22 = (double)(pSprite->uAreaX + pSprite->uAreaWidth + (pSprite->uBufferWidth >> 1) - pSprite->uBufferWidth); + if ( pSoftBillboard->uFlags & 4 ) + v22 = v22 * -1.0; + pBillboardRenderListD3D[v7].pQuads[3].specular = 0; + pBillboardRenderListD3D[v7].pQuads[3].diffuse = v12; + pBillboardRenderListD3D[v7].pQuads[3].pos.x = v22 * a1 + pSoftBillboard->uScreenSpaceX; + pBillboardRenderListD3D[v7].pQuads[3].pos.y = pSoftBillboard->uScreenSpaceY - (double)v21 * v29; + pBillboardRenderListD3D[v7].pQuads[3].pos.z = v15; + pBillboardRenderListD3D[v7].pQuads[3].rhw = v16; + pBillboardRenderListD3D[v7].pQuads[3].texcoord.x = 1.0; + pBillboardRenderListD3D[v7].pQuads[3].texcoord.y = 0.0; + //v23 = pSprite->pTexture; + pBillboardRenderListD3D[v7].uNumVertices = 4; + pBillboardRenderListD3D[v7].z_order = pSoftBillboard->zbuffer_depth; + pBillboardRenderListD3D[v7].pTexture = pSprite->pTexture; + } +} + +//----- (004A354F) -------------------------------------------------------- +void Render::MakeParticleBillboardAndPush_BLV(RenderBillboardTransform_local0 *a2, IDirect3DTexture2 *a3, unsigned int uDiffuse, int angle) +{ + unsigned int v8; // esi@3 + float v11; // ST28_4@3 + float v16; // ST2C_4@3 + float v17; // ST30_4@3 + signed int v18; // ST18_4@3 + signed int v19; // ST14_4@3 + signed int v20; // ST10_4@3 + signed int v21; // eax@3 + double v22; // st6@3 + float v23; // ST2C_4@3 + float v24; // ST30_4@3 + signed int v25; // ST10_4@3 + signed int v26; // ST14_4@3 + signed int v27; // ST18_4@3 + signed int v28; // eax@3 + double v29; // st6@3 + float v30; // ecx@3 + float v31; // ST2C_4@3 + float v32; // ST30_4@3 + signed int v33; // ST10_4@3 + signed int v34; // ST14_4@3 + signed int v35; // ST18_4@3 + signed int v36; // eax@3 + float v37; // ecx@3 + double v38; // st6@3 + float v39; // ST2C_4@3 + float v40; // ST30_4@3 + signed int v41; // ST10_4@3 + signed int v42; // ST14_4@3 + signed int v43; // ST18_4@3 + signed int v44; // eax@3 + double v45; // st6@3 + float v46; // eax@3 + + if ( this->uNumD3DSceneBegins ) + { + if (a2->zbuffer_depth) + { + //v5 = (double)a2->zbuffer_depth; + //v6 = v5; + //v7 = v5; + v8 = Billboard_ProbablyAddToListAndSortByZOrder(a2->zbuffer_depth); + pBillboardRenderListD3D[v8].opacity = RenderBillboardD3D::Opaque_1; + pBillboardRenderListD3D[v8].field_90 = a2->field_44; + pBillboardRenderListD3D[v8].sZValue = a2->sZValue; + pBillboardRenderListD3D[v8].sParentBillboardID = a2->sParentBillboardID; + //v9 = a2->uScreenSpaceX; + //v10 = a2->uScreenSpaceY; + v11 = (a2->_screenspace_x_scaler_packedfloat & 0xFFFF) * 0.000015260186 + HIWORD(a2->_screenspace_x_scaler_packedfloat); + //v12 = (double) a2->uScreenSpaceX; + //v13 = v12; + //v14 = (double)(a2->uScreenSpaceY - 12); + //v15 = v14; + v16 = (double)( a2->uScreenSpaceX - 12) - (double) a2->uScreenSpaceX; + v17 = (double)(a2->uScreenSpaceY - 25) - (double)(a2->uScreenSpaceY - 12); + v18 = stru_5C6E00->Cos(angle); + v19 = stru_5C6E00->Sin(angle); + v20 = stru_5C6E00->Sin(angle); + v21 = stru_5C6E00->Cos(angle); + pBillboardRenderListD3D[v8].pQuads[0].pos.x = (((double)(unsigned __int16)v18 * 0.000015259022 + + (double)(v18 >> 16)) + * v16 + - ((double)(unsigned __int16)v19 * 0.000015259022 + + (double)(v19 >> 16)) + * v17) + * v11 + (double) a2->uScreenSpaceX; + v22 = (((double)(unsigned __int16)v21 * 0.000015259022 + (double)(v21 >> 16)) * v17 + + ((double)(unsigned __int16)v20 * 0.000015259022 + (double)(v20 >> 16)) * v16 + - 12.0) + * v11 + + (double)a2->uScreenSpaceY; + pBillboardRenderListD3D[v8].pQuads[0].specular = 0; + pBillboardRenderListD3D[v8].pQuads[0].diffuse = uDiffuse; + pBillboardRenderListD3D[v8].pQuads[0].pos.y = v22; + pBillboardRenderListD3D[v8].pQuads[0].pos.z = 1.0 - 1.0 / (a2->zbuffer_depth * 0.061758894); + pBillboardRenderListD3D[v8].pQuads[0].rhw = 1.0 / a2->zbuffer_depth; + pBillboardRenderListD3D[v8].pQuads[0].texcoord.x = 0.0; + pBillboardRenderListD3D[v8].pQuads[0].texcoord.y = 0.0; + v31 = (double)(a2->uScreenSpaceX + 12) - (double) a2->uScreenSpaceX; + v32 = (double)a2->uScreenSpaceY - (double)(a2->uScreenSpaceY - 12); + v25 = stru_5C6E00->Cos(angle); + v26 = stru_5C6E00->Sin(angle); + v27 = stru_5C6E00->Sin(angle); + v28 = stru_5C6E00->Cos(angle); + pBillboardRenderListD3D[v8].pQuads[1].pos.x = (((double)(unsigned __int16)v25 * 0.000015259022 + + (double)(v25 >> 16)) + * v31 + - ((double)(unsigned __int16)v26 * 0.000015259022 + + (double)(v26 >> 16)) + * v32) + * v11 + (double) a2->uScreenSpaceX; + v29 = (((double)(unsigned __int16)v28 * 0.000015259022 + (double)(v28 >> 16)) * v32 + + ((double)(unsigned __int16)v27 * 0.000015259022 + (double)(v27 >> 16)) * v31 + - 12.0) + * v11 + + (double)a2->uScreenSpaceY; + pBillboardRenderListD3D[v8].pQuads[1].pos.z = pRenderer->pBillboardRenderListD3D[v8].pQuads[0].pos.z; + v30 = pBillboardRenderListD3D[v8].pQuads[0].rhw; + pBillboardRenderListD3D[v8].pQuads[1].pos.y = v29; + pBillboardRenderListD3D[v8].pQuads[1].specular = 0; + pBillboardRenderListD3D[v8].pQuads[1].rhw = v30; + pBillboardRenderListD3D[v8].pQuads[1].diffuse = uDiffuse; + pBillboardRenderListD3D[v8].pQuads[1].texcoord.x = 0.0; + pBillboardRenderListD3D[v8].pQuads[1].texcoord.y = 1.0; + v23 = (double)(a2->uScreenSpaceX - 12) - (double) a2->uScreenSpaceX; + v24 = (double)a2->uScreenSpaceY - (double)(a2->uScreenSpaceY - 12); + v33 = stru_5C6E00->Cos(angle); + v34 = stru_5C6E00->Sin(angle); + v35 = stru_5C6E00->Sin(angle); + v36 = stru_5C6E00->Cos(angle); + pBillboardRenderListD3D[v8].pQuads[2].pos.x = (((double)(unsigned __int16)v33 * 0.000015259022 + + (double)(v33 >> 16)) + * v23 + - ((double)(unsigned __int16)v34 * 0.000015259022 + + (double)(v34 >> 16)) + * v24) + * v11 + (double) a2->uScreenSpaceX; + v37 = pBillboardRenderListD3D[v8].pQuads[0].pos.z; + v38 = (((double)(unsigned __int16)v36 * 0.000015259022 + (double)(v36 >> 16)) * v24 + + ((double)(unsigned __int16)v35 * 0.000015259022 + (double)(v35 >> 16)) * v23 + - 12.0) + * v11 + + (double)a2->uScreenSpaceY; + pBillboardRenderListD3D[v8].pQuads[2].specular = 0; + pBillboardRenderListD3D[v8].pQuads[2].pos.z = v37; + pBillboardRenderListD3D[v8].pQuads[2].rhw = pBillboardRenderListD3D[v8].pQuads[0].rhw; + pBillboardRenderListD3D[v8].pQuads[2].diffuse = uDiffuse; + pBillboardRenderListD3D[v8].pQuads[2].pos.y = v38; + pBillboardRenderListD3D[v8].pQuads[2].texcoord.x = 1.0; + pBillboardRenderListD3D[v8].pQuads[2].texcoord.y = 1.0; + v39 = (double)(a2->uScreenSpaceX + 12) - (double) a2->uScreenSpaceX; + v40 = (double)(a2->uScreenSpaceY - 25) - (double)(a2->uScreenSpaceY - 12); + v41 = stru_5C6E00->Cos(angle); + v42 = stru_5C6E00->Sin(angle); + v43 = stru_5C6E00->Sin(angle); + v44 = stru_5C6E00->Cos(angle); + pBillboardRenderListD3D[v8].pQuads[3].pos.x = (((double)(unsigned __int16)v41 * 0.000015259022 + + (double)(v41 >> 16)) + * v39 + - ((double)(unsigned __int16)v42 * 0.000015259022 + + (double)(v42 >> 16)) + * v40) + * v11 + (double) a2->uScreenSpaceX; + v45 = (((double)(unsigned __int16)v44 * 0.000015259022 + (double)(v44 >> 16)) * v40 + + ((double)(unsigned __int16)v43 * 0.000015259022 + (double)(v43 >> 16)) * v39 + - 12.0) + * v11 + + (double)a2->uScreenSpaceY; + v46 = pBillboardRenderListD3D[v8].pQuads[0].pos.z; + pBillboardRenderListD3D[v8].pQuads[3].specular = 0; + pBillboardRenderListD3D[v8].pQuads[3].pos.z = v46; + pBillboardRenderListD3D[v8].pQuads[3].rhw = pBillboardRenderListD3D[v8].pQuads[0].rhw; + pBillboardRenderListD3D[v8].pQuads[3].diffuse = uDiffuse; + pBillboardRenderListD3D[v8].pTexture = a3; + pBillboardRenderListD3D[v8].z_order = a2->zbuffer_depth; + pBillboardRenderListD3D[v8].uNumVertices = 4; + pBillboardRenderListD3D[v8].pQuads[3].pos.y = v45; + pBillboardRenderListD3D[v8].pQuads[3].texcoord.x = 1.0; + pBillboardRenderListD3D[v8].pQuads[3].texcoord.y = 0.0; + } + } +} + +//----- (004A3AD9) -------------------------------------------------------- +void Render::MakeParticleBillboardAndPush_ODM(RenderBillboardTransform_local0 *a2, IDirect3DTexture2 *a3, unsigned int uDiffuse, int angle) +{ + double v5; // st7@2 + float v6; // ST28_4@2 + float v7; // ST00_4@2 + unsigned int v8; // esi@2 + //int v9; // eax@2 + //int v10; // ebx@2 + float v11; // ST34_4@2 + double v12; // st7@2 + float v13; // ST2C_4@2 + double v14; // st6@2 + float v15; // ST24_4@2 + float v16; // ST38_4@2 + float v17; // ST3C_4@2 + signed int v18; // ST1C_4@2 + int v19; // ST30_4@2 + signed int v20; // ST20_4@2 + signed int v21; // ST18_4@2 + signed int v22; // eax@2 + double v23; // st6@2 + float v24; // ST20_4@2 + float v25; // ST1C_4@2 + float v26; // ST38_4@2 + float v27; // ST3C_4@2 + signed int v28; // ST18_4@2 + signed int v29; // ST14_4@2 + signed int v30; // ST10_4@2 + signed int v31; // eax@2 + double v32; // st6@2 + float v33; // ST38_4@2 + float v34; // ST3C_4@2 + signed int v35; // ST10_4@2 + signed int v36; // ST14_4@2 + signed int v37; // ST18_4@2 + signed int v38; // eax@2 + double v39; // st6@2 + float v40; // ST38_4@2 + float v41; // ST3C_4@2 + signed int v42; // ST10_4@2 + signed int v43; // ST14_4@2 + signed int v44; // ST18_4@2 + signed int v45; // eax@2 + double v46; // st6@2 + + if ( this->uNumD3DSceneBegins ) + { + v5 = (double)a2->zbuffer_depth; + v6 = v5; + v7 = v5; + v8 = Billboard_ProbablyAddToListAndSortByZOrder(LODWORD(v7)); + pBillboardRenderListD3D[v8].opacity = RenderBillboardD3D::Opaque_1; + pBillboardRenderListD3D[v8].field_90 = a2->field_44; + pBillboardRenderListD3D[v8].sZValue = a2->sZValue; + pBillboardRenderListD3D[v8].sParentBillboardID = a2->sParentBillboardID; + + //v9 = a2->uScreenSpaceX; + //v10 = a2->uScreenSpaceY; + v11 = (a2->_screenspace_x_scaler_packedfloat & 0xFFFF) * 0.000015260186 + HIWORD(a2->_screenspace_x_scaler_packedfloat); + v12 = (double)a2->uScreenSpaceX; + v13 = (double)a2->uScreenSpaceX; + v14 = (double)(a2->uScreenSpaceY - 12); + v15 = v14; + v16 = (double)(a2->uScreenSpaceX - 12) - v12; + v17 = (double)(a2->uScreenSpaceY - 25) - v14; + v18 = stru_5C6E00->Cos(angle); + v19 = angle - stru_5C6E00->uIntegerHalfPi; + v20 = stru_5C6E00->Sin(angle); + v21 = stru_5C6E00->Sin(angle); + v22 = stru_5C6E00->Cos(angle); + pBillboardRenderListD3D[v8].pQuads[0].pos.x = (((double)(unsigned __int16)v18 * 0.000015259022 + + (double)(v18 >> 16)) * v16 + - ((double)(unsigned __int16)v20 * 0.000015259022 + + (double)(v20 >> 16)) * v17) + * v11 + v13; + v23 = (((double)(unsigned __int16)v22 * 0.000015259022 + (double)(v22 >> 16)) * v17 + + ((double)(unsigned __int16)v21 * 0.000015259022 + (double)(v21 >> 16)) * v16 + - 12.0) + * v11 + + (double)a2->uScreenSpaceY; + pBillboardRenderListD3D[v8].pQuads[0].specular = 0; + pBillboardRenderListD3D[v8].pQuads[0].diffuse = uDiffuse; + pBillboardRenderListD3D[v8].pQuads[0].pos.y = v23; + v24 = 1.0 - 1.0 / (v6 * 1000.0 / (double)pODMRenderParams->shading_dist_mist); + pBillboardRenderListD3D[v8].pQuads[0].pos.z = v24; + v25 = 1.0 / v6; + pBillboardRenderListD3D[v8].pQuads[0].rhw = v25; + pBillboardRenderListD3D[v8].pQuads[0].texcoord.x = 0.0; + pBillboardRenderListD3D[v8].pQuads[0].texcoord.y = 0.0; + + v26 = (double)(a2->uScreenSpaceX - 12) - v13; + v27 = (double)a2->uScreenSpaceY - v15; + v28 = stru_5C6E00->Cos(angle); + v29 = stru_5C6E00->Sin(v19 + stru_5C6E00->uIntegerHalfPi); + v30 = stru_5C6E00->Sin(v19 + stru_5C6E00->uIntegerHalfPi); + v31 = stru_5C6E00->Cos(angle); + pBillboardRenderListD3D[v8].pQuads[1].pos.x = (((double)(unsigned __int16)v28 * 0.000015259022 + + (double)(v28 >> 16)) * v26 + - ((double)(unsigned __int16)v29 * 0.000015259022 + + (double)(v29 >> 16)) * v27) + * v11 + v13; + v32 = (((double)(unsigned __int16)v31 * 0.000015259022 + (double)(v31 >> 16)) * v27 + + ((double)(unsigned __int16)v30 * 0.000015259022 + (double)(v30 >> 16)) * v26 + - 12.0) + * v11 + + (double)a2->uScreenSpaceY; + pBillboardRenderListD3D[v8].pQuads[1].pos.z = v24; + pBillboardRenderListD3D[v8].pQuads[1].pos.y = v32; + pBillboardRenderListD3D[v8].pQuads[1].specular = 0; + pBillboardRenderListD3D[v8].pQuads[1].rhw = v25; + pBillboardRenderListD3D[v8].pQuads[1].diffuse = uDiffuse; + pBillboardRenderListD3D[v8].pQuads[1].texcoord.x = 0.0; + pBillboardRenderListD3D[v8].pQuads[1].texcoord.y = 1.0; + + v33 = (double)(a2->uScreenSpaceX + 12) - v13; + v34 = (double)a2->uScreenSpaceY - v15; + v35 = stru_5C6E00->Cos(angle); + v36 = stru_5C6E00->Sin(v19 + stru_5C6E00->uIntegerHalfPi); + v37 = stru_5C6E00->Sin(v19 + stru_5C6E00->uIntegerHalfPi); + v38 = stru_5C6E00->Cos(angle); + pBillboardRenderListD3D[v8].pQuads[2].pos.x = (((double)(unsigned __int16)v35 * 0.000015259022 + + (double)(v35 >> 16)) * v33 + - ((double)(unsigned __int16)v36 * 0.000015259022 + + (double)(v36 >> 16)) * v34) + * v11 + v13; + v39 = (((double)(unsigned __int16)v38 * 0.000015259022 + (double)(v38 >> 16)) * v34 + + ((double)(unsigned __int16)v37 * 0.000015259022 + (double)(v37 >> 16)) * v33 + - 12.0) + * v11 + + (double)a2->uScreenSpaceY; + pBillboardRenderListD3D[v8].pQuads[2].specular = 0; + pBillboardRenderListD3D[v8].pQuads[2].pos.z = v24; + pBillboardRenderListD3D[v8].pQuads[2].rhw = v25; + pBillboardRenderListD3D[v8].pQuads[2].diffuse = uDiffuse; + pBillboardRenderListD3D[v8].pQuads[2].pos.y = v39; + pBillboardRenderListD3D[v8].pQuads[2].texcoord.x = 1.0; + pBillboardRenderListD3D[v8].pQuads[2].texcoord.y = 1.0; + + v40 = (double)(a2->uScreenSpaceX + 12) - v13; + v41 = (double)(a2->uScreenSpaceY - 25) - v15; + v42 = stru_5C6E00->Cos(angle); + v43 = stru_5C6E00->Sin(v19 + stru_5C6E00->uIntegerHalfPi); + v44 = stru_5C6E00->Sin(v19 + stru_5C6E00->uIntegerHalfPi); + v45 = stru_5C6E00->Cos(angle); + pBillboardRenderListD3D[v8].pQuads[3].pos.x = (((double)(unsigned __int16)v42 * 0.000015259022 + + (double)(v42 >> 16)) * v40 + - ((double)(unsigned __int16)v43 * 0.000015259022 + + (double)(v43 >> 16)) * v41) + * v11 + v13; + v46 = (((double)(unsigned __int16)v45 * 0.000015259022 + (double)(v45 >> 16)) * v41 + + ((double)(unsigned __int16)v44 * 0.000015259022 + (double)(v44 >> 16)) * v40 + - 12.0) + * v11 + + (double)a2->uScreenSpaceY; + pBillboardRenderListD3D[v8].pQuads[3].specular = 0; + pBillboardRenderListD3D[v8].pQuads[3].pos.z = v24; + pBillboardRenderListD3D[v8].pQuads[3].rhw = v25; + pBillboardRenderListD3D[v8].pQuads[3].diffuse = uDiffuse; + pBillboardRenderListD3D[v8].pTexture = a3; + pBillboardRenderListD3D[v8].z_order = v6; + pBillboardRenderListD3D[v8].uNumVertices = 4; + pBillboardRenderListD3D[v8].pQuads[3].pos.y = v46; + pBillboardRenderListD3D[v8].pQuads[3].texcoord.x = 1.0; + pBillboardRenderListD3D[v8].pQuads[3].texcoord.y = 0.0; + } +} + +//----- (004A4023) -------------------------------------------------------- +void Render::TransformBillboard(RenderBillboardTransform_local0 *a2, Sprite *pSprite, int dimming_level, RenderBillboard *pBillboard) +{ + unsigned int v8; // esi@2 + double v14; // st6@14 + double v15; // st5@14 + float v29; // [sp+28h] [bp-8h]@5 + float v30; // [sp+2Ch] [bp-4h]@5 + + if (!uNumD3DSceneBegins) + return; + + v8 = Billboard_ProbablyAddToListAndSortByZOrder(a2->zbuffer_depth); + + v30 = (a2->_screenspace_x_scaler_packedfloat & 0xFFFF) / 65530.0 + HIWORD(a2->_screenspace_x_scaler_packedfloat); + v29 = (a2->_screenspace_y_scaler_packedfloat & 0xFFFF) / 65530.0 + HIWORD(a2->_screenspace_y_scaler_packedfloat); + + unsigned int diffuse = ::GetActorTintColor(dimming_level, 0, a2->zbuffer_depth, 0, pBillboard); + if (a2->sTintColor & 0x00FFFFFF && bTinting) + { + diffuse = BlendColors(a2->sTintColor, diffuse); + if (a2->sTintColor & 0xFF000000) + diffuse = 0x007F7F7F & ((unsigned int)diffuse >> 1); + } + + unsigned int specular = 0; + if (bUsingSpecular) + specular = sub_47C3D7_get_fog_specular(0, 0, a2->zbuffer_depth); + + v14 = (double)((int)pSprite->uBufferWidth / 2 - pSprite->uAreaX); + v15 = (double)((int)pSprite->uBufferHeight - pSprite->uAreaY); + if (a2->uFlags & 4) + v14 *= -1.0; + pBillboardRenderListD3D[v8].pQuads[0].diffuse = diffuse; + pBillboardRenderListD3D[v8].pQuads[0].pos.x = (double)a2->uScreenSpaceX - v14 * v30; + pBillboardRenderListD3D[v8].pQuads[0].pos.y = (double)a2->uScreenSpaceY - v15 * v29; + pBillboardRenderListD3D[v8].pQuads[0].pos.z = 1.0 - 1.0 / (a2->zbuffer_depth * 1000.0 / (double)pODMRenderParams->shading_dist_mist); + pBillboardRenderListD3D[v8].pQuads[0].rhw = 1.0 / a2->zbuffer_depth; + pBillboardRenderListD3D[v8].pQuads[0].specular = specular; + pBillboardRenderListD3D[v8].pQuads[0].texcoord.x = 0.0; + pBillboardRenderListD3D[v8].pQuads[0].texcoord.y = 0.0; + + v14 = (double)((int)pSprite->uBufferWidth / 2 - pSprite->uAreaX); + v15 = (double)((int)pSprite->uBufferHeight - pSprite->uAreaHeight - pSprite->uAreaY); + if ( a2->uFlags & 4 ) + v14 = v14 * -1.0; + pBillboardRenderListD3D[v8].pQuads[1].specular = specular; + pBillboardRenderListD3D[v8].pQuads[1].diffuse = diffuse; + pBillboardRenderListD3D[v8].pQuads[1].pos.x = (double)a2->uScreenSpaceX - v14 * v30; + pBillboardRenderListD3D[v8].pQuads[1].pos.y = (double)a2->uScreenSpaceY - v15 * v29; + pBillboardRenderListD3D[v8].pQuads[1].pos.z = 1.0 - 1.0 / (a2->zbuffer_depth * 1000.0 / (double)pODMRenderParams->shading_dist_mist); + pBillboardRenderListD3D[v8].pQuads[1].rhw = 1.0 / a2->zbuffer_depth; + pBillboardRenderListD3D[v8].pQuads[1].texcoord.x = 0.0; + pBillboardRenderListD3D[v8].pQuads[1].texcoord.y = 1.0; + + v14 = (double)((int)pSprite->uAreaWidth + pSprite->uAreaX + pSprite->uBufferWidth / 2 - pSprite->uBufferWidth); + v15 = (double)((int)pSprite->uBufferHeight - pSprite->uAreaHeight - pSprite->uAreaY); + if ( a2->uFlags & 4 ) + v14 *= -1.0; + pBillboardRenderListD3D[v8].pQuads[2].diffuse = diffuse; + pBillboardRenderListD3D[v8].pQuads[2].specular = specular; + pBillboardRenderListD3D[v8].pQuads[2].pos.x = (double)a2->uScreenSpaceX + v14 * v30; + pBillboardRenderListD3D[v8].pQuads[2].pos.y = (double)a2->uScreenSpaceY - v15 * v29; + pBillboardRenderListD3D[v8].pQuads[2].pos.z = 1.0 - 1.0 / (a2->zbuffer_depth * 1000.0 / (double)pODMRenderParams->shading_dist_mist); + pBillboardRenderListD3D[v8].pQuads[2].rhw = 1.0 / a2->zbuffer_depth; + pBillboardRenderListD3D[v8].pQuads[2].texcoord.x = 1.0; + pBillboardRenderListD3D[v8].pQuads[2].texcoord.y = 1.0; + + v14 = (double)((int)pSprite->uAreaWidth + pSprite->uAreaX + pSprite->uBufferWidth / 2 - pSprite->uBufferWidth); + v15 = (double)((int)pSprite->uBufferHeight - pSprite->uAreaY); + if ( a2->uFlags & 4 ) + v14 *= -1.0; + pBillboardRenderListD3D[v8].pQuads[3].diffuse = diffuse; + pBillboardRenderListD3D[v8].pQuads[3].specular = specular; + pBillboardRenderListD3D[v8].pQuads[3].pos.x = (double)a2->uScreenSpaceX + v14 * v30; + pBillboardRenderListD3D[v8].pQuads[3].pos.y = (double)a2->uScreenSpaceY - v15 * v29; + pBillboardRenderListD3D[v8].pQuads[3].pos.z = 1.0 - 1.0 / (a2->zbuffer_depth * 1000.0 / (double)pODMRenderParams->shading_dist_mist); + pBillboardRenderListD3D[v8].pQuads[3].rhw = 1.0 / a2->zbuffer_depth; + pBillboardRenderListD3D[v8].pQuads[3].texcoord.x = 1.0; + pBillboardRenderListD3D[v8].pQuads[3].texcoord.y = 0.0; + + pBillboardRenderListD3D[v8].uNumVertices = 4; + pBillboardRenderListD3D[v8].pTexture = pSprite->pTexture; + pBillboardRenderListD3D[v8].z_order = a2->zbuffer_depth; + pBillboardRenderListD3D[v8].field_90 = a2->field_44; + pBillboardRenderListD3D[v8].sZValue = a2->sZValue; + pBillboardRenderListD3D[v8].sParentBillboardID = a2->sParentBillboardID; + + if (a2->sTintColor & 0xFF000000) + pBillboardRenderListD3D[v8].opacity = RenderBillboardD3D::Opaque_3; + else + pBillboardRenderListD3D[v8].opacity = RenderBillboardD3D::Transparent; +} + + +//----- (004A49D0) -------------------------------------------------------- +void Render::DrawProjectile(float srcX, float srcY, float a3, float a4, float dstX, float dstY, float a7, float a8, IDirect3DTexture2 *a9) +{ + int absXDifference; // eax@1 + int absYDifference; // eax@1 + unsigned int smallerabsdiff; // ebx@1 + unsigned int largerabsdiff; + double v16; // st7@7 + double v17; // st7@7 + double v18; // st6@7 + double v20; // st4@8 + double v21; // st4@10 + double v22; // st4@10 + double v23; // st4@10 + double v25; // st4@11 + double v26; // st4@13 + double v28; // st4@13 + RenderVertexD3D3 v29[4]; // [sp+0h] [bp-94h]@7 + int xDifference; // [sp+88h] [bp-Ch]@1 + signed int v32; // [sp+8Ch] [bp-8h]@1 + int yDifference; // [sp+90h] [bp-4h]@1 + + xDifference = bankersRounding(dstX - srcX); + yDifference = bankersRounding(dstY - srcY); + absYDifference = abs(yDifference); + absXDifference = abs(xDifference); + smallerabsdiff = min(absXDifference, absYDifference); + largerabsdiff = max(absXDifference, absYDifference); + v32 = (11 * smallerabsdiff >> 5) + largerabsdiff; + v16 = 1.0 / (double)v32; + v17 = (double)yDifference * v16 * a4; + v18 = (double)xDifference * v16 * a4; + if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor ) + { + v20 = a3 * 1000.0 / (double)pODMRenderParams->shading_dist_mist; + v25 = a7 * 1000.0 / (double)pODMRenderParams->shading_dist_mist; + } + else + { + v20 = a3 * 0.061758894; + v25 = a7 * 0.061758894; + } + v21 = 1.0 / a3; + v22 = (double)yDifference * v16 * a8; + v23 = (double)xDifference * v16 * a8; + v26 = 1.0 - 1.0 / v25; + v28 = 1.0 / a7; + v29[0].pos.x = srcX + v17; + v29[0].pos.y = srcY - v18; + v29[0].pos.z = 1.0 - 1.0 / v20; + v29[0].rhw = v21; + v29[0].diffuse = -1; + v29[0].specular = 0; + v29[0].texcoord.x = 1.0; + v29[0].texcoord.y = 0.0; + + v29[1].pos.x = v22 + dstX; + v29[1].pos.y = dstY - v23; + v29[1].pos.z = v26; + v29[1].rhw = v28; + v29[1].diffuse = -16711936; + v29[1].specular = 0; + v29[1].texcoord.x = 1.0; + v29[1].texcoord.y = 1.0; + + v29[2].pos.x = dstX - v22; + v29[2].pos.y = v23 + dstY; + v29[2].pos.z = v26; + v29[2].rhw = v28; + v29[2].diffuse = -1; + v29[2].specular = 0; + v29[2].texcoord.x = 0.0; + v29[2].texcoord.y = 1.0; + + v29[3].pos.x = srcX - v17; + v29[3].pos.y = v18 + srcY; + v29[3].pos.z = v29[0].pos.z; + v29[3].rhw = v21; + v29[3].diffuse = -1; + v29[3].specular = 0; + v29[3].texcoord.x = 0.0; + v29[3].texcoord.y = 0.0; + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, FALSE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE)); + ErrD3D(pRenderD3D->pDevice->SetTexture(0, a9)); + ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, v29, 4, 24)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CW)); +} + +//----- (004A4CC9) -------------------------------------------------------- +void Render::_4A4CC9_AddSomeBillboard(stru6_stru1_indoor_sw_billboard *a1, int diffuse) +{ + unsigned int v5; // eax@7 + double v10; // st6@9 + double v11; // st6@10 + int v12; // ebx@13 + + if (a1->uNumVertices < 3) + return; + + float depth = 1000000.0; + for (uint i = 0; i < (unsigned int)a1->uNumVertices; ++i) + { + if (a1->field_104[i].z < depth) + depth = a1->field_104[i * 4].z; + } + + v5 = Billboard_ProbablyAddToListAndSortByZOrder(depth); + pBillboardRenderListD3D[v5].field_90 = 0; + pBillboardRenderListD3D[v5].sParentBillboardID = -1; + pBillboardRenderListD3D[v5].opacity = RenderBillboardD3D::Opaque_2; + pBillboardRenderListD3D[v5].pTexture = 0; + pBillboardRenderListD3D[v5].uNumVertices = a1->uNumVertices; + pBillboardRenderListD3D[v5].z_order = depth; + + for (uint i = 0; i < (unsigned int)a1->uNumVertices; ++i) + { + pBillboardRenderListD3D[v5].pQuads[i].pos.x = a1->field_104[i].x; + pBillboardRenderListD3D[v5].pQuads[i].pos.y = a1->field_104[i].y; + + v10 = a1->field_104[i].z; + if (uCurrentlyLoadedLevelType == LEVEL_Indoor) + v11 = v10 * 0.061758894; + else + v11 = v10 * 1000.0 / (double)pODMRenderParams->shading_dist_mist; + pBillboardRenderListD3D[v5].pQuads[i].pos.z = 1.0 - 1.0 / v11; + pBillboardRenderListD3D[v5].pQuads[i].rhw = 1.0 / a1->field_104[i].z; + + if (diffuse & 0xFF000000) + v12 = a1->field_104[i].diffuse; + else + v12 = diffuse; + pBillboardRenderListD3D[v5].pQuads[i].diffuse = v12; + pBillboardRenderListD3D[v5].pQuads[i].specular = 0; + + pBillboardRenderListD3D[v5].pQuads[i].texcoord.x = 0.0; + pBillboardRenderListD3D[v5].pQuads[i].texcoord.y = 0.0; + } +} + +//----- (004A4DE1) -------------------------------------------------------- +bool Render::LoadTexture(const char *pName, unsigned int bMipMaps, IDirectDrawSurface4 **pOutSurface, IDirect3DTexture2 **pOutTexture) +{ + unsigned __int16 *v13; // ecx@19 + unsigned __int16 *v14; // eax@19 + DWORD v15; // edx@20 + stru350 Dst; // [sp+Ch] [bp-F8h]@12 + + HWLTexture* pHWLTexture = pD3DBitmaps.LoadTexture(pName, bMipMaps); + if ( pHWLTexture ) + { + bMipMaps = !strncmp(pName, "HDWTR", 5); + if ( !pRenderD3D->CreateTexture(pHWLTexture->uWidth, pHWLTexture->uHeight, pOutSurface, pOutTexture, true, + bMipMaps, uMinDeviceTextureDim) ) + Error("HiScreen16::LoadTexture - D3Drend->CreateTexture() failed: %x", 0); + if (bMipMaps) + { + Dst._450DDE(); + Dst._450DF1(&stru_4EFCBC, &stru_4EFCBC); + + IDirectDrawSurface4 *pNextSurf = *pOutSurface; + while ( 1 ) + { + DDSCAPS2 v19; + memset(&v19, 0, sizeof(DDSCAPS2)); + v19.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP; + + DDSURFACEDESC2 desc; + memset(&desc, 0, sizeof(DDSURFACEDESC2)); + desc.dwSize = sizeof(DDSURFACEDESC2); + + if ( LockSurface_DDraw4(pNextSurf, &desc, DDLOCK_WAIT | DDLOCK_WRITEONLY) ) + { + // linear scaling + for (int s = 0; s < desc.dwHeight; ++s) + for (int t = 0; t < desc.dwWidth; ++t) + { + unsigned int resampled_x = t * pHWLTexture->uWidth / desc.dwWidth, + resampled_y = s * pHWLTexture->uHeight / desc.dwHeight; + unsigned short sample = pHWLTexture->pPixels[resampled_y * pHWLTexture->uWidth + resampled_x]; + + ((unsigned short *)desc.lpSurface)[s * (desc.lPitch >> 1) + t] = sample; + } + + + //bicubic sampling + //Dst.sub_451007_scale_image_bicubic(pHWLTexture->pPixels, pHWLTexture->uWidth, pHWLTexture->uHeight, pHWLTexture->uWidth, + // (unsigned short *)desc.lpSurface, desc.dwWidth, desc.dwHeight, desc.lPitch >> 1, 0, 0); + + ErrD3D(pNextSurf->Unlock(NULL)); + //bMipMaps = 0x4D86ACu; + } + if (FAILED(pNextSurf->GetAttachedSurface(&v19, &pNextSurf))) + break; + } + //v20 = -1; + //nullsub_1(); + } + else + { + DDSCAPS2 v19; + memset(&v19, 0, sizeof(DDSCAPS2)); + v19.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP; + + DDSURFACEDESC2 desc; + memset(&desc, 0, sizeof(DDSURFACEDESC2)); + desc.dwSize = sizeof(DDSURFACEDESC2); + + if ( LockSurface_DDraw4(*pOutSurface, &desc, DDLOCK_WAIT | DDLOCK_WRITEONLY) ) + { + bMipMaps = 0; + v13 = pHWLTexture->pPixels; + v14 = (unsigned __int16 *)desc.lpSurface; + for(uint bMipMaps = 0; bMipMaps < desc.dwHeight; bMipMaps++) + { + for (v15 = 0; v15 < desc.dwWidth; v15++) + { + *v14 = *v13; + ++v14; + ++v13; + } + v14 += (desc.lPitch >> 1) - desc.dwWidth; + } + ErrD3D((*pOutSurface)->Unlock(NULL)); + } + } + delete [] pHWLTexture->pPixels; + delete pHWLTexture; + return true; + } + return false; +} + +//----- (004A5048) -------------------------------------------------------- +bool Render::MoveSpriteToDevice( Sprite *pSprite ) +{ + HWLTexture *sprite_texture; // eax@1 + unsigned __int16 *v9; // edx@5 + LPVOID v10; // eax@5 + DDSURFACEDESC2 Dst; // [sp+Ch] [bp-7Ch]@4 + + sprite_texture = pD3DSprites.LoadTexture(pSprite->pName, pSprite->uPaletteID); + if ( sprite_texture ) + { + pSprite->uAreaX = sprite_texture->uAreaX; + pSprite->uAreaY = sprite_texture->uAreaY; + pSprite->uBufferWidth = sprite_texture->uBufferWidth; + pSprite->uBufferHeight = sprite_texture->uBufferHeight; + pSprite->uAreaWidth = sprite_texture->uAreaWidth; + pSprite->uAreaHeight = sprite_texture->uAreaHeigth; + if (!pRenderD3D->CreateTexture(sprite_texture->uWidth, sprite_texture->uHeight, &pSprite->pTextureSurface, &pSprite->pTexture, 1u, 0, uMinDeviceTextureDim)) + Error("HiScreen16::LoadTexture - D3Drend->CreateTexture() failed: %x", 0); + memset(&Dst, 0, sizeof(DDSURFACEDESC2)); + Dst.dwSize = 124; + if ( LockSurface_DDraw4((IDirectDrawSurface4 *)pSprite->pTextureSurface, &Dst, DDLOCK_WAIT | DDLOCK_WRITEONLY) ) + { + v9 = sprite_texture->pPixels; + v10 = Dst.lpSurface; + for (uint i=0; iuHeight; ++i) + { + for (uint j=0; juWidth/2; ++j) + { + *(int *)v10 = *(int *)v9; + v9 += 2; + v10 = (char *)v10 + 4; + } + v10 = (char *)v10 + Dst.lPitch-sprite_texture->uWidth*2; + } + ErrD3D(pSprite->pTextureSurface->Unlock(NULL)); + } + delete [] sprite_texture->pPixels; + delete sprite_texture; + return true; + } + return false; +} + +//----- (004A51CB) -------------------------------------------------------- +void Render::BeginScene() +{ + //Render *v1; // esi@1 + unsigned int v2; // eax@1 +/*int v3; // eax@5 + unsigned __int16 **v4; // edi@6 + char *v5; // ebx@7*/ +// DDSURFACEDESC2 Dst; // [sp+Ch] [bp-7Ch]@4 + + //v1 = this; + v2 = this->uNumSceneBegins; + this->uNumSceneBegins = v2 + 1; + if ( !v2 ) + { + if ( this->pRenderD3D ) + { + /*if ( this->bColorKeySupported ) + { + memset(&Dst, 0, 0x7Cu); + Dst.dwSize = 124; + if ( LockSurface_DDraw4(this->pColorKeySurface4, &Dst, 0x800 | DDLOCK_WAIT) ) + { + this->pTargetSurface = (unsigned __int16 *)Dst.lpSurface; + this->uTargetSurfacePitch = Dst.lPitch >> 1; + this->field_18_locked_pitch = Dst.lPitch >> 1; + } + --this->uNumSceneBegins; + }*/ + } + else + { + if ( !this->pTargetSurface ) + { + LockRenderSurface((void **)&this->pTargetSurface, &this->uTargetSurfacePitch); + /*if ( this->pTargetSurface ) + { + this->field_18_locked_pitch = this->uTargetSurfacePitch; + }*/ + --this->uNumSceneBegins; + } + } + RestoreFrontBuffer(); + } +} + +//----- (004A527D) -------------------------------------------------------- +void Render::EndScene() +{ + if ( this->uNumSceneBegins ) + { + this->uNumSceneBegins--; + if ( !this->uNumSceneBegins ) + { + if ( this->pRenderD3D ) + { + /*if ( this->bColorKeySupported ) + { + this->pTargetSurface = 0; + this->uTargetSurfacePitch = 0; + this->field_18_locked_pitch = 0; + ErrD3D(this->pColorKeySurface4->Unlock(NULL)); + }*/ + } + else + { + this->pTargetSurface = 0; + this->uTargetSurfacePitch = 0; + //this->field_18_locked_pitch = 0; + UnlockBackBuffer(); + } + } + } +} + +//----- (004A52F1) -------------------------------------------------------- +void Render::ScreenFade(unsigned int color, float t) +{ + unsigned int v3; // esi@1 + unsigned int v7; // eax@6 + RenderVertexD3D3 v36[4]; // [sp+Ch] [bp-94h]@6 + int v40; // [sp+9Ch] [bp-4h]@6 + + v3 = 0; + + //{ + if (t > 1.0f) + t = 1.0f; + else if (t < 0.0f) + t = 0.0f; + + v40 = (char)floorf(t * 255.0f + 0.5f); + + v7 = color | (v40 << 24); + + v36[0].specular = 0; + v36[0].pos.x = pViewport->uViewportTL_X; + v36[0].pos.y = (double)pViewport->uViewportTL_Y; + v36[0].pos.z = 0.0; + v36[0].diffuse = v7; + v36[0].rhw = 1.0; + v36[0].texcoord.x = 0.0; + v36[0].texcoord.y = 0.0; + + v36[1].specular = 0; + v36[1].pos.x = pViewport->uViewportTL_X; + v36[1].pos.y = (double)(pViewport->uViewportBR_Y + 1); + v36[1].pos.z = 0.0; + v36[1].diffuse = v7; + v36[1].rhw = 1.0; + v36[1].texcoord.x = 0.0; + v36[1].texcoord.y = 0.0; + + v36[2].specular = 0; + v36[2].pos.x = (double)pViewport->uViewportBR_X; + v36[2].pos.y = (double)(pViewport->uViewportBR_Y + 1); + v36[2].pos.z = 0.0; + v36[2].diffuse = v7; + v36[2].rhw = 1.0; + v36[2].texcoord.x = 0.0; + v36[2].texcoord.y = 0.0; + + v36[3].specular = 0; + v36[3].pos.x = (double)pViewport->uViewportBR_X; + v36[3].pos.y = (double)pViewport->uViewportTL_Y; + v36[3].pos.z = 0.0; + v36[3].diffuse = v7; + v36[3].rhw = 1.0; + v36[3].texcoord.x = 0.0; + v36[3].texcoord.y = 0.0; + + ErrD3D(pRenderD3D->pDevice->SetTexture(0, 0)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, FALSE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, D3DCMP_ALWAYS)); + ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, v36, 4, 28)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, D3DCMP_LESS)); + /*} + else + { + v40 = (1.0 - a3) * 65536.0; + v39 = v40 + 6.7553994e15; + LODWORD(a3) = LODWORD(v39); + v38 = (signed int)(pViewport->uViewportBR_X - pViewport->uViewportTL_X) >> 1; + HIDWORD(v39) = pViewport->uViewportBR_Y - pViewport->uViewportTL_Y + 1; + v13 = pViewport->uViewportTL_X + ecx0->uTargetSurfacePitch - pViewport->uViewportBR_X; + v14 = &ecx0->pTargetSurface[pViewport->uViewportTL_X + pViewport->uViewportTL_Y * ecx0->uTargetSurfacePitch]; + v37 = 2 * v13; + LODWORD(v40) = (int)v14; + + int __i = 0; + v15 = dword_F1B430.data(); + do + { + v16 = v3; + v3 += LODWORD(a3); + dword_F1B430[__i++] = v16 >> 16; + } + //while ( (signed int)v15 < (signed int)&Aureal3D_SplashScreen ); + while (__i < 32); + + if ( pRenderer->uTargetGBits == 6 ) + { + v17 = sr_42690D_colors_cvt(this_); + v18 = (65536 - LODWORD(a3)) * (v17 & 0x1F); + this_ = (((65536 - LODWORD(a3)) * (unsigned __int16)(v17 & 0xF800) & 0xF800FFFF | v18 & 0x1F0000 | (65536 - LODWORD(a3)) * (v17 & 0x7E0) & 0x7E00000u) >> 16 << 16) | (((65536 - LODWORD(a3)) * (unsigned __int16)(v17 & 0xF800) & 0xF800FFFF | v18 & 0x1F0000 | (65536 - LODWORD(a3)) * (v17 & 0x7E0) & 0x7E00000u) >> 16); + v19 = v40; + v20 = off_4EFDB0; + v21 = HIDWORD(v39); + do + { + v22 = v38; + v31 = v21; + do + { + v23 = (*(int *)((char *)v20 + + ((((unsigned __int16)(*(short *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF800u) >> 9)) << 11) | *(unsigned int *)LODWORD(v19) & 0x7FF) & 0x7C0u) >> 4)) << 6) | (*(int *)((char *)v20 + ((((*(int *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF800u) >> 9)) << 11) | (*(int *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF8000000u) >> 25)) << 27) | *(unsigned int *)LODWORD(v19) & 0x7FF07FF) & 0x7C00000u) >> 20)) << 22) | ((*(int *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF800u) >> 9)) << 11) | (*(int *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF8000000u) >> 25)) << 27) | *(unsigned int *)LODWORD(v19) & 0x7FF07FF) & 0xF81FF81F; + result = this_ + + (*((int *)v20 + + (((unsigned __int8)(*((char *)v20 + + ((((unsigned __int16)(*(short *)((char *)v20 + + ((*(unsigned int *)LODWORD(v19) & 0xF800u) >> 9)) << 11) | *(unsigned int *)LODWORD(v19) & 0x7FF) & 0x7C0u) >> 4)) << 6) | *(unsigned int *)LODWORD(v19) & 0x1F) & 0x1F)) | (*(int *)((char *)v20 + ((v23 & 0x1F0000u) >> 14)) << 16) | ((*(int *)((char *)v20 + ((((unsigned __int16)(*(short *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF800u) >> 9)) << 11) | *(unsigned int *)LODWORD(v19) & 0x7FF) & 0x7C0u) >> 4)) << 6) | (*(int *)((char *)v20 + ((((*(int *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF800u) >> 9)) << 11) | (*(int *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF8000000u) >> 25)) << 27) | *(unsigned int *)LODWORD(v19) & 0x7FF07FF) & 0x7C00000u) >> 20)) << 22) | ((*(int *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF800u) >> 9)) << 11) | (*(int *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF8000000u) >> 25)) << 27) | *(unsigned int *)LODWORD(v19) & 0x7FF07FF) & 0xF81FF81F) & 0xFFE0FFE0); + *(unsigned int *)LODWORD(v19) = result; + LODWORD(v19) += 4; + --v22; + } + while ( v22 ); + LODWORD(v19) += v37; + v21 = v31 - 1; + } + while ( v31 != 1 ); + } + else + { + v24 = sr_4268E3_smthn_to_a1r5g5b5(this_); + v25 = (65536 - LODWORD(a3)) * (v24 & 0x1F); + this_ = (((65536 - LODWORD(a3)) * (v24 & 0x7C00) & 0x7C000000 | v25 & 0x1F0000 | (65536 - LODWORD(a3)) + * (v24 & 0x3E0) & 0x3E00000u) >> 16 << 16) | (((65536 - LODWORD(a3)) * (v24 & 0x7C00) & 0x7C000000 | v25 & 0x1F0000 | (65536 - LODWORD(a3)) * (v24 & 0x3E0) & 0x3E00000u) >> 16); + v26 = v40; + v27 = (char *)off_4EFDB0; + v28 = HIDWORD(v39); + do + { + v29 = v38; + v32 = v28; + do + { + v30 = 32 + * *(int *)&v27[(((unsigned __int16)(*(short *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C00u) >> 8] << 10) | *(unsigned int *)LODWORD(v26) & 0x3FF) & 0x3E0u) >> 3] | (*(int *)&v27[(((*(int *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C00u) >> 8] << 10) | (*(int *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C000000u) >> 24] << 26) | *(unsigned int *)LODWORD(v26) & 0x3FF03FF) & 0x3E00000u) >> 19] << 21) | ((*(int *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C00u) >> 8] << 10) | (*(int *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C000000u) >> 24] << 26) | *(unsigned int *)LODWORD(v26) & 0x3FF03FF) & 0x7C1F7C1F; + result = this_ + + (*(int *)&v27[4 + * (((unsigned __int8)(32 + * v27[(((unsigned __int16)(*(short *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C00u) >> 8] << 10) | *(unsigned int *)LODWORD(v26) & 0x3FF) & 0x3E0u) >> 3]) | *(unsigned int *)LODWORD(v26) & 0x1F) & 0x1F)] | (*(int *)&v27[(v30 & 0x1F0000u) >> 14] << 16) | (32 * *(int *)&v27[(((unsigned __int16)(*(short *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C00u) >> 8] << 10) | *(unsigned int *)LODWORD(v26) & 0x3FF) & 0x3E0u) >> 3] | (*(int *)&v27[(((*(int *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C00u) >> 8] << 10) | (*(int *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C000000u) >> 24] << 26) | *(unsigned int *)LODWORD(v26) & 0x3FF03FF) & 0x3E00000u) >> 19] << 21) | ((*(int *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C00u) >> 8] << 10) | (*(int *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C000000u) >> 24] << 26) | *(unsigned int *)LODWORD(v26) & 0x3FF03FF) & 0x7C1F7C1F) & 0xFFE0FFE0); + *(unsigned int *)LODWORD(v26) = result; + LODWORD(v26) += 4; + --v29; + } + while ( v29 ); + LODWORD(v26) += v37; + v28 = v32 - 1; + } + while ( v32 != 1 ); + } + }*/ +} + +//----- (004A5B81) -------------------------------------------------------- +void Render::SetTextureClipRect(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW) +{ + this->bClip = 1; + this->uClipX = uX; + this->uClipY = uY; + this->uClipZ = uZ; + this->uClipW = uW; +} + +//----- (004A5BB6) -------------------------------------------------------- +void Render::ResetTextureClipRect() +{ + this->bClip = 1; + this->uClipX = 0; + this->uClipY = 0; + this->uClipZ = window->GetWidth(); + this->uClipW = 480; +} + +unsigned __int32 Color32(unsigned __int16 color16) +{ + unsigned __int32 c = color16; + unsigned int b = (c & 31) * 8; + unsigned int g = ((c >> 5) & 63) * 4; + unsigned int r = ((c >> 11) & 31) * 8; + + return (r << 16) | (g << 8) | b;// +} + +//----- (0040DEF3) -------------------------------------------------------- +unsigned __int16 Color16(unsigned __int32 r, unsigned __int32 g, unsigned __int32 b) +{ + //return ((unsigned int)b >> (8 - LOBYTE(pRenderer->uTargetBBits))) | pRenderer->uTargetGMask & (g << (LOBYTE(pRenderer->uTargetGBits) + + // LOBYTE(pRenderer->uTargetBBits) - 8)) | pRenderer->uTargetRMask & (r << (LOBYTE(pRenderer->uTargetGBits) + + // LOBYTE(pRenderer->uTargetRBits) + LOBYTE(pRenderer->uTargetBBits) - 8)); + return (b >> (8 - 5)) | + 0x7E0 & (g << (6 + 5 - 8)) | + 0xF800 & (r << (6 + 5 + 5 - 8)); +} + + +//----- (004A5BE3) -------------------------------------------------------- +void Render::DrawTextureRGB(unsigned int uOutX, unsigned int uOutY, RGBTexture *a4) +{ + int v4; // edi@3 + unsigned __int16 *v6; // esi@3 + unsigned int v8; // eax@5 + unsigned int v9; // ebx@5 + unsigned int v11; // eax@7 + unsigned int v12; // ebx@8 + unsigned int v15; // eax@14 + int v19; // [sp+10h] [bp-8h]@3 + int v23; // [sp+28h] [bp+10h]@3 + + if ( this->uNumSceneBegins && a4 ) + { + v4 = a4->uWidth; + //v5 = &this->pTargetSurface[uOutX + uOutY * this->uTargetSurfacePitch]; + v6 = a4->pPixels; + v23 = a4->uHeight; + v19 = v4; + if ( this->bClip ) + { + if ( (signed int)uOutX < (signed int)this->uClipX ) + { + v8 = this->uClipX - uOutX; + v9 = uOutX - this->uClipX; + v8 *= 2; + v4 += v9; + v6 = (unsigned __int16 *)((char *)v6 + v8); + //v5 = (unsigned __int16 *)((char *)v5 + v8); + } + if ( (signed int)uOutY < (signed int)this->uClipY ) + { + v11 = this->uClipY - uOutY; + v6 += v19 * v11; + v23 += uOutY - this->uClipY; + //v5 += this->uTargetSurfacePitch * v11; + } + v12 = max(this->uClipX, uOutX); + if ( (signed int)(v4 + v12) > (signed int)this->uClipZ ) + { + v4 = this->uClipZ - max(this->uClipX, uOutX); + } + v15 = max(this->uClipY, uOutY); + if ( (signed int)(v15 + v23) > (signed int)this->uClipW ) + { + v23 = this->uClipW - max(this->uClipY, uOutY); + } + } + + for (int y = 0; y < v23; y++) + { + for (int x = 0; x < v4; x++) + { + WritePixel16(uOutX + x, uOutY + y, *v6); + //*v5 = *v6; + //++v5; + ++v6; + } + v6 += v19 - v4; + //v5 += this->uTargetSurfacePitch - v4; + } + } +} + +//----- (004A5D33) -------------------------------------------------------- +void Render::CreditsTextureScroll(unsigned int pX, unsigned int pY, int move_X, int move_Y, RGBTexture *pTexture) +{ + //unsigned __int16 *v7; // ebx@3 + int full_width; // ecx@3 + int full_height; // edi@3 + //int v23; // edi@23 + unsigned __int16 *pTexturea; // [sp+28h] [bp+18h]@3 + + if ( this->uNumSceneBegins && pTexture ) + { + /*auto v7 = this->pTargetSurface; + if (FORCE_16_BITS) + v7 = (unsigned __int32 *)((char *)v7 + (pX + pY * this->uTargetSurfacePitch) * 2); + else + v7 = (unsigned __int32 *)((char *)v7 + (pX + pY * this->uTargetSurfacePitch) * 4);*/ + full_width = pTexture->uWidth - move_X; + full_height = pTexture->uHeight - move_Y; + pTexturea = &pTexture->pPixels[move_X + move_Y * pTexture->uWidth]; + if ( this->bClip ) + { + if ( pX < this->uClipX )//если кадр выходит за правую границу + { + pTexturea = (unsigned __int16 *)((char *)pTexturea + (2 * (this->uClipX - pX))); + full_width += pX - this->uClipX; + //v7 = (unsigned __int32 *)((char *)v7 + ((FORCE_16_BITS ? 2 : 4) * (this->uClipX - pX))); + } + if ( pY < this->uClipY )//если кадр выходит за верхнюю границу + { + pTexturea += pTexture->uWidth * (this->uClipY - pY); + full_height += pY - this->uClipY; + //v7 = (unsigned __int32 *)((char *)v7 + (FORCE_16_BITS ? 2 : 4) * this->uTargetSurfacePitch * (this->uClipY - pY)); + } + if ( this->uClipX < pX )//если правая граница окна меньше х координаты кадра + this->uClipX = pX; + if ( this->uClipY < pY )//если верхняя граница окна меньше y координаты кадра + this->uClipY = pY; + if ( (full_width + this->uClipX) > this->uClipZ )//если ширина кадра выходит за правую границу + { + if ( this->uClipX < pX ) + this->uClipX = pX; + full_width = this->uClipZ - this->uClipX; + } + if ( (full_height + this->uClipY) > this->uClipW )//если высота кадра выходит за нижнюю границу + { + if ( this->uClipY < pY ) + this->uClipY = pY; + full_height = this->uClipW - this->uClipY; + } + } + + for (int y = 0; y < full_height; ++y) + { + for (int x = 0; x < full_width; ++x) + { + if ( *pTexturea != Color16(0, 0xFFu, 0xFFu) ) + { + WritePixel16(pX + x, pY + y, *pTexturea); + /*if (FORCE_16_BITS) + *(unsigned __int16 *)v7 = *pTexturea; + else + *(unsigned __int32 *)v7 = r5g6b5_2_r8g8b8(*pTexturea);*/ + } + ++pTexturea; + //++v7; + } + //v7 += this->uTargetSurfacePitch - full_width; + pTexturea = (unsigned __int16 *)((char *)pTexturea + 2 * (pTexture->uWidth - full_width)); + } + } +} + +//----- (004A6E7E) -------------------------------------------------------- +void Render::DrawTranslucent(unsigned int a2, unsigned int a3, Texture *a4) +{ + int v5; // edx@4 + unsigned int v6; // edi@4 + unsigned int v7; // edx@5 + unsigned int v8; // edx@6 + unsigned int v9; // edx@7 + unsigned int v10; // edx@8 + unsigned int v11; // ebx@9 + unsigned int v12; // esi@11 + unsigned int v13; // edx@12 + unsigned int v14; // ebx@15 + unsigned int v15; // esi@17 + unsigned int v16; // edi@18 + int v18; // [sp+14h] [bp-Ch]@4 + int v19; // [sp+18h] [bp-8h]@4 + unsigned __int8 *v20; // [sp+1Ch] [bp-4h]@4 + + if ( this->uNumSceneBegins && a4 && a4->pPalette16 ) + { + //v4 = &this->pTargetSurface[a2 + a3 * this->uTargetSurfacePitch]; + v20 = a4->pLevelOfDetail0_prolly_alpha_mask; + v5 = a4->uTextureWidth; + v6 = a4->uTextureHeight; + v19 = a4->uTextureWidth; + v18 = a4->uTextureWidth; + int clipped_out_x = a2; + int clipped_out_y = a3; + if ( this->bClip ) + { + v7 = this->uClipX; + if ( (signed int)a2 < (signed int)v7 ) + { + v8 = v7 - a2; + v20 += v8; + v19 += a2 - this->uClipX; + //v4 += v8; + clipped_out_x = uClipX; + } + v9 = this->uClipY; + if ( (signed int)a3 < (signed int)v9 ) + { + v10 = v9 - a3; + v20 += v18 * v10; + v6 = a3 - this->uClipY + a4->uTextureHeight; + //v4 += this->uTargetSurfacePitch * v10; + clipped_out_y = uClipY; + } + v11 = this->uClipX; + v5 = v19; + if ( (signed int)v11 < (signed int)a2 ) + v11 = a2; + v12 = this->uClipZ; + if ( (signed int)(v19 + v11) > (signed int)v12 ) + { + v13 = this->uClipX; + if ( (signed int)v13 < (signed int)a2 ) + v13 = a2; + v5 = v12 - v13; + } + v14 = this->uClipY; + if ( (signed int)v14 < (signed int)a3 ) + v14 = a3; + v15 = this->uClipW; + if ( (signed int)(v6 + v14) > (signed int)v15 ) + { + v16 = this->uClipY; + if ( (signed int)v16 < (signed int)a3 ) + v16 = a3; + v6 = v15 - v16; + } + } + + for (uint y = 0; y < v6; ++y) + { + for (int x = 0; x < v5; ++x) + { + if ( *v20 ) + WritePixel16(clipped_out_x + x, clipped_out_y + y, ((unsigned int)a4->pPalette16[*v20] >> 1) & 0x7BEF); + ++v20; + } + v20 += v18 - v5; + } + + /*if ( pRenderer->uTargetGBits == 5 ) + { + if ( (signed int)v6 > 0 ) + { + v23 = v6; + do + { + if ( v5 > 0 ) + { + v21 = v5; + do + { + if ( *v20 ) + *v4 = ((unsigned int)a4->pPalette16[*v20] >> 1) & 0x3DEF; + ++v4; + ++v20; + --v21; + } + while ( v21 ); + } + v20 += v18 - v5; + v17 = v23-- == 1; + v4 += this->uTargetSurfacePitch - v5; + } + while ( !v17 ); + } + } + else + { + if ( (signed int)v6 > 0 ) + { + v24 = v6; + do + { + if ( v5 > 0 ) + { + v22 = v5; + do + { + if ( *v20 ) + *v4 = ((unsigned int)a4->pPalette16[*v20] >> 1) & 0x7BEF; + ++v4; + ++v20; + --v22; + } + while ( v22 ); + } + v20 += v18 - v5; + v17 = v24-- == 1; + v4 += this->uTargetSurfacePitch - v5; + } + while ( !v17 ); + } + }*/ + } +} + +//----- (004A6DF5) -------------------------------------------------------- +void Render::_4A6DF5(unsigned __int16 *pBitmap, unsigned int uBitmapPitch, Vec2_int_ *pBitmapXY, void *pTarget, unsigned int uTargetPitch, Vec4_int_ *a7) +{ + int width; // ecx@3 + unsigned __int16 *pixels; // ebx@4 + int height; // esi@4 + + if ( !pBitmap || !pTarget) + return; + + width = a7->z - a7->x; + height = a7->w - a7->y; + pixels = (unsigned short *)pTarget + a7->x + uTargetPitch * a7->y; + for ( int y = 0; y < height; ++y ) + { + for ( int x = 0; x < width; ++x ) + { + WritePixel16(a7->x + x, a7->y + y, *pixels); + ++pixels; + } + pixels += uTargetPitch - width; + } +} + +//----- (004A6D87) -------------------------------------------------------- +void Render::FillRectFast(unsigned int uX, unsigned int uY, unsigned int uWidth, unsigned int uHeight, unsigned int uColor16) +{ + if (!uNumSceneBegins) + return; + + unsigned __int32 twoColors = (uColor16 << 16) | uColor16; + for (uint y = 0; y < uHeight; ++y) + { + void *pDst = (char *)pTargetSurface + (FORCE_16_BITS ? 2 : 4) * (uX + (y + uY) * uTargetSurfacePitch); + + memset32(pDst, + FORCE_16_BITS ? twoColors : 0xFF000000 | Color32(uColor16), // two colors per int (16bit) or 1 (32bit) + uWidth / (FORCE_16_BITS ? 2 : 1)); // two pixels per int (16bit) or 1 (32bit) + + if (FORCE_16_BITS && uWidth & 1) // we may miss one pixel for 16bit + ((unsigned __int16 *)pTargetSurface)[uX + uWidth - 1 + (y + uY) * uTargetSurfacePitch] = uColor16; + } +} + +//----- (004A6C4F) -------------------------------------------------------- +void Render::DrawText(signed int uOutX, signed int uOutY, unsigned __int8 *pFontPixels, unsigned int uCharWidth, + unsigned int uCharHeight, unsigned __int16 *pFontPalette, + unsigned __int16 uFaceColor, unsigned __int16 uShadowColor) +{ + unsigned int v9; // edi@2 + unsigned int v10; // esi@2 + unsigned int v12; // ebx@3 + //signed int v13; // edx@5 + int v14; // edx@6 + signed int v15; // ebx@7 + //unsigned int v16; // edx@9 + signed int v17; // edi@10 + signed int v18; // ebx@13 + unsigned int v19; // edx@15 + signed int v20; // esi@16 + unsigned __int16 v22; // dx@24 + unsigned __int8 *v24; // [sp+Ch] [bp-4h]@2 + + if (!this->uNumSceneBegins) + return; + + v9 = uCharWidth; + v10 = uCharHeight; + //v11 = &this->pTargetSurface[uOutX + uOutY * this->uTargetSurfacePitch]; + v24 = pFontPixels; + + int clipped_out_x = uOutX, clipped_out_y = uOutY; + if ( this->bClip ) + { + v12 = this->uClipX; + if ( uOutX < (signed int)v12 ) + { + v24 = &pFontPixels[v12 - uOutX]; + //v11 += v12 - uOutX; + clipped_out_x = uClipX; + v9 = uCharWidth + uOutX - v12; + } + //v13 = this->uClipY; + if ( uOutY < this->uClipY ) + { + v14 = this->uClipY - uOutY; + v24 += uCharWidth * v14; + v10 = uCharHeight + uOutY - this->uClipY; + //v11 += this->uTargetSurfacePitch * v14; + clipped_out_y = uClipY; + } + v15 = this->uClipX; + if ( this->uClipX < uOutX ) + v15 = uOutX; + //v16 = this->uClipZ; + if ( (signed int)(v9 + v15) > (signed int)this->uClipZ ) + { + v17 = this->uClipX; + if ( this->uClipX < uOutX ) + v17 = uOutX; + v9 = this->uClipZ - v17; + } + v18 = this->uClipY; + if ( this->uClipY < uOutY ) + v18 = uOutY; + v19 = this->uClipW; + if ( (signed int)(v10 + v18) > (signed int)v19 ) + { + v20 = this->uClipY; + if ( this->uClipY < uOutY ) + v20 = uOutY; + v10 = v19 - v20; + } + } + + for (uint y = 0; y < v10; ++y) + { + for (uint x = 0; x < v9; ++x) + { + if (*v24) + { + v22 = uShadowColor; + if ( *v24 != 1 ) + v22 = uFaceColor; + WritePixel16(clipped_out_x + x, clipped_out_y + y, v22); + } + ++v24; + } + v24 += uCharWidth - v9; + //v23 = uOutXa-- == 1; + //v11 += this->uTargetSurfacePitch - v9; + } +} + +//----- (004A6A68) -------------------------------------------------------- +void Render::GetLeather(unsigned int a2, unsigned int a3, Texture *a4, __int16 height) +{ + Texture tex; // [sp+Ch] [bp-48h]@1 + + memcpy(&tex, a4, sizeof(tex)); + tex.uTextureHeight = a4->uTextureHeight - height; + if ( (signed __int16)tex.uTextureHeight > 0 ) + DrawTextureIndexed(a2, a3, &tex); +} + +//----- (004A6AB1) -------------------------------------------------------- +void Render::DrawTextPalette( int x, int y, unsigned char* font_pixels, int a5, unsigned int uFontHeight, unsigned __int16 *pPalette, int a8 ) + { + int v8; // edi@2 + unsigned int v9; // esi@2 + unsigned char *v11; // edx@2 + int v14; // edx@6 + signed int v15; // ebx@7 + signed int v17; // edi@10 + signed int v18; // ebx@13 + signed int v20; // esi@16 + unsigned __int16 v24; // si@35 + int v25; // [sp+Ch] [bp-4h]@2 + unsigned int v28; // [sp+20h] [bp+10h]@30 + + int a2 = x; + int a3 = y; + uint a6 = uFontHeight; + if (!this->uNumSceneBegins) + return; + + v8 = a5; + v9 = a6; + //v10 = &pTargetSurface[x + y * uTargetSurfacePitch]; + v11 = (unsigned char *)font_pixels; + v25 = (int)font_pixels; + int clipped_out_x = x; + int clipped_out_y = y; + if ( this->bClip ) + { + if ( a2 < (signed int)this->uClipX ) + { + v25 = this->uClipX - a2 + (int)font_pixels; + //v10 += v12 - a2; + v8 = a5 + a2 - this->uClipX; + clipped_out_x = uClipX; + } + if ( a3 < this->uClipY ) + { + v14 = this->uClipY - a3; + v25 += a5 * v14; + v9 = a6 + a3 - this->uClipY; + //v10 += this->uTargetSurfacePitch * v14; + clipped_out_y = uClipY; + } + v15 = this->uClipX; + if ( this->uClipX < a2 ) + v15 = a2; + if ( v8 + v15 > (signed int)this->uClipZ ) + { + v17 = this->uClipX; + if ( v17 < a2 ) + v17 = a2; + v8 = this->uClipZ - v17; + } + v18 = this->uClipY; + if ( this->uClipY < a3 ) + v18 = a3; + if ( (signed int)(v9 + v18) > (signed int)this->uClipW ) + { + v20 = this->uClipY; + if ( this->uClipY < a3 ) + v20 = a3; + v9 = this->uClipW - v20; + } + v11 = (unsigned char *)v25; + } + + if ( a8 ) + { + v28 = 0x7FF; // 16bit pRenderer->uTargetGMask | pRenderer->uTargetBMask; + for (uint dy = 0; dy < v9; ++dy) + { + for (int dx = 0; dx < v8; ++dx) + { + if ( *v11 ) + v24 = pPalette[*v11]; + else + v24 = v28; + WritePixel16(clipped_out_x + dx, clipped_out_y + dy, v24); + //*v10 = v24; + //++v10; + ++v11; + //--v27; + + } + v11 += a5 - v8; + } + /*if ( (signed int)v9 > 0 ) + { + v23 = a5; + v30 = v9; + do + { + if ( v8 > 0 ) + { + v27 = v8; + do + { + if ( *v11 ) + v24 = pPalette[*v11]; + else + v24 = v28; + *v10 = v24; + ++v10; + ++v11; + --v27; + } + while ( v27 ); + } + v11 += v23 - v8; + v22 = v30-- == 1; + v10 += this->uTargetSurfacePitch - v8; + } + while ( !v22 ); + }*/ + } + else + { + for (uint dy = 0; dy < v9; ++dy) + { + for (int dx = 0; dx < v8; ++dx) + { + if ( *v11 ) + WritePixel16(clipped_out_x + dx, clipped_out_y + dy, pPalette[*v11]); + //*v10 = v24; + //++v10; + ++v11; + //--v27; + } + v11 += a5 - v8; + } + + /*if ( (signed int)v9 > 0 ) + { + v21 = a5; + v29 = v9; + do + { + if ( v8 > 0 ) + { + v26 = v8; + do + { + if ( *v11 ) + *v10 = pPalette[*v11]; + ++v10; + ++v11; + --v26; + } + while ( v26 ); + } + v11 += v21 - v8; + v22 = v29-- == 1; + v10 += this->uTargetSurfacePitch - v8; + } + while ( !v22 ); + }*/ + } +} + +//----- (004A68EF) -------------------------------------------------------- +void Render::DrawTransparentGreenShade(signed int a2, signed int a3, Texture *pTexture) +{ + DrawMasked(a2, a3, pTexture, 0x07E0); +} + + +//----- (004A6776) -------------------------------------------------------- +void Render::DrawTransparentRedShade(unsigned int a2, unsigned int a3, Texture *a4) +{ + DrawMasked(a2, a3, a4, 0xF800); + /*Texture *v4; // edi@2 + unsigned int v5; // ebx@4 + unsigned __int16 *v6; // eax@4 + unsigned int v7; // edx@5 + unsigned int v8; // edx@6 + unsigned int v9; // edx@7 + unsigned int v10; // edx@8 + unsigned int v11; // edx@9 + unsigned int v12; // esi@12 + unsigned int v13; // esi@15 + unsigned int v14; // edx@17 + unsigned int v15; // esi@18 + unsigned __int8 *v16; // ebx@22 + char v17; // zf@28 + int v18; // [sp+10h] [bp-10h]@4 + unsigned __int8 *v19; // [sp+18h] [bp-8h]@4 + int v20; // [sp+1Ch] [bp-4h]@4 + int a2a; // [sp+28h] [bp+8h]@24 + unsigned int a3a; // [sp+2Ch] [bp+Ch]@22 + unsigned int a4a; // [sp+30h] [bp+10h]@11 + + if ( this->uNumSceneBegins ) + { + v4 = a4; + if ( a4 ) + { + if ( a4->pPalette16 ) + { + v5 = a4->uTextureHeight; + v6 = &this->pTargetSurface[a2 + a3 * this->uTargetSurfacePitch]; + v19 = a4->pLevelOfDetail0_prolly_alpha_mask; + v20 = a4->uTextureWidth; + v18 = a4->uTextureWidth; + if ( this->bClip ) + { + v7 = this->uClipX; + if ( (signed int)a2 < (signed int)v7 ) + { + v8 = v7 - a2; + v19 += v8; + v20 += a2 - this->uClipX; + v6 += v8; + } + v9 = this->uClipY; + v5 = a4->uTextureHeight; + if ( (signed int)a3 < (signed int)v9 ) + { + v10 = v9 - a3; + v19 += v18 * v10; + v5 = a3 - this->uClipY + a4->uTextureHeight; + v4 = a4; + v6 += this->uTargetSurfacePitch * v10; + } + v11 = this->uClipX; + if ( (signed int)v11 < (signed int)a2 ) + v11 = a2; + a4a = this->uClipZ; + if ( (signed int)(v11 + v20) > (signed int)a4a ) + { + v12 = this->uClipX; + if ( (signed int)v12 < (signed int)a2 ) + v12 = a2; + v20 = a4a - v12; + } + v13 = this->uClipY; + if ( (signed int)v13 < (signed int)a3 ) + v13 = a3; + v14 = this->uClipW; + if ( (signed int)(v5 + v13) > (signed int)v14 ) + { + v15 = this->uClipY; + if ( (signed int)v15 < (signed int)a3 ) + v15 = a3; + v5 = v14 - v15; + } + } + if ( (signed int)v5 > 0 ) + { + a3a = v5; + v16 = v19; + do + { + if ( v20 > 0 ) + { + a2a = v20; + do + { + if ( *v16 ) + *v6 = this->uTargetRMask & v4->pPalette16[*v16]; + ++v6; + ++v16; + --a2a; + } + while ( a2a ); + } + v16 += v18 - v20; + v17 = a3a-- == 1; + v6 += this->uTargetSurfacePitch - v20; + } + while ( !v17 ); + } + } + } + }*/ +} + +//----- (004A68EF) -------------------------------------------------------- +void Render::DrawMasked(signed int a2, signed int a3, Texture *pTexture, unsigned __int16 mask) +{ + unsigned int v5; // ebx@4 + int v10; // edx@8 + signed int v11; // edx@9 + signed int v12; // esi@12 + signed int v13; // esi@15 + signed int v15; // esi@18 + unsigned __int8 *v16; // ebx@22 + int v18; // [sp+10h] [bp-10h]@4 + unsigned __int8 *v19; // [sp+18h] [bp-8h]@4 + int v20; // [sp+1Ch] [bp-4h]@4 + + if (!uNumSceneBegins || !pTexture) + return; + + if ( pTexture->pPalette16 ) + { + v5 = pTexture->uTextureHeight; + //v6 = &this->pTargetSurface[a2 + a3 * this->uTargetSurfacePitch]; + v19 = pTexture->pLevelOfDetail0_prolly_alpha_mask; + v20 = pTexture->uTextureWidth; + v18 = pTexture->uTextureWidth; + int clipped_out_x = a2; + int clipped_out_y = a3; + if ( this->bClip ) + { + if ( a2 < this->uClipX ) + { + v19 += this->uClipX - a2; + v20 += a2 - this->uClipX; + clipped_out_x = uClipX; + } + v5 = pTexture->uTextureHeight; + if ( a3 < this->uClipY ) + { + v10 = this->uClipY - a3; + v19 += v18 * v10; + v5 = a3 - this->uClipY + pTexture->uTextureHeight; + clipped_out_y = uClipY; + } + v11 = this->uClipX; + if ( this->uClipX < a2 ) + v11 = a2; + if ( v11 + v20 > (signed int)this->uClipZ ) + { + v12 = this->uClipX; + if ( this->uClipX < a2 ) + v12 = a2; + v20 = this->uClipZ - v12; + } + v13 = this->uClipY; + if ( this->uClipY < a3 ) + v13 = a3; + if ( (signed int)(v5 + v13) > (signed int)this->uClipW ) + { + v15 = this->uClipY; + if ( this->uClipY < a3 ) + v15 = a3; + v5 = this->uClipW - v15; + } + } + + v16 = v19; + for (uint y = 0; y < v5; ++y) + { + for (int x = 0; x < v20; ++x) + { + if ( *v16 ) + WritePixel16(clipped_out_x + x, clipped_out_y + y, pTexture->pPalette16[*v16] & mask); + ++v16; + } + v16 += v18 - v20; + } + + /*if ( (signed int)v5 > 0 ) + { + v22 = v5; + v16 = v19; + do + { + if ( v20 > 0 ) + { + v21 = v20; + do + { + if ( *v16 ) + *v6 = this->uTargetGMask & v4->pPalette16[*v16]; + ++v6; + ++v16; + --v21; + } + while ( v21 ); + } + v16 += v18 - v20; + v17 = v22-- == 1; + v6 += this->uTargetSurfacePitch - v20; + } + while ( !v17 ); + }*/ + } +} + + +//----- (004A65CC) -------------------------------------------------------- +void Render::_4A65CC(unsigned int x, unsigned int y, Texture *a4, Texture *a5, int a6, int a7, int a8) +{ + unsigned int uHeight; // edi@6 + unsigned int v14; // edx@11 + unsigned int v16; // edx@14 + unsigned int v17; // edx@17 + unsigned int v19; // edx@20 + int v20; // eax@27 + int v21; // edx@29 + unsigned __int8 *v24; // [sp+14h] [bp-4h]@6 + int Width; // [sp+2Ch] [bp+14h]@6 + + if ( this->uNumSceneBegins && a4 && a4->pPalette16 && a5 && a5->pPalette16 ) + { + v24 = a4->pLevelOfDetail0_prolly_alpha_mask; + Width = a4->uTextureWidth; + uHeight = a4->uTextureHeight; + int clipped_out_x = x; + int clipped_out_y = y; + if ( this->bClip ) + { + if ( (signed int)x < (signed int)this->uClipX ) + { + v24 += this->uClipX - x; + Width += x - this->uClipX; + clipped_out_x = uClipX; + } + if ( (signed int)y < (signed int)this->uClipY ) + { + v24 += a4->uTextureWidth * (this->uClipY - y); + uHeight = y - this->uClipY + a4->uTextureHeight; + clipped_out_y = uClipY; + } + v14 = this->uClipX; + if ( (signed int)this->uClipX < (signed int)x ) + v14 = x; + if ( (signed int)(Width + v14) > (signed int)this->uClipZ ) + { + v16 = this->uClipX; + if ( (signed int)this->uClipX < (signed int)x ) + v16 = x; + Width = this->uClipZ - v16; + } + v17 = this->uClipY; + if ( (signed int)this->uClipY < (signed int)y ) + v17 = y; + if ( (signed int)(uHeight + v17) > (signed int)this->uClipW ) + { + v19 = this->uClipY; + if ( (signed int)this->uClipY < (signed int)y ) + v19 = y; + uHeight = this->uClipW - v19; + } + } + + for (uint dy = 0; dy < uHeight; ++dy) + { + for (int dx = 0; dx < Width; ++dx) + { + v20 = *v24; + if ( v20 >= a7 && v20 <= a8 ) + { + v21 = a7 + (a6 + v20) % (2 * (a8 - a7)); + if ( (a6 + v20) % (2 * (a8 - a7)) >= a8 - a7 ) + v21 = 2 * a8 - v21 - a7; + WritePixel16(clipped_out_x + dx, clipped_out_y + dy, a4->pPalette16[v21]); + } + ++v24; + } + v24 += a4->uTextureWidth - Width; + } + /*if ( (signed int)v9 > 0 ) + { + ya = v9; + v23 = v22 - v27; + do + { + if ( v27 > 0 ) + { + xa = v27; + do + { + v20 = *v24; + if ( v20 >= a7 && v20 <= a8 ) + { + v21 = a7 + (a6 + v20) % (2 * (a8 - a7)); + if ( (a6 + v20) % (2 * (a8 - a7)) >= a8 - a7 ) + v21 = 2 * a8 - v21 - a7; + *v8 = a4->pPalette16[v21]; + } + ++v8; + ++v24; + --xa; + } + while ( xa ); + } + v8 += this->uTargetSurfacePitch - v27; + v24 += v23; + --ya; + } + while ( ya ); + }*/ + } +} + +//----- (004A63E6) -------------------------------------------------------- +void Render::DrawAura(unsigned int a2, unsigned int a3, Texture *a4, Texture *a5, int a6, int a7, int a8) +{ + unsigned int v14; // edx@11 + unsigned int v16; // edx@14 + unsigned int v17; // edx@17 + unsigned int v19; // edx@20 + int v20; // eax@27 + int v21; // edx@29 + int Height; // [sp+10h] [bp-8h]@6 + int Width; // [sp+14h] [bp-4h]@6 + int v27; // [sp+24h] [bp+Ch]@23 + unsigned __int8 *v28; // [sp+28h] [bp+10h]@6 + + if ( this->uNumSceneBegins ) + { + if ( a4 ) + { + if ( a4->pPalette16 ) + { + if ( a5 ) + { + if ( a5->pPalette16 ) + { + v28 = a4->pLevelOfDetail0_prolly_alpha_mask; + Width = a4->uTextureWidth; + Height = a4->uTextureHeight; + int clipped_out_x = a2; + int clipped_out_y = a3; + if ( this->bClip ) + { + if ( (signed int)a2 < (signed int)this->uClipX ) + { + v28 += this->uClipX - a2; + Width += a2 - this->uClipX; + clipped_out_x = uClipX; + } + + if ( (signed int)a3 < (signed int)this->uClipY ) + { + v28 += a4->uTextureWidth * (this->uClipY - a3); + Height += a3 - this->uClipY; + clipped_out_y = uClipY; + } + + v14 = this->uClipX; + if ( (signed int)this->uClipX < (signed int)a2 ) + v14 = a2; + if ( (signed int)(Width + v14) > (signed int)this->uClipZ ) + { + v16 = this->uClipX; + if ( (signed int)this->uClipX < (signed int)a2 ) + v16 = a2; + Width = this->uClipZ - v16; + } + + v17 = this->uClipY; + if ( (signed int)this->uClipY < (signed int)a3 ) + v17 = a3; + if ( (signed int)(Height + v17) > (signed int)this->uClipW ) + { + v19 = this->uClipY; + if ( (signed int)this->uClipY < (signed int)a3 ) + v19 = a3; + Height = this->uClipW - v19; + } + } + + v27 = 0; + for (int y = 0; y < Height; ++y) + { + for (int x = 0; x < Width; ++x) + { + if ( *v28 ) + { + v20 = *(&a5->pLevelOfDetail0_prolly_alpha_mask[x & a5->uWidthMinus1] + a5->uTextureWidth * (v27 & a5->uHeightMinus1)); + if ( v20 >= a7 ) + { + if ( v20 <= a8 ) + { + v21 = a7 + (a6 + v20) % (2 * (a8 - a7)); + if ( (a6 + v20) % (2 * (a8 - a7)) >= a8 - a7 ) + v21 = 2 * a8 - v21 - a7; + //v9 = a5; + //*v10 = a5->pPalette16[v21]; + WritePixel16(clipped_out_x + x, clipped_out_y + y, a5->pPalette16[v21]); + } + } + } + v28++; + } + v28 += a4->uTextureWidth - Width; + } + + /*if ( v24 > 0 ) + { + v23 = v22 - v25; + do + { + for ( i = 0; i < v25; ++v28 ) + { + if ( *v28 ) + { + v20 = *(&v9->pLevelOfDetail0_prolly_alpha_mask[i & v9->uWidthMinus1] + v9->uTextureWidth * (v27 & v9->uHeightMinus1)); + if ( v20 >= a7 ) + { + if ( v20 <= a8 ) + { + v21 = a7 + (a6 + v20) % (2 * (a8 - a7)); + if ( (a6 + v20) % (2 * (a8 - a7)) >= a8 - a7 ) + v21 = 2 * a8 - v21 - a7; + v9 = a5; + *v10 = a5->pPalette16[v21]; + } + } + } + ++i; + ++v10; + } + ++v27; + v10 += this->uTargetSurfacePitch - v25; + v28 += v23; + } + while ( v27 < v24 ); + }*/ + + } + } + } + } + } +} + +//----- (004A6274) -------------------------------------------------------- +void Render::DrawTextureTransparent(unsigned int uX, unsigned int uY, Texture *pTexture) +{ + int uHeight; // ebx@4 + unsigned int v11; // edx@9 + unsigned int v12; // esi@12 + unsigned int v13; // esi@15 + unsigned int v15; // esi@18 + unsigned __int8 *v19; // [sp+18h] [bp-8h]@4 + int uWidth; // [sp+1Ch] [bp-4h]@4 + + if ( this->uNumSceneBegins ) + { + if ( pTexture ) + { + if ( pTexture->pPalette16 ) + { + uHeight = pTexture->uTextureHeight; + v19 = pTexture->pLevelOfDetail0_prolly_alpha_mask; + uWidth = pTexture->uTextureWidth; + + int clipped_out_x = uX; + int clipped_out_y = uY; + if ( this->bClip ) + { + if ( (signed int)uX < (signed int)this->uClipX ) + { + v19 += this->uClipX - uX; + uWidth += uX - this->uClipX; + clipped_out_x = uClipX; + } + + uHeight = pTexture->uTextureHeight; + if ( (signed int)uY < (signed int)this->uClipY ) + { + v19 += pTexture->uTextureWidth * (this->uClipY - uY); + uHeight = uY - this->uClipY + pTexture->uTextureHeight; + clipped_out_y = uClipY; + } + v11 = this->uClipX; + if ( (signed int)this->uClipX < (signed int)uX ) + v11 = uX; + + if ( (signed int)(v11 + uWidth) > (signed int)this->uClipZ ) + { + v12 = this->uClipX; + if ( (signed int)this->uClipX < (signed int)uX ) + v12 = uX; + uWidth = this->uClipZ - v12; + } + v13 = this->uClipY; + if ( (signed int)this->uClipY < (signed int)uY ) + v13 = uY; + + if ( (signed int)(uHeight + v13) > (signed int)this->uClipW ) + { + v15 = this->uClipY; + if ( (signed int)this->uClipY < (signed int)uY ) + v15 = uY; + uHeight = this->uClipW - v15; + } + } + + for (int y = 0; y < uHeight; ++y) + { + for (int x = 0; x < uWidth; ++x) + { + if ( *v19 ) + WritePixel16(clipped_out_x + x, clipped_out_y + y, pTexture->pPalette16[*v19]); + ++v19; + } + v19 += pTexture->uTextureWidth - uWidth; + } + /*if ( (signed int)uHeight > 0 ) + { + uYa = uHeight; + v16 = v19; + do + { + if ( uWidth > 0 ) + { + uXa = uWidth; + do + { + if ( *v16 ) + *v6 = pCurrentTexture->pPalette16[*v16]; + ++v6; + ++v16; + } + while ( uXa-- !=1 ); + } + v16 += v18 - uWidth; + uFlag = uYa-- == 1; + v6 += this->uTargetSurfacePitch - uWidth; + } + while ( !uFlag ); + }*/ + } + } + } +} + +//----- (004A612A) -------------------------------------------------------- +void Render::DrawMaskToZBuffer(signed int uOutX, unsigned int uOutY, Texture *pTexture, int zVal) +{ + unsigned int v6; // edx@3 + int v7; // ebx@3 + int v8; // edi@3 + int v10; // eax@5 + signed int v12; // esi@8 + signed int v14; // esi@11 + unsigned int v15; // esi@14 + unsigned int v17; // ecx@17 + int v18; // edx@23 + int v19; // [sp+Ch] [bp-Ch]@3 + int v20; // [sp+10h] [bp-8h]@3 + int uOutXa; // [sp+20h] [bp+8h]@21 + unsigned __int8 *uOutYa; // [sp+24h] [bp+Ch]@3 + int *pZBuffer; // [sp+28h] [bp+10h]@3 + + if ( this->uNumSceneBegins ) + { + if ( pTexture ) + { + v6 = uOutY; + v7 = pTexture->uTextureHeight; + pZBuffer = &this->pActiveZBuffer[uOutX + window->GetWidth() * uOutY]; + uOutYa = pTexture->pLevelOfDetail0_prolly_alpha_mask; + v8 = pTexture->uTextureWidth; + v20 = pTexture->uTextureWidth; + v19 = pTexture->uTextureWidth; + if ( this->bClip ) + { + if ( uOutX < this->uClipX ) + { + v10 = this->uClipX - uOutX; + uOutYa += v10; + v8 += uOutX - this->uClipX; + v20 = v8; + pZBuffer += v10; + } + if ( (signed int)v6 < (signed int)this->uClipY ) + { + uOutYa += v19 * (this->uClipY - v6); + v7 += v6 - this->uClipY; + pZBuffer += window->GetWidth() * (this->uClipY - v6); + v8 = v20; + } + v12 = this->uClipX; + if ( this->uClipX < uOutX ) + v12 = uOutX; + if ( v8 + v12 > (signed int)this->uClipZ ) + { + v14 = this->uClipX; + if ( this->uClipX < uOutX ) + v14 = uOutX; + v8 = this->uClipZ - v14; + } + v15 = this->uClipY; + if ( (signed int)this->uClipY < (signed int)v6 ) + v15 = v6; + if ( (signed int)(v7 + v15) > (signed int)this->uClipW ) + { + v17 = this->uClipY; + if ( (signed int)this->uClipY >= (signed int)v6 ) + v6 = v17; + v7 = this->uClipW - v6; + } + } + if ( v7 > 0 ) + { + uOutXa = v7; + do + { + if ( v8 > 0 ) + { + v18 = v8; + do + { + if ( *uOutYa ) + *pZBuffer = zVal; + ++pZBuffer; + ++uOutYa; + --v18; + } + while ( v18 ); + } + pZBuffer += window->GetWidth() - v8; + uOutYa += v19 - v8; + --uOutXa; + } + while ( uOutXa ); + } + } + } +} + +//----- (004A601E) -------------------------------------------------------- +void Render::ZBuffer_Fill_2(signed int a2, signed int a3, Texture *pTexture, int a5) +{ + signed int v5; // edx@3 + int v6; // ebx@3 + int v7; // esi@3 + void *v8; // esi@3 + signed int v11; // edi@8 + signed int v13; // edi@11 + unsigned int v14; // edi@14 + unsigned int v16; // ecx@17 + int v17; // [sp+18h] [bp+Ch]@3 + unsigned int pTexturea; // [sp+1Ch] [bp+10h]@3 + + if ( this->uNumSceneBegins && pTexture ) + { + v5 = a3; + v6 = pTexture->uTextureHeight; + v7 = 5 * a3; + v17 = pTexture->uTextureHeight; + v8 = &this->pActiveZBuffer[a2 + (v7 << 7)]; + pTexturea = pTexture->uTextureWidth; + if ( this->bClip ) + { + if ( a2 < (signed int)this->uClipX ) + { + pTexturea += a2 - this->uClipX; + v8 = (char *)v8 + 4 * (this->uClipX - a2); + } + if ( v5 < (signed int)this->uClipY ) + { + v17 += v5 - this->uClipY; + v8 = (char *)v8 + 2560 * (this->uClipY - v5); + } + v11 = this->uClipX; + if ( this->uClipX < a2 ) + v11 = a2; + if ( (signed int)(pTexturea + v11) > (signed int)this->uClipZ ) + { + v13 = this->uClipX; + if ( this->uClipX < a2 ) + v13 = a2; + pTexturea = this->uClipZ - v13; + } + v14 = this->uClipY; + if ( (signed int)this->uClipY < v5 ) + v14 = v5; + v6 = v17; + if ( (signed int)(v17 + v14) > (signed int)this->uClipW ) + { + v16 = this->uClipY; + if ( (signed int)this->uClipY < v5 ) + v16 = v5; + v6 = this->uClipW - v16; + } + } + if ( v6 > 0 ) + { + do + { + if ( (signed int)pTexturea > 0 ) + { + memset32(v8, a5, pTexturea); + v8 = (char *)v8 + 4 * pTexturea; + } + v8 = (char *)v8 + 4 * (window->GetWidth() - pTexturea); + --v6; + } + while ( v6 ); + } + } +} + +//----- (004A5EB2) -------------------------------------------------------- +void Render::DrawTextureIndexed(unsigned int uX, unsigned int uY, Texture *a4) +{ + int v5; // ebx@4 + unsigned int v8; // edx@6 + unsigned int v10; // edx@8 + unsigned int v11; // edx@9 + unsigned int v12; // esi@12 + unsigned int v13; // esi@15 + unsigned int v15; // esi@18 + int v18; // [sp+10h] [bp-10h]@4 + unsigned __int8 *v19; // [sp+18h] [bp-8h]@4 + int v20; // [sp+1Ch] [bp-4h]@4 + + if ( this->uNumSceneBegins ) + { + if ( a4 ) + { + if ( a4->pPalette16 ) + { + v5 = a4->uTextureHeight; + //pTarget = &this->pTargetSurface[uX + uY * this->uTargetSurfacePitch]; + v19 = a4->pLevelOfDetail0_prolly_alpha_mask; + v20 = a4->uTextureWidth; + v18 = a4->uTextureWidth; + + int clipped_out_x = uX; + int clipped_out_y = uY; + if ( this->bClip ) + { + if ( (signed int)uX < (signed int)this->uClipX ) + { + v8 = this->uClipX - uX; + v19 += v8; + v20 += uX - this->uClipX; + clipped_out_x = uClipX; + } + + v5 = a4->uTextureHeight; + if ( (signed int)uY < (signed int)this->uClipY ) + { + v10 = this->uClipY - uY; + v19 += v18 * v10; + v5 = uY - this->uClipY + a4->uTextureHeight; + //v4 = a4; + clipped_out_y = uClipY; + } + + v11 = this->uClipX; + if ( (signed int)this->uClipX < (signed int)uX ) + v11 = uX; + + if ( (signed int)(v11 + v20) > (signed int)this->uClipZ ) + { + v12 = this->uClipX; + if ( (signed int)this->uClipX < (signed int)uX ) + v12 = uX; + v20 = this->uClipZ - v12; + } + + v13 = this->uClipY; + if ( (signed int)this->uClipY < (signed int)uY ) + v13 = uY; + + if ( (signed int)(v5 + v13) > (signed int)uClipW ) + { + v15 = this->uClipY; + if ( (signed int)this->uClipY < (signed int)uY ) + v15 = uY; + v5 = uClipW - v15; + } + } + + for (int y = 0; y < v5; ++y) + { + for (int x = 0; x < v20; ++x) + { + if ( a4->pPalette16[*v19] != 0x7FF )// 2047 + WritePixel16(clipped_out_x + x, clipped_out_y + y, a4->pPalette16[*v19]); + ++v19; + } + v19 += v18 - v20; + } + /*if ( (signed int)v5 > 0 ) + { + uYa = v5; + v16 = v19; + do + { + if ( v20 > 0 ) + { + uXa = v20; + do + { + *pTarget = v4->pPalette16[*v16]; + ++pTarget; + ++v16; + --uXa; + } + while ( uXa ); + } + v16 += v18 - v20; + v17 = uYa-- == 1; + pTarget += this->uTargetSurfacePitch - v20; + } + while ( !v17 ); + }*/ + } + } + } +} + +//----- (004667E9) -------------------------------------------------------- +void Render::ChangeBetweenWinFullscreenModes() +{ + float v0; // ST14_4@17 + int v4; // edx@26 + ObjectDesc *v5; // eax@26 + RGBTexture *v6; // esi@33 + const char *v8; // [sp-4h] [bp-28h]@33 +// struct tagRECT Rect; // [sp+14h] [bp-10h]@15 + + /*if ( !pRenderer->bWindowMode && (dword_6BE364_game_settings_1 & 2) ) + { + ModalWindow(pGlobalTXT_LocalizationStrings[62], UIMSG_0);// "Might and Magic VII requires your desktop to be in 16bit (32k or 65k) Color mode in order to operate in a window." + return; + }*/ + if ( bWindowMode || pRenderD3D->pAvailableDevices->bIsDeviceCompatible ) + { + if ( pEventTimer->bPaused ) + dword_6BE364_game_settings_1 |= GAME_SETTINGS_0800; + else + pEventTimer->Pause(); + if ( pMiscTimer->bPaused ) + dword_6BE364_game_settings_1 |= GAME_SETTINGS_1000; + else + pMiscTimer->Pause(); + pMouse->bActive = 0; + if ( pRenderD3D ) + { + pBitmaps_LOD->ReleaseHardwareTextures(); + pSprites_LOD->ReleaseAll(); + } + if ( bWindowMode ) + { + //SetMenu(hWnd, 0); + //SetWindowLongA(hWnd, -20, 0); + //SetWindowLongA(hWnd, -16, 0x10000000u); + window->SetFullscreenMode(); + pRenderer->InitializeFullscreen(); + v0 = (double)(signed int)uGammaPos * 0.1 + 0.6; + pGame->pGammaController->Initialize(v0); + } + else + { + //ClipCursor(0); + window->SetWindowedMode(window->GetWidth(), window->GetHeight()); + pRenderer->SwitchToWindow(); + } + if ( pRenderD3D ) + { + pBitmaps_LOD->_410423_move_textures_to_device(); + pSprites_LOD->MoveSpritesToVideoMemory(); + } + if (!( pPaletteManager->uNumTargetBBits == uTargetBBits + && pPaletteManager->uNumTargetGBits == uTargetGBits + && pPaletteManager->uNumTargetRBits == uTargetRBits )) + { + pPaletteManager->SetColorChannelInfo(uTargetRBits, uTargetGBits, uTargetBBits); + pPaletteManager->RecalculateAll(); + pBitmaps_LOD->SetupPalettes(uTargetRBits, uTargetGBits, uTargetBBits); + pIcons_LOD->SetupPalettes(uTargetRBits, uTargetGBits, uTargetBBits); + for (uint i = 0; i < pObjectList->uNumObjects; i++) + { + BYTE3(v4) = 0; + v5 = &pObjectList->pObjects[i]; + *(short *)((char *)&v4 + 1) = v5->uParticleTrailColorR; + LOBYTE(v4) = v5->uParticleTrailColorG; + v5->uParticleTrailColor = v5->uParticleTrailColorB | (v4 << 8); + } + SetUserInterface(pParty->alignment, true); + if ( pMediaPlayer->pVideoFrame.pPixels ) + pMediaPlayer->pVideoFrame.Load(pMediaPlayer->pVideoFrameTextureFilename, 1); + if ( sCurrentMenuID != MENU_CREATEPARTY ) + { + if ( sCurrentMenuID == MENU_CREDITSPROC ) + dword_A74C88 = 1; + } + else + { + if ( sCurrentMenuID ) + { + v6 = &pTexture_PCX; + pTexture_PCX.Release(); + v8 = "makeme.pcx"; + } + else + { + v6 = &pTexture_PCX; + pTexture_PCX.Release(); + v8 = "title.pcx"; + if ( sCurrentMenuID ) + v8 = "lsave640.pcx"; + } + v6->Load(v8, 0); + } + } + viewparams->bRedrawGameUI = 1; + viewparams->InitGrayPalette(); + pMouse->SetCurrentCursorBitmap(); + /*if ( pRenderer->bWindowMode ) + { + //MoveWindow(hWnd, uWindowX, uWindowY, uWindowWidth, uWindowHeight, 0); + CenterWindowAndAdjustSize(hWnd, windowed_mode_width, windowed_mode_height); + ShowWindow(hWnd, SW_SHOWNORMAL); + }*/ + pMouse->bActive = true; + if ( pMovie_Track ) + pMediaPlayer->SelectMovieType(); + if (dword_6BE364_game_settings_1 & GAME_SETTINGS_0800) + dword_6BE364_game_settings_1 &= ~GAME_SETTINGS_0800; + else + pEventTimer->Resume(); + if (dword_6BE364_game_settings_1 & GAME_SETTINGS_1000) + dword_6BE364_game_settings_1 &= ~GAME_SETTINGS_1000; + else + pMiscTimer->Resume(); + } +} + + +//----- (004524D8) -------------------------------------------------------- +HWLTexture *RenderHWLContainer::LoadTexture(const char *pName, int bMipMaps) +{ + void *v13; // eax@13 + int v16; // esi@14 + int v17; // ecx@16 + int v18; // esi@16 + unsigned __int16 *v19; // eax@16 + int v20; // edx@16 + int v21; // ecx@16 + int v22; // eax@16 + int v23; // esi@16 + unsigned __int16 *v26; // [sp+24h] [bp-10h]@13 + int v27; // [sp+28h] [bp-Ch]@14 + int v28; // [sp+2Ch] [bp-8h]@13 + int pDestb; // [sp+3Ch] [bp+8h]@15 + + if (!uNumItems) + return nullptr; + + /////////////////////////////// + //quick search(быстрый поиск)// + /////////////////////////////// + uint idx1 = 0, + idx2 = uNumItems; + while (true) + { + uint i = idx1 + (idx2 - idx1) / 2; + + int res = _stricmp(pName, pSpriteNames[i]); + if (!res) + { + fseek(pFile, pSpriteOffsets[i], SEEK_SET); + break; + } + else if (res < 0) + idx2 = idx1 + (idx2 - idx1) / 2; + else + idx1 = i + 1; + + if ( idx1 >= idx2 ) + return false; + } + + uint uCompressedSize = 0; + fread(&uCompressedSize, 4, 1, pFile); + + HWLTexture* pTex = new HWLTexture; + fread(&pTex->uBufferWidth, 4, 1, pFile); + fread(&pTex->uBufferHeight, 4, 1, pFile); + fread(&pTex->uAreaWidth, 4, 1, pFile); + fread(&pTex->uAreaHeigth, 4, 1, pFile); + fread(&pTex->uWidth, 4, 1, pFile); + fread(&pTex->uHeight, 4, 1, pFile); + fread(&pTex->uAreaX, 4, 1, pFile); + fread(&pTex->uAreaY, 4, 1, pFile); + + pTex->pPixels = new unsigned __int16[pTex->uWidth * pTex->uHeight]; + if (uCompressedSize) + { + char* pCompressedData = new char[uCompressedSize]; + fread(pCompressedData, 1, uCompressedSize, pFile); + uint uDecompressedSize = pTex->uWidth * pTex->uHeight * sizeof(short); + zlib::MemUnzip(pTex->pPixels, &uDecompressedSize, pCompressedData, uCompressedSize); + delete [] pCompressedData; + } + else + fread(pTex->pPixels, 2, pTex->uWidth * pTex->uHeight, pFile); + + if ( scale_hwls_to_half ) + { + __debugbreak();//Ritor1 + pTex->uHeight /= 2; + pTex->uWidth /= 2; + v13 = new unsigned __int16[pTex->uWidth * pTex->uHeight]; + v28 = 0; + v26 = (unsigned __int16 *)v13; + if ( pTex->uHeight > 0 ) + { + v16 = pTex->uWidth; + v27 = 1; + do + { + pDestb = 0; + if ( v16 > 0 ) + { + do + { + v17 = v16 * v27; + v18 = v28 * v16; + v19 = pTex->pPixels; + v20 = pDestb + 2 * v18; + v21 = (int)&v19[2 * (pDestb + v17)]; + v22 = (int)&v19[2 * v20]; + LOWORD(v20) = *(unsigned short *)(v21 + 2); + LOWORD(v21) = *(unsigned short *)v21; + v23 = pDestb + v18; + pDestb++; + + v26[v23] = _452442_color_cvt(*(unsigned short *)v22, *(unsigned short *)(v22 + 2), v21, v20); + v16 = pTex->uWidth; + } + while (pDestb < pTex->uWidth); + } + ++v28; + v27 += 2; + } + while ( v28 < (signed int)pTex->uHeight ); + } + delete [] pTex->pPixels; + pTex->pPixels = v26; + } + return pTex; +} +//----- (0045271F) -------------------------------------------------------- +bool RenderHWLContainer::Release() +{ + __int32 v4; // eax@6 + FILE *v5; // ST24_4@6 + FILE *File; // [sp+4h] [bp-4h]@6 + + if ( this->bDumpDebug) + { + File = fopen("logd3d.txt", "w"); + v4 = ftell(this->pFile); + v5 = this->pFile; + this->uDataOffset = v4; + fwrite(&this->uNumItems, 4u, 1u, v5); + for (uint i = 0; i < this->uNumItems; i++) + { + fwrite(this->pSpriteNames[i], 1u, 0x14u, this->pFile); + fprintf(File, "D3D texture name: %s\t\toffset: %x\n", this->pSpriteNames[i], *(unsigned int *)(&(this->pSpriteNames[i]) + 200000/sizeof(char*))); + } + fwrite(this->pSpriteOffsets, 4u, this->uNumItems, this->pFile); + fseek(this->pFile, 4, 0); + fwrite(&this->uDataOffset, 4u, 1u, this->pFile); + fclose(this->pFile); + fclose(File); + } + else + { + fclose(this->pFile); + for (uint i = 0; i < this->uNumItems; i++) + { + delete[] this->pSpriteNames[i]; + } + } + return true; +} + +//----- (00452347) -------------------------------------------------------- +RenderHWLContainer::RenderHWLContainer(): + bDumpDebug(false) +{ + this->pFile = 0; + uSignature = 0; + this->uDataOffset = 0; + memset(&this->uNumItems, 0, 0x61A84u); + this->uNumItems = 0; + this->scale_hwls_to_half = false; +} + +//----- (0045237F) -------------------------------------------------------- +bool RenderHWLContainer::Load(const wchar_t *pFilename) +{ + pFile = _wfopen(pFilename, L"rb"); + if (!pFile) + { + Log::Warning(L"Failed to open file: %s", pFilename); + return false; + } + + fread(&uSignature, 1, 4, pFile); + if (uSignature != 'TD3D') + { + Log::Warning(L"Invalid format: %s", pFilename); + return false; + } + + fread(&uDataOffset, 4, 1, pFile); + fseek(pFile, uDataOffset, SEEK_SET); + fread(&uNumItems, 4, 1, pFile); + + memset(pSpriteNames, 0, 50000 * sizeof(char *)); + for (uint i = 0; i < uNumItems; ++i) + { + pSpriteNames[i] = new char[20]; + fread(pSpriteNames[i], 1, 20, pFile); + } + fread(pSpriteOffsets, 4, uNumItems, pFile); + + return true; +} + +//----- (004A1C1E) -------------------------------------------------------- +void Render::DoRenderBillboards_D3D() +{ + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE)); + + /*if (pRenderer->uNumBillboardsToDraw) + { + auto p = &pRenderer->pBillboardRenderListD3D[0]; + for (int i = 0; i < p->uNumVertices; ++i) + { + p->pQuads[i].pos.z -= p->pQuads[i].pos.z * 0.6; + //p->pQuads[i].rhw = + 0.8 * (1.0f - p->pQuads[i].rhw); + } + p->pQuads[0].pos.x = 10; + p->pQuads[0].pos.y = 10; + + p->pQuads[1].pos.x = 10; + p->pQuads[1].pos.y = 200; + + p->pQuads[2].pos.x = 100; + p->pQuads[2].pos.y = 200; + + p->pQuads[3].pos.x = 100; + p->pQuads[3].pos.y = 10; + + if (p->uOpacity != RenderBillboardD3D::NoBlend) + SetBillboardBlendOptions(p->uOpacity); + + pRenderer->pRenderD3D->pDevice->SetTexture(0, p->pTexture); + ErrD3D(pRenderer->pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + p->pQuads, p->uNumVertices, + D3DDP_DONOTLIGHT | D3DDP_DONOTUPDATEEXTENTS)); + + }*/ + + for (int i = uNumBillboardsToDraw - 1; i >= 0; --i) + { + if (pBillboardRenderListD3D[i].opacity != RenderBillboardD3D::NoBlend) + SetBillboardBlendOptions(pBillboardRenderListD3D[i].opacity); + + pRenderD3D->pDevice->SetTexture(0, pBillboardRenderListD3D[i].pTexture); + ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + pBillboardRenderListD3D[i].pQuads, pBillboardRenderListD3D[i].uNumVertices, + D3DDP_DONOTLIGHT | D3DDP_DONOTUPDATEEXTENTS)); + } + + if (bFogEnabled) + { + bFogEnabled = false; + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, GetLevelFogColor() & 0xFFFFFF)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, 0)); + } + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CW)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE)); +} + +//----- (004A1DA8) -------------------------------------------------------- +void Render::SetBillboardBlendOptions(RenderBillboardD3D::OpacityType a1) +{ + switch (a1) + { + case RenderBillboardD3D::Transparent: + { + if (bFogEnabled) + { + bFogEnabled = false; + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, GetLevelFogColor() & 0xFFFFFF)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, 0)); + } + + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE)); + } + break; + + case RenderBillboardD3D::Opaque_1: + case RenderBillboardD3D::Opaque_2: + case RenderBillboardD3D::Opaque_3: + { + if (bUsingSpecular) + { + if (!bFogEnabled) + { + bFogEnabled = true; + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE)); + } + } + + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, FALSE)); + } + break; + + default: + Log::Warning(L"SetBillboardBlendOptions: invalid opacity type (%u)", a1); + assert(false); + break; + } +} +//----- (00424CD7) -------------------------------------------------------- +int ODM_NearClip(unsigned int num_vertices) +{ + bool current_vertices_flag; // edi@1 + bool next_vertices_flag; // [sp+Ch] [bp-24h]@6 + double t; // st6@10 + bool bFound; + + bFound = false; + + if (!num_vertices) + return 0; + for (uint i = 0; i < num_vertices; ++i)// есть ли пограничные вершины + { + if ( array_50AC10[i].vWorldViewPosition.x > 8.0 ) + { + bFound = true; + break; + } + } + if ( !bFound ) + return 0; + + memcpy(&array_50AC10[num_vertices], &array_50AC10[0], sizeof(array_50AC10[0])); + current_vertices_flag = false; + next_vertices_flag = false; + if ( array_50AC10[0].vWorldViewPosition.x <= 8.0 ) + current_vertices_flag = true; + //check for near clip plane(проверка по ближней границе) + // + // v3.__________________. v0 + // | | + // | | + // | | + // ----------------------- 8.0(near_clip - 8.0) + // | | + // .__________________. + // v2 v1 + + int out_num_vertices = 0; + for (uint i = 0; i < num_vertices; ++i) + { + next_vertices_flag = array_50AC10[i + 1].vWorldViewPosition.x <= 8.0;// + if ( current_vertices_flag ^ next_vertices_flag ) + { + if ( next_vertices_flag )//следующая вершина за ближней границей + { + //t = near_clip - v0.x / v1.x - v0.x (формула получения точки пересечения отрезка с плоскостью) + t = (8.0 - array_50AC10[i].vWorldViewPosition.x) / (array_50AC10[i + 1].vWorldViewPosition.x - array_50AC10[i].vWorldViewPosition.x); + array_507D30[out_num_vertices].vWorldViewPosition.x = 8.0; + array_507D30[out_num_vertices].vWorldViewPosition.y = array_50AC10[i].vWorldViewPosition.y + (array_50AC10[i + 1].vWorldViewPosition.y - array_50AC10[i].vWorldViewPosition.y) * t; + array_507D30[out_num_vertices].vWorldViewPosition.z = array_50AC10[i].vWorldViewPosition.z + (array_50AC10[i + 1].vWorldViewPosition.z - array_50AC10[i].vWorldViewPosition.z) * t; + array_507D30[out_num_vertices].u = array_50AC10[i].u + (array_50AC10[i + 1].u - array_50AC10[i].u) * t; + array_507D30[out_num_vertices].v = array_50AC10[i].v + (array_50AC10[i + 1].v - array_50AC10[i].v) * t; + array_507D30[out_num_vertices]._rhw = 1.0 / 8.0; + } + else// текущая вершина за ближней границей + { + t = (8.0 - array_50AC10[i].vWorldViewPosition.x) / (array_50AC10[i].vWorldViewPosition.x - array_50AC10[i + 1].vWorldViewPosition.x); + array_507D30[out_num_vertices].vWorldViewPosition.x = 8.0; + array_507D30[out_num_vertices].vWorldViewPosition.y = array_50AC10[i].vWorldViewPosition.y + (array_50AC10[i].vWorldViewPosition.y - array_50AC10[i + 1].vWorldViewPosition.y) * t; + array_507D30[out_num_vertices].vWorldViewPosition.z = array_50AC10[i].vWorldViewPosition.z + (array_50AC10[i].vWorldViewPosition.z - array_50AC10[i + 1].vWorldViewPosition.z) * t; + array_507D30[out_num_vertices].u = array_50AC10[i].u + (array_50AC10[i].u - array_50AC10[i + 1].u) * t; + array_507D30[out_num_vertices].v = array_50AC10[i].v + (array_50AC10[i].v - array_50AC10[i + 1].v) * t; + array_507D30[out_num_vertices]._rhw = 1.0 / 8.0; + } + //array_507D30[out_num_vertices]._rhw = 0x3E000000u; + ++out_num_vertices; + } + if ( !next_vertices_flag ) + { + memcpy(&array_507D30[out_num_vertices], &array_50AC10[i + 1], sizeof(array_50AC10[i + 1])); + out_num_vertices++; + } + current_vertices_flag = next_vertices_flag; + } + return out_num_vertices >= 3 ? out_num_vertices : 0; +} + +//----- (00424EE0) -------------------------------------------------------- +int ODM_FarClip(unsigned int uNumVertices) +{ + bool current_vertices_flag; // [sp+Ch] [bp-28h]@6 + bool next_vertices_flag; // edi@1 + double t; // st6@10 + signed int depth_num_vertices; // [sp+18h] [bp-1Ch]@1 + bool bFound; + //Доп инфо "Программирование трёхмерных игр для windows" Ламот стр 910 + + bFound = false; + + memcpy(&array_50AC10[uNumVertices], &array_50AC10[0], sizeof(array_50AC10[uNumVertices])); + depth_num_vertices = 0; + current_vertices_flag = false; + if ( array_50AC10[0].vWorldViewPosition.x >= pODMRenderParams->shading_dist_mist ) + current_vertices_flag = true;//настоящая вершина больше границы видимости + if ( (signed int)uNumVertices <= 0 ) + return 0; + for (uint i = 0; i < uNumVertices; ++i)// есть ли пограничные вершины + { + if ( array_50AC10[i].vWorldViewPosition.x < pODMRenderParams->shading_dist_mist ) + { + bFound = true; + break; + } + } + if ( !bFound ) + return 0; + //check for far clip plane(проверка по дальней границе) + // + // v3.__________________. v0 + // | | + // | | + // | | + // ----------------------- 8192.0(far_clip - 0x2000) + // | | + // .__________________. + // v2 v1 + + for ( uint i = 0; i < uNumVertices; ++i ) + { + next_vertices_flag = array_50AC10[i + 1].vWorldViewPosition.x >= pODMRenderParams->shading_dist_mist; + if ( current_vertices_flag ^ next_vertices_flag )//одна из граней за границей видимости + { + if ( next_vertices_flag )//следующая вершина больше границы видимости(настоящая вершина меньше границы видимости) - v3 + { + //t = far_clip - v2.x / v3.x - v2.x (формула получения точки пересечения отрезка с плоскостью) + t = (pODMRenderParams->shading_dist_mist - array_50AC10[i].vWorldViewPosition.x) / (array_50AC10[i].vWorldViewPosition.x - array_50AC10[i + 1].vWorldViewPosition.x); + array_507D30[depth_num_vertices].vWorldViewPosition.x = pODMRenderParams->shading_dist_mist; + //New_y = v2.y + (v3.y - v2.y)*t + array_507D30[depth_num_vertices].vWorldViewPosition.y = array_50AC10[i].vWorldViewPosition.y + (array_50AC10[i].vWorldViewPosition.y - array_50AC10[i + 1].vWorldViewPosition.y) * t; + //New_z = v2.z + (v3.z - v2.z)*t + array_507D30[depth_num_vertices].vWorldViewPosition.z = array_50AC10[i].vWorldViewPosition.z + (array_50AC10[i].vWorldViewPosition.z - array_50AC10[i + 1].vWorldViewPosition.z) * t; + array_507D30[depth_num_vertices].u = array_50AC10[i].u + (array_50AC10[i].u - array_50AC10[i + 1].u) * t; + array_507D30[depth_num_vertices].v = array_50AC10[i].v + (array_50AC10[i].v - array_50AC10[i + 1].v) * t; + array_507D30[depth_num_vertices]._rhw = 1.0 / pODMRenderParams->shading_dist_mist; + } + else//настоящая вершина больше границы видимости(следующая вершина меньше границы видимости) - v0 + { + //t = far_clip - v1.x / v0.x - v1.x + t = (pODMRenderParams->shading_dist_mist - array_50AC10[i].vWorldViewPosition.x) / (array_50AC10[i + 1].vWorldViewPosition.x - array_50AC10[i].vWorldViewPosition.x); + array_507D30[depth_num_vertices].vWorldViewPosition.x = pODMRenderParams->shading_dist_mist; + //New_y = (v0.y - v1.y)*t + v1.y + array_507D30[depth_num_vertices].vWorldViewPosition.y = array_50AC10[i].vWorldViewPosition.y + (array_50AC10[i + 1].vWorldViewPosition.y - array_50AC10[i].vWorldViewPosition.y) * t; + //New_z = (v0.z - v1.z)*t + v1.z + array_507D30[depth_num_vertices].vWorldViewPosition.z = array_50AC10[i].vWorldViewPosition.z + (array_50AC10[i + 1].vWorldViewPosition.z - array_50AC10[i].vWorldViewPosition.z) * t; + array_507D30[depth_num_vertices].u = array_50AC10[i].u + (array_50AC10[i + 1].u - array_50AC10[i].u) * t; + array_507D30[depth_num_vertices].v = array_50AC10[i].v + (array_50AC10[i + 1].v - array_50AC10[i].v) * t; + array_507D30[depth_num_vertices]._rhw = 1.0 / pODMRenderParams->shading_dist_mist; + } + ++depth_num_vertices; + } + if ( !next_vertices_flag )//оба в границе видимости + { + memcpy(&array_507D30[depth_num_vertices], &array_50AC10[i + 1], sizeof(array_507D30[depth_num_vertices])); + depth_num_vertices++; + } + current_vertices_flag = next_vertices_flag; + } + return depth_num_vertices >= 3 ? depth_num_vertices : 0; +} + +//----- (0047840D) -------------------------------------------------------- +void Render::DrawBuildingsD3D() +{ + int v9; // ecx@8 + Texture *pFaceTexture; // eax@10 + unsigned int v16; // edi@22 + int v27; // eax@57 +// int vertex_id; // eax@58 + unsigned int v34; // eax@80 + int v40; // [sp-4h] [bp-5Ch]@2 + int v49; // [sp+2Ch] [bp-2Ch]@10 + int v50; // [sp+30h] [bp-28h]@34 + int v51; // [sp+34h] [bp-24h]@35 + int v52; // [sp+38h] [bp-20h]@36 + int v53; // [sp+3Ch] [bp-1Ch]@8 + int uNumVertices; // [sp+4Ch] [bp-Ch]@34 + int unused; // [sp+50h] [bp-8h]@3 + + if ( !pRenderD3D ) + { + MessageBoxW(nullptr, L"D3D version of RenderBuildings called in software!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Odbuild.cpp:73", 0); + } + + unused = 0; + if ( (signed int)pOutdoor->uNumBModels > 0 ) + { + for ( uint model_id = 0; model_id < (unsigned int)pOutdoor->uNumBModels; model_id++ ) + { + if ( IsBModelVisible(model_id, &unused) ) + { + pOutdoor->pBModels[model_id].field_40 |= 1; + if ( pOutdoor->pBModels[model_id].uNumFaces > 0 ) + { + for ( int face_id = 0; face_id < pOutdoor->pBModels[model_id].uNumFaces; face_id++ ) + { + if (!pOutdoor->pBModels[model_id].pFaces[face_id].Invisible()) + { + v53 = 0; + array_77EC08[pODMRenderParams->uNumPolygons].flags = 0; + array_77EC08[pODMRenderParams->uNumPolygons].field_32 = 0; + v9 = pOutdoor->pBModels[model_id].pFaces[face_id].uTextureID; + if (pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & FACE_TEXTURE_FRAME) + v9 = pTextureFrameTable->GetFrameTexture(v9, pEventTimer->uTotalGameTimeElapsed); + pFaceTexture = pBitmaps_LOD->GetTexture(v9); + array_77EC08[pODMRenderParams->uNumPolygons].pTexture = pFaceTexture; + if (pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & FACE_FLUID) + array_77EC08[pODMRenderParams->uNumPolygons].flags |= 2; + if (pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & FACE_INDOOR_SKY ) + HIBYTE(array_77EC08[pODMRenderParams->uNumPolygons].flags) |= 4; + if ( pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & FACE_FLOW_DIAGONAL ) + HIBYTE(array_77EC08[pODMRenderParams->uNumPolygons].flags) |= 4; + else + { + if ( pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & FACE_FLOW_VERTICAL ) + HIBYTE(array_77EC08[pODMRenderParams->uNumPolygons].flags) |= 8; + } + if (pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & FACE_FLOW_HORIZONTAL) + array_77EC08[pODMRenderParams->uNumPolygons].flags |= 0x2000; + else + { + if (pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & FACE_DONT_CACHE_TEXTURE) + HIBYTE(array_77EC08[pODMRenderParams->uNumPolygons].flags) |= 0x10; + } + array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaU = pOutdoor->pBModels[model_id].pFaces[face_id].sTextureDeltaU; + array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaV = pOutdoor->pBModels[model_id].pFaces[face_id].sTextureDeltaV; + v16 = GetTickCount() >> 4; + if ( pOutdoor->pBModels[model_id].pFaces[face_id].pFacePlane.vNormal.z && abs(pOutdoor->pBModels[model_id].pFaces[face_id].pFacePlane.vNormal.z) >= 59082 ) + { + if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 4 ) + array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaV += v16 & array_77EC08[pODMRenderParams->uNumPolygons].pTexture->uHeightMinus1; + if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 8 ) + array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaV -= v16 & array_77EC08[pODMRenderParams->uNumPolygons].pTexture->uHeightMinus1; + } + else + { + if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 4 ) + array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaV -= v16 & array_77EC08[pODMRenderParams->uNumPolygons].pTexture->uHeightMinus1; + if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 8 ) + array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaV += v16 & array_77EC08[pODMRenderParams->uNumPolygons].pTexture->uHeightMinus1; + } + if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 0x10 ) + array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaU -= v16 & array_77EC08[pODMRenderParams->uNumPolygons].pTexture->uWidthMinus1; + else + { + if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 0x20 ) + array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaU += v16 & array_77EC08[pODMRenderParams->uNumPolygons].pTexture->uWidthMinus1; + } + v50 = 0; + v49 = 0; + uNumVertices = pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices; + if ( pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices > 0 ) + { + for ( uint vertex_id = 1; vertex_id <= pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices; vertex_id++ ) + { + array_73D150[vertex_id - 1].vWorldPosition.x = pOutdoor->pBModels[model_id].pVertices.pVertices[pOutdoor->pBModels[model_id].pFaces[face_id].pVertexIDs[vertex_id - 1]].x; + array_73D150[vertex_id - 1].vWorldPosition.y = pOutdoor->pBModels[model_id].pVertices.pVertices[pOutdoor->pBModels[model_id].pFaces[face_id].pVertexIDs[vertex_id - 1]].y; + array_73D150[vertex_id - 1].vWorldPosition.z = pOutdoor->pBModels[model_id].pVertices.pVertices[pOutdoor->pBModels[model_id].pFaces[face_id].pVertexIDs[vertex_id - 1]].z; + array_73D150[vertex_id - 1].u = (array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaU + (signed __int16)pOutdoor->pBModels[model_id].pFaces[face_id].pTextureUIDs[vertex_id - 1]) * (1.0 / (double)pFaceTexture->uTextureWidth); + array_73D150[vertex_id - 1].v = (array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaV + (signed __int16)pOutdoor->pBModels[model_id].pFaces[face_id].pTextureVIDs[vertex_id - 1]) * (1.0 / (double)pFaceTexture->uTextureHeight); + } + for ( uint i = 1; i <= pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices; i++ ) + { + if ( pOutdoor->pBModels[model_id].pVertices.pVertices[pOutdoor->pBModels[model_id].pFaces[face_id].pVertexIDs[0]].z == array_73D150[i - 1].vWorldPosition.z ) + ++v53; + pGame->pIndoorCameraD3D->ViewTransform(&array_73D150[i - 1], 1); + if ( array_73D150[i - 1].vWorldViewPosition.x < 8.0 || array_73D150[i - 1].vWorldViewPosition.x > pODMRenderParams->shading_dist_mist ) + { + if ( array_73D150[i - 1].vWorldViewPosition.x >= 8.0 ) + v49 = 1; + else + v50 = 1; + } + else + pGame->pIndoorCameraD3D->Project(&array_73D150[i - 1], 1, 0); + } + } + if ( v53 == pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices ) + LOBYTE(array_77EC08[pODMRenderParams->uNumPolygons].field_32) |= 1; + array_77EC08[pODMRenderParams->uNumPolygons].pODMFace = &pOutdoor->pBModels[model_id].pFaces[face_id]; + array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices = pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices; + array_77EC08[pODMRenderParams->uNumPolygons].field_59 = 5; + v51 = fixpoint_mul(-pOutdoor->vSunlight.x, pOutdoor->pBModels[model_id].pFaces[face_id].pFacePlane.vNormal.x); + v53 = fixpoint_mul(-pOutdoor->vSunlight.y, pOutdoor->pBModels[model_id].pFaces[face_id].pFacePlane.vNormal.y); + v52 = fixpoint_mul(-pOutdoor->vSunlight.z, pOutdoor->pBModels[model_id].pFaces[face_id].pFacePlane.vNormal.z); + array_77EC08[pODMRenderParams->uNumPolygons].dimming_level = 20 - fixpoint_mul(20, v51 + v53 + v52); + if ( array_77EC08[pODMRenderParams->uNumPolygons].dimming_level < 0 ) + array_77EC08[pODMRenderParams->uNumPolygons].dimming_level = 0; + if ( array_77EC08[pODMRenderParams->uNumPolygons].dimming_level > 31 ) + array_77EC08[pODMRenderParams->uNumPolygons].dimming_level = 31; + if ( pODMRenderParams->uNumPolygons >= 1999 + 5000) + return; + if ( ODMFace::IsBackfaceNotCulled(array_73D150, &array_77EC08[pODMRenderParams->uNumPolygons]) ) + { + pOutdoor->pBModels[model_id].pFaces[face_id].bVisible = 1; + array_77EC08[pODMRenderParams->uNumPolygons].uBModelFaceID = face_id; + array_77EC08[pODMRenderParams->uNumPolygons].uBModelID = model_id; + v27 = 8 * (face_id | (model_id << 6)); + LOBYTE(v27) = v27 | 6; + array_77EC08[pODMRenderParams->uNumPolygons].field_50 = v27; + for ( int vertex_id = 0; vertex_id < pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices; ++vertex_id) + { + memcpy(&array_50AC10[vertex_id], &array_73D150[vertex_id], sizeof(array_50AC10[vertex_id])); + array_50AC10[vertex_id]._rhw = 1.0 / (array_73D150[vertex_id].vWorldViewPosition.x + 0.0000001); + } + static stru154 static_RenderBuildingsD3D_stru_73C834; + /*static bool __init_flag = false; + if (!__init_flag) + { + __init_flag = true; + static_RenderBuildingsD3D_byte_73C84C_init_flag |= 1u; + stru154::stru154(&static_RenderBuildingsD3D_stru_73C834); + atexit(loc_4789D4); + }*/ + + v40 = (int)&pOutdoor->pBModels[model_id].pFaces[face_id]; + pGame->pLightmapBuilder->ApplyLights_OutdoorFace(&pOutdoor->pBModels[model_id].pFaces[face_id]); + pDecalBuilder->ApplyDecals_OutdoorFace(&pOutdoor->pBModels[model_id].pFaces[face_id]); + pGame->pLightmapBuilder->std__vector_000004_size = 0; + int v31 = 0; + if ( stru_F8AD28.uNumLightsApplied > 0 || pDecalBuilder->uNumDecals > 0 ) + { + v31 = v50 ? 3 : v49 != 0 ? 5 : 0; + static_RenderBuildingsD3D_stru_73C834.GetFacePlaneAndClassify(&pOutdoor->pBModels[model_id].pFaces[face_id], &pOutdoor->pBModels[model_id].pVertices); + if ( pDecalBuilder->uNumDecals > 0 ) + { + v40 = -1; + pDecalBuilder->ApplyDecals(31 - array_77EC08[pODMRenderParams->uNumPolygons].dimming_level, 2, &static_RenderBuildingsD3D_stru_73C834, + pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices, array_50AC10, 0, (char)v31, -1); + } + } + if ( stru_F8AD28.uNumLightsApplied > 0 ) + pGame->pLightmapBuilder->ApplyLights(&stru_F8AD28, &static_RenderBuildingsD3D_stru_73C834, uNumVertices, array_50AC10, 0, (char)v31); + if ( v50 ) + { + array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices = ODM_NearClip(pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices); + uNumVertices = array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices; + ODM_Project(array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices); + } + if ( v49 ) + { + array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices = ODM_FarClip(pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices); + uNumVertices = array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices; + ODM_Project(array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices); + } + if ( uNumVertices ) + { + if ( array_77EC08[pODMRenderParams->uNumPolygons].flags & 2 ) + { + if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 0x3C ) + v34 = pRenderer->pHDWaterBitmapIDs[0]; + else + v34 = pRenderer->pHDWaterBitmapIDs[pRenderer->hd_water_current_frame]; + v40 = (int)pBitmaps_LOD->pHardwareTextures[v34]; + } + else + v40 = (int)pBitmaps_LOD->pHardwareTextures[v9]; + pRenderer->DrawPolygon(uNumVertices, &array_77EC08[pODMRenderParams->uNumPolygons], &pOutdoor->pBModels[model_id].pFaces[face_id], (IDirect3DTexture2 *)v40); + } + } + } + } + } + } + } + } + return; +} +//----- (00479543) -------------------------------------------------------- +void Render::DrawOutdoorSkyD3D() +{ + int v9; // eax@4 + int v10; // ebx@4 + int v13; // edi@6 + int v14; // ecx@6 + int v15; // eax@8 + int v16; // eax@12 + signed __int64 v17; // qtt@13 + signed int v18; // ecx@13 + struct Polygon pSkyPolygon; // [sp+14h] [bp-150h]@1 + int v30; // [sp+134h] [bp-30h]@1 + int v32; // [sp+13Ch] [bp-28h]@6 + int v33; // [sp+140h] [bp-24h]@2 + signed __int64 v34; // [sp+144h] [bp-20h]@1 + int v35; // [sp+148h] [bp-1Ch]@4 + int v36; // [sp+14Ch] [bp-18h]@2 + int v37; // [sp+154h] [bp-10h]@8 + int v38; // [sp+158h] [bp-Ch]@1 + int v39; // [sp+15Ch] [bp-8h]@4 + + v30 = (signed __int64)((double)(pODMRenderParams->int_fov_rad * pGame->pIndoorCameraD3D->vPartyPos.z) + / ((double)pODMRenderParams->int_fov_rad + 8192.0) + + (double)(pViewport->uScreenCenterY)); + v34 = cos((double)pGame->pIndoorCameraD3D->sRotationX * 0.0030664064) * 0x2000;//(double)pODMRenderParams->shading_dist_mist, 8192 + v38 = (signed __int64)((double)(pViewport->uScreenCenterY) + - (double)pODMRenderParams->int_fov_rad + / (v34 + 0.0000001) + * (sin((double)pGame->pIndoorCameraD3D->sRotationX * 0.0030664064) + * (double)-0x2000//(double)pODMRenderParams->shading_dist_mist + - (double)pGame->pIndoorCameraD3D->vPartyPos.z)); + pSkyPolygon.Create_48607B(&stru_8019C8);//заполняется ptr_38 + pSkyPolygon.ptr_38->_48694B_frustum_sky(); + pSkyPolygon.uTileBitmapID = pOutdoor->sSky_TextureID;//179(original 166) + pSkyPolygon.pTexture = (Texture *)(SLOWORD(pOutdoor->sSky_TextureID) != -1 ? (int)&pBitmaps_LOD->pTextures[SLOWORD(pOutdoor->sSky_TextureID)] : 0); + if ( pSkyPolygon.pTexture ) + { + pSkyPolygon.dimming_level = 0; + pSkyPolygon.uNumVertices = 4; + //centering(центруем)----------------------------------------------------------------- + pSkyPolygon.v_18.x = -stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationX + 16); + pSkyPolygon.v_18.y = 0; + pSkyPolygon.v_18.z = -stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationX + 16); + + //sky wiew position(положение неба на экране)------------------------------------------ + // X + // 0._____________________________.3 + // |8,8 468,8 | + // | | + // | | + // Y| | + // | | + // |8,351 468,351 | + // 1._____________________________.2 + // + array_50AC10[0].vWorldViewProjX = (double)(signed int)pViewport->uViewportTL_X;//8 + array_50AC10[0].vWorldViewProjY = (double)(signed int)pViewport->uViewportTL_Y;//8 + + array_50AC10[1].vWorldViewProjX = (double)(signed int)pViewport->uViewportTL_X;//8 + array_50AC10[1].vWorldViewProjY = (double)v38;//247 + + array_50AC10[2].vWorldViewProjX = (double)(signed int)pViewport->uViewportBR_X;//468 + array_50AC10[2].vWorldViewProjY = (double)v38;//247 + + array_50AC10[3].vWorldViewProjX = (double)(signed int)pViewport->uViewportBR_X;//468 + array_50AC10[3].vWorldViewProjY = (double)(signed int)pViewport->uViewportTL_Y;//8 + + pSkyPolygon.sTextureDeltaU = 224 * pMiscTimer->uTotalGameTimeElapsed;//7168 + pSkyPolygon.sTextureDeltaV = 224 * pMiscTimer->uTotalGameTimeElapsed;//7168 + + pSkyPolygon.field_24 = 0x2000000u;//maybe attributes + v33 = 65536 / (signed int)(signed __int64)(((double)(pViewport->uViewportBR_X - pViewport->uViewportTL_X) / 2) / tan(0.6457717418670654) + 0.5); + for ( uint i = 0; i < pSkyPolygon.uNumVertices; ++i ) + { + //rotate skydome(вращение купола неба)-------------------------------------- + // В игре принята своя система измерения углов. Полный угол (180). Значению угла 0 соответствует + // направление на север и/или юг (либо на восток и/или запад), значению 65536 еденицам(0х10000) соответствует угол 90. + // две переменные хранят данные по углу обзора. field_14 по западу и востоку. field_20 по югу и северу + // от -25080 до 25080 + v39 = fixpoint_mul(pSkyPolygon.ptr_38->viewing_angle_from_west_east, v33 * (v30 - floor(array_50AC10[i].vWorldViewProjY + 0.5))); + v35 = v39 + pSkyPolygon.ptr_38->angle_from_north; + + v39 = fixpoint_mul(pSkyPolygon.ptr_38->viewing_angle_from_north_south, v33 * (v30 - floor(array_50AC10[i].vWorldViewProjY + 0.f))); + v36 = v39 + pSkyPolygon.ptr_38->angle_from_east; + + v9 = fixpoint_mul(pSkyPolygon.v_18.z, v33 * (v30 - floor(array_50AC10[i].vWorldViewProjY + 0.5))); + v10 = pSkyPolygon.v_18.x + v9; + if ( v10 > 0 ) + v10 = 0; + v13 = v33 * (pViewport->uScreenCenterX - (signed __int64)array_50AC10[i].vWorldViewProjX); + v34 = -pSkyPolygon.field_24; + v32 = (signed __int64)array_50AC10[i].vWorldViewProjY - 1.0; + v14 = v33 * (v30 - v32); + while ( 1 ) + { + if ( v10 ) + { + v37 = abs((int)v34 >> 14); + v15 = abs(v10); + if ( v37 <= v15 || v32 <= (signed int)pViewport->uViewportTL_Y ) + { + if ( v10 <= 0 ) + break; + } + } + v16 = fixpoint_mul(pSkyPolygon.v_18.z, v14); + --v32; + v14 += v33; + v10 = pSkyPolygon.v_18.x + v16; + } + LODWORD(v17) = LODWORD(v34) << 16; + HIDWORD(v17) = v34 >> 16; + v18 = v17 / v10; + if ( v18 < 0 ) + v18 = pODMRenderParams->shading_dist_mist; + v37 = v35 + fixpoint_mul(pSkyPolygon.ptr_38->angle_from_west, v13); + v35 = 224 * pMiscTimer->uTotalGameTimeElapsed + ((signed int)fixpoint_mul(v37, v18) >> 3); + array_50AC10[i].u = (double)v35 / ((double)pSkyPolygon.pTexture->uTextureWidth * 65536.0); + + v36 = v36 + fixpoint_mul(pSkyPolygon.ptr_38->angle_from_south, v13); + v35 = 224 * pMiscTimer->uTotalGameTimeElapsed + ((signed int)fixpoint_mul(v36, v18) >> 3); + array_50AC10[i].v = (double)v35 / ((double)pSkyPolygon.pTexture->uTextureHeight * 65536.0); + + array_50AC10[i].vWorldViewPosition.x = (double)0x2000;//pODMRenderParams->shading_dist_mist 8192 + array_50AC10[i]._rhw = 1.0 / (double)(v18 >> 16); + } + pRenderer->DrawOutdoorSkyPolygon(pSkyPolygon.uNumVertices, &pSkyPolygon, pBitmaps_LOD->pHardwareTextures[(signed __int16)pSkyPolygon.uTileBitmapID]); + array_50AC10[0].vWorldViewProjY = (double)v10; + array_50AC10[1].vWorldViewProjY = array_50AC10[1].vWorldViewProjY + 30.0; + array_50AC10[2].vWorldViewProjY = array_50AC10[2].vWorldViewProjY + 30.0; + array_50AC10[3].vWorldViewProjY = (double)v10; + pRenderer->DrawOutdoorSkyPolygon(pSkyPolygon.uNumVertices, &pSkyPolygon, pBitmaps_LOD->pHardwareTextures[(signed __int16)pSkyPolygon.uTileBitmapID]); + return; + } +} +//----- (004226C2) -------------------------------------------------------- +bool PauseGameDrawing() +{ + if ( pCurrentScreen != SCREEN_GAME + && pCurrentScreen != SCREEN_NPC_DIALOGUE + && pCurrentScreen != SCREEN_CHANGE_LOCATION ) + { + if (pCurrentScreen == SCREEN_INPUT_BLV) + return pMovie_Track;//pSmackerMovie != 0; + if ( pCurrentScreen != SCREEN_BRANCHLESS_NPC_DIALOG ) + return true; + } + return false; +} + + +//----- (0045E03A) -------------------------------------------------------- +unsigned short *Render::MakeScreenshot(signed int width, signed int height) +{ + unsigned __int16 *for_pixels; // ebx@1 + DDSURFACEDESC2 Dst; // [sp+4h] [bp-A0h]@6 + unsigned __int16 *pPixels; // [sp+80h] [bp-24h]@1 + float interval_x; // [sp+84h] [bp-20h]@1 + float interval_y; // [sp+8Ch] [bp-18h]@1 + + interval_x = game_viewport_width / (double)width; + interval_y = game_viewport_height / (double)height; + + pPixels = (unsigned __int16 *)malloc(2 * height * width); + memset(pPixels, 0 , 2 * height * width); + + for_pixels = pPixels; + + BeginSceneD3D(); + + if (uCurrentlyLoadedLevelType == LEVEL_Indoor) + pIndoor->Draw(); + else if (uCurrentlyLoadedLevelType == LEVEL_Outdoor) + pOutdoor->Draw(); + DrawBillboards_And_MaybeRenderSpecialEffects_And_EndScene(); + memset(&Dst, 0, sizeof(Dst)); + Dst.dwSize = sizeof(Dst); + + if ( LockSurface_DDraw4(pBackBuffer4, &Dst, DDLOCK_WAIT) ) + { + if (uCurrentlyLoadedLevelType == LEVEL_null) + memset(&for_pixels, 0, sizeof(for_pixels)); + else + { + for (uint y = 0; y < (unsigned int)height; ++y) + { + for (uint x = 0; x < (unsigned int)width; ++x) + { + if (Dst.ddpfPixelFormat.dwRGBBitCount == 32) + { + unsigned __int32 *p = (unsigned __int32 *)Dst.lpSurface + (int)(x * interval_x + 8.0) + (int)(y * interval_y + 8.0) * (Dst.lPitch >> 2); + *for_pixels = Color16((*p >> 16) & 255, (*p >> 8) & 255, *p & 255); + } + else if (Dst.ddpfPixelFormat.dwRGBBitCount == 16) + { + unsigned __int16 * p = (unsigned __int16 *)Dst.lpSurface + (int)(x * interval_x + 8.0) + y * Dst.lPitch; + *for_pixels = *p; + } + else + assert(false); + ++for_pixels; + } + } + } + ErrD3D(pBackBuffer4->Unlock(NULL)); + } + return pPixels; +} +//----- (0045E26C) -------------------------------------------------------- +void Render::SaveScreenshot(const char *pFilename, unsigned int width, unsigned int height) +{ + auto pixels = MakeScreenshot(width, height); + SavePCXImage(pFilename, pixels, width, height); + free(pixels); +} + +void Render::PackScreenshot(unsigned int width, unsigned int height, void *data, unsigned int data_size, unsigned int *out_screenshot_size) +{ + auto pixels = MakeScreenshot(150, 112); + PackPCXpicture(pixels, 150, 112, data, 1000000, out_screenshot_size); + free(pixels); +} + + +//----- (0046A7C8) -------------------------------------------------------- +int Render::_46А6АС_GetActorsInViewport(int pDepth) +{ + unsigned int v3; // eax@2 применяется в закле Жар печи для подсчёта кол-ва монстров видимых группе и заполнения массива id видимых монстров + unsigned int v5; // eax@2 + unsigned int v6; // eax@4 + unsigned int v12; // [sp+10h] [bp-14h]@1 + int mon_num; // [sp+1Ch] [bp-8h]@1 + unsigned int a1a; // [sp+20h] [bp-4h]@1 + + mon_num = 0; + v12 = GetBillboardDrawListSize(); + if ( (signed int)GetBillboardDrawListSize() > 0 ) + { + for ( a1a = 0; (signed int)a1a < (signed int)v12; ++a1a ) + { + v3 = GetParentBillboardID(a1a); + v5 = (unsigned __int16)pBillboardRenderList[v3].object_pid; + if ( PID_TYPE(v5) == OBJECT_Actor) + { + if ( pBillboardRenderList[v3].sZValue <= (unsigned int)(pDepth << 16) ) + { + v6 = PID_ID(v5); + if ( pActors[v6].uAIState != Dead && pActors[v6].uAIState != Dying && pActors[v6].uAIState != Removed + && pActors[v6].uAIState != Disabled && pActors[v6].uAIState != Summoned ) + { + if ( pGame->pVisInstance->DoesRayIntersectBillboard((double)pDepth, a1a) ) + { + if ( mon_num < 100 ) + { + _50BF30_actors_in_viewport_ids[mon_num] = v6; + mon_num++; + } + } + } + } + } + } + } + return mon_num; +} + + + + +void Render::BeginLightmaps() +{ + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP)); + + if (bUsingSpecular) + pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE); + + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, FALSE)); + ErrD3D(pRenderD3D->pDevice->SetTexture(0, pGame->pIndoorCameraD3D->LoadTextureAndGetHardwarePtr("effpar03"))); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE)); +} + +void Render::EndLightmaps() +{ + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE)); + + if (bUsingSpecular) + { + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, uFogColor)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, 0)); + } +} + + +void Render::BeginLightmaps2() +{ + if (bUsingSpecular) + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE)); + + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, FALSE)); + + ErrD3D(pRenderD3D->pDevice->SetTexture(0, pGame->pIndoorCameraD3D->LoadTextureAndGetHardwarePtr("effpar03"))); + + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE)); +} + + +void Render::EndLightmaps2() +{ + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CW)); + + if (bUsingSpecular) + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE)); +} + + + +//----- (00437C96) -------------------------------------------------------- +void Render::do_draw_debug_line_d3d(const RenderVertexD3D3 *pLineBegin, signed int sDiffuseBegin, const RenderVertexD3D3 *pLineEnd, signed int sDiffuseEnd, float z_stuff) +{ + double v6; // st7@2 + //IDirect3DDevice3 *v7; // eax@2 +// HRESULT v8; // eax@2 + std::string v9; // [sp-18h] [bp-60h]@3 +// const char *v10; // [sp-Ch] [bp-54h]@2 +// const char *v11; // [sp-8h] [bp-50h]@2 +// int v12; // [sp-4h] [bp-4Ch]@2 + RenderVertexD3D3 v13[2]; // [sp+8h] [bp-40h]@2 + + //if ( pRenderer->pRenderD3D ) + { + v6 = 0.001 - z_stuff; + memcpy(v13, pLineBegin, 0x20u); + memcpy(&v13[1], pLineEnd, sizeof(v13[1])); + v13[0].pos.z = v6; + v13[1].pos.z = v6; + v13[0].diffuse = sDiffuseBegin; + v13[1].diffuse = sDiffuseEnd; + ErrD3D(pRenderD3D->pDevice->SetTexture(0, nullptr)); + ErrD3D(pRenderD3D->pDevice->DrawPrimitive( + D3DPT_LINELIST, + 452, + v13, + 2, + 16)); + } +} + + +void Render::DrawLines(const RenderVertexD3D3 *vertices, unsigned int num_vertices) +{ + ErrD3D(pRenderD3D->pDevice->SetTexture(0, nullptr)); + ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_LINELIST, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + (void *)vertices, + num_vertices, + D3DDP_DONOTLIGHT)); +} + + +void Render::DrawFansTransparent(const RenderVertexD3D3 *vertices, unsigned int num_vertices) +{ + //ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false)); + //ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, false)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA)); + + ErrD3D(pRenderD3D->pDevice->SetTexture(0, nullptr)); + ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + (void *)vertices, + num_vertices, + 28)); + + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE)); + //ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, TRUE)); + //ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); +} + + +void Render::BeginDecals() +{ + // code chunk from 0049C304 + if (bUsingSpecular) + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP)); + + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, FALSE)); + + ErrD3D(pRenderD3D->pDevice->SetTexture(0, pGame->pIndoorCameraD3D->LoadTextureAndGetHardwarePtr("hwsplat04"))); +} + + +void Render::EndDecals() +{ + // code chunk from 0049C304 + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CW)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); + + if (bUsingSpecular) + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE)); +} + + + +//----- (0049C095) -------------------------------------------------------- +void Render::DrawDecal(Decal *pDecal, float z_bias) +{ + signed int v21; // [sp+Ch] [bp-864h]@15 + RenderVertexD3D3 pVerticesD3D[64]; // [sp+20h] [bp-850h]@6 + + if (pDecal->uNumVertices < 3) + { + Log::Warning(L"Decal has < 3 vertices"); + return; + } + + float color_mult; + if ( pDecal->field_C1C & 1 ) + color_mult = 1.0; + else + color_mult = pDecal->field_C18->_43B570_get_color_mult_by_time(); + + for (uint i = 0; i < (unsigned int)pDecal->uNumVertices; ++i) + { + uint uTint = Render::GetActorTintColor(pDecal->pVertices[i].vWorldViewPosition.x, pDecal->field_C14, 0, 0, nullptr); + + uint uTintR = (uTint >> 16) & 0xFF, + uTintG = (uTint >> 8) & 0xFF, + uTintB = uTint & 0xFF; + + uint uDecalColorMultR = (pDecal->uColorMultiplier >> 16) & 0xFF, + uDecalColorMultG = (pDecal->uColorMultiplier >> 8) & 0xFF, + uDecalColorMultB = pDecal->uColorMultiplier & 0xFF; + + uint uFinalR = floorf(uTintR / 255.0 * color_mult * uDecalColorMultR + 0.0f), + uFinalG = floorf(uTintG / 255.0 * color_mult * uDecalColorMultG + 0.0f), + uFinalB = floorf(uTintB / 255.0 * color_mult * uDecalColorMultB + 0.0f); + + + float v15; + if (fabs(z_bias) < 1e-5) + v15 = 1.0 - 1.0 / ((1.0f / pGame->pIndoorCameraD3D->GetShadingDistMist()) * pDecal->pVertices[i].vWorldViewPosition.x * 1000.0); + else + { + v15 = 1.0 - 1.0 / ((1.0f / pGame->pIndoorCameraD3D->GetShadingDistMist()) * pDecal->pVertices[i].vWorldViewPosition.x * 1000.0) - z_bias; + if (v15 < 0.000099999997) + v15 = 0.000099999997; + } + + pVerticesD3D[i].pos.z = v15; + + pVerticesD3D[i].pos.x = pDecal->pVertices[i].vWorldViewProjX; + pVerticesD3D[i].pos.y = pDecal->pVertices[i].vWorldViewProjY; + pVerticesD3D[i].texcoord.x = pDecal->pVertices[i].u; + pVerticesD3D[i].texcoord.y = pDecal->pVertices[i].v; + pVerticesD3D[i].diffuse = (uFinalR << 16) | (uFinalG << 8) | uFinalB; + pVerticesD3D[i].specular = 0; + pVerticesD3D[i].rhw = 1.0 / pDecal->pVertices[i].vWorldViewPosition.x; + } + + if (uCurrentlyLoadedLevelType == LEVEL_Indoor) + v21 = D3DDP_DONOTLIGHT | D3DDP_DONOTCLIP | D3DDP_DONOTUPDATEEXTENTS; + else + v21 = D3DDP_DONOTLIGHT; + + ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + pVerticesD3D, + pDecal->uNumVertices, + v21)); +} + + +void Render::DrawSpecialEffectsQuad(const RenderVertexD3D3 *vertices, IDirect3DTexture2 *texture) +{ + ErrD3D(pRenderD3D->pDevice->SetTexture(0, texture)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, FALSE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, D3DCMP_ALWAYS)); + ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + (void *)vertices, 4, 28)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, D3DCMP_LESS)); +} + +//----- (00452442) -------------------------------------------------------- +unsigned int __fastcall _452442_color_cvt(unsigned __int16 a1, unsigned __int16 a2, int a3, int a4) +{ + int v4; // ebx@0 + __int16 v5; // ST14_2@1 + __int16 v6; // dx@1 + int v7; // ecx@1 + __int16 v8; // ST10_2@1 + int v9; // edi@1 + unsigned __int16 v10; // dh@1@1 + int v11; // ebx@1 + int v12; // ebx@1 + __int16 a3a; // [sp+1Ch] [bp+8h]@1 + + v5 = a2 >> 2; + v6 = (unsigned __int16)a4 >> 2; + v8 = a1 >> 2; + a3a = (unsigned __int16)a3 >> 2; + LOWORD(v7) = a3a; + v9 = v7; + LOWORD(v4) = ((unsigned __int16)a4 >> 2) & 0xE0; + LOWORD(v7) = a3a & 0xE0; + LOWORD(v9) = v9 & 0x1C00; + v11 = v7 + v4; + LOWORD(v7) = v5 & 0xE0; + v12 = v7 + v11; + LOWORD(v7) = v8 & 0xE0; + __debugbreak(); // warning C4700: uninitialized local variable 'v10' used + return (PID_TYPE(v8) + PID_TYPE(v5) + PID_TYPE(a3a) + PID_TYPE(v6)) | (v7 + v12) | ((v8 & 0x1C00) + + (v5 & 0x1C00) + + v9 + + (__PAIR__(v10, (unsigned __int16)a4 >> 2) & 0x1C00)); +} + +//----- (0047C4FC) -------------------------------------------------------- +int __fastcall GetActorTintColor(int max_dimm, int min_dimm, float distance, int a4, RenderBillboard *a5) +{ + //int v5; // esi@1 + signed int v6; // edx@1 + //signed int result; // eax@2 + int v8; // eax@3 + double v9; // st7@12 + //double v10; // ST0C_8@18 + int v11; // ecx@28 + //signed int v12; // edi@28 + //double v13; // ST0C_8@33 + //double v14; // ST0C_8@34 + double v15; // st7@44 + //double v16; // ST0C_8@44 + //double v17; // ST0C_8@44 + int v18; // ST14_4@44 + //double v19; // ST0C_8@44 + signed int v20; // [sp+10h] [bp-4h]@10 + // float a3a; // [sp+1Ch] [bp+8h]@33 + //float a3b; // [sp+1Ch] [bp+8h]@34 + float a3c; // [sp+1Ch] [bp+8h]@44 + //float a3d; // [sp+1Ch] [bp+8h]@44 + //float a4b; // [sp+20h] [bp+Ch]@18 + //int a4a; // [sp+20h] [bp+Ch]@33 + //float a4c; // [sp+20h] [bp+Ch]@44 + //float a4d; // [sp+20h] [bp+Ch]@44 + int a5a; // [sp+24h] [bp+10h]@44 + + //v5 = a2; + v6 = 0; + + if (uCurrentlyLoadedLevelType == LEVEL_Indoor) + return 8 * (31 - max_dimm) | ((8 * (31 - max_dimm) | ((31 - max_dimm) << 11)) << 8); + + if (pParty->armageddon_timer) + return 0xFFFF0000; + + v8 = pWeather->bNight; + if (bUnderwater) + v8 = 0; + if (v8) + { + v20 = 1; + if ((signed __int64)pParty->pPartyBuffs[PARTY_BUFF_TORCHLIGHT].uExpireTime > 0) + v20 = pParty->pPartyBuffs[PARTY_BUFF_TORCHLIGHT].uPower; + v9 = (double)v20 * 1024.0; + if (a4) + { + v6 = 216; + goto LABEL_20; + } + if (distance <= v9) + { + if (distance > 0.0) + { + //a4b = distance * 216.0 / v9; + //v10 = a4b + 6.7553994e15; + //v6 = LODWORD(v10); + v6 = floorf(0.5f + distance * 216.0 / v9); + if (v6 > 216) + { + v6 = 216; + goto LABEL_20; + } + } + } + else + { + v6 = 216; + } + if (distance != 0.0) + { + LABEL_20: + if (a5) + v6 = 8 * _43F55F_get_billboard_light_level(a5, v6 >> 3); + if (v6 > 216) + v6 = 216; + return (255 - v6) | ((255 - v6) << 16) | ((255 - v6) << 8); + } + //LABEL_19: + v6 = 216; + goto LABEL_20; + } + + + + if (fabsf(distance) < 1.0e-6f) + return 0xFFF8F8F8; + + // dim in measured in 8-steps + v11 = 8 * (max_dimm - min_dimm); + //v12 = v11; + if (v11 >= 0) + { + if (v11 > 216) + v11 = 216; + } + else + v11 = 0; + + float fog_density_mult = 216.0f; + if (a4) + fog_density_mult += distance / (double)pODMRenderParams->shading_dist_shade * 32.0; + + v6 = v11 + floorf(pOutdoor->fFogDensity * fog_density_mult + 0.5f); + /*if ( a4 ) + { + //a3b = pOutdoor->fFogDensity * 216.0; + //v14 = a3b + 6.7553994e15; + //a4a = floorf(a3b + 0.5f);//LODWORD(v14); + } + else + { + //a3a = (distance / (double)pODMRenderParams->shading_dist_shade * 32.0 + 216.0) * pOutdoor->fFogDensity; + //v13 = a3a + 6.7553994e15; + //a4a = floorf(a3a + 0.5f);//LODWORD(v13); + } + v6 = a4a + v11;*/ + if (a5) + v6 = 8 * _43F55F_get_billboard_light_level(a5, v6 >> 3); + if (v6 > 216) + v6 = 216; + if (v6 < v11) + v6 = v11; + if (v6 > 8 * pOutdoor->max_terrain_dimming_level) + v6 = 8 * pOutdoor->max_terrain_dimming_level; + if (!bUnderwater) + return (255 - v6) | ((255 - v6) << 16) | ((255 - v6) << 8); + else + { + v15 = (double)(255 - v6) * 0.0039215689; + a3c = v15; + //a4c = v15 * 16.0; + //v16 = a4c + 6.7553994e15; + a5a = floorf(v15 * 16.0 + 0.5f);//LODWORD(v16); + //a4d = a3c * 194.0; + //v17 = a4d + 6.7553994e15; + v18 = floorf(a3c * 194.0 + 0.5f);//LODWORD(v17); + //a3d = a3c * 153.0; + //v19 = a3d + 6.7553994e15; + return (int)floorf(a3c * 153.0 + 0.5f)/*LODWORD(v19)*/ | ((v18 | (a5a << 8)) << 8); + } +} +// 6BE3C4: using guessed type char bUnderwater; + +//----- (0043F55F) -------------------------------------------------------- +int __fastcall _43F55F_get_billboard_light_level(RenderBillboard *a1, int uBaseLightLevel) +{ + signed int v3; // ecx@2 + + if (uCurrentlyLoadedLevelType == LEVEL_Indoor) + v3 = pIndoor->pSectors[a1->uIndoorSectorID].uMinAmbientLightLevel; + else + { + if (uBaseLightLevel == -1) + v3 = a1->dimming_level; + else + v3 = uBaseLightLevel; + } + return _43F5C8_get_point_light_level_with_respect_to_lights(v3, a1->uIndoorSectorID, a1->world_x, a1->world_y, a1->world_z); +} + +//----- (0043F5C8) -------------------------------------------------------- +int __fastcall _43F5C8_get_point_light_level_with_respect_to_lights(unsigned int uBaseLightLevel, int uSectorID, float x, float y, float z) +{ + // int v5; // esi@1 + signed int v6; // edi@1 + int v8; // eax@6 + int v9; // ebx@6 + unsigned int v10; // ecx@6 + unsigned int v11; // edx@9 + unsigned int v12; // edx@11 + signed int v13; // ecx@12 + BLVLightMM7 *v16; // esi@20 + int v17; // ebx@21 + // int v18; // eax@24 + // int v19; // ebx@24 + // unsigned int v20; // ecx@24 + // int v21; // edx@25 + // unsigned int v22; // edx@27 + // unsigned int v23; // edx@29 + signed int v24; // ecx@30 + int v26; // ebx@35 + // int v27; // eax@38 + // int v28; // ebx@38 + // unsigned int v29; // ecx@38 + // int v30; // edx@39 + // unsigned int v31; // edx@41 + // unsigned int v32; // edx@43 + //signed int v33; // ecx@44 + int v37; // [sp+Ch] [bp-18h]@37 + // int v38; // [sp+10h] [bp-14h]@5 + int v39; // [sp+10h] [bp-14h]@23 + int v40; // [sp+10h] [bp-14h]@36 + int v42; // [sp+14h] [bp-10h]@22 + unsigned int v43; // [sp+18h] [bp-Ch]@12 + unsigned int v44; // [sp+18h] [bp-Ch]@30 + unsigned int v45; // [sp+18h] [bp-Ch]@44 + + v6 = uBaseLightLevel; + for (uint i = 0; i < pMobileLightsStack->uNumLightsActive; ++i) + { + MobileLight* p = &pMobileLightsStack->pLights[i]; + + float distX = abs(p->vPosition.x - x); + if (distX <= p->uRadius) + { + float distY = abs(p->vPosition.y - y); + if (distY <= p->uRadius) + { + float distZ = abs(p->vPosition.z - z); + if (distZ <= p->uRadius) + { + v8 = distX; + v9 = distY; + v10 = distZ; + if (distX < distY) + { + v8 = distY; + v9 = distX; + } + if (v8 < distZ) + { + v11 = v8; + v8 = distZ; + v10 = v11; + } + if (v9 < (signed int)v10) + { + v12 = v10; + v10 = v9; + v9 = v12; + } + v43 = ((unsigned int)(11 * v9) / 32) + (v10 / 4) + v8; + v13 = p->uRadius; + if ((signed int)v43 < v13) + v6 += ((unsigned __int64)(30i64 * (signed int)(v43 << 16) / v13) >> 16) - 30; + } + } + } + } + + if (uCurrentlyLoadedLevelType == LEVEL_Indoor) + { + BLVSector* pSector = &pIndoor->pSectors[uSectorID]; + + for (uint i = 0; i < pSector->uNumLights; ++i) + { + v16 = pIndoor->pLights + pSector->pLights[i]; + if (~v16->uAtributes & 8) + { + v17 = abs(v16->vPosition.x - x); + if (v17 <= v16->uRadius) + { + v42 = abs(v16->vPosition.y - y); + if (v42 <= v16->uRadius) + { + v39 = abs(v16->vPosition.z - z); + if (v39 <= v16->uRadius) + { + v44 = int_get_vector_length(v17, v42, v39); + v24 = v16->uRadius; + if ((signed int)v44 < v24) + v6 += ((unsigned __int64)(30i64 * (signed int)(v44 << 16) / v24) >> 16) - 30; + } + } + } + } + } + } + + for (uint i = 0; i < pStationaryLightsStack->uNumLightsActive; ++i) + { + //StationaryLight* p = &pStationaryLightsStack->pLights[i]; + v26 = abs(pStationaryLightsStack->pLights[i].vPosition.x - x); + if (v26 <= pStationaryLightsStack->pLights[i].uRadius) + { + v40 = abs(pStationaryLightsStack->pLights[i].vPosition.y - y); + if (v40 <= pStationaryLightsStack->pLights[i].uRadius) + { + v37 = abs(pStationaryLightsStack->pLights[i].vPosition.z - z); + if (v37 <= pStationaryLightsStack->pLights[i].uRadius) + { + v45 = int_get_vector_length(v26, v40, v37); + //v33 = pStationaryLightsStack->pLights[i].uRadius; + if ((signed int)v45 < pStationaryLightsStack->pLights[i].uRadius) + v6 += ((unsigned __int64)(30i64 * (signed int)(v45 << 16) / pStationaryLightsStack->pLights[i].uRadius) >> 16) - 30; + } + } + } + } + + if (v6 <= 31) + { + if (v6 < 0) + v6 = 0; + } + else + v6 = 31; + return v6; +} + +//----- (0049D700) -------------------------------------------------------- +unsigned int __fastcall GetMaxMipLevels(unsigned int uDim) +{ + int v2; // ecx@1 + unsigned int v3; // eax@1 + + v2 = 0; + v3 = uDim - 1; + while (v3 & 1) + { + v3 >>= 1; + ++v2; + } + return v3 == 0 ? v2 : 0; +} + +//----- (0046E44E) -------------------------------------------------------- +int _46E44E_collide_against_faces_and_portals(unsigned int b1) +{ + BLVSector *pSector; // edi@1 + signed int v2; // ebx@1 + BLVFace *pFace; // esi@2 + __int16 pNextSector; // si@10 + int pArrayNum; // ecx@12 + unsigned __int8 v6; // sf@12 + unsigned __int8 v7; // of@12 + int result; // eax@14 + //int v10; // ecx@15 + int pFloor; // eax@16 + int v15; // eax@24 + int v16; // edx@25 + int v17; // eax@29 + unsigned int v18; // eax@33 + int v21; // eax@35 + int v22; // ecx@36 + int v23; // eax@40 + unsigned int v24; // eax@44 + int a3; // [sp+10h] [bp-48h]@28 + int v26; // [sp+14h] [bp-44h]@15 + int i; // [sp+18h] [bp-40h]@1 + int a10; // [sp+1Ch] [bp-3Ch]@1 + int v29; // [sp+20h] [bp-38h]@14 + int v32; // [sp+2Ch] [bp-2Ch]@15 + int pSectorsArray[10]; // [sp+30h] [bp-28h]@1 + + pSector = &pIndoor->pSectors[stru_721530.uSectorID]; + i = 1; + a10 = b1; + pSectorsArray[0] = stru_721530.uSectorID; + for (v2 = 0; v2 < pSector->uNumPortals; ++v2) + { + pFace = &pIndoor->pFaces[pSector->pPortals[v2]]; + if (stru_721530.sMaxX <= pFace->pBounding.x2 && stru_721530.sMinX >= pFace->pBounding.x1 + && stru_721530.sMaxY <= pFace->pBounding.y2 && stru_721530.sMinY >= pFace->pBounding.y1 + && stru_721530.sMaxZ <= pFace->pBounding.z2 && stru_721530.sMinZ >= pFace->pBounding.z1 + && abs((pFace->pFacePlane_old.dist + + stru_721530.normal.x * pFace->pFacePlane_old.vNormal.x + + stru_721530.normal.y * pFace->pFacePlane_old.vNormal.y + + stru_721530.normal.z * pFace->pFacePlane_old.vNormal.z) >> 16) <= stru_721530.field_6C + 16) + { + pNextSector = pFace->uSectorID == stru_721530.uSectorID ? pFace->uBackSectorID : pFace->uSectorID;//FrontSectorID + pArrayNum = i++; + v7 = i < 10; + v6 = i - 10 < 0; + pSectorsArray[pArrayNum] = pNextSector; + if (!(v6 ^ v7)) + break; + } + } + result = 0; + for (v29 = 0; v29 < i; v29++) + { + pSector = &pIndoor->pSectors[pSectorsArray[v29]]; + v32 = pSector->uNumFloors + pSector->uNumWalls + pSector->uNumCeilings; + for (v26 = 0; v26 < v32; v26++) + { + pFloor = pSector->pFloors[v26]; + pFace = &pIndoor->pFaces[pSector->pFloors[v26]]; + if (!pFace->Portal() + && stru_721530.sMaxX <= pFace->pBounding.x2 && stru_721530.sMinX >= pFace->pBounding.x1 + && stru_721530.sMaxY <= pFace->pBounding.y2 && stru_721530.sMinY >= pFace->pBounding.y1 + && stru_721530.sMaxZ <= pFace->pBounding.z2 && stru_721530.sMinZ >= pFace->pBounding.z1 + && pFloor != stru_721530.field_84) + { + v15 = (pFace->pFacePlane_old.dist + stru_721530.normal.x * pFace->pFacePlane_old.vNormal.x + + stru_721530.normal.y * pFace->pFacePlane_old.vNormal.y + + stru_721530.normal.z * pFace->pFacePlane_old.vNormal.z) >> 16; + if (v15 > 0) + { + v16 = (pFace->pFacePlane_old.dist + stru_721530.normal2.x * pFace->pFacePlane_old.vNormal.x + + stru_721530.normal2.y * pFace->pFacePlane_old.vNormal.y + + stru_721530.normal2.z * pFace->pFacePlane_old.vNormal.z) >> 16; + if (v15 <= stru_721530.prolly_normal_d || v16 <= stru_721530.prolly_normal_d) + { + if (v16 <= v15) + { + a3 = stru_721530.field_6C; + if (sub_47531C(stru_721530.prolly_normal_d, &a3, stru_721530.normal.x, stru_721530.normal.y, stru_721530.normal.z, + stru_721530.direction.x, stru_721530.direction.y, stru_721530.direction.z, pFace, a10)) + { + v17 = a3; + } + else + { + a3 = stru_721530.field_6C + stru_721530.prolly_normal_d; + if (!sub_475D85(&stru_721530.normal, &stru_721530.direction, &a3, pFace)) + goto LABEL_34; + v17 = a3 - stru_721530.prolly_normal_d; + a3 -= stru_721530.prolly_normal_d; + } + if (v17 < stru_721530.field_7C) + { + stru_721530.field_7C = v17; + v18 = 8 * pSector->pFloors[v26]; + LOBYTE(v18) = v18 | 6; + stru_721530.uFaceID = v18; + } + } + } + } + LABEL_34: + if (!(stru_721530.field_0 & 1) + || (v21 = (pFace->pFacePlane_old.dist + stru_721530.position.x * pFace->pFacePlane_old.vNormal.x + + stru_721530.position.y * pFace->pFacePlane_old.vNormal.y + + stru_721530.position.z * pFace->pFacePlane_old.vNormal.z) >> 16, v21 <= 0) + || (v22 = (pFace->pFacePlane_old.dist + stru_721530.field_4C * pFace->pFacePlane_old.vNormal.x + + stru_721530.field_50 * pFace->pFacePlane_old.vNormal.y + + stru_721530.field_54 * pFace->pFacePlane_old.vNormal.z) >> 16, v21 > stru_721530.prolly_normal_d) + && v22 > stru_721530.prolly_normal_d || v22 > v21) + continue; + a3 = stru_721530.field_6C; + if (sub_47531C(stru_721530.field_8_radius, &a3, stru_721530.position.x, stru_721530.position.y, stru_721530.position.z, + stru_721530.direction.x, stru_721530.direction.y, stru_721530.direction.z, pFace, a10)) + { + v23 = a3; + goto LABEL_43; + } + a3 = stru_721530.field_6C + stru_721530.field_8_radius; + if (sub_475D85(&stru_721530.position, &stru_721530.direction, &a3, pFace)) + { + v23 = a3 - stru_721530.prolly_normal_d; + a3 -= stru_721530.prolly_normal_d; + LABEL_43: + if (v23 < stru_721530.field_7C) + { + stru_721530.field_7C = v23; + v24 = 8 * pSector->pFloors[v26]; + LOBYTE(v24) = v24 | 6; + stru_721530.uFaceID = v24; + } + } + } + } + result = v29 + 1; + } + return result; +} +// 46E44E: using guessed type int var_28[10]; + +//----- (0046E889) -------------------------------------------------------- +int __fastcall _46E889_collide_against_bmodels(unsigned int ecx0) +{ + int result; // eax@1 + //int v3; // ebx@9 + int v8; // eax@19 + int v9; // ecx@20 + int v10; // eax@24 + unsigned int v14; // eax@28 + int v15; // eax@30 + int v16; // ecx@31 + unsigned int v17; // eax@36 + int v21; // eax@42 + unsigned int v22; // eax@43 + //int a11; // [sp+70h] [bp-18h]@1 + //int a10; // [sp+80h] [bp-8h]@1 + int a2; // [sp+84h] [bp-4h]@23 + + //a11 = ecx0; + + BLVFace face; // [sp+Ch] [bp-7Ch]@1 + + result = 0; + for (uint i = 0; i < (signed int)pOutdoor->uNumBModels; ++i) + { + if (stru_721530.sMaxX <= pOutdoor->pBModels[i].sMaxX && stru_721530.sMinX >= pOutdoor->pBModels[i].sMinX + && stru_721530.sMaxY <= pOutdoor->pBModels[i].sMaxY && stru_721530.sMinY >= pOutdoor->pBModels[i].sMinY + && stru_721530.sMaxZ <= pOutdoor->pBModels[i].sMaxZ && stru_721530.sMinZ >= pOutdoor->pBModels[i].sMinZ) + { + for (uint j = 0; j < pOutdoor->pBModels[i].uNumFaces; ++j) + { + if (stru_721530.sMaxX <= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.x2 && stru_721530.sMinX >= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.x1 + && stru_721530.sMaxY <= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.y2 && stru_721530.sMinY >= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.y1 + && stru_721530.sMaxZ <= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.z2 && stru_721530.sMinZ >= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.z1) + { + face.pFacePlane_old.vNormal.x = pOutdoor->pBModels[i].pFaces[j].pFacePlane.vNormal.x; + face.pFacePlane_old.vNormal.y = pOutdoor->pBModels[i].pFaces[j].pFacePlane.vNormal.y; + face.pFacePlane_old.vNormal.z = pOutdoor->pBModels[i].pFaces[j].pFacePlane.vNormal.z; + + face.pFacePlane_old.dist = pOutdoor->pBModels[i].pFaces[j].pFacePlane.dist; //incorrect + + face.uAttributes = pOutdoor->pBModels[i].pFaces[j].uAttributes; + + face.pBounding.x1 = pOutdoor->pBModels[i].pFaces[j].pBoundingBox.x1; + face.pBounding.y1 = pOutdoor->pBModels[i].pFaces[j].pBoundingBox.y1; + face.pBounding.z1 = pOutdoor->pBModels[i].pFaces[j].pBoundingBox.z1; + + face.pBounding.x2 = pOutdoor->pBModels[i].pFaces[j].pBoundingBox.x2; + face.pBounding.y2 = pOutdoor->pBModels[i].pFaces[j].pBoundingBox.y2; + face.pBounding.z2 = pOutdoor->pBModels[i].pFaces[j].pBoundingBox.z2; + + face.zCalc1 = pOutdoor->pBModels[i].pFaces[j].zCalc1; + face.zCalc2 = pOutdoor->pBModels[i].pFaces[j].zCalc2; + face.zCalc3 = pOutdoor->pBModels[i].pFaces[j].zCalc3; + + face.pXInterceptDisplacements = pOutdoor->pBModels[i].pFaces[j].pXInterceptDisplacements; + face.pYInterceptDisplacements = pOutdoor->pBModels[i].pFaces[j].pYInterceptDisplacements; + face.pZInterceptDisplacements = pOutdoor->pBModels[i].pFaces[j].pZInterceptDisplacements; + + face.uPolygonType = (PolygonType)pOutdoor->pBModels[i].pFaces[j].uPolygonType; + + face.uNumVertices = pOutdoor->pBModels[i].pFaces[j].uNumVertices; + + face.uBitmapID = pOutdoor->pBModels[i].pFaces[j].uTextureID; + + face.pVertexIDs = pOutdoor->pBModels[i].pFaces[j].pVertexIDs; + + if (!face.Ethereal() && !face.Portal()) + { + v8 = (face.pFacePlane_old.dist + face.pFacePlane_old.vNormal.x * stru_721530.normal.x + + face.pFacePlane_old.vNormal.y * stru_721530.normal.y + + face.pFacePlane_old.vNormal.z * stru_721530.normal.z) >> 16; + if (v8 > 0) + { + v9 = (face.pFacePlane_old.dist + face.pFacePlane_old.vNormal.x * stru_721530.normal2.x + + face.pFacePlane_old.vNormal.y * stru_721530.normal2.y + + face.pFacePlane_old.vNormal.z * stru_721530.normal2.z) >> 16; + if (v8 <= stru_721530.prolly_normal_d || v9 <= stru_721530.prolly_normal_d) + { + if (v9 <= v8) + { + a2 = stru_721530.field_6C; + if (sub_4754BF(stru_721530.prolly_normal_d, &a2, stru_721530.normal.x, stru_721530.normal.y, stru_721530.normal.z, + stru_721530.direction.x, stru_721530.direction.y, stru_721530.direction.z, &face, i, ecx0)) + { + v10 = a2; + } + else + { + a2 = stru_721530.prolly_normal_d + stru_721530.field_6C; + if (!sub_475F30(&a2, &face, stru_721530.normal.x, stru_721530.normal.y, stru_721530.normal.z, + stru_721530.direction.x, stru_721530.direction.y, stru_721530.direction.z, i)) + goto LABEL_29; + v10 = a2 - stru_721530.prolly_normal_d; + a2 -= stru_721530.prolly_normal_d; + } + if (v10 < stru_721530.field_7C) + { + stru_721530.field_7C = v10; + v14 = 8 * (j | (i << 6)); + LOBYTE(v14) = v14 | 6; + stru_721530.uFaceID = v14; + } + } + } + } + LABEL_29: + if (stru_721530.field_0 & 1) + { + v15 = (face.pFacePlane_old.dist + face.pFacePlane_old.vNormal.x * stru_721530.position.x + + face.pFacePlane_old.vNormal.y * stru_721530.position.y + + face.pFacePlane_old.vNormal.z * stru_721530.position.z) >> 16; + if (v15 > 0) + { + v16 = (face.pFacePlane_old.dist + face.pFacePlane_old.vNormal.x * stru_721530.field_4C + + face.pFacePlane_old.vNormal.y * stru_721530.field_50 + + face.pFacePlane_old.vNormal.z * stru_721530.field_54) >> 16; + if (v15 <= stru_721530.prolly_normal_d || v16 <= stru_721530.prolly_normal_d) + { + if (v16 <= v15) + { + a2 = stru_721530.field_6C; + if (sub_4754BF(stru_721530.field_8_radius, &a2, stru_721530.position.x, stru_721530.position.y, stru_721530.position.z, + stru_721530.direction.x, stru_721530.direction.y, stru_721530.direction.z, &face, i, ecx0)) + { + if (a2 < stru_721530.field_7C) + { + stru_721530.field_7C = a2; + v17 = 8 * (j | (i << 6)); + LOBYTE(v17) = v17 | 6; + stru_721530.uFaceID = v17; + } + } + else + { + a2 = stru_721530.field_6C + stru_721530.field_8_radius; + if (sub_475F30(&a2, &face, stru_721530.position.x, stru_721530.position.y, stru_721530.position.z, + stru_721530.direction.x, stru_721530.direction.y, stru_721530.direction.z, i)) + { + v21 = a2 - stru_721530.prolly_normal_d; + a2 -= stru_721530.prolly_normal_d; + if (a2 < stru_721530.field_7C) + { + stru_721530.field_7C = v21; + v22 = 8 * (j | (i << 6)); + LOBYTE(v22) = v22 | 6; + stru_721530.uFaceID = v22; + } + } + } + } + } + } + } + } + } + } + } + result = i; + } + return result; +} + +//----- (0046ED1B) -------------------------------------------------------- +int collide_against_floor(int x, int y, int z, unsigned int *pSectorID, unsigned int *pFaceID) +{ + uint uFaceID = -1; + int floor_level = BLV_GetFloorLevel(x, y, z, *pSectorID, &uFaceID); + + if (floor_level != -30000 && floor_level <= z + 50) + { + *pFaceID = uFaceID; + return floor_level; + } + + uint uSectorID = pIndoor->GetSector(x, y, z); + *pSectorID = uSectorID; + + floor_level = BLV_GetFloorLevel(x, y, z, uSectorID, &uFaceID); + if (uSectorID && floor_level != -30000) + *pFaceID = uFaceID; + else return -30000; + return floor_level; +} + +//----- (0046ED8A) -------------------------------------------------------- +void __fastcall _46ED8A_collide_against_sprite_objects(unsigned int _this) +{ + ObjectDesc *object; // edx@4 + int v10; // ecx@12 + int v11; // esi@13 + + for (uint i = 0; i < uNumSpriteObjects; ++i) + { + if (pSpriteObjects[i].uObjectDescID) + { + object = &pObjectList->pObjects[pSpriteObjects[i].uObjectDescID]; + if (!(object->uFlags & OBJECT_DESC_NO_COLLISION)) + { + if (stru_721530.sMaxX <= pSpriteObjects[i].vPosition.x + object->uRadius && stru_721530.sMinX >= pSpriteObjects[i].vPosition.x - object->uRadius + && stru_721530.sMaxY <= pSpriteObjects[i].vPosition.y + object->uRadius && stru_721530.sMinY >= pSpriteObjects[i].vPosition.y - object->uRadius + && stru_721530.sMaxZ <= pSpriteObjects[i].vPosition.z + object->uHeight && stru_721530.sMinZ >= pSpriteObjects[i].vPosition.z) + { + if (abs(((pSpriteObjects[i].vPosition.x - stru_721530.normal.x) * stru_721530.direction.y + - (pSpriteObjects[i].vPosition.y - stru_721530.normal.y) * stru_721530.direction.x) >> 16) + <= object->uHeight + stru_721530.prolly_normal_d) + { + v10 = ((pSpriteObjects[i].vPosition.x - stru_721530.normal.x) * stru_721530.direction.x + + (pSpriteObjects[i].vPosition.y - stru_721530.normal.y) * stru_721530.direction.y) >> 16; + if (v10 > 0) + { + v11 = stru_721530.normal.z + ((unsigned __int64)(stru_721530.direction.z * (signed __int64)v10) >> 16); + if (v11 >= pSpriteObjects[i].vPosition.z - stru_721530.prolly_normal_d) + { + if (v11 <= object->uHeight + stru_721530.prolly_normal_d + pSpriteObjects[i].vPosition.z) + { + if (v10 < stru_721530.field_7C) + sub_46DEF2(_this, i); + } + } + } + } + } + } + } + } +} + +//----- (0046EF01) -------------------------------------------------------- +int _46EF01_collision_chech_player(int a1) +{ + int result; // eax@1 + int v3; // ebx@7 + int v4; // esi@7 + int v5; // edi@8 + int v6; // ecx@9 + int v7; // edi@12 + int v10; // [sp+14h] [bp-8h]@7 + int v11; // [sp+18h] [bp-4h]@7 + + result = pParty->vPosition.x; + //v9 = pParty->uPartyHeight; + if (stru_721530.sMaxX <= pParty->vPosition.x + (2 * pParty->field_14_radius) && stru_721530.sMinX >= pParty->vPosition.x - (2 * pParty->field_14_radius) + && stru_721530.sMaxY <= pParty->vPosition.y + (2 * pParty->field_14_radius) && stru_721530.sMinY >= pParty->vPosition.y - (2 * pParty->field_14_radius) + && stru_721530.sMaxZ <= pParty->vPosition.z + pParty->uPartyHeight && stru_721530.sMinZ >= pParty->vPosition.z) + { + v3 = stru_721530.prolly_normal_d + (2 * pParty->field_14_radius); + v11 = pParty->vPosition.x - stru_721530.normal.x; + v4 = ((pParty->vPosition.x - stru_721530.normal.x) * stru_721530.direction.y + - (pParty->vPosition.y - stru_721530.normal.y) * stru_721530.direction.x) >> 16; + v10 = pParty->vPosition.y - stru_721530.normal.y; + result = abs(((pParty->vPosition.x - stru_721530.normal.x) * stru_721530.direction.y + - (pParty->vPosition.y - stru_721530.normal.y) * stru_721530.direction.x) >> 16); + if (result <= stru_721530.prolly_normal_d + (2 * pParty->field_14_radius)) + { + result = v10 * stru_721530.direction.y; + v5 = (v10 * stru_721530.direction.y + v11 * stru_721530.direction.x) >> 16; + if (v5 > 0) + { + v6 = fixpoint_mul(stru_721530.direction.z, v5) + stru_721530.normal.z; + result = pParty->vPosition.z; + if (v6 >= pParty->vPosition.z) + { + result = pParty->uPartyHeight + pParty->vPosition.z; + if (v6 <= (signed int)(pParty->uPartyHeight + pParty->vPosition.z) || a1) + { + result = integer_sqrt(v3 * v3 - v4 * v4); + v7 = v5 - integer_sqrt(v3 * v3 - v4 * v4); + if (v7 < 0) + v7 = 0; + if (v7 < stru_721530.field_7C) + { + stru_721530.field_7C = v7; + stru_721530.uFaceID = 4; + } + } + } + } + } + } + return result; +} + +//----- (0046E0B2) -------------------------------------------------------- +void _46E0B2_collide_against_decorations() +{ + BLVSector *sector; // ebp@1 + LevelDecoration *decor; // edi@2 + DecorationDesc *decor_desc; // esi@3 + int v8; // ebx@10 + int v9; // esi@11 + int v11; // eax@12 + int v12; // esi@14 + unsigned int v13; // eax@17 + signed int i; // [sp+4h] [bp-14h]@1 + int v15; // [sp+8h] [bp-10h]@10 + int v16; // [sp+Ch] [bp-Ch]@10 + int v17; // [sp+10h] [bp-8h]@10 + + sector = &pIndoor->pSectors[stru_721530.uSectorID]; + for (i = 0; i < sector->uNumDecorations; ++i) + { + decor = &pLevelDecorations[sector->pDecorationIDs[i]]; + if (!(decor->uFlags & LEVEL_DECORATION_INVISIBLE)) + { + decor_desc = &pDecorationList->pDecorations[decor->uDecorationDescID]; + if (!decor_desc->CanMoveThrough()) + { + if (stru_721530.sMaxX <= decor->vPosition.x + decor_desc->uRadius && stru_721530.sMinX >= decor->vPosition.x - decor_desc->uRadius + && stru_721530.sMaxY <= decor->vPosition.y + decor_desc->uRadius && stru_721530.sMinY >= decor->vPosition.y - decor_desc->uRadius + && stru_721530.sMaxZ <= decor->vPosition.z + decor_desc->uDecorationHeight && stru_721530.sMinZ >= decor->vPosition.z) + { + v16 = decor->vPosition.x - stru_721530.normal.x; + v15 = decor->vPosition.y - stru_721530.normal.y; + v8 = stru_721530.prolly_normal_d + decor_desc->uRadius; + v17 = ((decor->vPosition.x - stru_721530.normal.x) * stru_721530.direction.y + - (decor->vPosition.y - stru_721530.normal.y) * stru_721530.direction.x) >> 16; + if (abs(v17) <= stru_721530.prolly_normal_d + decor_desc->uRadius) + { + v9 = (v16 * stru_721530.direction.x + v15 * stru_721530.direction.y) >> 16; + if (v9 > 0) + { + v11 = stru_721530.normal.z + fixpoint_mul(stru_721530.direction.z, v9); + if (v11 >= decor->vPosition.z) + { + if (v11 <= decor_desc->uDecorationHeight + decor->vPosition.z) + { + v12 = v9 - integer_sqrt(v8 * v8 - v17 * v17); + if (v12 < 0) + v12 = 0; + if (v12 < stru_721530.field_7C) + { + stru_721530.field_7C = v12; + v13 = 8 * sector->pDecorationIDs[i]; + LOBYTE(v13) = v13 | 5; + stru_721530.uFaceID = v13; + } + } + } + } + } + } + } + } + } +} + +//----- (0046F04E) -------------------------------------------------------- +int _46F04E_collide_against_portals() +{ + unsigned int v1; // eax@1 + BLVFace *face; // eax@3 + int v4; // ecx@9 + int v5; // edx@9 + signed int result; // eax@21 + unsigned int v10; // [sp+8h] [bp-Ch]@1 + int a3; // [sp+Ch] [bp-8h]@13 + int v12; // [sp+10h] [bp-4h]@15 + + v1 = 0xFFFFFFu; + v10 = 0xFFFFFFu; + for (uint i = 0; i < pIndoor->pSectors[stru_721530.uSectorID].uNumPortals; ++i) + { + if (pIndoor->pSectors[stru_721530.uSectorID].pPortals[i] != stru_721530.field_80) + { + face = &pIndoor->pFaces[pIndoor->pSectors[stru_721530.uSectorID].pPortals[i]]; + if (stru_721530.sMaxX <= face->pBounding.x2 && stru_721530.sMinX >= face->pBounding.x1 + && stru_721530.sMaxY <= face->pBounding.y2 && stru_721530.sMinY >= face->pBounding.y1 + && stru_721530.sMaxZ <= face->pBounding.z2 && stru_721530.sMinZ >= face->pBounding.z1) + { + v4 = (stru_721530.normal.x * face->pFacePlane_old.vNormal.x + face->pFacePlane_old.dist + + stru_721530.normal.y * face->pFacePlane_old.vNormal.y + + stru_721530.normal.z * face->pFacePlane_old.vNormal.z) >> 16; + v5 = (stru_721530.normal2.z * face->pFacePlane_old.vNormal.z + face->pFacePlane_old.dist + + stru_721530.normal2.x * face->pFacePlane_old.vNormal.x + + stru_721530.normal2.y * face->pFacePlane_old.vNormal.y) >> 16; + if ((v4 < stru_721530.prolly_normal_d || v5 < stru_721530.prolly_normal_d) + && (v4 > -stru_721530.prolly_normal_d || v5 > -stru_721530.prolly_normal_d) + && (a3 = stru_721530.field_6C, sub_475D85(&stru_721530.normal, &stru_721530.direction, &a3, face)) + && a3 < (signed int)v10) + { + v10 = a3; + v12 = pIndoor->pSectors[stru_721530.uSectorID].pPortals[i]; + } + } + } + } + v1 = v10; + if (stru_721530.field_7C >= (signed int)v1 && (signed int)v1 <= stru_721530.field_6C) + { + stru_721530.field_80 = v12; + if (pIndoor->pFaces[v12].uSectorID == stru_721530.uSectorID) + stru_721530.uSectorID = pIndoor->pFaces[v12].uBackSectorID; + else + stru_721530.uSectorID = pIndoor->pFaces[v12].uSectorID; + stru_721530.field_7C = 268435455; + result = 0; + } + else + result = 1; + return result; +} + +//----- (0046DEF2) -------------------------------------------------------- +unsigned int __fastcall sub_46DEF2(signed int a2, unsigned int uLayingItemID) +{ + unsigned int result; // eax@1 + + result = uLayingItemID; + if (pObjectList->pObjects[pSpriteObjects[uLayingItemID].uObjectDescID].uFlags & 0x10) + result = _46BFFA_check_object_intercept(uLayingItemID, a2); + return result; +} + +//----- (0047253E) -------------------------------------------------------- +void UpdateObjects() +{ + ObjectDesc *object; // eax@5 + int v5; // ecx@6 + signed int v7; // eax@9 + signed int v11; // eax@17 + int v12; // edi@27 + int v18; // [sp+4h] [bp-10h]@27 + int v19; // [sp+8h] [bp-Ch]@27 + + for (uint i = 0; i < uNumSpriteObjects; ++i) + { + if (pSpriteObjects[i].uAttributes & OBJECT_40) + pSpriteObjects[i].uAttributes &= ~OBJECT_40; + else + { + object = &pObjectList->pObjects[pSpriteObjects[i].uObjectDescID]; + if (pSpriteObjects[i].AttachedToActor()) + { + v5 = PID_ID(pSpriteObjects[i].spell_target_pid); + pSpriteObjects[i].vPosition.x = pActors[v5].vPosition.x; + pSpriteObjects[i].vPosition.y = pActors[v5].vPosition.y; + pSpriteObjects[i].vPosition.z = pActors[v5].vPosition.z + pActors[v5].uActorHeight; + if (!pSpriteObjects[i].uObjectDescID) + continue; + pSpriteObjects[i].uSpriteFrameID += pEventTimer->uTimeElapsed; + if (!(object->uFlags & OBJECT_DESC_TEMPORARY)) + continue; + if (pSpriteObjects[i].uSpriteFrameID >= 0) + { + v7 = object->uLifetime; + if (pSpriteObjects[i].uAttributes & ITEM_BROKEN) + v7 = pSpriteObjects[i].field_20; + if (pSpriteObjects[i].uSpriteFrameID < v7) + continue; + } + SpriteObject::OnInteraction(i); + continue; + } + if (pSpriteObjects[i].uObjectDescID) + { + pSpriteObjects[i].uSpriteFrameID += pEventTimer->uTimeElapsed; + if (object->uFlags & OBJECT_DESC_TEMPORARY) + { + if (pSpriteObjects[i].uSpriteFrameID < 0) + { + SpriteObject::OnInteraction(i); + continue; + } + v11 = object->uLifetime; + if (pSpriteObjects[i].uAttributes & ITEM_BROKEN) + v11 = pSpriteObjects[i].field_20; + } + if (!(object->uFlags & OBJECT_DESC_TEMPORARY) || pSpriteObjects[i].uSpriteFrameID < v11) + { + if (uCurrentlyLoadedLevelType == LEVEL_Indoor) + SpriteObject::UpdateObject_fn0_BLV(i); + else + SpriteObject::UpdateObject_fn0_ODM(i); + if (pParty->bTurnBasedModeOn != 1 || !(pSpriteObjects[i].uSectorID & 4)) + continue; + v12 = abs(pParty->vPosition.x - pSpriteObjects[i].vPosition.x); + v18 = abs(pParty->vPosition.y - pSpriteObjects[i].vPosition.y); + v19 = abs(pParty->vPosition.z - pSpriteObjects[i].vPosition.z); + if (int_get_vector_length(v12, v18, v19) <= 5120) + continue; + SpriteObject::OnInteraction(i); + continue; + } + if (!(object->uFlags & OBJECT_DESC_INTERACTABLE)) + { + SpriteObject::OnInteraction(i); + continue; + } + _46BFFA_check_object_intercept(i, PID(OBJECT_Item, i)); + } + } + } +} + +//----- (0047531C) -------------------------------------------------------- +bool sub_47531C(int a1, int *a2, int pos_x, int pos_y, int pos_z, int dir_x, int dir_y, int dir_z, BLVFace *face, int a10) +{ + int v11; // ST1C_4@3 + int v12; // edi@3 + int v13; // esi@3 + int v14; // edi@4 + signed __int64 v15; // qtt@6 + //__int16 v16; // si@7 + int a7a; // [sp+30h] [bp+18h]@7 + int a9b; // [sp+38h] [bp+20h]@3 + int a9a; // [sp+38h] [bp+20h]@3 + int a10b; // [sp+3Ch] [bp+24h]@3 + signed int a10a; // [sp+3Ch] [bp+24h]@4 + int a10c; // [sp+3Ch] [bp+24h]@5 + + if (a10 && face->Ethereal()) + return 0; + v11 = fixpoint_mul(dir_x, face->pFacePlane_old.vNormal.x); + a10b = fixpoint_mul(dir_y, face->pFacePlane_old.vNormal.y); + a9b = fixpoint_mul(dir_z, face->pFacePlane_old.vNormal.z); + v12 = v11 + a9b + a10b; + a9a = v11 + a9b + a10b; + v13 = (a1 << 16) + - pos_x * face->pFacePlane_old.vNormal.x + - pos_y * face->pFacePlane_old.vNormal.y + - pos_z * face->pFacePlane_old.vNormal.z + - face->pFacePlane_old.dist; + if (abs((a1 << 16) + - pos_x * face->pFacePlane_old.vNormal.x + - pos_y * face->pFacePlane_old.vNormal.y + - pos_z * face->pFacePlane_old.vNormal.z - face->pFacePlane_old.dist) >= a1 << 16) + { + a10c = abs(v13) >> 14; + if (a10c > abs(v12)) + return 0; + LODWORD(v15) = v13 << 16; + HIDWORD(v15) = v13 >> 16; + v14 = a1; + a10a = v15 / a9a; + } + else + { + a10a = 0; + v14 = abs(v13) >> 16; + } + //v16 = pos_y + ((unsigned int)fixpoint_mul(a10a, dir_y) >> 16); + LOWORD(a7a) = (short)pos_x + ((unsigned int)fixpoint_mul(a10a, dir_x) >> 16) - fixpoint_mul(v14, face->pFacePlane_old.vNormal.x); + HIWORD(a7a) = pos_y + ((unsigned int)fixpoint_mul(a10a, dir_y) >> 16) - fixpoint_mul(v14, face->pFacePlane_old.vNormal.y); + if (!sub_475665(face, a7a, (short)pos_z + ((unsigned int)fixpoint_mul(a10a, dir_z) >> 16) - fixpoint_mul(v14, face->pFacePlane_old.vNormal.z))) + return 0; + *a2 = a10a >> 16; + if (a10a >> 16 < 0) + *a2 = 0; + return 1; +} + + +//----- (004754BF) -------------------------------------------------------- +bool sub_4754BF(int a1, int *a2, int X, int Y, int Z, int dir_x, int dir_y, int dir_z, BLVFace *face, int a10, int a11) +{ + int v12; // ST1C_4@3 + int v13; // edi@3 + int v14; // esi@3 + int v15; // edi@4 + signed __int64 v16; // qtt@6 + //__int16 v17; // si@7 + int a7a; // [sp+30h] [bp+18h]@7 + int a1b; // [sp+38h] [bp+20h]@3 + int a1a; // [sp+38h] [bp+20h]@3 + int a11b; // [sp+40h] [bp+28h]@3 + signed int a11a; // [sp+40h] [bp+28h]@4 + int a11c; // [sp+40h] [bp+28h]@5 + + if (a11 && face->Ethereal()) + return false; + v12 = fixpoint_mul(dir_x, face->pFacePlane_old.vNormal.x); + a11b = fixpoint_mul(dir_y, face->pFacePlane_old.vNormal.y); + a1b = fixpoint_mul(dir_z, face->pFacePlane_old.vNormal.z); + v13 = v12 + a1b + a11b; + a1a = v12 + a1b + a11b; + v14 = (a1 << 16) + - X * face->pFacePlane_old.vNormal.x + - Y * face->pFacePlane_old.vNormal.y + - Z * face->pFacePlane_old.vNormal.z + - face->pFacePlane_old.dist; + if (abs((a1 << 16) + - X * face->pFacePlane_old.vNormal.x + - Y * face->pFacePlane_old.vNormal.y + - Z * face->pFacePlane_old.vNormal.z - face->pFacePlane_old.dist) >= a1 << 16) + { + a11c = abs(v14) >> 14; + if (a11c > abs(v13)) + return false; + LODWORD(v16) = v14 << 16; + HIDWORD(v16) = v14 >> 16; + v15 = a1; + a11a = v16 / a1a; + } + else + { + a11a = 0; + v15 = abs(v14) >> 16; + } + //v17 = Y + ((unsigned int)fixpoint_mul(a11a, dir_y) >> 16); + LOWORD(a7a) = (short)X + ((unsigned int)fixpoint_mul(a11a, dir_x) >> 16) - fixpoint_mul(v15, face->pFacePlane_old.vNormal.x); + HIWORD(a7a) = Y + ((unsigned int)fixpoint_mul(a11a, dir_y) >> 16) - fixpoint_mul(v15, face->pFacePlane_old.vNormal.y); + if (!sub_4759C9(face, a10, a7a, (short)Z + ((unsigned int)fixpoint_mul(a11a, dir_z) >> 16) - fixpoint_mul(v15, face->pFacePlane_old.vNormal.z))) + return false; + *a2 = a11a >> 16; + if (a11a >> 16 < 0) + *a2 = 0; + return true; +} + +//----- (00475665) -------------------------------------------------------- +int sub_475665(BLVFace *face, int a2, __int16 a3) +{ + bool v16; // edi@14 + signed int v20; // ebx@18 + int v21; // edi@20 + signed int v22; // ST14_4@22 + signed __int64 v23; // qtt@22 + signed int result; // eax@25 + int v25; // [sp+14h] [bp-10h]@14 + int v26; // [sp+1Ch] [bp-8h]@2 + signed int v27; // [sp+20h] [bp-4h]@2 + signed int v28; // [sp+30h] [bp+Ch]@2 + signed int v29; // [sp+30h] [bp+Ch]@7 + signed int v30; // [sp+30h] [bp+Ch]@11 + signed int v31; // [sp+30h] [bp+Ch]@14 + + if (face->uAttributes & FACE_XY_PLANE) + { + v26 = (signed __int16)a2; + v27 = SHIWORD(a2); + if (face->uNumVertices) + { + for (v28 = 0; v28 < face->uNumVertices; v28++) + { + word_720C10_intercepts_xs[2 * v28] = face->pXInterceptDisplacements[v28] + pIndoor->pVertices[face->pVertexIDs[v28]].x; + word_720B40_intercepts_zs[2 * v28] = face->pYInterceptDisplacements[v28] + pIndoor->pVertices[face->pVertexIDs[v28]].y; + word_720C10_intercepts_xs[2 * v28 + 1] = face->pXInterceptDisplacements[v28 + 1] + pIndoor->pVertices[face->pVertexIDs[v28 + 1]].x; + word_720B40_intercepts_zs[2 * v28 + 1] = face->pYInterceptDisplacements[v28 + 1] + pIndoor->pVertices[face->pVertexIDs[v28 + 1]].y; + } + } + } + else + { + if (face->uAttributes & FACE_XZ_PLANE) + { + v26 = (signed __int16)a2; + v27 = a3; + if (face->uNumVertices) + { + for (v29 = 0; v29 < face->uNumVertices; v29++) + { + word_720C10_intercepts_xs[2 * v29] = face->pXInterceptDisplacements[v29] + pIndoor->pVertices[face->pVertexIDs[v29]].x; + word_720B40_intercepts_zs[2 * v29] = face->pZInterceptDisplacements[v29] + pIndoor->pVertices[face->pVertexIDs[v29]].z; + word_720C10_intercepts_xs[2 * v29 + 1] = face->pXInterceptDisplacements[v29 + 1] + pIndoor->pVertices[face->pVertexIDs[v29 + 1]].x; + word_720B40_intercepts_zs[2 * v29 + 1] = face->pZInterceptDisplacements[v29 + 1] + pIndoor->pVertices[face->pVertexIDs[v29 + 1]].z; + } + } + } + else + { + v26 = SHIWORD(a2); + v27 = a3; + if (face->uNumVertices) + { + for (v30 = 0; v30 < face->uNumVertices; v30++) + { + word_720C10_intercepts_xs[2 * v30] = face->pYInterceptDisplacements[v30] + pIndoor->pVertices[face->pVertexIDs[v30]].y; + word_720B40_intercepts_zs[2 * v30] = face->pZInterceptDisplacements[v30] + pIndoor->pVertices[face->pVertexIDs[v30]].z; + word_720C10_intercepts_xs[2 * v30 + 1] = face->pYInterceptDisplacements[v30 + 1] + pIndoor->pVertices[face->pVertexIDs[v30 + 1]].y; + word_720B40_intercepts_zs[2 * v30 + 1] = face->pZInterceptDisplacements[v30 + 1] + pIndoor->pVertices[face->pVertexIDs[v30 + 1]].z; + } + } + } + } + v31 = 0; + word_720C10_intercepts_xs[2 * face->uNumVertices] = word_720C10_intercepts_xs[0]; + word_720B40_intercepts_zs[2 * face->uNumVertices] = word_720B40_intercepts_zs[0]; + v16 = word_720B40_intercepts_zs[0] >= v27; + if (2 * face->uNumVertices <= 0) + return 0; + for (v25 = 0; v25 < 2 * face->uNumVertices; ++v25) + { + if (v31 >= 2) + break; + if (v16 ^ (word_720B40_intercepts_zs[v25 + 1] >= v27)) + { + if (word_720C10_intercepts_xs[v25 + 1] >= v26) + v20 = 0; + else + v20 = 2; + v21 = v20 | (word_720C10_intercepts_xs[v25] < v26); + if (v21 != 3) + { + v22 = word_720C10_intercepts_xs[v25 + 1] - word_720C10_intercepts_xs[v25]; + LODWORD(v23) = v22 << 16; + HIDWORD(v23) = v22 >> 16; + if (!v21 + || (word_720C10_intercepts_xs[v25] + ((signed int)(((unsigned __int64)(v23 + / (word_720B40_intercepts_zs[v25 + 1] - word_720B40_intercepts_zs[v25]) + * ((v27 - (signed int)word_720B40_intercepts_zs[v25]) << 16)) >> 16) + + 32768) >> 16) >= v26)) + ++v31; + } + } + v16 = word_720B40_intercepts_zs[v25 + 1] >= v27; + } + result = 1; + if (v31 != 1) + result = 0; + return result; +} + +//----- (004759C9) -------------------------------------------------------- +bool __fastcall sub_4759C9(BLVFace *face, int a2, int a3, __int16 a4) +{ + bool v12; // edi@14 + signed int v16; // ebx@18 + int v17; // edi@20 + signed int v18; // ST14_4@22 + signed __int64 v19; // qtt@22 + bool result; // eax@25 + int v21; // [sp+14h] [bp-10h]@14 + signed int v22; // [sp+18h] [bp-Ch]@1 + int v23; // [sp+1Ch] [bp-8h]@2 + signed int v24; // [sp+20h] [bp-4h]@2 + signed int a4d; // [sp+30h] [bp+Ch]@14 + + if (face->uAttributes & FACE_XY_PLANE) + { + v23 = (signed __int16)a3; + v24 = SHIWORD(a3); + if (face->uNumVertices) + { + for (v22 = 0; v22 < face->uNumVertices; ++v22) + { + word_720A70_intercepts_xs_plus_xs[2 * v22] = face->pXInterceptDisplacements[v22] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22]].x); + word_7209A0_intercepts_ys_plus_ys[2 * v22] = face->pYInterceptDisplacements[v22] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22]].y); + word_720A70_intercepts_xs_plus_xs[2 * v22 + 1] = face->pXInterceptDisplacements[v22 + 1] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22 + 1]].x); + word_7209A0_intercepts_ys_plus_ys[2 * v22 + 1] = face->pYInterceptDisplacements[v22 + 1] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22 + 1]].y); + } + } + } + else + { + if (face->uAttributes & FACE_XZ_PLANE) + { + v23 = (signed __int16)a3; + v24 = a4; + if (face->uNumVertices) + { + for (v22 = 0; v22 < face->uNumVertices; ++v22) + { + word_720A70_intercepts_xs_plus_xs[2 * v22] = face->pXInterceptDisplacements[v22] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22]].x); + word_7209A0_intercepts_ys_plus_ys[2 * v22] = face->pZInterceptDisplacements[v22] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22]].z); + word_720A70_intercepts_xs_plus_xs[2 * v22 + 1] = face->pXInterceptDisplacements[v22 + 1] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22 + 1]].x); + word_7209A0_intercepts_ys_plus_ys[2 * v22 + 1] = face->pZInterceptDisplacements[v22 + 1] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22 + 1]].z); + } + } + } + else + { + v23 = SHIWORD(a3); + v24 = a4; + if (face->uNumVertices) + { + for (v22 = 0; v22 < face->uNumVertices; ++v22) + { + word_720A70_intercepts_xs_plus_xs[2 * v22] = face->pYInterceptDisplacements[v22] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22]].y); + word_7209A0_intercepts_ys_plus_ys[2 * v22] = face->pZInterceptDisplacements[v22] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22]].z); + word_720A70_intercepts_xs_plus_xs[2 * v22 + 1] = face->pYInterceptDisplacements[v22 + 1] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22 + 1]].y); + word_7209A0_intercepts_ys_plus_ys[2 * v22 + 1] = face->pZInterceptDisplacements[v22 + 1] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22 + 1]].z); + } + } + } + } + a4d = 0; + word_720A70_intercepts_xs_plus_xs[2 * face->uNumVertices] = word_720A70_intercepts_xs_plus_xs[0]; + word_7209A0_intercepts_ys_plus_ys[2 * face->uNumVertices] = word_7209A0_intercepts_ys_plus_ys[0]; + v12 = word_7209A0_intercepts_ys_plus_ys[0] >= v24; + if (2 * face->uNumVertices <= 0) + return 0; + for (v21 = 0; v21 < 2 * face->uNumVertices; ++v21) + { + if (a4d >= 2) + break; + if (v12 ^ (word_7209A0_intercepts_ys_plus_ys[v21 + 1] >= v24)) + { + if (word_720A70_intercepts_xs_plus_xs[v21 + 1] >= v23) + v16 = 0; + else + v16 = 2; + v17 = v16 | (word_720A70_intercepts_xs_plus_xs[v21] < v23); + if (v17 != 3) + { + v18 = word_720A70_intercepts_xs_plus_xs[v21 + 1] - word_720A70_intercepts_xs_plus_xs[v21]; + LODWORD(v19) = v18 << 16; + HIDWORD(v19) = v18 >> 16; + if (!v17 + || (word_720A70_intercepts_xs_plus_xs[v21] + ((signed int)(((unsigned __int64)(v19 + / (word_7209A0_intercepts_ys_plus_ys[v21 + 1] - word_7209A0_intercepts_ys_plus_ys[v21]) + * ((v24 - (signed int)word_7209A0_intercepts_ys_plus_ys[v21]) << 16)) >> 16) + + 0x8000) >> 16) >= v23)) + ++a4d; + } + } + v12 = word_7209A0_intercepts_ys_plus_ys[v21 + 1] >= v24; + } + result = 1; + if (a4d != 1) + result = 0; + return result; +} + +//----- (00475D85) -------------------------------------------------------- +bool __fastcall sub_475D85(Vec3_int_ *a1, Vec3_int_ *a2, int *a3, BLVFace *a4) +{ + BLVFace *v4; // ebx@1 + int v5; // ST24_4@2 + int v6; // ST28_4@2 + int v7; // edi@2 + int v8; // eax@5 + signed int v9; // esi@5 + signed __int64 v10; // qtt@10 + Vec3_int_ *v11; // esi@11 + int v12; // ST14_4@11 + Vec3_int_ *v14; // [sp+Ch] [bp-18h]@1 + Vec3_int_ *v15; // [sp+14h] [bp-10h]@1 + // int v16; // [sp+18h] [bp-Ch]@2 + int v17; // [sp+20h] [bp-4h]@10 + int a4b; // [sp+30h] [bp+Ch]@2 + int a4c; // [sp+30h] [bp+Ch]@9 + signed int a4a; // [sp+30h] [bp+Ch]@10 + + v4 = a4; + v15 = a2; + v14 = a1; + v5 = fixpoint_mul(a2->x, a4->pFacePlane_old.vNormal.x); + a4b = fixpoint_mul(a2->y, a4->pFacePlane_old.vNormal.y); + v6 = fixpoint_mul(a2->z, v4->pFacePlane_old.vNormal.z); + v7 = v5 + v6 + a4b; + //(v16 = v5 + v6 + a4b) == 0; + if (a4->uAttributes & FACE_ETHEREAL || !v7 || v7 > 0 && !v4->Portal()) + return 0; + v8 = v4->pFacePlane_old.vNormal.z * a1->z; + v9 = -(v4->pFacePlane_old.dist + v8 + a1->y * v4->pFacePlane_old.vNormal.y + a1->x * v4->pFacePlane_old.vNormal.x); + if (v7 <= 0) + { + if (v4->pFacePlane_old.dist + v8 + a1->y * v4->pFacePlane_old.vNormal.y + a1->x * v4->pFacePlane_old.vNormal.x < 0) + return 0; + } + else + { + if (v9 < 0) + return 0; + } + a4c = abs(-(v4->pFacePlane_old.dist + v8 + a1->y * v4->pFacePlane_old.vNormal.y + a1->x * v4->pFacePlane_old.vNormal.x)) >> 14; + v11 = v14; + LODWORD(v10) = v9 << 16; + HIDWORD(v10) = v9 >> 16; + a4a = v10 / v7; + v17 = v10 / v7; + LOWORD(v12) = LOWORD(v14->x) + (((unsigned int)fixpoint_mul(v17, v15->x) + 0x8000) >> 16); + HIWORD(v12) = LOWORD(v11->y) + (((unsigned int)fixpoint_mul(v17, v15->y) + 0x8000) >> 16); + if (a4c > abs(v7) || (v17 > *a3 << 16) || !sub_475665(v4, v12, LOWORD(v11->z) + (((unsigned int)fixpoint_mul(v17, v15->z) + 0x8000) >> 16))) + return 0; + *a3 = a4a >> 16; + return 1; +} + +//----- (00475F30) -------------------------------------------------------- +bool __fastcall sub_475F30(int *a1, BLVFace *a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9) +{ + int v10; // ST20_4@2 + int v11; // ST28_4@2 + int v12; // ST24_4@2 + int v13; // zf@2 + int v14; // edi@2 + signed int v16; // esi@5 + int v17; // ST20_4@9 + signed __int64 v18; // qtt@10 + int v19; // ST14_4@11 + int v22; // [sp+1Ch] [bp-8h]@2 + int v23; // [sp+1Ch] [bp-8h]@10 + signed int v24; // [sp+20h] [bp-4h]@10 + + v10 = fixpoint_mul(a6, a2->pFacePlane_old.vNormal.x); + v11 = fixpoint_mul(a7, a2->pFacePlane_old.vNormal.y); + v12 = fixpoint_mul(a8, a2->pFacePlane_old.vNormal.z); + v13 = v10 + v12 + v11; + v14 = v10 + v12 + v11; + v22 = v10 + v12 + v11; + if (a2->Ethereal() || !v13 || v14 > 0 && !a2->Portal()) + return 0; + v16 = -(a2->pFacePlane_old.dist + a4 * a2->pFacePlane_old.vNormal.y + a3 * a2->pFacePlane_old.vNormal.x + a5 * a2->pFacePlane_old.vNormal.z); + if (v14 <= 0) + { + if (a2->pFacePlane_old.dist + a4 * a2->pFacePlane_old.vNormal.y + a3 * a2->pFacePlane_old.vNormal.x + a5 * a2->pFacePlane_old.vNormal.z < 0) + return 0; + } + else + { + if (v16 < 0) + return 0; + } + v17 = abs(-(a2->pFacePlane_old.dist + a4 * a2->pFacePlane_old.vNormal.y + a3 * a2->pFacePlane_old.vNormal.x + a5 * a2->pFacePlane_old.vNormal.z)) >> 14; + LODWORD(v18) = v16 << 16; + HIDWORD(v18) = v16 >> 16; + v24 = v18 / v22; + v23 = v18 / v22; + LOWORD(v19) = a3 + (((unsigned int)fixpoint_mul(v23, a6) + 0x8000) >> 16); + HIWORD(v19) = a4 + (((unsigned int)fixpoint_mul(v23, a7) + 0x8000) >> 16); + if (v17 > abs(v14) || v23 > *a1 << 16 || !sub_4759C9(a2, a9, v19, a5 + (((unsigned int)fixpoint_mul(v23, a8) + 0x8000) >> 16))) + return 0; + *a1 = v24 >> 16; + return 1; +} + +//----- (00479089) -------------------------------------------------------- +bool __fastcall IsBModelVisible(unsigned int uModelID, int *reachable) +{ + int v3; // edi@1 + int v4; // ebx@1 + int v9; // eax@3 + signed int v11; // esi@6 + int v12; // esi@8 + bool result; // eax@9 + int v17; // [sp+1Ch] [bp-10h]@1 + int v19; // [sp+20h] [bp-Ch]@3 + int angle; // [sp+24h] [bp-8h]@1 + + angle = (signed int)(pODMRenderParams->uCameraFovInDegrees << 11) / 360 / 2; + v3 = pOutdoor->pBModels[uModelID].vBoundingCenter.x - pGame->pIndoorCameraD3D->vPartyPos.x; + v4 = pOutdoor->pBModels[uModelID].vBoundingCenter.y - pGame->pIndoorCameraD3D->vPartyPos.y; + stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationX); + v17 = v3 * stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationY) + v4 * stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationY); + if (pGame->pIndoorCameraD3D->sRotationX) + v17 = fixpoint_mul(v17, stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationX)); + v19 = v4 * stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationY) - v3 * stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationY); + v9 = int_get_vector_length(abs(v3), abs(v4), 0); + //v10 = v14 * 188; + //v22 = v9; + *reachable = false; + if (v9 < pOutdoor->pBModels[uModelID].sBoundingRadius + 256) + *reachable = true; + if (v19 >= 0) + v11 = fixpoint_mul(stru_5C6E00->Sin(angle), v17) - fixpoint_mul(stru_5C6E00->Cos(angle), v19); + else + v11 = fixpoint_mul(stru_5C6E00->Cos(angle), v19) + fixpoint_mul(stru_5C6E00->Sin(angle), v17); + v12 = v11 >> 16; + if (v9 <= pODMRenderParams->shading_dist_mist + 2048) + { + //if ( abs(v12) > *(int *)((char *)&pOutdoor->pBModels->sBoundingRadius + v10) + 512 ) + if (abs(v12) > pOutdoor->pBModels[uModelID].sBoundingRadius + 512) + { + result = v12 < 0; + LOBYTE(result) = v12 >= 0; + return result; + } + else + return true; + } + return false; +} + +//----- (00479295) -------------------------------------------------------- +int Polygon::_479295() +{ + int v3; // ecx@4 + int v4; // eax@4 + int v5; // edx@4 + // int v6; // ST14_4@5 + Vec3_int_ thisa; // [sp+Ch] [bp-10h]@8 + int v11; // [sp+18h] [bp-4h]@4 + + if (!this->pODMFace->pFacePlane.vNormal.z) + { + v3 = this->pODMFace->pFacePlane.vNormal.x; + v4 = -this->pODMFace->pFacePlane.vNormal.y; + v5 = 0; + v11 = 65536; + } + else if ((this->pODMFace->pFacePlane.vNormal.x || this->pODMFace->pFacePlane.vNormal.y) + && abs(this->pODMFace->pFacePlane.vNormal.z) < 59082) + { + thisa.x = -this->pODMFace->pFacePlane.vNormal.y; + thisa.y = this->pODMFace->pFacePlane.vNormal.x; + thisa.z = 0; + thisa.Normalize_float(); + v4 = thisa.x; + v3 = thisa.y; + v5 = 0; + v11 = 65536; + } + else + { + v3 = 0; + v4 = 65536; + v11 = 0; + v5 = -65536; + } + sTextureDeltaU = this->pODMFace->sTextureDeltaU; + sTextureDeltaV = this->pODMFace->sTextureDeltaV; + ptr_38->_48616B_frustum_odm(v4, v3, 0, 0, v5, v11); + return 1; +} + + +unsigned short *LoadTgaTexture(const wchar_t *filename, int *out_width = nullptr, int *out_height = nullptr) +{ +#pragma pack(push, 1) + struct TGAHeader + { + unsigned char tgaSkip; + unsigned char colourmaptype; // type of colour map 0=none, 1=has palette + unsigned char tgaType; // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed + + short colourmapstart; // first colour map entry in palette + short colourmaplength; // number of colours in palette + char colourmapbits; // number of bits per palette entry 15,16,24,32 + + //unsigned char tgaDontCare2[9]; + short xstart; // image x origin + short ystart; // image y origin + + unsigned short tgaWidth; + unsigned short tgaHeight; + unsigned char tgaBPP; + + char descriptor; // image descriptor bits: 00vhaaaa + // h horizontal flip + // v vertical flip + // a alpha bits + }; +#pragma pack(pop) + + if (out_width) + *out_width = 0; + if (out_height) + *out_height = 0; + + DWORD w; + void* file = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr); + if (file == INVALID_HANDLE_VALUE) + return nullptr; + + TGAHeader header; + ReadFile(file, &header, sizeof(header), &w, nullptr); + SetFilePointer(file, header.tgaSkip, nullptr, FILE_CURRENT); + + if (header.tgaBPP != 24 || header.tgaType != 2) + { + CloseHandle(file); + return nullptr; + } + + int imgSize = header.tgaWidth * header.tgaHeight * 3; + unsigned char* pixels = new unsigned char[imgSize]; + ReadFile(file, pixels, imgSize, &w, nullptr); + CloseHandle(file); + + if (w != imgSize) + { + delete[] pixels; + return nullptr; + } + + if (out_width) + *out_width = header.tgaWidth; + if (out_height) + *out_height = header.tgaHeight; + + unsigned short* pixels_16bit = new unsigned short[imgSize / 3]; + for (int i = 0; i < imgSize / 3; ++i) + { + pixels_16bit[i] = (pixels[i * 3] / 8 & 0x1F) | + ((pixels[i * 3 + 1] / 4 & 0x3F) << 5) | + ((pixels[i * 3 + 2] / 8 & 0x1F) << 11); + } + delete[] pixels; + return pixels_16bit; +} + +unsigned short *skybox_xn, *skybox_xp, +*skybox_yn, *skybox_yp, +*skybox_zn, *skybox_zp; +int skybox_width, skybox_height; + +IDirect3DTexture2 *skybox_texture; +IDirectDrawSurface4 *skybox_surface; + +bool Skybox_Initialize(const wchar_t *skybox_name) +{ + wchar_t xn_filename[1024], xp_filename[1024], + yn_filename[1024], yp_filename[1024], + zn_filename[1024], zp_filename[1024]; + swprintf(xn_filename, wcslen(L"%s_xn.tga"), L"%s_xn.tga", skybox_name); swprintf(xp_filename, wcslen(L"%s_xp.tga"), L"%s_xp.tga", skybox_name); + swprintf(yn_filename, wcslen(L"%s_yn.tga"), L"%s_yn.tga", skybox_name); swprintf(yp_filename, wcslen(L"%s_yp.tga"), L"%s_yp.tga", skybox_name); + swprintf(zn_filename, wcslen(L"%s_zn.tga"), L"%s_zn.tga", skybox_name); swprintf(zp_filename, wcslen(L"%s_zp.tga"), L"%s_zp.tga", skybox_name); + + int xn_width, xn_height; + skybox_xn = LoadTgaTexture(xn_filename, &xn_width, &xn_height); + if (!skybox_xn) + return false; + + int xp_width, xp_height; + skybox_xp = LoadTgaTexture(xp_filename, &xp_width, &xp_height); + if (!skybox_xp || xp_width != xn_width || xp_height != xn_height) + { + delete[] skybox_xn; + delete[] skybox_xp; + return false; + } + + int yn_width, yn_height; + skybox_yn = LoadTgaTexture(yn_filename, &yn_width, &yn_height); + if (!skybox_yn || yn_width != xn_width || yn_height != xn_height) + { + delete[] skybox_xn; + delete[] skybox_xp; + delete[] skybox_yn; + return false; + } + + int yp_width, yp_height; + skybox_yp = LoadTgaTexture(yp_filename, &yp_width, &yp_height); + if (!skybox_yp || yp_width != xn_width || yp_height != xn_height) + { + delete[] skybox_xn; + delete[] skybox_xp; + delete[] skybox_yn; + delete[] skybox_yp; + return false; + } + + int zn_width, zn_height; + skybox_zn = LoadTgaTexture(zn_filename, &zn_width, &zn_height); + if (!skybox_zn || zn_width != xn_width || zn_height != xn_height) + { + delete[] skybox_xn; + delete[] skybox_xp; + delete[] skybox_yn; + delete[] skybox_yp; + delete[] skybox_zn; + return false; + } + + int zp_width, zp_height; + skybox_zp = LoadTgaTexture(zp_filename, &zp_width, &zp_height); + if (!skybox_zp || zp_width != xn_width || zp_height != xn_height) + { + delete[] skybox_xn; + delete[] skybox_xp; + delete[] skybox_yn; + delete[] skybox_yp; + delete[] skybox_zn; + delete[] skybox_zp; + return false; + } + + skybox_width = xn_width; + skybox_height = xn_height; + + __debugbreak(); + //if (!pRenderer->pRenderD3D->CreateTexture(skybox_width, skybox_height, &skybox_surface, &skybox_texture, + //false, false, pRenderer->uMinDeviceTextureDim)) + return false; + + return true; +} + +struct vector +{ + float x, y, z; +}; + +struct matrix +{ + float m[4][4]; +}; + +void VectorNormalize(vector *v) +{ + float invmag = 1.0f / sqrtf(v->x * v->x + v->y * v->y + v->z * v->z); + v->x *= invmag; + v->y *= invmag; + v->z *= invmag; +} + +void MatrixRotationAxis(matrix *pout, CONST vector *pv, float angle) +{ + memset(pout, 0, sizeof(matrix)); + pout->m[3][0] = 0; + pout->m[3][1] = 0; + pout->m[3][2] = 0; + pout->m[3][3] = 1; + + vector v; + v.x = pv->x; v.y = pv->y; v.z = pv->z; + VectorNormalize(&v); + + pout->m[0][0] = (1.0f - cos(angle)) * v.x * v.x + cos(angle); + pout->m[1][0] = (1.0f - cos(angle)) * v.x * v.y - sin(angle) * v.z; + pout->m[2][0] = (1.0f - cos(angle)) * v.x * v.z + sin(angle) * v.y; + pout->m[0][1] = (1.0f - cos(angle)) * v.y * v.x + sin(angle) * v.z; + pout->m[1][1] = (1.0f - cos(angle)) * v.y * v.y + cos(angle); + pout->m[2][1] = (1.0f - cos(angle)) * v.y * v.z - sin(angle) * v.x; + pout->m[0][2] = (1.0f - cos(angle)) * v.z * v.x - sin(angle) * v.y; + pout->m[1][2] = (1.0f - cos(angle)) * v.z * v.y + sin(angle) * v.x; + pout->m[2][2] = (1.0f - cos(angle)) * v.z * v.z + cos(angle); +} + +void VectorTransform(const matrix *m, const vector *v, vector *out) +{ + out->x = m->m[0][0] * v->x + m->m[1][0] * v->y + m->m[2][0] * v->z + m->m[3][0]; + out->y = m->m[0][1] * v->x + m->m[1][1] * v->y + m->m[2][1] * v->z + m->m[3][1]; + out->z = m->m[0][2] * v->x + m->m[1][2] * v->y + m->m[2][2] * v->z + m->m[3][2]; +} + +bool DrawSkyD3D_Skybox() +{ + static bool initialized = false, + initialization_failed = false; + if (initialization_failed) + return false; + + static int last_camera_rot_y, + last_camera_rot_x; + if (!initialized) + { + if (!Skybox_Initialize(L"data/skybox/stars")) + { + initialization_failed = true; + return false; + } + initialized = true; + + last_camera_rot_y = pParty->sRotationY + 1; // force update for the first run + last_camera_rot_x = pParty->sRotationX + 1; + } + + /* + r(y) = + cos y 0 sin y 0 + 0 1 0 0 + -sin y 0 cos y 0 + 0 0 0 1 + + x cos y - z sin y + y + x sin y + z cos y + 1 + + + + r(x) = // should be r(right) actually + 1 0 0 0 + 0 cos x -sin x 0 + 0 sin x cos x 0 + 0 0 0 1 + + + x + y cos x + z sin x + -y sin x + z cos x + 1 + + */ + + if (last_camera_rot_y == pParty->sRotationY && + last_camera_rot_x == pParty->sRotationX) + { + draw: + struct RenderVertexD3D3 v[6]; + + v[0].pos.x = pViewport->uScreen_TL_X; + v[0].pos.y = pViewport->uScreen_TL_Y; + v[0].pos.z = 0.99989998; + v[0].rhw = 1; + v[0].diffuse = -1; + v[0].specular = 0; + v[0].texcoord.x = 0; + v[0].texcoord.y = 0; + + v[1].pos.x = pViewport->uScreen_TL_X + pViewport->uScreenWidth; + v[1].pos.y = pViewport->uScreen_TL_Y + pViewport->uScreenHeight; + v[1].pos.z = 0.99989998; + v[1].rhw = 1; + v[1].diffuse = -1; + v[1].specular = 0; + v[1].texcoord.x = (float)pViewport->uScreenWidth / skybox_width; + v[1].texcoord.y = (float)pViewport->uScreenHeight / skybox_height; + + v[2].pos.x = pViewport->uScreen_TL_X + pViewport->uScreenWidth; + v[2].pos.y = pViewport->uScreen_TL_Y; + v[2].pos.z = 0.99989998; + v[2].rhw = 1; + v[2].diffuse = -1; + v[2].specular = 0; + v[2].texcoord.x = (float)pViewport->uScreenWidth / skybox_width; + v[2].texcoord.y = 0; + + memcpy(&v[3], &v[0], sizeof(*v)); + + v[4].pos.x = pViewport->uScreen_TL_X; + v[4].pos.y = pViewport->uScreen_TL_Y + pViewport->uScreenHeight; + v[4].pos.z = 0.99989998; + v[4].rhw = 1; + v[4].diffuse = -1; + v[4].specular = 0; + v[4].texcoord.x = 0; + v[4].texcoord.y = (float)pViewport->uScreenHeight / skybox_height; + + memcpy(&v[5], &v[1], sizeof(*v)); + + __debugbreak(); + /* + pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE); + pRenderer->pRenderD3D->pDevice->SetTexture(0, skybox_texture); + pRenderer->pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, v, 6, D3DDP_DONOTUPDATEEXTENTS | D3DDP_DONOTLIGHT); + */ + return true; + } + + + DDSURFACEDESC2 desc; + desc.dwSize = sizeof(desc); + if (!pRenderer->LockSurface_DDraw4(skybox_surface, &desc, DDLOCK_WAIT | DDLOCK_WRITEONLY)) + return false; + + last_camera_rot_y = pParty->sRotationY; + last_camera_rot_x = pParty->sRotationX; + + float aspect = (float)pViewport->uScreenWidth / (float)pViewport->uScreenHeight; + float fov_x = 3.141592f * (pODMRenderParams->uCameraFovInDegrees + 0) / 360.0f; + float fov_y = fov_x / aspect; + + float ray_dx = fov_x / (float)pViewport->uScreenWidth, + ray_dy = fov_y / (float)pViewport->uScreenHeight; + float party_angle_x = 2 * 3.141592653589 * pParty->sRotationX / 2048.0, + party_angle_y = 2 * 3.141592653589 * pParty->sRotationY / 2048.0; + for (int y = 0; y < pViewport->uScreenHeight; ++y) + for (int x = 0; x < pViewport->uScreenWidth; ++x) + { + float angle_x = party_angle_x - (y - pViewport->uScreenHeight / 2) * ray_dy; + float angle_y = party_angle_y - (x - pViewport->uScreenWidth / 2) * ray_dx; + + float _dir_x_ = 1, + _dir_y_ = 0, + _dir_z_ = 0; + + float dir_x_ = _dir_x_ * cosf(angle_y);// - _dir_z_ * sinf(angle_y); // rotation around y + //float dir_y_ = _dir_y_; + float dir_z_ = _dir_x_ * sinf(angle_y);// + _dir_z_ * cosf(angle_y); + + //float dir_x = dir_x_; // rotation around x + //float dir_y = /*dir_y_ * cosf(angle_x)*/ + dir_z_ * sinf(angle_x); + //float dir_z = /*-dir_y_ * sinf(angle_x)*/ + dir_z_ * cosf(angle_x); + + vector right; // rotate around right actually to avoid space distortion + right.x = /*dir_y * 0*/ -dir_z_ * 1; + right.y = /*dir_z_ * 0 - dir_x_ * */0; + right.z = dir_x_ * 1/* - dir_y_ * 0*/; + //VectorNormalize(&right); + + matrix rightMatrix; + MatrixRotationAxis(&rightMatrix, &right, angle_x); + + vector v1, v2; + v1.x = dir_x_; v1.y = 0; v1.z = dir_z_; + VectorTransform(&rightMatrix, &v1, &v2); + + float dir_x = v2.x, + dir_y = v2.y, + dir_z = v2.z; + + float abs_dir_x = fabsf(dir_x), + abs_dir_y = fabsf(dir_y), + abs_dir_z = fabsf(dir_z); + + unsigned short color = (0x1F << 11) | (0x1F << 5) | (5); //default to orange + if (abs_dir_x >= abs_dir_y) + { + if (abs_dir_x >= abs_dir_z) + { + if (dir_x >= 0) + { + float instersect_y = dir_y / (2.0f * dir_x); // plane equation for this side is x + 0.5 = 0 + float instersect_z = dir_z / (2.0f * dir_x); + + float u = 1.0f - (instersect_z + 0.5f), + v = 1.0f - (instersect_y + 0.5f); + + int tx = u * (skybox_width - 1), + ty = v * (skybox_height - 1); + + color = skybox_xp[ty * skybox_width + tx]; + //color = ty * 0x1F / skybox_height; + } + else + { + float instersect_y = dir_y / (2.0f * dir_x); + float instersect_z = dir_z / (2.0f * dir_x); + + float u = 1.0f - (instersect_z + 0.5f), + v = instersect_y + 0.5f; + + int tx = u * (skybox_width - 1), + ty = v * (skybox_height - 1); + + color = skybox_xn[ty * skybox_width + tx]; + //color = tx * 0x1F / skybox_height; + } + } + else if (dir_z >= 0) + goto DIR_ZP; + else + goto DIR_ZN; + } + else if (abs_dir_y >= abs_dir_z) + { + if (dir_y >= 0) + { + float instersect_x = dir_x / (2.0f * dir_y); + float instersect_z = dir_z / (2.0f * dir_y); + + float u = instersect_x + 0.5f, + v = instersect_z + 0.5f; + + int tx = u * (skybox_width - 1), + ty = v * (skybox_height - 1); + + color = skybox_yp[ty * skybox_width + tx]; + //color = tx * 0x1F / skybox_height; + } + /*else should never be seen i guess + { + __debugbreak(); + // -y + //Log::Warning(L"(%03u, %03u): -y", x, y); + }*/ + } + else if (dir_z >= 0) + { + DIR_ZP: + // +z + float instersect_x = dir_x / (2.0f * dir_z); + float instersect_y = dir_y / (2.0f * dir_z); + //float intersect_z = 0.5f; + + float u = instersect_x + 0.5f, + v = -instersect_y + 0.5f; + + int tx = u * (skybox_width - 1), + ty = v * (skybox_height - 1); + + color = skybox_zp[ty * skybox_width + tx]; + } + else + { + DIR_ZN: + // -z + float instersect_x = -dir_x / (2.0f * dir_z); + float instersect_y = -dir_y / (2.0f * dir_z); + //float intersect_z = -0.5f; + + float u = 1.0f - instersect_x - 0.5f, + v = -instersect_y + 0.5f; + + int tx = u * (skybox_width - 1), + ty = v * (skybox_height - 1); + + color = skybox_zn[ty * skybox_width + tx]; + } + + //pRenderer->pTargetSurface[(pViewport->uScreenY + y) * pRenderer->uTargetSurfacePitch + pViewport->uScreenX + x] = color; + ((unsigned __int16 *)((char *)desc.lpSurface + y * desc.lPitch))[x] = color; + } + + ErrD3D((skybox_surface)->Unlock(0)); + goto draw; +} + +//----- (00485F53) -------------------------------------------------------- +void sr_485F53(Vec2_int_ *v) +{ + ++v->y; + if (v->y > 1000) + v->y = 0; +} + +//----- (0048607B) -------------------------------------------------------- +void Polygon::Create_48607B(stru149 *a2) +{ + this->pTexture = 0; + this->ptr_38 = a2; +} + +//----- (00486089) -------------------------------------------------------- +void Polygon::_normalize_v_18() +{ + //double v2; // st7@1 + //double v3; // st6@1 + //double v5; // st5@1 + + // v2 = (double)this->v_18.x; + //v3 = (double)this->v_18.y; + // v5 = (double)this->v_18.z; + float len = sqrt((double)this->v_18.z * (double)this->v_18.z + (double)this->v_18.y * (double)this->v_18.y + (double)this->v_18.x * (double)this->v_18.x); + if (fabsf(len) < 1e-6f) + { + v_18.x = 0; + v_18.y = 0; + v_18.z = 65536; + } + else + { + v_18.x = round_to_int((double)this->v_18.x / len * 65536.0); + v_18.y = round_to_int((double)this->v_18.y / len * 65536.0); + v_18.y = round_to_int((double)this->v_18.z / len * 65536.0); + } +} + +//----- (0048616B) -------------------------------------------------------- +void stru149::_48616B_frustum_odm(int a2, int a3, int a4, int a5, int a6, int a7) +{ + int v7; // ebx@1 + int v9; // edi@1 + int v11; // edx@1 + int v17; // ST0C_4@6 + int v19; // ST0C_4@9 + int v24; // [sp+14h] [bp-14h]@1 + int v25; // [sp+18h] [bp-10h]@1 + int v27; // [sp+24h] [bp-4h]@1 + + v25 = pGame->pIndoorCameraD3D->int_cosine_x; + v7 = pGame->pIndoorCameraD3D->int_sine_y; + v27 = pGame->pIndoorCameraD3D->int_sine_x; + //v8 = -pIndoorCamera->pos.y; + v9 = pGame->pIndoorCameraD3D->int_cosine_y; + //v26 = -pIndoorCamera->pos.z; + v11 = pGame->pIndoorCameraD3D->int_cosine_y * -pGame->pIndoorCameraD3D->vPartyPos.x + pGame->pIndoorCameraD3D->int_sine_y * -pGame->pIndoorCameraD3D->vPartyPos.y; + v24 = pGame->pIndoorCameraD3D->int_cosine_y * -pGame->pIndoorCameraD3D->vPartyPos.y - pGame->pIndoorCameraD3D->int_sine_y * -pGame->pIndoorCameraD3D->vPartyPos.x; + if (pGame->pIndoorCameraD3D->sRotationX) + { + this->field_0_party_dir_x = fixpoint_mul(v11, pGame->pIndoorCameraD3D->int_cosine_x) + + fixpoint_mul((-pGame->pIndoorCameraD3D->vPartyPos.z) << 16, pGame->pIndoorCameraD3D->int_sine_x); + this->field_4_party_dir_y = v24; + this->field_8_party_dir_z = fixpoint_mul((-pGame->pIndoorCameraD3D->vPartyPos.z) << 16, v25) - fixpoint_mul(v11, v27); + } + else + { + this->field_0_party_dir_x = v11; + this->field_4_party_dir_y = v24; + this->field_8_party_dir_z = (-pGame->pIndoorCameraD3D->vPartyPos.z) << 16; + } + + if (pGame->pIndoorCameraD3D->sRotationX) + { + v17 = fixpoint_mul(a2, v9) + fixpoint_mul(a3, v7); + + this->angle_from_north = fixpoint_mul(v17, v25) + fixpoint_mul(a4, v27); + this->angle_from_west = fixpoint_mul(a3, v9) - fixpoint_mul(a2, v7); + this->viewing_angle_from_west_east = fixpoint_mul(a4, v25) - fixpoint_mul(v17, v27); + } + else + { + this->angle_from_north = fixpoint_mul(a2, v9) + fixpoint_mul(a3, v7); + this->angle_from_west = fixpoint_mul(a3, v9) - fixpoint_mul(a2, v7); + this->viewing_angle_from_west_east = a4; + } + + if (pGame->pIndoorCameraD3D->sRotationX) + { + v19 = fixpoint_mul(a5, v9) + fixpoint_mul(a6, v7); + + this->angle_from_east = fixpoint_mul(v19, v25) + fixpoint_mul(a7, v27); + this->angle_from_south = fixpoint_mul(a6, v9) - fixpoint_mul(a5, v7); + this->viewing_angle_from_north_south = fixpoint_mul(a7, v25) - fixpoint_mul(v19, v27); + } + else + { + this->angle_from_east = fixpoint_mul(a5, v9) + fixpoint_mul(a6, v7); + this->angle_from_south = fixpoint_mul(a6, v9) - fixpoint_mul(a5, v7); + this->viewing_angle_from_north_south = a7; + } + + this->angle_from_east = -this->angle_from_east; + this->angle_from_south = -this->angle_from_south; + this->viewing_angle_from_north_south = -this->viewing_angle_from_north_south; + + this->field_24 = fixpoint_dot(this->angle_from_north, this->field_0_party_dir_x, + this->angle_from_west, this->field_4_party_dir_y, + this->viewing_angle_from_west_east, this->field_8_party_dir_z); + this->field_28 = fixpoint_dot(this->angle_from_east, this->field_0_party_dir_x, + this->angle_from_south, this->field_4_party_dir_y, + this->viewing_angle_from_north_south, this->field_8_party_dir_z); +} + +//----- (0048694B) -------------------------------------------------------- +void stru149::_48694B_frustum_sky() +{ + this->angle_from_east = -this->angle_from_east; + this->angle_from_south = -this->angle_from_south; + this->viewing_angle_from_north_south = -this->viewing_angle_from_north_south; + + this->field_24 = fixpoint_dot(this->angle_from_north, this->field_0_party_dir_x, + this->angle_from_west, this->field_4_party_dir_y, + this->viewing_angle_from_west_east, this->field_8_party_dir_z); + this->field_28 = fixpoint_dot(this->angle_from_east, this->field_0_party_dir_x, + this->angle_from_south, this->field_4_party_dir_y, + this->viewing_angle_from_north_south, this->field_8_party_dir_z); +} + diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/Render.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/Render.h Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,469 @@ +#pragma once + +#include +#include +#include + +#include "lib\legacy_dx\d3d.h" +#include "OSWindow.h" +#include "RenderStruct.h" + +#include "VectorTypes.h" + +#include "IRender.h" + +#pragma pack(push, 1) +struct DDM_DLV_Header +{ + //----- (00462607) -------------------------------------------------------- + inline DDM_DLV_Header() + { + this->uLastRepawnDay = 0; + this->uNumRespawns = 0; + this->uReputation = 0; + this->field_C_alert = 0; + this->uNumFacesInBModels = 0; + this->uNumDecorations = 0; + this->uNumBModels = 0; + } + + + int uNumRespawns; + int uLastRepawnDay; + int uReputation; + int field_C_alert; + unsigned int uNumFacesInBModels; + unsigned int uNumDecorations; + unsigned int uNumBModels; + int field_1C; + int field_20; + int field_24; +}; +#pragma pack(pop) + + +struct ODMFace; + + +/* 141 */ +// stru148 +#pragma pack(push, 1) +struct Polygon +{ + inline Polygon() + { + uNumVertices = 0; + } + + int _479295(); + //void _48276F_sr(); + void _normalize_v_18(); + void Create_48607B(struct stru149 *a2); + + float field_0; + float field_4; + float field_8; + float field_C; + float field_10; + unsigned int uNumVertices; + Vec3_int_ v_18; + int field_24; + int sTextureDeltaU; + int sTextureDeltaV; + __int16 flags; + __int16 field_32; + int field_34; + struct stru149 *ptr_38; + struct Texture *pTexture; + struct Span *_unused_prolly_head; + struct Span *_unused_prolly_tail; + int **ptr_48; + unsigned __int16 uTileBitmapID; + __int16 field_4E; + __int16 field_50; + __int16 field_52; + ODMFace *pODMFace; + char dimming_level; + char field_59; + char field_5A; + char field_5B; + char terrain_grid_z; + char terrain_grid_x; + unsigned __int8 uBModelID; + unsigned __int8 uBModelFaceID; + struct Edge *pEdgeList1[20]; + unsigned int uEdgeList1Size; + struct Edge *pEdgeList2[20]; + unsigned int uEdgeList2Size; + char field_108; + char field_109; + char field_10A; + char field_10B; +}; +#pragma pack(pop) +extern std::array array_77EC08; + + +/* 142 */ +#pragma pack(push, 1) +struct stru149 +{ + void _48616B_frustum_odm(int a2, int a3, int a4, int a5, int a6, int a7); + void _48653D_frustum_blv(int a2, int a3, int a4, int a5, int a6, int a7); + void _48694B_frustum_sky(); + + int field_0_party_dir_x; + int field_4_party_dir_y; + int field_8_party_dir_z; + int angle_from_north;//field_C + int angle_from_west;//field_10 + int viewing_angle_from_west_east; + int angle_from_east;//field_18 + int angle_from_south;//field_1C + int viewing_angle_from_north_south;//field_20 + int field_24; + int field_28; +}; +#pragma pack(pop) +extern stru149 stru_8019C8; + +/* 88 */ +#pragma pack(push, 1) +struct ODMRenderParams +{ + //----- (00462684) -------------------------------------------------------- + ODMRenderParams() + { + uPickDepth = 0; + this->shading_dist_shade = 2048; + shading_dist_shademist = 4096; + shading_dist_mist = 8192; + int_fov_rad = 0; + this->bNoSky = 0; + this->bDoNotRenderDecorations = 0; + this->field_5C = 0; + this->field_60 = 0; + this->outdoor_no_wavy_water = 0; + this->outdoor_no_mist = 0; + } + + void Initialize(); + + int uPickDepth; + int shading_dist_shade; + int shading_dist_shademist; + int shading_dist_mist; + unsigned int uCameraFovInDegrees; + int int_fov_rad; // 157 struct IndoorCamera::fov_rad + int int_fov_rad_inv; // 157 struct IndoorCamera::fov_rad_inv + int _unused_camera_rotation_y_int_sine; // merged with BLVRenderParams equivalents + int _unused_camera_rotation_y_int_cosine; // into IndoorCameraD3D + int _unused_camera_rotation_x_int_sine; // --//-- + int _unused_camera_rotation_x_int_cosine; // --//-- + int uNumPolygons; + unsigned int _unused_uNumEdges; + unsigned int _unused_uNumSurfs; + unsigned int _unused_uNumSpans; + unsigned int uNumBillboards; + float field_40; + int field_44; + int outdoor_grid_band_3; + int field_4C; + int field_50; + unsigned int bNoSky; + unsigned int bDoNotRenderDecorations; + int field_5C; + int field_60; + int outdoor_no_wavy_water; + int outdoor_no_mist; + int building_gamme; + int terrain_gamma; + + unsigned int uMapGridCellX; // moved from 157 struct IndoorCamera::0C + unsigned int uMapGridCellZ; // moved from 157 struct IndoorCamera::10 +}; +#pragma pack(pop) +extern ODMRenderParams *pODMRenderParams; + + + +struct Render: public IRender +{ + Render(); + virtual ~Render(); + + static Render *Create() {return new Render;} + + virtual bool Initialize(OSWindow *window); + + virtual void ClearBlack(); + virtual void PresentBlackScreen(); + + virtual void SaveWinnersCertificate(const char *a1); + virtual void ClearTarget(unsigned int uColor); + virtual void Present(); + + virtual void _49FD3A_fullscreen(); + virtual bool InitializeFullscreen(); + + virtual void CreateZBuffer(); + virtual void Release(); + + virtual bool SwitchToWindow(); + virtual void RasterLine2D(signed int uX, signed int uY, signed int uZ, signed int uW, unsigned __int16 uColor); + virtual void ClearZBuffer(int a2, int a3); + virtual void SetRasterClipRect(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW); + virtual bool LockSurface_DDraw4(IDirectDrawSurface4 *pSurface, DDSURFACEDESC2 *pDesc, unsigned int uLockFlags); + virtual void GetTargetPixelFormat(DDPIXELFORMAT *pOut); + virtual void LockRenderSurface(void **pOutSurfacePtr, unsigned int *pOutPixelsPerRow); + virtual void UnlockBackBuffer(); + virtual void LockFrontBuffer(void **pOutSurface, unsigned int *pOutPixelsPerRow); + virtual void UnlockFrontBuffer(); + virtual void RestoreFrontBuffer(); + virtual void RestoreBackBuffer(); + virtual void BltToFront(RECT *pDstRect, IDirectDrawSurface *pSrcSurface, RECT *pSrcRect, unsigned int uBltFlags); + virtual void BltBackToFontFast(int a2, int a3, RECT *pSrcRect); + virtual void BeginSceneD3D(); + + virtual unsigned int GetActorTintColor(float a2, int tint, int a4, int a5, RenderBillboard *a6); + + virtual void DrawPolygon(unsigned int uNumVertices, struct Polygon *a3, ODMFace *a4, IDirect3DTexture2 *pTexture); + virtual void DrawTerrainPolygon(unsigned int uNumVertices, struct Polygon *a4, IDirect3DTexture2 *a5, bool transparent, bool clampAtTextureBorders); + virtual void DrawIndoorPolygon(unsigned int uNumVertices, struct BLVFace *a3, IDirect3DTexture2 *pHwTex, struct Texture *pTex, int uPackedID, unsigned int uColor, int a8); + + virtual void MakeParticleBillboardAndPush_BLV(RenderBillboardTransform_local0 *a2, IDirect3DTexture2 *a3, unsigned int uDiffuse, int angle); + virtual void MakeParticleBillboardAndPush_ODM(RenderBillboardTransform_local0 *a2, IDirect3DTexture2 *a3, unsigned int uDiffuse, int angle); + + virtual void DrawBillboards_And_MaybeRenderSpecialEffects_And_EndScene(); + virtual void DrawBillboard_Indoor(RenderBillboardTransform_local0 *pSoftBillboard, Sprite *pSprite, int dimming_level); + virtual void _4A4CC9_AddSomeBillboard(struct stru6_stru1_indoor_sw_billboard *a1, int diffuse); + virtual void TransformBillboardsAndSetPalettesODM(); + virtual void DrawBillboardList_BLV(); + + virtual void DrawProjectile(float srcX, float srcY, float a3, float a4, float dstX, float dstY, float a7, float a8, IDirect3DTexture2 *a9); + virtual bool LoadTexture(const char *pName, unsigned int bMipMaps, IDirectDrawSurface4 **pOutSurface, IDirect3DTexture2 **pOutTexture); + virtual bool MoveSpriteToDevice(Sprite *pSprite); + + virtual void BeginScene(); + virtual void EndScene(); + virtual void ScreenFade(unsigned int color, float t); + + virtual void SetTextureClipRect(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW); + virtual void ResetTextureClipRect(); + virtual void DrawTextureRGB(unsigned int uOutX, unsigned int uOutY, RGBTexture *a4); + virtual void CreditsTextureScroll(unsigned int pX, unsigned int pY, int move_X, int move_Y, RGBTexture *pTexture); + virtual void DrawTextureIndexed(unsigned int uX, unsigned int uY, struct Texture *a4); + + virtual void ZBuffer_Fill_2(signed int a2, signed int a3, struct Texture *pTexture, int a5); + virtual void DrawMaskToZBuffer(signed int uOutX, unsigned int uOutY, struct Texture *pTexture, int zVal); + virtual void DrawTextureTransparent(unsigned int uX, unsigned int uY, struct Texture *pTexture); + virtual void DrawAura(unsigned int a2, unsigned int a3, struct Texture *a4, struct Texture *a5, int a6, int a7, int a8); + virtual void _4A65CC(unsigned int x, unsigned int y, struct Texture *a4, struct Texture *a5, int a6, int a7, int a8); + + virtual void DrawTransparentRedShade(unsigned int a2, unsigned int a3, struct Texture *a4); + virtual void DrawTransparentGreenShade(signed int a2, signed int a3, struct Texture *pTexture); + virtual void DrawFansTransparent(const RenderVertexD3D3 *vertices, unsigned int num_vertices); + + virtual void DrawMasked(signed int a2, signed int a3, struct Texture *pTexture, unsigned __int16 mask); + virtual void GetLeather(unsigned int a2, unsigned int a3, struct Texture *a4, __int16 height); + + virtual void DrawTextPalette(int x, int y, unsigned char* font_pixels, int a5, unsigned int uFontHeight, unsigned __int16 *pPalette, int a8); + virtual void DrawText(signed int uOutX, signed int uOutY, unsigned __int8 *pFontPixels, unsigned int uCharWidth, unsigned int uCharHeight, unsigned __int16 *pFontPalette, unsigned __int16 uFaceColor, unsigned __int16 uShadowColor); + + virtual void FillRectFast(unsigned int uX, unsigned int uY, unsigned int uWidth, unsigned int uHeight, unsigned int uColor16); + virtual void _4A6DF5(unsigned __int16 *pBitmap, unsigned int uBitmapPitch, struct Vec2_int_ *pBitmapXY, void *pTarget, unsigned int uTargetPitch, Vec4_int_ *a7); + virtual void DrawTranslucent(unsigned int a2, unsigned int a3, struct Texture *a4); + + virtual void DrawBuildingsD3D(); + //struct BSPModel *DrawBuildingsSW(); + //int OnOutdoorRedrawSW(); + + virtual void DrawIndoorSky(unsigned int uNumVertices, unsigned int uFaceID); + virtual void DrawOutdoorSkyD3D(); + //int DrawSkySW(struct Span *a1, Polygon *a2, int a3); + virtual void DrawOutdoorSkyPolygon(unsigned int uNumVertices, struct Polygon *pSkyPolygon, IDirect3DTexture2 *pTexture); + virtual void DrawIndoorSkyPolygon(signed int uNumVertices, struct Polygon *pSkyPolygon, IDirect3DTexture2 *pTexture); + + virtual void PrepareDecorationsRenderList_ODM(); + virtual void DrawSpriteObjects_ODM(); + + //float DrawBezierTerrain(); + virtual void RenderTerrainD3D(); + //void DrawTerrainSW(int a1, int a2, int a3, int a4); + + //void ExecOutdoorDrawSW(); + virtual void ChangeBetweenWinFullscreenModes(); + virtual bool AreRenderSurfacesOk(); + virtual bool IsGammaSupported(); + + virtual void SaveScreenshot(const char *pFilename, unsigned int width, unsigned int height); + virtual void PackScreenshot(unsigned int width, unsigned int height, void *out_data, unsigned int data_size, unsigned int *screenshot_size); + virtual void SavePCXScreenshot(); + + virtual int _46А6АС_GetActorsInViewport(int pDepth); + + virtual void BeginLightmaps(); + virtual void EndLightmaps(); + virtual void BeginLightmaps2(); + virtual void EndLightmaps2(); + virtual bool DrawLightmap(struct Lightmap *pLightmap, struct Vec3_float_ *pColorMult, float z_bias); + + virtual void BeginDecals(); + virtual void EndDecals(); + virtual void DrawDecal(struct Decal *pDecal, float z_bias); + + virtual void do_draw_debug_line_d3d(const RenderVertexD3D3 *pLineBegin, signed int sDiffuseBegin, const RenderVertexD3D3 *pLineEnd, signed int sDiffuseEnd, float z_stuff); + virtual void DrawLines(const RenderVertexD3D3 *vertices, unsigned int num_vertices); + + virtual void DrawSpecialEffectsQuad(const RenderVertexD3D3 *vertices, IDirect3DTexture2 *texture); + + virtual void am_Blt_Copy(RECT *pSrcRect, POINT *pTargetXY, int a3); + virtual void am_Blt_Chroma(RECT *pSrcRect, POINT *pTargetPoint, int a3, int blend_mode); + + public:/* + int *pActiveZBuffer; + IDirectDraw4 *pDirectDraw4; + IDirectDrawSurface4 *pFrontBuffer4; + IDirectDrawSurface4 *pBackBuffer4; + void *pTargetSurface; + unsigned int uTargetSurfacePitch; + unsigned int bUseColoredLights; + unsigned int bTinting; + unsigned int bUsingSpecular; + uint32_t uFogColor; + unsigned int pHDWaterBitmapIDs[7]; + int hd_water_current_frame; + int hd_water_tile_id; + void (*pBeforePresentFunction)(); + uint32_t bFogEnabled; + RenderBillboardD3D pBillboardRenderListD3D[1000]; + unsigned int uNumBillboardsToDraw;*/ + + virtual void WritePixel16(int x, int y, unsigned __int16 color) + { + if (ddpfPrimarySuface.dwRGBBitCount == 32) + { + auto p = (unsigned __int32 *)pTargetSurface + x + y * uTargetSurfacePitch; + *p = Color32(color); + } + else if (ddpfPrimarySuface.dwRGBBitCount == 16) + { + auto p = (unsigned __int16 *)pTargetSurface + x + y * uTargetSurfacePitch; + *p = color; + } + else __debugbreak(); + } + + virtual unsigned __int16 ReadPixel16(int x, int y) + { + if (ddpfPrimarySuface.dwRGBBitCount == 32) + { + auto p = (unsigned __int32 *)pTargetSurface + x + y * uTargetSurfacePitch; + return Color16((*p >> 16) & 255, (*p >> 8) & 255, *p & 255); + } + else if (ddpfPrimarySuface.dwRGBBitCount == 16) + { + auto p = (unsigned __int16 *)pTargetSurface + x + y * uTargetSurfacePitch; + return *p; + } + else __debugbreak(); + } + + virtual void ToggleTint() {bTinting = !bTinting;} + virtual void ToggleColoredLights() {bUseColoredLights = !bUseColoredLights;} + + virtual unsigned int GetRenderWidth() {return window->GetWidth();} + virtual unsigned int GetRenderHeight() {return window->GetHeight();} + + virtual void Sub01() + { + if (pRenderD3D && !bWindowMode) + _49FD3A_fullscreen(); + } + + friend void Present_NoColorKey(); + + protected: + unsigned int uDesiredDirect3DDevice; + int raster_clip_x; + int raster_clip_y; // clipping rect for raster ops + int raster_clip_z; // like RasterLine2D for (mini)map + int raster_clip_w; + int *pDefaultZBuffer; + OSWindow *window; + unsigned int bWindowMode; + RenderD3D *pRenderD3D; + DDPIXELFORMAT ddpfPrimarySuface; + unsigned int uTargetRBits; + unsigned int uTargetGBits; + unsigned int uTargetBBits; + unsigned int uTargetRMask; + unsigned int uTargetGMask; + unsigned int uTargetBMask; + unsigned int uNumSceneBegins; + unsigned __int32 *pTargetSurface_unaligned; + unsigned int uClipY; + unsigned int uClipX; + unsigned int uClipW; + unsigned int uClipZ; + unsigned int bClip; + unsigned int uNumD3DSceneBegins; + int using_software_screen_buffer; + RenderHWLContainer pD3DBitmaps; + RenderHWLContainer pD3DSprites; + unsigned int bRequiredTextureStagesAvailable; + unsigned int uLevelOfDetail; + unsigned int uMaxDeviceTextureDim; + unsigned int uMinDeviceTextureDim; + + void DoRenderBillboards_D3D(); + void SetBillboardBlendOptions(RenderBillboardD3D::OpacityType a1); + void TransformBillboard(RenderBillboardTransform_local0 *a2, Sprite *pSprite, int dimming_level, RenderBillboard *pBillboard); + unsigned int Billboard_ProbablyAddToListAndSortByZOrder(float z); + unsigned int GetParentBillboardID(unsigned int uBillboardID); + unsigned int GetBillboardDrawListSize(); + + void DrawBorderTiles(struct Polygon *poly); + + unsigned short *MakeScreenshot(signed int width, signed int height); + bool CheckTextureStages(); + void ParseTargetPixelFormat(); + + void CreateDirectDraw(); + void SetDirectDrawCooperationMode(HWND hWnd, bool bFullscreen); + void SetDirectDrawDisplayMode(unsigned int uWidth, unsigned int uHeight, unsigned int uBPP); + void CreateFrontBuffer(); + void CreateBackBuffer(); + void CreateDirectDrawPrimarySurface(); + void CreateClipper(HWND a2); + + void PackPCXpicture(unsigned short* picture_data, int wight, int heidth, void *data_buff, int max_buff_size,unsigned int* packed_size); + void SavePCXImage(const char *Filename, unsigned short* picture_data, int width, int height); + + //int windowed_mode_width; + //int windowed_mode_height; +}; + +unsigned int __fastcall _452442_color_cvt(unsigned __int16 a1, unsigned __int16 a2, int a3, int a4); + +int __fastcall GetActorTintColor(int max_dim, int min_dim, float distance, int a4, struct RenderBillboard *a5); +int __fastcall _43F55F_get_billboard_light_level(struct RenderBillboard *a1, int uBaseLightLevel); +int __fastcall _43F5C8_get_point_light_level_with_respect_to_lights(unsigned int uBaseLightLevel, int uSectorID, float x, float y, float z); +unsigned int __fastcall GetMaxMipLevels(unsigned int uDim); +int _46E44E_collide_against_faces_and_portals(unsigned int b1); // idb +int __fastcall _46E889_collide_against_bmodels(unsigned int ecx0); +int collide_against_floor(int x, int y, int z, unsigned int *pSectorID, unsigned int *pFaceID); // idb +void __fastcall _46ED8A_collide_against_sprite_objects(unsigned int _this); +int _46EF01_collision_chech_player(int a1); // idb +void _46E0B2_collide_against_decorations(); +int _46F04E_collide_against_portals(); +unsigned int __fastcall sub_46DEF2(signed int a2, unsigned int uLayingItemID); +void UpdateObjects(); +bool sub_47531C(int a1, int *a2, int pos_x, int pos_y, int pos_z, int dir_x, int dir_y, int dir_z, struct BLVFace *face, int a10); +bool sub_4754BF(int a1, int *a2, int X, int Y, int Z, int dir_x, int dir_y, int dir_z, struct BLVFace *face, int a10, int a11); +int sub_475665(struct BLVFace *face, int a2, __int16 a3); +bool __fastcall sub_4759C9(struct BLVFace *face, int a2, int a3, __int16 a4); +bool __fastcall sub_475D85(Vec3_int_ *a1, Vec3_int_ *a2, int *a3, struct BLVFace *a4); +bool __fastcall sub_475F30(int *a1, struct BLVFace *a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9); + +bool __fastcall IsBModelVisible(unsigned int uModelID, int *unused); diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/RenderD3D11.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/RenderD3D11.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,325 @@ +#include +#include // _com_error + +#include "ErrorHandling.h" +#include "RenderD3D11.h" +#include "mm7_data.h" + +#define ErrorD3D(x)\ +{\ + HRESULT hr = x;\ + if (FAILED(hr))\ + {\ + _com_error com_error(hr);\ + Error("HRESULT = %08X\n%S", hr, com_error.ErrorMessage());\ + }\ +} + + +RenderD3D11::RenderD3D11() {} +RenderD3D11::~RenderD3D11() {} + + +void RenderD3D11::ClearBlack() {__debugbreak();} +void RenderD3D11::SaveWinnersCertificate(const char *a1) {__debugbreak();} +void RenderD3D11::Present() {__debugbreak();} +void RenderD3D11::_49FD3A_fullscreen() {__debugbreak();} +bool RenderD3D11::InitializeFullscreen() {__debugbreak(); return 0;} +void RenderD3D11::CreateZBuffer() {__debugbreak();} +void RenderD3D11::Release() {__debugbreak();} +void RenderD3D11::RasterLine2D(signed int uX, signed int uY, signed int uZ, signed int uW, unsigned __int16 uColor) {__debugbreak();} +void RenderD3D11::ClearZBuffer(int a2, int a3) {__debugbreak();} +void RenderD3D11::SetRasterClipRect(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW) {__debugbreak();} +bool RenderD3D11::LockSurface_DDraw4(IDirectDrawSurface4 *pSurface, DDSURFACEDESC2 *pDesc, unsigned int uLockFlags) {__debugbreak(); return 0;} +void RenderD3D11::GetTargetPixelFormat(DDPIXELFORMAT *pOut) {__debugbreak();} +void RenderD3D11::LockRenderSurface(void **pOutSurfacePtr, unsigned int *pOutPixelsPerRow) {__debugbreak();} +void RenderD3D11::UnlockBackBuffer() {__debugbreak();} +void RenderD3D11::LockFrontBuffer(void **pOutSurface, unsigned int *pOutPixelsPerRow) {__debugbreak();} +void RenderD3D11::UnlockFrontBuffer() {__debugbreak();} +void RenderD3D11::RestoreFrontBuffer() {__debugbreak();} +void RenderD3D11::RestoreBackBuffer() {__debugbreak();} +void RenderD3D11::BltToFront(RECT *pDstRect, IDirectDrawSurface *pSrcSurface, RECT *pSrcRect, unsigned int uBltFlags) {__debugbreak();} +void RenderD3D11::BltBackToFontFast(int a2, int a3, RECT *a4) {__debugbreak();} +void RenderD3D11::BeginSceneD3D() {__debugbreak();} +unsigned int RenderD3D11::GetActorTintColor(float a2, int tint, int a4, int a5, RenderBillboard *a6) {__debugbreak(); return 0;} +void RenderD3D11::DrawPolygon(unsigned int uNumVertices, struct Polygon *a3, ODMFace *a4, IDirect3DTexture2 *pTexture) {__debugbreak();} +void RenderD3D11::DrawTerrainPolygon(unsigned int uNumVertices, struct Polygon *a4, IDirect3DTexture2 *a5, bool transparent, bool clampAtTextureBorders) {__debugbreak();} +void RenderD3D11::DrawIndoorPolygon(unsigned int uNumVertices, struct BLVFace *a3, IDirect3DTexture2 *pHwTex, struct Texture *pTex, int uPackedID, unsigned int uColor, int a8) {__debugbreak();} +void RenderD3D11::MakeParticleBillboardAndPush_BLV(RenderBillboardTransform_local0 *a2, IDirect3DTexture2 *a3, unsigned int uDiffuse, int angle) {__debugbreak();} +void RenderD3D11::MakeParticleBillboardAndPush_ODM(RenderBillboardTransform_local0 *a2, IDirect3DTexture2 *a3, unsigned int uDiffuse, int angle) {__debugbreak();} +void RenderD3D11::DrawBillboards_And_MaybeRenderSpecialEffects_And_EndScene() {__debugbreak();} +void RenderD3D11::DrawBillboard_Indoor(RenderBillboardTransform_local0 *pSoftBillboard, Sprite *pSprite, int dimming_level) {__debugbreak();} +void RenderD3D11::_4A4CC9_AddSomeBillboard(struct stru6_stru1_indoor_sw_billboard *a1, int diffuse) {__debugbreak();} +void RenderD3D11::TransformBillboardsAndSetPalettesODM() {__debugbreak();} +void RenderD3D11::DrawBillboardList_BLV() {__debugbreak();} +void RenderD3D11::DrawProjectile(float srcX, float srcY, float a3, float a4, float dstX, float dstY, float a7, float a8, IDirect3DTexture2 *a9) {__debugbreak();} +bool RenderD3D11::LoadTexture(const char *pName, unsigned int bMipMaps, IDirectDrawSurface4 **pOutSurface, IDirect3DTexture2 **pOutTexture) {__debugbreak(); return 0;} +bool RenderD3D11::MoveSpriteToDevice(Sprite *pSprite) {__debugbreak(); return 0;} +void RenderD3D11::ScreenFade(unsigned int color, float t) {__debugbreak();} +void RenderD3D11::SetTextureClipRect(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW) {__debugbreak();} +void RenderD3D11::ResetTextureClipRect() {__debugbreak();} +void RenderD3D11::CreditsTextureScroll(unsigned int pX, unsigned int pY, int move_X, int move_Y, RGBTexture *pTexture) {__debugbreak();} +void RenderD3D11::DrawTextureIndexed(unsigned int uX, unsigned int uY, struct Texture *a4) {__debugbreak();} +void RenderD3D11::ZBuffer_Fill_2(signed int a2, signed int a3, struct Texture *pTexture, int a5) {__debugbreak();} +void RenderD3D11::DrawMaskToZBuffer(signed int uOutX, unsigned int uOutY, struct Texture *pTexture, int zVal) {__debugbreak();} +void RenderD3D11::DrawTextureTransparent(unsigned int uX, unsigned int uY, struct Texture *pTexture) {__debugbreak();} +void RenderD3D11::DrawAura(unsigned int a2, unsigned int a3, struct Texture *a4, struct Texture *a5, int a6, int a7, int a8) {__debugbreak();} +void RenderD3D11::_4A65CC(unsigned int x, unsigned int y, struct Texture *a4, struct Texture *a5, int a6, int a7, int a8) {__debugbreak();} +void RenderD3D11::DrawTransparentRedShade(unsigned int a2, unsigned int a3, struct Texture *a4) {__debugbreak();} +void RenderD3D11::DrawTransparentGreenShade(signed int a2, signed int a3, struct Texture *pTexture) {__debugbreak();} +void RenderD3D11::DrawFansTransparent(const RenderVertexD3D3 *vertices, unsigned int num_vertices) {__debugbreak();} +void RenderD3D11::DrawMasked(signed int a2, signed int a3, struct Texture *pTexture, unsigned __int16 mask) {__debugbreak();} +void RenderD3D11::GetLeather(unsigned int a2, unsigned int a3, struct Texture *a4, __int16 height) {__debugbreak();} +void RenderD3D11::DrawTextPalette(int x, int y, unsigned char* font_pixels, int a5, unsigned int uFontHeight, unsigned __int16 *pPalette, int a8) {__debugbreak();} +void RenderD3D11::DrawText(signed int uOutX, signed int uOutY, unsigned __int8 *pFontPixels, unsigned int uCharWidth, unsigned int uCharHeight, unsigned __int16 *pFontPalette, unsigned __int16 uFaceColor, unsigned __int16 uShadowColor) {__debugbreak();} +void RenderD3D11::FillRectFast(unsigned int uX, unsigned int uY, unsigned int uWidth, unsigned int uHeight, unsigned int uColor16) {__debugbreak();} +void RenderD3D11::_4A6DF5(unsigned __int16 *pBitmap, unsigned int uBitmapPitch, struct Vec2_int_ *pBitmapXY, void *pTarget, unsigned int uTargetPitch, Vec4_int_ *a7) {__debugbreak();} +void RenderD3D11::DrawTranslucent(unsigned int a2, unsigned int a3, struct Texture *a4) {__debugbreak();} +void RenderD3D11::DrawBuildingsD3D() {__debugbreak();} +void RenderD3D11::DrawIndoorSky(unsigned int uNumVertices, unsigned int uFaceID) {__debugbreak();} +void RenderD3D11::DrawOutdoorSkyD3D() {__debugbreak();} +void RenderD3D11::DrawOutdoorSkyPolygon(unsigned int uNumVertices, struct Polygon *pSkyPolygon, IDirect3DTexture2 *pTexture) {__debugbreak();} +void RenderD3D11::DrawIndoorSkyPolygon(signed int uNumVertices, struct Polygon *pSkyPolygon, IDirect3DTexture2 *pTexture) {__debugbreak();} +void RenderD3D11::PrepareDecorationsRenderList_ODM() {__debugbreak();} +void RenderD3D11::DrawSpriteObjects_ODM() {__debugbreak();} +void RenderD3D11::RenderTerrainD3D() {__debugbreak();} +void RenderD3D11::ChangeBetweenWinFullscreenModes() {__debugbreak();} +bool RenderD3D11::AreRenderSurfacesOk() {__debugbreak(); return 0;} +void RenderD3D11::SaveScreenshot(const char *pFilename, unsigned int width, unsigned int height) {__debugbreak();} +void RenderD3D11::PackScreenshot(unsigned int width, unsigned int height, void *out_data, unsigned int data_size, unsigned int *screenshot_size) {__debugbreak();} +void RenderD3D11::SavePCXScreenshot() {__debugbreak();} +int RenderD3D11::_46А6АС_GetActorsInViewport(int pDepth) {__debugbreak(); return 0;} +void RenderD3D11::BeginLightmaps() {__debugbreak();} +void RenderD3D11::EndLightmaps() {__debugbreak();} +void RenderD3D11::BeginLightmaps2() {__debugbreak();} +void RenderD3D11::EndLightmaps2() {__debugbreak();} +bool RenderD3D11::DrawLightmap(struct Lightmap *pLightmap, struct Vec3_float_ *pColorMult, float z_bias) {__debugbreak(); return 0;} +void RenderD3D11::BeginDecals() {__debugbreak();} +void RenderD3D11::EndDecals() {__debugbreak();} +void RenderD3D11::DrawDecal(struct Decal *pDecal, float z_bias) {__debugbreak();} +void RenderD3D11::do_draw_debug_line_d3d(const RenderVertexD3D3 *pLineBegin, signed int sDiffuseBegin, const RenderVertexD3D3 *pLineEnd, signed int sDiffuseEnd, float z_stuff) {__debugbreak();} +void RenderD3D11::DrawLines(const RenderVertexD3D3 *vertices, unsigned int num_vertices) {__debugbreak();} +void RenderD3D11::DrawSpecialEffectsQuad(const RenderVertexD3D3 *vertices, IDirect3DTexture2 *texture) {__debugbreak();} +void RenderD3D11::am_Blt_Copy(RECT *pSrcRect, POINT *pTargetXY, int a3) {__debugbreak();} +void RenderD3D11::am_Blt_Chroma(RECT *pSrcRect, POINT *pTargetPoint, int a3, int blend_mode) {__debugbreak();} + +void RenderD3D11::Sub01() {__debugbreak();} + + + + + +void RenderD3D11::PresentBlackScreen() +{ + ClearTarget(0xFF000000); + ErrorD3D(pSwapChain->Present(0, 0)); +} + +void RenderD3D11::BeginScene() {} +void RenderD3D11::EndScene() {} + +void RenderD3D11::ClearTarget(unsigned int uColor) +{ + float clear_color[] = + { + ((uColor & 0x00FF0000) >> 16) / 255.0f, + ((uColor & 0x0000FF00) >> 8) / 255.0f, + ((uColor & 0x000000FF) >> 0) / 255.0f, + ((uColor & 0xFF000000) >> 24) / 255.0f + }; + d3dc->ClearRenderTargetView(primary_srv, clear_color); +} + + +void RenderD3D11::DrawTextureRGB(unsigned int uOutX, unsigned int uOutY, RGBTexture *a4) +{ + __debugbreak(); +} + +bool RenderD3D11::IsGammaSupported() +{ + return false; +} + +struct +{ + unsigned char restore_resolution; + unsigned char _saved_screen_bpp; + unsigned short _saved_screen_width; + unsigned short _saved_screen_height; +} on_exit; + +void ChangeResolution(int new_width, int new_height, int new_bpp) +{ + if (!on_exit.restore_resolution) + { + on_exit.restore_resolution = true; + + auto hdc = GetDC(nullptr); + { + on_exit._saved_screen_width = GetDeviceCaps(hdc, HORZRES); + on_exit._saved_screen_height = GetDeviceCaps(hdc, VERTRES); + on_exit._saved_screen_bpp = GetDeviceCaps(hdc, BITSPIXEL); + } + ReleaseDC(nullptr, hdc); + } + + DEVMODEA dm; + dm.dmSize = sizeof(dm); + dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; + dm.dmBitsPerPel = new_bpp; + dm.dmPelsWidth = new_width; + dm.dmPelsHeight = new_height; + + if (ChangeDisplaySettingsA(&dm, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) + Error("ChangeDisplaySettingsA"); +} + +__declspec(noreturn) void ExitApp() +{ + if (on_exit.restore_resolution) + ChangeResolution(on_exit._saved_screen_width, on_exit._saved_screen_height, on_exit._saved_screen_bpp); + + ExitProcess(0); +} + + + +bool RenderD3D11::SwitchToWindow() +{ + if (on_exit.restore_resolution) + { + on_exit.restore_resolution = false; + ChangeResolution(on_exit._saved_screen_width, on_exit._saved_screen_height, on_exit._saved_screen_bpp); + } + return true; +} + + + + +bool RenderD3D11::Initialize(OSWindow *window) +{ + this->window = window; + + auto d3d_lib = LoadLibraryW(L"d3d11.dll"); + if (!d3d_lib) + return Error("d3d11.dll is missing"), false; + + + DXGI_SWAP_CHAIN_DESC swapChainDesc; + memset(&swapChainDesc, 0, sizeof(swapChainDesc)); + swapChainDesc.BufferDesc.Width = window->GetWidth(); + swapChainDesc.BufferDesc.Height = window->GetHeight(); + //swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; + //swapChainDesc.BufferDesc.RefreshRate.Denominator = 0; + swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + //swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; + //swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; + swapChainDesc.SampleDesc.Count = 1; + //swapChainDesc.SampleDesc.Quality = 0; + swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapChainDesc.BufferCount = 2; + swapChainDesc.OutputWindow = window->GetApiHandle(); + swapChainDesc.Windowed = true; + //swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + //swapChainDesc.Flags = 0; + + + D3D_FEATURE_LEVEL requested_feature_level = D3D_FEATURE_LEVEL_11_0, + received_feature_level; + + unsigned int device_flags = 0;//D3D11_CREATE_DEVICE_DISABLE_GPU_TIMEOUT; + #ifndef NODEBUG + device_flags |= 0/*D3D11_CREATE_DEVICE_DEBUG | D3D11_CREATE_DEVICE_DEBUGGABLE*/; + #endif + + HRESULT (__stdcall *dll_D3D11CreateDeviceAndSwapChain)(IDXGIAdapter* pAdapter, D3D_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, CONST D3D_FEATURE_LEVEL* pFeatureLevels, UINT FeatureLevels, UINT SDKVersion, CONST DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, IDXGISwapChain** ppSwapChain, ID3D11Device** ppDevice, D3D_FEATURE_LEVEL* pFeatureLevel, ID3D11DeviceContext** ppImmediateContext); + dll_D3D11CreateDeviceAndSwapChain = (decltype(dll_D3D11CreateDeviceAndSwapChain))GetProcAddress(d3d_lib, "D3D11CreateDeviceAndSwapChain"); + ErrorD3D(dll_D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, device_flags, nullptr, 0, D3D11_SDK_VERSION, &swapChainDesc, &pSwapChain, &d3dd, &received_feature_level, &d3dc)); + + if (received_feature_level < D3D_FEATURE_LEVEL_10_0) + { + MessageBoxA(nullptr, "Received Direct3D 9 or lower", "", 0); + __debugbreak(); + } + /*if (fullscreen) + { + extern void ChangeResolution(int new_dith, int new_height, int new_bpp); + ChangeResolution(target_window->GetWidth(), target_window->GetHeight(), 32); + + target_window->SetPosition(0, 0); + target_window->SetTopmost(true); + } + ErrorD3D(pSwapChain->SetFullscreenState(fullscreen, nullptr));*/ + + + ID3D11Texture2D *pSwapChainSurface; + { + ErrorD3D(pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void **)&pSwapChainSurface)); + ErrorD3D(d3dd->CreateRenderTargetView(pSwapChainSurface, nullptr, &primary_srv)); + } + pSwapChainSurface->Release(); + + + D3D11_TEXTURE2D_DESC z_desc; + memset(&z_desc, 0, sizeof(z_desc)); + z_desc.Width = window->GetWidth(); + z_desc.Height = window->GetHeight(); + z_desc.MipLevels = 1; + z_desc.ArraySize = 1; + z_desc.Format = DXGI_FORMAT_D32_FLOAT; + z_desc.SampleDesc.Count = 1; + //z_desc.SampleDesc.Quality = 0; + //z_desc.Usage = D3D11_USAGE_DEFAULT; + z_desc.BindFlags = D3D11_BIND_DEPTH_STENCIL; + //z_desc.CPUAccessFlags = 0; + //z_desc.MiscFlags = 0; + + ID3D11Texture2D *depth_surface; + ErrorD3D(d3dd->CreateTexture2D(&z_desc, nullptr, &depth_surface)); + + D3D11_DEPTH_STENCIL_VIEW_DESC depth_srv_desc; + memset(&depth_srv_desc, 0, sizeof(depth_srv_desc)); + depth_srv_desc.Format = DXGI_FORMAT_D32_FLOAT; + depth_srv_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; + //depth_srv_desc.Texture2D.MipSlice = 0; + ErrorD3D(d3dd->CreateDepthStencilView(depth_surface, &depth_srv_desc, &depth_srv)); + + d3dc->OMSetRenderTargets(1, &primary_srv, depth_srv); + d3dc->ClearDepthStencilView(depth_srv, D3D11_CLEAR_DEPTH, 1.0f, 0); + + + + D3D11_RASTERIZER_DESC d3drs_desc; + memset(&d3drs_desc, 0, sizeof(d3drs_desc)); + d3drs_desc.FillMode = D3D11_FILL_SOLID; + d3drs_desc.CullMode = D3D11_CULL_NONE; + //d3drs_desc.FrontCounterClockwise = false; + //d3drs_desc.DepthBias = 0; + //d3drs_desc.DepthBiasClamp = 0.0f; + //d3drs_desc.SlopeScaledDepthBias = 0.0f; + //d3drs_desc.DepthClipEnable = true; + //d3drs_desc.ScissorEnable = false; + //d3drs_desc.MultisampleEnable = false; + //d3drs_desc.AntialiasedLineEnable = false; + + ID3D11RasterizerState *d3drs; + ErrorD3D(d3dd->CreateRasterizerState(&d3drs_desc, &d3drs)); + d3dc->RSSetState(d3drs); + d3drs->Release(); + + + + D3D11_VIEWPORT viewport; + memset(&viewport, 0, sizeof(viewport)); + viewport.TopLeftX = game_viewport_x; + viewport.TopLeftY = game_viewport_y; + viewport.Width = game_viewport_width; + viewport.Height = game_viewport_height; + //viewport.MinDepth = 0; + viewport.MaxDepth = 1; + d3dc->RSSetViewports(1, &viewport); + + return true; +} \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/RenderD3D11.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/RenderD3D11.h Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,172 @@ +#pragma once + +#include +#include + +#include "lib\legacy_dx\d3d.h" +#include + +#include "OSWindow.h" +#include "RenderStruct.h" + +#include "VectorTypes.h" + +#include "IRender.h" + +struct RenderD3D11: public IRender +{ + RenderD3D11(); + virtual ~RenderD3D11(); + + static RenderD3D11 *Create() {return new RenderD3D11;} + + virtual bool Initialize(OSWindow *window); + + virtual void ClearBlack(); + virtual void PresentBlackScreen(); + + virtual void SaveWinnersCertificate(const char *a1); + virtual void ClearTarget(unsigned int uColor); + virtual void Present(); + + virtual void _49FD3A_fullscreen(); + virtual bool InitializeFullscreen(); + + virtual void CreateZBuffer(); + virtual void Release(); + + virtual bool SwitchToWindow(); + virtual void RasterLine2D(signed int uX, signed int uY, signed int uZ, signed int uW, unsigned __int16 uColor); + virtual void ClearZBuffer(int a2, int a3); + virtual void SetRasterClipRect(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW); + virtual bool LockSurface_DDraw4(IDirectDrawSurface4 *pSurface, DDSURFACEDESC2 *pDesc, unsigned int uLockFlags); + virtual void GetTargetPixelFormat(DDPIXELFORMAT *pOut); + virtual void LockRenderSurface(void **pOutSurfacePtr, unsigned int *pOutPixelsPerRow); + virtual void UnlockBackBuffer(); + virtual void LockFrontBuffer(void **pOutSurface, unsigned int *pOutPixelsPerRow); + virtual void UnlockFrontBuffer(); + virtual void RestoreFrontBuffer(); + virtual void RestoreBackBuffer(); + virtual void BltToFront(RECT *pDstRect, IDirectDrawSurface *pSrcSurface, RECT *pSrcRect, unsigned int uBltFlags); + virtual void BltBackToFontFast(int a2, int a3, RECT *pSrcRect); + virtual void BeginSceneD3D(); + + virtual unsigned int GetActorTintColor(float a2, int tint, int a4, int a5, RenderBillboard *a6); + + virtual void DrawPolygon(unsigned int uNumVertices, struct Polygon *a3, ODMFace *a4, IDirect3DTexture2 *pTexture); + virtual void DrawTerrainPolygon(unsigned int uNumVertices, struct Polygon *a4, IDirect3DTexture2 *a5, bool transparent, bool clampAtTextureBorders); + virtual void DrawIndoorPolygon(unsigned int uNumVertices, struct BLVFace *a3, IDirect3DTexture2 *pHwTex, struct Texture *pTex, int uPackedID, unsigned int uColor, int a8); + + virtual void MakeParticleBillboardAndPush_BLV(RenderBillboardTransform_local0 *a2, IDirect3DTexture2 *a3, unsigned int uDiffuse, int angle); + virtual void MakeParticleBillboardAndPush_ODM(RenderBillboardTransform_local0 *a2, IDirect3DTexture2 *a3, unsigned int uDiffuse, int angle); + + virtual void DrawBillboards_And_MaybeRenderSpecialEffects_And_EndScene(); + virtual void DrawBillboard_Indoor(RenderBillboardTransform_local0 *pSoftBillboard, Sprite *pSprite, int dimming_level); + virtual void _4A4CC9_AddSomeBillboard(struct stru6_stru1_indoor_sw_billboard *a1, int diffuse); + virtual void TransformBillboardsAndSetPalettesODM(); + virtual void DrawBillboardList_BLV(); + + virtual void DrawProjectile(float srcX, float srcY, float a3, float a4, float dstX, float dstY, float a7, float a8, IDirect3DTexture2 *a9); + virtual bool LoadTexture(const char *pName, unsigned int bMipMaps, IDirectDrawSurface4 **pOutSurface, IDirect3DTexture2 **pOutTexture); + virtual bool MoveSpriteToDevice(Sprite *pSprite); + + virtual void BeginScene(); + virtual void EndScene(); + virtual void ScreenFade(unsigned int color, float t); + + virtual void SetTextureClipRect(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW); + virtual void ResetTextureClipRect(); + virtual void DrawTextureRGB(unsigned int uOutX, unsigned int uOutY, RGBTexture *a4); + virtual void CreditsTextureScroll(unsigned int pX, unsigned int pY, int move_X, int move_Y, RGBTexture *pTexture); + virtual void DrawTextureIndexed(unsigned int uX, unsigned int uY, struct Texture *a4); + + virtual void ZBuffer_Fill_2(signed int a2, signed int a3, struct Texture *pTexture, int a5); + virtual void DrawMaskToZBuffer(signed int uOutX, unsigned int uOutY, struct Texture *pTexture, int zVal); + virtual void DrawTextureTransparent(unsigned int uX, unsigned int uY, struct Texture *pTexture); + virtual void DrawAura(unsigned int a2, unsigned int a3, struct Texture *a4, struct Texture *a5, int a6, int a7, int a8); + virtual void _4A65CC(unsigned int x, unsigned int y, struct Texture *a4, struct Texture *a5, int a6, int a7, int a8); + + virtual void DrawTransparentRedShade(unsigned int a2, unsigned int a3, struct Texture *a4); + virtual void DrawTransparentGreenShade(signed int a2, signed int a3, struct Texture *pTexture); + virtual void DrawFansTransparent(const RenderVertexD3D3 *vertices, unsigned int num_vertices); + + virtual void DrawMasked(signed int a2, signed int a3, struct Texture *pTexture, unsigned __int16 mask); + virtual void GetLeather(unsigned int a2, unsigned int a3, struct Texture *a4, __int16 height); + + virtual void DrawTextPalette(int x, int y, unsigned char* font_pixels, int a5, unsigned int uFontHeight, unsigned __int16 *pPalette, int a8); + virtual void DrawText(signed int uOutX, signed int uOutY, unsigned __int8 *pFontPixels, unsigned int uCharWidth, unsigned int uCharHeight, unsigned __int16 *pFontPalette, unsigned __int16 uFaceColor, unsigned __int16 uShadowColor); + + virtual void FillRectFast(unsigned int uX, unsigned int uY, unsigned int uWidth, unsigned int uHeight, unsigned int uColor16); + virtual void _4A6DF5(unsigned __int16 *pBitmap, unsigned int uBitmapPitch, struct Vec2_int_ *pBitmapXY, void *pTarget, unsigned int uTargetPitch, Vec4_int_ *a7); + virtual void DrawTranslucent(unsigned int a2, unsigned int a3, struct Texture *a4); + + virtual void DrawBuildingsD3D(); + + virtual void DrawIndoorSky(unsigned int uNumVertices, unsigned int uFaceID); + virtual void DrawOutdoorSkyD3D(); + virtual void DrawOutdoorSkyPolygon(unsigned int uNumVertices, struct Polygon *pSkyPolygon, IDirect3DTexture2 *pTexture); + virtual void DrawIndoorSkyPolygon(signed int uNumVertices, struct Polygon *pSkyPolygon, IDirect3DTexture2 *pTexture); + + virtual void PrepareDecorationsRenderList_ODM(); + virtual void DrawSpriteObjects_ODM(); + + virtual void RenderTerrainD3D(); + + virtual void ChangeBetweenWinFullscreenModes(); + virtual bool AreRenderSurfacesOk(); + virtual bool IsGammaSupported(); + + virtual void SaveScreenshot(const char *pFilename, unsigned int width, unsigned int height); + virtual void PackScreenshot(unsigned int width, unsigned int height, void *out_data, unsigned int data_size, unsigned int *screenshot_size); + virtual void SavePCXScreenshot(); + + virtual int _46А6АС_GetActorsInViewport(int pDepth); + + virtual void BeginLightmaps(); + virtual void EndLightmaps(); + virtual void BeginLightmaps2(); + virtual void EndLightmaps2(); + virtual bool DrawLightmap(struct Lightmap *pLightmap, struct Vec3_float_ *pColorMult, float z_bias); + + virtual void BeginDecals(); + virtual void EndDecals(); + virtual void DrawDecal(struct Decal *pDecal, float z_bias); + + virtual void do_draw_debug_line_d3d(const RenderVertexD3D3 *pLineBegin, signed int sDiffuseBegin, const RenderVertexD3D3 *pLineEnd, signed int sDiffuseEnd, float z_stuff); + virtual void DrawLines(const RenderVertexD3D3 *vertices, unsigned int num_vertices); + + virtual void DrawSpecialEffectsQuad(const RenderVertexD3D3 *vertices, IDirect3DTexture2 *texture); + + virtual void am_Blt_Copy(RECT *pSrcRect, POINT *pTargetXY, int a3); + virtual void am_Blt_Chroma(RECT *pSrcRect, POINT *pTargetPoint, int a3, int blend_mode); + + public: + + virtual void WritePixel16(int x, int y, unsigned __int16 color) + { +__debugbreak(); + } + + virtual unsigned __int16 ReadPixel16(int x, int y) + { +__debugbreak(); return 0; + } + + virtual void ToggleTint() {} + virtual void ToggleColoredLights() {} + + virtual unsigned int GetRenderWidth() {return window->GetWidth();} + virtual unsigned int GetRenderHeight() {return window->GetHeight();} + + virtual void Sub01(); + + + protected: + OSWindow *window; + + IDXGISwapChain *pSwapChain; + ID3D11Device *d3dd; + ID3D11DeviceContext *d3dc; + ID3D11RenderTargetView *primary_srv; + ID3D11DepthStencilView *depth_srv; +}; diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/RenderStruct.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/RenderStruct.h Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,348 @@ +#pragma once + +#include +#include + +#include "lib\legacy_dx\d3d.h" +#include "OSWindow.h" + +#include "VectorTypes.h" + + +#define ErrD3D(hr) \ + do \ + { \ + extern void ErrHR(HRESULT, const char *, const char *, const char *, int); \ + ErrHR(hr, "Direct3D", __FUNCTION__, __FILE__, __LINE__); \ + } while(0) + +struct Polygon; +struct Texture; +struct RGBTexture; +struct RenderBillboardTransform_local0; +struct ODMFace; + + +unsigned __int16 Color16(unsigned __int32 r, unsigned __int32 g, unsigned __int32 b); +unsigned __int32 Color32(unsigned __int16 color16); + +/* 119 */ +#pragma pack(push, 1) +struct RenderVertexSoft +{ + inline RenderVertexSoft(): + flt_2C(0.0f) + {} + + Vec3_float_ vWorldPosition; + Vec3_float_ vWorldViewPosition; + float vWorldViewProjX; + float vWorldViewProjY; + float _rhw; + float u; + float v; + float flt_2C; +}; +#pragma pack(pop) + + + +/* 112 */ +#pragma pack(push, 1) +struct RenderVertexD3D3 +{ + Vec3_float_ pos; + float rhw; + signed int diffuse; + unsigned int specular; + Vec2_float_ texcoord; +}; +#pragma pack(pop) + +class Sprite; +class SpriteFrame; + +/* 161 */ +#pragma pack(push, 1) +struct RenderBillboard +{ + int _screenspace_x_scaler_packedfloat; + int _screenspace_y_scaler_packedfloat; + float fov_x; + float fov_y; + union + { + int sZValue; + struct + { + unsigned __int16 object_pid; + signed __int16 actual_z; + }; + }; + int field_14_actor_id; + signed __int16 HwSpriteID; + __int16 uPalette; + __int16 uIndoorSectorID; + __int16 field_1E; + __int16 world_x; + __int16 world_y; + __int16 world_z; + __int16 uScreenSpaceX; + __int16 uScreenSpaceY; + unsigned __int16 dimming_level; + signed int sTintColor; + SpriteFrame *pSpriteFrame; + + inline float GetFloatZ() const + { + return (float)object_pid / 65535.0f + (float)actual_z; + } +}; +#pragma pack(pop) + + +#pragma pack(push, 1) +struct RenderD3D__DevInfo +{ + unsigned int bIsDeviceCompatible; + char *pName; + char *pDescription; + GUID *pGUID; + unsigned int uCaps; + char *pDriverName; + char *pDeviceDesc; + char *pDDraw4DevDesc; + GUID *pDirectDrawGUID; + int uVideoMem; +}; +#pragma pack(pop) + + + +#pragma pack(push, 1) +struct RenderD3D_D3DDevDesc +{ + int field_0; + int field_4; + int field_8; + int field_C; + int field_10; + char *pDriverName; + char *pDeviceDesc; + char *pDDraw4DevDesc; + GUID *pGUID; + unsigned int uVideoMem; +}; +#pragma pack(pop) + + + + + + + + + +/* 280 */ +#pragma pack(push, 1) +struct HWLTexture +{ + inline HWLTexture(): + field_0(0), field_4(0), field_8(0), + field_C(0), field_10(0), field_14(0) + {} + + int field_0; + int field_4; + int field_8; + int field_C; + int field_10; + int field_14; + int uBufferWidth; + int uBufferHeight; + int uAreaWidth; + int uAreaHeigth; + unsigned int uWidth; + unsigned int uHeight; + int uAreaX; + int uAreaY; + unsigned __int16 *pPixels; +}; +#pragma pack(pop) + + +/* 185 */ +#pragma pack(push, 1) +struct RenderHWLContainer +{ + RenderHWLContainer(); + bool Load(const wchar_t *pFilename); + bool Release(); + + HWLTexture *LoadTexture(const char *pName, int bMipMaps); + + FILE *pFile; + uint32_t uSignature; + unsigned int uDataOffset; + unsigned int uNumItems; + char *pSpriteNames[50000]; + int pSpriteOffsets[50000]; + int bDumpDebug; + int scale_hwls_to_half; +}; +#pragma pack(pop) + + + +/* 242 */ +#pragma pack(push, 1) +struct RenderBillboardD3D +{ + inline RenderBillboardD3D(): + opacity(Transparent), + field_90(-1), + sParentBillboardID(-1), + uNumVertices(4) + {} + + enum OpacityType: unsigned __int32 + { + Transparent = 0, + Opaque_1 = 1, + Opaque_2 = 2, + Opaque_3 = 3, + NoBlend = 0xFFFFFFFF + }; + + IDirect3DTexture2 *pTexture; + unsigned int uNumVertices; + RenderVertexD3D3 pQuads[4]; + float z_order; + OpacityType opacity; + int field_90; + int sZValue; + signed int sParentBillboardID; +}; +#pragma pack(pop) + + + + +#pragma pack(push, 1) +struct RenderD3D_aux +{ + RenderD3D__DevInfo *pInfo; + RenderD3D_D3DDevDesc *ptr_4; +}; +#pragma pack(pop) + + + +/* 183 */ +#pragma pack(push, 1) +class RenderD3D +{ +public: + RenderD3D(); + + void GetAvailableDevices(RenderD3D__DevInfo **pOutDevices); + void Release(); + bool CreateDevice(unsigned int uDeviceID, int bWindowed, OSWindow *window); + unsigned int GetDeviceCaps(); + void ClearTarget(unsigned int bClearColor, unsigned int uClearColor, unsigned int bClearDepth, float z_clear); + void Present(bool bForceBlit); + bool CreateTexture(unsigned int uTextureWidth, unsigned int uTextureHeight, IDirectDrawSurface4 **pOutSurface, IDirect3DTexture2 **pOutTexture, bool bAlphaChannel, bool bMipmaps, unsigned int uMinDeviceTexDim); + void HandleLostResources(); + + + unsigned int bWindowed; + int field_4; + int field_8; + HWND hWindow; + int field_10; + int field_14; + int field_18; + RenderD3D__DevInfo *pAvailableDevices; + IDirectDraw4 *pHost; + IDirect3D3 *pDirect3D; + IUnknown *pUnk; + IDirectDrawSurface4 *pBackBuffer; + IDirectDrawSurface4 *pFrontBuffer; + IDirectDrawSurface4 *pZBuffer; + IDirect3DDevice3 *pDevice; + IDirect3DViewport3 *pViewport; + int field_40; + int field_44; + char pErrorMessage[48]; + char field_78[208]; +}; +#pragma pack(pop) +extern struct RenderVertexD3D3 pVertices[50]; + +/* 182 */ +#pragma pack(push, 1) + +#pragma pack(pop) + +bool PauseGameDrawing(); + +extern struct IDirectDrawClipper *pDDrawClipper; +extern struct IRender *pRenderer; // idb +extern struct pUnkTerrain *Unks; + + + +/* 248 */ +#pragma pack(push, 1) +struct RenderBillboardTransform_local0 +{ + void *pTarget; + int *pTargetZ; + int uScreenSpaceX; + int uScreenSpaceY; + int _screenspace_x_scaler_packedfloat; + int _screenspace_y_scaler_packedfloat; + char field_18[8]; + unsigned __int16 *pPalette; + unsigned __int16 *pPalette2; + union + { + int sZValue; + struct + { + unsigned short object_pid; + short zbuffer_depth; + }; + }; + unsigned int uFlags; // & 4 - mirror horizontally + unsigned int uTargetPitch; + unsigned int uViewportX; + unsigned int uViewportY; + unsigned int uViewportZ; + unsigned int uViewportW; + int field_44; + int sParentBillboardID; + int sTintColor; +}; +#pragma pack(pop) + + + + +extern int uNumDecorationsDrawnThisFrame; // weak +extern RenderBillboard pBillboardRenderList[500]; +extern unsigned int uNumBillboardsToDraw; +extern int uNumSpritesDrawnThisFrame; // weak + + + + +extern RenderVertexSoft array_507D30[50]; +extern RenderVertexSoft array_50AC10[50]; +extern RenderVertexSoft array_73D150[20]; + +extern RenderVertexD3D3 d3d_vertex_buffer[50]; + + +int ODM_NearClip(unsigned int uVertexID); // idb +int ODM_FarClip(unsigned int uNumVertices); \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/Sprites.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/Sprites.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,813 @@ +#define _CRTDBG_MAP_ALLOC +#include +#include + +#define _CRT_SECURE_NO_WARNINGS +#include +#include +#include "ErrorHandling.h" + +#include "Sprites.h" +#include "PaletteManager.h" +#include "LOD.h" +#include "FrameTableInc.h" + +#include "Outdoor.h" +#include "DecorationList.h" +#include "MM7.h" +#include "Actor.h" +#include "Engine/Graphics/Level/Decoration.h" +#include "OurMath.h" + + + +struct SpriteFrameTable *pSpriteFrameTable; + + + + +//----- (0044D4D8) -------------------------------------------------------- +void SpriteFrameTable::ReleaseSFrames() +{ + free(this->pSpriteSFrames); + this->pSpriteSFrames = nullptr; + this->uNumSpriteFrames = 0; +} + +//----- (0044D4F6) -------------------------------------------------------- +void SpriteFrameTable::ResetSomeSpriteFlags() +{ + int v1; // esi@1 + signed int i; // edx@1 + char *v3; // eax@2 + + v1 = 0; + for ( i = 0; i < (signed int)this->uNumSpriteFrames; ++i ) + { + v3 = (char *)&this->pSpriteSFrames[v1].uFlags; + ++v1; + *v3 &= 0x7Fu; + } +} + +//----- (0044D513) -------------------------------------------------------- +void SpriteFrameTable::InitializeSprite( signed int uSpriteID ) +{ + //SpriteFrameTable *v2; // esi@1 + unsigned int v3; // ebx@3 + //char *v4; // edx@3 + //int v5; // eax@3 +// SpriteFrame *v6; // ecx@5 +// int v7; // eax@5 + __int16 v8; // ax@6 + //signed int v9; // edx@6 + //int v10; // ecx@6 +// signed int v11; // edi@10 + __int16 v12; // ax@16 +// int v13; // ecx@16 + size_t v14; // eax@19 +// signed int v15; // edi@19 +// __int16 v16; // ax@27 +// int v17; // ecx@27 +// signed int v18; // edi@29 +// SpriteFrame *v19; // eax@30 +// __int16 v20; // ax@45 +// int v21; // ecx@45 + + char Str[32]; // [sp+Ch] [bp-3Ch]@19 + char sprite_name[20]; // [sp+2Ch] [bp-1Ch]@15 + char Source[4]; // [sp+40h] [bp-8h]@19 + + + //v2 = this; + if ( uSpriteID <= this->uNumSpriteFrames ) + { + if ( uSpriteID >= 0 ) + { + v3 = uSpriteID; + + int uFlags = pSpriteSFrames[v3].uFlags; + if (!(uFlags & 0x0080)) //not loaded + { + pSpriteSFrames[v3].uFlags |= 0x80; //set loaded + while ( 1 ) + { + pSpriteSFrames[v3].uPaletteIndex = pPaletteManager->LoadPalette(pSpriteSFrames[v3].uPaletteID); + if ( uFlags & 0x10 ) //single frame per frame sequence + { + v8 = pSprites_LOD->LoadSprite(pSpriteSFrames[v3].pTextureName, pSpriteSFrames[v3].uPaletteID); + for (uint i = 0; i < 8; ++i) + { + + pSpriteSFrames[v3].pHwSpriteIDs[i] = v8; + } + + } + else if ( uFlags & 0x10000 ) + { + for (uint i = 0; i < 8; ++i) + { + switch ( i ) + { + case 3: + case 4: + case 5: + sprintf(sprite_name, "%s4", pSpriteSFrames[v3].pTextureName); + break; + case 2: + case 6: + sprintf(sprite_name, "%s2", pSpriteSFrames[v3].pTextureName); + break; + case 0: + case 1: + case 7: + sprintf(sprite_name, "%s0", pSpriteSFrames[v3].pTextureName); + break; + } + v12 = pSprites_LOD->LoadSprite(sprite_name, pSpriteSFrames[v3].uPaletteID); + + pSpriteSFrames[v3].pHwSpriteIDs[i]=v12; + } + + } + else if ( uFlags & 0x40 ) //part of monster fidgeting seq + { + strcpy(Source, "stA"); + strcpy(Str, pSpriteSFrames[v3].pTextureName); + v14 = strlen(Str); + strcpy(&Str[v14-3], Source); + for (uint i = 0; i < 8; ++i) + { + switch ( i ) + { + case 0: + sprintf(sprite_name, "%s0", pSpriteSFrames[v3].pTextureName); + break; + case 4: + sprintf(sprite_name, "%s4",&Str ); + break; + case 3: + case 5: + sprintf(sprite_name, "%s3",&Str ); + break; + case 2: + case 6: + sprintf(sprite_name, "%s2", pSpriteSFrames[v3].pTextureName); + break; + case 1: + case 7: + sprintf(sprite_name, "%s1", pSpriteSFrames[v3].pTextureName); + break; + } + v12 = pSprites_LOD->LoadSprite(sprite_name, pSpriteSFrames[v3].uPaletteID); + pSpriteSFrames[v3].pHwSpriteIDs[i]=v12; + } + } + + else + { + for (uint i = 0; i < 8; ++i) + + { + + if (((0x0100 << i) & pSpriteSFrames[v3].uFlags) ) //mirrors + { + switch ( i ) + { + case 1: + sprintf(sprite_name, "%s7", pSpriteSFrames[v3].pTextureName); + break; + case 2: + sprintf(sprite_name, "%s6", pSpriteSFrames[v3].pTextureName); + break; + case 3: + sprintf(sprite_name, "%s5", pSpriteSFrames[v3].pTextureName); + break; + case 4: + sprintf(sprite_name, "%s4", pSpriteSFrames[v3].pTextureName); + break; + + case 5: + sprintf(sprite_name, "%s3", pSpriteSFrames[v3].pTextureName); + break; + + case 6: + sprintf(sprite_name, "%s2", pSpriteSFrames[v3].pTextureName); + break; + case 7: + sprintf(sprite_name, "%s1", pSpriteSFrames[v3].pTextureName); + break; + } + } + else + { + sprintf(sprite_name, "%s%i", pSpriteSFrames[v3].pTextureName, i); + + } + v12 = pSprites_LOD->LoadSprite(sprite_name, pSpriteSFrames[v3].uPaletteID); + pSpriteSFrames[v3].pHwSpriteIDs[i]=v12; + + } + } + + if ( !(pSpriteSFrames[v3].uFlags & 1) ) + return; + ++v3; + } + } + } + } + } + +//----- (0044D813) -------------------------------------------------------- +signed int SpriteFrameTable::FastFindSprite( char *pSpriteName ) +{ + signed int result; // eax@2 + + int searchResult = BinarySearch(pSpriteName); + if ( searchResult < 0 ) + result = 0; + else + result = this->pSpriteEFrames[searchResult]; + return result; +} + +//----- (0044D83A) -------------------------------------------------------- +int SpriteFrameTable::BinarySearch( const char *pSpriteName ) +{ + int startPos = 0; + int endPos = uNumEFrames; + while ( 1 ) + { + int searchRange = endPos - startPos; + int middleFrameIndex = startPos + (endPos - startPos) / 2; + int comparisonResult = _stricmp(pSpriteName, this->pSpritePFrames[middleFrameIndex]->pIconName); + if ( !comparisonResult ) + { + return middleFrameIndex; + } + if ( startPos == endPos ) + { + return -1; + } + if ( comparisonResult >= 0 ) + { + startPos += max(((endPos - startPos) / 2), 1); + } + else{ + endPos = max(((endPos - startPos) / 2), 1) + startPos; + } + } +} + +//----- (0044D8D0) -------------------------------------------------------- +SpriteFrame *SpriteFrameTable::GetFrame(unsigned int uSpriteID, unsigned int uTime) +{ + //SpriteFrame *v3; // edi@1 + SpriteFrame *v4; // ecx@1 + //__int16 v5; // dx@2 + //int v6; // edx@3 + //unsigned int v7; // eax@3 + //char *i; // ecx@3 + //int v9; // esi@5 + //SpriteFrame *result; // eax@6 + + v4 = &pSpriteSFrames[uSpriteID]; + if (~v4->uFlags & 1 || !v4->uAnimLength) + return pSpriteSFrames + uSpriteID; + + for (uint t = (uTime / 8) % v4->uAnimLength; t > v4->uAnimTime; ++v4) + t -= v4->uAnimTime; + return v4; + + /*for (v4; v4->uAnimTime <= t; ++v4) + + v6 = (uTime / 8) % v4->uAnimLength; + //v7 = uSpriteID; + for ( i = (char *)&v4->uAnimTime; ; i += 60 ) + { + v9 = *(short *)i; + if ( v6 <= v9 ) + break; + v6 -= v9; + ++v7; + } + return &pSpriteSFrames[v7];*/ + +} + +//----- (0044D91F) -------------------------------------------------------- +SpriteFrame *SpriteFrameTable::GetFrameBy_x(unsigned int uSpriteID, signed int a3) +{ + SpriteFrame *v3; // edi@1 + SpriteFrame *v4; // esi@1 + __int16 v5; // ax@2 + int v6; // ecx@3 + int v7; // edx@3 + unsigned int v8; // eax@3 + int v9; // ecx@3 + char *i; // edx@3 + int v11; // esi@5 + SpriteFrame *result; // eax@6 + + v3 = this->pSpriteSFrames; + v4 = &v3[uSpriteID]; + if ( v4->uFlags & 1 && (v5 = v4->uAnimLength) != 0 ) + { + v6 = v5; + v7 = a3 % v5; + v8 = uSpriteID; + v9 = v6 - v7; + for ( i = (char *)&v4->uAnimTime; ; i += 60 ) + { + v11 = *(short *)i; + if ( v9 <= v11 ) + break; + v9 -= v11; + ++v8; + } + result = &v3[v8]; + } + else + { + result = &v3[uSpriteID]; + } + return result; +} + +//----- (0044D96D) -------------------------------------------------------- +void SpriteFrameTable::ToFile() +{ + SpriteFrameTable *v1; // esi@1 + FILE *v2; // eax@1 + FILE *v3; // edi@1 + + v1 = this; + v2 = fopen("data\\dsft.bin", "wb"); + v3 = v2; + if ( !v2 ) + Error("Unable to save dsft.bin!"); + fwrite(v1, 4u, 1u, v2); + fwrite(&v1->uNumEFrames, 4u, 1u, v3); + fwrite(v1->pSpriteSFrames, 0x3Cu, v1->uNumSpriteFrames, v3); + fwrite(v1->pSpriteEFrames, 2u, v1->uNumEFrames, v3); + fclose(v3); +} + +//----- (0044D9D7) -------------------------------------------------------- +void SpriteFrameTable::FromFile(void *data_mm6, void *data_mm7, void *data_mm8) +{ + uint num_mm6_frames = 0; + uint num_mm6_eframes = 0; + if (data_mm6) + { + num_mm6_frames = *(int *)data_mm6; + num_mm6_eframes = *((int *)data_mm6 + 1); + } + + uint num_mm7_frames = 0; + uint num_mm7_eframes = 0; + if (data_mm7) + { + num_mm7_frames = *(int *)data_mm7; + num_mm7_eframes = *((int *)data_mm7 + 1); + } + + uint num_mm8_frames = 0; + uint num_mm8_eframes = 0; + if (data_mm8) + { + num_mm8_frames = *(int *)data_mm8; + num_mm8_eframes = *((int *)data_mm8 + 1); + } + + uNumSpriteFrames = num_mm6_frames + num_mm7_frames + num_mm8_frames; + uNumEFrames = num_mm6_eframes + num_mm7_eframes + num_mm8_eframes; + + pSpriteSFrames = (SpriteFrame *)malloc(uNumSpriteFrames * sizeof(SpriteFrame)); + pSpriteEFrames = (__int16 *)malloc(uNumSpriteFrames * sizeof(short)); + + pSpritePFrames = (SpriteFrame **)malloc(4 * uNumSpriteFrames); + + uint mm7_frames_size = num_mm7_frames * sizeof(SpriteFrame); + memcpy(pSpriteSFrames, (char *)data_mm7 + 8, mm7_frames_size); + memcpy(pSpriteEFrames, (char *)data_mm7 + 8 + mm7_frames_size, 2 * num_mm7_eframes); + + uint mm6_frames_size = num_mm6_frames * sizeof(SpriteFrame_mm6); + for (uint i = 0; i < num_mm6_frames; ++i) + { + memcpy(pSpriteSFrames + num_mm7_frames + i, (char *)data_mm6 + 8 + i * sizeof(SpriteFrame_mm6), sizeof(SpriteFrame_mm6)); + pSpriteSFrames[num_mm7_frames + i].uAnimLength = 0; + } + memcpy(pSpriteEFrames + num_mm7_frames, (char *)data_mm6 + 8 + mm6_frames_size, 2 * num_mm6_eframes); + + uint mm8_frames_size = num_mm8_frames * sizeof(SpriteFrame); + memcpy(pSpriteSFrames + num_mm6_frames + num_mm7_frames, (char *)data_mm8 + 8, mm8_frames_size); + memcpy(pSpriteEFrames + num_mm6_frames + num_mm7_frames, (char *)data_mm8 + 8 + mm8_frames_size, 2 * num_mm8_eframes); + + //the original was using num_mmx_frames, but never accessed any element beyond num_mmx_eframes, but boing beyong eframes caused invalid memory accesses + for (uint i = 0; i < num_mm6_eframes + num_mm7_eframes + num_mm8_eframes; ++i) + pSpritePFrames[i] = &pSpriteSFrames[pSpriteEFrames[i]]; +} + +//----- (0044DA92) -------------------------------------------------------- +bool SpriteFrameTable::FromFileTxt(const char *Args) +{ + SpriteFrameTable *v2; // ebx@1 + FILE *v3; // eax@1 + unsigned int v4; // esi@3 + signed int result; // eax@10 + FILE *v6; // ST18_4@11 + char *i; // eax@11 + const char *v8; // ST20_4@14 + __int16 v9; // ax@14 + const char *v10; // ST0C_4@14 + double v11; // st7@14 + int v12; // eax@14 + const char *v13; // ST04_4@14 + __int16 v14; // ax@14 + const char *v15; // ST00_4@14 + int v16; // eax@14 + int v17; // eax@17 + int v18; // eax@23 + int v19; // eax@24 + int v20; // eax@25 + int v21; // eax@28 + int v22; // eax@29 + int j; // edi@30 + const char *v24; // esi@31 + int v25; // eax@32 + int v26; // edx@53 + int v27; // ecx@54 + int v28; // eax@55 + signed int k; // edx@58 + SpriteFrame *v30; // ecx@59 + int v31; // esi@59 + int l; // eax@60 + signed int v33; // eax@65 + int v34; // edi@66 + int v35; // esi@66 + SpriteFrame **v36; // eax@69 + int v37; // ecx@69 + SpriteFrame *v38; // edx@69 + __int16 *v39; // eax@69 + int v40; // ecx@69 + char Buf[500]; // [sp+Ch] [bp-2F0h]@3 + FrameTableTxtLine v42; // [sp+200h] [bp-FCh]@4 + FrameTableTxtLine v43; // [sp+27Ch] [bp-80h]@4 + FILE *File; // [sp+2F8h] [bp-4h]@1 + unsigned int Argsa; // [sp+304h] [bp+8h]@3 + int Argsb; // [sp+304h] [bp+8h]@59 + FILE *Argsc; // [sp+304h] [bp+8h]@67 + + v2 = this; + ReleaseSFrames(); + v3 = fopen(Args, "r"); + File = v3; + if ( !v3 ) + Error("CSpriteFrameTable::load - Unable to open file: %s.", Args); + + v4 = 0; + Argsa = 0; + if ( fgets(Buf, 490, v3) ) + { + do + { + *strchr(Buf, '\n') = 0; + memcpy(&v43, frame_table_txt_parser(Buf, &v42), sizeof(v43)); + if ( v43.uPropCount && *v43.pProperties[0] != '/' ) + ++Argsa; + } + while ( fgets(Buf, 490, File) ); + v4 = Argsa; + } + v2->uNumSpriteFrames = v4; + v2->pSpriteSFrames = (SpriteFrame *)malloc(60 * v4); + v2->pSpriteEFrames = (__int16 *)malloc(2 * v2->uNumSpriteFrames); + v2->pSpritePFrames = (SpriteFrame **)malloc(4 * v2->uNumSpriteFrames); + if ( v2->pSpriteSFrames ) + { + v6 = File; + v2->uNumSpriteFrames = 0; + fseek(v6, 0, 0); + for ( i = fgets(Buf, 490, File); i; i = fgets(Buf, 490, File) ) + { + *strchr(Buf, 10) = 0; + memcpy(&v43, frame_table_txt_parser(Buf, &v42), sizeof(v43)); + if ( v43.uPropCount && *v43.pProperties[0] != '/' ) + { + v8 = v43.pProperties[0]; + v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags = 0; + v2->pSpriteSFrames[v2->uNumSpriteFrames].uPaletteIndex = 0; + strcpy(v2->pSpriteSFrames[v2->uNumSpriteFrames].pIconName, v8); + strcpy(v2->pSpriteSFrames[v2->uNumSpriteFrames].pTextureName, v43.pProperties[1]); + v9 = atoi(v43.pProperties[3]); + v10 = v43.pProperties[4]; + v2->pSpriteSFrames[v2->uNumSpriteFrames].uPaletteID = v9; + v11 = atof(v10) * 65536.0; + v12 = abs((signed __int64)v11); + v13 = v43.pProperties[5]; + v2->pSpriteSFrames[v2->uNumSpriteFrames].scale = v12; + v14 = atoi(v13); + v15 = v43.pProperties[6]; + v2->pSpriteSFrames[v2->uNumSpriteFrames].uGlowRadius = v14; + v2->pSpriteSFrames[v2->uNumSpriteFrames].uAnimTime = atoi(v15); + v16 = (int)&v2->pSpriteSFrames[v2->uNumSpriteFrames]; + if ( *(short *)(v16 + 48) ) + *(int *)(v16 + 44) |= 2u; + if ( !_stricmp(v43.pProperties[2], "new") ) + { + v17 = (int)&v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags; + *(int *)v17 |= 4u; + v2->pSpritePFrames[v2->uNumEFrames] = &v2->pSpriteSFrames[v2->uNumSpriteFrames]; + v2->pSpriteEFrames[v2->uNumEFrames++] = LOWORD(v2->uNumSpriteFrames); + } + if ( !_stricmp(v43.pProperties[10], "1") ) + BYTE2(v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags) |= 4u; + if ( !_stricmp(v43.pProperties[11], "1") ) + BYTE2(v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags) |= 2u; + if ( !_stricmp(v43.pProperties[12], "1") ) + { + v18 = (int)&v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags; + *(int *)v18 |= 0x20u; + } + v19 = atoi(v43.pProperties[7]) - 1; + if ( v19 ) + { + v20 = v19 - 2; + if ( v20 ) + { + if ( v20 == 2 ) + BYTE1(v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags) |= 0xE0u; + } + else + { + v21 = (int)&v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags; + *(int *)v21 |= 0x1E000u; + } + } + else + { + v22 = (int)&v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags; + *(int *)v22 |= 0x10u; + } + for ( j = 13; j < v43.uPropCount; ++j ) + { + v24 = v43.pProperties[j]; + if ( _stricmp(v43.pProperties[j], "Luminous") ) + { + if ( _stricmp(v24, "Mirror0") ) + { + if ( _stricmp(v24, "Mirror1") ) + { + if ( _stricmp(v24, "Mirror2") ) + { + if ( _stricmp(v24, "Mirror3") ) + { + if ( _stricmp(v24, "Mirror4") ) + { + if ( _stricmp(v24, "Mirror5") ) + { + if ( _stricmp(v24, "Mirror6") ) + { + if ( !_stricmp(v24, "Mirror7") ) + BYTE1(v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags) |= 0x80u; + } + else + { + BYTE1(v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags) |= 0x40u; + } + } + else + { + BYTE1(v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags) |= 0x20u; + } + } + else + { + BYTE1(v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags) |= 0x10u; + } + } + else + { + BYTE1(v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags) |= 8u; + } + } + else + { + BYTE1(v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags) |= 4u; + } + } + else + { + BYTE1(v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags) |= 2u; + } + } + else + { + BYTE1(v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags) |= 1u; + } + } + else + { + v25 = (int)&v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags; + *(int *)v25 |= 2u; + } + } + ++v2->uNumSpriteFrames; + } + } + fclose(File); + v26 = 0; + if ( (signed int)(v2->uNumSpriteFrames - 1) > 0 ) + { + v27 = 0; + do + { + v28 = (int)&v2->pSpriteSFrames[v27]; + if ( !(*(char *)(v28 + 104) & 4) ) + *(int *)(v28 + 44) |= 1u; + ++v26; + ++v27; + } + while ( v26 < (signed int)(v2->uNumSpriteFrames - 1) ); + } + for ( k = 0; k < (signed int)v2->uNumSpriteFrames; *(short *)(Argsb + 56) = v31 ) + { + v30 = v2->pSpriteSFrames; + Argsb = (int)&v30[k]; + v31 = *(short *)(Argsb + 54); + if ( *(char *)(Argsb + 44) & 1 ) + { + ++k; + for ( l = (int)&v30[k]; *(char *)(l + 44) & 1; l += 60 ) + { + v31 += *(short *)(l + 54); + ++k; + } + LOWORD(v31) = v30[k].uAnimTime + v31; + } + ++k; + } + v33 = v2->uNumEFrames; + if ( v33 > 0 ) + { + v34 = 0; + v35 = 0; + File = (FILE *)1; + do + { + Argsc = File; + if ( (signed int)File < v33 ) + { + do + { + if ( _stricmp(v2->pSpritePFrames[(int)Argsc]->pIconName, v2->pSpritePFrames[v35]->pIconName) < 0 ) + { + v36 = v2->pSpritePFrames; + v37 = (int)&v36[(int)Argsc]; + v38 = *(SpriteFrame **)v37; + *(int *)v37 = (int)v36[v35]; + v2->pSpritePFrames[v35] = v38; + v39 = v2->pSpriteEFrames; + v40 = (int)&v39[(int)Argsc]; + LOWORD(v38) = *(short *)v40; + *(short *)v40 = v39[v34]; + v2->pSpriteEFrames[v34] = (signed __int16)v38; + } + Argsc = (FILE *)((char *)Argsc + 1); + } + while ( (signed int)Argsc < v2->uNumEFrames ); + } + File = (FILE *)((char *)File + 1); + v33 = v2->uNumEFrames; + ++v35; + ++v34; + } + while ( (signed int)((char *)File - 1) < v33 ); + } + result = 1; + } + else + { + MessageBoxW(nullptr, L"CSpriteFrameTable::load - Out of Memory!", nullptr, 0); + fclose(File); + result = 0; + } + return result; +} +//----- (0046E26D) -------------------------------------------------------- +void __fastcall _46E26D_collide_against_sprites(signed int a1, signed int a2) +{ + int v2; // edx@5 + unsigned __int16 *v3; // eax@5 + unsigned __int16 v4; // ax@6 + LevelDecoration *v5; // edi@7 + DecorationDesc *v6; // esi@8 + int v7; // edx@9 + int v8; // eax@9 + int v9; // ecx@11 + int v10; // ebx@13 + int v11; // esi@13 + int v12; // ebp@15 + int v13; // ebx@15 + int v14; // esi@16 + int v15; // edi@17 + int v16; // eax@17 + int v17; // esi@19 + char v18; // zf@23 + int v19; // [sp+0h] [bp-10h]@15 + unsigned __int16 *v20; // [sp+4h] [bp-Ch]@5 + int v21; // [sp+8h] [bp-8h]@15 + int v22; // [sp+Ch] [bp-4h]@13 + + if ( a1 >= 0 ) + { + if ( a1 <= 127 ) + { + if ( a2 >= 0 ) + { + if ( a2 <= 127 ) + { + v2 = a1 + (a2 << 7); + v3 = &pOutdoor->pFaceIDLIST[pOutdoor->pOMAP[v2]]; + v20 = &pOutdoor->pFaceIDLIST[pOutdoor->pOMAP[v2]]; + if ( v3 ) + { + do + { + v4 = *v3; + if ( PID_TYPE(v4) == OBJECT_Decoration) + { + v5 = &pLevelDecorations[(signed __int16)v4 >> 3]; + if (!(v5->uFlags & LEVEL_DECORATION_INVISIBLE)) + { + v6 = &pDecorationList->pDecorations[v5->uDecorationDescID]; + if (!v6->CanMoveThrough()) + { + v7 = v6->uRadius; + v8 = v5->vPosition.x; + if ( stru_721530.sMaxX <= v8 + v7 ) + { + if ( stru_721530.sMinX >= v8 - v7 ) + { + v9 = v5->vPosition.y; + if ( stru_721530.sMaxY <= v9 + v7 ) + { + if ( stru_721530.sMinY >= v9 - v7 ) + { + v10 = v6->uDecorationHeight; + v11 = v5->vPosition.z; + v22 = v10; + if ( stru_721530.sMaxZ <= v11 + v10 ) + { + if ( stru_721530.sMinZ >= v11 ) + { + v12 = v8 - stru_721530.normal.x; + v19 = v9 - stru_721530.normal.y; + v13 = stru_721530.prolly_normal_d + v7; + v21 = ((v8 - stru_721530.normal.x) * stru_721530.direction.y + - (v9 - stru_721530.normal.y) * stru_721530.direction.x) >> 16; + if ( abs(v21) <= stru_721530.prolly_normal_d + v7 ) + { + v14 = (v12 * stru_721530.direction.x + v19 * stru_721530.direction.y) >> 16; + if ( v14 > 0 ) + { + v15 = v5->vPosition.z; + v16 = stru_721530.normal.z + fixpoint_mul(stru_721530.direction.z, v14); + if ( v16 >= v15 ) + { + if ( v16 <= v22 + v15 ) + { + v17 = v14 - integer_sqrt(v13 * v13 - v21 * v21); + if ( v17 < 0 ) + v17 = 0; + if ( v17 < stru_721530.field_7C ) + { + stru_721530.field_7C = v17; + stru_721530.uFaceID = (signed __int16)*v20; + } + } + } + } + } + } + } + } + } + } + } + } + } + } + v3 = v20 + 1; + v18 = *v20 == 0; + ++v20; + } + while ( !v18 ); + } + } + } + } + } +} diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/Sprites.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/Sprites.h Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,88 @@ +#pragma once + + +/* 18 */ +#pragma pack(push, 1) +class Sprite //28h +{ +public: + void Release(); + + const char *pName; //0 + int uPaletteID; //4 + struct IDirectDrawSurface4 *pTextureSurface; //8 + struct IDirect3DTexture2 *pTexture; //ch + int uAreaX; //10h + int uAreaY; //14h + int uBufferWidth; //18h + int uBufferHeight; //1ch + int uAreaWidth; //20h + int uAreaHeight; //24h +}; +#pragma pack(pop) + + +/* 42 */ +#pragma pack(push, 1) +struct SpriteFrame_mm6 +{ + char pIconName[12]; + char pTextureName[12]; //c + __int16 pHwSpriteIDs[8]; //18h + int scale; //28h + int uFlags; //2c + __int16 uGlowRadius; //30 + __int16 uPaletteID; //32 + __int16 uPaletteIndex; + __int16 uAnimTime; + //__int16 uAnimLength; + //__int16 _pad; +}; + +class SpriteFrame: public SpriteFrame_mm6 +{ +public: + __int16 uAnimLength; + __int16 _pad; +}; +#pragma pack(pop) + +/* 43 */ +#pragma pack(push, 1) +struct SpriteFrameTable +{ + //----- (0044D4BA) -------------------------------------------------------- + inline SpriteFrameTable() + { + uNumSpriteFrames = 0; + pSpriteSFrames = nullptr; + pSpritePFrames = nullptr; + pSpriteEFrames = nullptr; + } + void ToFile(); + void FromFile(void *data_mm6, void *data_mm7, void *data_mm8); + bool FromFileTxt(const char *Args); + void ReleaseSFrames(); + void ResetSomeSpriteFlags(); + void InitializeSprite(signed int uSpriteID); + signed int FastFindSprite(char *pSpriteName); + int BinarySearch(const char *pSpriteName); + SpriteFrame *GetFrame(unsigned int uSpriteID, unsigned int uTime); + SpriteFrame *GetFrameBy_x(unsigned int uSpriteID, signed int a3); + + signed int uNumSpriteFrames; + unsigned int uNumEFrames;//field_4; + int unused_field; //field_8 + SpriteFrame *pSpriteSFrames; //0c + SpriteFrame **pSpritePFrames; //10h + __int16 *pSpriteEFrames; //14h +}; +#pragma pack(pop) + + + + +void __fastcall _46E26D_collide_against_sprites(signed int a1, signed int a2); + + +extern struct SpriteFrameTable *pSpriteFrameTable; \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/Texture.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/Texture.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,1960 @@ +#define _CRTDBG_MAP_ALLOC +#include +#include + +#define _CRT_SECURE_NO_WARNINGS +#include + +#include "Texture.h" +#include "FrameTableInc.h" +#include "LOD.h" +#include "PaletteManager.h" +#include "ErrorHandling.h" +#include "ZlibWrapper.h" + +#include "mm7_data.h" + +#include "OurMath.h" + + + + + + + + +struct TextureFrameTable *pTextureFrameTable; + + + + + +std::array pTexture_LloydBeacons; +Texture *pTexture_50635C; +Texture *pTex_book_button8_off; +Texture *pTex_book_button8_on; +Texture *pTex_book_button7_off; +Texture *pTex_book_button7_on; +Texture *pTex_book_button6_off; +Texture *pTex_book_button6_on; +Texture *pTex_book_button5_off; +Texture *pTex_book_button5_on; +Texture *pTex_book_button4_off; +Texture *pTex_book_button4_on; +Texture *pTex_book_button3_off; +Texture *pTex_book_button3_on; +Texture *pTex_book_button2_off; +Texture *pTex_book_button1_off; +Texture *pTex_book_button2_on; +Texture *pTex_book_button1_on; +std::array pTexture_TownPortalIcons; // [0]Harmonale, [1]Pierpont, [2]Nighon, [3]Evenmorn Island, [4]Celestia, [5]The Pit +std::array SBPageCSpellsTextureList; +std::array SBPageSSpellsTextureList; +Texture *pSBQuickSpellBtnTextr; +Texture *pSpellBookClickCloseBtnTextr; +Texture *pSBClickQuickSpellBtnTextr; +Texture *pSpellBookCloseBtnTextr; +std::array, 9> pTextures_tabs; +Texture *pTexture_mapbordr; // idb +Texture *pTexture_pagemask; // idb +std::array pSpellBookPagesTextr; +Texture *pSpellBookPagesTextr_9; +Texture *pSpellBookPagesTextr_10; +Texture *pSpellBookPagesTextr_11; +Texture *pSpellBookPagesTextr_12; +Texture *pSpellBookPagesTextr_13; +Texture *pTexture_AutonotesBook; +Texture *pTexture_CurrentBook; +Texture *pTex_moon_new; +Texture *pTex_moon_4; +Texture *pTex_moon_2; +Texture *pTex_moon_2_2; +Texture *pTex_moon_ful; + + + +RGBTexture stru_506E40; // weak +RGBTexture pTexture_PCX; + + +int uTextureID_RestUI_restb4; // weak +int uTextureID_RestUI_restexit; // weak +int uTextureID_RestUI_restb3; // weak +int uTextureID_RestUI_restb1; // weak +int uTextureID_RestUI_restb2; // weak +int uTextureID_RestUI_restmain; // weak +unsigned int uTextureID_Leather; +int uTextureID_ar_dn_dn; // weak +int uTextureID_ar_dn_up; // weak +int uTextureID_ar_up_dn; // weak +int uTextureID_ar_up_up; // weak + + +int uTextureID_507698; // weak +int uTextureID_50769C; // weak +int uTextureID_5076A0; // weak +int uTextureID_5076A4; // weak +int uTextureID_5076A8; // weak +int uTextureID_5076AC; // weak +int uTextureID_5076B0; // weak +int uTextureID_5076B4; // weak +int uTextureID_Parchment; // weak +unsigned int uTextureID_mhp_yel; +unsigned int uTextureID_mhp_red; +unsigned int uTextureID_mhp_grn; +unsigned int uTextureID_mhp_capr; +unsigned int uTextureID_mhp_capl; +unsigned int uTextureID_mhp_bd; +unsigned int uTextureID_BUTTDESC2; +unsigned int uTextureID_x_x_u; +unsigned int uTextureID_BUTTMAKE2; +unsigned int uTextureID_BUTTMAKE; +unsigned int uTextureID_BUTTYES2; +unsigned int uTextureID_x_ok_u; +std::array pPlayerPortraits; +std::array pTexture_IC_KNIGHT; +Texture *pTexture_MAKESKY; +Texture *pTexture_MAKETOP; +std::array pTextures_arrowr; +std::array pTextures_arrowl; +Texture *pTexture_presleft; +Texture *pTexture_pressrigh; +Texture *pTexture_buttminu; +Texture *pTexture_buttplus; +unsigned int uTextureID_Quit1; // weak +unsigned int uTextureID_Resume1; // weak +unsigned int uTextureID_Controls1; // weak +unsigned int uTextureID_Save1; // weak +unsigned int uTextureID_Load1; // weak +unsigned int uTextureID_New1; // weak +unsigned int uTextureID_Options; // weak + + +unsigned int uTextureID_ib_td5_A; +unsigned int uTextureID_ib_td4_A; +unsigned int uTextureID_ib_td3_A; +unsigned int uTextureID_ib_td2_A; +unsigned int uTextureID_ib_td1_A; +int uTextureID_CharacterUI_InventoryBackground; // weak +int uTextureID_50795C; // weak + + +unsigned int uTextureID_Btn_GameSettings; + + +unsigned int uTextureID_Btn_Rest; +unsigned int uTextureID_Btn_CastSpell; +unsigned int uTextureID_Btn_ZoomIn; +unsigned int uTextureID_Btn_ZoomOut; +unsigned int uTextureID_FONTPAL; +unsigned int uTextureID_Btn_NPCRight; +unsigned int uTextureID_Btn_NPCLeft; +std::array pTextureIDs_pMapDirs; + + +unsigned int uTextureID_BarRed; +unsigned int uTextureID_BarYellow; +unsigned int uTextureID_BarGreen; +unsigned int uTextureID_BarBlue; + + +unsigned int uTextureID_right_panel; // weak + + +RGBTexture *pTexture_StatusBar = new RGBTexture; +RGBTexture *pTexture_LeftFrame = new RGBTexture; +RGBTexture *pTexture_TopFrame = new RGBTexture; +RGBTexture *pTexture_BottomFrame = new RGBTexture; +RGBTexture *pTexture_RightFrame = new RGBTexture; + + +unsigned int uTextureID_right_panel_loop; + + +Texture *pTexture_Leather; +Texture *pTexture_RestUI_CurrentSkyFrame; // idb +Texture *pTexture_RestUI_CurrentHourglassFrame; // idb + + +std::array uTextureID_Optkb; + +unsigned int optvid_base_texture_id; +unsigned int bloodsplats_texture_id; +unsigned int us_colored_lights_texture_id; +unsigned int tinting_texture_id; +unsigned int uTextureID_507C20; // weak +unsigned int uTextureID_507C24; // weak +std::array pTextureIDs_GammaPositions; +unsigned int not_available_bloodsplats_texture_id; +unsigned int not_available_us_colored_lights_texture_id; +unsigned int not_available_tinting_texture_id; + + +unsigned int uTextureID_detaliz_close_button; // weak +unsigned int uTextureID_MAGNIF_B; // weak +unsigned int uTextureID_BACKDOLL; // weak +unsigned int uTextureID_BACKHAND; // weak + +stru355 stru_4E82A4 = {0x20, 0x41, 0, 0x20, 0xFF0000, 0xFF00, 0xFF, 0xFF000000}; +stru355 stru_4EFCBC = {0x20, 0x41, 0, 0x10, 0x7C00, 0x3E0, 0x1F, 0x8000}; + +Texture pTex_F7CE30; + + +RGBTexture stru_5773C4; // idb + + + + + + + + + + + +/* 245 */ +#pragma pack(push, 1) +struct PCXHeader1 +{ + char magic; + char version; + char encoding; + char bpp; + __int16 left; + __int16 up; + __int16 right; + __int16 bottom; + __int16 hres; + __int16 vres; +}; +#pragma pack(pop) + +/* 246 */ +#pragma pack(push, 1) +struct PCXHeader2 +{ + char reserved; + char planes; + __int16 pitch; + __int16 palette_info; +}; +#pragma pack(pop) + + + + + + + + + +//----- (0044E054) -------------------------------------------------------- +void TextureFrameTable::ToFile() +{ + TextureFrameTable *v1; // esi@1 + FILE *v2; // eax@1 + FILE *v3; // edi@1 + + v1 = this; + v2 = fopen("data\\dtft.bin", "wb"); + v3 = v2; + if ( !v2 ) + Error("Unable to save dtft.bin!"); + fwrite(v1, 4u, 1u, v2); + fwrite(v1->pTextures, 0x14u, v1->sNumTextures, v3); + fclose(v3); +} + +//----- (0044E0A0) -------------------------------------------------------- +void TextureFrameTable::FromFile(void *data_mm6, void *data_mm7, void *data_mm8) +{ + uint num_mm6_frames = data_mm6 ? *(int *)data_mm6 : 0, + num_mm7_frames = data_mm7 ? *(int *)data_mm7 : 0, + num_mm8_frames = data_mm8 ? *(int *)data_mm8 : 0; + + sNumTextures = num_mm6_frames + num_mm7_frames + num_mm8_frames; + Assert(sNumTextures); + Assert(!num_mm8_frames); + + pTextures = (TextureFrame *)malloc(sNumTextures * sizeof(TextureFrame)); + + memcpy(pTextures, (char *)data_mm7 + 4, num_mm7_frames * sizeof(TextureFrame)); + memcpy(pTextures + num_mm7_frames, (char *)data_mm6 + 4, num_mm6_frames * sizeof(TextureFrame)); + memcpy(pTextures + num_mm6_frames + num_mm7_frames, (char *)data_mm8 + 4, num_mm8_frames * sizeof(TextureFrame)); +} + +//----- (0044E0ED) -------------------------------------------------------- +void TextureFrameTable::LoadAnimationSequenceAndPalettes( signed int uIconID ) +{ + //TextureFrameTable *v3; // ebx@1 + unsigned int i; // edi@3 + + //v3 = this; + if ( (uIconID <= this->sNumTextures) && uIconID >= 0 ) + { + for ( i = uIconID; ; ++i ) + { + this->pTextures[i].uTextureID = pBitmaps_LOD->LoadTexture(this->pTextures[i].pTextureName, TEXTURE_DEFAULT); + + if (this->pTextures[i].uTextureID != -1) + pBitmaps_LOD->pTextures[this->pTextures[i].uTextureID].palette_id2 = pPaletteManager->LoadPalette(pBitmaps_LOD->pTextures[this->pTextures[i].uTextureID].palette_id1); + //result = (unsigned int)v3->pTextures; + //if ( !(*(char *)(result + i * 20 + 18) & 1) ) + if( this->pTextures[i].uFlags & 1) + break; + } + } + return; +} + +//----- (0044E163) -------------------------------------------------------- +signed int TextureFrameTable::FindTextureByName(const char *Str2) +{ + if ( (signed int)this->sNumTextures <= 0 ) + return -1; + for ( int i = 0; (signed int)i < (signed int)this->sNumTextures; ++i ) + { + if ( !_stricmp(this->pTextures[i].pTextureName, Str2) ) + return i; + } + return -1; +} + +//----- (0044E19A) -------------------------------------------------------- +int TextureFrameTable::GetFrameTexture(int uFrameID, signed int a3) +{ + int v3; // esi@1 + TextureFrame *v4; // edi@1 + TextureFrame *v5; // ecx@1 + __int16 v6; // dx@2 + int v7; // edx@3 + char *i; // eax@3 + int v9; // ecx@5 + unsigned int result; // eax@6 + + v3 = uFrameID; + v4 = this->pTextures; + v5 = &v4[uFrameID]; + if ( v5->uFlags & 1 && (v6 = v5->uAnimLength) != 0 ) + { + v7 = (a3 >> 3) % v6; + for ( i = (char *)&v5->uAnimTime; ; i += 20 ) + { + v9 = *(short *)i; + if ( v7 <= v9 ) + break; + v7 -= v9; + ++v3; + } + result = v4[v3].uTextureID; + } + else + { + result = v5->uTextureID; + } + return result; +} + + + + + + +//----- (0040F806) -------------------------------------------------------- +void *Texture::UnzipPalette() +{ + Texture *v1; // esi@1 + + void *v2; // edi@1 + Texture *pSource; // [sp+0h] [bp-4h]@1 + + pSource = this; + v1 = this; + v2 = malloc(this->uDecompressedSize); + zlib::MemUnzip(v2, (unsigned int *)&pSource, v1->pLevelOfDetail0_prolly_alpha_mask, v1->uTextureSize); + return v2; +} + +//----- (0040F77C) -------------------------------------------------------- +void Texture::Release() +{ + if (this) + { + pName[0] = 0; + + if (pBits & 0x0400) + { + __debugbreak(); + } + + free(pLevelOfDetail0_prolly_alpha_mask); + free(pPalette16); + free(pPalette24); + + + pLevelOfDetail0_prolly_alpha_mask = nullptr; + pLevelOfDetail1 = nullptr; + pLevelOfDetail2 = nullptr; + pLevelOfDetail3 = nullptr; + + pPalette16 = nullptr; + pPalette24 = nullptr; + + uSizeOfMaxLevelOfDetail = 0; + uTextureSize = 0; + uTextureHeight = 0; + uTextureWidth = 0; + uHeightLn2 = 0; + uWidthLn2 = 0; + palette_id1 = 0; + palette_id2 = 0; + pBits &= 0xFFFF0000; + } +} + +//----- (0040F5F5) -------------------------------------------------------- +int RGBTexture::Reload(const char *pContainer) +{ + //RGBTexture *v2; // esi@1 + FILE *v3; // eax@3 + FILE *v4; // edi@3 + void *v5; // ebx@7 + signed int result; // eax@11 + unsigned int v7; // ecx@12 + unsigned __int16 *v8; // ST20_4@14 + int v9; // eax@14 + char color_map[48]; // [sp+8h] [bp-98h]@9 + Texture DstBuf; // [sp+38h] [bp-68h]@1 + PCXHeader1 header1; // [sp+80h] [bp-20h]@9 + PCXHeader2 header2; // [sp+90h] [bp-10h]@9 + FILE *File; // [sp+98h] [bp-8h]@3 + size_t Count; // [sp+9Ch] [bp-4h]@6 + void *uSourceLena; // [sp+A8h] [bp+8h]@7 + + // v2 = this; + if ( !this->pPixels ) + return 2; + v3 = pIcons_LOD->FindContainer(pContainer, 0); + v4 = v3; + File = v3; + if ( !v3 ) + Error("Unable to load %s", pContainer); + + fread(&DstBuf, 1, 0x30, v3); + Count = DstBuf.uTextureSize; + if ( DstBuf.uDecompressedSize ) + { + v5 = malloc(DstBuf.uDecompressedSize); + uSourceLena = malloc(DstBuf.uTextureSize); + fread(uSourceLena, 1, Count, File); + zlib::MemUnzip(v5, &DstBuf.uDecompressedSize, uSourceLena, DstBuf.uTextureSize); + DstBuf.uTextureSize = DstBuf.uDecompressedSize; + free(uSourceLena); + } + else + { + v5 = malloc(DstBuf.uTextureSize); + fread(v5, 1, Count, v4); + } + memcpy(&header1, v5, 0x10u); + memcpy(color_map, (char *)v5 + 16, 0x30); + memcpy(&header2, (char *)v5 + 64, 6); + if ( header1.bpp != 8 ) + return 3; + v7 = (signed __int16)(header1.right - header1.left + 1); + if ( (signed int)(v7 * (signed __int16)(header1.bottom - header1.up + 1)) <= (signed int)this->uNumPixels ) + { + this->uWidth = header1.right - header1.left + 1; + v8 = this->pPixels; + v9 = v7 * this->uHeight; + this->uNumPixels = v9; + this->uHeight = v9; + this->DecodePCX((char *)v5, v8, v7); + free(v5); + result = 0; + } + else + { + result = -1; + } + return result; +} + +//----- (0040F5BE) -------------------------------------------------------- +Texture::Texture() +{ + pName[0] = 0; + uSizeOfMaxLevelOfDetail = 0; + uTextureSize = 0; + uTextureHeight = 0; + uTextureWidth = 0; + uHeightLn2 = 0; + uWidthLn2 = 0; + palette_id1 = 0; + palette_id2 = 0; + pLevelOfDetail0_prolly_alpha_mask = nullptr; + pLevelOfDetail3 = nullptr; + pLevelOfDetail2 = nullptr; + pLevelOfDetail1 = nullptr; + pPalette16 = nullptr; + pPalette24 = nullptr; +} + +//----- (0040F414) -------------------------------------------------------- +int RGBTexture::Load(const char *pContainer, int mode) +{ + FILE *file; // eax@1 + void *v6; // ebx@5 + char color_map[48]; // [sp+Ch] [bp-98h]@7 + Texture DstBuf; // [sp+3Ch] [bp-68h]@1 + PCXHeader1 header1; // [sp+84h] [bp-20h]@7 + PCXHeader2 header2; // [sp+94h] [bp-10h]@7 + size_t Count; // [sp+A0h] [bp-4h]@4 + char *Str1a; // [sp+ACh] [bp+8h]@5 + + file = pIcons_LOD->FindContainer(pContainer, 0); + if ( !file ) + Error("Unable to load %s", pContainer); + + fread(&DstBuf, 1, 0x30u, file); + Count = DstBuf.uTextureSize; + if ( DstBuf.uDecompressedSize ) + { + Str1a = (char *)malloc(DstBuf.uDecompressedSize); + v6 = malloc(DstBuf.uTextureSize); + fread(v6, 1, Count, file); + zlib::MemUnzip(Str1a, &DstBuf.uDecompressedSize, v6, DstBuf.uTextureSize); + DstBuf.uTextureSize = DstBuf.uDecompressedSize; + free(v6); + } + else + { + Str1a = (char *)malloc(DstBuf.uTextureSize); + fread(Str1a, 1, Count, file); + } + memcpy(&header1, Str1a, 0x10u); + memcpy(color_map, Str1a + 16, 0x30u); + memcpy(&header2, Str1a + 64, 6); + if ( header1.bpp != 8 ) + return 3; + this->uWidth = header1.right - header1.left + 1; + this->uHeight = header1.bottom - header1.up + 1; + this->uNumPixels = (signed __int16)this->uWidth * (signed __int16)this->uHeight; + this->pPixels = (unsigned __int16 *)malloc(2 * this->uNumPixels + 4); + if ( this->pPixels ) + { + if ( mode ) + { + if ( mode != 2 ) + { + if ( !this->pPixels ) + return 2; + this->DecodePCX(Str1a, this->pPixels, this->uWidth); + free(Str1a); + return 0; + } + this->_allocation_flags |= 1; + this->pPixels = (unsigned __int16 *)malloc(2 * this->uNumPixels + 4); + if ( !this->pPixels ) + return 2; + this->DecodePCX(Str1a, this->pPixels, this->uWidth); + free(Str1a); + return 0; + } + free(this->pPixels); + } + if ( !mode ) + { + this->pPixels = (unsigned __int16 *)malloc(2 * this->uNumPixels + 4); + if ( !this->pPixels ) + return 2; + this->DecodePCX(Str1a, this->pPixels, this->uWidth); + free(Str1a); + return 0; + } + if ( mode != 2 ) + { + if ( !this->pPixels ) + return 2; + this->DecodePCX(Str1a, this->pPixels, this->uWidth); + free(Str1a); + return 0; + } + this->_allocation_flags |= 1; + this->pPixels = (unsigned __int16 *)malloc(2 * this->uNumPixels + 4); + if ( !this->pPixels ) + return 2; + this->DecodePCX(Str1a, this->pPixels, this->uWidth); + free(Str1a); + return 0; +} + +//----- (0040F037) -------------------------------------------------------- +signed int RGBTexture::DecodePCX(char *pPcx, unsigned __int16 *pOutPixels, unsigned int uNumPixels) +{ +// signed int result; // eax@2 + unsigned char test_byte; // edx@3 + unsigned int read_offset; // ebx@37 + unsigned int row_position; // edi@40 + unsigned char value; // cl@63 + char count; // [sp+50h] [bp-Ch]@43 + unsigned short current_line; // [sp+54h] [bp-8h]@38 + unsigned short *dec_position; + unsigned short *temp_dec_position; + PCXHeader1 psx_head1; + PCXHeader2 psx_head2; +// short int width, height; + BYTE color_map[48]; // Colormap for 16-color images + + + memcpy(&psx_head1, pPcx , 16); + memcpy(&color_map, pPcx + 16, 48); + memcpy(&psx_head2, pPcx + 64, 6); + + + if (psx_head1.bpp!=8) + return 3; + uWidth=(short int )(psx_head1.right-psx_head1.left+1); // word @ 000014 + uHeight=(short int )(psx_head1.bottom-psx_head1.up+1); // word @ 000016 + + + uNumPixels=uWidth*uHeight; // dword @ 000010 + + memset(pOutPixels, 0, uNumPixels * sizeof(__int16)); + short i=1; + while ( (1<= 15) + break; + } + field_18=i; + short i_=1; + while ( (1<= 15) + break; + } + field_1A=i_; + switch (field_18) + { + case 2: field_1C = 3; break; + case 3: field_1C = 7; break; + case 4: field_1C = 15; break; + case 5: field_1C = 31; break; + case 6: field_1C = 63; break; + case 7: field_1C = 127; break; + case 8: field_1C = 255; break; + case 9: field_1C = 511; break; + case 10: field_1C = 1023; break; + case 11: field_1C = 2047; break; + case 12: field_1C = 4095; break; + } + + switch (field_1A) + { + case 2: field_1E = 3; break; + case 3: field_1E = 7; break; + case 4: field_1E = 15; break; + case 5: field_1E = 31; break; + case 6: field_1E = 63; break; + case 7: field_1E = 127; break; + case 8: field_1E = 255; break; + case 9: field_1E = 511; break; + case 10: field_1E = 1023; break; + case 11: field_1E = 2047; break; + case 12: field_1E = 4095; break; + } + + unsigned int r_mask = 0xF800; + unsigned int num_r_bits = 5; + unsigned int g_mask = 0x07E0; + unsigned int num_g_bits = 6; + unsigned int b_mask = 0x001F; + unsigned int num_b_bits = 5; + //При сохранении изображения подряд идущие пиксели одинакового цвета объединяются и вместо указания цвета для каждого пикселя + //указывается цвет группы пикселей и их количество. + read_offset = 128; + if (psx_head2.planes != 3) + return 0; + current_line = 0; + if ( uHeight > 0 ) + { + dec_position = pOutPixels; + do + { + temp_dec_position = dec_position; + row_position = 0; + //decode red line + if (psx_head2.pitch) + { + do + { + test_byte = pPcx[read_offset]; + ++read_offset; + if ((test_byte & 0xC0) == 0xC0)//имеется ли объединение + { + value = pPcx[read_offset]; + ++read_offset; + + if ((test_byte & 0x3F) > 0) + { + count = test_byte & 0x3F;//количество одинаковых пикселей + do + { + ++row_position; + //*temp_dec_position =0xFF000000; + //*temp_dec_position|=(unsigned long)value<<16; + *temp_dec_position |= r_mask & ((unsigned __int8)value << (num_g_bits + num_r_bits + num_b_bits - 8)); + temp_dec_position++; + if (row_position == psx_head2.pitch) + break; + } + while (count-- != 1); + } + } + else + { + ++row_position; + //*temp_dec_position =0xFF000000; + //*temp_dec_position|= (unsigned long)test_byte<<16; + + *temp_dec_position |= r_mask & ((unsigned __int8)test_byte << (num_g_bits + num_r_bits + num_b_bits - 8)); + + temp_dec_position++; + } + + } + while (row_position < psx_head2.pitch); + } + + temp_dec_position = dec_position; + row_position=0; + //decode green line + while (row_position < psx_head2.pitch) + { + test_byte = *(pPcx + read_offset); + ++read_offset; + if ((test_byte & 0xC0) == 0xC0) + { + value = *(pPcx + read_offset); + ++read_offset; + if ((test_byte & 0x3F) > 0) + { + count = test_byte & 0x3F; + do + { + //*temp_dec_position|= (unsigned int)value<<8; + //temp_dec_position++; + + *temp_dec_position|= g_mask & (unsigned __int16)((unsigned __int8)value << (num_g_bits + num_b_bits - 8)); + + temp_dec_position++; + ++row_position; + if (row_position == psx_head2.pitch) + break; + + } + while (count-- != 1); + } + } + else + { + //*temp_dec_position |=(unsigned int) test_byte<<8; + //temp_dec_position++; + + *temp_dec_position|= g_mask & (unsigned __int16)((unsigned __int8)test_byte << (num_g_bits + num_b_bits - 8)); + temp_dec_position++; + ++row_position; + } + } + + temp_dec_position = dec_position; + row_position=0; + //decode blue line + while (row_position < psx_head2.pitch) + { + test_byte = *(pPcx + read_offset); + read_offset++; + if ((test_byte & 0xC0) == 0xC0) + { + value = *(pPcx + read_offset); + ++read_offset; + if ((test_byte & 0x3F) > 0) + { + count = test_byte & 0x3F; + do + { + //*temp_dec_position|= value; + //temp_dec_position++; + + *temp_dec_position |= value >> (8 - num_b_bits); + temp_dec_position++; + + ++row_position; + if (row_position == psx_head2.pitch) + break; + } + while (count-- != 1); + } + } + else + { + //*temp_dec_position|= test_byte; + //temp_dec_position++; + *temp_dec_position |= test_byte >> (8 - num_b_bits); + temp_dec_position++; + + ++row_position; + } + + } + ++current_line; + dec_position += uWidth; + } + while (current_line < uHeight); + } + return 0; +/* + RGBTexture *v4; // esi@1 + signed int result; // eax@2 + unsigned __int16 v6; // ax@3 + unsigned __int16 *v7; // ecx@3 + unsigned int v8; // edx@3 + signed int v9; // ecx@3 + signed int v10; // ecx@8 + signed int v11; // ebx@37 + unsigned __int16 *v12; // eax@40 + int v13; // edi@40 + int v14; // ebx@41 + char v15; // bl@42 + unsigned __int16 *v16; // eax@50 + int v17; // ebx@51 + char v18; // bl@52 + unsigned __int16 *v19; // eax@61 + unsigned __int8 v20; // dl@62 + unsigned __int8 v21; // dl@63 + unsigned __int8 v22; // cl@63 + char color_map[48]; // [sp+8h] [bp-54h]@1 + PCXHeader1 header1; // [sp+38h] [bp-24h]@1 + PCXHeader2 header2; // [sp+48h] [bp-14h]@1 + unsigned int v26; // [sp+50h] [bp-Ch]@43 + int v27; // [sp+54h] [bp-8h]@38 + unsigned __int16 *v28; // [sp+58h] [bp-4h]@3 + int pOutPixelsa; // [sp+68h] [bp+Ch]@41 + int pOutPixelsb; // [sp+68h] [bp+Ch]@51 + + v4 = this; + memcpy(&header1, pPcx, 0x10u); + memcpy(color_map, pPcx + 16, 0x30u); + memcpy(&header2, pPcx + 64, 6u); + if ( header1.bpp == 8 ) + { + v6 = header1.right - header1.left + 1; + LOWORD(v7) = header1.bottom - header1.up + 1; + v4->uWidth = v6; + v4->uHeight = (unsigned __int16)v7; + v7 = (unsigned __int16 *)(signed __int16)v7; + v28 = v7; + v4->uNumPixels = (signed __int16)v7 * (signed __int16)v6; + HIWORD(v8) = 0; + v9 = 1; + while ( 1 << v9 != (signed __int16)v6 ) + { + ++v9; + if ( v9 >= 15 ) + goto LABEL_8; + } + v4->field_18 = v9; +LABEL_8: + v10 = 1; + while ( (unsigned __int16 *)(1 << v10) != v28 ) + { + ++v10; + if ( v10 >= 15 ) + goto LABEL_13; + } + v4->field_1A = v10; +LABEL_13: + switch ( v4->field_18 ) + { + case 2: + v4->field_1C = 3; + break; + case 3: + v4->field_1C = 7; + break; + case 4: + v4->field_1C = 15; + break; + case 5: + v4->field_1C = 31; + break; + case 6: + v4->field_1C = 63; + break; + case 7: + v4->field_1C = 127; + break; + case 8: + v4->field_1C = 255; + break; + case 9: + v4->field_1C = 511; + break; + case 10: + v4->field_1C = 1023; + break; + case 11: + v4->field_1C = 2047; + break; + case 12: + v4->field_1C = 4095; + break; + default: + break; + } + switch ( v4->field_1A ) + { + case 2: + v4->field_1E = 3; + break; + case 3: + v4->field_1E = 7; + break; + case 4: + v4->field_1E = 15; + break; + case 5: + v4->field_1E = 31; + break; + case 6: + v4->field_1E = 63; + break; + case 7: + v4->field_1E = 127; + break; + case 8: + v4->field_1E = 255; + break; + case 9: + v4->field_1E = 511; + break; + case 10: + v4->field_1E = 1023; + break; + case 11: + v4->field_1E = 2047; + break; + case 12: + v4->field_1E = 4095; + break; + default: + break; + } + v11 = 128; + if ( header2.planes == 3 ) + { + v27 = 0; + if ( (signed int)v28 > 0 ) + { + v28 = pOutPixels; + do + { + v12 = v28; + v13 = 0; + if ( header2.pitch ) + { + do + { + LOBYTE(v8) = pPcx[v11]; + v14 = v11 + 1; + pOutPixelsa = v14; + if ( (v8 & 0xC0) == -64 ) + { + pOutPixelsa = v14 + 1; + v15 = pPcx[v14]; + if ( (signed int)(v8 & 0x3F) > 0 ) + { + v26 = v8 & 0x3F; + do + { + ++v13; + *v12 = LOWORD(pRenderer->uTargetRMask) & ((unsigned __int8)v15 << (LOBYTE(pRenderer->uTargetGBits) + + LOBYTE(pRenderer->uTargetRBits) + + LOBYTE(pRenderer->uTargetBBits) + - 8)); + ++v12; + if ( v13 == (unsigned __int16)header2.pitch ) + v12 = &v12[uNumPixels - (unsigned __int16)header2.pitch - 1]; + --v26; + } + while ( v26 ); + } + } + else + { + LOWORD(v8) = (unsigned __int8)v8; + v8 = pRenderer->uTargetRMask & (v8 << (LOBYTE(pRenderer->uTargetGBits) + + LOBYTE(pRenderer->uTargetRBits) + + LOBYTE(pRenderer->uTargetBBits) + - 8)); + ++v13; + *v12 = v8; + ++v12; + } + v11 = pOutPixelsa; + } + while ( v13 < (unsigned __int16)header2.pitch ); + } + v16 = v28; + while ( v13 < 2 * (unsigned __int16)header2.pitch ) + { + LOBYTE(v8) = pPcx[v11]; + v17 = v11 + 1; + pOutPixelsb = v17; + if ( (v8 & 0xC0) == -64 ) + { + pOutPixelsb = v17 + 1; + v18 = pPcx[v17]; + if ( (signed int)(v8 & 0x3F) > 0 ) + { + v26 = v8 & 0x3F; + do + { + *v16 |= pRenderer->uTargetGMask & (unsigned __int16)((unsigned __int8)v18 << (LOBYTE(pRenderer->uTargetGBits) + + LOBYTE(pRenderer->uTargetBBits) + - 8)); + ++v13; + ++v16; + if ( v13 == (unsigned __int16)header2.pitch ) + v16 = &v16[uNumPixels - (unsigned __int16)header2.pitch - 1]; + --v26; + } + while ( v26 ); + } + } + else + { + LOWORD(v8) = (unsigned __int8)v8; + v8 = pRenderer->uTargetGMask & (v8 << (LOBYTE(pRenderer->uTargetGBits) + LOBYTE(pRenderer->uTargetBBits) - 8)); + *v16 |= v8; + ++v13; + ++v16; + } + v11 = pOutPixelsb; + } + v19 = v28; + while ( v13 < 3 * (unsigned __int16)header2.pitch ) + { + v20 = pPcx[v11++]; + if ( (v20 & 0xC0) == -64 ) + { + v21 = v20 & 0x3F; + v22 = pPcx[v11++]; + if ( (signed int)v21 > 0 ) + { + v26 = v21; + do + { + *v19 |= v22 >> (8 - LOBYTE(pRenderer->uTargetBBits)); + ++v13; + ++v19; + if ( v13 == (unsigned __int16)header2.pitch ) + { + v8 = uNumPixels - (unsigned __int16)header2.pitch; + v19 = &v19[uNumPixels - (unsigned __int16)header2.pitch - 1]; + } + --v26; + } + while ( v26 ); + } + } + else + { + *v19 |= v20 >> (8 - LOBYTE(pRenderer->uTargetBBits)); + ++v13; + ++v19; + } + } + ++v27; + v28 += uNumPixels; + } + while ( v27 < v4->uHeight ); + } + } + result = 0; + } + else + { + result = 3; + } + return result; + */ +} + +//----- (0040EAD8) -------------------------------------------------------- +unsigned int RGBTexture::LoadFromFILE(FILE *pFile, unsigned int mode, unsigned int bCloseFile) +{ +// signed int result; // eax@2 +// unsigned char test_byte; // edx@3 + //unsigned int read_offset; // ebx@37 +// unsigned int row_position; // edi@40 +// unsigned char value; // cl@63 +// char count; // [sp+50h] [bp-Ch]@43 +// unsigned short current_line; // [sp+54h] [bp-8h]@38 +// unsigned short *dec_position; +// unsigned short *temp_dec_position; + PCXHeader1 psx_head1; + PCXHeader2 psx_head2; +// short int width, height; + BYTE color_map[48]; // Colormap for 16-color images + + unsigned int num_r_bits = 5; + unsigned int num_g_bits = 6; + unsigned int num_b_bits = 5; + + unsigned int r_mask = 0xF800; + unsigned int g_mask = 0x07E0; + unsigned int b_mask = 0x001F; + + if (!pFile) + return 1; + + + fread(&psx_head1, 1, 16, pFile); + fread(&color_map, 1, 48, pFile); + fread(&psx_head2, 1, 6, pFile); + + if (psx_head1.bpp!=8) + return 3; + uWidth=(short int )(psx_head1.right-psx_head1.left+1); // word @ 000014 + uHeight=(short int )(psx_head1.bottom-psx_head1.up+1); // word @ 000016 + + + uNumPixels=uWidth*uHeight; // dword @ 000010 + + + if ( mode == 0 ) + { + free(pPixels); + pPixels = (unsigned __int16 *)malloc(2 * uNumPixels + 4); + } + else + { + if ( mode != 1 && mode == 2 ) + { + pPixels = (unsigned __int16 *)malloc((uNumPixels + 2) * sizeof(unsigned __int16)); + _allocation_flags |= 1; + } + } + + ushort* pOutPixels = pPixels; + + memset(pOutPixels, 0, uNumPixels * sizeof(__int16)); + + short i=1; + while ( (1<= 15) + break; + } + field_18=i; + short i_=1; + while ( (1<= 15) + break; + } + field_1A=i_; + switch (field_18) + { + case 2: field_1C = 3; break; + case 3: field_1C = 7; break; + case 4: field_1C = 15; break; + case 5: field_1C = 31; break; + case 6: field_1C = 63; break; + case 7: field_1C = 127; break; + case 8: field_1C = 255; break; + case 9: field_1C = 511; break; + case 10: field_1C = 1023; break; + case 11: field_1C = 2047; break; + case 12: field_1C = 4095; break; + } + + switch (field_1A) + { + case 2: field_1E = 3; break; + case 3: field_1E = 7; break; + case 4: field_1E = 15; break; + case 5: field_1E = 31; break; + case 6: field_1E = 63; break; + case 7: field_1E = 127; break; + case 8: field_1E = 255; break; + case 9: field_1E = 511; break; + case 10: field_1E = 1023; break; + case 11: field_1E = 2047; break; + case 12: field_1E = 4095; break; + } + + fseek(pFile, 128 - 70, SEEK_CUR); + + + for (uint y = 0; y < uHeight; ++y) + { + unsigned __int16 *pDst = pPixels + y * uWidth; + + uint x = 0; + do + { + uint ctrl = 0; + fread(&ctrl, 1, 1, pFile); + if ((ctrl & 0xC0) == 0xC0) + { + uint uNumPixels = ctrl & 0x3F; + uint clr = 0; + fread(&clr, 1, 1, pFile); + for (uint i = 0; i < uNumPixels; ++i) + pDst[x++] = r_mask & (clr << (num_g_bits + num_r_bits + num_b_bits - 8)); + } + else + { + pDst[x++] = r_mask & (ctrl << (num_g_bits + num_r_bits + num_b_bits - 8)); + } + } while (x < psx_head2.pitch); + + x = 0; + do + { + uint ctrl = 0; + fread(&ctrl, 1, 1, pFile); + if ((ctrl & 0xC0) == 0xC0) + { + uint uNumPixels = ctrl & 0x3F; + uint clr = 0; + fread(&clr, 1, 1, pFile); + for (uint i = 0; i < uNumPixels; ++i) + pDst[x++] |= g_mask & (clr << (num_g_bits + num_b_bits - 8)); + } + else + { + pDst[x++] |= g_mask & (ctrl << (num_g_bits + num_b_bits - 8)); + } + } while (x < psx_head2.pitch); + + x = 0; + do + { + uint ctrl = 0; + fread(&ctrl, 1, 1, pFile); + if ((ctrl & 0xC0) == 0xC0) + { + uint uNumPixels = ctrl & 0x3F; + uint clr = 0; + fread(&clr, 1, 1, pFile); + for (uint i = 0; i < uNumPixels; ++i) + pDst[x++] |= b_mask & (clr >> (8 - num_b_bits)); + } + else + { + pDst[x++] |= b_mask & (ctrl >> (8 - num_b_bits)); + } + } while (x < psx_head2.pitch); + } + + if (bCloseFile) + fclose(pFile); + return 0; +} + +//----- (0040E51F) -------------------------------------------------------- +void RGBTexture::Release() +{ + this->pName[0] = 0; + //if ( !(this->_allocation_flags & 1) ) + //free(this->pPixels); + //else + free(this->pPixels); + this->_allocation_flags = 0; + this->pPixels = 0; + this->uNumPixels = 0; + this->uHeight = 0; + this->uWidth = 0; + this->field_1A = 0; + this->field_18 = 0; +} + +//----- (0040E55E) -------------------------------------------------------- +int RGBTexture::LoadPCXFile(const char *Filename, unsigned int a3) +{ + signed int result; // eax@2 + char *v6; // eax@3 + int v7; // edx@3 + char v8; // cl@4 + signed int v14; // ecx@19 + signed int v15; // ecx@24 +// int v16; // eax@57 +// unsigned __int16 *v17; // ecx@57 +// unsigned __int16 *v18; // edi@57 +// signed int x; // eax@59 +// unsigned __int16 *v20; // edi@64 +// signed int v21; // eax@66 +// unsigned __int16 *v22; // edi@71 +// signed int v23; // eax@73 +// int v24; // eax@78 + char v25[48]; // [sp+Ch] [bp-54h]@3 + PCXHeader1 pcx_header1; + PCXHeader2 pcx_header2; + int y; // [sp+54h] [bp-Ch]@3 + FILE *File; // [sp+5Ch] [bp-4h]@1 + + unsigned int num_r_bits = 5; + unsigned int num_g_bits = 6; + unsigned int num_b_bits = 5; + + unsigned int r_mask = 0xF800; + unsigned int g_mask = 0x07E0; + unsigned int b_mask = 0x001F; + + + File = fopen(Filename, "rb"); + if ( !File ) + return 1; + + fread(&pcx_header1, sizeof(pcx_header1), 1, File); + fread(&v25,48,1,File); + fread(&pcx_header2, 4, 1, File); + + v6 = (char *)Filename; + v7 = (char *)this - Filename; + uint i = 0; + for ( i; i < 15; ++i ) + { + v8 = *v6; + if ( !*v6 ) + break; + if ( v8 == 46 ) + break; + (v6++)[v7] = v8; + } + this->pName[i] = 0; + if ( pcx_header1.bpp != 8 ) + return 3; + this->uWidth = pcx_header1.right - pcx_header1.left + 1; + this->uHeight = pcx_header1.bottom - pcx_header1.up + 1; + this->uNumPixels = (signed __int16)this->uWidth * (signed __int16)this->uHeight; + if ( !a3 ) + { + free(this->pPixels); + this->pPixels = (unsigned __int16 *)malloc(2 * this->uNumPixels + 4); + } + if ( a3 == 2 ) + { + this->_allocation_flags |= 1; + this->pPixels = (unsigned __int16 *)malloc((uNumPixels + 2) * sizeof(unsigned __int16)); + } + if ( this->pPixels ) + { + for ( v14 = 1; v14 < 15; ++v14 ) + { + if ( 1 << v14 == this->uWidth ) + this->field_18 = v14; + } + for ( v15 = 1; v15 < 15; ++v15 ) + { + if ( 1 << v15 == this->uHeight ) + this->field_1A = v15; + } + switch ( this->field_18 ) + { + case 2: this->field_1C = 3; break; + case 3: this->field_1C = 7; break; + case 4: this->field_1C = 15; break; + case 5: this->field_1C = 31; break; + case 6: this->field_1C = 63; break; + case 7: this->field_1C = 127; break; + case 8: this->field_1C = 255; break; + case 9: this->field_1C = 511; break; + case 10: this->field_1C = 1023; break; + case 11: this->field_1C = 2047; break; + case 12: this->field_1C = 4095; break; + default: break; + } + switch ( this->field_1A ) + { + case 2: this->field_1E = 3; break; + case 3: this->field_1E = 7; break; + case 4: this->field_1E = 15; break; + case 5: this->field_1E = 31; break; + case 6: this->field_1E = 63; break; + case 7: this->field_1E = 127; break; + case 8: this->field_1E = 255; break; + case 9: this->field_1E = 511; break; + case 10: this->field_1E = 1023; break; + case 11: this->field_1E = 2047; break; + case 12: this->field_1E = 4095; break; + default: break; + } + fseek(File, 128, 0); + ftell(File); + if ( pcx_header2.planes == 1 ) + Error("24bit PCX Only!"); + + if ( pcx_header2.planes == 3 ) + { + for ( y = 0; y < this->uHeight; ++y ) + { + unsigned __int16 *pDst = pPixels + y * uWidth; + uint x = 0; + do + { + uint ctrl = 0; + fread(&ctrl, 1, 1, File); + if ( (ctrl & 0xC0) == 0xC0 ) + { + uint uNumPixels = ctrl & 0x3F; + uint clr = 0; + ctrl &= 0x3F; + fread(&clr, 1, 1, File); + for ( uint i = 0; i < uNumPixels; ++i ) + pDst[x++] = r_mask & (clr << (num_r_bits + num_g_bits + num_b_bits - 8)); + } + else + pDst[x++] = r_mask & (ctrl << (num_g_bits + num_r_bits + num_b_bits - 8)); + } + while ( x < pcx_header2.pitch ); + + x = 0; + do + { + uint ctrl = 0; + fread(&ctrl, 1, 1, File); + if ( (ctrl & 0xC0) == 0xC0 ) + { + uint uNumPixels = ctrl & 0x3F; + uint clr = 0; + ctrl &= 0x3F; + fread(&clr, 1, 1, File); + for ( uint i = 0; i < uNumPixels; ++i ) + pDst[x++] |= g_mask & (clr << (num_g_bits + num_b_bits - 8)); + } + else + pDst[x++] |= g_mask & (ctrl << (num_g_bits + num_b_bits - 8)); + } + while (x < pcx_header2.pitch); + + x = 0; + do + { + uint ctrl = 0; + fread(&ctrl, 1, 1, File); + if ( (ctrl & 0xC0) == 0xC0 ) + { + uint uNumPixels = ctrl & 0x3F; + uint clr = 0; + fread(&clr, 1, 1, File); + for ( uint i = 0; i < uNumPixels; ++i ) + pDst[x++] |= b_mask & (clr >> (8 - num_b_bits)); + } + else + pDst[x++] |= b_mask & (ctrl >> (8 - num_b_bits)); + } + while (x < pcx_header2.pitch); + } + } + fclose(File); + result = 0; + } + else + { + result = 2; + } + return result; +} + +//----- (0040D73D) -------------------------------------------------------- +RGBTexture::RGBTexture() +{ + pName[0] = 0; + pPixels = 0; + uNumPixels = 0; + uHeight = 0; + uWidth = 0; + field_1A = 0; + field_18 = 0; + _allocation_flags = 0; +} +//----- (0044E1EC) -------------------------------------------------------- +int TextureFrameTable::FromFileTxt(const char *Args) +{ + TextureFrameTable *v2; // ebx@1 + FILE *v3; // eax@1 + int v4; // esi@3 + const void *v5; // ST0C_4@10 + void *v6; // eax@10 + FILE *v7; // ST0C_4@12 + char *i; // eax@12 + signed int v9; // esi@15 + int v10; // eax@17 + int v11; // edx@22 + int v12; // ecx@23 + int v13; // eax@24 + signed int j; // eax@27 + TextureFrame *v15; // edx@28 + int v16; // esi@28 + int k; // ecx@29 + char Buf; // [sp+Ch] [bp-2F8h]@3 + FrameTableTxtLine v20; // [sp+200h] [bp-104h]@4 + int v21; // [sp+27Ch] [bp-88h]@4 + char *Str1; // [sp+280h] [bp-84h]@5 + char *Str; // [sp+284h] [bp-80h]@15 + int v24; // [sp+2F8h] [bp-Ch]@3 + int v25; // [sp+2FCh] [bp-8h]@3 + FILE *File; // [sp+300h] [bp-4h]@1 + int Argsa; // [sp+30Ch] [bp+8h]@28 + + v2 = this; + v3 = fopen(Args, "r"); + File = v3; + if ( !v3 ) + Error("CTextureFrameTable::load - Unable to open file: %s.", Args); + + v4 = 0; + v24 = 0; + v25 = 1; + if ( fgets(&Buf, 490, v3) ) + { + do + { + *strchr(&Buf, 10) = 0; + memcpy(&v21, txt_file_frametable_parser(&Buf, &v20), 0x7Cu); + __debugbreak(); // warning C4700: uninitialized local variable 'Str1' used + if ( v21 && *Str1 != 47 ) + { + if ( v21 < 2 ) + Error("CTextureFrameTable::load, too few arguments, %s line %i.", Args, v25); + ++v24; + } + ++v25; + } + while ( fgets(&Buf, 490, File) ); + v4 = v24; + } + v5 = v2->pTextures; + v2->sNumTextures = v4; + v6 = malloc(20 * v4); + v2->pTextures = (TextureFrame *)v6; + if ( !v6 ) + Error("CTextureFrameTable::load - Out of Memory!"); + v7 = File; + v2->sNumTextures = 0; + fseek(v7, 0, 0); + for ( i = fgets(&Buf, 490, File); i; i = fgets(&Buf, 490, File) ) + { + *strchr(&Buf, 10) = 0; + memcpy(&v21, txt_file_frametable_parser(&Buf, &v20), 0x7Cu); + if ( v21 && *Str1 != 47 ) + { + strcpy(v2->pTextures[v2->sNumTextures].pTextureName, Str1); + __debugbreak(); // warning C4700: uninitialized local variable 'Str' used + v2->pTextures[v2->sNumTextures].uAnimTime = atoi(Str); + v9 = 2; + for ( v2->pTextures[v2->sNumTextures].uFlags = 0; v9 < v21; ++v9 ) + { + if ( !_stricmp((&Str1)[4 * v9], "New") ) + { + //v10 = (int)&v2->pTextures[v2->sNumTextures].uFlags; + v2->pTextures[v2->sNumTextures].uFlags |= 2; + } + } + ++v2->sNumTextures; + } + } + fclose(File); + v11 = 0; + if ( (signed int)(v2->sNumTextures - 1) > 0 ) + { + v12 = 0; + do + { + v13 = (int)&v2->pTextures[v12]; + if ( !(*(char *)(v13 + 38) & 2) ) + *(char *)(v13 + 18) |= 1u; + ++v11; + ++v12; + } + while ( v11 < (signed int)(v2->sNumTextures - 1) ); + } + for ( j = 0; j < (signed int)v2->sNumTextures; *(short *)(Argsa + 16) = v16 ) + { + v15 = v2->pTextures; + Argsa = (int)&v15[j]; + v16 = *(short *)(Argsa + 14); + if ( *(char *)(Argsa + 18) & 1 ) + { + ++j; + for ( k = (int)&v15[j]; *(char *)(k + 18) & 1; k += 20 ) + { + v16 += *(short *)(k + 14); + ++j; + } + LOWORD(v16) = v15[j].uAnimTime + v16; + } + ++j; + } + return 1; +} + +//----- (00451007) -------------------------------------------------------- +int stru350::sub_451007_scale_image_bicubic(unsigned short *pSrc, int srcWidth, int srcHeight, int srcPitch, //changing this to some library function might be a good idea + unsigned short *pDst, int dstWidth, int dstHeight, int dstPitch, + int a10, int a11) +{ + int result; // eax@1 + float v17; // ST3C_4@12 + float v18; // ST38_4@12 + unsigned int v19; // esi@12 + int v21; // eax@18 + unsigned int v22; // ecx@25 + unsigned int v23; // eax@29 + unsigned int heightRatioPlusOne; // [sp+Ch] [bp-7Ch]@12 + unsigned int widthRatio; // [sp+Ch] [bp-7Ch]@218 + unsigned int heightRatio; // [sp+14h] [bp-74h]@12 + unsigned int widthRatioPlusOne; // [sp+14h] [bp-74h]@218 + // int v160; // [sp+3Ch] [bp-4Ch]@13 + unsigned __int16 *v175; // [sp+4Ch] [bp-3Ch]@13 + unsigned __int16 *v193; // [sp+5Ch] [bp-2Ch]@7 + //signed int v231; // [sp+78h] [bp-10h]@7 + __int64 v240; // [sp+7Ch] [bp-Ch]@12 + unsigned int v251; // [sp+80h] [bp-8h]@218 + unsigned int v252; // [sp+84h] [bp-4h]@218 + float a6s; // [sp+A0h] [bp+18h]@218 + float a6t; // [sp+A0h] [bp+18h]@218 + unsigned int a6b; // [sp+A0h] [bp+18h]@218 + int field_0_bits; + int field_20_bits; + + int field0value = this->field_0.field_C; + switch (field0value) + { + case 8: field_0_bits = 1; + break; + case 16: field_0_bits = 2; + break; + case 32: field_0_bits = 4; + break; + default: + return field0value; + } + int field20value = this->field_20.field_C; + switch (field20value) + { + case 8: field_20_bits = 1; + break; + case 16: field_20_bits = 2; + break; + case 32: field_20_bits = 4; + break; + default: + return field20value; + } + + result = (int)pDst; + v193 = pDst; + if (dstHeight <= 0) + return result; + + //do + for (int height = 0; height < dstHeight; height++) + { + for (int width = 0; width < dstWidth; width++) + { + a6s = (double)width / (double)dstWidth * (double)srcWidth; + widthRatio = bankersRounding(a6s); + a6t = (double)(width + 1) / (double)dstWidth * (double)srcWidth; + widthRatioPlusOne = bankersRounding(a6t); + + v17 = (double)height / (double)dstHeight * (double)srcHeight; + heightRatio = bankersRounding(v17); + v18 = (double)(height + 1) / (double)dstHeight * (double)srcHeight; + heightRatioPlusOne = bankersRounding(v18); + + v251 = 0; + v19 = (heightRatioPlusOne - heightRatio) * (widthRatioPlusOne - widthRatio); + v252 = 0; + a6b = 0; + v240 = 0i64; + + v175 = (unsigned short*)((char *)pSrc + field_0_bits * (widthRatio + srcPitch * heightRatio)); + for (int heightDiff = 0; heightDiff < heightRatioPlusOne - heightRatio; heightDiff++) + { + //int ratioDiff = widthRatioPlusOne - widthRatio; + for (int ratioDiff = 0; ratioDiff < widthRatioPlusOne - widthRatio; ratioDiff++) + { + if (field0value == 32) + v21 = _450FB1(((int*)v175)[ratioDiff]); + else if (field0value == 16) + v21 = _450FB1(((_WORD*)v175)[ratioDiff]); + else if (field0value == 8) + v21 = _450FB1(((unsigned __int8*)v175)[ratioDiff]); + v240 += ((unsigned int)v21 >> 24); + a6b += BYTE2(v21); + v252 += BYTE1(v21); + v251 += (unsigned __int8)v21; + } + if (field0value == 32) + v175 += 2 * srcPitch; + else if (field0value == 16) + v175 += srcPitch; + else if (field0value == 8) + v175 = (unsigned short*)((char *)v175 + 2 * srcPitch); + } + + v22 = (unsigned int)v240 / ((heightRatioPlusOne - heightRatio) * (widthRatioPlusOne - widthRatio)); + if (v19) + { + a6b /= v19; + v252 /= v19; + v251 /= v19; + } + if (v22 != 255) + v22 &= 0x7FFFFFFFu; + v23 = _450F55(v251 | ((v252 | ((a6b | (v22 << 8)) << 8)) << 8)); + *(_DWORD *)v193 = v23; //Invalid memory access + v193 = (unsigned __int16 *)((char *)v193 + field_20_bits); + } + v193 = (unsigned __int16 *)((char *)v193 + field_20_bits * (dstPitch - dstWidth)); + //++v231; + result = height; + } + //while(v231 < dstHeight); + return result; +} + + +//----- (00450DDE) -------------------------------------------------------- +stru350 *stru350::_450DDE() +{ + _450DF1(&stru_4E82A4, &stru_4E82A4); + return this; +} + +//----- (00450DF1) -------------------------------------------------------- +bool stru350::_450DF1(const stru355 *p1, const stru355 *p2) +{ + //stru350 *v3; // esi@1 + //void *result; // eax@1 + unsigned int v5; // ecx@2 + int v6; // edi@2 + int v7; // edx@2 + unsigned int v8; // ecx@8 + int v9; // edi@8 + int v10; // edx@8 + int v11; // ecx@12 + int v12; // edi@12 + unsigned int v13; // ecx@12 + int v14; // edx@12 + int v15; // ecx@16 + unsigned int v16; // edx@16 + int v17; // ecx@16 + int v18; // edi@16 + char v19; // zf@20 + unsigned int v20; // ecx@21 + int v21; // edi@21 + int v22; // edx@21 + unsigned int v23; // ecx@27 + int v24; // edi@27 + int v25; // edx@27 + int v26; // ecx@31 + int v27; // edi@31 + unsigned int v28; // ecx@31 + int v29; // edx@31 + int v30; // ebx@35 + int v31; // ecx@35 + int v32; // edi@35 + int v33; // edx@35 + unsigned int i; // ecx@35 + int v35; // ecx@39 + unsigned int v36; // edx@39 + int v37; // ecx@39 + int v38; // ebx@39 + + //v3 = this; + memcpy(&field_0, p1, sizeof(stru355)); + memcpy(&field_20, p2, sizeof(stru355)); + //result = memcpy(&v3->field_20, p2, 0x20u); + //LOBYTE(result) = 1; + if (field_0.field_4 & 1) + { + v5 = field_0.field_1C; + v6 = 0; + v7 = 0; + while (!(v5 & 1)) + { + ++v6; + v5 >>= 1; + } + do + { + v5 >>= 1; + ++v7; + } while (v5 & 1); + field_40 = 32 - v7 - v6; + } + else + { + field_40 = 0; + } + v8 = field_0.field_10; + v9 = 0; + v10 = 0; + while (!(v8 & 1)) + { + ++v9; + v8 >>= 1; + } + do + { + v8 >>= 1; + ++v10; + } while (v8 & 1); + v11 = 24 - v10 - v9; + v12 = 0; + field_48 = v11; + v13 = field_0.field_14; + v14 = 0; + while (!(v13 & 1)) + { + ++v12; + v13 >>= 1; + } + do + { + v13 >>= 1; + ++v14; + } while (v13 & 1); + v15 = 16 - v14; + v16 = field_0.field_18; + field_50 = v15 - v12; + v17 = 0; + v18 = 0; + while (!(v16 & 1)) + { + ++v17; + v16 >>= 1; + } + do + { + v16 >>= 1; + ++v18; + } while (v16 & 1); + v19 = (field_20.field_4 & 1) == 0; + field_58 = v17 - v18 + 8; + if (v19) + { + field_44 = 0; + } + else + { + v20 = field_20.field_1C; + v21 = 0; + v22 = 0; + while (!(v20 & 1)) + { + ++v21; + v20 >>= 1; + } + do + { + v20 >>= 1; + ++v22; + } while (v20 & 1); + field_44 = 32 - v22 - v21; + } + v23 = field_20.field_10; + v24 = 0; + v25 = 0; + while (!(v23 & 1)) + { + ++v24; + v23 >>= 1; + } + do + { + v23 >>= 1; + ++v25; + } while (v23 & 1); + v26 = 24 - v25 - v24; + v27 = 0; + field_4C = v26; + v28 = field_20.field_14; + v29 = 0; + while (!(v28 & 1)) + { + ++v27; + v28 >>= 1; + } + do + { + v28 >>= 1; + ++v29; + } while (v28 & 1); + v30 = 0; + v31 = 16 - v29 - v27; + v32 = field_20.field_18; + field_54 = v31; + v33 = 0; + for (i = v32; !(i & 1); i >>= 1) + ++v30; + do + { + i >>= 1; + ++v33; + } while (i & 1); + v35 = 32 - v33; + v36 = v32; + field_5C = v35 - v30; + v37 = 0; + v38 = 0; + while (!(v36 & 1)) + { + ++v37; + v36 >>= 1; + } + do + { + v36 >>= 1; + ++v38; + } while (v36 & 1); + field_5C = v37 - v38 + 8; + return true; +} + +//----- (00450F55) -------------------------------------------------------- +unsigned int stru350::_450F55(int a2) +{ + int v2 = a2 & stru_4E82A4.field_1C; + if (field_20.field_4 & 1) + v2 = (unsigned int)v2 >> this->field_44; + return v2 & field_20.field_1C | + field_20.field_10 & ((a2 & (unsigned int)stru_4E82A4.field_10) >> field_4C) | + field_20.field_14 & ((a2 & (unsigned int)stru_4E82A4.field_14) >> field_54) | + field_20.field_18 & ((a2 & (unsigned int)stru_4E82A4.field_18) >> field_5C); +} + +//----- (00450FB1) -------------------------------------------------------- +int stru350::_450FB1(int a2) +{ + int v2 = 0; + int v4 = field_0.field_4 & 1; + if (v4) + v2 = a2 & field_0.field_1C; + if (v4) + v2 <<= field_40; + return v2 | ((a2 & field_0.field_10) << field_48) | ((a2 & field_0.field_14) << field_50) | ((a2 & field_0.field_18) << field_58); +} + diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/Texture.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/Texture.h Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,369 @@ +#pragma once +#include +#include + + + +/* 194 */ +#pragma pack(push, 1) +struct RGBTexture +{ + RGBTexture(); + void Release(); + int LoadPCXFile(const char *Filename, unsigned int a3); + unsigned int LoadFromFILE(FILE *pFile, unsigned int mode, unsigned int bCloseFile); + int DecodePCX(char *pPcx, unsigned __int16 *pOutPixels, unsigned int uNumPixels); + int Load(const char *pContainer, int mode); + int Reload(const char *pContainer); + + char pName[16]; + unsigned int uNumPixels; + unsigned __int16 uWidth; + unsigned __int16 uHeight; + __int16 field_18; + __int16 field_1A; + __int16 field_1C; + __int16 field_1E; + int _allocation_flags; // & 1 - malloc, else custom allocator + unsigned __int16 *pPixels; +}; +#pragma pack(pop) + + + +#pragma pack(push, 1) +struct Texture +{ + Texture(); + void Release(); + void *UnzipPalette(); + + char pName[16]; + unsigned int uSizeOfMaxLevelOfDetail; + unsigned int uTextureSize; + unsigned __int16 uTextureWidth; + unsigned __int16 uTextureHeight; + __int16 uWidthLn2; + __int16 uHeightLn2; + __int16 uWidthMinus1; + __int16 uHeightMinus1; + short palette_id1; + short palette_id2; + unsigned int uDecompressedSize; + int pBits; + unsigned __int8 *pLevelOfDetail0_prolly_alpha_mask; + unsigned __int8 *pLevelOfDetail1; + unsigned __int8 *pLevelOfDetail2; + unsigned __int8 *pLevelOfDetail3; + unsigned __int16 *pPalette16; + unsigned __int8 *pPalette24; +}; +#pragma pack(pop) + + + + + + + + + + + + + + + + + +/* 323 */ +enum TEXTURE_FRAME_TABLE_FLAGS +{ + TEXTURE_FRAME_TABLE_MORE_FRAMES = 0x1, + TEXTURE_FRAME_TABLE_FIRST = 0x2, +}; + + + +/* 41 */ +#pragma pack(push, 1) +struct TextureFrame +{ + char pTextureName[12]; + __int16 uTextureID; + __int16 uAnimTime; + __int16 uAnimLength; + __int16 uFlags; +}; +#pragma pack(pop) + +/* 40 */ +#pragma pack(push, 1) +struct TextureFrameTable +{ + //----- (0044D4C9) -------------------------------------------------------- + inline TextureFrameTable() + { + pTextures = 0; + sNumTextures = 0; + } + int FromFileTxt(const char *Args); + void ToFile(); + void FromFile(void *data_mm6, void *data_mm7, void *data_mm8); + void LoadAnimationSequenceAndPalettes(signed int uIconID); + int GetFrameTexture(int uFrameID, int time); + signed int FindTextureByName(const char *Str2); + + + signed int sNumTextures; + struct TextureFrame *pTextures; +}; +#pragma pack(pop) + +extern struct TextureFrameTable *pTextureFrameTable; + + + +extern std::array pSavegameThumbnails; +extern std::array pTexture_LloydBeacons; +extern struct Texture *pTexture_50635C; +extern struct Texture *pTex_book_button8_off; +extern struct Texture *pTex_book_button8_on; +extern struct Texture *pTex_book_button7_off; +extern struct Texture *pTex_book_button7_on; +extern struct Texture *pTex_book_button6_off; +extern struct Texture *pTex_book_button6_on; +extern struct Texture *pTex_book_button5_off; +extern struct Texture *pTex_book_button5_on; +extern struct Texture *pTex_book_button4_off; +extern struct Texture *pTex_book_button4_on; +extern struct Texture *pTex_book_button3_off; +extern struct Texture *pTex_book_button3_on; +extern struct Texture *pTex_book_button2_off; +extern struct Texture *pTex_book_button1_off; +extern struct Texture *pTex_book_button2_on; +extern struct Texture *pTex_book_button1_on; +extern std::array pTexture_TownPortalIcons; // [0]Harmonale, [1]Pierpont, [2]Nighon, [3]Evenmorn Island, [4]Celestia, [5]The Pit + +extern std::array SBPageCSpellsTextureList; +extern std::array SBPageSSpellsTextureList; +extern struct Texture *pSBQuickSpellBtnTextr; +extern struct Texture *pSpellBookClickCloseBtnTextr; +extern struct Texture *pSBClickQuickSpellBtnTextr; +extern struct Texture *pSpellBookCloseBtnTextr; +extern std::array, 9> pTextures_tabs; +extern struct Texture *pTexture_mapbordr; // idb +extern struct Texture *pTexture_pagemask; // idb +extern std::array pSpellBookPagesTextr; +extern struct Texture *pSpellBookPagesTextr_9; +extern struct Texture *pSpellBookPagesTextr_10; +extern struct Texture *pSpellBookPagesTextr_11; +extern struct Texture *pSpellBookPagesTextr_12; +extern struct Texture *pSpellBookPagesTextr_13; +extern struct Texture *pTexture_AutonotesBook; +extern struct Texture *pTexture_CurrentBook; +extern struct Texture *pTex_moon_new; +extern struct Texture *pTex_moon_4; +extern struct Texture *pTex_moon_2; +extern struct Texture *pTex_moon_2_2; +extern struct Texture *pTex_moon_ful; + + + +extern RGBTexture stru_506E40; // weak +extern RGBTexture pTexture_PCX; + + +extern int uTextureID_RestUI_restb4; // weak +extern int uTextureID_RestUI_restexit; // weak +extern int uTextureID_RestUI_restb3; // weak +extern int uTextureID_RestUI_restb1; // weak +extern int uTextureID_RestUI_restb2; // weak +extern int uTextureID_RestUI_restmain; // weak +extern unsigned int uTextureID_Leather; +extern int uTextureID_ar_dn_dn; // weak +extern int uTextureID_ar_dn_up; // weak +extern int uTextureID_ar_up_dn; // weak +extern int uTextureID_ar_up_up; // weak + + +extern int uTextureID_507698; // weak +extern int uTextureID_50769C; // weak +extern int uTextureID_5076A0; // weak +extern int uTextureID_5076A4; // weak +extern int uTextureID_5076A8; // weak +extern int uTextureID_5076AC; // weak +extern int uTextureID_5076B0; // weak +extern int uTextureID_5076B4; // weak +extern int uTextureID_Parchment; // weak +extern unsigned int uTextureID_mhp_yel; +extern unsigned int uTextureID_mhp_red; +extern unsigned int uTextureID_mhp_grn; +extern unsigned int uTextureID_mhp_capr; +extern unsigned int uTextureID_mhp_capl; +extern unsigned int uTextureID_mhp_bd; +extern unsigned int uTextureID_BUTTDESC2; +extern unsigned int uTextureID_x_x_u; +extern unsigned int uTextureID_BUTTMAKE2; +extern unsigned int uTextureID_BUTTMAKE; +extern unsigned int uTextureID_BUTTYES2; +extern unsigned int uTextureID_x_ok_u; +extern std::array pPlayerPortraits; +extern std::array pTexture_IC_KNIGHT; +extern struct Texture *pTexture_MAKESKY; +extern struct Texture *pTexture_MAKETOP; +extern std::array pTextures_arrowr; +extern std::array pTextures_arrowl; +extern struct Texture *pTexture_presleft; +extern struct Texture *pTexture_pressrigh; +extern struct Texture *pTexture_buttminu; +extern struct Texture *pTexture_buttplus; +extern unsigned int uTextureID_Quit1; +extern unsigned int uTextureID_Resume1; +extern unsigned int uTextureID_Controls1; +extern unsigned int uTextureID_Save1; +extern unsigned int uTextureID_Load1; +extern unsigned int uTextureID_New1; +extern unsigned int uTextureID_Options; + + +extern unsigned int uTextureID_ib_td5_A; +extern unsigned int uTextureID_ib_td4_A; +extern unsigned int uTextureID_ib_td3_A; +extern unsigned int uTextureID_ib_td2_A; +extern unsigned int uTextureID_ib_td1_A; +extern int uTextureID_CharacterUI_InventoryBackground; // weak +extern int uTextureID_50795C; // weak + + +extern unsigned int uTextureID_Btn_GameSettings; + + +extern unsigned int uTextureID_Btn_Rest; +extern unsigned int uTextureID_Btn_CastSpell; +extern unsigned int uTextureID_Btn_ZoomIn; +extern unsigned int uTextureID_Btn_ZoomOut; +extern unsigned int uTextureID_FONTPAL; +extern unsigned int uTextureID_Btn_NPCRight; +extern unsigned int uTextureID_Btn_NPCLeft; +extern std::array pTextureIDs_pMapDirs; + + +extern unsigned int uTextureID_BarRed; +extern unsigned int uTextureID_BarYellow; +extern unsigned int uTextureID_BarGreen; +extern unsigned int uTextureID_BarBlue; + + +extern unsigned int uTextureID_right_panel; // weak + + +extern RGBTexture *pTexture_StatusBar; +extern RGBTexture *pTexture_LeftFrame; +extern RGBTexture *pTexture_TopFrame; +extern RGBTexture *pTexture_BottomFrame; +extern RGBTexture *pTexture_RightFrame; + + +extern unsigned int uTextureID_right_panel_loop; // weak + + +extern struct Texture *pTexture_Leather; +extern struct Texture *pTexture_RestUI_CurrentSkyFrame; // idb +extern struct Texture *pTexture_RestUI_CurrentHourglassFrame; // idb + + +extern std::array uTextureID_Optkb; + +extern unsigned int optvid_base_texture_id; +extern unsigned int bloodsplats_texture_id; +extern unsigned int us_colored_lights_texture_id; +extern unsigned int tinting_texture_id; +extern unsigned int uTextureID_507C20; // weak +extern unsigned int uTextureID_507C24; // weak +extern std::array pTextureIDs_GammaPositions; +extern unsigned int not_available_bloodsplats_texture_id; +extern unsigned int not_available_us_colored_lights_texture_id; +extern unsigned int not_available_tinting_texture_id; + + +struct OptionsMenuSkin +{ + OptionsMenuSkin(); + void Relaease(); + + unsigned int uTextureID_Background; // 507C60 + unsigned int uTextureID_TurnSpeed[3]; // 507C64 + unsigned int uTextureID_ArrowLeft; // 507C70 + unsigned int uTextureID_ArrowRight; // 507C74 + unsigned int uTextureID_unused_0; // 507C78 + unsigned int uTextureID_unused_1; // 507C7C + unsigned int uTextureID_unused_2; // 507C80 + unsigned int uTextureID_FlipOnExit; // 507C84 + unsigned int uTextureID_SoundLevels[10]; // 507C88 + unsigned int uTextureID_AlwaysRun; // 507CB0 + unsigned int uTextureID_WalkSound; // 507CB4 + unsigned int uTextureID_ShowDamage; // 507CB8 +}; +extern OptionsMenuSkin options_menu_skin; // 507C60 + + +extern unsigned int uTextureID_detaliz_close_button; // weak +extern unsigned int uTextureID_MAGNIF_B; // weak +extern unsigned int uTextureID_BACKDOLL; // weak +extern unsigned int uTextureID_BACKHAND; // weak + + +extern struct Texture pTex_F7CE30; + + +extern RGBTexture stru_5773C4; // idb + +extern struct stru355 stru_4E82A4;// = {0x20, 0x41, 0, 0x20, 0xFF0000, 0xFF00, 0xFF, 0xFF000000}; moved to texture.h +extern struct stru355 stru_4EFCBC;// = {0x20, 0x41, 0, 0x10, 0x7C00, 0x3E0, 0x1F, 0x8000}; moved to texture.h + + + + + + + + + +struct stru355 +{ + int field_0; + int field_4; + int field_8; + int field_C; + int field_10; + int field_14; + int field_18; + int field_1C; +}; + +/* 390 */ +#pragma pack(push, 1) +struct stru350 +{ + stru350 *_450DDE(); + bool _450DF1(const struct stru355 *p1, const struct stru355 *p2); + unsigned int _450F55(int a2); + int _450FB1(int a2); + int sub_451007_scale_image_bicubic(unsigned short *pSrc, int srcWidth, int srcHeight, int srcPitch, + unsigned short *pDst, int dstWidth, int dstHeight, int dstPitch, + int a9, int a10); + + struct stru355 field_0; + struct stru355 field_20; + int field_40; + int field_44; + int field_48; + int field_4C; + int field_50; + int field_54; + int field_58; + int field_5C; +}; +#pragma pack(pop) + diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/Viewport.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/Viewport.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,714 @@ +#define _CRTDBG_MAP_ALLOC +#include +#include + +#define _CRT_SECURE_NO_WARNINGS +#include "Viewport.h" + + +#include "Party.h" +#include "OurMath.h" +#include "Actor.h" +#include "Outdoor.h" +#include "Events.h" +#include "Mouse.h" +#include "SpriteObject.h" +#include "ObjectList.h" +#include "DecorationList.h" +#include "texts.h" +#include "Game.h" +#include "Vis.h" +#include "LOD.h" +#include "GUIWindow.h" +#include "TurnEngine.h" +#include "stru123.h" +#include "MM7.h" +#include "Engine/Graphics/Level/Decoration.h" + + +//----- (004C0262) -------------------------------------------------------- +void Viewport::SetScreen( signed int sTL_X, signed int sTL_Y, signed int sBR_X, signed int sBR_Y ) + { + unsigned int tl_x; // edx@1 + unsigned int br_x; // esi@1 + unsigned int tl_y; // edi@3 + unsigned int br_y; // eax@3 + + tl_x = sTL_X; + br_x = sBR_X; + if ( sTL_X > sBR_X ) + { + br_x = sTL_X; // swap x's + tl_x = sBR_X; + } + tl_y = sTL_Y; + br_y = sBR_Y; + if ( sTL_Y > sBR_Y ) + { + br_y = sTL_Y; // swap y's + tl_y = sBR_Y; + } + this->uScreen_TL_X = tl_x; + this->uScreen_TL_Y = tl_y; + this->uScreen_BR_X = br_x; + this->uScreen_BR_Y = br_y; + this->uScreenWidth = br_x - tl_x + 1; + this->uScreenHeight = br_y - tl_y + 1; + this->uScreenCenterX = (signed int)(br_x + tl_x) /2; + //if ( pRenderer->pRenderD3D == 0 ) + // this->uScreenCenterY = this->uScreen_BR_Y - fixpoint_mul(field_30, uScreenHeight); + //else + this->uScreenCenterY = (br_y + tl_y)/2; + SetViewport(this->uScreen_TL_X, this->uScreen_TL_Y, this->uScreen_BR_X, this->uScreen_BR_Y); + } + +//----- (004C02F8) -------------------------------------------------------- +void Viewport::SetFOV(int field_of_view) +{ + this->field_of_view = field_of_view; + SetScreen(uScreen_TL_X, uScreen_TL_Y, uScreen_BR_X, uScreen_BR_Y); +} + +//----- (004C0312) -------------------------------------------------------- +void Viewport::SetViewport( signed int sTL_X, signed int sTL_Y, signed int sBR_X, signed int sBR_Y ) + { + signed int tl_x; // ebx@1 + signed int tl_y; // edi@3 + signed int br_x; // edx@5 + signed int br_y; // eax@7 + + tl_x = sTL_X; + if ( sTL_X < this->uScreen_TL_X ) + tl_x = this->uScreen_TL_X; + tl_y = sTL_Y; + if ( sTL_Y < this->uScreen_TL_Y ) + tl_y = this->uScreen_TL_Y; + br_x = sBR_X; + if ( sBR_X > this->uScreen_BR_X ) + br_x = this->uScreen_BR_X; + br_y = sBR_Y; + if ( sBR_Y > this->uScreen_BR_Y ) + br_y = this->uScreen_BR_Y; + this->uViewportTL_Y = tl_y; + this->uViewportTL_X = tl_x; + this->uViewportBR_X = br_x; + this->uViewportBR_Y = br_y; + } + +//----- (00443219) -------------------------------------------------------- + void ViewingParams::_443219() + { + this->sViewCenterY += 512; + + AdjustPosition(); + } + +//----- (00443225) -------------------------------------------------------- +void ViewingParams::_443225() +{ + this->sViewCenterX -= 512; + + AdjustPosition(); +} + +//----- (00443231) -------------------------------------------------------- +void ViewingParams::_443231() +{ + this->sViewCenterY -= 512; + + AdjustPosition(); +} + +//----- (0044323D) -------------------------------------------------------- +void ViewingParams::_44323D() +{ + this->sViewCenterX += 512; + + AdjustPosition(); +} + +//----- (00443249) -------------------------------------------------------- +void ViewingParams::CenterOnParty() +{ + this->uMapBookMapZoom = fixpoint_mul(0x8000, this->uMapBookMapZoom); + if (this->uMapBookMapZoom < 384) + this->uMapBookMapZoom = 384; + + this->sViewCenterX = pParty->vPosition.x; + this->sViewCenterY = pParty->vPosition.y; + + AdjustPosition(); +} + +//----- (00443291) -------------------------------------------------------- +void ViewingParams::CenterOnParty2() +{ + int v2; // eax@1 + + if (uCurrentlyLoadedLevelType == LEVEL_Outdoor) + v2 = 1536; + else if (uCurrentlyLoadedLevelType == LEVEL_Indoor) + v2 = 3072; + else assert(false); + + this->uMapBookMapZoom *= 2; + if (this->uMapBookMapZoom > v2 ) + this->uMapBookMapZoom = v2; + + this->sViewCenterX = pParty->vPosition.x; + this->sViewCenterY = pParty->vPosition.y; + AdjustPosition(); +} + +//----- (004432E7) -------------------------------------------------------- +void ViewingParams::AdjustPosition() +{ + ViewingParams *v1; // esi@1 + int v2; // ebx@1 + signed int v3; // edx@1 + int v4; // ecx@1 + int v5; // edi@3 + int v6; // eax@3 + int v7; // eax@5 + + + v1 = this; + v2 = this->indoor_center_y; + v3 = 88 >> (this->uMapBookMapZoom / 384); + v4 = (44 - v3) << 9; + if ( v1->sViewCenterY > v2 + v4 ) + v1->sViewCenterY = v2 + v4; + + v5 = v1->indoor_center_x; + v6 = (v3 - 44) << 9; + if ( v1->sViewCenterX < v5 + v6 ) + v1->sViewCenterX = v5 + v6; + + v7 = v2 + v6; + if ( v1->sViewCenterY < v7 ) + v1->sViewCenterY = v7; + + if ( v1->sViewCenterX > v5 + v4 ) + v1->sViewCenterX = v5 + v4; + } + +//----- (00443343) -------------------------------------------------------- +void ViewingParams::InitGrayPalette() + { + for (unsigned short i=0; i<256; ++i) + pPalette[i]=Color16(i, i, i); + } + +//----- (00443365) -------------------------------------------------------- +void ViewingParams::_443365() +{ + Vec3_short_ *v3; // eax@4 + Vec3_short_ *v6; // eax@12 + int minimum_y; // [sp+10h] [bp-10h]@2 + int maximum_y; // [sp+14h] [bp-Ch]@2 + int minimum_x; // [sp+18h] [bp-8h]@2 + int maximum_x; // [sp+1Ch] [bp-4h]@2 + + InitGrayPalette(); + if ( uCurrentlyLoadedLevelType == LEVEL_Indoor ) + { + minimum_x = 0x40000000; + minimum_y = 0x40000000; + + maximum_x = -0x40000000; + maximum_y = -0x40000000; + for (int i=0; ipMapOutlines->uNumOutlines; ++i) + { + v3 = &pIndoor->pVertices[pIndoor->pMapOutlines->pOutlines[i].uFace1ID]; + + if ( v3->x < minimum_x ) + minimum_x = v3->x; + if ( v3->x > maximum_x ) + maximum_x = v3->x; + if ( v3->y < minimum_y ) + minimum_y = v3->x; + if ( v3->y > maximum_y ) + maximum_y = v3->x; + + v6 = &pIndoor->pVertices[pIndoor->pMapOutlines->pOutlines[i].uFace2ID]; + + if ( v6->x < minimum_x ) + minimum_x = v3->x; + if ( v6->x > maximum_x ) + maximum_x = v3->x; + + if ( v6->y < minimum_y ) + minimum_y = v3->y; + if ( v6->y > maximum_y ) + maximum_y = v3->y; + } + + uMinimapZoom = 1024; + indoor_center_x = (signed int)(minimum_x + maximum_x) / 2; + field_28 = 10; + indoor_center_y = (signed int)(minimum_y + maximum_y) / 2; + } + else + { + indoor_center_x = 0; + indoor_center_y = 0; + uMinimapZoom = _576E2C_current_minimap_zoom; + field_28 = dword_576E28; + } + uMapBookMapZoom = 384; +} +//----- (0042213C) -------------------------------------------------------- +void OnGameViewportClick() +{ + signed int v0; // ebx@2 + POINT *v1; // esi@3 + signed int v6; // eax@14 + char *v7; // esi@15 + int v9; // eax@19 + unsigned int pTextureID; // eax@19 + int pEventID; // ecx@21 + int v15; // ecx@29 +// signed int v16; // edx@30 +// int v18; // ebx@47 +// signed int v21; // eax@58 + SpriteObject a1; // [sp+Ch] [bp-80h]@1 + POINT a2; // [sp+84h] [bp-8h]@3 + + int clickable_distance = 512; + + v1 = pMouse->GetCursorPos(&a2); + //if ( pRenderer->pRenderD3D ) + v0 = pGame->pVisInstance->get_picked_object_zbuf_val(); + //else + // v0 = pRenderer->pActiveZBuffer[v1->x + pSRZBufferLineOffsets[v1->y]]; + + if ( PID_TYPE(v0) == OBJECT_Item) + { + int item_id = PID_ID(v0); + //v21 = (signed int)(unsigned __int16)v0 >> 3; + if ( !(pObjectList->pObjects[pSpriteObjects[item_id].uObjectDescID].uFlags & 0x10) && item_id < 1000 && pSpriteObjects[item_id].uObjectDescID + && (unsigned int)v0 < 0x2000000 ) + { + if ( pSpriteObjects[item_id].stru_24.GetItemEquipType() == 18 ) + { + pParty->PartyFindsGold(pSpriteObjects[item_id].stru_24.uSpecEnchantmentType, 0); + viewparams->bRedrawGameUI = 1; + } + else + { + sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[471], pItemsTable->pItems[pSpriteObjects[item_id].stru_24.uItemID].pUnidentifiedName);//You found an item (%s)! + ShowStatusBarString(pTmpBuf2.data(), 2); + if ( pSpriteObjects[item_id].stru_24.uItemID == ITEM_ARTIFACT_SPLITTER ) + _449B7E_toggle_bit(pParty->_quest_bits, 184, 1); + if ( pSpriteObjects[item_id].stru_24.uItemID == 455 ) + _449B7E_toggle_bit(pParty->_quest_bits, 185, 1); + if ( !pParty->AddItemToParty(&pSpriteObjects[item_id].stru_24) ) + pParty->SetHoldingItem(&pSpriteObjects[item_id].stru_24); + } + SpriteObject::OnInteraction(item_id); + return; + } + if ( !pParty->pPickedItem.uItemID ) + return; + __debugbreak();//no checker + v6 = 0; + a1.uType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID; + if ( (signed int)pObjectList->uNumObjects <= 0 ) + LOWORD(v6) = 0; + else + { + v7 = (char *)&pObjectList->pObjects->uObjectID; + while ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID != *(short *)v7 ) + { + ++v6; + v7 += 56; + if ( v6 >= (signed int)pObjectList->uNumObjects ) + { + LOWORD(v6) = 0; + break; + } + } + } + a1.uObjectDescID = v6; + a1.vPosition.y = pParty->vPosition.y; + a1.spell_caster_pid = OBJECT_Player; + a1.vPosition.x = pParty->vPosition.x; + a1.vPosition.z = pParty->sEyelevel + pParty->vPosition.z; + a1.uSoundID = 0; + a1.uFacing = 0; + a1.uAttributes = 8; + a1.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->sEyelevel + pParty->vPosition.z); + a1.uSpriteFrameID = 0; + memcpy(&a1.stru_24, &pParty->pPickedItem, 0x24u); + + extern int UnprojectX(int); + //v9 = UnprojectX(v1->x); + a1.Create(pParty->sRotationY + UnprojectX(v1->x), 184, 200, 0); + pTextureID = pIcons_LOD->LoadTexture(pParty->pPickedItem.GetIconName(), TEXTURE_16BIT_PALETTE); + if (pTextureID != -1) + pIcons_LOD->pTextures[pTextureID].Release(); + pMouse->RemoveHoldingItem(); + pIcons_LOD->SyncLoadedFilesCount(); + return; + } + if ( PID_TYPE(v0) == OBJECT_Actor) + { + int mon_id = PID_ID(v0); + //a2.y = v16; + if ( pActors[mon_id].uAIState == Dead ) + { + if ( (unsigned int)v0 < 0x2000000 )//distance limit for loot monster + { + pActors[mon_id].LootActor(); + return; + } + if ( !pParty->pPickedItem.uItemID ) + return; + __debugbreak();//no checker + v6 = 0; + a1.uType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID; + if ( (signed int)pObjectList->uNumObjects <= 0 ) + LOWORD(v6) = 0; + else + { + v7 = (char *)&pObjectList->pObjects->uObjectID; + while ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID != *(short *)v7 ) + { + ++v6; + v7 += 56; + if ( v6 >= (signed int)pObjectList->uNumObjects ) + { + LOWORD(v6) = 0; + break; + } + } + } + a1.uObjectDescID = v6; + a1.vPosition.y = pParty->vPosition.y; + a1.spell_caster_pid = OBJECT_Player; + a1.vPosition.x = pParty->vPosition.x; + a1.vPosition.z = pParty->sEyelevel + pParty->vPosition.z; + a1.uSoundID = 0; + a1.uFacing = 0; + a1.uAttributes = 8; + a1.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->sEyelevel + pParty->vPosition.z); + a1.uSpriteFrameID = 0; + memcpy(&a1.stru_24, &pParty->pPickedItem, 0x24u); + + extern int UnprojectX(int); + //v9 = UnprojectX(v1->x); + a1.Create(pParty->sRotationY + UnprojectX(v1->x), 184, 200, 0); + pTextureID = pIcons_LOD->LoadTexture(pParty->pPickedItem.GetIconName(), TEXTURE_16BIT_PALETTE); + if (pTextureID != -1) + pIcons_LOD->pTextures[pTextureID].Release(); + pMouse->RemoveHoldingItem(); + pIcons_LOD->SyncLoadedFilesCount(); + return; + } + if ( GetAsyncKeyState(VK_SHIFT) >= 0 ) + { + if ( !pActors[mon_id].GetActorsRelation(0) && pActors[mon_id].ActorFriend() ) + { + if ( HIWORD(v0) >= clickable_distance) + { + if ( !pParty->pPickedItem.uItemID ) + return; + __debugbreak();//no checker + v6 = 0; + a1.uType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID; + if ( (signed int)pObjectList->uNumObjects <= 0 ) + LOWORD(v6) = 0; + else + { + v7 = (char *)&pObjectList->pObjects->uObjectID; + while ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID != *(short *)v7 ) + { + ++v6; + v7 += 56; + if ( v6 >= (signed int)pObjectList->uNumObjects ) + { + LOWORD(v6) = 0; + break; + } + } + } + a1.uObjectDescID = v6; + a1.vPosition.y = pParty->vPosition.y; + a1.spell_caster_pid = OBJECT_Player; + a1.vPosition.x = pParty->vPosition.x; + a1.vPosition.z = pParty->sEyelevel + pParty->vPosition.z; + a1.uSoundID = 0; + a1.uFacing = 0; + a1.uAttributes = 8; + a1.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->sEyelevel + pParty->vPosition.z); + a1.uSpriteFrameID = 0; + memcpy(&a1.stru_24, &pParty->pPickedItem, 0x24u); + + extern int UnprojectX(int); + //v9 = UnprojectX(v1->x); + a1.Create(pParty->sRotationY + UnprojectX(v1->x), 184, 200, 0); + pTextureID = pIcons_LOD->LoadTexture(pParty->pPickedItem.GetIconName(), TEXTURE_16BIT_PALETTE); + if (pTextureID != -1) + pIcons_LOD->pTextures[pTextureID].Release(); + pMouse->RemoveHoldingItem(); + pIcons_LOD->SyncLoadedFilesCount(); + return; + } + if ( !pActors[mon_id].CanAct() ) + return; + //v18 = mon_id; + Actor::AI_FaceObject(mon_id, 4, 0, 0); + if ( !pActors[mon_id].sNPC_ID ) + { + if ( pNPCStats->pGroups_copy[pActors[mon_id].uGroup] ) + { + if ( pNPCStats->pCatchPhrases[pNPCStats->pGroups_copy[pActors[mon_id].uGroup]] ) + { + pParty->uFlags |= 2; + strcpy(byte_5B0938.data(), pNPCStats->pCatchPhrases[pNPCStats->pGroups_copy[pActors[mon_id].uGroup]]); + sub_4451A8_press_any_key(0, 0, 0); + } + } + return; + } + pMessageQueue_50CBD0->AddGUIMessage(UIMSG_StartNPCDialogue, mon_id, 0); + return; + } + if ( pParty->bTurnBasedModeOn == true && pTurnEngine->turn_stage == TE_MOVEMENT ) + { + pTurnEngine->field_18 |= TE_FLAG_8; + return; + } + pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Attack, 0, 0); + } + else + { + if ( pParty->bTurnBasedModeOn == true && pTurnEngine->turn_stage == TE_MOVEMENT ) + { + pParty->uFlags |= PARTY_FLAGS_1_FALLING; + return; + } + if ( uActiveCharacter && sub_427769_isSpellQuickCastableOnShiftClick(pPlayers[uActiveCharacter]->uQuickSpell)) + pMessageQueue_50CBD0->AddGUIMessage(UIMSG_CastQuickSpell, 0, 0); + } + return; + } + if ( PID_TYPE(v0) == OBJECT_Decoration) + { + if ( (signed int)(((unsigned int)v0 >> 16) - pDecorationList->pDecorations[pLevelDecorations[(signed int)(unsigned __int16)v0 >> 3].uDecorationDescID].uRadius) >= clickable_distance ) + { + if ( !pParty->pPickedItem.uItemID ) + return; + __debugbreak();//no checker + v6 = 0; + a1.uType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID; + if ( (signed int)pObjectList->uNumObjects <= 0 ) + LOWORD(v6) = 0; + else + { + v7 = (char *)&pObjectList->pObjects->uObjectID; + while ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID != *(short *)v7 ) + { + ++v6; + v7 += 56; + if ( v6 >= (signed int)pObjectList->uNumObjects ) + { + LOWORD(v6) = 0; + break; + } + } + } + a1.uObjectDescID = v6; + a1.vPosition.y = pParty->vPosition.y; + a1.spell_caster_pid = OBJECT_Player; + a1.vPosition.x = pParty->vPosition.x; + a1.vPosition.z = pParty->sEyelevel + pParty->vPosition.z; + a1.uSoundID = 0; + a1.uFacing = 0; + a1.uAttributes = 8; + a1.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->sEyelevel + pParty->vPosition.z); + a1.uSpriteFrameID = 0; + memcpy(&a1.stru_24, &pParty->pPickedItem, 0x24u); + + extern int UnprojectX(int); + //v9 = UnprojectX(v1->x); + a1.Create(pParty->sRotationY + UnprojectX(v1->x), 184, 200, 0); + pTextureID = pIcons_LOD->LoadTexture(pParty->pPickedItem.GetIconName(), TEXTURE_16BIT_PALETTE); + if (pTextureID != -1) + pIcons_LOD->pTextures[pTextureID].Release(); + pMouse->RemoveHoldingItem(); + pIcons_LOD->SyncLoadedFilesCount(); + return; + } + if ( !pLevelDecorations[(signed int)(unsigned __int16)v0 >> 3].uEventID ) + { + if ( pLevelDecorations[(signed int)(unsigned __int16)v0 >> 3].IsInteractive() ) + { + v15 = stru_5E4C90_MapPersistVars._decor_events[pLevelDecorations[(signed int)(unsigned __int16)v0 >> 3]._idx_in_stru123 - 75] + 380; + activeLevelDecoration = &pLevelDecorations[(signed int)(unsigned __int16)v0 >> 3]; + EventProcessor(v15, 0, 1); + activeLevelDecoration = nullptr; + } + return; + } + pEventID = pLevelDecorations[(signed int)(unsigned __int16)v0 >> 3].uEventID; + EventProcessor(pEventID, (unsigned __int16)v0, 1); + return; + } + if ( PID_TYPE(v0) == OBJECT_BModel && HIWORD(v0) < clickable_distance) + { + if ( uCurrentlyLoadedLevelType == LEVEL_Indoor) + { + if ( !pIndoor->pFaces[PID_ID(v0)].Clickable() ) + { + if ( !pParty->pPickedItem.uItemID ) + { + ShowNothingHereStatus(); + if ( !pParty->pPickedItem.uItemID ) + return; + } + __debugbreak();//no checker + v6 = 0; + a1.uType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID; + if ( (signed int)pObjectList->uNumObjects <= 0 ) + LOWORD(v6) = 0; + else + { + v7 = (char *)&pObjectList->pObjects->uObjectID; + while ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID != *(short *)v7 ) + { + ++v6; + v7 += 56; + if ( v6 >= (signed int)pObjectList->uNumObjects ) + { + LOWORD(v6) = 0; + break; + } + } + } + a1.uObjectDescID = v6; + a1.vPosition.y = pParty->vPosition.y; + a1.spell_caster_pid = OBJECT_Player; + a1.vPosition.x = pParty->vPosition.x; + a1.vPosition.z = pParty->sEyelevel + pParty->vPosition.z; + a1.uSoundID = 0; + a1.uFacing = 0; + a1.uAttributes = 8; + a1.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->sEyelevel + pParty->vPosition.z); + a1.uSpriteFrameID = 0; + memcpy(&a1.stru_24, &pParty->pPickedItem, 0x24u); + + extern int UnprojectX(int); + v9 = UnprojectX(v1->x); + a1.Create(pParty->sRotationY + v9, 184, 200, 0); + pTextureID = pIcons_LOD->LoadTexture(pParty->pPickedItem.GetIconName(), TEXTURE_16BIT_PALETTE); + if (pTextureID != -1) + pIcons_LOD->pTextures[pTextureID].Release(); + pMouse->RemoveHoldingItem(); + pIcons_LOD->SyncLoadedFilesCount(); + return; + } + pEventID = pIndoor->pFaceExtras[pIndoor->pFaces[PID_ID(v0)].uFaceExtraID].uEventID; + } + if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor) + { + if ( !pOutdoor->pBModels[(signed int)(v0 & 0xFFFF) >> 9].pFaces[PID_ID(v0) & 0x3F].Clickable()) + { + if ( !pParty->pPickedItem.uItemID ) + { + ShowNothingHereStatus(); + if ( !pParty->pPickedItem.uItemID ) + return; + } + __debugbreak();//no checker + v6 = 0; + a1.uType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID; + if ( (signed int)pObjectList->uNumObjects <= 0 ) + LOWORD(v6) = 0; + else + { + v7 = (char *)&pObjectList->pObjects->uObjectID; + while ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID != *(short *)v7 ) + { + ++v6; + v7 += 56; + if ( v6 >= (signed int)pObjectList->uNumObjects ) + { + LOWORD(v6) = 0; + break; + } + } + } + a1.uObjectDescID = v6; + a1.vPosition.y = pParty->vPosition.y; + a1.spell_caster_pid = OBJECT_Player; + a1.vPosition.x = pParty->vPosition.x; + a1.vPosition.z = pParty->sEyelevel + pParty->vPosition.z; + a1.uSoundID = 0; + a1.uFacing = 0; + a1.uAttributes = 8; + a1.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->sEyelevel + pParty->vPosition.z); + a1.uSpriteFrameID = 0; + memcpy(&a1.stru_24, &pParty->pPickedItem, 0x24u); + + extern int UnprojectX(int); + v9 = UnprojectX(v1->x); + a1.Create(pParty->sRotationY + v9, 184, 200, 0); + pTextureID = pIcons_LOD->LoadTexture(pParty->pPickedItem.GetIconName(), TEXTURE_16BIT_PALETTE); + if (pTextureID != -1) + pIcons_LOD->pTextures[pTextureID].Release(); + pMouse->RemoveHoldingItem(); + pIcons_LOD->SyncLoadedFilesCount(); + return; + } + pEventID = pOutdoor->pBModels[(signed int)(v0 & 0xFFFF) >> 9].pFaces[PID_ID(v0) & 0x3F].sCogTriggeredID; + } + EventProcessor(pEventID, (unsigned __int16)v0, 1); + return; + } + if ( PID_TYPE(v0) != OBJECT_BModel || HIWORD(v0) >= clickable_distance ) + { + if ( !pParty->pPickedItem.uItemID ) + return; + //__debugbreak();//no checker + v6 = 0; + a1.uType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID; + if ( (signed int)pObjectList->uNumObjects <= 0 ) + LOWORD(v6) = 0; + else + { + v7 = (char *)&pObjectList->pObjects->uObjectID; + while ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID != *(short *)v7 ) + { + ++v6; + v7 += 56; + if ( v6 >= (signed int)pObjectList->uNumObjects ) + { + LOWORD(v6) = 0; + break; + } + } + } + a1.uObjectDescID = v6; + a1.vPosition.y = pParty->vPosition.y; + a1.spell_caster_pid = OBJECT_Player; + a1.vPosition.x = pParty->vPosition.x; + a1.vPosition.z = pParty->sEyelevel + pParty->vPosition.z; + a1.uSoundID = 0; + a1.uFacing = 0; + a1.uAttributes = 8; + a1.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->sEyelevel + pParty->vPosition.z); + a1.uSpriteFrameID = 0; + memcpy(&a1.stru_24, &pParty->pPickedItem, 0x24u); + + extern int UnprojectX(int); + //v9 = UnprojectX(v1->x); + a1.Create(pParty->sRotationY + UnprojectX(v1->x), 184, 200, 0); + pTextureID = pIcons_LOD->LoadTexture(pParty->pPickedItem.GetIconName(), TEXTURE_16BIT_PALETTE); + if (pTextureID != -1) + pIcons_LOD->pTextures[pTextureID].Release(); + pMouse->RemoveHoldingItem(); + pIcons_LOD->SyncLoadedFilesCount(); + return; + } +} diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/Viewport.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/Viewport.h Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,98 @@ +#pragma once + +/* 149 */ +#pragma pack(push, 1) +struct Viewport +{ + inline Viewport() + { + field_of_view = 65536 / 2; + SetScreen(0, 0, 639, 479); + } + + void SetScreen(signed int uX, signed int uY, signed int uZ, signed int uW); + void SetFOV(int a2); + void SetViewport(signed int uX, signed int uY, signed int uZ, signed int uW); + + + signed int uScreen_TL_X; + signed int uScreen_TL_Y; + signed int uScreen_BR_X; + signed int uScreen_BR_Y; + signed int uViewportTL_X; + signed int uViewportTL_Y; + signed int uViewportBR_X; + signed int uViewportBR_Y; + int uScreenWidth; + int uScreenHeight; + int uScreenCenterX; + int uScreenCenterY; + int field_of_view; +}; +#pragma pack(pop) + +void OnGameViewportClick(); + + +extern struct Viewport *pViewport; + + + +/* 201 */ +#pragma pack(push, 1) +struct ViewingParams +{ + inline ViewingParams() + { + draw_sw_outlines = false; + draw_d3d_outlines = false; + field_4C = 0; + } + + void CenterOnParty2(); + void InitGrayPalette(); + void _443219(); + void _443225(); + void _443231(); + void _44323D(); + void CenterOnParty(); + void AdjustPosition(); + void _443365(); + + + + int uSomeX; + int uSomeY; + int uSomeZ; + int uSomeW; + unsigned int uScreen_topL_X; + unsigned int uScreen_topL_Y; + unsigned int uScreen_BttmR_X; + unsigned int uScreen_BttmR_Y; + int field_20; + unsigned int uMinimapZoom; + int field_28; + unsigned int uMapBookMapZoom; + int sViewCenterX; + int sViewCenterY; + __int16 indoor_center_x; + __int16 indoor_center_y; + int field_3C; + unsigned int uTextureID_LocationMap; + int bRedrawGameUI; + int field_48; + int field_4C; + int draw_sw_outlines; + int draw_d3d_outlines; + int field_58; + int field_5C; + int field_60; + int field_64; + int field_68; + unsigned __int16 pPalette[256]; +}; +#pragma pack(pop) + + + +extern struct ViewingParams *viewparams; \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/Vis.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/Vis.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,1556 @@ +#define _CRTDBG_MAP_ALLOC +#include +#include + +#define _CRT_SECURE_NO_WARNINGS +#include "Vis.h" +#include "Sprites.h" +#include "Lod.h" +#include "Outdoor.h" +#include "Game.h" +#include "Actor.h" +#include "Viewport.h" +#include "OurMath.h" +#include "Log.h" +#include "ErrorHandling.h" + +#include "MM7.h" +#include "Engine/Graphics/Level/Decoration.h" + + +static Vis_SelectionList Vis_static_sub_4C1944_stru_F8BDE8; + +Vis_SelectionFilter vis_sprite_filter_1 = {VisObjectType_Sprite, OBJECT_Decoration, 0, 0, 2}; // 00F93E1C +Vis_SelectionFilter vis_sprite_filter_2 = {VisObjectType_Sprite, OBJECT_Decoration, 0, 0, 2}; // 00F93E30 +Vis_SelectionFilter vis_face_filter = {VisObjectType_Face, OBJECT_Any, -1, 0, 0}; // 00F93E44 +Vis_SelectionFilter vis_door_filter = {VisObjectType_Face, OBJECT_BLVDoor, -1, 0x100000, 0}; // 00F93E58 +Vis_SelectionFilter vis_sprite_filter_3 = {VisObjectType_Sprite, OBJECT_Decoration, -1, 0, 4}; // 00F93E6C +Vis_SelectionFilter vis_sprite_filter_4 = {VisObjectType_Any, OBJECT_Item, -1, 0, 0}; // static to sub_44EEA7 + + + +//----- (004C1026) -------------------------------------------------------- +Vis_ObjectInfo *Vis::DetermineFacetIntersection(BLVFace *face, unsigned int pid, float pick_depth) +{ +// char *v4; // eax@4 +// signed int v5; // ecx@4 + RenderVertexSoft pRay[2]; // [sp+20h] [bp-70h]@17 +// int v20; // [sp+84h] [bp-Ch]@10 + + static Vis_SelectionList SelectedPointersList;//stru_F8FE00 + SelectedPointersList.uNumPointers = 0; + + static bool _init_flag = false; + static RenderVertexSoft static_DetermineFacetIntersection_array_F8F200[64]; + if (!_init_flag) + { + _init_flag = true; + for (uint i = 0; i < 64; ++i) + static_DetermineFacetIntersection_array_F8F200[i].flt_2C = 0.0f; + } + + if (uCurrentlyLoadedLevelType == LEVEL_Indoor) + { + if ( (signed int)face->uNumVertices > 0 ) + { + for ( int i = 0; i < face->uNumVertices; i++) + { + static_DetermineFacetIntersection_array_F8F200[i].vWorldPosition.x = (double)pIndoor->pVertices[face->pVertexIDs[i]].x; + static_DetermineFacetIntersection_array_F8F200[i].vWorldPosition.y = (double)pIndoor->pVertices[face->pVertexIDs[i]].y; + static_DetermineFacetIntersection_array_F8F200[i].vWorldPosition.z = (double)pIndoor->pVertices[face->pVertexIDs[i]].z; + } + } + } + else if (uCurrentlyLoadedLevelType == LEVEL_Outdoor) + { + uint bmodel_id = pid >> 9; + Vec3_int_* v = (Vec3_int_ *)pOutdoor->pBModels[bmodel_id].pVertices.pVertices; + for (uint i = 0; i < face->uNumVertices; ++i) + { + static_DetermineFacetIntersection_array_F8F200[i].vWorldPosition.x = v[face->pVertexIDs[i]].x; + static_DetermineFacetIntersection_array_F8F200[i].vWorldPosition.y = v[face->pVertexIDs[i]].y; + static_DetermineFacetIntersection_array_F8F200[i].vWorldPosition.z = v[face->pVertexIDs[i]].z; + } + } + else assert(false); + + pGame->pIndoorCameraD3D->ViewTransform(static_DetermineFacetIntersection_array_F8F200, face->uNumVertices); + pGame->pIndoorCameraD3D->Project(static_DetermineFacetIntersection_array_F8F200, face->uNumVertices, 1); + + SortVectors_x(static_DetermineFacetIntersection_array_F8F200, 0, face->uNumVertices - 1); + if (static_DetermineFacetIntersection_array_F8F200[0].vWorldViewPosition.x > pick_depth) + return nullptr; + + float screenspace_center_x, + screenspace_center_y; + GetPolygonScreenSpaceCenter(static_DetermineFacetIntersection_array_F8F200, face->uNumVertices, &screenspace_center_x, &screenspace_center_y); + if (IsPolygonOccludedByBillboard(static_DetermineFacetIntersection_array_F8F200, face->uNumVertices, screenspace_center_x, screenspace_center_y)) + return nullptr; + + CastPickRay(pRay, screenspace_center_x, screenspace_center_y, pick_depth); + + if (uCurrentlyLoadedLevelType == LEVEL_Outdoor) + PickOutdoorFaces_Mouse(pick_depth, pRay, &SelectedPointersList, &vis_face_filter, true); + else if (uCurrentlyLoadedLevelType == LEVEL_Indoor) + PickIndoorFaces_Mouse(pick_depth, pRay, &SelectedPointersList, &vis_face_filter); + else assert(false); + + SelectedPointersList.create_object_pointers(); + sort_object_pointers(SelectedPointersList.object_pointers, 0, SelectedPointersList.uNumPointers - 1); + if (!SelectedPointersList.uNumPointers) + return nullptr; + + if (!SelectedPointersList.SelectionPointers(VisObjectType_Face, pid)) + return nullptr; + + if (SelectedPointersList.uNumPointers) + return SelectedPointersList.object_pointers[0]; + else return nullptr; +} +// F91E08: using guessed type char static_DetermineFacetIntersection_byte_F91E08__init_flags; + +//----- (004C12C3) -------------------------------------------------------- +bool Vis::IsPolygonOccludedByBillboard(RenderVertexSoft *vertices, int num_vertices, float x, float y) +{ + int v13 = -1; + //v5 = 0; + + //v6 = pRenderer->pBillboardRenderListD3D; + for (uint i = 0; i < pRenderer->uNumBillboardsToDraw; ++i) + { + RenderBillboardD3D* billboard = &pRenderer->pBillboardRenderListD3D[i]; + if (IsPointInsideD3DBillboard(billboard, x, y)) + { + if (v13 == -1) + v13 = i; + else if (pBillboardRenderList[billboard->sParentBillboardID].sZValue < + pBillboardRenderList[pRenderer->pBillboardRenderListD3D[v13].sParentBillboardID].sZValue) + v13 = i; + } + } + + if ( v13 == -1 ) + return false; + + // //Bounding rectangle(Ограничивающий прямоугольник)------------------------- + //v7 = 3.4028235e38; + float min_x = FLT_MAX; + //a4a = 3.4028235e38; + float min_y = FLT_MAX; + //a3a = -3.4028235e38; + float max_x = -FLT_MAX; + //thisb = -3.4028235e38; + float max_y = -FLT_MAX; + for (int i = 0; i < num_vertices; ++i) + { + RenderVertexSoft* v = &vertices[i]; + + if (v->vWorldViewProjX < min_x) + min_x = v->vWorldViewProjX; + if (v->vWorldViewProjX > max_x) + max_x = v->vWorldViewProjX; + + if (v->vWorldViewProjY < min_y) + min_y = v->vWorldViewProjY; + if (v->vWorldViewProjY > max_y) + max_y = v->vWorldViewProjY; + } + // //-------------------------------- + + if (min_x < pRenderer->pBillboardRenderListD3D[v13].pQuads[0].pos.x || pRenderer->pBillboardRenderListD3D[v13].pQuads[0].pos.y > min_y || + pRenderer->pBillboardRenderListD3D[v13].pQuads[3].pos.x < max_x || pRenderer->pBillboardRenderListD3D[v13].pQuads[1].pos.y < max_y) + return false; + + return true; +} + +//----- (004C1417) -------------------------------------------------------- +void Vis::GetPolygonCenter(RenderVertexD3D3 *pVertices, unsigned int uNumVertices, float *pCenterX, float *pCenterY) +{ + static RenderVertexD3D3 unk_F8EA00[64]; + + memcpy(unk_F8EA00, pVertices, 32 * uNumVertices); + + SortVerticesByX(unk_F8EA00, 0, uNumVertices - 1); + *pCenterX = (unk_F8EA00[uNumVertices - 1].pos.x - unk_F8EA00[0].pos.x) * 0.5 + unk_F8EA00[0].pos.x; + + SortVerticesByY(unk_F8EA00, 0, uNumVertices - 1); + *pCenterY = (unk_F8EA00[uNumVertices - 1].pos.y - unk_F8EA00[0].pos.y) * 0.5 + unk_F8EA00[0].pos.y; +} + +//----- (004C1495) -------------------------------------------------------- +void Vis::GetPolygonScreenSpaceCenter(RenderVertexSoft *vertices, int num_vertices, float *out_center_x, float *out_center_y) +{ +// char *v5; // eax@2 +// signed int v6; // ecx@2 +// float *result; // eax@5 + + static RenderVertexSoft static_sub_4C1495_array_F8DDF8[64]; + + memcpy(static_sub_4C1495_array_F8DDF8, vertices, 48 * num_vertices); + + SortByScreenSpaceX(static_sub_4C1495_array_F8DDF8, 0, num_vertices - 1); + *out_center_x = (static_sub_4C1495_array_F8DDF8[num_vertices - 1].vWorldViewProjX - static_sub_4C1495_array_F8DDF8[0].vWorldViewProjX) * 0.5 + static_sub_4C1495_array_F8DDF8[0].vWorldViewProjX; + + SortByScreenSpaceY(static_sub_4C1495_array_F8DDF8, 0, num_vertices - 1); + *out_center_y = (static_sub_4C1495_array_F8DDF8[num_vertices - 1].vWorldViewProjY - static_sub_4C1495_array_F8DDF8[0].vWorldViewProjY) * 0.5 + static_sub_4C1495_array_F8DDF8[0].vWorldViewProjY; +} + +//----- (004C1542) -------------------------------------------------------- +void Vis::PickBillboards_Mouse(float fPickDepth, float fX, float fY, Vis_SelectionList *list, Vis_SelectionFilter *filter) +{ + for (uint i = 0; i < pRenderer->uNumBillboardsToDraw; ++i) + { + RenderBillboardD3D* d3d_billboard = &pRenderer->pBillboardRenderListD3D[i]; + if (is_part_of_selection((void *)i, filter) && IsPointInsideD3DBillboard(d3d_billboard, fX, fY)) + { + if (DoesRayIntersectBillboard(fPickDepth, i)) + { + RenderBillboard* billboard = &pBillboardRenderList[d3d_billboard->sParentBillboardID]; + + list->AddObject((void *)d3d_billboard->sParentBillboardID, VisObjectType_Sprite, billboard->sZValue); + } + } + } +} + + +//----- (004C1607) -------------------------------------------------------- +bool Vis::IsPointInsideD3DBillboard(RenderBillboardD3D *a1, float x, float y) +{ + /*Not the original implementation. + This function is redone to use Grayface's mouse pick implementation to take only the visible + parts of billboards into account - I don't really have too much of an idea how it actually works*/ + float drX; // st7@2 + float drY; // ecx@2 + float drH; // [sp+4h] [bp-8h]@2 + float drW; // [sp+14h] [bp+8h]@2 + + if ( a1->sParentBillboardID == -1 ) + return false; + + drX = a1->pQuads[0].pos.x; + drW = a1->pQuads[3].pos.x - drX; + drY = a1->pQuads[0].pos.y; + drH = a1->pQuads[1].pos.y - drY; + + Sprite* ownerSprite = nullptr; + for (int i = 0; i < pSprites_LOD->uNumLoadedSprites; ++i) + { + if (pSprites_LOD->pHardwareSprites[i].pTexture == a1->pTexture) + { + ownerSprite = &pSprites_LOD->pHardwareSprites[i]; + break; + } + } + + if (ownerSprite == nullptr) + return false; + + int i = ownerSprite->uAreaX + int(ownerSprite->uAreaWidth * (x - drX) / drW); + int j = ownerSprite->uAreaY + int(ownerSprite->uAreaHeight * (y - drY) / drH); + + + LODSprite* spriteHeader = nullptr; + + for (int i = 0; i < MAX_LOD_SPRITES; ++i) + { + if (strcmp(pSprites_LOD->pSpriteHeaders[i].pName, ownerSprite->pName) == 0) + { + spriteHeader = &pSprites_LOD->pSpriteHeaders[i]; + break; + } + } + + if (j < 0 || j >= spriteHeader->uHeight) + return false; + + if (spriteHeader->pSpriteLines[j].a1 < 0 || i > spriteHeader->pSpriteLines[j].a2 || i < spriteHeader->pSpriteLines[j].a1) + { + return false; + } + return *(spriteHeader->pSpriteLines[j].pos + i - spriteHeader->pSpriteLines[j].a1) != 0; +} + +//----- (004C16B4) -------------------------------------------------------- +void Vis::PickIndoorFaces_Mouse(float fDepth, RenderVertexSoft *pRay, Vis_SelectionList *list, Vis_SelectionFilter *filter) +{ + int v5; // eax@1 + signed int pFaceID; // edi@2 + int v9; // eax@7 + unsigned int *pNumPointers; // eax@7 + Vis_ObjectInfo *v12; // edi@7 + RenderVertexSoft a1; // [sp+Ch] [bp-44h]@1 + void *v15; // [sp+40h] [bp-10h]@7 + int v17; // [sp+48h] [bp-8h]@1 + + v5 = 0; + v17 = 0; + for ( a1.flt_2C = 0.0; v17 < (signed int)pBspRenderer->num_faces; ++v17 ) + { + pFaceID = pBspRenderer->faces[v5].uFaceID; + if ( pFaceID >= 0 ) + { + if ( pFaceID < (signed int)pIndoor->uNumFaces ) + { + BLVFace* face = &pIndoor->pFaces[pFaceID]; + if ( is_part_of_selection(face, filter) ) + { + if ( !pGame->pIndoorCameraD3D->IsCulled(face) ) + { + if ( Intersect_Ray_Face(pRay, pRay + 1, &fDepth, &a1, face, 0xFFFFFFFFu) ) + { + pGame->pIndoorCameraD3D->ViewTransform(&a1, 1); + v9 = fixpoint_from_float(/*v8, */a1.vWorldViewPosition.x); + LOWORD(v9) = 0; + v15 = (void *)((PID(OBJECT_BModel,pFaceID)) + v9); + pNumPointers = &list->uNumPointers; + v12 = &list->object_pool[list->uNumPointers]; + v12->object = &pIndoor->pFaces[pFaceID]; + v12 = (Vis_ObjectInfo *) &v12->sZValue; + v12->object = v15; + v12->sZValue = 2; + ++*pNumPointers; + } + } + } + + if (face->uAttributes & FACE_PICKED) + face->uAttributes |= FACE_OUTLINED; + else + face->uAttributes &= ~FACE_OUTLINED; + face->uAttributes &= ~FACE_PICKED; + } + } + v5 = v17 + 1; + } +} + +//----- (004C17CF) -------------------------------------------------------- +void Vis::PickOutdoorFaces_Mouse(float fDepth, RenderVertexSoft *pRay, Vis_SelectionList *list, Vis_SelectionFilter *filter, bool only_reachable) +{ + if (!pOutdoor) + return; + + for (int i = 0; i < pOutdoor->uNumBModels; ++i) + { + int reachable; + if (!IsBModelVisible(i, &reachable)) + continue; + if (!reachable && only_reachable) + continue; + + BSPModel* bmodel = &pOutdoor->pBModels[i]; + for (int j = 0; j < bmodel->uNumFaces; ++j) + { + ODMFace* face = &bmodel->pFaces[j]; + if (is_part_of_selection(face, filter)) + { + BLVFace blv_face; + blv_face.FromODM(face); + + RenderVertexSoft intersection; + if (Intersect_Ray_Face(pRay, pRay + 1, &fDepth, &intersection, &blv_face, i)) + { + pGame->pIndoorCameraD3D->ViewTransform(&intersection, 1); + int v13 = fixpoint_from_float(/*v12, */intersection.vWorldViewPosition.x); + v13 &= 0xFFFF0000; + v13 += PID(OBJECT_BModel, j | (i << 6)); + + list->AddObject(face, VisObjectType_Face, v13); + } + + if (blv_face.uAttributes & FACE_PICKED) + face->uAttributes |= FACE_OUTLINED; + else + face->uAttributes &= ~FACE_OUTLINED; + blv_face.uAttributes &= ~FACE_PICKED; + } + } + } +} + +//----- (004C1930) -------------------------------------------------------- +//bool Vis::j_DoesRayIntersectBillboard(float fDepth, unsigned int uD3DBillboardIdx) +//{return DoesRayIntersectBillboard(fDepth, uD3DBillboardIdx);} + +//----- (004C1944) -------------------------------------------------------- +int Vis::PickClosestActor(int object_id, unsigned int pick_depth, int a4, int a5, int a6) +{ + Vis_SelectionFilter v8; // [sp+18h] [bp-20h]@3 + + static Vis_SelectionList Vis_static_sub_4C1944_stru_F8BDE8; + + v8.object_type = VisObjectType_Sprite; + v8.object_id = object_id; + v8.at_ai_state = a6; + v8.no_at_ai_state = a5; + v8.select_flags = a4; + Vis_static_sub_4C1944_stru_F8BDE8.uNumPointers = 0; + PickBillboards_Keyboard(pick_depth, &Vis_static_sub_4C1944_stru_F8BDE8, &v8); + Vis_static_sub_4C1944_stru_F8BDE8.create_object_pointers(Vis_SelectionList::Unique); + sort_object_pointers(Vis_static_sub_4C1944_stru_F8BDE8.object_pointers, 0, Vis_static_sub_4C1944_stru_F8BDE8.uNumPointers - 1); + + if (!Vis_static_sub_4C1944_stru_F8BDE8.uNumPointers) + return -1; + return Vis_static_sub_4C1944_stru_F8BDE8.object_pointers[0]->sZValue; +} + +//----- (004C1A02) -------------------------------------------------------- +void Vis::_4C1A02() +{ + RenderVertexSoft v1; // [sp+8h] [bp-C0h]@1 + RenderVertexSoft v2; // [sp+38h] [bp-90h]@1 + RenderVertexSoft v3; // [sp+68h] [bp-60h]@1 + RenderVertexSoft v4; // [sp+98h] [bp-30h]@1 + + v4.flt_2C = 0.0; + v4.vWorldPosition.x = 0.0; + v4.vWorldPosition.y = 65536.0; + v4.vWorldPosition.z = 0.0; + v3.flt_2C = 0.0; + v3.vWorldPosition.x = 65536.0; + v3.vWorldPosition.y = 0.0; + v3.vWorldPosition.z = 0.0; + memcpy(&v1, &v3, sizeof(v1)); + v3.flt_2C = 0.0; + v3.vWorldPosition.x = 0.0; + v3.vWorldPosition.y = 65536.0; + v3.vWorldPosition.z = 0.0; + memcpy(&v2, &v4, sizeof(v2)); + v4.flt_2C = 0.0; + v4.vWorldPosition.x = 65536.0; + v4.vWorldPosition.y = 0.0; + v4.vWorldPosition.z = 0.0; + memcpy(&this->stru_200C, &v1, 0x60u); + memcpy(&v1, &v4, sizeof(v1)); + memcpy(&v2, &v3, sizeof(v2)); + memcpy(&this->stru_206C, &v1, 0x60u); +} + +//----- (004C1ABA) -------------------------------------------------------- +void Vis::SortVectors_x(RenderVertexSoft *pArray, int start, int end) +{ + int left_sort_index; // ebx@2 + int right_sort_index; // ecx@2 + RenderVertexSoft temp_array; // [sp+4h] [bp-6Ch]@8 + RenderVertexSoft max_array; // [sp+34h] [bp-3Ch]@2 + + if ( end > start ) + { + left_sort_index = start - 1; + right_sort_index = end; + memcpy(&max_array, &pArray[end], sizeof(max_array)); + while ( 1 ) + { + do + { + ++left_sort_index; + } + while ( pArray[left_sort_index].vWorldViewPosition.x < (double)max_array.vWorldViewPosition.x ); + do + { + --right_sort_index; + } + while ( pArray[right_sort_index].vWorldViewPosition.x > (double)max_array.vWorldViewPosition.x ); + if ( left_sort_index >= right_sort_index ) + break; + memcpy(&temp_array, &pArray[left_sort_index], sizeof(temp_array)); + memcpy(&pArray[left_sort_index], &pArray[right_sort_index], sizeof(pArray[left_sort_index])); + memcpy(&pArray[right_sort_index], &temp_array, sizeof(pArray[right_sort_index])); + } + memcpy(&temp_array, &pArray[left_sort_index], sizeof(temp_array)); + memcpy(&pArray[left_sort_index], &pArray[end], sizeof(pArray[left_sort_index])); + memcpy(&pArray[end], &temp_array, sizeof(pArray[end])); + SortVectors_x(pArray, start, left_sort_index - 1); + SortVectors_x(pArray, left_sort_index + 1, end); + } +} + +//----- (004C1BAA) -------------------------------------------------------- +int Vis::get_object_zbuf_val(Vis_ObjectInfo *info) +{ + switch (info->object_type) + { + case VisObjectType_Sprite: + case VisObjectType_Face: + return info->sZValue; + + default: + MessageBoxW(nullptr, L"Undefined type requested for: CVis::get_object_zbuf_val()", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Vis.cpp:1037", 0); + return -1; + } +} + +//----- (004C1BF1) -------------------------------------------------------- +int Vis::get_picked_object_zbuf_val() +{ + if (!default_list.uNumPointers) + return -1; + + return get_object_zbuf_val(default_list.object_pointers[0]); +} + +//----- (004C1C0C) -------------------------------------------------------- +bool Vis::Intersect_Ray_Face(RenderVertexSoft *pRayStart, RenderVertexSoft *pRayEnd, float *pDepth, RenderVertexSoft *Intersection, BLVFace *pFace, signed int pBModelID) +{ + float c1; // st5@6 + float c2; // st7@11 + Vec3_short_ IntersectPoint; // ST04_6@11 + + + if (pFace->Portal() || pFace->Invisible()) + return false; + + int ray_dir_x = pRayEnd->vWorldPosition.x - pRayStart->vWorldPosition.x,//calculate the direction vector of the line(вычислим вектор направления линий) + ray_dir_y = pRayEnd->vWorldPosition.y - pRayStart->vWorldPosition.y, + ray_dir_z = pRayEnd->vWorldPosition.z - pRayStart->vWorldPosition.z; + +//c1 = -d-(n*p0) + c1 = -pFace->pFacePlane.dist -(pFace->pFacePlane.vNormal.x * pRayStart->vWorldPosition.x + + pFace->pFacePlane.vNormal.y * pRayStart->vWorldPosition.y + + pFace->pFacePlane.vNormal.z * pRayStart->vWorldPosition.z); + if (c1 > 0) + return false; +#define EPSILON 1e-6 +//c2 = n*u + c2 = pFace->pFacePlane.vNormal.x * ray_dir_y// get length of the line(Это дает нам длину линии) + + pFace->pFacePlane.vNormal.y * ray_dir_x + + pFace->pFacePlane.vNormal.z * ray_dir_z; + if (c2 > -EPSILON && c2 < EPSILON) // ray faces face's normal ( > 0) or parallel ( == 0) + return false; + +//t = -d-(n*p0)/n*u + float t = c1 / c2;//How far is crossing the line in percent for 0 to 1(Как далеко пересечение линии в процентах от 0 до 1 ) + + if (t < 0 || t > 1) + return false; + +// p(t) = p0 + tu; + Intersection->vWorldPosition.x = pRayStart->vWorldPosition.x + t * ray_dir_y;// add the interest to the start line(прибавляем процент линии к линии старта) + Intersection->vWorldPosition.y = pRayStart->vWorldPosition.y + t * ray_dir_x; + Intersection->vWorldPosition.z = pRayStart->vWorldPosition.z + t * ray_dir_z; + + IntersectPoint.x = Intersection->vWorldPosition.x; + IntersectPoint.y = Intersection->vWorldPosition.y; + IntersectPoint.z = Intersection->vWorldPosition.z; + + if ( !CheckIntersectBModel(pFace, IntersectPoint, pBModelID) ) + return false; + + *pDepth = t;//Record the distance from the origin of the ray (Записываем дистанцию от начала луча) + return true; +} + +//----- (004C1D2B) -------------------------------------------------------- +bool Vis::CheckIntersectBModel(BLVFace *pFace, Vec3_short_ IntersectPoint, signed int sModelID) +{ + int v5; // esi@10 + bool v6; // edi@10 + signed int v10; // ebx@14 +// int v15; // [sp+10h] [bp-Ch]@10 + signed int v16; // [sp+18h] [bp-4h]@10 + + int a = 0, b = 0; + + if (IntersectPoint.x < pFace->pBounding.x1 || IntersectPoint.x > pFace->pBounding.x2 || + IntersectPoint.y < pFace->pBounding.y1 || IntersectPoint.y > pFace->pBounding.y2 || + IntersectPoint.z < pFace->pBounding.z1 || IntersectPoint.z > pFace->pBounding.z2 ) + return false; + + if (sModelID != -1) + ODM_CreateIntersectFacesVertexCoordList(&a, &b, intersect_face_vertex_coords_list_a.data(), intersect_face_vertex_coords_list_b.data(), + &IntersectPoint, pFace, sModelID); + else + BLV_CreateIntersectFacesVertexCoordList(&a, &b, intersect_face_vertex_coords_list_a.data(), intersect_face_vertex_coords_list_b.data(), + &IntersectPoint, pFace); + v5 = 2 * pFace->uNumVertices; + v16 = 0; + intersect_face_vertex_coords_list_a[v5] = intersect_face_vertex_coords_list_a[0]; + intersect_face_vertex_coords_list_b[v5] = intersect_face_vertex_coords_list_b[0]; + v6 = intersect_face_vertex_coords_list_b[0] >= b; + if (v5 <= 0) + return false; + for ( int i = 0; i < v5; ++i ) + { + if ( v16 >= 2 ) + break; + if ( v6 ^ (intersect_face_vertex_coords_list_b[i + 1] >= b) ) + { + if ( intersect_face_vertex_coords_list_a[i + 1] >= a ) + v10 = 0; + else + v10 = 2; + v10 |= intersect_face_vertex_coords_list_a[i] < a ? 1 : 0; + if ( v10 != 3 ) + { + if ( !v10) + ++v16; + else + { + int _v1 = fixpoint_div(intersect_face_vertex_coords_list_a[i + 1] - intersect_face_vertex_coords_list_a[i], + intersect_face_vertex_coords_list_b[i + 1] - intersect_face_vertex_coords_list_b[i]); + int _v2 = fixpoint_mul(b - intersect_face_vertex_coords_list_b[i], _v1) + 32768; + + if (intersect_face_vertex_coords_list_a[i] + (_v2 >> 16) >= a) + ++v16; + } + } + } + v6 = intersect_face_vertex_coords_list_b[i + 1] >= b; + } + + if ( v16 != 1 ) + return false; + + if ( show_picked_face ) + pFace->uAttributes |= FACE_PICKED; + return true; +/* + int v5; // esi@10 + bool v6; // edi@10 + signed int v10; // ebx@14 + int v11; // edi@16 + signed int v12; // ST28_4@18 + signed __int64 v13; // qtt@18 + signed int result; // eax@21 + int v15; // [sp+10h] [bp-Ch]@10 + signed int v16; // [sp+18h] [bp-4h]@10 + + int a = 0, b = 0; + + if (IntersectPoint.x < pFace->pBounding.x1 || IntersectPoint.x > pFace->pBounding.x2 || + IntersectPoint.y < pFace->pBounding.y1 || IntersectPoint.y > pFace->pBounding.y2 || + IntersectPoint.z < pFace->pBounding.z1 || IntersectPoint.z > pFace->pBounding.z2 ) + return false; + + pFace->uAttributes |= 0x80000000; + + if (uModelID != -1) + ODM_CreateIntersectFacesVertexCoordList(&a, &b, intersect_face_vertex_coords_list_a, intersect_face_vertex_coords_list_b, + &IntersectPoint, pFace, uModelID); + else + BLV_CreateIntersectFacesVertexCoordList(&a, &b, intersect_face_vertex_coords_list_a, intersect_face_vertex_coords_list_b, + &IntersectPoint, pFace); + v5 = 2 * pFace->uNumVertices; + v16 = 0; + intersect_face_vertex_coords_list_a[v5] = intersect_face_vertex_coords_list_a[0]; + intersect_face_vertex_coords_list_b[v5] = intersect_face_vertex_coords_list_b[0]; + v6 = intersect_face_vertex_coords_list_b[0] >= b; + if (v5 <= 0) + return false; + for ( uint i = 0; i < v5; ++i ) + { + if ( v16 >= 2 ) + break; + if ( v6 ^ intersect_face_vertex_coords_list_b[i + 1] >= b ) + { + if ( intersect_face_vertex_coords_list_a[i + 1] >= a ) + v10 = 0; + else + v10 = 2; + v11 = v10 | intersect_face_vertex_coords_list_a[i] < a; + if ( v11 != 3 ) + { + if ( !v11 + || (v12 = intersect_face_vertex_coords_list_a[i + 1] - intersect_face_vertex_coords_list_a[i], + LODWORD(v13) = v12 << 16, + HIDWORD(v13) = v12 >> 16, + intersect_face_vertex_coords_list_a[i] + + ((signed int)(((unsigned __int64)(v13 / (intersect_face_vertex_coords_list_b[i + 1] - intersect_face_vertex_coords_list_b[i]) + * (signed int)((b - intersect_face_vertex_coords_list_b[i]) << 16)) >> 16) + 32768) >> 16) >= a) ) + ++v16; + } + } + v6 = intersect_face_vertex_coords_list_b[i + 1] >= b; + } + result = true; + if ( v16 != 1 ) + result = false; + return result; +}*/ +} + +//----- (004C1EE5) -------------------------------------------------------- +void Vis::BLV_CreateIntersectFacesVertexCoordList(int *a, int *b, __int16 *intersect_face_vertex_coords_list_a, + __int16 *intersect_face_vertex_coords_list_b, + Vec3_short_ *IntersectPoint, BLVFace *pFace) +{ + if (pFace->uAttributes & FACE_XY_PLANE) + { + *a = IntersectPoint->x; + *b = IntersectPoint->y; + + for (uint i = 0; i < pFace->uNumVertices; ++i) + { + intersect_face_vertex_coords_list_a[2 * i] = pFace->pXInterceptDisplacements[i] + pIndoor->pVertices[pFace->pVertexIDs[i]].x; + intersect_face_vertex_coords_list_a[2 * i + 1] = pFace->pXInterceptDisplacements[i + 1] + pIndoor->pVertices[pFace->pVertexIDs[i + 1]].x; + + intersect_face_vertex_coords_list_b[2 * i] = pFace->pYInterceptDisplacements[i] + pIndoor->pVertices[pFace->pVertexIDs[i]].y; + intersect_face_vertex_coords_list_b[2 * i + 1] = pFace->pYInterceptDisplacements[i + 1] + pIndoor->pVertices[pFace->pVertexIDs[i + 1]].y; + } + } + else if (pFace->uAttributes & FACE_XZ_PLANE) + { + *a = IntersectPoint->x; + *b = IntersectPoint->z; + + for (uint i = 0; i < pFace->uNumVertices; ++i) + { + intersect_face_vertex_coords_list_a[2 * i] = pFace->pXInterceptDisplacements[i] + pIndoor->pVertices[pFace->pVertexIDs[i]].x; + intersect_face_vertex_coords_list_a[2 * i + 1] = pFace->pXInterceptDisplacements[i + 1] + pIndoor->pVertices[pFace->pVertexIDs[i + 1]].x; + + intersect_face_vertex_coords_list_b[2 * i] = pFace->pZInterceptDisplacements[i] + pIndoor->pVertices[pFace->pVertexIDs[i]].z; + intersect_face_vertex_coords_list_b[2 * i + 1] = pFace->pZInterceptDisplacements[i + 1] + pIndoor->pVertices[pFace->pVertexIDs[i + 1]].z; + } + } + else if (pFace->uAttributes & FACE_YZ_PLANE) + { + *a = IntersectPoint->y; + *b = IntersectPoint->z; + + for (uint i = 0; i < pFace->uNumVertices; ++i) + { + intersect_face_vertex_coords_list_a[2 * i] = pFace->pYInterceptDisplacements[i] + pIndoor->pVertices[pFace->pVertexIDs[i]].y; + intersect_face_vertex_coords_list_a[2 * i + 1] = pFace->pYInterceptDisplacements[i + 1] + pIndoor->pVertices[pFace->pVertexIDs[i + 1]].y; + + intersect_face_vertex_coords_list_b[2 * i] = pFace->pZInterceptDisplacements[i] + pIndoor->pVertices[pFace->pVertexIDs[i]].z; + intersect_face_vertex_coords_list_b[2 * i + 1] = pFace->pZInterceptDisplacements[i + 1] + pIndoor->pVertices[pFace->pVertexIDs[i + 1]].z; + } + } + else assert(false); +} + +//----- (004C2186) -------------------------------------------------------- +void Vis::ODM_CreateIntersectFacesVertexCoordList(int *a, int *b, __int16 *intersect_face_vertex_coords_list_a, + __int16 *intersect_face_vertex_coords_list_b, + Vec3_short_ *IntersectPoint, BLVFace *pFace, unsigned int uModelID) +{ + if (pFace->uAttributes & FACE_XY_PLANE) + { + *a = IntersectPoint->x; + *b = IntersectPoint->y; + + for (int i = 0; i < pFace->uNumVertices; ++i) + { + intersect_face_vertex_coords_list_a[2 * i] = pFace->pXInterceptDisplacements[i] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i]].x; + intersect_face_vertex_coords_list_a[i * 2 + 1] = pFace->pXInterceptDisplacements[i + 1] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i + 1]].x; + + intersect_face_vertex_coords_list_b[2 * i] = pFace->pYInterceptDisplacements[i] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i]].y; + intersect_face_vertex_coords_list_b[i * 2 + 1] = pFace->pYInterceptDisplacements[i + 1] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i + 1]].y; + } + } + else if (pFace->uAttributes & FACE_XZ_PLANE) + { + *a = IntersectPoint->x; + *b = IntersectPoint->z; + + for (int i = 0; i < pFace->uNumVertices; ++i) + { + intersect_face_vertex_coords_list_a[2 * i] = pFace->pXInterceptDisplacements[i] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i]].x; + intersect_face_vertex_coords_list_a[i * 2 + 1] = pFace->pXInterceptDisplacements[i + 1] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i + 1]].x; + + intersect_face_vertex_coords_list_b[2 * i] = pFace->pZInterceptDisplacements[i] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i]].z; + intersect_face_vertex_coords_list_b[i * 2 + 1] = pFace->pZInterceptDisplacements[i + 1] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i + 1]].z; + } + } + else if (pFace->uAttributes & FACE_YZ_PLANE) + { + *a = IntersectPoint->y; + *b = IntersectPoint->z; + + for (int i = 0; i < pFace->uNumVertices; ++i) + { + intersect_face_vertex_coords_list_a[2 * i] = pFace->pYInterceptDisplacements[i] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i]].y; + intersect_face_vertex_coords_list_a[i * 2 + 1] = pFace->pYInterceptDisplacements[i + 1] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i + 1]].y; + + intersect_face_vertex_coords_list_b[2 * i] = pFace->pZInterceptDisplacements[i] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i]].z; + intersect_face_vertex_coords_list_b[i * 2 + 1] = pFace->pZInterceptDisplacements[i + 1] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i + 1]].z; + } + } + else assert(false); +} + +//----- (0046A0A1) -------------------------------------------------------- +int UnprojectX(int x) +{ + int v3; // [sp-4h] [bp-8h]@5 + + if ( uCurrentlyLoadedLevelType == LEVEL_Indoor ) + { + //if ( pRenderer->pRenderD3D ) + v3 = pGame->pIndoorCameraD3D->fov; + //else + // v3 = pIndoorCamera->fov_rad; + } + else + { + v3 = pODMRenderParams->int_fov_rad; + } + return stru_5C6E00->Atan2(x - pViewport->uScreenCenterX, v3) - stru_5C6E00->uIntegerHalfPi; +} + +//----- (0046A0F6) -------------------------------------------------------- +int UnprojectY(int y) +{ + int v3; // [sp-4h] [bp-8h]@5 + + if ( uCurrentlyLoadedLevelType == LEVEL_Indoor ) + { + //if ( pRenderer->pRenderD3D ) + v3 = pGame->pIndoorCameraD3D->fov; + //else + // v3 = pIndoorCamera->fov_rad; + } + else + { + v3 = pODMRenderParams->int_fov_rad; + } + return stru_5C6E00->Atan2(y - pViewport->uScreenCenterY, v3) - stru_5C6E00->uIntegerHalfPi; +} + +//----- (004C248E) -------------------------------------------------------- +void Vis::CastPickRay(RenderVertexSoft *pRay, float fMouseX, float fMouseY, float fPickDepth) +{ + int pRotY; // esi@1 + Vec3_int_ pStartR; // ST08_12@1 + int pRotX; // ST04_4@1 + int pDepth; // eax@1 + RenderVertexSoft v11[2]; // [sp+2Ch] [bp-74h]@1 + int outx; + int outz; // [sp+94h] [bp-Ch]@1 + int outy; // [sp+98h] [bp-8h]@1 + + pRotY = pGame->pIndoorCameraD3D->sRotationY + UnprojectX(fMouseX); + pRotX = pGame->pIndoorCameraD3D->sRotationX + UnprojectY(fMouseY); + + pStartR.z = pGame->pIndoorCameraD3D->vPartyPos.z; + pStartR.x = pGame->pIndoorCameraD3D->vPartyPos.x; + pStartR.y = pGame->pIndoorCameraD3D->vPartyPos.y; + + v11[1].vWorldPosition.x = (double)pGame->pIndoorCameraD3D->vPartyPos.x; + v11[1].vWorldPosition.y = (double)pGame->pIndoorCameraD3D->vPartyPos.y; + v11[1].vWorldPosition.z = (double)pGame->pIndoorCameraD3D->vPartyPos.z; + + pDepth = fixpoint_from_float(fPickDepth); + Vec3_int_::Rotate(pDepth, pRotY, pRotX, pStartR, &outx, &outy, &outz); + + v11[0].vWorldPosition.x = (double)outx; + v11[0].vWorldPosition.y = (double)outy; + v11[0].vWorldPosition.z = (double)outz; + + memcpy(pRay + 0, &v11[1], sizeof(RenderVertexSoft)); + memcpy(pRay + 1, &v11[0], sizeof(RenderVertexSoft)); +} + +//----- (004C2551) -------------------------------------------------------- +Vis_ObjectInfo *Vis_SelectionList::SelectionPointers(int pVisObjectType, int pid) +{ + //unsigned int v3; // esi@1 + //signed int v4; // edx@1 + //char *v5; // eax@2 + //Vis_ObjectInfo *result; // eax@6 + + //v3 = this->uNumPointers; + if ( this->uNumPointers > 0 ) + { + for ( uint i = 0; i < this->uNumPointers; ++i ) + { + if ( this->object_pool[i].object_type == pVisObjectType && (this->object_pool[i].sZValue & 0xFFFF) == pid ) + return &this->object_pool[i]; + } + } + return nullptr; + /*v4 = 0; + if ( this->uNumPointers <= 0 ) + return false; + else + { + //v5 = (char *)&this->object_pool[0].sZValue; + while ( this->object_pool[v4].object_type != a2 || (this->object_pool[v4].sZValue & 0xFFFF) != a3 ) + { + ++v4; + //v5 += 12; + if ( v4 >= this->uNumPointers ) + return false; + } + result = &this->object_pool[v4]; + } + return result;*/ +} + +//----- (004C2591) -------------------------------------------------------- +void Vis_SelectionList::create_object_pointers(PointerCreationType type) +{ + switch (type) + { + case All: + { + for (uint i = 0; i < uNumPointers; ++i) + object_pointers[i] = &object_pool[i]; + } + break; + + case Unique: // seems quite retarted; the inner if condition will never trigger, since we compare pointers, not values. pointers will always be unique + { // but it may be decompilation error thou + bool create = true; + + for (uint i = 0; i < uNumPointers; ++i) + { + for (uint j = 0; j < i; ++j) + { + if (object_pointers[j] == &object_pool[i]) + { + create = false; + break; + } + } + + if (create) + object_pointers[i] = &object_pool[i]; + } + } + break; + + default: + MessageBoxW(nullptr, L"Unknown pointer creation flag passed to ::create_object_pointers()", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Vis.cpp:1358", 0); + } +} + +//----- (004C264A) -------------------------------------------------------- +void Vis::sort_object_pointers( Vis_ObjectInfo **pPointers, int start, int end )//сортировка +{ + int sort_start; // edx@1 + int forward_sort_index; // esi@2 + signed int backward_sort_index; // ecx@2 + unsigned int last_z_val; // eax@3 + unsigned int more_lz_val; // ebx@4 + unsigned int less_lz_val; // ebx@6 + Vis_ObjectInfo *temp_pointer; // eax@7 +// Vis_ObjectInfo *a3a; // [sp+14h] [bp+Ch]@2 + + sort_start = start; + + if ( end > start ) + { + do + { + forward_sort_index = sort_start - 1; + backward_sort_index = end; + do + { + last_z_val = pPointers[end]->sZValue & 0xFFFF0000; + do + { + ++forward_sort_index; + more_lz_val = pPointers[forward_sort_index]->sZValue & 0xFFFF0000; + } + while ( more_lz_val < last_z_val ); + + do + { + if ( backward_sort_index < 1 ) + break; + --backward_sort_index; + less_lz_val = pPointers[backward_sort_index]->sZValue & 0xFFFF0000; + } + while ( less_lz_val > last_z_val ); + + temp_pointer = pPointers[forward_sort_index]; + if ( forward_sort_index >= backward_sort_index ) + { + pPointers[forward_sort_index] = pPointers[end]; + pPointers[end] = temp_pointer; + } + else + { + pPointers[forward_sort_index] = pPointers[backward_sort_index]; + pPointers[backward_sort_index] = temp_pointer; + } + + } while ( forward_sort_index < backward_sort_index ); + + sort_object_pointers(pPointers, sort_start, forward_sort_index - 1); + sort_start = forward_sort_index + 1; + } + while ( end > forward_sort_index + 1 ); + } +} + +//----- (004C26D0) -------------------------------------------------------- +void Vis::SortVerticesByX(RenderVertexD3D3 *pArray, unsigned int uStart, unsigned int uEnd) +{ + unsigned int left_sort_index; // ebx@2 + RenderVertexD3D3 temp_array; // [sp+4h] [bp-4Ch]@8 + RenderVertexD3D3 max_array; // [sp+24h] [bp-2Ch]@2 + unsigned int right_sort_index; // [sp+4Ch] [bp-4h]@2 + + if ( (signed int)uEnd > (signed int)uStart ) + { + left_sort_index = uStart - 1; + right_sort_index = uEnd; + while ( 1 ) + { + memcpy(&max_array, &pArray[uEnd], sizeof(max_array)); + do + { + ++left_sort_index; + } + while ( pArray[left_sort_index].pos.x < (double)max_array.pos.x ); + do + { + --right_sort_index; + } + while ( pArray[right_sort_index].pos.x > (double)max_array.pos.x ); + if ( (signed int)left_sort_index >= (signed int)right_sort_index ) + break; + memcpy(&temp_array, &pArray[left_sort_index], sizeof(temp_array)); + memcpy(&pArray[left_sort_index], &pArray[right_sort_index], sizeof(pArray[left_sort_index])); + memcpy(&pArray[right_sort_index], &temp_array, sizeof(pArray[right_sort_index])); + } + memcpy(&temp_array, &pArray[left_sort_index], sizeof(temp_array)); + memcpy(&pArray[left_sort_index], &pArray[uEnd], sizeof(pArray[left_sort_index])); + memcpy(&pArray[uEnd], &temp_array, sizeof(pArray[uEnd])); + SortVerticesByX(pArray, uStart, left_sort_index - 1); + SortVerticesByX(pArray, left_sort_index + 1, uEnd); + } +} + +//----- (004C27AD) -------------------------------------------------------- +void Vis::SortVerticesByY(RenderVertexD3D3 *pArray, unsigned int uStart, unsigned int uEnd) +{ + unsigned int left_sort_index; // ebx@2 + RenderVertexD3D3 temp_array; // [sp+4h] [bp-4Ch]@8 + RenderVertexD3D3 max_array; // [sp+24h] [bp-2Ch]@2 + unsigned int right_sort_index; // [sp+4Ch] [bp-4h]@2 + + if ( (signed int)uEnd > (signed int)uStart ) + { + left_sort_index = uStart - 1; + right_sort_index = uEnd; + while ( 1 ) + { + memcpy(&max_array, &pArray[uEnd], sizeof(max_array)); + do + { + ++left_sort_index; + } + while ( pArray[left_sort_index].pos.y < (double)max_array.pos.y ); + do + { + --right_sort_index; + } + while ( pArray[right_sort_index].pos.y > (double)max_array.pos.y ); + if ( (signed int)left_sort_index >= (signed int)right_sort_index ) + break; + memcpy(&temp_array, &pArray[left_sort_index], sizeof(temp_array)); + memcpy(&pArray[left_sort_index], &pArray[right_sort_index], sizeof(pArray[left_sort_index])); + memcpy(&pArray[right_sort_index], &temp_array, sizeof(pArray[right_sort_index])); + } + memcpy(&temp_array, &pArray[left_sort_index], sizeof(temp_array)); + memcpy(&pArray[left_sort_index], &pArray[uEnd], sizeof(pArray[left_sort_index])); + memcpy(&pArray[uEnd], &temp_array, sizeof(pArray[uEnd])); + SortVerticesByY(pArray, uStart, left_sort_index - 1); + SortVerticesByY(pArray, left_sort_index + 1, uEnd); + } +} + +//----- (004C288E) -------------------------------------------------------- +void Vis::SortByScreenSpaceX(RenderVertexSoft *pArray, int start, int end)//сортировка по возрастанию экранных координат х +{ + int left_sort_index; // ebx@2 + int right_sort_index; // ecx@2 + RenderVertexSoft temp_array; // [sp+4h] [bp-6Ch]@8 + RenderVertexSoft max_array; // [sp+34h] [bp-3Ch]@2 + + if ( end > start ) + { + left_sort_index = start - 1; + right_sort_index = end; + memcpy(&max_array, &pArray[end], sizeof(max_array)); + while ( 1 ) + { + do + { + ++left_sort_index; + } + while ( pArray[left_sort_index].vWorldViewProjX < (double)max_array.vWorldViewProjX ); + do + { + --right_sort_index; + } + while ( pArray[right_sort_index].vWorldViewProjX > (double)max_array.vWorldViewProjX ); + if ( left_sort_index >= right_sort_index ) + break; + memcpy(&temp_array, &pArray[left_sort_index], sizeof(temp_array)); + memcpy(&pArray[left_sort_index], &pArray[right_sort_index], sizeof(pArray[left_sort_index])); + memcpy(&pArray[right_sort_index], &temp_array, sizeof(pArray[right_sort_index])); + } + memcpy(&temp_array, &pArray[left_sort_index], sizeof(temp_array)); + memcpy(&pArray[left_sort_index], &pArray[end], sizeof(pArray[left_sort_index])); + memcpy(&pArray[end], &temp_array, sizeof(pArray[end])); + Vis::SortByScreenSpaceX(pArray, start, left_sort_index - 1); + Vis::SortByScreenSpaceX(pArray, left_sort_index + 1, end); + } +} + +//----- (004C297E) -------------------------------------------------------- +void Vis::SortByScreenSpaceY(RenderVertexSoft *pArray, int start, int end) +{ + int left_sort_index; // ebx@2 + int right_sort_index; // ecx@2 + RenderVertexSoft temp_array; // [sp+4h] [bp-6Ch]@8 + RenderVertexSoft max_array; // [sp+34h] [bp-3Ch]@2 + + if ( end > start ) + { + left_sort_index = start - 1; + right_sort_index = end; + memcpy(&max_array, &pArray[end], sizeof(max_array)); + while ( 1 ) + { + do + { + ++left_sort_index; + } + while ( pArray[left_sort_index].vWorldViewProjY < (double)max_array.vWorldViewProjY ); + do + { + --right_sort_index; + } + while ( pArray[right_sort_index].vWorldViewProjY > (double)max_array.vWorldViewProjY ); + if ( left_sort_index >= right_sort_index ) + break; + memcpy(&temp_array, &pArray[left_sort_index], sizeof(temp_array)); + memcpy(&pArray[left_sort_index], &pArray[right_sort_index], sizeof(pArray[left_sort_index])); + memcpy(&pArray[right_sort_index], &temp_array, sizeof(pArray[right_sort_index])); + } + memcpy(&temp_array, &pArray[left_sort_index], sizeof(temp_array)); + memcpy(&pArray[left_sort_index], &pArray[end], sizeof(pArray[left_sort_index])); + memcpy(&pArray[end], &temp_array, sizeof(pArray[end])); + Vis::SortByScreenSpaceY(pArray, start, left_sort_index - 1); + Vis::SortByScreenSpaceY(pArray, left_sort_index + 1, end); + } +} + +//----- (004C04AF) -------------------------------------------------------- +Vis::Vis() +{ + RenderVertexSoft v3; // [sp+Ch] [bp-60h]@1 + RenderVertexSoft v4; // [sp+3Ch] [bp-30h]@1 + + v3.flt_2C = 0.0; + v3.vWorldPosition.x = 0.0; + v3.vWorldPosition.y = 65536.0; + v3.vWorldPosition.z = 0.0; + v4.flt_2C = 0.0; + v4.vWorldPosition.x = 65536.0; + v4.vWorldPosition.y = 0.0; + v4.vWorldPosition.z = 0.0; + memcpy(&stru_200C, &v4, sizeof(stru_200C)); + + v4.flt_2C = 0.0; + v4.vWorldPosition.x = 0.0; + v4.vWorldPosition.y = 65536.0; + v4.vWorldPosition.z = 0.0; + memcpy(&stru_203C, &v3, sizeof(stru_203C)); + + v3.flt_2C = 0.0; + v3.vWorldPosition.x = 65536.0; + v3.vWorldPosition.y = 0.0; + v3.vWorldPosition.z = 0.0; + memcpy(&stru_206C, &v3, sizeof(stru_206C)); + memcpy(&stru_209C, &v4, sizeof(stru_209C)); + + keyboard_pick_depth = 512; +} + +//----- (004C055C) -------------------------------------------------------- +Vis_SelectionList::Vis_SelectionList() +{ + for (uint i = 0; i < 512; ++i) + { + object_pool[i].object = nullptr; + object_pool[i].sZValue = -1; + object_pool[i].object_type = VisObjectType_Any; + } + uNumPointers = 0; +} + +//----- (004C05CC) -------------------------------------------------------- +bool Vis::PickKeyboard(Vis_SelectionList *list, Vis_SelectionFilter *sprite_filter, Vis_SelectionFilter *face_filter) +{ + if (!list) + list = &default_list; + list->uNumPointers = 0; + + PickBillboards_Keyboard(keyboard_pick_depth, list, sprite_filter); + if (uCurrentlyLoadedLevelType == LEVEL_Indoor) + PickIndoorFaces_Keyboard(keyboard_pick_depth, list, face_filter); + else if (uCurrentlyLoadedLevelType == LEVEL_Outdoor) + PickOutdoorFaces_Keyboard(keyboard_pick_depth, list, face_filter); + else + assert(false); + + list->create_object_pointers(Vis_SelectionList::Unique); + sort_object_pointers(list->object_pointers, 0, list->uNumPointers - 1); + + return true; +} + +//----- (004C0646) -------------------------------------------------------- +bool Vis::PickMouse(float fDepth, float fMouseX, float fMouseY, Vis_SelectionFilter *sprite_filter, Vis_SelectionFilter *face_filter) +{ + RenderVertexSoft pMouseRay[2]; // [sp+1Ch] [bp-60h]@1 + + default_list.uNumPointers = 0; + CastPickRay(pMouseRay, fMouseX, fMouseY, fDepth); + PickBillboards_Mouse(fDepth, fMouseX, fMouseY, &default_list, sprite_filter); + if (uCurrentlyLoadedLevelType == LEVEL_Indoor) + PickIndoorFaces_Mouse(fDepth, pMouseRay, &default_list, face_filter); + else if (uCurrentlyLoadedLevelType == LEVEL_Outdoor) + PickOutdoorFaces_Mouse(fDepth, pMouseRay, &default_list, face_filter, false); + else + { + Log::Warning(L"Picking mouse in undefined level"); // picking in main menu is default (buggy) game behaviour. should've returned false in Game::PickMouse + return false; + } + default_list.create_object_pointers(Vis_SelectionList::All); + sort_object_pointers(default_list.object_pointers, 0, default_list.uNumPointers - 1); + + return true; +} + +//----- (004C06F8) -------------------------------------------------------- +void Vis::PickBillboards_Keyboard(float pick_depth, Vis_SelectionList *list, Vis_SelectionFilter *filter) +{ + for (uint i = 0; i < pRenderer->uNumBillboardsToDraw; ++i) + { + RenderBillboardD3D* d3d_billboard = &pRenderer->pBillboardRenderListD3D[i]; + + if (is_part_of_selection((void *)i, filter)) + { + if (DoesRayIntersectBillboard(pick_depth, i)) + { + RenderBillboard* billboard = &pBillboardRenderList[d3d_billboard->sParentBillboardID]; + + list->AddObject((void *)d3d_billboard->sParentBillboardID, VisObjectType_Sprite, billboard->sZValue); + } + } + } +} + + +// tests the object against selection filter to determine whether it can be picked or not +//----- (004C0791) -------------------------------------------------------- +bool Vis::is_part_of_selection(void *uD3DBillboardIdx_or_pBLVFace_or_pODMFace, Vis_SelectionFilter *filter) +{ + //stru157 *v3; // esi@1 + //int result; // eax@1 + //int v5; // edx@2 + //int v6; // ecx@2 + //char v7; // zf@3 + //int v8; // esi@5 +// std::string *v9; // ecx@7 + //Actor *v10; // edi@18 + //const char *v12; // [sp-20h] [bp-2Ch]@7 +// int v13; // [sp-1Ch] [bp-28h]@7 + //std::string v14; // [sp-18h] [bp-24h]@7 + //const char *v15; // [sp-8h] [bp-14h]@7 +// int v16; // [sp-4h] [bp-10h]@7 + + switch (filter->object_type) + { + case VisObjectType_Any: + return true; + + case VisObjectType_Sprite: + { + //v5 = filter->select_flags; + int object_idx = PID_ID(pBillboardRenderList[pRenderer->pBillboardRenderListD3D[(int)uD3DBillboardIdx_or_pBLVFace_or_pODMFace].sParentBillboardID].object_pid); + int object_type = PID_TYPE(pBillboardRenderList[pRenderer->pBillboardRenderListD3D[(int)uD3DBillboardIdx_or_pBLVFace_or_pODMFace].sParentBillboardID].object_pid); + if ( filter->select_flags & 2 ) + { + if (object_type == filter->object_id) + return false; + return true; + } + if ( filter->select_flags & 4 ) + { + //v8 = filter->object_id; + if ( object_type != filter->object_id) + return true; + if (filter->object_id != OBJECT_Decoration) + { + MessageBoxA(nullptr, "Unsupported \"exclusion if no event\" type in CVis::is_part_of_selection", "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Vis.cpp:207", 0); + return true; + } + if (pLevelDecorations[object_idx].uCog || pLevelDecorations[object_idx].uEventID) + return true; + return pLevelDecorations[object_idx].IsInteractive(); + } + if (object_type == filter->object_id) + { + if (object_type != OBJECT_Actor) + { + MessageBoxA(nullptr, "Default case reached in VIS", "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Vis.cpp:245", 0); + return true; + } + + //v10 = &pActors[object_idx]; + int result = 1 << LOBYTE(pActors[object_idx].uAIState); + if ( result & filter->no_at_ai_state + || !(result & filter->at_ai_state) + || filter->select_flags & 8 && (result = MonsterStats::BelongsToSupertype(pActors[object_idx].pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD)) == 0 ) + return false; + if ( !(filter->select_flags & 1) ) + return true; + + result = pActors[object_idx].GetActorsRelation(nullptr); + if (result == 0) + return false; + return true; + } + return false; + } + + case VisObjectType_Face: + { + uint face_attrib = 0; + bool no_event = true; + if (uCurrentlyLoadedLevelType == LEVEL_Outdoor) + { + ODMFace* face = (ODMFace *)uD3DBillboardIdx_or_pBLVFace_or_pODMFace; + no_event = face->sCogTriggeredID == 0; + face_attrib = face->uAttributes; + } + else if (uCurrentlyLoadedLevelType == LEVEL_Indoor) + { + BLVFace* face = (BLVFace *)uD3DBillboardIdx_or_pBLVFace_or_pODMFace; + no_event = pIndoor->pFaceExtras[face->uFaceExtraID].uEventID == 0; + face_attrib = face->uAttributes; + } + else + assert(false); + + if (filter->object_id != OBJECT_BLVDoor) + return true; + if (no_event || face_attrib & filter->no_at_ai_state)//face_attrib = 0x2009408 incorrect + return false; + return (face_attrib & filter->at_ai_state) != 0; + } + + default: + assert(false); + } +} + +//----- (004C091D) -------------------------------------------------------- +bool Vis::DoesRayIntersectBillboard(float fDepth, unsigned int uD3DBillboardIdx) +{ + int v3; // eax@3 + //signed int v5; // ecx@4 + //float v6; // ST04_4@6 + //float v7; // ST00_4@7 + //int v8; // eax@10 + //unsigned int v9; // eax@12 +// int v10; // eax@17 +// double v11; // st6@18 +// double v12; // st7@18 +// double v13; // st4@18 +// float v14; // ST0C_4@22 +// float v15; // ST08_4@22 + //float v16; // ST04_4@23 + //float v17; // ST00_4@24 + //signed int v18; // eax@27 + //unsigned int v19; // eax@29 +// double v20; // st6@32 +// double v21; // st7@32 +// int v22; // eax@32 +// double v23; // st7@36 + //void *v24; // esi@40 +// float v25; // ST08_4@40 + //float v26; // ST04_4@41 + //float v27; // ST00_4@42 +// int v28; // eax@45 +// unsigned int v29; // eax@47 +// char result; // al@48 + struct RenderVertexSoft pPickingRay[2]; + //int v31; // [sp+20h] [bp-DCh]@5 + struct RenderVertexSoft local_80[2]; + + float test_x; + float test_y; + + float t1_x; + float t1_y; + float t2_x; + float t2_y; + float swap_temp; +// int v37; // [sp+F0h] [bp-Ch]@5 + + signed int v40; // [sp+108h] [bp+Ch]@17 + + + static Vis_SelectionList Vis_static_stru_F91E10; + Vis_static_stru_F91E10.uNumPointers = 0; + v3 = pRenderer->pBillboardRenderListD3D[uD3DBillboardIdx].sParentBillboardID; + if (v3 == -1) + return false; + + if (pBillboardRenderList[v3].GetFloatZ() > fDepth) + return false; + + + GetPolygonCenter(pRenderer->pBillboardRenderListD3D[v3].pQuads, 4, &test_x, &test_y); + CastPickRay(pPickingRay, test_x, test_y, fDepth); + if (uCurrentlyLoadedLevelType == LEVEL_Indoor) + PickIndoorFaces_Mouse(fDepth, pPickingRay, &Vis_static_stru_F91E10, &vis_face_filter); + else + PickOutdoorFaces_Mouse(fDepth, pPickingRay, &Vis_static_stru_F91E10, &vis_face_filter, false); + Vis_static_stru_F91E10.create_object_pointers(); + sort_object_pointers(Vis_static_stru_F91E10.object_pointers, 0, Vis_static_stru_F91E10.uNumPointers - 1); + if (Vis_static_stru_F91E10.uNumPointers) + { + if (Vis_static_stru_F91E10.object_pointers[0]->actual_z > pBillboardRenderList[v3].actual_z) + return true; + } + else if ((double)(pViewport->uScreen_TL_X) <= test_x && + (double)pViewport->uScreen_BR_X >= test_x && + (double)pViewport->uScreen_TL_Y <= test_y && + (double)pViewport->uScreen_BR_Y >= test_y) + return true; + + for (v40 = 0; v40 < 4; ++v40) + { + test_x=pRenderer->pBillboardRenderListD3D[uD3DBillboardIdx].pQuads[v40].pos.x; + test_y= pRenderer->pBillboardRenderListD3D[uD3DBillboardIdx].pQuads[v40].pos.y; + if ((double)(pViewport->uScreen_TL_X) <= test_x && + (double)pViewport->uScreen_BR_X >= test_x && + (double)pViewport->uScreen_TL_Y <= test_y && + (double)pViewport->uScreen_BR_Y >= test_y) + { + CastPickRay(local_80, test_x, test_y, fDepth); + if ( uCurrentlyLoadedLevelType == LEVEL_Indoor ) + PickIndoorFaces_Mouse(fDepth, local_80, &Vis_static_stru_F91E10, &vis_face_filter); + else + PickOutdoorFaces_Mouse(fDepth, local_80, &Vis_static_stru_F91E10, &vis_face_filter, false); + Vis_static_stru_F91E10.create_object_pointers(); + sort_object_pointers(Vis_static_stru_F91E10.object_pointers, 0, Vis_static_stru_F91E10.uNumPointers - 1); + if ( !Vis_static_stru_F91E10.uNumPointers ) + return true; + if (Vis_static_stru_F91E10.object_pointers[0]->actual_z > pBillboardRenderList[v3].actual_z) + return true; + } + + } + + if ( v40 >= 4 ) + { + if ( uCurrentlyLoadedLevelType != LEVEL_Outdoor ) + return false; + t1_x = pRenderer->pBillboardRenderListD3D[uD3DBillboardIdx].pQuads[0].pos.x; + t2_x = pRenderer->pBillboardRenderListD3D[uD3DBillboardIdx].pQuads[3].pos.x; + + t1_y = pRenderer->pBillboardRenderListD3D[uD3DBillboardIdx].pQuads[0].pos.y; + t2_y = pRenderer->pBillboardRenderListD3D[uD3DBillboardIdx].pQuads[1].pos.y; + if ( t1_x > t2_x ) + { + swap_temp = t1_x; + t1_x = t2_x; + t2_x = swap_temp; + } + if ( t1_y > t2_y ) + test_y = t1_y; + else + test_y = t2_y; + + Vis_static_stru_F91E10.uNumPointers = 0; + + test_x = (t2_x - t1_x) * 0.5; + if ((double)(pViewport->uScreen_TL_X) <= test_x && + (double)pViewport->uScreen_BR_X >= test_x && + (double)pViewport->uScreen_TL_Y <= test_y && + (double)pViewport->uScreen_BR_Y >= test_y) + { + CastPickRay(local_80, test_x, test_y, fDepth); + if ( uCurrentlyLoadedLevelType == LEVEL_Indoor ) + PickIndoorFaces_Mouse(fDepth, local_80, &Vis_static_stru_F91E10, &vis_face_filter); + else + PickOutdoorFaces_Mouse(fDepth, local_80, &Vis_static_stru_F91E10, &vis_face_filter, false); + Vis_static_stru_F91E10.create_object_pointers(); + sort_object_pointers(Vis_static_stru_F91E10.object_pointers, 0, Vis_static_stru_F91E10.uNumPointers - 1); + if ( !Vis_static_stru_F91E10.uNumPointers ) + return true; + if (Vis_static_stru_F91E10.object_pointers[0]->actual_z > pBillboardRenderList[v3].actual_z) + return true; + + } + + } + return false; +} +// F93E18: using guessed type char static_byte_F93E18_init; + +//----- (004C0D32) -------------------------------------------------------- +void Vis::PickIndoorFaces_Keyboard(float pick_depth, Vis_SelectionList *list, Vis_SelectionFilter *filter) +{ + int result; // eax@1 + signed int pFaceID; // esi@2 + BLVFace *pFace; // edi@4 + //unsigned int v7; // eax@6 + Vis_ObjectInfo *v8; // eax@6 + signed int i; // [sp+18h] [bp-8h]@1 + + result = 0; + for ( i = 0; i < (signed int)pBspRenderer->num_faces; ++i ) + { + pFaceID = pBspRenderer->faces[result].uFaceID; + if ( pFaceID >= 0 ) + { + if ( pFaceID < (signed int)pIndoor->uNumFaces ) + { + pFace = &pIndoor->pFaces[pFaceID]; + if ( !pGame->pIndoorCameraD3D->IsCulled(&pIndoor->pFaces[pFaceID]) ) + { + if ( is_part_of_selection(pFace, filter) ) + { + v8 = DetermineFacetIntersection(pFace, PID(OBJECT_BModel, pFaceID), pick_depth); + if ( v8 ) + list->AddObject(v8->object, v8->object_type, v8->sZValue); + } + } + } + } + result = i + 1; + } +} + +//----- (004C0DEA) -------------------------------------------------------- +void Vis::PickOutdoorFaces_Keyboard(float pick_depth, Vis_SelectionList *list, Vis_SelectionFilter *filter) +{ + for (int i = 0; i < pOutdoor->uNumBModels; ++i) + { + int v17; + if (!IsBModelVisible(i, &v17)) + continue; + if (!v17) + continue; + + BSPModel* bmodel = &pOutdoor->pBModels[i]; + for (int j = 0; j < bmodel->uNumFaces; ++j) + { + //ODMFace* face = &bmodel->pFaces[j]; + + if (is_part_of_selection(&bmodel->pFaces[j], filter) ) + { + BLVFace blv_face; + blv_face.FromODM(&bmodel->pFaces[j]); + + int pid = PID(OBJECT_BModel, j | (i << 6)); + if (Vis_ObjectInfo* object_info = DetermineFacetIntersection(&blv_face, pid, pick_depth)) + list->AddObject(object_info->object, object_info->object_type, object_info->sZValue); + } + } + } +} \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/Vis.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/Vis.h Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,133 @@ +#pragma once +#include "Render.h" + + + +enum VisObjectType: unsigned __int32 +{ + VisObjectType_Any = 0, + VisObjectType_Sprite = 1, + VisObjectType_Face = 2 +}; + +/* 150 */ +#pragma pack(push, 1) +struct Vis_SelectionFilter //stru157 +{ + VisObjectType object_type; + int object_id; // OBJECT_Actor, OBJECT_Player etc + int at_ai_state; + int no_at_ai_state; + int select_flags; +}; +#pragma pack(pop) +extern Vis_SelectionFilter vis_sprite_filter_1; // 00F93E1C +extern Vis_SelectionFilter vis_sprite_filter_2; // 00F93E30 +extern Vis_SelectionFilter vis_face_filter; // 00F93E44 +extern Vis_SelectionFilter vis_door_filter; // 00F93E58 +extern Vis_SelectionFilter vis_sprite_filter_3; // 00F93E6C +extern Vis_SelectionFilter vis_sprite_filter_4; // static to sub_44EEA7 + + + +#pragma pack(push, 1) +struct Vis_ObjectInfo +{ + void *object; + union + { + int sZValue; + struct + { + unsigned __int16 object_pid; + signed __int16 actual_z; + }; + }; + VisObjectType object_type; +}; +#pragma pack(pop) + + +#pragma pack(push, 1) +struct Vis_SelectionList +{ + enum PointerCreationType + { + All = 0, + Unique = 1 + }; + + Vis_SelectionList(); + //----- (004C0585) -------------------------------------------------------- + ~Vis_SelectionList() {} + Vis_ObjectInfo *SelectionPointers(int a2, int a3); + void create_object_pointers(PointerCreationType type = All); + + inline void AddObject(void *object, VisObjectType type, int packed_zval) + { + object_pool[uNumPointers].object = object; + object_pool[uNumPointers].object_type = type; + object_pool[uNumPointers++].sZValue = packed_zval; + } + + void ( ***vdestructor_ptr)(Vis_SelectionList *, bool); + Vis_ObjectInfo object_pool[512]; + Vis_ObjectInfo *object_pointers[512]; + unsigned int uNumPointers; +}; +#pragma pack(pop) + + + +/* 116 */ +#pragma pack(push, 1) +class Vis +{ +public: + Vis(); + //----- (004C05A2) -------------------------------------------------------- + //virtual ~Vis() {} + //----- (004C05BE) -------------------------------------------------------- + virtual ~Vis() {} + bool PickKeyboard(Vis_SelectionList *list, Vis_SelectionFilter *sprite_filter, Vis_SelectionFilter *face_filter); + void PickBillboards_Keyboard(float pick_depth, Vis_SelectionList *list, Vis_SelectionFilter *filter); + void PickIndoorFaces_Keyboard(float pick_depth, Vis_SelectionList *list, Vis_SelectionFilter *filter); + void PickOutdoorFaces_Keyboard(float pick_depth, Vis_SelectionList *list, Vis_SelectionFilter *filter); + + bool PickMouse(float fDepth, float fMouseX, float fMouseY, Vis_SelectionFilter *sprite_filter, Vis_SelectionFilter *face_filter); + void PickBillboards_Mouse(float fPickDepth, float fX, float fY, Vis_SelectionList *list, Vis_SelectionFilter *filter); + void PickIndoorFaces_Mouse(float fDepth, struct RenderVertexSoft *pRay, Vis_SelectionList *list, Vis_SelectionFilter *filter); + void PickOutdoorFaces_Mouse(float fDepth, struct RenderVertexSoft *pRay, Vis_SelectionList *list, Vis_SelectionFilter *filter, bool only_reachable); + + bool is_part_of_selection(void *uD3DBillboardIdx_or_pBLVFace_or_pODMFace, Vis_SelectionFilter *filter); + bool DoesRayIntersectBillboard(float fDepth, unsigned int uD3DBillboardIdx); + Vis_ObjectInfo *DetermineFacetIntersection(struct BLVFace *face, unsigned int a3, float pick_depth); + bool IsPolygonOccludedByBillboard(struct RenderVertexSoft *vertices, int num_vertices, float x, float y); + void GetPolygonCenter(struct RenderVertexD3D3 *pVertices, unsigned int uNumVertices, float *pCenterX, float *pCenterY); + void GetPolygonScreenSpaceCenter(struct RenderVertexSoft *vertices, int num_vertices, float *out_center_x, float *out_center_y); + bool IsPointInsideD3DBillboard(struct RenderBillboardD3D *a1, float x, float y); + int PickClosestActor(int object_id, unsigned int pick_depth, int a4, int a5, int a6); + void _4C1A02(); + void SortVectors_x(RenderVertexSoft *pArray, int start, int end); + int get_object_zbuf_val(Vis_ObjectInfo *info); + int get_picked_object_zbuf_val(); + bool Intersect_Ray_Face(struct RenderVertexSoft *pRayStart, struct RenderVertexSoft *pRayEnd, float *pDepth, RenderVertexSoft *Intersection, BLVFace *pFace, signed int pBModelID); + bool CheckIntersectBModel(BLVFace *pFace, Vec3_short_ IntersectPoint, signed int sModelID); + void BLV_CreateIntersectFacesVertexCoordList(int *a, int *b, __int16 *intersect_face_vertex_coords_list_a, __int16 *intersect_face_vertex_coords_list_b, Vec3_short_ *IntersectPoint, BLVFace *pFace); + void ODM_CreateIntersectFacesVertexCoordList(int *a, int *b, __int16 *intersect_face_vertex_coords_list_a, __int16 *intersect_face_vertex_coords_list_b, Vec3_short_ *IntersectPoint, BLVFace *pFace, unsigned int uModelID); + void CastPickRay(RenderVertexSoft *pRay, float fMouseX, float fMouseY, float fPickDepth); + void sort_object_pointers(Vis_ObjectInfo **pPointers, int start, int end); + void SortVerticesByX(struct RenderVertexD3D3 *pArray, unsigned int uStart, unsigned int uEnd); + void SortVerticesByY(struct RenderVertexD3D3 *pArray, unsigned int uStart, unsigned int uEnd); + void SortByScreenSpaceX(struct RenderVertexSoft *pArray, int start, int end); + void SortByScreenSpaceY(struct RenderVertexSoft *pArray, int start, int end); + + //void ( ***vdestructor_ptr)(Vis *, bool); + Vis_SelectionList default_list; + RenderVertexSoft stru_200C; + RenderVertexSoft stru_203C; + RenderVertexSoft stru_206C; + RenderVertexSoft stru_209C; + int keyboard_pick_depth; +}; +#pragma pack(pop) diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/Weather.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/Weather.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,179 @@ +#define _CRTDBG_MAP_ALLOC +#include +#include + +#define _CRT_SECURE_NO_WARNINGS +#include + +#include "Weather.h" +#include "Viewport.h" +#include "Render.h" + +#include "mm7_data.h" ////TODO: remove this once LOWORD/HIWRD stuff is refactored + + + + +struct Weather *pWeather = new Weather; + + + +//----- (004C2AA6) -------------------------------------------------------- +int Weather::DrawSnow() +{ + +// if (!FORCE_16_BITS) + // __debugbreak(); // function expects 16bit target buffer, will fail otherwise + for ( uint i = 0; i < 700; ++i ) + { + int x = 2 * i; + int y = 2 * i + 1; + this->Screen_Coord[x] += rand() % 3 + 1; + this->Screen_Coord[y] += rand() % 2 + 1; + if ( this->Screen_Coord[x] < (signed int)(viewparams->uScreen_BttmR_X - 1) )//467 + { + if ( this->Screen_Coord[x] < (signed int)viewparams->uScreen_topL_X )//8 + this->Screen_Coord[x] = viewparams->uScreen_BttmR_X - rand() % 8; + } + else + this->Screen_Coord[x] = viewparams->uScreen_topL_X + rand() % 8; + if ( this->Screen_Coord[y] < (signed int)viewparams->uScreen_topL_Y//8 + || this->Screen_Coord[y] >= (signed int)viewparams->uScreen_BttmR_Y )//351 + { + this->Screen_Coord[y] = viewparams->uScreen_topL_Y; + this->Screen_Coord[x] = viewparams->uScreen_topL_X + (rand() % (signed int)((viewparams->uScreen_BttmR_X - viewparams->uScreen_topL_X) - 2)); + } + //v1[this->Screen_Coord[2 * i] + 640 * this->Screen_Coord[2 * i + 1]] = 0xFFFFu; + pRenderer->WritePixel16(this->Screen_Coord[x], this->Screen_Coord[y], 0xFFFF);//snowflake - point(снежинка - точка) + } + + for ( uint i = 700; i < 950; ++i ) + { + int x = 2 * i; + int y = 2 * i + 1; + this->Screen_Coord[x] += rand() % 5 - 3;//x + this->Screen_Coord[y] += 4;//y + if ( this->Screen_Coord[x] < (signed int)viewparams->uScreen_topL_X ) + this->Screen_Coord[x] = viewparams->uScreen_BttmR_X - rand() % 4 - 2; + if ( this->Screen_Coord[x] >= (signed int)(viewparams->uScreen_BttmR_X - 2) ) + this->Screen_Coord[x] = rand() % 4 + viewparams->uScreen_topL_X + 2; + if ( this->Screen_Coord[y] < (signed int)viewparams->uScreen_topL_Y || this->Screen_Coord[y] >= (signed int)(viewparams->uScreen_BttmR_Y - 1) ) + { + this->Screen_Coord[y] = viewparams->uScreen_topL_Y; + this->Screen_Coord[x] = viewparams->uScreen_topL_X + (rand() % (signed int)((viewparams->uScreen_BttmR_X - viewparams->uScreen_topL_X) - 2)); + } + pRenderer->WritePixel16(this->Screen_Coord[x], this->Screen_Coord[y], 0xFFFF);//x, y квадратная снежинка) + pRenderer->WritePixel16(this->Screen_Coord[x] + 1, this->Screen_Coord[y], 0xFFFF);//x + 1, y + pRenderer->WritePixel16(this->Screen_Coord[x], this->Screen_Coord[y] + 1, 0xFFFF);//x , y + 1 + pRenderer->WritePixel16(this->Screen_Coord[x] + 1, this->Screen_Coord[y] + 1, 0xFFFF);//x + 1, y + 1 + + //v1[this->Screen_Coord[2 * i] + 640 * this->Screen_Coord[2 * i + 1]] = 0xFFFFu; + //v1[this->Screen_Coord[2 * i] + 640 * this->Screen_Coord[2 * i + 1] + 1] = 0xFFFFu; + //v1[this->Screen_Coord[2 * i] + 640 * (this->Screen_Coord[2 * i + 1] + 1)] = 0xFFFFu; + //v1[this->Screen_Coord[2 * i] + 640 * this->Screen_Coord[2 * i + 1] + 641] = 0xFFFFu; + } + + for ( uint i = 0; i < 50; i++) + { + this->Screen_Coord[1901 + (i * 2)] += 8; + this->Screen_Coord[1901 + ((i * 2) -1)] += rand() % 11 - 5; + if ( this->Screen_Coord[1901 + ((i * 2) -1)] < (signed int)viewparams->uScreen_topL_X || this->Screen_Coord[1901 + ((i * 2) -1)] >= (signed int)(viewparams->uScreen_BttmR_X - 5) ) + { + this->Screen_Coord[1901 + (i * 2)] = viewparams->uScreen_topL_Y; + this->Screen_Coord[1901 + ((i * 2) -1)] = viewparams->uScreen_topL_X + (rand() % (signed int)((viewparams->uScreen_BttmR_X - viewparams->uScreen_topL_X) - 5)); + } + if ( this->Screen_Coord[1901 + (i * 2)] < (signed int)viewparams->uScreen_topL_Y || this->Screen_Coord[1901 + (i * 2)] >= (signed int)(viewparams->uScreen_BttmR_Y - 5) ) + { + this->Screen_Coord[1901 + (i * 2)] = viewparams->uScreen_topL_Y; + this->Screen_Coord[1901 + ((i * 2) -1)] = viewparams->uScreen_topL_X + (rand() % (signed int)((viewparams->uScreen_BttmR_X - viewparams->uScreen_topL_X) - 5)); + } + pRenderer->WritePixel16(this->Screen_Coord[1901 + ((i * 2) -1)], this->Screen_Coord[1901 + (i * 2)], 0xFFFF);//x, y + pRenderer->WritePixel16(this->Screen_Coord[1901 + ((i * 2) -1)], this->Screen_Coord[1901 + (i * 2)] + 1, 0xFFFF);//x, y + 1 + pRenderer->WritePixel16(this->Screen_Coord[1901 + ((i * 2) -1)], this->Screen_Coord[1901 + (i * 2)] + 2, 0xFFFF);//x, y + 2 + pRenderer->WritePixel16(this->Screen_Coord[1901 + ((i * 2) -1)], this->Screen_Coord[1901 + (i * 2)] + 3, 0xFFFF);//x, y + 3 + + pRenderer->WritePixel16(this->Screen_Coord[1901 + ((i * 2) -1)] + 1, this->Screen_Coord[1901 + (i * 2)], 0xFFFF);//x + 1, y + pRenderer->WritePixel16(this->Screen_Coord[1901 + ((i * 2) -1)] + 1, this->Screen_Coord[1901 + (i * 2)] + 1, 0xFFFF);//x + 1, y + 1 + pRenderer->WritePixel16(this->Screen_Coord[1901 + ((i * 2) -1)] + 1, this->Screen_Coord[1901 + (i * 2)] + 2, 0xFFFF);//x + 1, y + 2 + pRenderer->WritePixel16(this->Screen_Coord[1901 + ((i * 2) -1)] + 1, this->Screen_Coord[1901 + (i * 2)] + 3, 0xFFFF);//x + 1, y + 3 + + pRenderer->WritePixel16(this->Screen_Coord[1901 + ((i * 2) -1)] + 2, this->Screen_Coord[1901 + (i * 2)], 0xFFFF);//x + 2, y + pRenderer->WritePixel16(this->Screen_Coord[1901 + ((i * 2) -1)] + 2, this->Screen_Coord[1901 + (i * 2)] + 1, 0xFFFF);//x + 2, y + 1 + pRenderer->WritePixel16(this->Screen_Coord[1901 + ((i * 2) -1)] + 2, this->Screen_Coord[1901 + (i * 2)] + 2, 0xFFFF);//x + 2, y + 2 + pRenderer->WritePixel16(this->Screen_Coord[1901 + ((i * 2) -1)] + 2, this->Screen_Coord[1901 + (i * 2)] + 3, 0xFFFF);//x + 2, y + 3 + + pRenderer->WritePixel16(this->Screen_Coord[1901 + ((i * 2) -1)] + 3, this->Screen_Coord[1901 + (i * 2)], 0xFFFF);//x + 3, y + pRenderer->WritePixel16(this->Screen_Coord[1901 + ((i * 2) -1)] + 3, this->Screen_Coord[1901 + (i * 2)] + 1, 0xFFFF);//x + 3, y + 1 + pRenderer->WritePixel16(this->Screen_Coord[1901 + ((i * 2) -1)] + 3, this->Screen_Coord[1901 + (i * 2)] + 2, 0xFFFF);//x + 3, y + 2 + pRenderer->WritePixel16(this->Screen_Coord[1901 + ((i * 2) -1)] + 3, this->Screen_Coord[1901 + (i * 2)] + 3, 0xFFFF);//x + 3, y + 3 + + //v1[this->Screen_Coord[1901 + ((i * 2) -1)] + 640 * this->Screen_Coord[1901 + (i * 2)]] = 0xFFFFu;//x, y + //v1[this->Screen_Coord[1901 + ((i * 2) -1)] + 640 * (this->Screen_Coord[1901 + (i * 2)] + 1)] = 0xFFFFu;//x, y + 1 + //v1[this->Screen_Coord[1901 + ((i * 2) -1)] + 640 * (this->Screen_Coord[1901 + (i * 2)] + 2)] = 0xFFFFu;//x, y + 2 + //v1[this->Screen_Coord[1901 + ((i * 2) -1)] + 640 * (this->Screen_Coord[1901 + (i * 2)] + 3)] = 0xFFFFu;//x, y + 3 + + //*(&v1[640 * this->Screen_Coord[1901 + (i * 2)] + 1] + this->Screen_Coord[1901 + ((i * 2) -1)]) = 0xFFFFu;//y, x + 1 + //*(&v1[640 * this->Screen_Coord[1901 + (i * 2)] + 641] + this->Screen_Coord[1901 + ((i * 2) -1)]) = 0xFFFFu;//y + 1, x + 1 + //*(&v1[640 * this->Screen_Coord[1901 + (i * 2)] + 1281] + this->Screen_Coord[1901 + ((i * 2) -1)]) = 0xFFFFu;//y + 2, x + 1 + //*(&v1[640 * this->Screen_Coord[1901 + (i * 2)] + 1921] + this->Screen_Coord[1901 + ((i * 2) -1)]) = 0xFFFFu;//y + 3, x + 1 + + //*(&v1[640 * this->Screen_Coord[1901 + (i * 2)] + 2] + this->Screen_Coord[1901 + ((i * 2) -1)]) = 0xFFFFu;//y, x + 2 + //*(&v1[640 * this->Screen_Coord[1901 + (i * 2)] + 642] + this->Screen_Coord[1901 + ((i * 2) -1)]) = 0xFFFFu;//y + 1, x + 2 + //*(&v1[128 * (5 * this->Screen_Coord[1901 + (i * 2)]) + 1282] + this->Screen_Coord[1901 + ((i * 2) -1)]) = 0xFFFFu;//y + 2, x + 2 + //*(&v1[640 * this->Screen_Coord[1901 + (i * 2)] + 1922] + this->Screen_Coord[1901 + ((i * 2) -1)]) = 0xFFFFu;//y + 3, x + 2 + + //*(&v1[640 * this->Screen_Coord[1901 + (i * 2)] + 3] + this->Screen_Coord[1901 + ((i * 2) -1)]) = 0xFFFFu;//y, x + 3 + //*(&v1[640 * this->Screen_Coord[1901 + (i * 2)] + 643] + this->Screen_Coord[1901 + ((i * 2) -1)]) = 0xFFFFu;//y + 1, x + 3 + //*(&v1[640 * this->Screen_Coord[1901 + (i * 2)] + 1283] + this->Screen_Coord[1901 + ((i * 2) -1)]) = 0xFFFFu;//y + 2, x + 3 + //*(&v1[640 * this->Screen_Coord[1901 + (i * 2)] + 1923] + this->Screen_Coord[1901 + ((i * 2) -1)]) = 0xFFFFu;//y + 3, x + 3 + } + return 0; +} + +//----- (004C2EA0) -------------------------------------------------------- +int Weather::Initialize() +{ + signed int v3; // ebx@1 + signed int v4; // ebp@1 + + v3 = pViewport->uScreen_BR_X - pViewport->uScreen_TL_X - 4; + v4 = pViewport->uScreen_BR_Y - pViewport->uScreen_TL_Y - 4; + for ( uint i = 0; i < 1000; i++ ) + { + this->Screen_Coord[2 * i] = LOWORD(pViewport->uViewportTL_X) + rand() % v3; + this->Screen_Coord[(2 * (i + 1)) - 1] = LOWORD(pViewport->uViewportTL_Y) + rand() % v4; + } + return 0; +} + +//----- (004C2EFA) -------------------------------------------------------- +int Weather::Draw() +{ + if ( bRenderSnow || bSnow ) + DrawSnow(); + return 0; +} + +//----- (004C2F0B) -------------------------------------------------------- +bool Weather::OnPlayerTurn(__int16 a2) +{ + unsigned int screen_width; // esi@3 + + if ( this->bRenderSnow != true ) + return 0; + screen_width = viewparams->uScreen_BttmR_X - viewparams->uScreen_topL_X; + + for ( uint i = 0; i < 1000; ++i ) + { + this->Screen_Coord[2 * i] += a2; + if ( this->Screen_Coord[2 * i] < (signed int)viewparams->uScreen_BttmR_X - 4 ) + { + if ( this->Screen_Coord[2 * i] >= (signed int)viewparams->uScreen_topL_X ) + continue; + this->Screen_Coord[2 * i] += screen_width; + } + else + this->Screen_Coord[2 * i] = this->Screen_Coord[2 * i] - screen_width + 4; + } + return 1; +} \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/Weather.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/Weather.h Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,30 @@ +#pragma once + + +#pragma pack(push, 1) + + + +/* 255 */ +struct Weather +{ + inline Weather(): + bNight(false), bRenderSnow(false) + {} + + int DrawSnow(); + int Initialize(); + int Draw(); + bool OnPlayerTurn(__int16 dangle); + + + + __int16 Screen_Coord[2000]; + int bNight; + int bRenderSnow; +}; +#pragma pack(pop) + + + +extern struct Weather *pWeather; \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/stru10.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/stru10.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,860 @@ +#define _CRTDBG_MAP_ALLOC +#include +#include + +#define _CRT_SECURE_NO_WARNINGS +#include "stru10.h" +#include "Indoor.h" +#include "Game.h" +#include "Party.h" +#include "ErrorHandling.h" + + + +int _49CE9E_sub0_x(RenderVertexSoft *pVertices, unsigned int uNumVertices, float test_val) +{ + float max_val = FLT_MAX; + int idx = -1; + + float temp_val; + for (uint i = 0; i < uNumVertices; ++i) + { + if (pVertices[i].vWorldPosition.x <= test_val) + temp_val = test_val - pVertices[i].vWorldPosition.x; + else + temp_val = pVertices[i].vWorldPosition.x - test_val; + + if (temp_val < max_val) + { + max_val = temp_val; + idx = i; + } + } + return idx; +} + + +int _49CE9E_sub0_y(RenderVertexSoft *pVertices, unsigned int uNumVertices, float test_val) +{ + float max_val = FLT_MAX; + int idx = -1; + + float temp_val; + for (uint i = 0; i < uNumVertices; ++i) + { + if (pVertices[i].vWorldPosition.y <= test_val) + temp_val = test_val - pVertices[i].vWorldPosition.y; + else + temp_val = pVertices[i].vWorldPosition.y - test_val; + + if (temp_val < max_val) + { + max_val = temp_val; + idx = i; + } + } + return idx; +} + + +int _49CE9E_sub0_z(RenderVertexSoft *pVertices, unsigned int uNumVertices, float test_val) +{ + float max_val = FLT_MAX; + int idx = -1; + + float temp_val; + for (uint i = 0; i < uNumVertices; ++i) + { + if (pVertices[i].vWorldPosition.z <= test_val) + temp_val = test_val - pVertices[i].vWorldPosition.z; + else + temp_val = pVertices[i].vWorldPosition.z - test_val; + + if (temp_val < max_val) + { + max_val = temp_val; + idx = i; + } + } + return idx; +} + +//----- (0049CE9E) -------------------------------------------------------- +void stru10::_49CE9E(BLVFace *pFace, RenderVertexSoft *pVertices, unsigned int uNumVertices, RenderVertexSoft *pOutLimits) +{ + Assert(sizeof(RenderVertexSoft) == 0x30); + + RenderVertexSoft pLimits[64]; + stru10::CalcPolygonLimits(pFace, pLimits); + + if (pFace->uAttributes & FACE_XY_PLANE) + { + memcpy(&pOutLimits[0], &pVertices[_49CE9E_sub0_x(pVertices, uNumVertices, pLimits[0].vWorldPosition.x)], 0x30); + memcpy(&pOutLimits[2], &pVertices[_49CE9E_sub0_x(pVertices, uNumVertices, pLimits[2].vWorldPosition.x)], 0x30); + memcpy(&pOutLimits[1], &pVertices[_49CE9E_sub0_y(pVertices, uNumVertices, pLimits[1].vWorldPosition.y)], 0x30); + memcpy(&pOutLimits[3], &pVertices[_49CE9E_sub0_y(pVertices, uNumVertices, pLimits[3].vWorldPosition.y)], 0x30); + } + else if (pFace->uAttributes & FACE_XZ_PLANE) + { + memcpy(&pOutLimits[0], &pVertices[_49CE9E_sub0_x(pVertices, uNumVertices, pLimits[0].vWorldPosition.x)], 0x30); + memcpy(&pOutLimits[2], &pVertices[_49CE9E_sub0_x(pVertices, uNumVertices, pLimits[2].vWorldPosition.x)], 0x30); + memcpy(&pOutLimits[1], &pVertices[_49CE9E_sub0_z(pVertices, uNumVertices, pLimits[1].vWorldPosition.z)], 0x30); + memcpy(&pOutLimits[3], &pVertices[_49CE9E_sub0_z(pVertices, uNumVertices, pLimits[3].vWorldPosition.z)], 0x30); + } + else if (pFace->uAttributes & FACE_YZ_PLANE) + { + memcpy(&pOutLimits[0], &pVertices[_49CE9E_sub0_y(pVertices, uNumVertices, pLimits[0].vWorldPosition.y)], 0x30); + memcpy(&pOutLimits[2], &pVertices[_49CE9E_sub0_y(pVertices, uNumVertices, pLimits[2].vWorldPosition.y)], 0x30); + memcpy(&pOutLimits[1], &pVertices[_49CE9E_sub0_z(pVertices, uNumVertices, pLimits[1].vWorldPosition.z)], 0x30); + memcpy(&pOutLimits[3], &pVertices[_49CE9E_sub0_z(pVertices, uNumVertices, pLimits[3].vWorldPosition.z)], 0x30); + } +} + +//----- (0049D379) -------------------------------------------------------- +void stru10::CalcPolygonLimits(BLVFace *pFace, RenderVertexSoft *pOutVertices) +{ + struct + { + float x; + float y; + int c; + } v46[40]; //[sp+0C]; + + if (pFace->uAttributes & FACE_XY_PLANE) + { + for (uint i = 0; i < pFace->uNumVertices; ++i) + { + v46[i].x = pIndoor->pVertices[pFace->pVertexIDs[i]].x + pFace->pXInterceptDisplacements[i]; + v46[i].y = pIndoor->pVertices[pFace->pVertexIDs[i]].y + pFace->pYInterceptDisplacements[i]; + v46[i].c = i; + } + } + if (pFace->uAttributes & FACE_XZ_PLANE) + { + for (uint i = 0; i < pFace->uNumVertices; ++i) + { + v46[i].x = pIndoor->pVertices[pFace->pVertexIDs[i]].x + pFace->pXInterceptDisplacements[i]; + v46[i].y = pIndoor->pVertices[pFace->pVertexIDs[i]].z + pFace->pZInterceptDisplacements[i]; + v46[i].c = i; + } + } + if (pFace->uAttributes & FACE_YZ_PLANE) + { + for (uint i = 0; i < pFace->uNumVertices; ++i) + { + v46[i].x = pIndoor->pVertices[pFace->pVertexIDs[i]].y + pFace->pYInterceptDisplacements[i]; + v46[i].y = pIndoor->pVertices[pFace->pVertexIDs[i]].z + pFace->pZInterceptDisplacements[i]; + v46[i].c = i; + } + } + + float x_min = v46[0].x; + uint x_min_idx = 0; + + float x_max = v46[0].x; + uint x_max_idx = 0; + + float y_min = v46[0].y; + uint y_min_idx = 0; + + float y_max = v46[0].y; + uint y_max_idx = 0; + + for (uint i = 0; i < pFace->uNumVertices; ++i) + { + if (v46[i].x < x_min) + { + x_min = v46[i].x; + x_min_idx = v46[i].c; + } + if (v46[i].x > x_max) + { + x_max = v46[i].x; + x_max_idx = v46[i].c; + } + + if (v46[i].y < y_min) + { + y_min = v46[i].y; + y_min_idx = v46[i].c; + } + if (v46[i].y > y_max) + { + y_max = v46[i].y; + y_max_idx = v46[i].c; + } + } + + RenderVertexSoft v1; // [sp+30Ch] [bp-54h]@24 + v1.vWorldPosition.x = (float)pIndoor->pVertices[pFace->pVertexIDs[x_min_idx]].x; + v1.vWorldPosition.y = (float)pIndoor->pVertices[pFace->pVertexIDs[x_min_idx]].y; + v1.vWorldPosition.z = (float)pIndoor->pVertices[pFace->pVertexIDs[x_min_idx]].z; + memcpy(&pOutVertices[0], &v1, sizeof(RenderVertexSoft)); + + RenderVertexSoft v2; // [sp+30Ch] [bp-54h]@24 + v2.vWorldPosition.x = (float)pIndoor->pVertices[pFace->pVertexIDs[y_min_idx]].x; + v2.vWorldPosition.y = (float)pIndoor->pVertices[pFace->pVertexIDs[y_min_idx]].y; + v2.vWorldPosition.z = (float)pIndoor->pVertices[pFace->pVertexIDs[y_min_idx]].z; + memcpy(&pOutVertices[1], &v2, sizeof(RenderVertexSoft)); + + RenderVertexSoft v3; // [sp+30Ch] [bp-54h]@24 + v3.vWorldPosition.x = (float)pIndoor->pVertices[pFace->pVertexIDs[x_max_idx]].x; + v3.vWorldPosition.y = (float)pIndoor->pVertices[pFace->pVertexIDs[x_max_idx]].y; + v3.vWorldPosition.z = (float)pIndoor->pVertices[pFace->pVertexIDs[x_max_idx]].z; + memcpy(&pOutVertices[2], &v3, sizeof(RenderVertexSoft)); + + RenderVertexSoft v4; // [sp+30Ch] [bp-54h]@24 + v4.vWorldPosition.x = (double)pIndoor->pVertices[pFace->pVertexIDs[y_max_idx]].x; + v4.vWorldPosition.y = (double)pIndoor->pVertices[pFace->pVertexIDs[y_max_idx]].y; + v4.vWorldPosition.z = (double)pIndoor->pVertices[pFace->pVertexIDs[y_max_idx]].z; + memcpy(&pOutVertices[3], &v4, sizeof(RenderVertexSoft)); +} + + +//----- (0049C9E3) -------------------------------------------------------- +bool stru10::CalcFaceBounding(BLVFace *pFace, RenderVertexSoft *pFaceLimits, unsigned int uNumVertices, RenderVertexSoft *pOutBounding) +{ + //IndoorCameraD3D *v6; // edi@1 + //PolygonType v7; // al@1 + //unsigned int v8; // edx@7 + //char v10; // zf@10 + //float v13; // ST14_4@20 + //stru10 *v15; // ecx@21 + //RenderVertexSoft *v16; // ST0C_4@21 + //bool result; // eax@21 + //float v18; // ST14_4@24 + //stru10 *v19; // edi@29 + //float v20; // ST14_4@30 + //float v21; // ST14_4@30 + //float v22; // ST14_4@30 + //float v23; // ST14_4@30 + //float v24; // ST14_4@31 + //RenderVertexSoft v25; // [sp+10h] [bp-90h]@24 + //RenderVertexSoft v26; // [sp+40h] [bp-60h]@20 + //IndoorCameraD3D *thisa; // [sp+70h] [bp-30h]@1 + //stru10 *v31; // [sp+84h] [bp-1Ch]@1 + //float v32; // [sp+88h] [bp-18h]@8 + Vec3_float_ a1; // [sp+8Ch] [bp-14h]@1 + //float v35; // [sp+9Ch] [bp-4h]@8 + + //auto a3 = pFace; + //auto arg4 = pFaceBounding; + + //_ESI = a3; + //v31 = this; + //v6 = pGame->pIndoorCameraD3D; + //v7 = a3->uPolygonType; + + a1.x = 0.0f; + a1.y = 0.0f; + a1.z = 0.0f; + + float var_28; + float var_24; + switch (pFace->uPolygonType) + { + case POLYGON_VerticalWall: + a1.x = -pFace->pFacePlane.vNormal.y;// направление полигона + a1.y = pFace->pFacePlane.vNormal.x; + a1.z = 0.0f; + a1.Normalize(); + + var_28 = 0; + var_24 = 1; + break; + + case POLYGON_Floor: + case POLYGON_Ceiling: + a1.x = 1; + a1.y = 0; + a1.z = 0.0f; + + var_28 = 1; + var_24 = 0; + break; + + default: + Error("Invalid polygon type (%u)", pFace->uPolygonType); + } + + + float face_center_x; + float face_center_y; + float face_center_z; + float a3; + float var_8; + + if (pFace->uAttributes & FACE_XY_PLANE) + { + face_center_x = (pFaceLimits[0].vWorldPosition.x + pFaceLimits[2].vWorldPosition.x) / 2; + face_center_y = (pFaceLimits[3].vWorldPosition.y + pFaceLimits[1].vWorldPosition.y) / 2; + face_center_z = (pFaceLimits[0].vWorldPosition.z + pFaceLimits[2].vWorldPosition.z) / 2; + + a3 = face_center_x - pFaceLimits[0].vWorldPosition.x; + var_8 = face_center_y - pFaceLimits[1].vWorldPosition.y; + } + if (pFace->uAttributes & FACE_XZ_PLANE) + { + face_center_x = (pFaceLimits[0].vWorldPosition.x + pFaceLimits[2].vWorldPosition.x) / 2;// центр полигона + face_center_y = (pFaceLimits[0].vWorldPosition.y + pFaceLimits[2].vWorldPosition.y) / 2; + face_center_z = (pFaceLimits[1].vWorldPosition.z + pFaceLimits[3].vWorldPosition.z) / 2; + + a3 = face_center_x - pFaceLimits[0].vWorldPosition.x;//от центра до верхнего края + var_8 = face_center_z - pFaceLimits[1].vWorldPosition.z;// высота от центра + + if (pFace->uPolygonType == POLYGON_VerticalWall) + a3 /= a1.x; + } + if (pFace->uAttributes & FACE_YZ_PLANE) + { + face_center_x = (pFaceLimits[0].vWorldPosition.x + pFaceLimits[2].vWorldPosition.x) / 2; + face_center_y = (pFaceLimits[0].vWorldPosition.y + pFaceLimits[2].vWorldPosition.y) / 2; + face_center_z = (pFaceLimits[1].vWorldPosition.z + pFaceLimits[3].vWorldPosition.z) / 2; + + a3 = face_center_y - pFaceLimits[0].vWorldPosition.y; + var_8 = face_center_z - pFaceLimits[1].vWorldPosition.z; + // [0.5] + if (pFace->uPolygonType == POLYGON_VerticalWall) + { + if (a1.x != 1.0f) + a3 /= a1.y; + } + } + + + + + //_EBX = arg0; + //v15 = v31; + //v16 = arg0; + //float var_20 = var_8 * var_24; + //var_8 = a3 * a1.z; + //float arg_0 = var_8 + var_4; + +/* + + + +.text:0049CBB3 fld [ebp+var_8] 0 var8 +.text:0049CBB6 1 fmul ds:flt_4D84E8 0 var8 * flt_4D84E8 + +.text:0049CBBC 1 fld [ebp+var_8] 0 var8 + 1 var8 * flt_4D84E8 + +.text:0049CBBF 2 fmul [ebp+var_28] 0 var8 * var28 + 1 var8 * flt_4D84E8 + +.text:0049CBC2 2 fld [ebp+var_8] 0 var8 + 1 var8 * var28 + 2 var8 * flt_4D84E8 + +.text:0049CBC5 3 fmul [ebp+var_24] 0 var8 * var24 768 + 1 var8 * var28 0 + 2 var8 * flt_4D84E8 0 + +.text:0049CBD5 3 fst [ebp+var_20] 0 var8 * var24 768 + 1 var8 * var28 0 + 2 var8 * flt_4D84E8 0 + [var20] var8 * var24 768 + +.text:0049CBD8 3 fld [ebp+a3] 0 a3 -1984 + 1 var8 * var24 768 + 2 var8 * var28 0 + 3 var8 * flt_4D84E8 0 + +.text:0049CBDB 4 fmul [ebp+a1.x] 0 a3 * a1.x 1984 + 1 var8 * var24 768 + 2 var8 * var28 0 + 3 var8 * flt_4D84E8 0 + +.text:0049CBDE 4 fld [ebp+a3] 0 a3 + 1 a3 * a1.x 1984 + 2 var8 * var24 768 + 3 var8 * var28 0 + 4 var8 * flt_4D84E8 0 + +.text:0049CBE1 5 fmul [ebp+a1.y] 0 a3 * a1.y 0 + 1 a3 * a1.x 1984 + 2 var8 * var24 768 + 3 var8 * var28 0 + 4 var8 * flt_4D84E8 0 +.text:0049CBE4 5 fld [ebp+a3] +.text:0049CBE7 6 fmul [ebp+a1.z] 0 a3 * a1.z 0 + 1 a3 * a1.y 0 + 2 a3 * a1.x 1984 + 3 var8 * var24 768 + 4 var8 * var28 0 + 5 var8 * flt_4D84E8 0 + +.text:0049CBEC 6 fstp [ebp+var_8] + var8 <- a3 * a1.z 0 + +.text:0049CBEF 5 fld [ebp+arg4] 0 arg4 -1700 + 1 a3 * a1.y 0 + 2 a3 * a1.x 1984 + 3 var8 * var24 768 + 4 var8 * var28 0 + 5 var8 * flt_4D84E8 0 + +.text:0049CBF2 6 fsub st, st(2) 0 arg4 - a3 * a1.x -3684 + 1 a3 * a1.y 0 + 2 a3 * a1.x 1984 + 3 var8 * var24 768 + 4 var8 * var28 0 + 5 var8 * flt_4D84E8 0 + +.text:0049CBF4 6 fld st 0 arg4 - a3 * a1.x -3684 + 1 arg4 - a3 * a1.x -3684 + 2 a3 * a1.y 0 + 3 a3 * a1.x 1984 + 4 var8 * var24 768 + 5 var8 * var28 0 + 6 var8 * flt_4D84E8 0 + +.text:0049CBF6 7 fadd st, st(6) 0 arg4 - a3 * a1.x + var8 * flt_4D84E8 -3684 + 1 arg4 - a3 * a1.x -3684 + 2 a3 * a1.y 0 + 3 a3 * a1.x 1984 + 4 var8 * var24 768 + 5 var8 * var28 0 + 6 var8 * flt_4D84E8 0 +.text:0049CBF8 7 fstp dword ptr [ebx] + [0].x <- arg4 - a3 * a1.x + var8 * flt_4D84E8 -3684 + +.text:0049CBFA 6 fld [ebp+var_18] 0 var18 1480 + 1 arg4 - a3 * a1.x -3684 + 2 a3 * a1.y 0 + 3 a3 * a1.x 1984 + 4 var8 * var24 768 + 5 var8 * var28 0 + 6 var8 * flt_4D84E8 0 + +.text:0049CBFD 7 fsub st, st(2) 0 var18 - a3 * a1.y 1480 + 1 arg4 - a3 * a1.x -3684 + 2 a3 * a1.y 0 + 3 a3 * a1.x 1984 + 4 var8 * var24 768 + 5 var8 * var28 0 + 6 var8 * flt_4D84E8 0 + +.text:0049CBFF 7 fld st 0 var18 - a3 * a1.y 1480 + 1 var18 - a3 * a1.y 1480 + 2 arg4 - a3 * a1.x -3684 + 3 a3 * a1.y 0 + 4 a3 * a1.x 1984 + 5 var8 * var24 768 + 6 var8 * var28 0 + 7 var8 * flt_4D84E8 0 + +.text:0049CC01 8 fadd st, st(6) 0 var18 - a3 * a1.y + var8 * var28 1480 + 1 var18 - a3 * a1.y 1480 + 2 arg4 - a3 * a1.x -3684 + 3 a3 * a1.y 0 + 4 a3 * a1.x 1984 + 5 var8 * var24 768 + 6 var8 * var28 0 + 7 var8 * flt_4D84E8 0 + +.text:0049CC03 8 fstp dword ptr [ebx+4] + [0].y <- var18 - a3 * a1.y + var8 * var28 1480 + +.text:0049CC06 7 fld [ebp+var_4] +.text:0049CC09 8 fsub [ebp+var_8] 0 var4 - a3 * a1.z 768 + 1 var18 - a3 * a1.y 1480 + 2 arg4 - a3 * a1.x -3684 + 3 a3 * a1.y 0 + 4 a3 * a1.x 1984 + 5 var8 * var24 768 + 6 var8 * var28 0 + 7 var8 * flt_4D84E8 0 +.text:0049CC0C 8 fst [ebp+a3] + a3 <- var4 - a3 * a1.z 768 + +.text:0049CC0F 8 fadd st, st(5) +.text:0049CC11 8 fstp dword ptr [ebx+8] + [0].z <- var4 - a3 * a1.z + var8 * var24 1536 + + 0 var18 - a3 * a1.y 1480 + 1 arg4 - a3 * a1.x -3684 + 2 a3 * a1.y 0 + 3 a3 * a1.x 1984 + 4 var8 * var24 768 + 5 var8 * var28 0 + 6 var8 * flt_4D84E8 0 + + + + + [var20] var8 * var24 768 + [var8] a3 * a1.z + [a3] var4 - a3 * a1.z 768 + + +.text:0049CC14 7 fld st(1) +.text:0049CC16 8 fsub st, st(7) 0 arg4 - a3 * a1.x - var8 * flt_4D84E8 -3684 + 1 var18 - a3 * a1.y 1480 + 2 arg4 - a3 * a1.x -3684 + 3 a3 * a1.y 0 + 4 a3 * a1.x 1984 + 5 var8 * var24 768 + 6 var8 * var28 0 + 7 var8 * flt_4D84E8 0 +.text:0049CC18 8 fstp dword ptr [ebx+30h] + [1].x <- arg4 - a3 * a1.x - var8 * flt_4D84E8 -3684 + + 0 var18 - a3 * a1.y 1480 + 1 arg4 - a3 * a1.x -3684 + 2 a3 * a1.y 0 + 3 a3 * a1.x 1984 + 4 var8 * var24 768 + 5 var8 * var28 0 + 6 var8 * flt_4D84E8 0 +.text:0049CC1B 7 fsub st, st(5) +.text:0049CC1D 7 fstp dword ptr [ebx+34h] + [1].y <- var18 - a3 * a1.y - var8 * var28 1480 +.text:0049CC20 6 fstp st + 0 a3 * a1.y 0 + 1 a3 * a1.x 1984 + 2 var8 * var24 768 + 3 var8 * var28 0 + 4 var8 * flt_4D84E8 0 + + + [var20] var8 * var24 768 + [var8] a3 * a1.z + [a3] var4 - a3 * a1.z 768 + +.text:0049CC22 5 fld [ebp+a3] 0 var4 - a3 * a1.z 768 + 1 a3 * a1.y 0 + 2 a3 * a1.x 1984 + 3 var8 * var24 768 + 4 var8 * var28 0 + 5 var8 * flt_4D84E8 0 +.text:0049CC25 6 fsub st, st(3) +.text:0049CC27 6 fstp dword ptr [ebx+38h] + [1].z <- var4 - a3 * a1.z - var8 * var24 768 - 768 = 0 + + 0 a3 * a1.y 0 + 1 a3 * a1.x 1984 + 2 var8 * var24 768 + 3 var8 * var28 0 + 4 var8 * flt_4D84E8 0 + + +.text:0049CC2A fld st(1) +.text:0049CC2C 6 fadd [ebp+arg4] 0 arg4 + a3 * a1.x 284 + 1 a3 * a1.y 0 + 2 a3 * a1.x 1984 + 3 var8 * var24 768 + 4 var8 * var28 0 + 5 var8 * flt_4D84E8 0 +.text:0049CC2F 6 fst [ebp+a3] + + [var20] var8 * var24 768 + [var8] a3 * a1.z + [a3] arg4 + a3 * a1.x 284 +.text:0049CC32 6 fsub st, st(5) +.text:0049CC34 6 fstp dword ptr [ebx+60h] + [2].x <- arg4 + a3 * a1.x - var8 * flt_4D84E8 284 + + 0 a3 * a1.y 0 + 1 a3 * a1.x 1984 + 2 var8 * var24 768 + 3 var8 * var28 0 + 4 var8 * flt_4D84E8 0 + +.text:0049CC37 5 fadd [ebp+var_18] 0 var18 + a3 * a1.y 1480 + 1 a3 * a1.x 1984 + 2 var8 * var24 768 + 3 var8 * var28 0 + 4 var8 * flt_4D84E8 0 + +.text:0049CC3A 5 fstp st(2) 0 a3 * a1.x 1984 + 1 var18 + a3 * a1.y 1480 + 2 var8 * var28 0 + 3 var8 * flt_4D84E8 0 + +.text:0049CC3C 4 fstp st 0 var18 + a3 * a1.y 1480 + 1 var8 * var28 0 + 2 var8 * flt_4D84E8 0 + +.text:0049CC3E 3 fld st 0 var18 + a3 * a1.y 1480 + 1 var18 + a3 * a1.y 1480 + 2 var8 * var28 0 + 3 var8 * flt_4D84E8 0 +.text:0049CC40 4 fsub st, st(2) +.text:0049CC42 4 fstp dword ptr [ebx+64h] + [2].y <- var18 + a3 * a1.y - var8 * var28 1480 + + 0 var18 + a3 * a1.y 1480 + 1 var8 * var28 0 + 2 var8 * flt_4D84E8 0 + + [var20] var8 * var24 768 + [var8] a3 * a1.z + [a3] arg4 + a3 * a1.x 284 +.text:0049CC45 3 fld [ebp+var_8] +.text:0049CC48 4 fadd [ebp+var_4] 0 var4 + a3 * a1.z 768 + 1 var18 + a3 * a1.y 1480 + 2 var8 * var28 0 + 3 var8 * flt_4D84E8 0 + +.text:0049CC4B 4 fst [ebp+arg0] + [var20] var8 * var24 768 + [arg0] var4 + a3 * a1.z 768 + [var8] a3 * a1.z 0 + [a3] arg4 + a3 * a1.x 284 + +.text:0049CC4E 4 fsub [ebp+var_20] +.text:0049CC51 4 fstp dword ptr [ebx+68h] + [2].z <- var4 + a3 * a1.z - var8 * var24 0 + + + + [var20] var8 * var24 768 + [arg0] var4 + a3 * a1.z 768 + [var8] a3 * a1.z 0 + [a3] arg4 + a3 * a1.x 284 + + + 0 var18 + a3 * a1.y 1480 + 1 var8 * var28 0 + 2 var8 * flt_4D84E8 0 + +.text:0049CC54 3 fld [ebp+a3] +.text:0049CC57 4 fadd st, st(3) +.text:0049CC59 4 fstp dword ptr [ebx+90h] + [3].x <- arg4 + a3 * a1.x + var8 * flt_4D84E8 284 + +.text:0049CC5F 3 fadd st, st(1) +.text:0049CC61 3 fstp dword ptr [ebx+94h] + [3].y <- var18 + a3 * a1.y + var8 * var28 1480 + +.text:0049CC67 2 fstp st +.text:0049CC69 1 fstp st + 0 empty +.text:0049CC6B 0 fld [ebp+arg0] +.text:0049CC6E 1 fadd [ebp+var_20] +.text:0049CC71 1 fstp dword ptr [ebx+98h] + [3].z <- var4 + a3 * a1.z + var8 * var24 1536 + + 0 empty +*/ + + pOutBounding[0].vWorldPosition.x = face_center_x - a3 * a1.x + var_8 * flt_4D84E8; + pOutBounding[0].vWorldPosition.y = face_center_y - a3 * a1.y + var_8 * var_28; + pOutBounding[0].vWorldPosition.z = face_center_z - a3 * a1.z + var_8 * var_24; + + pOutBounding[1].vWorldPosition.x = face_center_x - a3 * a1.x - var_8 * flt_4D84E8; + pOutBounding[1].vWorldPosition.y = face_center_y - a3 * a1.y - var_8 * var_28; + pOutBounding[1].vWorldPosition.z = face_center_z - a3 * a1.z - var_8 * var_24; + + pOutBounding[2].vWorldPosition.x = face_center_x + a3 * a1.x - var_8 * flt_4D84E8; + pOutBounding[2].vWorldPosition.y = face_center_y + a3 * a1.y - var_8 * var_28; + pOutBounding[2].vWorldPosition.z = face_center_z + a3 * a1.z - var_8 * var_24; + + pOutBounding[3].vWorldPosition.x = face_center_x + a3 * a1.x + var_8 * flt_4D84E8; + pOutBounding[3].vWorldPosition.y = face_center_y + a3 * a1.y + var_8 * var_28; + pOutBounding[3].vWorldPosition.z = face_center_z + a3 * a1.z + var_8 * var_24; + + a1.x = 0.0f; + a1.y = 0.0f; + a1.z = 0.0f; + a3 = face_center_x + a3 * a1.x; + + if (!FindFacePlane(pOutBounding, &a1, &a3)) + return false; + + + + RenderVertexSoft v25; // [sp+10h] [bp-90h]@20 + memcpy(&v25, pOutBounding, sizeof(RenderVertexSoft)); + + float _dp = (v25.vWorldPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x) * a1.x + + (v25.vWorldPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y) * a1.y + + (v25.vWorldPosition.z - pGame->pIndoorCameraD3D->vPartyPos.z) * a1.z; + if (fabs(_dp) < 1e-6f) + { + memcpy(&v25, &pOutBounding[1], sizeof(RenderVertexSoft)); + memcpy(&pOutBounding[1], &pOutBounding[3], sizeof(RenderVertexSoft)); + memcpy(&pOutBounding[3], &v25, sizeof(RenderVertexSoft)); + } + + //if ( byte_4D864C && pGame->uFlags & GAME_FLAGS_1_DRAW_BLV_DEBUGS) + //{ + RenderVertexSoft v26; // [sp+40h] [bp-60h]@20 + if ( draw_portals_loops ) + { + if (!bDoNotDrawPortalFrustum) + { + v26.vWorldPosition.x = pParty->vPosition.x; + v26.vWorldPosition.y = pParty->vPosition.y; + v26.vWorldPosition.z = pParty->vPosition.z + pParty->sEyelevel; // frustum + + pGame->pIndoorCameraD3D->do_draw_debug_line_sw(&v26, 0xFF0000u, &pOutBounding[0], 0xFF0000u, 0, 0); + pGame->pIndoorCameraD3D->do_draw_debug_line_sw(&v26, 0xFF00u, &pOutBounding[1], 0xFF00u, 0, 0); + pGame->pIndoorCameraD3D->do_draw_debug_line_sw(&v26, 0xFFu, &pOutBounding[2], 0xFFu, 0, 0); + pGame->pIndoorCameraD3D->do_draw_debug_line_sw(&v26, 0xFFFFFFu, &pOutBounding[3], 0xFFFFFFu, 0, 0); + bDoNotDrawPortalFrustum = true; + } + pGame->pIndoorCameraD3D->debug_outline_sw(pOutBounding, uNumVertices, 0x1EFF1Eu, 0.00019999999); // bounding + } + //} + + //pGame->pIndoorCameraD3D->debug_outline_sw(pFaceLimits, 4, 0xFFF14040, 0.000099999997); // limits + + /*if ( byte_4D864C && pGame->uFlags & GAME_FLAGS_1_DRAW_BLV_DEBUGS) + { + RenderVertexSoft v26; // [sp+40h] [bp-60h]@20 + v26.vWorldPosition.x = face_center_x; // corner to center + v26.vWorldPosition.y = face_center_y; + v26.vWorldPosition.z = face_center_z; + + pGame->pIndoorCameraD3D->do_draw_debug_line_sw(pFaceLimits, 0xFF00u, &v26, 0xFF0000u, 0, 0); + }*/ + + + /*if ( byte_4D864C ) + { + if ( pGame->uFlags & GAME_FLAGS_1_DRAW_BLV_DEBUGS)*/ + { + RenderVertexSoft v25; // [sp+10h] [bp-90h]@20 + RenderVertexSoft v26; // [sp+40h] [bp-60h]@20 + + v25.vWorldPosition.x = face_center_x; // portal normal + v25.vWorldPosition.y = face_center_y; + v25.vWorldPosition.z = face_center_z; + + v26.vWorldPosition.x = face_center_x + a1.x * 400.0f; + v26.vWorldPosition.y = face_center_y + a1.y * 400.0f; + v26.vWorldPosition.z = face_center_z + a1.z * 400.0f; + + if ( draw_portals_loops ) + pGame->pIndoorCameraD3D->do_draw_debug_line_sw(&v25, -1, &v26, 0xFFFF00u, 0, 0); + } + //} + + return true; +} + + + +//----- (0049C5B0) -------------------------------------------------------- +stru10::stru10() +{ + this->bDoNotDrawPortalFrustum = false; +} + +//----- (0049C5BD) -------------------------------------------------------- +stru10::~stru10() +{ +} + +//----- (0049C5DA) -------------------------------------------------------- +char stru10::_49C5DA(BLVFace *pFace, RenderVertexSoft *pVertices, unsigned int *pNumVertices, IndoorCameraD3D_Vec4 *a5, RenderVertexSoft *pOutBounding) +{ + RenderVertexSoft pLimits[4]; // [sp+Ch] [bp-C0h]@1 + + _49CE9E(pFace, pVertices, *pNumVertices, pLimits); + + //if ( byte_4D864C && pGame->uFlags & GAME_FLAGS_1_DRAW_BLV_DEBUGS) + // pGame->pIndoorCameraD3D->debug_outline_sw(a4a, 4u, 0xFF1E1Eu, 0.000099999997); + if (CalcFaceBounding(pFace, pLimits, 4, pOutBounding)) + return _49C720(pOutBounding, a5); + return false; +} +// 4D864C: using guessed type char byte_4D864C; + +//----- (0049C681) -------------------------------------------------------- +bool stru10::CalcPortalShape(BLVFace *pFace, IndoorCameraD3D_Vec4 *pPortalDataFrustum, RenderVertexSoft *pOutBounding) +{ + RenderVertexSoft pLimits[4]; // [sp+Ch] [bp-C0h]@1 + + CalcPolygonLimits(pFace, pLimits);//определение границ портала + //if ( byte_4D864C && pGame->uFlags & GAME_FLAGS_1_DRAW_BLV_DEBUGS) + // pGame->pIndoorCameraD3D->debug_outline_sw(pLimits, 4, 0xFF1E1E, 0.000099999997); + if (CalcFaceBounding(pFace, pLimits, 4, pOutBounding)) + return _49C720(pOutBounding, pPortalDataFrustum) != 0; + return false; +} + +// 4D864C: using guessed type char byte_4D864C; + +//----- (0049C720) -------------------------------------------------------- +char stru10::_49C720(RenderVertexSoft *pFaceBounding, IndoorCameraD3D_Vec4 *pPortalDataFrustum) +{ + Vec3_float_ pRayStart; // [sp+4h] [bp-34h]@1 + pRayStart.x = (double)pGame->pIndoorCameraD3D->vPartyPos.x; + pRayStart.y = (double)pGame->pIndoorCameraD3D->vPartyPos.y; + pRayStart.z = (double)pGame->pIndoorCameraD3D->vPartyPos.z; + + if (FindFaceNormal(&pFaceBounding[0], &pFaceBounding[1], &pRayStart, &pPortalDataFrustum[0]) && + FindFaceNormal(&pFaceBounding[1], &pFaceBounding[2], &pRayStart, &pPortalDataFrustum[1]) && + FindFaceNormal(&pFaceBounding[2], &pFaceBounding[3], &pRayStart, &pPortalDataFrustum[2]) && + FindFaceNormal(&pFaceBounding[3], &pFaceBounding[0], &pRayStart, &pPortalDataFrustum[3])) + return true; + return false; +} + +//----- (0049C7C5) -------------------------------------------------------- +bool stru10::FindFaceNormal(RenderVertexSoft *pFaceBounding1, RenderVertexSoft *pFaceBounding2, Vec3_float_ *pRayStart, IndoorCameraD3D_Vec4 *pPortalDataFrustum) +{ + Vec3_float_ ray_dir; // [sp+4h] [bp-48h]@1 + Vec3_float_ pRay2; // [sp+10h] [bp-3Ch]@1 + + ray_dir.x = pFaceBounding1->vWorldPosition.x - pRayStart->x;//get ray for cmera to bounding1 + ray_dir.y = pFaceBounding1->vWorldPosition.y - pRayStart->y; + ray_dir.z = pFaceBounding1->vWorldPosition.z - pRayStart->z; + Vec3_float_::Cross(&ray_dir, &pRay2, pFaceBounding2->vWorldPosition.x - pFaceBounding1->vWorldPosition.x, + pFaceBounding2->vWorldPosition.y - pFaceBounding1->vWorldPosition.y, + pFaceBounding2->vWorldPosition.z - pFaceBounding1->vWorldPosition.z); + + float sqr_mag = pRay2.x * pRay2.x + pRay2.y * pRay2.y + pRay2.z * pRay2.z; + if (fabsf(sqr_mag) > 1e-6f) + { + float inv_mag = 1.0f / sqrtf(sqr_mag); + pRay2.x *= inv_mag; + pRay2.y *= inv_mag; + pRay2.z *= inv_mag; + pRay2.Normalize(); + + pPortalDataFrustum->x = pRay2.x; + pPortalDataFrustum->y = pRay2.y; + pPortalDataFrustum->z = pRay2.z; + pPortalDataFrustum->dot = pRayStart->z * pRay2.z + pRayStart->y * pRay2.y + pRayStart->x * pRay2.x; + return true; + } + return false; +} + +//----- (0049C8DC) -------------------------------------------------------- +bool stru10::FindFacePlane(RenderVertexSoft *arg0, Vec3_float_ *a2, float *a3) +{ + Vec3_float_ v1; // [sp+8h] [bp-3Ch]@1 + Vec3_float_ v2; // [sp+14h] [bp-30h]@1 + + v1.x = arg0[1].vWorldPosition.x - arg0[0].vWorldPosition.x; + v1.y = arg0[1].vWorldPosition.y - arg0[0].vWorldPosition.y; + v1.z = arg0[1].vWorldPosition.z - arg0[0].vWorldPosition.z; + + Vec3_float_::Cross(&v1, &v2, arg0[2].vWorldPosition.x - arg0[1].vWorldPosition.x, + arg0[2].vWorldPosition.y - arg0[1].vWorldPosition.y, + arg0[2].vWorldPosition.z - arg0[1].vWorldPosition.z); + + float sqr_mag = v2.x * v2.x + v2.y * v2.y + v2.z * v2.z; + if (fabsf(sqr_mag) > 1e-6f) + { + //v2.Normalize(); + float inv_mag = 1.0f / sqrtf(sqr_mag); + v2.x *= inv_mag; + v2.y *= inv_mag; + v2.z *= inv_mag; + + a2->x = v2.x; + a2->y = v2.y; + a2->z = v2.z; + *a3 = -(arg0[0].vWorldPosition.z * v2.z + arg0[0].vWorldPosition.y * v2.y + arg0[0].vWorldPosition.x * v2.x); + return true; + } + return false; +} diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/stru10.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/stru10.h Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,23 @@ +#pragma once + + +/* 127 */ +#pragma pack(push, 1) +struct stru10 +{ + stru10(); + virtual ~stru10(); + char _49C5DA(struct BLVFace *pFace, struct RenderVertexSoft *pVertices, unsigned int *pNumVertices, struct IndoorCameraD3D_Vec4 *a5, struct RenderVertexSoft *pOutBounding); + bool CalcPortalShape(struct BLVFace *pFace, struct IndoorCameraD3D_Vec4 *pPortalDataFrustum, struct RenderVertexSoft *pOutBounding); + char _49C720(struct RenderVertexSoft *pFaceBounding, struct IndoorCameraD3D_Vec4 *pPortalDataFrustum); + bool FindFaceNormal(struct RenderVertexSoft *pFaceBounding1, struct RenderVertexSoft *pFaceBounding2, struct Vec3_float_ *pRayStart, struct IndoorCameraD3D_Vec4 *pPortalDataFrustum); + bool FindFacePlane(struct RenderVertexSoft *face, struct Vec3_float_ *out_normal, float *out_distance); + bool CalcFaceBounding(struct BLVFace *pFace, struct RenderVertexSoft *pFaceLimits, unsigned int uNumVertices, struct RenderVertexSoft *pOutBounding); + void CalcPolygonLimits(struct BLVFace *pFace, struct RenderVertexSoft pOutVertices[4]); + void _49CE9E(struct BLVFace *pFace, struct RenderVertexSoft *pVertices, unsigned int uNumVertices, RenderVertexSoft *pOutLimits); + + + void ( ***vdestructor_ptr)(stru10 *, bool); + int bDoNotDrawPortalFrustum; +}; +#pragma pack(pop) diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/stru9.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/stru9.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,457 @@ +#define _CRTDBG_MAP_ALLOC +#include +#include + +#define _CRT_SECURE_NO_WARNINGS +#include "stru9.h" +#include "IndoorCameraD3D.h" + +#include "mm7_data.h" + + + +//----- (00498377) -------------------------------------------------------- +bool stru9::_498377(struct RenderVertexSoft *pPortalBounding, unsigned int uNumVertices, struct IndoorCameraD3D_Vec4 *pVertices, struct RenderVertexSoft *pVertices2, unsigned int *pOutNumVertices) +{ + int result; // eax@7 + //unsigned int *v7; // ebx@7 + //char *v8; // esi@8 + RenderVertexSoft *v9; // ecx@9 + //double v10; // st7@12 + //double v11; // st6@12 + //RenderVertexSoft *v12; // esi@13 + //int v13; // ecx@25 + //VertexBuffer *v14; // edx@26 + //char *v15; // eax@26 + //unsigned int i; // ecx@26 + //int v17; // [sp+0h] [bp-28h]@9 + //char *v18; // [sp+10h] [bp-18h]@8 + RenderVertexSoft *v19; // [sp+14h] [bp-14h]@0 + //RenderVertexSoft *v20; // [sp+18h] [bp-10h]@0 + signed int v21; // [sp+1Ch] [bp-Ch]@7 + //RenderVertexSoft *a2; // [sp+20h] [bp-8h]@8 + //stru9 *thisa; // [sp+24h] [bp-4h]@1 +// signed int a3a; // [sp+38h] [bp+10h]@12 + //int a3b; // [sp+38h] [bp+10h]@25 + + //__debugbreak(); + //thisa = this; + return true; + + static RenderVertexSoft static_AE3FB4; + /*static bool __init_flag1 = false; + if (!__init_flag1) + { + __init_flag1 = true; + + static_AE3FB4.flt_2C = 0.0; + }*/ + + static stru312 static_AE3FA4; // idb + /*static bool __init_flag2 = false; + if (!__init_flag2) + { + __init_flag2 = true; + + //stru312::stru312(&static_AE3FA4); + }*/ + + static VertexBuffer static_AE33A0; // idb + /*static bool __init_flag3 = false; + if (!__init_flag3) + { + __init_flag3 = true; + + //VertexBuffer::VertexBuffer(&static_AE33A0); + }*/ + + result = false; + //v7 = pOutNumVertices; + v21 = 0; + if ( (signed int)uNumVertices <= 0 ) + { + *pOutNumVertices = 0; + return true; + } + //a2 = a1; + //v8 = (char *)&a3->y; + //v18 = (char *)&a3->y; + //do + for (uint j = 0; j < uNumVertices; j++ ) + { + //v17 = result + 1; + result = j; + v9 = &pPortalBounding[(j + 1) % (signed int)uNumVertices]; + if ( pPortalBounding->vWorldPosition.x != v9->vWorldPosition.x + || pPortalBounding->vWorldPosition.y != v9->vWorldPosition.y + || pPortalBounding->vWorldPosition.z != v9->vWorldPosition.z ) + { + //v10 = a3->z; + //v11 = a3->y; + ++v21; + //result = 0; + static_AE33A0.uNumVertices = 0; + //a3a = 0; + static_AE3FA4.x = pVertices->x; + static_AE3FA4.y = pVertices->y; + static_AE3FA4.z = pVertices->z; + if ( (signed int)*pOutNumVertices <= 0 ) + { + *pOutNumVertices = 0; + return true; + } + //do + for ( int i = 0; i < (signed int)*pOutNumVertices; i++ ) + { + //v12 = &pVertices[result]; + if ( result ) + { + if ( _4989E1(&pVertices2[i], &pVertices2[i], pPortalBounding, &static_AE3FA4) + && _498774(&pVertices2[i], &pVertices2[i], pPortalBounding, &static_AE3FA4, &static_AE3FB4) ) + AddVertex(&static_AE33A0, &static_AE3FB4); + } + else + { + v19 = &pVertices2[i]; + } + //v20 = v12; + if ( AreVectorsCollinear(&pVertices2[i], pPortalBounding, &static_AE3FA4) ) + AddVertex(&static_AE33A0, &pVertices2[i]); + //pOutNumVertices = pOutNumVertices; + //a3a++; + } + //while ( a3a < (signed int)*pOutNumVertices ); + if ( !static_AE33A0.uNumVertices ) + { + *pOutNumVertices = 0; + return true; + } + if ( _4989E1(&pVertices2[result], v19, pPortalBounding, &static_AE3FA4) + && _498774(&pVertices2[result], v19, pPortalBounding, &static_AE3FA4, &static_AE3FB4) ) + AddVertex(&static_AE33A0, &static_AE3FB4); + + for (uint i = 0; i < static_AE33A0.uNumVertices; ++i) + { + pVertices2[i].vWorldPosition.x = static_AE33A0.pVertices[i].vWorldPosition.x; + pVertices2[i].vWorldPosition.y = static_AE33A0.pVertices[i].vWorldPosition.y; + pVertices2[i].vWorldPosition.z = static_AE33A0.pVertices[i].vWorldPosition.z; + pVertices2[i].u = static_AE33A0.pVertices[i].u; + pVertices2[i].v = static_AE33A0.pVertices[i].v; + } + + //v13 = static_AE33A0.uNumVertices; + /*a3b = 0; + if ( static_AE33A0.uNumVertices > 0 ) + { + v14 = &static_AE33A0; + v15 = (char *)&pVertices->vWorldPosition.y; + for ( i = (char *)&static_AE33A0.pVertices[0].vWorldPosition.y - (char *)pVertices; + ; + i = (char *)&static_AE33A0.pVertices[0].vWorldPosition.y - (char *)pVertices ) + { + ++a3b; + pVertices->vWorldPosition.x = v14->pVertices[0].vWorldPosition.x; + v14 = (VertexBuffer *)((char *)v14 + 48); + pVertices->vWorldPosition.y = *(float *)&v15[(char *)&static_AE33A0 - (char *)pVertices]; + pVertices->vWorldPosition.z = *(float *)&v15[i]; + pVertices->u = *(float *)&v15[(char *)&static_AE33A0.pVertices[0]._rhw - (char *)pVertices]; + pVertices->v = *(float *)&v15[(char *)&static_AE33A0.pVertices[0].u - (char *)pVertices]; + //static_AE33A0.uNumVertices = static_AE33A0.uNumVertices; + v15 += 48; + if ( a3b >= static_AE33A0.uNumVertices ) + break; + } + }*/ + + //v7 = pOutNumVertices; + //a3->y = a3->y; + *pOutNumVertices = static_AE33A0.uNumVertices; + } + //result = v17; + ++pPortalBounding; + pVertices++; + //v18 = (char *)&a3->y; + } + //while ( v17 < (signed int)uNumVertices ); + if ( v21 < 3 ) + *pOutNumVertices = 0; + return true; +} + + +//----- (004985FB) -------------------------------------------------------- +bool stru9::CalcPortalShape(struct RenderVertexSoft *a1, signed int a2, struct RenderVertexSoft *pVertices, unsigned int *pOutNumVertices, struct Vec3_float_ *a5, float a6, char *a7, int unused) +{ + //RenderVertexSoft *v9; // ecx@1 + //Vec3_float_ *v10; // esi@1 + //char *v11; // ebx@1 + //RenderVertexSoft *pVertices; // edi@1 + double pLinelength1; // st7@1 + //bool result; // eax@4 + signed int v15; // edx@9 + RenderVertexSoft *pLineEnd; // ecx@9 + double pLinelength2; // st7@9 + double t; // st6@12 + signed int v19; // [sp+Ch] [bp-Ch]@7 + //float v20; // [sp+10h] [bp-8h]@1 + bool v21; // [sp+14h] [bp-4h]@2 + + //v9 = a1; + //v10 = a5; + //v11 = (char *)&a1->vWorldPosition.z; + RenderVertexSoft* pLineStart = &a1[0]; + //pVertices = a3; + pLinelength1 = a5->x * a1[0].vWorldPosition.x + a1[0].vWorldPosition.y * a5->y + a1[0].vWorldPosition.z * a5->z; + //v20 = v13; + v21 = pLinelength1 >= a6; + + *pOutNumVertices = 0; + if ( a2 <= 0 ) + return false; + v19 = 1; + + while ( 1 ) + { + if ( v21 ) + { + //++pVertices; + memcpy(pVertices, pLineStart, sizeof(RenderVertexSoft)); + ++*pOutNumVertices; + //v10 = a5; + pVertices++; + //v9 = a1; + } + v15 = 0; + pLineEnd = &a1[v19 % a2]; + pLinelength2 = a5->x * pLineEnd->vWorldPosition.x + pLineEnd->vWorldPosition.y * a5->y + pLineEnd->vWorldPosition.z * a5->z; + if ( pLinelength2 >= a6 ) + v15 = 1; + + if ( v21 != v15 ) + { + t = (a6 - pLinelength1) / (pLinelength2 - pLinelength1); + pVertices->vWorldPosition.x = pLineStart->vWorldPosition.x + (pLineEnd->vWorldPosition.x - pLineStart->vWorldPosition.x) * t; + pVertices->vWorldPosition.y = pLineStart->vWorldPosition.y + (pLineEnd->vWorldPosition.y - pLineStart->vWorldPosition.y) * t; + pVertices->vWorldPosition.z = pLineStart->vWorldPosition.z + (pLineEnd->vWorldPosition.z - pLineStart->vWorldPosition.z) * t; + pVertices->u = pLineStart->u + (pLineEnd->u - pLineStart->u) * t; + pVertices->v = pLineStart->v + (pLineEnd->v - pLineStart->v) * t; + ++pVertices; + //a3 = pVertices; + ++*pOutNumVertices; + *a7 = 1; + } + + pLineStart++; + v21 = v15; + pLinelength1 = pLinelength2; + if ( v19 >= a2 ) + break; + //v9 = a1; + v19++; + } + + return *pOutNumVertices >= 3; +} + +//----- (00498737) -------------------------------------------------------- +void stru9::AddVertex(struct VertexBuffer *pVertexBuffer, struct RenderVertexSoft *pVertex) +{ +// __debugbreak(); + RenderVertexSoft *v3; // eax@1 + + v3 = &pVertexBuffer->pVertices[pVertexBuffer->uNumVertices]; + v3->vWorldPosition.x = pVertex->vWorldPosition.x; + v3->vWorldPosition.y = pVertex->vWorldPosition.y; + v3->vWorldPosition.z = pVertex->vWorldPosition.z; + v3->u = pVertex->u; + v3->v = pVertex->v; + ++pVertexBuffer->uNumVertices; +} + +//----- (00498774) -------------------------------------------------------- +bool stru9::_498774(struct RenderVertexSoft *a1, struct RenderVertexSoft *a2, struct RenderVertexSoft *a3, struct stru312 *a4, struct RenderVertexSoft *a5) +{ + RenderVertexSoft *v6; // ecx@5 + int result; // eax@5 + double v8; // st7@5 + __int16 v9; // fps@5 + double v10; // st7@6 + double v11; // st6@8 + double v12; // st6@18 + char v13; // c0@24 + char v14; // c2@24 + char v15; // c3@24 + float a1a; // [sp+10h] [bp+8h]@5 + + __debugbreak(); + + static stru312 static_AE3388; + static stru312 static_AE3378; + + v6 = a1; + static_AE3378.x = a1->vWorldPosition.x - a3->vWorldPosition.x; + static_AE3378.y = a1->vWorldPosition.y - a3->vWorldPosition.y; + HIWORD(result) = HIWORD(a4); + static_AE3378.z = a1->vWorldPosition.z - a3->vWorldPosition.z; + static_AE3388.x = a2->vWorldPosition.x - a1->vWorldPosition.x; + static_AE3388.y = a2->vWorldPosition.y - a1->vWorldPosition.y; + static_AE3388.z = a2->vWorldPosition.z - a1->vWorldPosition.z; + a1a = static_AE3388.x * a4->x + static_AE3388.z * a4->z + static_AE3388.y * a4->y; + v8 = static_AE3378.x * a4->x + static_AE3378.z * a4->z + static_AE3378.y * a4->y; + //UNDEF(v9); + if ( a1a != 0.0 ) + { + v10 = -(v8 / a1a); + if ( a1a <= 0.0 ) + { + if ( v10 <= 0.0 ) + v12 = 0.0; + else + v12 = v10; + if ( v12 <= 1.0 ) + { + if ( v10 <= 0.0 ) + v10 = (float)0.0; + } + else + v10 = 1.0; + } + else + { + if ( v10 >= 1.0 ) + v11 = 1.0; + else + v11 = v10; + if ( v11 >= 0.0 ) + { + if ( v10 >= 1.0 ) + v10 = (float)1.0; + } + else + v10 = 0.0; + } + result = (bool)a5; + a5->vWorldPosition.x = (a2->vWorldPosition.x - v6->vWorldPosition.x) * v10 + v6->vWorldPosition.x; + a5->vWorldPosition.y = (a2->vWorldPosition.y - v6->vWorldPosition.y) * v10 + v6->vWorldPosition.y; + a5->vWorldPosition.z = (a2->vWorldPosition.z - v6->vWorldPosition.z) * v10 + v6->vWorldPosition.z; + a5->u = (a2->u - v6->u) * v10 + v6->u; + a5->v = (a2->v - v6->v) * v10 + v6->v; + return 1; + } + v13 = v8 < 0.0; + v14 = 0; + v15 = v8 == 0.0; + // BYTE1(result) = HIBYTE(v9); + if ( v8 < 0.0 ) + return 1; + return 0; +} +// AE3398: using guessed type char static_init_flag__AE3388_bit1__AE3378_bit2; + +//----- (0049895A) -------------------------------------------------------- +bool stru9::AreVectorsCollinear(struct RenderVertexSoft *a1, struct RenderVertexSoft *a2, struct stru312 *a3) +{ + static stru312 static_F942A0; + + static_F942A0.x = a1->vWorldPosition.x - a2->vWorldPosition.x; + static_F942A0.y = a1->vWorldPosition.y - a2->vWorldPosition.y; + static_F942A0.z = a1->vWorldPosition.z - a2->vWorldPosition.z; + + static float flt_F942B4 = static_F942A0.z * a3->z + static_F942A0.y * a3->y + static_F942A0.x * a3->x; + if (flt_F942B4 >= 0) + return true; + return false; +} + + +//----- (004989E1) -------------------------------------------------------- +bool stru9::_4989E1(struct RenderVertexSoft *a1, struct RenderVertexSoft *a2, struct RenderVertexSoft *a3, struct stru312 *a4) +{ + bool r1; + bool r2; + + r1 = AreVectorsCollinear(a1, a3, a4); + r2 = AreVectorsCollinear(a2, a3, a4); + return !r1 && r2 == 1 || + r1 == 1 && !r2; +} + +//----- (004980B9) -------------------------------------------------------- +bool stru9::_4980B9(RenderVertexSoft *a1, unsigned int uNumVertices, float a3, float a4, float a5, RenderVertexSoft *pOutVertices, unsigned int *pOutNumVertices) +{ + RenderVertexSoft *v12; // ecx@9 + double v13; // st7@12 + double v14; // st6@12 + double v15; // st5@12 + signed int v25; // [sp+18h] [bp-Ch]@7 + + static RenderVertexSoft stru_AE4BFC; + static stru312 static_sub_4980B9_stru_AE4BEC; // idb + static VertexBuffer static_sub_4980B9_stru_AE3FE8; // idb + + v25 = 0; + if (uNumVertices <= 0) + { + *pOutNumVertices = 0; + return true; + } + + for (uint i = 0; i < uNumVertices; ++i) + { + v12 = &a1[(i + 1) % uNumVertices]; + if (a1[i].vWorldPosition.x != v12->vWorldPosition.x || + a1[i].vWorldPosition.y != v12->vWorldPosition.y || + a1[i].vWorldPosition.z!= v12->vWorldPosition.z) + { + v13 = v12->vWorldPosition.x - a1[i].vWorldPosition.x; + v14 = v12->vWorldPosition.y - a1[i].vWorldPosition.y; + v15 = v12->vWorldPosition.z - a1[i].vWorldPosition.z; + ++v25; + + static_sub_4980B9_stru_AE3FE8.uNumVertices = 0; + static_sub_4980B9_stru_AE4BEC.x = a4 * v15 - v14 * a5; + static_sub_4980B9_stru_AE4BEC.y = v13 * a5 - v15 * a3; + static_sub_4980B9_stru_AE4BEC.z = v14 * a3 - v13 * a4; + if (*pOutNumVertices == 0) + return true; + + for (uint j = 0; j < *pOutNumVertices; ++j) + { + if (j) + { + if (_4989E1(&pOutVertices[j - 1], &pOutVertices[j], &a1[i], &static_sub_4980B9_stru_AE4BEC) && + _498774(&pOutVertices[j - 1], &pOutVertices[j], &a1[i], &static_sub_4980B9_stru_AE4BEC, &stru_AE4BFC)) + AddVertex(&static_sub_4980B9_stru_AE3FE8, &stru_AE4BFC); + } + + if (AreVectorsCollinear(&pOutVertices[j], &a1[i], &static_sub_4980B9_stru_AE4BEC)) + AddVertex(&static_sub_4980B9_stru_AE3FE8, &pOutVertices[j]); + } + + if (!static_sub_4980B9_stru_AE3FE8.uNumVertices) + { + *pOutNumVertices = 0; + return true; + } + if (_4989E1(&pOutVertices[*pOutNumVertices - 1], &pOutVertices[0], &a1[i], &static_sub_4980B9_stru_AE4BEC) && + _498774(&pOutVertices[*pOutNumVertices - 1], &pOutVertices[0], &a1[i], &static_sub_4980B9_stru_AE4BEC, &stru_AE4BFC) ) + AddVertex(&static_sub_4980B9_stru_AE3FE8, &stru_AE4BFC); + + for (uint j = 0; j < static_sub_4980B9_stru_AE3FE8.uNumVertices; ++j) + { + pOutVertices[j].vWorldPosition.y = static_sub_4980B9_stru_AE3FE8.pVertices[j].vWorldPosition.x; + pOutVertices[j].vWorldPosition.y = static_sub_4980B9_stru_AE3FE8.pVertices[j].vWorldPosition.y; + pOutVertices[j].vWorldPosition.z = static_sub_4980B9_stru_AE3FE8.pVertices[j].vWorldPosition.z; + pOutVertices[j].u = static_sub_4980B9_stru_AE3FE8.pVertices[j].u; + pOutVertices[j].v = static_sub_4980B9_stru_AE3FE8.pVertices[j].v; + } + *pOutNumVertices = static_sub_4980B9_stru_AE3FE8.uNumVertices; + } + } + + if (v25 < 3) + *pOutNumVertices = 0; + + return true; +} +// AE4C2C: using guessed type char static_sub_4980B9_byte_AE4C2C_init_flag; \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Engine/Graphics/stru9.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/stru9.h Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,63 @@ +#pragma once +#include "Render.h" + +/* 341 */ +#pragma pack(push, 1) +struct VertexBuffer +{ + //----- (0049835A) -------------------------------------------------------- + inline VertexBuffer() + { + for (unsigned int i = 0; i < 64; ++i) + pVertices[i].flt_2C = 0.0f; + + uNumVertices = 0; + } + + + RenderVertexSoft pVertices[64]; + int uNumVertices; +}; +#pragma pack(pop) + + + + +/* 342 */ +#pragma pack(push, 1) +struct stru312 +{ + //----- (004BE6D1) -------------------------------------------------------- + inline stru312() + { + } + + float x; + float y; + float z; + char field_C; + char pad[3]; +}; +#pragma pack(pop) + + + +/* 126 */ +#pragma pack(push, 1) +struct stru9 +{ + //----- (00498093) -------------------------------------------------------- + inline stru9() + {} + + bool _4980B9(struct RenderVertexSoft *a1, unsigned int uNumVertices, float a3, float a4, float a5, struct RenderVertexSoft *pOutVertices, unsigned int *pOutNumVertices); + bool _498377(struct RenderVertexSoft *pPortalBounding, unsigned int uNumVertices, struct IndoorCameraD3D_Vec4 *pVertices, struct RenderVertexSoft *pVertices2, unsigned int *pOutNumVertices); + bool CalcPortalShape(struct RenderVertexSoft *a1, signed int a2, struct RenderVertexSoft *pVertices, unsigned int *pOutNumVertices, struct Vec3_float_ *a5, float a6, char *a7, int unused); + void AddVertex(struct VertexBuffer *pVertexBuffer, struct RenderVertexSoft *pVertex); + bool _498774(struct RenderVertexSoft *a1, struct RenderVertexSoft *a2, struct RenderVertexSoft *a3, struct stru312 *a4, struct RenderVertexSoft *a5); + bool AreVectorsCollinear(struct RenderVertexSoft *a1, struct RenderVertexSoft *a2, struct stru312 *a3); + bool _4989E1(struct RenderVertexSoft *a1, struct RenderVertexSoft *a2, struct RenderVertexSoft *a3, struct stru312 *a4); + + void ( ***vdestructor_ptr)(stru9 *, bool); +}; +#pragma pack(pop) \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Events.cpp --- a/Events.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/Events.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -6,15 +6,15 @@ #include "ErrorHandling.h" -#include "Weather.h" -#include "Texture.h" +#include "Engine/Graphics/Weather.h" +#include "Engine/Graphics/Texture.h" #include "mm7_data.h" #include "MediaPlayer.h" #include "Mouse.h" #include "MapInfo.h" #include "Game.h" -#include "Render.h" +#include "Engine/Graphics/Render.h" #include "GUIWindow.h" #include "GUIProgressBar.h" #include "SpriteObject.h" @@ -25,8 +25,8 @@ #include "Party.h" #include "OurMath.h" #include "AudioPlayer.h" -#include "Indoor.h" -#include "Viewport.h" +#include "Engine/Graphics/Indoor.h" +#include "Engine/Graphics/Viewport.h" #include "texts.h" #include "stru123.h" #include "stru159.h" @@ -34,10 +34,10 @@ #include "Events2D.h" #include "UI\UIHouses.h" #include "MM7.h" -#include "Level/Decoration.h" +#include "Engine/Graphics/Level/Decoration.h" #include "LuaVM.h" #include "Log.h" -#include "DecorationList.h" +#include "Engine/Graphics/DecorationList.h" std::array pSomeOtherEVT_Events; diff -r 7b076fe64f23 -r 5abd8fc8f1c6 GUIFont.cpp --- a/GUIFont.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/GUIFont.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -9,7 +9,7 @@ #include "LOD.h" #include "GUIFont.h" #include "GUIWindow.h" -#include "Render.h" +#include "Engine/Graphics/Render.h" #include "mm7_data.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 GUIProgressBar.cpp --- a/GUIProgressBar.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/GUIProgressBar.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -7,7 +7,7 @@ #include "ErrorHandling.h" #include "LOD.h" #include "Party.h" -#include "Render.h" +#include "Engine/Graphics/Render.h" #include "IconFrameTable.h" #include "mm7_data.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 GUIProgressBar.h --- a/GUIProgressBar.h Wed Sep 17 17:35:13 2014 +0600 +++ b/GUIProgressBar.h Thu Sep 18 17:38:54 2014 +0600 @@ -1,5 +1,5 @@ #pragma once -#include "Texture.h" +#include "Engine/Graphics/Texture.h" /* 278 */ diff -r 7b076fe64f23 -r 5abd8fc8f1c6 GUIWindow.cpp --- a/GUIWindow.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/GUIWindow.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -14,7 +14,7 @@ #include "Timer.h" #include "AudioPlayer.h" #include "Mouse.h" -#include "Viewport.h" +#include "Engine/Graphics/Viewport.h" #include "StorylineTextTable.h" #include "UI\UIHouses.h" #include "UI\UIBooks.h" @@ -22,14 +22,14 @@ #include "Autonotes.h" #include "Awards.h" #include "Chest.h" -#include "Outdoor.h" +#include "Engine/Graphics/Outdoor.h" #include "Game.h" #include "IconFrameTable.h" #include "Actor.h" #include "UI\UIArena.h" #include "Events.h" -#include "Level\Decoration.h" +#include "Engine/Graphics/Level\Decoration.h" typedef struct _RGBColor { diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Game.cpp --- a/Game.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/Game.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -3,27 +3,27 @@ #include #define _CRT_SECURE_NO_WARNINGS -#include "Arcomage.h" - -#include "Vis.h" -#include "Weather.h" -#include "LightmapBuilder.h" -#include "DecalBuilder.h" -#include "ParticleEngine.h" +#include "Arcomage\Arcomage.h" + +#include "Engine/Graphics/Vis.h" +#include "Engine/Graphics/Weather.h" +#include "Engine/Graphics/LightmapBuilder.h" +#include "Engine/Graphics/DecalBuilder.h" +#include "Engine/Graphics/ParticleEngine.h" #include "Mouse.h" #include "Keyboard.h" -#include "GammaControl.h" +#include "Engine/Graphics/GammaControl.h" #include "stru6.h" -#include "stru9.h" -#include "stru10.h" +#include "Engine/Graphics/stru9.h" +#include "Engine/Graphics/stru10.h" #include "ErrorHandling.h" #include "Game.h" #include "Party.h" -#include "Viewport.h" +#include "Engine/Graphics/Viewport.h" #include "Timer.h" -#include "Outdoor.h" -#include "Overlays.h" +#include "Engine/Graphics/Outdoor.h" +#include "Engine/Graphics/Overlays.h" #include "AudioPlayer.h" #include "LOD.h" #include "GUIWindow.h" @@ -33,27 +33,27 @@ #include "texts.h" #include "GUIFont.h" #include "Log.h" -#include "Lights.h" +#include "Engine/Graphics/Lights.h" #include "CastSpellInfo.h" #include "FrameTableInc.h" #include "Actor.h" #include "GUIProgressBar.h" #include "ObjectList.h" -#include "Level/Decoration.h" -#include "PaletteManager.h" +#include "Engine/Graphics/Level/Decoration.h" +#include "Engine/Graphics/PaletteManager.h" #include "UI\UIHouses.h" #include "UI\UIShops.h" #include "UI\UIPartyCreation.h" #include "SaveLoad.h" #include "SpriteObject.h" #include "mm7.h" -#include "Sprites.h" +#include "Engine/Graphics/Sprites.h" #include "Registry.h" #include "Chest.h" #include "UI\UIGame.h" -#include "DecorationList.h" +#include "Engine/Graphics/DecorationList.h" #include "IconFrameTable.h" #include "PlayerFrameTable.h" #include "MapsLongTimer.h" @@ -61,7 +61,7 @@ #include "FactionTable.h" #include "stru123.h" #include "LuaVM.h" -#include "RenderD3D11.h" +#include "Engine/Graphics/RenderD3D11.h" #include "MMT.h" #include "NewUI\MainMenu.h" #include diff -r 7b076fe64f23 -r 5abd8fc8f1c6 GammaControl.cpp --- a/GammaControl.cpp Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,142 +0,0 @@ -#define _CRTDBG_MAP_ALLOC -#include -#include - -#define _CRT_SECURE_NO_WARNINGS -#include - -#include "GammaControl.h" -#include "Render.h" - -#include "mm7_data.h" - - - -//----- (0044F324) -------------------------------------------------------- -void GammaController::GetRamp() -{ - if (pGammaControl) - ErrD3D(pGammaControl->GetGammaRamp(0, &pDefaultRamp)); - else - MessageBoxW(nullptr, L"Gamma control not active", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\GammaControl.cpp:83", 0); -} - -//----- (0044F377) -------------------------------------------------------- -double GammaController::_44F377(DDGAMMARAMP *a1) -{ - double v2; // st7@1 - unsigned __int16 *v3; // ecx@1 - double v4; // st6@2 - signed int v6; // [sp+0h] [bp-8h]@1 - signed int v7; // [sp+4h] [bp-4h]@1 - - v2 = 0.0; - v6 = 256; - v3 = a1->green; - for ( v7 = 0; v7 < 256; ++v7 ) - { - v4 = ((double)*(v3 - 256) + (double)v3[256] + (double)*v3) * 0.000015259022 * 0.33333334; - if ( v4 == 0.0 ) - --v6; - else - v2 = v2 + (double)v7 * 0.0039215689 / v4; - ++v3; - } - if ( v6 ) - return v2 / (double)v6; - else - return 1.0; -} - -//----- (0044F408) -------------------------------------------------------- -void GammaController::SetGammaRamp(DDGAMMARAMP *pRamp) -{ - if (pGammaControl) - ErrD3D(pGammaControl->SetGammaRamp(0, pRamp)); - else - MessageBoxW(nullptr, L"Gamma control not active", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\GammaControl.cpp:120", 0); -} - -//----- (0044F45B) -------------------------------------------------------- -int GammaController::InitGammaRamp(DDGAMMARAMP *pRamp) -{ - unsigned __int16 *v2; // esi@1 - double v3; // st7@2 - signed __int64 v4; // qax@3 - signed int v6; // [sp+Ch] [bp-4h]@1 - - v2 = pRamp->green; - for ( v6 = 0; v6 < 256; ++v6 ) - { - v3 = (double)v6 * 0.0039215689 * this->fGamma; - if ( v3 >= 1.0 || (v4 = (signed __int64)(v3 * 65535.0), (signed int)v4 > 65535) ) - LODWORD(v4) = 65535; - else if ( (signed int)v4 < 0 ) - LODWORD(v4) = 0; - else - { - if ( (signed int)v4 > 65535 ) - LODWORD(v4) = 65535; - } - v2[256] = v4; - *v2 = v4; - *(v2 - 256) = v4; - ++v2; - } - return v4; -} - -//----- (0044F4D9) -------------------------------------------------------- -void GammaController::Initialize(float gamma) -{ - double v3; // st7@3 - double v4; // st6@4 - - //if (pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || - //pVersion->pVersionInfo.dwMajorVersion != 4) - { - InitializeFromSurface(pRenderer->pFrontBuffer4); - v3 = 2.8; - if ( gamma <= 2.8f ) - v4 = gamma; - else - v4 = 2.8; - if ( v4 >= 0.1f ) - { - if ( gamma <= 2.8f ) - v3 = gamma; - } - else - v3 = 0.1; - this->fGamma = v3; - InitGammaRamp(&this->field_60C); - SetGammaRamp(&this->field_60C); - } -} - -//----- (0044F215) -------------------------------------------------------- -GammaController::GammaController() -{ - static float flt_4D8670_default_gamma = 1.0f; - - pGammaControl = nullptr; - fGamma = flt_4D8670_default_gamma; -} - -//----- (0044F24B) -------------------------------------------------------- -void GammaController::InitializeFromSurface(IDirectDrawSurface4 *a2) -{ - this->pSurface = a2; - if ( this->pGammaControl ) - { - this->pGammaControl->Release(); - this->pGammaControl = 0; - } - if ( pRenderer->IsGammaSupported() ) - { - ErrD3D(a2->QueryInterface(IID_IDirectDrawGammaControl, (LPVOID *)&this->pGammaControl)); - GetRamp(); - memcpy(&this->field_60C, &this->pDefaultRamp, 0x600u); - fGamma = _44F377(&this->field_60C); - } -} \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 GammaControl.h --- a/GammaControl.h Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ -#pragma once -#include "lib\legacy_dx\d3d.h" - -#pragma pack(push, 1) -class GammaController -{ -public: - GammaController(); - inline ~GammaController() {} //----- (0044F22E) - - void Initialize/*_44F4D9*/(float gamma); - - void GetRamp(); - double _44F377(DDGAMMARAMP *a1); - void SetGammaRamp(DDGAMMARAMP *pRamp); - int InitGammaRamp(DDGAMMARAMP *pRamp); - - /*protected*/void InitializeFromSurface(struct IDirectDrawSurface4 *a2); - - - - void ( ***vdestructor_ptr)(GammaController *, bool); - IDirectDrawSurface4 *pSurface; - IDirectDrawGammaControl *pGammaControl; - DDGAMMARAMP pDefaultRamp; - DDGAMMARAMP field_60C; - float fGamma;//field_C0C; -}; -#pragma pack(pop) diff -r 7b076fe64f23 -r 5abd8fc8f1c6 IRender.h --- a/IRender.h Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,169 +0,0 @@ -#pragma once - -#include "lib\legacy_dx\d3d.h" -#include "OSWindow.h" -#include "RenderStruct.h" -#include "VectorTypes.h" - -struct IRender -{ - public: - virtual ~IRender() {} - - virtual bool Initialize(OSWindow *window) = 0; - - virtual void ClearBlack() = 0; - virtual void PresentBlackScreen() = 0; - - virtual void SaveWinnersCertificate(const char *a1) = 0; - virtual void ClearTarget(unsigned int uColor) = 0; - virtual void Present() = 0; - - virtual void _49FD3A_fullscreen() = 0; - virtual bool InitializeFullscreen() = 0; - - virtual void CreateZBuffer() = 0; - virtual void Release() = 0; - - virtual bool SwitchToWindow() = 0; - virtual void RasterLine2D(signed int uX, signed int uY, signed int uZ, signed int uW, unsigned __int16 uColor) = 0; - virtual void ClearZBuffer(int a2, int a3) = 0; - virtual void SetRasterClipRect(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW) = 0; - virtual bool LockSurface_DDraw4(IDirectDrawSurface4 *pSurface, DDSURFACEDESC2 *pDesc, unsigned int uLockFlags) = 0; - virtual void GetTargetPixelFormat(DDPIXELFORMAT *pOut) = 0; - virtual void LockRenderSurface(void **pOutSurfacePtr, unsigned int *pOutPixelsPerRow) = 0; - virtual void UnlockBackBuffer() = 0; - virtual void LockFrontBuffer(void **pOutSurface, unsigned int *pOutPixelsPerRow) = 0; - virtual void UnlockFrontBuffer() = 0; - virtual void RestoreFrontBuffer() = 0; - virtual void RestoreBackBuffer() = 0; - virtual void BltToFront(RECT *pDstRect, IDirectDrawSurface *pSrcSurface, RECT *pSrcRect, unsigned int uBltFlags) = 0; - virtual void BltBackToFontFast(int a2, int a3, RECT *a4) = 0; - virtual void BeginSceneD3D() = 0; - - virtual unsigned int GetActorTintColor(float a2, int tint, int a4, int a5, RenderBillboard *a6) = 0; - - virtual void DrawPolygon(unsigned int uNumVertices, struct Polygon *a3, ODMFace *a4, IDirect3DTexture2 *pTexture) = 0; - virtual void DrawTerrainPolygon(unsigned int uNumVertices, struct Polygon *a4, IDirect3DTexture2 *a5, bool transparent, bool clampAtTextureBorders) = 0; - virtual void DrawIndoorPolygon(unsigned int uNumVertices, struct BLVFace *a3, IDirect3DTexture2 *pHwTex, struct Texture *pTex, int uPackedID, unsigned int uColor, int a8) = 0; - - virtual void MakeParticleBillboardAndPush_BLV(RenderBillboardTransform_local0 *a2, IDirect3DTexture2 *a3, unsigned int uDiffuse, int angle) = 0; - virtual void MakeParticleBillboardAndPush_ODM(RenderBillboardTransform_local0 *a2, IDirect3DTexture2 *a3, unsigned int uDiffuse, int angle) = 0; - - virtual void DrawBillboards_And_MaybeRenderSpecialEffects_And_EndScene() = 0; - virtual void DrawBillboard_Indoor(RenderBillboardTransform_local0 *pSoftBillboard, Sprite *pSprite, int dimming_level) = 0; - virtual void _4A4CC9_AddSomeBillboard(struct stru6_stru1_indoor_sw_billboard *a1, int diffuse) = 0; - virtual void TransformBillboardsAndSetPalettesODM() = 0; - virtual void DrawBillboardList_BLV() = 0; - - virtual void DrawProjectile(float srcX, float srcY, float a3, float a4, float dstX, float dstY, float a7, float a8, IDirect3DTexture2 *a9) = 0; - virtual bool LoadTexture(const char *pName, unsigned int bMipMaps, IDirectDrawSurface4 **pOutSurface, IDirect3DTexture2 **pOutTexture) = 0; - virtual bool MoveSpriteToDevice(Sprite *pSprite) = 0; - - virtual void BeginScene() = 0; - virtual void EndScene() = 0; - virtual void ScreenFade(unsigned int color, float t) = 0; - - virtual void SetTextureClipRect(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW) = 0; - virtual void ResetTextureClipRect() = 0; - virtual void DrawTextureRGB(unsigned int uOutX, unsigned int uOutY, RGBTexture *a4) = 0; - virtual void CreditsTextureScroll(unsigned int pX, unsigned int pY, int move_X, int move_Y, RGBTexture *pTexture) = 0; - virtual void DrawTextureIndexed(unsigned int uX, unsigned int uY, struct Texture *a4) = 0; - - virtual void ZBuffer_Fill_2(signed int a2, signed int a3, struct Texture *pTexture, int a5) = 0; - virtual void DrawMaskToZBuffer(signed int uOutX, unsigned int uOutY, struct Texture *pTexture, int zVal) = 0; - virtual void DrawTextureTransparent(unsigned int uX, unsigned int uY, struct Texture *pTexture) = 0; - virtual void DrawAura(unsigned int a2, unsigned int a3, struct Texture *a4, struct Texture *a5, int a6, int a7, int a8) = 0; - virtual void _4A65CC(unsigned int x, unsigned int y, struct Texture *a4, struct Texture *a5, int a6, int a7, int a8) = 0; - - virtual void DrawTransparentRedShade(unsigned int a2, unsigned int a3, struct Texture *a4) = 0; - virtual void DrawTransparentGreenShade(signed int a2, signed int a3, struct Texture *pTexture) = 0; - virtual void DrawFansTransparent(const RenderVertexD3D3 *vertices, unsigned int num_vertices) = 0; - - virtual void DrawMasked(signed int a2, signed int a3, struct Texture *pTexture, unsigned __int16 mask) = 0; - virtual void GetLeather(unsigned int a2, unsigned int a3, struct Texture *a4, __int16 height) = 0; - - virtual void DrawTextPalette(int x, int y, unsigned char* font_pixels, int a5, unsigned int uFontHeight, unsigned __int16 *pPalette, int a8) = 0; - virtual void DrawText(signed int uOutX, signed int uOutY, unsigned __int8 *pFontPixels, unsigned int uCharWidth, unsigned int uCharHeight, unsigned __int16 *pFontPalette, unsigned __int16 uFaceColor, unsigned __int16 uShadowColor) = 0; - - virtual void FillRectFast(unsigned int uX, unsigned int uY, unsigned int uWidth, unsigned int uHeight, unsigned int uColor16) = 0; - virtual void _4A6DF5(unsigned __int16 *pBitmap, unsigned int uBitmapPitch, struct Vec2_int_ *pBitmapXY, void *pTarget, unsigned int uTargetPitch, Vec4_int_ *a7) = 0; - virtual void DrawTranslucent(unsigned int a2, unsigned int a3, struct Texture *a4) = 0; - - virtual void DrawBuildingsD3D() = 0; - - virtual void DrawIndoorSky(unsigned int uNumVertices, unsigned int uFaceID = 0) = 0; - virtual void DrawOutdoorSkyD3D() = 0; - virtual void DrawOutdoorSkyPolygon(unsigned int uNumVertices, struct Polygon *pSkyPolygon, IDirect3DTexture2 *pTexture) = 0; - virtual void DrawIndoorSkyPolygon(signed int uNumVertices, struct Polygon *pSkyPolygon, IDirect3DTexture2 *pTexture) = 0; - - virtual void PrepareDecorationsRenderList_ODM() = 0; - virtual void DrawSpriteObjects_ODM() = 0; - - virtual void RenderTerrainD3D() = 0; - - virtual void ChangeBetweenWinFullscreenModes() = 0; - virtual bool AreRenderSurfacesOk() = 0; - virtual bool IsGammaSupported() = 0; - - virtual void SaveScreenshot(const char *pFilename, unsigned int width, unsigned int height) = 0; - virtual void PackScreenshot(unsigned int width, unsigned int height, void *out_data, unsigned int data_size, unsigned int *screenshot_size) = 0; - virtual void SavePCXScreenshot() = 0; - - virtual int _46А6АС_GetActorsInViewport(int pDepth) = 0; - - virtual void BeginLightmaps() = 0; - virtual void EndLightmaps() = 0; - virtual void BeginLightmaps2() = 0; - virtual void EndLightmaps2() = 0; - virtual bool DrawLightmap(struct Lightmap *pLightmap, struct Vec3_float_ *pColorMult, float z_bias) = 0; - - virtual void BeginDecals() = 0; - virtual void EndDecals() = 0; - virtual void DrawDecal(struct Decal *pDecal, float z_bias) = 0; - - virtual void do_draw_debug_line_d3d(const RenderVertexD3D3 *pLineBegin, signed int sDiffuseBegin, const RenderVertexD3D3 *pLineEnd, signed int sDiffuseEnd, float z_stuff) = 0; - virtual void DrawLines(const RenderVertexD3D3 *vertices, unsigned int num_vertices) = 0; - - virtual void DrawSpecialEffectsQuad(const RenderVertexD3D3 *vertices, IDirect3DTexture2 *texture) = 0; - - virtual void am_Blt_Copy(RECT *pSrcRect, POINT *pTargetXY, int a3) = 0; - virtual void am_Blt_Chroma(RECT *pSrcRect, POINT *pTargetPoint, int a3, int blend_mode) = 0; - - - - - - - - - - int *pActiveZBuffer; - IDirectDraw4 *pDirectDraw4; - IDirectDrawSurface4 *pFrontBuffer4; - IDirectDrawSurface4 *pBackBuffer4; - void *pTargetSurface; - unsigned int uTargetSurfacePitch; - unsigned int bUseColoredLights; - unsigned int bTinting; - unsigned int bUsingSpecular; - uint32_t uFogColor; - unsigned int pHDWaterBitmapIDs[7]; - int hd_water_current_frame; - int hd_water_tile_id; - void (*pBeforePresentFunction)(); - uint32_t bFogEnabled; - RenderBillboardD3D pBillboardRenderListD3D[1000]; - unsigned int uNumBillboardsToDraw; - - virtual void WritePixel16(int x, int y, unsigned __int16 color) = 0; - virtual unsigned __int16 ReadPixel16(int x, int y) = 0; - - virtual void ToggleTint() = 0; - virtual void ToggleColoredLights() = 0; - - virtual unsigned int GetRenderWidth() = 0; - virtual unsigned int GetRenderHeight() = 0; - - virtual void Sub01() = 0; -}; \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Indoor.cpp --- a/Indoor.cpp Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6446 +0,0 @@ -#define _CRTDBG_MAP_ALLOC -#include -#include - -#define _CRT_SECURE_NO_WARNINGS -#include "ErrorHandling.h" -#include "ZlibWrapper.h" - -#include "LightmapBuilder.h" -#include "DecalBuilder.h" -#include "stru9.h" -#include "stru10.h" -#include "stru367.h" - -#include "Outdoor.h" -#include "SpriteObject.h" -#include "Events.h" -#include "Game.h" -#include "Viewport.h" -#include "Timer.h" -#include "Party.h" -#include "OurMath.h" -#include "LOD.h" -#include "DecorationList.h" -#include "ObjectList.h" -#include "Actor.h" -#include "Chest.h" -#include "GUIProgressBar.h" -#include "stru123.h" -#include "AudioPlayer.h" -#include "Log.h" -#include "TurnEngine.h" -#include "PaletteManager.h" -#include "Lights.h" - -#include "MM7.h" -#include "Sprites.h" -#include "stru6.h" -#include "ParticleEngine.h" -#include "texts.h" -#include "GUIWindow.h" -#include "Level/Decoration.h" -#include "Overlays.h" - - - -IndoorLocation *pIndoor = new IndoorLocation; -BLVRenderParams *pBLVRenderParams = new BLVRenderParams; - - -LEVEL_TYPE uCurrentlyLoadedLevelType = LEVEL_null; - -stru320 stru_F8AD28; // idb -stru337 stru_F81018; -BspRenderer_PortalViewportData stru_F8A590; -BspRenderer *pBspRenderer = new BspRenderer; // idb -stru141_actor_collision_object stru_721530; -std::array stru_F83B80; - - - -unsigned __int16 pDoorSoundIDsByLocationID[78] = -{ - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 404, 302, 306, 308, 304, 308, 302, 400, 302, 300, - 308, 308, 306, 308, 308, 304, 300, 404, 406, 300, 400, 406, 404, - 306, 302, 408, 304, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 404, 304, - 400, 300, 300, 404, 304, 400, 300, 300, 404, 304, 400, 300, 300 -}; - - -std::array _4E6BDC_loc_names= - { - "mdt12.blv", - "d18.blv", - "mdt14.blv", - "d37.blv", - "mdk01.blv", - "mdt01.blv", - "mdr01.blv", - "mdt10.blv", - "mdt09.blv", - "mdt15.blv", - "mdt11.blv" - }; - - -//----- (0043F39E) -------------------------------------------------------- -void __fastcall PrepareDrawLists_BLV() -{ - int v5; // eax@4 - unsigned int v7; // ebx@8 - BLVSector *v8; // esi@8 - - pBLVRenderParams->Reset(); - pMobileLightsStack->uNumLightsActive = 0; - //uNumMobileLightsApplied = 0; - uNumDecorationsDrawnThisFrame = 0; - uNumSpritesDrawnThisFrame = 0; - uNumBillboardsToDraw = 0; - - if ( !byte_4D864C || !(pGame->uFlags & 0x1000) ) // lightspot around party - { - //v2 = pParty->flt_TorchlightColorB + 6.7553994e15; - //v11 = LOBYTE(v2); - v5 = 800; - if (pParty->TorchlightActive()) - v5 *= pParty->pPartyBuffs[PARTY_BUFF_TORCHLIGHT].uPower; - //LOBYTE(v1) = _4E94D0_light_type; - //v4 = pParty->flt_TorchlightColorR + 6.7553994e15; - //v3 = pParty->flt_TorchlightColorG + 6.7553994e15; - pMobileLightsStack->AddLight(pGame->pIndoorCameraD3D->vPartyPos.x, - pGame->pIndoorCameraD3D->vPartyPos.y, - pGame->pIndoorCameraD3D->vPartyPos.z, - pBLVRenderParams->uPartySectorID, - v5, - floorf(pParty->flt_TorchlightColorR + 0.5f), - floorf(pParty->flt_TorchlightColorG + 0.5f), - floorf(pParty->flt_TorchlightColorB + 0.5f), - _4E94D0_light_type); - } - PrepareBspRenderList_BLV(); - PrepareItemsRenderList_BLV(); - PrepareActorRenderList_BLV(); - - for (uint i = 0; i < pBspRenderer->uNumVisibleNotEmptySectors; ++i) - { - v7 = pBspRenderer->pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[i]; - v8 = &pIndoor->pSectors[pBspRenderer->pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[i]]; - - for (uint j = 0; j < v8->uNumDecorations; ++j) - PrepareDecorationsRenderList_BLV(v8->pDecorationIDs[j], v7); - } - FindBillboardsLightLevels_BLV(); - pGame->PrepareBloodsplats(); -} - -//----- (004407D9) -------------------------------------------------------- -void BLVRenderParams::Reset() -{ - int v7; // eax@1 - - this->field_0_timer_ = pEventTimer->uTotalGameTimeElapsed; - - pGame->pIndoorCameraD3D->debug_flags = 0; - if (viewparams->draw_sw_outlines) - pGame->pIndoorCameraD3D->debug_flags |= BLV_RENDER_DRAW_SW_OUTLINES; - if (viewparams->draw_d3d_outlines) - pGame->pIndoorCameraD3D->debug_flags |= BLV_RENDER_DRAW_D3D_OUTLINES; - - //v2 = a2; - //this->field_0_timer_ = a2->field_0_timer; - //this->uFlags = a2->uFlags; - //this->vPartyPos.x = a2->vPosition.x; - //this->vPartyPos.y = a2->vPosition.y; - //this->vPartyPos.z = a2->vPosition.z; - //v4 = this->vPartyPos.z; - //v5 = this->vPartyPos.y; - //this->sPartyRotY = a2->sRotationY; - //v6 = this->vPartyPos.x; - //this->sPartyRotX = a2->sRotationX; - v7 = pIndoor->GetSector(pGame->pIndoorCameraD3D->vPartyPos.x, - pGame->pIndoorCameraD3D->vPartyPos.y, - pGame->pIndoorCameraD3D->vPartyPos.z); - this->uPartySectorID = v7; - if ( !v7 ) - { - //__debugbreak(); // shouldnt happen, please provide savegame - /*v8 = this->vPartyPos.z; - this->vPartyPos.x = pParty->vPosition.x; - v9 = pParty->vPosition.y; - v10 = this->vPartyPos.x; - this->vPartyPos.y = pParty->vPosition.y;*/ - this->uPartySectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z); - } - //if ( pRenderer->pRenderD3D ) - { - //this->sCosineY = stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationY); - //this->sSineY = stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationY); - //this->sCosineNegX = stru_5C6E00->Cos(-pGame->pIndoorCameraD3D->sRotationX); - //this->sSineNegX = stru_5C6E00->Sin(-pGame->pIndoorCameraD3D->sRotationX); - //this->fCosineY = cos((3.141592653589793 + 3.141592653589793) * (double)pGame->pIndoorCameraD3D->sRotationY * 0.00048828125); - //this->fSineY = sin((3.141592653589793 + 3.141592653589793) * (double)pGame->pIndoorCameraD3D->sRotationY * 0.00048828125); - //this->fCosineNegX = cos((3.141592653589793 + 3.141592653589793) * (double)-pGame->pIndoorCameraD3D->sRotationX * 0.00048828125); - //this->fSineNegX = sin((3.141592653589793 + 3.141592653589793) * (double)-pGame->pIndoorCameraD3D->sRotationX * 0.00048828125); - this->field_64 = pViewport->field_of_view; - - this->uViewportX = pViewport->uScreen_TL_X; - this->uViewportY = pViewport->uScreen_TL_Y; - this->uViewportZ = pViewport->uScreen_BR_X; - this->uViewportW = pViewport->uScreen_BR_Y; - - this->uViewportWidth = uViewportZ - uViewportX + 1; - this->uViewportHeight = uViewportW - uViewportY + 1; - this->uViewportCenterX = (uViewportZ + uViewportX) / 2; - this->uViewportCenterY = (uViewportY + uViewportW) / 2; - } - /*else - { - __debugbreak(); // no sw - this->sCosineY = stru_5C6E00->Cos(-this->sPartyRotY); - this->sSineY = stru_5C6E00->Sin(-this->sPartyRotY); - this->sCosineNegX = stru_5C6E00->Cos(-this->sPartyRotX); - this->sSineNegX = stru_5C6E00->Sin(-this->sPartyRotX); - v17 = cos((double)-this->sPartyRotY * 0.0030664064); - v18 = this->sPartyRotY; - this->fCosineY = v17; - v19 = sin((double)-v18 * 0.0030664064); - v20 = this->sPartyRotX; - this->fSineY = v19; - v21 = cos((double)-v20 * 0.0030664064); - v22 = this->sPartyRotX; - this->fCosineNegX = v21; - this->fSineNegX = sin((double)-v22 * 0.0030664064); - v23 = this->uViewportX; - this->field_64 = a2->field_3C; - v24 = this->uViewportZ; - this->field_70 = this->uViewportZ - v23 + 1; - v25 = this->uViewportW - this->uViewportY + 1; - this->uViewportHeight = v25; - v29 = v25; - v26 = this->field_64; - this->uViewportCenterX = (signed int)(v24 + v23) >> 1; - this->uViewportCenterY = this->uViewportW - ((unsigned __int64)(v26 * (signed __int64)v29) >> 16); - }*/ - //v27 = (unsigned int)(signed __int64)((double)this->uViewportWidth * 0.5 - // / tan((double)(v2->fov_deg >> 1) * 0.01745329) - // + 0.5) << 16; - extern float _calc_fov(int viewport_width, int angle_degree); - this->fov_rad_fixpoint = fixpoint_from_int(_calc_fov(uViewportWidth, 65), 0); - this->fov_rad_inv_fixpoint = 0x100000000i64 / this->fov_rad_fixpoint; - this->pRenderTarget = pRenderer->pTargetSurface; - this->uTargetWidth = window->GetWidth(); - this->uTargetHeight = window->GetHeight(); - this->pTargetZBuffer = pRenderer->pActiveZBuffer; - this->field_8C = 0; - this->field_84 = 0; - this->uNumFacesRenderedThisFrame = 0; - this->field_88 = 0; - pBLVRenderParams->field_90 = 64; - pBLVRenderParams->field_94 = 6; -} - -//----- (00440B44) -------------------------------------------------------- -void IndoorLocation::ExecDraw(bool bD3D) -{ - if (bD3D) - { - pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z); - for (uint i = 0; i < pBspRenderer->num_faces; ++i) - { - if (pBspRenderer->nodes[pBspRenderer->faces[i].uNodeID].viewing_portal_id == -1) - IndoorLocation::ExecDraw_d3d(pBspRenderer->faces[i].uFaceID, nullptr, 4, nullptr); - else - IndoorLocation::ExecDraw_d3d(pBspRenderer->faces[i].uFaceID, - pBspRenderer->nodes[pBspRenderer->faces[i].uNodeID].std__vector_0007AC, 4, - pBspRenderer->nodes[pBspRenderer->faces[i].uNodeID].pPortalBounding); - } - } - else for (uint j = 0; j < pBspRenderer->num_faces; ++j ) - { - __debugbreak(); // no SW - //pBLVRenderParams->field_7C = &pBspRenderer->nodes[pBspRenderer->faces[j].uNodeID].PortalScreenData; - //IndoorLocation::ExecDraw_sw(pBspRenderer->faces[j].uFaceID); - } -} - - -/* -//----- (00440BED) -------------------------------------------------------- -void __fastcall sub_440BED(IndoorLocation_drawstru *_this) -{ - unsigned __int16 *v1; // edi@7 - BspRenderer_stru0 *v2; // esi@8 - int v3; // ecx@9 - unsigned int v4; // edx@9 - short *v5; // eax@10 - signed int v6; // [sp+8h] [bp-8h]@7 - int v7; // [sp+Ch] [bp-4h]@8 - short *v8; - - PrepareDrawLists_BLV(_this); - if (pBLVRenderParams->uPartySectorID) - IndoorLocation::ExecDraw(pRenderer->pRenderD3D != 0); - pRenderer->DrawBillboardList_BLV(); - - if ( !pRenderer->pRenderD3D ) - { - if (pBLVRenderParams->uFlags & INDOOR_CAMERA_DRAW_D3D_OUTLINES) - pBspRenderer->DrawFaceOutlines(); - if (pBLVRenderParams->uFlags & INDOOR_CAMERA_DRAW_SW_OUTLINES) - { - v1 = pBLVRenderParams->pRenderTarget; - v7 = 0; - for(int i=0; i < pBspRenderer->num_nodes; i++) - { - BspRenderer_stru0 *pNode = &pBspRenderer->nodes[i]; - v4 = pRenderer->uTargetSurfacePitch * pNode->PortalScreenData._viewport_space_y; - if ( pNode->PortalScreenData._viewport_space_y <= pNode->PortalScreenData._viewport_space_w ) - { - //v5 = (char *)&pBspRenderer->nodes[0].field_C.array_3D8[pNode->field_C._viewport_space_y + v7]; - v5 = &pNode->PortalScreenData.viewport_right_side[pNode->PortalScreenData._viewport_space_y]; - v8 = &pNode->PortalScreenData.viewport_left_side[pNode->PortalScreenData._viewport_space_y]; - do - { - v1[v4 + *v8] = 255; - ++pNode->PortalScreenData._viewport_space_y; - v1[v4 + *v5] = 255; - v4 += pRenderer->uTargetSurfacePitch; - ++v5; - ++v8; - } - while ( pNode->PortalScreenData._viewport_space_y <= pNode->PortalScreenData._viewport_space_w ); - } - } - } - } -} -*/ - -//----- (00441BD4) -------------------------------------------------------- -void IndoorLocation::Draw() -{ - //int v0; // eax@1 - //IndoorLocation_drawstru _this; // [sp+0h] [bp-4Ch]@5 -// int v2; // [sp+44h] [bp-8h]@5 -// int v3; // [sp+48h] [bp-4h]@5 - - /*_this.uFlags = 0; - if (viewparams->draw_sw_outlines) - _this.uFlags |= BLV_RENDER_DRAW_SW_OUTLINES; - if (viewparams->draw_d3d_outlines) - _this.uFlags |= BLV_RENDER_DRAW_D3D_OUTLINES; - - _this.uFlags |= BLV_RENDER_DRAW_SW_OUTLINES; - _this.uFlags |= BLV_RENDER_DRAW_D3D_OUTLINES; - - _this.field_0_timer = pEventTimer->uTotalGameTimeElapsed; - //_this.fov_deg = 65; - //_this.vPosition.x = pParty->vPosition.x - fixpoint_mul(stru_5C6E00->Cos(pParty->sRotationY), pParty->y_rotation_granularity); - //_this.vPosition.y = pParty->vPosition.y - fixpoint_mul(stru_5C6E00->Sin(pParty->sRotationY), pParty->y_rotation_granularity); - //_this.vPosition.z = pParty->vPosition.z + pParty->sEyelevel; - //_this.sRotationX = pParty->sRotationX; - //_this.sRotationY = pParty->sRotationY; - _this.pRenderTarget = pRenderer->pTargetSurface; - _this.uViewportX = pViewport->uScreen_TL_X; - _this.uViewportY = pViewport->uScreen_TL_Y; - _this.uViewportZ = pViewport->uScreen_BR_X; - _this.uViewportW = pViewport->uScreen_BR_Y; - _this.field_3C = pViewport->field_30; - - _this.uTargetWidth = 640; - _this.uTargetHeight = 480; - _this.pTargetZ = pRenderer->pActiveZBuffer;*/ - - //sub_440BED(&_this); -- inlined - //{ - PrepareDrawLists_BLV(); - if (pBLVRenderParams->uPartySectorID) - IndoorLocation::ExecDraw(true/*pRenderer->pRenderD3D != 0*/); - pRenderer->DrawBillboardList_BLV(); - //} - - pParty->uFlags &= ~2; - pGame->DrawParticles(); - trail_particle_generator.UpdateParticles(); -} - -//----- (004C0EF2) -------------------------------------------------------- -void BLVFace::FromODM(ODMFace *face) -{ - this->pFacePlane_old.vNormal.x = face->pFacePlane.vNormal.x; - this->pFacePlane_old.vNormal.y = face->pFacePlane.vNormal.y; - this->pFacePlane_old.vNormal.z = face->pFacePlane.vNormal.z; - this->pFacePlane_old.dist = face->pFacePlane.dist; - this->pFacePlane.vNormal.x = (double)(face->pFacePlane.vNormal.x & 0xFFFF) * 0.000015259022 - + (double)(face->pFacePlane.vNormal.x >> 16); - this->pFacePlane.vNormal.y = (double)(face->pFacePlane.vNormal.y & 0xFFFF) * 0.000015259022 - + (double)(face->pFacePlane.vNormal.y >> 16); - this->pFacePlane.vNormal.z = (double)(face->pFacePlane.vNormal.z & 0xFFFF) * 0.000015259022 - + (double)(face->pFacePlane.vNormal.z >> 16); - this->pFacePlane.dist = (double)(face->pFacePlane.dist & 0xFFFF) * 0.000015259022 + (double)(face->pFacePlane.dist >> 16); - this->uAttributes = face->uAttributes; - this->pBounding.x1 = face->pBoundingBox.x1; - this->pBounding.y1 = face->pBoundingBox.y1; - this->pBounding.z1 = face->pBoundingBox.z1; - this->pBounding.x2 = face->pBoundingBox.x2; - this->pBounding.y2 = face->pBoundingBox.y2; - this->pBounding.z2 = face->pBoundingBox.z2; - this->zCalc1 = face->zCalc1; - this->zCalc2 = face->zCalc2; - this->zCalc3 = face->zCalc3; - this->pXInterceptDisplacements = face->pXInterceptDisplacements; - this->pYInterceptDisplacements = face->pYInterceptDisplacements; - this->pZInterceptDisplacements = face->pZInterceptDisplacements; - this->uPolygonType = (PolygonType)face->uPolygonType; - this->uNumVertices = face->uNumVertices; - this->uBitmapID = face->uTextureID; - this->pVertexIDs = face->pVertexIDs; -} - -//----- (004B0A25) -------------------------------------------------------- -void IndoorLocation::ExecDraw_d3d(unsigned int uFaceID, IndoorCameraD3D_Vec4 *pVertices, unsigned int uNumVertices, RenderVertexSoft *pPortalBounding) -{ - int v17; // ebx@25 - IDirect3DTexture2 *v27; // eax@42 - unsigned int uNumVerticesa; // [sp+24h] [bp-4h]@17 - int a4a; // [sp+34h] [bp+Ch]@25 - - if (uFaceID >= pIndoor->uNumFaces) - return; - - static RenderVertexSoft static_vertices_F7C228[64]; - static RenderVertexSoft static_vertices_F7B628[64]; - static stru154 stru_F7B60C; // idb - - BLVFace* pFace = &pIndoor->pFaces[uFaceID]; - if (pFace->uNumVertices < 3) - return; - - - if (pFace->Invisible()) - return; - - ++pBLVRenderParams->uNumFacesRenderedThisFrame; - pFace->uAttributes |= FACE_UNKNOW4; - - if (!pFace->GetTexture()) - return; - - if (!pGame->pIndoorCameraD3D->IsCulled(pFace)) - { - uNumVerticesa = pFace->uNumVertices; - for (uint i = 0; i < pFace->uNumVertices; ++i) - { - static_vertices_F7C228[i].vWorldPosition.x = pIndoor->pVertices[pFace->pVertexIDs[i]].x; - static_vertices_F7C228[i].vWorldPosition.y = pIndoor->pVertices[pFace->pVertexIDs[i]].y; - static_vertices_F7C228[i].vWorldPosition.z = pIndoor->pVertices[pFace->pVertexIDs[i]].z; - static_vertices_F7C228[i].u = (signed short)pFace->pVertexUIDs[i]; - static_vertices_F7C228[i].v = (signed short)pFace->pVertexVIDs[i]; - } - - if (!pVertices || - (pGame->pStru9Instance->_498377(pPortalBounding, 4, pVertices, static_vertices_F7C228, &uNumVerticesa), uNumVerticesa) ) - { - if (pGame->pIndoorCameraD3D->CalcPortalShape(static_vertices_F7C228, &uNumVerticesa, - static_vertices_F7B628, pGame->pIndoorCameraD3D->std__vector_000034_prolly_frustrum, 4, false, 0) != 1 || uNumVerticesa ) - { - a4a = SHIWORD(stru_F8AD28.uCurrentAmbientLightLevel); - v17 = (248 - 8 * SHIWORD(stru_F8AD28.uCurrentAmbientLightLevel)) | (((248 - 8 * SHIWORD(stru_F8AD28.uCurrentAmbientLightLevel)) - | ((248 - 8 * SHIWORD(stru_F8AD28.uCurrentAmbientLightLevel)) << 8)) << 8); - sub_4B0E07(uFaceID); - pGame->pLightmapBuilder->ApplyLights_IndoorFace(uFaceID); - pDecalBuilder->ApplyBloodsplatDecals_IndoorFace(uFaceID); - pGame->pIndoorCameraD3D->ViewTransfrom_OffsetUV(static_vertices_F7B628, uNumVerticesa, array_507D30, &stru_F8AD28); - pGame->pIndoorCameraD3D->Project(array_507D30, uNumVerticesa, 0); - pGame->pLightmapBuilder->std__vector_000004_size = 0; - if (stru_F8AD28.uNumLightsApplied > 0 || pDecalBuilder->uNumDecals > 0) - { - stru_F7B60C.face_plane.vNormal.x = pFace->pFacePlane.vNormal.x; - stru_F7B60C.polygonType = pFace->uPolygonType; - stru_F7B60C.face_plane.vNormal.y = pFace->pFacePlane.vNormal.y; - stru_F7B60C.face_plane.vNormal.z = pFace->pFacePlane.vNormal.z; - stru_F7B60C.face_plane.dist = pFace->pFacePlane.dist; - } - - if (stru_F8AD28.uNumLightsApplied > 0 && !pFace->Indoor_sky()) - pGame->pLightmapBuilder->ApplyLights(&stru_F8AD28, &stru_F7B60C, uNumVerticesa, array_507D30, pVertices, 0); - - if (pDecalBuilder->uNumDecals > 0)//отрисовка пятен крови - pDecalBuilder->ApplyDecals(a4a, 1, &stru_F7B60C, uNumVerticesa, array_507D30, pVertices, 0, pFace->uSectorID); - - if (pFace->Fluid()) - { - if (pFace->uBitmapID == pRenderer->hd_water_tile_id) - v27 = pBitmaps_LOD->pHardwareTextures[pRenderer->pHDWaterBitmapIDs[pRenderer->hd_water_current_frame]]; - else - { - //auto v24 = GetTickCount() / 4; - //auto v25 = v24 - stru_5C6E00->uIntegerHalfPi; - uint eightSeconds = GetTickCount() % 8000; - float angle = (eightSeconds / 8000.0f) * 2 * 3.1415f; - - //animte lava back and forth - for (uint i = 0; i < uNumVerticesa; ++i) - //array_507D30[i].v += (double)(pBitmaps_LOD->pTextures[pFace->uBitmapID].uHeightMinus1 & (unsigned int)(stru_5C6E00->SinCos(v25) >> 8)); - array_507D30[i].v += pBitmaps_LOD->pTextures[pFace->uBitmapID].uHeightMinus1 * cosf(angle); - v27 = pBitmaps_LOD->pHardwareTextures[pFace->uBitmapID]; - } - } - else if (pFace->uAttributes & FACE_TEXTURE_FRAME) - v27 = pBitmaps_LOD->pHardwareTextures[pTextureFrameTable->GetFrameTexture(pFace->uBitmapID, pBLVRenderParams->field_0_timer_)]; - else - { - v17 = 0xFF808080; - v27 = pBitmaps_LOD->pHardwareTextures[pFace->uBitmapID]; - } - - if (pFace->Indoor_sky()) - pRenderer->DrawIndoorSky(uNumVerticesa, uFaceID); - else - pRenderer->DrawIndoorPolygon(uNumVerticesa, pFace, v27, pFace->GetTexture(), PID(OBJECT_BModel, uFaceID), v17, 0); - return; - } - } - } -} - -//----- (004B0E07) -------------------------------------------------------- -unsigned int __fastcall sub_4B0E07(unsigned int uFaceID) -{ - unsigned int result; // eax@1 - - stru_F8AD28.pDeltaUV[0] = pIndoor->pFaceExtras[pIndoor->pFaces[uFaceID].uFaceExtraID].sTextureDeltaU; - stru_F8AD28.pDeltaUV[1] = pIndoor->pFaceExtras[pIndoor->pFaces[uFaceID].uFaceExtraID].sTextureDeltaV; - result = GetTickCount() >> 3; - if ( pIndoor->pFaces[uFaceID].uAttributes & FACE_FLOW_DIAGONAL ) - stru_F8AD28.pDeltaUV[1] -= result & pBitmaps_LOD->GetTexture(pIndoor->pFaces[uFaceID].uBitmapID)->uHeightMinus1; - else - { - if ( pIndoor->pFaces[uFaceID].uAttributes & FACE_FLOW_VERTICAL ) - stru_F8AD28.pDeltaUV[1] += result & pBitmaps_LOD->GetTexture(pIndoor->pFaces[uFaceID].uBitmapID)->uHeightMinus1; - } - if ( pIndoor->pFaces[uFaceID].uAttributes & FACE_FLOW_HORIZONTAL ) - stru_F8AD28.pDeltaUV[0] -= result & pBitmaps_LOD->GetTexture(pIndoor->pFaces[uFaceID].uBitmapID)->uWidthMinus1; - else - { - if ( pIndoor->pFaces[uFaceID].uAttributes & FACE_DONT_CACHE_TEXTURE ) - stru_F8AD28.pDeltaUV[0] += result & pBitmaps_LOD->GetTexture(pIndoor->pFaces[uFaceID].uBitmapID)->uWidthMinus1; - } - return result; -} - -//----- (004B0EA8) -------------------------------------------------------- -void BspRenderer::AddFaceToRenderList_d3d(unsigned int node_id, unsigned int uFaceID) -{ - unsigned __int16 pTransitionSector; // ax@11 - int v9; // edx@15 - char v29; // al@48 - - nodes[num_nodes].viewing_portal_id = -1; - //v39 = &pIndoor->pFaces[uFaceID]; - - BLVFace* pFace = &pIndoor->pFaces[uFaceID]; - - if (!pFace->Portal()) - { - if (num_faces < 1000) - { - faces[num_faces].uFaceID = uFaceID; - faces[num_faces++].uNodeID = node_id; - } - return; - } - - if (nodes[node_id].uFaceID == uFaceID) - return; - if (!node_id && - pGame->pIndoorCameraD3D->vPartyPos.x >= pFace->pBounding.x1 - 16 && // we are probably standing at the portal plane - pGame->pIndoorCameraD3D->vPartyPos.x <= pFace->pBounding.x2 + 16 && - pGame->pIndoorCameraD3D->vPartyPos.y >= pFace->pBounding.y1 - 16 && - pGame->pIndoorCameraD3D->vPartyPos.y <= pFace->pBounding.y2 + 16 && - pGame->pIndoorCameraD3D->vPartyPos.z >= pFace->pBounding.z1 - 16 && - pGame->pIndoorCameraD3D->vPartyPos.z <= pFace->pBounding.z2 + 16 ) - { - if ( abs(pFace->pFacePlane_old.dist + pGame->pIndoorCameraD3D->vPartyPos.x * pFace->pFacePlane_old.vNormal.x - + pGame->pIndoorCameraD3D->vPartyPos.y * pFace->pFacePlane_old.vNormal.y - + pGame->pIndoorCameraD3D->vPartyPos.z * pFace->pFacePlane_old.vNormal.z) <= 589824 ) // we sure are standing at the portal plane - { - pTransitionSector = pFace->uSectorID; - if ( nodes[0].uSectorID == pTransitionSector ) // draw back sector - pTransitionSector = pFace->uBackSectorID; - nodes[num_nodes].uSectorID = pTransitionSector; - nodes[num_nodes].uFaceID = uFaceID; - nodes[num_nodes].uViewportX = pBLVRenderParams->uViewportX; - nodes[num_nodes].uViewportZ = pBLVRenderParams->uViewportZ; - nodes[num_nodes].uViewportY = pBLVRenderParams->uViewportY; - nodes[num_nodes].uViewportW = pBLVRenderParams->uViewportW; - nodes[num_nodes].PortalScreenData.GetViewportData(pBLVRenderParams->uViewportX, pBLVRenderParams->uViewportY, - pBLVRenderParams->uViewportZ, pBLVRenderParams->uViewportW); - AddBspNodeToRenderList(++num_nodes - 1); - return; - } - } - - v9 = pFace->pFacePlane_old.vNormal.x * (pIndoor->pVertices[pFace->pVertexIDs[0]].x - pGame->pIndoorCameraD3D->vPartyPos.x) - + pFace->pFacePlane_old.vNormal.y * (pIndoor->pVertices[pFace->pVertexIDs[0]].y - pGame->pIndoorCameraD3D->vPartyPos.y) - + pFace->pFacePlane_old.vNormal.z * (pIndoor->pVertices[pFace->pVertexIDs[0]].z - pGame->pIndoorCameraD3D->vPartyPos.z); - if (nodes[node_id].uSectorID != pFace->uSectorID) - v9 = -v9; - if (v9 >= 0) - return; - - int num_vertices = GetPortalScreenCoord(uFaceID); - if (num_vertices < 2) - return; - - int face_min_screenspace_x = PortalFace._screen_space_x[0], - face_max_screenspace_x = PortalFace._screen_space_x[0]; - int face_min_screenspace_y = PortalFace._screen_space_y[0], - face_max_screenspace_y = PortalFace._screen_space_y[0]; - for (uint i = 1; i < num_vertices; ++i) - { - if (face_min_screenspace_x > PortalFace._screen_space_x[i]) - face_min_screenspace_x = PortalFace._screen_space_x[i]; - if (face_max_screenspace_x < PortalFace._screen_space_x[i]) - face_max_screenspace_x = PortalFace._screen_space_x[i]; - - if (face_min_screenspace_y > PortalFace._screen_space_y[i]) - face_min_screenspace_y = PortalFace._screen_space_y[i]; - if (face_max_screenspace_y < PortalFace._screen_space_y[i]) - face_max_screenspace_y = PortalFace._screen_space_y[i]; - } - //_screen_space_x = 719, 568, 493 - //savegame: qw , 0Bh and 0x1D4h - //problem here when standing near/on portal, condition is false because of face_min_screenspace_x > p->uViewportZ - if (face_max_screenspace_x >= nodes[node_id].uViewportX && - face_min_screenspace_x <= nodes[node_id].uViewportZ && - face_max_screenspace_y >= nodes[node_id].uViewportY && - face_min_screenspace_y <= nodes[node_id].uViewportW && - PortalFrustrum(num_vertices, &nodes[num_nodes].PortalScreenData, &nodes[node_id].PortalScreenData, uFaceID)) - { - pTransitionSector = pFace->uSectorID; - if (nodes[node_id].uSectorID == pTransitionSector ) - pTransitionSector = pFace->uBackSectorID; - nodes[num_nodes].uSectorID = pTransitionSector; - nodes[num_nodes].uFaceID = uFaceID; - nodes[num_nodes].uViewportX = pBLVRenderParams->uViewportX; - nodes[num_nodes].uViewportZ = pBLVRenderParams->uViewportZ; - nodes[num_nodes].uViewportY = pBLVRenderParams->uViewportY; - nodes[num_nodes].uViewportW = pBLVRenderParams->uViewportW; - v29 = false; - if (nodes[node_id].viewing_portal_id == -1)//for first portal - v29 = pGame->pStru10Instance->CalcPortalShape(pFace, nodes[num_nodes].std__vector_0007AC, nodes[num_nodes].pPortalBounding); - else//for next portals - { - static RenderVertexSoft static_subAddFaceToRenderList_d3d_stru_F7AA08[64]; - static RenderVertexSoft static_subAddFaceToRenderList_d3d_stru_F79E08[64]; - - for (uint k = 0; k < pFace->uNumVertices; ++k) - { - static_subAddFaceToRenderList_d3d_stru_F7AA08[k].vWorldPosition.x = pIndoor->pVertices[pFace->pVertexIDs[k]].x; - static_subAddFaceToRenderList_d3d_stru_F7AA08[k].vWorldPosition.y = pIndoor->pVertices[pFace->pVertexIDs[k]].y; - static_subAddFaceToRenderList_d3d_stru_F7AA08[k].vWorldPosition.z = pIndoor->pVertices[pFace->pVertexIDs[k]].z; - } - - unsigned int pNewNumVertices = pFace->uNumVertices; - pGame->pIndoorCameraD3D->CalcPortalShape(static_subAddFaceToRenderList_d3d_stru_F7AA08, &pNewNumVertices, - static_subAddFaceToRenderList_d3d_stru_F79E08, nodes[node_id].std__vector_0007AC, 4, 0, 0); - - v29 = pGame->pStru10Instance->_49C5DA(pFace, static_subAddFaceToRenderList_d3d_stru_F79E08, &pNewNumVertices, - nodes[num_nodes].std__vector_0007AC, nodes[num_nodes].pPortalBounding); - } - if ( 1 ) - { - assert(num_nodes < 150); - - nodes[num_nodes].viewing_portal_id = uFaceID; - AddBspNodeToRenderList(++num_nodes - 1); - } - if (pGame->pIndoorCameraD3D->debug_flags & BLV_RENDER_DRAW_SW_OUTLINES) - pGame->pIndoorCameraD3D->PrepareAndDrawDebugOutline(pFace, 0x1E1EFF); - //pGame->pIndoorCameraD3D->DebugDrawPortal(pFace); - } -} - -//----- (004AE5BA) -------------------------------------------------------- -Texture *BLVFace::GetTexture() -{ - unsigned int v1; // ecx@2 - - if ( uAttributes & FACE_TEXTURE_FRAME ) - v1 = pTextureFrameTable->GetFrameTexture(this->uBitmapID, pBLVRenderParams->field_0_timer_); - else - v1 = uBitmapID; - return pBitmaps_LOD->GetTexture(v1); -} - - -//----- (00498B15) -------------------------------------------------------- -void IndoorLocation::Release() -{ - free(this->ptr_0002B4_doors_ddata); - this->ptr_0002B4_doors_ddata = NULL; - - free(this->ptr_0002B0_sector_rdata); - this->ptr_0002B0_sector_rdata = NULL; - - free(this->ptr_0002B8_sector_lrdata); - this->ptr_0002B8_sector_lrdata = NULL; - - free(this->pLFaces); - this->pLFaces = NULL; - - free(this->pSpawnPoints); - this->pSpawnPoints = NULL; - - this->uNumSectors = 0; - this->uNumFaces = 0; - this->uNumVertices = 0; - this->uNumNodes = 0; - this->uNumDoors = 0; - this->uNumLights = 0; - - free(this->pVertices); - this->pVertices = NULL; - - free(this->pFaces); - this->pFaces = NULL; - - free(this->pFaceExtras); - this->pFaceExtras = NULL; - - free(this->pSectors); - this->pSectors = NULL; - - free(this->pLights); - this->pLights = NULL; - - free(this->pDoors); - this->pDoors = NULL; - - free(this->pNodes); - this->pNodes = NULL; - - free(this->pMapOutlines); - this->pMapOutlines = NULL; - - this->bLoaded = 0; -} - -//----- (00498C45) -------------------------------------------------------- -bool IndoorLocation::Alloc() - { - pVertices = (Vec3_short_ *) malloc(15000 * sizeof(Vec3_short_));//0x15F90u - pFaces = (BLVFace *) malloc(10000 * sizeof(BLVFace));//0xEA600u - pFaceExtras = (BLVFaceExtra *) malloc(5000 * sizeof(BLVFaceExtra)); //0x2BF20u - pSectors = (BLVSector *) malloc(512 * sizeof(BLVSector));//0xE800u - pLights = (BLVLightMM7 *) malloc(400 * sizeof(BLVLightMM7));//0x1900u - pDoors = (BLVDoor *) malloc(200 * sizeof(BLVDoor));//0x3E80u - pNodes = (BSPNode *) malloc(5000 * sizeof(BSPNode));//0x9C40u - pMapOutlines =(BLVMapOutlines *)malloc(sizeof(BLVMapOutlines));//0x14824u - if (pVertices && pFaces && pFaceExtras && pSectors && pLights && pDoors && pNodes && pMapOutlines ) - { - memset(pVertices, 0, 15000*sizeof(Vec3_short_)); - memset(pFaces, 0, 10000*sizeof(BLVFace)); - memset(pFaceExtras,0, 5000*sizeof(BLVFaceExtra)); - memset(pSectors, 0, 512*sizeof(BLVSector)); - memset(pLights, 0, 400*sizeof(BLVLightMM7)); - memset(pDoors, 0, 200*sizeof(BLVDoor)); - memset(pNodes, 0, 5000*sizeof(BSPNode)); - memset(pMapOutlines,0, sizeof(BLVMapOutlines)); - return true; - } - else - return false; -} - -//----- (00444810) -------------------------------------------------------- -unsigned int IndoorLocation::GetLocationIndex(const char *Str1) -{ - for (uint i = 0; i < 11; ++i) - if (!_stricmp(Str1, _4E6BDC_loc_names[i])) - return i + 1; - return 0; -} - -//----- (004488F7) -------------------------------------------------------- -void IndoorLocation::ToggleLight(signed int sLightID, unsigned int bToggle) -{ - if ( uCurrentlyLoadedLevelType == LEVEL_Indoor && (sLightID <= pIndoor->uNumLights - 1) && (sLightID >= 0) ) - { - if ( bToggle ) - pIndoor->pLights[sLightID].uAtributes &= 0xFFFFFFF7; - else - pIndoor->pLights[sLightID].uAtributes |= 8; - pParty->uFlags |= 2; - } -} - -//----- (00498E0A) -------------------------------------------------------- -bool IndoorLocation::Load(char *pFilename, int a3, size_t _i, char *pDest) -{ - /*unsigned int v5; // ebx@1 - //IndoorLocation *v6; // esi@1 - FILE *v7; // edi@3 - bool result; // eax@3 - char *v9; // ecx@4 - void *v10; // eax@4 - //unsigned __int8 v11; // zf@4 - //unsigned __int8 v12; // sf@4 - int v13; // eax@5 - size_t v14; // ecx@6 - char *v15; // ecx@6 - int v16; // edx@6 - size_t v17; // ecx@6 - char *v18; // ecx@6 - int v19; // edx@6 - unsigned __int16 *v20; // edx@6 - unsigned __int16 *v21; // edx@6 - unsigned __int16 *v22; // edx@6 - __int16 v23; // ax@10 - char *v24; // ecx@10 - __int16 v25; // cx@10 - __int16 v26; // ax@11 - char *v27; // ecx@11 - unsigned __int16 v28; // ax@17 - BLVFaceExtra *v29; // ecx@17 - char *v30; // edx@17 - int v31; // ecx@20 - void *v32; // eax@25 - int v33; // eax@26 - unsigned __int16 *v34; // edx@27 - size_t v35; // ecx@27 - char *v36; // ecx@27 - int v37; // edx@27 - size_t v38; // ecx@27 - char *v39; // ecx@27 - int v40; // edx@27 - unsigned __int16 *v41; // edx@27 - unsigned __int16 *v42; // edx@27 - unsigned __int16 *v43; // edx@27 - unsigned __int16 *v44; // edx@27 - size_t v45; // ecx@27 - unsigned __int16 *v46; // edx@27 - void *v47; // eax@28 - BLVSector *v48; // eax@29 - size_t v49; // ecx@29 - unsigned __int16 *v50; // edx@31 - void *v51; // eax@32 - int v52; // eax@33 - unsigned __int16 *v53; // edx@34 - size_t v54; // ecx@34 - char *v55; // ecx@34 - int v56; // edx@34 - size_t v57; // ecx@34 - char *v58; // ecx@34 - int v59; // edx@34 - unsigned __int16 *v60; // edx@34 - unsigned __int16 *v61; // edx@34 - unsigned __int16 *v62; // edx@34 - unsigned __int16 *v63; // edx@34 - int v64; // ecx@34 - BLVDoor *v65; // ecx@36 - char *v66; // eax@37 - int v67; // edx@38 - int v68; // ecx@38 - BLVFace *v69; // edx@38 - int v70; // ecx@38 - int v71; // edx@38 - int v72; // eax@38 - unsigned __int16 v73; // ax@42 - char *v74; // ecx@42 - SpriteObject *v75; // ecx@44 - size_t v76; // eax@45 - int j; // edx@46 - unsigned __int16 v78; // ax@50 - void *v79; // eax@52 - void **v80; // esi@52 - unsigned int v145; // eax@103 - void *v146; // eax@103 - unsigned int v147; // ecx@103 - int v148; // ebx@103 - unsigned int *v149; // ecx@103*/ - //size_t v150; // eax@103 - //unsigned int v151; // ebx@109 - //unsigned int v152; // ecx@116 - //unsigned int v153; // eax@117 - //size_t v154; // ebx@126 - //unsigned int v155; // ebx@134 - //size_t v156; // eax@140 - //signed int v157; // ebx@142 - //int v158; // ebx@148 - //BLVFace *v159; // eax@149 -// BLVFaceExtra *v160; // ecx@149 - //BLVFaceExtra *v161; // ecx@149 - //signed int v162; // ebx@154 - //unsigned int outz; // ebx@157 - //unsigned int v164; // ebx@157 - //unsigned int v165; // edx@158 - //char *v166; // ecx@158 - //unsigned __int16 v167; // ax@161 - //__int16 v168; // ax@165 - //unsigned int v169; // ebx@168 - //void *v170; // eax@168 - //size_t v171; // ebx@168 - //int v172; // edx@168 - //BLVDoor *v173; // ecx@169 - //int k; // eax@169 - //BLVDoor *v175; // ecx@172 - //int v176; // edx@172 - //BLVDoor *v177; // ecx@172 - //int v178; // edx@172 - //BLVDoor *v179; // ecx@172 - //int v180; // edx@172 - //BLVDoor *v181; // ecx@172 - //int v182; // edx@172 - //BLVDoor *v183; // ecx@172 - //int v184; // edx@172 - //BLVDoor *v185; // ecx@172 - //int v186; // edx@172 - //BLVDoor *v187; // ecx@172 - //int v188; // edx@172 - //unsigned __int16 *v189; // ebx@172 - //char *v190; // edx@173 - //BLVDoor *v191; // ecx@174 - //BLVDoor *l; // eax@175 - //signed int v193; // ebx@176 - //int v194; // ecx@176 - //BLVFaceExtra *v195; // ecx@176 - //BLVFace *v196; // ebx@178 - //std::string v197; // [sp-18h] [bp-680h]@66 - //void *v198; // [sp-14h] [bp-67Ch]@72 - //size_t v199; // [sp-10h] [bp-678h]@72 - //size_t v200; // [sp-Ch] [bp-674h]@72 - //const char *v201; // [sp-8h] [bp-670h]@4 - //int v202; // [sp-4h] [bp-66Ch]@4 - char v203[875]; // [sp+Ch] [bp-65Ch]@130 -// char FileName[260]; // [sp+378h] [bp-2F0h]@1 - //char DstBuf; // [sp+47Ch] [bp-1ECh]@4 -// __int32 Offset; // [sp+480h] [bp-1E8h]@4 -// __int32 v207; // [sp+48Ch] [bp-1DCh]@4 -// __int32 v208; // [sp+498h] [bp-1D0h]@4 -// __int32 v209; // [sp+4A4h] [bp-1C4h]@4 -// __int32 v210; // [sp+4B0h] [bp-1B8h]@4 -// __int32 v211; // [sp+4BCh] [bp-1ACh]@15 -// __int32 v212; // [sp+4C8h] [bp-1A0h]@15 -// __int32 v213; // [sp+4D4h] [bp-194h]@25 -// __int32 v214; // [sp+4E0h] [bp-188h]@25 -// __int32 v215; // [sp+4ECh] [bp-17Ch]@32 -// __int32 v216; // [sp+4F8h] [bp-170h]@32 -// __int32 v217; // [sp+504h] [bp-164h]@40 -// __int32 v218; // [sp+510h] [bp-158h]@40 -// __int32 v219; // [sp+51Ch] [bp-14Ch]@43 -// __int32 v220; // [sp+528h] [bp-140h]@43 -// __int32 v221; // [sp+534h] [bp-134h]@52 -// __int32 v222; // [sp+540h] [bp-128h]@52 -// __int32 v223; // [sp+54Ch] [bp-11Ch]@52 -// __int32 v224; // [sp+558h] [bp-110h]@52 -// __int32 v225; // [sp+564h] [bp-104h]@52 -// __int32 v226; // [sp+570h] [bp-F8h]@52 -// __int32 v227; // [sp+57Ch] [bp-ECh]@52 -// __int32 v228; // [sp+588h] [bp-E0h]@52 -// __int32 v229; // [sp+594h] [bp-D4h]@52 -// __int32 v230; // [sp+5A0h] [bp-C8h]@52 -// __int32 v231; // [sp+5ACh] [bp-BCh]@52 -// __int32 v232; // [sp+5B8h] [bp-B0h]@52 -// __int32 v233; // [sp+5C4h] [bp-A4h]@52 -// __int32 v234; // [sp+5D0h] [bp-98h]@52 - //char pName[40]; // [sp+5FCh] [bp-6Ch]@42 - //size_t pSource; // [sp+624h] [bp-44h]@67 - //char Dst[12]; // [sp+628h] [bp-40h]@9 - //char *v238; // [sp+634h] [bp-34h]@38 - ODMHeader header; // [sp+638h] [bp-30h]@61 - //void *ptr; // [sp+648h] [bp-20h]@66 - //size_t Count; // [sp+64Ch] [bp-1Ch]@109 - //int uSourceLen; // [sp+653h] [bp-15h]@66 - FILE *File; // [sp+658h] [bp-10h]@56 - //BLVSector *v244; // [sp+65Ch] [bp-Ch]@72 - //int v245; // [sp+660h] [bp-8h]@72 - //BLVFace *Src; // [sp+664h] [bp-4h]@73 -// signed int Argsa; // [sp+670h] [bp+8h]@4 -// signed int Argsb; // [sp+670h] [bp+8h]@7 -// signed int Argsc; // [sp+670h] [bp+8h]@15 -// signed int Argsd; // [sp+670h] [bp+8h]@18 -// int Argse; // [sp+670h] [bp+8h]@25 -// int Argsf; // [sp+670h] [bp+8h]@28 -// int Argsg; // [sp+670h] [bp+8h]@32 -// int Argsh; // [sp+670h] [bp+8h]@35 -// signed int Argsi; // [sp+670h] [bp+8h]@40 -// signed int Argsj; // [sp+670h] [bp+8h]@45 - //int Argsk; // [sp+670h] [bp+8h]@143 - //void *Argsl; // [sp+670h] [bp+8h]@155 - //signed int Argsm; // [sp+670h] [bp+8h]@161 - //signed int Argsn; // [sp+670h] [bp+8h]@175 - - //v5 = 0; - //v6 = this; - _6807E0_num_decorations_with_sounds_6807B8 = 0; - - #pragma region "loading from txt" - /*sprintf(FileName, "levels\\%s", pFilename); - if ( GetFileAttributesA(FileName) != -1 ) - { - Release(); - if ( Alloc() ) - { - v7 = fopen(FileName, "rb"); - result = 1; - if ( !v7 ) - return result; - v9 = pDest; - bLoaded = 1; - v202 = (int)v7; - v201 = (const char *)1; - *(int *)v9 = 1; - fread(&DstBuf, 0x180u, (size_t)v201, (FILE *)v202); - fseek(v7, Offset, 0); - fread(&blv, 0x88u, 1u, v7); - fseek(v7, v207, 0); - fread(&uNumVertices, 1u, 4u, v7); - fseek(v7, v208, 0); - fread(pVertices, 6u, uNumVertices, v7); - fseek(v7, v209, 0); - fread(&uNumFaces, 4u, 1u, v7); - fseek(v7, v210, 0); - fread(pFaces, 0x60u, uNumFaces, v7); - v10 = malloc(ptr_2AC, blv.uFaces_fdata_Size, "L.FData"); - v202 = (int)v7; - ptr_2AC = (unsigned __int16 *)v10; - fread(v10, 1u, blv.uFaces_fdata_Size, (FILE *)v202); - v11 = uNumFaces == 0; - v12 = (uNumFaces & 0x80000000u) != 0; - pDest = 0; - Argsa = 0; - if ( !(v12 | v11) ) - { - v13 = 0; - do - { - pFaces[v13].pVertexIDs = (unsigned __int16 *)&pDest[(unsigned int)ptr_2AC]; - v14 = (size_t)&pFaces[v13]; - i = v14; - v15 = &pDest[2 * *(char *)(v14 + 93) + 2]; - v16 = (int)&v15[(unsigned int)ptr_2AC]; - pDest = v15; - *(int *)(i + 52) = v16; - v17 = (size_t)&pFaces[v13]; - i = v17; - v18 = &pDest[2 * *(char *)(v17 + 93) + 2]; - v19 = (int)&v18[(unsigned int)ptr_2AC]; - pDest = v18; - *(int *)(i + 56) = v19; - i = (size_t)&pFaces[v13]; - v20 = ptr_2AC; - pDest += 2 * *(char *)(i + 93) + 2; - *(int *)(i + 60) = (int)(char *)v20 + (int)pDest; - i = (size_t)&pFaces[v13]; - v21 = ptr_2AC; - pDest += 2 * *(char *)(i + 93) + 2; - *(int *)(i + 64) = (int)(char *)v21 + (int)pDest; - i = (size_t)&pFaces[v13]; - ++v13; - v22 = ptr_2AC; - pDest += 2 * *(char *)(i + 93) + 2; - ++Argsa; - *(int *)(i + 68) = (int)(char *)v22 + (int)pDest; - pDest += 2 * *((char *)&pFaces[v13] - 3) + 2; - } - while ( Argsa < (signed int)uNumFaces ); - } - Argsb = 0; - if ( (signed int)uNumFaces > 0 ) - { - pDest = 0; - do - { - fread(Dst, 1u, 0xAu, v7); - if ( pDest[(unsigned int)pFaces + 45] & 0x40 ) - { - v23 = pTextureFrameTable->FindTextureByName(Dst); - v24 = pDest; - *(short *)&pDest[(unsigned int)pFaces + 74] = v23; - v25 = *(short *)&v24[(unsigned int)pFaces + 74]; - if ( v25 ) - { - pTextureFrameTable->LoadAnimationSequenceAndPalettes(v25); - } - else - { - v26 = pBitmaps_LOD->LoadTexture(Dst); - v27 = pDest; - *(short *)&pDest[(unsigned int)pFaces + 74] = v26; - v27[(unsigned int)pFaces + 45] &= 0xBFu; - } - } - else - { - *(short *)&pDest[(unsigned int)pFaces + 74] = pBitmaps_LOD->LoadTexture(Dst); - } - ++Argsb; - pDest += 96; - } - while ( Argsb < (signed int)uNumFaces ); - } - fseek(v7, v211, 0); - fread(&uNumFaceExtras, 4u, 1u, v7); - fseek(v7, v212, 0); - fread(pFaceExtras, 0x24u, uNumFaceExtras, v7); - Argsc = 0; - if ( (signed int)uNumFaceExtras > 0 ) - { - pDest = 0; - do - { - fread(Dst, 1u, 0xAu, v7); - v28 = pBitmaps_LOD->LoadTexture(Dst); - v29 = pFaceExtras; - v30 = pDest; - ++Argsc; - pDest += 36; - *(unsigned __int16 *)((char *)&v29->uAdditionalBitmapID + (int)v30) = v28; - } - while ( Argsc < (signed int)uNumFaceExtras ); - } - Argsd = 0; - if ( (signed int)uNumFaces > 0 ) - { - pDest = 0; - do - { - v31 = (int)&pFaceExtras[*(short *)&pDest[(unsigned int)pFaces + 72]]; - if ( *(short *)(v31 + 26) ) - { - if ( ((BLVFaceExtra *)v31)->HasEventint() ) - pDest[(unsigned int)pFaces + 46] |= 0x10u; - else - pDest[(unsigned int)pFaces + 46] &= 0xEFu; - } - ++Argsd; - pDest += 96; - } - while ( Argsd < (signed int)uNumFaces ); - } - fseek(v7, v213, 0); - fread(&uNumSectors, 4u, 1u, v7); - fseek(v7, v214, 0); - fread(pSectors, 0x74u, uNumSectors, v7); - v32 = malloc(ptr_0002B0_sector_rdata, blv.uSector_rdata_Size, "L.RData"); - v202 = (int)v7; - ptr_0002B0_sector_rdata = (unsigned __int16 *)v32; - fread(v32, 1u, blv.uSector_rdata_Size, (FILE *)v202); - v11 = uNumSectors == 0; - v12 = uNumSectors < 0; - pDest = 0; - Argse = 0; - if ( !(v12 | v11) ) - { - v33 = 0; - do - { - pSectors[v33].pFloors = (unsigned __int16 *)&pDest[(unsigned int)ptr_0002B0_sector_rdata]; - i = (size_t)&pSectors[v33]; - v34 = ptr_0002B0_sector_rdata; - pDest += 2 * *(short *)(i + 4); - *(int *)(i + 16) = (int)(char *)v34 + (int)pDest; - v35 = (size_t)&pSectors[v33]; - i = v35; - v36 = &pDest[2 * *(short *)(v35 + 12)]; - v37 = (int)&v36[(unsigned int)ptr_0002B0_sector_rdata]; - pDest = v36; - *(int *)(i + 24) = v37; - v38 = (size_t)&pSectors[v33]; - i = v38; - v39 = &pDest[2 * *(short *)(v38 + 20)]; - v40 = (int)&v39[(unsigned int)ptr_0002B0_sector_rdata]; - pDest = v39; - *(int *)(i + 32) = v40; - i = (size_t)&pSectors[v33]; - v41 = ptr_0002B0_sector_rdata; - pDest += 2 * *(short *)(i + 28); - *(int *)(i + 40) = (int)(char *)v41 + (int)pDest; - i = (size_t)&pSectors[v33]; - v42 = ptr_0002B0_sector_rdata; - pDest += 2 * *(short *)(i + 36); - *(int *)(i + 48) = (int)(char *)v42 + (int)pDest; - i = (size_t)&pSectors[v33]; - v43 = ptr_0002B0_sector_rdata; - pDest += 2 * *(short *)(i + 44); - *(int *)(i + 64) = (int)(char *)v43 + (int)pDest; - i = (size_t)&pSectors[v33]; - v44 = ptr_0002B0_sector_rdata; - pDest += 2 * *(short *)(i + 60); - *(int *)(i + 72) = (int)(char *)v44 + (int)pDest; - v45 = (size_t)&pSectors[v33]; - ++v33; - i = v45; - v46 = ptr_0002B0_sector_rdata; - pDest += 2 * *(short *)(v45 + 68); - ++Argse; - *(int *)(v45 + 80) = (int)(char *)v46 + (int)pDest; - pDest += 2 * *((short *)&pSectors[v33] - 20); - } - while ( Argse < uNumSectors ); - } - v47 = malloc( - ptr_0002B8_sector_lrdata, - blv.uSector_lrdata_Size, - "L.RLData"); - v202 = (int)v7; - ptr_0002B8_sector_lrdata = (unsigned __int16 *)v47; - fread(v47, 1u, blv.uSector_lrdata_Size, (FILE *)v202); - v11 = uNumSectors == 0; - v12 = uNumSectors < 0; - pDest = 0; - Argsf = 0; - if ( !(v12 | v11) ) - { - v48 = pSectors; - v49 = 0; - for ( i = 0; ; v49 = i ) - { - v50 = ptr_0002B8_sector_lrdata; - i += 116; - ++Argsf; - *(BLVLightMM7 **)((char *)&v48->pLights + v49) = (BLVLightMM7 *)((char *)v50 + (int)pDest); - v48 = pSectors; - pDest += 2 * *(__int16 *)((char *)&v48->uNumLights + v49); - if ( Argsf >= uNumSectors ) - break; - } - } - fseek(v7, v215, 0); - fread(&uNumDoors, 4u, 1u, v7); - fseek(v7, v216, 0); - fread(pDoors, 0x50u, 0xC8u, v7); - v51 = malloc(ptr_0002B4_doors_ddata, blv.uDoors_ddata_Size, "L.DData"); - v202 = (int)v7; - ptr_0002B4_doors_ddata = (unsigned __int16 *)v51; - fread(v51, 1u, blv.uDoors_ddata_Size, (FILE *)v202); - v11 = uNumDoors == 0; - v12 = uNumDoors < 0; - pDest = 0; - Argsg = 0; - if ( !(v12 | v11) ) - { - v52 = 0; - do - { - pDoors[v52].pVertexIDs = (unsigned __int16 *)&pDest[(unsigned int)ptr_0002B4_doors_ddata]; - i = (size_t)&pDoors[v52]; - v53 = ptr_0002B4_doors_ddata; - pDest += 2 * *(short *)(i + 68); - *(int *)(i + 40) = (int)(char *)v53 + (int)pDest; - v54 = (size_t)&pDoors[v52]; - i = v54; - v55 = &pDest[2 * *(short *)(v54 + 70)]; - v56 = (int)&v55[(unsigned int)ptr_0002B4_doors_ddata]; - pDest = v55; - *(int *)(i + 44) = v56; - v57 = (size_t)&pDoors[v52]; - i = v57; - v58 = &pDest[2 * *(short *)(v57 + 72)]; - v59 = (int)&v58[(unsigned int)ptr_0002B4_doors_ddata]; - pDest = v58; - *(int *)(i + 48) = v59; - i = (size_t)&pDoors[v52]; - v60 = ptr_0002B4_doors_ddata; - pDest += 2 * *(short *)(i + 70); - *(int *)(i + 52) = (int)(char *)v60 + (int)pDest; - i = (size_t)&pDoors[v52]; - v61 = ptr_0002B4_doors_ddata; - pDest += 2 * *(short *)(i + 70); - *(int *)(i + 56) = (int)(char *)v61 + (int)pDest; - i = (size_t)&pDoors[v52]; - v62 = ptr_0002B4_doors_ddata; - pDest += 2 * *(short *)(i + 74); - *(int *)(i + 60) = (int)(char *)v62 + (int)pDest; - i = (size_t)&pDoors[v52]; - v63 = ptr_0002B4_doors_ddata; - pDest += 2 * *(short *)(i + 74); - *(int *)(i + 64) = (int)(char *)v63 + (int)pDest; - ++Argsg; - v64 = pDoors[v52].uNumOffsets; - ++v52; - pDest += 2 * v64; - } - while ( Argsg < uNumDoors ); - } - Argsh = 0; - if ( uNumDoors > 0 ) - { - v65 = pDoors; - pDest = 0; - do - { - i = 0; - v66 = &pDest[(int)v65]; - if ( *(short *)&pDest[(int)v65 + 70] > 0 ) - { - do - { - v67 = *((int *)v66 + 10); - a3 = 2 * i; - v68 = *(short *)(v67 + 2 * i); - v69 = pFaces; - ++i; - v70 = (int)&pFaceExtras[v69[v68].uFaceExtraID]; - v71 = *((int *)v66 + 12); - v72 = a3; - v238 = (char *)v70; - *(short *)(a3 + v71) = *(short *)(v70 + 20); - *(__int16 *)(*(char **)((char *)&pDoors->pDeltaVs + (unsigned int)pDest) + v72) = *((short *)v238 + 11); - v65 = pDoors; - v66 = &pDest[(int)v65]; - } - while ( (signed int)i < *(short *)&pDest[(int)v65 + 70] ); - } - ++Argsh; - pDest += 80; - } - while ( Argsh < uNumDoors ); - } - fseek(v7, v217, 0); - fread(&uNumLevelDecorations, 4u, 1u, v7); - fseek(v7, v218, 0); - fread(pLevelDecorations, 0x20u, uNumLevelDecorations, v7); - Argsi = 0; - if ( (signed int)uNumLevelDecorations > 0 ) - { - pDest = (char *)pLevelDecorations; - do - { - fread(pName, 1u, 0x20u, v7); - v73 = pDecorationList->GetDecorIdByName(pName); - v74 = pDest; - ++Argsi; - pDest += 32; - *(short *)v74 = v73; - } - while ( Argsi < (signed int)uNumLevelDecorations ); - } - fseek(v7, v219, 0); - fread(&uNumSpriteObjects, 4u, 1u, v7); - fseek(v7, v220, 0); - fread(pSpriteObjects, 0x70u, uNumSpriteObjects, v7); - if ( (signed int)uNumSpriteObjects > 0 ) - { - v75 = pSpriteObjects; - pDest = (char *)uNumSpriteObjects; - do - { - Argsj = 0; - v76 = 48 * v75->stru_24.uItemID; - v11 = pObjectList->uNumObjects == 0; - v12 = (pObjectList->uNumObjects & 0x80000000u) != 0; - LOWORD(v76) = *(unsigned __int16 *)((char *)&pItemsTable->pItems[0].uSpriteID + v76); - i = v76; - v75->uItemType = v76; - if ( v12 | v11 ) - { -LABEL_50: - v78 = 0; - } - else - { - for ( j = (int)&pObjectList->pObjects->uObjectID; (short)v76 != *(short *)j; j = a3 ) - { - ++Argsj; - a3 = j + 56; - if ( Argsj >= (signed int)pObjectList->uNumObjects ) - goto LABEL_50; - LOWORD(v76) = i; - } - v78 = Argsj; - } - v75->uObjectDescID = v78; - ++v75; - --pDest; - } - while ( pDest ); - } - fseek(v7, v221, 0); - fread(&uNumActors, 4u, 1u, v7); - fseek(v7, v222, 0); - fread(pActors, 0x344u, uNumActors, v7); - fseek(v7, v228, 0); - fread(&uNumChests, 4u, 1u, v7); - fseek(v7, v229, 0); - fread(pChests, 0x14CCu, uNumChests, v7); - fseek(v7, v224, 0); - fread(&uNumLights, 4u, 1u, v7); - fseek(v7, v225, 0); - fread(pLights, 0x10u, uNumLights, v7); - fseek(v7, v226, 0); - fread(&uNumNodes, 4u, 1u, v7); - fseek(v7, v227, 0); - fread(pNodes, 8u, uNumNodes, v7); - fseek(v7, v230, 0); - fread(&uNumSpawnPoints, 4u, 1u, v7); - v79 = malloc(pSpawnPoints, 24 * uNumSpawnPoints, "Spawn"); - v202 = 0; - pSpawnPoints = (SpawnPointMM7 *)v79; - fseek(v7, v231, v202); - fread(pSpawnPoints, 0x18u, uNumSpawnPoints, v7); - fseek(v7, v232, 0); - fread(&dlv, 0x28u, 1u, v7); - fseek(v7, v233, 0); - fread(&stru_5E4C90, 1u, 0xC8u, v7); - fseek(v7, v234, 0); - fread(&uLastVisitDay, 1u, 0x38u, v7); - fseek(v7, v223, 0); - v80 = (void **)&pMapOutlines; - fread(*v80, 4u, 1u, v7); - fread((char *)*v80 + 4, 0xCu, *(int *)*v80, v7); - fclose(v7); - goto LABEL_179; - } - return 4; - }*/ - #pragma endregion - - if (bLoaded) - { - Log::Warning(L"BLV is already loaded"); - return 3; - } - - if ( !pGames_LOD->DoesContainerExist(pFilename) ) - Error("Unable to find %s in Games.LOD", pFilename); - - //v238 = pFilename - 4; - //v81 = strlen(pFilename); - strcpy(this->pFilename, pFilename); - strcpy(&pFilename[strlen(pFilename) - 4], ".blv"); - File = pGames_LOD->FindContainer(pFilename, 1); - //File = v82; - - Release(); - if ( !Alloc() ) - return 4; - - header.uVersion = 91969; - header.pMagic[0] = 'm'; - header.pMagic[1] = 'v'; - header.pMagic[2] = 'i'; - header.pMagic[3] = 'i'; - header.uCompressedSize = 0; - header.uDecompressedSize = 0; - fread(&header, sizeof(ODMHeader), 1, File); - if (header.uVersion != 91969 || - header.pMagic[0] != 'm' || - header.pMagic[1] != 'v' || - header.pMagic[2] != 'i' || - header.pMagic[3] != 'i' ) - { - MessageBoxW(nullptr, L"Can't load file!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Polydata.cpp:792", 0); - } - //v83 = header.uCompressedSize; - //pSource = header.uDecompressedSize; - //v84 = malloc(header.uDecompressedSize); - //v85 = v84; - //ptr = v84; - void* pRawBLV = malloc(header.uDecompressedSize); - memset(pRawBLV, 0, header.uDecompressedSize); - - if (header.uCompressedSize == header.uDecompressedSize) - fread(pRawBLV, header.uDecompressedSize, 1, File); - else if (header.uCompressedSize < header.uDecompressedSize) - { - void* pTmpMem = malloc(header.uCompressedSize); - { - fread(pTmpMem, header.uCompressedSize, 1, File); - - uint uDecompressedSize = header.uDecompressedSize; - zlib::MemUnzip(pRawBLV, &uDecompressedSize, pTmpMem, header.uCompressedSize); - - if (uDecompressedSize != header.uDecompressedSize) - Log::Warning(L"uDecompressedSize != header.uDecompressedSize in BLV"); - } - free(pTmpMem); - } - else - { - MessageBoxW(nullptr, L"Can't load file!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Polydata.cpp:803", 0); - return 0; - } - - bLoaded = true; - - char* pData = (char *)pRawBLV; - - pGameLoadingUI_ProgressBar->Progress(); - - memcpy(&blv, pData, 136); - memcpy(&uNumVertices, pData += 136, 4); - memcpy(pVertices, pData += 4, uNumVertices * sizeof(Vec3_short_)); - - pGameLoadingUI_ProgressBar->Progress(); - - memcpy(&uNumFaces, pData += uNumVertices * sizeof(Vec3_short_), 4); - - pGameLoadingUI_ProgressBar->Progress(); - - memcpy(pFaces, pData += 4, uNumFaces * sizeof (BLVFace)); - pLFaces = (unsigned __int16 *)malloc(blv.uFaces_fdata_Size); - - memcpy(pLFaces, pData += uNumFaces * sizeof (BLVFace), blv.uFaces_fdata_Size); - - for (uint i = 0, j = 0; i < uNumFaces; ++i) - { - BLVFace* pFace = &pFaces[i]; - - pFace->pVertexIDs = &pLFaces[j]; - - j += pFace->uNumVertices + 1; - pFace->pXInterceptDisplacements = (short *)(&pLFaces[j]); - - j += pFace->uNumVertices + 1; - pFace->pYInterceptDisplacements = (short *)(&pLFaces[j]); - - j += pFace->uNumVertices + 1; - pFace->pZInterceptDisplacements = (short *)(&pLFaces[j]); - - j += pFace->uNumVertices + 1; - pFace->pVertexUIDs = (__int16 *)(&pLFaces[j]); - - j += pFace->uNumVertices + 1; - pFace->pVertexVIDs = (__int16 *)(&pLFaces[j]); - - j += pFace->uNumVertices + 1; - /*v93 = &pFaces[v92]; - Src = v93; - v94 = (BLVSector *)((char *)v244 + 2 * v93->uNumVertices + 2); - v95 = (unsigned __int16 *)((char *)v94 + (unsigned int)ptr_2AC); - v244 = v94; - Src->pXInterceptDisplacements = v95; - v96 = (int)&pFaces[v92]; - Src = (BLVFace *)v96; - v97 = (BLVSector *)((char *)v244 + 2 * *(char *)(v96 + 93) + 2); - v98 = (unsigned __int16 *)((char *)v97 + (unsigned int)ptr_2AC); - v244 = v97; - Src->pYInterceptDisplacements = v98; - Src = &pFaces[v92]; - v99 = ptr_2AC; - v244 = (BLVSector *)((char *)v244 + 2 * Src->uNumVertices + 2); - Src->pZInterceptDisplacements = (unsigned __int16 *)((char *)v99 + (int)v244); - Src = &pFaces[v92]; - v100 = ptr_2AC; - v244 = (BLVSector *)((char *)v244 + 2 * Src->uNumVertices + 2); - Src->pVertexUIDs = (unsigned __int16 *)((char *)v100 + (int)v244); - Src = &pFaces[v92]; - ++v92; - v101 = ptr_2AC; - v244 = (BLVSector *)((char *)v244 + 2 * Src->uNumVertices + 2); - ++v245; - Src->pVertexVIDs = (unsigned __int16 *)((char *)v101 + (int)v244); - v244 = (BLVSector *)((char *)v244 + 2 * *((char *)&pFaces[v92] - 3) + 2);*/ - } - - pGameLoadingUI_ProgressBar->Progress(); - - pData += blv.uFaces_fdata_Size; - - for (uint i = 0; i < uNumFaces; ++i) - { - BLVFace* pFace = &pFaces[i]; - - char pTexName[16]; - strncpy(pTexName, pData, 10); - pData += 10; - - if (pFace->uAttributes & FACE_TEXTURE_FRAME) - { - pFace->uBitmapID = pTextureFrameTable->FindTextureByName(pTexName); - if (pFace->uBitmapID) - pTextureFrameTable->LoadAnimationSequenceAndPalettes(pFace->uBitmapID); - else - { - pFace->uBitmapID = pBitmaps_LOD->LoadTexture(pTexName); - pFace->uAttributes &= ~FACE_TEXTURE_FRAME; - } - } - else - pFace->uBitmapID = pBitmaps_LOD->LoadTexture(pTexName); - } - - pGameLoadingUI_ProgressBar->Progress(); - - memcpy(&uNumFaceExtras, pData, 4); - memcpy(pFaceExtras, pData += 4, uNumFaceExtras * sizeof(BLVFaceExtra)); - pData += uNumFaceExtras * sizeof(BLVFaceExtra); - - pGameLoadingUI_ProgressBar->Progress(); - - //v108 = (char *)v107 + 36 * uNumFaceExtras; - //v245 = 0; - //*(int *)((char *)&uSourceLen + 1) = 0; - for (uint i = 0; i < uNumFaceExtras; ++i) - { - char pTexName[32]; - strncpy(pTexName, pData, 10); - pData += 10; - - if (!strcmp(pTexName, "")) - pFaceExtras[i].uAdditionalBitmapID = -1; - else - pFaceExtras[i].uAdditionalBitmapID = pBitmaps_LOD->LoadTexture(pTexName); - } - - - for (uint i = 0; i < uNumFaces; ++i) - { - BLVFace* pFace = &pFaces[i]; - BLVFaceExtra* pFaceExtra = &pFaceExtras[pFace->uFaceExtraID]; - - if (pFaceExtra->uEventID) - { - if (pFaceExtra->HasEventint()) - pFace->uAttributes |= FACE_HAS_EVENT; - else - pFace->uAttributes &= ~FACE_HAS_EVENT; - } - } - - pGameLoadingUI_ProgressBar->Progress(); - - memcpy(&uNumSectors, pData, 4); - memcpy(pSectors, pData + 4, uNumSectors * sizeof(BLVSector)); - pData += 4 + uNumSectors * sizeof(BLVSector); - - pGameLoadingUI_ProgressBar->Progress(); - - ptr_0002B0_sector_rdata = (unsigned short *)malloc(blv.uSector_rdata_Size);//, "L.RData"); - memcpy(ptr_0002B0_sector_rdata, pData, blv.uSector_rdata_Size); - pData += blv.uSector_rdata_Size; - - for (uint i = 0, j = 0; i < uNumSectors; ++i) - { - BLVSector* pSector = &pSectors[i]; - - pSector->pFloors = &ptr_0002B0_sector_rdata[j]; - j += pSector->uNumFloors; - - pSector->pWalls = &ptr_0002B0_sector_rdata[j]; - j += pSector->uNumWalls; - - pSector->pCeilings = &ptr_0002B0_sector_rdata[j]; - j += pSector->uNumCeilings; - - pSector->pFluids = &ptr_0002B0_sector_rdata[j]; - j += pSector->uNumFluids; - - pSector->pPortals = &ptr_0002B0_sector_rdata[j]; - j += pSector->uNumPortals; - - pSector->pFaceIDs = &ptr_0002B0_sector_rdata[j]; - j += pSector->uNumFaces; - - pSector->pCogs = &ptr_0002B0_sector_rdata[j]; - j += pSector->uNumCogs; - - pSector->pDecorationIDs = &ptr_0002B0_sector_rdata[j]; - j += pSector->uNumDecorations; - - pSector->pMarkers = &ptr_0002B0_sector_rdata[j]; - j += pSector->uNumMarkers; - - - //do - //{ - /*pSectors[v118].pFloors = (unsigned __int16 *)((char *)Src + (unsigned int)ptr_0002B0_sector_rdata); - v244 = &pSectors[v118]; - v119 = ptr_0002B0_sector_rdata; - Src = (BLVFace *)((char *)Src + 2 * v244->field_4); - v244->pWalls = (unsigned __int16 *)((char *)v119 + (int)Src); - v120 = (int)&pSectors[v118]; - v244 = (BLVSector *)v120; - v121 = (BLVFace *)((char *)Src + 2 * *(short *)(v120 + 12)); - v122 = (unsigned __int16 *)((char *)v121 + (unsigned int)ptr_0002B0_sector_rdata); - Src = v121; - v244->pCeilings = v122; - v123 = (int)&pSectors[v118]; - v244 = (BLVSector *)v123; - v124 = (BLVFace *)((char *)Src + 2 * *(short *)(v123 + 20)); - v125 = (unsigned __int16 *)((char *)v124 + (unsigned int)ptr_0002B0_sector_rdata); - Src = v124; - v244->pFluids = v125; - v244 = &pSectors[v118]; - v126 = ptr_0002B0_sector_rdata; - Src = (BLVFace *)((char *)Src + 2 * v244->field_1C); - v244->pPortals = (unsigned __int16 *)((char *)v126 + (int)Src); - v244 = &pSectors[v118]; - v127 = ptr_0002B0_sector_rdata; - Src = (BLVFace *)((char *)Src + 2 * v244->uNumPortals); - v244->pFaceIDs = (unsigned __int16 *)((char *)v127 + (int)Src); - v244 = &pSectors[v118]; - v128 = ptr_0002B0_sector_rdata; - Src = (BLVFace *)((char *)Src + 2 * v244->field_2C); - v244->pCogs = (unsigned __int16 *)((char *)v128 + (int)Src); - v244 = &pSectors[v118]; - v129 = ptr_0002B0_sector_rdata; - Src = (BLVFace *)((char *)Src + 2 * v244->field_3C); - v244->pDecorationIDs = (unsigned __int16 *)((char *)v129 + (int)Src); - v130 = (int)&pSectors[v118]; - ++v118; - v244 = (BLVSector *)v130; - v131 = ptr_0002B0_sector_rdata; - Src = (BLVFace *)((char *)Src + 2 * *(short *)(v130 + 68)); - ++v245; - *(int *)(v130 + 80) = (int)(char *)v131 + (int)Src; - Src = (BLVFace *)((char *)Src + 2 * *((short *)&pSectors[v118] - 20));*/ - //} - //while ( v245 < uNumSectors ); - } - - ptr_0002B8_sector_lrdata = (unsigned __int16 *)malloc(blv.uSector_lrdata_Size);//, "L.RLData"); - memcpy(ptr_0002B8_sector_lrdata, pData, blv.uSector_lrdata_Size); - pData += blv.uSector_lrdata_Size; - - pGameLoadingUI_ProgressBar->Progress(); - - for (uint i = 0, j = 0; i < uNumSectors; ++i) - { - pSectors[i].pLights = ptr_0002B8_sector_lrdata + j; - j += pSectors[i].uNumLights; - } - - pGameLoadingUI_ProgressBar->Progress(); - - memcpy(&uNumDoors, pData, 4); - pData += 4; - - pGameLoadingUI_ProgressBar->Progress(); - pGameLoadingUI_ProgressBar->Progress(); - - memcpy(&uNumLevelDecorations, pData, 4); - memcpy(pLevelDecorations.data(), pData + 4, uNumLevelDecorations * sizeof(LevelDecoration)); - pData += 4 + uNumLevelDecorations * sizeof(LevelDecoration); - - for (uint i = 0; i < uNumLevelDecorations; ++i) - { - pLevelDecorations[i].uDecorationDescID = pDecorationList->GetDecorIdByName(pData); - - pData += 32; - } - - pGameLoadingUI_ProgressBar->Progress(); - - memcpy(&uNumLights, pData, 4); - memcpy(pLights, pData + 4, uNumLights * sizeof(BLVLightMM7)); - pData += 4 + uNumLights * sizeof(BLVLightMM7); - - pGameLoadingUI_ProgressBar->Progress(); - pGameLoadingUI_ProgressBar->Progress(); - - memcpy(&uNumNodes, pData, 4); - memcpy(pNodes, pData + 4, uNumNodes * sizeof(BSPNode)); - pData += 4 + uNumNodes * sizeof(BSPNode); - - pGameLoadingUI_ProgressBar->Progress(); - pGameLoadingUI_ProgressBar->Progress(); - - memcpy(&uNumSpawnPoints, pData, 4); - pSpawnPoints = (SpawnPointMM7 *)malloc(uNumSpawnPoints * sizeof(SpawnPointMM7)); - memcpy(pSpawnPoints, pData + 4, uNumSpawnPoints * sizeof(SpawnPointMM7)); - pData += 4 + uNumSpawnPoints * sizeof(SpawnPointMM7); - - pGameLoadingUI_ProgressBar->Progress(); - pGameLoadingUI_ProgressBar->Progress(); - - //v201 = (const char *)v148; - //v200 = (size_t)pMapOutlines; - memcpy(&pMapOutlines->uNumOutlines, pData, 4); - memcpy(pMapOutlines->pOutlines, pData + 4, pMapOutlines->uNumOutlines * sizeof(BLVMapOutline)); - //v149 = pMapOutlines; - //v199 = 12 * *v149; - //memcpy(v149 + 1, (const void *)(v148 + 4), v199); - free(pRawBLV); - pRawBLV = nullptr; - - void *pRawDLV = nullptr; - strcpy(&pFilename[strlen(pFilename) - 4], ".dlv"); - File = pNew_LOD->FindContainer(pFilename, 1);//error on D28.dlv - fread(&header, 0x10, 1, File);//(FILE *)v245); - bool _v244 = false; - if (header.uVersion != 91969 || - header.pMagic[0] != 'm' || - header.pMagic[1] != 'v' || - header.pMagic[2] != 'i' || - header.pMagic[3] != 'i' ) - { - MessageBoxW(nullptr, L"Can't load file!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Polydata.cpp:1090", 0); - _v244 = true; - } - else - { - pRawDLV = malloc(header.uDecompressedSize); - if (header.uCompressedSize == header.uDecompressedSize) - fread(pRawDLV, 1, header.uCompressedSize, File); - else if (header.uCompressedSize < header.uDecompressedSize) - { - void* pTmpMem = malloc(header.uCompressedSize); - { - fread(pTmpMem, header.uCompressedSize, 1, File); - - uint uDecompressedSize = header.uDecompressedSize; - zlib::MemUnzip(pRawDLV, &uDecompressedSize, pTmpMem, header.uCompressedSize); - - if (uDecompressedSize != header.uDecompressedSize) - Log::Warning(L"uDecompressedSize != header.uDecompressedSize in DLV"); - } - free(pTmpMem); - } - else - MessageBoxW(nullptr, L"Can't load file!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Polydata.cpp:1108", 0); - - pData = (char *)pRawDLV; - } - - memcpy(&dlv, pData, 40); - pData += 40; - - //v152 = dlv.uNumFacesInBModels; - if (dlv.uNumFacesInBModels) - { - //v153 = dlv.uNumDecorations; - if (dlv.uNumDecorations) - { - if (dlv.uNumFacesInBModels != uNumFaces || - dlv.uNumDecorations != uNumLevelDecorations) - _v244 = true; - } - } - - if (dword_6BE364_game_settings_1 & GAME_SETTINGS_2000 ) - _i = 0x1BAF800; - bool _a = false; - if ( a3 - dlv.uLastRepawnDay >= _i && _stricmp(pCurrentMapName, "d29.dlv") ) - _a = true; - - //v154 = 875; - if (_v244 || (_a || !dlv.uLastRepawnDay)) - { - if (_v244) - { - memset(v203, 0, 0x36B); - } - else if (_a || !dlv.uLastRepawnDay) - { - memcpy(v203, pData, 0x36B); - } - - free(pRawDLV); - dlv.uLastRepawnDay = a3; - if (_v244) - ++dlv.uNumRespawns; - //v201 = pFilename; - *(int *)pDest = 1; - File = pGames_LOD->FindContainer(pFilename, 0); - fread(&header, 0x10u, 1, File); - uint v155 = header.uCompressedSize; - uint Count = header.uDecompressedSize; - BLVFace* Src = (BLVFace *)malloc(header.uDecompressedSize); - pRawDLV = Src; - if (v155 <= Count) - { - if (v155 == Count) - fread(Src, 1, Count, File); - else - { - void* _uSourceLen = malloc(v155); - fread(_uSourceLen, v155, 1, File); - zlib::MemUnzip(Src, &Count, _uSourceLen, v155); - free(_uSourceLen); - } - } - else - MessageBoxW(nullptr, L"Can't load file!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Polydata.cpp:1195", 0); - pData = ((char *)Src + 40); - //v154 = 875; - } - else - { - *(int *)pDest = 0; - } - - -//LABEL_140: - //v202 = (int)".blv"; - //v156 = strlen(pFilename); - strcpy(&pFilename[strlen(pFilename) - 4], ".blv"); - memcpy(_visible_outlines, pData, 875); - pData += 875; - - if ( *(int *)pDest ) - memcpy(_visible_outlines, v203, 875); - - for (uint i = 0; i < pMapOutlines->uNumOutlines; ++i) - { - BLVMapOutline* pVertex = &pMapOutlines->pOutlines[i]; - if ((unsigned __int8)(1 << (7 - i % 8)) & _visible_outlines[i / 8]) - pVertex->uFlags |= 1; - } - - - for (uint i = 0; i < uNumFaces; ++i) - { - BLVFace* pFace = &pFaces[i]; - BLVFaceExtra* pFaceExtra = &pFaceExtras[pFace->uFaceExtraID]; - - memcpy(&pFace->uAttributes, pData, 4); - pData += 4; - - if (pFaceExtra->uEventID) - { - if (pFaceExtra->HasEventint()) - pFace->uAttributes |= FACE_HAS_EVENT; - else - pFace->uAttributes &= ~FACE_HAS_EVENT; - } - } - - pGameLoadingUI_ProgressBar->Progress(); - - for (uint i = 0; i < uNumLevelDecorations; ++i) - { - memcpy(&pLevelDecorations[i].uFlags, pData, 2); - pData += 2; - } - - pGameLoadingUI_ProgressBar->Progress(); - - memcpy(&uNumActors, pData, 4); - memcpy(&pActors, pData + 4, uNumActors * sizeof(Actor)); - pData += 4 + uNumActors * sizeof(Actor); - - pGameLoadingUI_ProgressBar->Progress(); - pGameLoadingUI_ProgressBar->Progress(); - - memcpy(&uNumSpriteObjects, pData, 4); - memcpy(pSpriteObjects.data(), pData + 4, uNumSpriteObjects * sizeof(SpriteObject)); - pData += 4 + uNumSpriteObjects * sizeof(SpriteObject); - - pGameLoadingUI_ProgressBar->Progress(); - - for ( uint i = 0; i < uNumSpriteObjects; ++i ) - { - if (pSpriteObjects[i].stru_24.uItemID && !(pSpriteObjects[i].uAttributes & 0x0100)) - { - pSpriteObjects[i].uType = pItemsTable->pItems[pSpriteObjects[i].stru_24.uItemID].uSpriteID; - - //uint uObjectID = 0; - for ( uint j = 0; j < pObjectList->uNumObjects; ++j ) - if ( pSpriteObjects[i].uType == pObjectList->pObjects[j].uObjectID ) - { - pSpriteObjects[i].uObjectDescID = j; - break; - } - } - } - - pGameLoadingUI_ProgressBar->Progress(); - - memcpy(&uNumChests, pData, 4); - memcpy(pChests.data(), pData + 4, uNumChests * sizeof(Chest)); - pData += 4 + uNumChests * sizeof(Chest); - - pGameLoadingUI_ProgressBar->Progress(); - pGameLoadingUI_ProgressBar->Progress(); - - memcpy(pDoors, pData, 0x3E80); - pData += 0x3E80; - - //v201 = (const char *)blv.uDoors_ddata_Size; - //v200 = (size_t)ptr_0002B4_doors_ddata; - //v170 = malloc(ptr_0002B4_doors_ddata, blv.uDoors_ddata_Size, "L.DData"); - //v171 = blv.uDoors_ddata_Size; - ptr_0002B4_doors_ddata = (unsigned __int16 *)malloc(blv.uDoors_ddata_Size);//, "L.DData"); - memcpy(ptr_0002B4_doors_ddata, pData, blv.uDoors_ddata_Size); - pData += blv.uDoors_ddata_Size; - - //Src = (BLVFace *)((char *)Src + v171); - //v172 = 0; - //v245 = 0; - //if (uNumDoors > 0) - for (uint i = 0, j = 0; i < uNumDoors; ++i) - { - BLVDoor* pDoor = &pDoors[i]; - - pDoor->pVertexIDs = &ptr_0002B4_doors_ddata[j]; - j += pDoor->uNumVertices; - - pDoor->pFaceIDs = &ptr_0002B4_doors_ddata[j]; - j += pDoor->uNumFaces; - - pDoor->pSectorIDs = &ptr_0002B4_doors_ddata[j]; - j += pDoor->field_48; - - pDoor->pDeltaUs = (short *)(&ptr_0002B4_doors_ddata[j]); - j += pDoor->uNumFaces; - - pDoor->pDeltaVs = (short *)(&ptr_0002B4_doors_ddata[j]); - j += pDoor->uNumFaces; - - pDoor->pXOffsets = &ptr_0002B4_doors_ddata[j]; - j += pDoor->uNumOffsets; - - pDoor->pYOffsets = &ptr_0002B4_doors_ddata[j]; - j += pDoor->uNumOffsets; - - pDoor->pZOffsets = &ptr_0002B4_doors_ddata[j]; - j += pDoor->uNumOffsets; - /*v173 = pDoors; - for ( k = 0; ; v172 = v188 + 2 * *((short *)&v173[k] - 3) ) - { - v173[k].pVertexIDs = (unsigned __int16 *)((char *)ptr_0002B4_doors_ddata + v172); - v175 = &pDoors[k]; - v176 = v172 + 2 * v175->uNumVertices; - v175->pFaceIDs = (unsigned __int16 *)((char *)ptr_0002B4_doors_ddata + v176); - v177 = &pDoors[k]; - v178 = v176 + 2 * v177->uNumFaces; - v177->pSectorIDs = (unsigned __int16 *)((char *)ptr_0002B4_doors_ddata + v178); - v179 = &pDoors[k]; - v180 = v178 + 2 * v179->field_48; - v179->pDeltaUs = (__int16 *)((char *)ptr_0002B4_doors_ddata + v180); - v181 = &pDoors[k]; - v182 = v180 + 2 * v181->uNumFaces; - v181->pDeltaVs = (__int16 *)((char *)ptr_0002B4_doors_ddata + v182); - v183 = &pDoors[k]; - v184 = v182 + 2 * v183->uNumFaces; - v183->pXOffsets = (unsigned __int16 *)((char *)ptr_0002B4_doors_ddata + v184); - v185 = &pDoors[k]; - v186 = v184 + 2 * v185->uNumOffsets; - v185->pYOffsets = (unsigned __int16 *)((char *)ptr_0002B4_doors_ddata + v186); - v187 = &pDoors[k]; - ++k; - v188 = v186 + 2 * v187->uNumOffsets; - v189 = (unsigned __int16 *)((char *)ptr_0002B4_doors_ddata + v188); - ++v245; - v187->pZOffsets = v189; - v173 = pDoors; - if ( v245 >= uNumDoors ) - break; - }*/ - } - //v190 = 0; - //v245 = 0; - for (uint i = 0; i < uNumDoors; ++i) - { - BLVDoor* pDoor = &pDoors[i]; - - for (uint j = 0; j < pDoor->uNumFaces; ++j) - { - BLVFace* pFace = &pFaces[pDoor->pFaceIDs[j]]; - BLVFaceExtra* pFaceExtra = &pFaceExtras[pFace->uFaceExtraID]; - - pDoor->pDeltaUs[j] = pFaceExtra->sTextureDeltaU; - pDoor->pDeltaVs[j] = pFaceExtra->sTextureDeltaV; - } - //v191 = pDoors; - //pDest = 0; - //do - // { - /*Argsn = 0; - for ( l = (BLVDoor *)&v190[(int)v191]; - Argsn < *(short *)&v190[(int)v191 + 70]; - l = (BLVDoor *)&v190[(int)v191] ) - { - v193 = Argsn; - v194 = l->pFaceIDs[Argsn++]; - v195 = &pFaceExtras[pFaces[v194].uFaceExtraID]; - l->pDeltaUs[v193] = v195->sTextureDeltaU; - v190 = pDest; - *(short *)(v193 * 2 + *(int *)&pDest[(unsigned int)pDoors + 52]) = v195->sTextureDeltaV; - v191 = pDoors; - } - ++v245; - v190 += 80; - pDest = v190;*/ - //} - //while ( v245 < uNumDoors ); - } - - - pGameLoadingUI_ProgressBar->Progress(); - - memcpy(&stru_5E4C90_MapPersistVars, pData, 0xC8); - pData += 0xC8; - - pGameLoadingUI_ProgressBar->Progress(); - - memcpy(&stru1, pData, 0x38u); - pData += 0x38; - - free(pRawDLV); - //v5 = 0; - - pSoundList->LoadSound(64, 0); - pSoundList->LoadSound(103, 0); - pSoundList->LoadSound(63, 0); - pSoundList->LoadSound(102, 0); - pSoundList->LoadSound(50, 0); - pSoundList->LoadSound(89, 0); - - return 0; -} - - -//----- (0049AC17) -------------------------------------------------------- -int IndoorLocation::GetSector(int sX, int sY, int sZ) -{ - int v4; // esi@1 - signed int v25; // edx@21 - int v26; // ebx@23 - int v37; // edi@38 - int pSectorID; // ebx@40 - int v39; // eax@41 - int v43[50]; // [sp+Ch] [bp-108h]@1 - bool v50; // [sp+ECh] [bp-28h]@19 - int v51; // [sp+F0h] [bp-24h]@9 - int v53; // [sp+F8h] [bp-1Ch]@10 - int v54; // [sp+FCh] [bp-18h]@16 - int v55; // [sp+100h] [bp-14h]@1 - int v59; // [sp+110h] [bp-4h]@16 - - v4 = 0; - v43[0] = 0; - - v55 = 0; - - if (uNumSectors < 2) - return 0; - - for (uint i = 1; i < uNumSectors; ++i) - { - BLVSector* pSector = &pSectors[i]; - - if (pSector->pBounding.x1 > sX || pSector->pBounding.x2 < sX || - pSector->pBounding.y1 > sY || pSector->pBounding.y2 < sY || - pSector->pBounding.z1 - 64 > sZ || pSector->pBounding.z2 + 64 < sZ) - continue; - - //Log::Warning(L"Sector[%u]", i); - v51 = pSector->uNumFloors + pSector->uNumPortals; - if (!v51) - continue; - - - for (uint j = 0; j < v51; ++j) - { - uint uFaceID; - if (j < pSector->uNumFloors) - uFaceID = pSector->pFloors[j]; - else - uFaceID = pSector->pPortals[j - pSector->uNumFloors]; - - BLVFace* pFace = &pFaces[uFaceID]; - if (pFace->uPolygonType != POLYGON_Floor && - pFace->uPolygonType != POLYGON_InBetweenFloorAndWall) - continue; - - v54 = 0; - v50 = pVertices[pFace->pVertexIDs[0]].y >= sY; - - for (uint k = 1; k <= pFace->uNumVertices; k++) - { - v59 = v50; - - if (v54 >= 2) - break; - - Vec3* v2 = &pVertices[pFace->pVertexIDs[k]]; - v50 = v2->y >= sY; - - if (v59 == v50) - continue; - - Vec3* v1 = &pVertices[pFace->pVertexIDs[k - 1]]; - v25 = v2->x >= sX ? 0 : 2; - v26 = v25 | (v1->x < sX); - - if (v26 == 3) - continue; - - if (!v26) - ++v54; - else - { - if (v1->x >= v2->x) - { - /*int _a58; - int _a59; - - v32 = v1->x - v2->x; - LODWORD(v33) = v32 << 16; - HIDWORD(v33) = v32 >> 16;*/ - //fixpoint_div(v1->x - v2->x, v1->y - v2->y); - //_a58 = v33 / (v1->y - v2->y); - //_a59 = fixpoint_mul(_a58, sY - v2->y); - long long x_div_y = fixpoint_div(v1->x - v2->x, v1->y - v2->y); - long long res = fixpoint_mul(x_div_y, sY - v2->y); // a / b * c - looks like projection - if (res + v2->x > sX) - ++v54; - } - else - { - long long x_div_y = fixpoint_div(v2->x - v1->x, v2->y - v1->y); - long long res = fixpoint_mul(x_div_y, sY - v1->y); - - if (res + v1->x > sX) - ++v54; - - /*int _a58; - int _a59; - auto v32 = v2->x - v1->x; - LODWORD(v33) = v32 << 16; - HIDWORD(v33) = v32 >> 16; - _a58 = v33 / (v2->y - v1->y); - _a59 = fixpoint_mul(_a58, sY - v1->y); - - if (_a59 + pVertices[k].x > sX) - ++v54;*/ - } - } - } - - if (pFace->uNumVertices && v54 == 1) - v43[v55++] = uFaceID; - } - } - - v4 = v43[0]; - if ( v55 == 1 ) - return this->pFaces[v4].uSectorID; - if ( !v55 ) - return 0; - pSectorID = 0; - v53 = 0xFFFFFFu; - if ( v55 > 0 ) - { - v39 = sY; - for ( v37 = 0; v37 < v55; ++v37 ) - { - if ( this->pFaces[v43[v37]].uPolygonType == POLYGON_Floor ) - v39 = sZ - this->pVertices[*this->pFaces[v43[v37]].pVertexIDs].z; - if ( this->pFaces[v43[v37]].uPolygonType == POLYGON_InBetweenFloorAndWall ) - { - v39 = sZ - ((fixpoint_mul(this->pFaces[v43[v37]].zCalc1, (sX << 16)) - + fixpoint_mul(this->pFaces[v43[v37]].zCalc2, (sY << 16)) - + this->pFaces[v43[v37]].zCalc3 - + 0x8000) >> 16); - } - if ( v39 >= 0 ) - { - if ( v39 < v53 ) - { - pSectorID = this->pFaces[v43[v37]].uSectorID; - v53 = v39; - } - } - } - } - return pSectorID; -} -// 49AC17: using guessed type int var_108[50]; - - -//----- (00498A41) -------------------------------------------------------- -void BLVFace::_get_normals(Vec3_int_ *a2, Vec3_int_ *a3) -{ - Vec3_float_ a1; // [sp+Ch] [bp-Ch]@8 - - if ( this->uPolygonType == POLYGON_VerticalWall ) - { - a2->x = -this->pFacePlane_old.vNormal.y; - a2->y = this->pFacePlane_old.vNormal.x; - a2->z = 0; - - a3->x = 0; - a3->y = 0; - a3->z = 0xFFFF0000u; - - } - else if ( this->uPolygonType == POLYGON_Floor || this->uPolygonType == POLYGON_Ceiling ) - { - a2->x = 0x10000u; - a2->y = 0; - a2->z = 0; - - a3->x = 0; - a3->y = 0xFFFF0000u; - a3->z = 0; - - } - else if ( this->uPolygonType == POLYGON_InBetweenFloorAndWall || this->uPolygonType == POLYGON_InBetweenCeilingAndWall ) - { - if ( abs(this->pFacePlane_old.vNormal.z) < 46441 ) - { - a1.x = (double)-this->pFacePlane_old.vNormal.y; - a1.y = (double)this->pFacePlane_old.vNormal.x; - a1.z = 0.0; - a1.Normalize(); - - a2->x = (signed __int64)(a1.x * 65536.0); - a2->y = (signed __int64)(a1.y * 65536.0); - a2->z = 0; - - a3->y = 0; - a3->z = 0xFFFF0000u; - a3->x = 0; - - } - else - { - a2->x = 0x10000u; - a2->y = 0; - a2->z = 0; - - a3->x = 0; - a3->y = 0xFFFF0000u; - a3->z = 0; - } - - } -//LABEL_12: - if ( this->uAttributes & FACE_UNKNOW3 ) - { - a2->x = -a2->x; - a2->y = -a2->y; - a2->z = -a2->z; - } - if ( this->uAttributes & FACE_UNKNOW4 ) - { - a3->x = -a3->x; - a3->y = -a3->y; - a3->z = -a3->z; - } - return; -} - -//----- (0044C23B) -------------------------------------------------------- -bool BLVFaceExtra::HasEventint() -{ - signed int event_index; // eax@1 - _evt_raw* start_evt; - _evt_raw* end_evt; - - event_index = 0; - if ( (uLevelEVT_NumEvents - 1) <= 0 ) - return false; - while ( pLevelEVT_Index[event_index].uEventID != this->uEventID ) - { - ++event_index; - if ( event_index >= (signed int)(uLevelEVT_NumEvents - 1) ) - return false; - } - end_evt=(_evt_raw*)&pLevelEVT[pLevelEVT_Index[event_index+1].uEventOffsetInEVT]; - start_evt=(_evt_raw*)&pLevelEVT[pLevelEVT_Index[event_index].uEventOffsetInEVT]; - if ( (end_evt->_e_type != EVENT_Exit) || (start_evt->_e_type!= EVENT_MouseOver) ) - return false; - else - return true; -} - -//----- (0046F228) -------------------------------------------------------- -void BLV_UpdateDoors() -{ - BLVFace *face; // ebx@24 - Vec3_short_ *v17; // esi@24 - int v18; // eax@24 - int v19; // edx@24 - signed int v20; // eax@24 - int v24; // esi@25 - int v25; // eax@25 - signed __int64 v27; // qtt@27 - BLVFaceExtra *v28; // esi@32 - int v32; // eax@34 - Vec3_short_ *v34; // eax@35 - int v35; // ecx@35 - int v36; // edx@35 - signed int v37; // eax@35 - signed int v38; // edx@35 - int v39; // eax@35 - int v40; // edx@35 - Vec3_short_ *v43; // edi@36 - int v57; // eax@58 - Vec3_int_ v67; - Vec3_int_ v70; - int v73; // [sp+20h] [bp-44h]@24 - int v75; // [sp+28h] [bp-3Ch]@36 - int v76; // [sp+2Ch] [bp-38h]@36 - int v77; // [sp+30h] [bp-34h]@36 - int v82; // [sp+44h] [bp-20h]@35 - int v83; // [sp+48h] [bp-1Ch]@34 - int v84; // [sp+4Ch] [bp-18h]@34 - SoundID eDoorSoundID; // [sp+54h] [bp-10h]@1 - int v88; // [sp+5Ch] [bp-8h]@18 - int v89; // [sp+60h] [bp-4h]@6 - - eDoorSoundID = (SoundID)pDoorSoundIDsByLocationID[dword_6BE13C_uCurrentlyLoadedLocationID]; - for (uint i = 0; i < pIndoor->uNumDoors; ++i) - { - BLVDoor* door = &pIndoor->pDoors[i]; - if (door->uState == BLVDoor::Closed || door->uState == BLVDoor::Open) - { - door->uAttributes &= 0xFFFFFFFDu;//~0x2 - continue; - } - door->uTimeSinceTriggered += pEventTimer->uTimeElapsed; - if (door->uState == BLVDoor::Opening) - { - v89 = (signed int)(door->uTimeSinceTriggered * door->uCloseSpeed) / 128; - if ( v89 >= door->uMoveLength ) - { - v89 = door->uMoveLength; - door->uState = BLVDoor::Open; - if ( !(door->uAttributes & FACE_UNKNOW5) && door->uNumVertices != 0) - pAudioPlayer->PlaySound((SoundID)((int)eDoorSoundID + 1), PID(OBJECT_BLVDoor,i), 0, -1, 0, 0, 0, 0); - //goto LABEL_18; - } - else if (!(door->uAttributes & FACE_UNKNOW5) && door->uNumVertices) - pAudioPlayer->PlaySound(eDoorSoundID, PID(OBJECT_BLVDoor, i), 1, -1, 0, 0, 0, 0); - } - else - { - signed int v5 = (signed int)(door->uTimeSinceTriggered * door->uOpenSpeed) / 128; - if ( v5 >= door->uMoveLength) - { - v89 = 0; - door->uState = BLVDoor::Closed; - if ( !(door->uAttributes & FACE_UNKNOW5) && door->uNumVertices != 0) - pAudioPlayer->PlaySound((SoundID)((int)eDoorSoundID + 1), PID(OBJECT_BLVDoor,i), 0, -1, 0, 0, 0, 0); - //goto LABEL_18; - } - else - { - v89 = door->uMoveLength - v5; - if (!(door->uAttributes & FACE_UNKNOW5) && door->uNumVertices) - pAudioPlayer->PlaySound(eDoorSoundID, PID(OBJECT_BLVDoor, i), 1, -1, 0, 0, 0, 0); - } - } - -//LABEL_18: - for (uint j = 0; j < door->uNumVertices; ++j) - { - pIndoor->pVertices[door->pVertexIDs[j]].x = fixpoint_mul(door->vDirection.x, v89) + door->pXOffsets[j]; - pIndoor->pVertices[door->pVertexIDs[j]].y = fixpoint_mul(door->vDirection.y, v89) + door->pYOffsets[j]; - pIndoor->pVertices[door->pVertexIDs[j]].z = fixpoint_mul(door->vDirection.z, v89) + door->pZOffsets[j]; - } - for ( v88 = 0; v88 < door->uNumFaces; ++v88 ) - { - face = &pIndoor->pFaces[door->pFaceIDs[v88]]; - v17 = &pIndoor->pVertices[face->pVertexIDs[0]]; - v18 = face->pFacePlane_old.vNormal.y; - v73 = *(int *)&v17->x; - v19 = face->pFacePlane_old.vNormal.z; - v20 = -(v19 * (int)v17->z + (signed __int16)v73 * face->pFacePlane_old.vNormal.x + SHIWORD(v73) * v18); - face->pFacePlane_old.dist = v20; - face->pFacePlane.dist = -((double)v17->z * face->pFacePlane.vNormal.z - + (double)v17->y * face->pFacePlane.vNormal.y - + (double)v17->x * face->pFacePlane.vNormal.x); - if ( v19 ) - { - v24 = abs(v20 >> 15); - v25 = abs(face->pFacePlane_old.vNormal.z); - if ( v24 > v25 ) - Error("Door Error\ndoor id: %i\nfacet no: %i\n\nOverflow dividing facet->d [%i] by facet->nz [%i]", - door->uDoorID, door->pFaceIDs[v88], face->pFacePlane_old.dist, face->pFacePlane_old.vNormal.z); - LODWORD(v27) = face->pFacePlane_old.dist << 16; - HIDWORD(v27) = face->pFacePlane_old.dist >> 16; - face->zCalc3 = -v27 / face->pFacePlane_old.vNormal.z; - } - //if ( face->uAttributes & FACE_TEXTURE_FLOW || pRenderer->pRenderD3D ) - face->_get_normals(&v70, &v67); - v28 = &pIndoor->pFaceExtras[face->uFaceExtraID]; - /*if ( !pRenderer->pRenderD3D ) - { - if ( !(face->uAttributes & FACE_TEXTURE_FLOW) ) - continue; - v83 = (unsigned __int64)(door->vDirection.x * (signed __int64)v70.x) >> 16; - v85 = (unsigned __int64)(door->vDirection.y * (signed __int64)v70.y) >> 16; - v84 = (unsigned __int64)(door->vDirection.z * (signed __int64)v70.z) >> 16; - v29 = v89; - v28->sTextureDeltaU = -((v83 + v85 + v84) * (signed __int64)v89) >> 16; - v85 = (unsigned __int64)(door->vDirection.x * (signed __int64)v67.x) >> 16; - v83 = (unsigned __int64)(door->vDirection.y * (signed __int64)v67.y) >> 16; - v84 = (unsigned __int64)(door->vDirection.z * (signed __int64)v67.z) >> 16; - v31 = (v85 + v83 + v84) * (signed __int64)v29; - v32 = v31 >> 16; - v57 = -v32; - v28->sTextureDeltaV = v57; - v28->sTextureDeltaU += door->pDeltaUs[v88]; - v28->sTextureDeltaV = v57 + door->pDeltaVs[v88]; - continue; - }*/ - v28->sTextureDeltaU = 0; - v28->sTextureDeltaV = 0; - v34 = &pIndoor->pVertices[face->pVertexIDs[0]]; - v35 = v34->z; - v36 = v34->y; - v82 = v34->x; - v37 = v70.x * v82 + v70.y * v36 + v70.z * v35; - v38 = v67.x * v82 + v67.y * v36 + v67.z * v35; - v39 = v37 >> 16; - *face->pVertexUIDs = v39; - v40 = v38 >> 16; - *face->pVertexVIDs = v40; - v84 = v39; - v82 = v40; - for (uint j = 1; j < face->uNumVertices; ++j) - { - v43 = &pIndoor->pVertices[face->pVertexIDs[j]]; - v76 = ((__int64)v70.z * v43->z + (__int64)v70.x * v43->x + (__int64)v70.y * v43->y) >> 16; - v77 = ((__int64)v67.x * v43->x + (__int64)v67.y * v43->y + (__int64)v43->z * v67.z) >> 16; - if ( v76 < v39 ) - v39 = v76; - if ( v77 < v40 ) - v40 = v77; - if ( v76 > v84 ) - v84 = v76; - if ( v77 > v82 ) - v82 = v77; - face->pVertexUIDs[j] = v76; - face->pVertexVIDs[j] = v77; - } - if ( face->uAttributes & 0x00001000 ) - v28->sTextureDeltaU -= v39; - else - { - if ( SBYTE1(face->uAttributes) < 0 ) - { - if ( face->uBitmapID != -1 ) - v28->sTextureDeltaU -= v84 + pBitmaps_LOD->pTextures[face->uBitmapID].uTextureWidth; - } - } - if ( face->uAttributes & FACE_UNKNOW6 ) - v28->sTextureDeltaV -= v40; - else - { - if ( face->uAttributes & FACE_INDOOR_DOOR ) - { - if ( face->uBitmapID != -1 ) - v28->sTextureDeltaV -= v82 + pBitmaps_LOD->GetTexture(face->uBitmapID)->uTextureHeight; - } - } - if ( face->uAttributes & FACE_TEXTURE_FLOW ) - { - v84 = fixpoint_mul(door->vDirection.x, v70.x); - v82 = fixpoint_mul(door->vDirection.y, v70.y); - v83 = fixpoint_mul(door->vDirection.z, v70.z); - v75 = v84 + v82 + v83; - v82 = fixpoint_mul(v75, v89); - v28->sTextureDeltaU = -v82; - v84 = fixpoint_mul(door->vDirection.x, v67.x); - v82 = fixpoint_mul(door->vDirection.y, v67.y); - v83 = fixpoint_mul(door->vDirection.z, v67.z); - v75 = v84 + v82 + v83; - v32 = fixpoint_mul(v75, v89); - v57 = -v32; - v28->sTextureDeltaV = v57; - v28->sTextureDeltaU += door->pDeltaUs[v88]; - v28->sTextureDeltaV = v57 + door->pDeltaVs[v88]; - } - } - } -} -// 6BE13C: using guessed type int dword_6BE13C_uCurrentlyLoadedLocationID; - -//----- (0046F90C) -------------------------------------------------------- -void UpdateActors_BLV() -{ - int v2; // edi@6 - int v3; // eax@6 - int v4; // eax@8 - __int16 v5; // ax@11 - signed int v6; // ebx@14 - signed __int64 v10; // qax@18 - int v22; // edi@46 - unsigned int v24; // eax@51 - int v27; // ST08_4@54 - int v28; // edi@54 - int v29; // eax@54 - int v30; // ecx@62 - int v31; // ebx@62 - int v32; // eax@62 - int v33; // eax@64 - signed int v37; // ebx@85 - int v44; // ecx@96 - int v45; // edi@101 - AIDirection v52; // [sp+0h] [bp-60h]@75 - AIDirection v53; // [sp+1Ch] [bp-44h]@116 - unsigned int uSectorID; // [sp+3Ch] [bp-24h]@6 - int v56; // [sp+40h] [bp-20h]@6 - unsigned int _this; // [sp+44h] [bp-1Ch]@51 - int v58; // [sp+48h] [bp-18h]@51 - int v59; // [sp+4Ch] [bp-14h]@8 - unsigned int uFaceID; // [sp+50h] [bp-10h]@6 - int v61; // [sp+54h] [bp-Ch]@14 - int v62; // [sp+58h] [bp-8h]@6 - unsigned int actor_id; // [sp+5Ch] [bp-4h]@1 - - for ( actor_id = 0; actor_id < uNumActors; actor_id++ ) - { - if ( pActors[actor_id].uAIState == Removed || pActors[actor_id].uAIState == Disabled - || pActors[actor_id].uAIState == Summoned || !pActors[actor_id].uMovementSpeed ) - continue; - uSectorID = pActors[actor_id].uSectorID; - v2 = collide_against_floor(pActors[actor_id].vPosition.x, pActors[actor_id].vPosition.y, pActors[actor_id].vPosition.z, &uSectorID, &uFaceID); - pActors[actor_id].uSectorID = uSectorID; - v3 = pActors[actor_id].pMonsterInfo.uFlying; - v56 = v2; - v62 = v3; - if ( !pActors[actor_id].CanAct() ) - v62 = 0; - v4 = pActors[actor_id].vPosition.z; - v59 = 0; - if ( pActors[actor_id].vPosition.z > v2 + 1 ) - v59 = 1; - if ( v2 <= -30000 ) - { - v5 = pIndoor->GetSector(pActors[actor_id].vPosition.x, pActors[actor_id].vPosition.y, v4); - pActors[actor_id].uSectorID = v5; - v56 = BLV_GetFloorLevel(pActors[actor_id].vPosition.x, pActors[actor_id].vPosition.y, pActors[actor_id].vPosition.z, v5, &uFaceID); - if ( !v5 || v56 == -30000 ) - continue; - } - if ( pActors[actor_id].uCurrentActionAnimation == ANIM_Walking)//монстр двигается - { - v6 = pActors[actor_id].uMovementSpeed; - if ( pActors[actor_id].pActorBuffs[ACTOR_BUFF_SLOWED].uExpireTime > 0 ) - { - if ( pActors[actor_id].pActorBuffs[ACTOR_BUFF_SLOWED].uPower ) - LODWORD(v10) = pActors[actor_id].uMovementSpeed / (unsigned __int16)pActors[actor_id].pActorBuffs[ACTOR_BUFF_SLOWED].uPower; - else - v10 = (signed __int64)((double)pActors[actor_id].uMovementSpeed * 0.5); - v6 = v10; - } - if ( pActors[actor_id].uAIState == Pursuing || pActors[actor_id].uAIState == Fleeing ) - v6 *= 2; - if ( pParty->bTurnBasedModeOn == true && pTurnEngine->turn_stage == TE_WAIT ) - v6 = (signed __int64)((double)v6 * flt_6BE3AC_debug_recmod1_x_1_6); - if ( v6 > 1000 ) - v6 = 1000; - pActors[actor_id].vVelocity.x = fixpoint_mul(stru_5C6E00->Cos(pActors[actor_id].uYawAngle), v6); - pActors[actor_id].vVelocity.y = fixpoint_mul(stru_5C6E00->Sin(pActors[actor_id].uYawAngle), v6); - if ( v62 ) - pActors[actor_id].vVelocity.z = fixpoint_mul(stru_5C6E00->Sin(pActors[actor_id].uPitchAngle), v6); - } - else//actor is not moving(актор не двигается) - { - pActors[actor_id].vVelocity.x = fixpoint_mul(55000, pActors[actor_id].vVelocity.x); - pActors[actor_id].vVelocity.y = fixpoint_mul(55000, pActors[actor_id].vVelocity.y); - if ( v62 ) - pActors[actor_id].vVelocity.z = fixpoint_mul(55000, pActors[actor_id].vVelocity.z); - } - if ( pActors[actor_id].vPosition.z <= v56 ) - { - pActors[actor_id].vPosition.z = v56 + 1; - if ( pIndoor->pFaces[uFaceID].uPolygonType == 3 ) - { - if ( pActors[actor_id].vVelocity.z < 0 ) - pActors[actor_id].vVelocity.z = 0; - } - else - { - if ( pIndoor->pFaces[uFaceID].pFacePlane_old.vNormal.z < 45000 ) - pActors[actor_id].vVelocity.z -= LOWORD(pEventTimer->uTimeElapsed) * GetGravityStrength(); - } - } - else - { - if ( v59 && !v62 ) - pActors[actor_id].vVelocity.z += -8 * LOWORD(pEventTimer->uTimeElapsed) * GetGravityStrength(); - } - if ( pActors[actor_id].vVelocity.x * pActors[actor_id].vVelocity.x - + pActors[actor_id].vVelocity.y * pActors[actor_id].vVelocity.y - + pActors[actor_id].vVelocity.z * pActors[actor_id].vVelocity.z >= 400 ) - { - stru_721530.field_84 = -1; - stru_721530.field_70 = 0; - stru_721530.field_0 = 1; - stru_721530.field_8_radius = pActors[actor_id].uActorRadius; - stru_721530.prolly_normal_d = pActors[actor_id].uActorRadius; - stru_721530.height = pActors[actor_id].uActorHeight; - v22 = 0; - for ( uSectorID = 0; uSectorID < 100; uSectorID++ ) - { - stru_721530.position.x = pActors[actor_id].vPosition.x; - stru_721530.normal.x = stru_721530.position.x; - stru_721530.position.y = pActors[actor_id].vPosition.y; - stru_721530.normal.y = stru_721530.position.y; - stru_721530.normal.z = pActors[actor_id].vPosition.z + pActors[actor_id].uActorRadius + 1; - stru_721530.position.z = pActors[actor_id].vPosition.z - pActors[actor_id].uActorRadius + stru_721530.height - 1; - if ( stru_721530.position.z < stru_721530.normal.z ) - stru_721530.position.z = pActors[actor_id].vPosition.z + pActors[actor_id].uActorRadius + 1; - stru_721530.velocity.x = pActors[actor_id].vVelocity.x; - stru_721530.velocity.y = pActors[actor_id].vVelocity.y; - stru_721530.velocity.z = pActors[actor_id].vVelocity.z; - stru_721530.uSectorID = pActors[actor_id].uSectorID; - if ( !stru_721530._47050A(v22) ) - { - v58 = 0; - v24 = 8 * actor_id; - LOBYTE(v24) = PID(OBJECT_Actor,actor_id); - for ( v61 = 0; v61 < 100; ++v61 ) - { - _46E44E_collide_against_faces_and_portals(1); - _46E0B2_collide_against_decorations(); - _46EF01_collision_chech_player(0); - _46ED8A_collide_against_sprite_objects(v24); - for ( uint j = 0; j < ai_arrays_size; j++ ) - { - if ( ai_near_actors_ids[j] != actor_id ) - { - v27 = abs(pActors[ai_near_actors_ids[j]].vPosition.z - pActors[actor_id].vPosition.z); - v28 = abs(pActors[ai_near_actors_ids[j]].vPosition.y - pActors[actor_id].vPosition.y); - v29 = abs(pActors[ai_near_actors_ids[j]].vPosition.x - pActors[actor_id].vPosition.x); - if ( int_get_vector_length(v29, v28, v27) >= pActors[actor_id].uActorRadius + (signed int)pActors[ai_near_actors_ids[j]].uActorRadius - && Actor::_46DF1A_collide_against_actor(ai_near_actors_ids[j], 40) ) - ++v58; - } - } - if ( _46F04E_collide_against_portals() ) - break; - } - v56 = v58 > 1; - if ( stru_721530.field_7C >= stru_721530.field_6C ) - { - v30 = stru_721530.normal2.x; - v31 = stru_721530.normal2.y; - v32 = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1; - } - else - { - v30 = pActors[actor_id].vPosition.x + fixpoint_mul(stru_721530.field_7C, stru_721530.direction.x); - v31 = pActors[actor_id].vPosition.y + fixpoint_mul(stru_721530.field_7C, stru_721530.direction.y); - v32 = pActors[actor_id].vPosition.z + fixpoint_mul(stru_721530.field_7C, stru_721530.direction.z); - } - v33 = collide_against_floor(v30, v31, v32, &stru_721530.uSectorID, &uFaceID); - if (pIndoor->pFaces[uFaceID].uAttributes & FACE_INDOOR_SKY && pActors[actor_id].uAIState == Dead) - { - pActors[actor_id].uAIState = Removed; - continue; - } - if ( v59 || v62 || !(pIndoor->pFaces[uFaceID].uAttributes & FACE_INDOOR_SKY) ) - { - if ( v33 == -30000 ) - continue; - if ( pActors[actor_id].uCurrentActionAnimation != 1 || v33 >= pActors[actor_id].vPosition.z - 100 || v59 || v62 ) - { - if ( stru_721530.field_7C < stru_721530.field_6C ) - { - pActors[actor_id].vPosition.x += fixpoint_mul(stru_721530.field_7C, stru_721530.direction.x); - pActors[actor_id].vPosition.y += fixpoint_mul(stru_721530.field_7C, stru_721530.direction.y); - pActors[actor_id].vPosition.z += fixpoint_mul(stru_721530.field_7C, stru_721530.direction.z); - pActors[actor_id].uSectorID = LOWORD(stru_721530.uSectorID); - stru_721530.field_70 += stru_721530.field_7C; - v37 = PID_ID(stru_721530.uFaceID); - if (PID_TYPE(stru_721530.uFaceID) == OBJECT_Actor) - { - if (pParty->bTurnBasedModeOn == 1 && (pTurnEngine->turn_stage == TE_ATTACK || pTurnEngine->turn_stage == TE_MOVEMENT)) - { - pActors[actor_id].vVelocity.x = fixpoint_mul(58500, pActors[actor_id].vVelocity.x); - pActors[actor_id].vVelocity.y = fixpoint_mul(58500, pActors[actor_id].vVelocity.y); - pActors[actor_id].vVelocity.z = fixpoint_mul(58500, pActors[actor_id].vVelocity.z); - v22 = 0; - continue; - } - if (pActors[actor_id].pMonsterInfo.uHostilityType) - { - if (!v56) - { - Actor::AI_Flee(actor_id, stru_721530.uFaceID, v22, (AIDirection *)v22); - pActors[actor_id].vVelocity.x = fixpoint_mul(58500, pActors[actor_id].vVelocity.x); - pActors[actor_id].vVelocity.y = fixpoint_mul(58500, pActors[actor_id].vVelocity.y); - pActors[actor_id].vVelocity.z = fixpoint_mul(58500, pActors[actor_id].vVelocity.z); - v22 = 0; - continue; - } - } - else - { - if (!v56) - { - if (!pActors[v37].pMonsterInfo.uHostilityType) - { - Actor::AI_FaceObject(actor_id, stru_721530.uFaceID, v22, (AIDirection *)v22); - pActors[actor_id].vVelocity.x = fixpoint_mul(58500, pActors[actor_id].vVelocity.x); - pActors[actor_id].vVelocity.y = fixpoint_mul(58500, pActors[actor_id].vVelocity.y); - pActors[actor_id].vVelocity.z = fixpoint_mul(58500, pActors[actor_id].vVelocity.z); - v22 = 0; - continue; - } - Actor::AI_Flee(actor_id, stru_721530.uFaceID, v22, (AIDirection *)v22); - pActors[actor_id].vVelocity.x = fixpoint_mul(58500, pActors[actor_id].vVelocity.x); - pActors[actor_id].vVelocity.y = fixpoint_mul(58500, pActors[actor_id].vVelocity.y); - pActors[actor_id].vVelocity.z = fixpoint_mul(58500, pActors[actor_id].vVelocity.z); - v22 = 0; - continue; - } - } - Actor::AI_StandOrBored(actor_id, 4, v22, &v53); - pActors[actor_id].vVelocity.x = fixpoint_mul(58500, pActors[actor_id].vVelocity.x); - pActors[actor_id].vVelocity.y = fixpoint_mul(58500, pActors[actor_id].vVelocity.y); - pActors[actor_id].vVelocity.z = fixpoint_mul(58500, pActors[actor_id].vVelocity.z); - v22 = 0; - continue; - } - if (PID_TYPE(stru_721530.uFaceID) == OBJECT_Player) - { - if (pActors[actor_id].GetActorsRelation(0)) - { - //v51 = __OFSUB__(HIDWORD(pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime), v22); - //v49 = HIDWORD(pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime) == v22; - //v50 = HIDWORD(pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime) - v22 < 0; - pActors[actor_id].vVelocity.y = v22; - pActors[actor_id].vVelocity.x = v22; - if (pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime > v22) - pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].Reset(); - viewparams->bRedrawGameUI = 1; - pActors[actor_id].vVelocity.x = fixpoint_mul(58500, pActors[actor_id].vVelocity.x); - pActors[actor_id].vVelocity.y = fixpoint_mul(58500, pActors[actor_id].vVelocity.y); - pActors[actor_id].vVelocity.z = fixpoint_mul(58500, pActors[actor_id].vVelocity.z); - v22 = 0; - continue; - } - Actor::AI_FaceObject(actor_id, stru_721530.uFaceID, v22, (AIDirection *)v22); - pActors[actor_id].vVelocity.x = fixpoint_mul(58500, pActors[actor_id].vVelocity.x); - pActors[actor_id].vVelocity.y = fixpoint_mul(58500, pActors[actor_id].vVelocity.y); - pActors[actor_id].vVelocity.z = fixpoint_mul(58500, pActors[actor_id].vVelocity.z); - v22 = 0; - continue; - } - if (PID_TYPE(stru_721530.uFaceID) == OBJECT_Decoration) - { - _this = integer_sqrt(pActors[actor_id].vVelocity.x * pActors[actor_id].vVelocity.x + pActors[actor_id].vVelocity.y * pActors[actor_id].vVelocity.y); - v45 = stru_5C6E00->Atan2(pActors[actor_id].vPosition.x - pLevelDecorations[v37].vPosition.x, - pActors[actor_id].vPosition.y - pLevelDecorations[v37].vPosition.y); - pActors[actor_id].vVelocity.x = fixpoint_mul(stru_5C6E00->Cos(v45), _this); - pActors[actor_id].vVelocity.y = fixpoint_mul(stru_5C6E00->Sin(v45), _this); - pActors[actor_id].vVelocity.x = fixpoint_mul(58500, pActors[actor_id].vVelocity.x); - pActors[actor_id].vVelocity.y = fixpoint_mul(58500, pActors[actor_id].vVelocity.y); - pActors[actor_id].vVelocity.z = fixpoint_mul(58500, pActors[actor_id].vVelocity.z); - v22 = 0; - continue; - } - if (PID_TYPE(stru_721530.uFaceID) == OBJECT_BModel) - { - stru_721530.field_84 = stru_721530.uFaceID >> 3; - if (pIndoor->pFaces[v37].uPolygonType == 3) - { - pActors[actor_id].vVelocity.z = 0; - pActors[actor_id].vPosition.z = pIndoor->pVertices[*pIndoor->pFaces[v37].pVertexIDs].z + 1; - if (pActors[actor_id].vVelocity.x * pActors[actor_id].vVelocity.x - + pActors[actor_id].vVelocity.y * pActors[actor_id].vVelocity.y < 400) - { - pActors[actor_id].vVelocity.y = 0; - pActors[actor_id].vVelocity.x = 0; - pActors[actor_id].vVelocity.x = fixpoint_mul(58500, pActors[actor_id].vVelocity.x); - pActors[actor_id].vVelocity.y = fixpoint_mul(58500, pActors[actor_id].vVelocity.y); - pActors[actor_id].vVelocity.z = fixpoint_mul(58500, pActors[actor_id].vVelocity.z); - v22 = 0; - continue; - } - } - else - { - v61 = abs(pIndoor->pFaces[v37].pFacePlane_old.vNormal.x * pActors[actor_id].vVelocity.x + pIndoor->pFaces[v37].pFacePlane_old.vNormal.y - * pActors[actor_id].vVelocity.y - + pIndoor->pFaces[v37].pFacePlane_old.vNormal.z - * pActors[actor_id].vVelocity.z) >> 16; - if ((stru_721530.speed >> 3) > v61) - v61 = stru_721530.speed >> 3; - pActors[actor_id].vVelocity.x += fixpoint_mul(v61, pIndoor->pFaces[v37].pFacePlane_old.vNormal.x); - pActors[actor_id].vVelocity.y += fixpoint_mul(v61, pIndoor->pFaces[v37].pFacePlane_old.vNormal.y); - pActors[actor_id].vVelocity.z += fixpoint_mul(v61, pIndoor->pFaces[v37].pFacePlane_old.vNormal.z); - if (pIndoor->pFaces[v37].uPolygonType != 4 && pIndoor->pFaces[v37].uPolygonType != 3) - { - v44 = stru_721530.prolly_normal_d - - ((pIndoor->pFaces[v37].pFacePlane_old.dist - + pIndoor->pFaces[v37].pFacePlane_old.vNormal.z * pActors[actor_id].vPosition.z - + pIndoor->pFaces[v37].pFacePlane_old.vNormal.y * pActors[actor_id].vPosition.y - + pIndoor->pFaces[v37].pFacePlane_old.vNormal.x * pActors[actor_id].vPosition.x) >> 16); - if (v44 > 0) - { - pActors[actor_id].vPosition.x += fixpoint_mul(v44, pIndoor->pFaces[v37].pFacePlane_old.vNormal.x); - pActors[actor_id].vPosition.y += fixpoint_mul(v44, pIndoor->pFaces[v37].pFacePlane_old.vNormal.y); - pActors[actor_id].vPosition.z += fixpoint_mul(v44, pIndoor->pFaces[v37].pFacePlane_old.vNormal.z); - } - pActors[actor_id].uYawAngle = stru_5C6E00->Atan2(pActors[actor_id].vVelocity.x, pActors[actor_id].vVelocity.y); - } - } - if (pIndoor->pFaces[v37].uAttributes & FACE_UNKNOW1) - EventProcessor(pIndoor->pFaceExtras[pIndoor->pFaces[v37].uFaceExtraID].uEventID, 0, 1); - } - pActors[actor_id].vVelocity.x = fixpoint_mul(58500, pActors[actor_id].vVelocity.x); - pActors[actor_id].vVelocity.y = fixpoint_mul(58500, pActors[actor_id].vVelocity.y); - pActors[actor_id].vVelocity.z = fixpoint_mul(58500, pActors[actor_id].vVelocity.z); - v22 = 0; - continue; - } - else - { - pActors[actor_id].vPosition.x = LOWORD(stru_721530.normal2.x); - pActors[actor_id].vPosition.y = LOWORD(stru_721530.normal2.y); - pActors[actor_id].vPosition.z = LOWORD(stru_721530.normal2.z) - LOWORD(stru_721530.prolly_normal_d) - 1; - pActors[actor_id].uSectorID = LOWORD(stru_721530.uSectorID); - //goto LABEL_123; - break; - } - - } - else if ( pActors[actor_id].vPosition.x & 1 ) - pActors[actor_id].uYawAngle += 100; - else - pActors[actor_id].uYawAngle -= 100; - } - else - { - if (pParty->bTurnBasedModeOn == 1 && (pTurnEngine->turn_stage == TE_ATTACK || pTurnEngine->turn_stage == TE_MOVEMENT)) - continue; - if ( !pActors[actor_id].pMonsterInfo.uHostilityType || v56 != v22 ) - { - Actor::AI_StandOrBored(actor_id, 4, v22, &v52); - continue; - } - } - } - } - } - else - { - pActors[actor_id].vVelocity.z = 0; - pActors[actor_id].vVelocity.y = 0; - pActors[actor_id].vVelocity.x = 0; - if ( pIndoor->pFaces[uFaceID].uAttributes & FACE_INDOOR_SKY ) - { - if (pActors[actor_id].uAIState == Dead) - pActors[actor_id].uAIState = Removed; - } - } -//LABEL_123: - ; - } -} - - -//----- (00460A78) -------------------------------------------------------- -void PrepareToLoadBLV(unsigned int bLoading) -{ - unsigned int respawn; // ebx@1 - unsigned int map_id; // eax@8 - MapInfo *map_info; // edi@9 - int v4; // eax@11 - DecorationDesc *decoration; // eax@54 - char v28; // zf@81 - signed int v30; // edi@94 - int v34[4]; // [sp+3E8h] [bp-2Ch]@96 - int v35; // [sp+3F8h] [bp-1Ch]@1 - int v38; // [sp+404h] [bp-10h]@1 - int pDest; // [sp+40Ch] [bp-8h]@1 - - respawn = 0; - pGameLoadingUI_ProgressBar->Reset(0x20u); - bUnderwater = false; - bNoNPCHiring = false; - pDest = 1; - uCurrentlyLoadedLevelType = LEVEL_Indoor; - pGame->uFlags2 &= 0xFFFFFFF7u; - if ( Is_out15odm_underwater() ) - { - bUnderwater = true; - pGame->uFlags2 |= 8; - } - if ( !_stricmp(pCurrentMapName, "out15.odm") || !_stricmp(pCurrentMapName, "d23.blv") ) - bNoNPCHiring = true; - pPaletteManager->pPalette_tintColor[0] = 0; - pPaletteManager->pPalette_tintColor[1] = 0; - pPaletteManager->pPalette_tintColor[2] = 0; - pPaletteManager->RecalculateAll(); - if ( _A750D8_player_speech_timer ) - _A750D8_player_speech_timer = 0i64; - map_id = pMapStats->GetMapInfo(pCurrentMapName); - if ( map_id ) - { - map_info = &pMapStats->pInfos[map_id]; - respawn = pMapStats->pInfos[map_id].uRespawnIntervalDays; - v38 = GetAlertStatus(); - } - else - map_info = (MapInfo *)bLoading; - dword_6BE13C_uCurrentlyLoadedLocationID = map_id; - - pStationaryLightsStack->uNumLightsActive = 0; - v4 = pIndoor->Load(pCurrentMapName, (unsigned int)(signed __int64)((double)pParty->uTimePlayed * 0.234375) / 60 / 60 / 24 + 1, respawn, (char *)&pDest) - 1; - if ( !v4 ) - Error("Unable to open %s", pCurrentMapName); - - if ( v4 == 1 ) - Error("File %s is not a BLV File", pCurrentMapName); - - if ( v4 == 2 ) - Error("Attempt to open new level before clearing old"); - if ( v4 == 3 ) - Error("Out of memory loading indoor level"); - if ( !(dword_6BE364_game_settings_1 & GAME_SETTINGS_2000) ) - { - Actor::InitializeActors(); - SpriteObject::InitializeSpriteObjects(); - } - dword_6BE364_game_settings_1 &= ~GAME_SETTINGS_2000; - if ( !map_id ) - pDest = 0; - if ( pDest == 1 ) - { - for (uint i = 0; i < pIndoor->uNumSpawnPoints; ++i ) - { - if ( pIndoor->pSpawnPoints[i].uKind == 3 ) - SpawnEncounter(map_info, &pIndoor->pSpawnPoints[i], 0, 0, 0); - else - map_info->SpawnRandomTreasure(&pIndoor->pSpawnPoints[i]); - } - RespawnGlobalDecorations(); - } - - pSoundList->LoadSound(pDoorSoundIDsByLocationID[map_id], 0); - pSoundList->LoadSound(pDoorSoundIDsByLocationID[map_id] + 1, 0); - - for (uint i = 0; i < pIndoor->uNumDoors; ++i) - { - if (pIndoor->pDoors[i].uAttributes & 0x01) - { - pIndoor->pDoors[i].uState = BLVDoor::Opening; - pIndoor->pDoors[i].uTimeSinceTriggered = 15360; - pIndoor->pDoors[i].uAttributes = 2; - } - - if (pIndoor->pDoors[i].uState == BLVDoor::Closed) - { - pIndoor->pDoors[i].uState = BLVDoor::Closing; - pIndoor->pDoors[i].uTimeSinceTriggered = 15360; - pIndoor->pDoors[i].uAttributes = 2; - } - else if (pIndoor->pDoors[i].uState == BLVDoor::Open) - { - pIndoor->pDoors[i].uState = BLVDoor::Opening; - pIndoor->pDoors[i].uTimeSinceTriggered = 15360; - pIndoor->pDoors[i].uAttributes = 2; - } - } - - for (uint i = 0; i < pIndoor->uNumFaces; ++i) - { - if (pIndoor->pFaces[i].uBitmapID != -1) - pBitmaps_LOD->pTextures[pIndoor->pFaces[i].uBitmapID].palette_id2 = pPaletteManager->LoadPalette(pBitmaps_LOD->pTextures[pIndoor->pFaces[i].uBitmapID].palette_id1); - } - - pGameLoadingUI_ProgressBar->Progress(); - - v35 = 0; - for (uint i = 0; i < uNumLevelDecorations; ++i) - { - pDecorationList->InitializeDecorationSprite(pLevelDecorations[i].uDecorationDescID); - - if (pDecorationList->pDecorations[pLevelDecorations[i].uDecorationDescID].uSoundID && _6807E0_num_decorations_with_sounds_6807B8 < 9) - { - pSoundList->LoadSound(pDecorationList->pDecorations[pLevelDecorations[i].uDecorationDescID].uSoundID, 0); - _6807B8_level_decorations_ids[_6807E0_num_decorations_with_sounds_6807B8++] = i; - } - - if (!(pLevelDecorations[i].uFlags & LEVEL_DECORATION_INVISIBLE)) - { - decoration = &pDecorationList->pDecorations[pLevelDecorations[i].uDecorationDescID]; - if (!decoration->DontDraw()) - { - if ( decoration->uLightRadius ) - { - unsigned char r = 255, - g = 255, - b = 255; - if (/*pRenderer->pRenderD3D*/true && pRenderer->bUseColoredLights) - { - r = decoration->uColoredLightRed; - g = decoration->uColoredLightGreen; - b = decoration->uColoredLightBlue; - } - pStationaryLightsStack->AddLight(pLevelDecorations[i].vPosition.x, - pLevelDecorations[i].vPosition.y, - pLevelDecorations[i].vPosition.z + decoration->uDecorationHeight, decoration->uLightRadius, r, g, b, _4E94D0_light_type); - } - } - } - - if (!pLevelDecorations[i].uEventID) - { - if (pLevelDecorations[i].IsInteractive()) - { - if ( v35 < 124 ) - { - pLevelDecorations[i]._idx_in_stru123 = v35 + 75; - if ( !stru_5E4C90_MapPersistVars._decor_events[v35] ) - pLevelDecorations[i].uFlags |= LEVEL_DECORATION_INVISIBLE; - v35++; - } - } - } - } - - pGameLoadingUI_ProgressBar->Progress(); - - for (uint i = 0; i < uNumSpriteObjects; ++i) - { - if (pSpriteObjects[i].uObjectDescID) - { - if ( pSpriteObjects[i].stru_24.uItemID ) - { - if ( pSpriteObjects[i].stru_24.uItemID != 220 && pItemsTable->pItems[ pSpriteObjects[i].stru_24.uItemID].uEquipType == EQUIP_POTION && - !pSpriteObjects[i].stru_24.uEnchantmentType) - pSpriteObjects[i].stru_24.uEnchantmentType = rand() % 15 + 5; - pItemsTable->SetSpecialBonus(&pSpriteObjects[i].stru_24); - } - } - } - - // INDOOR initialize actors - v38 = 0; - for (uint i = 0; i < uNumActors; ++i) - { - if (pActors[i].uAttributes & ACTOR_UNKNOW7) - { - if ( !map_id ) - { - pActors[i].pMonsterInfo.field_3E = 19; - pActors[i].uAttributes |= ACTOR_UNKNOW11; - continue; - } - v28 = v38 == 0; - } - else - v28 = v38 == 1; - - if ( !v28 ) - { - pActors[i].PrepareSprites(0); - pActors[i].pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly; - if ( pActors[i].pMonsterInfo.field_3E != 11 && pActors[i].pMonsterInfo.field_3E != 19 && (!pActors[i].sCurrentHP || !pActors[i].pMonsterInfo.uHP) ) - { - pActors[i].pMonsterInfo.field_3E = 5; - pActors[i].UpdateAnimation(); - } - } - else - { - pActors[i].pMonsterInfo.field_3E = 19; - pActors[i].uAttributes |= ACTOR_UNKNOW11; - } - } - - pGameLoadingUI_ProgressBar->Progress(); - - //Party to start position - Actor this_; - this_.pMonsterInfo.uID = 45; - this_.PrepareSprites(0); - if ( !bLoading ) - { - pParty->sRotationX = 0; - pParty->sRotationY = 0; - pParty->vPosition.z = 0; - pParty->vPosition.y = 0; - pParty->vPosition.x = 0; - pParty->uFallStartY = 0; - pParty->uFallSpeed = 0; - TeleportToStartingPoint(uLevel_StartingPointType); - } - viewparams->_443365(); - PlayLevelMusic(); - if ( !bLoading ) - { - v30 = 0; - for ( uint pl_id = 1; pl_id <= 4; ++pl_id ) - { - if ( pPlayers[pl_id]->CanAct() ) - v34[v30++] = pl_id; - } - if ( v30 ) - { - if ( pDest ) - { - _A750D8_player_speech_timer = 256i64; - PlayerSpeechID = SPEECH_46; - uSpeakingCharacter = v34[rand() % v30]; - } - } - } -} -//----- (0046CEC3) -------------------------------------------------------- -int BLV_GetFloorLevel(int x, int y, int z, unsigned int uSectorID, unsigned int *pFaceID) -{ - int v13; // ecx@13 - signed int v14; // ebx@14 - int v15; // eax@16 - int v21; // eax@27 - signed int v28; // eax@45 - int v29; // ebx@47 - int v38; // edx@62 - bool v47; // [sp+24h] [bp-1Ch]@43 - bool current_vertices_Y; // [sp+28h] [bp-18h]@10 - bool v49; // [sp+28h] [bp-18h]@41 - bool next_vertices_Y; // [sp+2Ch] [bp-14h]@12 - signed int number_hits; // [sp+30h] [bp-10h]@10 - signed int v54; // [sp+30h] [bp-10h]@41 - signed int v55; // [sp+34h] [bp-Ch]@1 - - //LOG_DECOMPILATION_WARNING(); - - static int blv_floor_id[50]; // 00721200 - static int blv_floor_level[50]; // 007212C8 - - static __int16 blv_floor_face_vert_coord_Y[104]; // word_721390_ys - static __int16 blv_floor_face_vert_coord_X[104]; // word_721460_xs - - BLVSector* pSector = &pIndoor->pSectors[uSectorID]; - v55 = 0; - for (uint i = 0; i < pSector->uNumFloors; ++i) - { - BLVFace* pFloor = &pIndoor->pFaces[pSector->pFloors[i]]; - if (pFloor->Ethereal()) - continue; - - assert(pFloor->uNumVertices); - if (x <= pFloor->pBounding.x2 && x >= pFloor->pBounding.x1 && - y <= pFloor->pBounding.y2 && y >= pFloor->pBounding.y1) - { - for (uint j = 0; j < pFloor->uNumVertices; ++j) - { - blv_floor_face_vert_coord_X[2 * j] = pFloor->pXInterceptDisplacements[j] + pIndoor->pVertices[pFloor->pVertexIDs[j]].x; - blv_floor_face_vert_coord_X[2 * j + 1] = pFloor->pXInterceptDisplacements[j] + pIndoor->pVertices[pFloor->pVertexIDs[j + 1]].x; - blv_floor_face_vert_coord_Y[2 * j] = pFloor->pYInterceptDisplacements[j] + pIndoor->pVertices[pFloor->pVertexIDs[j]].y; - blv_floor_face_vert_coord_Y[2 * j + 1] = pFloor->pYInterceptDisplacements[j] + pIndoor->pVertices[pFloor->pVertexIDs[j + 1]].y; - } - blv_floor_face_vert_coord_X[2 * pFloor->uNumVertices] = blv_floor_face_vert_coord_X[0]; - blv_floor_face_vert_coord_Y[2 * pFloor->uNumVertices] = blv_floor_face_vert_coord_Y[0]; - - next_vertices_Y = blv_floor_face_vert_coord_Y[0] >= y; - number_hits = 0; - - for (uint j = 0; j < 2 * pFloor->uNumVertices; ++j) - { - if (number_hits >= 2) - break; - - current_vertices_Y = next_vertices_Y; - next_vertices_Y = blv_floor_face_vert_coord_Y[j + 1] >= y; - - v13 = i; - if (current_vertices_Y == next_vertices_Y) - continue; - - v14 = blv_floor_face_vert_coord_X[j + 1] >= x ? 0 : 2; - v15 = v14 | (blv_floor_face_vert_coord_X[j] < x); - - if (v15 == 3) - continue; - else if (!v15) - ++number_hits; - else - { - long long a_div_b = fixpoint_div(y - blv_floor_face_vert_coord_Y[j], blv_floor_face_vert_coord_Y[j + 1] - blv_floor_face_vert_coord_Y[j]); - long long res = fixpoint_mul((signed int)blv_floor_face_vert_coord_X[j + 1] - (signed int)blv_floor_face_vert_coord_X[j], a_div_b); - - if (res + blv_floor_face_vert_coord_X[j] >= x) - ++number_hits; - } - } - - - if ( number_hits == 1 ) - { - if ( v55 >= 50 ) - break; - if ( pFloor->uPolygonType == POLYGON_Floor || pFloor->uPolygonType == POLYGON_Ceiling ) - v21 = pIndoor->pVertices[pFloor->pVertexIDs[0]].z; - else - v21 = fixpoint_mul(pFloor->zCalc1, x) + fixpoint_mul(pFloor->zCalc2, y) + (short)(pFloor->zCalc3 >> 16); - blv_floor_level[v55] = v21; - blv_floor_id[v55] = pSector->pFloors[i]; - v55++; - } - } - } - - if ( pSector->field_0 & 8 ) - { - for (uint i = 0; i < pSector->uNumPortals; ++i) - { - BLVFace* portal = &pIndoor->pFaces[pSector->pPortals[i]]; - if (portal->uPolygonType != POLYGON_Floor) - continue; - - if (!portal->uNumVertices) - continue; - - if (x <= portal->pBounding.x2 && x >= portal->pBounding.x1 && - y <= portal->pBounding.y2 && y >= portal->pBounding.y1 ) - { - for (uint j = 0; j < portal->uNumVertices; ++j) - { - blv_floor_face_vert_coord_X[2 * j] = portal->pXInterceptDisplacements[j] + pIndoor->pVertices[portal->pVertexIDs[j]].x; - blv_floor_face_vert_coord_X[2 * j + 1] = portal->pXInterceptDisplacements[j + 1] + pIndoor->pVertices[portal->pVertexIDs[j + 1]].x; - blv_floor_face_vert_coord_Y[2 * j] = portal->pYInterceptDisplacements[j] + pIndoor->pVertices[portal->pVertexIDs[j]].y; - blv_floor_face_vert_coord_Y[2 * j + 1] = portal->pYInterceptDisplacements[j + 1] + pIndoor->pVertices[portal->pVertexIDs[j + 1]].y; - } - blv_floor_face_vert_coord_X[2 * portal->uNumVertices] = blv_floor_face_vert_coord_X[0]; - blv_floor_face_vert_coord_Y[2 * portal->uNumVertices] = blv_floor_face_vert_coord_Y[0]; - v54 = 0; - v47 = blv_floor_face_vert_coord_Y[0] >= y; - - for (uint j = 0; j < 2 * portal->uNumVertices; ++j) - { - v49 = v47; - if ( v54 >= 2 ) - break; - v47 = blv_floor_face_vert_coord_Y[j + 1] >= y; - if ( v49 != v47 ) - { - v28 = blv_floor_face_vert_coord_X[j + 1] >= x ? 0 : 2; - v29 = v28 | (blv_floor_face_vert_coord_X[j] < x); - if ( v29 != 3 ) - { - if ( !v29 ) - ++v54; - else - { - long long a_div_b = fixpoint_div(y - blv_floor_face_vert_coord_Y[j], blv_floor_face_vert_coord_Y[j + 1] - blv_floor_face_vert_coord_Y[j]); - long long res = fixpoint_mul(blv_floor_face_vert_coord_X[j + 1] - blv_floor_face_vert_coord_X[j], a_div_b); - if (res + blv_floor_face_vert_coord_X[j] >= x) - ++v54; - } - } - } - } - if ( v54 == 1 ) - { - if ( v55 >= 50 ) - break; - blv_floor_level[v55] = -29000; - blv_floor_id[v55] = pSector->pPortals[i]; - v55++; - } - } - } - } - if ( v55 == 1 ) - { - *pFaceID = blv_floor_id[0]; - if ( blv_floor_level[0] <= -29000 ) - __debugbreak(); - return blv_floor_level[0]; - } - if ( !v55 ) - return -30000; - *pFaceID = blv_floor_id[0]; - //result = blv_floor_level[0]; - - /*for ( v35 = 1; v35 < v55; ++v35 ) - { - if ( blv_floor_level[0] <= z + 5 ) - { - if ( blv_floor_level[v35] >= blv_floor_level[0] || blv_floor_level[v35] > z + 5 ) - continue; - blv_floor_level[0] = blv_floor_level[v35]; - *pFaceID = blv_floor_id[v35]; - continue; - } - if ( blv_floor_level[v35] < blv_floor_level[0] ) - { - blv_floor_level[0] = blv_floor_level[v35]; - *pFaceID = blv_floor_id[v35]; - } - }*/ - - - int result = blv_floor_level[0]; - for (uint i = 1; i < v55; ++i) - { - v38 = blv_floor_level[i]; - if ( result <= z + 5 ) - { - if ( v38 > result && v38 <= z + 5 ) - { - result = blv_floor_level[i]; - if ( blv_floor_level[i] <= -29000 ) - __debugbreak(); - *pFaceID = blv_floor_id[i]; - } - } - else if ( v38 < result ) - { - result = blv_floor_level[i]; - if ( blv_floor_level[i] <= -29000 ) - __debugbreak(); - *pFaceID = blv_floor_id[i]; - } - } - - return result; -} -//----- (0043FDED) -------------------------------------------------------- -void PrepareActorRenderList_BLV() -{ - unsigned int v4; // eax@5 - int v6; // esi@5 - int v8; // eax@10 - SpriteFrame *v9; // eax@16 - int v12; // ecx@28 - signed __int64 v18; // qtt@36 - int v25; // edx@44 - __int16 v26; // ax@44 - int a5a; // [sp+2Ch] [bp-28h]@36 - __int16 v41; // [sp+3Ch] [bp-18h]@18 - int a6; // [sp+40h] [bp-14h]@34 - int v43; // [sp+44h] [bp-10h]@34 - int z; // [sp+48h] [bp-Ch]@32 - signed int y; // [sp+4Ch] [bp-8h]@32 - int x; // [sp+50h] [bp-4h]@32 - - for (uint i = 0; i < uNumActors; ++i) - { - if (pActors[i].uAIState == Removed || pActors[i].uAIState == Disabled) - continue; - - v4 = stru_5C6E00->Atan2(pActors[i].vPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x, pActors[i].vPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y); - v6 = ((signed int)(pActors[i].uYawAngle + ((signed int)stru_5C6E00->uIntegerPi >> 3) - v4 + stru_5C6E00->uIntegerPi) >> 8) & 7; - v8 = pActors[i].uCurrentActionTime; - if ( pParty->bTurnBasedModeOn ) - { - if ( pActors[i].uCurrentActionAnimation == 1 ) - v8 = i * 32 + pMiscTimer->uTotalGameTimeElapsed; - } - else - { - if ( pActors[i].uCurrentActionAnimation == 1 ) - v8 = i * 32 + pBLVRenderParams->field_0_timer_; - } - if (pActors[i].pActorBuffs[ACTOR_BUFF_STONED].uExpireTime > 0 || pActors[i].pActorBuffs[ACTOR_BUFF_PARALYZED].uExpireTime > 0 ) - v8 = 0; - - if (pActors[i].uAIState == Resurrected) - v9 = pSpriteFrameTable->GetFrameBy_x(pActors[i].pSpriteIDs[pActors[i].uCurrentActionAnimation], v8); - else - v9 = pSpriteFrameTable->GetFrame(pActors[i].pSpriteIDs[pActors[i].uCurrentActionAnimation], v8); - - v41 = 0; - if (v9->uFlags & 2) - v41 = 2; - if (v9->uFlags & 0x40000) - v41 |= 0x40u; - if (v9->uFlags & 0x20000) - LOBYTE(v41) = v41 | 0x80; - if ( (256 << v6) & v9->uFlags) - v41 |= 4; - if ( v9->uGlowRadius ) - { - //LOBYTE(v11) = _4E94D3_light_type; - pMobileLightsStack->AddLight(pActors[i].vPosition.x, pActors[i].vPosition.y, pActors[i].vPosition.z, pActors[i].uSectorID, v9->uGlowRadius, 0xFFu, 0xFFu, 0xFFu, _4E94D3_light_type); - } - for ( v12 = 0; v12 < pBspRenderer->uNumVisibleNotEmptySectors; ++v12 ) - { - if ( pBspRenderer->pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[v12] == pActors[i].uSectorID ) - { - if ( !pGame->pIndoorCameraD3D->ApplyViewTransform_TrueIfStillVisible_BLV(pActors[i].vPosition.x, pActors[i].vPosition.y, pActors[i].vPosition.z, &x, &y, &z, 1) - || abs(x) < abs(y) ) - continue; - pGame->pIndoorCameraD3D->Project(x, y, z, &v43, &a6); - if (uNumBillboardsToDraw >= 500) - break; - ++uNumBillboardsToDraw; - ++uNumSpritesDrawnThisFrame; - pActors[i].uAttributes |= ACTOR_UNKNOW2; - pBillboardRenderList[uNumBillboardsToDraw - 1].HwSpriteID = v9->pHwSpriteIDs[v6]; - pBillboardRenderList[uNumBillboardsToDraw - 1].uPalette = v9->uPaletteIndex; - pBillboardRenderList[uNumBillboardsToDraw - 1].uIndoorSectorID = pActors[i].uSectorID; - /*if ( !pRenderer->pRenderD3D ) - { - LODWORD(v20) = pBLVRenderParams->fov_rad_fixpoint << 16; - HIDWORD(v20) = pBLVRenderParams->fov_rad_fixpoint >> 16; - v0->_screenspace_x_scaler_packedfloat = fixpoint_mul(v10->scale, v20 / x); - a5a = fixpoint_mul(v10->scale, v20 / x); - } - else - {*/ - pBillboardRenderList[uNumBillboardsToDraw - 1].fov_x = pGame->pIndoorCameraD3D->fov_x; - pBillboardRenderList[uNumBillboardsToDraw - 1].fov_y = pGame->pIndoorCameraD3D->fov_y; - LODWORD(v18) = 0; - HIDWORD(v18) = floorf(pBillboardRenderList[uNumBillboardsToDraw - 1].fov_x + 0.5f); - pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_x_scaler_packedfloat = fixpoint_mul(v9->scale, v18 / x); - a5a = fixpoint_mul(v9->scale, v18 / x); - //} - pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_y_scaler_packedfloat = a5a; - if ( pActors[i].pActorBuffs[ACTOR_BUFF_SHRINK].uExpireTime <= 0 ) - { - if ( pActors[i].pActorBuffs[ACTOR_BUFF_MASS_DISTORTION].uExpireTime > 0 ) - pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_y_scaler_packedfloat = fixpoint_mul(pGame->pStru6Instance->_4A806F(&pActors[i]), - pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_y_scaler_packedfloat); - } - else - { - if ( pActors[i].pActorBuffs[ACTOR_BUFF_SHRINK].uPower > 0 ) - pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_x_scaler_packedfloat = fixpoint_mul(65536 / pActors[i].pActorBuffs[ACTOR_BUFF_SHRINK].uPower, pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_x_scaler_packedfloat); - } - HIWORD(v25) = HIWORD(x); - pBillboardRenderList[uNumBillboardsToDraw - 1].world_x = pActors[i].vPosition.x; - pBillboardRenderList[uNumBillboardsToDraw - 1].world_y = pActors[i].vPosition.y; - pBillboardRenderList[uNumBillboardsToDraw - 1].world_z = pActors[i].vPosition.z; - pBillboardRenderList[uNumBillboardsToDraw - 1].uScreenSpaceX = v43; - pBillboardRenderList[uNumBillboardsToDraw - 1].uScreenSpaceY = a6; - LOWORD(v25) = 0; - LOBYTE(v26) = v41; - - //v0->sZValue = v25 + (PID(OBJECT_Actor,i)); - pBillboardRenderList[uNumBillboardsToDraw - 1].actual_z = HIWORD(x); - pBillboardRenderList[uNumBillboardsToDraw - 1].object_pid = PID(OBJECT_Actor,i); - - //v29 = HIDWORD(p->pActorBuffs[ACTOR_BUFF_STONED].uExpireTime) == 0; - //v30 = HIDWORD(p->pActorBuffs[ACTOR_BUFF_STONED].uExpireTime) < 0; - pBillboardRenderList[uNumBillboardsToDraw - 1].field_1E = v41; - pBillboardRenderList[uNumBillboardsToDraw - 1].pSpriteFrame = v9; - pBillboardRenderList[uNumBillboardsToDraw - 1].sTintColor = pMonsterList->pMonsters[pActors[i].pMonsterInfo.uID - 1].sTintColor; - if ( pActors[i].pActorBuffs[ACTOR_BUFF_STONED].uExpireTime > 0 ) - { - HIBYTE(v26) = HIBYTE(v41) | 1; - pBillboardRenderList[uNumBillboardsToDraw - 1].field_1E = v26; - } - } - } - } -} -//----- (0044028F) -------------------------------------------------------- -void PrepareItemsRenderList_BLV() -{ - SpriteFrame *v4; // eax@12 - unsigned int v6; // eax@12 - int v7; // ecx@12 - int v9; // ecx@12 - __int64 v18; // ST5C_4@27 - int a6; // [sp+2Ch] [bp-30h]@12 - int v31; // [sp+38h] [bp-24h]@27 - signed __int16 v34; // [sp+44h] [bp-18h]@14 - int v35; // [sp+48h] [bp-14h]@25 - int v36; // [sp+4Ch] [bp-10h]@25 - signed int z; // [sp+50h] [bp-Ch]@24 - signed int y; // [sp+54h] [bp-8h]@24 - signed int x; // [sp+58h] [bp-4h]@24 - - for (uint i = 0; i < uNumSpriteObjects; ++i) - { - if (pSpriteObjects[i].uObjectDescID) - { - if ( !(pObjectList->pObjects[pSpriteObjects[i].uObjectDescID].uFlags & 1) ) - { - if ( ( pSpriteObjects[i].uType < 1000 || pSpriteObjects[i].uType >= 10000) - && (pSpriteObjects[i].uType < 500 || pSpriteObjects[i].uType >= 600) - && (pSpriteObjects[i].uType < 811 || pSpriteObjects[i].uType >= 815) - || pGame->pStru6Instance->_4A81CA(&pSpriteObjects[i])) - { - v4 = pSpriteFrameTable->GetFrame(pObjectList->pObjects[pSpriteObjects[i].uObjectDescID].uSpriteID, pSpriteObjects[i].uSpriteFrameID); - a6 = v4->uGlowRadius * pSpriteObjects[i].field_22_glow_radius_multiplier; - v6 = stru_5C6E00->Atan2(pSpriteObjects[i].vPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x, - pSpriteObjects[i].vPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y); - LOWORD(v7) = pSpriteObjects[i].uFacing; - v9 = ((signed int)(stru_5C6E00->uIntegerPi + ((signed int)stru_5C6E00->uIntegerPi >> 3) + v7 - v6) >> 8) & 7; - pBillboardRenderList[uNumBillboardsToDraw].HwSpriteID = v4->pHwSpriteIDs[v9]; - if ( v4->uFlags & 0x20 ) - pSpriteObjects[i].vPosition.z -= (signed int)(fixpoint_mul(v4->scale, pSprites_LOD->pSpriteHeaders[pBillboardRenderList[uNumBillboardsToDraw].HwSpriteID].uHeight) / 2); - - v34 = 0; - if ( v4->uFlags & 2 ) - v34 = 2; - if ( v4->uFlags & 0x40000 ) - v34 |= 0x40u; - if ( v4->uFlags & 0x20000 ) - LOBYTE(v34) = v34 | 0x80; - //v11 = (int *)(256 << v9); - if ( (256 << v9) & v4->uFlags ) - v34 |= 4; - if ( a6 ) - { - //LOBYTE(v11) = _4E94D3_light_type; - pMobileLightsStack->AddLight(pSpriteObjects[i].vPosition.x, pSpriteObjects[i].vPosition.y, pSpriteObjects[i].vPosition.z, - pSpriteObjects[i].uSectorID, a6, pObjectList->pObjects[pSpriteObjects[i].uObjectDescID].uParticleTrailColorR, - pObjectList->pObjects[pSpriteObjects[i].uObjectDescID].uParticleTrailColorG, - pObjectList->pObjects[pSpriteObjects[i].uObjectDescID].uParticleTrailColorB, _4E94D3_light_type); - } - if ( pGame->pIndoorCameraD3D->ApplyViewTransform_TrueIfStillVisible_BLV(pSpriteObjects[i].vPosition.x, pSpriteObjects[i].vPosition.y, - pSpriteObjects[i].vPosition.z, &x, &y, &z, 1) ) - { - pGame->pIndoorCameraD3D->Project(x, y, z, &v36, &v35); - - assert(uNumBillboardsToDraw < 500); - //if ( (signed int)uNumBillboardsToDraw >= 500 ) - // return; - ++uNumBillboardsToDraw; - ++uNumSpritesDrawnThisFrame; - pSpriteObjects[i].uAttributes |= 1; - pBillboardRenderList[uNumBillboardsToDraw - 1].uPalette = v4->uPaletteIndex; - pBillboardRenderList[uNumBillboardsToDraw - 1].uIndoorSectorID = pSpriteObjects[i].uSectorID; - //if ( pRenderer->pRenderD3D ) - { - pBillboardRenderList[uNumBillboardsToDraw - 1].fov_x = pGame->pIndoorCameraD3D->fov_x; - pBillboardRenderList[uNumBillboardsToDraw - 1].fov_y = pGame->pIndoorCameraD3D->fov_y; - LODWORD(v18) = 0; - HIDWORD(v18) = (int)floorf(pBillboardRenderList[uNumBillboardsToDraw - 1].fov_x + 0.5f); - pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_x_scaler_packedfloat = fixpoint_mul(v4->scale, v18 / x); - v31 = fixpoint_mul(v4->scale, v18 / x); - } - /*else - { - __debugbreak(); // sw rendering - LODWORD(v19) = pBLVRenderParams->field_40 << 16; - HIDWORD(v19) = pBLVRenderParams->field_40 >> 16; - v20 = v19 / x; - pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_x_scaler_packedfloat = fixpoint_mul(v24->scale, v19 / x); - v31 = fixpoint_mul(v24->scale, v20); - }*/ - //HIWORD(v21) = HIWORD(x); - //LOWORD(v21) = 0; - pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_y_scaler_packedfloat = v31; - pBillboardRenderList[uNumBillboardsToDraw - 1].field_1E = v34; - pBillboardRenderList[uNumBillboardsToDraw - 1].world_x = pSpriteObjects[i].vPosition.x; - pBillboardRenderList[uNumBillboardsToDraw - 1].world_y = pSpriteObjects[i].vPosition.y; - pBillboardRenderList[uNumBillboardsToDraw - 1].world_z = pSpriteObjects[i].vPosition.z; - pBillboardRenderList[uNumBillboardsToDraw - 1].uScreenSpaceX = v36; - pBillboardRenderList[uNumBillboardsToDraw - 1].sTintColor = 0; - pBillboardRenderList[uNumBillboardsToDraw - 1].uScreenSpaceY = v35; - //v23 = 8 * i; - //LOBYTE(v23) = PID(OBJECT_Item,i); - pBillboardRenderList[uNumBillboardsToDraw - 1].pSpriteFrame = v4; - //v12 = (p->uAttributes & 0x20) == 0; - //pBillboardRenderList[uNumBillboardsToDraw - 1].sZValue = v21 + v23; - pBillboardRenderList[uNumBillboardsToDraw - 1].actual_z = HIWORD(x); - pBillboardRenderList[uNumBillboardsToDraw - 1].object_pid = PID(OBJECT_Item,i); - /*if (pSpriteObjects[i].uAttributes & 0x20) - { - if ( !pRenderer->pRenderD3D ) - pBillboardRenderList[uNumBillboardsToDraw - 1].sZValue = 0; - }*/ - } - } - } - } - } -} - -//----- (00440639) -------------------------------------------------------- -void AddBspNodeToRenderList(unsigned int node_id) -{ - BLVSector *pSector; // esi@1 - - pSector = &pIndoor->pSectors[pBspRenderer->nodes[node_id].uSectorID]; - //if ( pRenderer->pRenderD3D ) - { - for (uint i = 0; i < pSector->uNumNonBSPFaces; ++i) - //Log::Warning(L"Non-BSP face: %X", v3->pFaceIDs[v2]); - pBspRenderer->AddFaceToRenderList_d3d(node_id, pSector->pFaceIDs[i]);//рекурсия\recursion - } - /*else - { - for (uint i = 0; i < pSector->uNumNonBSPFaces; ++i) - pBspRenderer->AddFaceToRenderList_sw(node_id, pSector->pFaceIDs[i]); - }*/ - if ( pSector->field_0 & 0x10 ) - sub_4406BC(node_id, pSector->uFirstBSPNode); -} - -//----- (004406BC) -------------------------------------------------------- -void __fastcall sub_4406BC(unsigned int node_id, unsigned int uFirstNode) -{ - BLVSector *pSector; // esi@2 - BSPNode *pNode; // edi@2 - BLVFace *pFace; // eax@2 - int v5; // ecx@2 - __int16 v6; // ax@6 - int v7; // ebp@10 - int v8; // ebx@10 - __int16 v9; // di@18 - BspRenderer_stru0 *node; // [sp+18h] [bp-4h]@1 - - //Log::Warning(L"sub_4406BC(%u, %u)", a1, uFirstNode); - - //v10 = a1; - node = &pBspRenderer->nodes[node_id]; - while ( 1 ) - { - pSector = &pIndoor->pSectors[node->uSectorID]; - pNode = &pIndoor->pNodes[uFirstNode]; - pFace = &pIndoor->pFaces[pSector->pFaceIDs[pNode->uCoplanarOffset]]; - v5 = pFace->pFacePlane_old.dist + - pGame->pIndoorCameraD3D->vPartyPos.x * pFace->pFacePlane_old.vNormal.x + - pGame->pIndoorCameraD3D->vPartyPos.y * pFace->pFacePlane_old.vNormal.y + - pGame->pIndoorCameraD3D->vPartyPos.z * pFace->pFacePlane_old.vNormal.z;//plane equation - if (pFace->Portal() && pFace->uSectorID != node->uSectorID ) - v5 = -v5; - //v11 = v5 > 0; - if ( v5 <= 0 ) - v6 = pNode->uFront; - else - v6 = pNode->uBack; - if ( v6 != -1 ) - sub_4406BC(node_id, v6); - v7 = pNode->uCoplanarOffset; - v8 = v7 + pNode->uCoplanarSize; - - //Log::Warning(L"Node %u: %X to %X (%hX)", uFirstNode, v7, v8, v2->pFaceIDs[v7]); - - //if ( pRenderer->pRenderD3D ) - { - while ( v7 < v8 ) - pBspRenderer->AddFaceToRenderList_d3d(node_id, pSector->pFaceIDs[v7++]); - } - /*else - { - while ( v7 < v8 ) - pBspRenderer->AddFaceToRenderList_sw(node_id, pSector->pFaceIDs[v7++]); - }*/ - v9 = v5 > 0 ? pNode->uFront : pNode->uBack; - if ( v9 == -1 ) - break; - uFirstNode = v9; - } -} -//----- (0043FA33) -------------------------------------------------------- -void PrepareDecorationsRenderList_BLV(unsigned int uDecorationID, unsigned int uSectorID) -{ - unsigned int v8; // edi@5 - int v9; // edi@5 - int v10; // eax@7 - SpriteFrame *v11; // eax@7 - signed __int64 v20; // qtt@19 - Particle_sw particle; // [sp+Ch] [bp-A0h]@3 - int v30; // [sp+8Ch] [bp-20h]@7 - int a5; // [sp+94h] [bp-18h]@17 - int z; // [sp+98h] [bp-14h]@15 - int a6; // [sp+9Ch] [bp-10h]@17 - int y; // [sp+A0h] [bp-Ch]@15 - int x; // [sp+A4h] [bp-8h]@15 - int v37; // [sp+A8h] [bp-4h]@5 - - if (pLevelDecorations[uDecorationID].uFlags & LEVEL_DECORATION_INVISIBLE) - return; - - if (pDecorationList->pDecorations[pLevelDecorations[uDecorationID].uDecorationDescID].uFlags & DECORATION_DESC_EMITS_FIRE) - { - memset(&particle, 0, sizeof(particle)); // fire, like at the Pit's tavern - particle.type = ParticleType_Bitmap | ParticleType_Rotating | ParticleType_8; - particle.uDiffuse = 0xFF3C1E; - particle.x = (double)pLevelDecorations[uDecorationID].vPosition.x; - particle.y = (double)pLevelDecorations[uDecorationID].vPosition.y; - particle.z = (double)pLevelDecorations[uDecorationID].vPosition.z; - particle.r = 0.0; - particle.g = 0.0; - particle.b = 0.0; - particle.flt_28 = 1.0; - particle.timeToLive = (rand() & 0x80) + 128; - particle.uTextureID = pBitmaps_LOD->LoadTexture("effpar01"); - pGame->pParticleEngine->AddParticle(&particle); - return; - } - - if (pDecorationList->pDecorations[pLevelDecorations[uDecorationID].uDecorationDescID].uFlags & DECORATION_DESC_DONT_DRAW) - return; - - v8 = pLevelDecorations[uDecorationID].field_10_y_rot + ((signed int)stru_5C6E00->uIntegerPi >> 3) - - stru_5C6E00->Atan2(pLevelDecorations[uDecorationID].vPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x, - pLevelDecorations[uDecorationID].vPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y); - v9 = ((signed int)(stru_5C6E00->uIntegerPi + v8) >> 8) & 7; - v37 = pBLVRenderParams->field_0_timer_; - if (pParty->bTurnBasedModeOn) - v37 = pMiscTimer->uTotalGameTimeElapsed; - v10 = abs(pLevelDecorations[uDecorationID].vPosition.x + pLevelDecorations[uDecorationID].vPosition.y); - v11 = pSpriteFrameTable->GetFrame(pDecorationList->pDecorations[pLevelDecorations[uDecorationID].uDecorationDescID].uSpriteID, v37 + v10); - v30 = 0; - if ( v11->uFlags & 2 ) - v30 = 2; - if ( v11->uFlags & 0x40000 ) - v30 |= 0x40u; - if ( v11->uFlags & 0x20000 ) - LOBYTE(v30) = v30 | 0x80; - if ( (256 << v9) & v11->uFlags ) - v30 |= 4; - if ( pGame->pIndoorCameraD3D->ApplyViewTransform_TrueIfStillVisible_BLV(pLevelDecorations[uDecorationID].vPosition.x, - pLevelDecorations[uDecorationID].vPosition.y, - pLevelDecorations[uDecorationID].vPosition.z, &x, &y, &z, 1) ) - { - if ( abs(x) >= abs(y) ) - { - pGame->pIndoorCameraD3D->Project(x, y, z, &a5, &a6); - - assert(uNumBillboardsToDraw < 500); - - ++uNumBillboardsToDraw; - ++uNumDecorationsDrawnThisFrame; - pBillboardRenderList[uNumBillboardsToDraw - 1].HwSpriteID = v11->pHwSpriteIDs[v9]; - pBillboardRenderList[uNumBillboardsToDraw - 1].uPalette = v11->uPaletteIndex; - pBillboardRenderList[uNumBillboardsToDraw - 1].uIndoorSectorID = uSectorID; - /*if ( !pRenderer->pRenderD3D ) - { - LODWORD(v21) = pBLVRenderParams->fov_rad_fixpoint << 16; - HIDWORD(v21) = pBLVRenderParams->fov_rad_fixpoint >> 16; - //LODWORD(v31) = v12->scale; - pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_x_scaler_packedfloat = fixpoint_mul(v12->scale, v21 / x); - v37 = fixpoint_mul(v12->scale, v21 / x); - } - else - {*/ - pBillboardRenderList[uNumBillboardsToDraw - 1].fov_x = pGame->pIndoorCameraD3D->fov_x; - pBillboardRenderList[uNumBillboardsToDraw - 1].fov_y = pGame->pIndoorCameraD3D->fov_y; - LODWORD(v20) = 0; - HIDWORD(v20) = floorf(pBillboardRenderList[uNumBillboardsToDraw - 1].fov_x + 0.5f); - pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_x_scaler_packedfloat = fixpoint_mul(v11->scale, v20 / x); - LODWORD(v20) = 0; - HIDWORD(v20) = floorf(pBillboardRenderList[uNumBillboardsToDraw - 1].fov_y + 0.5f); - v37 = fixpoint_mul(v11->scale, v20 / x); - //} - //HIWORD(v22) = HIWORD(x); - //LOWORD(v22) = 0; - pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_y_scaler_packedfloat = v37; - pBillboardRenderList[uNumBillboardsToDraw - 1].field_1E = v30; - pBillboardRenderList[uNumBillboardsToDraw - 1].world_x = pLevelDecorations[uDecorationID].vPosition.x; - pBillboardRenderList[uNumBillboardsToDraw - 1].world_y = pLevelDecorations[uDecorationID].vPosition.y; - pBillboardRenderList[uNumBillboardsToDraw - 1].world_z = pLevelDecorations[uDecorationID].vPosition.z; - pBillboardRenderList[uNumBillboardsToDraw - 1].uScreenSpaceX = a5; - pBillboardRenderList[uNumBillboardsToDraw - 1].uScreenSpaceY = a6; - //v23 = 8 * uDecorationID; - //LOBYTE(v23) = PID(OBJECT_Decoration,uDecorationID); - - //pBillboardRenderList[uNumBillboardsToDraw - 1].sZValue = v22 + v23; - pBillboardRenderList[uNumBillboardsToDraw - 1].actual_z = HIWORD(x); - pBillboardRenderList[uNumBillboardsToDraw - 1].object_pid = PID(OBJECT_Decoration,uDecorationID); - - pBillboardRenderList[uNumBillboardsToDraw - 1].sTintColor = 0; - pBillboardRenderList[uNumBillboardsToDraw - 1].pSpriteFrame = v11; - } - } -} -//----- (0043F953) -------------------------------------------------------- -void PrepareBspRenderList_BLV() -{ - pBspRenderer->num_faces = 0; - - if (pBLVRenderParams->uPartySectorID) - { - pBspRenderer->nodes[0].uSectorID = pBLVRenderParams->uPartySectorID; - pBspRenderer->nodes[0].uViewportW = pBLVRenderParams->uViewportW; - pBspRenderer->nodes[0].uViewportZ = pBLVRenderParams->uViewportZ; - pBspRenderer->nodes[0].uViewportY = pBLVRenderParams->uViewportY; - pBspRenderer->nodes[0].uViewportX = pBLVRenderParams->uViewportX; - pBspRenderer->nodes[0].PortalScreenData.GetViewportData(pBLVRenderParams->uViewportX, pBLVRenderParams->uViewportY, - pBLVRenderParams->uViewportZ, pBLVRenderParams->uViewportW); - pBspRenderer->nodes[0].uFaceID = -1; - pBspRenderer->nodes[0].viewing_portal_id = -1; - pBspRenderer->num_nodes = 1; - AddBspNodeToRenderList(0); - } - - pBspRenderer->MakeVisibleSectorList(); -} - -//----- (0043F9E1) -------------------------------------------------------- -void BspRenderer_PortalViewportData::GetViewportData(__int16 x, int y, __int16 z, int w) -{ - _viewport_space_y = y; - _viewport_space_w = w; - - for (uint i = 0; i < window->GetHeight(); ++i) - { - if ( i < y || i > w ) - { - viewport_left_side[i] = window->GetWidth(); - viewport_right_side[i] = -1; - } - else - { - viewport_left_side[i] = x; - viewport_right_side[i] = z; - } - } -} -//----- (0048653D) -------------------------------------------------------- -void stru149::_48653D_frustum_blv(int a2, int a3, int a4, int a5, int a6, int a7)//portal frustum culling -{ - int v8; // edi@1 - int v9; // eax@1 - int v16; // ST14_4@3 - int v17; // ST10_4@3 - int v19; // ST10_4@6 - int v21; // ST10_4@9 - int v28; // [sp+1Ch] [bp-Ch]@1 - int v29; // [sp+24h] [bp-4h]@1 - - v8 = stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationY); - v29 = stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationY); - v28 = stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationX); - v9 = stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationX); - //v11 = -pBLVRenderParams->vPartyPos.y; - //v26 = -pBLVRenderParams->vPartyPos.x; - //v27 = v9; - //v12 = -pBLVRenderParams->vPartyPos.z; - if (pGame->pIndoorCameraD3D->sRotationX) - { - v16 = v8 * -pGame->pIndoorCameraD3D->vPartyPos.x + v29 * -pGame->pIndoorCameraD3D->vPartyPos.y; - v17 = -65536 * pGame->pIndoorCameraD3D->vPartyPos.z; - this->field_0_party_dir_x = fixpoint_mul(v16, v28) + fixpoint_mul((-pGame->pIndoorCameraD3D->vPartyPos.z) << 16, v9); - this->field_4_party_dir_y = v8 * -pGame->pIndoorCameraD3D->vPartyPos.y - v29 * -pGame->pIndoorCameraD3D->vPartyPos.x; - this->field_8_party_dir_z = fixpoint_mul(v17, v28) - fixpoint_mul(v16, v9); - } - else - { - this->field_0_party_dir_x = v8 * -pGame->pIndoorCameraD3D->vPartyPos.x + v29 * -pGame->pIndoorCameraD3D->vPartyPos.y; - this->field_4_party_dir_y = v8 * -pGame->pIndoorCameraD3D->vPartyPos.y - v29 * -pGame->pIndoorCameraD3D->vPartyPos.x; - this->field_8_party_dir_z = (-pGame->pIndoorCameraD3D->vPartyPos.z) << 16; - } - - if (pGame->pIndoorCameraD3D->sRotationX) - { - v19 = fixpoint_mul(a2, v8) + fixpoint_mul(a3, v29); - - this->angle_from_north = fixpoint_mul(v19, v28) + fixpoint_mul(a4, v9); - this->angle_from_west = fixpoint_mul(a3, v8) - fixpoint_mul(a2, v29); - this->viewing_angle_from_west_east = fixpoint_mul(a4, v28) - fixpoint_mul(v19, v9); - } - else - { - this->angle_from_north = fixpoint_mul(a2, v8) + fixpoint_mul(a3, v29); - this->angle_from_west = fixpoint_mul(a3, v8) - fixpoint_mul(a2, v29); - this->viewing_angle_from_west_east = a4; - } - - if (pGame->pIndoorCameraD3D->sRotationX) - { - v21 = fixpoint_mul(a5, v8) + fixpoint_mul(a6, v29); - - this->angle_from_east = fixpoint_mul(v21, v28) + fixpoint_mul(a7, v9); - this->angle_from_south = fixpoint_mul(a6, v8) - fixpoint_mul(a5, v29); - this->viewing_angle_from_north_south = fixpoint_mul(a7, v28) - fixpoint_mul(v21, v9); - } - else - { - this->angle_from_east = fixpoint_mul(a5, v8) + fixpoint_mul(a6, v29); - this->angle_from_south = fixpoint_mul(a6, v8) - fixpoint_mul(a5, v29); - this->viewing_angle_from_north_south = a7; - } - - this->angle_from_east = -this->angle_from_east; - this->angle_from_south = -this->angle_from_south; - this->viewing_angle_from_north_south = -this->viewing_angle_from_north_south; - - this->field_24 = fixpoint_dot(this->angle_from_north, this->field_0_party_dir_x, - this->angle_from_west, this->field_4_party_dir_y, - this->viewing_angle_from_west_east, this->field_8_party_dir_z); - this->field_28 = fixpoint_dot(this->angle_from_east, this->field_0_party_dir_x, - this->angle_from_south, this->field_4_party_dir_y, - this->viewing_angle_from_north_south, this->field_8_party_dir_z); -} -//----- (00407A1C) -------------------------------------------------------- -bool __fastcall sub_407A1C(int x, int y, int z, Vec3_int_ v) -{ - unsigned int v4; // esi@1 - int dist_y; // edi@2 - int dist_z; // ebx@2 - int dist_x; // esi@2 - signed int v9; // ecx@2 - int v10; // eax@2 - int v12; // eax@4 - int v17; // ST34_4@25 - int v18; // ST38_4@25 - int v19; // eax@25 - char v20; // zf@25 - signed int v21; // ebx@25 - signed int v23; // edi@26 - int v24; // ST34_4@30 - signed int v32; // ecx@37 - int v33; // eax@37 - int v35; // eax@39 - ODMFace *odm_face; // esi@54 - signed int v40; // ebx@60 - signed int v42; // edi@61 - signed int v49; // ecx@73 - int v50; // eax@73 - int v51; // edx@75 - int v52; // ecx@75 - int v53; // eax@75 - int v59; // eax@90 - BLVFace *face; // esi@91 - int v63; // ST34_4@98 - int v64; // ST30_4@98 - int v65; // eax@98 - signed int v66; // ebx@98 - signed int v68; // edi@99 - int v69; // ST2C_4@103 - signed int v77; // ecx@111 - int v78; // eax@111 - int v79; // edx@113 - int v80; // ecx@113 - int v81; // eax@113 - int v87; // ecx@128 - signed int v91; // ebx@136 - signed int v93; // edi@137 - Vec3_int_ v97; // [sp-18h] [bp-94h]@1 - int v107; // [sp+10h] [bp-6Ch]@98 - int v108; // [sp+10h] [bp-6Ch]@104 - int v109; // [sp+18h] [bp-64h]@25 - int v110; // [sp+18h] [bp-64h]@31 - signed int v113; // [sp+20h] [bp-5Ch]@1 - signed int v114; // [sp+24h] [bp-58h]@1 - int v119; // [sp+34h] [bp-48h]@75 - int v120; // [sp+34h] [bp-48h]@113 - int v121; // [sp+38h] [bp-44h]@4 - int v122; // [sp+38h] [bp-44h]@39 - int v123; // [sp+38h] [bp-44h]@76 - int v124; // [sp+38h] [bp-44h]@114 - int v125; // [sp+3Ch] [bp-40h]@4 - int v126; // [sp+3Ch] [bp-40h]@39 - int v127; // [sp+3Ch] [bp-40h]@77 - int v128; // [sp+3Ch] [bp-40h]@115 - int v129; // [sp+40h] [bp-3Ch]@11 - int v130; // [sp+40h] [bp-3Ch]@46 - int v131; // [sp+40h] [bp-3Ch]@78 - int v132; // [sp+40h] [bp-3Ch]@116 - int v133; // [sp+44h] [bp-38h]@10 - int v134; // [sp+44h] [bp-38h]@45 - int v135; // [sp+44h] [bp-38h]@81 - int v136; // [sp+44h] [bp-38h]@119 - int v137; // [sp+48h] [bp-34h]@7 - int v138; // [sp+48h] [bp-34h]@42 - int v139; // [sp+48h] [bp-34h]@82 - int v140; // [sp+48h] [bp-34h]@120 - int v141; // [sp+4Ch] [bp-30h]@6 - int v142; // [sp+4Ch] [bp-30h]@41 - int v143; // [sp+4Ch] [bp-30h]@75 - int v144; // [sp+4Ch] [bp-30h]@113 - int v145; // [sp+50h] [bp-2Ch]@5 - int v146; // [sp+50h] [bp-2Ch]@40 - int v149; // [sp+54h] [bp-28h]@4 - int v150; // [sp+54h] [bp-28h]@39 - int sDepthb; // [sp+58h] [bp-24h]@90 - signed int a5b; // [sp+5Ch] [bp-20h]@83 - signed int a5c; // [sp+5Ch] [bp-20h]@121 - int v162; // [sp+60h] [bp-1Ch]@128 - int outz; // [sp+64h] [bp-18h]@2 - int outx; // [sp+68h] [bp-14h]@2 - int outy; // [sp+6Ch] [bp-10h]@2 - int sZ; // [sp+70h] [bp-Ch]@2 - int sX; // [sp+74h] [bp-8h]@2 - int sY; // [sp+78h] [bp-4h]@2 - //8bytes unused - int ya; // [sp+84h] [bp+8h]@60 - int yb; // [sp+84h] [bp+8h]@136 - int ve; // [sp+88h] [bp+Ch]@60 - int va; // [sp+88h] [bp+Ch]@60 - int vb; // [sp+88h] [bp+Ch]@66 - int vf; // [sp+88h] [bp+Ch]@136 - int vc; // [sp+88h] [bp+Ch]@136 - int vd; // [sp+88h] [bp+Ch]@142 - int v_4; // [sp+8Ch] [bp+10h]@60 - int v_4a; // [sp+8Ch] [bp+10h]@65 - int v_4b; // [sp+8Ch] [bp+10h]@136 - int v_4c; // [sp+8Ch] [bp+10h]@141 - - //__debugbreak();срабатывает при стрельбе огненным шаром - - v4 = stru_5C6E00->Atan2(v.x - x, v.y - y); - - v113 = 0; - v114 = 0; - - v97.z = z; - v97.x = x; - v97.y = y; - - if ( uCurrentlyLoadedLevelType == LEVEL_Indoor) - { - Vec3_int_::Rotate(32, stru_5C6E00->uIntegerHalfPi + v4, 0, v97, &sX, &sY, &sZ); - Vec3_int_::Rotate(32, stru_5C6E00->uIntegerHalfPi + v4, 0, v, &outx, &outy, &outz); - dist_y = outy - sY; - dist_z = outz - sZ; - dist_x = outx - sX; - v49 = integer_sqrt(dist_x * dist_x + dist_y * dist_y + dist_z * dist_z); - v50 = 65536; - if ( v49 ) - v50 = 65536 / v49; - v51 = outx; - v143 = dist_x * v50; - v52 = dist_y * v50; - v53 = dist_z * v50; - - v123 = max(outx, sX); - v119 = min(outx, sX); - - v131 = max(outy, sY); - v127 = min(outy, sY); - - v139 = max(outz, sZ); - v135 = min(outz, sZ); - - for ( a5b = 0; a5b < 2; a5b++ ) - { - if ( a5b ) - v59 = pIndoor->GetSector(sX, sY, sZ); - else - v59 = pIndoor->GetSector(outx, outy, outz); - //v60 = pIndoor->pSectors; - //v61 = 116 * v59; - //i = 116 * v59; - //for (sDepthb = 0; *(__int16 *)((char *)&pIndoor->pSectors->uNumWalls + v61) - //+ 2 * *(__int16 *)((char *)&pIndoor->pSectors->uNumFloors + v61); ++sDepthb) - for ( sDepthb = 0; sDepthb < pIndoor->pSectors[v59].uNumFaces; ++sDepthb ) - { - face = &pIndoor->pFaces[pIndoor->pSectors[v59].pFaceIDs[sDepthb]];// face = &pIndoor->pFaces[*(__int16 *)((char *)&pIndoor->pSectors->pWalls + v61)[sDepthb]] - v63 = fixpoint_mul(v143, face->pFacePlane_old.vNormal.x); - v64 = fixpoint_mul(v53, face->pFacePlane_old.vNormal.z); - v65 = fixpoint_mul(v52, face->pFacePlane_old.vNormal.y); - v20 = v63 + v64 + v65 == 0; - v66 = v63 + v64 + v65; - v107 = v63 + v64 + v65; - if ( face->Portal() - || v119 > face->pBounding.x2 || v123 < face->pBounding.x1 - || v127 > face->pBounding.y2 || v131 < face->pBounding.y1 - || v135 > face->pBounding.z2 || v139 < face->pBounding.z1 - || v20 ) - continue; - v68 = -(face->pFacePlane_old.dist + sX * face->pFacePlane_old.vNormal.x - + sY * face->pFacePlane_old.vNormal.y - + sZ * face->pFacePlane_old.vNormal.z); - if ( v66 <= 0 ) - { - if ( face->pFacePlane_old.dist + sX * face->pFacePlane_old.vNormal.x - + sY * face->pFacePlane_old.vNormal.y - + sZ * face->pFacePlane_old.vNormal.z < 0 ) - continue; - } - else - { - if ( face->pFacePlane_old.dist + sX * face->pFacePlane_old.vNormal.x - + sY * face->pFacePlane_old.vNormal.y - + sZ * face->pFacePlane_old.vNormal.z > 0 ) - continue; - } - v69 = abs(-(face->pFacePlane_old.dist + sX * face->pFacePlane_old.vNormal.x - + sY * face->pFacePlane_old.vNormal.y - + sZ * face->pFacePlane_old.vNormal.z )) >> 14; - if ( v69 <= abs(v66) ) - { - //LODWORD(v70) = v68 << 16; - //HIDWORD(v70) = v68 >> 16; - //v71 = v70 / v107; - //v108 = v70 / v107; - v108 = fixpoint_div(v68, v107); - if ( v108 >= 0 ) - { - if ( sub_4075DB(sX + ((signed int)(fixpoint_mul(v108, v143) + 0x8000) >> 16), - sY + ((signed int)(fixpoint_mul(v108, v52) + 0x8000) >> 16), - sZ + ((signed int)(fixpoint_mul(v108, v53) + 0x8000) >> 16), - face) ) - { - v114 = 1; - break; - } - } - } - } - } - - Vec3_int_::Rotate(32, v4 - stru_5C6E00->uIntegerHalfPi, 0, v97, &sX, &sY, &sZ); - Vec3_int_::Rotate(32, v4 - stru_5C6E00->uIntegerHalfPi, 0, v, &outx, &outy, &outz); - dist_y = outy - sY; - dist_z = outz - sZ; - dist_x = outx - sX; - v77 = integer_sqrt(dist_x * dist_x + dist_y * dist_y + dist_z * dist_z); - v78 = 65536; - if ( v77 ) - v78 = 65536 / v77; - v79 = outx; - v144 = dist_x * v78; - v80 = dist_y * v78; - v81 = dist_z * v78; - - v120 = max(outx, sX); - v124 = min(outx, sX); - - v132 = max(outy, sY); - v128 = min(outy, sY); - - v140 = max(outz, sZ); - v136 = min(outz, sZ); - - for ( a5c = 0; a5c < 2; a5c++ ) - { - if ( v113 ) - return !v114 || !v113; - if ( a5c ) - { - v87 = pIndoor->GetSector(sX, sY, sZ); - } - else - { - v87 = pIndoor->GetSector(outx, outy, outz); - } - for ( v162 = 0; v162 < pIndoor->pSectors[v87].uNumFaces; v162++) - { - face = &pIndoor->pFaces[pIndoor->pSectors[v87].pFaceIDs[v162]]; - yb = fixpoint_mul(v144, face->pFacePlane_old.vNormal.x); - v_4b = fixpoint_mul(v80, face->pFacePlane_old.vNormal.y); - vf = fixpoint_mul(v81, face->pFacePlane_old.vNormal.z); - v20 = yb + vf + v_4b == 0; - v91 = yb + vf + v_4b; - vc = yb + vf + v_4b; - if ( face->Portal() - || v120 > face->pBounding.x2 || v124 < face->pBounding.x1 - || v128 > face->pBounding.y2 || v132 < face->pBounding.y1 - || v136 > face->pBounding.z2 || v140 < face->pBounding.z1 - || v20 ) - continue; - v93 = -(face->pFacePlane_old.dist + sX * face->pFacePlane_old.vNormal.x - + sY * face->pFacePlane_old.vNormal.y - + sZ * face->pFacePlane_old.vNormal.z); - if ( v91 <= 0 ) - { - if ( face->pFacePlane_old.dist + sX * face->pFacePlane_old.vNormal.x - + sY * face->pFacePlane_old.vNormal.y - + sZ * face->pFacePlane_old.vNormal.z < 0 ) - continue; - } - else - { - if ( face->pFacePlane_old.dist + sX * face->pFacePlane_old.vNormal.x - + sY * face->pFacePlane_old.vNormal.y - + sZ * face->pFacePlane_old.vNormal.z > 0 ) - continue; - } - v_4c = abs(-(face->pFacePlane_old.dist + sX * face->pFacePlane_old.vNormal.x - + sY * face->pFacePlane_old.vNormal.y - + sZ * face->pFacePlane_old.vNormal.z)) >> 14; - if ( v_4c <= abs(v91) ) - { - vd = fixpoint_div(v93, vc); - if ( vd >= 0 ) - { - if ( sub_4075DB(sX + ((signed int)(fixpoint_mul(vd, v144) + 0x8000) >> 16), - sY + ((signed int)(fixpoint_mul(vd, v80) + 0x8000) >> 16), - sZ + ((signed int)(fixpoint_mul(vd, v81) + 0x8000) >> 16), - face) ) - { - v113 = 1; - break; - } - } - } - } - } - } - else if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor ) - { - Vec3_int_::Rotate(32, stru_5C6E00->uIntegerHalfPi + v4, 0, v97, &sX, &sY, &sZ); - Vec3_int_::Rotate(32, stru_5C6E00->uIntegerHalfPi + v4, 0, v, &outx, &outy, &outz); - dist_y = outy - sY; - dist_z = outz - sZ; - dist_x = outx - sX; - v9 = integer_sqrt(dist_x* dist_x+ dist_y* dist_y+ dist_z* dist_z); - v10 = 65536; - if ( v9 ) - v10 = 65536 / v9; - v125 = dist_x* v10; - v12 = dist_z* v10; - v121 = dist_y* v10; - - v145 = max(outx, sX); - v149 = min(outx, sX); - - v137 = max(outy, sY); - v141 = min(outy, sY); - - v129 = max(outz, sZ); - v133 = min(outz, sZ); - - for ( uint model_id = 0; model_id < pOutdoor->uNumBModels; model_id++) - { - if ( sub_4088E9(sX, sY, outx, outy, pOutdoor->pBModels[model_id].vPosition.x, pOutdoor->pBModels[model_id].vPosition.y) - <= pOutdoor->pBModels[model_id].sBoundingRadius + 128 ) - { - for ( uint face_id = 0; face_id < pOutdoor->pBModels[model_id].uNumFaces; ++face_id ) - { - odm_face = &pOutdoor->pBModels[model_id].pFaces[face_id]; - v17 = fixpoint_mul(v125, odm_face->pFacePlane.vNormal.x); - v18 = fixpoint_mul(v121, odm_face->pFacePlane.vNormal.y); - v19 = fixpoint_mul(v12, odm_face->pFacePlane.vNormal.z); - v20 = v17 + v18 + v19 == 0; - v21 = v17 + v18 + v19; - v109 = v17 + v18 + v19; - if ( v149 > odm_face->pBoundingBox.x2 || v145 < odm_face->pBoundingBox.x1 - || v141 > odm_face->pBoundingBox.y2 || v137 < odm_face->pBoundingBox.y1 - || v133 > odm_face->pBoundingBox.z2 || v129 < odm_face->pBoundingBox.z1 - || v20 ) - continue; - v23 = -(odm_face->pFacePlane.dist + sX * odm_face->pFacePlane.vNormal.x - + sY * odm_face->pFacePlane.vNormal.y - + sZ * odm_face->pFacePlane.vNormal.z); - if ( v21 <= 0 ) - { - if ( odm_face->pFacePlane.dist + sX * odm_face->pFacePlane.vNormal.x - + sY * odm_face->pFacePlane.vNormal.y - + sZ * odm_face->pFacePlane.vNormal.z < 0 ) - continue; - } - else - { - if ( odm_face->pFacePlane.dist + sX * odm_face->pFacePlane.vNormal.x - + sY * odm_face->pFacePlane.vNormal.y - + sZ * odm_face->pFacePlane.vNormal.z > 0 ) - continue; - } - v24 = abs(-(odm_face->pFacePlane.dist + sX * odm_face->pFacePlane.vNormal.x - + sY * odm_face->pFacePlane.vNormal.y - + sZ * odm_face->pFacePlane.vNormal.z)) >> 14; - if ( v24 <= abs(v21) ) - { - v110 = fixpoint_div(v23, v109); - if ( v110 >= 0 ) - { - if ( sub_4077F1(sX + ((signed int)(fixpoint_mul(v110, v125) + 0x8000) >> 16), - sY + ((signed int)(fixpoint_mul(v110, v121) + 0x8000) >> 16), - sZ + ((signed int)(fixpoint_mul(v110, v12) + 0x8000) >> 16), - odm_face, - &pOutdoor->pBModels[model_id].pVertices) ) - { - v114 = 1; - break; - } - } - } - } - } - } - - Vec3_int_::Rotate(32, v4 - stru_5C6E00->uIntegerHalfPi, 0, v97, &sX, &sY, &sZ); - Vec3_int_::Rotate(32, v4 - stru_5C6E00->uIntegerHalfPi, 0, v, &outx, &outy, &outz); - dist_y = outy - sY; - dist_z = outz - sZ; - dist_x = outx - sX; - v32 = integer_sqrt(dist_x * dist_x + dist_y * dist_y + dist_z * dist_z); - v33 = 65536; - if ( v32 ) - v33 = 65536 / v32; - v126 = dist_x * v33; - v35 = dist_z * v33; - v122 = dist_y * v33; - - v146 = max(outx, sX); - v150 = min(outx, sX); - - v138 = max(outy, sY); - v142 = min(outy, sY); - - v130 = max(outz, sZ); - v134 = min(outz, sZ); - - for ( uint model_id = 0; model_id < (signed int)pOutdoor->uNumBModels; ++model_id ) - { - if ( sub_4088E9(sX, sY, outx, outy, pOutdoor->pBModels[model_id].vPosition.x, pOutdoor->pBModels[model_id].vPosition.y) - <= pOutdoor->pBModels[model_id].sBoundingRadius + 128 ) - { - for ( uint face_id = 0; face_id < pOutdoor->pBModels[model_id].uNumFaces; ++face_id ) - { - odm_face = &pOutdoor->pBModels[model_id].pFaces[face_id]; - ya = fixpoint_mul(v126, odm_face->pFacePlane.vNormal.x); - ve = fixpoint_mul(v122, odm_face->pFacePlane.vNormal.y); - v_4 = fixpoint_mul(v35, odm_face->pFacePlane.vNormal.z); - v20 = ya + ve + v_4 == 0; - v40 = ya + ve + v_4; - va = ya + ve + v_4; - if ( v150 > odm_face->pBoundingBox.x2 || v146 < odm_face->pBoundingBox.x1 - || v142 > odm_face->pBoundingBox.y2 || v138 < odm_face->pBoundingBox.y1 - || v134 > odm_face->pBoundingBox.z2 || v130 < odm_face->pBoundingBox.z1 - || v20 ) - continue; - v42 = -(odm_face->pFacePlane.dist + sX * odm_face->pFacePlane.vNormal.x - + sY * odm_face->pFacePlane.vNormal.y - + sZ * odm_face->pFacePlane.vNormal.z); - if ( v40 <= 0 ) - { - if ( odm_face->pFacePlane.dist + sX * odm_face->pFacePlane.vNormal.x - + sY * odm_face->pFacePlane.vNormal.y - + sZ * odm_face->pFacePlane.vNormal.z < 0 ) - continue; - } - else - { - if ( odm_face->pFacePlane.dist + sX * odm_face->pFacePlane.vNormal.x - + sY * odm_face->pFacePlane.vNormal.y - + sZ * odm_face->pFacePlane.vNormal.z > 0 ) - continue; - } - v_4a = abs(-(odm_face->pFacePlane.dist + sX * odm_face->pFacePlane.vNormal.x - + sY * odm_face->pFacePlane.vNormal.y - + sZ * odm_face->pFacePlane.vNormal.z )) >> 14; - if ( v_4a <= abs(v40) ) - { - //LODWORD(v43) = v42 << 16; - //HIDWORD(v43) = v42 >> 16; - //vb = v43 / va; - vb = fixpoint_div(v42, va); - if ( vb >= 0 ) - { - if ( sub_4077F1(sX + ((signed int)(fixpoint_mul(vb, v126) + 0x8000) >> 16), - sY + ((signed int)(fixpoint_mul(vb, v122) + 0x8000) >> 16), - sZ + ((signed int)(fixpoint_mul(vb, v35) + 0x8000) >> 16), - odm_face, - &pOutdoor->pBModels[model_id].pVertices) ) - { - v113 = 1; - break; - } - } - } - } - } - } - - } - return !v114 || !v113; -} -//----- (0043F333) -------------------------------------------------------- -void BspRenderer::MakeVisibleSectorList() -{ -// int v6; // ebx@3 - - uNumVisibleNotEmptySectors = 0; - for (uint i = 0; i < num_nodes; ++i) - { - //if (!uNumVisibleNotEmptySectors) - //{ - //pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[uNumVisibleNotEmptySectors++] = nodes[i].uSectorID; - //continue; - //} - //v6 = 0; - //while (pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[v6] != nodes[i].uSectorID ) - for ( uint j = 0; j < uNumVisibleNotEmptySectors; j++ ) - { - //++v6; - if ( pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[j] == nodes[i].uSectorID) - break; - } - pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[uNumVisibleNotEmptySectors++] = nodes[i].uSectorID; - } -} -//----- (0046A334) -------------------------------------------------------- -char __fastcall DoInteractionWithTopmostZObject(int a1, int a2) -{ - int v17; // edi@36 - - v17 = PID_ID(a1); - switch ( PID_TYPE(a1) ) - { - case OBJECT_Item: // take the item - if ( pObjectList->pObjects[pSpriteObjects[v17].uObjectDescID].uFlags & 0x10 || v17 >= 1000 || !pSpriteObjects[v17].uObjectDescID ) - return 1; - if ( pItemsTable->pItems[pSpriteObjects[v17].stru_24.uItemID].uEquipType == EQUIP_GOLD) - { - pParty->PartyFindsGold(pSpriteObjects[v17].stru_24.uSpecEnchantmentType, 0); - viewparams->bRedrawGameUI = 1; - } - else - { - if ( pParty->pPickedItem.uItemID ) - return 1; - sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[471], pItemsTable->pItems[pSpriteObjects[v17].stru_24.uItemID].pUnidentifiedName);//You found an item (%s)! - ShowStatusBarString(pTmpBuf2.data(), 2); - if ( pSpriteObjects[v17].stru_24.uItemID == 506 )//artefact - _449B7E_toggle_bit(pParty->_quest_bits, 184, 1); - if ( pSpriteObjects[v17].stru_24.uItemID == 455 ) - _449B7E_toggle_bit(pParty->_quest_bits, 185, 1); - if ( !pParty->AddItemToParty(&pSpriteObjects[v17].stru_24) ) - pParty->SetHoldingItem(&pSpriteObjects[v17].stru_24); - } - SpriteObject::OnInteraction(v17); - break; - - case OBJECT_Actor: - if ( pActors[v17].uAIState == Dying || pActors[v17].uAIState == Summoned ) - return 1; - if ( pActors[v17].uAIState == Dead ) - pActors[v17].LootActor(); - else - { - if ( !pActors[v17].GetActorsRelation(0) && pActors[v17].ActorFriend() && pActors[v17].CanAct() ) - { - Actor::AI_FaceObject(v17, 4, 0, 0); - if ( pActors[v17].sNPC_ID ) - pMessageQueue_50CBD0->AddGUIMessage(UIMSG_StartNPCDialogue, v17, 0); - else - { - if ( pNPCStats->pGroups_copy[pActors[v17].uGroup] ) - { - if ( pNPCStats->pCatchPhrases[pNPCStats->pGroups_copy[pActors[v17].uGroup]] ) - { - pParty->uFlags |= 2; - strcpy(byte_5B0938.data(), pNPCStats->pCatchPhrases[pNPCStats->pGroups_copy[pActors[v17].uGroup]]); - sub_4451A8_press_any_key(0, 0, 0); - } - } - } - } - } - break; - - case OBJECT_Decoration: - if ( pLevelDecorations[v17].uEventID ) - { - EventProcessor(pLevelDecorations[v17].uEventID, a1, 1); - pLevelDecorations[v17].uFlags |= LEVEL_DECORATION_VISIBLE_ON_MAP; - } - else - { - if ( !pLevelDecorations[v17].IsInteractive() ) - return 1; - activeLevelDecoration = &pLevelDecorations[v17]; - EventProcessor(stru_5E4C90_MapPersistVars._decor_events[pLevelDecorations[v17]._idx_in_stru123 - 75] + 380, 0, 1); - activeLevelDecoration = nullptr; - } - break; - - default: - MessageBoxW(nullptr, L"Warning: Invalid ID reached!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Mouse.cpp:2020", 0); - return 1; - - case OBJECT_BModel: - if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor ) - { - int bmodel_id = a1 >> 9, - face_id = v17 & 0x3F; - if (bmodel_id >= pOutdoor->uNumBModels) - return 1; - if (pOutdoor->pBModels[bmodel_id].pFaces[face_id].uAttributes & FACE_HAS_EVENT - || pOutdoor->pBModels[bmodel_id].pFaces[face_id].sCogTriggeredID == 0 ) - return 1; - EventProcessor((signed __int16)pOutdoor->pBModels[bmodel_id].pFaces[face_id].sCogTriggeredID, a1, 1); - } - else - { - if ( !(pIndoor->pFaces[v17].uAttributes & FACE_CLICKABLE) ) - { - ShowNothingHereStatus(); - return 1; - } - if ( pIndoor->pFaces[v17].uAttributes & FACE_HAS_EVENT || !pIndoor->pFaceExtras[pIndoor->pFaces[v17].uFaceExtraID].uEventID ) - return 1; - if ( pCurrentScreen != SCREEN_BRANCHLESS_NPC_DIALOG ) - EventProcessor((signed __int16)pIndoor->pFaceExtras[pIndoor->pFaces[v17].uFaceExtraID].uEventID, a1, 1); - } - return 0; - break; - } - return 0; -} -//----- (0046BDF1) -------------------------------------------------------- -void BLV_UpdateUserInputAndOther() -{ - UpdateObjects(); - BLV_ProcessPartyActions(); - UpdateActors_BLV(); - BLV_UpdateDoors(); - check_event_triggers(); -} -//----- (00424829) -------------------------------------------------------- -// Finds out if current portal can be seen through the previous portal -bool PortalFrustrum(int pNumVertices, BspRenderer_PortalViewportData *far_portal, BspRenderer_PortalViewportData *near_portal, int uFaceID) -{ - int min_y; // esi@5 - int max_y; // edx@5 - int current_ID; // eax@12 - int v13; // eax@22 - int v15; // ecx@29 - int v18; // eax@39 - int v19; // eax@44 - int v20; // ecx@44 - int v22; // edi@46 - int v24; // edx@48 - int v26; // eax@55 - int v29; // edx@57 - int v31; // eax@64 - __int16 v36; // dx@67 - __int16 v38; // dx@67 - int v46; // edx@87 - int v49; // esi@93 - int v53; // [sp+Ch] [bp-34h]@44 - int v54; // [sp+10h] [bp-30h]@0 - int min_y_ID2; // [sp+14h] [bp-2Ch]@12 - int v59; // [sp+14h] [bp-2Ch]@87 - int v61; // [sp+1Ch] [bp-24h]@29 - int v62; // [sp+20h] [bp-20h]@0 - signed int direction1; // [sp+24h] [bp-1Ch]@3 - signed int direction2; // [sp+28h] [bp-18h]@3 - int min_y_ID; // [sp+2Ch] [bp-14h]@5 - int v69; // [sp+34h] [bp-Ch]@29 - int v70; // [sp+34h] [bp-Ch]@46 - - if ( pNumVertices <= 1 ) - return false; - min_y = PortalFace._screen_space_y[0]; - min_y_ID = 0; - max_y = PortalFace._screen_space_y[0]; - //face direction(направление фейса) - if ( !PortalFace.direction ) - { - direction1 = 1; - direction2 = -1; - } - else - { - direction1 = -1; - direction2 = 1; - } - - //get min and max y for portal(дать минимальное и максимальное значение y для портала) - for ( uint i = 1; i < pNumVertices; ++i ) - { - if (PortalFace._screen_space_y[i] < min_y) - { - min_y_ID = i; - min_y = PortalFace._screen_space_y[i]; - } - else if (PortalFace._screen_space_y[i] > max_y) - { - max_y = PortalFace._screen_space_y[i]; - } - } - if ( max_y == min_y ) - return false; - - //***************************************************************************************************************************** - far_portal->_viewport_space_y = min_y; - far_portal->_viewport_space_w = max_y; - current_ID = min_y_ID; - min_y_ID2 = min_y_ID; - - for ( uint i = 0; i < pNumVertices; ++i ) - { - current_ID += direction2; - if ( current_ID < pNumVertices ) - { - if ( current_ID < 0 ) - current_ID += pNumVertices; - } - else - current_ID -= pNumVertices; - if ( PortalFace._screen_space_y[current_ID] <= PortalFace._screen_space_y[min_y_ID] )//определение минимальной у - { - min_y_ID2 = current_ID; - min_y_ID = current_ID; - } - if ( PortalFace._screen_space_y[current_ID] == max_y ) - break; - } - - v13 = min_y_ID2 + direction2; - if ( v13 < pNumVertices ) - { - if ( v13 < 0 ) - v13 += pNumVertices; - } - else - v13 -= pNumVertices; - if ( PortalFace._screen_space_y[v13] != PortalFace._screen_space_y[min_y_ID2] ) - { - v62 = PortalFace._screen_space_x[min_y_ID2] << 16; - v54 = ((PortalFace._screen_space_x[v13] - PortalFace._screen_space_x[min_y_ID2]) << 16) / - (PortalFace._screen_space_y[v13] - PortalFace._screen_space_y[min_y_ID2]); - far_portal->viewport_left_side[min_y] = (short)PortalFace._screen_space_x[min_y_ID2]; - } - //**************************************************************************************************************************************** - // - v15 = min_y_ID; - v61 = min_y_ID; - for ( v69 = 0; v69 < pNumVertices; ++v69 ) - { - v15 += direction1; - if ( v15 < pNumVertices ) - { - if ( v15 < 0 ) - v15 += pNumVertices; - } - else - v15 -= pNumVertices; - if ( PortalFace._screen_space_y[v15] <= PortalFace._screen_space_y[min_y_ID] ) - { - v61 = v15; - min_y_ID = v15; - } - if ( PortalFace._screen_space_y[v15] == max_y ) - break; - } - v18 = direction1 + v61; - if ( v18 < pNumVertices ) - { - if ( v18 < 0 ) - v18 += pNumVertices; - } - else - v18 -= pNumVertices; - v19 = v18; - v20 = v61; - if ( PortalFace._screen_space_y[v19] != PortalFace._screen_space_y[v61] ) - { - v61 = PortalFace._screen_space_x[v20] << 16; - v53 = ((PortalFace._screen_space_x[v19] - PortalFace._screen_space_x[v20]) << 16) / - (PortalFace._screen_space_y[v19] - PortalFace._screen_space_y[v20]); - far_portal->viewport_right_side[max_y] = (short)PortalFace._screen_space_x[v20]; - } - //**************************************************************************************************************************************** - v22 = min_y; - if ( min_y <= max_y ) - { - for ( v70 = min_y; v70 <= max_y; ++v70 ) - { - v24 = v13; - if ( v22 >= PortalFace._screen_space_y[v13] && v22 != max_y ) - { - v13 = direction2 + v13; - if ( v13 < pNumVertices ) - { - if ( v13 < 0 ) - v13 += pNumVertices; - } - else - v13 -= pNumVertices; - v26 = v13; - if ( PortalFace._screen_space_y[v26] - PortalFace._screen_space_y[v24] > 0 ) - { - v54 = ((PortalFace._screen_space_x[v26] - PortalFace._screen_space_x[v24]) << 16) / (PortalFace._screen_space_y[v26] - PortalFace._screen_space_y[v24]); - v62 = PortalFace._screen_space_x[v24] << 16; - } - } - v29 = v18; - if ( v70 >= PortalFace._screen_space_y[v18] && v70 != max_y ) - { - v18 += direction1; - if ( v18 < pNumVertices ) - { - if ( v18 < 0 ) - v18 += pNumVertices; - } - else - v18 -= pNumVertices; - v31 = v18; - if ( PortalFace._screen_space_y[v31] - PortalFace._screen_space_y[v29] > 0 ) - { - v53 = ((PortalFace._screen_space_x[v31] - PortalFace._screen_space_x[v29]) << 16) / (PortalFace._screen_space_y[v31] - PortalFace._screen_space_y[v29]); - v61 = PortalFace._screen_space_x[v29] << 16; - } - } - far_portal->viewport_left_side[v70] = HIWORD(v62); - far_portal->viewport_right_side[v70] = HIWORD(v61); - if ( far_portal->viewport_left_side[v70] > far_portal->viewport_right_side[v70] ) - { - v36 = far_portal->viewport_left_side[v70] ^ far_portal->viewport_right_side[v70]; - //v37 = far_portal->viewport_right_side[v70]; - far_portal->viewport_left_side[v70] = v36; - v38 = far_portal->viewport_right_side[v70] ^ v36; - far_portal->viewport_left_side[v70] ^= v38; - far_portal->viewport_right_side[v70] = v38; - } - v62 += v54; - v22 = v70 + 1; - v61 += v53; - } - } - //***************************************************************************************************************************** - // check portals coordinates and determine max, min(проверка координат порталов и определение макс, мин-ой у) - if ( max_y < near_portal->_viewport_space_y ) - return false; - if ( min_y > near_portal->_viewport_space_w ) - return false; - if ( min_y < near_portal->_viewport_space_y ) - min_y = near_portal->_viewport_space_y; - if ( max_y > near_portal->_viewport_space_w ) - max_y = near_portal->_viewport_space_w; - if ( min_y <= max_y ) - { - for ( min_y; min_y <= max_y; ++min_y ) - { - if ( far_portal->viewport_right_side[min_y] >= near_portal->viewport_left_side[min_y] - && far_portal->viewport_left_side[min_y] <= near_portal->viewport_right_side[min_y] ) - break; - } - } - if ( max_y < min_y ) - return false; - for ( max_y; max_y >= min_y; --max_y ) - { - if ( far_portal->viewport_right_side[max_y] >= near_portal->viewport_left_side[max_y] - && far_portal->viewport_left_side[max_y] <= near_portal->viewport_right_side[max_y] ) - break; - } - if ( min_y >= max_y ) - return false; - //************************************************************************************************************************************* - v59 = min_y; - for ( v46 = max_y - min_y + 1; v46; --v46 ) - { - if ( far_portal->viewport_left_side[v59] < near_portal->viewport_left_side[v59] ) - far_portal->viewport_left_side[v59] = near_portal->viewport_left_side[v59]; - if ( far_portal->viewport_right_side[v59] > near_portal->viewport_right_side[v59] ) - far_portal->viewport_right_side[v59] = near_portal->viewport_right_side[v59]; - ++v59; - } - far_portal->_viewport_space_y = min_y; - far_portal->_viewport_space_w = max_y; - far_portal->_viewport_space_x = far_portal->viewport_left_side[min_y]; - far_portal->_viewport_space_z = far_portal->viewport_right_side[min_y]; - far_portal->_viewport_x_minID = min_y; - far_portal->_viewport_z_maxID = min_y; - v49 = min_y + 1; - if ( v49 <= max_y ) - { - for ( v49; v49 <= max_y; ++v49 ) - { - if ( far_portal->viewport_left_side[v49] < far_portal->_viewport_space_x ) - { - far_portal->_viewport_space_x = far_portal->viewport_left_side[v49]; - far_portal->_viewport_x_minID = v49; - } - if ( far_portal->viewport_right_side[v49] > far_portal->_viewport_space_z ) - { - far_portal->_viewport_space_z = far_portal->viewport_right_side[v49]; - far_portal->_viewport_z_maxID = v49; - } - } - } - return true; -} -//----- (00423B5D) -------------------------------------------------------- -int __fastcall GetPortalScreenCoord(unsigned int uFaceID) -{ - BLVFace *pFace; // ebx@1 - int pNextVertices; // edx@11 - int t; // ST28_4@12 - int pScreenX; // eax@22 - int pScreenY; // eax@27 - signed int left_num_vertices; // edi@31 - signed int right_num_vertices; // ebx@41 - signed int top_num_vertices; // edi@51 - int bottom_num_vertices; // ebx@61 - bool current_vertices_flag; // [sp+18h] [bp-10h]@9 - signed int depth_num_vertices; // [sp+1Ch] [bp-Ch]@9 - bool next_vertices_flag; // [sp+20h] [bp-8h]@10 - - //Доп инфо "Программирование трёхмерных игр для windows" Ламот стр 910 - - pFace = &pIndoor->pFaces[uFaceID]; - memset(&PortalFace, 0, sizeof(stru367)); - - //get direction the face(определение направленности фейса)********************************************************************************* - if ( pFace->pFacePlane_old.vNormal.x * (pIndoor->pVertices[pIndoor->pFaces[uFaceID].pVertexIDs[0]].x - pGame->pIndoorCameraD3D->vPartyPos.x) - + pFace->pFacePlane_old.vNormal.y * (pIndoor->pVertices[pIndoor->pFaces[uFaceID].pVertexIDs[0]].y - pGame->pIndoorCameraD3D->vPartyPos.y) - + pFace->pFacePlane_old.vNormal.z * (pIndoor->pVertices[pIndoor->pFaces[uFaceID].pVertexIDs[0]].z - pGame->pIndoorCameraD3D->vPartyPos.z) < 0 ) - { - PortalFace.direction = true; - } - else - { - PortalFace.direction = false; - if ( !(pFace->Portal()) ) - return 0; - } - //***************************************************************************************************************************************** - //generate/cinvertetion in camera location coordinates(генерация/конвертирование в координаты пространства камеры) - - //for new coordinates: - //int x = 0x AAAA BBBB; - //AAAA - integer(целая часть), BBBB - fractional(дробная) - //float v = HIWORD(x) + LOWORD(x) / 65535.0f; - //0x0351A281 это 849(351 в шестнадцатиричной) в целой части и A281 в дробной(хотя как точно BBBB считалась не помню) - //if in HIWORD: FFFF = -1 - //FFFE = -2 - //FFFD = -3 - //.... - //8000 = -32767 - //7FFF = 32767 - //7FFE = 32766 - //если в LOWORD например лежит FFFF то не совсем понятно, что это - //потому что если и hiword и loword равны FFFF FFFF то двойное отрицание как бы, нужно тестировать что конкретно получается чтобы понять что это значит - //всё что больше 7FFF для верхнего слова это идёт уже с минусом/Nomad/ - - if ( (signed int)pFace->uNumVertices > 0 ) - { - for (uint i = 0; i < pFace->uNumVertices; ++i) - { - pGame->pIndoorCameraD3D->ApplyViewTransform_TrueIfStillVisible_BLV(pIndoor->pVertices[pFace->pVertexIDs[i]].x, - pIndoor->pVertices[pFace->pVertexIDs[i]].y, - pIndoor->pVertices[pFace->pVertexIDs[i]].z, - &PortalFace._view_transformed_z[i + 3], &PortalFace._view_transformed_x[i + 3], &PortalFace._view_transformed_y[i + 3], 0); - } - } - //***************************************************************************************************************************************** - //check vertices for the nearest plane(проверка вершин есть ли в области за ближайшей плоскостью) - if ( pFace->uNumVertices <= 0 ) - return 0; - bool bFound = false; - for (uint i = 0; i < pFace->uNumVertices; ++i) - { - if ( PortalFace._view_transformed_z[i + 3] >= 524288 )// 8.0(0x80000) - { - bFound = true; - break; - } - } - if ( !bFound ) - return 0; - //***************************************************************************************************************************************** - //check for near clip plane(проверка по ближней границе) - // - // v0 v1 - // ._________________. - // / \ - // / \ - // v5. . v2 - // | | - // | | - // | | - // ---------------------------- 8.0(near_clip) - // | | - // ._______________________. - // v4 v3 - depth_num_vertices = 0; - PortalFace._view_transformed_z[pFace->uNumVertices + 3] = PortalFace._view_transformed_z[3]; - PortalFace._view_transformed_x[pFace->uNumVertices + 3] = PortalFace._view_transformed_x[3]; - PortalFace._view_transformed_y[pFace->uNumVertices + 3] = PortalFace._view_transformed_y[3]; - current_vertices_flag = PortalFace._view_transformed_z[3] >= 0x80000; //524288 - if ( pFace->uNumVertices >= 1 ) - { - for ( uint i = 1; i <= pFace->uNumVertices; ++i) - { - next_vertices_flag = PortalFace._view_transformed_z[i + 3] >= 0x80000; //524288;// 8.0 - if ( current_vertices_flag ^ next_vertices_flag )//или текущая или следующая вершина за ближней границей - v5 - { - if ( next_vertices_flag )//следующая вершина за ближней границей - { - //t = near_clip - v4.z / v5.z - v4.z - t = fixpoint_div(0x80000 - PortalFace._view_transformed_z[i + 2], PortalFace._view_transformed_z[i + 3] - PortalFace._view_transformed_z[i + 2]); - //New_x = (v5.x - v4.x)*t + v4.x - PortalFace._view_transformed_x[depth_num_vertices] = fixpoint_mul((PortalFace._view_transformed_x[i + 3] - PortalFace._view_transformed_x[i + 2]), t) - + PortalFace._view_transformed_x[i + 2]; - //New_y = (v5.y - v4.y)*t + v4.y - PortalFace._view_transformed_y[depth_num_vertices] = fixpoint_mul((PortalFace._view_transformed_y[i + 3] - PortalFace._view_transformed_y[i + 2]), t) - + PortalFace._view_transformed_y[i + 2]; - //New_z = 8.0(0x80000) - PortalFace._view_transformed_z[depth_num_vertices] = 0x80000; //524288 - } - else// текущая вершина за ближней границей - { - //t = near_clip - v1.z / v0.z - v1.z - t = fixpoint_div(524288 - PortalFace._view_transformed_z[i + 3], PortalFace._view_transformed_z[i + 2] - PortalFace._view_transformed_z[i + 3]); - //New_x = (v0.x - v1.x)*t + v1.x - PortalFace._view_transformed_x[depth_num_vertices] = fixpoint_mul((PortalFace._view_transformed_x[i + 2] - PortalFace._view_transformed_x[i + 3]), t) - + PortalFace._view_transformed_x[i + 3]; - //New_y = (v0.x - v1.y)*t + v1.y - PortalFace._view_transformed_y[depth_num_vertices] = fixpoint_mul((PortalFace._view_transformed_y[i + 2] - PortalFace._view_transformed_y[i + 3]), t) - + PortalFace._view_transformed_y[i + 3]; - //New_z = 8.0(0x80000) - PortalFace._view_transformed_z[depth_num_vertices] = 0x80000; //524288 - } - depth_num_vertices++; - } - if ( next_vertices_flag )//если следующая вершина за ближней границей - { - pNextVertices = depth_num_vertices++; - PortalFace._view_transformed_z[pNextVertices] = PortalFace._view_transformed_z[i + 3]; - PortalFace._view_transformed_x[pNextVertices] = PortalFace._view_transformed_x[i + 3]; - PortalFace._view_transformed_y[pNextVertices] = PortalFace._view_transformed_y[i + 3]; - } - current_vertices_flag = next_vertices_flag; - } - } - //результат: нет моргания на границе портала(когда проходим сквозь портал) - //************************************************************************************************************************************ - //convertion in screen coordinates(конвертирование в координаты экрана) - PortalFace._view_transformed_z[depth_num_vertices] = PortalFace._view_transformed_z[0]; - PortalFace._view_transformed_x[depth_num_vertices] = PortalFace._view_transformed_x[0]; - PortalFace._view_transformed_y[depth_num_vertices] = PortalFace._view_transformed_y[0]; - for ( uint i = 0; i < depth_num_vertices; ++i ) - { - if ( (abs(PortalFace._view_transformed_x[i]) >> 13) <= abs(PortalFace._view_transformed_z[i]) ) - pScreenX = fixpoint_div(PortalFace._view_transformed_x[i], PortalFace._view_transformed_z[i]); - else - { - if ( PortalFace._view_transformed_x[i] >= 0 ) - { - if (PortalFace._view_transformed_z[i] >= 0) - pScreenX = 0x400000; // 64.0 - else - pScreenX = 0xFFC00000; // -63.0 - } - else - { - if (PortalFace._view_transformed_z[i] >= 0) - pScreenX = 0xFFC00000; // -63.0 - else - pScreenX = 0x400000; // 64.0 - } - } - - if ( (abs(PortalFace._view_transformed_y[i]) >> 13) <= abs(PortalFace._view_transformed_z[i]) ) - pScreenY = fixpoint_div(PortalFace._view_transformed_y[i], PortalFace._view_transformed_z[i]); - else - { - if ( PortalFace._view_transformed_y[i] >= 0 ) - { - if (PortalFace._view_transformed_z[i] >= 0) - pScreenY = 0x400000; // 64.0 - else - pScreenY = 0xFFC00000; // -63.0 - } - else - { - if (PortalFace._view_transformed_z[i] >= 0) - pScreenY = 0xFFC00000; // -63.0 - else - pScreenY = 0x400000; // 64.0 - } - } - PortalFace._screen_space_x[i + 12] = pBLVRenderParams->uViewportCenterX - fixpoint_mul(SHIWORD(pBLVRenderParams->fov_rad_fixpoint), pScreenX); - PortalFace._screen_space_y[i + 12] = pBLVRenderParams->uViewportCenterY - fixpoint_mul(SHIWORD(pBLVRenderParams->fov_rad_fixpoint), pScreenY); - } - // результат: при повороте камеры, когда граница портала сдвигается к краю экрана, портал остается прозрачным(видимым) - //****************************************************************************************************************************************** - //координаты как в Ида-базе игры так и в данном проекте перевёрнутые,т.е. портал который в правой части экрана имеет экранные координаты - //которые для левой части экрана. Например, x(оригинал) = 8, у нас х = 468(противоположный край экрана), точно также и с у. - // - //check for left_clip plane(порверка по левой границе) - left_num_vertices = 0; - PortalFace._screen_space_x[depth_num_vertices + 12] = PortalFace._screen_space_x[12]; - PortalFace._screen_space_y[depth_num_vertices + 12] = PortalFace._screen_space_y[12]; - current_vertices_flag = PortalFace._screen_space_x[12] >= (signed int)pBLVRenderParams->uViewportX;//8.0 - if ( depth_num_vertices < 1 ) - return 0; - for ( uint i = 1; i <= depth_num_vertices; ++i ) - { - next_vertices_flag = PortalFace._screen_space_x[i + 12] >= (signed int)pBLVRenderParams->uViewportX; - if ( current_vertices_flag ^ next_vertices_flag ) - { - if ( next_vertices_flag ) - { - //t = left_clip - v0.x / v1.x - v0.x - t = fixpoint_div(pBLVRenderParams->uViewportX - PortalFace._screen_space_x[i + 11], PortalFace._screen_space_x[i + 12] - PortalFace._screen_space_x[i + 11]); - //New_y = (v1.y - v0.y)*t + v0.y - PortalFace._screen_space_y[left_num_vertices + 9] = fixpoint_mul((PortalFace._screen_space_y[i + 12]- PortalFace._screen_space_y[i + 11]), t) - + PortalFace._screen_space_y[i + 11]; - //New_x = left_clip - PortalFace._screen_space_x[left_num_vertices + 9] = pBLVRenderParams->uViewportX; - } - else - { - //t = left_clip - v1.x / v0.x - v1.x - t = fixpoint_div(pBLVRenderParams->uViewportX - PortalFace._screen_space_x[i + 12], PortalFace._screen_space_x[i + 11] - PortalFace._screen_space_x[i + 12]); - //New_y = (v0.y - v1.y)*t + v1.y - PortalFace._screen_space_y[left_num_vertices + 9] = fixpoint_mul((PortalFace._screen_space_y[i + 11] - PortalFace._screen_space_y[i + 12]), t) - + PortalFace._screen_space_y[i + 12]; - //New_x = left_clip - PortalFace._screen_space_x[left_num_vertices + 9] = pBLVRenderParams->uViewportX; - } - left_num_vertices++; - } - if ( next_vertices_flag ) - { - pNextVertices = left_num_vertices++; - PortalFace._screen_space_x[pNextVertices + 9] = PortalFace._screen_space_x[i + 12]; - PortalFace._screen_space_y[pNextVertices + 9] = PortalFace._screen_space_y[i + 12]; - } - current_vertices_flag = next_vertices_flag; - } -//********************************************************************************************************************************* -//for right_clip plane(проверка по правой плоскости) - right_num_vertices = 0; - PortalFace._screen_space_x[left_num_vertices + 9] = PortalFace._screen_space_x[9]; - PortalFace._screen_space_y[left_num_vertices + 9] = PortalFace._screen_space_y[9]; - current_vertices_flag = PortalFace._screen_space_x[9] <= (signed int)pBLVRenderParams->uViewportZ;//468.0 - if (left_num_vertices < 1) - return 0; - for ( uint i = 1; i <= left_num_vertices; ++i ) - { - next_vertices_flag = PortalFace._screen_space_x[i + 9] <= (signed int)pBLVRenderParams->uViewportZ; - if ( current_vertices_flag ^ next_vertices_flag ) - { - if ( next_vertices_flag ) - { - //t = right_clip - v1.x / v0.x - v1.x - t = fixpoint_div(pBLVRenderParams->uViewportZ - PortalFace._screen_space_x[i + 8], PortalFace._screen_space_x[i + 9] - PortalFace._screen_space_x[i + 8]); - //New_y = (v0.y - v1.y)*t + v1.y - PortalFace._screen_space_y[right_num_vertices + 6] = fixpoint_mul((PortalFace._screen_space_y[i + 9] - PortalFace._screen_space_y[i + 8]), t) - + PortalFace._screen_space_y[i + 8]; - //New_x = right_clip - PortalFace._screen_space_x[right_num_vertices + 6] = pBLVRenderParams->uViewportZ; - } - else - { - //t = right_clip - v0.x / v1.x - v0.x - t = fixpoint_div(pBLVRenderParams->uViewportZ - PortalFace._screen_space_x[i + 9], PortalFace._screen_space_x[i + 8] - PortalFace._screen_space_x[i + 9]); - //New_y = (v1.y - v0.y)*t + v0.y - PortalFace._screen_space_y[right_num_vertices + 6] = fixpoint_mul((PortalFace._screen_space_y[i + 8] - PortalFace._screen_space_y[i + 9]), t) - + PortalFace._screen_space_y[i + 9]; - //New_x = right_clip - PortalFace._screen_space_x[right_num_vertices + 6] = pBLVRenderParams->uViewportZ; - } - right_num_vertices++; - } - if ( next_vertices_flag ) - { - pNextVertices = right_num_vertices++; - PortalFace._screen_space_x[pNextVertices + 6] = PortalFace._screen_space_x[i + 9]; - PortalFace._screen_space_y[pNextVertices + 6] = PortalFace._screen_space_y[i + 9]; - } - current_vertices_flag = next_vertices_flag; - } - //************************************************************************************************************************************ - // for top clip plane - top_num_vertices = 0; - PortalFace._screen_space_x[right_num_vertices + 6] = PortalFace._screen_space_x[6]; - PortalFace._screen_space_y[right_num_vertices + 6] = PortalFace._screen_space_y[6]; - - current_vertices_flag = PortalFace._screen_space_y[6] >= (signed int)pBLVRenderParams->uViewportY;//8.0 - if ( right_num_vertices < 1 ) - return 0; - for ( uint i = 1; i <= right_num_vertices; ++i ) - { - next_vertices_flag = PortalFace._screen_space_y[i + 6] >= (signed int)pBLVRenderParams->uViewportY; - if ( current_vertices_flag ^ next_vertices_flag ) - { - if ( next_vertices_flag ) - { - t = fixpoint_div(pBLVRenderParams->uViewportY - PortalFace._screen_space_y[i + 5], PortalFace._screen_space_y[i + 6] - PortalFace._screen_space_y[i + 5]); - PortalFace._screen_space_x[top_num_vertices + 3] = ((signed int)((PortalFace._screen_space_x[i + 6] - PortalFace._screen_space_x[i + 5]) - * t) >> 16) + PortalFace._screen_space_x[i + 5]; - PortalFace._screen_space_y[top_num_vertices + 3] = pBLVRenderParams->uViewportY; - } - else - { - t = fixpoint_div(pBLVRenderParams->uViewportY - PortalFace._screen_space_y[i + 6], PortalFace._screen_space_y[i + 5] - PortalFace._screen_space_y[i + 6]); - PortalFace._screen_space_x[top_num_vertices + 3] = fixpoint_mul((PortalFace._screen_space_x[i + 5]- PortalFace._screen_space_x[i + 6]), t) - + PortalFace._screen_space_x[i + 6]; - PortalFace._screen_space_y[top_num_vertices + 3] = pBLVRenderParams->uViewportY; - } - top_num_vertices++; - } - current_vertices_flag = next_vertices_flag; - if ( next_vertices_flag ) - { - pNextVertices = top_num_vertices++; - PortalFace._screen_space_x[pNextVertices + 3] = PortalFace._screen_space_x[i + 6]; - PortalFace._screen_space_y[pNextVertices + 3] = PortalFace._screen_space_y[i + 6]; - } - } -//********************************************************************************************************************************** -//for bottom_clip plane(проверка по нижней плоскости) - bottom_num_vertices = 0; - PortalFace._screen_space_x[top_num_vertices + 3] = PortalFace._screen_space_x[3]; - PortalFace._screen_space_y[top_num_vertices + 3] = PortalFace._screen_space_y[3]; - current_vertices_flag = PortalFace._screen_space_y[3] <= (signed int)pBLVRenderParams->uViewportW;//351.0 - if ( top_num_vertices < 1 ) - return 0; - for ( uint i =1; i <= top_num_vertices; ++i ) - { - next_vertices_flag = PortalFace._screen_space_y[i + 3] <= (signed int)pBLVRenderParams->uViewportW; - if ( current_vertices_flag ^ next_vertices_flag ) - { - if ( next_vertices_flag ) - { - t = fixpoint_div(pBLVRenderParams->uViewportW - PortalFace._screen_space_y[i + 2], PortalFace._screen_space_y[i + 3] - PortalFace._screen_space_y[i + 2]); - PortalFace._screen_space_x[bottom_num_vertices] = fixpoint_mul((PortalFace._screen_space_x[i + 3] - PortalFace._screen_space_x[i + 2]), t) - + PortalFace._screen_space_x[i + 2]; - PortalFace._screen_space_y[bottom_num_vertices] = pBLVRenderParams->uViewportW; - } - else - { - t = fixpoint_div(pBLVRenderParams->uViewportW - PortalFace._screen_space_y[i + 3], PortalFace._screen_space_y[i + 2] - PortalFace._screen_space_y[i + 3]); - PortalFace._screen_space_x[bottom_num_vertices] = fixpoint_mul((PortalFace._screen_space_x[i + 2] - PortalFace._screen_space_x[i + 3]), t) - + PortalFace._screen_space_x[i + 3]; - PortalFace._screen_space_y[bottom_num_vertices] = pBLVRenderParams->uViewportW; - } - bottom_num_vertices++; - } - if ( next_vertices_flag ) - { - pNextVertices = bottom_num_vertices++; - PortalFace._screen_space_x[pNextVertices] = PortalFace._screen_space_x[i + 3]; - PortalFace._screen_space_y[pNextVertices] = PortalFace._screen_space_y[i + 3]; - } - current_vertices_flag = next_vertices_flag; - } -//*************************************************************************************************************************************** - - if ( !bottom_num_vertices ) - return 0; - PortalFace._screen_space_x[bottom_num_vertices] = PortalFace._screen_space_x[0]; - PortalFace._screen_space_y[bottom_num_vertices] = PortalFace._screen_space_y[0]; -//check for software(проверка для софтвар) - /*if ( !pRenderer->pRenderD3D && bottom_num_vertices > 3 ) - { - PortalFace._screen_space_x[bottom_num_vertices + 1] = PortalFace._screen_space_x[1]; - PortalFace._screen_space_y[bottom_num_vertices + 1] = PortalFace._screen_space_y[1]; - thisf = PortalFace.direction == true ? 1 : - 1; - if ( bottom_num_vertices > 0 ) - { - v62 = 1; - v71 = 1; - do - { - v63 = v62 - 1; - v64 = v62 + 1; - v80 = v62 + 1; - if ( v62 - 1 >= bottom_num_vertices ) - v63 -= bottom_num_vertices; - if ( v62 >= bottom_num_vertices ) - v62 -= bottom_num_vertices; - if ( v64 >= bottom_num_vertices ) - v64 -= bottom_num_vertices; - if ( thisf * ((PortalFace._screen_space_y[v64] - PortalFace._screen_space_y[v63]) - * (PortalFace._screen_space_x[v62] - PortalFace._screen_space_x[v63]) - - (PortalFace._screen_space_y[v62] - PortalFace._screen_space_y[v63]) - * (PortalFace._screen_space_x[v64] - PortalFace._screen_space_x[v63])) < 0 ) - { - v62 = v80; - v71 = v80; - } - else - { - v62 = v71; - v65 = v71; - if ( v71 < bottom_num_vertices || (v65 = v71 - bottom_num_vertices, v71 - bottom_num_vertices < bottom_num_vertices) ) - { - memcpy(&PortalFace._screen_space_y[v65], &PortalFace._screen_space_y[v65 + 1], - 4 * ((unsigned int)(4 * (bottom_num_vertices - v65)) >> 2)); - memcpy(&PortalFace._screen_space_x[v65], &PortalFace._screen_space_x[v65 + 1], - 4 * ((unsigned int)(4 * (bottom_num_vertices - v65)) >> 2)); - } - --bottom_num_vertices; - } - } - while ( v62 - 1 < bottom_num_vertices ); - } - PortalFace._screen_space_x[bottom_num_vertices] = PortalFace._screen_space_x[0]; - PortalFace._screen_space_y[bottom_num_vertices] = PortalFace._screen_space_y[0]; - }*/ - return bottom_num_vertices; -} - -//----- (004AAEA6) -------------------------------------------------------- -int __fastcall sub_4AAEA6_transform(RenderVertexSoft *a1) -{ - double v4; // st5@2 - double v5; // st4@3 - float v11; // [sp+8h] [bp-8h]@2 - float v12; // [sp+8h] [bp-8h]@6 - float v13; // [sp+Ch] [bp-4h]@2 - float v14; // [sp+Ch] [bp-4h]@6 - - if (pGame->pIndoorCameraD3D->sRotationX) - { - v13 = a1->vWorldPosition.x - (double)pParty->vPosition.x; - v11 = a1->vWorldPosition.y - (double)pParty->vPosition.y; - v4 = a1->vWorldPosition.z - (double)pParty->vPosition.z; - //if ( pRenderer->pRenderD3D ) - //{ - v5 = v11 * pGame->pIndoorCameraD3D->fRotationYSine + v13 * pGame->pIndoorCameraD3D->fRotationYCosine; - a1->vWorldViewPosition.y = v13 * pGame->pIndoorCameraD3D->fRotationYSine - v11 * pGame->pIndoorCameraD3D->fRotationYCosine; - /*} - else - { - v5 = v13 * pBLVRenderParams->fCosineY - v11 * pBLVRenderParams->fSineY; - a1->vWorldViewPosition.y = v13 * pBLVRenderParams->fSineY + v11 * pBLVRenderParams->fCosineY; - }*/ - a1->vWorldViewPosition.x = v5 * pGame->pIndoorCameraD3D->fRotationXCosine - v4 * pGame->pIndoorCameraD3D->fRotationXSine; - a1->vWorldViewPosition.z = v5 * pGame->pIndoorCameraD3D->fRotationXSine + v4 * pGame->pIndoorCameraD3D->fRotationXCosine; - } - else - { - v14 = a1->vWorldPosition.x - (double)pParty->vPosition.x; - v12 = a1->vWorldPosition.y - (double)pParty->vPosition.y; - a1->vWorldViewPosition.z = a1->vWorldPosition.z - (double)pParty->vPosition.z; - //if ( pRenderer->pRenderD3D ) - //{ - a1->vWorldViewPosition.x = v12 * pGame->pIndoorCameraD3D->fRotationYSine + v14 * pGame->pIndoorCameraD3D->fRotationYCosine; - a1->vWorldViewPosition.y = v14 * pGame->pIndoorCameraD3D->fRotationYSine - v12 * pGame->pIndoorCameraD3D->fRotationYCosine; - /*} - else - { - a1->vWorldViewPosition.x = v14 * pBLVRenderParams->fCosineY - v12 * pBLVRenderParams->fSineY; - a1->vWorldViewPosition.y = v14 * pBLVRenderParams->fSineY + v12 * pBLVRenderParams->fCosineY; - }*/ - } - return 0; -} -//----- (00472866) -------------------------------------------------------- -void BLV_ProcessPartyActions() -{ - int v1; // ebx@1 - int v2; // edi@1 - double v10; // st7@27 - int new_party_z; // esi@96 - int v38; // eax@96 - int v39; // ecx@106 - int v40; // eax@106 - int v42; // eax@120 - BLVFace *pFace; // esi@126 - int v46; // ecx@133 - int v52; // eax@140 - int v54; // ebx@146 - unsigned int uFaceEvent; // [sp+14h] [bp-4Ch]@1 - bool party_running_flag; // [sp+1Ch] [bp-44h]@1 - bool bFeatherFall; // [sp+24h] [bp-3Ch]@15 - unsigned int uSectorID; // [sp+28h] [bp-38h]@1 - bool party_walking_flag; // [sp+2Ch] [bp-34h]@1 - unsigned int uFaceID; // [sp+30h] [bp-30h]@1 - int v80; // [sp+34h] [bp-2Ch]@1 - int v82; // [sp+3Ch] [bp-24h]@47 - int _view_angle; // [sp+40h] [bp-20h]@47 - bool hovering; // [sp+44h] [bp-1Ch]@1 - int new_party_y; // [sp+48h] [bp-18h]@1 - int new_party_x; // [sp+4Ch] [bp-14h]@1 - int party_z; // [sp+50h] [bp-10h]@1 - int angle; // [sp+5Ch] [bp-4h]@47 - - uFaceEvent = 0; - //v89 = pParty->uFallSpeed; - v1 = 0; - v2 = 0; - new_party_x = pParty->vPosition.x; - new_party_y = pParty->vPosition.y; - party_z = pParty->vPosition.z; - uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z); - party_running_flag = false; - party_walking_flag = false; - hovering = false; - - uFaceID = -1; - int floor_level = collide_against_floor(new_party_x, new_party_y, party_z + 40, &uSectorID, &uFaceID);//получить высоту пола - - if ( pParty->bFlying )//отключить полёт - { - pParty->bFlying = false; - if (pParty->FlyActive()) - pOtherOverlayList->pOverlays[pParty->pPartyBuffs[PARTY_BUFF_FLY].uOverlayID - 1].field_E |= 1; - } - - if ( floor_level == -30000 || uFaceID == -1) - { - floor_level = collide_against_floor_approximate(new_party_x, new_party_y, party_z + 40, &uSectorID, &uFaceID); - if ( floor_level == -30000 || uFaceID == -1) - { - __debugbreak(); // level built with errors - pParty->vPosition.x = blv_prev_party_x; - pParty->vPosition.y = blv_prev_party_z; - pParty->vPosition.z = blv_prev_party_y; - pParty->uFallStartY = blv_prev_party_y; - return; - } - } - - blv_prev_party_x = pParty->vPosition.x; - blv_prev_party_z = pParty->vPosition.y; - blv_prev_party_y = pParty->vPosition.z; - if (!pParty->bTurnBasedModeOn) - { - static int dword_720CDC = 0; - - int v67 = GetTickCount() / 500; - if (dword_720CDC != v67 ) - { - dword_4F8580[3 * dword_4F8580[1]] = pParty->vPosition.x; - dword_4F8580[3 * dword_4F8580[2]] = pParty->vPosition.y; - dword_4F8580[3 * dword_4F8580[3]] = pParty->vPosition.z; - if ( dword_4F8580[0] > 60 ) - dword_4F8580[0] = 1; - - dword_720CDC = v67; - } - } - - int fall_start; - /* - if (!pParty->FeatherFallActive())// не активно падение пера - { - bFeatherFall = false; - if (!pParty->pPlayers[0].WearsItemAnyWhere(ITEM_ARTIFACT_LADYS_ESCORT) && // grants feather fall - !pParty->pPlayers[1].WearsItemAnyWhere(ITEM_ARTIFACT_LADYS_ESCORT) && - !pParty->pPlayers[2].WearsItemAnyWhere(ITEM_ARTIFACT_LADYS_ESCORT) && - !pParty->pPlayers[3].WearsItemAnyWhere(ITEM_ARTIFACT_LADYS_ESCORT)) - { - fall_start = pParty->uFallStartY; - } - else// was missing - { - fall_start = floor_level; - bFeatherFall = true; - pParty->uFallStartY = floor_level; - } - } - else// активно падение пера - { - fall_start = floor_level; - bFeatherFall = true; - pParty->uFallStartY = floor_level; - } - - Reworked condition below - */ - if (pParty->FeatherFallActive() - || pParty->pPlayers[0].WearsItemAnyWhere(ITEM_ARTIFACT_LADYS_ESCORT) - || pParty->pPlayers[1].WearsItemAnyWhere(ITEM_ARTIFACT_LADYS_ESCORT) - || pParty->pPlayers[2].WearsItemAnyWhere(ITEM_ARTIFACT_LADYS_ESCORT) - || pParty->pPlayers[3].WearsItemAnyWhere(ITEM_ARTIFACT_LADYS_ESCORT)) - { - fall_start = floor_level; - bFeatherFall = true; - pParty->uFallStartY = floor_level; - } - else - { - bFeatherFall = false; - fall_start = pParty->uFallStartY; - } - - if (fall_start - party_z > 512 && !bFeatherFall && party_z <= floor_level + 1)//повреждение от падения с высоты - { - assert(~pParty->uFlags & PARTY_FLAGS_1_LANDING); // why land in indoor? - if (pParty->uFlags & PARTY_FLAGS_1_LANDING) - pParty->uFlags &= ~PARTY_FLAGS_1_LANDING; - else for (uint i = 0; i < 4; ++i) - { // receive falling damage - if (!pParty->pPlayers[i].HasEnchantedItemEquipped(72) && !pParty->pPlayers[i].WearsItem(ITEM_ARTIFACT_HERMES_SANDALS, EQUIP_BOOTS)) - { - pParty->pPlayers[i].ReceiveDamage((pParty->uFallStartY - party_z) * (0.1f * pParty->pPlayers[i].GetMaxHealth()) / 256, DMGT_PHISYCAL); - v10 = (double)(20 - pParty->pPlayers[i].GetParameterBonus(pParty->pPlayers[i].GetActualEndurance())) * flt_6BE3A4_debug_recmod1 * 2.133333333333333; - pParty->pPlayers[i].SetRecoveryTime((signed __int64)v10); - } - } - } - - if ( party_z > floor_level + 1 ) - hovering = true; - - bool not_high_fall = false; - - if ( party_z - floor_level <= 32 ) - { - pParty->uFallStartY = party_z; - not_high_fall = true; - } - - if (bWalkSound && pParty->walk_sound_timer)//таймеры для звуков передвижения - { - if (pParty->walk_sound_timer > pEventTimer->uTimeElapsed) - pParty->walk_sound_timer -= pEventTimer->uTimeElapsed; - else pParty->walk_sound_timer = 0; - } - - if (party_z <= floor_level + 1)// группа ниже уровня пола - { - party_z = floor_level + 1; - pParty->uFallStartY = floor_level + 1; - - if (!hovering && pParty->floor_face_pid != uFaceID)// не парящие и - { - if (pIndoor->pFaces[uFaceID].uAttributes & FACE_PRESSURE_PLATE) - uFaceEvent = pIndoor->pFaceExtras[pIndoor->pFaces[uFaceID].uFaceExtraID].uEventID; - } - } - if (!hovering) - pParty->floor_face_pid = uFaceID; - - bool on_water = false; - if ( pIndoor->pFaces[uFaceID].Fluid())// на воде - on_water = true; - - //v81 = pParty->uWalkSpeed; - angle = pParty->sRotationY; - _view_angle = pParty->sRotationX; - v82 = (unsigned __int64)(pEventTimer->dt_in_some_format * (signed __int64)((signed int)(pParty->y_rotation_speed * stru_5C6E00->uIntegerPi) - / 180)) >> 16; - while ( pPartyActionQueue->uNumActions ) - { - switch ( pPartyActionQueue->Next() ) - { - case PARTY_TurnLeft: - if (uTurnSpeed) - angle = stru_5C6E00->uDoublePiMask & (angle + uTurnSpeed); - else - angle = stru_5C6E00->uDoublePiMask & (angle + (int)(v82 * fTurnSpeedMultiplier)); - break; - case PARTY_TurnRight: - if (uTurnSpeed) - angle = stru_5C6E00->uDoublePiMask & (angle - uTurnSpeed); - else - angle = stru_5C6E00->uDoublePiMask & (angle - (int)(v82 * fTurnSpeedMultiplier)); - break; - - case PARTY_FastTurnLeft: - if (uTurnSpeed) - angle = stru_5C6E00->uDoublePiMask & (angle + uTurnSpeed); - else - angle = stru_5C6E00->uDoublePiMask & (angle + (int)(2.0f * fTurnSpeedMultiplier * (double)v82)); - break; - - case PARTY_FastTurnRight: - if (uTurnSpeed) - angle = stru_5C6E00->uDoublePiMask & (angle - uTurnSpeed); - else - angle = stru_5C6E00->uDoublePiMask & (angle - (int)(2.0f * fTurnSpeedMultiplier * (double)v82)); - break; - - case PARTY_StrafeLeft: - v2 -= fixpoint_mul(stru_5C6E00->Sin(angle), pParty->uWalkSpeed * fWalkSpeedMultiplier / 2); - v1 += fixpoint_mul(stru_5C6E00->Cos(angle), pParty->uWalkSpeed * fWalkSpeedMultiplier / 2); - party_walking_flag = true; - break; - case PARTY_StrafeRight: - v2 += fixpoint_mul(stru_5C6E00->Sin(angle), pParty->uWalkSpeed * fWalkSpeedMultiplier / 2); - v1 -= fixpoint_mul(stru_5C6E00->Cos(angle), pParty->uWalkSpeed * fWalkSpeedMultiplier / 2); - party_walking_flag = true; - break; - case PARTY_WalkForward: - v2 += fixpoint_mul(stru_5C6E00->Cos(angle), 5 * pParty->uWalkSpeed * fWalkSpeedMultiplier); - v1 += fixpoint_mul(stru_5C6E00->Sin(angle), 5 * pParty->uWalkSpeed * fWalkSpeedMultiplier); - party_walking_flag = true; - break; - case PARTY_WalkBackward: - v2 -= fixpoint_mul(stru_5C6E00->Cos(angle), pParty->uWalkSpeed * fBackwardWalkSpeedMultiplier); - v1 -= fixpoint_mul(stru_5C6E00->Sin(angle), pParty->uWalkSpeed * fBackwardWalkSpeedMultiplier); - party_walking_flag = true; - break; - case PARTY_RunForward://Бег вперёд - v2 += fixpoint_mul(stru_5C6E00->Cos(angle), 2 * pParty->uWalkSpeed * fWalkSpeedMultiplier); - v1 += fixpoint_mul(stru_5C6E00->Sin(angle), 2 * pParty->uWalkSpeed * fWalkSpeedMultiplier); - party_running_flag = true; - break; - case PARTY_RunBackward: - //v32 = stru_5C6E00->SinCos(angle); - //v33 = (double)v81; - //v88 = (double)v81; - v2 -= fixpoint_mul(stru_5C6E00->Cos(angle), pParty->uWalkSpeed * fBackwardWalkSpeedMultiplier); - //v34 = stru_5C6E00->SinCos(angle - stru_5C6E00->uIntegerHalfPi); - v1 -= fixpoint_mul(stru_5C6E00->Sin(angle), pParty->uWalkSpeed * fBackwardWalkSpeedMultiplier); - party_running_flag = true; - break; - case PARTY_LookUp: - _view_angle += (signed __int64)(flt_6BE150_look_up_down_dangle * 25.0); - if ( _view_angle > 128 ) - _view_angle = 128; - if ( uActiveCharacter ) - pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)SPEECH_63, 0); - break; - case PARTY_LookDown: - _view_angle += (signed __int64)(flt_6BE150_look_up_down_dangle * -25.0); - if ( _view_angle < -128 ) - _view_angle = -128; - if ( uActiveCharacter ) - pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)SPEECH_64, 0); - break; - case PARTY_CenterView: - _view_angle = 0; - break; - case PARTY_Jump: - if ( (!hovering || party_z <= floor_level + 6 && pParty->uFallSpeed <= 0) && pParty->field_24 ) - { - hovering = true; - pParty->uFallSpeed = (signed __int64)((double)(pParty->field_24 << 6) * 1.5 + (double)pParty->uFallSpeed); - } - break; - default: - break; - } - } - pParty->sRotationY = angle; - pParty->sRotationX = _view_angle; - if ( hovering )//парящие - { - pParty->uFallSpeed += -2 * pEventTimer->uTimeElapsed * GetGravityStrength();// расчёт скорости падения - if ( hovering && pParty->uFallSpeed <= 0 ) - { - if ( pParty->uFallSpeed < -500 && !pParty->bFlying ) - { - for ( uint pl = 1; pl <= 4; pl++ ) - { - if ( !pPlayers[pl]->HasEnchantedItemEquipped(72) && !pPlayers[pl]->WearsItem(ITEM_ARTIFACT_HERMES_SANDALS, EQUIP_BOOTS) ) //was 8 - pPlayers[pl]->PlayEmotion(CHARACTER_EXPRESSION_SCARED, 0); - } - } - } - else - pParty->uFallStartY = party_z; - } - else// не парящие - { - if ( pIndoor->pFaces[uFaceID].pFacePlane_old.vNormal.z < 0x8000 ) - { - pParty->uFallSpeed -= pEventTimer->uTimeElapsed * GetGravityStrength(); - pParty->uFallStartY = party_z; - } - else - { - if (! (pParty->uFlags & PARTY_FLAGS_1_LANDING) ) - pParty->uFallSpeed = 0; - pParty->uFallStartY = party_z; - } - } - if ( v2 * v2 + v1 * v1 < 400 ) - { - v1 = 0; - v2 = 0; - } - - stru_721530.field_84 = -1; - stru_721530.field_70 = 0; - stru_721530.prolly_normal_d = pParty->field_14_radius; - stru_721530.field_8_radius = pParty->field_14_radius / 2; - stru_721530.field_0 = 1; - stru_721530.height = pParty->uPartyHeight - 32; - for ( uint i = 0; i < 100; i++ ) - { - new_party_z = party_z; - stru_721530.position.x = new_party_x; - stru_721530.position.y = new_party_y; - stru_721530.position.z = stru_721530.height + party_z + 1; - - stru_721530.normal.x = new_party_x; - stru_721530.normal.y = new_party_y; - stru_721530.normal.z = stru_721530.prolly_normal_d + party_z + 1; - - stru_721530.velocity.x = v2; - stru_721530.velocity.y = v1; - stru_721530.velocity.z = pParty->uFallSpeed; - - stru_721530.uSectorID = uSectorID; - v38 = 0; - if ( pParty->bTurnBasedModeOn == true && pTurnEngine->turn_stage == TE_MOVEMENT ) - v38 = 13312; - if ( stru_721530._47050A(v38) ) - break; - for ( uint j = 0; j < 100; ++j ) - { - _46E44E_collide_against_faces_and_portals(1); - _46E0B2_collide_against_decorations();//столкновения с декором - for ( v80 = 0; v80 < (signed int)uNumActors; ++v80 ) - Actor::_46DF1A_collide_against_actor(v80, 0);//столкновения с монстрами - if ( _46F04E_collide_against_portals() )//столкновения с порталами - break; - } - if ( stru_721530.field_7C >= stru_721530.field_6C ) - { - v39 = stru_721530.normal2.x; - uSectorID = stru_721530.normal2.y; - v40 = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1; - } - else - { - v39 = new_party_x + fixpoint_mul(stru_721530.field_7C, stru_721530.direction.x); - uSectorID = new_party_y + fixpoint_mul(stru_721530.field_7C, stru_721530.direction.y); - v40 = new_party_z + fixpoint_mul(stru_721530.field_7C, stru_721530.direction.z); - } - v42 = collide_against_floor(v39, uSectorID, v40 + 40, &stru_721530.uSectorID, &uFaceID); - if ( v42 == -30000 || v42 - new_party_z > 128 ) - return; - if ( stru_721530.field_7C >= stru_721530.field_6C )//??? - { - new_party_x = stru_721530.normal2.x; - new_party_y = stru_721530.normal2.y; - new_party_z = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1; - break; - } - new_party_x += fixpoint_mul(stru_721530.field_7C, stru_721530.direction.x); - new_party_y += fixpoint_mul(stru_721530.field_7C, stru_721530.direction.y); - uSectorID = stru_721530.uSectorID; - stru_721530.field_70 += stru_721530.field_7C; - unsigned long long v87 = new_party_z + fixpoint_mul(stru_721530.field_7C, stru_721530.direction.z); - if ( PID_TYPE(stru_721530.uFaceID) == OBJECT_Actor)//при столкновении с монстром - { - if ( pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime > 0 ) - pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].Reset(); - viewparams->bRedrawGameUI = true; - } - else if ( PID_TYPE(stru_721530.uFaceID) == OBJECT_Decoration)//при столкновении с декорацией - { - v54 = stru_5C6E00->Atan2(new_party_x - pLevelDecorations[stru_721530.uFaceID >> 3].vPosition.x, - new_party_y - pLevelDecorations[stru_721530.uFaceID >> 3].vPosition.y); - v2 = fixpoint_mul(stru_5C6E00->Cos(v54), integer_sqrt(v2 * v2 + v1 * v1)); - v1 = fixpoint_mul(stru_5C6E00->Sin(v54), integer_sqrt(v2 * v2 + v1 * v1)); - } - else if ( PID_TYPE(stru_721530.uFaceID) == OBJECT_BModel)//при столкновении с bmodel - { - pFace = &pIndoor->pFaces[(signed int)stru_721530.uFaceID >> 3]; - if ( pFace->uPolygonType == POLYGON_Floor )// если bmodel - пол - { - if ( pParty->uFallSpeed < 0 ) - pParty->uFallSpeed = 0; - v87 = pIndoor->pVertices[*pFace->pVertexIDs].z + 1; - if ( pParty->uFallStartY - v87 < 512 ) - pParty->uFallStartY = v87; - if ( v2 * v2 + v1 * v1 < 400 ) - { - v1 = 0; - v2 = 0; - } - if ( pParty->floor_face_pid != PID_ID(stru_721530.uFaceID) && pFace->Pressure_Plate() ) - uFaceEvent = pIndoor->pFaceExtras[pFace->uFaceExtraID].uEventID; - } - else// если не пол - { - v46 = pParty->uFallSpeed * pFace->pFacePlane_old.vNormal.z; - if ( pFace->uPolygonType != POLYGON_InBetweenFloorAndWall )//полез на холм - { - v80 = abs(v1 * pFace->pFacePlane_old.vNormal.y + v46 + v2 * pFace->pFacePlane_old.vNormal.x) >> 16; - if ((stru_721530.speed >> 3) > v80 ) - v80 = stru_721530.speed >> 3; - v2 += fixpoint_mul(v80, pFace->pFacePlane_old.vNormal.x); - v1 += fixpoint_mul(v80, pFace->pFacePlane_old.vNormal.y); - pParty->uFallSpeed += fixpoint_mul(v80, pFace->pFacePlane_old.vNormal.z); - //v80 = pFace->pFacePlane_old.vNormal.y; - v52 = stru_721530.prolly_normal_d - ((pFace->pFacePlane_old.dist - + v87 * pFace->pFacePlane_old.vNormal.z - + new_party_y * pFace->pFacePlane_old.vNormal.y - + new_party_x * pFace->pFacePlane_old.vNormal.x) >> 16); - if ( v52 > 0 ) - { - new_party_x += fixpoint_mul(v52, pFace->pFacePlane_old.vNormal.x); - new_party_y += fixpoint_mul(v52, pFace->pFacePlane_old.vNormal.y); - v87 += fixpoint_mul(v52, pFace->pFacePlane_old.vNormal.z); - } - if ( pParty->floor_face_pid != PID_ID(stru_721530.uFaceID) && pFace->Pressure_Plate() ) - uFaceEvent = pIndoor->pFaceExtras[pFace->uFaceExtraID].uEventID; - } - if ( pFace->uPolygonType == POLYGON_InBetweenFloorAndWall ) - { - v80 = abs(v1 * pFace->pFacePlane_old.vNormal.y + v46 + v2 * pFace->pFacePlane_old.vNormal.x) >> 16; - if ((stru_721530.speed >> 3) > v80 ) - v80 = stru_721530.speed >> 3; - v2 += fixpoint_mul(v80, pFace->pFacePlane_old.vNormal.x); - v1 += fixpoint_mul(v80, pFace->pFacePlane_old.vNormal.y); - pParty->uFallSpeed += fixpoint_mul(v80, pFace->pFacePlane_old.vNormal.z); - if ( v2 * v2 + v1 * v1 >= 400 ) - { - if ( pParty->floor_face_pid != PID_ID(stru_721530.uFaceID) && pFace->Pressure_Plate() ) - uFaceEvent = pIndoor->pFaceExtras[pFace->uFaceExtraID].uEventID; - } - else - { - v2 = 0; - v1 = 0; - pParty->uFallSpeed = 0; - } - } - } - } - v2 = fixpoint_mul(58500, v2); - v1 = fixpoint_mul(58500, v1); - pParty->uFallSpeed = fixpoint_mul(58500, pParty->uFallSpeed); - } - - // //Воспроизведение звуков ходьбы/бега------------------------- - uint pX_ = abs(pParty->vPosition.x - new_party_x); - uint pY_ = abs(pParty->vPosition.y - new_party_y); - uint pZ_ = abs(pParty->vPosition.z - new_party_z); - if ( bWalkSound && pParty->walk_sound_timer <= 0 ) - { - pAudioPlayer->_4AA258(804);//stop sound - if ( party_running_flag && (!hovering || not_high_fall) ) //Бег и (не прыжок или не высокое падение ) - { - if ( integer_sqrt(pX_ * pX_ + pY_ * pY_ + pZ_ * pZ_) >= 16 ) - { - if ( on_water ) - pAudioPlayer->PlaySound(SOUND_RunAlongWater, 804, 1, -1, 0, 0, 0, 0); - else if ( pIndoor->pFaces[uFaceID].uAttributes & FACE_INDOOR_CARPET )//по ковру - pAudioPlayer->PlaySound((SoundID)50, 804, 1, -1, 0, 0, 0, 0); - else - pAudioPlayer->PlaySound(SOUND_RunAlong3DModel, 804, 1, -1, 0, 0, 0, 0); - pParty->walk_sound_timer = 96;//64 - } - } - else if ( party_walking_flag && (!hovering || not_high_fall) )//Ходьба и (не прыжок или не высокое падение) - { - if ( integer_sqrt(pX_ * pX_ + pY_ * pY_ + pZ_ * pZ_) >= 8 ) - { - if ( on_water ) - pAudioPlayer->PlaySound(SOUND_WalkAlongWater, 804, 1, -1, 0, 0, 0, 0); - else if ( pIndoor->pFaces[uFaceID].uAttributes & FACE_INDOOR_CARPET )//по ковру - pAudioPlayer->PlaySound((SoundID)89, 804, 1, -1, 0, 0, 0, 0); - else - pAudioPlayer->PlaySound(SOUND_WalkAlong3DModel, 804, 1, -1, 0, 0, 0, 0); - pParty->walk_sound_timer = 144;//64 - } - } - } - if ( integer_sqrt(pX_ * pX_ + pY_ * pY_ + pZ_ * pZ_) < 8 )//отключить звук ходьбы при остановке - pAudioPlayer->_4AA258(804); - //------------------------------------------------------------- - if ( !hovering || !not_high_fall ) - pParty->uFlags &= ~PARTY_FLAGS_1_FALLING; - else - pParty->uFlags |= PARTY_FLAGS_1_FALLING; - pParty->uFlags &= ~PARTY_FLAGS_1_BURNING; - pParty->vPosition.x = new_party_x; - pParty->vPosition.z = new_party_z; - pParty->vPosition.y = new_party_y; - //pParty->uFallSpeed = v89; - if ( !hovering && pIndoor->pFaces[uFaceID].uAttributes & FACE_INDOOR_LAVA ) - pParty->uFlags |= PARTY_FLAGS_1_BURNING;//0x200 - if (uFaceEvent) - EventProcessor(uFaceEvent, 0, 1); -} - -//----- (00449A49) -------------------------------------------------------- -void Door_switch_animation(unsigned int uDoorID, int a2) -{ - int old_state; // eax@1 - signed int door_id; // esi@2 - - if ( !pIndoor->pDoors ) - return; - for ( door_id = 0; door_id < 200; ++door_id ) - { - if ( pIndoor->pDoors[door_id].uDoorID == uDoorID ) - break; - } - if ( door_id >= 200 ) - { - Error("Unable to find Door ID: %i!", uDoorID); - } - old_state = pIndoor->pDoors[door_id].uState; - //old_state: 0 - в нижнем положении/закрыто - // 2 - в верхнем положении/открыто, - //a2: 1 - открыть - // 2 - опустить/поднять - if ( a2 == 2 ) - { - if ( pIndoor->pDoors[door_id].uState == BLVDoor::Closing || pIndoor->pDoors[door_id].uState == BLVDoor::Opening ) - return; - if ( pIndoor->pDoors[door_id].uState ) - { - if ( pIndoor->pDoors[door_id].uState != BLVDoor::Closed && pIndoor->pDoors[door_id].uState != BLVDoor::Closing ) - { - pIndoor->pDoors[door_id].uState = BLVDoor::Closing; - if ( old_state == BLVDoor::Open ) - { - pIndoor->pDoors[door_id].uTimeSinceTriggered = 0; - return; - } - if ( pIndoor->pDoors[door_id].uTimeSinceTriggered != 15360 ) - { - pIndoor->pDoors[door_id].uTimeSinceTriggered = (pIndoor->pDoors[door_id].uMoveLength << 7) / pIndoor->pDoors[door_id].uOpenSpeed - - ((signed int)(pIndoor->pDoors[door_id].uTimeSinceTriggered * pIndoor->pDoors[door_id].uCloseSpeed) - / 128 << 7) / pIndoor->pDoors[door_id].uOpenSpeed; - return; - } - pIndoor->pDoors[door_id].uTimeSinceTriggered = 15360; - } - return; - } - } - else - { - if ( a2 == 0 ) - { - if ( pIndoor->pDoors[door_id].uState != BLVDoor::Closed && pIndoor->pDoors[door_id].uState != BLVDoor::Closing ) - { - pIndoor->pDoors[door_id].uState = BLVDoor::Closing; - if ( old_state == BLVDoor::Open ) - { - pIndoor->pDoors[door_id].uTimeSinceTriggered = 0; - return; - } - if ( pIndoor->pDoors[door_id].uTimeSinceTriggered != 15360 ) - { - pIndoor->pDoors[door_id].uTimeSinceTriggered = (pIndoor->pDoors[door_id].uMoveLength << 7) / pIndoor->pDoors[door_id].uOpenSpeed - - ((signed int)(pIndoor->pDoors[door_id].uTimeSinceTriggered * pIndoor->pDoors[door_id].uCloseSpeed) - / 128 << 7) / pIndoor->pDoors[door_id].uOpenSpeed; - return; - } - pIndoor->pDoors[door_id].uTimeSinceTriggered = 15360; - } - return; - } - if ( a2 != 1 ) - return; - } - if ( old_state != BLVDoor::Open && old_state != BLVDoor::Opening ) - { - pIndoor->pDoors[door_id].uState = BLVDoor::Opening; - if ( old_state == BLVDoor::Closed ) - { - pIndoor->pDoors[door_id].uTimeSinceTriggered = 0; - return; - } - if ( pIndoor->pDoors[door_id].uTimeSinceTriggered != 15360 ) - { - pIndoor->pDoors[door_id].uTimeSinceTriggered = (pIndoor->pDoors[door_id].uMoveLength << 7) / pIndoor->pDoors[door_id].uCloseSpeed - - ((signed int)(pIndoor->pDoors[door_id].uTimeSinceTriggered * pIndoor->pDoors[door_id].uOpenSpeed) - / 128 << 7) / pIndoor->pDoors[door_id].uCloseSpeed; - return; - } - pIndoor->pDoors[door_id].uTimeSinceTriggered = 15360; - } - return; -} - - -//----- (004088E9) -------------------------------------------------------- -int __fastcall sub_4088E9(int x1, int y1, int x2, int y2, int x3, int y3) -{ - signed int result; // eax@1 - - result = integer_sqrt(abs(x2 - x1) * abs(x2 - x1) + abs(y2 - y1) * abs(y2 - y1)); - if ( result ) - result = abs(((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / result); - return result; -} - -//----- (00450DA3) -------------------------------------------------------- -int GetAlertStatus() -{ - int result; // eax@2 - - if ( uCurrentlyLoadedLevelType == LEVEL_Indoor ) - result = pOutdoor->ddm.field_C_alert; - else - result = uCurrentlyLoadedLevelType == LEVEL_Outdoor ? pIndoor->dlv.field_C_alert : 0; - return result; -} - - -//----- (0045063B) -------------------------------------------------------- -int __fastcall _45063B_spawn_some_monster(MapInfo *a1, int a2) -{ - int result; // eax@8 - int v6; // edi@11 - int v7; // ebx@11 - int v8; // edi@11 - int v9; // ebx@12 - int v10; // eax@12 - char v11; // zf@16 - int v12; // edi@20 - int v13; // eax@20 - int v14; // ebx@20 - int v15; // eax@20 - int v16; // eax@20 - int v17; // eax@20 - int v18; // eax@21 - SpawnPointMM7 v19; // [sp+Ch] [bp-38h]@1 - int v22; // [sp+2Ch] [bp-18h]@3 - unsigned int uFaceID; // [sp+38h] [bp-Ch]@10 - int v26; // [sp+3Ch] [bp-8h]@11 - int v27; // [sp+40h] [bp-4h]@11 - - if (!uNumActors) - return 0; - - for ( uint mon_id = 0; mon_id < uNumActors; ++mon_id ) - { - if ((pActors[mon_id].pMonsterInfo.uID < 121 || pActors[mon_id].pMonsterInfo.uID > 123) && // Dwarf FemaleC A-C - (pActors[mon_id].pMonsterInfo.uID < 124 || pActors[mon_id].pMonsterInfo.uID > 126) && // Dwarf MaleA A-C - (pActors[mon_id].pMonsterInfo.uID < 133 || pActors[mon_id].pMonsterInfo.uID > 135) && // Peasant Elf FemaleA A-C - pActors[mon_id].CanAct()) - { - if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor ) - { - v22 = 0; - uint face_id = 0; - for ( face_id; face_id < 100; ++face_id ) - { - v6 = rand() % 1024 + 512; - v7 = rand() % (signed int)stru_5C6E00->uIntegerDoublePi; - v19.vPosition.x = pParty->vPosition.x + fixpoint_mul(stru_5C6E00->Cos(v7), v6); - v8 = 0; - v19.uIndex = a2; - v19.vPosition.y = fixpoint_mul(stru_5C6E00->Sin(v7), v6) + pParty->vPosition.y; - v19.vPosition.z = pParty->vPosition.z; - v26 = 0; - v27 = 0; - v19.vPosition.z = ODM_GetFloorLevel(v19.vPosition.x, v19.vPosition.y, pParty->vPosition.z, 0, &v26, &v27, 0); - for( int i = 0; i < pOutdoor->uNumBModels; i++ ) - { - v9 = abs(v19.vPosition.y - pOutdoor->pBModels[i].vBoundingCenter.y); - v10 = abs(v19.vPosition.x - pOutdoor->pBModels[i].vBoundingCenter.x); - if ( int_get_vector_length(v10, v9, 0) < pOutdoor->pBModels[i].sBoundingRadius + 256 ) - { - v22 = 1; - break; - } - } - if ( v22 ) - { - v11 = face_id == 100; - break; - } - } - v11 = face_id == 100; - } - else if ( uCurrentlyLoadedLevelType == LEVEL_Indoor ) - { - v22 = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z); - for ( uint i = 0; i < 100; ++i ) - { - v12 = rand() % 512 + 256; - v13 = rand(); - v14 = v13 % (signed int)stru_5C6E00->uIntegerDoublePi; - v15 = stru_5C6E00->Cos(v13 % (signed int)stru_5C6E00->uIntegerDoublePi); - v19.vPosition.x = pParty->vPosition.x + fixpoint_mul(v15, v12); - v16 = stru_5C6E00->Sin(v13 % (signed int)stru_5C6E00->uIntegerDoublePi); - v19.vPosition.y = fixpoint_mul(v16, v12) + pParty->vPosition.y; - v19.vPosition.z = pParty->vPosition.z; - v19.uIndex = a2; - v17 = pIndoor->GetSector(v19.vPosition.x, v19.vPosition.y, pParty->vPosition.z); - if ( v17 == v22 ) - { - v18 = BLV_GetFloorLevel(v19.vPosition.x, v19.vPosition.y, v19.vPosition.z, v17, &uFaceID); - v19.vPosition.z = v18; - if ( v18 != -30000 ) - { - if ( abs(v18 - pParty->vPosition.z) <= 1024 ) - break; - } - } - } - v11 = v26 == 100; - } - if ( v11 ) - result = 0; - else - { - SpawnEncounter(a1, &v19, 0, 0, 1); - result = a2; - } - } - - //break; - //v22 = v3->pMonsterInfo.uID - 1; - //v4 = (signed __int64)((double)v22 * 0.3333333333333333); - //if ( (int)v4 != 40 ) - //{ - // if ( (int)v4 != 41 && (int)v4 != 44 && v3->CanAct() ) - // break; - //} - //++v2; - //++v3; - //if ( v2 >= (signed int)uNumActors ) - // goto LABEL_8; - } - return result; -} - -//----- (00450521) -------------------------------------------------------- -int __fastcall sub_450521_ProllyDropItemAt(int ecx0, signed int a2, int a3, int a4, int a5, unsigned __int16 a6) -{ - int v6; // edi@1 - int v7; // esi@1 - signed int v8; // edi@1 - unsigned __int16 v9; // cx@1 - // char *v10; // edx@2 - unsigned __int16 v11; // ax@5 - SpriteObject a1; // [sp+8h] [bp-70h]@1 - - v6 = ecx0; - v7 = a2; - pItemsTable->GenerateItem(v6, v7, &a1.stru_24); - v8 = 0; - v9 = pItemsTable->pItems[a1.stru_24.uItemID].uSpriteID; - a1.uType = pItemsTable->pItems[a1.stru_24.uItemID].uSpriteID; - v11 = 0; - for( int i = 0; i < pObjectList->uNumObjects; i++ ) - { - if( v9 == pObjectList->pObjects[i].uObjectID ) - { - v11 = i; - break; - } - } - a1.uObjectDescID = v11; - a1.vPosition.y = a4; - a1.vPosition.x = a3; - a1.vPosition.z = a5; - a1.uFacing = a6; - a1.uAttributes = 0; - a1.uSectorID = pIndoor->GetSector(a3, a4, a5); - a1.uSpriteFrameID = 0; - return a1.Create(0, 0, 0, 0); -} - -//----- (004075DB) -------------------------------------------------------- -bool __fastcall sub_4075DB(int x, int y, int z, BLVFace *face) -{ - int v8; // edi@2 - signed int v25; // eax@22 - bool result; // eax@25 - signed int a3a; // [sp+24h] [bp+8h]@14 - int a4a; // [sp+28h] [bp+Ch]@2 - - std::array dword_4F5CC8_ys; // idb - std::array dword_4F5D98_xs; // idb - - //__debugbreak(); - - if (face->uAttributes & FACE_XY_PLANE) - { - a4a = x; - v8 = y; - for (int i = 0; i < face->uNumVertices; i++) - { - dword_4F5D98_xs[i] = pIndoor->pVertices[face->pVertexIDs[i]].x; - dword_4F5CC8_ys[i] = pIndoor->pVertices[face->pVertexIDs[i]].y; - } - } - else - { - v8 = z; - if (face->uAttributes & FACE_XZ_PLANE) - { - a4a = x; - for (int i = 0; i < face->uNumVertices; i++) - { - dword_4F5D98_xs[i] = pIndoor->pVertices[face->pVertexIDs[i]].x; - dword_4F5CC8_ys[i] = pIndoor->pVertices[face->pVertexIDs[i]].z; - } - } - else - { - a4a = y; - for (int i = 0; i < face->uNumVertices; i++) - { - dword_4F5D98_xs[i] = pIndoor->pVertices[face->pVertexIDs[i]].y; - dword_4F5CC8_ys[i] = pIndoor->pVertices[face->pVertexIDs[i]].z; - } - } - } - a3a = 0; - dword_4F5D98_xs[face->uNumVertices] = dword_4F5D98_xs[0]; - dword_4F5CC8_ys[face->uNumVertices] = dword_4F5CC8_ys[0]; - for (int i = 0; i < face->uNumVertices && a3a < 2; i++) - { - if (dword_4F5CC8_ys[i] >= v8 ^ (dword_4F5CC8_ys[i + 1] >= v8)) - { - //if( dword_4F5D98_xs[i + 1] >= a4a || dword_4F5D98_xs[i] >= a4a) - if (!(dword_4F5D98_xs[i + 1] >= a4a && dword_4F5D98_xs[i] < a4a)) - { - if ((dword_4F5D98_xs[i + 1] < a4a && dword_4F5D98_xs[i] >= a4a)) - ++a3a; - //|| (v25 = dword_4F5D98_xs[i + 1] - dword_4F5D98_xs[i],LODWORD(v26) = v25 << 16, HIDWORD(v26) = v25 >> 16, - //dword_4F5D98_xs[i] + ((signed int)(((unsigned __int64)(v26 / (dword_4F5CC4_ys[i + 2] - dword_4F5CC4_ys[i + 1])* ((v8 - dword_4F5CC4_ys[i + 1]) << 16)) >> 16) - // + 32768) >> 16) >= a4a) ) - else - { - v25 = fixpoint_div(dword_4F5D98_xs[i + 1] - dword_4F5D98_xs[i], dword_4F5CC8_ys[i + 1] - dword_4F5CC8_ys[i]); - if (dword_4F5D98_xs[i] + (fixpoint_mul(v25, (v8 - dword_4F5CC8_ys[i]) << 16) + 0x8000 >> 16) >= a4a) - ++a3a; - } - } - } - } - result = 1; - if (a3a != 1) - result = 0; - return result; -} - -//----- (004077F1) -------------------------------------------------------- -bool __fastcall sub_4077F1(int a1, int a2, int a3, ODMFace *face, BSPVertexBuffer *a5) -{ - int a4a; // [sp+28h] [bp+Ch]@2 - signed int a5a; // [sp+2Ch] [bp+10h]@14 - - std::array dword_4F5B24_ys; // idb - std::array dword_4F5BF4_xs; // idb - - //__debugbreak(); //срабатывает при нападении стрекозавров с огнём - - if (face->uAttributes & FACE_XY_PLANE) - { - a4a = a1; - a3 = a2; - for (int i = 0; i < face->uNumVertices; i++) - { - dword_4F5BF4_xs[i + 1] = a5->pVertices[face->pVertexIDs[i]].x; - dword_4F5B24_ys[i + 1] = a5->pVertices[face->pVertexIDs[i]].y; - } - } - else - { - if (face->uAttributes & FACE_XY_PLANE) - { - a4a = a1; - for (int i = 0; i < face->uNumVertices; i++) - { - dword_4F5BF4_xs[i + 1] = a5->pVertices[face->pVertexIDs[i]].x; - dword_4F5B24_ys[i + 1] = a5->pVertices[face->pVertexIDs[i]].z; - } - } - else - { - a4a = a2; - for (int i = 0; i < face->uNumVertices; i++) - { - dword_4F5BF4_xs[i + 1] = a5->pVertices[face->pVertexIDs[i]].y; - dword_4F5B24_ys[i + 1] = a5->pVertices[face->pVertexIDs[i]].z; - } - } - } - a5a = 0; - dword_4F5BF4_xs[face->uNumVertices + 1] = dword_4F5BF4_xs[1]; - dword_4F5B24_ys[face->uNumVertices + 1] = dword_4F5B24_ys[1]; - for (int i = 0; i < face->uNumVertices; i++) - { - if (a5a >= 2) - break; - if (dword_4F5B24_ys[i + 1] >= a3 ^ (dword_4F5B24_ys[i + 2] >= a3)) - { - if (dword_4F5BF4_xs[i + 2] >= a4a || dword_4F5BF4_xs[i] >= a4a) - { - if (dword_4F5BF4_xs[i + 2] >= a4a && dword_4F5BF4_xs[i + 1] >= a4a) - ++a5a; - else - { - //v23 = (__int64)(dword_4F5BF4_xs[i + 2] - dword_4F5BF4_xs[i + 1]) << 16; - __int64 _a = dword_4F5B24_ys[i + 2] - dword_4F5B24_ys[i + 1]; - __int64 _b = (__int64)(a3 - dword_4F5B24_ys[i + 1]) << 16; - - if (dword_4F5BF4_xs[i + 1] + ((((((__int64)(dword_4F5BF4_xs[i + 2] - dword_4F5BF4_xs[i + 1]) << 16) / _a * _b) >> 16) + 0x8000) >> 16) >= a4a) - ++a5a; - } - } - } - } - - if (a5a != 1) - return false; - return true; - -} - -//----- (0049B04D) -------------------------------------------------------- -void stru154::GetFacePlaneAndClassify(ODMFace *a2, BSPVertexBuffer *a3) -{ - Vec3_float_ v; // [sp+4h] [bp-Ch]@1 - float v7; - - v.x = 0.0; - v.y = 0.0; - v.z = 0.0; - GetFacePlane(a2, a3, &v, &v7); - - if (fabsf(a2->pFacePlane.vNormal.z) < 1e-6f) - polygonType = POLYGON_VerticalWall; - else if (fabsf(a2->pFacePlane.vNormal.x) < 1e-6f && - fabsf(a2->pFacePlane.vNormal.y) < 1e-6f) - polygonType = POLYGON_Floor; - else - polygonType = POLYGON_InBetweenFloorAndWall; - - face_plane.vNormal.x = v.x; - face_plane.vNormal.y = v.y; - face_plane.vNormal.z = v.z; - face_plane.dist = v7; -} - -//----- (0049B0C9) -------------------------------------------------------- -void stru154::ClassifyPolygon(Vec3_float_ *pNormal, float dist) -{ - if (fabsf(pNormal->z) < 1e-6f) - polygonType = POLYGON_VerticalWall; - else if (fabsf(pNormal->x) < 1e-6f && - fabsf(pNormal->y) < 1e-6f) - polygonType = POLYGON_Floor; - else - polygonType = POLYGON_InBetweenFloorAndWall; - - face_plane.vNormal.x = pNormal->x; - face_plane.dist = dist; - face_plane.vNormal.y = pNormal->y; - face_plane.vNormal.z = pNormal->z; -} - -//----- (0049B13D) -------------------------------------------------------- -void stru154::GetFacePlane(ODMFace *pFace, BSPVertexBuffer *pVertices, Vec3_float_ *pOutNormal, float *pOutDist) -{ - Vec3_float_ *v19; // eax@3 - Vec3_float_ v2; // [sp+4h] [bp-64h]@3 - float v26; // [sp+1Ch] [bp-4Ch]@3 - float v27; // [sp+20h] [bp-48h]@3 - float v28; // [sp+24h] [bp-44h]@3 - Vec3_float_ v1; // [sp+40h] [bp-28h]@1 - Vec3_float_ v38; // [sp+58h] [bp-10h]@3 - - v1.x = 0.0; - v1.y = 0.0; - v1.z = 0.0; - - if (pFace->uNumVertices >= 2) - { - for (int i = 0; i < pFace->uNumVertices - 2; i++) - { - v1.x = pVertices->pVertices[pFace->pVertexIDs[i + 1]].x - pVertices->pVertices[pFace->pVertexIDs[i]].x; - v1.y = pVertices->pVertices[pFace->pVertexIDs[i + 1]].y - pVertices->pVertices[pFace->pVertexIDs[i]].y; - v1.z = pVertices->pVertices[pFace->pVertexIDs[i + 1]].z - pVertices->pVertices[pFace->pVertexIDs[i]].z; - - v26 = pVertices->pVertices[pFace->pVertexIDs[i + 2]].x - pVertices->pVertices[pFace->pVertexIDs[i + 1]].x; - v27 = pVertices->pVertices[pFace->pVertexIDs[i + 2]].y - pVertices->pVertices[pFace->pVertexIDs[i + 1]].y; - v28 = pVertices->pVertices[pFace->pVertexIDs[i + 2]].z - pVertices->pVertices[pFace->pVertexIDs[i + 1]].z; - - v19 = Vec3_float_::Cross(&v1, &v2, v26, v27, v28); - v38.x = v19->x; - v38.y = v19->y; - v38.z = v19->z; - if (v38.x != 0.0 || v38.y != 0.0 || v38.z != 0.0) - { - v38.Normalize(); - - pOutNormal->x = v38.x; - pOutNormal->y = v38.y; - pOutNormal->z = v38.z; - - *pOutDist = -(pVertices->pVertices[pFace->pVertexIDs[i]].x * v38.x - + pVertices->pVertices[pFace->pVertexIDs[i]].y * v38.y - + pVertices->pVertices[pFace->pVertexIDs[i]].z * v38.z); - return; - } - } - } - - pOutNormal->x = (double)(pFace->pFacePlane.vNormal.x & 0xFFFF) / 65535.0f + (double)(pFace->pFacePlane.vNormal.x >> 16); - pOutNormal->y = (double)(pFace->pFacePlane.vNormal.y & 0xFFFF) / 65535.0f + (double)(pFace->pFacePlane.vNormal.y >> 16); - pOutNormal->z = (double)(pFace->pFacePlane.vNormal.z & 0xFFFF) / 65535.0f + (double)(pFace->pFacePlane.vNormal.z >> 16); - *pOutDist = (double)(pFace->pFacePlane.dist & 0xFFFF) / 65535.0f + (double)(pFace->pFacePlane.dist >> 16); -} - -//----- (0043F515) -------------------------------------------------------- -void FindBillboardsLightLevels_BLV() -{ - for (uint i = 0; i < uNumBillboardsToDraw; ++i) - { - if (pBillboardRenderList[i].field_1E & 2 || uCurrentlyLoadedLevelType == LEVEL_Indoor && !pBillboardRenderList[i].uIndoorSectorID) - pBillboardRenderList[i].dimming_level = 0; - else - pBillboardRenderList[i].dimming_level = _43F55F_get_billboard_light_level(&pBillboardRenderList[i], -1); - } -} - -//----- (0047272C) -------------------------------------------------------- -int collide_against_floor_approximate(int x, int y, int z, unsigned int *pSectorID, unsigned int *pFaceID) -{ - int result; // eax@1 - - *pSectorID = pIndoor->GetSector(x - 2, y, z + 40); - result = collide_against_floor(x - 2, y, z + 40, pSectorID, pFaceID); - if (result == -30000 || !*pSectorID) - { - *pSectorID = pIndoor->GetSector(x + 2, y, z + 40); - result = collide_against_floor(x + 2, y, z + 40, pSectorID, pFaceID); - if (result == -30000 || !*pSectorID) - { - *pSectorID = pIndoor->GetSector(x, y - 2, z + 40); - result = collide_against_floor(x, y - 2, z + 40, pSectorID, pFaceID); - if (result == -30000 || !*pSectorID) - { - *pSectorID = pIndoor->GetSector(x, y + 2, z + 40); - result = collide_against_floor(x, y + 2, z + 40, pSectorID, pFaceID); - if (result == -30000 || !*pSectorID) - { - *pSectorID = pIndoor->GetSector(x, y, z + 140); - result = collide_against_floor(x, y, z + 140, pSectorID, pFaceID); - } - } - } - } - return result; -} - -//----- (0047050A) -------------------------------------------------------- -int stru141_actor_collision_object::_47050A(int dt) -{ - int v7; // eax@1 - signed int result; // eax@4 - int v17; // eax@5 - int v18; // eax@7 - int v21; // eax@9 - int v22; // eax@11 - - int speed = 1 | integer_sqrt(this->velocity.z * this->velocity.z + this->velocity.y * this->velocity.y + this->velocity.x * this->velocity.x); - - this->direction.x = 65536 / speed * this->velocity.x; - this->direction.y = 65536 / speed * this->velocity.y; - this->direction.z = 65536 / speed * this->velocity.z; - - this->speed = speed; - this->inv_speed = 65536 / speed; - - if (dt) - v7 = dt; - else - v7 = pEventTimer->dt_in_some_format; - - //v8 = fixpoint_mul(v7, speed) - this->field_70; // speed * dt - something - this->field_6C = fixpoint_mul(v7, speed) - this->field_70; - if (this->field_6C > 0) - { - //v10 = fixpoint_mul(v8, this->direction.x) + this->normal.x; - this->field_4C = fixpoint_mul(this->field_6C, this->direction.x) + this->normal.x; - this->normal2.x = fixpoint_mul(this->field_6C, this->direction.x) + this->normal.x; - //v11 = fixpoint_mul(this->field_6C, this->direction.y) + this->normal.y; - this->field_50 = fixpoint_mul(this->field_6C, this->direction.y) + this->normal.y; - this->normal2.y = fixpoint_mul(this->field_6C, this->direction.y) + this->normal.y; - this->normal2.z = fixpoint_mul(this->field_6C, this->direction.z) + this->normal.z; - //v12 = this->position.z; - //v13 = this->normal.x; - //v14 = this->normal2.x; - //v15 = this->prolly_normal_d; - //v16 = this->position.z + fixpoint_mul(this->field_6C, this->direction.z); - //v28 = this->position.z + fixpoint_mul(this->field_6C, this->direction.z); - this->field_54 = this->position.z + fixpoint_mul(this->field_6C, this->direction.z); - v17 = this->normal.x; - if (v17 >= this->normal2.x) - v17 = this->normal2.x; - this->sMaxX = v17 - this->prolly_normal_d; - v18 = this->prolly_normal_d + this->normal.x; - if (this->normal.x <= this->normal2.x) - v18 = this->prolly_normal_d + this->normal2.x; - //v19 = this->normal.y; - //v20 = this->normal2.y; - this->sMinX = v18; - v21 = this->normal.y; - if (v21 >= this->normal2.y) - v21 = this->normal2.y; - this->sMaxY = v21 - this->prolly_normal_d; - v22 = this->prolly_normal_d + this->normal.y; - if (this->normal.y <= this->normal2.y) - v22 = this->normal2.y + this->prolly_normal_d; - //v23 = this->normal2.z; - this->sMinY = v22; - //v24 = this->normal.z; - if (this->normal.z >= this->normal2.z) - this->sMaxZ = this->normal2.z - this->prolly_normal_d; - else - this->sMaxZ = this->normal.z - this->prolly_normal_d; - //this->sMaxZ = v25; - //v26 = this->field_8_radius; - if (this->position.z <= this->position.z + fixpoint_mul(this->field_6C, this->direction.z)) - this->sMinZ = (this->position.z + fixpoint_mul(this->field_6C, this->direction.z)) + this->field_8_radius; - else - this->sMinZ = this->position.z + this->field_8_radius; - this->uFaceID = 0; - this->field_80 = -1; - this->field_88 = -1; - //this->sMinZ = v27; - this->field_7C = 0xFFFFFFu; - result = 0; - } - else - result = 1; - return result; -} diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Indoor.h --- a/Indoor.h Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,921 +0,0 @@ -#pragma once -#include - -#include "Render.h" -#include "IndoorCameraD3D.h" -#include "mm7_data.h" - -/* 358 */ -#pragma pack(push, 1) -struct stru320 -{ - int field_0; - Plane_int_ plane_4; - Vec3_int_ vec_14; - Vec3_int_ vec_20; - unsigned int uCurrentAmbientLightLevel; - int field_30; - int field_34; - int field_38; - int pDeltaUV[2]; - int field_44; - int field_48; - char field_4C[8]; - Vec3_int_ rotated_normal; - Vec3_int_ vec_60; - int field_6C; - Vec3_int_ vec_70; - int field_7C; - Vec3_int_ vec_80; - Vec3_int_ vec_8C; - int field_98; - Vec3_int_ vec_9C; - int field_A8; - unsigned int uNumLightsApplied; - int _blv_lights_radii[20]; - int _blv_lights_inv_radii[20]; - int _blv_lights_xs[20]; - int _blv_lights_ys[20]; - int _blv_lights_light_dot_faces[20]; - int field_240; - int field_244; - int field_248; - int field_24C; - int field_250; - int field_254; - int field_258; - int field_25C; - int field_260; - int field_264; - int field_268; - int field_26C; - int field_270; - int field_274; - int field_278; - int field_27C; - int field_280; - int field_284; - int field_288; - int field_28C; - int _blv_lights_zs[20]; - float _blv_lights_rs[20]; - float _blv_lights_gs[20]; - float _blv_lights_bs[20]; - char _blv_lights_types[20]; - int field_3E4; - int field_3E8; - int field_3EC; - int field_3F0; - int field_3F4; - unsigned int uDefaultAmbientLightLevel; -}; -#pragma pack(pop) - -extern stru320 stru_F8AD28; // idb - - - - - - - - -/* 345 */ -#pragma pack(push, 1) -struct stru315 -{ - int field_0; - int field_4; - int field_8; - int field_C; - int field_10; - int field_14; - int field_18; - int field_1C; - int field_20; - int field_24; - int field_28; - int field_2C; - int field_30; - unsigned __int16 *field_34_palette; - unsigned __int16 *pTextureLOD; - unsigned int *pDepthBuffer; - unsigned __int16 *pColorBuffer; -}; -#pragma pack(pop) - - - - - -/* 346 */ -#pragma pack(push, 1) -struct stru316 -{ - int field_0; - int field_4; - int field_8; - int field_C; - int field_10; - int field_14; - int field_18; - int field_1C; - int field_20; - unsigned __int16 *field_24_palette; -}; -#pragma pack(pop) - - - - - - -/* 134 */ -#pragma pack(push, 1) -struct stru141_actor_collision_object -{ - int _47050A(int a2); - - int field_0; - int prolly_normal_d; - int field_8_radius; - int height; - int field_10; - int field_14; - int field_18; - Vec3_int_ velocity; - Vec3_int_ normal; - Vec3_int_ position; - Vec3_int_ normal2; - int field_4C; - int field_50; - int field_54; - Vec3_int_ direction; // velocity's unit vector - int speed; - int inv_speed; - int field_6C; - int field_70; - unsigned int uSectorID; - unsigned int uFaceID; - int field_7C; - int field_80; - int field_84; - int field_88; - int sMaxX; - int sMinX; - int sMaxY; - int sMinY; - int sMaxZ; - int sMinZ; - int field_A4; -}; -#pragma pack(pop) -extern stru141_actor_collision_object stru_721530; - - - - - - -/* 378 */ -#pragma pack(push, 1) -struct stru337_stru0 -{ - int field_0; - int field_4; - int field_8; - int field_C; - int field_10; -}; -#pragma pack(pop) - - - -/* 377 */ -#pragma pack(push, 1) -struct stru337 -{ - stru337_stru0 field_0; - int field_14; - int field_18; - int field_1C; - int field_20; - int field_24; - int field_28; - int field_2C; - int field_30; - stru337_stru0 field_34; -}; -#pragma pack(pop) -extern stru337 stru_F81018; - - -/* 291 */ -enum PolygonType : __int8 -{ - POLYGON_Invalid = 0x0, - POLYGON_VerticalWall = 0x1, - POLYGON_unk = 0x2, - POLYGON_Floor = 0x3, - POLYGON_InBetweenFloorAndWall = 0x4, - POLYGON_Ceiling = 0x5, - POLYGON_InBetweenCeilingAndWall = 0x6, -}; - - -/* 147 */ -#pragma pack(push, 1) - -struct stru154 -{ - //----- (0049B001) -------------------------------------------------------- - inline stru154() - {} - - //----- (0049B027) -------------------------------------------------------- - inline ~stru154() - {} - - void GetFacePlaneAndClassify(struct ODMFace *a2, struct BSPVertexBuffer *a3); - void ClassifyPolygon(struct Vec3_float_ *pNormal, float dist); - void GetFacePlane(struct ODMFace *pFace, struct BSPVertexBuffer *pVertices, struct Vec3_float_ *pOutNormal, float *pOutDist); - - - void(***vdestructor_ptr)(stru154 *, bool); - Plane_float_ face_plane; - PolygonType polygonType; - char field_15; - char field_16; - char field_17; -}; -#pragma pack(pop) - - - - - -/* 392 */ -#pragma pack(push, 1) -struct stru352 -{ - int field_0; - int field_4; - int field_8; - int field_C; - int field_10; - int field_14; - int field_18; - int field_1C; - int field_20; - int field_24; - int field_28; - int field_2C; - int field_30; - int field_34; -}; -#pragma pack(pop) -//extern std::array stru_F83B80; - -#pragma pack(push, 1) -struct LocationTime_stru1 -{ - unsigned __int64 uLastVisitDay; - char sky_texture_name[12]; - int day_attrib; - int day_fogrange_1; - int day_fogrange_2; - char field_2F4[24]; -}; -#pragma pack(pop) - -/* 319 */ -enum LEVEL_TYPE -{ - LEVEL_null = 0, - LEVEL_Indoor = 0x1, - LEVEL_Outdoor = 0x2, -}; -extern LEVEL_TYPE uCurrentlyLoadedLevelType; - - - - - - - - - - - - - -/* 86 */ -#pragma pack(push, 1) -struct SpawnPointMM6 -{ - Vec3_int_ vPosition; - unsigned __int16 uRadius; - unsigned __int16 uKind; - unsigned __int16 uIndex; - unsigned __int16 uAttributes; -}; -#pragma pack(pop) - - - -/* 102 */ -#pragma pack(push, 1) -struct SpawnPointMM7 -{ - //----- (00448DD6) -------------------------------------------------------- - SpawnPointMM7() - { - uRadius = 32; - uAttributes = 0; - uIndex = 0; - uKind = 0; - uGroup = 0; - } - - - Vec3_int_ vPosition; - unsigned __int16 uRadius; - unsigned __int16 uKind; - unsigned __int16 uIndex; - unsigned __int16 uAttributes; - unsigned int uGroup; -}; -#pragma pack(pop) - - - - - - -/* 90 */ -#pragma pack(push, 1) -struct BLVHeader -{ - char field_0[104]; - unsigned int uFaces_fdata_Size; - unsigned int uSector_rdata_Size; - unsigned int uSector_lrdata_Size; - unsigned int uDoors_ddata_Size; - char field_78[16]; -}; -#pragma pack(pop) - - - -/* 96 */ -#pragma pack(push, 1) -struct BLVSectorMM8 -{ - int dword_000074; -}; -#pragma pack(pop) - -/* 97 */ -#pragma pack(push, 1) -struct BLVLightMM6 -{ - Vec3_short_ vPosition; - __int16 uRadius; - __int16 uAttributes; - unsigned __int16 uBrightness; -}; -#pragma pack(pop) - -/* 98 */ -#pragma pack(push, 1) -struct BLVLightMM7 //10h -{ - struct Vec3_short_ vPosition; - __int16 uRadius; - char uRed; - char uGreen; - char uBlue; - char uType; - __int16 uAtributes; // & 0x08 doesn't light faces - __int16 uBrightness; -}; -#pragma pack(pop) - -/* 99 */ -#pragma pack(push, 1) -struct BLVLightMM8 -{ - int uID; -}; -#pragma pack(pop) - - - -/* 100 */ -#pragma pack(push, 1) -struct BLVDoor //50h -{ - enum State: unsigned __int16 - { - Closed = 0, - Opening = 1, - Open = 2, - Closing = 3 - }; - - unsigned int uAttributes; - unsigned int uDoorID; - unsigned int uTimeSinceTriggered; - Vec3_int_ vDirection; - int uMoveLength; - int uOpenSpeed; - int uCloseSpeed; - unsigned __int16 *pVertexIDs; - unsigned __int16 *pFaceIDs; - unsigned __int16 *pSectorIDs; - __int16 *pDeltaUs; - __int16 *pDeltaVs; - unsigned __int16 *pXOffsets; - unsigned __int16 *pYOffsets; - unsigned __int16 *pZOffsets; - unsigned __int16 uNumVertices; - unsigned __int16 uNumFaces; - __int16 field_48; - unsigned __int16 uNumOffsets; - State uState; - __int16 field_4E; -}; -#pragma pack(pop) - -/* 101 */ -#pragma pack(push, 1) -struct BLVMapOutline //0C -{ - unsigned __int16 uVertex1ID; - unsigned __int16 uVertex2ID; - unsigned __int16 uFace1ID; - unsigned __int16 uFace2ID; - __int16 sZ; - unsigned __int16 uFlags; -}; -#pragma pack(pop) - - -#define FACE_PORTAL 0x00000001 // portal/two-sided -#define FACE_CAN_SATURATE_COLOR 0x00000002 -#define FACE_FLOW_DIAGONAL 0x00000004 // Diagonal flow of the lava or water -#define FACE_UNKNOW5 0x00000006 -#define FACE_UNKNOW6 0x00000008 -#define FACE_FLUID 0x00000010 // wavy animated water or lava -#define FACE_FLOW_VERTICAL 0x00000020 // Vertical flow of the lava or water -#define FACE_DONT_CACHE_TEXTURE 0x00000040 // do not load face texture if it isn't loaded already -#define FACE_UNKNOW4 0x00000080 -#define FACE_XY_PLANE 0x00000100 -#define FACE_XZ_PLANE 0x00000200 -#define FACE_YZ_PLANE 0x00000400 -#define FACE_FLOW_HORIZONTAL 0x00000800 // Horizontal flow of the lava or water -#define FACE_HAS_EVENT_HINT 0x00001000 -#define FACE_INVISIBLE 0x00002000 -#define FACE_TEXTURE_FRAME 0x00004000 // Texture ID is a frameset from TextureFrameTable, otherwise BitmapID -#define FACE_OUTLINED 0x00010000 // outline face edges -#define FACE_INDOOR_DOOR 0x00020000 -#define FACE_TEXTURE_FLOW 0x00040000 // The texture moves slowly. For horizontal facets only. -#define FACE_HAS_EVENT 0x00100000 -#define FACE_INDOOR_CARPET 0x00200000 -#define FACE_INDOOR_SKY 0x00400000 -#define FACE_UNKNOW3 0x00800000 -#define FACE_UNKNOW4 0x01000000 -#define FACE_CLICKABLE 0x02000000 // Event can be triggered by clicking on the facet. -#define FACE_PRESSURE_PLATE 0x04000000 // Event can be triggered by stepping on the facet. -#define FACE_INDICATE 0x06000000 // Event can be triggered by indicating on the facet. -#define FACE_UNKNOW1 0x08000000 -#define FACE_UNKNOW2 0x10000000 -#define FACE_ETHEREAL 0x20000000 // Untouchable. You can pass through it. -#define FACE_INDOOR_LAVA 0x40000000 -#define FACE_PICKED 0x80000000 - -/* 93 */ -#pragma pack(push, 1) -struct BLVFace //60h -{ - //----- (0046ED02) -------------------------------------------------------- - inline BLVFace() - { - this->uNumVertices = 0; - this->uAttributes = 0; - this->uFaceExtraID = 0; - this->pVertexIDs = nullptr; - this->pZInterceptDisplacements = nullptr; - this->pYInterceptDisplacements = nullptr; - this->pXInterceptDisplacements = nullptr; - } - - void _get_normals(Vec3_int_ *a2, Vec3_int_ *a3); - struct Texture *GetTexture(); - void FromODM(struct ODMFace *face); - - inline bool Invisible() const {return (uAttributes & FACE_INVISIBLE) != 0;} - inline bool Visible() const {return !Invisible();} - inline bool Portal() const {return (uAttributes & FACE_PORTAL) != 0;} - inline bool Fluid() const {return (uAttributes & FACE_FLUID) != 0;} - inline bool Indoor_sky() const {return (uAttributes & FACE_INDOOR_SKY) != 0;} - inline bool Clickable() const {return (uAttributes & FACE_CLICKABLE) != 0;} - inline bool Pressure_Plate() const {return (uAttributes & FACE_PRESSURE_PLATE) != 0;} - inline bool Ethereal() const {return (uAttributes & FACE_ETHEREAL) != 0;} - - struct Plane_float_ pFacePlane; - struct Plane_int_ pFacePlane_old; - int zCalc1; - int zCalc2; - int zCalc3; - unsigned int uAttributes; - unsigned __int16 *pVertexIDs; - signed __int16 *pXInterceptDisplacements; - signed __int16 *pYInterceptDisplacements; - signed __int16 *pZInterceptDisplacements; - signed __int16 *pVertexUIDs; - signed __int16 *pVertexVIDs; - unsigned __int16 uFaceExtraID; - unsigned __int16 uBitmapID; - unsigned __int16 uSectorID; - __int16 uBackSectorID; - struct BBox_short_ pBounding; - PolygonType uPolygonType; - unsigned __int8 uNumVertices; - char field_5E; - char field_5F; -}; -#pragma pack(pop) - -/* 94 */ -#pragma pack(push, 1) -struct BLVFaceExtra //24h -{ -bool HasEventint(); - - __int16 field_0; - __int16 field_2; - __int16 field_4; - __int16 field_6; - __int16 field_8; - __int16 field_A; - __int16 field_C; - unsigned __int16 uAdditionalBitmapID; - __int16 field_10; - __int16 field_12; - __int16 sTextureDeltaU; - __int16 sTextureDeltaV; - __int16 sCogNumber; - unsigned __int16 uEventID; - __int16 field_1C; - __int16 field_1E; - __int16 field_20; - __int16 field_22; -}; -#pragma pack(pop) - -/* 95 */ -#pragma pack(push, 1) -struct BLVSector //0x74 -{ - int field_0; - unsigned __int16 uNumFloors; - __int16 field_6; - unsigned __int16 *pFloors; - unsigned __int16 uNumWalls; - __int16 field_E; - unsigned __int16 *pWalls; - unsigned __int16 uNumCeilings; - __int16 field_16; - unsigned __int16 *pCeilings; - unsigned __int16 uNumFluids; - __int16 field_1E; - unsigned __int16 *pFluids; - __int16 uNumPortals; - __int16 field_26; - unsigned __int16 *pPortals; - unsigned __int16 uNumFaces; - unsigned __int16 uNumNonBSPFaces; - unsigned __int16 *pFaceIDs; - unsigned __int16 uNumCylinderFaces; - __int16 field_36; - int pCylinderFaces; - unsigned __int16 uNumCogs; - __int16 field_3E; - unsigned __int16 *pCogs; - unsigned __int16 uNumDecorations; - __int16 field_46; - unsigned __int16 *pDecorationIDs; - unsigned __int16 uNumMarkers; - __int16 field_4E; - unsigned __int16 *pMarkers; - unsigned __int16 uNumLights; - __int16 field_56; - unsigned __int16 *pLights; - __int16 uWaterLevel; - __int16 uMistLevel; - __int16 uLightDistanceMultiplier; - __int16 uMinAmbientLightLevel; - __int16 uFirstBSPNode; - __int16 exit_tag; - BBox_short_ pBounding; -}; -#pragma pack(pop) - - -#pragma pack(push, 1) -struct BLVMapOutlines -{ - int uNumOutlines; - BLVMapOutline pOutlines[7000]; -}; -#pragma pack(pop) - - - - - - - -/* 89 */ -#pragma pack(push, 1) -struct IndoorLocation -{ - //----- (00462592) -------------------------------------------------------- - inline IndoorLocation() - { - bLoaded = 0; - ptr_0002B8_sector_lrdata = 0; - ptr_0002B4_doors_ddata = 0; - ptr_0002B0_sector_rdata = 0; - pLFaces = 0; - pVertices = 0; - pFaces = 0; - pFaceExtras = 0; - pSectors = 0; - pLights = 0; - pDoors = 0; - pNodes = 0; - pMapOutlines = 0; - uNumSpawnPoints = 0; - pSpawnPoints = 0; - uNumSectors = 0; - } - - int GetSector(int sX, int sY, int sZ); - void Release(); - bool Alloc(); - bool Load(char *pFilename, int a3, size_t i, char *pDest); - void Draw(); - void ToggleLight(signed int uLightID, unsigned int bToggle); - - static unsigned int GetLocationIndex(const char *Str1); - static void ExecDraw(bool bD3D); - //static void ExecDraw_sw(unsigned int uFaceID); - static void ExecDraw_d3d(unsigned int uFaceID, struct IndoorCameraD3D_Vec4 *pVertices, unsigned int uNumVertices, struct RenderVertexSoft *pPortalBounding); - - char pFilename[32]; - char field_20[48]; - unsigned int bLoaded; - char field_54[404]; - struct BLVHeader blv; - unsigned int uNumVertices; - struct Vec3_short_ *pVertices; - unsigned int uNumFaces; - struct BLVFace *pFaces; - unsigned int uNumFaceExtras; - struct BLVFaceExtra *pFaceExtras; - int uNumSectors; - struct BLVSector *pSectors; - int uNumLights; - struct BLVLightMM7 *pLights; - int uNumDoors; - struct BLVDoor *pDoors; - unsigned int uNumNodes; - struct BSPNode *pNodes; - BLVMapOutlines *pMapOutlines; - unsigned __int16 *pLFaces; - unsigned __int16 *ptr_0002B0_sector_rdata; - unsigned __int16 *ptr_0002B4_doors_ddata; - unsigned __int16 *ptr_0002B8_sector_lrdata; - unsigned int uNumSpawnPoints; - struct SpawnPointMM7 *pSpawnPoints; - struct DDM_DLV_Header dlv; - LocationTime_stru1 stru1; - char _visible_outlines[875]; - char padding; -}; -#pragma pack(pop) - -extern IndoorLocation *pIndoor; - - - - - - - - - - - - - -/* 162 */ -#pragma pack(push, 1) -struct BLVRenderParams -{ - inline BLVRenderParams() - { - uViewportX = 0; - uViewportY = 0; - uViewportZ = 0; - uViewportW = 0; - } - - void Reset(); - - int field_0_timer_; - int _unused_uFlags; // & INDOOR_CAMERA_DRAW_D3D_OUTLINES: render d3d outlines - Vec3_int_ _unused_vPartyPos; - int _unused_sPartyRotY; - int _unused_sPartyRotX; - int uPartySectorID; - int _unused_sCosineY; // matches ODMRenderParams::int sines and cosines - int _unused_sSineY; // computed in 0048600E - int _unused_sCosineNegX; // merged into IndoorCameraD3D - int _unused_sSineNegX; // --//-- - float _unused_fCosineY; // matches old IndoorCamera::fRotationCosineY (new IndoorCameraD3D::fRotationCosineY) - float _unused_fSineY; // matches old IndoorCamera::fRotationSineY (new IndoorCameraD3D::fRotationSineY) - float _unused_fCosineNegX; // the same - float _unused_fSineNegX; // the same - int fov_rad_fixpoint; - int fov_rad_inv_fixpoint;//float - void *pRenderTarget; - unsigned int uTargetWidth; - unsigned int uTargetHeight; - unsigned int uViewportX; - unsigned int uViewportY; - unsigned int uViewportZ; - unsigned int uViewportW; - int field_64; - int *pTargetZBuffer; - int uViewportHeight; - int uViewportWidth; - int uViewportCenterX; - int uViewportCenterY; - struct BspRenderer_PortalViewportData *field_7C; - unsigned int uNumFacesRenderedThisFrame; - int field_84; - int field_88; - int field_8C; - int field_90; - int field_94; -}; -#pragma pack(pop) -extern BLVRenderParams *pBLVRenderParams; - - - - - -int __fastcall GetPortalScreenCoord(unsigned int uFaceID); -bool PortalFrustrum(int pNumVertices, struct BspRenderer_PortalViewportData *a2, struct BspRenderer_PortalViewportData *near_portal, int uFaceID); -void PrepareBspRenderList_BLV(); -void PrepareDecorationsRenderList_BLV(unsigned int uDecorationID, unsigned int uSectorID); -void PrepareActorRenderList_BLV(); -void PrepareItemsRenderList_BLV(); -void AddBspNodeToRenderList(unsigned int node_id); -void __fastcall sub_4406BC(unsigned int node_id, unsigned int uFirstNode); // idb -char __fastcall DoInteractionWithTopmostZObject(int a1, int a2); -int __fastcall sub_4AAEA6_transform(struct RenderVertexSoft *a1); -unsigned int __fastcall sub_4B0E07(unsigned int uFaceID); // idb -void BLV_UpdateUserInputAndOther(); -int BLV_GetFloorLevel(int x, int y, int z, unsigned int uSectorID, unsigned int *pFaceID); -void BLV_UpdateDoors(); -void UpdateActors_BLV(); -void BLV_ProcessPartyActions(); -void Door_switch_animation(unsigned int uDoorID, int a2); // idb: sub_449A49 -int __fastcall sub_4088E9(int a1, int a2, int a3, int a4, int a5, int a6); -void __fastcall PrepareDrawLists_BLV(); -void PrepareToLoadBLV(unsigned int bLoading); -int GetAlertStatus(); -int __fastcall _45063B_spawn_some_monster(struct MapInfo *a1, int a2); -int __fastcall sub_450521_ProllyDropItemAt(int ecx0, signed int a2, int a3, int a4, int a5, unsigned __int16 a6); - -bool __fastcall sub_4075DB(int a1, int a2, int a3, struct BLVFace *face); -bool __fastcall sub_4077F1(int a1, int a2, int a3, struct ODMFace *face, struct BSPVertexBuffer *a5); - -#pragma once - - - - - -/* 165 */ -#pragma pack(push, 1) -struct BspRenderer_PortalViewportData -{ - void GetViewportData(__int16 x, int y, __int16 z, int w); - - int _viewport_space_y; - int _viewport_space_w; - int _viewport_space_x; - int _viewport_space_z; - int _viewport_x_minID; - int _viewport_z_maxID; - __int16 viewport_left_side[480]; - __int16 viewport_right_side[480]; -}; -#pragma pack(pop) -extern BspRenderer_PortalViewportData stru_F8A590; - - - - -/* 164 */ -#pragma pack(push, 1) -struct BspRenderer_stru0 -{ - //----- (0043F2BF) -------------------------------------------------------- - inline BspRenderer_stru0() - { - //_eh_vector_constructor_iterator_(std__vector_0007AC, 24, 4, - // (void ( *)(void *))IndoorCameraD3D_Vec4::IndoorCameraD3D_Vec4, - // (void ( *)(void *))IndoorCameraD3D_Vec4::dtor); - //for (int i = 0; i < 4; ++i) - // pVertices[i].flt_2C = 0.0f; - } - - //----- (0043F2A9) -------------------------------------------------------- - ~BspRenderer_stru0() - { - //_eh_vector_destructor_iterator_(this->std__vector_0007AC, 24, 4, IndoorCameraD3D_Vec4::dtor); - } - - unsigned __int16 uSectorID; - unsigned __int16 uViewportX; - unsigned __int16 uViewportY; - unsigned __int16 uViewportZ; - unsigned __int16 uViewportW; - __int16 field_A; - BspRenderer_PortalViewportData PortalScreenData; - unsigned __int16 uFaceID; - __int16 field_7A6; - unsigned int viewing_portal_id; // portal through which we're seeing this node - IndoorCameraD3D_Vec4 std__vector_0007AC[4]; - RenderVertexSoft pPortalBounding[4]; -}; -#pragma pack(pop) - - - - -#pragma pack(push, 1) -struct BspFace -{ - unsigned __int16 uFaceID; - unsigned __int16 uNodeID; -}; -#pragma pack(pop) - - -/* 163 */ -#pragma pack(push, 1) -struct BspRenderer // stru170 -{ - //----- (0043F282) -------------------------------------------------------- - inline BspRenderer() - { - // _eh_vector_constructor_iterator_(field_FA8, 2252, 150, - // (void ( *)(void *))stru170_stru0::stru170_stru0, - // (void ( *)(void *))stru170_stru0::dtor); - num_faces = 0; - num_nodes = 0; - uNumVisibleNotEmptySectors = 0; - } - - //void AddFaceToRenderList_sw(unsigned int node_id, unsigned int uFaceID); - void AddFaceToRenderList_d3d(unsigned int node_id, unsigned int uFaceID); - void MakeVisibleSectorList(); - //void DrawFaceOutlines(); - - unsigned int num_faces; - //__int16 pFaceIDs[2000]; - BspFace faces[1000]; - //char field_130[3700]; - unsigned int num_nodes; - BspRenderer_stru0 nodes[150]; - unsigned int uNumVisibleNotEmptySectors; - unsigned __int16 pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[6]; -}; -#pragma pack(pop) - - -extern struct BspRenderer *pBspRenderer; // idb - -void FindBillboardsLightLevels_BLV(); - -int collide_against_floor_approximate(int x, int y, int z, unsigned int *pSectorID, unsigned int *pFaceID); // idb - -bool __fastcall sub_407A1C(int x, int z, int y, struct Vec3_int_ v); // idb diff -r 7b076fe64f23 -r 5abd8fc8f1c6 IndoorCameraD3D.cpp --- a/IndoorCameraD3D.cpp Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1466 +0,0 @@ -#define _CRTDBG_MAP_ALLOC -#include -#include - -#define _CRT_SECURE_NO_WARNINGS -#include "ErrorHandling.h" -#include "IndoorCameraD3D.h" -#include "Game.h" -#include "Indoor.h" -#include "Viewport.h" -#include "LOD.h" -#include "OurMath.h" - -#include "stru9.h" - - -// calculates FOV (Field of View) angle in radians for IndoorCamera::Initialize and BLVRenderParams::Reset -float _calc_fov(int viewport_width, int angle_degree) -{ - return viewport_width * 0.5 / tan(angle_degree / 2 * 0.01745329) + 0.5; -} - - - -//----- (004361EF) -------------------------------------------------------- -IndoorCameraD3D::IndoorCameraD3D() -{ - this->field_108 = 0.0; - this->field_138 = 0.0; - this->field_168 = 0.0; - this->field_198 = 0.0; - this->field_1C8 = 0.0; - this->field_1F8 = 0.0; - this->field_228 = 0.0; - this->field_258 = 0.0; - this->field_288 = 0.0; - this->field_2B8 = 0.0; - this->field_2E8 = 0.0; - this->field_2BC = 0.0; - this->field_2C0 = 0.0; - this->field_2C4 = 0.0; - this->field_318 = 0.0; - this->field_2EC = 0.0; - this->field_2F0 = 0.0; - this->field_2F4 = 0.0; - this->field_348 = 0.0; - this->field_31C = 0.0; - this->field_320 = 0.0; - this->field_324 = 0.0; - this->field_378 = 0.0; - this->field_34C = 0.0; - this->field_350 = 0.0; - this->field_354 = 0.0; - for (uint i = 0; i < 16384; ++i) - { - list_0037C[i].field_0 = 0; - list_0037C[i].flt_30 = 0.0f; - } - list_0037C_size = 0; - for (uint i = 0; i < 256; ++i) - list_E0380[i].mm7__vector_000004_size = 0; - list_E0380_size = 0; -} - - -//----- (0043643E) -------------------------------------------------------- -float IndoorCameraD3D::GetPickDepth() -{ - if (uCurrentlyLoadedLevelType == LEVEL_Outdoor) - return pODMRenderParams->uPickDepth; - else - return 16192.0; -} - -//----- (00436427) -------------------------------------------------------- -float IndoorCameraD3D::GetShadingDistMist() -{ - if (uCurrentlyLoadedLevelType == LEVEL_Outdoor) - return (double)pODMRenderParams->shading_dist_mist; - else - return 16192.0; -} - -//----- (004364C5) -------------------------------------------------------- -void IndoorCameraD3D::ViewTransfrom_OffsetUV(RenderVertexSoft *pVertices, unsigned int uNumVertices, RenderVertexSoft *pOutVertices, stru320 *a5) -{ - for (uint i = 0; i < uNumVertices; ++i) - { - pOutVertices[i].vWorldPosition.x = pVertices[i].vWorldPosition.x; - pOutVertices[i].vWorldPosition.y = pVertices[i].vWorldPosition.y; - pOutVertices[i].vWorldPosition.z = pVertices[i].vWorldPosition.z; - - pOutVertices[i].u = pVertices[i].u + a5->pDeltaUV[0]; - pOutVertices[i].v = pVertices[i].v + a5->pDeltaUV[1]; - } - ViewTransform(pOutVertices, uNumVertices); -} - -//----- (0043669D) -------------------------------------------------------- -bool IndoorCameraD3D::ApplyViewTransform_TrueIfStillVisible_BLV(int x, int y, int z, signed int *pOutX, int *pOutZ, int *pOutY, char bDoNotShow) -{ - int to_z; // esi@2 - int v9; // ecx@3 - //signed int *v10; // esi@5 - //int pOutY_; // ecx@5 - //signed int v12; // esi@7 - int v14; // [sp+8h] [bp-4h]@3 - int to_x; // [sp+14h] [bp+8h]@1 - int to_y; // [sp+18h] [bp+Ch]@1 -// int a2b; // [sp+18h] [bp+Ch]@5 - int a3a; // [sp+1Ch] [bp+10h]@5 - - to_x = x - pGame->pIndoorCameraD3D->vPartyPos.x; - to_y = y - pGame->pIndoorCameraD3D->vPartyPos.y; - if (pGame->pIndoorCameraD3D->sRotationX) - { - to_z = (z - pGame->pIndoorCameraD3D->vPartyPos.z) << 16; - //if ( pRenderer->pRenderD3D ) - //{ - v14 = (unsigned __int64)(to_x * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) - + (unsigned __int64)(to_y * (signed __int64)pGame->pIndoorCameraD3D->int_sine_y); - v9 = (unsigned __int64)(to_x * (signed __int64)pGame->pIndoorCameraD3D->int_sine_y) - - (unsigned __int64)(to_y * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y); - //} - a3a = (z - pGame->pIndoorCameraD3D->vPartyPos.z) << 16; - *pOutX = fixpoint_mul(v14, pGame->pIndoorCameraD3D->int_cosine_x) - fixpoint_mul(to_z, pGame->pIndoorCameraD3D->int_sine_x); - *pOutZ = v9; - *pOutY = fixpoint_mul(v14, pGame->pIndoorCameraD3D->int_sine_x) + fixpoint_mul(a3a, pGame->pIndoorCameraD3D->int_cosine_x); - } - else - { - *pOutY = (z - pGame->pIndoorCameraD3D->vPartyPos.z) << 16; - //if ( pRenderer->pRenderD3D ) - //{ - //v10 = pOutX; - *pOutX = (unsigned __int64)(to_x * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) - + (unsigned __int64)(to_y * (signed __int64)pGame->pIndoorCameraD3D->int_sine_y); - *pOutZ = (unsigned __int64)(to_x * (signed __int64)pGame->pIndoorCameraD3D->int_sine_y) - - (unsigned __int64)(to_y * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y); - //} - } - if (!bDoNotShow) - return false; - - return *pOutX >= fixpoint_from_int(4, 0) && - *pOutX <= fixpoint_from_int(8000, 0); -} - -//----- (00436455) -------------------------------------------------------- -bool IndoorCameraD3D::IsCulled(BLVFace *pFace) -{ - RenderVertexSoft v; // [sp+8h] [bp-30h]@1 - - //----- (0043648F) -------------------------------------------------------- - auto Vec3_short__to_RenderVertexSoft = [](RenderVertexSoft *_this, Vec3_short_ *a2) -> void - { - _this->flt_2C = 0.0; - - _this->vWorldPosition.x = a2->x; - _this->vWorldPosition.y = a2->y; - _this->vWorldPosition.z = a2->z; - }; - - - Vec3_short__to_RenderVertexSoft(&v, &pIndoor->pVertices[*pFace->pVertexIDs]); - return is_face_faced_to_camera(pFace, &v); -} - - -//----- (00436523) -------------------------------------------------------- -void IndoorCameraD3D::ViewTransform(RenderVertexSoft *a1a, unsigned int uNumVertices) -{ - if (byte_4D864C && pGame->uFlags & 0x80 || - uCurrentlyLoadedLevelType == LEVEL_Indoor) - { - float sin_x = fRotationXSine, - cos_x = fRotationXCosine; - float sin_y = fRotationYSine, - cos_y = fRotationYCosine; - - //v4 = uNumVertices; - //v7 = pIndoorCamera->fRotationXSine; - if (pGame->pIndoorCameraD3D->sRotationX) - { - - //_EAX = a1a; - for (uint i = 0; i < uNumVertices; ++i) - { - float st0, st1, st2; - //if ( pRenderer->pRenderD3D ) - { - /*__asm - { - fld [ebp+uNumVertices] // [(a1a[i].y - pIndoorCamera->pos.y)] [(a1a[i].z - pIndoorCamera->pos.z)] [pIndoorCamera->fRotationXCosine] [pIndoorCamera->fRotationYSine] [pIndoorCamera->fRotationYCosine] - fmul st, st(3) // [pIndoorCamera->fRotationYSine * (a1a[i].y - pIndoorCamera->pos.y)] [(a1a[i].z - pIndoorCamera->pos.z)] [pIndoorCamera->fRotationXCosine] [pIndoorCamera->fRotationYSine] [pIndoorCamera->fRotationYCosine] - fld [ebp+a1] // [(a1a[i].x - pIndoorCamera->pos.x)] [pIndoorCamera->fRotationYSine * (a1a[i].y - pIndoorCamera->pos.y)] [(a1a[i].z - pIndoorCamera->pos.z)] [pIndoorCamera->fRotationXCosine] [pIndoorCamera->fRotationYSine] [pIndoorCamera->fRotationYCosine] - fmul st, st(5) // 0[pIndoorCamera->fRotationYCosine * (a1a[i].x - pIndoorCamera->pos.x)] - // 1[pIndoorCamera->fRotationYSine * (a1a[i].y - pIndoorCamera->pos.y)] - // 2[(a1a[i].z - pIndoorCamera->pos.z)] - // 3[pIndoorCamera->fRotationXCosine] - // 4[pIndoorCamera->fRotationYSine] - // 5[pIndoorCamera->fRotationYCosine] - faddp st(1), st // [pIndoorCamera->fRotationYCosine * (a1a[i].x - pIndoorCamera->pos.x) + pIndoorCamera->fRotationYSine * (a1a[i].y - pIndoorCamera->pos.y)] [(a1a[i].z - pIndoorCamera->pos.z)] [pIndoorCamera->fRotationXCosine] [pIndoorCamera->fRotationYSine] [pIndoorCamera->fRotationYCosine] - fld [ebp+a1] // [(a1a[i].x - pIndoorCamera->pos.x)] [pIndoorCamera->fRotationYCosine * (a1a[i].x - pIndoorCamera->pos.x) + pIndoorCamera->fRotationYSine * (a1a[i].y - pIndoorCamera->pos.y)] [(a1a[i].z - pIndoorCamera->pos.z)] [pIndoorCamera->fRotationXCosine] [pIndoorCamera->fRotationYSine] [pIndoorCamera->fRotationYCosine] - fmul st, st(4) // [pIndoorCamera->fRotationYSine * (a1a[i].x - pIndoorCamera->pos.x)] [pIndoorCamera->fRotationYCosine * (a1a[i].x - pIndoorCamera->pos.x) + pIndoorCamera->fRotationYSine * (a1a[i].y - pIndoorCamera->pos.y)] [(a1a[i].z - pIndoorCamera->pos.z)] [pIndoorCamera->fRotationXCosine] [pIndoorCamera->fRotationYSine] [pIndoorCamera->fRotationYCosine] - - fld [ebp+uNumVertices] // 0[a1a[i].y - pIndoorCamera->pos.y] - // 1[pIndoorCamera->fRotationYSine * (a1a[i].x - pIndoorCamera->pos.x)] - // 2[pIndoorCamera->fRotationYCosine * (a1a[i].x - pIndoorCamera->pos.x) + pIndoorCamera->fRotationYSine * (a1a[i].y - pIndoorCamera->pos.y)] - // 3[(a1a[i].z - pIndoorCamera->pos.z)] - // 4[pIndoorCamera->fRotationXCosine] - // 5[pIndoorCamera->fRotationYSine] - // 6[pIndoorCamera->fRotationYCosine] - - fmul st, st(6) // 0[pIndoorCamera->fRotationYCosine * (a1a[i].y - pIndoorCamera->pos.y)] - // 1[pIndoorCamera->fRotationYSine * (a1a[i].x - pIndoorCamera->pos.x)] - // 2[pIndoorCamera->fRotationYCosine * (a1a[i].x - pIndoorCamera->pos.x) + pIndoorCamera->fRotationYSine * (a1a[i].y - pIndoorCamera->pos.y)] - // 3[(a1a[i].z - pIndoorCamera->pos.z)] - // 4[pIndoorCamera->fRotationXCosine] - // 5[pIndoorCamera->fRotationYSine] - // 6[pIndoorCamera->fRotationYCosine] - - fsubp st(1), st // 0[pIndoorCamera->fRotationYSine * (a1a[i].x - pIndoorCamera->pos.x) - pIndoorCamera->fRotationYCosine * (a1a[i].y - pIndoorCamera->pos.y)] - // 1[pIndoorCamera->fRotationYCosine * (a1a[i].x - pIndoorCamera->pos.x) + pIndoorCamera->fRotationYSine * (a1a[i].y - pIndoorCamera->pos.y)] - // 2[(a1a[i].z - pIndoorCamera->pos.z)] - // 3[pIndoorCamera->fRotationXCosine] - // 4[pIndoorCamera->fRotationYSine] - // 5[pIndoorCamera->fRotationYCosine] - }*/ - st0 = sin_y * (a1a[i].vWorldPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x) - cos_y * (a1a[i].vWorldPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y); - st1 = cos_y * (a1a[i].vWorldPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x) + sin_y * (a1a[i].vWorldPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y); - st2 = (a1a[i].vWorldPosition.z - pGame->pIndoorCameraD3D->vPartyPos.z); - } - if (false)//else - { - /*__asm - { - fld [ebp+a1] // 0[(a1a[i].x - pIndoorCamera->pos.x)] - // 1[(a1a[i].z - pIndoorCamera->pos.z)] - // 2[pIndoorCamera->fRotationXCosine] - // 3[pIndoorCamera->fRotationYSine] - // 4[pIndoorCamera->fRotationYCosine] - fmul st, st(4) // 0[pIndoorCamera->fRotationYCosine * (a1a[i].x - pIndoorCamera->pos.x)] - // 1[(a1a[i].z - pIndoorCamera->pos.z)] - // 2[pIndoorCamera->fRotationXCosine] - // 3[pIndoorCamera->fRotationYSine] - // 4[pIndoorCamera->fRotationYCosine] - fld [ebp+uNumVertices] // 0[(a1a[i].y - pIndoorCamera->pos.y)] - // 1[pIndoorCamera->fRotationYCosine * (a1a[i].x - pIndoorCamera->pos.x)] - // 2[(a1a[i].z - pIndoorCamera->pos.z)] - // 3[pIndoorCamera->fRotationXCosine] - // 4[pIndoorCamera->fRotationYSine] - // 5[pIndoorCamera->fRotationYCosine] - fmul st, st(4) // 0[pIndoorCamera->fRotationYSine * (a1a[i].y - pIndoorCamera->pos.y)] - // 1[pIndoorCamera->fRotationYCosine * (a1a[i].x - pIndoorCamera->pos.x)] - // 2[(a1a[i].z - pIndoorCamera->pos.z)] - // 3[pIndoorCamera->fRotationXCosine] - // 4[pIndoorCamera->fRotationYSine] - // 5[pIndoorCamera->fRotationYCosine] - fsubp st(1), st // 0[pIndoorCamera->fRotationYCosine * (a1a[i].x - pIndoorCamera->pos.x) - pIndoorCamera->fRotationYSine * (a1a[i].y - pIndoorCamera->pos.y)] - // 1[(a1a[i].z - pIndoorCamera->pos.z)] - // 2[pIndoorCamera->fRotationXCosine] - // 3[pIndoorCamera->fRotationYSine] - // 4[pIndoorCamera->fRotationYCosine] - fld [ebp+a1] // 0[(a1a[i].x - pIndoorCamera->pos.x)] - // 1[pIndoorCamera->fRotationYCosine * (a1a[i].x - pIndoorCamera->pos.x) - pIndoorCamera->fRotationYSine * (a1a[i].y - pIndoorCamera->pos.y)] - // 2[(a1a[i].z - pIndoorCamera->pos.z)] - // 3[pIndoorCamera->fRotationXCosine] - // 4[pIndoorCamera->fRotationYSine] - // 5[pIndoorCamera->fRotationYCosine] - fmul st, st(4) // 0[pIndoorCamera->fRotationYSine * (a1a[i].x - pIndoorCamera->pos.x)] - // 1[pIndoorCamera->fRotationYCosine * (a1a[i].x - pIndoorCamera->pos.x) - pIndoorCamera->fRotationYSine * (a1a[i].y - pIndoorCamera->pos.y)] - // 2[(a1a[i].z - pIndoorCamera->pos.z)] - // 3[pIndoorCamera->fRotationXCosine] - // 4[pIndoorCamera->fRotationYSine] - // 5[pIndoorCamera->fRotationYCosine] - fld [ebp+uNumVertices] // 0[(a1a[i].y - pIndoorCamera->pos.y)] - // 1[pIndoorCamera->fRotationYSine * (a1a[i].x - pIndoorCamera->pos.x)] - // 2[pIndoorCamera->fRotationYCosine * (a1a[i].x - pIndoorCamera->pos.x) - pIndoorCamera->fRotationYSine * (a1a[i].y - pIndoorCamera->pos.y)] - // 3[(a1a[i].z - pIndoorCamera->pos.z)] - // 4[pIndoorCamera->fRotationXCosine] - // 5[pIndoorCamera->fRotationYSine] - // 6[pIndoorCamera->fRotationYCosine] - fmul st, st(6) // 0[pIndoorCamera->fRotationYCosine * (a1a[i].y - pIndoorCamera->pos.y)] - // 1[pIndoorCamera->fRotationYSine * (a1a[i].x - pIndoorCamera->pos.x)] - // 2[pIndoorCamera->fRotationYCosine * (a1a[i].x - pIndoorCamera->pos.x) - pIndoorCamera->fRotationYSine * (a1a[i].y - pIndoorCamera->pos.y)] - // 3[(a1a[i].z - pIndoorCamera->pos.z)] - // 4[pIndoorCamera->fRotationXCosine] - // 5[pIndoorCamera->fRotationYSine] - // 6[pIndoorCamera->fRotationYCosine] - faddp st(1), st // 0[pIndoorCamera->fRotationYCosine * (a1a[i].y - pIndoorCamera->pos.y) + pIndoorCamera->fRotationYSine * (a1a[i].x - pIndoorCamera->pos.x)] - // 1[pIndoorCamera->fRotationYCosine * (a1a[i].x - pIndoorCamera->pos.x) - pIndoorCamera->fRotationYSine * (a1a[i].y - pIndoorCamera->pos.y)] - // 2[(a1a[i].z - pIndoorCamera->pos.z)] - // 3[pIndoorCamera->fRotationXCosine] - // 4[pIndoorCamera->fRotationYSine] - // 5[pIndoorCamera->fRotationYCosine] - }*/ - st0 = cos_y * (a1a[i].vWorldPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y) + sin_y * (a1a[i].vWorldPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x); - st1 = cos_y * (a1a[i].vWorldPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x) - sin_y * (a1a[i].vWorldPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y); - st2 = (a1a[i].vWorldPosition.z - pGame->pIndoorCameraD3D->vPartyPos.z); - } - - a1a[i].vWorldViewPosition.x = st1*cos_x - st2*sin_x; - a1a[i].vWorldViewPosition.y = st0; - a1a[i].vWorldViewPosition.z = st2*cos_x + st1*sin_x; - } - } - else - { - for (uint i = 0; i < uNumVertices; ++i) - { - //if ( pRenderer->pRenderD3D ) - { - /*__asm - { - fld [ebp+uNumVertices] // 0[(a1a[i].y - pIndoorCamera->pos.y)] - // 1[(a1a[i].z - pIndoorCamera->pos.z)] - // 2[sin_y] - // 3[cos_y] - fmul st, st(2) // 0[sin_y * (a1a[i].y - pIndoorCamera->pos.y)] - // 1[(a1a[i].z - pIndoorCamera->pos.z)] - // 2[sin_y] - // 3[cos_y] - fld [ebp+a1] // 0[(a1a[i].x - pIndoorCamera->pos.x)] - // 1[sin_y * (a1a[i].y - pIndoorCamera->pos.y)] - // 2[(a1a[i].z - pIndoorCamera->pos.z)] - // 3[sin_y] - // 4[cos_y] - fmul st, st(4) // 0[cos_y * (a1a[i].x - pIndoorCamera->pos.x)] - // 1[sin_y * (a1a[i].y - pIndoorCamera->pos.y)] - // 2[(a1a[i].z - pIndoorCamera->pos.z)] - // 3[sin_y] - // 4[cos_y] - faddp st(1), st // 0[cos_y * (a1a[i].x - pIndoorCamera->pos.x) + sin_y * (a1a[i].y - pIndoorCamera->pos.y)] - // 1[(a1a[i].z - pIndoorCamera->pos.z)] - // 2[sin_y] - // 3[cos_y] - fstp dword ptr [eax+0Ch] - fld [ebp+a1] // 0[(a1a[i].x - pIndoorCamera->pos.x)] - // 1[(a1a[i].z - pIndoorCamera->pos.z)] - // 2[sin_y] - // 3[cos_y] - fmul st, st(2) // 0[sin_y * (a1a[i].x - pIndoorCamera->pos.x)] - // 1[(a1a[i].z - pIndoorCamera->pos.z)] - // 2[sin_y] - // 3[cos_y] - fld [ebp+uNumVertices] // 0[(a1a[i].y - pIndoorCamera->pos.y)] - // 1[sin_y * (a1a[i].x - pIndoorCamera->pos.x)] - // 2[(a1a[i].z - pIndoorCamera->pos.z)] - // 3[sin_y] - // 4[cos_y] - fmul st, st(4) // 0[cos_y * (a1a[i].y - pIndoorCamera->pos.y)] - // 1[sin_y * (a1a[i].x - pIndoorCamera->pos.x)] - // 2[(a1a[i].z - pIndoorCamera->pos.z)] - // 3[sin_y] - // 4[cos_y] - fsubp st(1), st // 0[sin_y * (a1a[i].x - pIndoorCamera->pos.x) - cos_y * (a1a[i].y - pIndoorCamera->pos.y)] - // 1[(a1a[i].z - pIndoorCamera->pos.z)] - // 2[sin_y] - // 3[cos_y] - fstp dword ptr [eax+10h] - fstp dword ptr [eax+14h] - }*/ - a1a[i].vWorldViewPosition.x = cos_y * (a1a[i].vWorldPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x) + sin_y * (a1a[i].vWorldPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y); - a1a[i].vWorldViewPosition.y = sin_y * (a1a[i].vWorldPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x) - cos_y * (a1a[i].vWorldPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y); - a1a[i].vWorldViewPosition.z = (a1a[i].vWorldPosition.z - pGame->pIndoorCameraD3D->vPartyPos.z); - } - if (false)//else - { - __debugbreak(); - /*__asm - { - fld [ebp+a1] - fmul st, st(3) - fld [ebp+uNumVertices] - fmul st, st(3) - fsubp st(1), st - fstp dword ptr [eax+0Ch] - fld [ebp+a1] - fmul st, st(2) - fld [ebp+uNumVertices] - fmul st, st(4) - faddp st(1), st - - fstp dword ptr [eax+10h] - fstp dword ptr [eax+14h] - }*/ - } - } - } - } - else for (uint i = 0; i < uNumVertices; ++i) - //pIndoorCamera->ViewTransform_ODM(a1a + i); - { - //ViewTransform_ODM(a1a + i); - - RenderVertexSoft* a1 = &a1a[i]; - //----- (00481CCE) -------------------------------------------------------- - //void ViewTransform_ODM(RenderVertexSoft *a1) - { - float result; // eax@1 - double vCamToVertexZ; // st7@1 - double v3; // st6@1 - double v4; // st5@1 - double v5; // st4@1 - float v6; // ST04_4@3 - float v7; // [sp+0h] [bp-14h]@1 - float v8; // [sp+8h] [bp-Ch]@1 - float vCamToVertexX; // [sp+Ch] [bp-8h]@1 - float vCamToVertexY; // [sp+10h] [bp-4h]@1 - - v8 = fRotationXCosine; - result = fRotationXSine; - v7 = fRotationXSine; - vCamToVertexX = a1->vWorldPosition.x - (double)pGame->pIndoorCameraD3D->vPartyPos.x; - vCamToVertexY = a1->vWorldPosition.y - (double)pGame->pIndoorCameraD3D->vPartyPos.y; - vCamToVertexZ = a1->vWorldPosition.z - (double)pGame->pIndoorCameraD3D->vPartyPos.z; - v3 = fRotationYCosine; - v4 = fRotationYSine; - v5 = vCamToVertexY * fRotationYSine + fRotationYCosine * vCamToVertexX; - if (pGame->pIndoorCameraD3D->sRotationX) - { - v6 = vCamToVertexY * fRotationYSine + fRotationYCosine * vCamToVertexX; - a1->vWorldViewPosition.x = v5 * fRotationXCosine + fRotationXSine * vCamToVertexZ; - a1->vWorldViewPosition.y = v3 * vCamToVertexY - v4 * vCamToVertexX; - a1->vWorldViewPosition.z = v8 * vCamToVertexZ - v6 * v7; - } - else - { - a1->vWorldViewPosition.x = vCamToVertexY * fRotationYSine + fRotationYCosine * vCamToVertexX; - a1->vWorldViewPosition.y = v3 * vCamToVertexY - v4 * vCamToVertexX; - a1->vWorldViewPosition.z = vCamToVertexZ; - } - } - } -} - - -//----- (00436932) -------------------------------------------------------- -bool IndoorCameraD3D::GetFacetOrientation(char polyType, Vec3_float_ *a2, Vec3_float_ *a3, Vec3_float_ *a4) -{ - switch ((PolygonType)polyType) - { - case POLYGON_VerticalWall: - { - a4->x = -a2->y; - a4->y = a2->x; - a4->z = 0.0; - - a3->x = 0.0; - a3->y = 0.0; - a3->z = 1.0f; - } - return true; - - case POLYGON_Floor: - case POLYGON_Ceiling: - { - a4->x = 1.0; - a4->y = 0.0; - a4->z = 0.0; - - a3->x = 0.0; - a3->y = 1.0; - a3->z = 0.0; - } - return true; - - case POLYGON_InBetweenFloorAndWall: - case POLYGON_InBetweenCeilingAndWall: - { - if (fabs(a2->z) < 0.70811361) - { - a4->x = -a2->y; - a4->y = a2->x; - a4->z = 0.0; - a4->Normalize(); - - a3->x = 0.0; - a3->y = 0.0; - a3->z = 1.0; - } - else - { - a4->x = 1.0; - a4->y = 0.0; - a4->z = 0.0; - - a3->x = 0.0; - a3->y = 1.0; - a3->z = 0.0; - } - } - return true; - - default: - return false; - } -} - -//----- (00438258) -------------------------------------------------------- -bool IndoorCameraD3D::is_face_faced_to_camera(BLVFace *pFace, RenderVertexSoft *a2) -{ - if (pFace->Portal()) - return false; - - //really strange cull; dot(to_cam, normal) < 0 means we see the BACK face, not font %_% - if ( (a2->vWorldPosition.z - (double)pGame->pIndoorCameraD3D->vPartyPos.z) * (double)pFace->pFacePlane_old.vNormal.z - + (a2->vWorldPosition.y - (double)pGame->pIndoorCameraD3D->vPartyPos.y) * (double)pFace->pFacePlane_old.vNormal.y - + (a2->vWorldPosition.x - (double)pGame->pIndoorCameraD3D->vPartyPos.x) * (double)pFace->pFacePlane_old.vNormal.x < 0.0) - return false; - - return true; -} - - -//----- (00437AB5) -------------------------------------------------------- -void IndoorCameraD3D::do_draw_debug_line_sw(RenderVertexSoft *pLineBegin, signed int sStartDiffuse, RenderVertexSoft *pLineEnd, signed int sEndDiffuse, unsigned int uOutNumVertices, float z_stuff) -{ - RenderVertexSoft a1[20]; // [sp+8h] [bp-7C4h]@6 - RenderVertexSoft pVertices[20]; // [sp+3C8h] [bp-404h]@2 - RenderVertexD3D3 v24[2]; // [sp+788h] [bp-44h]@11 - - //if ( pRenderer->pRenderD3D ) - //{ - for ( uint i = 0; i < 20; i++ ) - pVertices[i].flt_2C = 0.0; - if ( (char)uOutNumVertices ) - { - pVertices[0].vWorldViewProjX = pLineBegin->vWorldViewProjX; - pVertices[0].vWorldViewProjY = pLineBegin->vWorldViewProjY; - - pVertices[1].vWorldViewProjX = pLineEnd->vWorldViewProjX; - pVertices[1].vWorldViewProjY = pLineEnd->vWorldViewProjY; - v24[0].specular = 0; - v24[0].pos.x = pVertices[0].vWorldViewProjX; - v24[0].pos.y = pVertices[0].vWorldViewProjY; - v24[0].pos.z = 0.001 - z_stuff; - v24[0].diffuse = sStartDiffuse; - v24[0].rhw = 0.001; - v24[0].texcoord.x = 0.0; - v24[0].texcoord.y = 0.0; - - v24[1].pos.x = pVertices[1].vWorldViewProjX; - v24[1].pos.y = pVertices[1].vWorldViewProjY; - v24[1].diffuse = sEndDiffuse; - v24[1].pos.z = 0.001 - z_stuff; - v24[1].specular = 0; - v24[1].rhw = 0.001; - v24[1].texcoord.x = 0.0; - v24[1].texcoord.y = 0.0; - //v19 = pRenderer->pRenderD3D->pDevice; - pRenderer->DrawLines(v24, 2); - return; - } - for ( uint i = 0; i < 20; i++ ) - a1[i].flt_2C = 0.0; - uOutNumVertices = 2; - a1[0].vWorldPosition.x = pLineBegin->vWorldPosition.x; - a1[0].vWorldPosition.y = pLineBegin->vWorldPosition.y; - a1[0].vWorldPosition.z = pLineBegin->vWorldPosition.z; - a1[1].vWorldPosition.x = pLineEnd->vWorldPosition.x; - a1[1].vWorldPosition.y = pLineEnd->vWorldPosition.y; - a1[1].vWorldPosition.z = pLineEnd->vWorldPosition.z; - if ( CalcPortalShape(a1, &uOutNumVertices, pVertices, this->std__vector_000034_prolly_frustrum, 4, 1, 0) != 1 || (signed int)uOutNumVertices >= 2 ) - { - ViewTransform(pVertices, 2); - Project(pVertices, 2, 0); - v24[0].specular = 0; - v24[0].pos.x = pVertices[0].vWorldViewProjX; - v24[0].pos.y = pVertices[0].vWorldViewProjY; - v24[0].pos.z = 0.001 - z_stuff; - v24[0].diffuse = sStartDiffuse; - v24[0].rhw = 0.001; - v24[0].texcoord.x = 0.0; - v24[0].texcoord.y = 0.0; - - v24[1].pos.x = pVertices[1].vWorldViewProjX; - v24[1].pos.y = pVertices[1].vWorldViewProjY; - v24[1].diffuse = sEndDiffuse; - v24[1].pos.z = 0.001 - z_stuff; - v24[1].specular = 0; - v24[1].rhw = 0.001; - v24[1].texcoord.x = 0.0; - v24[1].texcoord.y = 0.0; - //v19 = pRenderer->pRenderD3D->pDevice; - pRenderer->DrawLines(v24, 2); - return; - } - //} -} - -//----- (00437A55) -------------------------------------------------------- -void IndoorCameraD3D::debug_outline_d3d(const RenderVertexD3D3 *pLineVertices, unsigned int uNumLines, int uDiffuse, float z_stuff) -{ - unsigned int v5; // esi@1 - const RenderVertexD3D3 *v6; // ecx@2 - unsigned int v7; // ebx@2 - const RenderVertexD3D3 *v8; // edi@3 - - v5 = 0; - if ( (signed int)(uNumLines - 1) > 0 ) - { - v6 = pLineVertices; - v5 = uNumLines - 1; - for ( v7 = uNumLines - 1; v7; --v7 ) - { - v8 = v6 + 1; - pRenderer->do_draw_debug_line_d3d(v6, uDiffuse, v6 + 1, uDiffuse, z_stuff); - v6 = v8; - } - } - pRenderer->do_draw_debug_line_d3d(&pLineVertices[v5], uDiffuse, pLineVertices, uDiffuse, z_stuff); -} - -//----- (004379EE) -------------------------------------------------------- -void IndoorCameraD3D::debug_outline_sw(RenderVertexSoft *a2, unsigned int uNumVertices, unsigned int uDiffuse, float a5) -{ - if ( !uNumVertices ) - return; - if ( (signed int)(uNumVertices - 1) > 0 ) - { - for ( uint i = 0; i < uNumVertices - 1; i++ ) - do_draw_debug_line_sw(&a2[i], uDiffuse, &a2[i + 1], uDiffuse, 0, a5); - } - do_draw_debug_line_sw(&a2[uNumVertices - 1], uDiffuse, a2, uDiffuse, 0, a5); -} - - -void IndoorCameraD3D::DebugDrawPortal(BLVFace *pFace) -{ - Assert(pFace->uNumVertices <= 32); - - RenderVertexSoft sw[32]; - for (uint i = 0; i < pFace->uNumVertices; ++i) - { - sw[i].vWorldPosition.x = pIndoor->pVertices[pFace->pVertexIDs[i]].x; - sw[i].vWorldPosition.y = pIndoor->pVertices[pFace->pVertexIDs[i]].y; - sw[i].vWorldPosition.z = pIndoor->pVertices[pFace->pVertexIDs[i]].z; - } - ViewTransform(sw, pFace->uNumVertices); - Project(sw, pFace->uNumVertices, 0); - - - - RenderVertexD3D3 v[32]; - for (uint i = 0; i < pFace->uNumVertices; ++i) - { - v[i].pos.x = sw[i].vWorldViewProjX; - v[i].pos.y = sw[i].vWorldViewProjY; - v[i].pos.z = 1.0 - 1.0 / (sw[i].vWorldViewPosition.x * 0.061758894); - v[i].rhw = 1.0 / sw[i].vWorldViewPosition.x; - v[i].diffuse = 0x80F020F0; - v[i].specular = 0; - //v[i].texcoord.x = pFace->pVertexUIDs[i] / (double)pTex->uTextureWidth; - //v[i].texcoord.y = pFace->pVertexUIDs[i] / (double)pTex->uTextureHeight; - v[i].texcoord.x = 0; - v[i].texcoord.y = 0; - } - - pRenderer->DrawFansTransparent(v, pFace->uNumVertices); -} - -//----- (00437906) -------------------------------------------------------- -void IndoorCameraD3D::PrepareAndDrawDebugOutline(BLVFace *pFace, unsigned int uDiffuse) -{ - static RenderVertexSoft static_sub_437906_array_50CDD0[64]; - static bool __init_flag1 = false; - if (!__init_flag1) - { - __init_flag1 = true; - - for (uint i = 0; i < 64; ++i) - static_sub_437906_array_50CDD0[i].flt_2C = 0.0f; - } - if ( pFace->uNumVertices ) - { - for ( uint i = 0; i < pFace->uNumVertices; i++ ) - { - static_sub_437906_array_50CDD0[i].vWorldPosition.x = (double)pIndoor->pVertices[pFace->pVertexIDs[i]].x; - static_sub_437906_array_50CDD0[i].vWorldPosition.y = (double)pIndoor->pVertices[pFace->pVertexIDs[i]].y; - static_sub_437906_array_50CDD0[i].vWorldPosition.z = (double)pIndoor->pVertices[pFace->pVertexIDs[i]].z; - static_sub_437906_array_50CDD0[i].u = (double)pFace->pVertexUIDs[i]; - static_sub_437906_array_50CDD0[i].v = (double)pFace->pVertexVIDs[i]; - } - } - if ( draw_portals_loops ) - debug_outline_sw(static_sub_437906_array_50CDD0, pFace->uNumVertices, uDiffuse, 0.0); -} -// 50D9D0: using guessed type char static_sub_437906_byte_50D9D0_init_flag; - -//----- (004378BA) -------------------------------------------------------- -void IndoorCameraD3D::MatrixMultiply(Matrix3x3_float_ *ma, Matrix3x3_float_ *mb, Matrix3x3_float_ *m_out) -{ - float sum; - - for ( uint row = 0; row < 3; row++ ) - { - for ( uint col = 0; col < 3; col++ ) - { - sum = 0; - for ( int index = 0; index < 3; index++ ) - sum += ma->v[row][index]*mb->v[index][col]; - m_out->v[row][col] = sum; - } - } -} - -//----- (004376E7) -------------------------------------------------------- -void IndoorCameraD3D::CreateWorldMatrixAndSomeStuff() -{ - Matrix3x3_float_ m1; // [sp+10h] [bp-B8h]@1 - Matrix3x3_float_ m2; // [sp+34h] [bp-94h]@1 - Matrix3x3_float_ m3; // [sp+58h] [bp-70h]@1 - Matrix3x3_float_ m4; // [sp+7Ch] [bp-4Ch]@1 - Matrix3x3_float_ m5; // [sp+A0h] [bp-28h]@1 - - //RotationZ(0) - m5._11 = cosf(0); m5._12 = sinf(0); m5._13 = 0; - m5._21 = -sinf(0); m5._22 = cosf(0); m5._23 = 0; - m5._31 = 0; m5._32 = 0; m5._33 = 1; - - float cos_x1 = fRotationXCosine, - sin_x1 = fRotationXSine; - //RotationX(x) - m4._11 = 1; m4._12 = 0; m4._13 = 0; - m4._21 = 0; m4._22 = cos_x1; m4._23 = sin_x1; - m4._31 = 0; m4._32 = -sin_x1; m4._33 = cos_x1; - - float cos_y1 = fRotationYCosine, - sin_y1 = fRotationYSine; - //RotationY(some_angle) - m3._11 = cos_y1; m3._12 = 0; m3._13 = -sin_y1; - m3._21 = 0; m3._22 = 1; m3._23 = 0; - m3._31 = sin_y1; m3._32 = 0; m3._33 = cos_y1; - - MatrixMultiply(&m5, &m3, &m1); - MatrixMultiply(&m4, &m1, &m2); - - for (uint i = 0; i < 3; ++i) - { - field_4[0].v[i] = m2.v[1][i]; - field_4[1].v[i] = m2.v[0][i]; - field_4[2].v[i] = m2.v[2][i]; - } - - inv_fov = 1.1344639; - fov_x = (double)pViewport->uScreenWidth * 0.8814736; - - fov_y = 0.8814736 * (double)pViewport->uScreenHeight; - fov = fov_y; - if ( fov_x > fov ) - fov = fov_x; - screenCenterX = (double)pViewport->uScreenCenterX; - screenCenterY = (double)(pViewport->uScreenCenterY - pViewport->uScreen_TL_Y); -} - -//----- (00437691) -------------------------------------------------------- -void IndoorCameraD3D::Vec3Transform(const IndoorCameraD3D_Vec3 *pVector, IndoorCameraD3D_Vec3 *pOut) -{ - pOut->y = field_4[1].x * pVector->x + field_4[0].x * pVector->y + field_4[2].x * pVector->z; - pOut->z = field_4[1].y * pVector->x + field_4[0].y * pVector->y + field_4[2].y * pVector->z; - pOut->x = field_4[1].z * pVector->x + field_4[0].z * pVector->y + field_4[2].z * pVector->z; -} - -//----- (00437607) -------------------------------------------------------- -void IndoorCameraD3D::_437607(IndoorCameraD3D_Vec3 *a1, IndoorCameraD3D_Vec4 *a2) -{ - double v4; // st7@1 - IndoorCameraD3D_Vec3 v8; // [sp+8h] [bp-1Ch]@1 - - v8.x = (double)pGame->pIndoorCameraD3D->vPartyPos.x; - v8.y = (double)pGame->pIndoorCameraD3D->vPartyPos.y; - v8.z = (double)pGame->pIndoorCameraD3D->vPartyPos.z; - Vec3Transform(a1, a2); - - v4 = v8.x * a2->x + v8.y * a2->y + v8.z * a2->z; - a2->dot = v4 + 0.000099999997; -} - -//----- (004374E8) -------------------------------------------------------- -void IndoorCameraD3D::_4374E8_ProllyBuildFrustrum() -{ - //IndoorCameraD3D *v1; // esi@1 - //double v2; // st7@1 - double v3; // st7@1 - //double v4; // st7@1 - double v5; // st7@1 - //double v6; // st7@1 - IndoorCameraD3D_Vec3 v7; // [sp+Ch] [bp-24h]@1 - //float v8; // [sp+10h] [bp-20h]@1 - //float v9; // [sp+14h] [bp-1Ch]@1 - //float v10; // [sp+18h] [bp-18h]@1 - //float v11; // [sp+1Ch] [bp-14h]@1 - //float v12; // [sp+20h] [bp-10h]@1 - //int v13; // [sp+2Ch] [bp-4h]@1 - - //v1 = this; - //IndoorCameraD3D_Vec3::IndoorCameraD3D_Vec3(&v7); - //v2 = 2.0 / inv_fov; - //v13 = 0; - v3 = atan(2.0 / inv_fov * fov / fov_x); - //v12 = v3; - //v11 = sin(v3); - //v4 = cos(v3); - v7.x = -sin(v3); - v7.y = 0.0; - v7.z = cos(v3); - _437607(&v7, std__vector_000034_prolly_frustrum + 0); - v7.x = sin(v3); - _437607(&v7, std__vector_000034_prolly_frustrum + 1); - v5 = atan(2.0 / inv_fov * fov / (fov_y + 0.5)); - //v12 = v5; - //v11 = sin(v5); - //v6 = cos(v5); - v7.y = sin(v5); - v7.x = 0.0; - v7.z = cos(v5); - _437607(&v7, &std__vector_000034_prolly_frustrum[2]); - v7.y = -sin(v5); - _437607(&v7, &std__vector_000034_prolly_frustrum[3]); - //v13 = -1; - //IndoorCameraD3D_Vec3::dtor(&v7); -} - -//----- (00437376) -------------------------------------------------------- -char IndoorCameraD3D::_437376(stru154 *thisa, RenderVertexSoft *a2, unsigned int *pOutNumVertices) -{ - //unsigned int v4; // ebx@1 - //RenderVertexSoft *v5; // edx@2 - double v6; // st7@3 - //unsigned int v7; // edi@5 - signed int v8; // esi@6 - int v9; // ebx@8 - int v10; // eax@8 - //int v11; // ecx@14 - //int v12; // eax@14 - int v13; // eax@15 - signed int v14; // ebx@17 - //RenderVertexSoft *v15; // eax@18 - unsigned int *v16; // eax@20 -// char result; // al@24 - RenderVertexSoft v18; // [sp+Ch] [bp-34h]@2 - int v19; // [sp+3Ch] [bp-4h]@8 - signed int thisb; // [sp+48h] [bp+8h]@6 - bool a2_3; // [sp+4Fh] [bp+Fh]@5 - - //v4 = *pOutNumVertices; - //v5 = a2; - memcpy(&v18, a2, sizeof(v18)); - a2_3 = false; - memcpy(&a2[*pOutNumVertices], a2, sizeof(a2[*pOutNumVertices])); - memcpy(&a2[*pOutNumVertices + 1], &a2[1], sizeof(a2[*pOutNumVertices + 1])); - //v7 = *pOutNumVertices; - - if ( (signed int)*pOutNumVertices <= 3 - || (((v18.vWorldPosition.z - (double)pGame->pIndoorCameraD3D->vPartyPos.z) * thisa->face_plane.vNormal.z - + (v18.vWorldPosition.y - (double)pGame->pIndoorCameraD3D->vPartyPos.y) * thisa->face_plane.vNormal.y - + (v18.vWorldPosition.x - (double)pGame->pIndoorCameraD3D->vPartyPos.x) * thisa->face_plane.vNormal.x < 0.0) ? (v6 = 1.0) : (v6 = -1.0), - (signed int)*pOutNumVertices <= 0) ) - return 0; - v8 = 1; - for ( thisb = 1; thisb - 1 < (signed int)*pOutNumVertices; v8 = thisb ) - { - v9 = v8 - 1; - v10 = v8 + 1; - v19 = v8 + 1; - if ( v8 - 1 >= (signed int)*pOutNumVertices ) - v9 -= *pOutNumVertices; - if ( v8 >= (signed int)*pOutNumVertices ) - v8 -= *pOutNumVertices; - if ( v19 >= (signed int)*pOutNumVertices ) - v10 = v19 - *pOutNumVertices; - //v11 = (int)&a2[v10]; - //v12 = (int)&a2[v9]; - if ( -0.009999999776482582 > ((a2[v8].vWorldViewProjX - a2[v9].vWorldViewProjX) - * (a2[v10].vWorldViewProjY - a2[v9].vWorldViewProjY) - - (a2[v8].vWorldViewProjY - a2[v9].vWorldViewProjY) - * (a2[v10].vWorldViewProjX - a2[v9].vWorldViewProjX)) - * v6 ) - { - thisb = v19; - v16 = pOutNumVertices; - } - else - { - v13 = thisb; - if ( thisb >= (signed int)*pOutNumVertices ) - v13 = thisb - *pOutNumVertices; - if ( v13 < (signed int)*pOutNumVertices ) - { - for ( v14 = v13; v14 < (signed int)*pOutNumVertices; ++v14 ) - memcpy(&a2[v14], &a2[v14 + 1], sizeof(a2[v14])); - } - v16 = pOutNumVertices; - a2_3 = true; - --*v16; - } - *pOutNumVertices = *v16; - //if ( thisb - 1 >= (signed int)*v16 ) - //break; - } - if ( a2_3 ) - return true; - else - return false; -} - -//----- (00437285) -------------------------------------------------------- -bool IndoorCameraD3D::CalcPortalShape(RenderVertexSoft *a1, unsigned int *pOutNumVertices, RenderVertexSoft *pVertices, IndoorCameraD3D_Vec4 *a4, signed int uNumVertices, char a6, int _unused) -{ -// char *v8; // eax@2 -// signed int v9; // ecx@2 - //bool result; // eax@5 - int v11; // ecx@5 - //signed int v12; // ecx@6 - //char *v13; // esi@6 - RenderVertexSoft *v14; // eax@8 - RenderVertexSoft *v15; // edx@8 - Vec3_float_ a5; // [sp+18h] [bp-3Ch]@12 - //float v17; // [sp+44h] [bp-10h]@1 - //int v18; // [sp+48h] [bp-Ch]@5 - //stru9 *thisa; // [sp+4Ch] [bp-8h]@1 - int a7a; // [sp+53h] [bp-1h]@5 - //bool a6a; // [sp+70h] [bp+1Ch]@5 - - //v17 = 0.0; - //thisa = pGame->pStru9Instance; - - static RenderVertexSoft sr_vertices_50D9D8[64]; - - //result = 0; - a7a = 0; - v11 = 2 * (a6 == 0) + 1; - //a6a = 0; - //v18 = v11; - if (uNumVertices <= 0) - return false; - - //v12 = *pOutNumVertices; - //v13 = (char *)&a4->y; - - //while ( 1 ) - for ( uint i = 0; i < uNumVertices; ++i ) - { - if (i % 2) - { - v14 = a1; - v15 = sr_vertices_50D9D8; - } - else - { - v15 = a1; - v14 = sr_vertices_50D9D8; - } - if (i == uNumVertices - 1) - v14 = pVertices; - a5.x = a4[i].x; - a5.y = a4[i].y; - a5.z = a4[i].z; - pGame->pStru9Instance->CalcPortalShape(v15, *pOutNumVertices, v14, pOutNumVertices, &a5, a4[i].dot, (char *)&a7a, _unused); - //v12 = *pOutNumVertices; - if (*pOutNumVertices < v11) - { - *pOutNumVertices = 0; - return true; - } - //result = a6a; - //v13 += 24; - //if (++i >= uNumVertices) - // - } - return a7a; -} - -//----- (004371C3) -------------------------------------------------------- -bool IndoorCameraD3D::_4371C3(RenderVertexSoft *pVertices, unsigned int *pOutNumVertices, int _unused) -{ -// char *v4; // eax@2 -// signed int v5; // ecx@2 - RenderVertexSoft *v6; // esi@5 - unsigned int *v7; // edi@5 - char *v8; // ecx@6 - int v9; // eax@6 - IndoorCameraD3D *thisa; // [sp+0h] [bp-Ch]@1 - signed int v12; // [sp+4h] [bp-8h]@5 - unsigned int pVerticesa; // [sp+14h] [bp+8h]@6 - unsigned int pOutNumVerticesa; // [sp+18h] [bp+Ch]@6 - - thisa = this; - - - static RenderVertexSoft static_4371C3_array_50E5E0[64]; - static bool __init_flag1 = false; - if (!__init_flag1) - { - __init_flag1 = true; - - for (uint i = 0; i < 64; ++i) - static_4371C3_array_50E5E0[i].flt_2C = 0.0f; - } - - v12 = 0; - v6 = pVertices; - v7 = pOutNumVertices; - if ( (signed int)*pOutNumVertices > 0 ) - { - pOutNumVerticesa = (char *)static_4371C3_array_50E5E0 - (char *)pVertices; - pVerticesa = (char *)&static_4371C3_array_50E5E0[0].vWorldViewProjY - (char *)pVertices; - v8 = (char *)&static_4371C3_array_50E5E0[0].vWorldPosition.y; - v9 = (int)&v6->vWorldPosition.z; - do - { - ++v12; - *((int *)v8 - 1) = *(int *)(v9 - 8); - *(int *)v8 = *(int *)(v9 - 4); - v8 += 48; - *(float *)(pOutNumVerticesa + v9) = *(float *)v9; - *(float *)(pVerticesa + v9) = *(float *)(v9 + 28); - *(float *)((char *)&static_4371C3_array_50E5E0[0]._rhw - (char *)v6 + v9) = *(float *)(v9 + 32); - v9 += 48; - } - while ( v12 < (signed int)*v7 ); - } - return CalcPortalShape( - static_4371C3_array_50E5E0, - v7, - v6, - thisa->std__vector_000034_prolly_frustrum, - 4, - 0, - _unused); -} -// 50F1E0: using guessed type char static_sub_4371C3_byte_50F1E0_init_flags; - -//----- (00437143) -------------------------------------------------------- -void IndoorCameraD3D::_437143(unsigned int uNumInVertices, RenderVertexSoft *pOutVertices, RenderVertexSoft *pInVertices, unsigned int *pOutNumVertices) -{ - double v9; // st7@3 - - uint i = 0; - - for ( i; i < uNumInVertices; ++i ) - { - pInVertices[i]._rhw = 1.0 / (pInVertices[i].vWorldViewPosition.x + 0.0000001); - memcpy(&pOutVertices[i], &pInVertices[i], sizeof(pOutVertices[i])); - v9 = (double)pODMRenderParams->int_fov_rad * pInVertices[i]._rhw; - pOutVertices[i].vWorldViewProjX = (double)pViewport->uScreenCenterX - v9 * pInVertices[i].vWorldViewPosition.y; - pOutVertices[i].vWorldViewProjY = (double)pViewport->uScreenCenterY - v9 * pInVertices[i].vWorldViewPosition.z; - } - *pOutNumVertices = i; - return; -} - -//----- (00436F09) -------------------------------------------------------- -void IndoorCameraD3D::_436F09_mess_with_lightmap__clipflag_4(RenderVertexSoft *pInVertices, int uNumInVertices, RenderVertexSoft *pOutVertices, unsigned int *pOutNumVertices) -{ - unsigned int *pOutNumVertices_; // ebx@1 - double v6; // st7@2 - signed int v7; // esi@2 - char *v8; // edx@5 - unsigned int v9; // eax@10 - RenderVertexSoft *v10; // ecx@11 - double v11; // st6@11 - double v12; // st6@12 - unsigned int v13; // edi@14 - unsigned __int8 v14; // c2@16 - unsigned __int8 v15; // c3@16 - unsigned int v16; // edi@17 - bool a1a; // [sp+Ch] [bp+8h]@7 - int a4a; // [sp+18h] [bp+14h]@5 - - pOutNumVertices_ = pOutNumVertices; - *pOutNumVertices = 0; - if ( uNumInVertices ) - { - memcpy(&pInVertices[uNumInVertices], pInVertices, sizeof(pInVertices[uNumInVertices])); - v6 = (double)pODMRenderParams->shading_dist_mist; - v7 = 0; - if ( v6 >= pInVertices->vWorldViewPosition.x ) - v7 = 1; - if ( uNumInVertices + 1 > 1 ) - { - a4a = uNumInVertices; - v8 = (char *)&pInVertices[1].u; - do - { - a1a = v6 >= *((float *)v8 - 6); - if ( v7 == a1a ) - { - v10 = pOutVertices; - //goto LABEL_23; - } - else - { - - v9 = *pOutNumVertices_; - if (a1a) - { - v10 = pOutVertices; - v11 = (v6 - *((float *)v8 - 18)) / (*((float *)v8 - 6) - *((float *)v8 - 18)); - pOutVertices[v9].vWorldViewPosition.y = (*((float *)v8 - 5) - *((float *)v8 - 17)) * v11 + *((float *)v8 - 17); - pOutVertices[*pOutNumVertices_].vWorldViewPosition.z = (*((float *)v8 - 4) - *((float *)v8 - 16)) * v11 - + *((float *)v8 - 16); - pOutVertices[*pOutNumVertices_].u = (*(float *)v8 - *((float *)v8 - 12)) * v11 + *((float *)v8 - 12); - pOutVertices[*pOutNumVertices_].v = (*((float *)v8 + 1) - *((float *)v8 - 11)) * v11 + *((float *)v8 - 11); - } - else - { - v12 = (v6 - *((float *)v8 - 6)) / (*((float *)v8 - 18) - *((float *)v8 - 6)); - pOutVertices[v9].vWorldViewPosition.y = (*((float *)v8 - 17) - *((float *)v8 - 5)) * v12 + *((float *)v8 - 5); - pOutVertices[*pOutNumVertices_].vWorldViewPosition.z = (*((float *)v8 - 16) - *((float *)v8 - 4)) * v12 - + *((float *)v8 - 4); - pOutVertices[*pOutNumVertices_].u = (*((float *)v8 - 12) - *(float *)v8) * v12 + *(float *)v8; - pOutVertices[*pOutNumVertices_].v = (*((float *)v8 - 11) - *((float *)v8 + 1)) * v12 + *((float *)v8 + 1); - v10 = pOutVertices; - } - v10[*pOutNumVertices_].vWorldViewPosition.x = v6; - v10[*pOutNumVertices_]._rhw = 1.0 / v6; - if (v7) - { - v13 = (unsigned int)&v10[*pOutNumVertices_]; - if (*(float *)(v13 + 12) != *((float *)v8 - 18) || *(float *)(v13 + 16) != *((float *)v8 - 17)) - { - ++*pOutNumVertices_; - //goto LABEL_23; - } - else - { - v14 = 0; - v15 = *(float *)(v13 + 20) == *((float *)v8 - 16); - if (!(v15 | v14)) - { - //goto LABEL_21; - ++*pOutNumVertices_; - //goto LABEL_23; - } - } - } - else - { - v16 = (unsigned int)&v10[*pOutNumVertices_]; - if (*(float *)(v16 + 12) != *((float *)v8 - 6) || *(float *)(v16 + 16) != *((float *)v8 - 5)) - { - //LABEL_21: - ++*pOutNumVertices_; - //goto LABEL_23; - } - else - { - v14 = 0; - v15 = *(float *)(v16 + 20) == *((float *)v8 - 4); - if (!(v15 | v14)) - { - //goto LABEL_21; - ++*pOutNumVertices_; - //goto LABEL_23; - } - } - } - } - //LABEL_23: - if ( a1a ) - { - memcpy(&v10[*pOutNumVertices_], v8 - 36, sizeof(v10[*pOutNumVertices_])); - pOutVertices[*pOutNumVertices_]._rhw = 1.0 / (*((float *)v8 - 6) + 0.0000001); - pOutVertices[(*pOutNumVertices_)++].flt_2C = *((float *)v8 + 2); - } - v7 = a1a; - v8 += 48; - --a4a; - } - while ( a4a ); - } - if ( (signed int)*pOutNumVertices_ < 3 ) - *pOutNumVertices_ = 0; - } -} - -//----- (00436CDC) -------------------------------------------------------- -void IndoorCameraD3D::_436CDC_mess_with_lightmap__clipflag_2(RenderVertexSoft *pInVertices, int uNumInVertices, RenderVertexSoft *pOutVertices, unsigned int *pOutNumVertices) -{ - signed int v5; // esi@2 - char *v6; // edx@5 - unsigned int v7; // eax@10 - RenderVertexSoft *v8; // ecx@11 - double v9; // st6@11 - double v10; // st6@12 - unsigned int v11; // edi@14 - unsigned __int8 v12; // c2@16 - unsigned __int8 v13; // c3@16 - unsigned int v14; // edi@17 - bool a1a; // [sp+Ch] [bp+8h]@7 - - if ( uNumInVertices ) - { - *pOutNumVertices = 0; - memcpy(&pInVertices[uNumInVertices], pInVertices, sizeof(pInVertices[uNumInVertices])); - v5 = 0; - if ( pInVertices->vWorldViewPosition.x >= 8.0 ) - v5 = 1; - if ( uNumInVertices + 1 > 1 ) - { - v6 = (char *)&pInVertices[1].u; - do - { - a1a = *((float *)v6 - 6) >= 8.0; - if ( v5 == a1a ) - { - v8 = pOutVertices; - goto LABEL_23; - } - v7 = *pOutNumVertices; - if ( a1a ) - { - v8 = pOutVertices; - v9 = (8.0 - *((float *)v6 - 18)) / (*((float *)v6 - 6) - *((float *)v6 - 18)); - pOutVertices[v7].vWorldViewPosition.y = (*((float *)v6 - 5) - *((float *)v6 - 17)) * v9 + *((float *)v6 - 17); - pOutVertices[*pOutNumVertices].vWorldViewPosition.z = (*((float *)v6 - 4) - *((float *)v6 - 16)) * v9 - + *((float *)v6 - 16); - pOutVertices[*pOutNumVertices].u = (*(float *)v6 - *((float *)v6 - 12)) * v9 + *((float *)v6 - 12); - pOutVertices[*pOutNumVertices].v = (*((float *)v6 + 1) - *((float *)v6 - 11)) * v9 + *((float *)v6 - 11); - } - else - { - v10 = (8.0 - *((float *)v6 - 6)) / (*((float *)v6 - 18) - *((float *)v6 - 6)); - pOutVertices[v7].vWorldViewPosition.y = (*((float *)v6 - 17) - *((float *)v6 - 5)) * v10 + *((float *)v6 - 5); - pOutVertices[*pOutNumVertices].vWorldViewPosition.z = (*((float *)v6 - 16) - *((float *)v6 - 4)) * v10 - + *((float *)v6 - 4); - pOutVertices[*pOutNumVertices].u = (*((float *)v6 - 12) - *(float *)v6) * v10 + *(float *)v6; - pOutVertices[*pOutNumVertices].v = (*((float *)v6 - 11) - *((float *)v6 + 1)) * v10 + *((float *)v6 + 1); - v8 = pOutVertices; - } - v8[*pOutNumVertices].vWorldViewPosition.x = 8.0; - v8[*pOutNumVertices]._rhw = 0.125; - if ( v5 ) - { - v11 = (unsigned int)&v8[*pOutNumVertices]; - if ( *(float *)(v11 + 12) != *((float *)v6 - 18) || *(float *)(v11 + 16) != *((float *)v6 - 17) ) - goto LABEL_21; - v12 = 0; - v13 = *(float *)(v11 + 20) == *((float *)v6 - 16); - } - else - { - v14 = (unsigned int)&v8[*pOutNumVertices]; - if ( *(float *)(v14 + 12) != *((float *)v6 - 6) || *(float *)(v14 + 16) != *((float *)v6 - 5) ) - { -LABEL_21: - ++*pOutNumVertices; - goto LABEL_23; - } - v12 = 0; - v13 = *(float *)(v14 + 20) == *((float *)v6 - 4); - } - if ( !(v13 | v12) ) - goto LABEL_21; -LABEL_23: - if ( a1a ) - { - memcpy(&v8[*pOutNumVertices], v6 - 36, sizeof(v8[*pOutNumVertices])); - pOutVertices[(*pOutNumVertices)++]._rhw = 1.0 / (*((float *)v6 - 6) + 0.0000001); - } - v5 = a1a; - v6 += 48; - --uNumInVertices; - } - while ( uNumInVertices ); - } - if ( (signed int)*pOutNumVertices < 3 ) - *pOutNumVertices = 0; - } -} - -//----- (00481D77) -------------------------------------------------------- -void _outdoor_project(RenderVertexSoft *v) -{ - double v1; // st7@1 - double v2; // st7@1 - - v1 = 1.0 / (v->vWorldViewPosition.x + 0.0000001); - v->_rhw = v1; - v2 = v1 * (double)pODMRenderParams->int_fov_rad; - v->vWorldViewProjX = (double)pViewport->uScreenCenterX - v2 * v->vWorldViewPosition.y; - v->vWorldViewProjY = (double)pViewport->uScreenCenterY - v2 * v->vWorldViewPosition.z; -} - -//----- (00436BB7) -------------------------------------------------------- -void IndoorCameraD3D::Project(RenderVertexSoft *pVertices, unsigned int uNumVertices, char a4) -{ - double v7; // st7@7 - double v8; // st7@9 - double v9; // st6@10 - double v10; // st5@12 - double v11; // st7@16 - double v12; // st6@17 - double v13; // st5@19 - float uNumVerticesa; // [sp+14h] [bp+Ch]@13 - float uNumVerticesb; // [sp+14h] [bp+Ch]@20 - - for (uint i = 0; i < uNumVertices; ++i) - { - if (byte_4D864C && pGame->uFlags & 0x80 || uCurrentlyLoadedLevelType == LEVEL_Indoor) - { - v7 = 1.0 / pVertices[i].vWorldViewPosition.x; - - pVertices[i].vWorldViewProjX = pVertices[i].vWorldViewPosition.y * fov * v7 + screenCenterX; - pVertices[i].vWorldViewProjY = (signed int)pViewport->uViewportBR_Y - (pVertices[i].vWorldViewPosition.z * fov * v7 + screenCenterY); - } - else - { - extern void _outdoor_project(RenderVertexSoft *v); - _outdoor_project(pVertices + i); - } - - if ( a4 ) - { -// __debugbreak(); - v8 = (double)(signed int)pViewport->uViewportBR_X; - if ( v8 >= pVertices[i].vWorldViewProjX ) - v9 = pVertices[i].vWorldViewProjX; - else - v9 = v8; - v10 = (double)(signed int)pViewport->uViewportTL_X; - if ( v10 <= v9 ) - { - if ( v8 >= pVertices[i].vWorldViewProjX) - v8 = pVertices[i].vWorldViewProjX; - } - else - { - uNumVerticesa = v10; - v8 = uNumVerticesa; - } - pVertices[i].vWorldViewProjX = v8; - v11 = (double)(signed int)pViewport->uViewportBR_Y; - if ( v11 >= pVertices[i].vWorldViewProjY) - v12 = pVertices[i].vWorldViewProjY; - else - v12 = v11; - v13 = (double)(signed int)pViewport->uViewportTL_Y; - if ( v13 <= v12 ) - { - if ( v11 >= pVertices[i].vWorldViewProjY) - v11 = pVertices[i].vWorldViewProjY; - } - else - { - uNumVerticesb = v13; - v11 = uNumVerticesb; - } - pVertices[i].vWorldViewProjY = v11; - } - } -} - -//----- (00436A9A) -------------------------------------------------------- -void IndoorCameraD3D::Project(signed int x, signed int y, signed int z, int *a5, int *a6) -{ - double v6; // ST00_8@2 - //double v7; // ST08_8@2 - //double v8; // ST00_8@2 -// signed __int64 v9; // qtt@3 -// int v10; // ST04_4@3 - float a2a; // [sp+18h] [bp+8h]@2 - float a2b; // [sp+18h] [bp+8h]@2 - - //if ( pRenderer->pRenderD3D ) - { - v6 = 1.0 / (double)x; - a2a = (double)y * fov * v6 + screenCenterX; - //v7 = a2a + 6.7553994e15; - *a5 = floorf(a2a + 0.5f); - a2b = (double)z * fov * v6 + screenCenterY; - //v8 = a2b + 6.7553994e15; - *a6 = pViewport->uViewportBR_Y - floorf(a2b + 0.5f); - } - /*else - { - LODWORD(v9) = pBLVRenderParams->fov_rad_fixpoint << 16; - HIDWORD(v9) = pBLVRenderParams->fov_rad_fixpoint >> 16; - v10 = v9 / x; - LODWORD(v9) = pBLVRenderParams->fov_rad_fixpoint << 16; - HIDWORD(v9) = pBLVRenderParams->fov_rad_fixpoint >> 16; - *a5 = pBLVRenderParams->uViewportCenterX - - ((signed int)(((unsigned __int64)(v10 * (signed __int64)y) >> 16) + 32768) >> 16); - *a6 = pBLVRenderParams->uViewportCenterY - ((signed int)(((unsigned __int64)(v9 / x * z) >> 16) + 32768) >> 16); - }*/ -} - -//----- (00436A6D) -------------------------------------------------------- -double IndoorCameraD3D::GetPolygonMinZ(RenderVertexSoft *pVertices, unsigned int uStripType) -{ - unsigned int v3; // edx@1 - double result; // st7@1 - float *v5; // ecx@2 - - v3 = uStripType; - result = 3.402823466385289e38; - if ( (signed int)uStripType > 0 ) - { - v5 = &pVertices->vWorldPosition.z; - do - { - if ( *v5 < result ) - result = *v5; - v5 += 12; - --v3; - } - while ( v3 ); - } - return result; -} - -//----- (00436A24) -------------------------------------------------------- -struct IDirect3DTexture2 *IndoorCameraD3D::LoadTextureAndGetHardwarePtr(char *Str1) -{ - return pBitmaps_LOD->pHardwareTextures[pBitmaps_LOD->LoadTexture(Str1)]; -} - -//----- (00436A40) -------------------------------------------------------- -double IndoorCameraD3D::GetPolygonMaxZ(RenderVertexSoft *pVertex, unsigned int uStripType) -{ - double result; // st7@1 - - result = 1.1754944e-38; - for ( uint i = 0; i < uStripType; i++ ) - { - if ( pVertex[i].vWorldPosition.z > result ) - result = pVertex[i].vWorldPosition.z; - } - return result; -} - -// -- new -// merged from IndoorCamera::Initialize2 -// and ODMRenderParams::RotationToInts -// and BLVRenderParams::Reset -void IndoorCameraD3D::CalculateRotations(int camera_rot_x, int camera_rot_y) -{ - sRotationX = camera_rot_x; - sRotationY = camera_rot_y; - - fRotationYSine = sin((3.141592653589793 + 3.141592653589793) * (double)sRotationY / 2048.0); - fRotationYCosine = cos((3.141592653589793 + 3.141592653589793) * (double)sRotationY / 2048.0); - if (byte_4D864C && pGame->uFlags & 0x80 || uCurrentlyLoadedLevelType == LEVEL_Indoor) - { - fRotationXSine = sin((3.141592653589793 + 3.141592653589793) * (double)-sRotationX / 2048.0); - fRotationXCosine = cos((3.141592653589793 + 3.141592653589793) * (double)-sRotationX / 2048.0); - - int_sine_y = stru_5C6E00->Sin( pGame->pIndoorCameraD3D->sRotationY); - int_cosine_y = stru_5C6E00->Cos( pGame->pIndoorCameraD3D->sRotationY); - int_sine_x = stru_5C6E00->Sin(-pGame->pIndoorCameraD3D->sRotationX); - int_cosine_x = stru_5C6E00->Cos(-pGame->pIndoorCameraD3D->sRotationX); - } - else - { - fRotationXSine = sin((3.141592653589793 + 3.141592653589793) * (double)sRotationX / 2048.0); - fRotationXCosine = cos((3.141592653589793 + 3.141592653589793) * (double)sRotationX / 2048.0); - - int_sine_y = stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationY); - int_cosine_y = stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationY); - int_sine_x = stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationX); - int_cosine_x = stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationX); - } -} \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 IndoorCameraD3D.h --- a/IndoorCameraD3D.h Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,254 +0,0 @@ -#pragma once -#include "VectorTypes.h" - - - -/* 124 */ -#pragma pack(push, 1) -struct IndoorCameraD3D_Vec3 -{ - //----- (004C0376) -------------------------------------------------------- - inline IndoorCameraD3D_Vec3() {} - //----- (004C037F) -------------------------------------------------------- - virtual ~IndoorCameraD3D_Vec3() {} - //----- (004C039C) -------------------------------------------------------- - //void ~IndoorCameraD3D_Vec3() {} - - //void ( ***vdestructor_ptr)(IndoorCameraD3D_Vec3 *, bool); - - union - { - struct - { - float x; - float y; - float z; - }; - float v[3]; - }; -}; -#pragma pack(pop) - -/* 125 */ -#pragma pack(push, 1) -struct IndoorCameraD3D_Vec4: public IndoorCameraD3D_Vec3 -{ - //----- (00498038) -------------------------------------------------------- - inline IndoorCameraD3D_Vec4(): - IndoorCameraD3D_Vec3() - {} - - //----- (00498069) -------------------------------------------------------- - virtual ~IndoorCameraD3D_Vec4() - {} - - float dot; - int _wtf; // sizeof vec4 is 18 and first member is vdtor, but vdtor is already included in vec3 so very weird -}; -#pragma pack(pop) - - - -/* 199 */ -#pragma pack(push, 1) -struct IndoorCameraD3D_stru3 -{ - int field_0; - int field_4; - int field_8; - int field_C; - int field_10; - int field_14; - int field_18; - int field_1C; - int field_20; - int field_24; - int field_28; - int field_2C; - float flt_30; - int field_34; -}; -#pragma pack(pop) - - - -/* 197 */ -#pragma pack(push, 1) -struct IndoorCameraD3D_stru1 -{ - //----- (004363A2) -------------------------------------------------------- - IndoorCameraD3D_stru1() - { - this->flt_2C = 0.0; - } - - - int field_0; - int field_4; - int field_8; - int field_C; - int field_10; - int field_14; - int field_18; - int field_1C; - int field_20; - int field_24; - int field_28; - float flt_2C; -}; -#pragma pack(pop) - -/* 198 */ -#pragma pack(push, 1) -struct IndoorCameraD3D_stru2 -{ - unsigned int mm7__vector_000004_size; - IndoorCameraD3D_stru1 mm7__vector_000004[64]; - int field_C04; - int field_C08; - int field_C0C; -}; -#pragma pack(pop) - - - -#define BLV_RENDER_DRAW_SW_OUTLINES (1 << 0) // 1 -#define BLV_RENDER_DRAW_D3D_OUTLINES (1 << 1) // 2 -#define ODM_RENDER_DRAW_D3D_OUTLINES (1 << 2) // 4 -#define ODM_RENDER_DRAW_TERRAIN_OUTLINES (1 << 3) // 8 - -/* 123 */ -#pragma pack(push, 1) -struct IndoorCameraD3D -{ - IndoorCameraD3D(); - - //----- (004363C6) -------------------------------------------------------- - virtual ~IndoorCameraD3D() - { - //this->vdestructor_ptr = &stru8_pvdtor; - //_eh_vector_destructor_iterator_(this->std__vector_000034_prolly_frustrum, 24, 6, IndoorCameraD3D_Vec4::dtor); - //IndoorCameraD3D_Vec3::dtor(&v1->field_24); - //IndoorCameraD3D_Vec3::dtor(&v1->field_14); - //IndoorCameraD3D_Vec3::dtor(&v1->field_4); - } - - double GetPolygonMaxZ(struct RenderVertexSoft *pVertex, unsigned int uStripType); - double GetPolygonMinZ(struct RenderVertexSoft *pVertices, unsigned int uStripType); - struct IDirect3DTexture2 *LoadTextureAndGetHardwarePtr(char *Str1); - void Project(signed int x, signed int y, signed int z, int *a5, int *a6); - void Project(struct RenderVertexSoft *pVertices, unsigned int uNumVertices, char a4); - void _436CDC_mess_with_lightmap__clipflag_2(struct RenderVertexSoft *pInVertices, int uNumInVertices, struct RenderVertexSoft *pOutVertices, unsigned int *pOutNumVertices); - void _436F09_mess_with_lightmap__clipflag_4(struct RenderVertexSoft *pInVertices, int uNumInVertices, struct RenderVertexSoft *pOutVertices, unsigned int *pOutNumVertices); - void _437143(unsigned int uNumInVertices, struct RenderVertexSoft *pOutVertices, struct RenderVertexSoft *pInVertices, unsigned int *pOutNumVertices); - bool _4371C3(struct RenderVertexSoft *pVertices, unsigned int *pOutNumVertices, int _unused); - bool CalcPortalShape(struct RenderVertexSoft *a1, unsigned int *pOutNumVertices, struct RenderVertexSoft *pVertices, IndoorCameraD3D_Vec4 *a4, signed int uNumVertices, char a6, int _unused); - char _437376(struct stru154 *thisa, struct RenderVertexSoft *a2, unsigned int *pOutNumVertices); - void _4374E8_ProllyBuildFrustrum(); - void _437607(IndoorCameraD3D_Vec3 *a1, IndoorCameraD3D_Vec4 *a2); - void Vec3Transform(const IndoorCameraD3D_Vec3 *pVector, IndoorCameraD3D_Vec3 *pOut); - void CreateWorldMatrixAndSomeStuff(); - void MatrixMultiply(struct Matrix3x3_float_ *a1, struct Matrix3x3_float_ *a2, struct Matrix3x3_float_ *a3); - void PrepareAndDrawDebugOutline(struct BLVFace *pFace, unsigned int uDiffuse); - void debug_outline_sw(struct RenderVertexSoft *a2, unsigned int uNumVertices, unsigned int uDiffuse, float a5); - void debug_outline_d3d(const struct RenderVertexD3D3 *pLineVertices, unsigned int uNumLines, int uDiffuse, float z_stuff); - void do_draw_debug_line_sw(struct RenderVertexSoft *pLineBegin, signed int sStartDiffuse, struct RenderVertexSoft *pLineEnd, signed int sEndDiffuse, unsigned int uOutNumVertices, float z_stuff); - //void sr_437D4A_draw_some_vertices(float x, float y, float z, unsigned int a5, char a6, float a7); - //void sr_438141_draw_list_0037C(); - //void sr_438240_draw_lits(); - //void sr_Reset_list_0037C(); - bool is_face_faced_to_camera(struct BLVFace *pFace, struct RenderVertexSoft *a2); - bool GetFacetOrientation(char polyType, struct Vec3_float_ *a2, struct Vec3_float_ *a3, struct Vec3_float_ *a4); - void ViewTransform(struct RenderVertexSoft *a1a, unsigned int uNumVertices); - bool IsCulled(struct BLVFace *pFace); - void ViewTransfrom_OffsetUV(struct RenderVertexSoft *pVertices, unsigned int uNumVertices, struct RenderVertexSoft *pOutVertices, struct stru320 *a5); - bool ApplyViewTransform_TrueIfStillVisible_BLV(int x, int y, int z, signed int *pOutX, int *pOutZ, int *pOutY, char bDoNotShow); - float GetPickDepth(); - float GetShadingDistMist(); - - void DebugDrawPortal(struct BLVFace *pFace); - - //void ( ***vdestructor_ptr)(IndoorCameraD3D *, bool); - IndoorCameraD3D_Vec3 field_4[3]; - //IndoorCameraD3D_Vec3 field_14; - //IndoorCameraD3D_Vec3 field_24; - IndoorCameraD3D_Vec4 std__vector_000034_prolly_frustrum[6]; - float fov; - float screenCenterX; - float screenCenterY; - float fov_x; - float fov_y; - float inv_fov; - float _unused_blv_party_x; - float _unused_blv_party_y; - float _unused_blv_party_z; - char field_E8[32]; - float field_108; - float _unused_blv_party_x_2; - float _unused_blv_party_y_2; - float _unused_blv_party_z_2; - char field_118[32]; - float field_138; - char field_13C[44]; - float field_168; - char field_16C[44]; - float field_198; - char field_19C[44]; - float field_1C8; - char field_1CC[44]; - float field_1F8; - char field_1FC[44]; - float field_228; - char field_22C[44]; - float field_258; - char field_25C[44]; - float field_288; - char field_28C[44]; - float field_2B8; - float field_2BC; - float field_2C0; - float field_2C4; - char field_2C8[32]; - float field_2E8; - float field_2EC; - float field_2F0; - float field_2F4; - char field_2F8[32]; - float field_318; - float field_31C; - float field_320; - float field_324; - char field_328[32]; - float field_348; - float field_34C; - float field_350; - float field_354; - char field_358[32]; - float field_378; - IndoorCameraD3D_stru3 list_0037C[16384]; - unsigned int list_0037C_size; - IndoorCameraD3D_stru2 list_E0380[256]; - int list_E0380_size; - - - void CalculateRotations(int camera_rot_x, int camera_rot_y); - int sRotationY; // moved from 157 struct IndoorCamera::18 - int sRotationX; // moved from 157 struct IndoorCamera::14 - float fRotationYSine; // moved from 157 struct IndoorCamera::2C - float fRotationYCosine; // moved from 157 struct IndoorCamera::30 - float fRotationXSine; // moved from 157 struct IndoorCamera::34 - float fRotationXCosine; // moved from 157 struct IndoorCamera::38 - Vec3 vPartyPos; // moved from 157 struct IndoorCamera::00 - // merged from 162 struct BLVRenderParams::08 - int debug_flags; // moved from 157 struct IndoorCamera::4C - // merged from 162 struct BLVRenderParams::04 - int int_sine_y; // moved from 157 struct ODMRenderParams::1C - // merged from 162 struct BLVRenderParams::24 - int int_cosine_y; // moved from 157 struct ODMRenderParams::20 - // merged from 162 struct BLVRenderParams::20 - int int_sine_x; // moved from 157 struct ODMRenderParams::24 - // merged from 162 struct BLVRenderParams::2C - int int_cosine_x; // moved from 157 struct ODMRenderParams::28 - // merged from 162 struct BLVRenderParams::28 -}; -#pragma pack(pop) \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Items.cpp --- a/Items.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/Items.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -468,8 +468,8 @@ uAllItemsCount = 0; item_counter = 0; while (item_counter < 800) - { - test_string = strtok(NULL, "\r") + 1; + { + test_string = strtok(NULL, "\r") + 1; auto tokens = Tokenize(test_string, '\t'); item_counter=atoi(tokens[0]); uAllItemsCount=item_counter; @@ -498,7 +498,7 @@ } pItems[item_counter].uDamageMod=atoi(tokens[7]); auto findResult3 = materialMap.find(tokens[8]); - pItems[item_counter].uMaterial = findResult3 == materialMap.end() ? MATERIAL_COMMON : findResult->second; + pItems[item_counter].uMaterial = findResult3 == materialMap.end() ? MATERIAL_COMMON : findResult3->second; pItems[item_counter].uItemID_Rep_St=atoi(tokens[9]); pItems[item_counter].pUnidentifiedName = RemoveQuotes(tokens[10]); pItems[item_counter].uSpriteID=atoi(tokens[11]); @@ -1646,6 +1646,14 @@ itemId = ITEM_ARTIFACT_HEROS_BELT; NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_STRENGTH, 15); NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_ARMSMASTER, 5); + + itemId = ITEM_ARTIFACT_LADYS_ESCORT; + NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_FIRE, 10); + NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_AIR, 10); + NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_WATER, 10); + NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_EARTH, 10); + NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_MIND, 10); + NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_BODY, 10); } void ItemGen::GetItemBonusSpecialEnchantment( Player* owner, CHARACTER_ATTRIBUTE_TYPE attrToGet, int* additiveBonus, int* halfSkillBonus ) diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Keyboard.cpp --- a/Keyboard.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/Keyboard.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -7,15 +7,15 @@ #include "GUIWindow.h" #include "Game.h" -#include "Vis.h" +#include "Engine/Graphics/Vis.h" #include "MM7.h" #include "Actor.h" #include "Party.h" #include "Timer.h" #include "TurnEngine.h" -#include "Weather.h" +#include "Engine/Graphics/Weather.h" #include "CastSpellInfo.h" -#include "Indoor.h" +#include "Engine/Graphics/Indoor.h" #include "Registry.h" #include diff -r 7b076fe64f23 -r 5abd8fc8f1c6 LOD.cpp --- a/LOD.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/LOD.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -5,12 +5,12 @@ #define _CRT_SECURE_NO_WARNINGS #include "ErrorHandling.h" #include "LOD.h" -#include "Render.h" -#include "Viewport.h" +#include "Engine/Graphics/Render.h" +#include "Engine/Graphics/Viewport.h" #include "mm7_data.h" #include "ZlibWrapper.h" -#include "Sprites.h" +#include "Engine/Graphics/Sprites.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 LOD.h --- a/LOD.h Wed Sep 17 17:35:13 2014 +0600 +++ b/LOD.h Thu Sep 18 17:38:54 2014 +0600 @@ -3,7 +3,7 @@ #include #include -#include "Texture.h" +#include "Engine/Graphics/Texture.h" class Sprite; diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Level/Decoration.cpp --- a/Level/Decoration.cpp Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,184 +0,0 @@ -#define _CRTDBG_MAP_ALLOC -#include -#include - -#define _CRT_SECURE_NO_WARNINGS -#include "Decoration.h" -#include "../Party.h" -#include "../ErrorHandling.h" - -std::array pLevelDecorations; -size_t uNumLevelDecorations; -LevelDecoration* activeLevelDecoration; - -//----- (004583B0) -------------------------------------------------------- -LevelDecoration::LevelDecoration() -{ - memset(this, 0, sizeof(*this)); -} - -//----- (00450929) -------------------------------------------------------- -int LevelDecoration::GetGlobalEvent() -{ - //LevelDecoration *v1; // esi@1 - //signed int v2; // eax@1 - //int v3; // eax@5 - //int v4; // eax@6 - //int v5; // eax@7 - //int v6; // eax@8 - //int v7; // eax@9 - //int result; // eax@14 - //int v9; // eax@18 - //int v10; // eax@19 - //int v11; // eax@20 - //int v12; // eax@21 - //int v13; // eax@22 - - switch (uDecorationDescID) - { - case 0: case 1: - case 2: case 3: - return 0; - - case 4: return 16; // dec01 "Trash Pile" - case 5: return 32; // dec02 "Campfire" - case 6: return 12 + rand() % 4; // dec03 "Cauldron" - case 7: case 8: - case 9: case 10: - return 0; - - case 11: return 34; // dec08 "Fruit plate" - case 12: - return 0; - - case 13: return 17; // dec10 "Trash Pile" - case 14: return 18; // dec11 "Filth" - case 15: case 16: case 17: - case 18: case 19: case 20: - case 21: case 22: case 23: - return 0; - - case 24: return 36; // dec21 "Keg" - case 25: case 26: case 27: case 28: case 29: - case 30: case 31: case 32: case 33: - return 0; - - case 34: return 4 + rand() % 6; // dec32 "Barrel" - case 35: case 36: case 37: case 38: case 39: - case 40: case 41: case 42: case 43: case 44: case 45: case 46: case 47: case 48: case 49: - case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: case 58: case 59: - case 60: case 61: case 62: case 63: case 64: case 65: case 66: case 67: case 68: case 69: - case 70: case 71: case 72: case 73: case 74: case 75: case 76: case 77: case 78: case 79: - case 80: case 81: case 82: case 83: case 84: case 85: case 86: case 87: case 88: case 89: - case 90: case 91: case 92: case 93: case 94: case 95: case 96: case 97: case 98: case 99: - case 100: case 101: case 102: case 103: case 104: case 105: case 106: case 107: case 108: case 109: - case 110: case 111: case 112: case 113: case 114: case 115: case 116: case 117: case 118: case 119: - case 120: case 121: case 122: case 123: case 124: case 125: case 126: case 127: case 128: case 129: - case 130: case 131: case 132: case 133: case 134: case 135: case 136: case 137: case 138: case 139: - case 140: case 141: case 142: case 143: case 144: case 145: case 146: case 147: case 148: case 149: - case 150: case 151: case 152: case 153: case 154: case 155: case 156: case 157: case 158: case 159: - case 160: case 161: case 162: case 163: case 164: case 165: case 166: case 167: case 168: case 169: - case 170: case 171: case 172: case 173: case 174: case 175: case 176: case 177: case 178: case 179: - case 180: case 181: case 182: case 183: - - case 184: return 33; // dec24 "Campfire" - case 185: case 186: - return 0; - - case 187: // dec88 "Mushroom" - case 190: // dec91 "Mushroom" - return 37; - - case 188: case 189: - case 191: case 192: case 193: case 194: case 195: case 196: - case 197: case 198: case 199: case 200: case 201: case 202: - case 203: case 204: case 205: - return 0; - - case 206: return 162 + rand() % 7; // dec60 - case 207: return 169 + rand() % 7; // dec61 - case 208: return 176 + rand() % 7; // dec62 - case 209: return 183 + rand() % 7; // dec63 - case 210: return 150; // dec64 "Magic pedestal" - case 211: return 151; // dec65 "Magic pedestal" - case 212: return 152; // dec66 "Magic pedestal" - case 213: return 153; // dec67 "Magic pedestal" - case 214: return 154; // dec68 "Magic pedestal" - case 215: return 155; // dec69 "Magic pedestal" - case 216: return 156; // dec70 "Magic pedestal" - case 217: return 157; // dec71 "Magic pedestal" - case 218: return 158; // dec72 "Magic pedestal" - case 219: return 159; // dec73 "Magic pedestal" - case 220: return 160; // dec74 "Magic pedestal" - case 221: return 161; // dec75 "Magic pedestal" - - case 222: case 223: case 224: - case 225: case 226: case 227: - return 0; - - default: Error("Invalid DecorationDescID: %u", uDecorationDescID); - } -} - -//----- (0047A825) -------------------------------------------------------- -bool LevelDecoration::IsObeliskChestActive() -{ - //bool v1; // ebx@1 - //LevelDecoration *v2; // edi@1 - - static const std::array aObeliskQuests = { - PARTY_QUEST_OBELISK_HARMONDALE, - PARTY_QUEST_OBELISK_ERATHIA, - PARTY_QUEST_OBELISK_TULAREAN_FOREST, - PARTY_QUEST_OBELISK_DEYJA, - PARTY_QUEST_OBELISK_BRACADA_DESERT, - PARTY_QUEST_OBELISK_CELESTE, - PARTY_QUEST_OBELISK_THE_PIT, - PARTY_QUEST_OBELISK_EVENMORN_ISLAND, - PARTY_QUEST_OBELISK_MOUNT_NIGHON, - PARTY_QUEST_OBELISK_BARROW_DOWNS, - PARTY_QUEST_OBELISK_LAND_OF_THE_GIANTS, - PARTY_QUEST_OBELISK_TATALIA, - PARTY_QUEST_OBELISK_AVLEE, - PARTY_QUEST_OBELISK_STONE_CITY - }; - - if (pParty->uCurrentHour == 0 - && !TestPartyQuestBit(PARTY_QUEST_OBELISK_TREASURE_FOUND) - && std::all_of(aObeliskQuests.begin(), aObeliskQuests.end(), TestPartyQuestBit)) - { - this->uFlags &= ~LEVEL_DECORATION_INVISIBLE; - return true; - } - - this->uFlags |= LEVEL_DECORATION_INVISIBLE; - return false; -} - -//----- (0044C2F4) -------------------------------------------------------- -bool LevelDecoration::IsInteractive() -{ - switch (uDecorationDescID) - { - case 4: // trash pile - case 5: // campfire - case 6: // cauldron - case 11: // fruit plate - case 13: // trash pile - case 14: // dirt - case 24: // keg - case 184: // fire - case 187: // fire - case 190: // fire - return true; - } - - if (uDecorationDescID >= 206 && uDecorationDescID <= 209) // lighthouse fire - return true; - if (uDecorationDescID >= 210 && uDecorationDescID <= 221) // magic pedestal - return true; - - return false; -} - - diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Level/Decoration.h --- a/Level/Decoration.h Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -#pragma once - -#include -#include - -#include "../VectorTypes.h" - - -enum LEVEL_DECORATION_FLAGS: uint16_t -{ - LEVEL_DECORATION_TRIGGERED_BY_TOUCH = 0x01, - LEVEL_DECORATION_TRIGGERED_BY_MONSTER = 0x02, - LEVEL_DECORATION_TRIGGERED_BY_OBJECT = 0x04, - LEVEL_DECORATION_VISIBLE_ON_MAP = 0x08, - LEVEL_DECORATION_CHEST = 0x10, - LEVEL_DECORATION_INVISIBLE = 0x20, - LEVEL_DECORATION_OBELISK_CHEST = 0x40, -}; - -/* 74 */ -#pragma pack(push, 1) -struct LevelDecoration -{ - LevelDecoration(); - int GetGlobalEvent(); - bool IsInteractive(); - bool IsObeliskChestActive(); - - uint16_t uDecorationDescID; - uint16_t uFlags; - Vec3_int_ vPosition; - int32_t field_10_y_rot; - uint16_t uCog; - uint16_t uEventID; - uint16_t uTriggerRange; - int16_t field_1A; - int16_t _idx_in_stru123; - int16_t field_1E; -}; - - - -extern std::array pLevelDecorations; -extern size_t uNumLevelDecorations; -extern LevelDecoration* activeLevelDecoration; // 5C3420 -#pragma pack(pop) diff -r 7b076fe64f23 -r 5abd8fc8f1c6 LightmapBuilder.cpp --- a/LightmapBuilder.cpp Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1444 +0,0 @@ -#define _CRTDBG_MAP_ALLOC -#include -#include - -#define _CRT_SECURE_NO_WARNINGS -#include "LightmapBuilder.h" -#include "Game.h" -#include "stru314.h" -#include "Outdoor.h" -#include "Log.h" -#include "ErrorHandling.h" - -#include "Lights.h" - -#include "stru9.h" - - - - -LightsStack_StationaryLight_ *pStationaryLightsStack = new LightsStack_StationaryLight_; -//StationaryLight pStationaryLights[400]; -//int uNumStationaryLightsApplied; // weak -LightsStack_MobileLight_ *pMobileLightsStack = new LightsStack_MobileLight_; -//MobileLight pMobileLights[400]; -//int uNumMobileLightsApplied; - - - - - -//----- (0045DF13) -------------------------------------------------------- -Lightmap::Lightmap() -{ - field_C18 = 0; -} - -//----- (0045BB06) -------------------------------------------------------- -LightmapBuilder::LightmapBuilder() -{ -} - -//----- (0045BC07) -------------------------------------------------------- -bool LightmapBuilder::ApplyLights(stru320 *a2, stru154 *a3, unsigned int uNumVertices, RenderVertexSoft *a5, IndoorCameraD3D_Vec4 *a6, char uClipFlag) -{ - Vec3_int_ pos; // [sp+2Ch] [bp-40h]@21 - RenderVertexSoft *a9; // [sp+68h] [bp-4h]@8 - - if (!uNumVertices) - return false; - - static RenderVertexSoft static_69B140[64]; - - a9 = a5; - if (a6) - { - for (uint i = 0; i < uNumVertices; ++i) - memcpy(static_69B140 + i, a5 + i, sizeof(RenderVertexSoft)); - - //__debugbreak(); - if (pGame->pIndoorCameraD3D->_437376(a3, static_69B140, &uNumVertices) == 1) - { - if ( !uNumVertices ) - return false; - a9 = static_69B140; - } - } - - static stru314 static_69B110; - static_69B110.field_4.x = a3->face_plane.vNormal.x; - static_69B110.field_4.y = a3->face_plane.vNormal.y; - static_69B110.field_4.z = a3->face_plane.vNormal.z; - static_69B110.dist = a3->face_plane.dist; - if (!pGame->pIndoorCameraD3D->GetFacetOrientation(a3->polygonType, &static_69B110.field_4, - &static_69B110.field_10, &static_69B110.field_1C)) - { - MessageBoxW(nullptr, L"Error: Failed to get the facet orientation", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Light.cpp:119", 0); - ExitProcess(0); - } - - for (uint i = 0; i < a2->uNumLightsApplied; ++i) - { - pos.x = a2->_blv_lights_xs[i]; - pos.y = a2->_blv_lights_ys[i]; - pos.z = a2->_blv_lights_zs[i]; - - uint uColorR = (uint)floorf(a2->_blv_lights_rs[i] * 255.0 + 0.5f) & 0xFF, - uColorG = (uint)floorf(a2->_blv_lights_gs[i] * 255.0 + 0.5f) & 0xFF, - uColorB = (uint)floorf(a2->_blv_lights_bs[i] * 255.0 + 0.5f) & 0xFF; - uint uColor = (uColorR << 16) | (uColorG << 8) | uColorB; - if (!uColor) - uColor = 0x00FFFFF; - - if (!_45BE86_build_light_polygon(&pos, a2->_blv_lights_radii[i], uColor, a2->_blv_lights_light_dot_faces[i], - a2->_blv_lights_types[i], &static_69B110, uNumVertices, a9, uClipFlag) ) - { - MessageBoxW(nullptr, L"Error: Failed to build light polygon", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Light.cpp:138", 0); - } - } - return true; -} - -//----- (0045BE86) -------------------------------------------------------- -bool LightmapBuilder::_45BE86_build_light_polygon(Vec3_int_ *pos, float radius, unsigned int uColorMask, float dot_dist, int uLightType, stru314 *a7, unsigned int uNumVertices, RenderVertexSoft *a9, char uClipFlag) -{ - Lightmap *v11; // edi@3 - double v17; // st7@5 - double v24; // st7@6 - double v38; // st7@14 - double v39; // st7@16 - double v40; // st7@16 - int v45; // eax@24 - - if (fabsf(radius) < 1e-6f) - return true; - - v11 = uLightType & 1 ? &std__vector_000004[std__vector_000004_size] : - &std__vector_183808[std__vector_183808_size]; - flt_3C8C24 = radius - dot_dist; - flt_3C8C28 = sqrt((radius + dot_dist) * (radius - dot_dist)); - flt_3C8C2C_lightmaps_brightness = 1.0 - (radius - flt_3C8C28) / radius; - v11->field_C08 = (double)pos->x - dot_dist * a7->field_4.x; - v11->field_C0A = (double)pos->y - dot_dist * a7->field_4.y; - v11->field_C0C = (double)pos->z - dot_dist * a7->field_4.z; - - v17 = radius * flt_3C8C2C_lightmaps_brightness; - flt_3C8C30 = v17; - flt_3C8C0C = v17 * a7->field_10.x; - flt_3C8C10 = v17 * a7->field_10.y; - flt_3C8C14 = v17 * a7->field_10.z; - flt_3C8C18 = v17 * a7->field_1C.x; - flt_3C8C1C = v17 * a7->field_1C.y; - flt_3C8C20 = v17 * a7->field_1C.z; - - /* - v11->pVertices[0].vWorldPosition.x = v11->field_C08 - flt_3C8C18 + flt_3C8C0C; - v11->pVertices[0].vWorldPosition.y = v11->field_C0A - flt_3C8C1C + flt_3C8C10; - v11->pVertices[0].vWorldPosition.z = v11->field_C0C - flt_3C8C20 + flt_3C8C14; - v11->pVertices[0].u = 0.0; - v11->pVertices[0].v = 0.0; - - v11->pVertices[1].vWorldPosition.x = v11->field_C08 - flt_3C8C18 - flt_3C8C0C; - v11->pVertices[1].vWorldPosition.y = v11->field_C0A - flt_3C8C1C - flt_3C8C10; - v11->pVertices[1].vWorldPosition.z = v11->field_C0C - flt_3C8C20 - flt_3C8C14; - v11->pVertices[1].u = 0.0; - v11->pVertices[1].v = 1.0; - - v11->pVertices[2].vWorldPosition.x = v11->field_C08 + flt_3C8C18 - flt_3C8C0C; - v11->pVertices[2].vWorldPosition.y = v11->field_C0A + flt_3C8C1C - flt_3C8C10; - v11->pVertices[2].vWorldPosition.z = v11->field_C0C + flt_3C8C20 - flt_3C8C14; - v11->pVertices[2].u = 1.0; - v11->pVertices[2].v = 1.0; - - v11->pVertices[3].vWorldPosition.x = v11->field_C08 + flt_3C8C18 + flt_3C8C0C; - v11->pVertices[3].vWorldPosition.y = v11->field_C0A + flt_3C8C1C + flt_3C8C10; - v11->pVertices[3].vWorldPosition.z = v11->field_C0C + flt_3C8C20 + flt_3C8C14; - v11->pVertices[3].u = 1.0; - v11->pVertices[3].v = 0.0; - */ - - for (uint i = 0; i < 4; ++i) - { - v11->pVertices[i].vWorldPosition.x = v11->field_C08 - flt_3C8C18 + flt_3C8C0C; - v11->pVertices[i].vWorldPosition.y = v11->field_C0A - flt_3C8C1C + flt_3C8C10; - v11->pVertices[i].vWorldPosition.z = v11->field_C0C - flt_3C8C20 + flt_3C8C14; - v11->pVertices[i].u = 0.0; - v11->pVertices[i].v = 0.0; - - v24 = a7->field_4.y * v11->pVertices[i].vWorldPosition.y - + a7->field_4.z * v11->pVertices[i].vWorldPosition.z - + a7->field_4.x * v11->pVertices[i].vWorldPosition.x - + a7->dist; - - v11->pVertices[i].vWorldPosition.x -= v24 * a7->field_4.x; - v11->pVertices[i].vWorldPosition.y -= v24 * a7->field_4.y; - v11->pVertices[i].vWorldPosition.z -= v24 * a7->field_4.z; - } - - v11->uColorMask = uColorMask; - v11->uNumVertices = 4; - - if (~pGame->uFlags2 & 4) - v11->fBrightness = flt_3C8C2C_lightmaps_brightness; - else - { - Vec3_float_ a1; // [sp+2Ch] [bp-20h]@8 - a1.x = (double)pos->x - v11->field_C08; - a1.y = (double)pos->y - v11->field_C0A; - a1.z = (double)pos->z - v11->field_C0C; - a1.Normalize(); - - auto dist_x = abs(pos->x - v11->field_C08), //v31 - dist_y = abs(pos->y - v11->field_C0A), //v32 arg0a - dist_z = abs(pos->z - v11->field_C0C); //v33 _v64 - v38 = int_get_vector_length(dist_x, dist_y, dist_z); - if (v38 > radius) - return true; - //radius = (1 / radius) * v38; - if ( uLightType & 4 ) - { - //v59 = (void *)v37; - //uLightType = flt_4D86CC; - //v58 = v37; - v39 = fabs(a1.x * a7->field_4.x + a1.z * a7->field_4.z + a1.y * a7->field_4.y); - v40 = v39 * 1.0 * flt_4D86CC; - - v11->fBrightness = v40 - (1 / radius) * v38 * v40; - } - else if ( uLightType & 8 ) - { - v40 = 1.0 * 1.0; - v11->fBrightness = v40 - (1 / radius) * v38; - } - else - MessageBoxW(nullptr, L"Invalid light type!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Light.cpp:277", 0); - } - - if (!pGame->pStru9Instance->_4980B9(a9, uNumVertices, - a7->field_4.x, a7->field_4.y, a7->field_4.z, - v11->pVertices, &v11->uNumVertices)) - return false; - - //v44 = &v11->uNumVertices; - if (!v11->uNumVertices) - return true; - - v45 = _45C6D6(uNumVertices, a9, v11); - if ( v45 != uNumVertices && v45 > 0 ) - _45C4B9(uNumVertices, a9, v11); - //v59 = v11->uNumVertices; - //v46 = (RenderVertexSoft *)pLightmapVertices_; - pGame->pIndoorCameraD3D->ViewTransform(v11->pVertices, v11->uNumVertices); - //v59 = 0; - //v58 = v11->uNumVertices; - pGame->pIndoorCameraD3D->Project(v11->pVertices, v11->uNumVertices, 0); - - unsigned int _a4 = 0; - if ( !(uClipFlag & 1) ) - _a4 = 1; - else if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor) - { - if ( uClipFlag & 2 ) - { - //v59 = &a4; - //v58 = (unsigned int)field_3C8C34; - //v57 = *v44; - pGame->pIndoorCameraD3D->_436CDC_mess_with_lightmap__clipflag_2(v11->pVertices, v11->uNumVertices, field_3C8C34, &_a4); - - //v59 = v44; - //v58 = (unsigned int)field_3C8C34; - //v57 = (int)v46; - //v56 = a4; - pGame->pIndoorCameraD3D->_437143(_a4, v11->pVertices, field_3C8C34, &v11->uNumVertices); - } - else if ( uClipFlag & 4 ) - { - //v59 = &a4; - //v58 = (unsigned int)field_3C8C34; - //v57 = *v44; - pGame->pIndoorCameraD3D->_436F09_mess_with_lightmap__clipflag_4(v11->pVertices, v11->uNumVertices, field_3C8C34, &_a4); - - //v59 = v44; - //v58 = (unsigned int)field_3C8C34; - //v57 = (int)v46; - //v56 = a4; - pGame->pIndoorCameraD3D->_437143(_a4, v11->pVertices, field_3C8C34, &v11->uNumVertices); - } - else - MessageBoxW(nullptr, L"Undefined clip flag specified", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Light.cpp:330", 0); - } - else - MessageBoxW(nullptr, L"Lightpoly builder native indoor clipping not implemented", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Light.cpp:335", 0); - - if (_a4) - { - if (uLightType & 1) - { - //v48 = (char *)&std__vector_000004_size; - //v49 = std__vector_000004_size; - //v51 = __OFSUB__(std__vector_000004_size, 511); - //v50 = std__vector_000004_size - 511 < 0; - if (std__vector_000004_size < 512 - 1) - ++std__vector_000004_size; - } - else - { - //v48 = (char *)&std__vector_183808_size; - //v49 = std__vector_183808_size; - //v51 = __OFSUB__(std__vector_183808_size, 767); - //v50 = std__vector_183808_size - 767 < 0; - if (std__vector_183808_size < 768 - 1) - ++std__vector_183808_size; - } - //if ( v50 ^ v51 ) - // *(unsigned int *)v48 = v49 + 1; - } - return true; -} - -//----- (0045C4B9) -------------------------------------------------------- -int LightmapBuilder::_45C4B9(int a2, RenderVertexSoft *a3, Lightmap *pLightmap) -{ - Lightmap *v4; // edi@1 - int v5; // eax@1 - signed int v6; // ecx@1 - RenderVertexSoft *v7; // ebx@2 - int v8; // edx@3 - RenderVertexSoft *v9; // esi@3 - int v10; // eax@6 -// char *v11; // edi@7 - RenderVertexSoft *v12; // ecx@8 - char v13; // bl@17 - signed int v14; // edx@17 - double v15; // st6@18 - double v16; // st6@21 - double v17; // st6@24 - signed int v18; // edx@33 - int v20; // [sp+4h] [bp-1Ch]@3 - //int v21; // [sp+8h] [bp-18h]@8 - float v22; // [sp+Ch] [bp-14h]@23 - float v23; // [sp+10h] [bp-10h]@20 - int v24; // [sp+14h] [bp-Ch]@1 - RenderVertexSoft *v25; // [sp+18h] [bp-8h]@2 - char v26; // [sp+1Eh] [bp-2h]@17 - char v27; // [sp+1Fh] [bp-1h]@17 - - //__debugbreak();//Ritor1: needed cleaning - - v4 = pLightmap; - v5 = 0; - v6 = pLightmap->uNumVertices; - v24 = 0; - if ( v6 > 0 ) - { - v7 = pLightmap->pVertices; - v25 = pLightmap->pVertices; - do - { - v20 = v5 + 1; - v8 = (v5 + 1) % v6; - v9 = &v4->pVertices[v8]; - if ( v7->vWorldPosition.x != v9->vWorldPosition.x - || v7->vWorldPosition.y != v4->pVertices[v8].vWorldPosition.y - || v7->vWorldPosition.z != v4->pVertices[v8].vWorldPosition.z ) - { - //v10 = 0; - if ( a2 > 0 ) - { - //v11 = (char *)&a3->vWorldPosition.z; - for ( v10 = 1; v10 <= a2; ++v10 ) - { - //v21 = v10 + 1; - v12 = &a3[v10 % a2]; - if ((a3[v10].vWorldPosition.x != v12->vWorldPosition.x - || a3[v10].vWorldPosition.y != v12->vWorldPosition.y || a3[v10].vWorldPosition.z != v12->vWorldPosition.z) - && v7->vWorldPosition.x == a3[v10].vWorldPosition.x - && v7->vWorldPosition.y == a3[v10].vWorldPosition.y && v7->vWorldPosition.z == a3[v10].vWorldPosition.z - && (v9->vWorldPosition.x != v12->vWorldPosition.x - || v9->vWorldPosition.y != v12->vWorldPosition.y || v9->vWorldPosition.z != v12->vWorldPosition.z) ) - { - v13 = 0; - v14 = 0; - v27 = 0; - v26 = 0; - if ( v9->vWorldPosition.x <= (double)v12->vWorldPosition.x ) - v15 = v12->vWorldPosition.x - v9->vWorldPosition.x; - else - v15 = v9->vWorldPosition.x - v12->vWorldPosition.x; - v23 = v15; - - if ( v9->vWorldPosition.y <= (double)v12->vWorldPosition.y ) - v16 = v12->vWorldPosition.y - v9->vWorldPosition.y; - else - v16 = v9->vWorldPosition.y - v12->vWorldPosition.y; - v22 = v16; - - if ( v9->vWorldPosition.z <= (double)v12->vWorldPosition.z ) - v17 = v12->vWorldPosition.z - v9->vWorldPosition.z; - else - v17 = v9->vWorldPosition.z - v12->vWorldPosition.z; - if ( v23 < 1.0 ) - { - v13 = 1; - v14 = 1; - } - if ( v22 < 1.0 ) - { - v27 = 1; - ++v14; - } - if ( v17 < 1.0 ) - { - v26 = 1; - ++v14; - } - if ( v14 > 1 ) - { - v18 = 0; - if ( v13 && v9->vWorldPosition.x != v12->vWorldPosition.x ) - { - v18 = 1; - v9->vWorldPosition.x = v12->vWorldPosition.x; - } - if ( v27 && v9->vWorldPosition.y != v12->vWorldPosition.y ) - { - ++v18; - v9->vWorldPosition.y = v12->vWorldPosition.y; - } - if ( v26 && v9->vWorldPosition.z != v12->vWorldPosition.z ) - { - ++v18; - v9->vWorldPosition.z = v12->vWorldPosition.z; - } - if ( v18 > 0 ) - ++v24; - } - v7 = v25; - } - //++v10; - //v11 += 48; - } - //while ( v21 < a2 ); - v4 = pLightmap; - } - } - v5 = v20; - v6 = v4->uNumVertices; - ++v7; - v25 = v7; - } - while ( v20 < v6 ); - } - return v24; -} - -//----- (0045C6D6) -------------------------------------------------------- -int LightmapBuilder::_45C6D6(int a2, RenderVertexSoft *a3, Lightmap *pLightmap) -{ - signed int v6; // esi@1 - double v9; // st7@6 - double v10; // st6@10 - double v11; // st5@14 - double v12; // st7@17 - int v15; // [sp+Ch] [bp-8h]@1 - float v16; // [sp+10h] [bp-4h]@1 - - v6 = -1; - v16 = 3.4028235e38; - v15 = 0; - if ( (signed int)pLightmap->uNumVertices > 0 ) - { - for ( uint i = 0; i < (signed int)pLightmap->uNumVertices; ++i ) - { - if ( a2 > 0 ) - { - for ( uint j = 0; j < a2; ++j ) - { - if ( pLightmap->pVertices[i].vWorldPosition.x <= (double)a3[j].vWorldPosition.x ) - v9 = a3[j].vWorldPosition.x - pLightmap->pVertices[i].vWorldPosition.x; - else - v9 = pLightmap->pVertices[i].vWorldPosition.x - a3[j].vWorldPosition.x; - if ( v9 < 2.0 ) - { - v10 = pLightmap->pVertices[i].vWorldPosition.y <= (double)a3[j].vWorldPosition.y - ? a3[j].vWorldPosition.y - pLightmap->pVertices[i].vWorldPosition.y - : pLightmap->pVertices[i].vWorldPosition.y - a3[j].vWorldPosition.y; - if ( v10 < 2.0 ) - { - v11 = pLightmap->pVertices[i].vWorldPosition.z <= (double)a3[j].vWorldPosition.z - ? a3[j].vWorldPosition.z - pLightmap->pVertices[i].vWorldPosition.z - : pLightmap->pVertices[i].vWorldPosition.z - a3[j].vWorldPosition.z; - if ( v11 < 2.0 ) - { - v12 = v9 + v11 + v10; - if ( v12 < v16 ) - { - v16 = v12; - v6 = j; - } - } - } - } - } - if ( v6 != -1 ) - { - ++v15; - pLightmap->pVertices[i].vWorldPosition.x = a3[v6].vWorldPosition.x; - pLightmap->pVertices[i].vWorldPosition.y = a3[v6].vWorldPosition.y; - pLightmap->pVertices[i].vWorldPosition.z = a3[v6].vWorldPosition.z; - } - } - v6 = -1; - v16 = 3.4028235e38; - } - } - return v15; -} - -//----- (0045C7F6) -------------------------------------------------------- -bool LightmapBuilder::ApplyLights_IndoorFace(unsigned int uFaceID) -{ - BLVFace* pFace = &pIndoor->pFaces[uFaceID]; - BLVSector* pSector = &pIndoor->pSectors[pFace->uSectorID]; - - stru_F8AD28.uCurrentAmbientLightLevel = (stru_F8AD28.uDefaultAmbientLightLevel + pSector->uMinAmbientLightLevel) << 16; - - uint uNumLightsApplied = 0; - for (uint i = 0; i < pMobileLightsStack->uNumLightsActive; ++i) - { - if (uNumLightsApplied >= 20) - break; - - ApplyLight_BLV((StationaryLight *)(pMobileLightsStack->pLights + i), pFace, &uNumLightsApplied, true, 0); - } - - for (uint i = 0; i < pSector->uNumLights; ++i) - { - if (uNumLightsApplied >= 20 ) - break; - - BLVLightMM7* pLight = &pIndoor->pLights[pSector->pLights[i]]; - if (~pLight->uAtributes & 0x08) - ApplyLight_BLV((StationaryLight *)pLight, pFace, &uFaceID, false, &_4E94D0_light_type); - } - - for (uint i = 0; i < pStationaryLightsStack->uNumLightsActive; ++i) - { - if (uNumLightsApplied >= 20) - break; - - ApplyLight_BLV(pStationaryLightsStack->pLights + i, pFace, &uNumLightsApplied, false, &_4E94D0_light_type); - } - - stru_F8AD28.uNumLightsApplied = uNumLightsApplied; - return true; -} - -//----- (0045C911) -------------------------------------------------------- -bool LightmapBuilder::ApplyLight_BLV(StationaryLight *pLight, BLVFace *a2, unsigned int *pSlot, bool bLightBackfaces, char *a5) -{ - double v13; // st7@8 - - if (!pLight->uRadius) - return false; - - if (pLight->vPosition.x > a2->pBounding.x1 - pLight->uRadius && - pLight->vPosition.x < a2->pBounding.x2 + pLight->uRadius && - pLight->vPosition.y > a2->pBounding.y1 - pLight->uRadius && - pLight->vPosition.y < a2->pBounding.y2 + pLight->uRadius && - pLight->vPosition.z > a2->pBounding.z1 - pLight->uRadius && - pLight->vPosition.z < a2->pBounding.z2 + pLight->uRadius) - { - v13 = (double)pLight->vPosition.z * a2->pFacePlane.vNormal.z + - (double)pLight->vPosition.y * a2->pFacePlane.vNormal.y + - (double)pLight->vPosition.x * a2->pFacePlane.vNormal.x + - a2->pFacePlane.dist; - if ((bLightBackfaces || v13 >= 0.0f) && fabsf(v13) <= pLight->uRadius) - { - unsigned int slot = *pSlot; - - stru_F8AD28._blv_lights_radii[slot] = pLight->uRadius; - stru_F8AD28._blv_lights_inv_radii[slot] = 65536 / pLight->uRadius; - stru_F8AD28._blv_lights_xs[slot] = pLight->vPosition.x; - stru_F8AD28._blv_lights_ys[slot] = pLight->vPosition.y; - stru_F8AD28._blv_lights_zs[slot] = pLight->vPosition.z; - stru_F8AD28._blv_lights_rs[slot] = (double)pLight->uLightColorR / 255.0f; - stru_F8AD28._blv_lights_gs[slot] = (double)pLight->uLightColorG / 255.0f; - stru_F8AD28._blv_lights_bs[slot] = (double)pLight->uLightColorB / 255.0f; - stru_F8AD28._blv_lights_light_dot_faces[slot] = abs((int)floorf(v13 + 0.5f)); - stru_F8AD28._blv_lights_types[slot] = pLight->uLightType; - - *pSlot += 1; - return true; - } - } - - return false; -} - -//----- (0045CA88) -------------------------------------------------------- -int LightmapBuilder::_45CA88(stru320 *a2, RenderVertexSoft *a3, int a4, Vec3_float_ *pNormal) -{ - int result; // eax@1 - stru320 *v6; // ecx@2 - RenderVertexSoft *v7; // ebx@2 - double v8; // st7@2 - double v9; // st6@2 - char *v10; // eax@3 - double v11; // st7@5 - __int64 v12; // ST2C_8@5 - float v13; // edx@5 - int v14; // eax@5 - float v15; // ST10_4@5 - Vec3_float_ v16; // ST00_12@5 - double v17; // st7@5 - int a5; // [sp+2Ch] [bp-1Ch]@1 - float v19; // [sp+30h] [bp-18h]@1 - float v20; // [sp+34h] [bp-14h]@1 - //LightmapBuilder *thisa; // [sp+38h] [bp-10h]@1 - int v22; // [sp+3Ch] [bp-Ch]@1 - int *j; // [sp+40h] [bp-8h]@3 - int i; // [sp+44h] [bp-4h]@1 - int a3a; // [sp+58h] [bp+10h]@2 - - __debugbreak();//Ritor1: needed cleaning - - *(float *)&a5 = 0.0; - v19 = 0.0; - //thisa = this; - v20 = 0.0; - result = _45CBD4(a3, a4, dword_69B010.data(), &v22); - for ( i = 0; i < v22; result = i ) - { - v6 = a2; - a3a = 0; - v7 = &a3[dword_69B010[i]]; - v8 = v7->vWorldPosition.z; - v9 = v7->vWorldPosition.y; - *(float *)&a5 = v7->vWorldPosition.x; - v19 = v9; - v20 = v8; - v7->flt_2C = 0.0; - if ( a2->uNumLightsApplied > 0 ) - { - v10 = (char *)a2->_blv_lights_ys; - for ( j = a2->_blv_lights_ys; ; v10 = (char *)j ) - { - v11 = (double)*((signed int *)v10 - 60); - LODWORD(v12) = *((unsigned int *)v10 - 20); - HIDWORD(v12) = *(unsigned int *)v10; - LODWORD(v13) = *((unsigned int *)v10 + 60); - v14 = a3a; - LOBYTE(v14) = v6->_blv_lights_types[a3a]; - v15 = v11; - *(_QWORD *)&v16.x = v12; - v16.z = v13; - v17 = _45CC0C_light(v16/*COERCE_VEC3_FLOAT_(v16.x)*/, 1.0, v15, pNormal, *(float *)&a5/*COERCE_FLOAT(&a5)*/, v14) - + v7->flt_2C; - ++a3a; - ++j; - v7->flt_2C = v17; - if ( a3a >= a2->uNumLightsApplied ) - break; - v6 = a2; - } - } - ++i; - } - return result; -} - -//----- (0045CB89) -------------------------------------------------------- -int LightmapBuilder::_45CB89(RenderVertexSoft *a1, int a2) -{ - int v3; // edx@1 - int result; // eax@2 - char *v5; // ecx@2 - double v6; // st7@4 - __int16 v7; // fps@4 - char v8; // c0@4 - char v9; // c2@4 - char v10; // c3@4 - double v11; // st7@5 - double v12; // st7@6 - __int16 v13; // fps@6 - char v14; // c0@6 - char v15; // c2@6 - char v16; // c3@6 - - v3 = a2; - if ( a2 > 0 ) - { - HIWORD(result) = HIWORD(a1); - v5 = (char *)&a1->flt_2C; - do - { - __debugbreak(); // warning C4700: uninitialized local variable 'v7' used - if ( *(float *)v5 < 0.0 - || (v6 = *(float *)v5, /*UNDEF(v7),*/ v8 = 1.0 < v6, v9 = 0, v10 = 1.0 == v6, LOWORD(result) = v7, v6 <= 1.0) ) - { - v12 = *(float *)v5; - //UNDEF(v13); - v14 = 0.0 < v12; - v15 = 0; - v16 = 0.0 == v12; - __debugbreak(); // warning C4700: uninitialized local variable 'v13' used - LOWORD(result) = v13; - if ( v12 >= 0.0 ) - v11 = *(float *)v5; - else - v11 = 0.0; - } - else - { - v11 = 1.0; - } - *(float *)v5 = v11; - v5 += 48; - --v3; - } - while ( v3 ); - } - return result; -} - -//----- (0045CBD4) -------------------------------------------------------- -int LightmapBuilder::_45CBD4(RenderVertexSoft *a2, int a3, int *a4, int *a5) -{ - int result; // eax@1 - int v6; // edx@1 - int v7; // ecx@2 - int v8; // esi@2 - - result = (int)a5; - v6 = 0; - for ( *a5 = 0; v6 < a3; ++v6 ) - { - v7 = *a5; - v8 = 0; - if ( *a5 <= 0 ) - { -//LABEL_5: - a4[v7] = v6; - ++*a5; - } - else - { - while ( a4[v8] != v6 ) - { - ++v8; - if (v8 >= v7) - { - a4[v7] = v6; - ++*a5; - break; - //goto LABEL_5; - } - } - } - } - return result; -} - -//----- (0045CC0C) -------------------------------------------------------- -double LightmapBuilder::_45CC0C_light(Vec3_float_ a1, float a2, float a3, Vec3_float_ *pNormal, float a5, int uLightType) -{ - float v7; // esi@1 - int v8; // eax@1 -// int v9; // ebx@1 -// unsigned int v10; // ecx@1 -// int v11; // edx@2 -// int v12; // edx@4 -// unsigned int v13; // edx@6 - double v14; // st7@7 - double result; // st7@8 - double v16; // st7@9 - int v17; // esi@9 - const char *v18; // ecx@9 - double v19; // st7@10 - double v20; // st7@10 - std::string v21; // [sp-10h] [bp-40h]@13 - const char *v22[6]; // [sp+0h] [bp-30h]@10 - double v23; // [sp+18h] [bp-18h]@1 -// double v24; // [sp+20h] [bp-10h]@1 - int v25; // [sp+28h] [bp-8h]@1 - int v26; // [sp+2Ch] [bp-4h]@1 - - v7 = a5; - LODWORD(a5) = *(unsigned int *)(LODWORD(a5) + 8); - //v24 = a5 + 6.7553994e15; - v26 = floorf(a5 + 0.5f);//LODWORD(v24); - LODWORD(a5) = *(unsigned int *)(LODWORD(v7) + 4); - //v24 = a5 + 6.7553994e15; - auto _v24 = floorf(a5 + 0.5f); - LODWORD(a5) = *(unsigned int *)LODWORD(v7); - //v23 = a5 + 6.7553994e15; - auto _v23 = floorf(a5 + 0.5f); - //*(_QWORD *)((char *)&v24 + 4) = __PAIR__(LODWORD(v24), LODWORD(v23)); - v26 = abs((signed)LODWORD(a1.z) - v26); - //v25 = abs((signed)LODWORD(a1.y) - (signed)LODWORD(v24)); - //v8 = abs((int)a1.x - (signed)LODWORD(v23)); - v25 = abs((signed)LODWORD(a1.y) - (signed)_v24); - v8 = abs((int)a1.x - (signed)_v23); - v14 = int_get_vector_length(v26, v25, v8); - if ( v14 <= a3 ) - { - a5 = v14 / a3; - v16 = (double)(signed int)a1.x; - *(float *)&v23 = (double)SLODWORD(a1.y); - LODWORD(a1.x) = *(unsigned int *)LODWORD(v7); - v17 = LODWORD(v7) + 4; - *((float *)&v23 + 1) = (double)SLODWORD(a1.z); - LODWORD(a1.y) = *(unsigned int *)v17; - LODWORD(a1.z) = *(unsigned int *)(v17 + 4); - a3 = *((float *)&v23 + 1) - a1.z; - a1.z = a3; - a1.x = v16 - a1.x; - a1.y = (float)v23 - a1.y; - a1.Normalize(); - if ( uLightType & 4 ) - { - __debugbreak(); // warning C4700: uninitialized local variable 'v18' used - v22[1] = v18; - uLightType = dword_4D86D8; - v22[0] = v18; - v19 = fabs(a1.z * pNormal->z + a1.y * pNormal->y + a1.x * pNormal->x); - v20 = v19 * *(float *)&uLightType * a2; - } - else - { - if ( uLightType & 8 ) - { - v20 = 1.3 * a2; - } - else - { - MessageBoxW(nullptr, L"Invalid light type detected!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Light.cpp:783", 0); - v20 = *(float *)&uLightType; - } - } - result = v20 - a5 * v20; - } - else - { - result = 0.0; - } - return result; -} -// 4D86D8: using guessed type int dword_4D86D8; - -//----- (0045CDB7) -------------------------------------------------------- -bool LightmapBuilder::ApplyLights_OutdoorFace(ODMFace *pFace) -{ - int v3; // eax@1 - bool result; // eax@9 - int pSlot; // [sp+10h] [bp-4h]@1 - - v3 = stru_F8AD28.uDefaultAmbientLightLevel + pFace->uShadeType; - pSlot = 0; - stru_F8AD28.uCurrentAmbientLightLevel = v3 << 16; - for ( uint i = 0; i < pMobileLightsStack->uNumLightsActive; ++i ) - { - if ( pSlot >= 20 ) - break; - ApplyLight_ODM((StationaryLight *)pMobileLightsStack[i].pLights, pFace, (unsigned int *)&pSlot, 1); - } - for ( uint i = 0; i < pStationaryLightsStack->uNumLightsActive; ++i ) - { - if ( pSlot >= 20 ) - break; - ApplyLight_ODM(&pStationaryLightsStack->pLights[i], pFace, (unsigned int *)&pSlot, 0); - } - result = pSlot; - stru_F8AD28.uNumLightsApplied = pSlot; - return true; -} - -//----- (0045CE50) -------------------------------------------------------- -bool LightmapBuilder::ApplyLight_ODM(StationaryLight *pLight, ODMFace *pFace, unsigned int *pSlot, char a4) -{ - int result; // eax@0 - int v10; // ecx@8 - //unsigned int v12; // ebx@11 - //RenderD3D *v13; // ecx@11 - char v14; // dl@11 - - //__debugbreak(); - - result = (int)pFace; - v10 = (pFace->pFacePlane.dist - + pLight->vPosition.x * pFace->pFacePlane.vNormal.x - + pLight->vPosition.y * pFace->pFacePlane.vNormal.y - + pLight->vPosition.z * pFace->pFacePlane.vNormal.z) >> 16; - if ( pLight->uRadius > 0 - && (pLight->vPosition.x > pFace->pBoundingBox.x1 - pLight->uRadius) && pLight->vPosition.x < pLight->uRadius + pFace->pBoundingBox.x2 - && (pLight->vPosition.y > pFace->pBoundingBox.y1 - pLight->uRadius) && pLight->vPosition.y < pLight->uRadius + pFace->pBoundingBox.y2 - && (pLight->vPosition.z > pFace->pBoundingBox.z1 - pLight->uRadius) && pLight->vPosition.z < pLight->uRadius + pFace->pBoundingBox.z2 - && ((a4) || v10 >= 0) && v10 <= pLight->uRadius ) - { - stru_F8AD28._blv_lights_radii[*pSlot] = pLight->uRadius; - stru_F8AD28._blv_lights_inv_radii[*pSlot] = 65536 / pLight->uRadius; - stru_F8AD28._blv_lights_xs[*pSlot] = pLight->vPosition.x; - stru_F8AD28._blv_lights_ys[*pSlot] = pLight->vPosition.y; - stru_F8AD28._blv_lights_zs[*pSlot] = pLight->vPosition.z; - stru_F8AD28._blv_lights_rs[*pSlot] = (double)pLight->uLightColorR * 0.0039215689; - stru_F8AD28._blv_lights_gs[*pSlot] = (double)pLight->uLightColorG * 0.0039215689; - stru_F8AD28._blv_lights_bs[*pSlot] = (double)pLight->uLightColorB * 0.0039215689; - //v11 = abs(v10); - //v12 = pRenderer->bUsingSpecular; - stru_F8AD28._blv_lights_light_dot_faces[*pSlot] = abs(v10); - stru_F8AD28._blv_lights_types[*pSlot] = pLight->uLightType; - //v13 = pRenderer->pRenderD3D; - v14 = stru_F8AD28._blv_lights_types[*pSlot]; - if ( /*pRenderer->pRenderD3D &&*/ pRenderer->bUsingSpecular && v14 & 4 ) - v14 = _4E94D2_light_type; - stru_F8AD28._blv_lights_types[*pSlot] = v14; - result = 4 * *pSlot; - if ( /*v13*/true && pRenderer->bUsingSpecular ) - { - if ( stru_F8AD28._blv_lights_types[*pSlot] & 4 ) - { - *(float *)((char *)stru_F8AD28._blv_lights_rs + result) = *(float *)((char *)stru_F8AD28._blv_lights_rs + result) - * 0.33000001; - *(float *)((char *)stru_F8AD28._blv_lights_gs + result) = *(float *)((char *)stru_F8AD28._blv_lights_gs + result) - * 0.33000001; - *(float *)((char *)stru_F8AD28._blv_lights_bs + result) = *(float *)((char *)stru_F8AD28._blv_lights_bs + result) - * 0.33000001; - } - } - ++*pSlot; - LOBYTE(result) = 1; - } - else - LOBYTE(result) = 0; - return result; -} -// 4E94D2: using guessed type char _4E94D2_light_type; - -//----- (0045D036) -------------------------------------------------------- -bool LightmapBuilder::StackLights_TerrainFace(Vec3_float_ *pNormal, float *a2, RenderVertexSoft *a3, unsigned int uStripType, bool bLightBackfaces) -{ - /*int v6; // esi@1 - //LightmapBuilder *v7; // edi@1 - MobileLight *v8; // ebx@2 - int v9; // esi@5 - StationaryLight *v10; // ebx@6 - //bool result; // eax@9 - unsigned int a7; // [sp+Ch] [bp-4h]@1 - - v6 = 0; - //v7 = this; - a7 = 0; - stru_F8AD28.uCurrentAmbientLightLevel = pOutdoor->field_CBC_terrain_triangles_shade_type; - if ( pMobileLightsStack->uNumLightsActive > 0 ) - { - v8 = pMobileLightsStack->pLights; - do - { - if ( (signed int)a7 >= 20 ) - break; - StackLight_TerrainFace((StationaryLight *)v8, pNormal, a3, a1, uStripType, bLightBackfaces, &a7); - ++v6; - ++v8; - } - while ( v6 < pMobileLightsStack->uNumLightsActive ); - } - v9 = 0; - if ( pStationaryLightsStack->uNumLightsActive > 0 ) - { - v10 = pStationaryLightsStack->pLights; - do - { - if ( (signed int)a7 >= 20 ) - break; - StackLight_TerrainFace(v10, pNormal, a3, a1, uStripType, bLightBackfaces, &a7); - ++v9; - ++v10; - } - while ( v9 < pStationaryLightsStack->uNumLightsActive ); - } - - stru_F8AD28.uNumLightsApplied = a7; - return true;*/ -// bool __stdcall sub_45D036(struct Vec3 *pNormal, int a2, struct RenderVertex *a3, int a4, signed int X) -//{ -// float v6; // ebx@2 - unsigned int v10; // [sp+Ch] [bp-4h]@1 - int i; - - v10 = 0; - stru_F8AD28.uCurrentAmbientLightLevel = pOutdoor->max_terrain_dimming_level; - for (i = 0; i < pMobileLightsStack->uNumLightsActive; ++i) - { - if ( v10 >= 20 ) - break; - StackLight_TerrainFace((StationaryLight *)&pMobileLightsStack->pLights[i], pNormal, a2, a3, uStripType, bLightBackfaces, &v10); - } - - for (i = 0; i < pStationaryLightsStack->uNumLightsActive; ++i) - { - if ( v10 >= 20 ) - break; - StackLight_TerrainFace(&pStationaryLightsStack->pLights[i], pNormal, a2, a3, uStripType, bLightBackfaces, &v10); - } - - stru_F8AD28.uNumLightsApplied = v10; - return true; - -} -// 519AB4: using guessed type int uNumStationaryLightsApplied; - -//----- (0045D0D5) -------------------------------------------------------- -bool LightmapBuilder::StackLight_TerrainFace(StationaryLight *pLight, Vec3_float_ *pNormal, float *a3, RenderVertexSoft *a1, unsigned int uStripType, int X, unsigned int *pSlot) -{ - StationaryLight *v8; // edi@1 - bool result; // eax@1 -// unsigned int v10; // esi@2 - RenderVertexSoft *v11; // ebx@2 - float v12; // eax@3 - float v13; // eax@4 -// double v14; // st7@11 - double maxz; // st7@11 - double v16; // st7@11 - double v17; // st6@11 -// __int16 v18; // fps@11 -// char v19; // c0@11 - char v20; // c2@11 -// char v21; // c3@11 -// double v22; // st6@12 -// __int16 v23; // fps@12 -// char v24; // c0@12 -// char v25; // c2@12 -// char v26; // c3@12 -// double v27; // st7@13 -// double v28; // st6@13 -// __int16 v29; // fps@13 -// char v30; // c0@13 -// char v31; // c2@13 -// char v32; // c3@13 -// double v33; // st6@14 -// __int16 v34; // fps@14 -// char v35; // c0@14 -// char v36; // c2@14 -// char v37; // c3@14 -// double v38; // st7@15 -// double v39; // st6@15 -// __int16 v40; // fps@15 -// char v41; // c0@15 -// char v42; // c2@15 -// char v43; // c3@15 -// double v44; // st6@16 -// __int16 v45; // fps@16 -// char v46; // c0@16 -// char v47; // c2@16 -// char v48; // c3@16 - Vec3_float_ *v49; // esi@17 -// double v50; // st7@17 -// double v51; // st6@17 - signed int v52; // ecx@17 - unsigned int *v53; // esi@18 - int v54; // eax@18 - unsigned int v55; // ebx@18 - //RenderD3D *v56; // ecx@18 - char v57; // dl@18 - std::string v58; // [sp-18h] [bp-38h]@10 - const char *v59; // [sp-8h] [bp-28h]@10 - signed int v60; // [sp-4h] [bp-24h]@10 - double v61; // [sp+Ch] [bp-14h]@11 - float minz; // [sp+14h] [bp-Ch]@11 - int v63; // [sp+18h] [bp-8h]@1 - float v64; // [sp+1Ch] [bp-4h]@5 - - v8 = pLight; - result = pLight->uRadius; - v63 = pLight->uRadius; - if ( result <= 0 ) - return 0; - //v10 = uStripType; - v11 = a1; - if ( uStripType == 4 ) - { - pLight = (StationaryLight *)LODWORD(a1->vWorldPosition.x); - v12 = a1[3].vWorldPosition.x; - //uStripType = LODWORD(v12); - a1 = (RenderVertexSoft *)LODWORD(a1[1].vWorldPosition.y); - v13 = v11->vWorldPosition.y; - } - else - { - if ( uStripType != 3 ) - { - MessageBoxW(nullptr, L"Uknown strip type detected!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Light.cpp:981", 0); - //goto LABEL_11; - } - else if ((unsigned char)X) - { - pLight = (StationaryLight *)LODWORD(a1->vWorldPosition.x); - uStripType = LODWORD(a1[2].vWorldPosition.x); - a1 = (RenderVertexSoft *)LODWORD(a1[1].vWorldPosition.y); - v13 = v11[2].vWorldPosition.y; - v64 = v13; - //goto LABEL_11; - //goto LABEL_5; - } - else - { - pLight = (StationaryLight *)LODWORD(a1[1].vWorldPosition.x); - v12 = a1[2].vWorldPosition.x; - a1 = (RenderVertexSoft *)LODWORD(a1[1].vWorldPosition.y); - v13 = v11->vWorldPosition.y; - v64 = v13; - //uStripType = LODWORD(v12); - a1 = (RenderVertexSoft *)LODWORD(a1[1].vWorldPosition.y); - v13 = v11->vWorldPosition.y; - } - } - -//LABEL_11: - //v60 = v10; - v59 = (const char *)v11; - v60 = v12;//uStripType; - minz = pGame->pIndoorCameraD3D->GetPolygonMinZ(v11, uStripType); - maxz = pGame->pIndoorCameraD3D->GetPolygonMaxZ(v11, uStripType); - result = v8->vPosition.x; - *((float *)&v61 + 1) = maxz; - v16 = (double)result; - *(float *)&X = (double)v63; - v17 = *(float *)&pLight - *(float *)&X; - //UNDEF(v18); - //v19 = v16 < v17; - v20 = 0; - //v21 = v16 == v17; -/* BYTE1(result) = HIBYTE(v18); - if ( v16 <= v17 - || (v22 = *(float *)&X + *(float *)&uStripType, - //UNDEF(v23), - v24 = v16 < v22, - v25 = 0, - v26 = v16 == v22, - BYTE1(result) = HIBYTE(v23), - v16 >= v22) - || (result = v8->vPosition.y, - pLight = (StationaryLight *)v8->vPosition.y, - v27 = (double)(signed int)pLight, - v28 = *(float *)&a1 - *(float *)&X, - //UNDEF(v29), - v30 = v27 < v28, - v31 = 0, - v32 = v27 == v28, - BYTE1(result) = HIBYTE(v29), - v27 <= v28) - || (v33 = *(float *)&X + v64, - //UNDEF(v34), - v35 = v27 < v33, - v36 = 0, - v37 = v27 == v33, - BYTE1(result) = HIBYTE(v34), - v27 >= v33) - || (result = v8->vPosition.z, - pLight = (StationaryLight *)v8->vPosition.z, - v38 = (double)(signed int)pLight, - v39 = minz - *(float *)&X, - //UNDEF(v40), - v41 = v38 < v39, - v42 = 0, - v43 = v38 == v39, - BYTE1(result) = HIBYTE(v40), - v38 <= v39) - || (v44 = *(float *)&X + *((float *)&v61 + 1), - //UNDEF(v45), - v46 = v38 < v44, - v47 = 0, - v48 = v38 == v44, - BYTE1(result) = HIBYTE(v45), - v38 >= v44) - || (v49 = pNormal, - Vec3_float_::NegDot(&v11->vWorldPosition, pNormal, a3), - X = v8->vPosition.y, - v50 = (double)X * v49->y, - X = v8->vPosition.z, - v51 = (double)X * v49->z, - X = v8->vPosition.x, - *(float *)&a3 = v50 + v51 + (double)X * v49->x + *a3, - v61 = *(float *)&a3 + 6.7553994e15, - result = LODWORD(v61), - X = LODWORD(v61), - v52 = v63, - SLODWORD(v61) > v63) )*/ - v49 = pNormal; - Vec3_float_::NegDot(&v11->vWorldPosition, pNormal, a3); - *(float *)a3 = (double)v8->vPosition.x * v49->x - + (double)v8->vPosition.y * v49->y - + (double)v8->vPosition.z * v49->z + *a3; - v61 = *(float *)a3 + 6.7553994e15; - result = LODWORD(v61); - X = LODWORD(v61); - v52 = v63; - if ( SLODWORD(v61) > v63) - return 0; - v53 = pSlot; - v60 = X; - stru_F8AD28._blv_lights_radii[*pSlot] = v63; - stru_F8AD28._blv_lights_inv_radii[*v53] = 65536 / v63; - stru_F8AD28._blv_lights_xs[*v53] = v8->vPosition.x; - stru_F8AD28._blv_lights_ys[*v53] = v8->vPosition.y; - stru_F8AD28._blv_lights_zs[*v53] = v8->vPosition.z; - //a3 = (float *)v8->uLightColorR; - stru_F8AD28._blv_lights_rs[*v53] = v8->uLightColorR / 255.0f; - //a3 = (float *)v8->uLightColorG; - stru_F8AD28._blv_lights_gs[*v53] = v8->uLightColorG / 255.0f; - //a3 = (float *)v8->uLightColorB; - stru_F8AD28._blv_lights_bs[*v53] = v8->uLightColorB / 255.0f; - v54 = abs(v63); - v55 = pRenderer->bUsingSpecular; - stru_F8AD28._blv_lights_light_dot_faces[*v53] = v54; - stru_F8AD28._blv_lights_types[*v53] = v8->uLightType; - //v56 = pRenderer->pRenderD3D; - v57 = stru_F8AD28._blv_lights_types[*v53]; - if ( /*pRenderer->pRenderD3D &&*/ v55 && v57 & 4 ) - v57 = _4E94D2_light_type; - stru_F8AD28._blv_lights_types[*v53] = v57; - result = 4 * *v53; - if ( /*v56 &&*/ v55 ) - { - if ( stru_F8AD28._blv_lights_types[*v53] & 4 ) - { - stru_F8AD28._blv_lights_rs[result] = stru_F8AD28._blv_lights_rs[result] * 0.3300000131130219; - stru_F8AD28._blv_lights_gs[result] = stru_F8AD28._blv_lights_gs[result] * 0.3300000131130219; - stru_F8AD28._blv_lights_bs[result] = stru_F8AD28._blv_lights_bs[result] * 0.3300000131130219; - } - } - ++*v53; - return 1; -} - -//----- (0045D698) -------------------------------------------------------- -bool LightmapBuilder::DrawDebugOutlines(char bit_one_for_list1__bit_two_for_list2) -{ - bool result; // eax@1 - LightmapBuilder *v3; // esi@1 - RenderVertexSoft *v4; // edi@3 - RenderVertexSoft *v5; // edi@7 - IndoorCameraD3D *thisa; // [sp+10h] [bp-8h]@1 - bool v7; // [sp+14h] [bp-4h]@2 - bool a2a; // [sp+20h] [bp+8h]@6 - - result = (bool)pGame->pIndoorCameraD3D; - v3 = this; - thisa = pGame->pIndoorCameraD3D; - if ( bit_one_for_list1__bit_two_for_list2 & 1 ) - { - v7 = 0; - if ( (signed int)this->std__vector_000004_size > 0 ) - { - v4 = this->std__vector_000004[0].pVertices; - do - { - pGame->pIndoorCameraD3D->debug_outline_sw(v4, *((unsigned int *)v4 - 1), 0xFF00u, 0.0); - ++v7; - v4 = (RenderVertexSoft *)((char *)v4 + 3100); - result = v7; - } - while ( v7 < (signed int)v3->std__vector_000004_size ); - } - } - if ( bit_one_for_list1__bit_two_for_list2 & 2 ) - { - a2a = 0; - if ( (signed int)v3->std__vector_183808_size > 0 ) - { - v5 = v3->std__vector_183808[0].pVertices; - do - { - pGame->pIndoorCameraD3D->debug_outline_sw(v5, *((unsigned int *)v5 - 1), 0xC04000u, 0.00019999999); - ++a2a; - v5 = (RenderVertexSoft *)((char *)v5 + 3100); - result = a2a; - } - while ( a2a < (signed int)v3->std__vector_183808_size ); - } - } - LOBYTE(result) = 1; - return result; -} - -//----- (0045D73F) -------------------------------------------------------- -void LightmapBuilder::DrawLightmapsType(int type) -{ - if (type == 2) - Draw_183808_Lightmaps(); -} - -//----- (0045D74F) -------------------------------------------------------- -bool LightmapBuilder::DrawLightmaps(int *indices) -{ - //char v3; // zf@1 -// IDirect3DDevice3 *v4; // eax@2 -// HRESULT v5; // eax@2 - //char *v6; // eax@2 - //struct IDirect3DTexture2 *v7; // edi@4 -// HRESULT v8; // eax@8 -// HRESULT v9; // eax@8 -// HRESULT v10; // eax@8 -// HRESULT v11; // eax@8 -// HRESULT v12; // eax@8 - //int *v13; // eax@8 - //float v14; // ecx@15 - //IDirect3DDevice3 *v15; // eax@21 - //HRESULT v16; // eax@21 - //IDirect3DDevice3 *v17; // eax@21 - //HRESULT v18; // eax@21 - //IDirect3DDevice3 *v19; // eax@21 - //HRESULT v20; // eax@21 - //IDirect3DDevice3 *v21; // eax@21 - //HRESULT v22; // eax@21 - //IDirect3DDevice3 *v23; // eax@23 - std::string v25; // [sp+44h] [bp-44h]@12 -// signed int v26; // [sp+48h] [bp-40h]@21 -// signed int v27; // [sp+4Ch] [bp-3Ch]@21 - Lightmap *v28; // [sp+50h] [bp-38h]@2 -// int v29; // [sp+54h] [bp-34h]@2 - //float v30; // [sp+58h] [bp-30h]@2 - Vec3_float_ arg4; - //int arg4; // [sp+68h] [bp-20h]@8 - //float v32; // [sp+6Ch] [bp-1Ch]@8 - //float v33; // [sp+70h] [bp-18h]@8 -// int v34; // [sp+74h] [bp-14h]@19 -// int v35; // [sp+78h] [bp-10h]@2 - //int *v36; // [sp+7Ch] [bp-Ch]@10 - //int a1; // [sp+80h] [bp-8h]@12 - //float v38; // [sp+84h] [bp-4h]@1 - - if (std__vector_000004_size == 0) - return true; - - if (byte_4D864C && pGame->uFlags & GAME_FLAGS_1_01_lightmap_related) - return true; - - pRenderer->BeginLightmaps(); - - arg4.x = 1.0f; - arg4.y = 1.0f; - arg4.z = 1.0f; - if (indices) - { - for (int* i = indices; *i != -1; ++i) - { - v28 = &std__vector_000004[*i]; - if ( !pRenderer->DrawLightmap(v28, &arg4, 0.0) ) - Error("Invalid lightmap detected! (%u)", *i); - } - } - else - { - for (unsigned int i = 0; i < std__vector_000004_size; ++i) - { - Lightmap* _a1 = &std__vector_000004[(int)i]; - if ( !pRenderer->DrawLightmap(_a1, &arg4, 0.0) ) - Error("Invalid lightmap detected! (%u)", i); - } - } - - pRenderer->EndLightmaps(); - - return true; -} - - -//----- (0045DA56) -------------------------------------------------------- -bool LightmapBuilder::DoDraw_183808_Lightmaps(float z_bias) -{ - Vec3_float_ v; // [sp+Ch] [bp-1Ch]@2 - v.z = 1.0; - v.y = 1.0; - v.x = 1.0; - - for (uint i = 0; i < std__vector_183808_size; ++i) - if (!pRenderer->DrawLightmap(std__vector_183808 + i, &v, z_bias)) - Error("Invalid lightmap detected! (%u)", i); - - return true; -} - -//----- (0045DAE8) -------------------------------------------------------- -bool Render::DrawLightmap(Lightmap *pLightmap, Vec3_float_ *pColorMult, float z_bias) -{ - double v10; // st7@4 - double v14; // st7@7 -// __int16 v15; // fps@8 - double v18; // st3@8 - signed int v24; // [sp-1Ch] [bp-670h]@13 -// const char *v25; // [sp-18h] [bp-66Ch]@13 -// int v26; // [sp-14h] [bp-668h]@13 - RenderVertexD3D3 a2[32]; // [sp+0h] [bp-654h]@7 - - - if (pLightmap->uNumVertices < 3) - { - Log::Warning(L"Lightmap uNumVertices < 3"); - return false; - } - - uint uLightmapColorMaskR = (pLightmap->uColorMask >> 16) & 0xFF; - uint uLightmapColorR = floorf(uLightmapColorMaskR * pLightmap->fBrightness * pColorMult->x + 0.5f); - - uint uLightmapColorMaskG = (pLightmap->uColorMask >> 8) & 0xFF; - uint uLightmapColorG = floorf(uLightmapColorMaskG * pLightmap->fBrightness * pColorMult->y + 0.5f); - - uint uLightmapColorMaskB = pLightmap->uColorMask & 0xFF; - uint uLightmapColorB = floorf(uLightmapColorMaskB * pLightmap->fBrightness * pColorMult->z + 0.5f); - - uint uLightmapColor = uLightmapColorB | (uLightmapColorMaskG << 8) | (uLightmapColorMaskR << 16); - - if (uCurrentlyLoadedLevelType == LEVEL_Outdoor) - v10 = (double)pODMRenderParams->shading_dist_mist; - else - v10 = 16192.0; - v14 = 1.0 / v10; - - for (uint i = 0; i < pLightmap->uNumVertices; ++i) - { - v18 = 1.0 - 1.0 / (v14 * pLightmap->pVertices[i].vWorldViewPosition.x * 1000.0); - if (fabsf(z_bias) < 1e-5f) - { - v18 = v18 - z_bias; - if (v18 < 0.000099999997) - v18 = 0.000099999997; - } - - a2[i].pos.x = pLightmap->pVertices[i].vWorldViewProjX; - a2[i].pos.z = v18; - a2[i].pos.y = pLightmap->pVertices[i].vWorldViewProjY; - a2[i].rhw = 1.0 / pLightmap->pVertices[i].vWorldViewPosition.x; - a2[i].diffuse = uLightmapColor; - a2[i].specular = 0; - a2[i].texcoord.x = pLightmap->pVertices[i].u; - a2[i].texcoord.y = pLightmap->pVertices[i].v; - } - - if (uCurrentlyLoadedLevelType == LEVEL_Indoor) - v24 = D3DDP_DONOTLIGHT | D3DDP_DONOTCLIP | D3DDP_DONOTUPDATEEXTENTS; - else - v24 = D3DDP_DONOTLIGHT; - - ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, - D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, - a2, - pLightmap->uNumVertices, - v24)); - - return true; -} - -//----- (0045DCA9) -------------------------------------------------------- -void LightmapBuilder::Draw_183808_Lightmaps() -{ - if (!std__vector_183808_size) - return; - - pRenderer->BeginLightmaps2(); - - DoDraw_183808_Lightmaps(0.00050000002); - - pRenderer->EndLightmaps2(); -} \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 LightmapBuilder.h --- a/LightmapBuilder.h Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,93 +0,0 @@ -#pragma once -#include -#include "Render.h" - -struct LightsStack_StationaryLight_; -struct LightsStack_MobileLight_; - -/* 115 */ -#pragma pack(push, 1) -struct Lightmap -{ - Lightmap(); - virtual ~Lightmap() {} - - //void ( ***vdestructor_ptr)(Lightmap *, bool); - unsigned int uNumVertices; - RenderVertexSoft pVertices[64]; - __int16 field_C08; - __int16 field_C0A; - __int16 field_C0C; - __int16 field_C0E; - unsigned int uColorMask; - float fBrightness; - int field_C18; -}; -#pragma pack(pop) - - -/* 114 */ -#pragma pack(push, 1) -class LightmapBuilder -{ -public: - LightmapBuilder(); - virtual ~LightmapBuilder() //----- (0045BBAA) - {} - - void Draw_183808_Lightmaps(); - //bool DrawLightmap(Lightmap *a1, Vec3_float_ *pColorMult, float z_bias); - bool DoDraw_183808_Lightmaps(float a2); - bool DrawLightmaps(int *indices = nullptr); - void DrawLightmapsType(int type); - bool DrawDebugOutlines(char bit_one_for_list1__bit_two_for_list2); - double _45D643_sw(struct Edge *a1, float a2); - //int _45D426_sw(struct Span *a1, struct Edge **a2, unsigned int a3, struct Edge *a4, int a5); - //bool _45D3C7_sw(struct Polygon *a1); - bool StackLight_TerrainFace(struct StationaryLight *pLight, struct Vec3_float_ *pNormal, float *a3, struct RenderVertexSoft *a1, unsigned int uStripType, int X, unsigned int *pSlot); - bool StackLights_TerrainFace(struct Vec3_float_ *pNormal, float *a3, struct RenderVertexSoft *a1, unsigned int uStripType, bool bLightBackfaces); - bool ApplyLight_ODM(struct StationaryLight *pLight, struct ODMFace *pFace, unsigned int *pSlot, char a4); - bool ApplyLights_OutdoorFace(struct ODMFace *pFace); - double _45CC0C_light(struct Vec3_float_ a1, float a2, float a3, struct Vec3_float_ *pNormal, float a5, int uLightType); - int _45CBD4(struct RenderVertexSoft *a2, int a3, int *a4, int *a5); - int _45CB89(struct RenderVertexSoft *a1, int a2); - int _45CA88(struct stru320 *a2, struct RenderVertexSoft *a3, int a4, struct Vec3_float_ *pNormal); - bool ApplyLight_BLV(struct StationaryLight *pLight, struct BLVFace *a2, unsigned int *pSlot, bool bLightBackfaces, char *a5); - bool ApplyLights_IndoorFace(unsigned int uFaceID); - int _45C6D6(int a2, struct RenderVertexSoft *a3, Lightmap *pLightmap); - int _45C4B9(int a2, struct RenderVertexSoft *a3, Lightmap *pLightmap); - bool _45BE86_build_light_polygon(Vec3_int_ *pos, float radius, unsigned int uColorMask, float dot_dist, int uLightType, struct stru314 *a7, unsigned int uNumVertices, RenderVertexSoft *a9, char uClipFlag); - bool ApplyLights(struct stru320 *a2, struct stru154 *a3, unsigned int uNumVertices, struct RenderVertexSoft *a5, struct IndoorCameraD3D_Vec4 *, char uClipFlag); - - - //void ( ***vdestructor_ptr)(LightmapBuilder *, bool); - //std::vector std__vector_000004; - //std::vector std__vector_183808; - Lightmap std__vector_000004[512]; - unsigned int std__vector_000004_size; - Lightmap std__vector_183808[768]; - unsigned int std__vector_183808_size; - float flt_3C8C0C; - float flt_3C8C10; - float flt_3C8C14; - float flt_3C8C18; - float flt_3C8C1C; - float flt_3C8C20; - float flt_3C8C24; - float flt_3C8C28; - float flt_3C8C2C_lightmaps_brightness; - float flt_3C8C30; - RenderVertexSoft field_3C8C34[256]; - int uFlags; -}; -#pragma pack(pop) - - - - -extern LightsStack_StationaryLight_ *pStationaryLightsStack; -//extern StationaryLight pStationaryLights[400]; -//extern int uNumStationaryLightsApplied; // weak -extern LightsStack_MobileLight_ *pMobileLightsStack; -//extern MobileLight pMobileLights[400]; -//extern int uNumMobileLightsApplied; \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Lights.h --- a/Lights.h Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,111 +0,0 @@ -#pragma once - -#include "VectorTypes.h" - - -/* 257 */ -#pragma pack(push, 1) -struct StationaryLight -{ - Vec3_short_ vPosition; - __int16 uRadius; - unsigned __int8 uLightColorR; - unsigned __int8 uLightColorG; - unsigned __int8 uLightColorB; - char uLightType; -}; -#pragma pack(pop) - - - - -#pragma pack(push, 1) -struct MobileLight -{ - Vec3_short_ vPosition; - __int16 uRadius; - unsigned __int8 uLightColorR; - unsigned __int8 uLightColorG; - unsigned __int8 uLightColorB; - char uLightType; - __int16 field_C; - __int16 uSectorID; - __int16 field_10; -}; -#pragma pack(pop) - - - -/* -#pragma pack(push, 1) -struct LightStack -{ - int field_0; - char T[400]; - unsigned int uNumLightsActive; -}; -#pragma pack(pop)*/ - - - -/* 260 */ -#pragma pack(push, 1) -struct LightsStack_StationaryLight_ -{ - //----- (004AD385) -------------------------------------------------------- - LightsStack_StationaryLight_() - { - uNumLightsActive = 0; - } - - //----- (004AD395) -------------------------------------------------------- - virtual ~LightsStack_StationaryLight_() - { - uNumLightsActive = 0; - } - - //----- (004AD39D) -------------------------------------------------------- - inline unsigned int GetNumLights() - { - return uNumLightsActive; - } - - //----- (004AD3C8) -------------------------------------------------------- - bool AddLight(__int16 x, __int16 y, __int16 z, __int16 a5, unsigned char r, unsigned char g, unsigned char b, char uLightType); - - - - //void ( ***vdestructor_ptr)(LightsStack_StationaryLight_ *, bool); - StationaryLight pLights[400]; - unsigned int uNumLightsActive; -}; -#pragma pack(pop) - - - - -/* 261 */ -#pragma pack(push, 1) -struct LightsStack_MobileLight_ -{ - //----- (00467D45) -------------------------------------------------------- - inline LightsStack_MobileLight_() - { - this->uNumLightsActive = 0; - //this->vdestructor_ptr = &pLightsStack_MobileLight__pvdtor; - } - //----- (00467D55) -------------------------------------------------------- - virtual ~LightsStack_MobileLight_() - { - this->uNumLightsActive = 0; - } - - bool AddLight(__int16 x, __int16 y, __int16 z, __int16 uSectorID, int uRadius, unsigned __int8 r, unsigned __int8 g, unsigned __int8 b, char a10); - - - - //void ( ***vdestructor_ptr)(LightsStack_MobileLight_ *, bool); - MobileLight pLights[400]; - unsigned int uNumLightsActive; -}; -#pragma pack(pop) \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 LightsStack.cpp --- a/LightsStack.cpp Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -#define _CRTDBG_MAP_ALLOC -#include -#include - -#define _CRT_SECURE_NO_WARNINGS -#include -#include "Lights.h" -#include "OSAPI.h" - - -//----- (00467D88) -------------------------------------------------------- -bool LightsStack_MobileLight_::AddLight(__int16 x, __int16 y, __int16 z, __int16 uSectorID, int uRadius, unsigned __int8 r, unsigned __int8 g, unsigned __int8 b, char uLightType) -{ - if (uNumLightsActive >= 400) - { - MessageBoxW(nullptr, L"Too many mobile lights!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\MobileLightStack.cpp:51", 0); - return false; - } - - pLights[uNumLightsActive].vPosition.x = x; - pLights[uNumLightsActive].vPosition.y = y; - pLights[uNumLightsActive].vPosition.z = z; - pLights[uNumLightsActive].uRadius = uRadius; - pLights[uNumLightsActive].field_C = (((uRadius < 0) - 1) & 0x3E) - 31; - pLights[uNumLightsActive].uSectorID = uSectorID; - pLights[uNumLightsActive].field_10 = uRadius * uRadius >> 5; - pLights[uNumLightsActive].uLightColorR = r; - pLights[uNumLightsActive].uLightColorG = g; - pLights[uNumLightsActive].uLightColorB = b; - pLights[uNumLightsActive++].uLightType = uLightType; - - return true; -} - -bool LightsStack_StationaryLight_::AddLight( __int16 x, __int16 y, __int16 z, __int16 a5, unsigned char r, unsigned char g, unsigned char b, char uLightType ) -{ - //unsigned int v9; // eax@1 - //std::string v11; // [sp-18h] [bp-18h]@3 - - //v9 = this->uNumLightsActive; - if ( (signed int)this->uNumLightsActive >= 400 ) - { - MessageBoxW(nullptr, L"Too many stationary lights!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\StationaryLightStack.cpp:45", 0); - return false; - } - - StationaryLight* pLight = &pLights[uNumLightsActive++]; - pLight->vPosition.x = x; - pLight->vPosition.y = y; - pLight->vPosition.z = z; - pLight->uRadius = a5; - pLight->uLightColorR = (unsigned __int8)r; - pLight->uLightColorG = g; - pLight->uLightColorB = b; - pLight->uLightType = uLightType; - return true; -} diff -r 7b076fe64f23 -r 5abd8fc8f1c6 MMT.cpp --- a/MMT.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/MMT.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -11,7 +11,7 @@ #include "AudioPlayer.h" #include "Mouse.h" #include "LOD.h" -#include "Render.h" +#include "Engine/Graphics/Render.h" #include "GUIFont.h" #include "lib/libpng/png.h" #include "ErrorHandling.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 MapInfo.cpp --- a/MapInfo.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/MapInfo.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -9,11 +9,11 @@ #include "texts.h" #include "ObjectList.h" #include "SpriteObject.h" -#include "Indoor.h" +#include "Engine/Graphics/Indoor.h" -#include "Level/Decoration.h" -#include "DecorationList.h" +#include "Engine/Graphics/Level/Decoration.h" +#include "Engine/Graphics/DecorationList.h" #include "Party.h" #include "OurMath.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 MediaPlayer.cpp --- a/MediaPlayer.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/MediaPlayer.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -17,7 +17,7 @@ #include "Bink_Smacker.h" #include "AudioPlayer.h" #include "Timer.h" -#include "Render.h" +#include "Engine/Graphics/Render.h" #include "Game.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 MediaPlayer.h --- a/MediaPlayer.h Wed Sep 17 17:35:13 2014 +0600 +++ b/MediaPlayer.h Thu Sep 18 17:38:54 2014 +0600 @@ -1,6 +1,6 @@ #pragma once #include "OSWindow.h" -#include "Texture.h" +#include "Engine/Graphics/Texture.h" #include "ErrorHandling.h" #pragma pack(push, 1) diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Mouse.cpp --- a/Mouse.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/Mouse.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -11,9 +11,9 @@ #include "Game.h" #include "TurnEngine.h" -#include "Viewport.h" +#include "Engine/Graphics/Viewport.h" #include "GUIWindow.h" -#include "Vis.h" +#include "Engine/Graphics/Vis.h" #include "Actor.h" #include "MM7.h" #include "AudioPlayer.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 NPC.cpp --- a/NPC.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/NPC.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -12,12 +12,12 @@ #include "GUIWindow.h" #include "Events.h" #include "UI\UIHouses.h" -#include "Indoor.h" +#include "Engine/Graphics/Indoor.h" #include "MapInfo.h" #include "Actor.h" #include "AudioPlayer.h" #include "CastSpellInfo.h" -#include "Overlays.h" +#include "Engine/Graphics/Overlays.h" int pDialogueNPCCount; std::array pDialogueNPCPortraits; diff -r 7b076fe64f23 -r 5abd8fc8f1c6 NewUI/MainMenu.h --- a/NewUI/MainMenu.h Wed Sep 17 17:35:13 2014 +0600 +++ b/NewUI/MainMenu.h Thu Sep 18 17:38:54 2014 +0600 @@ -1,6 +1,6 @@ #pragma once #include "Core/UIControl.h" -#include "..\Render.h" +#include "..\Engine/Graphics/Render.h" class MainMenuWindow: public UIControl diff -r 7b076fe64f23 -r 5abd8fc8f1c6 OSWindow.cpp --- a/OSWindow.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/OSWindow.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -6,17 +6,17 @@ #include "OSWindow.h" #include "mm7_data.h" -#include "Arcomage.h" +#include "Arcomage\Arcomage.h" #include "AudioPlayer.h" #include "Mouse.h" #include "Timer.h" #include "GUIWindow.h" #include "Party.h" #include "Game.h" -#include "IndoorCameraD3D.h" +#include "Engine/Graphics/IndoorCameraD3D.h" #include "Keyboard.h" -#include "Viewport.h" -#include "Vis.h" +#include "Engine/Graphics/Viewport.h" +#include "Engine/Graphics/Vis.h" #include "AIL.h" #include "ErrorHandling.h" #include "Log.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 ObjectList.cpp --- a/ObjectList.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/ObjectList.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -5,7 +5,7 @@ #define _CRT_SECURE_NO_WARNINGS #include "ObjectList.h" #include "mm7_data.h" -#include "Sprites.h" +#include "Engine/Graphics/Sprites.h" #include "FrameTableInc.h" #include "ErrorHandling.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Outdoor.cpp --- a/Outdoor.cpp Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,5000 +0,0 @@ -#define _CRTDBG_MAP_ALLOC -#include -#include - -#define _CRT_SECURE_NO_WARNINGS -#include "ErrorHandling.h" - -#include "stru6.h" -#include "Weather.h" -#include "Sprites.h" -#include "LightmapBuilder.h" -#include "Outdoor.h" -#include "Party.h" -#include "SpriteObject.h" -#include "LOD.h" -#include "PaletteManager.h" -#include "GUIProgressBar.h" -#include "AudioPlayer.h" -#include "DecorationList.h" -#include "OurMath.h" -#include "ObjectList.h" -#include "Game.h" -#include "Actor.h" -#include "Chest.h" -#include "stru123.h" -#include "Timer.h" -#include "Viewport.h" -#include "Events.h" -#include "ParticleEngine.h" -#include "TurnEngine.h" - -#include "MM7.h" -#include "Lights.h" - -#include "GUIWindow.h" -#include "Level/Decoration.h" -#include "ZlibWrapper.h" -#include "MMT.h" - -MapStartPoint uLevel_StartingPointType; // weak - -OutdoorLocation *pOutdoor = new OutdoorLocation; -ODMRenderParams *pODMRenderParams; - - -stru149 stru_8019C8; -std::array array_77EC08; - - -struct FogProbabilityTableEntry -{ - unsigned char small_fog_chance; - unsigned char average_fog_chance; - unsigned char dense_fog_chance; - unsigned char __unused; -} fog_probability_table[15] = -{ - { 20, 10, 5, 0}, // MAP_EMERALD_ISLE - { 20, 10, 5, 0}, // MAP_HARMONDALE - { 20, 10, 5, 0}, // MAP_STEADWICK - { 20, 10, 5, 0}, // MAP_PIERPONT - { 20, 10, 5, 0}, // MAP_DEYJA - { 10, 5, 0, 0}, // MAP_BRAKADA_DESERT - { 0, 0, 0, 0}, // MAP_CELESTIA - { 0, 0, 0, 0}, // MAP_THE_PIT - { 20, 30, 50, 0}, // MAP_EVENMORN_ISLE - { 30, 20, 10, 0}, // MAP_MOUNT_NIGHON - { 10, 5, 0, 0}, // MAP_BARROW_DOWNS - { 20, 10, 5, 0}, // MAP_LAND_OF_GIANTS - { 20, 10, 5, 0}, // MAP_TATALIA - { 20, 10, 5, 0}, // MAP_AVLEE - { 0, 100, 0, 0} // MAP_SHOALS -}; - -//for future sky textures? -std::array dword_4EC268={{3,3,3,3,3,3,3,3,3}}; // weak -std::array dword_4EC28C={{3,3,3,3,3,3,3}}; // weak -int dword_4EC2A8=9; // weak -int dword_4EC2AC=7; // weak - - - -//----- (0047A59E) -------------------------------------------------------- -void OutdoorLocation::ExecDraw(unsigned int bRedraw) -{ - - pGame->pIndoorCameraD3D->debug_flags = 0; - if (viewparams->draw_d3d_outlines) - pGame->pIndoorCameraD3D->debug_flags |= ODM_RENDER_DRAW_D3D_OUTLINES; - - if (bRedraw || true/*pRenderer->pRenderD3D*/) - { - //pODMRenderParams->RotationToInts(); - sub_481ED9_MessWithODMRenderParams(); - } - - pODMRenderParams->uMapGridCellX = WorldPosToGridCellX(pParty->vPosition.x); - pODMRenderParams->uMapGridCellZ = WorldPosToGridCellZ(pParty->vPosition.y); - assert(pODMRenderParams->uMapGridCellX <= 127 && pODMRenderParams->uMapGridCellZ <= 127); - - if (bRedraw) - { - sub_487DA9(); - } - if ( pParty->uCurrentMinute != pOutdoor->uLastSunlightUpdateMinute ) - pOutdoor->UpdateSunlightVectors(); - pOutdoor->UpdateFog(); - //pGame->pIndoorCameraD3D->sr_Reset_list_0037C(); - - //if (pRenderer->pRenderD3D) // d3d - redraw always - { - pRenderer->DrawOutdoorSkyD3D(); - pRenderer->DrawBuildingsD3D(); - pRenderer->RenderTerrainD3D(); - //pRenderer->DrawBezierTerrain(); - } - /*else - { - if (!bRedraw) - pRenderer->OnOutdoorRedrawSW(); - else - { - pRenderer->DrawBuildingsSW(); - pRenderer->DrawBezierTerrain(); - sr_sub_486F92_MessWithEdgesAndSpans(); - pODMRenderParams->ApplyLightmapsSW(); - } - }*/ - - - pMobileLightsStack->uNumLightsActive = 0; - pStationaryLightsStack->uNumLightsActive = 0; - /*if ( !pRenderer->pRenderD3D ) - { - pRenderer->ExecOutdoorDrawSW(); - pGame->pIndoorCameraD3D->sr_438240_draw_lits(); - }*/ - pGame->PushStationaryLights(-1); - pGame->PrepareBloodsplats(); - if (bRedraw) - pOutdoor->UpdateDiscoveredArea(WorldPosToGridCellX(pParty->vPosition.x), WorldPosToGridCellZ(pParty->vPosition.y), 1); - pGame->uFlags2 &= 0xFFFFFFFEu; - if (/*pRenderer->pRenderD3D*/true && pRenderer->bUsingSpecular) - pGame->pLightmapBuilder->uFlags |= 1; - else - pGame->pLightmapBuilder->uFlags &= 0xFFFFFFFEu; - - uNumDecorationsDrawnThisFrame = 0; - uNumSpritesDrawnThisFrame = 0; - uNumBillboardsToDraw = 0; - - PrepareActorsDrawList(); - if (!pODMRenderParams->bDoNotRenderDecorations) - pRenderer->PrepareDecorationsRenderList_ODM(); - - pRenderer->DrawSpriteObjects_ODM(); - pRenderer->TransformBillboardsAndSetPalettesODM(); -} - - -//----- (00441CFF) -------------------------------------------------------- -void OutdoorLocation::Draw() -{ - bool redrawWorld = true; - if ( !(pParty->uFlags & 2) && !(pGame->uFlags2 & 1) ) - redrawWorld = false; - pOutdoor->ExecDraw(redrawWorld); - - pGame->DrawParticles(); - //pWeather->Draw();//если раскомментировать скорость снега быстрее - trail_particle_generator.UpdateParticles(); -} - -//----- (00488E23) -------------------------------------------------------- -double OutdoorLocation::GetFogDensityByTime() -{ - if ( pParty->uCurrentHour < 5 )//ночь - { - pWeather->bNight = true; - return 60.0 * 0.016666668; - } - else if ( pParty->uCurrentHour >= 5 && pParty->uCurrentHour < 6 )//рассвет - { - pWeather->bNight = false; - return (60.0 - (double)(60 * pParty->uCurrentHour + pParty->uCurrentMinute - 300)) * 0.016666668; - } - else if ( pParty->uCurrentHour >= 6 && pParty->uCurrentHour < 20 )//день - { - pWeather->bNight = false; - return 0.0; - } - else if ( pParty->uCurrentHour >= 20 && pParty->uCurrentHour < 21 )//сумерки - { - pWeather->bNight = false; - return ((double)(pParty->uCurrentHour - 20) * 60.0 + (double)(signed int)pParty->uCurrentMinute) * 0.016666668; - } - else//ночь - { - pWeather->bNight = true; - return 60.0 * 0.016666668; - } -} - -//----- (00488EB1) -------------------------------------------------------- -int OutdoorLocation::GetSomeOtherTileInfo(int sX, int sY) -{ - //OutdoorLocation *v3; // esi@1 - unsigned int v4; // edi@1 - unsigned int v5; // eax@1 -// int result; // eax@5 - -/* v3 = this; - v4 = WorldPosToGridCellZ(sY); - v5 = WorldPosToGridCellX(sX); - if ( (v5 & 0x80000000u) != 0 || (signed int)v5 > 127 || (v4 & 0x80000000u) != 0 || (signed int)v4 > 127 ) - result = 0; - else - result = ActuallyGetSomeOtherTileInfo(v5, v4); - return result;*/ - v4 = WorldPosToGridCellZ(sY); - v5 = WorldPosToGridCellX(sX); - if ( v5 < 0 || v5 > 127 || v4 < 0 || v4 > 127 ) - return 0; - return ActuallyGetSomeOtherTileInfo(v5, v4); -} -// 47F44B: using guessed type int __stdcall WorldPosToGridCellX(int); -// 47F458: using guessed type int __stdcall WorldPosToGridCellZ(int); - -//----- (00488EEF) -------------------------------------------------------- -unsigned int OutdoorLocation::GetTileTexture(signed int sX, signed int sY) -{ - //OutdoorLocation *v3; // esi@1 - signed int v4; // edi@1 - signed int v5; // eax@1 -// unsigned int result; // eax@5 - - /*v3 = this; - v4 = WorldPosToGridCellZ(sZ); - v5 = WorldPosToGridCellX(sX); - if ( v5< 0 || (signed int)v5 > 127 || v4 < 0 || (signed int)v4 > 127 )//if ( (v5 & 0x80000000u) != 0 || (signed int)v5 > 127 || (v4 & 0x80000000u) != 0 || (signed int)v4 > 127 ) - result = -1; - else - result = DoGetTileTexture(v5, v4); - return result;*/ - v4 = WorldPosToGridCellZ(sY); - v5 = WorldPosToGridCellX(sX); - if ( v5 < 0 || v5 > 127 || v4 < 0 || v4 > 127 ) - return -1; - return DoGetTileTexture(v5, v4); -} -// 47F44B: using guessed type int __stdcall WorldPosToGridCellX(int); -// 47F458: using guessed type int __stdcall WorldPosToGridCellZ(int); - -//----- (00488F2E) -------------------------------------------------------- -int OutdoorLocation::GetHeightOnTerrain(int sX, int sZ) - /* Функция предоставляет возможность перемещать камеру таким образом, чтобы она имитировала ходьбу по ландшафту. - То есть нам надо менять высоту камеры (координату Y) в зависимости от того, в каком месте ландшафта мы находимся. - Для этого мы сначала должны определить по координатам X и Z камеры квадрат ландшафта в котором мы находимся. - Все это делает функция Terrain::getHeight; в своих параметрах она получает координаты X и Z камеры и возвращает высоту, - на которой должна быть расположена камера, чтобы она оказалась над ландшафтом.*/ -{ - int result; // eax@5 - - if ( sX < 0 || sX > 127 || sZ < 0 || sZ > 127 ) - result = 0; - else - result = DoGetHeightOnTerrain(sX, sZ); - return result; -} - -//----- (00488F5C) -------------------------------------------------------- -bool OutdoorLocation::Initialize(const char *pFilename, int File, size_t uRespawnInterval, int *thisa) -{ - OutdoorLocation *v5; // esi@1 - bool result; // eax@2 - - v5 = this; - if ( pFilename ) - { - Release(); - pBitmaps_LOD->ReleaseAll2(); - pSprites_LOD->DeleteSomeOtherSprites(); - pSpriteFrameTable->ResetSomeSpriteFlags(); - pIcons_LOD->ReleaseAll2(); - - if ( !Load(pFilename, (ODMFace *)File, uRespawnInterval, thisa) ) - { - MessageBoxA(0, "Error!", "Couldn't Load Map!", 0); - CreateDebugLocation(); - } - ::day_attrib = v5->loc_time.day_attrib; - ::day_fogrange_1 = v5->loc_time.day_fogrange_1; - ::day_fogrange_2 = v5->loc_time.day_fogrange_2; - if ( Is_out15odm_underwater() ) - SetUnderwaterFog(); - _6BE134_odm_main_tile_group = v5->pTileTypes[0].tileset; - result = 1; - } - else - { - result = 0; - } - return result; -} - - - -char foot_travel_destinations[15][4] = -{ -// north south east west from - {MAP_INVALID, MAP_INVALID, MAP_INVALID, MAP_INVALID}, // MAP_EMERALD_ISLE - {MAP_PIERPONT, MAP_BARROW_DOWNS, MAP_PIERPONT, MAP_STEADWICK}, // MAP_HARMONDALE - {MAP_DEYJA, MAP_BRAKADA_DESERT, MAP_HARMONDALE, MAP_TATALIA}, // MAP_STEADWICK - {MAP_AVLEE, MAP_HARMONDALE, MAP_INVALID, MAP_DEYJA}, // MAP_PIERPONT - {MAP_PIERPONT, MAP_STEADWICK, MAP_PIERPONT, MAP_STEADWICK}, // MAP_DEYJA - {MAP_STEADWICK, MAP_INVALID, MAP_BARROW_DOWNS, MAP_INVALID}, // MAP_BRAKADA_DESERT - {MAP_INVALID, MAP_INVALID, MAP_INVALID, MAP_INVALID}, // MAP_CELESTIA - {MAP_INVALID, MAP_INVALID, MAP_INVALID, MAP_INVALID}, // MAP_THE_PIT - {MAP_INVALID, MAP_INVALID, MAP_INVALID, MAP_INVALID}, // MAP_EVENMORN_ISLE - {MAP_INVALID, MAP_INVALID, MAP_INVALID, MAP_INVALID}, // MAP_MOUNT_NIGHON - {MAP_HARMONDALE, MAP_BRAKADA_DESERT, MAP_HARMONDALE, MAP_BRAKADA_DESERT}, // MAP_BARROW_DOWNS - {MAP_INVALID, MAP_INVALID, MAP_INVALID, MAP_INVALID}, // MAP_LAND_OF_GIANTS - {MAP_INVALID, MAP_INVALID, MAP_STEADWICK, MAP_INVALID}, // MAP_TATALIA - {MAP_INVALID, MAP_PIERPONT, MAP_PIERPONT, MAP_INVALID}, // MAP_AVLEE - {MAP_INVALID, MAP_INVALID, MAP_INVALID, MAP_INVALID} // MAP_SHOALS -}; -unsigned char foot_travel_times[15][4] = -{ -// north south east west from - {0, 0, 0, 0}, // MAP_EMERALD_ISLE - {5, 5, 7, 5}, // MAP_HARMONDALE - {5, 5, 5, 5}, // MAP_STEADWICK - {5, 5, 0, 5}, // MAP_PIERPONT - {7, 5, 5, 4}, // MAP_DEYJA - {5, 0, 5, 0}, // MAP_BRAKADA_DESERT - {0, 0, 0, 0}, // MAP_CELESTIA - {0, 0, 0, 0}, // MAP_THE_PIT - {0, 0, 0, 0}, // MAP_EVENMORN_ISLE - {0, 0, 0, 0}, // MAP_MOUNT_NIGHON - {5, 7, 7, 5}, // MAP_BARROW_DOWNS - {0, 0, 0, 0}, // MAP_LAND_OF_GIANTS - {0, 0, 5, 0}, // MAP_TATALIA - {0, 7, 5, 0}, // MAP_AVLEE - {0, 0, 0, 0}, // MAP_SHOALS -}; - - -MapStartPoint foot_travel_arrival_points[15][4] = -{ -// north south east west from - {MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party}, // MAP_EMERALD_ISLE - {MapStartPoint_South, MapStartPoint_North, MapStartPoint_South, MapStartPoint_East}, // MAP_HARMONDALE - {MapStartPoint_South, MapStartPoint_North, MapStartPoint_West, MapStartPoint_East}, // MAP_STEADWICK - {MapStartPoint_East, MapStartPoint_North, MapStartPoint_Party, MapStartPoint_East}, // MAP_PIERPONT - {MapStartPoint_West, MapStartPoint_North, MapStartPoint_West, MapStartPoint_North}, // MAP_DEYJA - {MapStartPoint_South, MapStartPoint_Party, MapStartPoint_West, MapStartPoint_Party}, // MAP_BRAKADA_DESERT - {MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party}, // MAP_CELESTIA - {MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party}, // MAP_THE_PIT - {MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party}, // MAP_EVENMORN_ISLE - {MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party}, // MAP_MOUNT_NIGHON - {MapStartPoint_South, MapStartPoint_East, MapStartPoint_South, MapStartPoint_East}, // MAP_BARROW_DOWNS - {MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party}, // MAP_LAND_OF_GIANTS - {MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_West, MapStartPoint_Party}, // MAP_TATALIA - {MapStartPoint_Party, MapStartPoint_North, MapStartPoint_North, MapStartPoint_Party}, // MAP_AVLEE - {MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party}, // MAP_SHOALS -}; - - -//----- (0048902E) -------------------------------------------------------- -bool OutdoorLocation::GetTravelDestination(signed int sPartyX, signed int sPartyZ, char *pOut, signed int a5) -{ - char *mapNumberAsStr; // eax@3 - int mapNumberAsInt; // eax@3 - signed int direction; // esi@7 - signed int destinationMap; // eax@23 - char Str[140]; // [sp+8h] [bp-78h]@3 - - strcpy(Str, this->pLevelFilename);//настоящая локация - _strlwr(Str); - mapNumberAsStr = strtok(Str, "out"); - mapNumberAsStr[2] = 0; - mapNumberAsInt = atoi(mapNumberAsStr); - if ( a5 < 10 || strlen(this->pLevelFilename) != 9 || mapNumberAsInt < 1 || mapNumberAsInt > 15 ) //длина .odm и количество локаций - return 0; - if ( sPartyX < -22528 )//граница карты - direction = 4; - else if ( sPartyX > 22528 ) - direction = 3; - else if ( sPartyZ < -22528 ) - direction = 2; - else if ( sPartyZ > 22528 ) - direction = 1; - else - return false; - - if ( mapNumberAsInt == MAP_AVLEE && direction == 4) // to Shoals - { - if ( pPlayers[1]->HasUnderwaterSuitEquipped() && - pPlayers[2]->HasUnderwaterSuitEquipped() && - pPlayers[3]->HasUnderwaterSuitEquipped() && - pPlayers[4]->HasUnderwaterSuitEquipped()) - { - uDefaultTravelTime_ByFoot = 1; - strcpy(pOut, "out15.odm"); - uLevel_StartingPointType = MapStartPoint_East; - LOWORD(pParty->uFlags) &= 0xFD7Bu; - return true; - } - } - else if ( mapNumberAsInt == MAP_SHOALS && direction == 3 ) //from Shoals - { - uDefaultTravelTime_ByFoot = 1; - strcpy(pOut, "out14.odm");//Авли - uLevel_StartingPointType = MapStartPoint_West; - LOWORD(pParty->uFlags) &= 0xFD7Bu; - return true; - } - destinationMap = foot_travel_destinations[mapNumberAsInt - 1][direction - 1]; - if (destinationMap == MAP_INVALID) - return false; - - assert(destinationMap <= MAP_SHOALS); - - uDefaultTravelTime_ByFoot = foot_travel_times[mapNumberAsInt - 1][direction - 1]; - uLevel_StartingPointType = foot_travel_arrival_points[mapNumberAsInt - 1][direction - 1]; - sprintf(pOut, "out%02d.odm", destinationMap); //локация направления - return true; -} -// 6BD07C: using guessed type int uDefaultTravelTime_ByFoot; -// 6BE35C: using guessed type int uLevel_StartingPointType; - -//----- (0048917E) -------------------------------------------------------- -void OutdoorLocation::MessWithLUN() -{ - this->pSpriteIDs_LUN[0] = -1; - this->pSpriteIDs_LUN[1] = 0; - this->pSpriteIDs_LUN[2] = pSpriteFrameTable->FastFindSprite("LUN1-4"); - this->pSpriteIDs_LUN[3] = 0; - this->pSpriteIDs_LUN[4] = pSpriteFrameTable->FastFindSprite("LUN1-2"); - this->pSpriteIDs_LUN[5] = 0; - this->pSpriteIDs_LUN[6] = pSpriteFrameTable->FastFindSprite("LUN3-4"); - this->pSpriteIDs_LUN[7] = 0; - this->uSpriteID_LUNFULL = pSpriteFrameTable->FastFindSprite("LUNFULL"); - this->uSpriteID_LUN1_2_cp = pSpriteFrameTable->FastFindSprite("LUN1-2"); - this->uSpriteID_LUN1_4_cp = pSpriteFrameTable->FastFindSprite("LUN1-4"); - this->uSpriteID_LUN3_4_cp = pSpriteFrameTable->FastFindSprite("LUN3-4"); - this->field_D60 = -1; - this->field_CF0 = 4; - this->field_CF8 = 4; - this->field_D00 = 4; - this->field_CE8 = 0; - this->field_D3C = (int)this->pSpriteIDs_LUN; - this->field_D40 = 0; - this->field_D44 = 0; - this->field_D48 = 0; - this->field_D4C = 131072; - this->field_D5C = 0; - this->field_D64 = 0; - this->field_D28 = -1; - this->field_D08 = 0; - this->field_D0C = 0; - this->field_D10 = 0; - this->field_D24 = 0; - this->field_D2C = 0; - this->uSpriteID_LUN_SUN = pSpriteFrameTable->FastFindSprite("LUN-SUN"); - this->field_D14 = -131072; - for ( uint i = 0; i < 8; i++ ) - pSpriteFrameTable->InitializeSprite(this->pSpriteIDs_LUN[i]);//v2 += 2; - pSpriteFrameTable->InitializeSprite(this->uSpriteID_LUN_SUN); -} - -//----- (004892E6) -------------------------------------------------------- -void OutdoorLocation::UpdateSunlightVectors() -{ - unsigned int v3; // edi@3 - double v8; // st7@4 - - if ( pParty->uCurrentHour >= 5 && pParty->uCurrentHour < 21 ) - { - v3 = pParty->uCurrentMinute + 60 * (pParty->uCurrentHour - 5); - this->inv_sunlight_y = 0; - this->inv_sunlight_x = stru_5C6E00->Cos((v3 * stru_5C6E00->uIntegerPi) / 960); - this->inv_sunlight_z = stru_5C6E00->Sin((v3 * stru_5C6E00->uIntegerPi) / 960); - this->vSunlight.x = -this->inv_sunlight_x; - this->vSunlight.y = -this->inv_sunlight_y; - this->vSunlight.z = -this->inv_sunlight_z; - if ( v3 >= 480 ) - v8 = 960 - v3; - else - v8 = v3; - this->max_terrain_dimming_level = (int)(20.0 - v8 / 480.0 * 20.0); - this->uLastSunlightUpdateMinute = pParty->uCurrentMinute; - } -} - -//----- (004893C1) -------------------------------------------------------- -void OutdoorLocation::UpdateFog() -{ - fFogDensity = GetFogDensityByTime(); -} - -//----- (004893CF) -------------------------------------------------------- -int OutdoorLocation::GetNumFoodRequiredToRestInCurrentPos(int x, signed int y, int z) -{ - int v7; // eax@4 - int is_on_water; // [sp+8h] [bp-8h]@2 - int bmodel_standing_on_pid; // [sp+Ch] [bp-4h]@2 - - is_on_water = 0; - bmodel_standing_on_pid = 0; - ODM_GetFloorLevel(x, y, z, pParty->uDefaultPartyHeight, &is_on_water, &bmodel_standing_on_pid, 0); - if ( pParty->uFlags & 8 || bmodel_standing_on_pid || is_on_water )//на bmodel,и или на воде - return 2; - v7 = _47ED83(WorldPosToGridCellX(pParty->vPosition.x), WorldPosToGridCellZ(pParty->vPosition.y) - 1); - switch ( pTileTable->pTiles[GetTileIdByTileMapId(v7)].tileset ) - { - case Tileset_Grass://на траве - return 1; - case Tileset_Snow://на снегу - return 3; - case Tilset_Desert://на песке - return 5; - case Tileset_3: - case Tileset_Dirt:// на грязи - return 4; - case Tileset_Water:// on water(на воде) - return 3;//еденицы еды - default: - return 2; - } -} - -//----- (00489487) -------------------------------------------------------- -void OutdoorLocation::SetFog() -{ - strcpy(pOutdoor->pLevelFilename, pCurrentMapName); - - MAP_TYPE map_id = pMapStats->GetMapInfo(pCurrentMapName); - if (map_id == MAP_INVALID || map_id == MAP_CELESTIA || map_id == MAP_THE_PIT || map_id > MAP_SHOALS) - return; - - uint chance = rand() % 100; - - if (chance < fog_probability_table[map_id - 1].small_fog_chance) - { - ::day_fogrange_1 = 4096; - ::day_fogrange_2 = 8192; - ::day_attrib |= DAY_ATTRIB_FOG; - } - else if (chance < fog_probability_table[map_id - 1].small_fog_chance + - fog_probability_table[map_id - 1].average_fog_chance) - { - ::day_fogrange_2 = 4096; - ::day_fogrange_1 = 0; - ::day_attrib |= DAY_ATTRIB_FOG; - } - else if (fog_probability_table[map_id - 1].dense_fog_chance && - chance < fog_probability_table[map_id - 1].small_fog_chance + - fog_probability_table[map_id - 1].average_fog_chance + - fog_probability_table[map_id - 1].dense_fog_chance) - { - ::day_fogrange_2 = 2048; - ::day_fogrange_1 = 0; - ::day_attrib |= DAY_ATTRIB_FOG; - } - else - ::day_attrib &= ~DAY_ATTRIB_FOG; - - if ( Is_out15odm_underwater() ) - SetUnderwaterFog(); - pOutdoor->loc_time.day_fogrange_1 = ::day_fogrange_1; - pOutdoor->loc_time.day_fogrange_2 = ::day_fogrange_2; - pOutdoor->loc_time.day_attrib = ::day_attrib; -} - -//----- (00482170) -------------------------------------------------------- -bool ODMFace::IsBackfaceNotCulled(RenderVertexSoft *a2, struct Polygon *polygon) -{ - unsigned int numOfVertices; // edx@1 - RenderVertexSoft *currVertex; // ecx@2 - double v7; // st7@5 - double v8; // st6@5 - double v9; // st5@5 - float v18; // [sp+8h] [bp-38h]@5 - float v19; // [sp+10h] [bp-30h]@5 - float v20; // [sp+14h] [bp-2Ch]@5 - float v21; // [sp+18h] [bp-28h]@5 - float v22; // [sp+1Ch] [bp-24h]@5 - float v23; // [sp+24h] [bp-1Ch]@5 - float v24; // [sp+28h] [bp-18h]@5 - float v25; // [sp+30h] [bp-10h]@5 - float v26; // [sp+34h] [bp-Ch]@5 - float v27; // [sp+38h] [bp-8h]@5 - float v28; // [sp+3Ch] [bp-4h]@5 - float a3a; // [sp+48h] [bp+8h]@5 - float a3b; // [sp+48h] [bp+8h]@17 - float a3c; // [sp+48h] [bp+8h]@17 - float a3d; // [sp+48h] [bp+8h]@17 - float a3e; // [sp+48h] [bp+8h]@17 - - numOfVertices = polygon->uNumVertices; - if ( numOfVertices < 3 ) - return false; - currVertex = &a2[numOfVertices - 1]; - if ( a2->vWorldPosition.z == a2[1].vWorldPosition.z && a2[1].vWorldPosition.z == currVertex->vWorldPosition.z ) - polygon->flags |= 0x10u; - - v28 = a2[1].vWorldPosition.x - a2->vWorldPosition.x; - v27 = a2[1].vWorldPosition.y - a2->vWorldPosition.y; - a3a = a2[1].vWorldPosition.z - a2->vWorldPosition.z; - - - for (int i = 0; i < numOfVertices; i++) - { - v7 = currVertex->vWorldPosition.x - a2->vWorldPosition.x; - v8 = currVertex->vWorldPosition.y - a2->vWorldPosition.y; - v9 = currVertex->vWorldPosition.z - a2->vWorldPosition.z; - v26 = v27 * v9 - v8 * a3a; - v24 = v7 * a3a - v9 * v28; - v25 = v8 * v28 - v7 * v27; - if ( v24 != 0.0 || v25 != 0.0 || v26 != 0.0 ) - break; - currVertex--; - } - - if ( ((double)pGame->pIndoorCameraD3D->vPartyPos.x - a2->vWorldPosition.x) * v26 - + ((double)pGame->pIndoorCameraD3D->vPartyPos.z - a2->vWorldPosition.z) * v25 - + ((double)pGame->pIndoorCameraD3D->vPartyPos.y - a2->vWorldPosition.y) * v24 > 0.0 ) - { - - v19 = a2[1].vWorldViewPosition.x - a2->vWorldViewPosition.x; - v18 = a2[1].vWorldViewPosition.y - a2->vWorldViewPosition.y; - v20 = a2[1].vWorldViewPosition.z - a2->vWorldViewPosition.z; - v21 = currVertex->vWorldViewPosition.x - a2->vWorldViewPosition.x; - v22 = currVertex->vWorldViewPosition.y - a2->vWorldViewPosition.y; - v23 = currVertex->vWorldViewPosition.z - a2->vWorldViewPosition.z; - - a3b = v23 * v18 - v22 * v20; - polygon->v_18.x = bankersRounding(a3b); - a3c = v21 * v20 - v23 * v19; - polygon->v_18.y = bankersRounding(a3c); - a3d = v22 * v19 - v21 * v18; - polygon->v_18.z = bankersRounding(a3d); - polygon->_normalize_v_18(); - a3e = -((double)polygon->v_18.x * a2->vWorldViewPosition.x) - - (double)polygon->v_18.y * a2->vWorldViewPosition.y - - (double)polygon->v_18.z * a2->vWorldViewPosition.z; - polygon->field_24 = bankersRounding(a3e); - return true; - } - else - return false; -} - -//----- (0047C7A9) -------------------------------------------------------- -void OutdoorLocationTerrain::_47C7A9() -{ - this->field_10 = 0; - this->field_12 = 0; - this->field_16 = 0; - this->field_14 = 0; - this->field_1C = 0; - this->field_18 = 0; -} - -//----- (0047C7C2) -------------------------------------------------------- -void OutdoorLocationTerrain::Release()//очистить локацию -{ - free(this->pHeightmap); - pHeightmap = nullptr; - free(pTilemap); - pTilemap = nullptr; - free(pAttributemap); - pAttributemap = nullptr; - free(pDmap); - pDmap = nullptr; - - _47C7A9(); -} - -//----- (0047C80A) -------------------------------------------------------- -void OutdoorLocationTerrain::FillDMap( int X, int Y, int W, int Z ) -{ - double v6; // st7@1 - double v7; // st7@2 - double v8; // st7@2 - int result; // eax@3 - int v10; // eax@4 - int v11; // ecx@5 - int v12; // ecx@6 - int v13; // edi@7 - int v14; // edx@9 -// int v15; // eax@15 - unsigned __int8 *pMapHeight; // ebx@15 - int v17; // eax@15 - int v18; // ecx@15 - int v19; // esi@15 - int v20; // edi@15 - int v21; // edx@15 - int v22; // ecx@15 - int v23; // ebx@15 - int v24; // ecx@15 - int v25; // ST28_4@15 - double v26; // st7@15 - double v27; // st6@15 - double v28; // st5@15 - double v29; // st7@15 - double v30; // st7@16 - double v31; // st7@17 - int v32; // eax@21 - double v33; // st7@21 - double v34; // st6@21 - double v35; // st5@21 - double v36; // st7@21 - double v37; // st7@22 - double v38; // st7@23 - int v39; // [sp+14h] [bp-34h]@8 - int v40; // [sp+18h] [bp-30h]@15 - int v41; // [sp+1Ch] [bp-2Ch]@15 - int v42; // [sp+20h] [bp-28h]@15 - int v44; // [sp+28h] [bp-20h]@21 - float v45; // [sp+2Ch] [bp-1Ch]@1 - float v46; // [sp+30h] [bp-18h]@1 - float v47; // [sp+34h] [bp-14h]@1 - //int v48; // [sp+38h] [bp-10h]@7 - int v49; // [sp+3Ch] [bp-Ch]@10 - int v50; // [sp+40h] [bp-8h]@9 - float v51; // [sp+44h] [bp-4h]@15 - float v52; // [sp+44h] [bp-4h]@21 - float v53; // [sp+50h] [bp+8h]@15 - float v54; // [sp+50h] [bp+8h]@21 -// int v55; // [sp+54h] [bp+Ch]@15 - float v56; // [sp+54h] [bp+Ch]@15 - float v57; // [sp+54h] [bp+Ch]@21 - - v46 = -64.0; - v47 = -64.0; - v45 = 64.0; - v6 = sqrt(12288.0); - if ( v6 != 0.0 ) - { - v7 = 1.0 / v6; - v45 = 64.0 * v7; - v8 = v7 * -64.0; - v46 = v8; - v47 = v8; - } - result = Y; - if ( Y > Z ) - { - v10 = Z ^ Y; - Z ^= Y ^ Z; - result = Z ^ v10; - } - v11 = X; - if ( X > W ) - { - v12 = W ^ X; - W ^= X ^ W; - v11 = W ^ v12; - } - //v48 = result - 1; - if ( result - 1 <= Z ) - { - v39 = v11 - 1; - for ( v13 = result - 1; v13 <= Z; v13++ ) - { - v50 = v39; - if ( v39 <= W ) - { - result = (v39 - 63) << 9; - v49 = (v39 - 63) << 9; - for ( v14 = v39; v14 <= W; v14++ ) - { - if ( v13 >= 0 && result >= -32256 && v13 <= 127 && result <= 32768 ) - { - //v15 = pOutLocTerrain->field_10; - //v55 = pOutLocTerrain->field_10; - pMapHeight = this->pHeightmap; - v17 = (int)(&pMapHeight[v13 * this->field_10] + v14); - v18 = -v13; - v19 = (64 - v13) << 9; - v20 = 32 * *(char *)v17; - v21 = 32 * *(char *)(v17 + 1); - - v22 = (v18 + 63) << 9; - v41 = v22; - v23 = (int)(&pMapHeight[this->field_10 * (v13 + 1)] + v14); - v24 = v22 - v19; - v40 = 32 * *(char *)v23; - v42 = 32 * *(char *)(v23 + 1); - - v25 = v49 - 512 - v49; - v26 = (double)-((v20 - v21) * v24); - v51 = v26; - v27 = (double)-(v25 * (v42 - v21)); - v53 = v27; - v28 = (double)(v25 * v24); - v56 = v28; - v29 = sqrt(v28 * v28 + v27 * v27 + v26 * v26); - if ( v29 != 0.0 ) - { - v30 = 1.0 / v29; - v51 = v51 * v30; - v53 = v53 * v30; - v56 = v30 * v56; - } - v31 = (v56 * v47 + v53 * v46 + v51 * v45) * 31.0; - if ( v31 < 0.0 ) - v31 = 0.0; - if ( v31 > 31.0 ) - v31 = 31.0; - v44 = 2 * (v14 + v13 * this->field_10); - //pOutLocTerrain = pOutLocTerrain2; - *((char *)this->pDmap + v44 + 1) = (signed __int64)v31; - - v32 = v49 - (v49 - 512); - v33 = (double)-((v42 - v40) * (v19 - v41)); - v52 = v33; - v34 = (double)-(v32 * (v20 - v40)); - v54 = v34; - v35 = (double)(v32 * (v19 - v41)); - v57 = v35; - v36 = sqrt(v35 * v35 + v34 * v34 + v33 * v33); - if ( v36 != 0.0 ) - { - v37 = 1.0 / v36; - v52 = v52 * v37; - v54 = v54 * v37; - v57 = v37 * v57; - } - v38 = (v57 * v47 + v54 * v46 + v52 * v45) * 31.0; - if ( v38 < 0.0 ) - v38 = 0.0; - if ( v38 > 31.0 ) - v38 = 31.0; - //v13 = v48; - *((char *)this->pDmap + v44) = (signed __int64)v38; - //v14 = v50; - result = v49; - } - //++v14; - result += 512; - //v50 = v14; - v49 = result; - } - } - //++v13; - //v48 = v13; - } - //while ( v13 <= Z ); - } -} - -//----- (0047CB57) -------------------------------------------------------- -int OutdoorLocationTerrain::_47CB57(int a1, int a2, int a3) -{ - signed int result; // eax@2 -// unsigned __int16 *v5; // edx@3 -// double v6; // st7@3 -// int v8; // eax@3 -// int v9; // eax@4 -// int v10; // eax@5 -// double v11; // st6@7 -// signed int v12; // edi@7 -// int v13; // esi@9 -// char *v14; // esi@10 -// signed int v15; // ecx@10 -// char v16[256]; // [sp+4h] [bp-124h]@9 -// unsigned __int16 *v17; // [sp+104h] [bp-24h]@3 -// float v22; // [sp+118h] [bp-10h]@3 -// float v23; // [sp+11Ch] [bp-Ch]@3 -// int i; // [sp+120h] [bp-8h]@3 -// unsigned int v25; // [sp+124h] [bp-4h]@5 -// signed int a2a; // [sp+134h] [bp+Ch]@3 -// unsigned int a2b; // [sp+134h] [bp+Ch]@7 -// float a3a; // [sp+138h] [bp+10h]@7 -// int a3b; // [sp+138h] [bp+10h]@9 - - int num_r_bits = 5; - int num_g_bits = 6; - int num_b_bits = 5; - - int r_mask = 0xF800; - int g_mask = 0x7E0; - int b_mask = 0x1F; - - //if ( pRenderer->pRenderD3D ) - result = 0; - /*else - { - __debugbreak(); - v5 = PaletteManager::Get_Dark_or_Red_LUT(a2, 0, 1); - v6 = 0.0; - v22 = 0.0; - v8 = 0; - v17 = v5; - v23 = 0.0; - a2a = 0; - for ( i = 0; i < a3; ++i ) - { - v9 = *(char *)(v8 + a1); - if ( v9 ) - { - v10 = v5[v9]; - v6 = v6 + (double)((signed int)(r_mask & v10) >> (num_b_bits + num_g_bits)); - ++a2a; - v25 = b_mask & v10; - v22 = (double)((signed int)(g_mask & v10) >> num_b_bits) + v22; - v23 = (double)(signed int)(b_mask & v10) + v23; - } - v8 = i + 1; - } - v11 = 1.0 / (double)a2a; - a3a = v11; - v25 = (signed __int64)(a3a * v22); - i = (signed __int64)(a3a * v23); - v12 = 0; - a2b = num_b_bits + num_g_bits; - while ( 1 ) - { - v13 = v17[v12]; - a3b = abs((__int64)(signed __int64)(v11 * v6) - ((signed int)(r_mask & v17[v12]) >> a2b)); - BYTE3(a3b) = abs((signed)v25 - ((signed int)(g_mask & v13) >> num_b_bits)) + a3b; - v16[v12++] = abs((signed)i - (signed)(b_mask & v13)) + BYTE3(a3b); - if ( v12 >= 256 ) - break; - } - result = 0; - v14 = (char *)&pPaletteManager->field_D1600[42][23][116]; - v15 = 0; - do - { - if ( (unsigned __int8)v16[v15] < (signed int)v14 ) - { - v14 = (char *)(unsigned __int8)v16[v15]; - result = v15; - } - ++v15; - } - while ( v15 < 256 ); - }*/ - return result; -} - -//----- (0047CCE2) -------------------------------------------------------- -bool OutdoorLocationTerrain::ZeroLandscape() -{ - memset(this->pHeightmap, 0, 0x4000u); - memset(this->pTilemap, 90, 0x4000u); - memset(this->pAttributemap, 0, 0x4000u); - memset(this->pDmap, 0, 0x8000u); - this->field_12 = 128; - this->field_10 = 128; - this->field_16 = 7; - this->field_14 = 7; - this->field_1C = 127; - this->field_18 = 127; - return true; -} - -//----- (0047CD44) -------------------------------------------------------- -bool OutdoorLocationTerrain::Initialize() -{ - pHeightmap = (unsigned __int8 *)malloc(0x4000u);//height map - pTilemap = (unsigned __int8 *)malloc(0x4000u);//tile map - pAttributemap = (unsigned __int8 *)malloc(0x4000u);//карта атрибутов - pDmap = (struct DMap *)malloc(0x8000u); - if (pHeightmap && pTilemap && pAttributemap && pDmap ) - return true; - else - return false; -} - -//----- (0047CDE2) -------------------------------------------------------- -void OutdoorLocation::CreateDebugLocation() -{ - //OutdoorLocation *v1; // esi@1 - void *v2; // eax@1 - void *v3; // ST14_4@1 - void *v4; // eax@1 - void *v5; // ST14_4@1 - void *v6; // eax@1 - //unsigned int v7; // eax@1 - //char v8; // zf@1 - - //v1 = this; - strcpy(this->pLevelFilename, "blank"); - strcpy(this->pLocationFileName, "i6.odm"); - strcpy(this->pLocationFileDescription, "MM6 Outdoor v1.00"); - this->uNumBModels = 0; - this->pTileTypes[0].tileset = Tileset_Grass; - this->pTileTypes[1].tileset = Tileset_Water; - this->pTileTypes[2].tileset = Tileset_6; - this->pTileTypes[3].tileset = Tileset_RoadGrassCobble; - this->LoadTileGroupIds(); - this->LoadRoadTileset(); - free(this->pBModels); - free(this->pSpawnPoints); - this->pBModels = 0; - this->pSpawnPoints = 0; - this->pTerrain.Initialize(); - this->pTerrain.ZeroLandscape(); - this->pTerrain.FillDMap(0, 0, 128, 128); - free(this->pCmap); - this->pCmap = 0; - v2 = malloc(0x8000u); - v3 = this->pOMAP; - this->pCmap = v2; - free(v3); - this->pOMAP = 0; - v4 = malloc(0x10000u); - this->pOMAP = (unsigned int *)v4; - memset(v4, 0, 0x10000u); - v5 = this->pFaceIDLIST; - this->numFaceIDListElems = 0; - free(v5); - this->pFaceIDLIST = 0; - v6 = malloc(2); - this->pFaceIDLIST = (unsigned __int16 *)v6; - *(short *)v6 = 0; - strcpy(this->pSkyTextureName, pDefaultSkyTexture.data()); - this->sSky_TextureID = pBitmaps_LOD->LoadTexture(this->pSkyTextureName); - strcpy(this->pGroundTileset, byte_6BE124_cfg_textures_DefaultGroundTexture.data()); - //v7 = pBitmaps_LOD->LoadTexture(this->pGroundTileset); - this->sMainTile_BitmapID = pBitmaps_LOD->LoadTexture(this->pGroundTileset); - - if ( this->sSky_TextureID == -1 ) - Error("Invalid Sky Tex Handle"); - - if ( this->sMainTile_BitmapID == -1 ) - Error("Invalid Ground Tex Handle"); -} - -//----- (0047CF9C) -------------------------------------------------------- -void OutdoorLocation::Release() -{ - strcpy(pLevelFilename, "blank"); - strcpy(pLocationFileName, "default.odm"); - strcpy(pLocationFileDescription, "MM6 Outdoor v1.00"); - strcpy(pSkyTextureName, "sky043"); - strcpy(pGroundTileset, "hm005"); - - if (pBModels) - { - for (uint i = 0; i < uNumBModels; ++i) - pBModels[i].Release(); - - free(pBModels); - pBModels = nullptr; - uNumBModels = 0; - } - - free(pSpawnPoints); - pSpawnPoints = nullptr; - uNumSpawnPoints = 0; - - pTerrain.Release(); - - free(pCmap); - pCmap = nullptr; - free(pOMAP); - pOMAP = nullptr; - free(pFaceIDLIST); - pFaceIDLIST = nullptr; - free(pTerrainNormals); - pTerrainNormals = nullptr; -} - -//----- (0047D0A6) -------------------------------------------------------- -bool OutdoorLocation::Load(const char *pFilename, ODMFace *File, size_t pNumItems, int *thisa)//загрузка локации -{ - //OutdoorLocation *pOutdoorLocation; // esi@1 - /*bool result; // eax@9 - bool v7; // ebx@9 - size_t v8; // eax@10 - void *v9; // eax@10 - void *v10; // eax@10 - void *v11; // eax@10 - int v12; // ebx@11 - BSPModel *v13; // eax@12 - void *v14; // eax@12 - BSPModel *v15; // ecx@12 - void *v16; // eax@12 - BSPModel *v17; // ecx@12 - BSPModel *v18; // eax@12 - __int16 v19; // ax@15 - __int16 v20; // ax@16 - int v21; // ecx@16 - ODMFace *v22; // ebx@26 - SpriteObject *pItems; // ecx@27 - unsigned int v24; // eax@28 - //unsigned __int8 v25; // zf@28 - //unsigned __int8 v26; // sf@28 - ODMFace *v27; // eax@28 - const char *i; // edx@29 - unsigned __int16 v29; // ax@33 - unsigned __int16 v30; // ax@37 - int v31; // ecx@37 - int v32; // eax@38 - void *v33; // eax@38 - TileDesc *v34; // eax@43 - unsigned int v35; // eax@43 - unsigned int v36; // edi@43 - unsigned int v37; // edi@45*/ - //size_t v38; // eax@50 - FILE *v39; // eax@50 - //unsigned int v40; // edi@56 - //void *v41; // eax@56 - //void *v42; // ebx@56 - //const void *v43; // ebx@59 - //const void *v44; // ebx@59 - //unsigned int v45; // eax@59 - //BSPModel *v46; // eax@59 - //unsigned int v47; // ecx@59 - //int v48; // ebx@60 - //BSPModel *v49; // eax@61 - //BSPModel *v50; // eax@61 - //BSPModel *v51; // eax@61 - //BSPModel *v52; // eax@61 - //BSPModel *v53; // eax@61 - //BSPModel *v54; // ecx@61 - //BSPModel *v55; // ecx@61 - //BSPModel *v56; // ecx@61 - //void *v57; // ST24_4@61 - //BSPModel *v58; // ecx@61 - //void *v59; // ST18_4@61 - //BSPModel *v60; // eax@61 - //__int16 v61; // ax@64 - unsigned __int16 v62; // ax@65 - //ODMFace *v63; // ecx@65 - //unsigned __int16 v64; // ax@80 - //const char *v65; // ecx@80 - //int v66; // eax@81 - //void *v67; // eax@81 - //int v68; // ecx@81 - //void *v69; // eax@81 - //unsigned int v70; // eax@81 - //SpawnPointMM7 *v71; // eax@81 - //unsigned int v72; // ecx@81 - //size_t v73; // eax@81 - //int v74; // edi@87 - //void *v75; // edi@88 - //unsigned int v76; // edx@94 - //int v77; // ecx@94 - //char *v78; // eax@95 - //unsigned int v79; // edx@97 - //unsigned int v80; // eax@99 - //int v81; // eax@107 - //void *v82; // edi@114 - //size_t v83; // eax@120 - //const void *v84; // edi@120 - //const void *v85; // edi@120 - //BSPModel *v86; // eax@124 - //unsigned int v87; // eax@124 - //BSPModel *v88; // eax@126 - //BSPModel *v89; // eax@127 - //ODMFace *v90; // eax@129 - //const void *v91; // edi@138 - //const void *v92; // edi@141 - //const void *v93; // edi@141 - //const void *v94; // edi@144 - //const void *v95; // edi@144 - //const char *v96; // edi@147 - //unsigned int v97; // eax@147 - //TileDesc *v98; // eax@147 - //unsigned int v99; // eax@147 - //int v100; // ecx@150 - //unsigned int v101; // eax@157 -// int v102; // edi@159 - //void *v103; // [sp-14h] [bp-B94h]@55 - //void *v104; // [sp-10h] [bp-B90h]@59 - //size_t v105; // [sp-Ch] [bp-B8Ch]@59 - //char *v106; // [sp-8h] [bp-B88h]@59 -// int v107; // [sp-4h] [bp-B84h]@12 - int v108; // [sp+0h] [bp-B80h]@10 - char Src[968]; // [sp+10h] [bp-B70h]@110 - char Dst[968]; // [sp+3D8h] [bp-7A8h]@50 - char Str[256]; // [sp+7A0h] [bp-3E0h]@50 - /*char DstBuf; // [sp+8A0h] [bp-2E0h]@10 - __int32 Offset; // [sp+8A4h] [bp-2DCh]@10 - __int32 v114; // [sp+8B0h] [bp-2D0h]@10 - __int32 v115; // [sp+8BCh] [bp-2C4h]@10 - __int32 v116; // [sp+8C8h] [bp-2B8h]@10 - __int32 v117; // [sp+8D4h] [bp-2ACh]@10 - __int32 v118; // [sp+8E0h] [bp-2A0h]@10 - __int32 v119; // [sp+8ECh] [bp-294h]@10 - __int32 v120; // [sp+8F8h] [bp-288h]@10 - __int32 v121; // [sp+904h] [bp-27Ch]@10 - __int32 v122; // [sp+910h] [bp-270h]@10 - __int32 v123; // [sp+91Ch] [bp-264h]@10 - __int32 v124; // [sp+928h] [bp-258h]@26 - __int32 v125; // [sp+934h] [bp-24Ch]@35 - __int32 v126; // [sp+940h] [bp-240h]@38 - __int32 v127; // [sp+94Ch] [bp-234h]@38 - __int32 v128; // [sp+958h] [bp-228h]@38 - __int32 v129; // [sp+964h] [bp-21Ch]@38 - __int32 v130; // [sp+970h] [bp-210h]@38 - __int32 v131; // [sp+97Ch] [bp-204h]@38 - __int32 v132; // [sp+988h] [bp-1F8h]@38 - __int32 v133; // [sp+994h] [bp-1ECh]@38 - __int32 v134; // [sp+9A0h] [bp-1E0h]@38 - __int32 v135; // [sp+9ACh] [bp-1D4h]@38 - __int32 v136; // [sp+9D0h] [bp-1B0h]@10*/ - //char FileName[8]; // [sp+A20h] [bp-160h]@8 - //char v138; // [sp+A28h] [bp-158h]@12 - //int v139; // [sp+B1Ch] [bp-64h]@10 - //char pContainer[32]; // [sp+B20h] [bp-60h]@1 - //int *v141; // [sp+B40h] [bp-40h]@50 - //__int64 v142; // [sp+B44h] [bp-3Ch]@55 - //size_t pSource; // [sp+B4Ch] [bp-34h]@56 - //int v144; // [sp+B50h] [bp-30h]@61 - //int v145; // [sp+B54h] [bp-2Ch]@68 - ODMHeader header; // [sp+B58h] [bp-28h]@50 - //unsigned int pDestLen; // [sp+B68h] [bp-18h]@13 - //FILE *ptr; // [sp+B6Ch] [bp-14h]@12 - //void *v149; // [sp+B70h] [bp-10h]@19 - char *Str2; // [sp+B74h] [bp-Ch]@12 - //int v151; // [sp+B78h] [bp-8h]@59 - //void *uSourceLen; // [sp+B7Ch] [bp-4h]@59 - - //pOutdoorLocation = this; - //strcpy(pContainer, pFilename); - - if (bUnderwater) - { - pPaletteManager->pPalette_tintColor[0] = 0x10; - pPaletteManager->pPalette_tintColor[1] = 0xC2; - pPaletteManager->pPalette_tintColor[2] = 0x99; - pPaletteManager->SetMistColor(37, 143, 92); - } - else - { - pPaletteManager->pPalette_tintColor[0] = 0; - pPaletteManager->pPalette_tintColor[1] = 0; - pPaletteManager->pPalette_tintColor[2] = 0; - if (pPaletteManager->pPalette_mistColor[0] != 0x80 || - pPaletteManager->pPalette_mistColor[1] != 0x80 || - pPaletteManager->pPalette_mistColor[2] != 0x80) - { - pPaletteManager->SetMistColor(128, 128, 128); - pPaletteManager->RecalculateAll(); - } - } - - _6807E0_num_decorations_with_sounds_6807B8 = 0; - /*sprintf(FileName, "levels\\%s", pContainer); - if ( GetFileAttributesA(FileName) != -1 ) - { - result = (bool)fopen(FileName, "rb"); - v7 = result; - File = (ODMFace *)result; - if ( !result ) - return result; - *(int *)thisa = 1; - v8 = strlen(pContainer); - v108 = 2; - *((char *)&v139 + v8) = 0; - viewparams->uTextureID_LocationMap = pIcons_LOD->LoadTexture(pContainer, (enum TEXTURE_TYPE)v108); - fread(&DstBuf, 0x180u, 1u, (FILE *)v7); - fseek((FILE *)v7, Offset, 0); - fread(this, 0xB0u, 1u, (FILE *)v7); - LoadTileGroupIds(); - LoadRoadTileset(); - strcpy(pGroundTileset, "grastyl"); - fseek((FILE *)v7, v114, 0); - fread(&uNumBModels, 4u, 1u, (FILE *)v7); - fseek((FILE *)v7, v115, 0); - fread(&uNumSpriteObjects, 4u, 1u, (FILE *)v7); - fseek((FILE *)v7, v116, 0); - fread(&uNumLevelDecorations, 4u, 1u, (FILE *)v7); - fseek((FILE *)v7, v117, 0); - fread(&uNumActors, 4u, 1u, (FILE *)v7); - fseek((FILE *)v7, v118, 0); - fread(&uNumChests, 4u, 1u, (FILE *)v7); - pTerrain.Initialize(); - fseek((FILE *)v7, v119, 0); - fread(pTerrain.pHeightmap, 1u, 0x4000u, (FILE *)v7); - fseek((FILE *)v7, v120, 0); - fread(pTerrain.pTilemap, 1u, 0x4000u, (FILE *)v7); - fseek((FILE *)v7, v121, 0); - fread(pTerrain.pAttributemap, 1u, 0x4000u, (FILE *)v7); - pTerrain._47C80A(0, 0, 128, 128); - free(ptr_D4); - ptr_D4 = 0; - v9 = malloc(0, 0x8000u, "CMAP"); - v108 = (int)pOMAP; - ptr_D4 = v9; - free((void *)v108); - pOMAP = 0; - v10 = malloc(0, 0x10000u, "OMAP"); - v108 = 0; - pOMAP = (unsigned int *)v10; - fseek((FILE *)v7, v136, v108); - fread(&uNumTerrainNormals, 4u, 1u, (FILE *)v7); - fread(pTerrainSomeOtherData, 1u, 0x20000u, (FILE *)v7); - fread(pTerrainNormalIndices, 1u, 0x10000u, (FILE *)v7); - pTerrainNormals = (Vec3_float_ *)malloc(pTerrainNormals, 12 * uNumTerrainNormals, "TerNorm"); - fread(pTerrainNormals, 1u, 12 * uNumTerrainNormals, (FILE *)v7); - v11 = malloc(pBModels, 188 * uNumBModels, "BDdata"); - v108 = 0; - pBModels = (BSPModel *)v11; - fseek((FILE *)v7, v122, v108); - fread(pBModels, 0xBCu, uNumBModels, (FILE *)v7); - fseek((FILE *)v7, v123, 0); - pNumItems = 0; - if ( (signed int)uNumBModels > 0 ) - { - v12 = 0; - while ( 1 ) - { - pBModels[v12].pVertices.pVertices = 0; - pBModels[v12].pFaces = 0; - pBModels[v12].pFacesOrdering = 0; - pBModels[v12].pNodes = 0; - FileName[0] = 0; - v108 = (int)&pBModels[v12]; - sprintfex(FileName, "%s", v108); - v13 = pBModels; - v138 = 0; - pBModels[v12].pVertices.pVertices = (Vec3_int_ *)malloc(v13[v12].pVertices.pVertices, 12 * v13[v12].pVertices.uNumVertices, - FileName); - pBModels[v12].pFaces = (ODMFace *)malloc(pBModels[v12].pFaces, 308 * pBModels[v12].uNumFaces, - FileName); - pBModels[v12].pFacesOrdering = (unsigned __int16 *)malloc(pBModels[v12].pFacesOrdering, - 2 * pBModels[v12].uNumFaces, FileName); - v14 = malloc(pBModels[v12].pNodes, 8 * pBModels[v12].uNumNodes, FileName); - v15 = pBModels; - v108 = (int)File; - v15[v12].pNodes = (BSPNode *)v14; - fread(pBModels[v12].pVertices.pVertices, 0xCu, pBModels[v12].pVertices.uNumVertices, (FILE *)v108); - fread(pBModels[v12].pFaces, 0x134u, pBModels[v12].uNumFaces, (FILE *)File); - fread(pBModels[v12].pFacesOrdering, 2u, pBModels[v12].uNumFaces, (FILE *)File); - fread(pBModels[v12].pNodes, 8u, pBModels[v12].uNumNodes, (FILE *)File); - v16 = malloc(10 * pBModels[v12].uNumFaces); - v107 = (int)File; - v17 = pBModels; - ptr = (FILE *)v16; - fread(v16, 0xAu, v17[v12].uNumFaces, (FILE *)File); - v18 = pBModels; - Str2 = 0; - if ( (signed int)v18[v12].uNumFaces > 0 ) - break; -LABEL_25: - free(ptr); - ++pNumItems; - ++v12; - if ( (signed int)pNumItems >= (signed int)uNumBModels ) - goto LABEL_26; - } - pDestLen = 0; - pFilename = (char *)ptr; - while ( 1 ) - { - thisa = (int)((char *)v18[v12].pFaces + pDestLen); - if ( !(*(char *)(thisa + 29) & 0x40) ) - break; - v19 = pTextureFrameTable->FindTextureByName(pFilename); - *(short *)(thisa + 272) = v19; - if ( !v19 ) - { - v20 = pBitmaps_LOD->LoadTexture(pFilename); - v21 = thisa; - *(char *)(v21 + 29) &= 0xBFu; -LABEL_19: - *(short *)(v21 + 272) = v20; - v149 = (void *)(v20 != -1 ? &pBitmaps_LOD->pTextures[v20] : 0); - auto pTex = (Texture *)v149; - if (pTex) - pTex->palette_id2 = pPaletteManager->LoadPalette(pTex->palette_id1); - goto LABEL_20; - } - pTextureFrameTable->LoadAnimationSequenceAndPalettes(*(unsigned __int16 *)((char *)&pBModels[v12].pFaces->uTextureID + pDestLen)); -LABEL_20: - if ( *(short *)(thisa + 292) ) - { - if ( ((ODMFace *)thisa)->HasEventHint() ) - *(char *)(thisa + 30) |= 0x10u; - else - *(char *)(thisa + 30) &= 0xEFu; - } - ++Str2; - v18 = pBModels; - pDestLen += 308; - pFilename += 10; - if ( (signed int)Str2 >= (signed int)v18[v12].uNumFaces ) - goto LABEL_25; - } - v20 = pBitmaps_LOD->LoadTexture(pFilename); - v21 = thisa; - goto LABEL_19; - } -LABEL_26: - v22 = File; - fseek((FILE *)File, v124, 0); - fread(pSpriteObjects, 0x70u, uNumSpriteObjects, (FILE *)v22); - if ( (signed int)uNumSpriteObjects > 0 ) - { - pItems = pSpriteObjects; - pNumItems = uNumSpriteObjects; - do - { - v24 = pItems->stru_24.uItemID; - thisa = 0; - v27 = (ODMFace *)(48 * v24); - v25 = pObjectList->uNumObjects == 0; - v26 = (pObjectList->uNumObjects & 0x80000000u) != 0; - LOWORD(v27) = *(short *)((char *)&v27->pFacePlane.vNormal.x + (int)((char *)&pItemsTable + 24)); - File = v27; - pItems->uItemType = (unsigned __int16)v27; - if ( v26 | v25 ) - { -LABEL_33: - v29 = 0; - } - else - { - for ( i = (const char *)&pObjectList->pObjects->uObjectID; (short)v27 != *(short *)i; i = pFilename ) - { - ++thisa; - pFilename = (char *)i + 56; - if ( thisa >= (signed int)pObjectList->uNumObjects ) - goto LABEL_33; - LOWORD(v27) = (short)File; - } - v29 = thisa; - } - pItems->uObjectDescID = v29; - ++pItems; - --pNumItems; - } - while ( pNumItems ); - } - fseek((FILE *)v22, v125, 0); - fread(pLevelDecorations, 0x20u, uNumLevelDecorations, (FILE *)v22); - pNumItems = 0; - if ( (signed int)uNumLevelDecorations > 0 ) - { - thisa = (int)pLevelDecorations; - do - { - fread(FileName, 1u, 0x20u, (FILE *)v22); - v30 = pDecorationList->GetDecorIdByName(FileName); - v31 = thisa; - ++pNumItems; - thisa += 32; - *(short *)v31 = v30; - } - while ( (signed int)pNumItems < (signed int)uNumLevelDecorations ); - } - fseek((FILE *)v22, v126, 0); - fread(pActors, 0x344u, uNumActors, (FILE *)v22); - fseek((FILE *)v22, v127, 0); - fread(pChests, 0x14CCu, uNumChests, (FILE *)v22); - fseek((FILE *)v22, v128, 0); - fread(&field_DC, 4u, 1u, (FILE *)v22); - free(pFaceIDLIST); - v32 = field_DC; - pFaceIDLIST = 0; - v33 = malloc(0, 2 * v32, "IDLIST"); - v108 = (int)v22; - pFaceIDLIST = (unsigned __int16 *)v33; - fread(v33, 2u, field_DC, (FILE *)v108); - fseek((FILE *)v22, v129, 0); - fread(pOMAP, 4u, 0x4000u, (FILE *)v22); - fseek((FILE *)v22, v130, 0); - fread(&uNumSpawnPoints, 4u, 1u, (FILE *)v22); - pSpawnPoints = (SpawnPointMM7 *)malloc(pSpawnPoints, 24 * uNumSpawnPoints, "Spawn"); - fseek((FILE *)v22, v131, 0); - fread(pSpawnPoints, 0x18u, uNumSpawnPoints, (FILE *)v22); - fseek((FILE *)v22, v132, 0); - fread(&ddm, 0x28u, 1u, (FILE *)v22); - fseek((FILE *)v22, v133, 0); - fread(&stru_5E4C90, 1u, 0xC8u, (FILE *)v22); - fseek((FILE *)v22, v134, 0); - fread(&uLastVisitDay, 1u, 0x38u, (FILE *)v22); - fseek((FILE *)v22, v135, 0); - fread(&uLastVisitDay, 1u, 4u, (FILE *)v22); - thisa = (int)pTileTypes; - pTileTable->InitializeTileset(4); - pTileTable->InitializeTileset(pTileTypes[0].uTileGroup); - pTileTable->InitializeTileset(pTileTypes[1].uTileGroup); - pTileTable->InitializeTileset(pTileTypes[2].uTileGroup); - pTileTable->InitializeTileset(pTileTypes[3].uTileGroup); - if ( this != (OutdoorLocation *)-96 && pSkyTextureName[0] ) - { - v108 = 0; - v107 = (int)pSkyTextureName; - } - else - { - v108 = 0; - v107 = (int)pDefaultSkyTexture; - } - sSky_TextureID = pBitmaps_LOD->LoadTexture((const char *)v107, (enum TEXTURE_TYPE)v108); - strcpy(pGroundTileset, byte_6BE124_cfg_textures_DefaultGroundTexture); - v34 = pTileTable->GetTileById(pTileTypes[0].uTileID); - v35 = pBitmaps_LOD->LoadTexture(v34->pTileName); - v36 = sSky_TextureID; - sMainTile_BitmapID = v35; - if ( v36 != -1 ) - pBitmaps_LOD->pTextures[v36].palette_id2 = pPaletteManager->LoadPalette(pBitmaps_LOD->pTextures[v36].palette_id1); - - v37 = sMainTile_BitmapID; - if ( v37 != -1 ) - pBitmaps_LOD->pTextures[v37].palette_id2 = pPaletteManager->LoadPalette(pBitmaps_LOD->pTextures[v37].palette_id1); - - _47F0E2(); - pGameLoadingUI_ProgressBar->Progress(); - fclose((FILE *)v22); - goto LABEL_150; - }*/ - - assert(sizeof(BSPModel) == 188); - - if (!pGames_LOD->DoesContainerExist(pFilename)) - Error("Unable to find %s in Games.LOD", pFilename); - - - char pMinimapTextureFilename[1024]; - strcpy(pMinimapTextureFilename, pFilename); - pMinimapTextureFilename[strlen(pMinimapTextureFilename) - 4] = 0; - viewparams->uTextureID_LocationMap = pIcons_LOD->LoadTexture(pMinimapTextureFilename, TEXTURE_16BIT_PALETTE); - - //strcpy(FileName, pContainer); - strcpy(Str, pFilename); - strcpy(Str + strlen(Str) - 4, ".odm"); - //v141 = &v139; - //v38 = strlen(pFilename); - //strcpy((char *)&v139 + v38, ".odm"); - v39 = pGames_LOD->FindContainer(Str, 1); - //Str[strlen(Str) - 4] = 0; - - header.uCompressedSize = 0; - header.uDecompressedSize = 0; - //ptr = v39; - header.uVersion = 91969; - header.pMagic[0] = 'm'; - header.pMagic[1] = 'v'; - header.pMagic[2] = 'i'; - header.pMagic[3] = 'i'; - fread(&header, 0x10u, 1u, v39); - if (header.uVersion != 91969 || - header.pMagic[0] != 'm' || - header.pMagic[1] != 'v' || - header.pMagic[2] != 'i' || - header.pMagic[3] != 'i') - { - MessageBoxW(nullptr, L"Can't load file!", - L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Odmap.cpp:507", 0); - } - //v40 = header.uCompressedSize; - //pSource = header.uDecompressedSize; - //v41 = malloc(header.uDecompressedSize); - uchar* pSrcMem = (unsigned char *)malloc(header.uDecompressedSize); - uchar* pSrc = pSrcMem; - //v42 = v41; - //HIDWORD(v142) = (uint32)pSrc; - if (header.uCompressedSize < header.uDecompressedSize) - { - char* pComressedSrc = (char *)malloc(header.uCompressedSize); - fread(pComressedSrc, header.uCompressedSize, 1, v39); - - uint actualDecompressedSize = header.uDecompressedSize; - zlib::MemUnzip(pSrc, &actualDecompressedSize, pComressedSrc, header.uCompressedSize); - free(pComressedSrc); - } - else - { - fread(pSrc, header.uDecompressedSize, 1, v39); - } - - memcpy(pLevelFilename, pSrc, 0x20); - memcpy(pLocationFileName, pSrc + 0x20, 0x20); - memcpy(pLocationFileDescription, pSrc + 0x40, 0x20); - memcpy(pSkyTextureName, pSrc + 3 * 32, 32); - memcpy(pGroundTileset, pSrc + 0x80, 0x20); - memcpy(pTileTypes, pSrc + 0xA0, 0x10); - pSrc += 0xB0; - - //v43 = (char *)pSrc + 176; - LoadTileGroupIds(); - LoadRoadTileset(); - strcpy(pGroundTileset, "grastyl"); - pGameLoadingUI_ProgressBar->Progress(); - pTerrain.Initialize(); - //v108 = 16384; - //v107 = (int)v43; - //v106 = (char *)pTerrain.pHeightmap; - memcpy(pTerrain.pHeightmap, pSrc, 0x4000); - pSrc += 0x4000; - - //v43 = (char *)v43 + 16384; - //v105 = 16384; - //v104 = (void *)v43; - //v103 = pTerrain.pTilemap; - memcpy(pTerrain.pTilemap, pSrc, 0x4000); - pSrc += 0x4000; - - //v43 = (char *)v43 + 16384; - memcpy(pTerrain.pAttributemap, pSrc, 0x4000); - pSrc += 0x4000; - - //v43 = (char *)v43 + 16384; - //v108 = (int)ptr_D4; - free(pCmap); - pCmap = malloc(0x8000); - pTerrain.FillDMap(0, 0, 128, 128); - - pGameLoadingUI_ProgressBar->Progress(); - memcpy(&uNumTerrainNormals, pSrc, 4); - //v43 = (char *)v43 + 4; - memcpy(pTerrainSomeOtherData.data(), pSrc + 4, 0x20000); - pSrc += 4 + 0x20000; - //v43 = (char *)v43 + 131072; - memcpy(pTerrainNormalIndices.data(), pSrc, 0x10000); - pSrc += 0x10000; - //v43 = (char *)v43 + 65536; - - //pFilename = (char *)(12 * uNumTerrainNormals); - pTerrainNormals = (Vec3_float_ *)malloc(sizeof(Vec3_float_) * uNumTerrainNormals); - memcpy(pTerrainNormals, pSrc, 12 * uNumTerrainNormals); - pSrc += 12 * uNumTerrainNormals; - //v44 = (char *)v43 + (int)pFilename; - //v44 = (char *)v44 + 4; - //v45 = uNumBModels; - //v108 = (int)"BDdata"; - - pGameLoadingUI_ProgressBar->Progress(); - - //v107 = 188 * v45; - //v106 = (char *)pBModels; - //v46 = (BSPModel *)malloc(v106, 188 * v45, "BDdata"); - //v47 = uNumBModels; - memcpy(&uNumBModels, pSrc, 4); - pBModels = (BSPModel *)malloc(188 * uNumBModels); - //pFilename = (char *)(188 * v47); - memcpy(pBModels, pSrc + 4, 188 * uNumBModels); - pSrc += 4 + 188 * uNumBModels; - - pGameLoadingUI_ProgressBar->Progress(); - - //uSourceLen = (char *)v44 + (int)pFilename; - //v151 = 0; - for (uint i = 0; i < uNumBModels; ++i) - { - //v48 = 0; - //BSPModel* model = &pBModels[i]; - - pBModels[i].pVertices.pVertices = nullptr; - pBModels[i].pFaces = nullptr; - pBModels[i].pFacesOrdering = nullptr; - pBModels[i].pNodes = nullptr; - //FileName[0] = 0; - //v108 = (int)&pBModels[i]; - //sprintf(FileName, "%s", v108); - //v49 = pBModels; - //v138 = 0; - //v50 = &pBModels[v48]; - //v108 = (int)FileName; - //v107 = 12 * v50->pVertices.uNumVertices; - //v106 = (char *)v50->pVertices.pVertices; - assert(sizeof(Vec3_int_) == 12); - uint verticesSize = pBModels[i].pVertices.uNumVertices * sizeof(Vec3_int_); - pBModels[i].pVertices.pVertices = (Vec3_int_ *)malloc(verticesSize); - memcpy(pBModels[i].pVertices.pVertices, pSrc, verticesSize); - pSrc += verticesSize; - //v51 = &pBModels[v48]; - //v108 = (int)FileName; - //v107 = 308 * v51->uNumFaces; - //v106 = (char *)v51->pFaces; - assert(sizeof(ODMFace) == 308); - uint facesSize = pBModels[i].uNumFaces * sizeof(ODMFace); - pBModels[i].pFaces = (ODMFace *)malloc(facesSize); - memcpy(pBModels[i].pFaces, pSrc, facesSize); - pSrc += facesSize; - //v52 = &pBModels[v48]; - //v108 = (int)FileName; - //v107 = 2 * v52->uNumFaces; - //v106 = (char *)v52->pFacesOrdering; - uint facesOrderingSize = pBModels[i].uNumFaces * sizeof(short); - pBModels[i].pFacesOrdering = (unsigned __int16 *)malloc(facesOrderingSize); - memcpy(pBModels[i].pFacesOrdering, pSrc, facesOrderingSize); - pSrc += facesOrderingSize; - //v53 = &pBModels[v48]; - //v108 = (int)FileName; - //v107 = 8 * v53->uNumNodes; - //v106 = (char *)v53->pNodes; - assert(sizeof(BSPNode) == 8); - uint nodesSize = pBModels[i].uNumNodes * sizeof(BSPNode); - pBModels[i].pNodes = (BSPNode *)malloc(nodesSize); - memcpy(pBModels[i].pNodes, pSrc, nodesSize); - pSrc += nodesSize; - //v54 = &pBModels[v48]; - //v108 = 12 * v54->pVertices.uNumVertices; - //pFilename = (char *)v108; - //v107 = (int)uSourceLen; - //v106 = (char *)v54->pVertices.pVertices; - //memcpy(v106, uSourceLen, v108); - //uSourceLen = (char *)uSourceLen + (int)pFilename; - //v55 = &pBModels[v48]; - //v105 = 308 * v55->uNumFaces; - //v104 = uSourceLen; - //v103 = v55->pFaces; - //pFilename = (char *)v105; - //memcpy(v103, uSourceLen, v105); - //v56 = &pBModels[v48]; - //uSourceLen = (char *)uSourceLen + (int)pFilename; - //v57 = v56->pFacesOrdering; - //pFilename = (char *)(2 * v56->uNumFaces); - //memcpy(v57, uSourceLen, (size_t)pFilename); - //v58 = &pBModels[v48]; - //uSourceLen = (char *)uSourceLen + (int)pFilename; - //v59 = v58->pNodes; - //pFilename = (char *)(8 * v58->uNumNodes); - //memcpy(v59, uSourceLen, (size_t)pFilename); - //uSourceLen = (char *)uSourceLen + (int)pFilename; - //ptr = (FILE *)malloc(10 * model->uNumFaces); - const char* textureFilenames = (const char *)malloc(10 * pBModels[i].uNumFaces); - //pFilename = (char *)(10 * pBModels[v48].uNumFaces); - memcpy((char *)textureFilenames, pSrc, 10 * pBModels[i].uNumFaces); - pSrc += 10 * pBModels[i].uNumFaces; - //v144 = 0; - //uSourceLen = (char *)uSourceLen + (int)pFilename; - //v60 = pBModels; - for (uint j = 0; j < pBModels[i].uNumFaces; ++j) - { - const char* texFilename = &textureFilenames[j * 10]; - //v149 = 0; - //Str2 = (char *)ptr; - - //ODMFace* face = &pBModels[i].pFaces[j]; - //pFilename = (char *)v149 + (unsigned int)v60[v48].pFaces; - if ( !(pBModels[i].pFaces[j].uAttributes & FACE_DONT_CACHE_TEXTURE)) - { - v62 = pBitmaps_LOD->LoadTexture(texFilename); -// v63 = (ODMFace *)pFilename; - pBModels[i].pFaces[j].uTextureID = v62; - //v145 = (signed __int16)v62 != -1 ? &pBitmaps_LOD->pTextures[(signed __int16)v62] : 0; - //v108 = ((signed __int16)v62 != -1 ? pBitmaps_LOD->pTextures[(signed __int16)v62].palette_id1 : 36); - if ((signed __int16)v62 != -1) - pBitmaps_LOD->pTextures[v62].palette_id2 = pPaletteManager->LoadPalette(pBitmaps_LOD->pTextures[v62].palette_id1); - //goto LABEL_69; - //goto LABEL_68; - } - else - { - //v61 = pTextureFrameTable->FindTextureByName(texFilename); - pBModels[i].pFaces[j].uTextureID = pTextureFrameTable->FindTextureByName(texFilename); - if (!pBModels[i].pFaces[j].uTextureID) - { - v62 = pBitmaps_LOD->LoadTexture(texFilename); - //v63 = (ODMFace *)pFilename; - pBModels[i].pFaces[j].uAttributes &= ~FACE_DONT_CACHE_TEXTURE; - //LABEL_68: - pBModels[i].pFaces[j].uTextureID = v62; - //v145 = (signed __int16)v62 != -1 ? &pBitmaps_LOD->pTextures[(signed __int16)v62] : 0; - //v108 = ((signed __int16)v62 != -1 ? pBitmaps_LOD->pTextures[(signed __int16)v62].palette_id1 : 36); - if ((signed __int16)v62 != -1) - pBitmaps_LOD->pTextures[v62].palette_id2 = pPaletteManager->LoadPalette(pBitmaps_LOD->pTextures[v62].palette_id1); - //goto LABEL_69; - } - else - pTextureFrameTable->LoadAnimationSequenceAndPalettes(pBModels[i].pFaces[j].uTextureID); - } -//LABEL_69: - if (pBModels[i].pFaces[j].sCogTriggeredID) - { - if (pBModels[i].pFaces[j].HasEventHint()) - pBModels[i].pFaces[j].uAttributes |= FACE_HAS_EVENT; - else - pBModels[i].pFaces[j].uAttributes &= ~FACE_HAS_EVENT; - } - //++v144; - //v60 = pBModels; - //v149 = (char *)v149 + 308; - //Str2 += 10; - //if ( v144 >= (signed int)v60[v48].uNumFaces ) - //goto LABEL_74; - } - -//LABEL_74: - free((void *)textureFilenames); -// ++v151; -// ++v48; -// if ( v151 >= (signed int)uNumBModels ) -// goto LABEL_75; - } -//LABEL_75: - pGameLoadingUI_ProgressBar->Progress(); - - memcpy(&uNumLevelDecorations, pSrc, 4); - //uSourceLen = (char *)uSourceLen + 4; - if (uNumLevelDecorations > 3000) - MessageBoxW(nullptr, L"Can't load file!", - L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Odmap.cpp:678", 0); - - assert(sizeof(LevelDecoration) == 32); - //pFilename = (char *)(32 * uNumLevelDecorations); - memcpy(pLevelDecorations.data(), pSrc + 4, uNumLevelDecorations * sizeof(LevelDecoration)); - pSrc += 4 + sizeof(LevelDecoration) * uNumLevelDecorations; - - pGameLoadingUI_ProgressBar->Progress(); - - //v151 = 0; - //uSourceLen = (char *)uSourceLen + (int)pFilename; - for (uint i = 0; i < uNumLevelDecorations; ++i) - { - char name[256]; - memcpy(name, pSrc, sizeof(LevelDecoration)); - pSrc += sizeof(LevelDecoration); - - pLevelDecorations[i].uDecorationDescID = pDecorationList->GetDecorIdByName(name); - } - - pGameLoadingUI_ProgressBar->Progress(); - - memcpy(&numFaceIDListElems, pSrc, 4); - - //uSourceLen = (char *)uSourceLen + 4; - //v108 = (int)pFaceIDLIST; - free(pFaceIDLIST); - pFaceIDLIST = nullptr; - //v66 = field_DC; - //pFaceIDLIST = 0; - //v67 = malloc(0, 2 * v66, "IDLIST"); - uint faceIDListSize = 2 * numFaceIDListElems; - pFaceIDLIST = (unsigned short *)malloc(faceIDListSize); - //v68 = field_DC; - //pFaceIDLIST = (unsigned __int16 *)v67; - //pFilename = (char *)(2 * v68); - memcpy(pFaceIDLIST, pSrc + 4, faceIDListSize); - pSrc += 4 + faceIDListSize; - - //uSourceLen = (char *)uSourceLen + (int)pFilename; - pGameLoadingUI_ProgressBar->Progress(); - - //v108 = (int)pOMAP; - //free((void *)v108); - //pOMAP = 0; - free(pOMAP); - //v69 = malloc(0, 0x10000u, "OMAP"); - pOMAP = (unsigned int *)malloc(0x10000); - //v108 = 65536; - //pOMAP = (unsigned int *)v69; - memcpy(pOMAP, pSrc, 65536); - pSrc += 65536; - - //uSourceLen = (char *)uSourceLen + 65536; - pGameLoadingUI_ProgressBar->Progress(); - - memcpy(&uNumSpawnPoints, pSrc, 4); - //uSourceLen = (char *)uSourceLen + 4; - pGameLoadingUI_ProgressBar->Progress(); - //v70 = uNumSpawnPoints; - //v108 = (int)"Spawn"; - //v107 = 24 * v70; - //v106 = (char *)pSpawnPoints; - assert(sizeof(SpawnPointMM7) == 24); - uint spawnPointsSize = uNumSpawnPoints * sizeof(SpawnPointMM7); - pSpawnPoints = (SpawnPointMM7 *)malloc(spawnPointsSize); - //v72 = uNumSpawnPoints; - //pSpawnPoints = v71; - memcpy(pSpawnPoints, pSrc + 4, spawnPointsSize); - pSrc += 4 + spawnPointsSize; - - pGameLoadingUI_ProgressBar->Progress(); - - free(pSrcMem); - - //v108 = (int)".ddm"; - //v73 = strlen(pContainer); - strcpy(Str + strlen(Str) - 4, ".ddm"); - //strcpy((char *)v141 + v73, (const char *)v108); - v39 = pNew_LOD->FindContainer(Str, 1);//error - fread(&header, 0x10u, 1, v39); - Str2 = 0; - if (header.uVersion != 91969 || - header.pMagic[0] != 'm' || - header.pMagic[1] != 'v' || - header.pMagic[2] != 'i' || - header.pMagic[3] != 'i' ) - { - MessageBoxW(nullptr, L"Can't load file!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Odmap.cpp:746", 0); - Str2 = (char *)1; - } - //v74 = 0; - //pFilename = (char *)header.uCompressedSize; - //v149 = 0; - //pDestLen = header.uDecompressedSize; - if ( !Str2 ) - { - pSrcMem = (unsigned char *)malloc(header.uDecompressedSize); - pSrc = pSrcMem; - //v149 = v75; - if (header.uCompressedSize == header.uDecompressedSize) - fread(pSrc, header.uDecompressedSize, 1u, v39); - else if (header.uCompressedSize < header.uDecompressedSize) - { - void* compressedMem = malloc(header.uCompressedSize); - fread(compressedMem, header.uCompressedSize, 1, v39); - - uint actualDecompressedSize = header.uDecompressedSize; - zlib::MemUnzip(pSrc, &actualDecompressedSize, compressedMem, header.uCompressedSize); - free(compressedMem); - } - else - MessageBoxW(nullptr, L"Can't load file!", - L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Odmap.cpp:765", 0); - - assert(sizeof(DDM_DLV_Header) == 0x28); - memcpy(&ddm, pSrc, sizeof(DDM_DLV_Header)); - pSrc += sizeof(DDM_DLV_Header); - //v74 = (int)((char *)v75 + 40); - } - uint actualNumFacesInLevel = 0; - for (uint i = 0; i < uNumBModels; ++i) - actualNumFacesInLevel += pBModels[i].uNumFaces; - - //v79 = ddm.uNumFacesInBModels; - if (ddm.uNumFacesInBModels) - { - if ( ddm.uNumBModels ) - { - //v80 = ddm.uNumDecorations; - if (ddm.uNumDecorations) - { - if (ddm.uNumFacesInBModels != actualNumFacesInLevel || - ddm.uNumBModels != uNumBModels || - ddm.uNumDecorations != uNumLevelDecorations ) - Str2 = (char *)1; - } - } - } - - if (dword_6BE364_game_settings_1 & GAME_SETTINGS_2000) - pNumItems = 0x1BAF800; - - if (Str2 || ((unsigned int)((char *)File - ddm.uLastRepawnDay) >= pNumItems || !ddm.uLastRepawnDay)) - { - - if (Str2) - { - memset(Dst, 0, 0x3C8u); - memset(Src, 0, 0x3C8u); - //goto LABEL_112; - } - //v81 = ddm.uLastRepawnDay; - if ((unsigned int)((char *)File - ddm.uLastRepawnDay) >= pNumItems || !ddm.uLastRepawnDay) - { - memcpy(Dst, pSrc, 0x3C8u); - memcpy(Src, pSrc + 968, 0x3C8u); - } - //LABEL_112: - free(pSrcMem); - - ddm.uLastRepawnDay = (int)File; - if (Str2 == 0) - ++ddm.uNumRespawns; - v108 = 0; - *thisa = 1; - v39 = pGames_LOD->FindContainer(Str, 0); - fread(&header, 0x10, 1u, v39); - //pFilename = (char *)header.uCompressedSize; - //pDestLen = header.uDecompressedSize; - //v82 = malloc(header.uDecompressedSize); - pSrcMem = (unsigned char *)malloc(header.uDecompressedSize); - //v149 = v82; - if (header.uCompressedSize == header.uDecompressedSize) - fread(pSrcMem, header.uDecompressedSize, 1, v39); - else if (header.uCompressedSize < header.uDecompressedSize) - { - void* compressedMem = malloc(header.uCompressedSize); - fread(compressedMem, header.uCompressedSize, 1u, v39); - - uint actualDecompressedSize = header.uDecompressedSize; - zlib::MemUnzip(pSrcMem, &actualDecompressedSize, compressedMem, header.uCompressedSize); - free(compressedMem); - } - else - MessageBoxW(nullptr, L"Can't load file!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Odmap.cpp:857", 0); - - pSrc = pSrcMem + 40; - //goto LABEL_120; - } - else - *thisa = 0; -//LABEL_120: - //v108 = (int)".odm"; - //v83 = strlen(pContainer); - //strcpy((char *)v141 + v83, (const char *)v108); - memcpy(uFullyRevealedCellOnMap, pSrc, 0x3C8); - //v84 = (const void *)(v74 + 968); - memcpy(uPartiallyRevealedCellOnMap, pSrc + 0x3C8, 0x3C8); - pSrc += 2 * 0x3C8; - //v85 = (char *)v84 + 968; - - pGameLoadingUI_ProgressBar->Progress(); - - if ( *thisa ) - { - memcpy(uFullyRevealedCellOnMap, Dst, 0x3C8u); - memcpy(uPartiallyRevealedCellOnMap, Src, 0x3C8u); - } - - for (uint i = 0; i < uNumBModels; ++i) - { - BSPModel model = pBModels[i]; - for (uint j = 0; j < model.uNumFaces; ++j) - { - ODMFace face = model.pFaces[j]; - memcpy(&face.uAttributes, pSrc, 4); - pSrc += 4; - } - - for (uint j = 0; j < model.uNumFaces; ++j) - { - ODMFace face = model.pFaces[j]; - if (face.sCogTriggeredID) - { - if (face.HasEventHint()) - face.uAttributes |= FACE_HAS_EVENT_HINT; - else - face.uAttributes &= ~FACE_HAS_EVENT_HINT;//~0x00001000 - } - } - } - - pGameLoadingUI_ProgressBar->Progress(); - - for (uint i = 0; i < uNumLevelDecorations; ++i) - { - memcpy(&pLevelDecorations[i].uFlags, pSrc, 2); - pSrc += 2; - } - - pGameLoadingUI_ProgressBar->Progress(); - - memcpy(&uNumActors, pSrc, 4); - if (uNumActors > 500) - MessageBoxW(nullptr, L"Can't load file!", - L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Odmap.cpp:939", 0); - - pGameLoadingUI_ProgressBar->Progress(); - - assert(sizeof(Actor) == 836); - //pFilename = (char *)(836 * uNumActors); - memcpy(pActors.data(), pSrc + 4, uNumActors * sizeof(Actor)); - pSrc += 4 + uNumActors * sizeof(Actor); - //v92 = (char *)v91 + (int)pFilename; - pGameLoadingUI_ProgressBar->Progress(); - - memcpy(&uNumSpriteObjects, pSrc, 4); - assert(uNumSpriteObjects <= 1000 && "Too many objects"); - assert(sizeof(SpriteObject) == 112); - - pGameLoadingUI_ProgressBar->Progress(); - - //pFilename = (char *)(112 * uNumSpriteObjects); - memcpy(pSpriteObjects.data(), pSrc + 4, uNumSpriteObjects * sizeof(SpriteObject)); - pSrc += 4 + uNumSpriteObjects * sizeof(SpriteObject); - - //v94 = (char *)v93 + (int)pFilename; - pGameLoadingUI_ProgressBar->Progress(); - - memcpy(&uNumChests, pSrc, 4); - //v95 = (char *)v94 + 4; - if (uNumChests > 20) - MessageBoxW(nullptr, L"Can't load file!", - L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Odmap.cpp:968", 0); - - pGameLoadingUI_ProgressBar->Progress(); - - assert(sizeof(Chest) == 5324); - //pFilename = (char *)(5324 * uNumChests); - memcpy(pChests.data(), pSrc + 4 , uNumChests * sizeof(Chest)); - pSrc += 4 + uNumChests * sizeof(Chest); - //v96 = (char *)v95 + (int)pFilename; - pGameLoadingUI_ProgressBar->Progress(); - - memcpy(&stru_5E4C90_MapPersistVars, pSrc, 0xC8); - pSrc += 0xC8; - - pGameLoadingUI_ProgressBar->Progress(); - memcpy(&loc_time, pSrc, 0x38u); - - free(pSrcMem); - - pTileTable->InitializeTileset(Tileset_Dirt); - pTileTable->InitializeTileset(Tileset_Snow); - pTileTable->InitializeTileset(pTileTypes[0].tileset); - pTileTable->InitializeTileset(pTileTypes[1].tileset); - pTileTable->InitializeTileset(pTileTypes[2].tileset); - pTileTable->InitializeTileset(pTileTypes[3].tileset); - strcpy(pGroundTileset, byte_6BE124_cfg_textures_DefaultGroundTexture.data()); - TileDesc* v98 = pTileTable->GetTileById(pTileTypes[0].uTileID); - sMainTile_BitmapID = pBitmaps_LOD->LoadTexture(v98->pTileName, TEXTURE_DEFAULT); - if (sMainTile_BitmapID != -1) - pBitmaps_LOD->pTextures[sMainTile_BitmapID].palette_id2 = pPaletteManager->LoadPalette(pBitmaps_LOD->pTextures[sMainTile_BitmapID].palette_id1); - - _47F0E2(); - -//LABEL_150: - if ( pWeather->bRenderSnow ) //Ritor1: it's include for snow - strcpy(loc_time.sky_texture_name, "sky19"); - else if (loc_time.uLastVisitDay) - { - if ( (signed int)((signed int)(signed __int64)((double)loc_time.uLastVisitDay * 0.234375) / 60 / 60 / 24) % 28 != pParty->uDaysPlayed ) - { - if ( rand() % 100 >= 20 ) - v108 = dword_4EC268[rand() % dword_4EC2A8]; - else - v108 = dword_4EC28C[rand() % dword_4EC2AC]; - sprintf(loc_time.sky_texture_name, "plansky%d", v108); - } - } - else - strcpy(loc_time.sky_texture_name, "plansky3"); - - //v101 = pBitmaps_LOD->LoadTexture(field_4F8); - sSky_TextureID = pBitmaps_LOD->LoadTexture(loc_time.sky_texture_name); - if (sSky_TextureID != -1) - pBitmaps_LOD->pTextures[sSky_TextureID].palette_id2 = pPaletteManager->LoadPalette(pBitmaps_LOD->pTextures[sSky_TextureID].palette_id1); - - pPaletteManager->RecalculateAll(); - pSoundList->LoadSound(53, 0); - pSoundList->LoadSound(92, 0); - pSoundList->LoadSound(57, 0); - pSoundList->LoadSound(96, 0); - pSoundList->LoadSound(64, 0); - pSoundList->LoadSound(103, 0); - for (int i=0; i < 3;++i) - { - switch ( pTileTypes[i].tileset ) - { - case Tileset_Grass: - pSoundList->LoadSound(54, 0); - pSoundList->LoadSound(93, 0); - break; - case Tileset_Snow: - pSoundList->LoadSound(58, 0); - pSoundList->LoadSound(97, 0); - break; - case Tilset_Desert: - pSoundList->LoadSound(52, 0); - pSoundList->LoadSound(91, 0); - break; - case Tileset_3: - pSoundList->LoadSound(51, 0); - pSoundList->LoadSound(90, 0); - break; - case Tileset_Water: - pSoundList->LoadSound(62, 0); - pSoundList->LoadSound(101, 0); - break; - case Tileset_6: - pSoundList->LoadSound(49, 0); - pSoundList->LoadSound(88, 0); - break; - case Tileset_Swamp: - pSoundList->LoadSound(61, 0); - pSoundList->LoadSound(100, 0); - break; - } - } - return true; -} - -//----- (0047ECC1) -------------------------------------------------------- -int OutdoorLocation::GetTileIdByTileMapId(signed int a2) -{ - signed int result; // eax@2 - int v3; // eax@3 - - if ( a2 >= 90 ) - { - v3 = (a2 - 90) / 36; - if ( v3 && v3 != 1 && v3 != 2 ) - { - if ( v3 == Tileset_3 ) - result = this->pTileTypes[3].uTileID; - else - result = a2; - } - else - result = this->pTileTypes[v3].uTileID; - } - else - result = 0; - return result; -} - -//----- (0047ED08) -------------------------------------------------------- -unsigned int OutdoorLocation::DoGetTileTexture(signed int sX, signed int sY) -{ - int v3; // esi@5 -// unsigned int result; // eax@9 - - assert(sX < 128 && sY < 128); - - v3 = this->pTerrain.pTilemap[sY * 128 + sX]; - if (v3 < 198) // < Tileset_3 - { - if (v3 >= 90) - v3 = v3 + this->pTileTypes[(v3 - 90) / 36].uTileID - 36 * ((v3 - 90) / 36) - 90; - } - else - v3 = v3 + this->pTileTypes[3].uTileID - 198; - - #pragma region "New: seasons change" - - if (change_seasons) - switch (pParty->uCurrentMonth) - { - case 11: case 0: case 1: // winter - if (v3 >= 90) // Tileset_Grass begins at TileID = 90 - { - if (v3 <= 95) // some grastyl entries - v3 = 348; - else if (v3 <= 113) // rest of grastyl & all grdrt* - v3 = 348 + (v3 - 96); - } - /*switch (v3) - { - case 102: v3 = 354; break; // grdrtNE -> SNdrtne - case 104: v3 = 356; break; // grdrtNW -> SNdrtnw - case 108: v3 = 360; break; // grdrtN -> SNdrtn - }*/ - break; - - case 2: case 3: case 4: // spring - case 8: case 9: case 10: // autumn - if (v3 >= 90 && v3 <= 113) // just convert all Tileset_Grass to dirt - v3 = 1; - break; - - case 5: case 6: case 7: // summer - //all tiles are green grass by default - break; - - default: assert(pParty->uCurrentMonth >= 0 && pParty->uCurrentMonth < 12); - } - #pragma endregion - - return pTileTable->pTiles[v3].uBitmapID; -} - -//----- (0047ED83) -------------------------------------------------------- -int OutdoorLocation::_47ED83(signed int a2, signed int a3) -{ - assert(a2 < 128 && a3 < 128); - - return *(&this->pTerrain.pTilemap[128 * a3] + a2); -} - -//----- (0047EDB3) -------------------------------------------------------- -int OutdoorLocation::ActuallyGetSomeOtherTileInfo(signed int sX, signed int sY) -{ - assert(sX < 128 && sY < 128); - int v3; // esi@5 - - v3 = this->pTerrain.pTilemap[sY * 128 + sX]; - if ( v3 >= 90 ) - v3 = v3 + this->pTileTypes[(v3 - 90) / 36].uTileID - 36 * ((v3 - 90) / 36) - 90; - return pTileTable->pTiles[v3].uAttributes; -} - -//----- (0047EE16) -------------------------------------------------------- -int OutdoorLocation::DoGetHeightOnTerrain(signed int sX, signed int sZ) -{ - assert(sX < 128 && sZ < 128); - - return 32 * pTerrain.pHeightmap[sZ * 128 + sX]; -} - -//----- (0047EE49) -------------------------------------------------------- -int OutdoorLocation::GetSoundIdByPosition( signed int X_pos, signed int Y_pos, int running ) - { - signed int v4; // eax@5 - signed int v5; // eax@7 -// int v6; // eax@8 - signed int v8; // eax@9 - int modif=0; - - if ( X_pos < 0 || X_pos > 127 || Y_pos < 0 || Y_pos > 127 ) - v4 = 0; - else - v4 = this->pTerrain.pTilemap[128 * Y_pos + X_pos]; - v5 = GetTileIdByTileMapId(v4); - if (running) - modif=-39; - if ( !v5 ) - return 92+modif; - - switch (pTileTable->pTiles[v5].tileset) - { - case 0: return 93+ modif; - case 1: return 97+ modif; - case 2: return 91+ modif; - case 3: return 90+ modif; - case 4: return 101+ modif; - case 5: return 95+ modif; - case 6: return 88+ modif; - case 7: return 100+ modif; - case 8: return 93+ modif; - default: - v8=pTileTable->pTiles[v5].tileset; - if ( (v8 > 9 && v8 <= 17) || (v8 > 21 && v8 <= 27) ) - return 96+ modif; - else - return 95+ modif; - } - -} - -//----- (0047EF60) -------------------------------------------------------- -int OutdoorLocation::UpdateDiscoveredArea(int X_grid_pos, int Y_grid_poa, int a4) -{ - for (int i = -10; i < 10; i++) - { - int currYpos = Y_grid_poa + i - 20; - for (int j = -10; j < 10; j++) - { - int currXpos = X_grid_pos + j - 20; - int distanceSquared = i * i + j * j; - if ( distanceSquared <= 100 && currYpos >= 0 && currYpos <= 87 && currXpos >= 0 && currXpos <= 87 ) - { - unsigned char v13 = 1 << (7 - currXpos % 8); - this->uPartiallyRevealedCellOnMap[currYpos][currXpos / 8] |= v13; - if ( distanceSquared <= 49 ) - this->uFullyRevealedCellOnMap[currYpos][currXpos / 8] |= v13; - } - } - } - return 1; -} - - -//----- (0047F04C) -------------------------------------------------------- -bool OutdoorLocation::IsMapCellFullyRevealed(signed int x_pos, signed int y_pos) -{ - if ( x_pos < 0 || x_pos >= 88 || y_pos < 0 || y_pos >= 88 ) - return false; - else - return (uFullyRevealedCellOnMap[y_pos][x_pos/8] & (1 << (7 - (x_pos) % 8))) != 0; -} - -//----- (0047F097) -------------------------------------------------------- -bool OutdoorLocation::IsMapCellPartiallyRevealed(signed int x_pos, signed int y_pos) -{ - if ( x_pos < 0 || x_pos >= 88 || y_pos < 0 || y_pos >= 88 ) - return false; - else - return (uPartiallyRevealedCellOnMap[y_pos][x_pos/8] & (1 << (7 - (x_pos) % 8))) != 0; -} - -//----- (0047F0E2) -------------------------------------------------------- -bool OutdoorLocation::_47F0E2() -{ - for ( uint i = 0; i < (signed int)pBitmaps_LOD->uNumLoadedFiles; ++i ) - { - //if ( i != -1 ? (int)&pBitmaps_LOD->pTextures[i] : 0 ) - pBitmaps_LOD->pTextures[i].uDecompressedSize = this->pTerrain._47CB57((int)pBitmaps_LOD->pTextures[i].pLevelOfDetail0_prolly_alpha_mask, - pBitmaps_LOD->pTextures[i].palette_id2, - pBitmaps_LOD->pTextures[i].uTextureWidth * pBitmaps_LOD->pTextures[i].uTextureHeight); - } - return 1; -} - -//----- (0047F138) -------------------------------------------------------- -bool OutdoorLocation::PrepareDecorations() -{ - signed int v1; // ebx@1 - signed int v8; // [sp+Ch] [bp-4h]@1 - - v1 = 0; - v8 = 0; - if ( !_stricmp(pCurrentMapName, "out09.odm") ) - v8 = 1; - - for (uint i = 0; i < uNumLevelDecorations; ++i) - { - LevelDecoration* decor = &pLevelDecorations[i]; - - pDecorationList->InitializeDecorationSprite(decor->uDecorationDescID); - if ( pDecorationList->pDecorations[decor->uDecorationDescID].uSoundID && _6807E0_num_decorations_with_sounds_6807B8 < 9 ) - { - pSoundList->LoadSound(pDecorationList->pDecorations[decor->uDecorationDescID].uSoundID, 0); - _6807B8_level_decorations_ids[_6807E0_num_decorations_with_sounds_6807B8++] = i; - } - if ( v8 && decor->uCog == 20 ) - decor->uFlags |= LEVEL_DECORATION_OBELISK_CHEST; - if ( !decor->uEventID ) - { - if ( decor->IsInteractive() ) - { - if ( v1 < 124 ) - { - decor->_idx_in_stru123 = v1 + 75; - if ( !stru_5E4C90_MapPersistVars._decor_events[v1++] ) - decor->uFlags |= LEVEL_DECORATION_INVISIBLE; - } - } - } - } - - pGameLoadingUI_ProgressBar->Progress(); - return true; -} -// 6807E0: using guessed type int _6807E0_num_decorations_6807B8; - -//----- (0047F223) -------------------------------------------------------- -void OutdoorLocation::ArrangeSpriteObjects() -{ - OutdoorLocation *v5; // [sp+0h] [bp-4h]@1 - - v5 = this; - if ( (signed int)uNumSpriteObjects > 0 ) - { - for ( int i = 0; i < (signed int)uNumSpriteObjects; ++i ) - { - if ( pSpriteObjects[i].uObjectDescID ) - { - if ( !(pSpriteObjects[i].uAttributes & 8) && !(pObjectList->pObjects[pSpriteObjects[i].uObjectDescID].uFlags & 0x10) ) - pSpriteObjects[i].vPosition.z = GetTerrainHeightsAroundParty2(pSpriteObjects[i].vPosition.x, pSpriteObjects[i].vPosition.y, (int *)&v5, 0); - if ( pSpriteObjects[i].stru_24.uItemID ) - { - if ( pSpriteObjects[i].stru_24.uItemID != 220 - && pItemsTable->pItems[pSpriteObjects[i].stru_24.uItemID].uEquipType == EQUIP_POTION - && !pSpriteObjects[i].stru_24.uEnchantmentType ) - pSpriteObjects[i].stru_24.uEnchantmentType = rand() % 15 + 5; - pItemsTable->SetSpecialBonus(&pSpriteObjects[i].stru_24); - } - } - } - } - pGameLoadingUI_ProgressBar->Progress(); -} - -//----- (0047F2D3) -------------------------------------------------------- -bool OutdoorLocation::InitalizeActors(int a1) -{ - int alert_status; // [sp+348h] [bp-8h]@1 -// int v9; // [sp+34Ch] [bp-4h]@1 - - alert_status = 0; - for( int i = 0; i < uNumActors; ++i ) - { - if ( !(pActors[i].uAttributes & ACTOR_UNKNOW7) ) - { - if ( alert_status != 1 ) - { - pActors[i].uCurrentActionTime = 0; - pActors[i].uCurrentActionLength = 0; - if ( pActors[i].uAttributes & ACTOR_UNKNOW11 ) - pActors[i].uAIState = AIState::Disabled; - if ( pActors[i].uAIState != AIState::Removed && pActors[i].uAIState != AIState::Disabled && - (pActors[i].sCurrentHP == 0 || pActors[i].pMonsterInfo.uHP == 0) ) - pActors[i].uAIState = AIState::Dead; - pActors[i].vVelocity.x = 0; - pActors[i].vVelocity.y = 0; - pActors[i].vVelocity.z = 0; - pActors[i].UpdateAnimation(); - pActors[i].pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly; - pActors[i].PrepareSprites(0); - } - else - { - pActors[i].uAIState = AIState::Disabled; - pActors[i].uAttributes |= ACTOR_UNKNOW11; - } - } - else if ( a1 == 0 ) - { - pActors[i].uAIState = AIState::Disabled; - pActors[i].uAttributes |= ACTOR_UNKNOW11; - } - else if ( alert_status != 0 ) - { - pActors[i].uCurrentActionTime = 0; - pActors[i].uCurrentActionLength = 0; - if ( pActors[i].uAttributes & ACTOR_UNKNOW11 ) - pActors[i].uAIState = AIState::Disabled; - if ( pActors[i].uAIState != AIState::Removed && pActors[i].uAIState != AIState::Disabled && - (pActors[i].sCurrentHP == 0 || pActors[i].pMonsterInfo.uHP == 0) ) - pActors[i].uAIState = AIState::Dead; - pActors[i].vVelocity.x = 0; - pActors[i].vVelocity.y = 0; - pActors[i].vVelocity.z = 0; - pActors[i].UpdateAnimation(); - pActors[i].pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly; - pActors[i].PrepareSprites(0); - } - else - { - pActors[i].uAIState = AIState::Disabled; - pActors[i].uAttributes |= ACTOR_UNKNOW11; - alert_status = GetAlertStatus(); - } - } - - pGameLoadingUI_ProgressBar->Progress(); - //no use for this -// Actor thisa; -// thisa.pMonsterInfo.uID = 45; -// thisa.PrepareSprites(0); - return 1; -} - -//----- (0047F3EA) -------------------------------------------------------- -bool OutdoorLocation::LoadRoadTileset() -{ - pTileTypes[3].uTileID = pTileTable->GetTileForTerrainType(pTileTypes[3].tileset, 1); - pTileTable->InitializeTileset(pTileTypes[3].tileset); - return 1; -} - -//----- (0047F420) -------------------------------------------------------- -bool OutdoorLocation::LoadTileGroupIds() -{ - for (uint i = 0; i < 3; ++i) - pTileTypes[i].uTileID = pTileTable->GetTileForTerrainType(pTileTypes[i].tileset, 1); - - return true; -} - -//----- (0047B42C) -------------------------------------------------------- -void OutdoorLocation::PrepareActorsDrawList() -{ - unsigned int result; // eax@1 - int z; // esi@5 - float v4; // ST48_4@8 - unsigned int v8; // eax@11 - int v9; // edx@11 - signed int v12; // eax@16 - SpriteFrame *v14; // eax@24 - SpriteFrame *v15; // ebx@25 - int v17; // eax@35 - int v18; // ST78_4@36 - int v19; // eax@36 - int v20; // ecx@38 - int v21; // eax@38 - int v22; // ecx@41 - int v23; // ST5C_4@43 - int v24; // esi@44 - signed __int64 v25; // qtt@45 - int v26; // ST54_4@45 - int v27; // ecx@45 - int v34; // ecx@54 - int v41; // [sp+24h] [bp-3Ch]@11 - int v42; // [sp+28h] [bp-38h]@38 - int v43; // [sp+28h] [bp-38h]@45 - int v44; // [sp+2Ch] [bp-34h]@36 - int v45; // [sp+2Ch] [bp-34h]@44 - int v46; // [sp+2Ch] [bp-34h]@45 - int v47; // [sp+30h] [bp-30h]@36 - int v48; // [sp+30h] [bp-30h]@41 - signed int v49; // [sp+34h] [bp-2Ch]@5 - int v50; // [sp+34h] [bp-2Ch]@36 - int v51; // [sp+34h] [bp-2Ch]@41 - int v53; // [sp+38h] [bp-28h]@36 - int y; // [sp+40h] [bp-20h]@5 - int x; // [sp+44h] [bp-1Ch]@5 - int v57; // [sp+48h] [bp-18h]@45 - int v58; // [sp+4Ch] [bp-14h]@45 - int X; // [sp+54h] [bp-Ch]@36 - signed __int16 v62; // [sp+5Ch] [bp-4h]@25 - - //result = 0; - //v59 = 0; - for (int i = 0; i < uNumActors; ++i) - { - //v54 = 0; - //v1 = pActors;//[0].vPosition.z; - //do - //{ - //Actor* actor = &pActors[i]; - //v2 = actor->uAIState; - - pActors[i].uAttributes &= 0xFFFFFFF7;//~0x8 - if (pActors[i].uAIState == Removed || pActors[i].uAIState == Disabled) - continue; - - z = pActors[i].vPosition.z; - v49 = 0; - x = pActors[i].vPosition.x; - y = pActors[i].vPosition.y; - if (pActors[i].uAIState == Summoned) - { - if (PID_TYPE(pActors[i].uSummonerID) != OBJECT_Actor || - pActors[PID_ID(pActors[i].uSummonerID)].pMonsterInfo.uSpecialAbilityDamageDiceSides != 1 ) - { - z += floorf(pActors[i].uActorHeight * 0.5f + 0.5f); - } - else - { - v49 = 1; - pGame->pStru6Instance->_4A7F74(pActors[i].vPosition.x, pActors[i].vPosition.y, z); - v4 = (1.0 - (double)pActors[i].uCurrentActionTime / (double)pActors[i].uCurrentActionLength) * - (double)(2 * pActors[i].uActorHeight); - z -= floorf(v4 + 0.5f); - if ( z > pActors[i].vPosition.z ) - z = pActors[i].vPosition.z; - } - } - v8 = stru_5C6E00->Atan2(pActors[i].vPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x, - pActors[i].vPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y); - LOWORD(v9) = pActors[i].uYawAngle; - v41 = ((signed int)(stru_5C6E00->uIntegerPi + ((signed int)stru_5C6E00->uIntegerPi >> 3) + v9 - v8) >> 8) & 7; - if ( pParty->bTurnBasedModeOn ) - { - v12 = pActors[i].uCurrentActionTime; - if ( pActors[i].uCurrentActionAnimation == 1 ) - v12 = 32 * i + pMiscTimer->uTotalGameTimeElapsed; - } - else - { - v12 = pActors[i].uCurrentActionTime; - if ( pActors[i].uCurrentActionAnimation == 1 ) - v12 = 32 * i + pEventTimer->uTotalGameTimeElapsed; - } - if ( (signed __int64)pActors[i].pActorBuffs[ACTOR_BUFF_STONED].uExpireTime > 0 || (signed __int64)pActors[i].pActorBuffs[ACTOR_BUFF_PARALYZED].uExpireTime > 0 ) - v12 = 0; - if ( pActors[i].uAIState == 17 && !v49 ) - v14 = pSpriteFrameTable->GetFrame(uSpriteID_Spell11, v12); - else if ( pActors[i].uAIState == 16 ) - v14 = pSpriteFrameTable->GetFrameBy_x(pActors[i].pSpriteIDs[pActors[i].uCurrentActionAnimation], v12); - else - v14 = pSpriteFrameTable->GetFrame(pActors[i].pSpriteIDs[pActors[i].uCurrentActionAnimation], v12); - v62 = 0; - v15 = v14; - //v16 = (int *)v14->uFlags; - if (v14->uFlags & 2) - v62 = 2; - if (v14->uFlags & 0x40000) - v62 |= 0x40; - if (v14->uFlags & 0x20000) - LOBYTE(v62) = v62 | 0x80; - if ((256 << v41) & v14->uFlags) - v62 |= 4; - if ( v15->uGlowRadius ) - { - //LOBYTE(v16) = _4E94D3_light_type; - pMobileLightsStack->AddLight(x, y, z, 0, v15->uGlowRadius, 0xFFu, 0xFFu, 0xFFu, _4E94D3_light_type); - } - v17 = (x - pGame->pIndoorCameraD3D->vPartyPos.x) << 16; - if (pGame->pIndoorCameraD3D->sRotationX) - { - v18 = (y - pGame->pIndoorCameraD3D->vPartyPos.y) << 16; - v47 = (fixpoint_mul(v17, pGame->pIndoorCameraD3D->int_cosine_y) + fixpoint_mul(v18, pGame->pIndoorCameraD3D->int_sine_y)); - v50 = fixpoint_mul(v17, pGame->pIndoorCameraD3D->int_sine_y); - v53 = fixpoint_mul(v18, pGame->pIndoorCameraD3D->int_cosine_y); - v44 = (z - pGame->pIndoorCameraD3D->vPartyPos.z) << 16; - v19 = (fixpoint_mul(v44, pGame->pIndoorCameraD3D->int_sine_x) + fixpoint_mul(v47, pGame->pIndoorCameraD3D->int_cosine_x)); - X = fixpoint_mul(v44, pGame->pIndoorCameraD3D->int_sine_x) + fixpoint_mul(v47, pGame->pIndoorCameraD3D->int_cosine_x); - if ( v19 < 262144 || v19 > pODMRenderParams->shading_dist_mist << 16 ) - continue; - v20 = v53 - v50; - v42 = v53 - v50; - v21 = (fixpoint_mul(v44, pGame->pIndoorCameraD3D->int_cosine_x) - fixpoint_mul(v47, pGame->pIndoorCameraD3D->int_sine_x)); - } - else - { - v48 = (y - pGame->pIndoorCameraD3D->vPartyPos.y) << 16; - v51 = fixpoint_mul(v17, pGame->pIndoorCameraD3D->int_cosine_y); - v22 = fixpoint_mul(v48, pGame->pIndoorCameraD3D->int_sine_y); - X = v22 + v51; - if ( v22 + v51 < 262144 || v22 + v51 > pODMRenderParams->shading_dist_mist << 16 ) - continue; - v23 = fixpoint_mul(((x - pGame->pIndoorCameraD3D->vPartyPos.x) << 16), pGame->pIndoorCameraD3D->int_sine_y); - v20 = fixpoint_mul(v48, pGame->pIndoorCameraD3D->int_cosine_y) - v23; - v42 = fixpoint_mul(v48, pGame->pIndoorCameraD3D->int_cosine_y) - v23; - v21 = (z - pGame->pIndoorCameraD3D->vPartyPos.z) << 16; - } - v45 = v21; - v24 = abs(v20); - if ( abs(X) >= v24 ) - { - LODWORD(v25) = 0; - HIDWORD(v25) = SLOWORD(pODMRenderParams->int_fov_rad); - v58 = v25 / X; - v26 = v25 / X; - LODWORD(v25) = 0; - HIDWORD(v25) = SLOWORD(pODMRenderParams->int_fov_rad); - v57 = v25 / X; - v27 = pViewport->uScreenCenterX - ((signed int)(fixpoint_mul(v26, v42) + 0x8000) >> 16); - v43 = pViewport->uScreenCenterX - ((signed int)(fixpoint_mul(v26, v42) + 0x8000) >> 16); - v46 = pViewport->uScreenCenterY - ((signed int)(fixpoint_mul(v25 / X, v45) + 0x8000) >> 16); - result = uNumBillboardsToDraw; - //v28 = &pBillboardRenderList[uNumBillboardsToDraw]; - if (uNumBillboardsToDraw >= 500) - return; - ++uNumBillboardsToDraw; - ++uNumSpritesDrawnThisFrame; - pActors[i].uAttributes |= ACTOR_UNKNOW2; - pBillboardRenderList[uNumBillboardsToDraw - 1].HwSpriteID = v15->pHwSpriteIDs[v41]; - pBillboardRenderList[uNumBillboardsToDraw - 1].uIndoorSectorID = 0; - pBillboardRenderList[uNumBillboardsToDraw - 1].uPalette = v15->uPaletteIndex; - pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_x_scaler_packedfloat = fixpoint_mul(v15->scale, v58); - pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_y_scaler_packedfloat = fixpoint_mul(v15->scale, v57); - if ( pActors[i].pActorBuffs[ACTOR_BUFF_SHRINK].uExpireTime <= 0 ) - { - if ( pActors[i].pActorBuffs[ACTOR_BUFF_MASS_DISTORTION].uExpireTime > 0 ) - { - pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_y_scaler_packedfloat = fixpoint_mul(pGame->pStru6Instance->_4A806F(&pActors[i]), - pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_y_scaler_packedfloat); - LOWORD(v27) = v43; - } - } - else - { - if ( pActors[i].pActorBuffs[ACTOR_BUFF_SHRINK].uPower ) - { - pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_y_scaler_packedfloat = fixpoint_mul(65536 / pActors[i].pActorBuffs[ACTOR_BUFF_SHRINK].uPower, - pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_y_scaler_packedfloat); - LOWORD(v27) = v43; - } - } - pBillboardRenderList[uNumBillboardsToDraw - 1].uScreenSpaceX = v27; - pBillboardRenderList[uNumBillboardsToDraw - 1].uScreenSpaceY = v46; - pBillboardRenderList[uNumBillboardsToDraw - 1].world_x = x; - pBillboardRenderList[uNumBillboardsToDraw - 1].world_y = y; - pBillboardRenderList[uNumBillboardsToDraw - 1].world_z = z; - HIWORD(v34) = HIWORD(X); - LOWORD(v34) = 0; - pBillboardRenderList[uNumBillboardsToDraw - 1].dimming_level = 0; - pBillboardRenderList[uNumBillboardsToDraw - 1].sZValue = v34 + PID(OBJECT_Actor, i); - pBillboardRenderList[uNumBillboardsToDraw - 1].field_14_actor_id = i; - //v35 = pMonsterList->pMonsters; - //v36 = pActors[i].pMonsterInfo.uID; - pBillboardRenderList[uNumBillboardsToDraw - 1].field_1E = v62 | 0x200; - pBillboardRenderList[uNumBillboardsToDraw - 1].pSpriteFrame = v15; - pBillboardRenderList[uNumBillboardsToDraw - 1].sTintColor = pMonsterList->pMonsters[pActors[i].pMonsterInfo.uID - 1].sTintColor;//*((int *)&v35[v36] - 36); - if (pActors[i].pActorBuffs[ACTOR_BUFF_STONED].uExpireTime) - pBillboardRenderList[uNumBillboardsToDraw - 1].field_1E = v62 | 0x200; - } -//LABEL_58: - //++v59; - //v54 += 32; - //result = v59; - //++v1; - //} - //while ( v59 < (signed int)uNumActors ); - } - //return result; -} - -//----- (0044C1E8) -------------------------------------------------------- -bool ODMFace::HasEventHint() -{ - signed int event_index; // eax@1 - _evt_raw* start_evt; - _evt_raw* end_evt; - - event_index = 0; - if ( (uLevelEVT_NumEvents - 1) <= 0 ) - return false; - while ( pLevelEVT_Index[event_index].uEventID != this->sCogTriggeredID ) - { - ++event_index; - if ( event_index >= (signed int)(uLevelEVT_NumEvents - 1) ) - return false; - } - end_evt=(_evt_raw*)&pLevelEVT[pLevelEVT_Index[event_index+1].uEventOffsetInEVT]; - start_evt=(_evt_raw*)&pLevelEVT[pLevelEVT_Index[event_index].uEventOffsetInEVT]; - if ( (end_evt->_e_type != EVENT_Exit) || (start_evt->_e_type!= EVENT_MouseOver) ) - return false; - else - return true; -} -//----- (0046D49E) -------------------------------------------------------- -int ODM_GetFloorLevel(int X, signed int Y, int Z, int __unused, int *pIsOnWater, int *bmodel_pid, int bWaterWalk) -{ - BSPModel *pBModel; // esi@4 - ODMFace *pFace; // ecx@11 -// int v14; // edx@20 - signed int v18; // edx@26 - int v19; // eax@28 -// int v20; // edx@30 -// int v21; // ST1C_4@30 - signed int v22; // edx@30 - signed __int64 v23; // qtt@30 - int v24; // eax@36 - signed int v25; // ecx@38 -// int result; // eax@42 - signed int current_floor_level; // ecx@43 -// int v28; // edi@44 - signed int v29; // edx@44 -// int v30; // esi@45 -// int v31; // eax@45 -// int v33; // ecx@59 -// int v36; // [sp+14h] [bp-2Ch]@24 -// int v38; // [sp+1Ch] [bp-24h]@2 - int v39; // [sp+20h] [bp-20h]@9 - signed int pBModelNum; // [sp+28h] [bp-18h]@1 - int pFaceNum; // [sp+2Ch] [bp-14h]@8 - bool current_vertices_Y; // [sp+30h] [bp-10h]@22 - bool next_vertices_Y; // [sp+34h] [bp-Ch]@24 - signed int v46; // [sp+3Ch] [bp-4h]@1 - signed int number_hits; // [sp+58h] [bp+18h]@22 - signed int next_floor_level; // [sp+58h] [bp+18h]@43 - - v46 = 1; - current_BModel_id[0] = -1; - current_Face_id[0] = -1; - odm_floor_level[0] = GetTerrainHeightsAroundParty2(X, Y, pIsOnWater, bWaterWalk); - - for ( pBModelNum = 0; pBModelNum < pOutdoor->uNumBModels; ++pBModelNum ) - { - pBModel = &pOutdoor->pBModels[pBModelNum]; - if ( X <= pBModel->sMaxX && X >= pBModel->sMinX && - Y <= pBModel->sMaxY && Y >= pBModel->sMinY ) - { - if ( pBModel->uNumFaces > 0 ) - { - v39 = 0; - for ( pFaceNum = 0; pFaceNum < pBModel->uNumFaces; ++pFaceNum ) - { - pFace = &pBModel->pFaces[pFaceNum]; - if ( pFace->Ethereal() ) - continue; - if ( (pFace->uPolygonType == POLYGON_Floor || pFace->uPolygonType == POLYGON_InBetweenFloorAndWall) - && X <= pFace->pBoundingBox.x2 && X >= pFace->pBoundingBox.x1 - && Y <= pFace->pBoundingBox.y2 && Y >= pFace->pBoundingBox.y1 ) - { - for ( uint i = 0; i < pFace->uNumVertices; ++i) - { - odm_floor_face_vert_coord_X[2 * i] = pFace->pXInterceptDisplacements[i] + pBModel->pVertices.pVertices[pFace->pVertexIDs[i]].x; - odm_floor_face_vert_coord_Y[2 * i] = pFace->pYInterceptDisplacements[i] + pBModel->pVertices.pVertices[pFace->pVertexIDs[i]].y; - odm_floor_face_vert_coord_X[2 * i + 1] = pFace->pXInterceptDisplacements[i] + pBModel->pVertices.pVertices[pFace->pVertexIDs[i + 1]].x; - odm_floor_face_vert_coord_Y[2 * i + 1] = pFace->pYInterceptDisplacements[i] + pBModel->pVertices.pVertices[pFace->pVertexIDs[i + 1]].y; - } - odm_floor_face_vert_coord_X[2 * pFace->uNumVertices] = odm_floor_face_vert_coord_X[0]; - odm_floor_face_vert_coord_Y[2 * pFace->uNumVertices] = odm_floor_face_vert_coord_Y[0]; - - current_vertices_Y = odm_floor_face_vert_coord_Y[0] >= Y; - number_hits = 0; - if ( 2 * pFace->uNumVertices > 0 ) - { - for ( int i = 0; i < 2 * pFace->uNumVertices; ++i ) - { - if ( number_hits >= 2 ) - break; - //v36 = odm_floor_face_vert_coord_Y[i + 1]; - next_vertices_Y = odm_floor_face_vert_coord_Y[i + 1] >= Y; - if ( current_vertices_Y != next_vertices_Y )//проверка по Y - { - v18 = odm_floor_face_vert_coord_X[i + 1] >= X ? 0 : 2; - v19 = v18 | (odm_floor_face_vert_coord_X[i] < X); - if ( v19 != 3 ) - { - if ( !v19 ) - ++number_hits; - else - { - LODWORD(v23) = (Y - odm_floor_face_vert_coord_Y[i]) << 16; - HIDWORD(v23) = (Y - odm_floor_face_vert_coord_Y[i]) >> 16; - v22 = ((((odm_floor_face_vert_coord_X[i + 1] - odm_floor_face_vert_coord_X[i]) * v23 / (odm_floor_face_vert_coord_Y[i + 1] - - odm_floor_face_vert_coord_Y[i])) >> 16) + odm_floor_face_vert_coord_X[i]); - if ( v22 >= X) - ++number_hits; - } - } - } - current_vertices_Y = next_vertices_Y; - } - if ( number_hits == 1 ) - { - if ( v46 >= 20 ) - break; - if ( pFace->uPolygonType == POLYGON_Floor ) - v24 = pBModel->pVertices.pVertices[pFace->pVertexIDs[0]].z; - else - { - int a = fixpoint_mul(pFace->zCalc1, X); - int b = fixpoint_mul(pFace->zCalc2, Y); - int c = ((signed __int64)pFace->zCalc3 >> 16); - v24 = a + b + c; - } - v25 = v46++; - odm_floor_level[v25] = v24; - current_BModel_id[v25] = pBModelNum; - current_Face_id[v25] = pFaceNum; - } - } - } - - } - } - } - } - if ( v46 == 1 ) - { - *bmodel_pid = 0; - return odm_floor_level[0]; - } - current_floor_level = 0; - v29 = 0; - if ( v46 <= 1 ) - *bmodel_pid = 0; - else - { - current_floor_level = odm_floor_level[0]; - for ( uint i = 1; i < v46; ++i ) - { - next_floor_level = odm_floor_level[i]; - if ( current_floor_level <= Z + 5 ) - { - if ( next_floor_level > current_floor_level && next_floor_level <= Z + 5 ) - { - current_floor_level = next_floor_level; - v29 = i; - } - } - else if ( next_floor_level < current_floor_level ) - { - current_floor_level = next_floor_level; - v29 = i; - } - } - if ( !v29 ) - *bmodel_pid = 0; - else - *bmodel_pid = current_Face_id[v29] | (current_BModel_id[v29] << 6); - } - if ( v29 ) - { - *pIsOnWater = false; - if ( pOutdoor->pBModels[current_BModel_id[v29]].pFaces[current_Face_id[v29]].Fluid()) - *pIsOnWater = true; - } - if ( odm_floor_level[v29] >= odm_floor_level[0] ) - odm_floor_level[0] = odm_floor_level[v29]; - return odm_floor_level[0]; -} - -//not sure if right- or left-handed coordinate space assumed, so this could be normal of inverse normal -// for a right-handed system, that would be an inverse normal -//----- (0046DCC8) -------------------------------------------------------- -void ODM_GetTerrainNormalAt(int pos_x, int pos_z, Vec3_int_ *out) -{ - uint grid_x = WorldPosToGridCellX(pos_x); - uint grid_z = WorldPosToGridCellZ(pos_z) - 1; - - int grid_pos_x1 = GridCellToWorldPosX(grid_x); - int grid_pos_x2 = GridCellToWorldPosX(grid_x + 1); - int grid_pos_z1 = GridCellToWorldPosZ(grid_z); - int grid_pos_z2 = GridCellToWorldPosZ(grid_z + 1); - - int x1z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z); - int x2z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z); - int x2z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z + 1); - int x1z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z + 1); - - float side1_dx, side1_dy, side1_dz, - side2_dx, side2_dy, side2_dz; - - int dx = abs(pos_x - grid_pos_x1), - dz = abs(grid_pos_z1 - pos_z); - if (dz >= dx) - { - side2_dx = (double)(grid_pos_x2 - grid_pos_x1); - side2_dz = 0.0;//(double)(grid_pos_z2 - grid_pos_z2); // bug? z2 - z2 - side2_dy = (double)(x2z2_y - x1z2_y); - - side1_dx = 0.0;//(double)(grid_pos_x1 - grid_pos_x1); - side1_dz = (double)(grid_pos_z1 - grid_pos_z2); // z1 - z2 yes - side1_dy = (double)(x1z1_y - x1z2_y); - //Log::Warning(L"%S %S %u\n", __FILE__, __FUNCTION__, __LINE__); - /* |\ - side1 | \ - |____\ - side 2 */ - } - else - { - side2_dx = (double)(grid_pos_x1 - grid_pos_x2); - side2_dz = 0.0;//(double)(grid_pos_z1 - grid_pos_z1); - side2_dy = (double)(x1z1_y - x2z1_y); - - side1_dx = 0.0;//(double)(grid_pos_x2 - grid_pos_x1); - side1_dz = (double)(grid_pos_z2 - grid_pos_z1); - side1_dy = (double)(x2z2_y - x2z1_y); - /* side 2 - _____ - \ | - \ | side 1 - \| */ - } - - float nx = side1_dy * side2_dz - side1_dz * side2_dy; - float ny = side1_dx * side2_dy - side1_dy * side2_dx; - float nz = side1_dz * side2_dx - side1_dx * side2_dz; - - float mag = sqrt(nx * nx + ny * ny + nz * nz); - if (fabsf(mag) < 1e-6f) - { - out->y = 0; - out->x = 0; - out->z = 65536; - } - else - { - float invmag = 1.0 / mag; - out->x = invmag * nx * 65536.0; - out->y = invmag * ny * 65536.0; - out->z = invmag * nz * 65536.0; - } -} -//----- (0046BE0A) -------------------------------------------------------- -void ODM_UpdateUserInputAndOther() -{ - bool v0; // eax@5 - char pOut[32]; // [sp+8h] [bp-20h]@5 - - UpdateObjects(); - ODM_ProcessPartyActions(); - if ( pParty->vPosition.x < -22528 - || pParty->vPosition.x > 22528 - || pParty->vPosition.y < -22528 - || pParty->vPosition.y > 22528 ) - { - strcpy(pOutdoor->pLevelFilename, pCurrentMapName); - v0 = pOutdoor->GetTravelDestination(pParty->vPosition.x, pParty->vPosition.y, pOut, 32); - if ( !bUnderwater && (pParty->uFlags & (PARTY_FLAGS_1_STANDING_ON_WATER | PARTY_FLAGS_1_FALLING | 0x04) || pParty->uFlags & 0x0200 || pParty->bFlying) || !v0 ) - { - if ( pParty->vPosition.x < -22528 ) - pParty->vPosition.x = -22528; - if ( pParty->vPosition.x > 22528 ) - pParty->vPosition.x = 22528; - if ( pParty->vPosition.y < -22528 ) - pParty->vPosition.y = -22528; - if ( pParty->vPosition.y > 22528 ) - pParty->vPosition.y = 22528; - } - else - { - pAudioPlayer->StopChannels(-1, -1); - TravelUI_Load(); - } - } - UpdateActors_ODM(); - check_event_triggers(); -} -//----- (0041F54A) -------------------------------------------------------- -void OutdoorLocation::LoadActualSkyFrame() -{ - if ( pTexture_RestUI_CurrentSkyFrame ) - pTexture_RestUI_CurrentSkyFrame->Release(); - if ( pTexture_RestUI_CurrentHourglassFrame ) - pTexture_RestUI_CurrentHourglassFrame->Release(); - pIcons_LOD->SyncLoadedFilesCount(); - sprintf(pTmpBuf.data(), "TERRA%03d", pParty->uCurrentMinute / 6 + 10 * pParty->uCurrentHour); - pTexture_RestUI_CurrentSkyFrame = pIcons_LOD->LoadTexturePtr(pTmpBuf.data(), TEXTURE_16BIT_PALETTE); -} - - -//----- (004626BA) -------------------------------------------------------- -OutdoorLocation::OutdoorLocation() -{ - subconstuctor(); - uLastSunlightUpdateMinute = 0; - - uNumBModels = 0; - pBModels = nullptr; -} - -//----- (004626CD) -------------------------------------------------------- -void OutdoorLocation::subconstuctor() -{ - //OutdoorLocationTerrain::OutdoorLocationTerrain(&this->pTerrain); - field_F0 = 0; - field_F4 = 0x40000000u; - //DLVHeader::DLVHeader(&v1->ddm); - pSpawnPoints = 0; - pBModels = 0; - pCmap = 0; - pFaceIDLIST = 0; - pOMAP = 0; -} - -//----- (00481E55) -------------------------------------------------------- -void ODM_Project(unsigned int uNumVertices) -{ - for ( uint i = 0; i < uNumVertices; i++ ) - { - memcpy(&array_50AC10[i], &array_507D30[i], sizeof(array_50AC10[i])); - array_50AC10[i].vWorldViewProjX = (double)pViewport->uScreenCenterX - - ((double)pODMRenderParams->int_fov_rad * array_507D30[i]._rhw) * array_507D30[i].vWorldViewPosition.y; - array_50AC10[i].vWorldViewProjY = (double)pViewport->uScreenCenterY - - ((double)pODMRenderParams->int_fov_rad * array_507D30[i]._rhw) * array_507D30[i].vWorldViewPosition.z; - } - } -//----- (00485F64) -------------------------------------------------------- -void ODMRenderParams::Initialize() -{ - int v1; // eax@1 - int v2; // eax@2 - signed __int64 v3; // qtt@4 - int v4; // eax@4 - - this->uCameraFovInDegrees = 75; - v1 = stru_5C6E00->uPiMask & 0xD5; - if ( v1 >= (signed int)stru_5C6E00->uIntegerHalfPi ) - v2 = -stru_5C6E00->pTanTable[stru_5C6E00->uIntegerPi - v1]; - else - v2 = stru_5C6E00->pTanTable[v1]; - LODWORD(v3) = (viewparams->uSomeZ - viewparams->uSomeX) << 31; - HIDWORD(v3) = (viewparams->uSomeZ - viewparams->uSomeX) << 15 >> 16; - v4 = (signed int)(v3 / v2) >> 16; - this->int_fov_rad = v4; - this->field_4C = 360000; - this->int_fov_rad_inv = 65536 / v4; - this->field_50 = 115; - //sr_6BE060[1] = 1; - //RotationToInts(); -} -//----- (00473893) -------------------------------------------------------- -void ODM_ProcessPartyActions() -{ - int v1; // edi@1 - int v2; // ebx@1 - int floor_level; // eax@14 - int v6; // esi@45 - ODMFace *face; // ecx@45 - //signed int v33; // eax@143 - int v34; // esi@143 - int v35; // esi@147 - int v36; // eax@155 -// signed int v37; // esi@159 -// signed int v38; // eax@159 -// signed int i; // esi@159 - int v40; // esi@162 - bool v42; // eax@180 - signed int v43; // ecx@184 - signed int v44; // edx@184 - int v45; // ecx@200 - BSPModel *pModel; // eax@203 - bool pModel_; - ODMFace *pODMFace; // esi@203 - int v48; // eax@203 - int v54; // eax@215 - int v55; // eax@217 - unsigned int v66; // esi@263 - signed int v68; // ecx@263 - int v69; // eax@263 -// unsigned int v76; // edi@293 - bool v77; // edx@297 - bool v78; // ecx@303 - int v79; // ecx@314 - __int16 v80; // dx@317 - //int v81; // ebx@318 - //int v82; // ecx@318 - int pTerrainHeight; // eax@321 -// int v86; // [sp-20h] [bp-B4h]@246 - int v87; // [sp-20h] [bp-B4h]@248 - int v97; // [sp+Ch] [bp-88h]@180 - Vec3_int_ v98; - bool not_high_fall; // [sp+1Ch] [bp-78h]@33 - int v102; // [sp+20h] [bp-74h]@1 - int trigger_id; // [sp+24h] [bp-70h]@1 - bool bFeatherFall; // [sp+28h] [bp-6Ch]@4 - int bonus; - int on_ground; // [sp+2Ch] [bp-68h]@24 - bool bWaterWalk; // [sp+30h] [bp-64h]@1 - int ceiling_height; // [sp+3Ch] [bp-58h]@28 - int v110; // [sp+40h] [bp-54h]@180 - int v111; // [sp+44h] [bp-50h]@14 - bool hovering; // [sp+48h] [bp-4Ch]@1 - int v113; // [sp+4Ch] [bp-48h]@1 - bool party_running_flag; // [sp+50h] [bp-44h]@1 - int _walk_speed; // [sp+54h] [bp-40h]@48 - int pX; // [sp+58h] [bp-3Ch]@1 - int pY; // [sp+5Ch] [bp-38h]@1 - int v118; // [sp+60h] [bp-34h]@1 - int _angle_x; // [sp+68h] [bp-2Ch]@48 - unsigned int v122; // [sp+70h] [bp-24h]@180 - int pZ; // [sp+74h] [bp-20h]@1 - bool party_walking_flag; // [sp+78h] [bp-1Ch]@1 - int _angle_y; // [sp+7Ch] [bp-18h]@48 - int v128; // [sp+88h] [bp-Ch]@1 - int v129; // [sp+8Ch] [bp-8h]@92 - - v1 = 0; - trigger_id = 0; - v2 = 0; - //*(float *)&v128 = 0.0; - int fall_speed = pParty->uFallSpeed; - v128 = 0; - v129 = 0; - pX = pParty->vPosition.x; - pY = pParty->vPosition.y; - pZ = pParty->vPosition.z; - v113 = pParty->field_6F0; - hovering = false; - bool partyAtHighSlope = IsTerrainSlopeTooHigh(pParty->vPosition.x, pParty->vPosition.y); - party_running_flag = false; - party_walking_flag = false; - v102 = 0; - pModel_ = false; - bWaterWalk = false; - - if (!pParty->FeatherFallActive())//Проверка падение пера - { - bFeatherFall = false; - for (int i = 0; i < 4; ++i) - if (pParty->pPlayers[i].WearsItemAnyWhere(ITEM_ARTIFACT_LADYS_ESCORT)) // seems like flying boots - { - bFeatherFall = true; - break; - } - } - else - bFeatherFall = true; - - pParty->uFlags &= ~PARTY_FLAGS_1_STANDING_ON_WATER; - if (pParty->WaterWalkActive())//Проверка хождения по воде - { - //LOBYTE(pParty->uFlags) &= 0x7Fu; - bWaterWalk = true; - *(short *)&stru_5E4C90_MapPersistVars._decor_events[20 * pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uOverlayID + 119] |= 1u; - if (!(pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uFlags & 1) && - pParty->pPlayers[pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uCaster - 1].sMana <= 0 ) - bWaterWalk = false; - } - - int bmodel_standing_on_pid; - int is_on_water = false; - floor_level = ODM_GetFloorLevel(pX, pY, pZ, pParty->uPartyHeight, &is_on_water, &bmodel_standing_on_pid, bWaterWalk); - int is_not_on_bmodel = bmodel_standing_on_pid == 0; - - v111 = floor_level; - if ( bFeatherFall ) - pParty->uFallStartY = floor_level; - else - floor_level = pParty->uFallStartY; - - if ( floor_level - pZ > 512 && !bFeatherFall && pZ <= v111 + 1 )//падение на 3D Model - { - if (pParty->uFlags & PARTY_FLAGS_1_LANDING) - pParty->uFlags &= ~PARTY_FLAGS_1_LANDING; - else for (int i = 0; i < 4; ++i) // receive falling damage - { - if ( !pParty->pPlayers[i].HasEnchantedItemEquipped(72) && !pParty->pPlayers[i].WearsItem(ITEM_ARTIFACT_HERMES_SANDALS, EQUIP_BOOTS) ) - { - pParty->pPlayers[i].ReceiveDamage( - (signed int)((pParty->uFallStartY - pZ) * (unsigned __int64)(pParty->pPlayers[i].GetMaxHealth() / 10)) / 256, DMGT_PHISYCAL); - bonus = 20 - pParty->pPlayers[i].GetParameterBonus(pParty->pPlayers[i].GetActualEndurance()); - pParty->pPlayers[i].SetRecoveryTime((signed __int64)((double)bonus * flt_6BE3A4_debug_recmod1 * 2.133333333333333)); - } - } - } - - ceiling_height = -1; - if ( pParty->bFlying ) - ceiling_height = GetCeilingHeight(pX, pY, pZ + pParty->uPartyHeight, (int)&v102);//высота потолка - //v107 = bmodel_standing_on_pid == 0; - on_ground = v111 + 1; - if ( pZ <= on_ground )//полёт: посадка - { - ceiling_height = -1; - pParty->bFlying = false; - } - else - hovering = true; - not_high_fall = pZ - v111 <= 32; - - if ( bWalkSound && pParty->walk_sound_timer)//timer update - { - if (pParty->walk_sound_timer >= pEventTimer->uTimeElapsed) - pParty->walk_sound_timer -= pEventTimer->uTimeElapsed; - else - pParty->walk_sound_timer = 0; - } - - if (!bUnderwater && pParty->pPartyBuffs[PARTY_BUFF_FLY].uExpireTime <= 0)// конец действия полёта - pParty->bFlying = false; - - if (!hovering)// - { - if ( pParty->floor_face_pid != PID(OBJECT_BModel, bmodel_standing_on_pid) ) - { - if (bmodel_standing_on_pid) - { - if ( (bmodel_standing_on_pid >> 6) < pOutdoor->uNumBModels ) - { - face = pOutdoor->pBModels[bmodel_standing_on_pid >> 6].pFaces; - v6 = bmodel_standing_on_pid & 0x3F; - /*if ( *(char *)(v7->pFacePlane.vNormal.x + 308 * v6 + 31) & 4 ) - { - pParty->field_6F4_packedid = PID(OBJECT_BModel,v108); - v103 = *(short *)(v7->pFacePlane.vNormal.x + 308 * v6 + 292); - }*/ - if ( face[v6].uAttributes & FACE_PRESSURE_PLATE ) - { - pParty->floor_face_pid = PID(OBJECT_BModel, bmodel_standing_on_pid); - trigger_id = face[v6].sCogTriggeredID; // - } - } - } - } - pParty->floor_face_pid = PID(OBJECT_BModel, bmodel_standing_on_pid); - } - - _walk_speed = pParty->uWalkSpeed; - _angle_y = pParty->sRotationY; - _angle_x = pParty->sRotationX; - //v126 = pEventTimer->dt_in_some_format; - /*v119 = (Player **)((unsigned __int64)(pEventTimer->dt_in_some_format - * (signed __int64)((signed int)(pParty->field_20_prolly_turn_speed - * stru_5C6E00->uIntegerPi) - / 180)) >> 16);*/ - __int64 dturn = (unsigned __int64)(pEventTimer->dt_in_some_format * (signed __int64)((signed int)(pParty->y_rotation_speed * stru_5C6E00->uIntegerPi) / 180)) >> 16; - while (pPartyActionQueue->uNumActions) - { - switch (pPartyActionQueue->Next()) - { - case PARTY_FlyUp://полёт вверх - { - if (!pParty->FlyActive() && !bUnderwater) - break; - - pParty->bFlying = false; - if (bUnderwater || - pParty->pPartyBuffs[PARTY_BUFF_FLY].uFlags & 1 || - pParty->pPlayers[pParty->pPartyBuffs[PARTY_BUFF_FLY].uCaster - 1].sMana > 0 ) - { - extern int max_flight_height; - if ( pParty->vPosition.z < max_flight_height || hovering ) - { - pZ += 30; - v113 += 30; - pParty->bFlying = true; - if ( pZ > max_flight_height ) - { - pZ = max_flight_height; - v113 = max_flight_height; - } - v1 = 0; - v2 = 0; - fall_speed = 0; - *(float *)&v128 = 0.0; - if ( v102 && pZ < ceiling_height && (signed int)(pParty->uPartyHeight + pZ) >= ceiling_height )//столкновение с потолком - { - pParty->field_6E0 = 0; - pParty->field_6E4 = 0; - pPartyActionQueue->uNumActions = 0; - pParty->uFlags |= PARTY_FLAGS_1_LANDING; - pParty->vPosition.z = ceiling_height - pParty->uPartyHeight - 31; - pParty->field_6F0 = pZ; - pParty->bFlying = false; - pZ = ceiling_height - pParty->uPartyHeight - 31; - v113 = pParty->field_6F0; - } - pParty->uFallSpeed = 0; - pModel_ = true; - } - } - } - break; - - case PARTY_FlyDown://полёт вниз - if (pParty->FlyActive() || bUnderwater) - { - pParty->bFlying = false; - if ( bUnderwater - || pParty->pPartyBuffs[PARTY_BUFF_FLY].uFlags & 1 - || pParty->pPlayers[pParty->pPartyBuffs[PARTY_BUFF_FLY].uCaster - 1].sMana > 0 )//*(int *)&pParty->pArtifactsFound[6972 * pParty->pPartyBuffs[PARTY_BUFF_FLY].uCaster + 10] > 0 ) - { - pZ -= 30; - v113 -= 30; - pParty->uFallSpeed = 0; - fall_speed = 0; - pParty->bFlying = true; - pModel_ = true; - if ( pZ <= v111 ) - { - pParty->bFlying = false; - pPartyActionQueue->uNumActions = 0; - } - } - } - break; - - case PARTY_TurnLeft: - if (uTurnSpeed) - _angle_y += uTurnSpeed; //descrete turn - else - _angle_y += dturn * fTurnSpeedMultiplier; // time-based smooth turn - - _angle_y &= stru_5C6E00->uDoublePiMask; - break; - - case PARTY_TurnRight: - if (uTurnSpeed) - _angle_y -= uTurnSpeed; - else - _angle_y -= dturn * fTurnSpeedMultiplier; - - _angle_y &= stru_5C6E00->uDoublePiMask; - break; - - case PARTY_FastTurnLeft: - if (uTurnSpeed) - _angle_y += uTurnSpeed; - else - _angle_y += 2.0f * fTurnSpeedMultiplier * (double)dturn; - - _angle_y &= stru_5C6E00->uDoublePiMask; - break; - - case PARTY_FastTurnRight: - if (!uTurnSpeed) - _angle_y -= 2.0f * fTurnSpeedMultiplier * (double)dturn; - else - _angle_y -= uTurnSpeed; - - _angle_y &= stru_5C6E00->uDoublePiMask; - break; - - case PARTY_StrafeLeft://хождение боком в влево - { - *(float *)&v128 = pParty->uWalkSpeed; - - float sin_y = sinf(2 * 3.141592653589 * _angle_y / 2048.0); - int dx = sin_y * pParty->uWalkSpeed * fWalkSpeedMultiplier; - v2 -= 3 * dx / 4; - - float cos_y = cosf(2 * 3.141592653589 * _angle_y / 2048.0); - int dy = cos_y * pParty->uWalkSpeed * fWalkSpeedMultiplier; - v1 += 3 * dy / 4; - - v128 = v1; - party_walking_flag = true; - } - break; - - case PARTY_StrafeRight://хождение боком в вправо - { - *(float *)&v128 = pParty->uWalkSpeed; - - float sin_y = sinf(2 * 3.141592653589 * _angle_y / 2048.0); - int dx = sin_y * pParty->uWalkSpeed * fWalkSpeedMultiplier; - v2 += 3 * dx / 4; - - float cos_y = cosf(2 * 3.141592653589 * _angle_y / 2048.0); - int dy = cos_y * pParty->uWalkSpeed * fWalkSpeedMultiplier; - v1 -= 3 * dy / 4; - - v128 = v1; - party_walking_flag = true; - } - break; - - case PARTY_WalkForward:// идти вперёд - { - *(float *)&v128 = _walk_speed; - - float sin_y = sinf(2 * 3.141592653589 * _angle_y / 2048.0), - cos_y = cosf(2 * 3.141592653589 * _angle_y / 2048.0); - - int dx = cos_y * pParty->uWalkSpeed * fWalkSpeedMultiplier; - int dy = sin_y * pParty->uWalkSpeed * fWalkSpeedMultiplier; - - if ( new_speed ) - { - v2 += dx * 12; - v1 += dy * 12; - } - else - { - v2 += dx; - v1 += dy; - } - - v128 = v1; - party_walking_flag = true; - } - break; - - case PARTY_RunForward://бежать вперёд - { - *(float *)&v128 = _walk_speed; - - float sin_y = sinf(2 * 3.141592653589 * _angle_y / 2048.0); - float cos_y = cosf(2 * 3.141592653589 * _angle_y / 2048.0); - - int dx = cos_y * pParty->uWalkSpeed * fWalkSpeedMultiplier; - int dy = sin_y * pParty->uWalkSpeed * fWalkSpeedMultiplier; - - if (pParty->bFlying)//лететь вперёд - { - v2 += 4 * dx; - v1 += 4 * dy; - - v128 = v1; - } - else if (partyAtHighSlope && !bmodel_standing_on_pid)//сбегание со склона - { - v2 += dx; - v1 += dy; - - v128 = v1; - party_walking_flag = true; - } - else - { - /*v2 += (unsigned __int64)(stru_5C6E00->Cos(_angle_y) - * (signed __int64)(signed int)(2 * (unsigned __int64)(signed __int64)((double)_walk_speed * fWalkSpeedMultiplier))) >> 16; - v1 += (unsigned __int64)((signed int)stru_5C6E00->Sin(_angle_y) - * (signed __int64)(signed int)(2 * (unsigned __int64)(signed __int64)((double)_walk_speed * fWalkSpeedMultiplier))) >> 16;*/ - - v2 += 2 * dx; - v1 += 2 * dy; - - v128 = v1; - party_running_flag = true; - } - } - break; - - - case PARTY_WalkBackward://идти назад - { - *(float *)&v128 = _walk_speed; - - float sin_y = sinf(2 * 3.141592653589 * _angle_y / 2048.0), - cos_y = cosf(2 * 3.141592653589 * _angle_y / 2048.0); - - int dx = cos_y * pParty->uWalkSpeed * fBackwardWalkSpeedMultiplier; - v2 -= dx; - - int dy = sin_y * pParty->uWalkSpeed * fBackwardWalkSpeedMultiplier; - v1 -= dy; - - v128 = v1; - party_walking_flag = true; - } - break; - - - case PARTY_RunBackward://бежать назад - { - float sin_y = sinf(2 * 3.141592653589 * _angle_y / 2048.0), - cos_y = cosf(2 * 3.141592653589 * _angle_y / 2048.0); - - int dx = cos_y * pParty->uWalkSpeed * fBackwardWalkSpeedMultiplier; - int dy = sin_y * pParty->uWalkSpeed * fBackwardWalkSpeedMultiplier; - - if (pParty->bFlying) - { - v2 -= 4 * dx; - v1 -= 4 * dy; - v128 = v1; - } - else - { - v2 -= dx; - v1 -= dy; - - v128 = v1; - party_walking_flag = true; - } - } - break; - - case PARTY_CenterView://смотреть прямо - _angle_x = 0; - break; - - case PARTY_LookUp://смотреть вверх - _angle_x += (signed __int64)(flt_6BE150_look_up_down_dangle * 25.0); - if ( _angle_x > 128 ) - _angle_x = 128; - if (uActiveCharacter) - pPlayers[uActiveCharacter]->PlaySound(SPEECH_63, 0); - break; - - case PARTY_LookDown://смотреть вниз - _angle_x += (signed __int64)(flt_6BE150_look_up_down_dangle * -25.0); - if ( _angle_x < -128 ) - _angle_x = -128; - if (uActiveCharacter) - pPlayers[uActiveCharacter]->PlaySound(SPEECH_64, 0); - break; - - case PARTY_Jump://прыжок - if ( (!partyAtHighSlope || bmodel_standing_on_pid) && !hovering && pParty->field_24 && !(pParty->uFlags & 4) && !(pParty->uFlags & 0x200) ) - { - //v126 = pParty->field_24 << 6; - hovering = true; - fall_speed = (signed __int64)((double)(pParty->field_24 << 6) * 1.5 + (double)fall_speed); - } - break; - - case PARTY_Land://приземление(клавиша Home) - if (pParty->bFlying) - { - pParty->uFlags |= PARTY_FLAGS_1_LANDING; - pParty->uFallSpeed = 0; - } - pParty->bFlying = false; - pPartyActionQueue->uNumActions = 0; - break; - - default: - assert(false); - - - } - } - - pParty->sRotationY = _angle_y; - pParty->sRotationX = _angle_x; - //------------------------------------------- - if ( pParty->bFlying ) - { - v129 = fixpoint_mul(4, stru_5C6E00->Cos(GetTickCount())); - pZ = v113 + v129; - if ( pModel_ ) - pZ = v113; - if (pParty->FlyActive()) - stru_5E4C90_MapPersistVars._decor_events[20 * pParty->pPartyBuffs[PARTY_BUFF_FLY].uOverlayID + 119] &= 0xFE; - pParty->uFallStartY = pZ; - } - else if ( pZ < v111 ) - { - if ( is_on_water && fall_speed ) - SpriteObject::sub_42F960_create_object(pX, pY, v111); - fall_speed = 0; - pZ = v111; - pParty->uFallStartY = v111; - v113 = pZ; - if (pParty->FlyActive()) - stru_5E4C90_MapPersistVars._decor_events[20 * pParty->pPartyBuffs[PARTY_BUFF_FLY].uOverlayID + 119] |= 1; - } - else - { - v113 = pZ; - if (pParty->FlyActive()) - stru_5E4C90_MapPersistVars._decor_events[20 * pParty->pPartyBuffs[PARTY_BUFF_FLY].uOverlayID + 119] |= 1; - } - //------------------------------------------ - if (hovering && !pParty->bFlying)//расчёт скорости падения - { - //v33 = -(pEventTimer->uTimeElapsed * GetGravityStrength()); - v34 = fall_speed + (-(pEventTimer->uTimeElapsed * GetGravityStrength()) << 1); - fall_speed += (-(pEventTimer->uTimeElapsed * GetGravityStrength()) << 1 ); //y(t) = 2*gt - } - else if (!partyAtHighSlope) - v34 = fall_speed; - else if (!hovering) - { - if ( !bmodel_standing_on_pid ) - { - // rolling down the hill - // how it's done: you get a little bit pushed in the air along terrain normal, getting in the air - // and falling to the gravity, gradually sliding downwards. nice trick - pZ = v111; - ODM_GetTerrainNormalAt(pX, pY, &v98); - v35 = fall_speed + (8 * -(pEventTimer->uTimeElapsed * GetGravityStrength())); - v129 = abs(v2 * v98.x + v1 * v98.y + v35 * v98.z) >> 16; - v2 += fixpoint_mul(v129, v98.x); - v1 += fixpoint_mul(v129, v98.y); - v34 = v35 + fixpoint_mul(v129, v98.z); - v128 = v1; - fall_speed = v34; - } - } - else - v34 = fall_speed; - - if ( hovering )//блок для крика падения - { - if ( !bUnderwater && v34 <= 0) - { - if ( v34 < -500 && !pParty->bFlying && pParty->vPosition.z - v111 > 1000 && !pParty->FeatherFallActive()) - { // falling scream - for (int i = 0; i < 4; ++i) - { - if (!pParty->pPlayers[i].HasEnchantedItemEquipped(72) - && !pParty->pPlayers[i].WearsItem(ITEM_ARTIFACT_HERMES_SANDALS, EQUIP_BOOTS) - && pParty->pPlayers[i].CanAct()) - pParty->pPlayers[i].PlaySound(SPEECH_Falling_scream, 0);//крик падения - } - } - } - } - else - pParty->uFallStartY = pZ; - - if ( v2 * v2 + v1 * v1 < 400 && !partyAtHighSlope ) - { - *(float *)&v128 = 0.0; - v2 = 0; - } -//--(столкновения)------------------------------------------------------------------- - stru_721530.field_84 = -1; - stru_721530.field_70 = 0; - stru_721530.prolly_normal_d = pParty->field_14_radius; - stru_721530.field_8_radius = pParty->field_14_radius / 2; - stru_721530.field_0 = 1; - stru_721530.height = pParty->uPartyHeight - 32; - for ( uint i = 0; i < 100; i++ ) - { - stru_721530.position.x = pX; - stru_721530.position.y = pY; - stru_721530.position.z = stru_721530.height + pZ + 1; - - stru_721530.normal.x = pX; - stru_721530.normal.y = pY; - stru_721530.normal.z = stru_721530.prolly_normal_d + pZ + 1; - - stru_721530.velocity.x = v2; - stru_721530.velocity.y = v128; - stru_721530.velocity.z = fall_speed; - - stru_721530.uSectorID = 0; - v36 = 0; - if ( pParty->bTurnBasedModeOn == true && pTurnEngine->turn_stage == TE_MOVEMENT ) - v36 = 13312; - if ( stru_721530._47050A(v36) ) - break; - _46E889_collide_against_bmodels(1); - //v37 = WorldPosToGridCellZ(pParty->vPosition.y); - //v38 = WorldPosToGridCellX(pParty->vPosition.x); - _46E26D_collide_against_sprites(WorldPosToGridCellX(pParty->vPosition.x), WorldPosToGridCellZ(pParty->vPosition.y)); - _46ED8A_collide_against_sprite_objects(4); - for ( uint actor_id = 0; actor_id < (signed int)uNumActors; ++actor_id ) - Actor::_46DF1A_collide_against_actor(actor_id, 0); - if ( stru_721530.field_7C >= stru_721530.field_6C ) - { - _angle_x = stru_721530.normal2.x; - _angle_y = stru_721530.normal2.y; - v40 = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1; - } - else - { - _angle_x = pX + fixpoint_mul(stru_721530.field_7C, stru_721530.direction.x); - _angle_y = pY + fixpoint_mul(stru_721530.field_7C, stru_721530.direction.y); - //pModel = (BSPModel *)fixpoint_mul(stru_721530.field_7C, stru_721530.direction.z); - v40 = fixpoint_mul(stru_721530.field_7C, stru_721530.direction.z) + pZ; - } - v122 = v40; - ODM_GetFloorLevel(_angle_x, _angle_y, v40, pParty->uPartyHeight, &is_on_water, &bmodel_standing_on_pid, 0); - v129 = ODM_GetFloorLevel(_angle_x, pY, v40, pParty->uPartyHeight, &is_on_water, &v97, 0); - int v119 = ODM_GetFloorLevel(pX, _angle_y, v40, pParty->uPartyHeight, &is_on_water, &v110, 0); - bool v42_ = (BSPModel *)IsTerrainSlopeTooHigh(_angle_x, pY); - v42 = IsTerrainSlopeTooHigh(pX, _angle_y); - is_not_on_bmodel = false; - //v118 = v42; - if ( !v97 && !v110 && !bmodel_standing_on_pid ) - is_not_on_bmodel = true; - v43 = 1; - v44 = 1; - if ( bUnderwater || !is_not_on_bmodel ) - { - pX = _angle_x; - if ( v43 ) - pY = _angle_y; - } - else - { - if ( v42_ && v129 > pZ ) - v44 = 0; - if ( v42 && v119 > pZ ) - v43 = 0; - if ( v44 ) - { - pX = _angle_x; - if ( v43 ) - pY = _angle_y; - } - else if ( v43 ) - pY = _angle_y; - else - { - int new_ = ODM_GetFloorLevel(_angle_x, _angle_y, v40, pParty->uPartyHeight, &is_on_water, &bmodel_standing_on_pid, 0); - if ( IsTerrainSlopeTooHigh(_angle_x, _angle_y) && new_ <= pZ ) - { - v43 = 1; - pX = _angle_x; - if ( v43 ) - pY = _angle_y; - } - } - } - if ( stru_721530.field_7C >= stru_721530.field_6C ) - { - if ( !is_not_on_bmodel ) - { - pX = stru_721530.normal2.x; - pY = stru_721530.normal2.y; - } - pZ = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1; - break; - } - stru_721530.field_70 += stru_721530.field_7C; - pX = _angle_x; - pY = _angle_y; - v45 = stru_721530.uFaceID; - pZ = v40; - - if ( PID_TYPE(stru_721530.uFaceID) == OBJECT_Actor) - { - if (pParty->Invisible()) - pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].Reset(); - viewparams->bRedrawGameUI = true; - } - - if ( PID_TYPE(stru_721530.uFaceID) == OBJECT_Decoration) - { - v129 = stru_5C6E00->Atan2(_angle_x - pLevelDecorations[(signed int)stru_721530.uFaceID >> 3].vPosition.x, - _angle_y - pLevelDecorations[(signed int)stru_721530.uFaceID >> 3].vPosition.y); - v2 = fixpoint_mul(stru_5C6E00->Cos(v129), integer_sqrt(v2 * v2 + v128 * v128)); - v122 = fixpoint_mul(stru_5C6E00->Sin(v129), integer_sqrt(v2 * v2 + v128 * v128)); - v128 = fixpoint_mul(stru_5C6E00->Sin(v129), integer_sqrt(v2 * v2 + v128 * v128)); - } - - if ( PID_TYPE(stru_721530.uFaceID) == OBJECT_BModel) - { - pParty->bFlying = false; - pModel = &pOutdoor->pBModels[(signed int)stru_721530.uFaceID >> 9]; - pODMFace = &pModel->pFaces[((signed int)stru_721530.uFaceID >> 3) & 0x3F]; - v48 = pODMFace->pBoundingBox.z2 - pODMFace->pBoundingBox.z1; - v129 = v48 <= 32; - v119 = pODMFace->pFacePlane.vNormal.z < 46378; - if ( bUnderwater == 1 ) - v119 = 0; - if ( pODMFace->uPolygonType == POLYGON_Floor ) - { - if ( fall_speed < 0 ) - fall_speed = 0; - pZ = pModel->pVertices.pVertices[pODMFace->pVertexIDs[0]].z + 1; - if ( v2 * v2 + v128 * v128 < 400 ) - { - v2 = 0; - *(float *)&v128 = 0.0; - } - if ( pParty->floor_face_pid != v45 && pODMFace->Pressure_Plate() ) - { - pParty->floor_face_pid = v45; - trigger_id = pODMFace->sCogTriggeredID; - } - } - if ( !v129 && (pODMFace->uPolygonType != POLYGON_InBetweenFloorAndWall || v119) )// упёрся в столб - { - v118 = abs(v128 * pODMFace->pFacePlane.vNormal.y + fall_speed * pODMFace->pFacePlane.vNormal.z - + v2 * pODMFace->pFacePlane.vNormal.x) >> 16; - if ((stru_721530.speed >> 3) > v118 ) - v118 = stru_721530.speed >> 3; - v2 += fixpoint_mul(v118, pODMFace->pFacePlane.vNormal.x); - v128 += fixpoint_mul(v118, pODMFace->pFacePlane.vNormal.y); - v54 = 0; - if ( !v119 ) - v54 = fixpoint_mul(v118, pODMFace->pFacePlane.vNormal.z); - pParty->uFallSpeed += v54; - v55 = stru_721530.prolly_normal_d - ((signed int)(pODMFace->pFacePlane.dist + v122 * pODMFace->pFacePlane.vNormal.z - + _angle_y * pODMFace->pFacePlane.vNormal.y + _angle_x * pODMFace->pFacePlane.vNormal.x) >> 16); - if ( v55 > 0 ) - { - pX = _angle_x + fixpoint_mul(pODMFace->pFacePlane.vNormal.x, v55); - pY = _angle_y + fixpoint_mul(pODMFace->pFacePlane.vNormal.y, v55); - if ( !v119 ) - pZ = v122 + fixpoint_mul(pODMFace->pFacePlane.vNormal.z, v55); - } - if ( pParty->floor_face_pid != stru_721530.uFaceID && pODMFace->Pressure_Plate() ) - { - pParty->floor_face_pid = stru_721530.uFaceID; - trigger_id = pODMFace->sCogTriggeredID; // - } - } - if ( pODMFace->uPolygonType == POLYGON_InBetweenFloorAndWall ) - { - v118 = abs(v128 * pODMFace->pFacePlane.vNormal.y - + fall_speed * pODMFace->pFacePlane.vNormal.z + v2 * pODMFace->pFacePlane.vNormal.x) >> 16; - if ((stru_721530.speed >> 3) > v118 ) - v118 = stru_721530.speed >> 3; - v2 += fixpoint_mul(v118, pODMFace->pFacePlane.vNormal.x); - v128 += fixpoint_mul(v118, pODMFace->pFacePlane.vNormal.y); - fall_speed += fixpoint_mul(v118, pODMFace->pFacePlane.vNormal.z); - if ( v2 * v2 + v128 * v128 >= 400 ) - { - if ( pParty->floor_face_pid != stru_721530.uFaceID && pODMFace->Pressure_Plate() ) - { - pParty->floor_face_pid = stru_721530.uFaceID; - trigger_id = pODMFace->sCogTriggeredID; // - } - } - else - { - v2 = 0; - fall_speed = 0; - *(float *)&v128 = 0.0; - } - } - } - v2 = fixpoint_mul(58500, v2); - v128 = fixpoint_mul(58500, v128); - v122 = fixpoint_mul(58500, v122); - fall_speed = fixpoint_mul(58500, fall_speed); - } - - //Воспроизведение звуков ходьбы/бега------------------------ - uint pX_ = abs(pParty->vPosition.x - pX); - uint pY_ = abs(pParty->vPosition.y - pY); - uint pZ_ = abs(pParty->vPosition.z - pZ); - if ( bWalkSound && pParty->walk_sound_timer <= 0 ) - { - pAudioPlayer->_4AA258(804);//stop sound - if ( party_running_flag && (!hovering || not_high_fall) ) - { - if ( integer_sqrt(pX_ * pX_ + pY_ * pY_ + pZ_ * pZ_) >= 16 ) - { - if ( !is_not_on_bmodel && pOutdoor->pBModels[pParty->floor_face_pid >> 9].pFaces[(pParty->floor_face_pid >> 3) & 0x3F].Visible() ) - pAudioPlayer->PlaySound(SOUND_RunAlong3DModel, 804, 1, -1, 0, 0, 0, 0);//бег на 3D Modelи - else - { - v87 = pOutdoor->GetSoundIdByPosition(WorldPosToGridCellX(pParty->vPosition.x), WorldPosToGridCellZ(pParty->vPosition.y) - 1, 1); - pAudioPlayer->PlaySound((SoundID)v87, 804, 1, -1, 0, 0, 0, 0);//бег по земле 56 - } - pParty->walk_sound_timer = 96;//таймер для бега - } - } - else if( party_walking_flag && (!hovering || not_high_fall) ) - { - if ( integer_sqrt(pX_ * pX_ + pY_ * pY_ + pZ_ * pZ_) >= 8 ) - { - if ( !is_not_on_bmodel && pOutdoor->pBModels[pParty->floor_face_pid >> 9].pFaces[(pParty->floor_face_pid >> 3) & 0x3F].Visible() ) - pAudioPlayer->PlaySound(SOUND_WalkAlong3DModel, 804, 1, -1, 0, 0, 0, 0);// хождение на 3D Modelи - else - { - v87 = pOutdoor->GetSoundIdByPosition(WorldPosToGridCellX(pParty->vPosition.x), WorldPosToGridCellZ(pParty->vPosition.y) - 1, 0); - pAudioPlayer->PlaySound((SoundID)v87, 804, 1, -1, 0, 0, 0, 0);// хождение по земле - } - pParty->walk_sound_timer = 144;//таймер для ходьбы - } - } - } - if ( integer_sqrt(pX_ * pX_ + pY_ * pY_ + pZ_ * pZ_) < 8 )//отключить звук ходьбы при остановке - pAudioPlayer->_4AA258(804); -//------------------------------------------------------------------------ - if ( !hovering || !not_high_fall )// или не высокое падение - pParty->uFlags &= ~PARTY_FLAGS_1_FALLING; - else - pParty->uFlags |= PARTY_FLAGS_1_FALLING; - int pMap_X = WorldPosToGridCellX(pParty->vPosition.x); - int pMap_Y = WorldPosToGridCellZ(pParty->vPosition.y) - 1; - unsigned int v114_a = WorldPosToGridCellX(pX); - v66 = WorldPosToGridCellZ(pY) - 1; - unsigned int v122_a = (~(unsigned int)pOutdoor->ActuallyGetSomeOtherTileInfo(pMap_X, pMap_Y) / 2) & 1; - v122 = (~(unsigned int)pOutdoor->ActuallyGetSomeOtherTileInfo(v114_a, pMap_Y) / 2) & 1; - v69 = (~(unsigned int)pOutdoor->ActuallyGetSomeOtherTileInfo(pMap_X, v66) / 2) & 1; - - //-(обновление координат группы)--------------------------------------- - v68 = 0; - if ( v114_a == pMap_X && v66 == pMap_Y && v122 && v69 ) - v68 = 1; - if ( !is_not_on_bmodel ) // на bmodel,и - v68 = 1; - if ( v68 ) - { - pParty->vPosition.x = pX; - pParty->vPosition.y = pY; - pParty->vPosition.z = pZ; - pParty->field_6F0 = v113; - pParty->uFallSpeed = fall_speed; - if ( pZ > 8160 ) //ограничение высоты - { - pZ = 8160; - pParty->uFallStartY = 8160; - pParty->vPosition.z = 8160; - } - - if ( !trigger_id //падение на землю - || (EventProcessor(trigger_id, 0, 1), - pParty->vPosition.x == pX) - && pParty->vPosition.y == pY - && pParty->vPosition.z == pZ ) - { - if ( pParty->vPosition.z < v111 ) - { - pParty->uFallSpeed = 0; - //v73 = v105; - pParty->vPosition.z = on_ground; - if ( pParty->uFallStartY - pZ > 512 && !bFeatherFall && pZ <= on_ground && !bUnderwater )//Fall to the ground(падение на землю с высоты) - { - if ( pParty->uFlags & PARTY_FLAGS_1_LANDING ) - pParty->uFlags &= ~PARTY_FLAGS_1_LANDING; - else - { - for ( uint i = 1; i <= 4; ++i ) - { - pPlayers[i]->ReceiveDamage((signed int)((pParty->uFallStartY - pZ) * (unsigned __int64)(signed __int64)((double)pPlayers[i]->GetMaxHealth() * 0.1)) / 256, - DMGT_PHISYCAL); - v110 = 20 - pPlayers[i]->GetParameterBonus(pPlayers[i]->GetActualEndurance()); - pPlayers[i]->SetRecoveryTime((signed __int64)((double)v110 * flt_6BE3A4_debug_recmod1 * 2.133333333333333)); - } - //v73 = pParty->vPosition.z; - } - } - pParty->uFallStartY = pZ; - } - if ( v102 && pParty->vPosition.z < ceiling_height ) - { - if ( (signed int)(pParty->uPartyHeight + pParty->vPosition.z) >= ceiling_height ) - { - pParty->vPosition.z = ceiling_height - pParty->uPartyHeight - 1; - pParty->field_6F0 = ceiling_height - pParty->uPartyHeight - 1; - } - } - pParty->uFlags &= ~0x204; - } - return; - } -//----------------------------------------------------------------- - //v76 = pParty->bFlying; - if ( pParty->bFlying || !not_high_fall || bWaterWalk || !v122_a )// полёт или высокое падение или хождение по воде или - v77 = 1; - else - v77 = v122 != 0; - bool party_drowning_flag = false; - if ( !pParty->bFlying && not_high_fall && !bWaterWalk ) //не полёт и не высокое падение и не хождение по воде - { - if ( v122_a ) - v78 = v69 != 0; - else - { - party_drowning_flag = true;//утопление - v78 = true; - } - } - else - v78 = true; - - if ( v77 ) - pParty->vPosition.x = pX; - if ( v78 ) - pParty->vPosition.y = pY; - - if ( v78 || v77) - { - if ( bWaterWalk ) - { - pParty->uFlags &= ~PARTY_FLAGS_1_STANDING_ON_WATER; - //v79 = 20 * pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uOverlayID + 6180178; - //*(short *)&stru_5E4C90._decor_events[20 * pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uOverlayID + 119] |= 1u; - v79 = (int)&stru_5E4C90_MapPersistVars._decor_events[20 * pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uOverlayID + 119]; - *(short *)v79 |= 1; - if ( !v122 || !v69 ) - { - if ( !pParty->bFlying ) - { - v80 = *(short *)v79; - pParty->uFlags |= PARTY_FLAGS_1_STANDING_ON_WATER; - *(short *)v79 = v80 & 0xFFFE; - } - } - } - } - else if ( bWalkSound && pParty->walk_sound_timer <= 0 ) - { - pAudioPlayer->_4AA258(804); - pParty->walk_sound_timer = 64; - } - - //v81 = pZ; - //v82 = pZ; - pParty->vPosition.z = pZ; - if ( pZ > 8160 )//опять ограничение высоты - { - //v82 = 8160; - pParty->uFallStartY = 8160; - pParty->vPosition.z = 8160; - } - LOWORD(pParty->uFlags) &= 0xFDFBu; - pParty->uFallSpeed = fall_speed; - pParty->field_6F0 = v113; - if ( party_drowning_flag )//группа тонет - { - pTerrainHeight = GetTerrainHeightsAroundParty2(pParty->vPosition.x, pParty->vPosition.y, &v110, 1); - if ( pParty->vPosition.z <= pTerrainHeight + 1 )//положение группы всегда +1 - pParty->uFlags |= PARTY_FLAGS_1_WATER_DAMAGE; - } - - if ( !trigger_id//падение на воду - || (EventProcessor(trigger_id, 0, 1), - pParty->vPosition.x == pX) - && pParty->vPosition.y == pY - && pParty->vPosition.z == pZ ) - { - if ( pParty->vPosition.z < v111 ) - { - //v82 = on_ground; - pParty->uFallSpeed = 0; - pParty->vPosition.z = on_ground; - if ( pParty->uFallStartY - pZ > 512 && !bFeatherFall && pZ <= on_ground && !bUnderwater )//Fall to the water(падение на воду с высоты) - { - if ( pParty->uFlags & PARTY_FLAGS_1_LANDING ) - pParty->uFlags &= ~PARTY_FLAGS_1_LANDING; - else - { - for ( uint i = 1; i <= 4; ++i ) - { - v110 = pPlayers[i]->GetMaxHealth(); - pPlayers[i]->ReceiveDamage((signed int)((pParty->uFallStartY - pZ) * (unsigned __int64)(signed __int64)((double)v110 * 0.1)) / 256, - DMGT_PHISYCAL); - v110 = 20 - pPlayers[i]->GetParameterBonus(pPlayers[i]->GetActualEndurance()); - pPlayers[i]->SetRecoveryTime((signed __int64)((double)v110 * flt_6BE3A4_debug_recmod1 * 2.133333333333333)); - } - //v82 = pParty->vPosition.z; - } - } - pParty->uFallStartY = pZ; - } - if ( v102 && pParty->vPosition.z < ceiling_height && (signed int)(pParty->uPartyHeight + pParty->vPosition.z) >= ceiling_height ) - { - pParty->vPosition.z = pParty->vPosition.z + pParty->uPartyHeight - ceiling_height + 1; - pParty->field_6F0 = pParty->vPosition.z + pParty->uPartyHeight - ceiling_height + 1; - } - } -} - -//----- (0046D8E3) -------------------------------------------------------- -int GetCeilingHeight(int Party_X, signed int Party_Y, int Party_ZHeight, int pFaceID) -{ - signed int v13; // eax@25 - int v14; // edx@27 - int v16; // ST18_4@29 - signed int v17; // edx@29 - signed __int64 v18; // qtt@29 - int v19; // eax@35 - signed int v20; // ecx@37 - signed int v22; // ebx@42 -// int v24; // edx@44 -// int v25; // eax@44 - int v27; // [sp+10h] [bp-34h]@21 - bool v34; // [sp+30h] [bp-14h]@21 - bool v35; // [sp+34h] [bp-10h]@23 - signed int v37; // [sp+38h] [bp-Ch]@21 - signed int v38; // [sp+38h] [bp-Ch]@42 - signed int v39; // [sp+3Ch] [bp-8h]@1 - - dword_720ED0[0] = -1; - dword_720E80[0] = -1; - v39 = 1; - ceiling_height_level[0] = 10000;//нет потолка - for ( uint i = 0; i < (signed int)pOutdoor->uNumBModels; ++i ) - { - if ( Party_X <= pOutdoor->pBModels[i].sMaxX && Party_X >= pOutdoor->pBModels[i].sMinX - && Party_Y <= pOutdoor->pBModels[i].sMaxY && Party_Y >= pOutdoor->pBModels[i].sMinY ) - { - for ( uint j = 0; j < pOutdoor->pBModels[i].uNumFaces; ++j ) - { - if ( (pOutdoor->pBModels[i].pFaces[j].uPolygonType == POLYGON_Ceiling - || pOutdoor->pBModels[i].pFaces[j].uPolygonType == POLYGON_InBetweenCeilingAndWall) - && !pOutdoor->pBModels[i].pFaces[j].Ethereal() - && Party_X <= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.x2 && Party_X >= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.x1 - && Party_Y <= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.y2 && Party_Y >= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.y1 ) - { - for ( uint v = 0; v < pOutdoor->pBModels[i].pFaces[j].uNumVertices; v++ ) - { - word_720DB0_xs[2 * v] = pOutdoor->pBModels[i].pFaces[j].pXInterceptDisplacements[v] + LOWORD(pOutdoor->pBModels[i].pVertices.pVertices[pOutdoor->pBModels[i].pFaces[j].pVertexIDs[v]].x); - word_720CE0_ys[2 * v] = pOutdoor->pBModels[i].pFaces[j].pXInterceptDisplacements[v] + LOWORD(pOutdoor->pBModels[i].pVertices.pVertices[pOutdoor->pBModels[i].pFaces[j].pVertexIDs[v]].y); - word_720DB0_xs[2 * v + 1] = pOutdoor->pBModels[i].pFaces[j].pXInterceptDisplacements[v] + LOWORD(pOutdoor->pBModels[i].pVertices.pVertices[pOutdoor->pBModels[i].pFaces[j].pVertexIDs[v + 1]].x); - word_720CE0_ys[2 * v + 1] = pOutdoor->pBModels[i].pFaces[j].pXInterceptDisplacements[v] + LOWORD(pOutdoor->pBModels[i].pVertices.pVertices[pOutdoor->pBModels[i].pFaces[j].pVertexIDs[v + 1]].y); - } - v27 = 2 * pOutdoor->pBModels[i].pFaces[j].uNumVertices; - word_720DB0_xs[2 * pOutdoor->pBModels[i].pFaces[j].uNumVertices] = word_720DB0_xs[0]; - word_720CE0_ys[2 * pOutdoor->pBModels[i].pFaces[j].uNumVertices] = word_720CE0_ys[0]; - v34 = word_720CE0_ys[0] >= Party_Y; - v37 = 0; - for ( uint v = 0; v < v27; ++v ) - { - if ( v37 >= 2 ) - break; - v35 = word_720CE0_ys[v + 1] >= Party_Y; - if ( v34 != v35 ) - { - v13 = word_720DB0_xs[v + 1] >= Party_X ? 0 : 2; - v14 = v13 | (word_720DB0_xs[v] < Party_X); - if ( v14 != 3 ) - { - if ( !v14 || ( v16 = word_720CE0_ys[v + 1] - word_720CE0_ys[v], - v17 = Party_Y - word_720CE0_ys[v], - LODWORD(v18) = v17 << 16, - HIDWORD(v18) = v17 >> 16, - (signed int)(((unsigned __int64)(((signed int)word_720DB0_xs[v + 1] - - (signed int)word_720DB0_xs[v]) * v18 / v16) >> 16) + word_720DB0_xs[v]) >= Party_X) ) - ++v37; - } - } - v34 = v35; - } - if ( v37 == 1 ) - { - if ( v39 >= 20 ) - break; - if ( pOutdoor->pBModels[i].pFaces[j].uPolygonType == POLYGON_Ceiling ) - v19 = pOutdoor->pBModels[i].pVertices.pVertices[pOutdoor->pBModels[i].pFaces[j].pVertexIDs[0]].z; - else - v19 = fixpoint_mul(pOutdoor->pBModels[i].pFaces[j].zCalc1, Party_X) + fixpoint_mul(pOutdoor->pBModels[i].pFaces[j].zCalc2, Party_Y) - + HIWORD(pOutdoor->pBModels[i].pFaces[j].zCalc3); - v20 = v39++; - ceiling_height_level[v20] = v19; - dword_720ED0[v20] = i; - dword_720E80[v20] = j; - } - } - } - } - } - if ( !v39 ) - { - pFaceID = 0; - return ceiling_height_level[0]; - } - v22 = 0; - for ( v38 = 0; v38 < v39; ++v38 ) - { - if ( ceiling_height_level[v38] == ceiling_height_level[0] ) - v22 = v38; - else if ( ceiling_height_level[v38] < ceiling_height_level[0] && ceiling_height_level[0] > Party_ZHeight + 15 ) - v22 = v38; - else if ( ceiling_height_level[v38] > ceiling_height_level[0] && ceiling_height_level[v38] <= Party_ZHeight + 15 ) - v22 = v38; - } - if ( v22 ) - { - *(int *)pFaceID = dword_720E80[v22] | (dword_720ED0[v22] << 6); - return ceiling_height_level[v22];//если есть преграда - } - pFaceID = 0; - return ceiling_height_level[v22];// нет никакой преграды -} - - -//----- (00464839) -------------------------------------------------------- -char Is_out15odm_underwater() -{ - return _stricmp(pCurrentMapName, "out15.odm") == 0; -} - -//----- (00464851) -------------------------------------------------------- -void SetUnderwaterFog() -{ - day_fogrange_1 = 50; - day_fogrange_2 = 5000; -} - -//----- (00487DA9) -------------------------------------------------------- -void sub_487DA9() -{ - for (int i = 0; i < 20000; ++i) - array_77EC08[i].field_108 = 0; -} - -//----- (004706C6) -------------------------------------------------------- -void UpdateActors_ODM() -{ - int v3; // ebx@6 - int v5; // eax@10 - //int v6; // ecx@10 - signed int v8; // ebx@17 - // unsigned __int8 v10; // sf@17 - // unsigned __int16 v11; // ax@21 - __int16 v20; // ax@42 - int v25; // eax@45 - signed int v26; // ecx@50 - int v28; // eax@54 - signed int v29; // ebx@57 - signed int v30; // eax@57 - int v31; // edi@57 - signed int i; // ebx@57 - unsigned int v33; // ecx@58 - int v35; // edi@64 - int v36; // eax@64 - unsigned int v39; // edi@71 - ODMFace *face; // edi@75 - int v46; // ecx@82 - signed int v47; // ebx@85 - int v48; // edi@85 - // int v55; // eax@107 - // unsigned int v56; // edi@107 - // int v57; // ST10_4@107 - unsigned int v58; // edi@107 - unsigned int v59; // ebx@107 - // signed int v60; // eax@107 - int v61; // eax@124 - Vec3_int_ v62; // [sp+Ch] [bp-44h]@42 - int v63; // [sp+18h] [bp-38h]@64 - int v64; // [sp+1Ch] [bp-34h]@64 - bool v67; // [sp+28h] [bp-28h]@10 - unsigned int v69; // [sp+30h] [bp-20h]@6 - unsigned int v70; // [sp+34h] [bp-1Ch]@10 - int v71; // [sp+38h] [bp-18h]@62 - int uIsAboveFloor; // [sp+3Ch] [bp-14h]@10 - int v72b; - int uIsFlying; // [sp+44h] [bp-Ch]@8 - unsigned int v75; // [sp+48h] [bp-8h]@1 - int uIsOnWater; // [sp+4Ch] [bp-4h]@10 - - for (v75 = 0; v75 < uNumActors; ++v75) - { - if (pActors[v75].uAIState == Removed - || pActors[v75].uAIState == Disabled - || pActors[v75].uAIState == Summoned - || !pActors[v75].uMovementSpeed) - continue; - v3 = 0; - v69 = 0; - if (MonsterStats::BelongsToSupertype(pActors[v75].pMonsterInfo.uID, MONSTER_SUPERTYPE_WATER_ELEMENTAL)) - v3 = 1; - pActors[v75].uSectorID = 0; - uIsFlying = pActors[v75].pMonsterInfo.uFlying; - if (!pActors[v75].CanAct()) - uIsFlying = 0; - v70 = IsTerrainSlopeTooHigh(pActors[v75].vPosition.x, pActors[v75].vPosition.y); - v5 = ODM_GetFloorLevel(pActors[v75].vPosition.x, pActors[v75].vPosition.y, pActors[v75].vPosition.z, - pActors[v75].uActorHeight, &uIsOnWater, (int *)&v69, v3); - //v6 = pActors[v75].vPosition.z; - uIsAboveFloor = 0; - v67 = v69 == 0; - if (pActors[v75].vPosition.z > v5 + 1) - uIsAboveFloor = 1; - if (pActors[v75].uAIState == Dead && uIsOnWater && !uIsAboveFloor) - { - pActors[v75].uAIState = Removed; - continue; - } - if (pActors[v75].uCurrentActionAnimation == ANIM_Walking) - { - v8 = pActors[v75].uMovementSpeed; - if ((signed __int64)pActors[v75].pActorBuffs[ACTOR_BUFF_SLOWED].uExpireTime > 0) - v8 = (signed __int64)((double)v8 * 0.5); - if (pActors[v75].uAIState == Fleeing || pActors[v75].uAIState == Pursuing) - v8 *= 2; - if (pParty->bTurnBasedModeOn == true && pTurnEngine->turn_stage == TE_WAIT) - v8 *= flt_6BE3AC_debug_recmod1_x_1_6; - if (v8 > 1000) - v8 = 1000; - - pActors[v75].vVelocity.x = fixpoint_mul(stru_5C6E00->Cos(pActors[v75].uYawAngle), v8); - pActors[v75].vVelocity.y = fixpoint_mul(stru_5C6E00->Sin(pActors[v75].uYawAngle), v8); - if (uIsFlying) - { - pActors[v75].vVelocity.z = fixpoint_mul(stru_5C6E00->Sin(pActors[v75].uPitchAngle), v8); - } - //v7 = v68; - } - else - { - pActors[v75].vVelocity.x = fixpoint_mul(55000, pActors[v75].vVelocity.x); - pActors[v75].vVelocity.y = fixpoint_mul(55000, pActors[v75].vVelocity.y); - if (uIsFlying) - pActors[v75].vVelocity.z = fixpoint_mul(55000, pActors[v75].vVelocity.z); - } - if (pActors[v75].vPosition.z < v5) - { - pActors[v75].vPosition.z = v5; - pActors[v75].vVelocity.z = uIsFlying != 0 ? 0x14 : 0; - } - //v17 = 0; - if (!uIsAboveFloor || uIsFlying) - { - if (v70 && !uIsAboveFloor && v67) - { - pActors[v75].vPosition.z = v5; - ODM_GetTerrainNormalAt(pActors[v75].vPosition.x, pActors[v75].vPosition.y, &v62); - v20 = GetGravityStrength(); - //v21 = v62.y; - //v22 = v62.z; - //v23 = v62.y * v0->vVelocity.y; - pActors[v75].vVelocity.z += -8 * LOWORD(pEventTimer->uTimeElapsed) * v20; - int v73 = abs(v62.x * pActors[v75].vVelocity.x + v62.z * pActors[v75].vVelocity.z + v62.y * pActors[v75].vVelocity.y) >> 16; - //v72b = v21; - pActors[v75].vVelocity.x += fixpoint_mul(v73, v62.x); - pActors[v75].vVelocity.y += fixpoint_mul(v73, v62.y); - pActors[v75].vVelocity.z += fixpoint_mul(v73, v62.z); - //v17 = 0; - } - } - else - { - pActors[v75].vVelocity.z -= LOWORD(pEventTimer->uTimeElapsed) * GetGravityStrength(); - } - if (pParty->armageddon_timer != 0 && pActors[v75].CanAct()) - { - pActors[v75].vVelocity.x += rand() % 100 - 50; - pActors[v75].vVelocity.y += rand() % 100 - 50; - pActors[v75].vVelocity.z += rand() % 100 - 20; - v25 = rand(); - pActors[v75].uAIState = Stunned; - pActors[v75].uYawAngle += v25 % 32 - 16; - pActors[v75].UpdateAnimation(); - } - if (pActors[v75].vVelocity.x * pActors[v75].vVelocity.x + pActors[v75].vVelocity.y * pActors[v75].vVelocity.y < 400 && v70 == 0) - { - pActors[v75].vVelocity.y = 0; - pActors[v75].vVelocity.x = 0; - } - stru_721530.field_0 = 1; - if (!uIsFlying) - v26 = 40; - else - v26 = pActors[v75].uActorRadius; - - stru_721530.field_84 = -1; - stru_721530.field_8_radius = v26; - stru_721530.prolly_normal_d = v26; - stru_721530.height = pActors[v75].uActorHeight; - stru_721530.field_70 = 0; - - for (v69 = 0; v69 < 100; ++v69) - { - stru_721530.position.x = pActors[v75].vPosition.x; - stru_721530.normal.x = stru_721530.position.x; - stru_721530.position.y = pActors[v75].vPosition.y; - stru_721530.normal.y = stru_721530.position.y; - v28 = pActors[v75].vPosition.z; - stru_721530.normal.z = v28 + v26 + 1; - stru_721530.position.z = v28 - v26 + stru_721530.height - 1; - if (stru_721530.position.z < stru_721530.normal.z) - stru_721530.position.z = v28 + v26 + 1; - stru_721530.velocity.x = pActors[v75].vVelocity.x; - stru_721530.uSectorID = 0; - stru_721530.velocity.y = pActors[v75].vVelocity.y; - stru_721530.velocity.z = pActors[v75].vVelocity.z; - if (stru_721530._47050A(0)) - break; - _46E889_collide_against_bmodels(1); - v29 = WorldPosToGridCellZ(pActors[v75].vPosition.y); - v30 = WorldPosToGridCellX(pActors[v75].vPosition.x); - _46E26D_collide_against_sprites(v30, v29); - _46EF01_collision_chech_player(0); - _46ED8A_collide_against_sprite_objects(PID(OBJECT_Actor, v75)); - v31 = 0; - for (i = 0; v31 < ai_arrays_size; ++v31) - { - v33 = ai_near_actors_ids[v31]; - if (v33 != v75 && Actor::_46DF1A_collide_against_actor(v33, 40)) - ++i; - } - v71 = i > 1; - if (stru_721530.field_7C < stru_721530.field_6C) - v70 = fixpoint_mul(stru_721530.field_7C, stru_721530.direction.z); - //v34 = 0; - v35 = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1; - v36 = ODM_GetFloorLevel(stru_721530.normal2.x, stru_721530.normal2.y, - stru_721530.normal2.z - stru_721530.prolly_normal_d - 1, - pActors[v75].uActorHeight, (int *)&v63, &v64, 0); - if (uIsOnWater) - { - if (v35 < v36 + 60) - { - if (pActors[v75].uAIState == Dead || pActors[v75].uAIState == Dying || pActors[v75].uAIState == Removed - || pActors[v75].uAIState == Disabled) - { - if (v64) - v61 = v36 + 30; - else - v61 = v5 + 60; - SpriteObject::sub_42F960_create_object(pActors[v75].vPosition.x, pActors[v75].vPosition.y, v61); - pActors[v75].uAIState = Removed; - return; - } - } - } - if (stru_721530.field_7C >= stru_721530.field_6C) - { - pActors[v75].vPosition.x = LOWORD(stru_721530.normal2.x); - pActors[v75].vPosition.y = LOWORD(stru_721530.normal2.y); - pActors[v75].vPosition.z = LOWORD(stru_721530.normal2.z) - LOWORD(stru_721530.prolly_normal_d) - 1; - break; - } - //v72b = fixpoint_mul(stru_721530.field_7C, stru_721530.field_58.x); - pActors[v75].vPosition.x += fixpoint_mul(stru_721530.field_7C, stru_721530.direction.x); - //v72b = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.y) >> 16; - pActors[v75].vPosition.y += fixpoint_mul(stru_721530.field_7C, stru_721530.direction.y); - //v72b = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.z) >> 16; - pActors[v75].vPosition.z += fixpoint_mul(stru_721530.field_7C, stru_721530.direction.z); - stru_721530.field_70 += stru_721530.field_7C; - v39 = PID_ID(stru_721530.uFaceID); - switch (PID_TYPE(stru_721530.uFaceID)) - { - case OBJECT_Actor: - if (pTurnEngine->turn_stage != TE_ATTACK && pTurnEngine->turn_stage != TE_MOVEMENT || pParty->bTurnBasedModeOn != TE_WAIT) - { - //if(pParty->bTurnBasedModeOn == 1) - //v34 = 0; - if (pActors[v75].pMonsterInfo.uHostilityType) - { - if (v71 == 0) - Actor::AI_Flee(v75, stru_721530.uFaceID, 0, (AIDirection *)0); - else - Actor::AI_StandOrBored(v75, 4, 0, (AIDirection *)0); - } - else if (v71) - Actor::AI_StandOrBored(v75, 4, 0, (AIDirection *)0); - else if (pActors[v39].pMonsterInfo.uHostilityType == MonsterInfo::Hostility_Friendly) - Actor::AI_Flee(v75, stru_721530.uFaceID, 0, (AIDirection *)0); - else - Actor::AI_FaceObject(v75, stru_721530.uFaceID, 0, (AIDirection *)0); - } - break; - case OBJECT_Player: - if (!pActors[v75].GetActorsRelation(0)) - { - Actor::AI_FaceObject(v75, stru_721530.uFaceID, 0, (AIDirection *)0); - break; - } - //v52 = HIDWORD(pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime) == 0; - //v53 = SHIDWORD(pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime) < 0; - pActors[v75].vVelocity.y = 0; - pActors[v75].vVelocity.x = 0; - //if ( !v53 && (!(v53 | v52) || LODWORD(pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime) > 0) ) - if ((signed __int64)pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime < 0) - pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].Reset(); - viewparams->bRedrawGameUI = 1; - break; - case OBJECT_Decoration: - v47 = integer_sqrt(pActors[v75].vVelocity.x * pActors[v75].vVelocity.x + pActors[v75].vVelocity.y * pActors[v75].vVelocity.y); - v48 = stru_5C6E00->Atan2(pActors[v75].vPosition.x - pLevelDecorations[v39].vPosition.x, - pActors[v75].vPosition.y - pLevelDecorations[v39].vPosition.y); - //v49 = v48; - pActors[v75].vVelocity.x = fixpoint_mul(stru_5C6E00->Cos(v48), v47); - pActors[v75].vVelocity.y = fixpoint_mul(stru_5C6E00->Sin(v48), v47); - break; - case OBJECT_BModel: - face = &pOutdoor->pBModels[stru_721530.uFaceID >> 9].pFaces[v39 & 0x3F]; - if (!face->Ethereal()) - { - if (face->uPolygonType == 3) - { - pActors[v75].vVelocity.z = 0; - pActors[v75].vPosition.z = LOWORD(pOutdoor->pBModels[stru_721530.uFaceID >> 9].pVertices.pVertices[face->pVertexIDs[0]].z) + 1; - if (pActors[v75].vVelocity.x * pActors[v75].vVelocity.x - + pActors[v75].vVelocity.y * pActors[v75].vVelocity.y < 400) - { - pActors[v75].vVelocity.y = 0; - pActors[v75].vVelocity.x = 0; - } - } - else - { - v72b = abs(face->pFacePlane.vNormal.y * pActors[v75].vVelocity.y + face->pFacePlane.vNormal.z * pActors[v75].vVelocity.z - + face->pFacePlane.vNormal.x * pActors[v75].vVelocity.x) >> 16; - if ((stru_721530.speed >> 3) > v72b) - v72b = stru_721530.speed >> 3; - - pActors[v75].vVelocity.x += fixpoint_mul(v72b, face->pFacePlane.vNormal.x); - pActors[v75].vVelocity.y += fixpoint_mul(v72b, face->pFacePlane.vNormal.y); - pActors[v75].vVelocity.z += fixpoint_mul(v72b, face->pFacePlane.vNormal.z); - if (face->uPolygonType != 4) - { - v46 = stru_721530.prolly_normal_d - - ((face->pFacePlane.dist - + face->pFacePlane.vNormal.x * pActors[v75].vPosition.x - + face->pFacePlane.vNormal.y * pActors[v75].vPosition.y - + face->pFacePlane.vNormal.z * pActors[v75].vPosition.z) >> 16); - if (v46 > 0) - { - pActors[v75].vPosition.x += fixpoint_mul(v46, face->pFacePlane.vNormal.x); - pActors[v75].vPosition.y += fixpoint_mul(v46, face->pFacePlane.vNormal.y); - pActors[v75].vPosition.z += fixpoint_mul(v46, face->pFacePlane.vNormal.z); - } - pActors[v75].uYawAngle = stru_5C6E00->Atan2(pActors[v75].vVelocity.x, pActors[v75].vVelocity.y); - } - } - } - break; - } - - pActors[v75].vVelocity.x = fixpoint_mul(58500, pActors[v75].vVelocity.x); - pActors[v75].vVelocity.y = fixpoint_mul(58500, pActors[v75].vVelocity.y); - pActors[v75].vVelocity.z = fixpoint_mul(58500, pActors[v75].vVelocity.z); - - v26 = stru_721530.prolly_normal_d; - } - - v58 = ((unsigned int)~pOutdoor->ActuallyGetSomeOtherTileInfo(WorldPosToGridCellX(pActors[v75].vPosition.x), WorldPosToGridCellZ(pActors[v75].vPosition.y) - 1) >> 1) & 1; - v59 = ((unsigned int)~pOutdoor->ActuallyGetSomeOtherTileInfo(WorldPosToGridCellX(pActors[v75].vPosition.x), WorldPosToGridCellZ(pActors[v75].vPosition.y) - 1) >> 1) & 1; - if (WorldPosToGridCellX(pActors[v75].vPosition.x) == WorldPosToGridCellX(pActors[v75].vPosition.x) - && WorldPosToGridCellZ(pActors[v75].vPosition.y) == WorldPosToGridCellZ(pActors[v75].vPosition.y) - && v58 || v67 != 0) - { - if (MonsterStats::BelongsToSupertype(pActors[v75].pMonsterInfo.uID, MONSTER_SUPERTYPE_WATER_ELEMENTAL)) - { - v58 = v58 == 0; - v59 = v59 == 0; - } - if (!uIsFlying && v58 && !v59) - { - pActors[v75].vPosition.x = pActors[v75].vPosition.x; - pActors[v75].vPosition.y = pActors[v75].vPosition.y; - if (pActors[v75].CanAct()) - { - pActors[v75].uYawAngle -= 32; - pActors[v75].uCurrentActionTime = 0; - pActors[v75].uCurrentActionLength = 128; - pActors[v75].uAIState = Fleeing; - } - } - } - } -} - -//----- (0047A384) -------------------------------------------------------- -void ODM_LoadAndInitialize(const char *pLevelFilename, ODMRenderParams *thisa) -{ - int v2; // ebx@3 - unsigned int v3; // eax@3 - MapInfo *v4; // edi@4 - //int v5; // eax@8 - //SpawnPointMM7 *v6; // edx@14 - size_t v7; // eax@19 - //char *v8; // eax@19 - //char *v9; // eax@21 - char Source[120]; // [sp+Ch] [bp-84h]@19 - const char *pFilename; // [sp+84h] [bp-Ch]@1 - //unsigned int v12; // [sp+88h] [bp-8h]@12 - //int v13; // [sp+8Ch] [bp-4h]@11 - int v; - - pFilename = pLevelFilename; - //thisa->AllocSoftwareDrawBuffers(); - pODMRenderParams->Initialize(); - pWeather->bRenderSnow = false; - pRenderer->ClearZBuffer(0, 479); - //thisa = (ODMRenderParams *)1; - GetAlertStatus(); - if (_A750D8_player_speech_timer) - _A750D8_player_speech_timer = 0; - v2 = pMapStats->GetMapInfo(pCurrentMapName); - v3 = 0; - if (v2) - { - v4 = &pMapStats->pInfos[v2]; - v3 = v4->uRespawnIntervalDays; - } - else - v4 = (MapInfo *)1; - day_attrib &= ~DAY_ATTRIB_FOG; - dword_6BE13C_uCurrentlyLoadedLocationID = v2; - pOutdoor->Initialize( - pFilename, - (unsigned int)(signed __int64)((double)(signed __int64)pParty->uTimePlayed * 0.234375) / 0x3C / 0x3C / 0x18 + 1, - v3, - &v); - if (!(dword_6BE364_game_settings_1 & GAME_SETTINGS_2000)) - { - Actor::InitializeActors(); - SpriteObject::InitializeSpriteObjects(); - } - dword_6BE364_game_settings_1 &= ~GAME_SETTINGS_2000; - //v5 = 0; - if (!v2) - v = 0; - if (v == 1) - { - //v13 = 0; - for (uint i = 0; i < pOutdoor->uNumSpawnPoints; ++i) - { - //v12 = 0; - //while ( 1 ) - //{ - SpawnPointMM7* spawn = pOutdoor->pSpawnPoints + i; - //v6 = &pOutdoor->pSpawnPoints[v12 / 0x18]; - if (spawn->uKind == 3) - SpawnEncounter(v4, spawn, 0, 0, 0); - else - v4->SpawnRandomTreasure(spawn); - //++v13; - //v12 += 24; - //if ( v13 >= (signed int)pOutdoor->uNumSpawnPoints ) - // break; - //v5 = 0; - //} - } - RespawnGlobalDecorations(); - } - pOutdoor->PrepareDecorations(); - pOutdoor->ArrangeSpriteObjects(); - pOutdoor->InitalizeActors(v2); - pOutdoor->MessWithLUN(); - v7 = strlen("levels\\"); - strcpy(Source, &pFilename[v7]); - strcpy(pOutdoor->pLevelFilename, Source); - pWeather->Initialize(); - pGame->pIndoorCameraD3D->sRotationY = pParty->sRotationY; - pGame->pIndoorCameraD3D->sRotationX = pParty->sRotationX; - //pODMRenderParams->RotationToInts(); - pOutdoor->UpdateSunlightVectors(); - - float fov_rad; - float fov_rad_inv; - //----- (0042394D) -------------------------------------------------------- - //void IndoorCamera::Initialize(int degFov, unsigned int uViewportWidth, unsigned int uViewportHeight) - { - //pIndoorCamera->Initialize(65, viewparams->uScreen_BttmR_X - viewparams->uScreen_topL_X + 1, - // viewparams->uScreen_BttmR_Y - viewparams->uScreen_topL_Y + 1); - - int uViewportWidth = viewparams->uScreen_BttmR_X - viewparams->uScreen_topL_X + 1; - - extern float _calc_fov(int viewport_width, int angle_degree); - fov_rad = _calc_fov(uViewportWidth, 65); - fov_rad_inv = 65536.0 / fov_rad; - } - pODMRenderParams->int_fov_rad = (signed __int64)fov_rad; - pODMRenderParams->int_fov_rad_inv = (signed __int64)fov_rad_inv; - - for (int i = 0; i < 20000; ++i) - { - array_77EC08[i].ptr_38 = &stru_8019C8; - - array_77EC08[i].ptr_48 = nullptr; - } - - MM7Initialization(); -} - -//----- (0047C370) -------------------------------------------------------- -unsigned int GetLevelFogColor() -{ - signed __int64 v1; // qax@5 - int v2; // eax@6 - - if (bUnderwater) - return 0xFF258F5C; - - if (day_attrib & DAY_ATTRIB_FOG) - { - if (pWeather->bNight) // night-time fog - { - if (for_refactoring) - { - MessageBoxA(nullptr, "Nomad: decompilation can be inaccurate, please send savegame to Nomad", "", 0); - __debugbreak(); - } - v2 = -(pWeather->bNight != 1); - return (v2 & 0xE0E0E1) - 0xE0E0E1; - } - else - { - v1 = (signed __int64)((1.0 - pOutdoor->fFogDensity) * 200.0 + pOutdoor->fFogDensity * 31.0); - return v1 | (((unsigned int)v1 | (((unsigned int)v1 | 0xFFFFFF00) << 8)) << 8); - } - } - - return 0; -} - -//----- (0047C3D7) -------------------------------------------------------- -int __fastcall sub_47C3D7_get_fog_specular(int a1, int a2, float a3) -{ - int v3; // ecx@1 - signed int v7; // ecx@11 - - v3 = pWeather->bNight; - if (bUnderwater == 1) - v3 = 0; - if (pParty->armageddon_timer || !(day_attrib & DAY_ATTRIB_FOG) && !bUnderwater) - return 0xFF000000; - if (v3) - { - if (a3 < (double)day_fogrange_1) - { - v7 = 0; - if (a3 == 0.0) - v7 = 216; - if (a2) - v7 = 248; - return (-1 - v7) << 24; - } - else - { - if (a3 > (double)day_fogrange_2) - { - v7 = 216; - if (a3 == 0.0) - v7 = 216; - if (a2) - v7 = 248; - return (-1 - v7) << 24; - } - v7 = (signed __int64)((a3 - (double)day_fogrange_1) / ((double)day_fogrange_2 - (double)day_fogrange_1) * 216.0); - } - } - else - { - if (a3 < (double)day_fogrange_1) - { - v7 = 0; - if (a3 == 0.0) - v7 = 216; - if (a2) - v7 = 248; - return (-1 - v7) << 24; - } - else - { - if (a3 > (double)day_fogrange_2) - { - v7 = 216; - if (a3 == 0.0) - v7 = 216; - if (a2) - v7 = 248; - return (-1 - v7) << 24; - } - else - v7 = floorf(((a3 - (double)day_fogrange_1) * 216.0 / ((double)day_fogrange_2 - (double)day_fogrange_1)) + 0.5f); - } - } - if (v7 > 216) - v7 = 216; - else - { - if (a3 == 0.0) - v7 = 216; - } - if (a2) - v7 = 248; - return (-1 - v7) << 24; -} - - -//----- (0047F44B) -------------------------------------------------------- -unsigned int WorldPosToGridCellX(int sWorldPosX) -{ - return (sWorldPosX >> 9) + 64; // sar is in original exe, resulting -880 / 512 = -1 - // and -880 sar 9 = -2 -} - -//----- (0047F458) -------------------------------------------------------- -unsigned int WorldPosToGridCellZ(int sWorldPosZ) -{ - return 64 - (sWorldPosZ >> 9); // sar is in original exe, resulting -880 / 512 = -1 - // and -880 sar 9 = -2 -} - -//----- (0047F469) -------------------------------------------------------- -int GridCellToWorldPosX(int a1) -{ - return (a1 - 64) << 9; -} - -//----- (0047F476) -------------------------------------------------------- -int GridCellToWorldPosZ(int a1) -{ - return (64 - a1) << 9; -} - - - -//----- (00481ED9) -------------------------------------------------------- -void sub_481ED9_MessWithODMRenderParams() -{ - stru_8019C8._48616B_frustum_odm(65536, 0, 0, 0, 65536, 0); - pODMRenderParams->uNumPolygons = 0; - //pODMRenderParams->uNumEdges = 0; - //pODMRenderParams->uNumSpans = 0; - //pODMRenderParams->uNumSurfs = 0; - pODMRenderParams->uNumBillboards = 0; - pODMRenderParams->field_44 = 0; -} - -//----- (004823F4) -------------------------------------------------------- -bool IsTerrainSlopeTooHigh(int pos_x, int pos_z) -{ - //unsigned int v2; // ebx@1 - //unsigned int v3; // edi@1 - //int v4; // eax@1 - //int v6; // esi@5 - //int v7; // ecx@6 - //int v8; // edx@6 - //int v9; // eax@6 - //int y_min; // esi@10 - //int v11; // [sp+14h] [bp-8h]@1 - //int v12; // [sp+18h] [bp-4h]@1 - - //v12 = a1; - //v11 = a2; - unsigned int grid_x = WorldPosToGridCellX(pos_x); - unsigned int grid_z = WorldPosToGridCellZ(pos_z) - 1; - - int party_grid_x1 = GridCellToWorldPosX(grid_x); - //dword_76D56C_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(grid_x + 1); - //dword_76D570_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(grid_x + 1); - //dword_76D574_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(grid_x); - int party_grid_z1 = GridCellToWorldPosZ(grid_z); - //dword_76D55C_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(grid_z); - //dword_76D560_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(grid_z + 1); - //dword_76D564_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(grid_z + 1); - int party_x1z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z); - int party_x2z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z); - int party_x2z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z + 1); - int party_x1z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z + 1); - //dword_76D554_terrain_cell_world_pos_around_party_y = v4; - if (party_x1z1_y == party_x2z1_y && - party_x2z1_y == party_x2z2_y && - party_x2z2_y == party_x1z2_y) - return false; - - int dx = abs(pos_x - party_grid_x1), - dz = abs(party_grid_z1 - pos_z); - - int y1, y2, y3; - if (dz >= dx) - { - y1 = party_x1z2_y; // lower-left triangle - y2 = party_x2z2_y; // y3 | \ - y3 = party_x1z1_y; // | \ - /* | \ - |______ \ - y1 y2 */ - } - else - { - y1 = party_x2z1_y; // upper-right - y2 = party_x1z1_y; // y2_______ y1 - y3 = party_x2z2_y; // \ | - /* \ | - \ | - y3 */ - } - - int y_min = min(y1, min(y2, y3));// не верно при подъёме на склон - int y_max = max(y1, max(y2, y3)); - return (y_max - y_min) > 512; -} - -//----- (0048257A) -------------------------------------------------------- -int __fastcall GetTerrainHeightsAroundParty2(int a1, int a2, int *pIsOnWater, int bFloatAboveWater) -{ - // int result; // eax@9 - int v8; // ebx@11 - int v9; // eax@11 - int v10; // ecx@11 - int v13; // [sp+10h] [bp-8h]@11 - signed int v14; // [sp+14h] [bp-4h]@3 - int v15; // [sp+24h] [bp+Ch]@11 - - unsigned int grid_x = WorldPosToGridCellX(a1); - unsigned int grid_z = WorldPosToGridCellZ(a2) - 1; - - int grid_x1 = GridCellToWorldPosX(grid_x), - grid_x2 = GridCellToWorldPosX(grid_x + 1); - int grid_z1 = GridCellToWorldPosZ(grid_z), - grid_z2 = GridCellToWorldPosZ(grid_z + 1); - - int y_x1z1 = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z), - y_x2z1 = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z), - y_x2z2 = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z + 1), - y_x1z2 = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z + 1); - //v4 = WorldPosToGridCellX(a1); - //v5 = WorldPosToGridCellZ(v12) - 1; - //dword_76D538_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v4); - //dword_76D53C_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v4 + 1); - //dword_76D540_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v4 + 1); - //dword_76D544_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v4); - //dword_76D528_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v5); - //dword_76D52C_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v5); - //dword_76D530_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v5 + 1); - //dword_76D534_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v5 + 1); - //dword_76D518_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4, v5); - //dword_76D51C_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4 + 1, v5); - //dword_76D520_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4 + 1, v5 + 1); - //dword_76D524_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4, v5 + 1); - *pIsOnWater = false; - if (pOutdoor->ActuallyGetSomeOtherTileInfo(grid_x, grid_z) & 2) - *pIsOnWater = true; - v14 = 0; - if (!bFloatAboveWater && *pIsOnWater) - v14 = -60; - if (y_x1z1 != y_x2z1 || - y_x2z1 != y_x2z2 || - y_x2z2 != y_x1z2) - { - if (abs(grid_z1 - a2) >= abs(a1 - grid_x1)) - { - v8 = y_x1z2; - v9 = y_x2z2; - v10 = y_x1z1; - v15 = a1 - grid_x1; - v13 = a2 - grid_z2; - } - else - { - v8 = y_x2z1; - v9 = y_x1z1; - v10 = y_x2z2; - v15 = grid_x2 - a1; - v13 = grid_z1 - a2; - } - return v14 + v8 + fixpoint_mul(v13, (v10 - v8) * 128) + fixpoint_mul(v15, (v9 - v8) * 128); - } - else - return y_x1z1; -} diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Outdoor.h --- a/Outdoor.h Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,278 +0,0 @@ -#pragma - -#include "Indoor.h" -#include "TileFrameTable.h" -#include "BSPModel.h" - -#define DAY_ATTRIB_FOG 1 - -/* 256 */ -#pragma pack(push, 1) -struct ODMHeader -{ - int uVersion; - char pMagic[4]; - unsigned int uCompressedSize; - unsigned int uDecompressedSize; -}; -#pragma pack(pop) - - - -/* 78 */ -#pragma pack(push, 1) -struct OutdoorLocationTileType -{ - Tileset tileset; - unsigned __int16 uTileID; -}; -#pragma pack(pop) - -#pragma pack(push, 1) -struct DMap - { - unsigned __int8 field0; - unsigned __int8 field1; - }; -#pragma pack(pop) - -/* 79 */ -#pragma pack(push, 1) -struct OutdoorLocationTerrain -{ - //----- (0047C794) -------------------------------------------------------- - inline OutdoorLocationTerrain() - { - pHeightmap = nullptr; - pTilemap = nullptr; - pAttributemap = nullptr; - pDmap = nullptr;; - this->field_10 = 0; - this->field_12 = 0; - - - } - - void _47C7A9(); - void Release(); - void FillDMap(int X, int Y, int W, int Z); - int _47CB57(int a1, int a2, int a3); - bool ZeroLandscape(); - bool Initialize(); - - - unsigned __int8 *pHeightmap; - unsigned __int8 *pTilemap; - unsigned __int8 *pAttributemap; - struct DMap *pDmap; - __int16 field_10; - __int16 field_12; - __int16 field_14; - __int16 field_16; - int field_18; - int field_1C; -}; -#pragma pack(pop) - - -/* 81 */ -#pragma pack(push, 1) -struct ODMFace -{ - bool HasEventHint(); - - - static bool IsBackfaceNotCulled(struct RenderVertexSoft *a2, struct Polygon *polygon); - - inline bool Invisible() const {return (uAttributes & FACE_INVISIBLE) != 0;} - inline bool Visible() const {return !Invisible();} - inline bool Portal() const {return (uAttributes & FACE_PORTAL) != 0;} - inline bool Fluid() const {return (uAttributes & FACE_FLUID) != 0;} - inline bool Indoor_sky() const {return (uAttributes & FACE_INDOOR_SKY) != 0;} - inline bool Clickable() const {return (uAttributes & FACE_CLICKABLE) != 0;} - inline bool Pressure_Plate() const {return (uAttributes & FACE_PRESSURE_PLATE) != 0;} - inline bool Ethereal() const {return (uAttributes & FACE_ETHEREAL) != 0;} - - struct Plane_int_ pFacePlane; - int zCalc1; - int zCalc2; - int zCalc3; - unsigned int uAttributes; - unsigned __int16 pVertexIDs[20]; - unsigned __int16 pTextureUIDs[20]; - unsigned __int16 pTextureVIDs[20]; - signed __int16 pXInterceptDisplacements[20]; - signed __int16 pYInterceptDisplacements[20]; - signed __int16 pZInterceptDisplacements[20]; - __int16 uTextureID; - __int16 sTextureDeltaU; - __int16 sTextureDeltaV; - struct BBox_short_ pBoundingBox; - __int16 sCogNumber; - __int16 sCogTriggeredID; - __int16 sCogTriggerType; - char field_128; - char field_129; - unsigned __int8 uGradientVertex1; - unsigned __int8 uGradientVertex2; - unsigned __int8 uGradientVertex3; - unsigned __int8 uGradientVertex4; - unsigned __int8 uNumVertices; - unsigned __int8 uPolygonType; - unsigned __int8 uShadeType; - unsigned __int8 bVisible; - char field_132; - char field_133; -}; -#pragma pack(pop) - - - -#pragma pack(push, 1) -struct OutdoorLocation -{ - OutdoorLocation(); - void subconstuctor(); - - void ExecDraw(unsigned int bRedraw); - void PrepareActorsDrawList(); - void CreateDebugLocation(); - void Release(); - bool Load(const char *pFilename, ODMFace *File, size_t a4, int *thisa); - int GetTileIdByTileMapId(signed int a2); - unsigned int DoGetTileTexture(signed int uX, signed int uZ); - int _47ED83(signed int a2, signed int a3); - int ActuallyGetSomeOtherTileInfo(signed int uX, signed int uY); - int DoGetHeightOnTerrain(signed int sX, signed int sZ); - int GetSoundIdByPosition(signed int X_pos, signed int Y_pos, int a4); - int UpdateDiscoveredArea(int a2, int a3, int a4); - bool IsMapCellFullyRevealed(signed int a2, signed int a3); - bool IsMapCellPartiallyRevealed(signed int a2, signed int a3); - bool _47F0E2(); - bool PrepareDecorations(); - void ArrangeSpriteObjects(); - bool InitalizeActors(int a1); - bool LoadRoadTileset(); - bool LoadTileGroupIds(); - double GetFogDensityByTime(); - int GetSomeOtherTileInfo(int sX, int sY); - unsigned int GetTileTexture(int sX, int sZ); - int GetHeightOnTerrain(int sX, int sZ); - bool Initialize(const char *pFilename, int File, size_t uRespawnInterval, int *thisa); - //bool Release2(); - bool GetTravelDestination(signed int sPartyX, signed int sPartyZ, char *pOut, signed int a5); - void MessWithLUN(); - void UpdateSunlightVectors(); - void UpdateFog(); - int GetNumFoodRequiredToRestInCurrentPos(int x, signed int y, int z); - void SetFog(); - void Draw(); - - static void LoadActualSkyFrame(); - - - char pLevelFilename[32]; - char pLocationFileName[32]; - char pLocationFileDescription[32]; - char pSkyTextureName[32]; - char pGroundTileset[32]; - OutdoorLocationTileType pTileTypes[4]; // [3] road tileset - int uNumBModels; - struct OutdoorLocationTerrain pTerrain; - void *pCmap; - BSPModel *pBModels; - unsigned int numFaceIDListElems; - unsigned __int16 *pFaceIDLIST; - unsigned int *pOMAP; - signed int sSky_TextureID; - signed int sMainTile_BitmapID; - __int16 field_F0; - __int16 field_F2; - int field_F4; - char field_F8[968]; - unsigned int uNumSpawnPoints; - struct SpawnPointMM7 *pSpawnPoints; - struct DDM_DLV_Header ddm; - LocationTime_stru1 loc_time; - //unsigned __int64 uLastVisitDay; - //char sky_texture_name[12]; - //int day_attrib; - //int day_fogrange_1; - //int day_fogrange_2; - // char field_510[24]; - unsigned char uFullyRevealedCellOnMap[88][11];//968 the inner array is 11 bytes long, because every bit is used for a separate cell, so in the end it's 11 * 8 bits = 88 values - unsigned char uPartiallyRevealedCellOnMap[88][11];//[968] - int field_CB8; - int max_terrain_dimming_level; - int field_CC0; - unsigned int pSpriteIDs_LUN[8]; - unsigned int uSpriteID_LUNFULL; - int field_CE8; - unsigned int uSpriteID_LUN3_4_cp; - int field_CF0; - unsigned int uSpriteID_LUN1_2_cp; - int field_CF8; - unsigned int uSpriteID_LUN1_4_cp; - int field_D00; - unsigned __int16 uSpriteID_LUN_SUN; - __int16 field_D06; - int field_D08; - int field_D0C; - int field_D10; - int field_D14; - int inv_sunlight_x; - int inv_sunlight_y; - int inv_sunlight_z; - int field_D24; - int field_D28; - int field_D2C; - Vec3_int_ vSunlight; - int field_D3C; - int field_D40; - int field_D44; - int field_D48; - int field_D4C; - float field_D50; - int field_D54; - int field_D58; - int field_D5C; - int field_D60; - int field_D64; - char field_D68[111900]; - float fFogDensity; - int uLastSunlightUpdateMinute; -}; -#pragma pack(pop) - - -extern struct OutdoorLocation *pOutdoor; - -void ODM_UpdateUserInputAndOther(); -int ODM_GetFloorLevel(int X, signed int Y, int Z, int, int *pOnWater, int *bmodel_pid, int bWaterWalk); -int GetCeilingHeight(int Party_X, signed int Party_Y, int Party_ZHeight, int pFaceID); -void ODM_GetTerrainNormalAt(int pos_x, int pos_z, Vec3_int_ *out); -void UpdateActors_ODM(); -void ODM_ProcessPartyActions(); -char Is_out15odm_underwater(); -void SetUnderwaterFog(); -void ODM_Project(unsigned int uNumVertices); -void sub_487DA9(); -void ODM_LoadAndInitialize(const char *pLevelFilename, struct ODMRenderParams *thisa); -unsigned int GetLevelFogColor(); -int __fastcall sub_47C3D7_get_fog_specular(int a1, int a2, float a3); -unsigned int WorldPosToGridCellX(int); // weak -unsigned int WorldPosToGridCellZ(int); // weak -int GridCellToWorldPosX(int); // weak -int GridCellToWorldPosZ(int); // weak -void sub_481ED9_MessWithODMRenderParams(); -bool IsTerrainSlopeTooHigh(int pos_x, int pos_y); -int __fastcall GetTerrainHeightsAroundParty2(int a1, int a2, int *a3, int a4); - - - - - - - - - diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Overlays.cpp --- a/Overlays.cpp Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,259 +0,0 @@ -#define _CRTDBG_MAP_ALLOC -#include -#include - - -#define _CRT_SECURE_NO_WARNINGS -#include -#include "ErrorHandling.h" - -#include "Overlays.h" -#include "Sprites.h" -#include "FrameTableInc.h" -#include "IconFrameTable.h" -#include "Timer.h" -#include "Party.h" -#include "TurnEngine.h" -#include "LOD.h" -#include "Render.h" -#include "GUIWindow.h" - -#include "mm7_data.h" - - - - - -struct OtherOverlayList *pOtherOverlayList = new OtherOverlayList; // idb -struct OverlayList *pOverlayList = new OverlayList; - - - - - - -// inlined -//----- (mm6c::0045BD50) -------------------------------------------------- -void OtherOverlayList::Reset() -{ - for (uint i = 0; i < 50; ++i) - pOverlays[i].Reset(); -} - -//----- (004418B1) -------------------------------------------------------- -int OtherOverlayList::_4418B1(int a2, int a3, int a4, int a5) -{ - return 0; -} - -//----- (004418B6) -------------------------------------------------------- -int OtherOverlayList::_4418B6(int uOverlayID, __int16 a3, int a4, int a5, __int16 a6) -{ - signed int v9; // esi@6 - __int16 v11; // dx@11 - - for ( uint i = 0; i < 50; ++i ) - { - if ( this->pOverlays[i].field_6 <= 0 ) - { - this->pOverlays[i].field_0 = 0; - this->pOverlays[i].field_A = 0; - this->pOverlays[i].field_8 = 0; - this->pOverlays[i].field_C = a3; - v9 = 0; - for ( v9; v9 < (signed int)pOverlayList->uNumOverlays; ++v9 ) - { - if ( uOverlayID == pOverlayList->pOverlays[v9].uOverlayID ) - break; - } - this->pOverlays[i].field_2 = v9; - this->pOverlays[i].field_4 = 0; - if ( a4 ) - v11 = a4; - else - v11 = 8 * pSpriteFrameTable->pSpriteSFrames[pOverlayList->pOverlays[v9].uSpriteFramesetID].uAnimLength; - this->pOverlays[i].field_6 = v11; - this->pOverlays[i].field_10 = a5; - this->pOverlays[i].field_E = a6; - bRedraw = true; - return true; - } - } - return 0; -} - -//----- (00441964) -------------------------------------------------------- -void OtherOverlayList::DrawTurnBasedIcon(int a2) -{ - IconFrame *frame; // eax@12 - unsigned int v5; // [sp-8h] [bp-Ch]@4 - - if ( pCurrentScreen != SCREEN_GAME || !pParty->bTurnBasedModeOn) - return; - - if ( pTurnEngine->turn_stage == TE_MOVEMENT )//все персы отстрелялись(сжатый кулак) - frame = pIconsFrameTable->GetFrame(pIconIDs_Turn[5 - pTurnEngine->uActionPointsLeft / 26], pEventTimer->uStartTime); - else if ( pTurnEngine->turn_stage == TE_WAIT ) - { - if ( dword_50C998_turnbased_icon_1A ) - v5 = uIconID_TurnStart;//анимация руки(запуск пошагового режима) - else - v5 = uIconID_TurnHour; //группа ожидает(часы) - frame = pIconsFrameTable->GetFrame(v5, dword_50C994); - } - else if ( pTurnEngine->turn_stage == TE_ATTACK )//группа атакует(ладонь) - frame = pIconsFrameTable->GetFrame(uIconID_TurnStop, pEventTimer->uStartTime); - //if ( pRenderer->pRenderD3D ) - pRenderer->DrawTextureIndexed(394, 288, &pIcons_LOD->pTextures[frame->uTextureID]); - /*else - pRenderer->DrawTextureTransparent(0x18Au, 0x120u, v7);*/ - if ( dword_50C994 < dword_50C998_turnbased_icon_1A ) - { - dword_50C994 += pEventTimer->uTimeElapsed; - if ( (signed int)dword_50C994 >= dword_50C998_turnbased_icon_1A ) - dword_50C998_turnbased_icon_1A = 0; - } -} -// 4E28F8: using guessed type int pCurrentScreen; -// 50C994: using guessed type int dword_50C994; -// 50C998: using guessed type int dword_50C998_turnbased_icon_1A; - - -//----- (00458D97) -------------------------------------------------------- -void OverlayList::InitializeSprites() -{ - for (uint i = 0; i < uNumOverlays; ++i) - pSpriteFrameTable->InitializeSprite(pOverlays[i].uSpriteFramesetID); -} - -//----- (00458DBC) -------------------------------------------------------- -void OverlayList::ToFile() -{ - FILE *v2; // eax@1 - //FILE *v3; // edi@1 - - v2 = fopen("data\\doverlay.bin", "wb"); - //v3 = v2; - if ( !v2 ) - Error("Unable to save doverlay.bin!"); - fwrite(this, 4, 1, v2); - fwrite(this->pOverlays, 8, this->uNumOverlays, v2); - fclose(v2); -} - -//----- (00458E08) -------------------------------------------------------- -void OverlayList::FromFile(void *data_mm6, void *data_mm7, void *data_mm8) -{ - uint num_mm6_overlays = data_mm6 ? *(int *)data_mm6 : 0, - num_mm7_overlays = data_mm7 ? *(int *)data_mm7 : 0, - num_mm8_overlays = data_mm8 ? *(int *)data_mm8 : 0; - - uNumOverlays = num_mm6_overlays + num_mm7_overlays + num_mm8_overlays; - Assert(uNumOverlays); - Assert(!num_mm8_overlays); - - pOverlays = (OverlayDesc *)malloc(uNumOverlays * sizeof(OverlayDesc)); - memcpy(pOverlays, (char *)data_mm7 + 4, num_mm7_overlays * sizeof(OverlayDesc)); - memcpy(pOverlays + num_mm7_overlays, (char *)data_mm6 + 4, num_mm6_overlays * sizeof(OverlayDesc)); - memcpy(pOverlays + num_mm6_overlays + num_mm7_overlays, (char *)data_mm8 + 4, num_mm8_overlays * sizeof(OverlayDesc)); -} - -//----- (00458E4F) -------------------------------------------------------- -bool OverlayList::FromFileTxt(const char *Args) -{ - __int32 v3; // edi@1 - FILE *v4; // eax@1 - unsigned int v5; // esi@3 - void *v7; // eax@9 - //FILE *v8; // ST0C_4@11 - char *i; // eax@11 - char Buf; // [sp+10h] [bp-2F0h]@3 - FrameTableTxtLine v18; // [sp+204h] [bp-FCh]@4 - FrameTableTxtLine v19; // [sp+280h] [bp-80h]@4 - FILE *File; // [sp+2FCh] [bp-4h]@1 - unsigned int Argsa; // [sp+308h] [bp+8h]@3 - - free(this->pOverlays); - v3 = 0; - this->pOverlays = nullptr; - this->uNumOverlays = 0; - v4 = fopen(Args, "r"); - File = v4; - if ( !v4 ) - Error("ObjectDescriptionList::load - Unable to open file: %s."); - - v5 = 0; - Argsa = 0; - if ( fgets(&Buf, 490, v4) ) - { - do - { - *strchr(&Buf, 10) = 0; - memcpy(&v19, txt_file_frametable_parser(&Buf, &v18), sizeof(v19)); - if ( v19.uPropCount && *v19.pProperties[0] != 47 ) - ++Argsa; - } - while ( fgets(&Buf, 490, File) ); - v5 = Argsa; - v3 = 0; - } - this->uNumOverlays = v5; - v7 = malloc(8 * v5); - this->pOverlays = (OverlayDesc *)v7; - if ( v7 == (void *)v3 ) - Error("OverlayDescriptionList::load - Out of Memory!"); - - memset(v7, v3, 8 * this->uNumOverlays); - //v8 = File; - this->uNumOverlays = v3; - fseek(File, v3, v3); - for ( i = fgets(&Buf, 490, File); i; i = fgets(&Buf, 490, File) ) - { - *strchr(&Buf, 10) = 0; - memcpy(&v19, txt_file_frametable_parser(&Buf, &v18), sizeof(v19)); - if ( v19.uPropCount && *v19.pProperties[0] != 47 ) - { - this->pOverlays[this->uNumOverlays].uOverlayID = atoi(v19.pProperties[0]); - if ( _stricmp(v19.pProperties[1], "center") ) - { - if ( !_stricmp(v19.pProperties[1], "transparent") ) - this->pOverlays[this->uNumOverlays].uOverlayType = 2; - else - this->pOverlays[this->uNumOverlays].uOverlayType = 1; - } - else - this->pOverlays[this->uNumOverlays].uOverlayType = 0; - this->pOverlays[this->uNumOverlays++].uSpriteFramesetID = pSpriteFrameTable->FastFindSprite((char *)v19.pProperties[2]); - } - } - fclose(File); - return 1; -} - -//----- (0045855F) -------------------------------------------------------- -void OtherOverlay::Reset() -{ - this->field_0 = 0; - this->field_2 = 0; - this->field_4 = 0; - this->field_6 = 0; - this->field_8 = 0; - this->field_A = 0; - this->field_C = 0; - this->field_E = 0; - this->field_10 = 65536; -} - -//----- (004584B8) -------------------------------------------------------- -OtherOverlay::OtherOverlay() -{ - this->field_0 = 0; - this->field_2 = 0; - this->field_4 = 0; - this->field_6 = 0; - this->field_8 = 0; - this->field_A = 0; - this->field_C = 0; - this->field_E = 0; - this->field_10 = 65536; -} \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Overlays.h --- a/Overlays.h Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ -#pragma once - - -/* 282 */ -#pragma pack(push, 1) -struct OtherOverlay -{ - OtherOverlay(); - void Reset(); - - __int16 field_0; - __int16 field_2; - __int16 field_4; - __int16 field_6; - __int16 field_8; - __int16 field_A; - __int16 field_C; - __int16 field_E; - int field_10; -}; -#pragma pack(pop) - -/* 63 */ -#pragma pack(push, 1) -struct OtherOverlayList -{ - inline OtherOverlayList(): //----- (0045848D) - field_3E8(0), bRedraw(false) - {} - - void Reset(); - int _4418B1(int a2, int a3, int a4, int a5); - int _4418B6(int uOverlayID, __int16 a3, int a4, int a5, __int16 a6); - void DrawTurnBasedIcon(int a2); - - OtherOverlay pOverlays[50]; - int field_3E8; - int bRedraw; -}; -#pragma pack(pop) - - - - -/* 52 */ -#pragma pack(push, 1) -struct OverlayDesc -{ - unsigned __int16 uOverlayID; - unsigned __int16 uOverlayType; - unsigned __int16 uSpriteFramesetID; - __int16 field_6; -}; -#pragma pack(pop) - - - -#pragma pack(push, 1) -struct OverlayList -{ - inline OverlayList(): //----- (00458474) - uNumOverlays(0), pOverlays(nullptr) - {} - - void ToFile(); - void FromFile(void *data_mm6, void *data_mm7, void *data_mm8); - bool FromFileTxt(const char *Args); - void InitializeSprites(); - - - unsigned int uNumOverlays; - struct OverlayDesc *pOverlays; -}; -#pragma pack(pop) - - - - -extern struct OtherOverlayList *pOtherOverlayList; // idb -extern struct OverlayList *pOverlayList; \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 PaletteManager.cpp --- a/PaletteManager.cpp Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,986 +0,0 @@ -#define _CRTDBG_MAP_ALLOC -#include -#include - -#define _CRT_SECURE_NO_WARNINGS -#include "ErrorHandling.h" -#include "PaletteManager.h" -#include "Game.h" -#include "LOD.h" -#include "Log.h" -#include "OurMath.h" - -#include "mm7_data.h" - - - - -PaletteManager *pPaletteManager = new PaletteManager; - - - -//----- (00452AE2) -------------------------------------------------------- -int __fastcall MakeColorMaskFromBitDepth(int a1) -{ - signed __int64 v1; // qax@1 - - v1 = 4294967296i64; - if ( a1 > 0 ) - { - do - { - LODWORD(v1) = HIDWORD(v1) + v1; - HIDWORD(v1) *= 2; - --a1; - } - while ( a1 ); - } - return v1; -} - -//----- (0048A643) -------------------------------------------------------- -bool __fastcall HSV2RGB(float *a1, float *a2, float *a3, float a4, float a5, float a6) -{ - float *v6; // ebx@1 - float *v7; // edi@1 - float *v8; // esi@1 - double v9; // st7@5 - signed __int64 v10; // qax@5 - double v11; // st7@5 - double v12; // st5@5 - int v13; // eax@6 - int v14; // eax@7 - int v15; // eax@8 - int v16; // eax@9 - float v17; // eax@11 - float a3a; // [sp+1Ch] [bp+8h]@14 - float a4b; // [sp+20h] [bp+Ch]@5 - float a4c; // [sp+20h] [bp+Ch]@5 - float a4a; // [sp+20h] [bp+Ch]@5 - - v6 = a3; - v7 = a2; - v8 = a1; - if ( a5 == 0.0 ) - { - *a3 = a6; - *a2 = a6; - *a1 = a6; - goto LABEL_20; - } - if ( a4 == 360.0 ) - a4 = 0.0; - v9 = a4 * 0.01666666666666667; - a4b = v9; - floor(v9); - v10 = (signed __int64)v9; - a4c = a4b - (double)(signed int)(signed __int64)v9; - v11 = (1.0 - a5) * a6; - v12 = (1.0 - a4c * a5) * a6; - a4a = (1.0 - (1.0 - a4c) * a5) * a6; - if ( (int)v10 ) - { - v13 = v10 - 1; - if ( v13 ) - { - v14 = v13 - 1; - if ( v14 ) - { - v15 = v14 - 1; - if ( v15 ) - { - v16 = v15 - 1; - if ( v16 ) - { - if ( v16 != 1 ) - goto LABEL_20; - *v8 = a6; - v17 = v12; - *v7 = v11; - goto LABEL_12; - } - *(int *)v8 = LODWORD(a4a); - *v7 = v11; - } - else - { - *v8 = v11; - a3a = v12; - *(int *)v7 = LODWORD(a3a); - } - v17 = a6; - } - else - { - *v8 = v11; - *(int *)v7 = LODWORD(a6); - v17 = a4a; - } -LABEL_12: - *(int *)v6 = LODWORD(v17); - goto LABEL_20; - } - *v8 = v12; - *v7 = a6; - } - else - { - *v8 = a6; - *(int *)v7 = LODWORD(a4a); - } - *a3 = v11; -LABEL_20: - if ( *v8 > 1.0 ) - *v8 = 1.0; - if ( *v7 > 1.0 ) - *v7 = 1.0; - if ( *v6 > 1.0 ) - *v6 = 1.0; - if ( *v8 < 0.0 ) - *v8 = 0.0; - if ( *v7 < 0.0 ) - *v7 = 0.0; - if ( *v6 < 0.0 ) - *v6 = 0.0; - return 1; -} - -//----- (0048A7AA) -------------------------------------------------------- -void __fastcall RGB2HSV(float *a1, float *a2, float a3, float a4, float a5, float *a6) -{ - double v6; // st7@2 - double v7; // st6@7 - double v8; // st5@12 - double v9; // st7@15 - double v10; // st7@17 -// double v11; // st7@21 -// __int16 v12; // fps@21 -// unsigned __int8 v13; // c0@21 -// unsigned __int8 v14; // c2@21 - float a6a; // [sp+14h] [bp+14h]@16 - - if ( a3 <= (double)a4 ) - v6 = a4; - else - v6 = a3; - if ( v6 < a5 ) - v6 = a5; - if ( a3 <= (double)a4 ) - v7 = a3; - else - v7 = a4; - if ( v7 > a5 ) - v7 = a5; - *a6 = v6; - if ( v6 == 0.0 ) - v8 = 0.0; - else - v8 = (v6 - v7) / v6; - *a2 = v8; - if ( v8 == 0.0 ) - { - v9 = 0.0; -//LABEL_23: - *a1 = v9; - return; - } - a6a = v6 - v7; - if ( a3 == v6 ) - { - v10 = (a4 - a5) / a6a; - } - else - { - if ( a4 == v6 ) - v10 = (a5 - a3) / a6a + 2.0; - else - v10 = (a3 - a4) / a6a + 4.0; - } - //*a1 = v10; - //v11 = *a1 * 60.0; - //UNDEF(v12); - *a1 = v10 * 60.0; - if (*a1 < 0) - { - *a1 += 360.0; - } -} - - - -//----- (0048A8A3) -------------------------------------------------------- -int PaletteManager::LockAll() -{ - int *v1; // edx@1 - signed int v2; // eax@1 - - v1 = &this->pPaletteIDs[1]; - v2 = 1; - do - { - if ( *v1 ) - this->_num_locked = v2 + 1; - ++v2; - ++v1; - } - while ( v2 < 50 ); - return this->_num_locked; -} - -//----- (0048A8CC) -------------------------------------------------------- -int PaletteManager::LockTestAll() -{ - char *v1; // edx@1 - signed int v2; // eax@1 - - v1 = (char *)&this->pPaletteIDs[1]; - v2 = 1; - do - { - if ( *(int *)v1 ) - this->_pal_lock_test = v2 + 1; - ++v2; - v1 += 4; - } - while ( v2 < 50 ); - return this->_pal_lock_test; -} - - -//----- (0048A8F5) -------------------------------------------------------- -void PaletteManager::SetColorChannelInfo(int uNumRBits, int uNumGBits, int uNumBBits) -{ - PaletteManager *v4; // esi@1 - int v5; // edi@1 - int v6; // eax@1 - int v7; // ebx@1 - - v4 = this; - this->uNumTargetRBits = uNumRBits; - this->uNumTargetGBits = uNumGBits; - v5 = this->uNumTargetGBits; - this->uNumTargetBBits = uNumBBits; - v6 = MakeColorMaskFromBitDepth(uNumRBits); - v7 = v4->uNumTargetBBits; - v4->uTargetRMask = v6 << (v5 + v4->uNumTargetBBits); - v4->uTargetGMask = MakeColorMaskFromBitDepth(v5) << v7; - v4->uTargetBMask = MakeColorMaskFromBitDepth(v7); -} - - -//----- (00489BE0) -------------------------------------------------------- -void PaletteManager::CalcPalettes_LUT(int a2) -{ - PaletteManager *v2; // esi@1 - //char *v3; // edi@1 - //signed int v4; // ebx@4 - //float v5; // ST08_4@5 - //float v6; // ST04_4@5 - //float v7; // ST00_4@5 - //int v8; // eax@7 - //float *v9; // edx@8 - //float *v10; // ST0C_4@8 - //float *v11; // ecx@8 - //int v12; // ebx@8 - //int v13; // eax@8 - //float v14; // ebx@8 -// float v15; // ST08_4@8 -// float v16; // ST04_4@8 -// float v17; // ST00_4@8 - //unsigned __int8 v18; // sf@8 - //unsigned __int8 v19; // of@8 - //int v20; // eax@10 - double v21; // st5@11 - //float v22; // ST0C_4@13 - unsigned int v23; // eax@13 - //__int16 v24; // bx@16 - //int v25; // eax@16 - double v26; // st7@20 - //float v27; // ST0C_4@22 - unsigned int v28; // eax@22 - //__int16 v29; // bx@25 - //__int16 *v30; // eax@25 - //int v31; // eax@27 - double v32; // st5@28 - //float v33; // ST0C_4@30 - //float v34; // ST08_4@30 - unsigned int v35; // ebx@30 - signed __int64 v36; // qax@33 - signed int v37; // edx@33 - char v38; // cl@33 - unsigned int v39; // ebx@33 - signed int v40; // edi@33 - unsigned int v41; // ecx@33 - unsigned int v42; // ecx@35 - //int v43; // eax@39 - signed int v44; // edx@39 - //unsigned __int8 v45; // al@40 - //double v46; // st6@43 - //signed int v47; // eax@43 - //int v48; // eax@45 - double v49; // st6@47 - //float v50; // ST08_4@49 - //unsigned int v51; // ebx@49 - int v52; // edi@55 - int v53; // ebx@55 - signed __int64 v54; // qax@55 - double v55; // st7@56 - unsigned int v56; // ecx@57 - unsigned int v57; // ecx@59 - //int v58; // edx@61 - unsigned int v59; // ecx@61 - unsigned int v60; // eax@63 - char v61; // cl@63 - //int result; // eax@63 - float v63[256]; // [sp+1Ch] [bp-C38h]@5 - float v64[256]; // [sp+41Ch] [bp-838h]@5 - float a6[256]; // [sp+81Ch] [bp-438h]@5 -// int v66; // [sp+C1Ch] [bp-38h]@43 - float v67; // [sp+C20h] [bp-34h]@43 - float v68; // [sp+C24h] [bp-30h]@43 - //PaletteManager *v69; // [sp+C28h] [bp-2Ch]@9 - //float v70; // [sp+C2Ch] [bp-28h]@43 - //double v71; // [sp+C30h] [bp-24h]@10 - //int v72; // [sp+C38h] [bp-1Ch]@9 - //int v73; // [sp+C3Ch] [bp-18h]@9 - //int i; // [sp+C40h] [bp-14h]@7 - //float v75; // [sp+C44h] [bp-10h]@5 - float a2a; // [sp+C48h] [bp-Ch]@13 - float a1; // [sp+C4Ch] [bp-8h]@13 - float a3; // [sp+C50h] [bp-4h]@13 - signed int v79; // [sp+C5Ch] [bp+8h]@33 - //signed int v80; // [sp+C5Ch] [bp+8h]@43 - int v81; // [sp+C5Ch] [bp+8h]@57 - - v2 = this; - //v3 = (char *)pBaseColors[a2]; - if (pPalette_tintColor[0] || pPalette_tintColor[1] || pPalette_tintColor[2]) - { - //v8 = 0; - //i = 0; - - for (uint i = 0; i < 256; ++i) - RGB2HSV(&v64[i], &v63[i], (pBaseColors[a2][i][0] + pPalette_tintColor[0]) / (255.0f + 255.0f), //Uninitialized memory access - (pBaseColors[a2][i][1] + pPalette_tintColor[1]) / (255.0f + 255.0f), - (pBaseColors[a2][i][2] + pPalette_tintColor[2]) / (255.0f + 255.0f), &a6[i]); - //do - //{ - //v9 = (float *)((char *)v63 + v8); - //v10 = (float *)((char *)a6 + v8); - //v11 = (float *)((char *)v64 + v8); - //v12 = pPalette_tintColor[1]; - //LODWORD(v75) = pPalette_tintColor[2] + (unsigned __int8)v3[2]; - //v13 = pPalette_tintColor[1] + (unsigned __int8)v3[1]; - //LODWORD(v14) = (unsigned __int8)*v3; - //v15 = (double)((unsigned __int8)v3[2] + pPalette_tintColor[2]) / (2.0f * 255.0f); - //LODWORD(v75) = v13; - //LODWORD(v75) = (unsigned __int8)*v3 + pPalette_tintColor[0]; - //v16 = (double)((unsigned __int8)v3[1] + pPalette_tintColor[1]) / 510.0f; - //v17 = (double)((unsigned __int8)*v3 + pPalette_tintColor[0]) / 510.0f; - //RGB2HSV(&v64[i], &v63[i], v17, v16, v15, &a6[i]); - //v3 += 3; - //v8 = i + 4; - //v19 = __OFSUB__(i + 4, 1024); - //v18 = i - 1020 < 0; - //i += 4; - //} - //while ( i < ); - } - else - { - for (uint i = 0; i < 256; ++i) - RGB2HSV(&v64[i], &v63[i], pBaseColors[a2][i][0] / 255.0f, - pBaseColors[a2][i][1] / 255.0f, - pBaseColors[a2][i][2] / 255.0f, &a6[i]); - /*v4 = 0; - do - { - LODWORD(v75) = (unsigned __int8)v3[2]; - v5 = (double)SLODWORD(v75) * 0.00392156862745098; - LODWORD(v75) = (unsigned __int8)v3[1]; - v6 = (double)SLODWORD(v75) * 0.00392156862745098; - LODWORD(v75) = (unsigned __int8)*v3; - v7 = (double)SLODWORD(v75) * 0.00392156862745098; - RGB2HSV(&v64[v4], &v63[v4], v7, v6, v5, &a6[v4]); - ++v4; - v3 += 3; - } - while ( v4 < 256 );*/ - } - - //v69 = (PaletteManager *)((char *)v2 + 16384 * a2); - //v72 = 0; - //v73 = (int)pPalette1[a2]; - for (uint i = 0; i < 32; ++i) - //do - { - //v20 = 0; - //i = 0; - //v71 = 1.0 - (double)v72 / 31.0f; - //do - for (uint j = 0; j < 256; ++j) - { - v21 = a6[j] * (1.0f - i / 32.0f); - if ( v21 < 0.0 ) - v21 = 0.0; - - //v22 = v21; - HSV2RGB(&a1, &a2a, &a3, v64[j], v63[j], v21); - v23 = v2->uNumTargetGBits; - if ( v23 == 6 ) // r5g6b5 - { - a1 = a1 * 31.0; - a2a = a2a * 62.0; - a3 = a3 * 31.0; - } - else if (v23 == 5) // r5g5b5 - { - a1 = a1 * 31.0; - a2a = a2a * 31.0; - a3 = a3 * 31.0; - } - else if (v23 == 0) - Log::Warning(L"Calling palette manager with num_target_bits == 0"); - else Error("(%u)", v23); - //v24 = (unsigned __int32)a3 | ((unsigned __int32)a2a << v2->uNumTargetBBits) | ((unsigned __int32)a1 << (v2->uNumTargetBBits + v2->uNumTargetGBits)); - //v25 = v73; - //v73 += 2; - //*(short *)v25 = v24; - pPalette1[a2][i][j] = (unsigned __int32)a3 | - ((unsigned __int32)a2a << v2->uNumTargetBBits) | - ((unsigned __int32)a1 << (v2->uNumTargetBBits + v2->uNumTargetGBits)); - //v20 = i + 4; - //v19 = __OFSUB__(i + 4, 1024); - //v18 = i - 1020 < 0; - //i += 4; - } - //while ( v18 ^ v19 ); - //++v72; - } - //while ( v72 < 32 ); - - //v72 = 0; - //v73 = (int)v69->field_199600_palettes; - //do - for (uint i = 0; i < 32; ++i) - { - //i = 0; - //v71 = 1.0 - (double)v72 / 31.0f; - //do - for (uint j = 0; j < 256; ++j) - { - v26 = a6[j] * (1.0 - i / 31.0f); - if ( v26 < 0.0 ) - v26 = 0.0; - - //v27 = v26; - HSV2RGB(&a1, &a2a, &a3, 1.0, 1.0, v26); - v28 = v2->uNumTargetGBits; - if ( v28 == 6 ) - { - a1 = a1 * 31.0; - a2a = a2a * 62.0; - a3 = a3 * 31.0; - } - else if (v28 == 5) - { - a1 = a1 * 31.0; - a2a = a2a * 31.0; - a3 = a3 * 31.0; - } - else if (v23 == 0) - Log::Warning(L"Calling palette manager with num_target_bits == 0"); - else Error("(%u)", v23); - - //v29 = (unsigned __int64)(signed __int64)a3 | ((unsigned __int16)(signed __int64)a2a << v2->uNumTargetBBits) | (unsigned __int16)((unsigned __int16)(signed __int64)a1 << (v2->uNumTargetBBits + v28)); - //v30 = (__int16 *)v73; - //++i; - //v73 += 2; - //v19 = __OFSUB__(i, 256); - //v18 = i - 256 < 0; - //*v30 = v29; - field_199600_palettes[a2][i][j] = (unsigned __int64)(signed __int64)a3 | ((unsigned __int16)(signed __int64)a2a << v2->uNumTargetBBits) | (unsigned __int16)((unsigned __int16)(signed __int64)a1 << (v2->uNumTargetBBits + v28)); - } - //while ( v18 ^ v19 ); - //++v72; - } - //while ( v72 < 32 ); - - //v73 = (int)((char *)v2 + 512 * (a2 + 4875)); // field_261600[a2] - //v31 = 0; - //i = 0; - for (uint i = 0; i < 256; ++i) - //do - { - //v32 = (*(float *)((char *)a6 + v31) - 0.8) * 0.8387096774193549 + 0.8; - v32 = (a6[i] - 0.8f) * 0.8387096774193549 + 0.8; - if ( v32 < 0.0 ) - v32 = 0.0; - - //v33 = v32; - //v34 = v63[i] * 0.7034339229968783; - HSV2RGB(&a1, &a2a, &a3, v64[i], v63[i] * 0.7034339229968783, v32); - v35 = v2->uNumTargetGBits; - if ( v35 == 6 ) - { - a1 = a1 * 31.0; - a2a = a2a * 62.0; - a3 = a3 * 31.0; - } - else if (v35 == 5) - { - a1 = a1 * 31.0; - a2a = a2a * 31.0; - a3 = a3 * 31.0; - } - else if (v23 == 0) - Log::Warning(L"Calling palette manager with num_target_bits == 0"); - else Error("(%u)", v23); - - v36 = (signed __int64)((a1 + a2a + a3) * 0.3333333333333333 * 8.0); - v37 = (signed int)v36 >> (8 - v2->uNumTargetRBits); - v38 = 8 - v35; - v39 = v2->uNumTargetBBits; - v40 = (signed int)v36 >> v38; - v41 = v2->uNumTargetRBits; - v79 = (signed int)v36 >> (8 - v39); - if ( v37 > (1 << v41) - 1 ) - v37 = (1 << v41) - 1; - v42 = v2->uNumTargetGBits; - if ( v40 > (1 << v42) - 1 ) - v40 = (1 << v42) - 1; - if ( v79 > (1 << v39) - 1 ) - v79 = (1 << v39) - 1; - //v43 = v73; - v44 = v37 << (v39 + v2->uNumTargetGBits); - //v73 += 2; - //*(short *)v43 = v79 | ((short)v40 << v39) | (unsigned __int16)v44; - field_261600[a2][i] = v79 | ((unsigned short)v40 << v39) | (unsigned __int16)v44; - //v31 = i + 4; - //v19 = __OFSUB__(i + 4, 1024); - //v18 = i - 1020 < 0; - //i += 4; - } - //while ( v18 ^ v19 ); - - //v45 = pPalette_mistColor[0]; - float mist_a, mist_b, mist_c; - if (pPalette_mistColor[0] || pPalette_mistColor[1] || pPalette_mistColor[2]) - { - //v46 = (double)v45; - //v80 = pPalette_mistColor[1]; - //v47 = pPalette_mistColor[2]; - //v70 = v46 * 0.00392156862745098; - //*((float *)&v71 + 1) = (double)v80 * 0.00392156862745098; - //v75 = (double)v47 * 0.00392156862745098; - mist_a = pPalette_mistColor[0] / 255.0f; - mist_b = pPalette_mistColor[1] / 255.0f; - mist_c = pPalette_mistColor[2] / 255.0f; - - float unused; - RGB2HSV(&v68, &v67, mist_a, mist_b, mist_c, &unused); - } - - //v72 = 0; - //v73 = (int)v69->field_D1600; - //do - for (uint i = 0; i < 32; ++i) - { - //v48 = 0; - //for ( i = 0; ; v48 = i ) - for (uint j = 0; j < 256; ++j) - { - v49 = v63[j]; - if ( v49 < 0.0 ) - v49 = 0.0; - - //v50 = v49; - HSV2RGB(&a1, &a2a, &a3, v64[j], v49, a6[j]); - //v51 = v2->uNumTargetGBits; - if ( v2->uNumTargetGBits == 6 ) - { - a1 = a1 * 31.0; - a2a = a2a * 62.0; - a3 = a3 * 31.0; - } - else if (v2->uNumTargetGBits == 5) - { - a1 = a1 * 31.0; - a2a = a2a * 31.0; - a3 = a3 * 31.0; - } - else if (v23 == 0) - Log::Warning(L"Calling palette manager with num_target_bits == 0"); - else Error("(%u)", v23); - - if (pPalette_mistColor[0] || pPalette_mistColor[1] || pPalette_mistColor[2]) - { - v55 = (double)i / 31.0f; - v52 = (signed __int64)((double)(1 << v2->uNumTargetRBits) * mist_a * v55 + a1 * (1.0 - v55)); - v53 = (signed __int64)((double)(1 << v2->uNumTargetGBits) * mist_b * v55 + a2a * (1.0 - v55)); - v54 = (signed __int64)((double)(1 << v2->uNumTargetBBits) * mist_c * v55 + a3 * (1.0 - v55)); - } - else - { - v52 = (signed __int64)a1; - v53 = (signed __int64)a2a; - v54 = (signed __int64)a3; - } - - v56 = v2->uNumTargetRBits; - v81 = v54; - if ( v52 > (1 << v56) - 1 ) - v52 = (1 << v56) - 1; - v57 = v2->uNumTargetGBits; - if ( v53 > (1 << v57) - 1 ) - v53 = (1 << v57) - 1; - HIDWORD(v54) = v2->uNumTargetBBits; - v59 = v2->uNumTargetBBits; - if ( (signed int)v54 > (1 << v59) - 1 ) - v81 = (1 << v59) - 1; - v60 = v2->uNumTargetGBits; - //i += 4; - v61 = uNumTargetBBits + v60; - //result = v73; - //v73 += 2; - //v19 = __OFSUB__(i, 1024); - //v18 = i - 1024 < 0; - //*(short *)result = v81 | ((short)v53 << uNumTargetBBits) | (v52 << v61); - field_D1600[a2][i][j] = v81 | ((short)v53 << uNumTargetBBits) | (v52 << v61); - //if ( !(v18 ^ v19) ) - // break; - } - //++v72; - } - //while ( v72 < 32 ); -} - - -//----- (0048A300) -------------------------------------------------------- -PaletteManager::PaletteManager(): - uNumTargetRBits(0), uNumTargetGBits(0),uNumTargetBBits(0),_num_locked(0) -{ - for (uint i = 0; i < 256; ++i) - { - pBaseColors[0][i][0] = i; - pBaseColors[0][i][1] = i; - pBaseColors[0][i][2] = i; - } - - memset(pPaletteIDs, 0, sizeof(pPaletteIDs)); - memset(pPalette_tintColor, 0, sizeof(pPalette_tintColor)); - memset(pPalette_mistColor, 0, sizeof(pPalette_mistColor)); - CalcPalettes_LUT(0); -} - -//----- (0048A336) -------------------------------------------------------- -// make grayscale palette at 0, clear all palettes ids that aren't locked -int PaletteManager::ResetNonLocked() -{ - PaletteManager *v1; // esi@1 - signed int v2; // ecx@1 - int v3; // eax@1 - signed int result; // eax@3 - void *v5; // edi@4 - int v6; // ecx@4 - - v1 = this; - v2 = 0; - v3 = (int)&v1->pBaseColors[0][0][1]; - do - { - *(char *)(v3 + 1) = v2; - *(char *)v3 = v2; - *(char *)(v3 - 1) = v2++; - v3 += 3; - } - while ( v2 < 256 ); - CalcPalettes_LUT(0); - result = v1->_num_locked; - if ( result < 50 ) - { - v5 = &v1->pPaletteIDs[result]; - v6 = 50 - result; - result = 0; - memset(v5, 0, 4 * v6); - } - return result; -} - -//----- (0048A379) -------------------------------------------------------- -// make grayscale palette at 0, clear all palettes ids that aren't in "lock_test" -int PaletteManager::ResetNonTestLocked() -{ - PaletteManager *v1; // esi@1 - signed int v2; // ecx@1 - int v3; // eax@1 - signed int result; // eax@3 - void *v5; // edi@4 - int v6; // ecx@4 - - v1 = this; - v2 = 0; - v3 = (int)&v1->pBaseColors[0][0][1]; - do - { - *(char *)(v3 + 1) = v2; - *(char *)v3 = v2; - *(char *)(v3 - 1) = v2++; - v3 += 3; - } - while ( v2 < 256 ); - CalcPalettes_LUT(0); - result = v1->_pal_lock_test; - if ( result < 50 ) - { - v5 = &v1->pPaletteIDs[result]; - v6 = 50 - result; - result = 0; - memset(v5, 0, 4 * v6); - } - return result; -} - -//----- (0048A3BC) -------------------------------------------------------- -int PaletteManager::LoadPalette(unsigned int uPaletteID) -{ - unsigned int *v2; // ecx@1 - signed int result; // eax@1 - signed int v4; // esi@6 - double v5; // st7@7 - double v6; // st7@12 - double v7; // st6@17 - signed __int64 v8; // qax@17 - double v9; // st6@17 - char v10[768]; // [sp+18h] [bp-388h]@6 - //char v11; // [sp+19h] [bp-387h]@17 - //char v12[766]; // [sp+1Ah] [bp-386h]@17 - char Source[32]; // [sp+360h] [bp-40h]@4 - //PaletteManager *v15; // [sp+380h] [bp-20h]@1 - float v16; // [sp+384h] [bp-1Ch]@7 - int v17; // [sp+388h] [bp-18h]@6 - float v18; // [sp+38Ch] [bp-14h]@7 - float a2a; // [sp+390h] [bp-10h]@7 - float a1; // [sp+394h] [bp-Ch]@7 - float a6; // [sp+398h] [bp-8h]@7 - float a3; // [sp+39Ch] [bp-4h]@7 - - //v15 = this; - v2 = (unsigned int *)&this->pPaletteIDs[1]; - result = 1; - while ( *v2 != uPaletteID ) - { - ++result; - ++v2; - if ( result >= 50 ) - { - sprintf(Source, "pal%03i", uPaletteID); - - Texture tex; // [sp+318h] [bp-88h]@4 - //Texture::Texture(&tex); - - if ( pBitmaps_LOD->LoadTextureFromLOD(&tex, Source, TEXTURE_24BIT_PALETTE) == 1 ) - { - v4 = 0; - v17 = 1 - (int)&v10; - do - { - //LODWORD(a1) = tex.pPalette24[v4]; - a1 = (double)tex.pPalette24[v4] / 255.0f; - LODWORD(a2a) = (unsigned __int8)*(&v10 + v4 + v17 + (unsigned int)tex.pPalette24); - a2a = (double)tex.pPalette24[v4 + 1] / 255.0f; - //a3 = tex.pPalette24[v4 + 2]; - a3 = (double)tex.pPalette24[v4 + 2] / 255.0f; - RGB2HSV(&v16, &v18, a1, a2a, a3, &a6); - v5 = a6 * 1.1; - if ( v5 >= 0.0 && v5 >= 1.0 ) - v5 = 1.0; - else - { - if ( v5 < 0.0 ) - v5 = 0.0; - } - a6 = v5; - v6 = v18 * 0.64999998; - if ( v6 >= 0.0 && v6 >= 1.0 ) - v6 = 1.0; - else - { - if ( v6 < 0.0 ) - v6 = 0.0; - } - v18 = v6; - HSV2RGB(&a1, &a2a, &a3, v16, v18, a6); - v7 = a2a * 255.0; - v10[v4] = (signed __int64)(a1 * 255.0); - v8 = (signed __int64)v7; - v9 = a3 * 255.0; - v10[v4 + 1] = v8; - v10[v4 + 2] = (signed __int64)v9; - v4 += 3; - } - while ( v4 < 768 ); - tex.Release(); - result = this->MakeBasePaletteLut(uPaletteID, v10); - } - else - result = 0; - return result; - } - } - return result; -} -// 48A3BC: using guessed type char var_386[766]; - -//----- (0048A5A4) -------------------------------------------------------- -int PaletteManager::MakeBasePaletteLut(int idx, char *entries) -{ - //PaletteManager *v3; // edi@1 - //signed int result; // eax@1 - //int *v5; // ecx@1 - int v6; // eax@4 - int v7; // esi@4 - //int v8; // eax@9 - //signed int v9; // ecx@9 - //int v10; // edx@9 - - //v3 = this; - //result = 0; - //v5 = this->pPaletteIDs; - - for (uint i = 0; i < 50; ++i) - if (pPaletteIDs[i] == idx) - return i; - - v6 = (int)&pPaletteIDs[1]; - v7 = 1; - while ( *(int *)v6 ) - { - ++v7; - v6 += 4; - if ( v7 >= 50 ) - return 0; - } - /*v8 = (int)pBaseColors[v7];//(int)((char *)v3 + 768 * v7); - v9 = 768; - v10 = (int)(entries - v8); - do - { - *(char *)v8 = *(char *)(v10 + v8); - ++v8; - --v9; - } - while ( v9 );*/ - unsigned __int8 *dst = (unsigned __int8 *)pBaseColors[v7]; - for (uint i = 0; i < 768; ++i) - dst[i] = entries[i]; - - pPaletteIDs[v7] = idx; - CalcPalettes_LUT(v7); - return v7; - -} - -// inlined -//----- (mm6c::0045C610) --------------------------------------------------- -void PaletteManager::SetMistColor(unsigned char r, unsigned char g, unsigned char b) -{ - pPalette_mistColor[0] = r; - pPalette_mistColor[1] = g; - pPalette_mistColor[2] = b; -} - -//----- (0048A614) -------------------------------------------------------- -void PaletteManager::RecalculateAll() -{ - CalcPalettes_LUT(0); - - for (uint i = 1; i < 50; ++i) - if (pPaletteIDs[i]) - CalcPalettes_LUT(i); -} - - -//----- (0047BE67) -------------------------------------------------------- -unsigned __int16 *PaletteManager::Get(int a1) -{ - return (unsigned __int16 *)pPaletteManager->field_199600_palettes[a1]; -} - -//----- (0047BE72) -------------------------------------------------------- -unsigned __int16 *PaletteManager::Get_Mist_or_Red_LUT(int a1, int a2, char a3) -{ - int v3; // eax@4 - - if ( a3 & 2 || byte_4D864C && BYTE2(pGame->uFlags) & 4 ) - v3 = 32 * a1 + a2 + 3275; - else - v3 = 32 * a1 + a2 + 1675; - return (unsigned __int16 *)((char *)&pPaletteManager + 512 * v3); -} -// 4D864C: using guessed type char byte_4D864C; - - -//----- (0041F50D) -------------------------------------------------------- -unsigned __int16 *PaletteManager::Get_Dark_or_Red_LUT(int a1, int a2, char a3) -{ - int v3; // eax@4 - - if ( a3 & 2 || byte_4D864C && BYTE2(pGame->uFlags) & 4 ) - v3 = 32 * a1 + a2 + 3275; - else - v3 = 32 * a1 + a2 + 75; - return (unsigned __int16 *)((char *)&pPaletteManager + 512 * v3); -} -// 4D864C: using guessed type char byte_4D864C; - - -//----- (0047C30E) -------------------------------------------------------- -unsigned __int16 *PaletteManager::_47C30E_get_palette(int a1, char a2) -{ - char *result; // eax@4 - - if ( a2 & 2 || byte_4D864C && BYTE2(pGame->uFlags) & 4 ) - result = (char *)pPaletteManager->field_199600_palettes[a1]; - else - result = (char *)pPaletteManager->field_D1600[a1]; - return (unsigned __int16 *)result; -} - - -//----- (0047C33F) -------------------------------------------------------- -unsigned __int16 *PaletteManager::_47C33F_get_palette(int a1, char a2) -{ - unsigned __int16 *result; // eax@4 - - if ( a2 & 2 || byte_4D864C && BYTE2(pGame->uFlags) & 4 ) - result = (unsigned __int16 *)pPaletteManager->field_199600_palettes[a1]; - else - result = (unsigned __int16 *)pPaletteManager->pPalette1[a1]; - return result; -} -// 4D864C: using guessed type char byte_4D864C; - - -//----- (0048A959) -------------------------------------------------------- -signed int ReplaceHSV(unsigned int uColor, float h_replace, float s_replace, float v_replace) -{ - float r = ((uColor & 0x00FF0000) >> 16) / 255.0f, - g = ((uColor & 0x0000FF00) >> 8) / 255.0f, - b = (uColor & 0x000000FF) / 255.0f; - - float h, s, v; - RGB2HSV(&h, &s, r, g, b, &v); - - if ( h_replace != -1.0 ) - h = h_replace; - if ( s_replace != -1.0 ) - s = s_replace; - if ( v_replace != -1.0 ) - v = v_replace; - HSV2RGB(&r, &g, &b, h, s, v); - - return (((uint)round_to_int(r * 255.0f) & 0xFF) << 16) | - (((uint)round_to_int(g * 255.0f) & 0xFF) << 8) | - (((uint)round_to_int(b * 255.0f) & 0xFF)); -} \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 PaletteManager.h --- a/PaletteManager.h Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -#pragma once - - -/* 148 */ -#pragma pack(push, 1) -struct PaletteManager -{ - PaletteManager(); - - void SetMistColor(unsigned char r, unsigned char g, unsigned char b); - int ResetNonTestLocked(); - void CalcPalettes_LUT(int a2); - int ResetNonLocked(); - int LoadPalette(unsigned int uPaletteID); - int MakeBasePaletteLut(int a2, char *entries); - void RecalculateAll(); - int LockAll(); - int LockTestAll(); - void SetColorChannelInfo(int uNumRBits, int uNumGBits, int uNumBBits); - - static unsigned __int16 *Get(int a1); - static unsigned __int16 *Get_Mist_or_Red_LUT(int paletteIdx, int a2, char a3); - static unsigned __int16 *Get_Dark_or_Red_LUT(int paletteIdx, int a2, char a3); - static unsigned __int16 *_47C30E_get_palette(int a1, char a2); - static unsigned __int16 *_47C33F_get_palette(int a1, char a2); - - unsigned __int8 pBaseColors[50][256][3]; - unsigned __int16 pPalette1[50][32][256]; - unsigned __int16 field_D1600[50][32][256]; - unsigned __int16 field_199600_palettes[50][32][256]; - unsigned __int16 field_261600[50][256]; - int pPaletteIDs[50]; - int _num_locked; - int _pal_lock_test; - unsigned __int8 pPalette_mistColor[3]; - unsigned char pPalette_tintColor[3]; - char field_267AD6; - char field_267AD7; - unsigned int uNumTargetRBits; - unsigned int uNumTargetGBits; - unsigned int uNumTargetBBits; - unsigned int uTargetRMask; - unsigned int uTargetGMask; - unsigned int uTargetBMask; -}; -#pragma pack(pop) - - - -bool __fastcall HSV2RGB(float *a1, float *a2, float *a3, float a4, float a5, float a6); -void __fastcall RGB2HSV(float *a1, float *a2, float a3, float a4, float a5, float *a6); -signed int ReplaceHSV(unsigned int uColor, float a2, float gamma, float a4); -extern PaletteManager *pPaletteManager; \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 ParticleEngine.cpp --- a/ParticleEngine.cpp Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,768 +0,0 @@ -#define _CRTDBG_MAP_ALLOC -#include -#include - -#define _CRT_SECURE_NO_WARNINGS -#include "ParticleEngine.h" -#include "Timer.h" -#include "Viewport.h" -#include "Outdoor.h" -#include "Game.h" -#include "OurMath.h" -#include "LOD.h" - -#include "Sprites.h" - -TrailParticleGenerator trail_particle_generator; - - -//----- (00440DF5) -------------------------------------------------------- -void TrailParticleGenerator::AddParticle(int x, int y, int z, int bgr16) -{ - particles[num_particles].x = x; - particles[num_particles].y = y; - particles[num_particles].z = z; - particles[num_particles].time_to_live = rand() % 64 + 256; - particles[num_particles].time_left = particles[num_particles].time_to_live; - particles[num_particles].bgr16 = bgr16; - - num_particles++; - assert(num_particles < 100); -} - -//----- (00440E91) -------------------------------------------------------- -void TrailParticleGenerator::GenerateTrailParticles(int x, int y, int z, int bgr16) -{ - for (int i = 0; i < 5 + rand() % 6; ++i) - AddParticle(rand() % 33 + x - 16, - rand() % 33 + y - 16, - rand() % 33 + z, bgr16); -} - -//----- (00440F07) -------------------------------------------------------- -void TrailParticleGenerator::UpdateParticles() -{ - for (uint i = 0; i < 100; ++i) - { - if (particles[i].time_left > 0) - { - particles[i].x += rand() % 5 + 4; - particles[i].y += rand() % 5 - 2; - particles[i].z += rand() % 5 - 2; - particles[i].time_left -= pEventTimer->uTimeElapsed; - } - } -} - -//----- (0048AAC5) -------------------------------------------------------- -ParticleEngine::ParticleEngine() -{ - for (uint i = 0; i < 500; ++i) - memset(&pParticles[i], 0, sizeof(pParticles[i])); - - ResetParticles(); -} - -//----- (0048AAF6) -------------------------------------------------------- -void ParticleEngine::ResetParticles() -{ - memset(pParticles, 0, 500 * sizeof(*pParticles)); - uStartParticle = 500; - uEndParticle = 0; - uTimeElapsed = 0; -} - -//----- (0048AB23) -------------------------------------------------------- -void ParticleEngine::AddParticle(Particle_sw *a2) -{ - signed int v2; // eax@2 - Particle *v3; // edx@2 - Particle *v4; // esi@10 - int v5; // ecx@10 - //char v6; // zf@10 - - if ( !pMiscTimer->bPaused ) - { - v2 = 0; - v3 = (Particle *)this; - do - { - if (v3->type == ParticleType_Invalid) - break; - ++v2; - ++v3; - } - while ( v2 < 500 ); - if ( v2 < 500 ) - { - if ( v2 < this->uStartParticle ) - this->uStartParticle = v2; - if ( v2 > this->uEndParticle ) - this->uEndParticle = v2; - v4 = &this->pParticles[v2]; - v4->type = a2->type; - v4->x = a2->x; - v4->y = a2->y; - v4->z = a2->z; - v4->_x = a2->x; - v4->_y = a2->y; - v4->_z = a2->z; - v4->flt_10 = a2->r; - v4->flt_14 = a2->g; - v4->flt_18 = a2->b; - v5 = a2->uDiffuse; - v4->uParticleColor = v5; - v4->uLightColor_bgr = v5; - //v6 = (v4->uType & 4) == 0; - v4->timeToLive = a2->timeToLive; - v4->uTextureID = a2->uTextureID; - v4->flt_28 = a2->flt_28; - if (v4->type & ParticleType_Rotating) - { - v4->rotation_speed = (rand() % 256) - 128; - v4->angle = rand(); - } - else - { - v4->rotation_speed = 0; - v4->angle = 0; - } - } - } -} - -//----- (0048ABF3) -------------------------------------------------------- -void ParticleEngine::Draw() -{ - uTimeElapsed += pEventTimer->uTimeElapsed; - pLines.uNumLines = 0; - - if (uCurrentlyLoadedLevelType == LEVEL_Indoor) - DrawParticles_BLV(); - else - DrawParticles_ODM(); - - //if (pRenderer->pRenderD3D) - { - if (pLines.uNumLines) - { - pRenderer->DrawLines(pLines.pLineVertices, pLines.uNumLines); - /*pRenderer->pRenderD3D->pDevice->SetTexture(0, 0); - pRenderer->pRenderD3D->pDevice->DrawPrimitive( - D3DPT_LINELIST, - D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, - pLines.pLineVertices, - pLines.uNumLines, - D3DDP_DONOTLIGHT);*/ - } - } -} - -//----- (0048AC65) -------------------------------------------------------- -void ParticleEngine::UpdateParticles() -{ - unsigned int time; // edi@1 - //int v5; // eax@3 - //char v6; // sf@4 - float v7; // ST4C_4@11 - double v8; // st7@12 - //int v9; // eax@12 - //double v10; // st7@14 - signed int v19; // [sp+38h] [bp-14h]@1 - int v20; // [sp+3Ch] [bp-10h]@1 - unsigned int time_; // [sp+40h] [bp-Ch]@1 - int v22; // [sp+44h] [bp-8h]@12 - - v20 = 0; - time = pMiscTimer->bPaused == 0 ? pEventTimer->uTimeElapsed : 0; - v19 = 500; - time_ = pMiscTimer->bPaused == 0 ? pEventTimer->uTimeElapsed : 0; - - for (uint i = uStartParticle; i <= uEndParticle; ++i) - { - Particle* p = &pParticles[i]; - - if (p->type == ParticleType_Invalid) - continue; - - if (p->timeToLive <= time) - { - p->timeToLive = 0; - p->type = ParticleType_Invalid; - continue; - } - p->timeToLive -= time; - - if (p->type & ParticleType_Line) - { - p->_x = p->x; - p->_y = p->y; - p->_z = p->z; - } - - if (p->type & ParticleType_1) - p->flt_18 = p->flt_18 - (double)(signed int)time_ * 5.0; - - if (p->type & ParticleType_8) - { - v7 = (double)(signed int)time_; - *(float *)&p->x += (double)(rand() % 5 - 2) * v7 / 16.0f; - *(float *)&p->y += (double)(rand() % 5 - 2) * v7 / 16.0f; - *(float *)&p->z += (double)(rand() % 5 + 4) * v7 / 16.0f; - } - v8 = (double)(signed int)time_ / 128.0f; - //v9 = (signed int)(time * p->rotation_speed) / 16; - - p->x += v8 * p->flt_10; - p->y += v8 * p->flt_14; - p->z += v8 * p->flt_18; - - p->angle += time * p->rotation_speed / 16; - v22 = 2 * p->timeToLive; - if (v22 >= 255 ) - v22 = 255; - //v10 = (double)v22 * 0.0039215689; - p->uLightColor_bgr = ((uint)floorf(p->b * (v22 / 255.0f) + 0.5) << 16) | - ((uint)floorf(p->g * (v22 / 255.0f) + 0.5) << 8) | - ((uint)floorf(p->r * (v22 / 255.0f) + 0.5) << 0); - if ( i < v19 ) - v19 = i; - if ( i > v20 ) - v20 = i; - } - - uEndParticle = v20; - uStartParticle = v19; -} - -//----- (0048AE74) -------------------------------------------------------- -bool ParticleEngine::ViewProject_TrueIfStillVisible_BLV(unsigned int uParticleID) -{ - Particle *pParticle; // esi@1 - //double v56; // ST28_8@2 - //float v4; // eax@4 - //double v5; // ST34_8@4 - signed __int64 v6; // qtt@4 - //double v7; // st7@4 - //float v8; // ST18_4@4 -// int v9; // ecx@4 - //int v10; // eax@4 - //double v11; // ST44_8@7 - //double v12; // ST4C_8@7 -// double v13; // ST4C_8@7 -// int v14; // ecx@7 - //signed __int64 v15; // qtt@7 -// int v16; // eax@7 -// int v17; // edx@7 -// float v18; // edx@7 -// int v19; // eax@7 -// int v20; // edx@7 -// int v21; // ST50_4@8 -// int v22; // ebx@8 -// int v23; // ecx@10 -// int v24; // edi@10 - //double v25; // ST44_8@12 - //double v26; // ST4C_8@12 -// int v27; // edi@12 -// int v28; // ST40_4@12 -// int v29; // ecx@12 - //signed __int64 v30; // qtt@12 -// int v31; // eax@12 -// int v32; // edx@12 -// float v33; // edx@12 - //int v34; // eax@12 -// int v35; // ecx@12 -// int v36; // ST38_4@13 -// int v37; // ST30_4@15 -// int v38; // eax@16 - //signed __int64 v40; // qtt@18 -// int v41; // eax@18 -// int v42; // ecx@18 -// int v43; // eax@18 -// unsigned __int64 v44; // qax@18 - //double v45; // st7@18 - //int v46; // ecx@18 - //float v47; // ST18_4@18 - //unsigned __int64 v48; // qax@18 - int y_int_; // [sp+10h] [bp-40h]@2 -// int a2; // [sp+18h] [bp-38h]@10 - int x_int; // [sp+20h] [bp-30h]@2 - int z_int_; // [sp+24h] [bp-2Ch]@2 -// int z_int_4; // [sp+28h] [bp-28h]@8 - int z; // [sp+3Ch] [bp-14h]@3 -// double a5; // [sp+40h] [bp-10h]@4 -// int a6; // [sp+48h] [bp-8h]@4 - int y; // [sp+4Ch] [bp-4h]@3 - - pParticle = &this->pParticles[uParticleID]; - if (pParticle->type == ParticleType_Invalid) - return 0; - //uParticleID = LODWORD(pParticle->x); - //v56 = *(float *)&uParticleID + 6.7553994e15; - x_int = floorf(pParticle->x + 0.5f); - //uParticleID = LODWORD(pParticle->y); - //y_int_ = *(float *)&uParticleID + 6.7553994e15; - y_int_ = floorf(pParticle->y + 0.5f); - //uParticleID = LODWORD(pParticle->z); - //z_int_ = *(float *)&uParticleID + 6.7553994e15; - z_int_ = floorf(pParticle->z + 0.5f); - /*if ( !pRenderer->pRenderD3D ) - { - if (pGame->pIndoorCameraD3D->sRotationX) - { - if (pParticle->type & ParticleType_Line) - { - //v11 = pParticle->_x + 6.7553994e15; - int _uParticleID = (int)(floorf(pParticle->_x + 0.5f) - pBLVRenderParams->vPartyPos.x) << 16; - //v12 = pParticle->_y + 6.7553994e15; - y = (int)(floorf(pParticle->_y + 0.5f) - pBLVRenderParams->vPartyPos.y) << 16; - z = (unsigned __int64)(y * (signed __int64)pGame->pIndoorCameraD3D->int_sine_y) >> 16; - HIDWORD(a5) = ((unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16) - - z; - a6 = (unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_sine_y) >> 16; - //v13 = pParticle->_z + 6.7553994e15; - _uParticleID = (int)(floorf(pParticle->_z + 0.5f) - pBLVRenderParams->vPartyPos.z) << 16; - z = ((unsigned __int64)(SHIDWORD(a5) * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_x) >> 16) - - ((unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_sine_x) >> 16); - v14 = z; - HIDWORD(v13) = (unsigned __int64)(SHIDWORD(a5) * (signed __int64)pGame->pIndoorCameraD3D->int_sine_x) >> 16; - HIDWORD(a5) = (unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_x) >> 16; - //LODWORD(v15) = pBLVRenderParams->field_40 << 16; - //HIDWORD(v15) = pBLVRenderParams->field_40 >> 16; - //v16 = v15 / z; - v16 = fixpoint_div(pBLVRenderParams->field_40, z); - v17 = (unsigned __int64)(y * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16; - pParticle->_screenspace_scale = v16; - _uParticleID = (unsigned __int64)(v16 * (signed __int64)(a6 + v17)) >> 16; - LODWORD(v18) = pBLVRenderParams->uViewportCenterX - - ((signed int)((unsigned __int64)(v16 * (signed __int64)(a6 + v17)) >> 16) >> 16); - v19 = pParticle->_screenspace_scale; - pParticle->uScreenSpaceZ = v18; - _uParticleID = (unsigned __int64)(v19 * (signed __int64)(HIDWORD(v13) + HIDWORD(a5))) >> 16; - v20 = pBLVRenderParams->uViewportCenterY - - ((signed int)((unsigned __int64)(v19 * (signed __int64)(HIDWORD(v13) + HIDWORD(a5))) >> 16) >> 16); - pParticle->sZValue2 = v14; - pParticle->uScreenSpaceW = v20; - } - int _uParticleID = (x_int - pBLVRenderParams->vPartyPos.x) << 16; - y = (y_int_ - pBLVRenderParams->vPartyPos.y) << 16; - HIDWORD(a5) = ((unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16) - - ((unsigned __int64)(y * (signed __int64)pGame->pIndoorCameraD3D->int_sine_y) >> 16); - a6 = (unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_sine_y) >> 16; - z_int_4 = (unsigned __int64)(y * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16; - _uParticleID = (z_int_ - pBLVRenderParams->vPartyPos.z) << 16; - v21 = (unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_sine_x) >> 16; - v22 = ((unsigned __int64)(SHIDWORD(a5) * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_x) >> 16) - v21; - z = ((unsigned __int64)(SHIDWORD(a5) * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_x) >> 16) - v21; - if ( v22 < (signed int)0x40000u || v22 > (signed int)0x1F400000u ) - return 0; - v23 = a6 + z_int_4; - a2 = a6 + z_int_4; - v24 = ((unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_x) >> 16) - + ((unsigned __int64)(SHIDWORD(a5) * (signed __int64)pGame->pIndoorCameraD3D->int_sine_x) >> 16); - } - else - { - if (pParticle->type & ParticleType_Line) - { - //v25 = pParticle->_x + 6.7553994e15; - int _uParticleID = ((int)floorf(pParticle->_x + 0.5f) - pBLVRenderParams->vPartyPos.x) << 16; - //v26 = pParticle->_y + 6.7553994e15; - y = ((int)floorf(pParticle->_y + 0.5f) - pBLVRenderParams->vPartyPos.y) << 16; - auto _hiword_v25 = (__int64)(y * (signed __int64)pGame->pIndoorCameraD3D->int_sine_y) >> 16; - v27 = ((unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16) - _hiword_v25; - z = ((unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16) - _hiword_v25; - v28 = (unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_sine_y) >> 16; - //a5 = pParticle->_z + 6.7553994e15; - v29 = ((int)floorf(pParticle->_z + 0.5f) - pBLVRenderParams->vPartyPos.z) << 16; - //LODWORD(v30) = pBLVRenderParams->field_40 << 16; - //HIDWORD(v30) = pBLVRenderParams->field_40 >> 16; - //v31 = v30 / z; - v31 = fixpoint_div(pBLVRenderParams->field_40, z); - v32 = (unsigned __int64)(y * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16; - pParticle->_screenspace_scale = v31; - _uParticleID = (unsigned __int64)(v31 * (signed __int64)(v28 + v32)) >> 16; - LODWORD(v33) = pBLVRenderParams->uViewportCenterX - ((signed int)((unsigned __int64)(v31 * (signed __int64)(v28 + v32)) >> 16) >> 16); - //v34 = pParticle->_screenspace_scale; - pParticle->uScreenSpaceZ = v33; - v35 = pBLVRenderParams->uViewportCenterY - ((signed int)((unsigned __int64)(pParticle->_screenspace_scale * (signed __int64)v29) >> 16) >> 16); - pParticle->sZValue2 = v27; - pParticle->uScreenSpaceW = v35; - } - int _uParticleID = (x_int - pBLVRenderParams->vPartyPos.x) << 16; - y = (y_int_ - pBLVRenderParams->vPartyPos.y) << 16; - v36 = (unsigned __int64)(y * (signed __int64)pGame->pIndoorCameraD3D->int_sine_y) >> 16; - v22 = ((unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16) - v36; - z = ((unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16) - v36; - if ( v22 < 262144 || v22 > 524288000 ) - return 0; - v37 = (unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_sine_y) >> 16; - _uParticleID = (unsigned __int64)(y * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16; - v23 = v37 + ((unsigned __int64)(y * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16); - a2 = v37 + ((unsigned __int64)(y * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16); - v24 = (z_int_ - pBLVRenderParams->vPartyPos.z) << 16; - } - int _uParticleID = abs(v23); - v38 = abs(v22); - if ( v38 >= (signed int)_uParticleID ) - { - //LODWORD(v40) = pBLVRenderParams->field_40 << 16; - //HIDWORD(v40) = pBLVRenderParams->field_40 >> 16; - v41 = fixpoint_div(pBLVRenderParams->field_40, z); - pParticle->_screenspace_scale = v41; - _uParticleID = (unsigned __int64)(v41 * (signed __int64)a2) >> 16; - v42 = pBLVRenderParams->uViewportCenterX - ((signed int)((unsigned __int64)(v41 * (signed __int64)a2) >> 16) >> 16); - v43 = pParticle->_screenspace_scale; - pParticle->uScreenSpaceX = v42; - v44 = v43 * (signed __int64)v24; - //uParticleID = v44 >> 16; - LODWORD(v44) = (signed int)(v44 >> 16) >> 16; - pParticle->uScreenSpaceY = pBLVRenderParams->uViewportCenterY - v44; - pParticle->_screenspace_scale = fixpoint_mul(fixpoint_from_float(pParticle->flt_28), pParticle->_screenspace_scale); - pParticle->sZValue = z; - return true; - } - return false; - }*/ - - int x; - if ( !pGame->pIndoorCameraD3D->ApplyViewTransform_TrueIfStillVisible_BLV( - x_int, - y_int_, - z_int_, - &x, - &y, - &z, - 1) ) - return false; - pGame->pIndoorCameraD3D->Project(x, y, z, &pParticle->uScreenSpaceX, &pParticle->uScreenSpaceY); - pParticle->flt_5C = pGame->pIndoorCameraD3D->fov_x; - //v4 = pParticle->flt_5C; - pParticle->flt_60 = pGame->pIndoorCameraD3D->fov_y; - //v5 = v4 + 6.7553994e15; - LODWORD(v6) = 0; - HIDWORD(v6) = floorf(pParticle->flt_5C + 0.5f); - //v7 = pParticle->flt_28; - //pParticle->_screenspace_scale = v6 / x; - //v8 = v7; - pParticle->_screenspace_scale = fixpoint_mul(fixpoint_from_float(pParticle->flt_28), v6 / x); - pParticle->sZValue = x; - return true; -} - - - - -//----- (0048B5B3) -------------------------------------------------------- -bool ParticleEngine::ViewProject_TrueIfStillVisible_ODM(unsigned int uID) -{ - int v3; // ebx@1 - int v4; // edi@1 - int v5; // ecx@1 - int v11; // ST44_4@4 - signed __int64 v13; // qtt@4 - int v16; // edi@6 - int v17; // eax@6 - signed __int64 v22; // qtt@8 - int v26; // edx@9 - int v28; // ebx@12 - signed __int64 v29; // qtt@13 - int v40; // [sp+14h] [bp-3Ch]@12 - int v44; // [sp+2Ch] [bp-24h]@1 - int v45; // [sp+40h] [bp-10h]@5 - int X_4; // [sp+48h] [bp-8h]@5 - - v3 = stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationX); - v44 = stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationX); - v4 = stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationY); - v5 = stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationY); - - if (pParticles[uID].type == ParticleType_Invalid) - return false; - - if ( v3 ) - { - if (pParticles[uID].type & ParticleType_Line) - { - v11 = fixpoint_sub_unknown(pParticles[uID].x - pGame->pIndoorCameraD3D->vPartyPos.x, v4) - + fixpoint_sub_unknown(pParticles[uID].y - pGame->pIndoorCameraD3D->vPartyPos.y, v5); - long long _hidword_v12 = fixpoint_mul(v11, v3) + fixpoint_sub_unknown(pParticles[uID].z - pGame->pIndoorCameraD3D->vPartyPos.z, v44); - LODWORD(v13) = 0; - HIDWORD(v13) = SLOWORD(pODMRenderParams->int_fov_rad); - pParticles[uID]._screenspace_scale = v13 / _hidword_v12; - pParticles[uID].uScreenSpaceX = pViewport->uScreenCenterX - - ((signed int)fixpoint_mul(pParticles[uID]._screenspace_scale, (fixpoint_sub_unknown(pParticles[uID].y - - pGame->pIndoorCameraD3D->vPartyPos.y, v4) - - fixpoint_sub_unknown(pParticles[uID].x - pGame->pIndoorCameraD3D->vPartyPos.x, v5))) >> 16); - pParticles[uID].uScreenSpaceY = pViewport->uScreenCenterY - - ((signed int)fixpoint_mul(pParticles[uID]._screenspace_scale, (fixpoint_sub_unknown(pParticles[uID].z - - pGame->pIndoorCameraD3D->vPartyPos.z, v3) - - fixpoint_mul(v11, v44))) >> 16); - pParticles[uID].sZValue = _hidword_v12; - } - v45 = fixpoint_sub_unknown(pParticles[uID].x - pGame->pIndoorCameraD3D->vPartyPos.x, v4) + fixpoint_sub_unknown(pParticles[uID].y - - pGame->pIndoorCameraD3D->vPartyPos.y, v5); - X_4 = fixpoint_sub_unknown(pParticles[uID].z - pGame->pIndoorCameraD3D->vPartyPos.z, v44) + fixpoint_mul(v45, v3); - if ( X_4 < 0x40000 ) - return 0; - v16 = fixpoint_sub_unknown(pParticles[uID].y - pGame->pIndoorCameraD3D->vPartyPos.y, v4) - - fixpoint_sub_unknown(pParticles[uID].x - pGame->pIndoorCameraD3D->vPartyPos.x, v5); - v17 = fixpoint_sub_unknown(pParticles[uID].z - pGame->pIndoorCameraD3D->vPartyPos.z, v3) - fixpoint_mul(v45, v44); - } - else - { - if (pParticles[uID].type & ParticleType_Line) - { - LODWORD(v22) = 0; - HIDWORD(v22) = SLOWORD(pODMRenderParams->int_fov_rad); - long long _var_123 = fixpoint_sub_unknown(pParticles[uID].x - pGame->pIndoorCameraD3D->vPartyPos.x, v4) - + fixpoint_sub_unknown(pParticles[uID].y - pGame->pIndoorCameraD3D->vPartyPos.y, v5); - pParticles[uID]._screenspace_scale = v22 / _var_123; - pParticles[uID].uScreenSpaceX = pViewport->uScreenCenterX - - ((signed int)fixpoint_mul(pParticles[uID]._screenspace_scale, (fixpoint_sub_unknown(pParticles[uID].y - - pGame->pIndoorCameraD3D->vPartyPos.y, v4) - - fixpoint_sub_unknown(pParticles[uID].x - pGame->pIndoorCameraD3D->vPartyPos.x, v5))) >> 16); - pParticles[uID].uScreenSpaceY = pViewport->uScreenCenterY - (fixpoint_sub_unknown(pParticles[uID].z, pParticles[uID]._screenspace_scale) >> 16); - pParticles[uID].sZValue = _var_123; - } - v26 = fixpoint_sub_unknown(pParticles[uID].y - pGame->pIndoorCameraD3D->vPartyPos.y, v5); - X_4 = v26 + fixpoint_sub_unknown(pParticles[uID].x - pGame->pIndoorCameraD3D->vPartyPos.x, v4); - if ( X_4 < 0x40000 || X_4 > (pODMRenderParams->uPickDepth - 1000) << 16 ) - return 0; - v17 = pParticles[uID].z; - v16 = fixpoint_sub_unknown(pParticles[uID].y - pGame->pIndoorCameraD3D->vPartyPos.y, v4) - - fixpoint_sub_unknown(pParticles[uID].x - pGame->pIndoorCameraD3D->vPartyPos.x, v5); - } - v40 = v17; - v28 = abs(v16); - if ( abs(X_4) >= v28 ) - { - LODWORD(v29) = 0; - HIDWORD(v29) = SLOWORD(pODMRenderParams->int_fov_rad); - pParticles[uID]._screenspace_scale = v29 / X_4; - pParticles[uID].uScreenSpaceX = pViewport->uScreenCenterX - ((signed int)fixpoint_mul(pParticles[uID]._screenspace_scale, v16) >> 16); - pParticles[uID].uScreenSpaceY = pViewport->uScreenCenterY - ((signed int)fixpoint_mul(pParticles[uID]._screenspace_scale, v40) >> 16); - pParticles[uID]._screenspace_scale = fixpoint_mul(fixpoint_from_float(pParticles[uID].flt_28), pParticles[uID]._screenspace_scale); - pParticles[uID].sZValue = X_4; - if ( pParticles[uID].uScreenSpaceX >= (signed int)pViewport->uViewportTL_X - && pParticles[uID].uScreenSpaceX < (signed int)pViewport->uViewportBR_X - && pParticles[uID].uScreenSpaceY >= (signed int)pViewport->uViewportTL_Y - && pParticles[uID].uScreenSpaceY < (signed int)pViewport->uViewportBR_Y ) - return true; - } - return false; -} - -//----- (0048BBA6) -------------------------------------------------------- -void ParticleEngine::DrawParticles_BLV() -{ -// int v11; // eax@18 -// int v12; // ecx@20 -// int v13; // edx@20 - //Particle *v14; // eax@28 - RenderBillboardTransform_local0 v15; // [sp+Ch] [bp-58h]@1 - - v15.sParentBillboardID = -1; - - for (uint i = uStartParticle; i < uEndParticle; ++i) - { - Particle* p = &pParticles[i]; - - if (p->type == ParticleType_Invalid) - continue; - - if (!ViewProject_TrueIfStillVisible_BLV(i)) - continue; - - if (p->uScreenSpaceX >= pBLVRenderParams->uViewportX && - p->uScreenSpaceX < pBLVRenderParams->uViewportZ && - p->uScreenSpaceY >= pBLVRenderParams->uViewportY && - p->uScreenSpaceY < pBLVRenderParams->uViewportW) - { - /*if (!pRenderer->pRenderD3D) - { - __debugbreak(); - v11 = 13 * p->_screenspace_scale >> 16; - if ( v11 > 30 ) - v11 = 30; - v12 = p->uScreenSpaceY - v11; - v13 = p->uScreenSpaceX - (v11 >> 1); - if ( v13 + v11 < (signed int)pViewport->uViewportTL_X - || v13 >= (signed int)pViewport->uViewportBR_X - || v12 + v11 < (signed int)pViewport->uViewportTL_Y - || v12 >= (signed int)pViewport->uViewportBR_Y ) - { - ; - } - else - { - pRenderer->MakeParticleBillboardAndPush_BLV_Software(v13, v12, p->sZValue, p->uLightColor_bgr, v11); - } - } - else*/ - - if (p->type & ParticleType_Diffuse) - { - //v14 = &pParticles[i]; - v15._screenspace_x_scaler_packedfloat = p->_screenspace_scale / 4; - v15._screenspace_y_scaler_packedfloat = p->_screenspace_scale / 4; - v15.uScreenSpaceX = p->uScreenSpaceX; - v15.uScreenSpaceY = p->uScreenSpaceY; - v15.sZValue = p->sZValue; - pRenderer->MakeParticleBillboardAndPush_BLV(&v15, 0, p->uLightColor_bgr, p->angle); - return; - } - if (p->type & ParticleType_Line) - { - if (pLines.uNumLines < 100) - { - pLines.pLineVertices[2 * pLines.uNumLines].pos.x = p->uScreenSpaceX; - pLines.pLineVertices[2 * pLines.uNumLines].pos.y = p->uScreenSpaceY; - pLines.pLineVertices[2 * pLines.uNumLines].pos.z = 1.0 - 1.0 / ((short)p->sZValue * 0.061758894); - pLines.pLineVertices[2 * pLines.uNumLines].rhw = 1.0; - pLines.pLineVertices[2 * pLines.uNumLines].diffuse = p->uLightColor_bgr; - pLines.pLineVertices[2 * pLines.uNumLines].specular = 0; - pLines.pLineVertices[2 * pLines.uNumLines].texcoord.x = 0.0; - pLines.pLineVertices[2 * pLines.uNumLines].texcoord.y = 0.0; - - pLines.pLineVertices[2 * pLines.uNumLines + 1].pos.x = p->uScreenSpaceZ; - pLines.pLineVertices[2 * pLines.uNumLines + 1].pos.y = p->uScreenSpaceW; - pLines.pLineVertices[2 * pLines.uNumLines + 1].pos.z = 1.0 - 1.0 / ((short)p->sZValue2 * 0.061758894); - pLines.pLineVertices[2 * pLines.uNumLines + 1].rhw = 1.0; - pLines.pLineVertices[2 * pLines.uNumLines + 1].diffuse = p->uLightColor_bgr; - pLines.pLineVertices[2 * pLines.uNumLines + 1].specular = 0; - pLines.pLineVertices[2 * pLines.uNumLines + 1].texcoord.x = 0.0; - pLines.pLineVertices[2 * pLines.uNumLines++ + 1].texcoord.y = 0.0; - } - } - if (p->type & ParticleType_Bitmap) - { - v15._screenspace_x_scaler_packedfloat = p->_screenspace_scale; - v15._screenspace_y_scaler_packedfloat = p->_screenspace_scale; - v15.uScreenSpaceX = p->uScreenSpaceX; - v15.uScreenSpaceY = p->uScreenSpaceY; - v15.sZValue = p->sZValue; - pRenderer->MakeParticleBillboardAndPush_BLV(&v15, pBitmaps_LOD->pHardwareTextures[p->uTextureID], p->uLightColor_bgr, p->angle); - } - if (p->type & ParticleType_Sprite) - { - v15._screenspace_x_scaler_packedfloat = p->_screenspace_scale; - v15._screenspace_y_scaler_packedfloat = p->_screenspace_scale; - v15.uScreenSpaceX = p->uScreenSpaceX; - v15.uScreenSpaceY = p->uScreenSpaceY; - v15.sZValue = p->sZValue; - pRenderer->MakeParticleBillboardAndPush_BLV(&v15, pSprites_LOD->pHardwareSprites[p->uTextureID].pTexture, p->uLightColor_bgr, p->angle); - } - } - } -} - -//----- (0048BEEF) -------------------------------------------------------- -void ParticleEngine::DrawParticles_ODM() -{ - ParticleEngine *pParticleEngine; // esi@1 - //int pParticleNum; // eax@1 -// unsigned __int8 v3; // zf@1 -// char v4; // sf@1 -// unsigned __int8 v5; // of@1 - //char *v7; // edi@2 - //int v8; // eax@6 - //signed int pNumLines; // eax@8 -// int v10; // eax@14 -// int v11; // ecx@16 -// int v12; // edx@16 - //Particle *pParticle; // eax@24 - RenderBillboardTransform_local0 pBillboard; // [sp+Ch] [bp-58h]@1 - //int v15; // [sp+5Ch] [bp-8h]@9 -// int v16; // [sp+60h] [bp-4h]@1 - - pBillboard.sParentBillboardID = -1; - pParticleEngine = this; - //v2 = this->uStartParticle; - //v5 = v2 > this->uEndParticle;// v5 = __OFSUB__(v2, this->uEndParticle); - //v3 = v2 == this->uEndParticle; - //v4 = v2 - this->uEndParticle < 0; - //v16 = this->uStartParticle; - for (uint i = uStartParticle; i <= uEndParticle; ++i) - { - Particle* particle = &pParticles[i]; - if (particle->type == ParticleType_Invalid || !ViewProject_TrueIfStillVisible_ODM(i)) - continue; - - /*if ( !pRenderer->pRenderD3D ) - { - __debugbreak(); - v10 = 13 * particle->_screenspace_scale >> 16; - if ( v10 > 30 ) - v10 = 30; - v11 = particle->uScreenSpaceX - (v10 >> 1); - v12 = particle->uScreenSpaceY - v10; - if ( v11 + v10 < pViewport->uViewportTL_X - || v11 >= pViewport->uViewportBR_X - || particle->uScreenSpaceY < pViewport->uViewportTL_Y - || v12 >= (signed int)pViewport->uViewportBR_Y ) - { - ; - } - else - { - pRenderer->MakeParticleBillboardAndPush_BLV_Software(v11, v12, particle->sZValue, particle->uLightColor_bgr, v10); - } - } - else*/ - - //v8 = *(_DWORD *)(v7 - 82); - if (particle->type & ParticleType_Diffuse) - { - pBillboard._screenspace_x_scaler_packedfloat = particle->_screenspace_scale / 4; - pBillboard._screenspace_y_scaler_packedfloat = particle->_screenspace_scale / 4; - pBillboard.uScreenSpaceX = particle->uScreenSpaceX; - pBillboard.uScreenSpaceY = particle->uScreenSpaceY; - pBillboard.sZValue = particle->sZValue; - pRenderer->MakeParticleBillboardAndPush_ODM(&pBillboard, 0, particle->uLightColor_bgr, particle->angle); - return; - } - if (particle->type & ParticleType_Line) - { - if (pLines.uNumLines < 100) - { - pLines.pLineVertices[2 * pLines.uNumLines].pos.x = particle->uScreenSpaceX; - pLines.pLineVertices[2 * pLines.uNumLines].pos.y = particle->uScreenSpaceY; - pLines.pLineVertices[2 * pLines.uNumLines].pos.z = 1.0 - 1.0 / ((double)particle->zbuffer_depth * 1000.0 / (double)pODMRenderParams->shading_dist_mist); - pLines.pLineVertices[2 * pLines.uNumLines].rhw = 1.0; - pLines.pLineVertices[2 * pLines.uNumLines].diffuse = particle->uLightColor_bgr; - pLines.pLineVertices[2 * pLines.uNumLines].specular = 0; - pLines.pLineVertices[2 * pLines.uNumLines].texcoord.x = 0.0; - pLines.pLineVertices[2 * pLines.uNumLines].texcoord.y = 0.0; - - pLines.pLineVertices[2 * pLines.uNumLines + 1].pos.x = particle->uScreenSpaceZ; - pLines.pLineVertices[2 * pLines.uNumLines + 1].pos.y = particle->uScreenSpaceW; - pLines.pLineVertices[2 * pLines.uNumLines + 1].pos.z = 1.0 - 1.0 / ((double)particle->zbuffer_depth * 1000.0 / (double)pODMRenderParams->shading_dist_mist); - pLines.pLineVertices[2 * pLines.uNumLines + 1].rhw = 1.0; - pLines.pLineVertices[2 * pLines.uNumLines + 1].diffuse = particle->uLightColor_bgr; - pLines.pLineVertices[2 * pLines.uNumLines + 1].specular = 0; - pLines.pLineVertices[2 * pLines.uNumLines + 1].texcoord.x = 0.0; - pLines.pLineVertices[2 * pLines.uNumLines + 1].texcoord.y = 0.0; - pLines.uNumLines++; - } - } - if (particle->type & ParticleType_Bitmap) - { - pBillboard._screenspace_x_scaler_packedfloat = particle->_screenspace_scale; - pBillboard._screenspace_y_scaler_packedfloat = particle->_screenspace_scale; - pBillboard.uScreenSpaceX = particle->uScreenSpaceX; - pBillboard.uScreenSpaceY = particle->uScreenSpaceY; - pBillboard.sZValue = particle->sZValue; - pRenderer->MakeParticleBillboardAndPush_ODM(&pBillboard, pBitmaps_LOD->pHardwareTextures[particle->uTextureID], particle->uLightColor_bgr, particle->angle); - } - if (particle->type & ParticleType_Sprite) - { - pBillboard._screenspace_x_scaler_packedfloat = particle->_screenspace_scale; - pBillboard._screenspace_y_scaler_packedfloat = particle->_screenspace_scale; - pBillboard.uScreenSpaceX = particle->uScreenSpaceX; - pBillboard.uScreenSpaceY = particle->uScreenSpaceY; - pBillboard.sZValue = particle->sZValue; - pRenderer->MakeParticleBillboardAndPush_ODM(&pBillboard, pSprites_LOD->pHardwareSprites[particle->uTextureID].pTexture, particle->uLightColor_bgr, particle->angle); - } - } -} \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 ParticleEngine.h --- a/ParticleEngine.h Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,199 +0,0 @@ -#pragma once -#include "Render.h" - - - -enum ParticleType: unsigned __int32 -{ - ParticleType_Invalid = 0, - ParticleType_1 = 0x0001, - ParticleType_Rotating = 0x0004, - ParticleType_8 = 0x0008, - ParticleType_Diffuse = 0x0100, // colored plane - ParticleType_Line = 0x0200, // line - ParticleType_Bitmap = 0x0400, // textured planed - ParticleType_Sprite = 0x0800 -}; - -/* 305 */ -#pragma pack(push, 1) -struct Particle_sw -{ - unsigned int type; - float x; - float y; - float z; - float r; - float g; - float b; - unsigned int uDiffuse; - int timeToLive; - unsigned int uTextureID; - float flt_28; - int field_2C; - int field_30; - int field_34; - int field_38[12]; -}; -#pragma pack(pop) - - - -/* 109 */ -#pragma pack(push, 1) -struct Particle -{ - unsigned int type; - float x; - float y; - float z; - float flt_10; - float flt_14; - float flt_18; - union - { - struct - { - unsigned char r, g, b, a; - }; - unsigned int uParticleColor; - }; - int timeToLive; - unsigned int uTextureID; - float flt_28; - float _x; - float _y; - float _z; - int rotation_speed; - int angle; - int uScreenSpaceX; - int uScreenSpaceY; - int uScreenSpaceZ; // line end x - int uScreenSpaceW; // line end y - union - { - int sZValue; - struct - { - unsigned short object_pid; - short zbuffer_depth; - }; - }; - int sZValue2; // line end z - int _screenspace_scale; - float flt_5C; - float flt_60; - int uLightColor_bgr; -}; -#pragma pack(pop) - - - -/* 111 */ -#pragma pack(push, 1) -struct stru2_LineList -{ - unsigned int uNumLines; - RenderVertexD3D3 pLineVertices[48]; - char field_604[60]; -}; -#pragma pack(pop) - - - - - -/* 110 */ -#pragma pack(push, 1) -class ParticleEngine -{ -public: - ParticleEngine(); - - void ResetParticles(); - void AddParticle(Particle_sw *a2); - void Draw(); - void UpdateParticles(); - bool ViewProject_TrueIfStillVisible_BLV(unsigned int uParticleID); - bool ViewProject_TrueIfStillVisible_ODM(unsigned int uID); - void DrawParticles_BLV(); - void DrawParticles_ODM(); - - Particle pParticles[500]; - stru2_LineList pLines; - char field_D160[4800]; - float field_E420; - int uStartParticle; - int uEndParticle; - int uTimeElapsed; -}; -#pragma pack(pop) - - - - - - - - - - - -/* 160 */ -#pragma pack(push, 1) -struct TrailParticle // stru167 -{ - inline TrailParticle() - { - x = 0; - y = 0; - z = 0; - time_left = 0; - time_to_live = 0; - bgr16 = 0; - } - - char field_0; - char field_1; - char field_2; - char field_3; - char field_4; - char field_5; - __int16 x; - __int16 y; - __int16 z; - __int16 time_left; - __int16 time_to_live; - char field_10; - char field_11; - char field_12; - char field_13; - __int16 bgr16; - char field_16; - char field_17; -}; -#pragma pack(pop) - - -/* 363 */ -#pragma pack(push, 1) -struct TrailParticleGenerator // stru167_wrap -{ - public: - inline TrailParticleGenerator() - { - num_particles = 0; - } - - void GenerateTrailParticles(int x, int y, int z, int bgr16); - void UpdateParticles(); - - protected: - void AddParticle(int x, int y, int z, int bgr16); - - TrailParticle particles[100]; - int num_particles; - int field_964; -}; -#pragma pack(pop) -extern TrailParticleGenerator trail_particle_generator; // 005118E8 \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Party.cpp --- a/Party.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/Party.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -12,13 +12,13 @@ #include "Mouse.h" #include "PlayerFrameTable.h" #include "TurnEngine.h" -#include "Viewport.h" +#include "Engine/Graphics/Viewport.h" #include "Actor.h" #include "GUIWindow.h" #include "texts.h" #include "MM7.h" -#include "Outdoor.h" +#include "Engine/Graphics/Outdoor.h" #include "LOD.h" #include "SpriteObject.h" #include "ObjectList.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Player.cpp --- a/Player.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/Player.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -13,14 +13,14 @@ #include "Party.h" #include "LOD.h" #include "GUIWindow.h" -#include "Viewport.h" +#include "Engine/Graphics/Viewport.h" #include "Actor.h" #include "Game.h" #include "Mouse.h" #include "TurnEngine.h" #include "Events.h" #include "Events2D.h" -#include "Outdoor.h" +#include "Engine/Graphics/Outdoor.h" #include "StorylineTextTable.h" #include "Autonotes.h" #include "Awards.h" @@ -31,7 +31,7 @@ #include "ObjectList.h" #include "MM7.h" #include "SpriteObject.h" -#include "DecalBuilder.h" +#include "Engine/Graphics/DecalBuilder.h" #include "CastSpellInfo.h" #include "OurMath.h" #include "UI\UIPartyCreation.h" @@ -2750,6 +2750,7 @@ int v7; // esi@20 int racialBonus = 0; __int16* resStat; + int result; switch (a2) { @@ -2788,7 +2789,13 @@ Error("Unknown attribute"); } v7 = GetItemsBonus(a2) + racialBonus; - return v7 + *resStat; + result = v7 + *resStat; + if ( classType == PLAYER_CLASS_LICH ) + { + if ( result > 200 ) + result = 200; + } + return result; } //----- (0048E7D0) -------------------------------------------------------- @@ -2835,6 +2842,11 @@ } baseRes = GetBaseResistance(a2); result = v10 + GetMagicalBonus(a2) + baseRes + *(resStat); + if ( classType == PLAYER_CLASS_LICH ) + { + if ( result > 200 ) + result = 200; + } return result; } diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Render.cpp --- a/Render.cpp Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,11264 +0,0 @@ -#define _CRTDBG_MAP_ALLOC -#include -#include - -#define _CRT_SECURE_NO_WARNINGS - -#include "ZlibWrapper.h" -#include "ErrorHandling.h" - -#include "Render.h" -#include "MediaPlayer.h" -#include "Sprites.h" -#include "Mouse.h" -#include "GammaControl.h" -#include "stru6.h" -#include "GUIWindow.h" -#include "DecalBuilder.h" -#include "ParticleEngine.h" -#include "Outdoor.h" -#include "Party.h" -#include "LOD.h" -#include "Viewport.h" -#include "OurMath.h" -#include "PaletteManager.h" -#include "Timer.h" -#include "Game.h" -#include "LightmapBuilder.h" -#include "ObjectList.h" -#include "SpriteObject.h" -#include "DecorationList.h" -#include "Actor.h" -#include "Log.h" -#include "MM7.h" -#include "Lights.h" -#include "Level/Decoration.h" -#include "Vis.h" -#include "Registry.h" -#include "Weather.h" -#include "MMT.h" - - -//#pragma comment(lib, "lib\\legacy_dx\\lib\\ddraw.lib") -//#pragma comment(lib, "lib\\legacy_dx\\lib\\dxguid.lib") - -struct IDirectDrawClipper *pDDrawClipper; -struct IRender *pRenderer; // idb -struct RenderVertexD3D3 pVertices[50]; -int uNumDecorationsDrawnThisFrame; // weak -RenderBillboard pBillboardRenderList[500]; -unsigned int uNumBillboardsToDraw; -int uNumSpritesDrawnThisFrame; // weak - -RenderVertexSoft array_507D30[50]; -RenderVertexSoft array_50AC10[50]; -RenderVertexSoft array_73D150[20]; - -RenderVertexD3D3 d3d_vertex_buffer[50]; - -/* 384 */ -#pragma pack(push, 1) -struct PCXHeader_1 -{ - char manufacturer; - char version; - char encoding; - char bpp; - __int16 left; - __int16 up; - __int16 right; - __int16 bottom; - __int16 hdpi; - __int16 vdpi; -}; -#pragma pack(pop) - -/* 385 */ -#pragma pack(push, 1) -struct PCXHeader_2 -{ - char reserved; - char planes; - __int16 pitch; - __int16 palette_info; -}; -#pragma pack(pop) - -HRESULT __stdcall D3DZBufferFormatEnumerator(DDPIXELFORMAT *Src, DDPIXELFORMAT *Dst); -HRESULT __stdcall DDrawDisplayModesEnumerator(DDSURFACEDESC2 *pSurfaceDesc, __int16 *a2); -HRESULT __stdcall D3DDeviceEnumerator(const GUID *lpGUID, const char *lpDeviceDesc, const char *lpDeviceName, D3DDEVICEDESC *pHWDesc, D3DDEVICEDESC *pSWDesc, struct RenderD3D_aux *a6); -signed int __stdcall RenderD3D__DeviceEnumerator(GUID *lpGUID, const char *lpDevDesc, const char *lpDriverName, RenderD3D__DevInfo *pOut); // idb - -//----- (0049E79F) -------------------------------------------------------- -bool Render::CheckTextureStages() -{ - bool v0; // edi@1 - IDirectDrawSurface4 *pSurface2; // [sp+Ch] [bp-14h]@1 - IDirectDrawSurface4 *pSurface1; // [sp+10h] [bp-10h]@1 - DWORD v4; // [sp+14h] [bp-Ch]@1 - IDirect3DTexture2 *pTexture2; // [sp+18h] [bp-8h]@1 - IDirect3DTexture2 *pTexture1; // [sp+1Ch] [bp-4h]@1 - - v0 = false; - pRenderD3D->CreateTexture(64, 64, &pSurface1, &pTexture1, true, false, 32); - pRenderD3D->CreateTexture(64, 64, &pSurface2, &pTexture2, true, false, 32); - - ErrD3D(pRenderD3D->pDevice->SetTexture(0, pTexture1)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLOROP, 2)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, 2)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, 2)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MINFILTER, 2)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, 1)); - - ErrD3D(pRenderD3D->pDevice->SetTexture(0, pTexture2)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_COLOROP, 7)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_COLORARG1, 2)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_COLORARG2, 1)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_MAGFILTER, 2)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_MINFILTER, 2)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_MIPFILTER, 1)); - - if ( !pRenderD3D->pDevice->ValidateDevice(&v4) && v4 == 1 ) - v0 = true; - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_COLOROP, 1)); - pTexture1->Release(); - pTexture2->Release(); - pSurface1->Release(); - pSurface2->Release(); - return v0; -} - - -//----- (00440CB8) -------------------------------------------------------- -void Render::DrawBillboardList_BLV() -{ - RenderBillboardTransform_local0 soft_billboard; // [sp+4h] [bp-50h]@1 - - soft_billboard.sParentBillboardID = -1; - soft_billboard.pTarget = pBLVRenderParams->pRenderTarget; - soft_billboard.pTargetZ = pBLVRenderParams->pTargetZBuffer; - soft_billboard.uTargetPitch = uTargetSurfacePitch; - soft_billboard.uViewportX = pBLVRenderParams->uViewportX; - soft_billboard.uViewportY = pBLVRenderParams->uViewportY; - soft_billboard.uViewportZ = pBLVRenderParams->uViewportZ - 1; - soft_billboard.uViewportW = pBLVRenderParams->uViewportW; - - pODMRenderParams->uNumBillboards = ::uNumBillboardsToDraw; - for (uint i = 0; i < ::uNumBillboardsToDraw; ++i) - { - RenderBillboard* p = &pBillboardRenderList[i]; - - soft_billboard.uScreenSpaceX = p->uScreenSpaceX; - soft_billboard.sParentBillboardID = i; - soft_billboard.uScreenSpaceY = p->uScreenSpaceY; - soft_billboard._screenspace_x_scaler_packedfloat = p->_screenspace_x_scaler_packedfloat; - soft_billboard._screenspace_y_scaler_packedfloat = p->_screenspace_y_scaler_packedfloat; - soft_billboard.sZValue = p->sZValue; - soft_billboard.uFlags = p->field_1E; - soft_billboard.sTintColor = p->sTintColor; - if ( p->HwSpriteID != -1 ) - { - if ( pRenderD3D ) - DrawBillboard_Indoor(&soft_billboard, &pSprites_LOD->pHardwareSprites[p->HwSpriteID], p->dimming_level); - else - { - soft_billboard.pPalette = PaletteManager::Get_Dark_or_Red_LUT(p->uPalette, p->dimming_level, 1); - if (p->field_1E & 0x0100) - soft_billboard.pPalette = pPaletteManager->field_261600[p->uPalette]; - if ( !(soft_billboard.uFlags & 0x40) && soft_billboard.uFlags & 0x80 ) - soft_billboard.pPalette2 = PaletteManager::Get_Dark_or_Red_LUT(p->uPalette, 0, 1); - if ( p->HwSpriteID >= 0 ) - pSprites_LOD->pSpriteHeaders[p->HwSpriteID].DrawSprite_sw(&soft_billboard, 1); - } - } - } -} - -//----- (004A16A5) -------------------------------------------------------- -bool Render::AreRenderSurfacesOk() -{ - return pFrontBuffer4 && pBackBuffer4; -} - - -//----- (004A19D8) -------------------------------------------------------- -unsigned int BlendColors(unsigned int a1, unsigned int a2) -{ - /*signed __int64 v2; // ST10_8@1 - double v3; // st7@1 - float v4; // ST24_4@1 - double v5; // ST10_8@1 - int v6; // ST1C_4@1 - float v7; // ST24_4@1 - double v8; // ST10_8@1 - unsigned __int8 v9; // ST20_1@1 - float v10; // ST24_4@1 - double v11; // ST10_8@1 - float v12; // ST24_4@1 - double v13; // ST08_8@1*/ - - uint alpha = (uint)floorf(0.5f + (a1 >> 24) / 255.0f * - (a2 >> 24) / 255.0f * 255.0f), - red = (uint)floorf(0.5f + ((a1 >> 16) & 0xFF) / 255.0f * - ((a2 >> 16) & 0xFF) / 255.0f * 255.0f), - green = (uint)floorf(0.5f + ((a1 >> 8) & 0xFF) / 255.0f * - ((a2 >> 8) & 0xFF) / 255.0f * 255.0f), - blue = (uint)floorf(0.5f + ((a1 >> 0) & 0xFF) / 255.0f * - ((a2 >> 0) & 0xFF) / 255.0f * 255.0f); - return (alpha << 24) | (red << 16) | (green << 8) | blue; - /*v2 = a1 >> 24; - v3 = (double)v2 / 255.0f; - HIDWORD(v2) = 0; - LODWORD(v2) = a2 >> 24; - v4 = v3 * (double)v2 / 255.0f * 255.0; - v5 = v4 + 6.7553994e15; - v6 = LODWORD(v5); - v7 = (double)((a1 >> 16) & 0xFFi64) / 255.0f * (double)((a2 >> 16) & 0xFF) * 0.0039215689 * 255.0; - v8 = v7 + 6.7553994e15; - v9 = LOBYTE(v8); - v10 = (double)((unsigned __int16)a1 >> 8) / 255.0f * (double)((unsigned __int16)a2 >> 8) / 255.0f * 255.0; - v11 = v10 + 6.7553994e15; - v12 = (double)(a1 & 0xFFi64) / 255.0f * (double)(unsigned __int8)a2 / 255.0f * 255.0; - v13 = v12 + 6.7553994e15; - return LOBYTE(v13) | ((LOBYTE(v11) | (((v6 << 8) | v9) << 8)) << 8);*/ -} - - -void Render::RenderTerrainD3D() // New function -{ - int v6; // ecx@8 - struct Polygon *pTilePolygon; // ebx@8 - float Light_tile_dist; - - //warning: the game uses CW culling by default, ccw is incosistent - pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CCW); - - static RenderVertexSoft pTerrainVertices[128 * 128];//vertexCountX and vertexCountZ - - //Генерация местоположения вершин------------------------------------------------------------------------- - //решётка вершин делится на две части от -64 до 0 и от 0 до 64 - // - // -64 X 0 64 - // --------------- 64 - // | | | - // | | | - // | | | - // 0|------+------| Z - // | | | - // | | | - // | | | - // --------------- - // -64 - - int blockScale = 512; - int heightScale = 32; - for (unsigned int z = 0; z < 128; ++z) - { - for (unsigned int x = 0; x < 128; ++x) - { - pTerrainVertices[z * 128 + x].vWorldPosition.x = (-64 + (signed)x) * blockScale; - pTerrainVertices[z * 128 + x].vWorldPosition.y = (64 - (signed)z) * blockScale; - pTerrainVertices[z * 128 + x].vWorldPosition.z = heightScale * pOutdoor->pTerrain.pHeightmap[z * 128 + x]; - pGame->pIndoorCameraD3D->ViewTransform(&pTerrainVertices[z * 128 + x], 1); - pGame->pIndoorCameraD3D->Project(&pTerrainVertices[z * 128 + x], 1, 0); - } - } -//-------(Отсечение невидимой части карты)------------------------------------------------------------------------------------------ - float direction = (float)(pGame->pIndoorCameraD3D->sRotationY / 256);//direction of the camera(напрвление камеры) - //0-East(B) - //1-NorthEast(CB) - //2-North(C) - //3-WestNorth(CЗ) - //4-West(З) - //5-SouthWest(ЮЗ) - //6-South(Ю) - //7-SouthEast(ЮВ) - unsigned int Start_X, End_X, Start_Z, End_Z; - if ( direction >= 0 && direction < 1.0 )//East(B) - NorthEast(CB) - { - Start_X = pODMRenderParams->uMapGridCellX - 2, End_X = 127; - Start_Z = 0, End_Z = 127; - } - else if (direction >= 1.0 && direction < 3.0)//NorthEast(CB) - WestNorth(CЗ) - { - Start_X = 0, End_X = 127; - Start_Z = 0, End_Z = pODMRenderParams->uMapGridCellZ + 1; - } - else if (direction >= 3.0 && direction < 5.0)//WestNorth(CЗ) - SouthWest(ЮЗ) - { - Start_X = 0, End_X = pODMRenderParams->uMapGridCellX + 2; - Start_Z = 0, End_Z = 127; - } - else if ( direction >= 5.0 && direction < 7.0 )//SouthWest(ЮЗ) - //SouthEast(ЮВ) - { - Start_X = 0, End_X = 127; - Start_Z = pODMRenderParams->uMapGridCellZ - 2, End_Z = 127; - } - else//SouthEast(ЮВ) - East(B) - { - Start_X = pODMRenderParams->uMapGridCellX - 2, End_X = 127; - Start_Z = 0, End_Z = 127; - } - for (unsigned int z = Start_Z; z < End_Z; ++z) - { - for (unsigned int x = Start_X; x < End_X; ++x) - { - pTilePolygon = &array_77EC08[pODMRenderParams->uNumPolygons]; - pTilePolygon->flags = 0; - pTilePolygon->field_32 = 0; - pTilePolygon->uTileBitmapID = pOutdoor->DoGetTileTexture(x, z); - pTilePolygon->pTexture = (Texture *)&pBitmaps_LOD->pHardwareTextures[pTilePolygon->uTileBitmapID]; - if (pTilePolygon->uTileBitmapID == 0xFFFF) - continue; - - //pTile->flags = 0x8010 |pOutdoor->GetSomeOtherTileInfo(x, z); - pTilePolygon->flags = pOutdoor->GetSomeOtherTileInfo(x, z); - pTilePolygon->field_32 = 0; - pTilePolygon->field_59 = 1; - pTilePolygon->sTextureDeltaU = 0; - pTilePolygon->sTextureDeltaV = 0; -// x,z x+1,z -// .____________. -// | | -// | | -// | | -// | | -// | | -// .____________. -// x,z+1 x+1,z+1 - memcpy(&array_73D150[0], &pTerrainVertices[z * 128 + x], sizeof(RenderVertexSoft));//x, z - array_73D150[0].u = 0; - array_73D150[0].v = 0; - memcpy(&array_73D150[1], &pTerrainVertices[z * 128 + x + 1], sizeof(RenderVertexSoft));//x + 1, z - array_73D150[1].u = 1; - array_73D150[1].v = 0; - memcpy(&array_73D150[2], &pTerrainVertices[(z + 1) * 128 + x + 1], sizeof(RenderVertexSoft));//x + 1, z + 1 - array_73D150[2].u = 1; - array_73D150[2].v = 1; - memcpy(&array_73D150[3], &pTerrainVertices[(z + 1) * 128 + x], sizeof(RenderVertexSoft));//x, z + 1 - array_73D150[3].u = 0; - array_73D150[3].v = 1; - //v58 = 0; - //if (v58 == 4) // if all y == first y; primitive in xz plane - //pTile->field_32 |= 0x0001; - pTilePolygon->pODMFace = nullptr; - pTilePolygon->uNumVertices = 4; - pTilePolygon->field_59 = 5; - -//shading (затенение)---------------------------------------------------------------------------- - //uint norm_idx = pTerrainNormalIndices[2 * (z * 128 + x) + 1]; - uint norm_idx = pTerrainNormalIndices[2 * (x * 128 + z) + 2]; - assert(norm_idx < uNumTerrainNormals); - - Vec3_float_* norm = &pTerrainNormals[norm_idx]; - float _f = ((norm->x * (float)pOutdoor->vSunlight.x / 65536.0) - - (norm->y * (float)pOutdoor->vSunlight.y / 65536.0) - - (norm->z * (float)pOutdoor->vSunlight.z / 65536.0)); - pTilePolygon->dimming_level = 20.0 - floorf(20.0 * _f + 0.5f); - if ( norm_idx < 0 || norm_idx > uNumTerrainNormals - 1 ) - norm = 0; - else - norm = &pTerrainNormals[norm_idx]; - if (for_refactoring) - { - MessageBoxA(nullptr, "Ritor1: function StackLights_TerrainFace needed refactoring and result - slows", "", 0); - __debugbreak(); - } - //pGame->pLightmapBuilder->StackLights_TerrainFace(norm, &Light_tile_dist, array_50AC10, 4, 1);//Ritor1: slows - //pDecalBuilder->_49BE8A(pTilePolygon, norm, &Light_tile_dist, array_50AC10, 4, 1); - //unsigned int a5 = 4; -//---------------------------------------------------------------------------- - - ++pODMRenderParams->uNumPolygons; - ++pODMRenderParams->field_44; - assert(pODMRenderParams->uNumPolygons < 20000); - - pTilePolygon->uBModelID = 0; - pTilePolygon->uBModelFaceID = 0; - pTilePolygon->field_50 = (8 * (0 | (0 << 6))) | 6; - for (unsigned int k = 0; k < pTilePolygon->uNumVertices; ++k) - { - memcpy(&array_50AC10[k], &array_73D150[k], sizeof(struct RenderVertexSoft)); - array_50AC10[k]._rhw = 1.0 / (array_73D150[k].vWorldViewPosition.x + 0.0000001000000011686097); - } -//---------Draw distance(Дальность отрисовки)------------------------------- - int temp = pODMRenderParams->shading_dist_mist; - if ( draw_terrain_dist_mist ) - pODMRenderParams->shading_dist_mist = 0x5000; - bool neer_clip = array_73D150[0].vWorldViewPosition.x < 8.0 - || array_73D150[1].vWorldViewPosition.x < 8.0 - || array_73D150[2].vWorldViewPosition.x < 8.0 - || array_73D150[3].vWorldViewPosition.x < 8.0; - bool far_clip = (double)pODMRenderParams->shading_dist_mist < array_73D150[0].vWorldViewPosition.x - || (double)pODMRenderParams->shading_dist_mist < array_73D150[1].vWorldViewPosition.x - || (double)pODMRenderParams->shading_dist_mist < array_73D150[2].vWorldViewPosition.x - || (double)pODMRenderParams->shading_dist_mist < array_73D150[3].vWorldViewPosition.x; - - /* int v33 = 0; - static stru154 static_sub_0048034E_stru_154; - pGame->pLightmapBuilder->std__vector_000004_size = 0; - if ( stru_F8AD28.uNumLightsApplied > 0 || pDecalBuilder->uNumDecals > 0 ) - { - if ( neer_clip ) - v33 = 3; - else - v33 = far_clip != 0 ? 5 : 0; - static_sub_0048034E_stru_154.ClassifyPolygon(norm, Light_tile_dist); - if ( pDecalBuilder->uNumDecals > 0 ) - pDecalBuilder->ApplyDecals(31 - pTilePolygon->dimming_level, 4, &static_sub_0048034E_stru_154, a5, array_50AC10, 0, *(float *)&v33, -1); - } - if ( stru_F8AD28.uNumLightsApplied > 0 ) - pGame->pLightmapBuilder->ApplyLights(&stru_F8AD28, &static_sub_0048034E_stru_154, a5, array_50AC10, 0, v33);*/ - - if ( !byte_4D864C || ~pGame->uFlags & 0x80 ) - { - //if ( neer_clip ) //Ritor1: Даёт искажения на подъёме, возможно требуется ф-ция Безье - //{ - // pTilePolygon->uNumVertices = ODM_NearClip(pTilePolygon->uNumVertices); - // ODM_Project(pTilePolygon->uNumVertices); - //} - if ( far_clip ) - { - pTilePolygon->uNumVertices = ODM_FarClip(pTilePolygon->uNumVertices); - ODM_Project(pTilePolygon->uNumVertices); - } - } - pODMRenderParams->shading_dist_mist = temp; - -// check the transparency and texture (tiles) mapping (проверка прозрачности и наложение текстур (тайлов))---------------------- - bool transparent = false; - if ( !( pTilePolygon->flags & 1 ) ) // не поддерживается TextureFrameTable - { - if ( /*pTile->flags & 2 && */pTilePolygon->uTileBitmapID == pRenderer->hd_water_tile_id) - { - //transparent = false; - v6 = pRenderer->pHDWaterBitmapIDs[pRenderer->hd_water_current_frame]; - } - else - { - v6 = pTilePolygon->uTileBitmapID; - if ( !_strnicmp(pBitmaps_LOD->pTextures[pTilePolygon->uTileBitmapID].pName, "wtrdr", 5) ) - transparent = true; - } - - assert(v6 < 1000); // many random crashes here - - // for all shore tiles - draw a tile water under them since they're half-empty - if (!_strnicmp(pBitmaps_LOD->pTextures[pTilePolygon->uTileBitmapID].pName, "wtrdr", 5)) // all shore tile filenames are wtrdrXXX - DrawBorderTiles(pTilePolygon); - - pRenderer->DrawTerrainPolygon(pTilePolygon->uNumVertices, pTilePolygon, pBitmaps_LOD->pHardwareTextures[v6], transparent, true); - } - //else //здесь уже пограничные тайлы воды - //pTile->DrawBorderTiles(); -//-------------------------------------------------------------------------------------------------------------------------------- - - --pODMRenderParams->uNumPolygons; - --pODMRenderParams->field_44; - } - } -} - -//----- (004811A3) -------------------------------------------------------- -void Render::DrawBorderTiles(struct Polygon *poly) -{ - pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false); - DrawTerrainPolygon(poly->uNumVertices, poly, - pBitmaps_LOD->pHardwareTextures[pHDWaterBitmapIDs[hd_water_current_frame]], false, true); - - pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, true); - //DrawTerrainPolygon(poly->uNumVertices, poly, pBitmaps_LOD->pHardwareTextures[poly->uTileBitmapID], true, true); -} - - -//----- (0047BACF) -------------------------------------------------------- -void Render::TransformBillboardsAndSetPalettesODM() -{ - //int v0; // edi@1 - //char *v1; // esi@2 - //unsigned int v2; // edx@3 - //int v3; // eax@3 - //int v4; // edi@3 - //int v5; // eax@3 - //__int16 v6; // di@3 - //int v7; // eax@3 - //int v8; // ebx@4 -// unsigned __int16 *v9; // eax@7 -// char v10; // zf@9 - //DWORD v11; // eax@13 -// int v12; // eax@13 -// int v13; // eax@14 - RenderBillboardTransform_local0 billboard; // [sp+4h] [bp-60h]@1 -// int v15; // [sp+54h] [bp-10h]@13 - //int v16; // [sp+58h] [bp-Ch]@1 - //int v17; // [sp+5Ch] [bp-8h]@2 -// int v18; // [sp+60h] [bp-4h]@13 - - billboard.sParentBillboardID = -1; - billboard.pTarget = pRenderer->pTargetSurface; - billboard.pTargetZ = pRenderer->pActiveZBuffer; - billboard.uTargetPitch = pRenderer->uTargetSurfacePitch; - billboard.uViewportX = pViewport->uViewportTL_X; - billboard.uViewportY = pViewport->uViewportTL_Y; - billboard.uViewportZ = pViewport->uViewportBR_X - 1; - billboard.uViewportW = pViewport->uViewportBR_Y; - pODMRenderParams->uNumBillboards = uNumBillboardsToDraw; - - for (unsigned int i = 0; i < ::uNumBillboardsToDraw; ++i) - { - billboard.uScreenSpaceX = pBillboardRenderList[i].uScreenSpaceX; - billboard.uScreenSpaceY = pBillboardRenderList[i].uScreenSpaceY; - billboard.sParentBillboardID = i; - billboard._screenspace_x_scaler_packedfloat = pBillboardRenderList[i]._screenspace_x_scaler_packedfloat; - billboard.sTintColor = pBillboardRenderList[i].sTintColor; - billboard._screenspace_y_scaler_packedfloat = pBillboardRenderList[i]._screenspace_y_scaler_packedfloat; - billboard.sZValue = pBillboardRenderList[i].sZValue; - billboard.uFlags = pBillboardRenderList[i].field_1E; - if (pBillboardRenderList[i].HwSpriteID != -1) - { - if (!pRenderD3D) __debugbreak(); // no sw rendering - //if (pRenderer->pRenderD3D) - TransformBillboard(&billboard, - &pSprites_LOD->pHardwareSprites[pBillboardRenderList[i].HwSpriteID], - pBillboardRenderList[i].dimming_level, &pBillboardRenderList[i]); - /*else - { - assert(false); - - auto v1 = (char *)&pBillboard->uScreenSpaceY; - if ( *(v1 - 10) & 2 ) - v9 = PaletteManager::Get_Dark_or_Red_LUT(*((short *)v1 - 7), 0, 1); - else - v9 = sr_GetBillboardPalette((RenderBillboard *)(v1 - 40), *((short *)v1 - 7), pBillboard->sZValue, *((short *)v1 + 1)); - v10 = (*(v1 - 9) & 1) == 0; - billboard.pPalette = v9; - if ( !v10 ) - billboard.pPalette = pPaletteManager->field_261600[*((short *)v1 - 7)]; - if ( !(billboard.uFlags & 0x40) && billboard.uFlags & 0x80 ) - { - v12 = stru_5C6E00->Cos(i * 5 + GetTickCount()); - v15 = abs(v12); - v18 = (unsigned __int64)(15i64 * v15) >> 16; - billboard.pPalette2 = PaletteManager::Get_Dark_or_Red_LUT(*((short *)v1 - 7), 15 - v18, 1); - } - v13 = *((short *)v1 - 8); - if ( v13 >= 0 ) - pSprites_LOD->pSpriteHeaders[v13].DrawSprite_sw(&billboard, 1); - }*/ - } - } -} - -//----- (0047AF11) -------------------------------------------------------- -void Render::DrawSpriteObjects_ODM() -{ - SpriteFrame *frame; // eax@10 - unsigned int v6; // eax@10 - int v9; // ecx@10 - int v17; // ecx@25 - int v18; // eax@25 -// int v22; // ST3C_4@29 - signed __int64 v23; // qtt@30 - int v26; // eax@31 -// char v27; // zf@31 - int v30; // [sp+14h] [bp-2Ch]@23 - int v37; // [sp+1Ch] [bp-24h]@23 - int a6; // [sp+20h] [bp-20h]@10 - int v42; // [sp+2Ch] [bp-14h]@23 - int y; // [sp+30h] [bp-10h]@10 - int x; // [sp+34h] [bp-Ch]@10 - int z; // [sp+38h] [bp-8h]@10 - signed __int16 v46; // [sp+3Ch] [bp-4h]@12 - - //v41 = 0; - for (unsigned int i = 0; i < uNumSpriteObjects; ++i) - { - SpriteObject* object = &pSpriteObjects[i]; - //auto v0 = (char *)&pSpriteObjects[i].uSectorID; - //v0 = (char *)&pSpriteObjects[0].uSectorID; - //do - //{ - if (!object->uObjectDescID) // item probably pciked up - continue; - - assert(object->uObjectDescID < pObjectList->uNumObjects); - ObjectDesc* object_desc = &pObjectList->pObjects[object->uObjectDescID]; - if (object_desc->NoSprite()) - continue; - - //v1 = &pObjectList->pObjects[*((short *)v0 - 13)]; - //if ( !(v1->uFlags & 1) ) - //{ - //v2 = *((short *)v0 - 14) - //v2 = object->uType; - if ( (object->uType < 1000 || object->uType >= 10000) && (object->uType < 500 || object->uType >= 600) - || pGame->pStru6Instance->_4A81CA(object) ) - { - //a5 = *(short *)v0; - x = object->vPosition.x; - y = object->vPosition.y; - z = object->vPosition.z; - frame = pSpriteFrameTable->GetFrame(object_desc->uSpriteID, object->uSpriteFrameID); - a6 = frame->uGlowRadius * object->field_22_glow_radius_multiplier; - v6 = stru_5C6E00->Atan2(object->vPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x, object->vPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y); - //LOWORD(v7) = object->uFacing; - //v8 = v36; - v9 = ((signed int)(stru_5C6E00->uIntegerPi + ((signed int)stru_5C6E00->uIntegerPi >> 3) + object->uFacing - v6) >> 8) & 7; - pBillboardRenderList[::uNumBillboardsToDraw].HwSpriteID = frame->pHwSpriteIDs[v9]; - if ( frame->uFlags & 0x20 ) - { - //v8 = v36; - z -= fixpoint_mul(frame->scale, pSprites_LOD->pSpriteHeaders[(signed __int16)frame->pHwSpriteIDs[v9]].uHeight) / 2; - } - v46 = 0; - if ( frame->uFlags & 2 ) - v46 = 2; - //v11 = (int *)(256 << v9); - if ( (256 << v9) & frame->uFlags ) - v46 |= 4; - if ( frame->uFlags & 0x40000 ) - v46 |= 0x40; - if ( frame->uFlags & 0x20000 ) - LOBYTE(v46) = v46 | 0x80; - if ( a6 ) - { - //LOBYTE(v11) = _4E94D3_light_type; - pMobileLightsStack->AddLight(x, y, z, object->uSectorID, a6, 0xFF, 0xFF, 0xFF, _4E94D3_light_type); - } - if (pGame->pIndoorCameraD3D->sRotationX) - { - v30 = fixpoint_mul((x - pGame->pIndoorCameraD3D->vPartyPos.x) << 16, pGame->pIndoorCameraD3D->int_cosine_y) - + fixpoint_mul((y - pGame->pIndoorCameraD3D->vPartyPos.y) << 16, pGame->pIndoorCameraD3D->int_sine_y); - v37 = fixpoint_mul((x - pGame->pIndoorCameraD3D->vPartyPos.x) << 16, pGame->pIndoorCameraD3D->int_sine_y); - v42 = fixpoint_mul((z - pGame->pIndoorCameraD3D->vPartyPos.z) << 16, pGame->pIndoorCameraD3D->int_sine_x) - + fixpoint_mul(v30, pGame->pIndoorCameraD3D->int_cosine_x); - if ( v42 >= 0x40000 && v42 <= pODMRenderParams->shading_dist_mist << 16 ) - { - v17 = fixpoint_mul((y - pGame->pIndoorCameraD3D->vPartyPos.y) << 16, pGame->pIndoorCameraD3D->int_cosine_y) - v37; - v18 = fixpoint_mul((z - pGame->pIndoorCameraD3D->vPartyPos.z) << 16, pGame->pIndoorCameraD3D->int_cosine_x) - - fixpoint_mul(v30, pGame->pIndoorCameraD3D->int_sine_x); - if ( abs(v42) >= abs(v17) ) - { - LODWORD(v23) = 0; - HIDWORD(v23) = SLOWORD(pODMRenderParams->int_fov_rad); - - object->uAttributes |= 1; - pBillboardRenderList[::uNumBillboardsToDraw].uPalette = frame->uPaletteIndex; - pBillboardRenderList[::uNumBillboardsToDraw].uIndoorSectorID = object->uSectorID; - pBillboardRenderList[::uNumBillboardsToDraw]._screenspace_x_scaler_packedfloat = fixpoint_mul(frame->scale, v23 / v42); - pBillboardRenderList[::uNumBillboardsToDraw].pSpriteFrame = frame; - pBillboardRenderList[::uNumBillboardsToDraw]._screenspace_y_scaler_packedfloat = fixpoint_mul(frame->scale, v23 / v42); - pBillboardRenderList[::uNumBillboardsToDraw].field_1E = v46; - pBillboardRenderList[::uNumBillboardsToDraw].world_x = x; - pBillboardRenderList[::uNumBillboardsToDraw].world_y = y; - pBillboardRenderList[::uNumBillboardsToDraw].world_z = z; - pBillboardRenderList[::uNumBillboardsToDraw].uScreenSpaceX = pViewport->uScreenCenterX - ((signed int)(fixpoint_mul(v23 / v42, v17) + 0x8000) >> 16); - pBillboardRenderList[::uNumBillboardsToDraw].uScreenSpaceY = pViewport->uScreenCenterY - (((unsigned int)fixpoint_mul(v23 / v42, v18) + 0x8000) >> 16); - HIWORD(v26) = HIWORD(v42); - LOWORD(v26) = 0; - pBillboardRenderList[::uNumBillboardsToDraw].sZValue = v26 + (PID(OBJECT_Item,i)); - pBillboardRenderList[::uNumBillboardsToDraw].dimming_level = 0; - pBillboardRenderList[::uNumBillboardsToDraw].sTintColor = 0; - if ( !(object->uAttributes & 0x20) ) - { - if ( !pRenderD3D ) - { - __debugbreak(); - pBillboardRenderList[::uNumBillboardsToDraw].sZValue = 0; - } - } - //if (::uNumBillboardsToDraw >= 500) - // return; - assert(::uNumBillboardsToDraw < 500); - ++::uNumBillboardsToDraw; - ++uNumSpritesDrawnThisFrame; - } - } - } - else - { - v42 = fixpoint_mul((y - pGame->pIndoorCameraD3D->vPartyPos.y) << 16, pGame->pIndoorCameraD3D->int_sine_y) - + fixpoint_mul((x - pGame->pIndoorCameraD3D->vPartyPos.x) << 16, pGame->pIndoorCameraD3D->int_cosine_y); - if ( v42 >= 0x40000 && v42 <= pODMRenderParams->shading_dist_mist << 16 ) - { - v17 = fixpoint_mul((y - pGame->pIndoorCameraD3D->vPartyPos.y) << 16, pGame->pIndoorCameraD3D->int_cosine_y) - - fixpoint_mul(((x - pGame->pIndoorCameraD3D->vPartyPos.x) << 16), pGame->pIndoorCameraD3D->int_sine_y); - v18 = (z - pGame->pIndoorCameraD3D->vPartyPos.z) << 16; - if ( abs(v42) >= abs(v17) ) - { - LODWORD(v23) = 0; - HIDWORD(v23) = SLOWORD(pODMRenderParams->int_fov_rad); - - object->uAttributes |= 1; - pBillboardRenderList[::uNumBillboardsToDraw].uPalette = frame->uPaletteIndex; - pBillboardRenderList[::uNumBillboardsToDraw].uIndoorSectorID = object->uSectorID; - pBillboardRenderList[::uNumBillboardsToDraw]._screenspace_x_scaler_packedfloat = fixpoint_mul(frame->scale, v23 / v42); - pBillboardRenderList[::uNumBillboardsToDraw].pSpriteFrame = frame; - pBillboardRenderList[::uNumBillboardsToDraw]._screenspace_y_scaler_packedfloat = fixpoint_mul(frame->scale, v23 / v42); - pBillboardRenderList[::uNumBillboardsToDraw].field_1E = v46; - pBillboardRenderList[::uNumBillboardsToDraw].world_x = x; - pBillboardRenderList[::uNumBillboardsToDraw].world_y = y; - pBillboardRenderList[::uNumBillboardsToDraw].world_z = z; - pBillboardRenderList[::uNumBillboardsToDraw].uScreenSpaceX = pViewport->uScreenCenterX - ((signed int)(fixpoint_mul(v23 / v42, v17) + 0x8000) >> 16); - pBillboardRenderList[::uNumBillboardsToDraw].uScreenSpaceY = pViewport->uScreenCenterY - (((unsigned int)fixpoint_mul(v23 / v42, v18) + 0x8000) >> 16); - HIWORD(v26) = HIWORD(v42); - LOWORD(v26) = 0; - pBillboardRenderList[::uNumBillboardsToDraw].sZValue = v26 + (PID(OBJECT_Item,i)); - pBillboardRenderList[::uNumBillboardsToDraw].dimming_level = 0; - pBillboardRenderList[::uNumBillboardsToDraw].sTintColor = 0; - if ( !(object->uAttributes & 0x20) ) - { - if ( !pRenderD3D ) - { - __debugbreak(); - pBillboardRenderList[::uNumBillboardsToDraw].sZValue = 0; - } - } - //if (::uNumBillboardsToDraw >= 500) - // return; - assert(::uNumBillboardsToDraw < 500); - ++::uNumBillboardsToDraw; - ++uNumSpritesDrawnThisFrame; - } - } - } - } - } -} - -//----- (0049D9BC) -------------------------------------------------------- -signed int __stdcall RenderD3D__DeviceEnumerator(GUID *lpGUID, const char *lpDevDesc, const char *lpDriverName, RenderD3D__DevInfo *pOut) -{ - size_t v4; // eax@1 - size_t v5; // eax@1 - size_t v7; // eax@13 - DDDEVICEIDENTIFIER ddDevId; // [sp+4h] [bp-4F8h]@11 - DDSURFACEDESC2 v10;/*int v10; // [sp+42Ch] [bp-D0h]@16*/ - DDSCAPS2 ddsCaps; // [sp+4A8h] [bp-54h]@14 - unsigned int uFreeVideoMem; // [sp+4B8h] [bp-44h]@14 - RenderD3D_aux aux; // [sp+4BCh] [bp-40h]@19 - IDirect3D3 *pDirect3D3; // [sp+4C4h] [bp-38h]@18 - int is_there_a_compatible_screen_mode; // [sp+4C8h] [bp-34h]@16 - RenderD3D_D3DDevDesc v20; // [sp+4CCh] [bp-30h]@1 - LPDIRECTDRAW pDirectDraw = nullptr; // [sp+4F4h] [bp-8h]@4 - IDirectDraw4 *pDirectDraw4; // [sp+4F8h] [bp-4h]@7 - - v4 = strlen(lpDriverName); - v20.pDriverName = new char[v4 + 1]; - v5 = strlen(lpDevDesc); - v20.pDeviceDesc = new char[v5 + 1]; - strcpy(v20.pDriverName, lpDriverName); - strcpy(v20.pDeviceDesc, lpDevDesc); - if ( lpGUID ) - { - v20.pGUID = new GUID; - memcpy(v20.pGUID, lpGUID, 0x10); - } - else - v20.pGUID = 0; - - if (FAILED(DirectDrawCreate(v20.pGUID, &pDirectDraw, 0))) - { - delete [] v20.pDriverName; - delete [] v20.pDeviceDesc; - delete v20.pGUID; - } - else - { - if (FAILED(pDirectDraw->QueryInterface(IID_IDirectDraw4, (LPVOID *)&pDirectDraw4))) - { - delete [] v20.pDriverName; - delete [] v20.pDeviceDesc; - delete v20.pGUID; - pDirectDraw->Release(); - } - else - { - pDirectDraw->Release(); - if (FAILED( pDirectDraw4->GetDeviceIdentifier(&ddDevId, 1))) - v20.pDDraw4DevDesc = 0; - else - { - v7 = strlen(ddDevId.szDescription); - v20.pDDraw4DevDesc = new char[v7 + 1]; - strcpy(v20.pDDraw4DevDesc, ddDevId.szDescription); - } - memset(&ddsCaps, 0, sizeof(ddsCaps)); - if (FAILED(pDirectDraw4->GetAvailableVidMem(&ddsCaps, (LPDWORD)&v20.uVideoMem, (LPDWORD)&uFreeVideoMem))) - v20.uVideoMem = 0; - memset(&v10, 0, sizeof(v10)); - v10.dwSize = 124; - v10.dwFlags = 6; - v10.dwHeight = window->GetWidth(); - v10.dwWidth = window->GetHeight(); - v10.ddpfPixelFormat.dwSize = 32; - - is_there_a_compatible_screen_mode = false; - if ( FAILED(pDirectDraw4->EnumDisplayModes(0, 0, &is_there_a_compatible_screen_mode, (LPDDENUMMODESCALLBACK2)DDrawDisplayModesEnumerator)) - || !is_there_a_compatible_screen_mode - || FAILED(pDirectDraw4->QueryInterface(IID_IDirect3D3, (LPVOID *)&pDirect3D3))) - { - delete [] v20.pDriverName; - delete [] v20.pDeviceDesc; - //free(v20.pDDraw4DevDesc); - delete [] v20.pDDraw4DevDesc; - delete v20.pGUID; - pDirectDraw4->Release(); - } - else - { - aux.pInfo = pOut; - aux.ptr_4 = &v20; - pDirect3D3->EnumDevices((LPD3DENUMDEVICESCALLBACK)D3DDeviceEnumerator, &aux); - delete [] v20.pDriverName; - delete [] v20.pDeviceDesc; - delete [] v20.pDDraw4DevDesc; - delete v20.pGUID; - pDirectDraw4->Release(); - pDirectDraw4 = 0; - pDirect3D3->Release(); - } - } - } - return 1; -} - -//----- (0049D784) -------------------------------------------------------- -HRESULT __stdcall D3DDeviceEnumerator(const GUID *lpGUID, const char *lpDeviceDesc, const char *lpDeviceName, D3DDEVICEDESC *pHWDesc, D3DDEVICEDESC *pSWDesc, RenderD3D_aux *a6) -{ - signed int v7; // edi@1 - - v7 = -1; - if ( pHWDesc->dwFlags ) - { - if ( !a6->ptr_4->pGUID ) - v7 = 0; - if ( pHWDesc->dwFlags && a6->ptr_4->pGUID ) - v7 = 1; - } - if ( !strcmp(lpDeviceName, "RGB Emulation") && !a6->ptr_4->pGUID ) - v7 = 2; - if ( !strcmp(lpDeviceName, "Reference Rasterizer") && !a6->ptr_4->pGUID ) - v7 = 3; - if ( v7 != -1 ) - { - a6->pInfo[v7].bIsDeviceCompatible = 1; - a6->pInfo[v7].uCaps = 0; - if ( !(pHWDesc->dpcTriCaps.dwSrcBlendCaps & 0x10) ) - a6->pInfo[v7].uCaps |= 2; - if ( !(pHWDesc->dpcTriCaps.dwSrcBlendCaps & 2) ) - a6->pInfo[v7].uCaps |= 4; - if ( !(pHWDesc->dpcTriCaps.dwSrcBlendCaps & 1) ) - a6->pInfo[v7].uCaps |= 8; - if ( !(pHWDesc->dpcTriCaps.dwDestBlendCaps & 0x20) ) - a6->pInfo[v7].uCaps |= 16; - if ( !(pHWDesc->dpcTriCaps.dwDestBlendCaps & 2) ) - a6->pInfo[v7].uCaps |= 32; - if ( !(pHWDesc->dpcTriCaps.dwDestBlendCaps & 4) ) - a6->pInfo[v7].uCaps |= 64; - if ( !(BYTE1(pHWDesc->dwDevCaps) & 0x10) ) - BYTE1(a6->pInfo[v7].uCaps) |= 1; - if ( pHWDesc->dpcTriCaps.dwTextureCaps & 0x20 ) - LOBYTE(a6->pInfo[v7].uCaps) |= 0x80; - - a6->pInfo[v7].pName = new char[strlen(lpDeviceName) + 1]; - strcpy(a6->pInfo[v7].pName, lpDeviceName); - - a6->pInfo[v7].pDescription = new char[strlen(lpDeviceDesc) + 1]; - strcpy(a6->pInfo[v7].pDescription, lpDeviceDesc); - - a6->pInfo[v7].pGUID = new GUID; - memcpy(a6->pInfo[v7].pGUID, lpGUID, 0x10); - - a6->pInfo[v7].pDriverName = new char[strlen(a6->ptr_4->pDriverName) + 1]; - strcpy(a6->pInfo[v7].pDriverName, a6->ptr_4->pDriverName); - - a6->pInfo[v7].pDeviceDesc = new char[strlen(a6->ptr_4->pDeviceDesc) + 1]; - strcpy(a6->pInfo[v7].pDeviceDesc, a6->ptr_4->pDeviceDesc); - - a6->pInfo[v7].pDDraw4DevDesc = new char[strlen(a6->ptr_4->pDDraw4DevDesc) + 1]; - strcpy(a6->pInfo[v7].pDDraw4DevDesc, a6->ptr_4->pDDraw4DevDesc); - - if ( a6->ptr_4->pGUID ) - { - a6->pInfo[v7].pDirectDrawGUID = new GUID; - memcpy(a6->pInfo[v7].pDirectDrawGUID, a6->ptr_4->pGUID, 0x10); - } - else - a6->pInfo[v7].pDirectDrawGUID = 0; - a6->pInfo[v7].uVideoMem = a6->ptr_4->uVideoMem; - } - return 1; -} - -//----- (0049D75C) -------------------------------------------------------- -HRESULT __stdcall DDrawDisplayModesEnumerator(DDSURFACEDESC2 *pSurfaceDesc, __int16 *found_compatible_mode) -{ - if ( pSurfaceDesc->ddsCaps.dwCaps | DDSCAPS_3DDEVICE /*&& pSurfaceDesc->ddpfPixelFormat.dwRGBBitCount == 16*/ ) - { - *found_compatible_mode = 1; - return S_OK; - } - return 1; -} - -//----- (0047A95E) -------------------------------------------------------- -void Render::PrepareDecorationsRenderList_ODM() -{ - unsigned int v6; // edi@9 - int v7; // eax@9 - SpriteFrame *v8; // eax@9 - unsigned __int16 *v10; // eax@9 - int v13; // ecx@9 - int v14; // ecx@20 - char v15; // dl@20 - signed int v16; // eax@20 - int v17; // eax@23 - int v18; // ecx@24 - int v19; // eax@24 - int v20; // ecx@24 - int v21; // ebx@26 - int v22; // eax@26 - signed __int64 v24; // qtt@31 - int v25; // ebx@31 - __int16 v29; // cx@37 - int v30; // ecx@37 - int v31; // ebx@37 - Particle_sw local_0; // [sp+Ch] [bp-98h]@7 - unsigned __int16 *v37; // [sp+84h] [bp-20h]@9 - int v38; // [sp+88h] [bp-1Ch]@9 - int v40; // [sp+90h] [bp-14h]@24 - int v41; // [sp+94h] [bp-10h]@24 - int v42; // [sp+98h] [bp-Ch]@9 - int b; // [sp+A0h] [bp-4h]@22 - - for (unsigned int i = 0; i < uNumLevelDecorations; ++i) - { - //LevelDecoration* decor = &pLevelDecorations[i]; - if ((!(pLevelDecorations[i].uFlags & LEVEL_DECORATION_OBELISK_CHEST) - || pLevelDecorations[i].IsObeliskChestActive()) && !(pLevelDecorations[i].uFlags & LEVEL_DECORATION_INVISIBLE)) - { - DecorationDesc* decor_desc = &pDecorationList->pDecorations[pLevelDecorations[i].uDecorationDescID]; - if ( (char)decor_desc->uFlags >= 0 ) - { - if ( !(decor_desc->uFlags & 0x22) ) - { - v6 = pMiscTimer->uTotalGameTimeElapsed; - v7 = abs(pLevelDecorations[i].vPosition.x + pLevelDecorations[i].vPosition.y); - - #pragma region "New: seasons change" - extern bool change_seasons; - if (change_seasons) - switch (pParty->uCurrentMonth) - { - // case 531 (tree60), 536 (tree65), 537 (tree66) have no autumn/winter sprites - case 11: case 0: case 1: // winter - switch (decor_desc->uSpriteID) - { - //case 468: //bush02 grows on swamps, which are evergreeen actually - case 548: // flower10 - case 547: // flower09 - case 541: // flower03 - case 539: continue; // flower01 - - case 483: // tree01 - case 486: // tree04 - case 492: // tree10 - pSpriteFrameTable->InitializeSprite(decor_desc->uSpriteID + 2); - v8 = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID + 2, v6 + v7); - break; - - default: - v8 = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID, v6 + v7); - } - break; - - case 2: case 3: case 4: // spring - switch (decor_desc->uSpriteID) - { - } - v8 = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID, v6 + v7); - break; - - case 8: case 9: case 10: // autumn - switch (decor_desc->uSpriteID) - { - //case 468: //bush02 grows on swamps, which are evergreeen actually - case 548: // flower10 - case 547: // flower09 - case 541: // flower03 - case 539: continue; // flower01 - - case 483: // tree01 - case 486: // tree04 - case 492: // tree10 - pSpriteFrameTable->InitializeSprite(decor_desc->uSpriteID + 1); - v8 = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID + 1, v6 + v7); - break; - - default: - v8 = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID, v6 + v7); - } - break; - - case 5: case 6: case 7: // summer - //all green by default - v8 = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID, v6 + v7); - break; - - default: assert(pParty->uCurrentMonth >= 0 && pParty->uCurrentMonth < 12); - } - else - v8 = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID, v6 + v7); - #pragma endregion - //v8 = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID, v6 + v7); - - v10 = (unsigned __int16 *)stru_5C6E00->Atan2(pLevelDecorations[i].vPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x, - pLevelDecorations[i].vPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y); - v38 = 0; - v13 = ((signed int)(stru_5C6E00->uIntegerPi + ((signed int)stru_5C6E00->uIntegerPi >> 3) + pLevelDecorations[i].field_10_y_rot - (signed int)v10) >> 8) & 7; - v37 = (unsigned __int16 *)v13; - if ( v8->uFlags & 2 ) - v38 = 2; - if ( (256 << v13) & v8->uFlags ) - v38 |= 4; - if ( v8->uFlags & 0x40000 ) - v38 |= 0x40; - if ( v8->uFlags & 0x20000 ) - LOBYTE(v38) = v38 | 0x80; - if ( v8->uGlowRadius ) - { - if ( pRenderD3D && bUseColoredLights ) - { - v14 = /*255;//*/decor_desc->uColoredLightRed; - v15 = /*255;//*/decor_desc->uColoredLightGreen; - v16 = /*255;//*/decor_desc->uColoredLightBlue; - } - else - { - v16 = 255; - v14 = 255; - v15 = 255; - } - pStationaryLightsStack->AddLight(pLevelDecorations[i].vPosition.x, pLevelDecorations[i].vPosition.y, pLevelDecorations[i].vPosition.z + decor_desc->uDecorationHeight / 2, - v8->uGlowRadius, v14, v15, v16, _4E94D0_light_type); - } - v17 = (pLevelDecorations[i].vPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x) << 16; - if (pGame->pIndoorCameraD3D->sRotationX) - { - v40 = (pLevelDecorations[i].vPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y) << 16; - v18 = fixpoint_mul(v17, pGame->pIndoorCameraD3D->int_cosine_y) + fixpoint_mul(v40, pGame->pIndoorCameraD3D->int_sine_y); - v41 = fixpoint_mul((pLevelDecorations[i].vPosition.z - pGame->pIndoorCameraD3D->vPartyPos.z) << 16, pGame->pIndoorCameraD3D->int_sine_x); - v19 = fixpoint_mul(v18, pGame->pIndoorCameraD3D->int_cosine_x); - v20 = v19 + fixpoint_mul((pLevelDecorations[i].vPosition.z - pGame->pIndoorCameraD3D->vPartyPos.z) << 16, pGame->pIndoorCameraD3D->int_sine_x); - if ( v20 >= 0x40000 && v20 <= pODMRenderParams->shading_dist_mist << 16 ) - { - v21 = fixpoint_mul(v40, pGame->pIndoorCameraD3D->int_cosine_y) - fixpoint_mul(v17, pGame->pIndoorCameraD3D->int_sine_y); - v22 = fixpoint_mul((pLevelDecorations[i].vPosition.z - pGame->pIndoorCameraD3D->vPartyPos.z) << 16, pGame->pIndoorCameraD3D->int_cosine_x) - fixpoint_mul(v18, pGame->pIndoorCameraD3D->int_sine_x); - if ( 2 * abs(v20) >= abs(v21) ) - { - LODWORD(v24) = 0; - HIDWORD(v24) = SLOWORD(pODMRenderParams->int_fov_rad); - v25 = pViewport->uScreenCenterX - ((signed int)(fixpoint_mul(v24 / v20, v21) + 0x8000) >> 16); - v40 = pViewport->uScreenCenterY - ((signed int)(fixpoint_mul(v24 / v20, v22) + 0x8000) >> 16); - v41 = fixpoint_mul(v8->scale, v24 / v20); - if ( pRenderD3D ) - b = fixpoint_mul(pSprites_LOD->pHardwareSprites[v8->pHwSpriteIDs[(int)v37]].uBufferWidth / 2, v41); - else - { - __debugbreak(); - b = fixpoint_mul(pSprites_LOD->pSpriteHeaders[v8->pHwSpriteIDs[(int)v37]].uWidth / 2, v41); - } - if ( b + v25 >= (signed int)pViewport->uViewportTL_X && v25 - b <= (signed int)pViewport->uViewportBR_X ) - { - if (::uNumBillboardsToDraw >= 500) - return; - pBillboardRenderList[::uNumBillboardsToDraw].HwSpriteID = v8->pHwSpriteIDs[(int)v37]; - pBillboardRenderList[::uNumBillboardsToDraw]._screenspace_x_scaler_packedfloat = v41; - pBillboardRenderList[::uNumBillboardsToDraw]._screenspace_y_scaler_packedfloat = v41; - v29 = v38; - pBillboardRenderList[::uNumBillboardsToDraw].uScreenSpaceX = v25; - HIBYTE(v29) |= 2; - pBillboardRenderList[::uNumBillboardsToDraw].uPalette = v8->uPaletteIndex; - pBillboardRenderList[::uNumBillboardsToDraw].field_1E = v29; - pBillboardRenderList[::uNumBillboardsToDraw].world_x = pLevelDecorations[i].vPosition.x; - pBillboardRenderList[::uNumBillboardsToDraw].world_y = pLevelDecorations[i].vPosition.y; - pBillboardRenderList[::uNumBillboardsToDraw].world_z = pLevelDecorations[i].vPosition.z; - pBillboardRenderList[::uNumBillboardsToDraw].uScreenSpaceY = v40; - HIWORD(v30) = HIWORD(v20); - v31 = PID(OBJECT_Decoration,i); - LOWORD(v30) = 0; - pBillboardRenderList[::uNumBillboardsToDraw].uIndoorSectorID = 0; - pBillboardRenderList[::uNumBillboardsToDraw].sZValue = v30 + v31; - pBillboardRenderList[::uNumBillboardsToDraw].dimming_level = 0; - pBillboardRenderList[::uNumBillboardsToDraw].pSpriteFrame = v8; - pBillboardRenderList[::uNumBillboardsToDraw].sTintColor = 0; - ::uNumBillboardsToDraw++; - ++uNumDecorationsDrawnThisFrame; - } - } - continue; - } - } - else - { - v42 = (pLevelDecorations[i].vPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x) << 16; - v40 = (pLevelDecorations[i].vPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y) << 16; - v20 = fixpoint_mul(v17, pGame->pIndoorCameraD3D->int_cosine_y) + fixpoint_mul(v40, pGame->pIndoorCameraD3D->int_sine_y); - if ( v20 >= 0x40000 && v20 <= pODMRenderParams->shading_dist_mist << 16 ) - { - v21 = fixpoint_mul(v40, pGame->pIndoorCameraD3D->int_cosine_y) - fixpoint_mul(v42, pGame->pIndoorCameraD3D->int_sine_y); - v22 = (pLevelDecorations[i].vPosition.z - pGame->pIndoorCameraD3D->vPartyPos.z) << 16; - v42 = v22; - if ( 2 * abs(v20) >= abs(v21) ) - { - LODWORD(v24) = 0; - HIDWORD(v24) = SLOWORD(pODMRenderParams->int_fov_rad); - v25 = pViewport->uScreenCenterX - ((signed int)(fixpoint_mul(v24 / v20, v21) + 0x8000) >> 16); - v40 = pViewport->uScreenCenterY - ((signed int)(fixpoint_mul(v24 / v20, v42) + 0x8000) >> 16); - v41 = fixpoint_mul(v8->scale, v24 / v20); - if ( pRenderD3D ) - b = fixpoint_mul(pSprites_LOD->pHardwareSprites[v8->pHwSpriteIDs[(int)v37]].uBufferWidth / 2, v41); - else - { - __debugbreak(); - b = fixpoint_mul(pSprites_LOD->pSpriteHeaders[v8->pHwSpriteIDs[(int)v37]].uWidth / 2, v41); - } - if ( b + v25 >= (signed int)pViewport->uViewportTL_X && v25 - b <= (signed int)pViewport->uViewportBR_X ) - { - if (::uNumBillboardsToDraw >= 500) - return; - pBillboardRenderList[::uNumBillboardsToDraw].HwSpriteID = v8->pHwSpriteIDs[(int)v37]; - pBillboardRenderList[::uNumBillboardsToDraw]._screenspace_x_scaler_packedfloat = v41; - pBillboardRenderList[::uNumBillboardsToDraw]._screenspace_y_scaler_packedfloat = v41; - v29 = v38; - pBillboardRenderList[::uNumBillboardsToDraw].uScreenSpaceX = v25; - HIBYTE(v29) |= 2; - pBillboardRenderList[::uNumBillboardsToDraw].uPalette = v8->uPaletteIndex; - pBillboardRenderList[::uNumBillboardsToDraw].field_1E = v29; - pBillboardRenderList[::uNumBillboardsToDraw].world_x = pLevelDecorations[i].vPosition.x; - pBillboardRenderList[::uNumBillboardsToDraw].world_y = pLevelDecorations[i].vPosition.y; - pBillboardRenderList[::uNumBillboardsToDraw].world_z = pLevelDecorations[i].vPosition.z; - pBillboardRenderList[::uNumBillboardsToDraw].uScreenSpaceY = v40; - HIWORD(v30) = HIWORD(v20); - v31 = PID(OBJECT_Decoration,i); - LOWORD(v30) = 0; - pBillboardRenderList[::uNumBillboardsToDraw].uIndoorSectorID = 0; - pBillboardRenderList[::uNumBillboardsToDraw].sZValue = v30 + v31; - pBillboardRenderList[::uNumBillboardsToDraw].dimming_level = 0; - pBillboardRenderList[::uNumBillboardsToDraw].pSpriteFrame = v8; - pBillboardRenderList[::uNumBillboardsToDraw].sTintColor = 0; - ::uNumBillboardsToDraw++; - ++uNumDecorationsDrawnThisFrame; - } - } - continue; - } - } - } - } - else - { - memset(&local_0, 0, 0x68); - local_0.type = ParticleType_Bitmap | ParticleType_Rotating | ParticleType_8; - local_0.uDiffuse = 0xFF3C1E; - local_0.x = (double)pLevelDecorations[i].vPosition.x; - local_0.y = (double)pLevelDecorations[i].vPosition.y; - local_0.z = (double)pLevelDecorations[i].vPosition.z; - local_0.r = 0.0; - local_0.g = 0.0; - local_0.b = 0.0; - local_0.flt_28 = 1.0; - local_0.timeToLive = (rand() & 0x80) + 128; - local_0.uTextureID = pBitmaps_LOD->LoadTexture("effpar01"); - pGame->pParticleEngine->AddParticle(&local_0); - } - } - } -} - -//----- (0049D717) -------------------------------------------------------- -HRESULT __stdcall D3DZBufferFormatEnumerator(DDPIXELFORMAT *Src, DDPIXELFORMAT *Dst) -{ - if ( Src->dwFlags & (0x400 | 0x2000)) - { - if ( Src->dwRGBBitCount == 16 && !Src->dwRBitMask ) - { - memcpy(Dst, Src, sizeof(DDPIXELFORMAT)); - return 0; - } - if ( !Dst->dwSize ) - { - memcpy(Dst, Src, sizeof(DDPIXELFORMAT)); - return 1; - } - } - return 1; -} - -//----- (0049DC28) -------------------------------------------------------- -void RenderD3D::GetAvailableDevices(RenderD3D__DevInfo **pOutDevices) -{ - RenderD3D__DevInfo *v2; // eax@1 - - v2 = new RenderD3D__DevInfo[4];// 4 items - *pOutDevices = v2; - memset(v2, 0, sizeof(v2)); - DirectDrawEnumerateExA((LPDDENUMCALLBACKEXA)RenderD3D__DeviceEnumerator, *pOutDevices, DDENUM_ATTACHEDSECONDARYDEVICES); -} - -//----- (0049DC58) -------------------------------------------------------- -RenderD3D::RenderD3D() -{ - this->pHost = nullptr; - this->pDirect3D = nullptr; - this->pUnk = nullptr; - this->pBackBuffer = nullptr; - this->pFrontBuffer = nullptr; - this->pZBuffer = nullptr; - this->pDevice = nullptr; - this->pViewport = nullptr; - this->field_40 = 1; - this->field_44 = 10; - GetAvailableDevices(&this->pAvailableDevices); -} - -//----- (0049DC90) -------------------------------------------------------- -void RenderD3D::Release() -{ - if ( !this->bWindowed ) - { - if ( this->pHost ) - { - this->pHost->RestoreDisplayMode(); - this->pHost->SetCooperativeLevel(this->hWindow, DDSCL_NORMAL); - this->pHost->FlipToGDISurface(); - } - } - - for (int i = 0; i < 4; i++) - { - delete[] this->pAvailableDevices[i].pDriverName; - this->pAvailableDevices[i].pDriverName = nullptr; - - delete[] this->pAvailableDevices[i].pDeviceDesc; - this->pAvailableDevices[i].pDeviceDesc = nullptr; - - delete[] this->pAvailableDevices[i].pDDraw4DevDesc; - this->pAvailableDevices[i].pDDraw4DevDesc = nullptr; - - delete this->pAvailableDevices[i].pDirectDrawGUID; - this->pAvailableDevices[i].pDirectDrawGUID = nullptr; - - delete[] this->pAvailableDevices[i].pName; - this->pAvailableDevices[i].pName = nullptr; - - delete[] this->pAvailableDevices[i].pDescription; - this->pAvailableDevices[i].pDescription = nullptr; - - delete this->pAvailableDevices[i].pGUID; - this->pAvailableDevices[i].pGUID = nullptr; - } - - delete[] this->pAvailableDevices; - this->pAvailableDevices = NULL; - - if ( this->pViewport ) - { - this->pViewport->Release(); - this->pViewport = NULL; - } - - if ( this->pUnk ) - { - this->pUnk->Release(); - this->pUnk = NULL; - } - - if ( this->pZBuffer ) - { - this->pZBuffer->Release(); - this->pZBuffer = NULL; - } - - if ( this->pDevice ) - { - this->pDevice->Release(); - this->pDevice = NULL; - } - - if ( this->pDirect3D ) - { - this->pDirect3D->Release(); - this->pDirect3D = NULL; - } - - if ( this->pBackBuffer ) - { - this->pBackBuffer->Release(); - this->pBackBuffer = NULL; - } - - if ( this->pFrontBuffer ) - { - this->pFrontBuffer->Release(); - this->pFrontBuffer = NULL; - } - - if ( this->pHost ) - { - this->pHost->Release(); - this->pHost = NULL; - } -} - -//----- (0049DE14) -------------------------------------------------------- -bool RenderD3D::CreateDevice(unsigned int uDeviceID, int bWindowed, OSWindow *window) -{ - DWORD v26; // [sp-4h] [bp-DCh]@30 - DDSCAPS2 v27; // [sp+Ch] [bp-CCh]@37 - DDSURFACEDESC2 ddsd2; // [sp+1Ch] [bp-BCh]@11 - D3DVIEWPORT2 d3dvp2; // [sp+98h] [bp-40h]@28 - IDirectDrawClipper *lpddclipper; // [sp+C4h] [bp-14h]@18 - LPDIRECTDRAW lpDD; // [sp+C8h] [bp-10h]@1 - - auto hWnd = window->GetApiHandle(); - int game_width = window->GetWidth(); - int game_height = window->GetHeight(); - - this->bWindowed = bWindowed; - this->hWindow = hWnd; - - //Создание объекта DirectDraw - if (FAILED(DirectDrawCreate(pAvailableDevices[uDeviceID].pDirectDrawGUID, &lpDD, NULL))) - { - sprintf(pErrorMessage, "Init - Failed to create DirectDraw interface.\n"); - return 0; - } - - //Запрос интерфейса IDirectDraw4 - if (FAILED(lpDD->QueryInterface(IID_IDirectDraw4, (LPVOID *)&pHost))) - { - sprintf(pErrorMessage, "Init - Failed to create DirectDraw4 interface.\n"); - if (lpDD) - lpDD->Release(); - return 0; - } - lpDD->Release(); - lpDD = NULL; - - //Задаём уровень совместного доступа для приложения DirectDraw в оконном режиме - if (bWindowed && !pAvailableDevices[uDeviceID].pDirectDrawGUID) - { - if (FAILED(pHost->SetCooperativeLevel(hWnd, DDSCL_MULTITHREADED | DDSCL_NORMAL))) - { - sprintf(pErrorMessage, "Init - Failed to set cooperative level.\n"); - if (pHost) - { - pHost->Release(); - pHost = NULL; - } - return 0; - } - - // - memset(&ddsd2, 0, sizeof(DDSURFACEDESC2)); - ddsd2.dwSize = sizeof(DDSURFACEDESC2); - ddsd2.dwFlags = DDSD_CAPS; - ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; - //Создаём первичную поверхность - if ( FAILED(pHost->CreateSurface(&ddsd2, &pFrontBuffer, NULL)) ) - { - sprintf(pErrorMessage, "Init - Failed to create front buffer.\n"); - if (pHost) - { - pHost->Release(); - pHost = NULL; - } - return 0; - } - ddsd2.dwSize = sizeof(DDSURFACEDESC2); - pHost->GetDisplayMode(&ddsd2); - if ( FORCE_16_BITS && ddsd2.ddpfPixelFormat.dwRGBBitCount != 16 ) - { - sprintf(pErrorMessage, "Init - Desktop isn't in 16 bit mode.\n"); - if (pFrontBuffer) - { - pFrontBuffer->Release(); - pFrontBuffer = NULL; - } - if (pHost) - { - pHost->Release(); - pHost = NULL; - } - return 0; - } - - ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd2.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE; - ddsd2.dwWidth = game_width; - ddsd2.dwHeight = game_height; - if (pHost->CreateSurface(&ddsd2, &pBackBuffer, NULL) ) - { - sprintf(pErrorMessage, "Init - Failed to create back buffer.\n"); - if (pFrontBuffer) - { - pFrontBuffer->Release(); - pFrontBuffer = NULL; - } - if (pHost) - { - pHost->Release(); - pHost = NULL; - } - return 0; - } - //Создание отсекателя DirectDraw - if ( pHost->CreateClipper(0, &lpddclipper, NULL) ) - { - sprintf(pErrorMessage, "Init - Failed to create clipper.\n"); - if (pBackBuffer) - { - pBackBuffer->Release(); - pBackBuffer = NULL; - } - if (pFrontBuffer) - { - pFrontBuffer->Release(); - pFrontBuffer= NULL; - } - if (pHost) - { - pHost->Release(); - pHost = NULL; - } - return 0; - } - lpddclipper->SetHWnd(0, hWnd); - pFrontBuffer->SetClipper(lpddclipper); - - lpddclipper->Release(); - lpddclipper = NULL; - // - - pHost->QueryInterface(IID_IDirect3D3, (LPVOID *)&pDirect3D); - - ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; - ddsd2.ddsCaps.dwCaps = DDSCAPS_ZBUFFER; - ddsd2.dwWidth = game_width; - ddsd2.dwHeight = game_height; - - if ( pDirect3D->EnumZBufferFormats(*pAvailableDevices[uDeviceID].pGUID, - (HRESULT (__stdcall *)(DDPIXELFORMAT *, void *))D3DZBufferFormatEnumerator, - &ddsd2.ddpfPixelFormat) ) - { - sprintf(pErrorMessage, "Init - Failed to enumerate Z buffer formats.\n"); - if (pBackBuffer) - { - pBackBuffer->Release(); - pBackBuffer = NULL; - } - if (pFrontBuffer) - { - pFrontBuffer->Release(); - pFrontBuffer= NULL; - } - if (pHost) - { - pHost->Release(); - pHost = NULL; - } - return 0; - } - if ( uDeviceID == 2 || uDeviceID == 3 ) - ddsd2.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; - - if ( !pHost->CreateSurface(&ddsd2, &pZBuffer, NULL) ) - { - if ( !pBackBuffer->AddAttachedSurface(pZBuffer) ) - { - if ( !pDirect3D->CreateDevice(*pAvailableDevices[uDeviceID].pGUID, pBackBuffer, &pDevice, 0) ) - { - memset(&d3dvp2, 0, sizeof(D3DVIEWPORT2)); - d3dvp2.dvClipWidth = 2.0; - d3dvp2.dvClipY = 1.0; - d3dvp2.dvClipHeight = 2.0; - d3dvp2.dvMaxZ = 1.0; - d3dvp2.dvMinZ = 0.0; - goto LABEL_54; - } - sprintf(pErrorMessage, "Init - Failed to create D3D device.\n"); - if (pDirect3D) - { - pDirect3D->Release(); - pDirect3D = NULL; - } - if (pZBuffer) - { - pZBuffer->Release(); - pZBuffer = NULL; - } - if (pBackBuffer) - { - pBackBuffer->Release(); - pBackBuffer = NULL; - } - if (pFrontBuffer) - { - pFrontBuffer->Release(); - pFrontBuffer= NULL; - } - if (pHost) - { - pHost->Release(); - pHost = NULL; - } - return 0; - } - sprintf(pErrorMessage, "Init - Failed to attach z-buffer to back buffer.\n"); - if (pZBuffer) - { - pZBuffer->Release(); - pZBuffer = NULL; - } - if (pBackBuffer) - { - pBackBuffer->Release(); - pBackBuffer = NULL; - } - if (pFrontBuffer) - { - pFrontBuffer->Release(); - pFrontBuffer= NULL; - } - if (pHost) - { - pHost->Release(); - pHost = NULL; - } - return 0; - } - sprintf(pErrorMessage, "Init - Failed to create z-buffer.\n"); - if (pBackBuffer) - { - pBackBuffer->Release(); - pBackBuffer = NULL; - } - if (pFrontBuffer) - { - pFrontBuffer->Release(); - pFrontBuffer= NULL; - } - if (pHost) - { - pHost->Release(); - pHost = NULL; - } - return 0; - } - if ( uDeviceID == 1 ) - v26 = 1045; - else - v26 = 1041; - if (pHost->SetCooperativeLevel(hWnd, v26) ) - { - sprintf(pErrorMessage, "Init - Failed to set cooperative level.\n"); - if (pHost) - { - pHost->Release(); - pHost = NULL; - } - return 0; - } - if (pHost->SetDisplayMode(window->GetWidth(), window->GetHeight(), 16, 0, 0) ) - { - sprintf(pErrorMessage, "Init - Failed to set display mode.\n"); - if (pHost) - { - pHost->Release(); - pHost = NULL; - } - return 0; - } - - memset(&ddsd2, 0, sizeof(DDSURFACEDESC2)); - ddsd2.dwSize = sizeof(DDSURFACEDESC2); - //Подключение полей с достоверными данными - ddsd2.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; - //Запрос сложной структуры с возможностью переключения - ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; - //Присвоение полю счётчика задних буферов значения 1 - ddsd2.dwBackBufferCount = 1; - if ( pHost->CreateSurface(&ddsd2, &pFrontBuffer, NULL) ) - { - sprintf(pErrorMessage, "Init - Failed to create front buffer.\n"); - if (pHost) - { - pHost->Release(); - pHost = NULL; - } - return 0; - } - //a3a = &pBackBuffer; - //v14 = *v34; - memset(&v27, 0, sizeof(DDSCAPS2)); - - v27.dwCaps = DDSCAPS_BACKBUFFER; - //v33 = (IDirect3DDevice3 **)v14->GetAttachedSurface(&v27, &pBackBuffer); - //hWnda = &pDirect3D; - pHost->QueryInterface(IID_IDirect3D3, (LPVOID *)&pDirect3D); - - if (FAILED(pFrontBuffer->GetAttachedSurface(&v27, &pBackBuffer))) - { - sprintf(pErrorMessage, "Init - Failed to get D3D interface.\n"); - if (pBackBuffer) - { - pBackBuffer->Release(); - pBackBuffer = NULL; - } - if (pFrontBuffer) - { - pFrontBuffer->Release(); - pFrontBuffer= NULL; - } - if (pHost) - { - pHost->Release(); - pHost = NULL; - } - return 0; - } - - ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; - ddsd2.ddsCaps.dwCaps = DDSCAPS_ZBUFFER; - ddsd2.dwWidth = 640; - ddsd2.dwHeight = 480; - if ( pDirect3D->EnumZBufferFormats(*pAvailableDevices[uDeviceID].pGUID, - (HRESULT (__stdcall *)(DDPIXELFORMAT *, void *))D3DZBufferFormatEnumerator, - &ddsd2.ddpfPixelFormat) ) - { - sprintf(pErrorMessage, "Init - Failed to enumerate Z buffer formats.\n"); - if (pBackBuffer) - { - pBackBuffer->Release(); - pBackBuffer = 0; - } - if (pFrontBuffer) - { - pFrontBuffer->Release(); - pFrontBuffer= 0; - } - if (pHost) - { - pHost->Release(); - pHost = 0; - } - return 0; - } - if ( uDeviceID == 2 || uDeviceID == 3 ) - BYTE1(ddsd2.ddsCaps.dwCaps) |= 8; - //uDeviceIDa = &pZBuffer; - if (pHost->CreateSurface(&ddsd2, &pZBuffer, NULL) ) - { - sprintf(pErrorMessage, "Init - Failed to create z-buffer.\n"); - if (pBackBuffer) - { - pBackBuffer->Release(); - pBackBuffer = 0; - } - if (pFrontBuffer) - { - pFrontBuffer->Release(); - pFrontBuffer= 0; - } - if (pHost) - { - pHost->Release(); - pHost = 0; - } - return 0; - } - if (pBackBuffer->AddAttachedSurface(pZBuffer)) - { - sprintf(pErrorMessage, "Init - Failed to attach z-buffer to back buffer.\n"); - if (pZBuffer) - { - pZBuffer->Release(); - pZBuffer = 0; - } - if (pBackBuffer) - { - pBackBuffer->Release(); - pBackBuffer = 0; - } - if (pFrontBuffer) - { - pFrontBuffer->Release(); - pFrontBuffer= 0; - } - if (pHost) - { - pHost->Release(); - pHost = 0; - } - return 0; - } - //v33 = &pDevice; - if (pDirect3D->CreateDevice(*pAvailableDevices[uDeviceID].pGUID, pBackBuffer, &pDevice, 0) ) - { - sprintf(pErrorMessage, "Init - Failed to create D3D device.\n"); - if (pDirect3D) - { - pDirect3D->Release(); - pDirect3D = 0; - } - if (pZBuffer) - { - pZBuffer->Release(); - pZBuffer = 0; - } - if (pBackBuffer) - { - pBackBuffer->Release(); - pBackBuffer = 0; - } - if (pFrontBuffer) - { - pFrontBuffer->Release(); - pFrontBuffer= 0; - } - if (pHost) - { - pHost->Release(); - pHost = 0; - } - return 0; - } - memset(&d3dvp2, 0, sizeof(D3DVIEWPORT2)); - d3dvp2.dvClipWidth = 2.0; - d3dvp2.dvClipY = 1.0; - d3dvp2.dvClipHeight = 2.0; - d3dvp2.dvMaxZ = 1.0; - -LABEL_54: - d3dvp2.dwSize = sizeof(D3DVIEWPORT2); - //v17 = *hWnda; - d3dvp2.dwWidth = game_width; - d3dvp2.dwHeight = game_height; - d3dvp2.dvClipX = -1.0; - //v18 = v17->lpVtbl; - //v32 = &v4->pViewport; - if (pDirect3D->CreateViewport(&pViewport, 0)) - { - sprintf(pErrorMessage, "Init - Failed to create viewport.\n"); - if (pDevice) - { - pDevice->Release(); - pDevice = 0; - } - if (pDirect3D) - { - pDirect3D->Release(); - pDirect3D = 0; - } - if (pZBuffer) - { - pZBuffer->Release(); - pZBuffer = 0; - } - if (pBackBuffer) - { - pBackBuffer->Release(); - pBackBuffer = 0; - } - if (pFrontBuffer) - { - pFrontBuffer->Release(); - pFrontBuffer= 0; - } - if (pHost) - { - pHost->Release(); - pHost = 0; - } - return 0; - } - - pDevice->AddViewport(pViewport); - pViewport->SetViewport2(&d3dvp2); - pDevice->SetCurrentViewport(pViewport); - return 1; -} - -//----- (0049E444) -------------------------------------------------------- -unsigned int RenderD3D::GetDeviceCaps() -{ - unsigned int v1; // ebx@1 - unsigned int result; // eax@2 - D3DDEVICEDESC refCaps; // [sp+Ch] [bp-1F8h]@1 - D3DDEVICEDESC halCaps; // [sp+108h] [bp-FCh]@1 - - v1 = 0; - - memset(&halCaps, 0, sizeof(halCaps)); - halCaps.dwSize = sizeof(halCaps); - - memset(&refCaps, 0, sizeof(refCaps)); - refCaps.dwSize = sizeof(refCaps); - - if ( this->pDevice->GetCaps(&halCaps, &refCaps) ) - result = 1; - else - { - if ( !(halCaps.dpcTriCaps.dwSrcBlendCaps & D3DPBLENDCAPS_SRCALPHA) ) - v1 = 2; - if ( !(halCaps.dpcTriCaps.dwSrcBlendCaps & D3DPBLENDCAPS_ONE) ) - v1 |= 4; - if ( !(halCaps.dpcTriCaps.dwSrcBlendCaps & D3DPBLENDCAPS_ZERO) ) - v1 |= 8; - if ( !(halCaps.dpcTriCaps.dwDestBlendCaps & D3DPBLENDCAPS_INVSRCALPHA) ) - v1 |= 16; - if ( !(halCaps.dpcTriCaps.dwDestBlendCaps & D3DPBLENDCAPS_ONE) ) - v1 |= 32; - if ( !(halCaps.dpcTriCaps.dwDestBlendCaps & D3DPBLENDCAPS_SRCCOLOR) ) - v1 |= 64; - if ( halCaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_SQUAREONLY ) - v1 |= 128; - result = v1; - } - return result; -} - -//----- (0049E4FC) -------------------------------------------------------- -void RenderD3D::ClearTarget(unsigned int bClearColor, unsigned int uClearColor, unsigned int bClearDepth, float z_clear) -{ - uint uClearFlags = 0; - - if (bClearColor) - uClearFlags |= D3DCLEAR_TARGET; - if (bClearDepth) - uClearFlags |= D3DCLEAR_ZBUFFER; - - D3DRECT rects[] = {{0, 0, window->GetWidth(), window->GetHeight()}}; - if (uClearFlags) - pViewport->Clear2(1, rects, uClearFlags, uClearColor, z_clear, 0); -} - -//----- (0049E54D) -------------------------------------------------------- -void RenderD3D::Present(bool bForceBlit) -{ - RECT source_rect; // [sp+18h] [bp-18h]@1 - struct tagPOINT Point; // [sp+28h] [bp-8h]@4 - - source_rect.left = 0; - source_rect.top = 0; - source_rect.bottom = 480;//window->GetHeight(); //Ritor1: проблема с кнопкой "развернуть" - source_rect.right = 640; //window->GetWidth(); - - if (bWindowed || bForceBlit) - { - RECT dest_rect; - GetClientRect(hWindow, &dest_rect); - Point.y = 0; - Point.x = 0; - ClientToScreen(hWindow, &Point); - OffsetRect(&dest_rect, Point.x, Point.y); - pFrontBuffer->Blt(&dest_rect, pBackBuffer, &source_rect, DDBLT_WAIT, NULL); - } - else - pFrontBuffer->Flip(NULL, DDFLIP_WAIT); -} - -//----- (0049E5D4) -------------------------------------------------------- -bool RenderD3D::CreateTexture(unsigned int uTextureWidth, unsigned int uTextureHeight, IDirectDrawSurface4 **pOutSurface, IDirect3DTexture2 **pOutTexture, bool bAlphaChannel, bool bMipmaps, unsigned int uMinDeviceTexDim) -{ - unsigned int v9; // ebx@5 - unsigned int v10; // eax@5 - DWORD v11; // edx@5 - DDSURFACEDESC2 ddsd2; // [sp+Ch] [bp-80h]@1 - - memset(&ddsd2, 0, sizeof(ddsd2)); - ddsd2.dwSize = sizeof(ddsd2); - ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; - ddsd2.ddsCaps.dwCaps = DDSCAPS_TEXTURE; - ddsd2.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE; - ddsd2.dwHeight = uTextureHeight; - ddsd2.dwWidth = uTextureWidth; - if ( bMipmaps ) - { - if ( (signed int)uTextureHeight <= (signed int)uTextureWidth ) - { - ddsd2.dwMipMapCount = GetMaxMipLevels(uTextureHeight) - GetMaxMipLevels(uMinDeviceTexDim); - if ( ddsd2.dwMipMapCount ) - { - ddsd2.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT; - ddsd2.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP; - } - goto LABEL_12; - } - if ( (signed int)uTextureWidth < (signed int)uMinDeviceTexDim ) - { - ddsd2.dwMipMapCount = GetMaxMipLevels(uMinDeviceTexDim); - if ( ddsd2.dwMipMapCount ) - { - ddsd2.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT; - ddsd2.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP; - } - goto LABEL_12; - } - v9 = GetMaxMipLevels(uTextureWidth); - v10 = GetMaxMipLevels(uMinDeviceTexDim); - ddsd2.dwMipMapCount = v9 - v10; - if ( v9 == v10 ) - { - ddsd2.dwFlags = 0x1007; - __debugbreak(); // warning C4700: uninitialized local variable 'v11' used - ddsd2.ddsCaps.dwCaps = v11; - goto LABEL_12; - } - } - else - ddsd2.dwMipMapCount = 1; - ddsd2.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT; - ddsd2.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP; -LABEL_12: - ddsd2.ddpfPixelFormat.dwRGBBitCount = 16; - ddsd2.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); - if (bAlphaChannel) - { - ddsd2.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS; - ddsd2.ddpfPixelFormat.dwRBitMask = 0x7C00; - ddsd2.ddpfPixelFormat.dwGBitMask = 0x03E0; - ddsd2.ddpfPixelFormat.dwBBitMask = 0x001F; - ddsd2.ddpfPixelFormat.dwRGBAlphaBitMask = 0x8000; - } - else - { - ddsd2.ddpfPixelFormat.dwFlags = DDPF_RGB; - ddsd2.ddpfPixelFormat.dwRBitMask = 0xF800; - ddsd2.ddpfPixelFormat.dwGBitMask = 0x07E0; - ddsd2.ddpfPixelFormat.dwBBitMask = 0x001F; - ddsd2.ddpfPixelFormat.dwRGBAlphaBitMask = 0; - } - if (FAILED(pHost->CreateSurface(&ddsd2, pOutSurface, NULL))) - return false; - if (FAILED((*pOutSurface)->QueryInterface(IID_IDirect3DTexture2, (void **)pOutTexture))) - { - (*pOutSurface)->Release(); - *pOutSurface = 0; - return false; - } - return true; -} - -//----- (004A5190) -------------------------------------------------------- -void RenderD3D::HandleLostResources() -{ - pBitmaps_LOD->ReleaseLostHardwareTextures(); - pBitmaps_LOD->_410423_move_textures_to_device(); - pSprites_LOD->ReleaseLostHardwareSprites(); -} - -//----- (004A2050) -------------------------------------------------------- -void Render::DrawPolygon(unsigned int uNumVertices, struct Polygon *a3, ODMFace *a4, IDirect3DTexture2 *pTexture) -{ - unsigned int v6; // ebx@1 - int v8; // eax@7 - unsigned int v41; // eax@29 - //unsigned int v54; // [sp+5Ch] [bp-Ch]@3 - signed int a2; // [sp+64h] [bp-4h]@4 - - v6 = 0; - if ( this->uNumD3DSceneBegins && (signed int)uNumVertices >= 3 ) - { - //v54 = pGame->pLightmapBuilder->std__vector_000004_size; - if ( pGame->pLightmapBuilder->std__vector_000004_size) - a2 = -1; - pGame->AlterGamma_ODM(a4, &a2); - if ( byte_4D864C && pGame->uFlags & GAME_FLAGS_1_01_lightmap_related) - { - v8 = ::GetActorTintColor(a3->dimming_level, 0, array_50AC10[0].vWorldViewPosition.x, 0, 0); - pGame->pLightmapBuilder->DrawLightmaps(/*v8, 0*/); - } - else - { - if ( !pGame->pLightmapBuilder->std__vector_000004_size || byte_4D864C && pGame->uFlags & 2 ) - { - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CW)); - if (bUsingSpecular) - { - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); - } - for (uint i = 0; i < uNumVertices; ++i) - { - - d3d_vertex_buffer[i].pos.x = array_50AC10[i].vWorldViewProjX; - d3d_vertex_buffer[i].pos.y = array_50AC10[i].vWorldViewProjY; - d3d_vertex_buffer[i].pos.z = 1.0 - 1.0 / ((array_50AC10[i].vWorldViewPosition.x * 1000) / (double)pODMRenderParams->shading_dist_mist); - d3d_vertex_buffer[i].rhw = 1.0 / (array_50AC10[i].vWorldViewPosition.x + 0.0000001); - d3d_vertex_buffer[i].diffuse = ::GetActorTintColor(a3->dimming_level, 0, array_50AC10[i].vWorldViewPosition.x, 0, 0); - pGame->AlterGamma_ODM(a4, &d3d_vertex_buffer[i].diffuse); - - if ( this->bUsingSpecular ) - d3d_vertex_buffer[i].specular = sub_47C3D7_get_fog_specular(0, 0, array_50AC10[i].vWorldViewPosition.x); - else - d3d_vertex_buffer[i].specular = 0; - d3d_vertex_buffer[i].texcoord.x = array_50AC10[i].u; - d3d_vertex_buffer[i].texcoord.y = array_50AC10[i].v; - - } - - if (a4->uAttributes & FACE_OUTLINED) - { - int color; - if (GetTickCount() % 300 >= 150) - color = 0xFFFF2020; - else color = 0xFF901010; - - for (uint i = 0; i < uNumVertices; ++i) - d3d_vertex_buffer[i].diffuse = color; - } - - pRenderD3D->pDevice->SetTexture(0, pTexture); - pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, - D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, - d3d_vertex_buffer, - uNumVertices, - D3DDP_DONOTLIGHT); - } - else - { - for (uint i = 0; i < uNumVertices; ++i) - { - - d3d_vertex_buffer[i].pos.x = array_50AC10[i].vWorldViewProjX; - d3d_vertex_buffer[i].pos.y = array_50AC10[i].vWorldViewProjY; - d3d_vertex_buffer[i].pos.z = 1.0 - 1.0 / ((array_50AC10[i].vWorldViewPosition.x * 1000) / (double)pODMRenderParams->shading_dist_mist); - d3d_vertex_buffer[i].rhw = 1.0 / (array_50AC10[i].vWorldViewPosition.x + 0.0000001); - d3d_vertex_buffer[i].diffuse = GetActorTintColor(a3->dimming_level, 0, array_50AC10[i].vWorldViewPosition.x, 0, 0); - if ( this->bUsingSpecular ) - d3d_vertex_buffer[i].specular = sub_47C3D7_get_fog_specular(0, 0, array_50AC10[i].vWorldViewPosition.x); - else - d3d_vertex_buffer[i].specular = 0; - d3d_vertex_buffer[i].texcoord.x = array_50AC10[i].u; - d3d_vertex_buffer[i].texcoord.y = array_50AC10[i].v; - - } - - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); - if (bUsingSpecular) - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE)); - - ErrD3D(pRenderD3D->pDevice->SetTexture(0, nullptr)); - ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, - D3DFVF_XYZRHW | D3DFVF_TEX1 | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, - d3d_vertex_buffer, - uNumVertices, - D3DDP_DONOTLIGHT)); - //v50 = (const char *)v5->pRenderD3D->pDevice; - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE)); - //(*(void (**)(void))(*(int *)v50 + 88))(); - pGame->pLightmapBuilder->DrawLightmaps(/*-1, 0*/); - for (uint i = 0; i < uNumVertices; ++i) - { - d3d_vertex_buffer[i].diffuse = a2; - } - ErrD3D(pRenderD3D->pDevice->SetTexture(0, pTexture)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); - if ( !pRenderer->bUsingSpecular ) - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); - - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ZERO)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_SRCCOLOR)); - ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, - D3DFVF_XYZRHW | D3DFVF_TEX1 | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, - d3d_vertex_buffer, - uNumVertices, - D3DDP_DONOTLIGHT)); - if (bUsingSpecular) - { - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); - - for (uint i = 0; i < uNumVertices; ++i) - { - d3d_vertex_buffer[i].diffuse = pRenderer->uFogColor | d3d_vertex_buffer[i].specular & 0xFF000000; - d3d_vertex_buffer[i].specular = 0; - } - - ErrD3D(pRenderD3D->pDevice->SetTexture(0, nullptr)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_INVSRCALPHA)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_SRCALPHA)); - ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, - D3DFVF_XYZRHW | D3DFVF_TEX1 | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, - d3d_vertex_buffer, - uNumVertices, - D3DDP_DONOTLIGHT)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE)); - //v40 = pRenderer->pRenderD3D->pDevice->lpVtbl; - v41 = GetLevelFogColor(); - pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, GetLevelFogColor() & 0xFFFFFF); - v6 = 0; - pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, 0); - } - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, v6)); - } - } - } -} -// 4D864C: using guessed type char byte_4D864C; - -//----- (0049EB79) -------------------------------------------------------- -Render::~Render() -{ - free(this->pDefaultZBuffer); - this->pD3DBitmaps.Release(); - this->pD3DSprites.Release(); - Release(); - this->bWindowMode = 1; - //nullsub_1(); - //nullsub_1(); -} - - -//----- (0049E992) -------------------------------------------------------- -Render::Render() -{ - //Render *v1; // esi@1 -// int v2; // eax@1 -// char v3; // zf@1 - - //v1 = this; - this->pDirectDraw4 = nullptr; - this->pFrontBuffer4 = nullptr; - this->pBackBuffer4 = nullptr; - //this->pColorKeySurface4 = 0; - //this->pDirectDraw2 = 0; - //this->pFrontBuffer2 = 0; - //this->pBackBuffer2 = 0; - //this->pSomeSurface2 = 0; - //RenderHWLContainer::RenderHWLContainer(&this->pD3DBitmaps); - //RenderHWLContainer::RenderHWLContainer(&v1->pD3DSprites); - this->bWindowMode = 1; - //this->field_40054 = 0; - //this->field_10 = 640; - //this->field_14 = 480; - //this->field_40030 = 0; - //this->field_4002C = 0; - this->pActiveZBuffer = nullptr; - this->pDefaultZBuffer = nullptr; - this->raster_clip_y = 0; - this->raster_clip_x = 0; - this->raster_clip_z = 639; - this->raster_clip_w = 479; - //this->field_4003C = 0x004EED80; - //this->field_40040 = dword_4EED78; - this->uClipZ = 640; - //this->field_40044 = 2; - //this->field_40048 = 6; - this->pFrontBuffer4 = nullptr; - this->pBackBuffer4 = nullptr; - //this->pColorKeySurface4 = 0; - this->pDirectDraw4 = nullptr; - this->pRenderD3D = 0; - this->uNumSceneBegins = 0; - this->uNumD3DSceneBegins = 0; - this->using_software_screen_buffer = 0; - this->pTargetSurface = nullptr; - this->uTargetSurfacePitch = 0; - this->uClipY = 0; - this->uClipX = 0; - this->uClipW = 480; - this->bClip = 1; - //this->bColorKeySupported = 0; - this->bRequiredTextureStagesAvailable = 0; - this->bTinting = 1; - //LOBYTE(this->field_103668) = 0; - uNumBillboardsToDraw = 0; - bFogEnabled = false; - - hd_water_tile_id = -1; - hd_water_current_frame = 0; -} - -bool Render::Initialize(OSWindow *window/*, bool bColoredLights, uint32_t uDetailLevel, bool bTinting*/) -{ - //bUserDirect3D = true;//ReadWindowsRegistryInt("Use D3D", 0); - - this->window = window; - //bStartInWindow = true; - //windowed_mode_width = windowed_width; - //windowed_mode_height = windowed_height; - - uDesiredDirect3DDevice = ReadWindowsRegistryInt("D3D Device", 0); - - bUseColoredLights = ReadWindowsRegistryInt("Colored Lights", false); - uLevelOfDetail = ReadWindowsRegistryInt("Detail Level", 1); - bTinting = ReadWindowsRegistryInt("Tinting", 1) != 0; - - bool r1 = pD3DBitmaps.Load(L"data\\d3dbitmap.hwl"); - bool r2 = pD3DSprites.Load(L"data\\d3dsprite.hwl"); - - return r1 && r2; -} - - -//----- (0049ECC4) -------------------------------------------------------- -void Render::ClearBlack() -{ - //if (pRenderD3D) - { - if (using_software_screen_buffer) - pRenderD3D->ClearTarget(true, 0, false, 0.0); - } - //else - //memset(pRenderer->pTargetSurface, 0, 4 * (field_10 * field_14 / 2)); -} - -//----- (0049ED18) -------------------------------------------------------- -void Render::PresentBlackScreen() -{ - IDirectDrawSurface *lpddsback; // eax@3 - DDBLTFX lpDDBltFx; // [sp+4h] [bp-74h]@5 - RECT dest_rect; // [sp+68h] [bp-10h]@3 - - memset(&lpDDBltFx, 0, sizeof(DDBLTFX)); - lpDDBltFx.dwSize = sizeof(DDBLTFX); - - GetWindowRect(window->GetApiHandle(), &dest_rect); - lpddsback = (IDirectDrawSurface *)this->pBackBuffer4; - - lpDDBltFx.dwFillColor = 0; - lpddsback->Blt(&dest_rect, NULL, NULL, DDBLT_COLORFILL, &lpDDBltFx); - pRenderer->Present(); -} - -//----- (0049EDB6) -------------------------------------------------------- -void Render::SavePCXScreenshot() -{ - int v5; // eax@8 - FILE *pOutFile; // edi@10 - unsigned short *v8; // eax@11 - signed int v12; // eax@18 - char v15[56]; // [sp+Ch] [bp-158h]@10 - DDSURFACEDESC2 Dst; // [sp+48h] [bp-11Ch]@7 - char color_map[48]; // [sp+C4h] [bp-A0h]@10 - char Filename[40]; // [sp+F4h] [bp-70h]@3 - char *lineB; // [sp+11Ch] [bp-48h]@14 - char *lineG; // [sp+120h] [bp-44h]@14 - FILE *File; // [sp+128h] [bp-3Ch]@3 - PCXHeader_1 header1; // [sp+130h] [bp-34h]@10 - PCXHeader_2 header2; // [sp+140h] [bp-24h]@10 - char *lineRGB; // [sp+148h] [bp-1Ch]@10 - void *surface; // [sp+14Ch] [bp-18h]@8 - unsigned int image_width; // [sp+150h] [bp-14h]@4 - int pitch; // [sp+154h] [bp-10h]@4 - char v31; // [sp+15Ah] [bp-Ah]@25 - unsigned char pict_byte; // [sp+15Bh] [bp-9h]@17 - unsigned short *line_picture_data; // [sp+15Ch] [bp-8h]@10 - byte test_byte; // [sp+163h] [bp-1h]@17 - - int num_r_bits = 5; - int num_g_bits = 6; - int num_b_bits = 5; - - int r_mask = 0xF800; - int g_mask = 0x7E0; - int b_mask = 0x1F; - - if ( !this->pRenderD3D || this->using_software_screen_buffer ) - { - sprintf(Filename, "screen%0.2i.pcx", ScreenshotFileNumber++ % 100); - File = fopen(Filename, "wb"); - if ( File ) - { - pitch = this->GetRenderWidth(); - if ( pitch & 1 ) - pitch = pitch + 1; - if ( this->pRenderD3D ) - { - memset(&Dst, 0, sizeof(Dst)); - Dst.dwSize = sizeof(Dst); - if ( !pRenderer->LockSurface_DDraw4(pRenderer->pBackBuffer4, &Dst, DDLOCK_WAIT) ) - return; - surface = Dst.lpSurface; - v5 = Dst.lPitch / 2; - } - else - { - pRenderer->BeginScene(); - surface = pRenderer->pTargetSurface; - v5 = pRenderer->uTargetSurfacePitch; - } - header1.right = GetRenderWidth() - 1; - header1.left = 0; - header1.bottom = this->GetRenderHeight() - 1; - header1.up = 0; - header2.pitch = pitch; - memset(color_map, 0, sizeof(color_map)); - memset(v15, 0, sizeof(v15)); - header2.reserved = 0; - header1.manufacturer = 10; - pOutFile = File; - header1.version = 5; - header1.encoding = 1; - header1.bpp = 8; - header1.hdpi = 75; - header1.vdpi = 75; - header2.planes = 3; - header2.palette_info = 1; - fwrite(&header1, 1, 1, File); - fwrite(&header1.version, 1, 1, pOutFile); - fwrite(&header1.encoding, 1, 1, pOutFile); - fwrite(&header1.bpp, 1, 1, pOutFile); - fwrite(&header1.left, 2, 1, pOutFile); - fwrite(&header1.up, 2, 1, pOutFile); - fwrite(&header1.right, 2, 1, pOutFile); - fwrite(&header1.bottom, 2, 1, pOutFile); - fwrite(&header1.hdpi, 2, 1, pOutFile); - fwrite(&header1.vdpi, 2, 1, pOutFile); - fwrite(color_map, 0x30, 1, pOutFile); - fwrite(&header2, 1, 1, pOutFile); - fwrite(&header2.planes, 1, 1, pOutFile); - fwrite(&header2.pitch, 2, 1, pOutFile); - fwrite(&header2.palette_info, 2, 1, pOutFile); - fwrite(v15, 0x3Au, 1, pOutFile); - lineRGB = (char *)malloc(3 * GetRenderWidth() + 6); - if ( this->GetRenderHeight() > 0 ) - { - image_width = 3 * pitch; - //v24 = 2 * v5; - v8 = (unsigned short *)surface; - for ( unsigned int y = 0; y < this->GetRenderHeight(); y++ ) - { - line_picture_data = v8; - if ( GetRenderWidth() > 0 ) - { - lineG = (char *)lineRGB + pitch; - lineB = (char *)lineRGB + 2 * pitch; - for ( uint x = 0; x < this->GetRenderWidth(); x++ ) - { - //int p = *line_picture_data; //0x2818 - //int for_rad = (pRenderer->uTargetGBits + pRenderer->uTargetBBits );//16 = 8 + 8 - //int value = (pRenderer->uTargetRMask & *line_picture_data);//0 = 0xFF0000 & 0x2818 - //int result = (pRenderer->uTargetRMask & *line_picture_data) >> (pRenderer->uTargetGBits + pRenderer->uTargetBBits ); - lineRGB[x] = (uTargetRMask & *line_picture_data) >> (uTargetGBits + uTargetBBits );// + pRenderer->uTargetRBits - 8); - lineG[x] = (uTargetGMask & *line_picture_data) >> (uTargetBBits);// + pRenderer->uTargetGBits - 8); - //int value2 = (pRenderer->uTargetGMask & *line_picture_data); //10240 = 0xFF00 & 0x2818 - //int result2 = (pRenderer->uTargetGMask & *line_picture_data) >> (pRenderer->uTargetBBits); - lineB[x] = (uTargetBMask & *line_picture_data);// << (8 - pRenderer->uTargetBBits); - //int value3 = (pRenderer->uTargetBMask & *line_picture_data);//24 = 0xFF & 0x2818 - line_picture_data += 2; - } - } - for ( uint i = 0; i < image_width; i += test_byte ) - { - pict_byte = lineRGB[i]; - for ( test_byte = 1; test_byte < 0x3F; ++test_byte ) - { - v12 = i + test_byte; - if ( lineRGB[v12] != pict_byte ) - break; - if ( !(v12 % pitch) ) - break; - } - if ( i + test_byte > image_width ) - test_byte = 3 * pitch - i; - if ( test_byte > 1 || pict_byte >= 0xC0 ) - { - v31 = test_byte | 0xC0; - fwrite(&v31, 1, 1, pOutFile); - } - fwrite(&pict_byte, 1, 1, pOutFile); - } - v8 += v5; - } - } - if ( this->pRenderD3D ) - ErrD3D(pRenderer->pBackBuffer4->Unlock(NULL)); - else - pRenderer->EndScene(); - - free(lineRGB); - fclose(pOutFile); - } - } -} - -//----- (0049F1BC) -------------------------------------------------------- -void Render::SaveWinnersCertificate(const char *a1) -{ - unsigned int v6; // eax@8 - //FILE *v7; // edi@10 -// int v8; // ecx@11 - unsigned short *v9; // eax@11 - int v10; // eax@13 - signed int v13; // eax@18 -// char v14; // zf@27 -// HRESULT v15; // eax@29 - char v16[56]; // [sp+Ch] [bp-12Ch]@10 - __int16 v17; // [sp+44h] [bp-F4h]@10 - DDSURFACEDESC2 Dst; // [sp+48h] [bp-F0h]@7 -// int v19; // [sp+58h] [bp-E0h]@8 -// unsigned __int16 *v20; // [sp+6Ch] [bp-CCh]@8 - char color_map[48]; // [sp+C4h] [bp-74h]@10 -// unsigned int v22; // [sp+F4h] [bp-44h]@11 - char *lineB; // [sp+F8h] [bp-40h]@14 - int image_width; // [sp+FCh] [bp-3Ch]@11 - int v25; // [sp+100h] [bp-38h]@4 - FILE *File; // [sp+104h] [bp-34h]@3 - char Str; // [sp+108h] [bp-30h]@10 - char v28; // [sp+109h] [bp-2Fh]@10 - char v29; // [sp+10Ah] [bp-2Eh]@10 - char v30; // [sp+10Bh] [bp-2Dh]@10 - __int16 v31; // [sp+10Ch] [bp-2Ch]@10 - __int16 v32; // [sp+10Eh] [bp-2Ah]@10 - __int16 v33; // [sp+110h] [bp-28h]@10 - __int16 v34; // [sp+112h] [bp-26h]@10 - __int16 v35; // [sp+114h] [bp-24h]@10 - __int16 v36; // [sp+116h] [bp-22h]@10 - char v37; // [sp+118h] [bp-20h]@10 - char v38; // [sp+119h] [bp-1Fh]@10 - __int16 v39; // [sp+11Ah] [bp-1Eh]@10 - __int16 v40; // [sp+11Ch] [bp-1Ch]@10 - char *lineRGB; // [sp+120h] [bp-18h]@10 - void *surface; // [sp+124h] [bp-14h]@8 - int pitch; // [sp+128h] [bp-10h]@4 - char v44; // [sp+12Fh] [bp-9h]@25 - char *lineG; // [sp+130h] [bp-8h]@10 - unsigned char pict_byte; // [sp+137h] [bp-1h]@17 - byte test_byte; - - int num_r_bits = 5; - int num_g_bits = 6; - int num_b_bits = 5; - - int r_mask = 0xF800; - int g_mask = 0x7E0; - int b_mask = 0x1F; - - if ( !this->pRenderD3D || this->using_software_screen_buffer ) - { - static int _4EFA84_num_winners_certificates = 0; - ++_4EFA84_num_winners_certificates; - - File = fopen(a1, "wb"); - if ( File ) - { - v25 = this->GetRenderWidth(); - pitch = v25; - if ( pitch & 1 ) - pitch = pitch + 1; - if ( this->pRenderD3D ) - { - memset(&Dst, 0, 0x7C); - Dst.dwSize = 124; - if ( !pRenderer->LockSurface_DDraw4(pRenderer->pBackBuffer4, (DDSURFACEDESC2 *)&Dst, DDLOCK_WAIT) ) - return; - surface = Dst.lpSurface; - v6 = Dst.lPitch / 2; - } - else - { - pRenderer->BeginScene(); - surface = pRenderer->pTargetSurface; - v6 = pRenderer->uTargetSurfacePitch; - } - v33 = this->GetRenderWidth() - 1; - v31 = 0; - v34 = (short)this->GetRenderHeight() - 1; - v32 = 0; - v39 = pitch; - memset(&color_map, 0, sizeof(color_map)); - memset(&v16, 0, sizeof(v16)); - v37 = 0; - Str = 10; - v17 = 0; - v28 = 5; - v29 = 1; - v30 = 8; - v35 = 75; - v36 = 75; - v38 = 3; - v40 = 1; - fwrite(&Str, 1, 1, File); - fwrite(&v28, 1, 1, File); - fwrite(&v29, 1, 1, File); - fwrite(&v30, 1, 1, File); - fwrite(&v31, 2, 1, File); - fwrite(&v32, 2, 1, File); - fwrite(&v33, 2, 1, File); - fwrite(&v34, 2, 1, File); - fwrite(&v35, 2, 1, File); - fwrite(&v36, 2, 1, File); - fwrite(&color_map, 0x30, 1, File); - fwrite(&v37, 1, 1, File); - fwrite(&v38, 1, 1, File); - fwrite(&v39, 2, 1, File); - fwrite(&v40, 2, 1, File); - fwrite(&v16, 0x3A, 1, File); - lineRGB = (char *)malloc(3 * (v25 + 2)); - if ( (signed int)this->GetRenderHeight() > 0 ) - { - image_width = 3 * pitch; - v9 = (unsigned short *)surface; - for ( uint j = 0; j < this->GetRenderHeight(); j++) - { - a1 = (const char *)v9; - if ( v25 > 0 ) - { - lineG = (char *)lineRGB + pitch; - lineB = (char *)lineRGB + 2 * pitch; - for ( v10 = 0; v10 < v25; v10++ ) - { - lineRGB[v10] = (signed int)(r_mask & *(short *)a1) >> (num_g_bits + num_b_bits + num_r_bits - 8); - lineG[v10] = (signed int)(g_mask & *(short *)a1) >> (num_b_bits + num_g_bits - 8); - lineB[v10] = (b_mask & *(short *)a1) << (8 - num_b_bits); - a1 += 2; - } - } - for ( uint i = 0; i < image_width; i += test_byte ) - { - pict_byte = lineRGB[i]; - for ( test_byte = 1; test_byte < 0x3F; test_byte ) - { - v13 = i + test_byte; - if ( lineRGB[v13] != pict_byte ) - break; - if ( !(v13 % pitch) ) - break; - } - if ( i + test_byte > image_width ) - test_byte = 3 * pitch - i; - if ( test_byte > 1 || pict_byte >= 0xC0 ) - { - v44 = test_byte | 0xC0; - fwrite(&v44, 1, 1, File); - } - fwrite(&pict_byte, 1, 1, File); - } - v9 += pitch; - } - } - if ( this->pRenderD3D ) - ErrD3D(pRenderer->pBackBuffer4->Unlock(NULL)); - else - pRenderer->EndScene(); - free(lineRGB); - fclose(File); - } - } -} - -//----- (0049F5A2) -------------------------------------------------------- -void Render::PackPCXpicture( unsigned short* picture_data, int wight, int heidth, void *data_buff, int max_buff_size,unsigned int* packed_size ) -{ - void *v8; // esi@3 - void *v9; // esi@3 - unsigned short* v11; // eax@4 -// int v13; // eax@8 -// int v14; // ecx@8 - signed int v15; // eax@11 -// char v16; // zf@20 -// int result; // eax@21 - char v18[58]; // [sp+Ch] [bp-ACh]@3 - char v20[48]; // [sp+48h] [bp-70h]@3 - char *lineG; // [sp+78h] [bp-40h]@7 - char *lineB; // [sp+7Ch] [bp-3Ch]@7 - int v23; // [sp+80h] [bp-38h]@4 - int v24; // [sp+84h] [bp-34h]@4 - int v25; // [sp+88h] [bp-30h]@4 - int v26; // [sp+8Ch] [bp-2Ch]@4 - PCXHeader_1 Src; // [sp+90h] [bp-28h]@3 - PCXHeader_2 v27; // [sp+A0h] [bp-18h]@3 - char *lineRGB; // [sp+A8h] [bp-10h]@3 - int pitch; // [sp+ACh] [bp-Ch]@1 - char v43; // [sp+B3h] [bp-5h]@18 - int i; // [sp+B4h] [bp-4h]@6 - unsigned short* line_picture_data; - byte test_byte; - unsigned char pict_byte; - - int num_r_bits = 5; - int num_g_bits = 6; - int num_b_bits = 5; - - int r_mask = 0xF800; - int g_mask = 0x7E0; - int b_mask = 0x1F; - - pitch = wight; - if ( wight & 1 ) - pitch = wight + 1; - Src.left = 0; - Src.up = 0; - Src.right = wight - 1; - Src.bottom = heidth - 1; - v27.pitch = pitch; - memset(&v20, 0, 0x30u); - memset(&v18, 0, 0x38u); - v8 = data_buff; - v27.reserved = 0; - *(_WORD *)&v18[56] = 0; - Src.manufacturer = 10; - Src.version = 5; - Src.encoding = 1; - Src.bpp = 8; - Src.hdpi = 75; - Src.vdpi = 75; - v27.planes = 3; - v27.palette_info = 1; - memcpy(data_buff, &Src, 1); - v8 = (char *)v8 + 1; - memcpy(v8, &Src.version, 1); - v8 = (char *)v8 + 1; - memcpy(v8, &Src.encoding, 1); - v8 = (char *)v8 + 1; - memcpy(v8, &Src.bpp, 1); - v8 = (char *)v8 + 1; - memcpy(v8, &Src.left, 2); - v8 = (char *)v8 + 2; - memcpy(v8, &Src.up, 2); - v8 = (char *)v8 + 2; - memcpy(v8, &Src.right, 2); - v8 = (char *)v8 + 2; - memcpy(v8, &Src.bottom, 2); - v8 = (char *)v8 + 2; - memcpy(v8, &Src.hdpi, 2); - v8 = (char *)v8 + 2; - memcpy(v8, &Src.vdpi, 2); - v8 = (char *)v8 + 2; - memcpy(v8, &v20, 0x30u); - v8 = (char *)v8 + 48; - memcpy(v8, &v27, 1u); - v8 = (char *)v8 + 1; - memcpy(v8, &v27.planes, 1); - v8 = (char *)v8 + 1; - memcpy(v8, &v27.pitch, 2); - v8 = (char *)v8 + 2; - memcpy(v8, &v27.palette_info, 2); - v8 = (char *)v8 + 2; - memcpy(v8, &v18, 0x3Au); - v9 = (char *)v8 + 58; - - lineRGB = (char*)malloc(3 * (wight + 2)); - if ( heidth > 0 ) - { - v26 = 3 * pitch; - v23 = 2 * wight; - v11 = picture_data; - v24 = (int)picture_data; - for ( v25 = heidth; v25; v25-- ) - { - line_picture_data = v11; - if ( wight > 0 ) - { - lineG = (char *)lineRGB + pitch; - lineB = (char *)lineRGB + 2 * pitch; - for ( uint i = 0; i < wight; i++ ) - { - lineRGB[i] = (signed int)(r_mask & *line_picture_data) >> (num_g_bits + num_b_bits + num_r_bits - 8); - lineG[i] = (signed int)(g_mask & *line_picture_data) >> ( num_b_bits + num_g_bits- 8); - lineB[i] = (b_mask & *line_picture_data) << (8 - num_b_bits); - line_picture_data += 1; - } - } - for ( i = 0; i < v26; v9 = (char *)v9 + 1 ) - { - pict_byte = lineRGB[i]; - for ( test_byte = 1; test_byte < 63; ++test_byte ) - { - v15 = i + test_byte; - if ( lineRGB[v15] != pict_byte )//Uninitialized memory access - break; - if ( !(v15 % pitch) ) - break; - } - if ( i + test_byte > v26 ) - test_byte = 3 * pitch - i; - if ( test_byte > 1 || pict_byte >= 192 ) - { - v43 = test_byte | 0xC0; - memcpy(v9, &v43, 1); - v9 = (char *)v9 + 1; - } - memcpy(v9, &pict_byte, 1); - i += test_byte; - } - v11 += wight; - } - } - free(lineRGB); - *(int *)packed_size = (char *)v9 - data_buff; -} - -//----- (0049F8B5) -------------------------------------------------------- -void Render::SavePCXImage(const char *Filename, unsigned short* picture_data, int width, int height) -{ - FILE *result; // eax@1 - FILE *pOutFile; // edi@4 - unsigned short* v9; // eax@5 -// int v10; // eax@7 - signed int v12; // eax@12 -// char v13; // zf@21 - char v14[56]; // [sp+4h] [bp-A0h]@4 - __int16 v15; // [sp+3Ch] [bp-68h]@4 - char color_map[48]; // [sp+40h] [bp-64h]@4 - int v18; // [sp+74h] [bp-30h]@5 -// char *v19; // [sp+78h] [bp-2Ch]@5 - int image_width; // [sp+7Ch] [bp-28h]@5 - PCXHeader_1 header1; // [sp+80h] [bp-24h]@4 - PCXHeader_2 header2; // [sp+90h] [bp-14h]@4 - char *lineRGB; // [sp+98h] [bp-Ch]@4 - int pitch; // [sp+9Ch] [bp-8h]@2 - char *lineB; // [sp+A0h] [bp-4h]@8 - char *lineG; - unsigned short* line_pictute_data; - byte test_byte; - char v43; - - int num_r_bits = 5; - int num_g_bits = 6; - int num_b_bits = 5; - - int r_mask = 0xF800; - int g_mask = 0x7E0; - int b_mask = 0x1F; - - result = fopen(Filename, "wb"); - Filename = (const char *)result; - if ( result ) - { - pitch = width; - if ( width & 1 ) - pitch = width + 1; - header1.left = 0; - header1.up = 0; - header1.right = width - 1; - header1.bottom = height - 1; - header2.pitch = pitch; - memset(color_map, 0, sizeof(color_map)); - header2.reserved = 0; - memset(v14, 0, sizeof(v14)); - v15 = 0; - header1.manufacturer = 10; - header1.version = 5; - header1.encoding = 1; - header1.bpp = 8; - header1.hdpi = 75; - header1.vdpi = 75; - header2.planes = 3; - header2.palette_info = 1; - fwrite(&header1, 1, 1, (FILE *)Filename); - pOutFile = (FILE *)Filename; - fwrite(&header1.version, 1, 1, (FILE *)Filename); - fwrite(&header1.encoding, 1, 1, pOutFile); - fwrite(&header1.bpp, 1, 1, pOutFile); - fwrite(&header1.left, 2, 1, pOutFile); - fwrite(&header1.up, 2, 1, pOutFile); - fwrite(&header1.right, 2, 1, pOutFile); - fwrite(&header1.bottom, 2, 1, pOutFile); - fwrite(&header1.hdpi, 2, 1, pOutFile); - fwrite(&header1.vdpi, 2, 1, pOutFile); - fwrite(color_map, 0x30u, 1, pOutFile); - fwrite(&header2, 1, 1, pOutFile); - fwrite(&header2.planes, 1, 1, pOutFile); - fwrite(&header2.pitch, 2, 1, pOutFile); - fwrite(&header2.palette_info, 2, 1, pOutFile); - fwrite(v14, 0x3Au, 1, pOutFile); - - lineRGB = (char *)malloc(3 * (width + 2)); - //При сохранении изображения подряд идущие пиксели одинакового цвета объединяются и вместо указания цвета для каждого пикселя - //указывается цвет группы пикселей и их количество. - image_width = 3 * pitch; - v9 = picture_data; - for ( v18 = 0; v18 < height; v18++ )//столбец - { - line_pictute_data = v9; - lineG = (char *)lineRGB + pitch; - lineB = (char *)lineRGB + 2 * pitch; - - for ( int i = 0; i < width; i++ )//строка - { - lineRGB[i] = (signed int)(r_mask & *line_pictute_data) >> (num_g_bits + num_b_bits + num_r_bits - 8); - lineG[i] = (signed int)(g_mask & *line_pictute_data) >> (num_b_bits + num_g_bits - 8); - lineB[i] = (b_mask & *line_pictute_data) << (8 - num_b_bits); - line_pictute_data += 1; - } - test_byte = 1; - for ( int i = 0; (signed int)i < image_width; i += test_byte ) - { - unsigned char pic_byte = lineRGB[i]; - for ( test_byte; test_byte < 63; ++test_byte )// расчёт количества одинаковых цветов - { - v12 = i + test_byte; - if ( lineRGB[v12] != pic_byte ) - break; - if ( !(v12 % pitch) ) - break; - } - if ( i + test_byte > image_width ) - test_byte = 3 * pitch - i; - if ( test_byte > 1 || pic_byte >= 0xC0 ) - { - v43 = test_byte | 0xC0;//тест-байт объединения - fwrite(&v43, 1, 1, pOutFile); - } - fwrite(&pic_byte, 1, 1, pOutFile); - } - v9 += width; - } - free(lineRGB); - fclose(pOutFile); - } -} - -//----- (0049FBCD) -------------------------------------------------------- -void Render::ClearTarget(unsigned int uColor) -{ - //if (pRenderD3D) - { - if (using_software_screen_buffer) - pRenderD3D->ClearTarget(true, uColor, false, 0.0); - } - //else - //memset32(pTargetSurface, uColor, field_10 * field_14 / 2); -} - - -//----- (0049FC37) -------------------------------------------------------- -void Render::Present() -{ - //struct tagRECT Rect; // [sp+8h] [bp-28h]@11 - //RECT a4; // [sp+18h] [bp-18h]@11 - //struct tagPOINT Point; // [sp+28h] [bp-8h]@11 - - if ( !pRenderD3D || this->using_software_screen_buffer ) - { - this->pBeforePresentFunction(); - if ( this->pRenderD3D ) - { - if ( this->using_software_screen_buffer ) - pRenderD3D->Present(false); - } - else - __debugbreak(); // no sr - /*{ - if ( this->bWindowMode ) - { - RestoreFrontBuffer(); - GetClientRect(this->hWnd, &Rect); - Point.y = 0; - Point.x = 0; - ClientToScreen(this->hWnd, &Point); - OffsetRect(&Rect, Point.x, Point.y); - a4.top = 0; - a4.bottom = 480; - a4.left = 0; - a4.right = 640; - PresentRect(&Rect, &a4); - } - else - { - RestoreFrontBuffer(); - a4.top = 0; - a4.bottom = 480; - a4.left = 0; - a4.right = 640; - BltBackToFontFast(0, 0, &a4); - } - }*/ - } -} - -//----- (0049FD3A) -------------------------------------------------------- -void Render::_49FD3A_fullscreen() -{ - RECT src_rect; // [sp+8h] [bp-10h]@6 - - if ( this->pRenderD3D ) - { - if (pFrontBuffer4->IsLost() == DDERR_SURFACELOST) - pFrontBuffer4->Restore(); - if (pBackBuffer4->IsLost() == DDERR_SURFACELOST) - pBackBuffer4->Restore(); - src_rect.top = 0; - src_rect.bottom = window->GetHeight(); - src_rect.left = 0; - src_rect.right = window->GetWidth(); - this->pBackBuffer4->BltFast(NULL, NULL, this->pFrontBuffer4, &src_rect, DDBLTFAST_WAIT); - } -} - -//----- (0049FDBF) -------------------------------------------------------- -void Render::CreateZBuffer() -{ - if (!pDefaultZBuffer) - { - pDefaultZBuffer = pActiveZBuffer = (int *)malloc(0x12C000); - memset32(pActiveZBuffer, 0xFFFF0000, 0x4B000u); // // inlined Render::ClearActiveZBuffer (mm8::004A085B) - } -} - -//----- (0049FE05) -------------------------------------------------------- -void Render::Release() -{ - //Render *v1; // esi@1 - //RenderD3D *v2; // ecx@1 - //char v3; // zf@4 - //void *v4; // ebx@6 -// IDirectDraw *v5; // eax@10 -// IDirectDrawSurface2 *v6; // eax@11 -// IDirectDrawSurface2 *v7; // eax@13 -// IDirectDrawSurface2 *v8; // eax@15 -// IDirectDraw2 *v9; // eax@17 -// IDirectDraw4 *v10; // eax@19 -// IDirectDrawSurface4 *v11; // eax@20 -// IDirectDrawSurface4 *v12; // eax@22 -// IDirectDrawSurface4 *v13; // eax@24 -// IDirectDraw4 *v14; // eax@26 -// unsigned __int16 **v15; // ebx@28 -// void **v16; // esi@29 - - // v1 = this; - if (pRenderD3D) - { - if ( this->using_software_screen_buffer ) - { - pRenderD3D->ClearTarget(true, 0, false, 1.0); - pRenderD3D->Present(0); - pRenderD3D->ClearTarget(true, 0, false, 1.0); - } - //this->pColorKeySurface4 = 0; - this->pBackBuffer4 = nullptr; - this->pFrontBuffer4 = nullptr; - this->pDirectDraw4 = nullptr; - delete [] this->pTargetSurface_unaligned; - this->pTargetSurface = nullptr; - this->pTargetSurface_unaligned = nullptr; - if (pRenderD3D) - { - pRenderD3D->Release(); - delete pRenderD3D; - } - pRenderD3D = nullptr; - } - else - ;//__debugbreak(); // no sr - /*{ - if ( bWinNT4_0 == 1 ) - { - v5 = (IDirectDraw *)this->pDirectDraw2; - if ( !v5 ) - return; - v5->SetCooperativeLevel(this->hWnd, 8u); - this->pDirectDraw2->FlipToGDISurface(); - v6 = this->pSomeSurface2; - if ( v6 ) - { - v6->Release(); - this->pSomeSurface2 = 0; - } - v7 = this->pBackBuffer2; - if ( v7 ) - { - v7->Release(); - this->pBackBuffer2 = 0; - } - v8 = this->pFrontBuffer2; - if ( v8 ) - { - v8->Release(); - this->pFrontBuffer2 = 0; - } - v9 = this->pDirectDraw2; - if ( v9 ) - { - v9->Release(); - this->pDirectDraw2 = 0; - } - } - else - { - v10 = this->pDirectDraw4; - if ( !v10 ) - return; - v10->SetCooperativeLevel(this->hWnd, 1032u); - this->pDirectDraw4->FlipToGDISurface(); - v11 = this->pColorKeySurface4; - if ( v11 ) - { - v11->Release(); - this->pColorKeySurface4 = 0; - } - v12 = this->pBackBuffer4; - if ( v12 ) - { - v12->Release(); - this->pBackBuffer4 = 0; - } - v13 = this->pFrontBuffer4; - if ( v13 ) - { - v13->Release(); - this->pFrontBuffer4 = 0; - } - v14 = this->pDirectDraw4; - if ( v14 ) - { - v14->Release(); - this->pDirectDraw4 = 0; - } - } - v15 = &this->pTargetSurface; - if ( this->pTargetSurface ) - { - v16 = (void **)&this->ptr_400E8; - free(*v16); - *v15 = 0; - *v16 = 0; - } - }*/ -} - -void Present32(unsigned __int32 *src, unsigned int src_pitch, - unsigned __int32 *dst, unsigned int dst_pitch) -{ - for (uint y = 0; y < 8; ++y) - memcpy(dst + y * dst_pitch, - src + y * src_pitch, src_pitch * sizeof(__int32)); - - for (uint y = 8; y < 352; ++y) - { - memcpy(dst + y * dst_pitch, - src + y * src_pitch, 8 * sizeof(__int32)); - memcpy(dst + 8 + game_viewport_width + y * dst_pitch, - src + 8 + game_viewport_width + y * src_pitch, 174/*172*/ * sizeof(__int32)); - } - - for (uint y = 352; y < 480; ++y) - memcpy(dst + y * dst_pitch, - src + y * src_pitch, src_pitch * sizeof(__int32)); - - for (uint y = pViewport->uViewportTL_Y; y < pViewport->uViewportBR_Y + 1; ++y) - { - for (uint x = pViewport->uViewportTL_X; x < pViewport->uViewportBR_X; ++x) - { - //if (src[x + y * src_pitch] != (pRenderer->uTargetGMask | pRenderer->uTargetBMask)) - if (src[x + y * src_pitch] != 0xFF00FCF8) // FFF8FCF8 = Color32(Color16(g_mask | b_mask)) - dst[x + y * dst_pitch] = src[x + y * src_pitch]; - } - } -} - -//----- (004A597D) -------------------------------------------------------- -void Present_NoColorKey() -{ - void *v2; // edi@4 - int v9; // eax@10 - unsigned int v10; // esi@10 - unsigned __int32 v11; // edi@10 - unsigned int v13; // ebx@10 - DDSURFACEDESC2 Dst; // [sp+Ch] [bp-98h]@3 - int v21; // [sp+8Ch] [bp-18h]@10 - __int32 v22; // [sp+90h] [bp-14h]@10 - unsigned int v24; // [sp+98h] [bp-Ch]@4 - - int r_mask = 0xF800; - int g_mask = 0x7E0; - int b_mask = 0x1F; - - //if ( !pRenderer->uNumSceneBegins ) - { - //if ( pRenderer->using_software_screen_buffer ) - //{ - memset(&Dst, 0, sizeof(Dst)); - Dst.dwSize = sizeof(Dst); - if ( pRenderer->LockSurface_DDraw4(pRenderer->pBackBuffer4, &Dst, DDLOCK_WAIT) ) - { - //v26 = Dst.lpSurface; - //pRenderer->pCurrentlyLockedSurfaceDataPtr = (unsigned __int16 *)Dst.lpSurface; - v24 = g_mask | b_mask | ((g_mask | b_mask) << 16); - //pRenderer->pCurrentlyLockedSoftSurface = pRenderer->pTargetSurface; - //pRenderer->uCurrentlyLockedSurfacePitch = Dst.lPitch; - //v1 = pRenderer->pTargetSurface; - v2 = Dst.lpSurface; - - - /*for (uint y = 0; y < 480; ++y) - { - auto pDst = (unsigned short *)((char *)Dst.lpSurface + y * Dst.lPitch); - for (uint x = 0; x < 640; ++x) - pDst[x] = pRenderer->uTargetRMask | pRenderer->uTargetBMask; - }*/ - - if (!FORCE_16_BITS) - Present32((unsigned __int32 *)pRenderer->pTargetSurface, pRenderer->uTargetSurfacePitch, (unsigned __int32 *)Dst.lpSurface, Dst.lPitch / 4); - else - { - ushort* pSrc = (unsigned short *)pRenderer->pTargetSurface; - short* pDst = (__int16 *)Dst.lpSurface; - - for (uint y = 0; y < 8; ++y) - memcpy(pDst + y * Dst.lPitch / 2, - - pSrc + y * window->GetWidth(), window->GetWidth() * sizeof(__int16)); - - for (uint y = 8; y < 352; ++y) - { - memcpy(pDst + y * Dst.lPitch / 2, - pSrc + y * window->GetWidth(), 8 * sizeof(__int16)); - memcpy(pDst + 8 + game_viewport_width/*462*/ + y * Dst.lPitch / 2, - pSrc + 8 + game_viewport_width/*462*/ + y * window->GetWidth(), 174/*172*/ * sizeof(__int16)); - } - - for (uint y = 352; y < window->GetHeight(); ++y) - memcpy(pDst + y * Dst.lPitch / 2, - pSrc + y * window->GetWidth(), window->GetWidth() * sizeof(__int16)); - - - ushort* pSrc_x1y1 = pSrc + window->GetWidth() * pViewport->uViewportTL_Y + pViewport->uViewportTL_X; - //_this = (unsigned int)&pSrc[2 * (((signed int)pViewport->uViewportX >> 1) + 320 * pViewport->uViewportY)]; - short* pDst_x1y1 = pDst + Dst.lPitch * pViewport->uViewportTL_Y + pViewport->uViewportTL_X; - //v23 = (unsigned __int32)((char *)v26 + 4 * (((signed int)pViewport->uViewportX >> 1) + (Dst.lPitch >> 2) * pViewport->uViewportY)); - v9 = ((signed int)pViewport->uViewportTL_X >> 1) - ((signed int)pViewport->uViewportBR_X >> 1); - //v20 = ((signed int)pViewport->uViewportZ >> 1) - ((signed int)pViewport->uViewportX >> 1); - v22 = 4 * ((Dst.lPitch / 4) + v9); - v21 = 4 * v9 + 1280; - - //auto uNumLines = pViewport->uViewportW - pViewport->uViewportY + 1; - //v26 = (LPVOID)(pViewport->uViewportW - pViewport->uViewportY + 1); - v10 = (int)pSrc_x1y1; - v11 = (int)pDst_x1y1; - int uHalfWidth = (pViewport->uViewportBR_X - pViewport->uViewportTL_X) / 2; - v13 = v24; - - for (uint y = pViewport->uViewportTL_Y; y < pViewport->uViewportBR_Y + 1; ++y) - { - //memcpy(pDst + pViewport->uViewportX + y * Dst.lPitch / 2, - // pSrc + pViewport->uViewportX + y * 640, (pViewport->uViewportZ - pViewport->uViewportX) * sizeof(__int16)); - for (uint x = pViewport->uViewportTL_X; x < pViewport->uViewportBR_X; ++x) - { - if (pSrc[y * window->GetWidth() + x] != (g_mask | b_mask)) - pDst[y * Dst.lPitch / 2 + x] = pSrc[y * window->GetWidth() + x]; - } - } - } - - ErrD3D(pRenderer->pBackBuffer4->Unlock(NULL)); - - /* while ( 1 ) - { - while ( 1 ) - { - v14 = *(int *)v10; - v10 += 4; - if ( v14 == v13 ) - break; - if ( (short)v14 == (short)v13 ) - { - *(int *)v11 = *(int *)v11 & 0xFFFF | v14 & 0xFFFF0000; - v11 += 4; - --uHalfWidth; - if ( !uHalfWidth ) - goto LABEL_21; - } - else - { - v15 = __ROL__(v14, 16); - if ( (short)v15 == (short)v13 ) - { - v17 = __ROR__(v15, 16); - *(int *)v11 = *(int *)v11 & 0xFFFF0000 | (unsigned __int16)v17; - v11 += 4; - --uHalfWidth; - if ( !uHalfWidth ) - goto LABEL_21; - } - else - { - v16 = __ROR__(v15, 16); - *(int *)v11 = v16; - v11 += 4; - --uHalfWidth; - if ( !uHalfWidth ) - goto LABEL_21; - } - } - } - v11 += 4; - --uHalfWidth; - if ( !uHalfWidth ) - { -LABEL_21: - v10 += v21; - v11 += v22; - uHalfWidth = v20; - if ( !--uNumLines ) - { - ErrD3D(pRenderer->pBackBuffer4->Unlock(NULL)); - return; - } - } - }*/ - } - //} - } -} - - -//----- (0049FFFB) -------------------------------------------------------- -bool Render::InitializeFullscreen() -{ - RenderD3D__DevInfo *v7; // ecx@5 - bool v8; // eax@6 - unsigned int v10; // eax@13 - signed int v15; // ebx@31 - int *v22; // eax@42 - int v23; // ecx@42 - D3DDEVICEDESC refCaps; // [sp+Ch] [bp-300h]@25 - DDSURFACEDESC2 pDesc; // [sp+108h] [bp-204h]@40 - D3DDEVICEDESC halCaps; // [sp+184h] [bp-188h]@25 - int v29; // [sp+308h] [bp-4h]@2 - - //__debugbreak(); // Nomad - - this->using_software_screen_buffer = 0; - //this->pColorKeySurface4 = 0; - this->pBackBuffer4 = nullptr; - this->pFrontBuffer4 = nullptr; - this->pDirectDraw4 = nullptr; - //this->bColorKeySupported = 0; - Release(); - //v3 = hWnd; - this->window = window; - CreateZBuffer(); - - /*if (!bUserDirect3D) - { - CreateDirectDraw(); - SetDirectDrawCooperationMode(hWnd, 1); - SetDirectDrawDisplayMode(640u, 480u, 16u); - CreateDirectDrawPrimarySurface(); - v15 = 1; - } - else - {*/ - pRenderD3D = new RenderD3D; - //v28 = pRenderD3D; - //v6 = uDesiredDirect3DDevice; - v29 = -1; - v7 = pRenderD3D->pAvailableDevices; - if ( pRenderD3D->pAvailableDevices[uDesiredDirect3DDevice].bIsDeviceCompatible ) - v8 = pRenderD3D->CreateDevice(uDesiredDirect3DDevice, /*0*/true, window); - else - { - if ( v7[1].bIsDeviceCompatible ) - v8 = pRenderD3D->CreateDevice(1, /*0*/true, window); - else - { - if ( !v7->bIsDeviceCompatible ) - Error("There aren't any D3D devices to create."); - - v8 = pRenderD3D->CreateDevice(0, /*0*/true, window); - } - } - if ( !v8 ) - Error("D3Drend->Init failed."); - - //v9 = pRenderD3D; - pBackBuffer4 = pRenderD3D->pBackBuffer; - pFrontBuffer4 = pRenderD3D->pFrontBuffer; - pDirectDraw4 = pRenderD3D->pHost; - v10 = pRenderD3D->GetDeviceCaps(); - if ( v10 & 1 ) - { - if ( pRenderD3D ) - { - pRenderD3D->Release(); - delete pRenderD3D; - } - pRenderD3D = nullptr; - pBackBuffer4 = nullptr; - pFrontBuffer4 = nullptr; - pDirectDraw4 = nullptr; - Error("Direct3D renderer: The device failed to return capabilities."); - } - if ( v10 & 0x3E ) - { - if ( pRenderD3D ) - { - pRenderD3D->Release(); - delete pRenderD3D; - } - //pColorKeySurface4 = 0; - pRenderD3D = nullptr; - pBackBuffer4 = nullptr; - pFrontBuffer4 = nullptr; - pDirectDraw4 = nullptr; - Error("Direct3D renderer: The device doesn't support the necessary alpha blending modes."); - } - if ( (v10 & 0x80) != 0 ) - { - if ( pRenderD3D ) - { - pRenderD3D->Release(); - delete pRenderD3D; - } - pRenderD3D = nullptr; - pBackBuffer4 = nullptr; - pFrontBuffer4 = nullptr; - pDirectDraw4 = nullptr; - Error("Direct3D renderer: The device doesn't support non-square textures."); - } - //LOBYTE(field_10365C) = ~(unsigned __int8)(v10 >> 6) & 1; - bRequiredTextureStagesAvailable = CheckTextureStages(); - - memset(&halCaps, 0, sizeof(halCaps)); - halCaps.dwSize = sizeof(halCaps); - - memset(&refCaps, 0, sizeof(refCaps)); - refCaps.dwSize = sizeof(refCaps); - - ErrD3D(pRenderD3D->pDevice->GetCaps(&halCaps, &refCaps)); - - uMinDeviceTextureDim = halCaps.dwMinTextureWidth; - if ( (unsigned int)halCaps.dwMinTextureWidth >= halCaps.dwMinTextureHeight ) - uMinDeviceTextureDim = halCaps.dwMinTextureHeight; - uMinDeviceTextureDim = halCaps.dwMaxTextureWidth; - if ( (unsigned int)halCaps.dwMaxTextureWidth < halCaps.dwMaxTextureHeight ) - uMinDeviceTextureDim = halCaps.dwMaxTextureHeight; - if ( (unsigned int)uMinDeviceTextureDim < 4 ) - uMinDeviceTextureDim = 4; - v15 = 1; - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, true)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, true)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, 2)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SPECULARENABLE, false)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_COLORKEYENABLE, false)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, false)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, 1)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, 2)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MINFILTER, 2)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, 3)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, 2)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, 0)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, 2)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, 2)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, 0)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLOROP, 4)); - //} - ddpfPrimarySuface.dwSize = 32; - GetTargetPixelFormat(&ddpfPrimarySuface); - ParseTargetPixelFormat(); - - if (!pRenderD3D) - { - __debugbreak(); - pBeforePresentFunction = 0;//nullsub_1; - } - //else - //{ - /*v16 = IsColorKeySupported(pDirectDraw4); - v17 = uAcquiredDirect3DDevice == v15; - bColorKeySupported = v16; - if ( !v17 ) - bColorKeySupported = 0; - if ( bColorKeySupported ) - { - memset(&ddsd2, 0, sizeof(ddsd2)); - ddsd2.dwSize = sizeof(ddsd2); - ddsd2.ddckCKSrcBlt.dwColorSpaceLowValue = uTargetGMask | uTargetBMask; - ddsd2.ddckCKSrcBlt.dwColorSpaceHighValue = ddsd2.ddckCKSrcBlt.dwColorSpaceLowValue; - ddsd2.dwFlags = 65543; - ddsd2.ddsCaps.dwCaps = 2112; - ddsd2.dwWidth = 640; - ddsd2.dwHeight = 480; - ErrD3D(pDirectDraw4->CreateSurface(&ddsd2, &pColorKeySurface4, NULL)); - pBeforePresentFunction = Present_ColorKey; - } - else*/ - { - pTargetSurface = nullptr; - pTargetSurface_unaligned = (unsigned int *)malloc(window->GetWidth() * window->GetHeight() * 2 + 32); - if ( !pTargetSurface_unaligned ) - return 0; - memset(&pDesc, 0, sizeof(pDesc)); - pDesc.dwSize = sizeof(pDesc); - if ( !pRenderer->LockSurface_DDraw4(pRenderer->pBackBuffer4, &pDesc, v15) ) - return 0; - pBackBuffer4->Unlock(NULL); - v22 = (int *)pTargetSurface_unaligned + 4; - v23 = (unsigned int)pDesc.lpSurface & 7; - LOBYTE(v22) = (unsigned __int8)v22 & 0xF8; - uTargetSurfacePitch = window->GetWidth(); - pBeforePresentFunction = Present_NoColorKey; - v15 = 1; - pTargetSurface = (unsigned __int32 *)((char *)v22 + 2 * v23); - } - using_software_screen_buffer = v15; - //} - bWindowMode = 0; - pParty->uFlags |= 2; - pViewport->SetFOV(flt_6BE3A0 * 65536.0f); - return v15 != 0; -} - -//----- (004A05F3) -------------------------------------------------------- -bool Render::SwitchToWindow() -{ - bool v7; // eax@7 - unsigned int v9; // eax@12 - int v12; // eax@24 - int v13; // eax@26 - D3DDEVICEDESC refCaps; // [sp+Ch] [bp-300h]@24 - DDSURFACEDESC2 pDesc; // [sp+108h] [bp-204h]@37 - D3DDEVICEDESC halCaps; // [sp+184h] [bp-188h]@24 - int v29; // [sp+308h] [bp-4h]@2 - - pParty->uFlags |= PARTY_FLAGS_1_0002; - pViewport->SetFOV(flt_6BE3A0 * 65536.0f); - using_software_screen_buffer = 0; - Release(); - //pColorKeySurface4 = 0; - pBackBuffer4 = nullptr; - pFrontBuffer4 = nullptr; - pDirectDraw4 = nullptr; - //bColorKeySupported = 0; - CreateZBuffer(); - /*if (!bUserDirect3D) - { - CreateDirectDraw(); - SetDirectDrawCooperationMode(hWnd, 0); - field_4004C = 1; - CreateFrontBuffer(); - CreateClipper(hWnd); - CreateBackBuffer(); - field_40030 = 0; - field_18_locked_pitch = 0; - } - else - {*/ - /*v3 = malloc(0x148u); - thisa = (RenderD3D *)v3; - v29 = 0; - if ( v3 ) - v4 = RenderD3D::RenderD3D((RenderD3D *)v3); - else - v4 = 0;*/ - pRenderD3D = new RenderD3D; - //v4 = pRenderD3D; - //v5 = uDesiredDirect3DDevice; - v29 = -1; - //v6 = pRenderD3D->pAvailableDevices; - if (pRenderD3D->pAvailableDevices[uDesiredDirect3DDevice].bIsDeviceCompatible && - uDesiredDirect3DDevice != 1 ) - { - v7 = pRenderD3D->CreateDevice(uDesiredDirect3DDevice, true, window); - } - else - { - if ( !pRenderD3D->pAvailableDevices[0].bIsDeviceCompatible ) - Error("There aren't any D3D devices to init."); - - v7 = pRenderD3D->CreateDevice(0, true, window); - } - if ( !v7 ) - Error("D3Drend->Init failed."); - - //v8 = pRenderD3D; - //pColorKeySurface4 = 0; - pBackBuffer4 = pRenderD3D->pBackBuffer; - pFrontBuffer4 = pRenderD3D->pFrontBuffer; - pDirectDraw4 = pRenderD3D->pHost; - v9 = pRenderD3D->GetDeviceCaps(); - if ( v9 & 1 ) - { - if (pRenderD3D) - { - pRenderD3D->Release(); - delete pRenderD3D; - } - pRenderD3D = nullptr; - pBackBuffer4 = nullptr; - pFrontBuffer4 = nullptr; - pDirectDraw4 = nullptr; - Error("Direct3D renderer: The device failed to return capabilities."); - } - if ( v9 & 0x3E ) - { - if (pRenderD3D) - { - pRenderD3D->Release(); - delete pRenderD3D; - } - //pColorKeySurface4 = 0; - pRenderD3D = nullptr; - pBackBuffer4 = nullptr; - pFrontBuffer4 = nullptr; - pDirectDraw4 = nullptr; - Error("Direct3D renderer: The device doesn't support the necessary alpha blending modes."); - } - if (v9 & 0x80) - { - if (pRenderD3D) - { - pRenderD3D->Release(); - delete pRenderD3D; - } - pRenderD3D = nullptr; - pBackBuffer4 = nullptr; - pFrontBuffer4 = nullptr; - pDirectDraw4 = nullptr; - Error("Direct3D renderer: The device doesn't support non-square textures."); - } - //LOBYTE(field_10365C) = ~(unsigned __int8)(v9 >> 6) & 1; - bRequiredTextureStagesAvailable = CheckTextureStages(); - - memset(&halCaps, 0, sizeof(halCaps)); - halCaps.dwSize = sizeof(halCaps); - - memset(&refCaps, 0, sizeof(refCaps)); - refCaps.dwSize = sizeof(refCaps); - - ErrD3D(pRenderD3D->pDevice->GetCaps(&halCaps, &refCaps)); - v12 = halCaps.dwMinTextureWidth; - if ( (unsigned int)halCaps.dwMinTextureWidth > halCaps.dwMinTextureHeight ) - v12 = halCaps.dwMinTextureHeight; - uMinDeviceTextureDim = v12; - v13 = halCaps.dwMaxTextureWidth; - if ( (unsigned int)halCaps.dwMaxTextureWidth < halCaps.dwMaxTextureHeight ) - v13 = halCaps.dwMaxTextureHeight; - uMaxDeviceTextureDim = v13; - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, 1)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, 1)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, 2)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SPECULARENABLE, 0)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_COLORKEYENABLE, 0)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, 1)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, 2)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MINFILTER, 2)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, 3)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, 2)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, 0)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, 2)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, 2)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, 0)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLOROP, 4)); - //} - - ddpfPrimarySuface.dwSize = 32; - GetTargetPixelFormat(&ddpfPrimarySuface); - ParseTargetPixelFormat(); - - if ( !pRenderD3D ) - { - __debugbreak(); - //pBeforePresentFunction = 0;//nullsub_1; - //goto LABEL_47; - } - /*v14 = IsColorKeySupported(pDirectDraw4); - v15 = uAcquiredDirect3DDevice == 1; - bColorKeySupported = v14; - if ( !v15 ) - bColorKeySupported = 0;*/ - //if ( bColorKeySupported ) - if (false) - { - /*memset(&ddsd2, 0, 0x7Cu); - ddsd2.ddckCKSrcBlt.dwColorSpaceLowValue = uTargetGMask | uTargetBMask; - ddsd2.ddckCKSrcBlt.dwColorSpaceHighValue = ddsd2.ddckCKSrcBlt.dwColorSpaceLowValue; - v16 = pDirectDraw4; - ddsd2.dwSize = 124; - ddsd2.dwFlags = 65543; - ddsd2.ddsCaps.dwCaps = 2112; - ddsd2.dwWidth = 640; - ddsd2.dwHeight = 480; - ErrD3D(v16->CreateSurface(&ddsd2, &pColorKeySurface4, NULL)); - pBeforePresentFunction = Present_ColorKey;*/ - using_software_screen_buffer = 1; -//LABEL_47: - bWindowMode = 1; - //hWnd = hWnd; - return 0; - } - pTargetSurface = 0; - pTargetSurface_unaligned = 0; - - uint num_pixels = window->GetWidth() * window->GetHeight(); - pTargetSurface_unaligned = new unsigned int[num_pixels]; - - if (!pTargetSurface_unaligned) - return false; - - memset(&pDesc, 0, sizeof(pDesc)); - pDesc.dwSize = sizeof(pDesc); - if (!pRenderer->LockSurface_DDraw4(pRenderer->pBackBuffer4, &pDesc, DDLOCK_WAIT)) - { - delete [] pTargetSurface_unaligned; - return false; - } - - memset32(pTargetSurface_unaligned, -1, num_pixels); - - pRenderer->pBackBuffer4->Unlock(NULL); - /*v19 = pTargetSurface_unaligned; - v20 = (unsigned int)pDesc.lpSurface & 7; - v21 = (unsigned int)ptr_400E8 & 7; - if ( v21 == v20 ) - pTargetSurface = (unsigned __int16 *)v19; - else - { - if ( (signed int)v21 >= v20 ) - v22 = (int)((char *)v19 + 2 * (v21 - v20) + 16); - else - v22 = (int)((char *)v19 + 2 * (v20 - v21) + 16); - pTargetSurface = (unsigned __int16 *)v22; - }*/ - pTargetSurface = pTargetSurface_unaligned; - uTargetSurfacePitch = window->GetWidth(); - pBeforePresentFunction = Present_NoColorKey; - using_software_screen_buffer = 1; - bWindowMode = 1; - return 0; -} - - -//----- (0044F2B2) -------------------------------------------------------- -bool Render::IsGammaSupported() -{ -// bool result; // eax@3 -// HRESULT v1; // eax@4 - - //if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 ) - { - DDCAPS halCaps; // [sp+0h] [bp-180h]@4 - memset(&halCaps, 0, sizeof(DDCAPS)); - halCaps.dwSize = sizeof(DDCAPS); - - ErrD3D(pDirectDraw4->GetCaps(&halCaps, 0)); - return (halCaps.dwCaps2 >> 17) & 1; - } - /*else - return false;*/ -} - -//----- (004A0BEE) -------------------------------------------------------- -void Render::RasterLine2D(signed int uX, signed int uY, signed int uZ, signed int uW, unsigned __int16 uColor) -{ - signed int lower_bound; // eax@17 -// signed int left_bound; - unsigned int v21; // edi@46 - int v22; // esi@47 - int v23; // ebx@47 - signed int v24; // edx@50 - signed int v25; // esi@52 - unsigned __int16 *v26; // ecx@52 - int v27; // ebx@54 - int v28; // edi@55 - int v29; // edx@55 - int v30; // ebx@60 - int v31; // edx@61 - int v32; // edi@61 - signed int upper_bound; // [sp+18h] [bp-4h]@28 - unsigned int uXa; // [sp+24h] [bp+8h]@49 - int uYb; // [sp+28h] [bp+Ch]@47 - bool left_border_x = false; - bool right_border_x = false; - bool left_border_z = false; - bool right_border_z = false; - bool upper_border_y = false; - bool bottom_border_y = false; - bool upper_border_w = false; - bool bottom_border_w = false; - - if ( uX < this->raster_clip_x )// x выходит за рамки левой границы - left_border_x = true; - if ( uX > this->raster_clip_z )// x выходит за рамки правой границы - right_border_x = true; - - if ( uZ < this->raster_clip_x )// z выходит за рамки левой границы - left_border_z = true; - if ( uZ > this->raster_clip_z )// z выходит за рамки правой границы - right_border_z = true; - - if ( uY < this->raster_clip_y )// y выходит за рамки верхней границы - upper_border_y = true; - if ( uY > this->raster_clip_w )// y выходит за рамки нижней границы - bottom_border_y = true; - - if ( uW < this->raster_clip_y )// w выходит за рамки верхней границы - upper_border_w = true; - if ( uW > this->raster_clip_w )// w выходит за рамки нижней границы - bottom_border_w = true; - - if ( (left_border_x && left_border_z) || (right_border_x && right_border_z ) - || (upper_border_y && upper_border_w) || (bottom_border_y && bottom_border_w)) - return; - - if ( left_border_x || left_border_z || right_border_x || right_border_z - || upper_border_y || upper_border_w || bottom_border_y || bottom_border_w) - { - if ( left_border_x || left_border_z )//if ( (BYTE4(v36) ^ (unsigned __int8)v36) & 8 )//for left (левая граница) - { - if ( left_border_x )//left_border = true; х меньше левой границы - { - uY += (uW - uY) * ((this->raster_clip_x - uX) / (uZ - uX));//t = near_clip - v0.x / v1.x - v0.x (формула получения точки пересечения отрезка с плоскостью) - uX = this->raster_clip_x; - } - else if ( left_border_z )//z меньше левой границы - { - uZ = this->raster_clip_x; - uW += (uY - uW) * ((this->raster_clip_x - uZ) / (uX - uZ)); - } - } - - if ( right_border_x || right_border_z )//if ( (BYTE4(v36) ^ (unsigned __int8)v36) & 4 )//for right (правая граница) - { - if ( right_border_x ) //right_border = true; х больше правой границы - { - uY += (uY - uW) * ((this->raster_clip_z - uX) / (uZ - uX)); - uX = this->raster_clip_z; - } - else if ( right_border_z )//z больше правой границы - { - uW += (uW - uY) * ((this->raster_clip_z - uZ) / (uX - uZ)); - uZ = this->raster_clip_z; - } - } - - upper_bound = 0; - if ( uY < this->raster_clip_y ) - upper_bound = 2; - if ( uY > this->raster_clip_w ) - upper_bound |= 1; - - lower_bound = 0; - if ( uW < this->raster_clip_y ) - lower_bound = 2; - if ( uW > this->raster_clip_w ) - lower_bound |= 1; - - if ( !(lower_bound & upper_bound) )//for up and down(для верха и низа) - { - lower_bound ^= upper_bound; - if ( lower_bound & 2 ) - { - if ( upper_bound & 2 ) - { - uX += (uZ - uX) * ((this->raster_clip_y - uY) / (uW - uY)); - uY = this->raster_clip_y; - } - else - { - uZ += (uX - uZ) * ((this->raster_clip_y - uW) / (uY - uW)); - uW = this->raster_clip_y; - } - } - if ( lower_bound & 1 ) - { - if ( upper_bound & 1 ) - { - uX += (uZ - uX) * ((this->raster_clip_w - uY) / (uW - uY)); - uY = this->raster_clip_w; - } - else - { - uZ += (uX - uZ) * ((this->raster_clip_w - uW) / (uY - uW)); - uW = this->raster_clip_w; - } - } - } - } - v21 = pRenderer->uTargetSurfacePitch; - if ( pRenderer->uTargetSurfacePitch ) - { - //v12 = uX + uY * pRenderer->uTargetSurfacePitch; - v22 = uW - uY; - v23 = v22; - uYb = v22; - if ( v22 < 0 ) - { - v23 = -v22; - uYb = -v22; - v21 = -pRenderer->uTargetSurfacePitch; - } - uXa = uZ - uX; - if ((signed)(uZ - uX) >= 0) - v24 = 1; - else - { - uXa = -uXa; - v24 = -1; - } - v25 = 0; - - v26 = (unsigned __int16 *)this->pTargetSurface; - if ( v26 ) - { - if ( (signed int)uXa <= v23 )//рисуем вертикальную линию - { - v30 = v23 + 1; - if ( v30 > 0 ) - { - v31 = 2 * v24; - v32 = 2 * v21; - //v12 = (int)&v26[v12]; - int y = 0; - int x = 0; - for ( v30; v30; --v30 ) - { - v25 += uXa; - //*(short *)v12 = uColor; - //v12 += v32; - WritePixel16(uX + x, uY + y, uColor); - if ( v32 >= 0 ) - y += 1; - else - y -= 1; - if ( v25 > 0 ) - { - v25 -= uYb; - //v12 += v31; - if ( v31 >= 0 ) - x += 1; - else - x -= 1; - } - } - } - } - else//рисуем горизонтальную линию - { - v27 = uXa + 1; - if ( (signed int)(uXa + 1) > 0 ) - { - v28 = 2 * v21; - v29 = 2 * v24; - int y = 0; - int x = 0; - //v12 = (int)&v26[v12]; - for ( v27; v27; --v27 ) - { - v25 += uYb; - //*(short *)v12 = uColor; - //v12 += v29; - WritePixel16(uX + x, uY + y, uColor); - if ( v29 >= 0 ) - x += 1; - else - x -= 1; - if ( v25 > (signed int)uXa ) - { - v25 -= uXa; - //v12 += v28; - if ( v28 >= 0 ) - y += 1; - else - y -= 1; - } - } - } - } - } - } - return; -} - -//----- (004A0E80) -------------------------------------------------------- -void Render::ClearZBuffer(int a2, int a3) -{ - memset32(this->pActiveZBuffer, -65536, 0x4B000); -} - -//----- (004A0E97) -------------------------------------------------------- -void Render::SetRasterClipRect(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW) -{ - this->raster_clip_x = uX; - this->raster_clip_y = uY; - this->raster_clip_z = uZ; - this->raster_clip_w = uW; -} - -//----- (004A0EB6) -------------------------------------------------------- -void Render::ParseTargetPixelFormat() -{ - signed int v2; // ecx@1 - DWORD uRedMask; // edx@1 - unsigned int uGreenMask; // esi@5 - signed int v5; // ecx@5 - unsigned int uBlueMask; // edx@9 - signed int v7; // ecx@9 - //unsigned int v8; // ecx@13 - - v2 = 0; - uRedMask = this->ddpfPrimarySuface.dwRBitMask; - this->uTargetBBits = 0; - this->uTargetGBits = 0; - this->uTargetRBits = 0; - do - { - if ( (1 << v2) & uRedMask ) - ++this->uTargetRBits; - ++v2; - } - while ( v2 < 32 ); - uGreenMask = this->ddpfPrimarySuface.dwGBitMask; - v5 = 0; - do - { - if ( (1 << v5) & uGreenMask ) - ++this->uTargetGBits; - ++v5; - } - while ( v5 < 32 ); - uBlueMask = this->ddpfPrimarySuface.dwBBitMask; - v7 = 0; - do - { - if ( (1 << v7) & uBlueMask ) - ++this->uTargetBBits; - ++v7; - } - while ( v7 < 32 ); - this->uTargetGMask = uGreenMask; - this->uTargetRMask = this->ddpfPrimarySuface.dwRBitMask; - this->uTargetBMask = uBlueMask; -} - -//----- (004A0F40) -------------------------------------------------------- -bool Render::LockSurface_DDraw4(IDirectDrawSurface4 *pSurface, DDSURFACEDESC2 *pDesc, unsigned int uLockFlags) -{ - HRESULT result; // eax@1 - HRESULT v6; // eax@4 - char v9; // [sp+Bh] [bp-1h]@1 - - v9 = 1; - result = pSurface->Lock(NULL, pDesc, uLockFlags, NULL); - /* - Когда объект DirectDrawSurface теряет поверхностную память, методы возвратят DDERR_SURFACELOST - и не выполнят никакую другую функцию. Метод IDirectDrawSurface::Restore перераспределит поверхностную память - и повторно присоединит ее к объекту DirectDrawSurface. - */ - if ( result == DDERR_SURFACELOST ) - { - v6 = pSurface->Restore();//Восстанавливает потерянную поверхность. Это происходит, когда поверхностная память, - //связанная с объектом DirectDrawSurface была освобождена. - if ( v6 ) - { - if ( v6 != DDERR_IMPLICITLYCREATED )//DDERR_IMPLICITLYCREATED - Поверхность не может быть восстановлена, - //потому что она - неявно созданная поверхность. - { - v9 = 0; - result = (bool)memset(pDesc, 0, 4); - LOBYTE(result) = v9; - return 0; - } - pRenderer->pFrontBuffer4->Restore(); - pSurface->Restore(); - } - result = pSurface->Lock(NULL, pDesc, DDLOCK_WAIT, NULL); - if ( result == DDERR_INVALIDRECT || result == DDERR_SURFACEBUSY )//DDERR_SURFACEBUSY - Доступ к этой поверхности отказан, - //потому что поверхность блокирована другой нитью. DDERR_INVALIDRECT - Обеспечиваемый прямоугольник недопустим. - { - v9 = 0; - result = (bool)memset(pDesc, 0, 4); - LOBYTE(result) = v9; - return result; - } - ErrD3D(result); - if ( result ) - { - //v8 = 0; - //v7 = 2161; -//LABEL_19: - //CheckHRESULT((CheckHRESULT_stru0 *)&pSurface, result, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Screen16.cpp", v7, v8); - v9 = 0; - result = (bool)memset(pDesc, 0, 4); - LOBYTE(result) = v9; - return result; - } - if ( pRenderD3D ) - pRenderD3D->HandleLostResources(); - result = pRenderer->pDirectDraw4->RestoreAllSurfaces(); - } - else - { - if ( result ) - { - if ( result == DDERR_INVALIDRECT || result == DDERR_SURFACEBUSY ) - { - v9 = 0; - result = (bool)memset(pDesc, 0, 4); - LOBYTE(result) = v9; - return result; - } - ErrD3D(result); - //v8 = 0; - //v7 = 2199; - //goto LABEL_19; - } - } - return true; -} - - -//----- (004A10E4) -------------------------------------------------------- -void Render::CreateDirectDraw() -{ - //Render *v1; // edi@1 -// HRESULT v2; // eax@1 -// HRESULT v3; // eax@5 -// int v6; // [sp-Ch] [bp-20h]@3 -// unsigned int v9; // [sp+0h] [bp-14h]@0 - IDirectDraw *lpDD; // [sp+10h] [bp-4h]@1 - - //v1 = this; - ErrD3D(DirectDrawCreate(0, &lpDD, 0)); - - pDirectDraw4 = nullptr; - - ErrD3D(lpDD->QueryInterface(IID_IDirectDraw4, (void **)&pDirectDraw4)); - - lpDD->Release(); - lpDD = nullptr; -} - -//----- (004A1169) -------------------------------------------------------- -void Render::SetDirectDrawCooperationMode(HWND hWnd, bool bFullscreen) -{ - DWORD flags; // eax@1 - - //Установка взаимодействия для полноэкранного и оконного режимов - flags = bFullscreen ? DDSCL_NORMAL | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN : DDSCL_NORMAL; - - ErrD3D(pDirectDraw4->SetCooperativeLevel(hWnd, flags | DDSCL_MULTITHREADED)); -} - -//----- (004A11C6) -------------------------------------------------------- -void Render::SetDirectDrawDisplayMode(unsigned int uWidth, unsigned int uHeight, unsigned int uBPP) -{ - ErrD3D(pDirectDraw4->SetDisplayMode(uWidth, uHeight, uBPP, 0, 0)); -} - -//----- (004A121C) -------------------------------------------------------- -void Render::CreateFrontBuffer() -{ - //Render *v1; // esi@1 - IDirectDraw *pDD; // eax@3 - IDirectDrawSurface **pOutSurf; // esi@3 - struct _DDSURFACEDESC *v4; // edx@3 -//// HRESULT v5; // eax@5 - int v6; // [sp-8h] [bp-8Ch]@3 - DDSURFACEDESC2 a2; // [sp+4h] [bp-80h]@3 - - //v1 = this; - //if (pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || - //pVersion->pVersionInfo.dwMajorVersion != 4 ) - { - memset(&a2, 0, sizeof(a2)); - a2.dwSize = sizeof(a2); - - pDD = (IDirectDraw *)this->pDirectDraw4; - a2.dwFlags = 1; - a2.ddsCaps.dwCaps = 512;//DDSCAPS_PRIMARYSURFACE = 0x200 - - v6 = 2357; - pOutSurf = (IDirectDrawSurface **)&this->pFrontBuffer4; - v4 = (struct _DDSURFACEDESC *)&a2; - } - /*else - { - memset(&a2.lPitch, 0, 0x6Cu); // DDSURFACEDESC here - pDD = (IDirectDraw *)v1->pDirectDraw2; - a2.lPitch = 108; - a2.dwBackBufferCount = 1; - a2.dwTextureStage = 512; - v6 = 2346; - pOutSurf = (IDirectDrawSurface **)&v1->pFrontBuffer2; - v4 = (struct _DDSURFACEDESC *)&a2.lPitch; - }*/ - ErrD3D(pDD->CreateSurface(v4, pOutSurf, NULL)); -} - -//----- (004A12CD) -------------------------------------------------------- -void Render::CreateBackBuffer() -{ - //Render *v1; // esi@1 - IDirectDraw *v2; // eax@3 - IDirectDrawSurface **ppBackBuffer; // esi@3 - struct _DDSURFACEDESC *v4; // edx@3 -// HRESULT v5; // eax@5 - int v6; // [sp-8h] [bp-8Ch]@3 - unsigned int v7; // [sp-4h] [bp-88h]@3 - DDSURFACEDESC2 a2; // [sp+4h] [bp-80h]@3 - - //v1 = this; - //if (pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || - // pVersion->pVersionInfo.dwMajorVersion != 4 ) - { - memset(&a2, 0, sizeof(a2)); - a2.dwSize = sizeof(a2); - - v2 = (IDirectDraw *)this->pDirectDraw4; - a2.dwFlags = 7; - a2.ddsCaps.dwCaps = 2112;//0x840 = DDSCAPS_SYSTEMMEMORY = 0x800 | DDSCAPS_OFFSCREENPLAIN = 0x40 - a2.dwWidth = window->GetWidth(); - a2.dwHeight = window->GetHeight(); - - v7 = 0; - v6 = 2387; - ppBackBuffer = (IDirectDrawSurface **)&this->pBackBuffer4; - v4 = (struct _DDSURFACEDESC *)&a2; - } - /*else - { - memset(&a2.lPitch, 0, 0x6Cu); - v2 = (IDirectDraw *)v1->pDirectDraw2; - a2.lPitch = 108; - a2.dwBackBufferCount = 7; - v7 = 0; - a2.dwTextureStage = 2112; - a2.dwAlphaBitDepth = 640; - a2.dwMipMapCount = 480; - v6 = 2374; - ppBackBuffer = (IDirectDrawSurface **)&v1->pBackBuffer2; - v4 = (struct _DDSURFACEDESC *)&a2.lPitch; // //DDSURFACEDESC here fo ddraw2 - }*/ - ErrD3D(v2->CreateSurface(v4, ppBackBuffer, NULL)); -} - -//----- (004A139A) -------------------------------------------------------- -void Render::CreateDirectDrawPrimarySurface() -{ - IDirectDrawSurface *pFrontBuffer; // eax@3 - DDSCAPS2 *v6; // edx@3 - IDirectDraw4 *v7; // eax@4 - int v9; // ST14_4@5 - IDirectDrawSurface *v10; // ST10_4@5 - IDirectDrawSurface **ppBackBuffer; // [sp-4h] [bp-A4h]@3 - DDSURFACEDESC2 ddsd2; // [sp+Ch] [bp-94h]@3 - DDSCAPS2 v17; // [sp+88h] [bp-18h]@4 - - //v1 = this; - //if (pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || - //pVersion->pVersionInfo.dwMajorVersion != 4 ) - { - //v2 = 0; - //this->field_4004C = 1; - memset(&ddsd2, 0, sizeof(ddsd2)); - ddsd2.dwSize = sizeof(ddsd2); - - ddsd2.dwBackBufferCount = 1; - ddsd2.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; - ddsd2.ddsCaps.dwCaps = DDSCAPS_COMPLEX | DDSCAPS_FLIP | DDSCAPS_3DDEVICE | DDSCAPS_PRIMARYSURFACE; - ErrD3D(this->pDirectDraw4->CreateSurface(&ddsd2, &pFrontBuffer4, NULL)); - pFrontBuffer = (IDirectDrawSurface *)this->pFrontBuffer4; - ppBackBuffer = (IDirectDrawSurface **)&this->pBackBuffer4; - } - /*else - { - v2 = 0; - this->field_4004C = 1; - - DDSURFACEDESC ddsd; - memset(&ddsd, 0, sizeof(DDSURFACEDESC)); - - ddsd.lpSurface = (LPVOID)1; - ddsd.lPitch = 108; - ddsd.dwBackBufferCount = 33; - ddsd.ddsCaps.dwCaps = 8728; - ErrD3D(pDirectDraw2->CreateSurface(&ddsd, (IDirectDrawSurface **)&pFrontBuffer2, NULL)); - - pFrontBuffer = (IDirectDrawSurface *)v1->pFrontBuffer2; - ppBackBuffer = (IDirectDrawSurface **)&v1->pBackBuffer2; - }*/ - __debugbreak(); // warning C4700: uninitialized local variable 'v6' used - v9 = (int)v6; - v10 = pFrontBuffer; // BUG - - v17.dwCaps = 4; - ErrD3D(pFrontBuffer->GetAttachedSurface((DDSCAPS *)&v17, ppBackBuffer));// hr = this->pFrontBuffer->GetAttachedSurface(&ddsCaps2, ppBackBuffer); - //CheckHRESULT(&thisa, v11, (const char *)v10, v9, (unsigned int)ppBackBuffer); - //v1->field_40030 = v2; - //v1->field_18_locked_pitch = v2; -} - -//----- (004A14F4) -------------------------------------------------------- -void Render::CreateClipper(HWND a2) -{ - ErrD3D(pDirectDraw4->CreateClipper(0, &pDDrawClipper, NULL)); - ErrD3D(pDDrawClipper->SetHWnd(0, a2)); - ErrD3D(pFrontBuffer4->SetClipper(pDDrawClipper)); -} - -//----- (004A15D8) -------------------------------------------------------- -void Render::GetTargetPixelFormat(DDPIXELFORMAT *pOut) -{ - pFrontBuffer4->GetPixelFormat(pOut); -} - -//----- (004A1605) -------------------------------------------------------- -void Render::LockRenderSurface(void **pOutSurfacePtr, unsigned int *pOutPixelsPerRow) -{ - signed int v4; // eax@3 - - //if (pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || - //pVersion->pVersionInfo.dwMajorVersion != 4 ) - { - DDSURFACEDESC2 pDesc; // [sp+4h] [bp-7Ch]@3 - - memset(&pDesc, 0, sizeof(pDesc)); - pDesc.dwSize = sizeof(pDesc); - - LockSurface_DDraw4(this->pBackBuffer4, &pDesc, DDLOCK_WAIT); - *pOutSurfacePtr = pDesc.lpSurface; - v4 = pDesc.lPitch; - } - /*else - { - DDSURFACEDESC pDesc; // [sp+4h] [bp-7Ch]@3 - memset(&pDesc.lPitch, 0, 0x6Cu); - pDesc.lPitch = 108; - LockSurface_DDraw2(this->pBackBuffer2, &pDesc, 1); - *pOutSurfacePtr = (void *)pDesc.lpSurface; - v4 = pDesc.dwReserved; - }*/ - *pOutPixelsPerRow = v4 >> 1; -} - -//----- (004A16E1) -------------------------------------------------------- -void Render::UnlockBackBuffer() -{ - ErrD3D(pBackBuffer4->Unlock(NULL)); -} - -//----- (004A172E) -------------------------------------------------------- -void Render::LockFrontBuffer(void **pOutSurface, unsigned int *pOutPixelsPerRow) -{ - signed int v4; // eax@3 - - //if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 ) - { - DDSURFACEDESC2 pDesc; // [sp+4h] [bp-7Ch]@3 - - memset(&pDesc, 0, sizeof(pDesc)); - pDesc.dwSize = sizeof(pDesc); - - LockSurface_DDraw4(this->pFrontBuffer4, &pDesc, DDLOCK_WAIT); - *pOutSurface = pDesc.lpSurface; - v4 = pDesc.lPitch; - } - /*else - { - DDSURFACEDESC pDesc; // [sp+4h] [bp-7Ch]@3 - memset(&pDesc.lPitch, 0, 0x6Cu); - pDesc.lPitch = 108; - LockSurface_DDraw2(this->pFrontBuffer2, &pDesc, 1); - *pOutSurface = (void *)pDesc.lpSurface; - v4 = pDesc.dwReserved; - }*/ - *pOutPixelsPerRow = v4 >> 1; -} - -//----- (004A17C7) -------------------------------------------------------- -void Render::UnlockFrontBuffer() -{ - ErrD3D(pFrontBuffer4->Unlock(NULL)); -} - -//----- (004A1814) -------------------------------------------------------- -void Render::RestoreFrontBuffer() -{ - if (pFrontBuffer4->IsLost() == DDERR_SURFACELOST ) - pFrontBuffer4->Restore(); -} - -//----- (004A184C) -------------------------------------------------------- -void Render::RestoreBackBuffer() -{ - if ( pBackBuffer4->IsLost() == DDERR_SURFACELOST ) - pBackBuffer4->Restore(); -} - -//----- (004A18F5) -------------------------------------------------------- -void Render::BltToFront(RECT *pDstRect, IDirectDrawSurface *pSrcSurface, RECT *pSrcRect, unsigned int uBltFlags) -{ - ErrD3D(pFrontBuffer4->Blt(pDstRect, (IDirectDrawSurface4 *)pSrcSurface, pSrcRect, uBltFlags, nullptr)); -} - -//----- (004A194A) -------------------------------------------------------- -void Render::BltBackToFontFast(int a2, int a3, RECT *pSrcRect) -{ - IDirectDrawSurface *pFront; // eax@3 - IDirectDrawSurface *pBack; // [sp-Ch] [bp-Ch]@3 - - //if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 ) - { - pFront = (IDirectDrawSurface *)this->pFrontBuffer4; - pBack = (IDirectDrawSurface *)this->pBackBuffer4; - } - /*else - { - pFront = (IDirectDrawSurface *)this->pFrontBuffer2; - pBack = (IDirectDrawSurface *)this->pBackBuffer2; - }*/ - pFront->BltFast(NULL, NULL, pBack, pSrcRect, DDBLTFAST_WAIT); -} - -//----- (004A1B22) -------------------------------------------------------- -unsigned int Render::Billboard_ProbablyAddToListAndSortByZOrder(float z) -{ - unsigned int v7; // edx@6 - - if (uNumBillboardsToDraw >= 999 ) - return 0; - if (!uNumBillboardsToDraw) - { - uNumBillboardsToDraw = 1; - return 0; - } - - for (int left = 0, right = uNumBillboardsToDraw; left < right; ) // binsearch - { - v7 = left + (right - left) / 2; - if (z <= pRenderer->pBillboardRenderListD3D[v7].z_order) - right = v7; - else - left = v7 + 1; - } - - if (z > pRenderer->pBillboardRenderListD3D[v7].z_order ) - { - if ( v7 == pRenderer->uNumBillboardsToDraw - 1 ) - v7 = pRenderer->uNumBillboardsToDraw; - else - { - if ( (signed int)pRenderer->uNumBillboardsToDraw > (signed int)v7 ) - { - for ( uint i = 0; i < pRenderer->uNumBillboardsToDraw - v7; i++ ) - { - memcpy(&pRenderer->pBillboardRenderListD3D[pRenderer->uNumBillboardsToDraw - i], - &pRenderer->pBillboardRenderListD3D[pRenderer->uNumBillboardsToDraw - (i + 1)], - sizeof(pRenderer->pBillboardRenderListD3D[pRenderer->uNumBillboardsToDraw - i])); - } - } - ++v7; - } - uNumBillboardsToDraw++; - return v7; - } - if (z <= pRenderer->pBillboardRenderListD3D[v7].z_order ) - { - if ( (signed int)pRenderer->uNumBillboardsToDraw > (signed int)v7 ) - { - for ( uint i = 0; i < pRenderer->uNumBillboardsToDraw - v7; i++ ) - { - memcpy(&pRenderer->pBillboardRenderListD3D[pRenderer->uNumBillboardsToDraw - i], - &pRenderer->pBillboardRenderListD3D[pRenderer->uNumBillboardsToDraw -(i + 1)], - sizeof(pRenderer->pBillboardRenderListD3D[pRenderer->uNumBillboardsToDraw - i])); - } - } - uNumBillboardsToDraw++; - return v7; - } - return v7; -} - -//----- (004A1E9D) -------------------------------------------------------- -unsigned int Render::GetBillboardDrawListSize() -{ - return pRenderer->uNumBillboardsToDraw; -} - -//----- (004A1EA3) -------------------------------------------------------- -unsigned int Render::GetParentBillboardID(unsigned int uBillboardID) -{ - return pRenderer->pBillboardRenderListD3D[uBillboardID].sParentBillboardID; -} - -//----- (004A1EB6) -------------------------------------------------------- -void Render::BeginSceneD3D() -{ - if (!uNumD3DSceneBegins++) - { - //if (pRenderD3D) - { - pRenderD3D->ClearTarget(true, 0x00F08020, true, 1.0); - pRenderer->uNumBillboardsToDraw = 0; - pRenderD3D->pDevice->BeginScene(); - - if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor ) - uFogColor = GetLevelFogColor(); - else - uFogColor = 0; - - if ( uFogColor & 0xFF000000 ) - { - pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 1); - pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, uFogColor & 0xFFFFFF); - pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, 0); - bUsingSpecular = true; - } - else - { - pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 0); - bUsingSpecular = 0; - } - } - /*else - { - LockRenderSurface((void **)&pTargetSurface, &uTargetSurfacePitch); - if (pTargetSurface) - field_18_locked_pitch = uTargetSurfacePitch; - else - --uNumD3DSceneBegins; - }*/ - } -} - -//----- (004A1FE1) -------------------------------------------------------- -void Render::DrawBillboards_And_MaybeRenderSpecialEffects_And_EndScene() -{ - --uNumD3DSceneBegins; - if (uNumD3DSceneBegins) - return; - - if (pRenderD3D) - { - pGame->draw_debug_outlines(); - DoRenderBillboards_D3D(); - pGame->pStru6Instance->RenderSpecialEffects(); - pRenderD3D->pDevice->EndScene(); - } - else - pGame->pStru6Instance->RenderSpecialEffects(); -} - -//----- (004A2031) -------------------------------------------------------- -unsigned int Render::GetActorTintColor(float a2, int tint, int a4, int a5, RenderBillboard *a6) -{ -// __debugbreak(); // should not fire outside decal builder - return ::GetActorTintColor(tint, a4, a2, a5, a6); -} - -/*void Render::DrawTerrainPolygon_new(Polygon *a3, IDirect3DTexture2 *pTexture)//new function -{ - int v5; // ebx@1 - int v6; // edi@1 - int v8; // eax@7 - float v9; // eax@12 - float *v10; // esi@12 - float v11; // ecx@14 - double v12; // st7@14 - double v13; // st7@14 - double v14; // st7@14 - signed int v15; // eax@14 - int v16; // eax@15 - float v17; // ST48_4@15 - char v18; // zf@17 - int v19; // eax@18 - int v20; // eax@18 - int v21; // edx@20 - signed int v22; // ecx@20 - int v23; // eax@20 - const char *v24; // ST4C_4@20 - unsigned int v25; // ST50_4@20 - int v26; // ST54_4@20 - int v27; // eax@20 - _UNKNOWN *v28; // eax@21 - int v29; // ecx@23 - int v30; // eax@23 - int v31; // eax@23 - int v32; // eax@24 - int v33; // eax@25 - int v34; // eax@25 - int v35; // eax@25 - int v36; // eax@25 - signed int v37; // ecx@26 - int v38; // eax@26 - _UNKNOWN *v39; // eax@27 - int v40; // edx@28 - int v41; // eax@29 - int v42; // eax@29 - int v43; // eax@29 - int v44; // eax@29 - unsigned int v46; // eax@29 - int v47; // eax@30 - int v48; // eax@30 - int v49; // eax@30 - double v52; // st6@35 - const char *v55; // [sp+4Ch] [bp-1Ch]@20 - int v57; // [sp+5Ch] [bp-Ch]@3 - signed int v59; // [sp+60h] [bp-8h]@12 - int v61; // [sp+64h] [bp-4h]@4 - int i; - - v6 = (int)this; - v5 = 0; - if (!this->uNumD3DSceneBegins) - return; - - - - - this->pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP); - this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE); - if (this->bUsingSpecular) - { - this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE); - this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE); - this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO); - } - - pVertices[0].pos.x = array_50AC10[0].vWorldViewProjX; - pVertices[0].pos.y = array_50AC10[0].vWorldViewProjY; - pVertices[0].pos.z = 1.0 - 1.0 / (1000 * array_50AC10[0].vWorldViewPosition.x / (double)pODMRenderParams->shading_dist_mist); - pVertices[0].rhw = 1.0 / (array_50AC10[0].vWorldViewPosition.x + 0.0000001000000011686097); - pVertices[0].diffuse = GetActorTintColor(a3->field_58, 0, array_50AC10[0].vWorldViewPosition.x, 0, 0); - pVertices[0].specular = 0; - pVertices[0].texcoord.x = array_50AC10[0].u; - pVertices[0].texcoord.y = array_50AC10[0].v; - - pVertices[1].pos.x = array_50AC10[3].vWorldViewProjX; - pVertices[1].pos.y = array_50AC10[3].vWorldViewProjY; - pVertices[1].pos.z = 1.0 - 1.0 / (1000 * array_50AC10[3].vWorldViewPosition.x / (double)pODMRenderParams->shading_dist_mist); - pVertices[1].rhw = 1.0 / (array_50AC10[3].vWorldViewPosition.x + 0.0000001000000011686097); - pVertices[1].diffuse = GetActorTintColor(a3->field_58, 0, array_50AC10[3].vWorldViewPosition.x, 0, 0); - pVertices[1].specular = 0; - pVertices[1].texcoord.x = array_50AC10[3].u; - pVertices[1].texcoord.y = array_50AC10[3].v; - - pVertices[2].pos.x = array_50AC10[1].vWorldViewProjX; - pVertices[2].pos.y = array_50AC10[1].vWorldViewProjY; - pVertices[2].pos.z = 1.0 - 1.0 / (1000 * array_50AC10[1].vWorldViewPosition.x / (double)pODMRenderParams->shading_dist_mist); - pVertices[2].rhw = 1.0 / (array_50AC10[1].vWorldViewPosition.x + 0.0000001000000011686097); - pVertices[2].diffuse = GetActorTintColor(a3->field_58, 0, array_50AC10[1].vWorldViewPosition.x, 0, 0); - pVertices[2].specular = 0; - pVertices[2].texcoord.x = array_50AC10[1].u; - pVertices[2].texcoord.y = array_50AC10[1].v; - - memcpy(pVertices + 3, pVertices + 2, sizeof(RenderVertexD3D3)); - memcpy(pVertices + 4, pVertices + 1, sizeof(RenderVertexD3D3)); - - pVertices[5].pos.x = array_50AC10[2].vWorldViewProjX; - pVertices[5].pos.y = array_50AC10[2].vWorldViewProjY; - pVertices[5].pos.z = 1.0 - 1.0 / (1000 * array_50AC10[2].vWorldViewPosition.x / (double)pODMRenderParams->shading_dist_mist); - pVertices[5].rhw = 1.0 / (array_50AC10[2].vWorldViewPosition.x + 0.0000001000000011686097); - pVertices[5].diffuse = GetActorTintColor(a3->field_58, 0, array_50AC10[2].vWorldViewPosition.x, 0, 0); - pVertices[5].specular = 0; - pVertices[5].texcoord.x = array_50AC10[2].u; - pVertices[5].texcoord.y = array_50AC10[2].v; - - - this->pRenderD3D->pDevice->SetTexture(0, pTexture); - this->pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, pVertices, 6, D3DDP_DONOTLIGHT); - -}*/ - -//----- (004A26BC) -------------------------------------------------------- -void Render::DrawTerrainPolygon(unsigned int uNumVertices, struct Polygon *a4, IDirect3DTexture2 *a5, bool transparent, bool clampAtTextureBorders) -{ - unsigned int v8; // ebx@1 - int v11; // eax@5 - int v20; // eax@14 - unsigned int v45; // eax@28 - - v8 = 0; - if (!this->uNumD3DSceneBegins) - return; - if ( uNumVertices < 3) - return; - - //v61 = pVertices; - - /* v9 = pGame->pLightmapBuilder; - v65 = v9; - v10 = v9->std__vector_000004_size;*/ - if ( byte_4D864C && pGame->uFlags & GAME_FLAGS_1_01_lightmap_related) - { - v11 = ::GetActorTintColor(a4->dimming_level, 0, array_50AC10[0].vWorldViewPosition.x, 0, 0); - pGame->pLightmapBuilder->DrawLightmaps(/*v11, 0*/); - } - else - { - if (transparent || !pGame->pLightmapBuilder->std__vector_000004_size || - byte_4D864C && pGame->uFlags & 2 ) - { - if (clampAtTextureBorders) - this->pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP); - else - this->pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP); - - if (transparent || this->bUsingSpecular) - { - this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE); - if (transparent) - { - this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA); - this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA); - //this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ZERO); - //this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE); - } - else - { - this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE); - this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO); - } - } - - for (uint i = 0; i < uNumVertices; ++i) - { - - d3d_vertex_buffer[i].pos.x = array_50AC10[i].vWorldViewProjX; - d3d_vertex_buffer[i].pos.y = array_50AC10[i].vWorldViewProjY; - d3d_vertex_buffer[i].pos.z = 1.0 - 1.0 / ((array_50AC10[i].vWorldViewPosition.x * 1000) / (double)pODMRenderParams->shading_dist_mist); - d3d_vertex_buffer[i].rhw = 1.0 / (array_50AC10[i].vWorldViewPosition.x + 0.0000001); - d3d_vertex_buffer[i].diffuse = ::GetActorTintColor(a4->dimming_level, 0, array_50AC10[i].vWorldViewPosition.x, 0, 0); - if ( this->bUsingSpecular ) - { - d3d_vertex_buffer[i].specular = sub_47C3D7_get_fog_specular(0, 0, array_50AC10[i].vWorldViewPosition.x); - } - else - { - d3d_vertex_buffer[i].specular = 0; - } - d3d_vertex_buffer[i].texcoord.x = array_50AC10[i].u; - d3d_vertex_buffer[i].texcoord.y = array_50AC10[i].v; - } - - this->pRenderD3D->pDevice->SetTexture(0, a5); - this->pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, d3d_vertex_buffer, uNumVertices, 16); - if (transparent) - { - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); - } - } - else - { - for (uint i = 0; i < uNumVertices; ++i) - { - - d3d_vertex_buffer[i].pos.x = array_50AC10[i].vWorldViewProjX; - d3d_vertex_buffer[i].pos.y = array_50AC10[i].vWorldViewProjY; - d3d_vertex_buffer[i].pos.z = 1.0 - 1.0 / ((array_50AC10[i].vWorldViewPosition.x * 1000) / (double)pODMRenderParams->shading_dist_mist); - d3d_vertex_buffer[i].rhw = 1.0 / (array_50AC10[i].vWorldViewPosition.x + 0.0000001); - d3d_vertex_buffer[i].diffuse = GetActorTintColor(a4->dimming_level, 0, array_50AC10[i].vWorldViewPosition.x, 0, 0); - if ( this->bUsingSpecular ) - { - d3d_vertex_buffer[i].specular = sub_47C3D7_get_fog_specular(0, 0, array_50AC10[i].vWorldViewPosition.x); - } - else - { - d3d_vertex_buffer[i].specular = 0; - } - __debugbreak(); // warning C4700: uninitialized local variable 'v20' used - d3d_vertex_buffer[i].specular = v20; - d3d_vertex_buffer[i].texcoord.x = array_50AC10[i].u; - d3d_vertex_buffer[i].texcoord.y = array_50AC10[i].v; - } - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); - if (pRenderer->bUsingSpecular) - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE)); - - ErrD3D(pRenderD3D->pDevice->SetTexture(0, 0)); - ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, - D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, - d3d_vertex_buffer, - uNumVertices, - 16)); - //v63 = (const char *)v7->pRenderD3D->pDevice; - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE)); - //(*(void (**)(void))(*(int *)v63 + 88))(); - pGame->pLightmapBuilder->DrawLightmaps(/*-1, 0*/); - for (uint i = 0; i < uNumVertices; ++i) - { - d3d_vertex_buffer[i].diffuse = -1; - } - ErrD3D(pRenderD3D->pDevice->SetTexture(0, a5)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); - if ( !pRenderer->bUsingSpecular ) - { - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); - } - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ZERO)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_SRCCOLOR)); - ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, - D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, - d3d_vertex_buffer, - uNumVertices, - 16)); - if ( pRenderer->bUsingSpecular ) - { - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); - ErrD3D(pRenderD3D->pDevice->SetTexture(0, 0)); - for (uint i = 0; i < uNumVertices; ++i) - { - d3d_vertex_buffer[i].diffuse = pRenderer->uFogColor | d3d_vertex_buffer[i].specular & 0xFF000000; - d3d_vertex_buffer[i].specular = 0; - } - - ErrD3D(pRenderD3D->pDevice->SetTexture(0, 0));//problem - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_INVSRCALPHA)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_SRCALPHA)); - ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, - D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, - d3d_vertex_buffer, - uNumVertices, - 16)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE)); - //v44 = pRenderer->pRenderD3D->pDevice; - v45 = GetLevelFogColor(); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, v45 & 0xFFFFFF)); - v8 = 0; - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, 0)); - } - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, v8)); - } - } - - //if (pIndoorCamera->flags & INDOOR_CAMERA_DRAW_TERRAIN_OUTLINES || pBLVRenderParams->uFlags & INDOOR_CAMERA_DRAW_TERRAIN_OUTLINES) - if (pGame->pIndoorCameraD3D->debug_flags & ODM_RENDER_DRAW_TERRAIN_OUTLINES) - pGame->pIndoorCameraD3D->debug_outline_d3d(d3d_vertex_buffer, uNumVertices, 0x00FFFFFF, 0.0); - } -// 4A26BC: could not find valid save-restore pair for esi -// 4D864C: using guessed type char byte_4D864C; - -//----- (004A2DA3) -------------------------------------------------------- -void Render::DrawOutdoorSkyPolygon(unsigned int uNumVertices, struct Polygon *pSkyPolygon, IDirect3DTexture2 *pTexture) -{ - int v7; // eax@7 - - if ( !this->uNumD3DSceneBegins ) - return; - if ( uNumVertices >= 3 ) - { - this->pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP); - if ( this->bUsingSpecular ) - { - this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE); - this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE); - this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO); - } - for ( uint i = 0; i < uNumVertices; ++i ) - { - pVertices[i].pos.x = array_50AC10[i].vWorldViewProjX; - pVertices[i].pos.y = array_50AC10[i].vWorldViewProjY; - pVertices[i].pos.z = 0.99989998; - pVertices[i].rhw = array_50AC10[i]._rhw; - - pVertices[i].diffuse = ::GetActorTintColor(31, 0, array_50AC10[i].vWorldViewPosition.x, 1, 0); - v7 = 0; - if (this->bUsingSpecular) - v7 = sub_47C3D7_get_fog_specular(0, 1, array_50AC10[i].vWorldViewPosition.x); - pVertices[i].specular = v7; - pVertices[i].texcoord.x = array_50AC10[i].u; - pVertices[i].texcoord.y = array_50AC10[i].v; - } - pRenderD3D->pDevice->SetTexture(0, pTexture); - pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, - pVertices, uNumVertices, D3DDP_DONOTUPDATEEXTENTS | D3DDP_DONOTLIGHT); - } -} - -//----- (004A2ED5) -------------------------------------------------------- -void Render::DrawIndoorSkyPolygon(signed int uNumVertices, struct Polygon *pSkyPolygon, IDirect3DTexture2 *pTexture) -{ - int v5; // eax@3 - - if ( this->uNumD3DSceneBegins ) - { - if ( uNumVertices >= 3 ) - { - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); - v5 = 31 - (pSkyPolygon->dimming_level & 0x1F); - if ( v5 < pOutdoor->max_terrain_dimming_level ) - v5 = pOutdoor->max_terrain_dimming_level; - for (uint i = 0; i < (unsigned int)uNumVertices; ++i) - { - d3d_vertex_buffer[i].pos.x = array_507D30[i].vWorldViewProjX; - d3d_vertex_buffer[i].pos.y = array_507D30[i].vWorldViewProjY; - d3d_vertex_buffer[i].pos.z = 1.0 - 1.0 / (array_507D30[i].vWorldViewPosition.x * 0.061758894); - d3d_vertex_buffer[i].rhw = array_507D30[i]._rhw; - d3d_vertex_buffer[i].diffuse = 8 * v5 | ((8 * v5 | (v5 << 11)) << 8); - d3d_vertex_buffer[i].specular = 0; - d3d_vertex_buffer[i].texcoord.x = array_507D30[i].u; - d3d_vertex_buffer[i].texcoord.y = array_507D30[i].v; - } - ErrD3D(pRenderD3D->pDevice->SetTexture(0, pTexture)); - ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, - d3d_vertex_buffer, uNumVertices, 28)); - } - } -} - -//----- (00479A53) -------------------------------------------------------- -void Render::DrawIndoorSky(unsigned int uNumVertices, unsigned int uFaceID) -{ - BLVFace *pFace; // esi@1 - double v5; // st7@3 - signed __int64 v6; // qax@3 - int v12; // edx@7 - int v13; // eax@7 - int v17; // edi@9 - double v18; // st7@9 - signed int v19; // ebx@9 - void *v20; // ecx@9 - int v21; // ebx@11 - int v22; // eax@14 - signed __int64 v23; // qtt@16 - double v28; // st7@20 - double v33; // st6@23 - const void *v35; // ecx@31 - int v36; // eax@31 - const void *v37; // edi@31 - signed __int64 v38; // qax@31 - int v39; // ecx@31 - int v40; // ebx@33 - int v41; // eax@36 - signed __int64 v42; // qtt@39 - int v43; // eax@39 - double v48; // st7@41 - double v51; // st7@46 - struct Polygon pSkyPolygon; // [sp+14h] [bp-160h]@6 - unsigned int v63; // [sp+120h] [bp-54h]@7 - unsigned int v65; // [sp+128h] [bp-4Ch]@1 - unsigned int v66; // [sp+12Ch] [bp-48h]@7 - __int64 v69; // [sp+13Ch] [bp-38h]@3 - int v70; // [sp+144h] [bp-30h]@3 - int X; // [sp+148h] [bp-2Ch]@9 - int v72; // [sp+14Ch] [bp-28h]@7 - float v73; // [sp+150h] [bp-24h]@16 - unsigned int v74; // [sp+154h] [bp-20h]@3 - unsigned int v74_; // [sp+154h] [bp-20h]@3 - RenderVertexSoft *v75; // [sp+158h] [bp-1Ch]@3 - float v76; // [sp+15Ch] [bp-18h]@9 - int v77; // [sp+160h] [bp-14h]@9 - int v78; // [sp+164h] [bp-10h]@7 - void *v79; // [sp+168h] [bp-Ch]@9 - float v80; // [sp+16Ch] [bp-8h]@3 - const void *v81; // [sp+170h] [bp-4h]@7 - - pFace = &pIndoor->pFaces[uFaceID]; - //for floor and wall(for example Selesta)------------------- - if (pFace->uPolygonType == POLYGON_InBetweenFloorAndWall || pFace->uPolygonType == POLYGON_Floor) - { - int v69 = (GetTickCount() / 32) - pGame->pIndoorCameraD3D->vPartyPos.x; - int v55 = (GetTickCount() / 32) + pGame->pIndoorCameraD3D->vPartyPos.y; - for (uint i = 0; i < uNumVertices; ++i) - { - array_507D30[i].u = (v69 + array_507D30[i].u) * 0.25f; - array_507D30[i].v = (v55 + array_507D30[i].v) * 0.25f; - } - pRenderer->DrawIndoorPolygon(uNumVertices, pFace, pBitmaps_LOD->pHardwareTextures[pFace->uBitmapID], pFace->GetTexture(), PID(OBJECT_BModel, uFaceID), -1, 0); - return; - } -//--------------------------------------- - v70 = (signed __int64)((double)(pBLVRenderParams->fov_rad_fixpoint * pGame->pIndoorCameraD3D->vPartyPos.z)//179 - / (((double)pBLVRenderParams->fov_rad_fixpoint + 16192.0) - * 65536.0) - + (double)pBLVRenderParams->uViewportCenterY); - v5 = (double)pGame->pIndoorCameraD3D->sRotationX * 0.0030664064;//0 - v6 = (signed __int64)((double)pBLVRenderParams->uViewportCenterY//183 - - (double)pBLVRenderParams->fov_rad_fixpoint - / ((cos(v5) * 16192.0 + 0.0000001) - * 65535.0) - * (sin(v5) * -16192.0 - (double)pGame->pIndoorCameraD3D->vPartyPos.z)); - - stru_8019C8._48653D_frustum_blv(65536, 0, 0, 0, 65536, 0); - pSkyPolygon.Create_48607B(&stru_8019C8); - pSkyPolygon.uTileBitmapID = pFace->uBitmapID; - - pSkyPolygon.pTexture = pBitmaps_LOD->GetTexture(pSkyPolygon.uTileBitmapID); - if ( !pSkyPolygon.pTexture ) - return; - - pSkyPolygon.dimming_level = 0; - pSkyPolygon.uNumVertices = uNumVertices; - - pSkyPolygon.v_18.x = -stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationX + 16); - pSkyPolygon.v_18.y = 0; - pSkyPolygon.v_18.z = -stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationX + 16); - - memcpy(&array_507D30[uNumVertices], array_507D30, sizeof(array_507D30[uNumVertices])); - pSkyPolygon.field_24 = 0x2000000; - - extern float _calc_fov(int viewport_width, int angle_degree); - //v64 = (double)(signed int)(pBLVRenderParams->uViewportZ - pBLVRenderParams->uViewportX) * 0.5; - //v72 = 65536 / (signed int)(signed __int64)(v64 / tan(0.6457717418670654) + 0.5); - v72 = 65536.0f / _calc_fov(pBLVRenderParams->uViewportZ - pBLVRenderParams->uViewportX, 74); - v12 = pSkyPolygon.pTexture->uWidthMinus1; - v13 = pSkyPolygon.pTexture->uHeightMinus1; - //v67 = 1.0 / (double)pSkyPolygon.pTexture->uTextureWidth; - v63 = 224 * pMiscTimer->uTotalGameTimeElapsed & v13; - v66 = 224 * pMiscTimer->uTotalGameTimeElapsed & v12; - v78 = 0; - //v81 = 0; - float v68 = 1.0 / (double)pSkyPolygon.pTexture->uTextureHeight; - if ( (signed int)pSkyPolygon.uNumVertices <= 0 ) - return; - - int _507D30_idx = 0; - for ( _507D30_idx; _507D30_idx < pSkyPolygon.uNumVertices; _507D30_idx++ ) - { - //v15 = (void *)(v72 * (v70 - (int)array_507D30[_507D30_idx].vWorldViewProjY)); - v77 = fixpoint_mul(pSkyPolygon.ptr_38->viewing_angle_from_west_east, v72 * (v70 - array_507D30[_507D30_idx].vWorldViewProjY)); - v74 = v77 + pSkyPolygon.ptr_38->angle_from_north; - - v77 = fixpoint_mul(pSkyPolygon.ptr_38->viewing_angle_from_north_south, v72 * (v70 - array_507D30[_507D30_idx].vWorldViewProjY)); - v74_ = v77 + pSkyPolygon.ptr_38->angle_from_east; - - v79 = (void *)(fixpoint_mul(pSkyPolygon.v_18.z, v72 * (v70 - (int)array_507D30[_507D30_idx].vWorldViewProjY))); - v17 = v72 * (pBLVRenderParams->uViewportCenterX - (int)array_507D30[_507D30_idx].vWorldViewProjX); - v18 = array_507D30[_507D30_idx].vWorldViewProjY - 1.0; - v19 = -pSkyPolygon.field_24; - v77 = -pSkyPolygon.field_24; - X = (int)((char *)v79 + pSkyPolygon.v_18.x); - LODWORD(v76) = (signed __int64)v18; - v20 = (void *)(v72 * (v70 - LODWORD(v76))); - while ( 1 ) - { - v79 = v20; - if ( !X ) - goto LABEL_14; - v21 = abs(v19 >> 14); - if ( v21 <= abs(X) )//0x800 <= 0x28652 - break; - if ( SLODWORD(v76) <= (signed int)pViewport->uViewportTL_Y ) - break; - v19 = v77; - v20 = v79; -LABEL_14: - v79 = (void *)fixpoint_mul(pSkyPolygon.v_18.z, (int)v20); - v22 = fixpoint_mul(pSkyPolygon.v_18.z, (int)v20); - --LODWORD(v76); - v20 = (char *)v20 + v72; - X = v22 + pSkyPolygon.v_18.x; - v78 = 1; - } - if ( !v78 ) - { - LODWORD(v23) = v77 << 16; - HIDWORD(v23) = v77 >> 16;//v23 = 0xfffffe0000000000 - v79 = (void *)(v23 / X);//X = FFFF9014(-28652) - v77 = v17; - signed __int64 s = v74 + fixpoint_mul(pSkyPolygon.ptr_38->angle_from_west, v17);// s = 0xFFFFFFFF FFFF3EE6 - LODWORD(v80) = v66 + ((signed int)fixpoint_mul(SLODWORD(s), v23 / X) >> 4); - array_507D30[_507D30_idx].u = ((double)SLODWORD(v80) * 0.000015259022) * (1.0 / (double)pSkyPolygon.pTexture->uTextureWidth); - - signed __int64 s2 = v74_ + fixpoint_mul(pSkyPolygon.ptr_38->angle_from_south, v17); - LODWORD(v80) = v63 + ((signed int)fixpoint_mul(SLODWORD(s2), v23 / X) >> 4); - array_507D30[_507D30_idx].v = ((double)SLODWORD(v80) * 0.000015259022) * v68; - - v77 = fixpoint_mul(SLODWORD(s), v23 / X); - LODWORD(v73) = fixpoint_mul(SLODWORD(s2), v23 / X); - array_507D30[_507D30_idx]._rhw = 65536.0 / (double)(signed int)v79; - - //if ( (int)v81 >= pSkyPolygon.uNumVertices ) - //{ - // pRenderer->DrawIndoorSkyPolygon(pSkyPolygon.uNumVertices, &pSkyPolygon, - // pBitmaps_LOD->pHardwareTextures[(signed __int16)pSkyPolygon.uTileBitmapID]); - // return; - //} - continue; - } - break; - } - if ( _507D30_idx >= pSkyPolygon.uNumVertices ) - { - pRenderer->DrawIndoorSkyPolygon(pSkyPolygon.uNumVertices, &pSkyPolygon, - pBitmaps_LOD->pHardwareTextures[(signed __int16)pSkyPolygon.uTileBitmapID]); - return; - } - LODWORD(v73) = 0; - v80 = v76; - if ( (signed int)pSkyPolygon.uNumVertices > 0 ) - { - v28 = (double)SLODWORD(v76); - LODWORD(v76) = (int)(char *)array_50AC10 + 28; - uint i = 0; - for ( v78 = pSkyPolygon.uNumVertices; v78; --v78 ) - { - ++LODWORD(v73); - memcpy(&array_50AC10[i], &array_507D30[i], 0x30u); - LODWORD(v76) += 48; - if ( v28 < array_507D30[i].vWorldViewProjY | v28 == array_507D30[i].vWorldViewProjY - || v28 >= array_507D30[i + 1].vWorldViewProjY ) - { - if ( v28 >= array_507D30[i].vWorldViewProjY || v28 <= array_507D30[i + 1].vWorldViewProjY ) - { - i++; - continue; - } - v33 = (array_507D30[i + 1].vWorldViewProjX - array_507D30[i].vWorldViewProjX) * v28 / (array_507D30[i + 1].vWorldViewProjY - array_507D30[i].vWorldViewProjY) - + array_507D30[i + 1].vWorldViewProjX; - } - else - { - v33 = (array_507D30[i].vWorldViewProjX - array_507D30[i + 1].vWorldViewProjX) * v28 / (array_507D30[i].vWorldViewProjY - array_507D30[i + 1].vWorldViewProjY) - + array_507D30[i].vWorldViewProjX; - } - array_50AC10[i + 1].vWorldViewProjX = v33; - ++LODWORD(v73); - *(unsigned int *)LODWORD(v76) = v28; - LODWORD(v76) += 48; - i++; - } - } - if ( SLODWORD(v73) <= 0 ) - goto LABEL_40; - //v34 = (char *)&array_50AC10[0].vWorldViewProjY; - uint j = 0; - v65 = v77 >> 14; - //HIDWORD(v69) = LODWORD(v73); - for ( int t = (int)LODWORD(v73); t > 1; t-- ) - { - v35 = (const void *)(v72 * (v70 - (unsigned __int64)(signed __int64)array_50AC10[j].vWorldViewProjY)); - - //v78 = pSkyPolygon.ptr_38->viewing_angle_from_west_east; - //v81 = (const void *)fixpoint_mul(pSkyPolygon.ptr_38->viewing_angle_from_west_east, v35); - v36 = (int)(fixpoint_mul(pSkyPolygon.ptr_38->viewing_angle_from_west_east, (int)v35) + pSkyPolygon.ptr_38->angle_from_north); - - v81 = v35; - v74 = v36; - //v78 = pSkyPolygon.ptr_38->viewing_angle_from_north_south; - v81 = (const void *)fixpoint_mul(pSkyPolygon.ptr_38->viewing_angle_from_north_south, (int)v35); - v78 = (int)v35; - v75 = (RenderVertexSoft *)((char *)v81 + pSkyPolygon.ptr_38->angle_from_east); - //v81 = (const void *)pSkyPolygon.v_18.z; - v78 = fixpoint_mul(pSkyPolygon.v_18.z, (int)v35); - v37 = (const void *)(v72 * (pBLVRenderParams->uViewportCenterX - (unsigned __int64)(signed __int64)array_50AC10[j].vWorldViewProjX)); - v38 = (signed __int64)(array_50AC10[j].vWorldViewProjY - 1.0); - v81 = 0; - LODWORD(v76) = v38; - v39 = v72 * (v70 - v38); - while ( 1 ) - { - v78 = v39; - if ( !X ) - goto LABEL_36; - v40 = abs(X); - if ( abs((signed __int64)v65) <= v40 ) - break; - if ( SLODWORD(v76) <= (signed int)pViewport->uViewportTL_Y ) - break; - v39 = v78; -LABEL_36: - v78 = pSkyPolygon.v_18.z; - v41 = fixpoint_mul(pSkyPolygon.v_18.z, v39); - --LODWORD(v76); - v39 += v72; - X = v41 + pSkyPolygon.v_18.x; - v81 = (const void *)1; - } - if ( v81 ) - { - v79 = (void *)pSkyPolygon.v_18.z; - v78 = 2 * LODWORD(v76); - v81 = (const void *)fixpoint_mul(pSkyPolygon.v_18.z, (((double)v70 - ((double)(2 * LODWORD(v76)) - array_50AC10[j].vWorldViewProjY)) - * (double)v72)); - X = (int)((char *)v81 + pSkyPolygon.v_18.x); - } - LODWORD(v42) = v77 << 16; - HIDWORD(v42) = v77 >> 16; - v79 = (void *)(v42 / X); - v81 = v37; - - //v78 = pSkyPolygon.ptr_38->angle_from_west; - v81 = (const void *)fixpoint_mul(pSkyPolygon.ptr_38->angle_from_west, (int)v37); - v43 = v74 + fixpoint_mul(pSkyPolygon.ptr_38->angle_from_west, (int)v37); - v74 = (unsigned int)v37; - LODWORD(v76) = v43; - - //v78 = pSkyPolygon.ptr_38->angle_from_south; - v75 = (RenderVertexSoft *)((char *)v75 + fixpoint_mul(pSkyPolygon.ptr_38->angle_from_south, (int)v37)); - //v74 = fixpoint_mul(v43, v42 / X); - v81 = (const void *)fixpoint_mul((int)v75, v42 / X); - - //v34 += 48; - //v78 = v66 + ((signed int)fixpoint_mul(v43, v42 / X) >> 4); - //v44 = HIDWORD(v69)-- == 1; - //v45 = (double)(v66 + ((signed int)fixpoint_mul(v43, v42 / X) >> 4)) * 0.000015259022; - //v78 = v63 + ((signed int)fixpoint_mul((int)v75, v42 / X) >> 4); - array_50AC10[j].u = ((double)(v66 + ((signed int)fixpoint_mul(v43, v42 / X) >> 4)) * 0.000015259022) * (1.0 / (double)pSkyPolygon.pTexture->uTextureWidth); - array_50AC10[j].v = ((double)(v66 + ((signed int)fixpoint_mul(v43, v42 / X) >> 4)) * 0.000015259022) * v68; - //v46 = (double)(signed int)v79; - array_50AC10[j].vWorldViewPosition.x = 0.000015258789 * (double)(signed int)v79; - array_50AC10[j]._rhw = 65536.0 / (double)(signed int)v79; - ++j; - } - //while ( !v44 ); -LABEL_40: - uint i = 0; - if ( SLODWORD(v73) > 0 ) - { - v48 = (double)SLODWORD(v80); - for ( HIDWORD(v69) = LODWORD(v73); HIDWORD(v69); --HIDWORD(v69) ) - { - if ( v48 >= array_50AC10[i].vWorldViewProjY ) - { - ++i; - memcpy(&array_507D30[i], &array_50AC10[i], 0x30u); - } - } - } - pSkyPolygon.uNumVertices = i; - pRenderer->DrawIndoorSkyPolygon(pSkyPolygon.uNumVertices, &pSkyPolygon, pBitmaps_LOD->pHardwareTextures[(signed __int16)pSkyPolygon.uTileBitmapID]); - int pNumVertices = 0; - if ( SLODWORD(v73) > 0 ) - { - v51 = (double)SLODWORD(v80); - for ( v80 = v73; v80 != 0.0; --LODWORD(v80) ) - { - if ( v51 <= array_50AC10[pNumVertices].vWorldViewProjY ) - { - ++pNumVertices; - memcpy(&array_507D30[pNumVertices], &array_50AC10[pNumVertices], 0x30u); - } - } - } - pRenderer->DrawIndoorSkyPolygon(pNumVertices, &pSkyPolygon, pBitmaps_LOD->pHardwareTextures[(signed __int16)pSkyPolygon.uTileBitmapID]); -} - - -//----- (004A2FC0) -------------------------------------------------------- -void Render::DrawIndoorPolygon(unsigned int uNumVertices, BLVFace *pFace, IDirect3DTexture2 *pHwTex, Texture *pTex, int uPackedID, unsigned int uColor, int a8) -{ - if (!uNumD3DSceneBegins || uNumVertices < 3) - return; - - //auto a3 = pFace; - //auto a6 = uPackedID; - //v59 = pGame->pLightmapBuilder; - //v9 = v59->std__vector_000004_size; - - int sCorrectedColor = uColor; - if (pGame->pLightmapBuilder->std__vector_000004_size) - sCorrectedColor = -1; - pGame->AlterGamma_BLV(pFace, &sCorrectedColor); - - - if (pFace->uAttributes & FACE_OUTLINED) - { -// int color; - if (GetTickCount() % 300 >= 150) - uColor = sCorrectedColor = 0xFF20FF20; - else uColor = sCorrectedColor = 0xFF109010; - } - - if (byte_4D864C && pGame->uFlags & GAME_FLAGS_1_01_lightmap_related) - { - __debugbreak(); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); - for (uint i = 0; i < uNumVertices; ++i) - { - d3d_vertex_buffer[i].pos.x = array_507D30[i].vWorldViewProjX; - d3d_vertex_buffer[i].pos.y = array_507D30[i].vWorldViewProjY; - d3d_vertex_buffer[i].pos.z = 1.0 - 1.0 / (array_507D30[i].vWorldViewPosition.x * 0.061758894); - d3d_vertex_buffer[i].rhw = 1.0 / array_507D30[i].vWorldViewPosition.x; - d3d_vertex_buffer[i].diffuse = sCorrectedColor; - d3d_vertex_buffer[i].specular = 0; - d3d_vertex_buffer[i].texcoord.x = array_507D30[i].u / (double)pTex->uTextureWidth; - d3d_vertex_buffer[i].texcoord.y = array_507D30[i].v / (double)pTex->uTextureHeight; - } - - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); - ErrD3D(pRenderD3D->pDevice->SetTexture(0, nullptr)); - ErrD3D(pRenderD3D->pDevice->DrawPrimitive( - D3DPT_TRIANGLEFAN, - D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, - d3d_vertex_buffer, - uNumVertices, - 28)); - pGame->pLightmapBuilder->DrawLightmaps(/*-1, 0*/); - } - else - { - if (!pGame->pLightmapBuilder->std__vector_000004_size || - byte_4D864C && pGame->uFlags & 2) - { - for (uint i = 0; i < uNumVertices; ++i) - { - d3d_vertex_buffer[i].pos.x = array_507D30[i].vWorldViewProjX; - d3d_vertex_buffer[i].pos.y = array_507D30[i].vWorldViewProjY; - d3d_vertex_buffer[i].pos.z = 1.0 - 1.0 / (array_507D30[i].vWorldViewPosition.x * 0.061758894); - d3d_vertex_buffer[i].rhw = 1.0 / array_507D30[i].vWorldViewPosition.x; - d3d_vertex_buffer[i].diffuse = sCorrectedColor; - d3d_vertex_buffer[i].specular = 0; - d3d_vertex_buffer[i].texcoord.x = array_507D30[i].u / (double)pTex->uTextureWidth; - d3d_vertex_buffer[i].texcoord.y = array_507D30[i].v / (double)pTex->uTextureHeight; - } - - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); - ErrD3D(pRenderD3D->pDevice->SetTexture(0, pHwTex)); - ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, - D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, - d3d_vertex_buffer, - uNumVertices, - 28)); - } - else - { - for (uint i = 0; i < uNumVertices; ++i) - { - d3d_vertex_buffer[i].pos.x = array_507D30[i].vWorldViewProjX; - d3d_vertex_buffer[i].pos.y = array_507D30[i].vWorldViewProjY; - d3d_vertex_buffer[i].pos.z = 1.0 - 1.0 / (array_507D30[i].vWorldViewPosition.x * 0.061758894); - d3d_vertex_buffer[i].rhw = 1.0 / array_507D30[i].vWorldViewPosition.x; - d3d_vertex_buffer[i].diffuse = uColor; - d3d_vertex_buffer[i].specular = 0; - d3d_vertex_buffer[i].texcoord.x = array_507D30[i].u / (double)pTex->uTextureWidth; - d3d_vertex_buffer[i].texcoord.y = array_507D30[i].v / (double)pTex->uTextureHeight; - } - //__debugbreak(); - //if ( (signed int)uNumVertices > 0 ) - //{ - //v23 = pTex; - //v24 = (char *)&array_507D30[0].vWorldViewPosition; - //v25 = (char *)&d3d_vertex_buffer[0].pos.y; - //pTex = (Texture *)uNumVertices; - //uint v18; - //do - //{ - //v26 = *(float *)v24 * 0.061758894; - //v27 = *((int *)v24 + 3); - //*((int *)v25 + 4) = 0; - //*((int *)v25 - 1) = v27; - //*(int *)v25 = *((int *)v24 + 4); - //*((int *)v25 + 3) = uColor; - //v25 += 32; - //*((float *)v25 - 7) = 1.0 - 1.0 / v26; - //v28 = 1.0 / *(float *)v24; - //v24 += 48; - //v18 = pTex == (Texture *)1; - //pTex = (Texture *)((char *)pTex - 1); - //*((float *)v25 - 6) = v28; - //a3 = (BLVFace *)v23->uTextureWidth; - //*((float *)v25 - 3) = *((float *)v24 - 6) / (double)(signed int)v23->uTextureWidth; - //a3 = (BLVFace *)v23->uTextureHeight; - //*((float *)v25 - 2) = *((float *)v24 - 5) / (double)(signed int)v23->uTextureHeight; - //} - //while ( !v18 ); - //} - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); - ErrD3D(pRenderD3D->pDevice->SetTexture(0, nullptr)); - ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, - D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, - d3d_vertex_buffer, - uNumVertices, - 28)); - - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE)); - pGame->pLightmapBuilder->DrawLightmaps(/*-1, 0*/); - - for (uint i = 0; i < uNumVertices; ++i) - d3d_vertex_buffer[i].diffuse = sCorrectedColor; - /*v33 = uNumVertices; - if ( (signed int)uNumVertices > 0 ) - { - v34 = (char *)&d3d_vertex_buffer[0].diffuse; - do - { - *(int *)v34 = uCorrectedColor; - v34 += 32; - --v33; - } - while ( v33 ); - }*/ - ErrD3D(pRenderD3D->pDevice->SetTexture(0, pHwTex)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ZERO)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_SRCCOLOR)); - ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, - D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, - d3d_vertex_buffer, - uNumVertices, - 28)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE)); - } - } -} -// 4D864C: using guessed type char byte_4D864C; - -//----- (004A43B1) -------------------------------------------------------- -void Render::DrawBillboard_Indoor(RenderBillboardTransform_local0 *pSoftBillboard, Sprite *pSprite, int dimming_level) -{ - unsigned int v7; // eax@2 - signed int v11; // eax@9 - signed int v12; // eax@9 - double v15; // st5@12 - double v16; // st4@12 - double v17; // st3@12 - double v18; // st2@12 - int v19; // ecx@14 - double v20; // st3@14 - int v21; // ecx@16 - double v22; // st3@16 - float v27; // [sp+24h] [bp-Ch]@5 - int v28; // [sp+28h] [bp-8h]@2 - float v29; // [sp+2Ch] [bp-4h]@5 - float v31; // [sp+3Ch] [bp+Ch]@5 - float a1; // [sp+40h] [bp+10h]@5 - - if ( this->uNumD3DSceneBegins ) - { - //v4 = pSoftBillboard; - //v5 = (double)pSoftBillboard->zbuffer_depth; - //pSoftBillboarda = pSoftBillboard->zbuffer_depth; - //v6 = pSoftBillboard->zbuffer_depth; - v7 = Billboard_ProbablyAddToListAndSortByZOrder(pSoftBillboard->zbuffer_depth); - //v8 = dimming_level; - //v9 = v7; - v28 = dimming_level & 0xFF000000; - if ( dimming_level & 0xFF000000 ) - pBillboardRenderListD3D[v7].opacity = RenderBillboardD3D::Opaque_3; - else - pBillboardRenderListD3D[v7].opacity = RenderBillboardD3D::Transparent; - //v10 = a3; - pBillboardRenderListD3D[v7].field_90 = pSoftBillboard->field_44; - pBillboardRenderListD3D[v7].sZValue = pSoftBillboard->sZValue; - pBillboardRenderListD3D[v7].sParentBillboardID = pSoftBillboard->sParentBillboardID; - //v25 = pSoftBillboard->uScreenSpaceX; - //v24 = pSoftBillboard->uScreenSpaceY; - a1 = (pSoftBillboard->_screenspace_x_scaler_packedfloat & 0xFFFF) * 0.000015260186 + HIWORD(pSoftBillboard->_screenspace_x_scaler_packedfloat); - v29 = (pSoftBillboard->_screenspace_y_scaler_packedfloat & 0xFFFF) * 0.000015260186 + HIWORD(pSoftBillboard->_screenspace_y_scaler_packedfloat); - v31 = (double)((pSprite->uBufferWidth >> 1) - pSprite->uAreaX); - v27 = (double)(pSprite->uBufferHeight - pSprite->uAreaY); - if ( pSoftBillboard->uFlags & 4 ) - v31 = v31 * -1.0; - if ( pSoftBillboard->sTintColor && this->bTinting ) - { - v11 = ::GetActorTintColor(dimming_level, 0, pSoftBillboard->zbuffer_depth, 0, 0); - v12 = BlendColors(pSoftBillboard->sTintColor, v11); - if ( v28 ) - v12 = (unsigned int)((char *)&array_77EC08[1852].pEdgeList1[17] + 3) & ((unsigned int)v12 >> 1); - } - else - { - v12 = ::GetActorTintColor(dimming_level, 0, pSoftBillboard->zbuffer_depth, 0, 0); - } - //v13 = (double)v25; - pBillboardRenderListD3D[v7].pQuads[0].specular = 0; - pBillboardRenderListD3D[v7].pQuads[0].diffuse = v12; - pBillboardRenderListD3D[v7].pQuads[0].pos.x = pSoftBillboard->uScreenSpaceX - v31 * a1; - //v14 = (double)v24; - //v32 = v14; - pBillboardRenderListD3D[v7].pQuads[0].pos.y = pSoftBillboard->uScreenSpaceY - v27 * v29; - v15 = 1.0 - 1.0 / (pSoftBillboard->zbuffer_depth * 0.061758894); - pBillboardRenderListD3D[v7].pQuads[0].pos.z = v15; - v16 = 1.0 / pSoftBillboard->zbuffer_depth; - pBillboardRenderListD3D[v7].pQuads[0].rhw = 1.0 / pSoftBillboard->zbuffer_depth; - pBillboardRenderListD3D[v7].pQuads[0].texcoord.x = 0.0; - pBillboardRenderListD3D[v7].pQuads[0].texcoord.y = 0.0; - v17 = (double)((pSprite->uBufferWidth >> 1) - pSprite->uAreaX); - v18 = (double)(pSprite->uBufferHeight - pSprite->uAreaY - pSprite->uAreaHeight); - if ( pSoftBillboard->uFlags & 4 ) - v17 = v17 * -1.0; - pBillboardRenderListD3D[v7].pQuads[1].specular = 0; - pBillboardRenderListD3D[v7].pQuads[1].diffuse = v12; - pBillboardRenderListD3D[v7].pQuads[1].pos.x = pSoftBillboard->uScreenSpaceX - v17 * a1; - pBillboardRenderListD3D[v7].pQuads[1].pos.y = pSoftBillboard->uScreenSpaceY - v18 * v29; - pBillboardRenderListD3D[v7].pQuads[1].pos.z = v15; - pBillboardRenderListD3D[v7].pQuads[1].rhw = v16; - pBillboardRenderListD3D[v7].pQuads[1].texcoord.x = 0.0; - pBillboardRenderListD3D[v7].pQuads[1].texcoord.y = 1.0; - v19 = pSprite->uBufferHeight - pSprite->uAreaY - pSprite->uAreaHeight; - v20 = (double)(pSprite->uAreaX + pSprite->uAreaWidth + (pSprite->uBufferWidth >> 1) - pSprite->uBufferWidth); - if ( pSoftBillboard->uFlags & 4 ) - v20 = v20 * -1.0; - pBillboardRenderListD3D[v7].pQuads[2].specular = 0; - pBillboardRenderListD3D[v7].pQuads[2].diffuse = v12; - pBillboardRenderListD3D[v7].pQuads[2].pos.x = v20 * a1 + pSoftBillboard->uScreenSpaceX; - pBillboardRenderListD3D[v7].pQuads[2].pos.y = pSoftBillboard->uScreenSpaceY - (double)v19 * v29; - pBillboardRenderListD3D[v7].pQuads[2].pos.z = v15; - pBillboardRenderListD3D[v7].pQuads[2].rhw = v16; - pBillboardRenderListD3D[v7].pQuads[2].texcoord.x = 1.0; - pBillboardRenderListD3D[v7].pQuads[2].texcoord.y = 1.0; - v21 = pSprite->uBufferHeight - pSprite->uAreaY; - v22 = (double)(pSprite->uAreaX + pSprite->uAreaWidth + (pSprite->uBufferWidth >> 1) - pSprite->uBufferWidth); - if ( pSoftBillboard->uFlags & 4 ) - v22 = v22 * -1.0; - pBillboardRenderListD3D[v7].pQuads[3].specular = 0; - pBillboardRenderListD3D[v7].pQuads[3].diffuse = v12; - pBillboardRenderListD3D[v7].pQuads[3].pos.x = v22 * a1 + pSoftBillboard->uScreenSpaceX; - pBillboardRenderListD3D[v7].pQuads[3].pos.y = pSoftBillboard->uScreenSpaceY - (double)v21 * v29; - pBillboardRenderListD3D[v7].pQuads[3].pos.z = v15; - pBillboardRenderListD3D[v7].pQuads[3].rhw = v16; - pBillboardRenderListD3D[v7].pQuads[3].texcoord.x = 1.0; - pBillboardRenderListD3D[v7].pQuads[3].texcoord.y = 0.0; - //v23 = pSprite->pTexture; - pBillboardRenderListD3D[v7].uNumVertices = 4; - pBillboardRenderListD3D[v7].z_order = pSoftBillboard->zbuffer_depth; - pBillboardRenderListD3D[v7].pTexture = pSprite->pTexture; - } -} - -//----- (004A354F) -------------------------------------------------------- -void Render::MakeParticleBillboardAndPush_BLV(RenderBillboardTransform_local0 *a2, IDirect3DTexture2 *a3, unsigned int uDiffuse, int angle) -{ - unsigned int v8; // esi@3 - float v11; // ST28_4@3 - float v16; // ST2C_4@3 - float v17; // ST30_4@3 - signed int v18; // ST18_4@3 - signed int v19; // ST14_4@3 - signed int v20; // ST10_4@3 - signed int v21; // eax@3 - double v22; // st6@3 - float v23; // ST2C_4@3 - float v24; // ST30_4@3 - signed int v25; // ST10_4@3 - signed int v26; // ST14_4@3 - signed int v27; // ST18_4@3 - signed int v28; // eax@3 - double v29; // st6@3 - float v30; // ecx@3 - float v31; // ST2C_4@3 - float v32; // ST30_4@3 - signed int v33; // ST10_4@3 - signed int v34; // ST14_4@3 - signed int v35; // ST18_4@3 - signed int v36; // eax@3 - float v37; // ecx@3 - double v38; // st6@3 - float v39; // ST2C_4@3 - float v40; // ST30_4@3 - signed int v41; // ST10_4@3 - signed int v42; // ST14_4@3 - signed int v43; // ST18_4@3 - signed int v44; // eax@3 - double v45; // st6@3 - float v46; // eax@3 - - if ( this->uNumD3DSceneBegins ) - { - if (a2->zbuffer_depth) - { - //v5 = (double)a2->zbuffer_depth; - //v6 = v5; - //v7 = v5; - v8 = Billboard_ProbablyAddToListAndSortByZOrder(a2->zbuffer_depth); - pBillboardRenderListD3D[v8].opacity = RenderBillboardD3D::Opaque_1; - pBillboardRenderListD3D[v8].field_90 = a2->field_44; - pBillboardRenderListD3D[v8].sZValue = a2->sZValue; - pBillboardRenderListD3D[v8].sParentBillboardID = a2->sParentBillboardID; - //v9 = a2->uScreenSpaceX; - //v10 = a2->uScreenSpaceY; - v11 = (a2->_screenspace_x_scaler_packedfloat & 0xFFFF) * 0.000015260186 + HIWORD(a2->_screenspace_x_scaler_packedfloat); - //v12 = (double) a2->uScreenSpaceX; - //v13 = v12; - //v14 = (double)(a2->uScreenSpaceY - 12); - //v15 = v14; - v16 = (double)( a2->uScreenSpaceX - 12) - (double) a2->uScreenSpaceX; - v17 = (double)(a2->uScreenSpaceY - 25) - (double)(a2->uScreenSpaceY - 12); - v18 = stru_5C6E00->Cos(angle); - v19 = stru_5C6E00->Sin(angle); - v20 = stru_5C6E00->Sin(angle); - v21 = stru_5C6E00->Cos(angle); - pBillboardRenderListD3D[v8].pQuads[0].pos.x = (((double)(unsigned __int16)v18 * 0.000015259022 - + (double)(v18 >> 16)) - * v16 - - ((double)(unsigned __int16)v19 * 0.000015259022 - + (double)(v19 >> 16)) - * v17) - * v11 + (double) a2->uScreenSpaceX; - v22 = (((double)(unsigned __int16)v21 * 0.000015259022 + (double)(v21 >> 16)) * v17 - + ((double)(unsigned __int16)v20 * 0.000015259022 + (double)(v20 >> 16)) * v16 - - 12.0) - * v11 - + (double)a2->uScreenSpaceY; - pBillboardRenderListD3D[v8].pQuads[0].specular = 0; - pBillboardRenderListD3D[v8].pQuads[0].diffuse = uDiffuse; - pBillboardRenderListD3D[v8].pQuads[0].pos.y = v22; - pBillboardRenderListD3D[v8].pQuads[0].pos.z = 1.0 - 1.0 / (a2->zbuffer_depth * 0.061758894); - pBillboardRenderListD3D[v8].pQuads[0].rhw = 1.0 / a2->zbuffer_depth; - pBillboardRenderListD3D[v8].pQuads[0].texcoord.x = 0.0; - pBillboardRenderListD3D[v8].pQuads[0].texcoord.y = 0.0; - v31 = (double)(a2->uScreenSpaceX + 12) - (double) a2->uScreenSpaceX; - v32 = (double)a2->uScreenSpaceY - (double)(a2->uScreenSpaceY - 12); - v25 = stru_5C6E00->Cos(angle); - v26 = stru_5C6E00->Sin(angle); - v27 = stru_5C6E00->Sin(angle); - v28 = stru_5C6E00->Cos(angle); - pBillboardRenderListD3D[v8].pQuads[1].pos.x = (((double)(unsigned __int16)v25 * 0.000015259022 - + (double)(v25 >> 16)) - * v31 - - ((double)(unsigned __int16)v26 * 0.000015259022 - + (double)(v26 >> 16)) - * v32) - * v11 + (double) a2->uScreenSpaceX; - v29 = (((double)(unsigned __int16)v28 * 0.000015259022 + (double)(v28 >> 16)) * v32 - + ((double)(unsigned __int16)v27 * 0.000015259022 + (double)(v27 >> 16)) * v31 - - 12.0) - * v11 - + (double)a2->uScreenSpaceY; - pBillboardRenderListD3D[v8].pQuads[1].pos.z = pRenderer->pBillboardRenderListD3D[v8].pQuads[0].pos.z; - v30 = pBillboardRenderListD3D[v8].pQuads[0].rhw; - pBillboardRenderListD3D[v8].pQuads[1].pos.y = v29; - pBillboardRenderListD3D[v8].pQuads[1].specular = 0; - pBillboardRenderListD3D[v8].pQuads[1].rhw = v30; - pBillboardRenderListD3D[v8].pQuads[1].diffuse = uDiffuse; - pBillboardRenderListD3D[v8].pQuads[1].texcoord.x = 0.0; - pBillboardRenderListD3D[v8].pQuads[1].texcoord.y = 1.0; - v23 = (double)(a2->uScreenSpaceX - 12) - (double) a2->uScreenSpaceX; - v24 = (double)a2->uScreenSpaceY - (double)(a2->uScreenSpaceY - 12); - v33 = stru_5C6E00->Cos(angle); - v34 = stru_5C6E00->Sin(angle); - v35 = stru_5C6E00->Sin(angle); - v36 = stru_5C6E00->Cos(angle); - pBillboardRenderListD3D[v8].pQuads[2].pos.x = (((double)(unsigned __int16)v33 * 0.000015259022 - + (double)(v33 >> 16)) - * v23 - - ((double)(unsigned __int16)v34 * 0.000015259022 - + (double)(v34 >> 16)) - * v24) - * v11 + (double) a2->uScreenSpaceX; - v37 = pBillboardRenderListD3D[v8].pQuads[0].pos.z; - v38 = (((double)(unsigned __int16)v36 * 0.000015259022 + (double)(v36 >> 16)) * v24 - + ((double)(unsigned __int16)v35 * 0.000015259022 + (double)(v35 >> 16)) * v23 - - 12.0) - * v11 - + (double)a2->uScreenSpaceY; - pBillboardRenderListD3D[v8].pQuads[2].specular = 0; - pBillboardRenderListD3D[v8].pQuads[2].pos.z = v37; - pBillboardRenderListD3D[v8].pQuads[2].rhw = pBillboardRenderListD3D[v8].pQuads[0].rhw; - pBillboardRenderListD3D[v8].pQuads[2].diffuse = uDiffuse; - pBillboardRenderListD3D[v8].pQuads[2].pos.y = v38; - pBillboardRenderListD3D[v8].pQuads[2].texcoord.x = 1.0; - pBillboardRenderListD3D[v8].pQuads[2].texcoord.y = 1.0; - v39 = (double)(a2->uScreenSpaceX + 12) - (double) a2->uScreenSpaceX; - v40 = (double)(a2->uScreenSpaceY - 25) - (double)(a2->uScreenSpaceY - 12); - v41 = stru_5C6E00->Cos(angle); - v42 = stru_5C6E00->Sin(angle); - v43 = stru_5C6E00->Sin(angle); - v44 = stru_5C6E00->Cos(angle); - pBillboardRenderListD3D[v8].pQuads[3].pos.x = (((double)(unsigned __int16)v41 * 0.000015259022 - + (double)(v41 >> 16)) - * v39 - - ((double)(unsigned __int16)v42 * 0.000015259022 - + (double)(v42 >> 16)) - * v40) - * v11 + (double) a2->uScreenSpaceX; - v45 = (((double)(unsigned __int16)v44 * 0.000015259022 + (double)(v44 >> 16)) * v40 - + ((double)(unsigned __int16)v43 * 0.000015259022 + (double)(v43 >> 16)) * v39 - - 12.0) - * v11 - + (double)a2->uScreenSpaceY; - v46 = pBillboardRenderListD3D[v8].pQuads[0].pos.z; - pBillboardRenderListD3D[v8].pQuads[3].specular = 0; - pBillboardRenderListD3D[v8].pQuads[3].pos.z = v46; - pBillboardRenderListD3D[v8].pQuads[3].rhw = pBillboardRenderListD3D[v8].pQuads[0].rhw; - pBillboardRenderListD3D[v8].pQuads[3].diffuse = uDiffuse; - pBillboardRenderListD3D[v8].pTexture = a3; - pBillboardRenderListD3D[v8].z_order = a2->zbuffer_depth; - pBillboardRenderListD3D[v8].uNumVertices = 4; - pBillboardRenderListD3D[v8].pQuads[3].pos.y = v45; - pBillboardRenderListD3D[v8].pQuads[3].texcoord.x = 1.0; - pBillboardRenderListD3D[v8].pQuads[3].texcoord.y = 0.0; - } - } -} - -//----- (004A3AD9) -------------------------------------------------------- -void Render::MakeParticleBillboardAndPush_ODM(RenderBillboardTransform_local0 *a2, IDirect3DTexture2 *a3, unsigned int uDiffuse, int angle) -{ - double v5; // st7@2 - float v6; // ST28_4@2 - float v7; // ST00_4@2 - unsigned int v8; // esi@2 - //int v9; // eax@2 - //int v10; // ebx@2 - float v11; // ST34_4@2 - double v12; // st7@2 - float v13; // ST2C_4@2 - double v14; // st6@2 - float v15; // ST24_4@2 - float v16; // ST38_4@2 - float v17; // ST3C_4@2 - signed int v18; // ST1C_4@2 - int v19; // ST30_4@2 - signed int v20; // ST20_4@2 - signed int v21; // ST18_4@2 - signed int v22; // eax@2 - double v23; // st6@2 - float v24; // ST20_4@2 - float v25; // ST1C_4@2 - float v26; // ST38_4@2 - float v27; // ST3C_4@2 - signed int v28; // ST18_4@2 - signed int v29; // ST14_4@2 - signed int v30; // ST10_4@2 - signed int v31; // eax@2 - double v32; // st6@2 - float v33; // ST38_4@2 - float v34; // ST3C_4@2 - signed int v35; // ST10_4@2 - signed int v36; // ST14_4@2 - signed int v37; // ST18_4@2 - signed int v38; // eax@2 - double v39; // st6@2 - float v40; // ST38_4@2 - float v41; // ST3C_4@2 - signed int v42; // ST10_4@2 - signed int v43; // ST14_4@2 - signed int v44; // ST18_4@2 - signed int v45; // eax@2 - double v46; // st6@2 - - if ( this->uNumD3DSceneBegins ) - { - v5 = (double)a2->zbuffer_depth; - v6 = v5; - v7 = v5; - v8 = Billboard_ProbablyAddToListAndSortByZOrder(LODWORD(v7)); - pBillboardRenderListD3D[v8].opacity = RenderBillboardD3D::Opaque_1; - pBillboardRenderListD3D[v8].field_90 = a2->field_44; - pBillboardRenderListD3D[v8].sZValue = a2->sZValue; - pBillboardRenderListD3D[v8].sParentBillboardID = a2->sParentBillboardID; - - //v9 = a2->uScreenSpaceX; - //v10 = a2->uScreenSpaceY; - v11 = (a2->_screenspace_x_scaler_packedfloat & 0xFFFF) * 0.000015260186 + HIWORD(a2->_screenspace_x_scaler_packedfloat); - v12 = (double)a2->uScreenSpaceX; - v13 = (double)a2->uScreenSpaceX; - v14 = (double)(a2->uScreenSpaceY - 12); - v15 = v14; - v16 = (double)(a2->uScreenSpaceX - 12) - v12; - v17 = (double)(a2->uScreenSpaceY - 25) - v14; - v18 = stru_5C6E00->Cos(angle); - v19 = angle - stru_5C6E00->uIntegerHalfPi; - v20 = stru_5C6E00->Sin(angle); - v21 = stru_5C6E00->Sin(angle); - v22 = stru_5C6E00->Cos(angle); - pBillboardRenderListD3D[v8].pQuads[0].pos.x = (((double)(unsigned __int16)v18 * 0.000015259022 - + (double)(v18 >> 16)) * v16 - - ((double)(unsigned __int16)v20 * 0.000015259022 - + (double)(v20 >> 16)) * v17) - * v11 + v13; - v23 = (((double)(unsigned __int16)v22 * 0.000015259022 + (double)(v22 >> 16)) * v17 - + ((double)(unsigned __int16)v21 * 0.000015259022 + (double)(v21 >> 16)) * v16 - - 12.0) - * v11 - + (double)a2->uScreenSpaceY; - pBillboardRenderListD3D[v8].pQuads[0].specular = 0; - pBillboardRenderListD3D[v8].pQuads[0].diffuse = uDiffuse; - pBillboardRenderListD3D[v8].pQuads[0].pos.y = v23; - v24 = 1.0 - 1.0 / (v6 * 1000.0 / (double)pODMRenderParams->shading_dist_mist); - pBillboardRenderListD3D[v8].pQuads[0].pos.z = v24; - v25 = 1.0 / v6; - pBillboardRenderListD3D[v8].pQuads[0].rhw = v25; - pBillboardRenderListD3D[v8].pQuads[0].texcoord.x = 0.0; - pBillboardRenderListD3D[v8].pQuads[0].texcoord.y = 0.0; - - v26 = (double)(a2->uScreenSpaceX - 12) - v13; - v27 = (double)a2->uScreenSpaceY - v15; - v28 = stru_5C6E00->Cos(angle); - v29 = stru_5C6E00->Sin(v19 + stru_5C6E00->uIntegerHalfPi); - v30 = stru_5C6E00->Sin(v19 + stru_5C6E00->uIntegerHalfPi); - v31 = stru_5C6E00->Cos(angle); - pBillboardRenderListD3D[v8].pQuads[1].pos.x = (((double)(unsigned __int16)v28 * 0.000015259022 - + (double)(v28 >> 16)) * v26 - - ((double)(unsigned __int16)v29 * 0.000015259022 - + (double)(v29 >> 16)) * v27) - * v11 + v13; - v32 = (((double)(unsigned __int16)v31 * 0.000015259022 + (double)(v31 >> 16)) * v27 - + ((double)(unsigned __int16)v30 * 0.000015259022 + (double)(v30 >> 16)) * v26 - - 12.0) - * v11 - + (double)a2->uScreenSpaceY; - pBillboardRenderListD3D[v8].pQuads[1].pos.z = v24; - pBillboardRenderListD3D[v8].pQuads[1].pos.y = v32; - pBillboardRenderListD3D[v8].pQuads[1].specular = 0; - pBillboardRenderListD3D[v8].pQuads[1].rhw = v25; - pBillboardRenderListD3D[v8].pQuads[1].diffuse = uDiffuse; - pBillboardRenderListD3D[v8].pQuads[1].texcoord.x = 0.0; - pBillboardRenderListD3D[v8].pQuads[1].texcoord.y = 1.0; - - v33 = (double)(a2->uScreenSpaceX + 12) - v13; - v34 = (double)a2->uScreenSpaceY - v15; - v35 = stru_5C6E00->Cos(angle); - v36 = stru_5C6E00->Sin(v19 + stru_5C6E00->uIntegerHalfPi); - v37 = stru_5C6E00->Sin(v19 + stru_5C6E00->uIntegerHalfPi); - v38 = stru_5C6E00->Cos(angle); - pBillboardRenderListD3D[v8].pQuads[2].pos.x = (((double)(unsigned __int16)v35 * 0.000015259022 - + (double)(v35 >> 16)) * v33 - - ((double)(unsigned __int16)v36 * 0.000015259022 - + (double)(v36 >> 16)) * v34) - * v11 + v13; - v39 = (((double)(unsigned __int16)v38 * 0.000015259022 + (double)(v38 >> 16)) * v34 - + ((double)(unsigned __int16)v37 * 0.000015259022 + (double)(v37 >> 16)) * v33 - - 12.0) - * v11 - + (double)a2->uScreenSpaceY; - pBillboardRenderListD3D[v8].pQuads[2].specular = 0; - pBillboardRenderListD3D[v8].pQuads[2].pos.z = v24; - pBillboardRenderListD3D[v8].pQuads[2].rhw = v25; - pBillboardRenderListD3D[v8].pQuads[2].diffuse = uDiffuse; - pBillboardRenderListD3D[v8].pQuads[2].pos.y = v39; - pBillboardRenderListD3D[v8].pQuads[2].texcoord.x = 1.0; - pBillboardRenderListD3D[v8].pQuads[2].texcoord.y = 1.0; - - v40 = (double)(a2->uScreenSpaceX + 12) - v13; - v41 = (double)(a2->uScreenSpaceY - 25) - v15; - v42 = stru_5C6E00->Cos(angle); - v43 = stru_5C6E00->Sin(v19 + stru_5C6E00->uIntegerHalfPi); - v44 = stru_5C6E00->Sin(v19 + stru_5C6E00->uIntegerHalfPi); - v45 = stru_5C6E00->Cos(angle); - pBillboardRenderListD3D[v8].pQuads[3].pos.x = (((double)(unsigned __int16)v42 * 0.000015259022 - + (double)(v42 >> 16)) * v40 - - ((double)(unsigned __int16)v43 * 0.000015259022 - + (double)(v43 >> 16)) * v41) - * v11 + v13; - v46 = (((double)(unsigned __int16)v45 * 0.000015259022 + (double)(v45 >> 16)) * v41 - + ((double)(unsigned __int16)v44 * 0.000015259022 + (double)(v44 >> 16)) * v40 - - 12.0) - * v11 - + (double)a2->uScreenSpaceY; - pBillboardRenderListD3D[v8].pQuads[3].specular = 0; - pBillboardRenderListD3D[v8].pQuads[3].pos.z = v24; - pBillboardRenderListD3D[v8].pQuads[3].rhw = v25; - pBillboardRenderListD3D[v8].pQuads[3].diffuse = uDiffuse; - pBillboardRenderListD3D[v8].pTexture = a3; - pBillboardRenderListD3D[v8].z_order = v6; - pBillboardRenderListD3D[v8].uNumVertices = 4; - pBillboardRenderListD3D[v8].pQuads[3].pos.y = v46; - pBillboardRenderListD3D[v8].pQuads[3].texcoord.x = 1.0; - pBillboardRenderListD3D[v8].pQuads[3].texcoord.y = 0.0; - } -} - -//----- (004A4023) -------------------------------------------------------- -void Render::TransformBillboard(RenderBillboardTransform_local0 *a2, Sprite *pSprite, int dimming_level, RenderBillboard *pBillboard) -{ - unsigned int v8; // esi@2 - double v14; // st6@14 - double v15; // st5@14 - float v29; // [sp+28h] [bp-8h]@5 - float v30; // [sp+2Ch] [bp-4h]@5 - - if (!uNumD3DSceneBegins) - return; - - v8 = Billboard_ProbablyAddToListAndSortByZOrder(a2->zbuffer_depth); - - v30 = (a2->_screenspace_x_scaler_packedfloat & 0xFFFF) / 65530.0 + HIWORD(a2->_screenspace_x_scaler_packedfloat); - v29 = (a2->_screenspace_y_scaler_packedfloat & 0xFFFF) / 65530.0 + HIWORD(a2->_screenspace_y_scaler_packedfloat); - - unsigned int diffuse = ::GetActorTintColor(dimming_level, 0, a2->zbuffer_depth, 0, pBillboard); - if (a2->sTintColor & 0x00FFFFFF && bTinting) - { - diffuse = BlendColors(a2->sTintColor, diffuse); - if (a2->sTintColor & 0xFF000000) - diffuse = 0x007F7F7F & ((unsigned int)diffuse >> 1); - } - - unsigned int specular = 0; - if (bUsingSpecular) - specular = sub_47C3D7_get_fog_specular(0, 0, a2->zbuffer_depth); - - v14 = (double)((int)pSprite->uBufferWidth / 2 - pSprite->uAreaX); - v15 = (double)((int)pSprite->uBufferHeight - pSprite->uAreaY); - if (a2->uFlags & 4) - v14 *= -1.0; - pBillboardRenderListD3D[v8].pQuads[0].diffuse = diffuse; - pBillboardRenderListD3D[v8].pQuads[0].pos.x = (double)a2->uScreenSpaceX - v14 * v30; - pBillboardRenderListD3D[v8].pQuads[0].pos.y = (double)a2->uScreenSpaceY - v15 * v29; - pBillboardRenderListD3D[v8].pQuads[0].pos.z = 1.0 - 1.0 / (a2->zbuffer_depth * 1000.0 / (double)pODMRenderParams->shading_dist_mist); - pBillboardRenderListD3D[v8].pQuads[0].rhw = 1.0 / a2->zbuffer_depth; - pBillboardRenderListD3D[v8].pQuads[0].specular = specular; - pBillboardRenderListD3D[v8].pQuads[0].texcoord.x = 0.0; - pBillboardRenderListD3D[v8].pQuads[0].texcoord.y = 0.0; - - v14 = (double)((int)pSprite->uBufferWidth / 2 - pSprite->uAreaX); - v15 = (double)((int)pSprite->uBufferHeight - pSprite->uAreaHeight - pSprite->uAreaY); - if ( a2->uFlags & 4 ) - v14 = v14 * -1.0; - pBillboardRenderListD3D[v8].pQuads[1].specular = specular; - pBillboardRenderListD3D[v8].pQuads[1].diffuse = diffuse; - pBillboardRenderListD3D[v8].pQuads[1].pos.x = (double)a2->uScreenSpaceX - v14 * v30; - pBillboardRenderListD3D[v8].pQuads[1].pos.y = (double)a2->uScreenSpaceY - v15 * v29; - pBillboardRenderListD3D[v8].pQuads[1].pos.z = 1.0 - 1.0 / (a2->zbuffer_depth * 1000.0 / (double)pODMRenderParams->shading_dist_mist); - pBillboardRenderListD3D[v8].pQuads[1].rhw = 1.0 / a2->zbuffer_depth; - pBillboardRenderListD3D[v8].pQuads[1].texcoord.x = 0.0; - pBillboardRenderListD3D[v8].pQuads[1].texcoord.y = 1.0; - - v14 = (double)((int)pSprite->uAreaWidth + pSprite->uAreaX + pSprite->uBufferWidth / 2 - pSprite->uBufferWidth); - v15 = (double)((int)pSprite->uBufferHeight - pSprite->uAreaHeight - pSprite->uAreaY); - if ( a2->uFlags & 4 ) - v14 *= -1.0; - pBillboardRenderListD3D[v8].pQuads[2].diffuse = diffuse; - pBillboardRenderListD3D[v8].pQuads[2].specular = specular; - pBillboardRenderListD3D[v8].pQuads[2].pos.x = (double)a2->uScreenSpaceX + v14 * v30; - pBillboardRenderListD3D[v8].pQuads[2].pos.y = (double)a2->uScreenSpaceY - v15 * v29; - pBillboardRenderListD3D[v8].pQuads[2].pos.z = 1.0 - 1.0 / (a2->zbuffer_depth * 1000.0 / (double)pODMRenderParams->shading_dist_mist); - pBillboardRenderListD3D[v8].pQuads[2].rhw = 1.0 / a2->zbuffer_depth; - pBillboardRenderListD3D[v8].pQuads[2].texcoord.x = 1.0; - pBillboardRenderListD3D[v8].pQuads[2].texcoord.y = 1.0; - - v14 = (double)((int)pSprite->uAreaWidth + pSprite->uAreaX + pSprite->uBufferWidth / 2 - pSprite->uBufferWidth); - v15 = (double)((int)pSprite->uBufferHeight - pSprite->uAreaY); - if ( a2->uFlags & 4 ) - v14 *= -1.0; - pBillboardRenderListD3D[v8].pQuads[3].diffuse = diffuse; - pBillboardRenderListD3D[v8].pQuads[3].specular = specular; - pBillboardRenderListD3D[v8].pQuads[3].pos.x = (double)a2->uScreenSpaceX + v14 * v30; - pBillboardRenderListD3D[v8].pQuads[3].pos.y = (double)a2->uScreenSpaceY - v15 * v29; - pBillboardRenderListD3D[v8].pQuads[3].pos.z = 1.0 - 1.0 / (a2->zbuffer_depth * 1000.0 / (double)pODMRenderParams->shading_dist_mist); - pBillboardRenderListD3D[v8].pQuads[3].rhw = 1.0 / a2->zbuffer_depth; - pBillboardRenderListD3D[v8].pQuads[3].texcoord.x = 1.0; - pBillboardRenderListD3D[v8].pQuads[3].texcoord.y = 0.0; - - pBillboardRenderListD3D[v8].uNumVertices = 4; - pBillboardRenderListD3D[v8].pTexture = pSprite->pTexture; - pBillboardRenderListD3D[v8].z_order = a2->zbuffer_depth; - pBillboardRenderListD3D[v8].field_90 = a2->field_44; - pBillboardRenderListD3D[v8].sZValue = a2->sZValue; - pBillboardRenderListD3D[v8].sParentBillboardID = a2->sParentBillboardID; - - if (a2->sTintColor & 0xFF000000) - pBillboardRenderListD3D[v8].opacity = RenderBillboardD3D::Opaque_3; - else - pBillboardRenderListD3D[v8].opacity = RenderBillboardD3D::Transparent; -} - - -//----- (004A49D0) -------------------------------------------------------- -void Render::DrawProjectile(float srcX, float srcY, float a3, float a4, float dstX, float dstY, float a7, float a8, IDirect3DTexture2 *a9) -{ - int absXDifference; // eax@1 - int absYDifference; // eax@1 - unsigned int smallerabsdiff; // ebx@1 - unsigned int largerabsdiff; - double v16; // st7@7 - double v17; // st7@7 - double v18; // st6@7 - double v20; // st4@8 - double v21; // st4@10 - double v22; // st4@10 - double v23; // st4@10 - double v25; // st4@11 - double v26; // st4@13 - double v28; // st4@13 - RenderVertexD3D3 v29[4]; // [sp+0h] [bp-94h]@7 - int xDifference; // [sp+88h] [bp-Ch]@1 - signed int v32; // [sp+8Ch] [bp-8h]@1 - int yDifference; // [sp+90h] [bp-4h]@1 - - xDifference = bankersRounding(dstX - srcX); - yDifference = bankersRounding(dstY - srcY); - absYDifference = abs(yDifference); - absXDifference = abs(xDifference); - smallerabsdiff = min(absXDifference, absYDifference); - largerabsdiff = max(absXDifference, absYDifference); - v32 = (11 * smallerabsdiff >> 5) + largerabsdiff; - v16 = 1.0 / (double)v32; - v17 = (double)yDifference * v16 * a4; - v18 = (double)xDifference * v16 * a4; - if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor ) - { - v20 = a3 * 1000.0 / (double)pODMRenderParams->shading_dist_mist; - v25 = a7 * 1000.0 / (double)pODMRenderParams->shading_dist_mist; - } - else - { - v20 = a3 * 0.061758894; - v25 = a7 * 0.061758894; - } - v21 = 1.0 / a3; - v22 = (double)yDifference * v16 * a8; - v23 = (double)xDifference * v16 * a8; - v26 = 1.0 - 1.0 / v25; - v28 = 1.0 / a7; - v29[0].pos.x = srcX + v17; - v29[0].pos.y = srcY - v18; - v29[0].pos.z = 1.0 - 1.0 / v20; - v29[0].rhw = v21; - v29[0].diffuse = -1; - v29[0].specular = 0; - v29[0].texcoord.x = 1.0; - v29[0].texcoord.y = 0.0; - - v29[1].pos.x = v22 + dstX; - v29[1].pos.y = dstY - v23; - v29[1].pos.z = v26; - v29[1].rhw = v28; - v29[1].diffuse = -16711936; - v29[1].specular = 0; - v29[1].texcoord.x = 1.0; - v29[1].texcoord.y = 1.0; - - v29[2].pos.x = dstX - v22; - v29[2].pos.y = v23 + dstY; - v29[2].pos.z = v26; - v29[2].rhw = v28; - v29[2].diffuse = -1; - v29[2].specular = 0; - v29[2].texcoord.x = 0.0; - v29[2].texcoord.y = 1.0; - - v29[3].pos.x = srcX - v17; - v29[3].pos.y = v18 + srcY; - v29[3].pos.z = v29[0].pos.z; - v29[3].rhw = v21; - v29[3].diffuse = -1; - v29[3].specular = 0; - v29[3].texcoord.x = 0.0; - v29[3].texcoord.y = 0.0; - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, FALSE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE)); - ErrD3D(pRenderD3D->pDevice->SetTexture(0, a9)); - ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, - D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, v29, 4, 24)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CW)); -} - -//----- (004A4CC9) -------------------------------------------------------- -void Render::_4A4CC9_AddSomeBillboard(stru6_stru1_indoor_sw_billboard *a1, int diffuse) -{ - unsigned int v5; // eax@7 - double v10; // st6@9 - double v11; // st6@10 - int v12; // ebx@13 - - if (a1->uNumVertices < 3) - return; - - float depth = 1000000.0; - for (uint i = 0; i < (unsigned int)a1->uNumVertices; ++i) - { - if (a1->field_104[i].z < depth) - depth = a1->field_104[i * 4].z; - } - - v5 = Billboard_ProbablyAddToListAndSortByZOrder(depth); - pBillboardRenderListD3D[v5].field_90 = 0; - pBillboardRenderListD3D[v5].sParentBillboardID = -1; - pBillboardRenderListD3D[v5].opacity = RenderBillboardD3D::Opaque_2; - pBillboardRenderListD3D[v5].pTexture = 0; - pBillboardRenderListD3D[v5].uNumVertices = a1->uNumVertices; - pBillboardRenderListD3D[v5].z_order = depth; - - for (uint i = 0; i < (unsigned int)a1->uNumVertices; ++i) - { - pBillboardRenderListD3D[v5].pQuads[i].pos.x = a1->field_104[i].x; - pBillboardRenderListD3D[v5].pQuads[i].pos.y = a1->field_104[i].y; - - v10 = a1->field_104[i].z; - if (uCurrentlyLoadedLevelType == LEVEL_Indoor) - v11 = v10 * 0.061758894; - else - v11 = v10 * 1000.0 / (double)pODMRenderParams->shading_dist_mist; - pBillboardRenderListD3D[v5].pQuads[i].pos.z = 1.0 - 1.0 / v11; - pBillboardRenderListD3D[v5].pQuads[i].rhw = 1.0 / a1->field_104[i].z; - - if (diffuse & 0xFF000000) - v12 = a1->field_104[i].diffuse; - else - v12 = diffuse; - pBillboardRenderListD3D[v5].pQuads[i].diffuse = v12; - pBillboardRenderListD3D[v5].pQuads[i].specular = 0; - - pBillboardRenderListD3D[v5].pQuads[i].texcoord.x = 0.0; - pBillboardRenderListD3D[v5].pQuads[i].texcoord.y = 0.0; - } -} - -//----- (004A4DE1) -------------------------------------------------------- -bool Render::LoadTexture(const char *pName, unsigned int bMipMaps, IDirectDrawSurface4 **pOutSurface, IDirect3DTexture2 **pOutTexture) -{ - unsigned __int16 *v13; // ecx@19 - unsigned __int16 *v14; // eax@19 - DWORD v15; // edx@20 - stru350 Dst; // [sp+Ch] [bp-F8h]@12 - - HWLTexture* pHWLTexture = pD3DBitmaps.LoadTexture(pName, bMipMaps); - if ( pHWLTexture ) - { - bMipMaps = !strncmp(pName, "HDWTR", 5); - if ( !pRenderD3D->CreateTexture(pHWLTexture->uWidth, pHWLTexture->uHeight, pOutSurface, pOutTexture, true, - bMipMaps, uMinDeviceTextureDim) ) - Error("HiScreen16::LoadTexture - D3Drend->CreateTexture() failed: %x", 0); - if (bMipMaps) - { - Dst._450DDE(); - Dst._450DF1(&stru_4EFCBC, &stru_4EFCBC); - - IDirectDrawSurface4 *pNextSurf = *pOutSurface; - while ( 1 ) - { - DDSCAPS2 v19; - memset(&v19, 0, sizeof(DDSCAPS2)); - v19.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP; - - DDSURFACEDESC2 desc; - memset(&desc, 0, sizeof(DDSURFACEDESC2)); - desc.dwSize = sizeof(DDSURFACEDESC2); - - if ( LockSurface_DDraw4(pNextSurf, &desc, DDLOCK_WAIT | DDLOCK_WRITEONLY) ) - { - // linear scaling - for (int s = 0; s < desc.dwHeight; ++s) - for (int t = 0; t < desc.dwWidth; ++t) - { - unsigned int resampled_x = t * pHWLTexture->uWidth / desc.dwWidth, - resampled_y = s * pHWLTexture->uHeight / desc.dwHeight; - unsigned short sample = pHWLTexture->pPixels[resampled_y * pHWLTexture->uWidth + resampled_x]; - - ((unsigned short *)desc.lpSurface)[s * (desc.lPitch >> 1) + t] = sample; - } - - - //bicubic sampling - //Dst.sub_451007_scale_image_bicubic(pHWLTexture->pPixels, pHWLTexture->uWidth, pHWLTexture->uHeight, pHWLTexture->uWidth, - // (unsigned short *)desc.lpSurface, desc.dwWidth, desc.dwHeight, desc.lPitch >> 1, 0, 0); - - ErrD3D(pNextSurf->Unlock(NULL)); - //bMipMaps = 0x4D86ACu; - } - if (FAILED(pNextSurf->GetAttachedSurface(&v19, &pNextSurf))) - break; - } - //v20 = -1; - //nullsub_1(); - } - else - { - DDSCAPS2 v19; - memset(&v19, 0, sizeof(DDSCAPS2)); - v19.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP; - - DDSURFACEDESC2 desc; - memset(&desc, 0, sizeof(DDSURFACEDESC2)); - desc.dwSize = sizeof(DDSURFACEDESC2); - - if ( LockSurface_DDraw4(*pOutSurface, &desc, DDLOCK_WAIT | DDLOCK_WRITEONLY) ) - { - bMipMaps = 0; - v13 = pHWLTexture->pPixels; - v14 = (unsigned __int16 *)desc.lpSurface; - for(uint bMipMaps = 0; bMipMaps < desc.dwHeight; bMipMaps++) - { - for (v15 = 0; v15 < desc.dwWidth; v15++) - { - *v14 = *v13; - ++v14; - ++v13; - } - v14 += (desc.lPitch >> 1) - desc.dwWidth; - } - ErrD3D((*pOutSurface)->Unlock(NULL)); - } - } - delete [] pHWLTexture->pPixels; - delete pHWLTexture; - return true; - } - return false; -} - -//----- (004A5048) -------------------------------------------------------- -bool Render::MoveSpriteToDevice( Sprite *pSprite ) -{ - HWLTexture *sprite_texture; // eax@1 - unsigned __int16 *v9; // edx@5 - LPVOID v10; // eax@5 - DDSURFACEDESC2 Dst; // [sp+Ch] [bp-7Ch]@4 - - sprite_texture = pD3DSprites.LoadTexture(pSprite->pName, pSprite->uPaletteID); - if ( sprite_texture ) - { - pSprite->uAreaX = sprite_texture->uAreaX; - pSprite->uAreaY = sprite_texture->uAreaY; - pSprite->uBufferWidth = sprite_texture->uBufferWidth; - pSprite->uBufferHeight = sprite_texture->uBufferHeight; - pSprite->uAreaWidth = sprite_texture->uAreaWidth; - pSprite->uAreaHeight = sprite_texture->uAreaHeigth; - if (!pRenderD3D->CreateTexture(sprite_texture->uWidth, sprite_texture->uHeight, &pSprite->pTextureSurface, &pSprite->pTexture, 1u, 0, uMinDeviceTextureDim)) - Error("HiScreen16::LoadTexture - D3Drend->CreateTexture() failed: %x", 0); - memset(&Dst, 0, sizeof(DDSURFACEDESC2)); - Dst.dwSize = 124; - if ( LockSurface_DDraw4((IDirectDrawSurface4 *)pSprite->pTextureSurface, &Dst, DDLOCK_WAIT | DDLOCK_WRITEONLY) ) - { - v9 = sprite_texture->pPixels; - v10 = Dst.lpSurface; - for (uint i=0; iuHeight; ++i) - { - for (uint j=0; juWidth/2; ++j) - { - *(int *)v10 = *(int *)v9; - v9 += 2; - v10 = (char *)v10 + 4; - } - v10 = (char *)v10 + Dst.lPitch-sprite_texture->uWidth*2; - } - ErrD3D(pSprite->pTextureSurface->Unlock(NULL)); - } - delete [] sprite_texture->pPixels; - delete sprite_texture; - return true; - } - return false; -} - -//----- (004A51CB) -------------------------------------------------------- -void Render::BeginScene() -{ - //Render *v1; // esi@1 - unsigned int v2; // eax@1 -/*int v3; // eax@5 - unsigned __int16 **v4; // edi@6 - char *v5; // ebx@7*/ -// DDSURFACEDESC2 Dst; // [sp+Ch] [bp-7Ch]@4 - - //v1 = this; - v2 = this->uNumSceneBegins; - this->uNumSceneBegins = v2 + 1; - if ( !v2 ) - { - if ( this->pRenderD3D ) - { - /*if ( this->bColorKeySupported ) - { - memset(&Dst, 0, 0x7Cu); - Dst.dwSize = 124; - if ( LockSurface_DDraw4(this->pColorKeySurface4, &Dst, 0x800 | DDLOCK_WAIT) ) - { - this->pTargetSurface = (unsigned __int16 *)Dst.lpSurface; - this->uTargetSurfacePitch = Dst.lPitch >> 1; - this->field_18_locked_pitch = Dst.lPitch >> 1; - } - --this->uNumSceneBegins; - }*/ - } - else - { - if ( !this->pTargetSurface ) - { - LockRenderSurface((void **)&this->pTargetSurface, &this->uTargetSurfacePitch); - /*if ( this->pTargetSurface ) - { - this->field_18_locked_pitch = this->uTargetSurfacePitch; - }*/ - --this->uNumSceneBegins; - } - } - RestoreFrontBuffer(); - } -} - -//----- (004A527D) -------------------------------------------------------- -void Render::EndScene() -{ - if ( this->uNumSceneBegins ) - { - this->uNumSceneBegins--; - if ( !this->uNumSceneBegins ) - { - if ( this->pRenderD3D ) - { - /*if ( this->bColorKeySupported ) - { - this->pTargetSurface = 0; - this->uTargetSurfacePitch = 0; - this->field_18_locked_pitch = 0; - ErrD3D(this->pColorKeySurface4->Unlock(NULL)); - }*/ - } - else - { - this->pTargetSurface = 0; - this->uTargetSurfacePitch = 0; - //this->field_18_locked_pitch = 0; - UnlockBackBuffer(); - } - } - } -} - -//----- (004A52F1) -------------------------------------------------------- -void Render::ScreenFade(unsigned int color, float t) -{ - unsigned int v3; // esi@1 - unsigned int v7; // eax@6 - RenderVertexD3D3 v36[4]; // [sp+Ch] [bp-94h]@6 - int v40; // [sp+9Ch] [bp-4h]@6 - - v3 = 0; - - //{ - if (t > 1.0f) - t = 1.0f; - else if (t < 0.0f) - t = 0.0f; - - v40 = (char)floorf(t * 255.0f + 0.5f); - - v7 = color | (v40 << 24); - - v36[0].specular = 0; - v36[0].pos.x = pViewport->uViewportTL_X; - v36[0].pos.y = (double)pViewport->uViewportTL_Y; - v36[0].pos.z = 0.0; - v36[0].diffuse = v7; - v36[0].rhw = 1.0; - v36[0].texcoord.x = 0.0; - v36[0].texcoord.y = 0.0; - - v36[1].specular = 0; - v36[1].pos.x = pViewport->uViewportTL_X; - v36[1].pos.y = (double)(pViewport->uViewportBR_Y + 1); - v36[1].pos.z = 0.0; - v36[1].diffuse = v7; - v36[1].rhw = 1.0; - v36[1].texcoord.x = 0.0; - v36[1].texcoord.y = 0.0; - - v36[2].specular = 0; - v36[2].pos.x = (double)pViewport->uViewportBR_X; - v36[2].pos.y = (double)(pViewport->uViewportBR_Y + 1); - v36[2].pos.z = 0.0; - v36[2].diffuse = v7; - v36[2].rhw = 1.0; - v36[2].texcoord.x = 0.0; - v36[2].texcoord.y = 0.0; - - v36[3].specular = 0; - v36[3].pos.x = (double)pViewport->uViewportBR_X; - v36[3].pos.y = (double)pViewport->uViewportTL_Y; - v36[3].pos.z = 0.0; - v36[3].diffuse = v7; - v36[3].rhw = 1.0; - v36[3].texcoord.x = 0.0; - v36[3].texcoord.y = 0.0; - - ErrD3D(pRenderD3D->pDevice->SetTexture(0, 0)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, FALSE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, D3DCMP_ALWAYS)); - ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, - D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, v36, 4, 28)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, D3DCMP_LESS)); - /*} - else - { - v40 = (1.0 - a3) * 65536.0; - v39 = v40 + 6.7553994e15; - LODWORD(a3) = LODWORD(v39); - v38 = (signed int)(pViewport->uViewportBR_X - pViewport->uViewportTL_X) >> 1; - HIDWORD(v39) = pViewport->uViewportBR_Y - pViewport->uViewportTL_Y + 1; - v13 = pViewport->uViewportTL_X + ecx0->uTargetSurfacePitch - pViewport->uViewportBR_X; - v14 = &ecx0->pTargetSurface[pViewport->uViewportTL_X + pViewport->uViewportTL_Y * ecx0->uTargetSurfacePitch]; - v37 = 2 * v13; - LODWORD(v40) = (int)v14; - - int __i = 0; - v15 = dword_F1B430.data(); - do - { - v16 = v3; - v3 += LODWORD(a3); - dword_F1B430[__i++] = v16 >> 16; - } - //while ( (signed int)v15 < (signed int)&Aureal3D_SplashScreen ); - while (__i < 32); - - if ( pRenderer->uTargetGBits == 6 ) - { - v17 = sr_42690D_colors_cvt(this_); - v18 = (65536 - LODWORD(a3)) * (v17 & 0x1F); - this_ = (((65536 - LODWORD(a3)) * (unsigned __int16)(v17 & 0xF800) & 0xF800FFFF | v18 & 0x1F0000 | (65536 - LODWORD(a3)) * (v17 & 0x7E0) & 0x7E00000u) >> 16 << 16) | (((65536 - LODWORD(a3)) * (unsigned __int16)(v17 & 0xF800) & 0xF800FFFF | v18 & 0x1F0000 | (65536 - LODWORD(a3)) * (v17 & 0x7E0) & 0x7E00000u) >> 16); - v19 = v40; - v20 = off_4EFDB0; - v21 = HIDWORD(v39); - do - { - v22 = v38; - v31 = v21; - do - { - v23 = (*(int *)((char *)v20 - + ((((unsigned __int16)(*(short *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF800u) >> 9)) << 11) | *(unsigned int *)LODWORD(v19) & 0x7FF) & 0x7C0u) >> 4)) << 6) | (*(int *)((char *)v20 + ((((*(int *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF800u) >> 9)) << 11) | (*(int *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF8000000u) >> 25)) << 27) | *(unsigned int *)LODWORD(v19) & 0x7FF07FF) & 0x7C00000u) >> 20)) << 22) | ((*(int *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF800u) >> 9)) << 11) | (*(int *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF8000000u) >> 25)) << 27) | *(unsigned int *)LODWORD(v19) & 0x7FF07FF) & 0xF81FF81F; - result = this_ - + (*((int *)v20 - + (((unsigned __int8)(*((char *)v20 - + ((((unsigned __int16)(*(short *)((char *)v20 - + ((*(unsigned int *)LODWORD(v19) & 0xF800u) >> 9)) << 11) | *(unsigned int *)LODWORD(v19) & 0x7FF) & 0x7C0u) >> 4)) << 6) | *(unsigned int *)LODWORD(v19) & 0x1F) & 0x1F)) | (*(int *)((char *)v20 + ((v23 & 0x1F0000u) >> 14)) << 16) | ((*(int *)((char *)v20 + ((((unsigned __int16)(*(short *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF800u) >> 9)) << 11) | *(unsigned int *)LODWORD(v19) & 0x7FF) & 0x7C0u) >> 4)) << 6) | (*(int *)((char *)v20 + ((((*(int *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF800u) >> 9)) << 11) | (*(int *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF8000000u) >> 25)) << 27) | *(unsigned int *)LODWORD(v19) & 0x7FF07FF) & 0x7C00000u) >> 20)) << 22) | ((*(int *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF800u) >> 9)) << 11) | (*(int *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF8000000u) >> 25)) << 27) | *(unsigned int *)LODWORD(v19) & 0x7FF07FF) & 0xF81FF81F) & 0xFFE0FFE0); - *(unsigned int *)LODWORD(v19) = result; - LODWORD(v19) += 4; - --v22; - } - while ( v22 ); - LODWORD(v19) += v37; - v21 = v31 - 1; - } - while ( v31 != 1 ); - } - else - { - v24 = sr_4268E3_smthn_to_a1r5g5b5(this_); - v25 = (65536 - LODWORD(a3)) * (v24 & 0x1F); - this_ = (((65536 - LODWORD(a3)) * (v24 & 0x7C00) & 0x7C000000 | v25 & 0x1F0000 | (65536 - LODWORD(a3)) - * (v24 & 0x3E0) & 0x3E00000u) >> 16 << 16) | (((65536 - LODWORD(a3)) * (v24 & 0x7C00) & 0x7C000000 | v25 & 0x1F0000 | (65536 - LODWORD(a3)) * (v24 & 0x3E0) & 0x3E00000u) >> 16); - v26 = v40; - v27 = (char *)off_4EFDB0; - v28 = HIDWORD(v39); - do - { - v29 = v38; - v32 = v28; - do - { - v30 = 32 - * *(int *)&v27[(((unsigned __int16)(*(short *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C00u) >> 8] << 10) | *(unsigned int *)LODWORD(v26) & 0x3FF) & 0x3E0u) >> 3] | (*(int *)&v27[(((*(int *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C00u) >> 8] << 10) | (*(int *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C000000u) >> 24] << 26) | *(unsigned int *)LODWORD(v26) & 0x3FF03FF) & 0x3E00000u) >> 19] << 21) | ((*(int *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C00u) >> 8] << 10) | (*(int *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C000000u) >> 24] << 26) | *(unsigned int *)LODWORD(v26) & 0x3FF03FF) & 0x7C1F7C1F; - result = this_ - + (*(int *)&v27[4 - * (((unsigned __int8)(32 - * v27[(((unsigned __int16)(*(short *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C00u) >> 8] << 10) | *(unsigned int *)LODWORD(v26) & 0x3FF) & 0x3E0u) >> 3]) | *(unsigned int *)LODWORD(v26) & 0x1F) & 0x1F)] | (*(int *)&v27[(v30 & 0x1F0000u) >> 14] << 16) | (32 * *(int *)&v27[(((unsigned __int16)(*(short *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C00u) >> 8] << 10) | *(unsigned int *)LODWORD(v26) & 0x3FF) & 0x3E0u) >> 3] | (*(int *)&v27[(((*(int *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C00u) >> 8] << 10) | (*(int *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C000000u) >> 24] << 26) | *(unsigned int *)LODWORD(v26) & 0x3FF03FF) & 0x3E00000u) >> 19] << 21) | ((*(int *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C00u) >> 8] << 10) | (*(int *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C000000u) >> 24] << 26) | *(unsigned int *)LODWORD(v26) & 0x3FF03FF) & 0x7C1F7C1F) & 0xFFE0FFE0); - *(unsigned int *)LODWORD(v26) = result; - LODWORD(v26) += 4; - --v29; - } - while ( v29 ); - LODWORD(v26) += v37; - v28 = v32 - 1; - } - while ( v32 != 1 ); - } - }*/ -} - -//----- (004A5B81) -------------------------------------------------------- -void Render::SetTextureClipRect(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW) -{ - this->bClip = 1; - this->uClipX = uX; - this->uClipY = uY; - this->uClipZ = uZ; - this->uClipW = uW; -} - -//----- (004A5BB6) -------------------------------------------------------- -void Render::ResetTextureClipRect() -{ - this->bClip = 1; - this->uClipX = 0; - this->uClipY = 0; - this->uClipZ = window->GetWidth(); - this->uClipW = 480; -} - -unsigned __int32 Color32(unsigned __int16 color16) -{ - unsigned __int32 c = color16; - unsigned int b = (c & 31) * 8; - unsigned int g = ((c >> 5) & 63) * 4; - unsigned int r = ((c >> 11) & 31) * 8; - - return (r << 16) | (g << 8) | b;// -} - -//----- (0040DEF3) -------------------------------------------------------- -unsigned __int16 Color16(unsigned __int32 r, unsigned __int32 g, unsigned __int32 b) -{ - //return ((unsigned int)b >> (8 - LOBYTE(pRenderer->uTargetBBits))) | pRenderer->uTargetGMask & (g << (LOBYTE(pRenderer->uTargetGBits) + - // LOBYTE(pRenderer->uTargetBBits) - 8)) | pRenderer->uTargetRMask & (r << (LOBYTE(pRenderer->uTargetGBits) + - // LOBYTE(pRenderer->uTargetRBits) + LOBYTE(pRenderer->uTargetBBits) - 8)); - return (b >> (8 - 5)) | - 0x7E0 & (g << (6 + 5 - 8)) | - 0xF800 & (r << (6 + 5 + 5 - 8)); -} - - -//----- (004A5BE3) -------------------------------------------------------- -void Render::DrawTextureRGB(unsigned int uOutX, unsigned int uOutY, RGBTexture *a4) -{ - int v4; // edi@3 - unsigned __int16 *v6; // esi@3 - unsigned int v8; // eax@5 - unsigned int v9; // ebx@5 - unsigned int v11; // eax@7 - unsigned int v12; // ebx@8 - unsigned int v15; // eax@14 - int v19; // [sp+10h] [bp-8h]@3 - int v23; // [sp+28h] [bp+10h]@3 - - if ( this->uNumSceneBegins && a4 ) - { - v4 = a4->uWidth; - //v5 = &this->pTargetSurface[uOutX + uOutY * this->uTargetSurfacePitch]; - v6 = a4->pPixels; - v23 = a4->uHeight; - v19 = v4; - if ( this->bClip ) - { - if ( (signed int)uOutX < (signed int)this->uClipX ) - { - v8 = this->uClipX - uOutX; - v9 = uOutX - this->uClipX; - v8 *= 2; - v4 += v9; - v6 = (unsigned __int16 *)((char *)v6 + v8); - //v5 = (unsigned __int16 *)((char *)v5 + v8); - } - if ( (signed int)uOutY < (signed int)this->uClipY ) - { - v11 = this->uClipY - uOutY; - v6 += v19 * v11; - v23 += uOutY - this->uClipY; - //v5 += this->uTargetSurfacePitch * v11; - } - v12 = max(this->uClipX, uOutX); - if ( (signed int)(v4 + v12) > (signed int)this->uClipZ ) - { - v4 = this->uClipZ - max(this->uClipX, uOutX); - } - v15 = max(this->uClipY, uOutY); - if ( (signed int)(v15 + v23) > (signed int)this->uClipW ) - { - v23 = this->uClipW - max(this->uClipY, uOutY); - } - } - - for (int y = 0; y < v23; y++) - { - for (int x = 0; x < v4; x++) - { - WritePixel16(uOutX + x, uOutY + y, *v6); - //*v5 = *v6; - //++v5; - ++v6; - } - v6 += v19 - v4; - //v5 += this->uTargetSurfacePitch - v4; - } - } -} - -//----- (004A5D33) -------------------------------------------------------- -void Render::CreditsTextureScroll(unsigned int pX, unsigned int pY, int move_X, int move_Y, RGBTexture *pTexture) -{ - //unsigned __int16 *v7; // ebx@3 - int full_width; // ecx@3 - int full_height; // edi@3 - //int v23; // edi@23 - unsigned __int16 *pTexturea; // [sp+28h] [bp+18h]@3 - - if ( this->uNumSceneBegins && pTexture ) - { - /*auto v7 = this->pTargetSurface; - if (FORCE_16_BITS) - v7 = (unsigned __int32 *)((char *)v7 + (pX + pY * this->uTargetSurfacePitch) * 2); - else - v7 = (unsigned __int32 *)((char *)v7 + (pX + pY * this->uTargetSurfacePitch) * 4);*/ - full_width = pTexture->uWidth - move_X; - full_height = pTexture->uHeight - move_Y; - pTexturea = &pTexture->pPixels[move_X + move_Y * pTexture->uWidth]; - if ( this->bClip ) - { - if ( pX < this->uClipX )//если кадр выходит за правую границу - { - pTexturea = (unsigned __int16 *)((char *)pTexturea + (2 * (this->uClipX - pX))); - full_width += pX - this->uClipX; - //v7 = (unsigned __int32 *)((char *)v7 + ((FORCE_16_BITS ? 2 : 4) * (this->uClipX - pX))); - } - if ( pY < this->uClipY )//если кадр выходит за верхнюю границу - { - pTexturea += pTexture->uWidth * (this->uClipY - pY); - full_height += pY - this->uClipY; - //v7 = (unsigned __int32 *)((char *)v7 + (FORCE_16_BITS ? 2 : 4) * this->uTargetSurfacePitch * (this->uClipY - pY)); - } - if ( this->uClipX < pX )//если правая граница окна меньше х координаты кадра - this->uClipX = pX; - if ( this->uClipY < pY )//если верхняя граница окна меньше y координаты кадра - this->uClipY = pY; - if ( (full_width + this->uClipX) > this->uClipZ )//если ширина кадра выходит за правую границу - { - if ( this->uClipX < pX ) - this->uClipX = pX; - full_width = this->uClipZ - this->uClipX; - } - if ( (full_height + this->uClipY) > this->uClipW )//если высота кадра выходит за нижнюю границу - { - if ( this->uClipY < pY ) - this->uClipY = pY; - full_height = this->uClipW - this->uClipY; - } - } - - for (int y = 0; y < full_height; ++y) - { - for (int x = 0; x < full_width; ++x) - { - if ( *pTexturea != Color16(0, 0xFFu, 0xFFu) ) - { - WritePixel16(pX + x, pY + y, *pTexturea); - /*if (FORCE_16_BITS) - *(unsigned __int16 *)v7 = *pTexturea; - else - *(unsigned __int32 *)v7 = r5g6b5_2_r8g8b8(*pTexturea);*/ - } - ++pTexturea; - //++v7; - } - //v7 += this->uTargetSurfacePitch - full_width; - pTexturea = (unsigned __int16 *)((char *)pTexturea + 2 * (pTexture->uWidth - full_width)); - } - } -} - -//----- (004A6E7E) -------------------------------------------------------- -void Render::DrawTranslucent(unsigned int a2, unsigned int a3, Texture *a4) -{ - int v5; // edx@4 - unsigned int v6; // edi@4 - unsigned int v7; // edx@5 - unsigned int v8; // edx@6 - unsigned int v9; // edx@7 - unsigned int v10; // edx@8 - unsigned int v11; // ebx@9 - unsigned int v12; // esi@11 - unsigned int v13; // edx@12 - unsigned int v14; // ebx@15 - unsigned int v15; // esi@17 - unsigned int v16; // edi@18 - int v18; // [sp+14h] [bp-Ch]@4 - int v19; // [sp+18h] [bp-8h]@4 - unsigned __int8 *v20; // [sp+1Ch] [bp-4h]@4 - - if ( this->uNumSceneBegins && a4 && a4->pPalette16 ) - { - //v4 = &this->pTargetSurface[a2 + a3 * this->uTargetSurfacePitch]; - v20 = a4->pLevelOfDetail0_prolly_alpha_mask; - v5 = a4->uTextureWidth; - v6 = a4->uTextureHeight; - v19 = a4->uTextureWidth; - v18 = a4->uTextureWidth; - int clipped_out_x = a2; - int clipped_out_y = a3; - if ( this->bClip ) - { - v7 = this->uClipX; - if ( (signed int)a2 < (signed int)v7 ) - { - v8 = v7 - a2; - v20 += v8; - v19 += a2 - this->uClipX; - //v4 += v8; - clipped_out_x = uClipX; - } - v9 = this->uClipY; - if ( (signed int)a3 < (signed int)v9 ) - { - v10 = v9 - a3; - v20 += v18 * v10; - v6 = a3 - this->uClipY + a4->uTextureHeight; - //v4 += this->uTargetSurfacePitch * v10; - clipped_out_y = uClipY; - } - v11 = this->uClipX; - v5 = v19; - if ( (signed int)v11 < (signed int)a2 ) - v11 = a2; - v12 = this->uClipZ; - if ( (signed int)(v19 + v11) > (signed int)v12 ) - { - v13 = this->uClipX; - if ( (signed int)v13 < (signed int)a2 ) - v13 = a2; - v5 = v12 - v13; - } - v14 = this->uClipY; - if ( (signed int)v14 < (signed int)a3 ) - v14 = a3; - v15 = this->uClipW; - if ( (signed int)(v6 + v14) > (signed int)v15 ) - { - v16 = this->uClipY; - if ( (signed int)v16 < (signed int)a3 ) - v16 = a3; - v6 = v15 - v16; - } - } - - for (uint y = 0; y < v6; ++y) - { - for (int x = 0; x < v5; ++x) - { - if ( *v20 ) - WritePixel16(clipped_out_x + x, clipped_out_y + y, ((unsigned int)a4->pPalette16[*v20] >> 1) & 0x7BEF); - ++v20; - } - v20 += v18 - v5; - } - - /*if ( pRenderer->uTargetGBits == 5 ) - { - if ( (signed int)v6 > 0 ) - { - v23 = v6; - do - { - if ( v5 > 0 ) - { - v21 = v5; - do - { - if ( *v20 ) - *v4 = ((unsigned int)a4->pPalette16[*v20] >> 1) & 0x3DEF; - ++v4; - ++v20; - --v21; - } - while ( v21 ); - } - v20 += v18 - v5; - v17 = v23-- == 1; - v4 += this->uTargetSurfacePitch - v5; - } - while ( !v17 ); - } - } - else - { - if ( (signed int)v6 > 0 ) - { - v24 = v6; - do - { - if ( v5 > 0 ) - { - v22 = v5; - do - { - if ( *v20 ) - *v4 = ((unsigned int)a4->pPalette16[*v20] >> 1) & 0x7BEF; - ++v4; - ++v20; - --v22; - } - while ( v22 ); - } - v20 += v18 - v5; - v17 = v24-- == 1; - v4 += this->uTargetSurfacePitch - v5; - } - while ( !v17 ); - } - }*/ - } -} - -//----- (004A6DF5) -------------------------------------------------------- -void Render::_4A6DF5(unsigned __int16 *pBitmap, unsigned int uBitmapPitch, Vec2_int_ *pBitmapXY, void *pTarget, unsigned int uTargetPitch, Vec4_int_ *a7) -{ - int width; // ecx@3 - unsigned __int16 *pixels; // ebx@4 - int height; // esi@4 - - if ( !pBitmap || !pTarget) - return; - - width = a7->z - a7->x; - height = a7->w - a7->y; - pixels = (unsigned short *)pTarget + a7->x + uTargetPitch * a7->y; - for ( int y = 0; y < height; ++y ) - { - for ( int x = 0; x < width; ++x ) - { - WritePixel16(a7->x + x, a7->y + y, *pixels); - ++pixels; - } - pixels += uTargetPitch - width; - } -} - -//----- (004A6D87) -------------------------------------------------------- -void Render::FillRectFast(unsigned int uX, unsigned int uY, unsigned int uWidth, unsigned int uHeight, unsigned int uColor16) -{ - if (!uNumSceneBegins) - return; - - unsigned __int32 twoColors = (uColor16 << 16) | uColor16; - for (uint y = 0; y < uHeight; ++y) - { - void *pDst = (char *)pTargetSurface + (FORCE_16_BITS ? 2 : 4) * (uX + (y + uY) * uTargetSurfacePitch); - - memset32(pDst, - FORCE_16_BITS ? twoColors : 0xFF000000 | Color32(uColor16), // two colors per int (16bit) or 1 (32bit) - uWidth / (FORCE_16_BITS ? 2 : 1)); // two pixels per int (16bit) or 1 (32bit) - - if (FORCE_16_BITS && uWidth & 1) // we may miss one pixel for 16bit - ((unsigned __int16 *)pTargetSurface)[uX + uWidth - 1 + (y + uY) * uTargetSurfacePitch] = uColor16; - } -} - -//----- (004A6C4F) -------------------------------------------------------- -void Render::DrawText(signed int uOutX, signed int uOutY, unsigned __int8 *pFontPixels, unsigned int uCharWidth, - unsigned int uCharHeight, unsigned __int16 *pFontPalette, - unsigned __int16 uFaceColor, unsigned __int16 uShadowColor) -{ - unsigned int v9; // edi@2 - unsigned int v10; // esi@2 - unsigned int v12; // ebx@3 - //signed int v13; // edx@5 - int v14; // edx@6 - signed int v15; // ebx@7 - //unsigned int v16; // edx@9 - signed int v17; // edi@10 - signed int v18; // ebx@13 - unsigned int v19; // edx@15 - signed int v20; // esi@16 - unsigned __int16 v22; // dx@24 - unsigned __int8 *v24; // [sp+Ch] [bp-4h]@2 - - if (!this->uNumSceneBegins) - return; - - v9 = uCharWidth; - v10 = uCharHeight; - //v11 = &this->pTargetSurface[uOutX + uOutY * this->uTargetSurfacePitch]; - v24 = pFontPixels; - - int clipped_out_x = uOutX, clipped_out_y = uOutY; - if ( this->bClip ) - { - v12 = this->uClipX; - if ( uOutX < (signed int)v12 ) - { - v24 = &pFontPixels[v12 - uOutX]; - //v11 += v12 - uOutX; - clipped_out_x = uClipX; - v9 = uCharWidth + uOutX - v12; - } - //v13 = this->uClipY; - if ( uOutY < this->uClipY ) - { - v14 = this->uClipY - uOutY; - v24 += uCharWidth * v14; - v10 = uCharHeight + uOutY - this->uClipY; - //v11 += this->uTargetSurfacePitch * v14; - clipped_out_y = uClipY; - } - v15 = this->uClipX; - if ( this->uClipX < uOutX ) - v15 = uOutX; - //v16 = this->uClipZ; - if ( (signed int)(v9 + v15) > (signed int)this->uClipZ ) - { - v17 = this->uClipX; - if ( this->uClipX < uOutX ) - v17 = uOutX; - v9 = this->uClipZ - v17; - } - v18 = this->uClipY; - if ( this->uClipY < uOutY ) - v18 = uOutY; - v19 = this->uClipW; - if ( (signed int)(v10 + v18) > (signed int)v19 ) - { - v20 = this->uClipY; - if ( this->uClipY < uOutY ) - v20 = uOutY; - v10 = v19 - v20; - } - } - - for (uint y = 0; y < v10; ++y) - { - for (uint x = 0; x < v9; ++x) - { - if (*v24) - { - v22 = uShadowColor; - if ( *v24 != 1 ) - v22 = uFaceColor; - WritePixel16(clipped_out_x + x, clipped_out_y + y, v22); - } - ++v24; - } - v24 += uCharWidth - v9; - //v23 = uOutXa-- == 1; - //v11 += this->uTargetSurfacePitch - v9; - } -} - -//----- (004A6A68) -------------------------------------------------------- -void Render::GetLeather(unsigned int a2, unsigned int a3, Texture *a4, __int16 height) -{ - Texture tex; // [sp+Ch] [bp-48h]@1 - - memcpy(&tex, a4, sizeof(tex)); - tex.uTextureHeight = a4->uTextureHeight - height; - if ( (signed __int16)tex.uTextureHeight > 0 ) - DrawTextureIndexed(a2, a3, &tex); -} - -//----- (004A6AB1) -------------------------------------------------------- -void Render::DrawTextPalette( int x, int y, unsigned char* font_pixels, int a5, unsigned int uFontHeight, unsigned __int16 *pPalette, int a8 ) - { - int v8; // edi@2 - unsigned int v9; // esi@2 - unsigned char *v11; // edx@2 - int v14; // edx@6 - signed int v15; // ebx@7 - signed int v17; // edi@10 - signed int v18; // ebx@13 - signed int v20; // esi@16 - unsigned __int16 v24; // si@35 - int v25; // [sp+Ch] [bp-4h]@2 - unsigned int v28; // [sp+20h] [bp+10h]@30 - - int a2 = x; - int a3 = y; - uint a6 = uFontHeight; - if (!this->uNumSceneBegins) - return; - - v8 = a5; - v9 = a6; - //v10 = &pTargetSurface[x + y * uTargetSurfacePitch]; - v11 = (unsigned char *)font_pixels; - v25 = (int)font_pixels; - int clipped_out_x = x; - int clipped_out_y = y; - if ( this->bClip ) - { - if ( a2 < (signed int)this->uClipX ) - { - v25 = this->uClipX - a2 + (int)font_pixels; - //v10 += v12 - a2; - v8 = a5 + a2 - this->uClipX; - clipped_out_x = uClipX; - } - if ( a3 < this->uClipY ) - { - v14 = this->uClipY - a3; - v25 += a5 * v14; - v9 = a6 + a3 - this->uClipY; - //v10 += this->uTargetSurfacePitch * v14; - clipped_out_y = uClipY; - } - v15 = this->uClipX; - if ( this->uClipX < a2 ) - v15 = a2; - if ( v8 + v15 > (signed int)this->uClipZ ) - { - v17 = this->uClipX; - if ( v17 < a2 ) - v17 = a2; - v8 = this->uClipZ - v17; - } - v18 = this->uClipY; - if ( this->uClipY < a3 ) - v18 = a3; - if ( (signed int)(v9 + v18) > (signed int)this->uClipW ) - { - v20 = this->uClipY; - if ( this->uClipY < a3 ) - v20 = a3; - v9 = this->uClipW - v20; - } - v11 = (unsigned char *)v25; - } - - if ( a8 ) - { - v28 = 0x7FF; // 16bit pRenderer->uTargetGMask | pRenderer->uTargetBMask; - for (uint dy = 0; dy < v9; ++dy) - { - for (int dx = 0; dx < v8; ++dx) - { - if ( *v11 ) - v24 = pPalette[*v11]; - else - v24 = v28; - WritePixel16(clipped_out_x + dx, clipped_out_y + dy, v24); - //*v10 = v24; - //++v10; - ++v11; - //--v27; - - } - v11 += a5 - v8; - } - /*if ( (signed int)v9 > 0 ) - { - v23 = a5; - v30 = v9; - do - { - if ( v8 > 0 ) - { - v27 = v8; - do - { - if ( *v11 ) - v24 = pPalette[*v11]; - else - v24 = v28; - *v10 = v24; - ++v10; - ++v11; - --v27; - } - while ( v27 ); - } - v11 += v23 - v8; - v22 = v30-- == 1; - v10 += this->uTargetSurfacePitch - v8; - } - while ( !v22 ); - }*/ - } - else - { - for (uint dy = 0; dy < v9; ++dy) - { - for (int dx = 0; dx < v8; ++dx) - { - if ( *v11 ) - WritePixel16(clipped_out_x + dx, clipped_out_y + dy, pPalette[*v11]); - //*v10 = v24; - //++v10; - ++v11; - //--v27; - } - v11 += a5 - v8; - } - - /*if ( (signed int)v9 > 0 ) - { - v21 = a5; - v29 = v9; - do - { - if ( v8 > 0 ) - { - v26 = v8; - do - { - if ( *v11 ) - *v10 = pPalette[*v11]; - ++v10; - ++v11; - --v26; - } - while ( v26 ); - } - v11 += v21 - v8; - v22 = v29-- == 1; - v10 += this->uTargetSurfacePitch - v8; - } - while ( !v22 ); - }*/ - } -} - -//----- (004A68EF) -------------------------------------------------------- -void Render::DrawTransparentGreenShade(signed int a2, signed int a3, Texture *pTexture) -{ - DrawMasked(a2, a3, pTexture, 0x07E0); -} - - -//----- (004A6776) -------------------------------------------------------- -void Render::DrawTransparentRedShade(unsigned int a2, unsigned int a3, Texture *a4) -{ - DrawMasked(a2, a3, a4, 0xF800); - /*Texture *v4; // edi@2 - unsigned int v5; // ebx@4 - unsigned __int16 *v6; // eax@4 - unsigned int v7; // edx@5 - unsigned int v8; // edx@6 - unsigned int v9; // edx@7 - unsigned int v10; // edx@8 - unsigned int v11; // edx@9 - unsigned int v12; // esi@12 - unsigned int v13; // esi@15 - unsigned int v14; // edx@17 - unsigned int v15; // esi@18 - unsigned __int8 *v16; // ebx@22 - char v17; // zf@28 - int v18; // [sp+10h] [bp-10h]@4 - unsigned __int8 *v19; // [sp+18h] [bp-8h]@4 - int v20; // [sp+1Ch] [bp-4h]@4 - int a2a; // [sp+28h] [bp+8h]@24 - unsigned int a3a; // [sp+2Ch] [bp+Ch]@22 - unsigned int a4a; // [sp+30h] [bp+10h]@11 - - if ( this->uNumSceneBegins ) - { - v4 = a4; - if ( a4 ) - { - if ( a4->pPalette16 ) - { - v5 = a4->uTextureHeight; - v6 = &this->pTargetSurface[a2 + a3 * this->uTargetSurfacePitch]; - v19 = a4->pLevelOfDetail0_prolly_alpha_mask; - v20 = a4->uTextureWidth; - v18 = a4->uTextureWidth; - if ( this->bClip ) - { - v7 = this->uClipX; - if ( (signed int)a2 < (signed int)v7 ) - { - v8 = v7 - a2; - v19 += v8; - v20 += a2 - this->uClipX; - v6 += v8; - } - v9 = this->uClipY; - v5 = a4->uTextureHeight; - if ( (signed int)a3 < (signed int)v9 ) - { - v10 = v9 - a3; - v19 += v18 * v10; - v5 = a3 - this->uClipY + a4->uTextureHeight; - v4 = a4; - v6 += this->uTargetSurfacePitch * v10; - } - v11 = this->uClipX; - if ( (signed int)v11 < (signed int)a2 ) - v11 = a2; - a4a = this->uClipZ; - if ( (signed int)(v11 + v20) > (signed int)a4a ) - { - v12 = this->uClipX; - if ( (signed int)v12 < (signed int)a2 ) - v12 = a2; - v20 = a4a - v12; - } - v13 = this->uClipY; - if ( (signed int)v13 < (signed int)a3 ) - v13 = a3; - v14 = this->uClipW; - if ( (signed int)(v5 + v13) > (signed int)v14 ) - { - v15 = this->uClipY; - if ( (signed int)v15 < (signed int)a3 ) - v15 = a3; - v5 = v14 - v15; - } - } - if ( (signed int)v5 > 0 ) - { - a3a = v5; - v16 = v19; - do - { - if ( v20 > 0 ) - { - a2a = v20; - do - { - if ( *v16 ) - *v6 = this->uTargetRMask & v4->pPalette16[*v16]; - ++v6; - ++v16; - --a2a; - } - while ( a2a ); - } - v16 += v18 - v20; - v17 = a3a-- == 1; - v6 += this->uTargetSurfacePitch - v20; - } - while ( !v17 ); - } - } - } - }*/ -} - -//----- (004A68EF) -------------------------------------------------------- -void Render::DrawMasked(signed int a2, signed int a3, Texture *pTexture, unsigned __int16 mask) -{ - unsigned int v5; // ebx@4 - int v10; // edx@8 - signed int v11; // edx@9 - signed int v12; // esi@12 - signed int v13; // esi@15 - signed int v15; // esi@18 - unsigned __int8 *v16; // ebx@22 - int v18; // [sp+10h] [bp-10h]@4 - unsigned __int8 *v19; // [sp+18h] [bp-8h]@4 - int v20; // [sp+1Ch] [bp-4h]@4 - - if (!uNumSceneBegins || !pTexture) - return; - - if ( pTexture->pPalette16 ) - { - v5 = pTexture->uTextureHeight; - //v6 = &this->pTargetSurface[a2 + a3 * this->uTargetSurfacePitch]; - v19 = pTexture->pLevelOfDetail0_prolly_alpha_mask; - v20 = pTexture->uTextureWidth; - v18 = pTexture->uTextureWidth; - int clipped_out_x = a2; - int clipped_out_y = a3; - if ( this->bClip ) - { - if ( a2 < this->uClipX ) - { - v19 += this->uClipX - a2; - v20 += a2 - this->uClipX; - clipped_out_x = uClipX; - } - v5 = pTexture->uTextureHeight; - if ( a3 < this->uClipY ) - { - v10 = this->uClipY - a3; - v19 += v18 * v10; - v5 = a3 - this->uClipY + pTexture->uTextureHeight; - clipped_out_y = uClipY; - } - v11 = this->uClipX; - if ( this->uClipX < a2 ) - v11 = a2; - if ( v11 + v20 > (signed int)this->uClipZ ) - { - v12 = this->uClipX; - if ( this->uClipX < a2 ) - v12 = a2; - v20 = this->uClipZ - v12; - } - v13 = this->uClipY; - if ( this->uClipY < a3 ) - v13 = a3; - if ( (signed int)(v5 + v13) > (signed int)this->uClipW ) - { - v15 = this->uClipY; - if ( this->uClipY < a3 ) - v15 = a3; - v5 = this->uClipW - v15; - } - } - - v16 = v19; - for (uint y = 0; y < v5; ++y) - { - for (int x = 0; x < v20; ++x) - { - if ( *v16 ) - WritePixel16(clipped_out_x + x, clipped_out_y + y, pTexture->pPalette16[*v16] & mask); - ++v16; - } - v16 += v18 - v20; - } - - /*if ( (signed int)v5 > 0 ) - { - v22 = v5; - v16 = v19; - do - { - if ( v20 > 0 ) - { - v21 = v20; - do - { - if ( *v16 ) - *v6 = this->uTargetGMask & v4->pPalette16[*v16]; - ++v6; - ++v16; - --v21; - } - while ( v21 ); - } - v16 += v18 - v20; - v17 = v22-- == 1; - v6 += this->uTargetSurfacePitch - v20; - } - while ( !v17 ); - }*/ - } -} - - -//----- (004A65CC) -------------------------------------------------------- -void Render::_4A65CC(unsigned int x, unsigned int y, Texture *a4, Texture *a5, int a6, int a7, int a8) -{ - unsigned int uHeight; // edi@6 - unsigned int v14; // edx@11 - unsigned int v16; // edx@14 - unsigned int v17; // edx@17 - unsigned int v19; // edx@20 - int v20; // eax@27 - int v21; // edx@29 - unsigned __int8 *v24; // [sp+14h] [bp-4h]@6 - int Width; // [sp+2Ch] [bp+14h]@6 - - if ( this->uNumSceneBegins && a4 && a4->pPalette16 && a5 && a5->pPalette16 ) - { - v24 = a4->pLevelOfDetail0_prolly_alpha_mask; - Width = a4->uTextureWidth; - uHeight = a4->uTextureHeight; - int clipped_out_x = x; - int clipped_out_y = y; - if ( this->bClip ) - { - if ( (signed int)x < (signed int)this->uClipX ) - { - v24 += this->uClipX - x; - Width += x - this->uClipX; - clipped_out_x = uClipX; - } - if ( (signed int)y < (signed int)this->uClipY ) - { - v24 += a4->uTextureWidth * (this->uClipY - y); - uHeight = y - this->uClipY + a4->uTextureHeight; - clipped_out_y = uClipY; - } - v14 = this->uClipX; - if ( (signed int)this->uClipX < (signed int)x ) - v14 = x; - if ( (signed int)(Width + v14) > (signed int)this->uClipZ ) - { - v16 = this->uClipX; - if ( (signed int)this->uClipX < (signed int)x ) - v16 = x; - Width = this->uClipZ - v16; - } - v17 = this->uClipY; - if ( (signed int)this->uClipY < (signed int)y ) - v17 = y; - if ( (signed int)(uHeight + v17) > (signed int)this->uClipW ) - { - v19 = this->uClipY; - if ( (signed int)this->uClipY < (signed int)y ) - v19 = y; - uHeight = this->uClipW - v19; - } - } - - for (uint dy = 0; dy < uHeight; ++dy) - { - for (int dx = 0; dx < Width; ++dx) - { - v20 = *v24; - if ( v20 >= a7 && v20 <= a8 ) - { - v21 = a7 + (a6 + v20) % (2 * (a8 - a7)); - if ( (a6 + v20) % (2 * (a8 - a7)) >= a8 - a7 ) - v21 = 2 * a8 - v21 - a7; - WritePixel16(clipped_out_x + dx, clipped_out_y + dy, a4->pPalette16[v21]); - } - ++v24; - } - v24 += a4->uTextureWidth - Width; - } - /*if ( (signed int)v9 > 0 ) - { - ya = v9; - v23 = v22 - v27; - do - { - if ( v27 > 0 ) - { - xa = v27; - do - { - v20 = *v24; - if ( v20 >= a7 && v20 <= a8 ) - { - v21 = a7 + (a6 + v20) % (2 * (a8 - a7)); - if ( (a6 + v20) % (2 * (a8 - a7)) >= a8 - a7 ) - v21 = 2 * a8 - v21 - a7; - *v8 = a4->pPalette16[v21]; - } - ++v8; - ++v24; - --xa; - } - while ( xa ); - } - v8 += this->uTargetSurfacePitch - v27; - v24 += v23; - --ya; - } - while ( ya ); - }*/ - } -} - -//----- (004A63E6) -------------------------------------------------------- -void Render::DrawAura(unsigned int a2, unsigned int a3, Texture *a4, Texture *a5, int a6, int a7, int a8) -{ - unsigned int v14; // edx@11 - unsigned int v16; // edx@14 - unsigned int v17; // edx@17 - unsigned int v19; // edx@20 - int v20; // eax@27 - int v21; // edx@29 - int Height; // [sp+10h] [bp-8h]@6 - int Width; // [sp+14h] [bp-4h]@6 - int v27; // [sp+24h] [bp+Ch]@23 - unsigned __int8 *v28; // [sp+28h] [bp+10h]@6 - - if ( this->uNumSceneBegins ) - { - if ( a4 ) - { - if ( a4->pPalette16 ) - { - if ( a5 ) - { - if ( a5->pPalette16 ) - { - v28 = a4->pLevelOfDetail0_prolly_alpha_mask; - Width = a4->uTextureWidth; - Height = a4->uTextureHeight; - int clipped_out_x = a2; - int clipped_out_y = a3; - if ( this->bClip ) - { - if ( (signed int)a2 < (signed int)this->uClipX ) - { - v28 += this->uClipX - a2; - Width += a2 - this->uClipX; - clipped_out_x = uClipX; - } - - if ( (signed int)a3 < (signed int)this->uClipY ) - { - v28 += a4->uTextureWidth * (this->uClipY - a3); - Height += a3 - this->uClipY; - clipped_out_y = uClipY; - } - - v14 = this->uClipX; - if ( (signed int)this->uClipX < (signed int)a2 ) - v14 = a2; - if ( (signed int)(Width + v14) > (signed int)this->uClipZ ) - { - v16 = this->uClipX; - if ( (signed int)this->uClipX < (signed int)a2 ) - v16 = a2; - Width = this->uClipZ - v16; - } - - v17 = this->uClipY; - if ( (signed int)this->uClipY < (signed int)a3 ) - v17 = a3; - if ( (signed int)(Height + v17) > (signed int)this->uClipW ) - { - v19 = this->uClipY; - if ( (signed int)this->uClipY < (signed int)a3 ) - v19 = a3; - Height = this->uClipW - v19; - } - } - - v27 = 0; - for (int y = 0; y < Height; ++y) - { - for (int x = 0; x < Width; ++x) - { - if ( *v28 ) - { - v20 = *(&a5->pLevelOfDetail0_prolly_alpha_mask[x & a5->uWidthMinus1] + a5->uTextureWidth * (v27 & a5->uHeightMinus1)); - if ( v20 >= a7 ) - { - if ( v20 <= a8 ) - { - v21 = a7 + (a6 + v20) % (2 * (a8 - a7)); - if ( (a6 + v20) % (2 * (a8 - a7)) >= a8 - a7 ) - v21 = 2 * a8 - v21 - a7; - //v9 = a5; - //*v10 = a5->pPalette16[v21]; - WritePixel16(clipped_out_x + x, clipped_out_y + y, a5->pPalette16[v21]); - } - } - } - v28++; - } - v28 += a4->uTextureWidth - Width; - } - - /*if ( v24 > 0 ) - { - v23 = v22 - v25; - do - { - for ( i = 0; i < v25; ++v28 ) - { - if ( *v28 ) - { - v20 = *(&v9->pLevelOfDetail0_prolly_alpha_mask[i & v9->uWidthMinus1] + v9->uTextureWidth * (v27 & v9->uHeightMinus1)); - if ( v20 >= a7 ) - { - if ( v20 <= a8 ) - { - v21 = a7 + (a6 + v20) % (2 * (a8 - a7)); - if ( (a6 + v20) % (2 * (a8 - a7)) >= a8 - a7 ) - v21 = 2 * a8 - v21 - a7; - v9 = a5; - *v10 = a5->pPalette16[v21]; - } - } - } - ++i; - ++v10; - } - ++v27; - v10 += this->uTargetSurfacePitch - v25; - v28 += v23; - } - while ( v27 < v24 ); - }*/ - - } - } - } - } - } -} - -//----- (004A6274) -------------------------------------------------------- -void Render::DrawTextureTransparent(unsigned int uX, unsigned int uY, Texture *pTexture) -{ - int uHeight; // ebx@4 - unsigned int v11; // edx@9 - unsigned int v12; // esi@12 - unsigned int v13; // esi@15 - unsigned int v15; // esi@18 - unsigned __int8 *v19; // [sp+18h] [bp-8h]@4 - int uWidth; // [sp+1Ch] [bp-4h]@4 - - if ( this->uNumSceneBegins ) - { - if ( pTexture ) - { - if ( pTexture->pPalette16 ) - { - uHeight = pTexture->uTextureHeight; - v19 = pTexture->pLevelOfDetail0_prolly_alpha_mask; - uWidth = pTexture->uTextureWidth; - - int clipped_out_x = uX; - int clipped_out_y = uY; - if ( this->bClip ) - { - if ( (signed int)uX < (signed int)this->uClipX ) - { - v19 += this->uClipX - uX; - uWidth += uX - this->uClipX; - clipped_out_x = uClipX; - } - - uHeight = pTexture->uTextureHeight; - if ( (signed int)uY < (signed int)this->uClipY ) - { - v19 += pTexture->uTextureWidth * (this->uClipY - uY); - uHeight = uY - this->uClipY + pTexture->uTextureHeight; - clipped_out_y = uClipY; - } - v11 = this->uClipX; - if ( (signed int)this->uClipX < (signed int)uX ) - v11 = uX; - - if ( (signed int)(v11 + uWidth) > (signed int)this->uClipZ ) - { - v12 = this->uClipX; - if ( (signed int)this->uClipX < (signed int)uX ) - v12 = uX; - uWidth = this->uClipZ - v12; - } - v13 = this->uClipY; - if ( (signed int)this->uClipY < (signed int)uY ) - v13 = uY; - - if ( (signed int)(uHeight + v13) > (signed int)this->uClipW ) - { - v15 = this->uClipY; - if ( (signed int)this->uClipY < (signed int)uY ) - v15 = uY; - uHeight = this->uClipW - v15; - } - } - - for (int y = 0; y < uHeight; ++y) - { - for (int x = 0; x < uWidth; ++x) - { - if ( *v19 ) - WritePixel16(clipped_out_x + x, clipped_out_y + y, pTexture->pPalette16[*v19]); - ++v19; - } - v19 += pTexture->uTextureWidth - uWidth; - } - /*if ( (signed int)uHeight > 0 ) - { - uYa = uHeight; - v16 = v19; - do - { - if ( uWidth > 0 ) - { - uXa = uWidth; - do - { - if ( *v16 ) - *v6 = pCurrentTexture->pPalette16[*v16]; - ++v6; - ++v16; - } - while ( uXa-- !=1 ); - } - v16 += v18 - uWidth; - uFlag = uYa-- == 1; - v6 += this->uTargetSurfacePitch - uWidth; - } - while ( !uFlag ); - }*/ - } - } - } -} - -//----- (004A612A) -------------------------------------------------------- -void Render::DrawMaskToZBuffer(signed int uOutX, unsigned int uOutY, Texture *pTexture, int zVal) -{ - unsigned int v6; // edx@3 - int v7; // ebx@3 - int v8; // edi@3 - int v10; // eax@5 - signed int v12; // esi@8 - signed int v14; // esi@11 - unsigned int v15; // esi@14 - unsigned int v17; // ecx@17 - int v18; // edx@23 - int v19; // [sp+Ch] [bp-Ch]@3 - int v20; // [sp+10h] [bp-8h]@3 - int uOutXa; // [sp+20h] [bp+8h]@21 - unsigned __int8 *uOutYa; // [sp+24h] [bp+Ch]@3 - int *pZBuffer; // [sp+28h] [bp+10h]@3 - - if ( this->uNumSceneBegins ) - { - if ( pTexture ) - { - v6 = uOutY; - v7 = pTexture->uTextureHeight; - pZBuffer = &this->pActiveZBuffer[uOutX + window->GetWidth() * uOutY]; - uOutYa = pTexture->pLevelOfDetail0_prolly_alpha_mask; - v8 = pTexture->uTextureWidth; - v20 = pTexture->uTextureWidth; - v19 = pTexture->uTextureWidth; - if ( this->bClip ) - { - if ( uOutX < this->uClipX ) - { - v10 = this->uClipX - uOutX; - uOutYa += v10; - v8 += uOutX - this->uClipX; - v20 = v8; - pZBuffer += v10; - } - if ( (signed int)v6 < (signed int)this->uClipY ) - { - uOutYa += v19 * (this->uClipY - v6); - v7 += v6 - this->uClipY; - pZBuffer += window->GetWidth() * (this->uClipY - v6); - v8 = v20; - } - v12 = this->uClipX; - if ( this->uClipX < uOutX ) - v12 = uOutX; - if ( v8 + v12 > (signed int)this->uClipZ ) - { - v14 = this->uClipX; - if ( this->uClipX < uOutX ) - v14 = uOutX; - v8 = this->uClipZ - v14; - } - v15 = this->uClipY; - if ( (signed int)this->uClipY < (signed int)v6 ) - v15 = v6; - if ( (signed int)(v7 + v15) > (signed int)this->uClipW ) - { - v17 = this->uClipY; - if ( (signed int)this->uClipY >= (signed int)v6 ) - v6 = v17; - v7 = this->uClipW - v6; - } - } - if ( v7 > 0 ) - { - uOutXa = v7; - do - { - if ( v8 > 0 ) - { - v18 = v8; - do - { - if ( *uOutYa ) - *pZBuffer = zVal; - ++pZBuffer; - ++uOutYa; - --v18; - } - while ( v18 ); - } - pZBuffer += window->GetWidth() - v8; - uOutYa += v19 - v8; - --uOutXa; - } - while ( uOutXa ); - } - } - } -} - -//----- (004A601E) -------------------------------------------------------- -void Render::ZBuffer_Fill_2(signed int a2, signed int a3, Texture *pTexture, int a5) -{ - signed int v5; // edx@3 - int v6; // ebx@3 - int v7; // esi@3 - void *v8; // esi@3 - signed int v11; // edi@8 - signed int v13; // edi@11 - unsigned int v14; // edi@14 - unsigned int v16; // ecx@17 - int v17; // [sp+18h] [bp+Ch]@3 - unsigned int pTexturea; // [sp+1Ch] [bp+10h]@3 - - if ( this->uNumSceneBegins && pTexture ) - { - v5 = a3; - v6 = pTexture->uTextureHeight; - v7 = 5 * a3; - v17 = pTexture->uTextureHeight; - v8 = &this->pActiveZBuffer[a2 + (v7 << 7)]; - pTexturea = pTexture->uTextureWidth; - if ( this->bClip ) - { - if ( a2 < (signed int)this->uClipX ) - { - pTexturea += a2 - this->uClipX; - v8 = (char *)v8 + 4 * (this->uClipX - a2); - } - if ( v5 < (signed int)this->uClipY ) - { - v17 += v5 - this->uClipY; - v8 = (char *)v8 + 2560 * (this->uClipY - v5); - } - v11 = this->uClipX; - if ( this->uClipX < a2 ) - v11 = a2; - if ( (signed int)(pTexturea + v11) > (signed int)this->uClipZ ) - { - v13 = this->uClipX; - if ( this->uClipX < a2 ) - v13 = a2; - pTexturea = this->uClipZ - v13; - } - v14 = this->uClipY; - if ( (signed int)this->uClipY < v5 ) - v14 = v5; - v6 = v17; - if ( (signed int)(v17 + v14) > (signed int)this->uClipW ) - { - v16 = this->uClipY; - if ( (signed int)this->uClipY < v5 ) - v16 = v5; - v6 = this->uClipW - v16; - } - } - if ( v6 > 0 ) - { - do - { - if ( (signed int)pTexturea > 0 ) - { - memset32(v8, a5, pTexturea); - v8 = (char *)v8 + 4 * pTexturea; - } - v8 = (char *)v8 + 4 * (window->GetWidth() - pTexturea); - --v6; - } - while ( v6 ); - } - } -} - -//----- (004A5EB2) -------------------------------------------------------- -void Render::DrawTextureIndexed(unsigned int uX, unsigned int uY, Texture *a4) -{ - int v5; // ebx@4 - unsigned int v8; // edx@6 - unsigned int v10; // edx@8 - unsigned int v11; // edx@9 - unsigned int v12; // esi@12 - unsigned int v13; // esi@15 - unsigned int v15; // esi@18 - int v18; // [sp+10h] [bp-10h]@4 - unsigned __int8 *v19; // [sp+18h] [bp-8h]@4 - int v20; // [sp+1Ch] [bp-4h]@4 - - if ( this->uNumSceneBegins ) - { - if ( a4 ) - { - if ( a4->pPalette16 ) - { - v5 = a4->uTextureHeight; - //pTarget = &this->pTargetSurface[uX + uY * this->uTargetSurfacePitch]; - v19 = a4->pLevelOfDetail0_prolly_alpha_mask; - v20 = a4->uTextureWidth; - v18 = a4->uTextureWidth; - - int clipped_out_x = uX; - int clipped_out_y = uY; - if ( this->bClip ) - { - if ( (signed int)uX < (signed int)this->uClipX ) - { - v8 = this->uClipX - uX; - v19 += v8; - v20 += uX - this->uClipX; - clipped_out_x = uClipX; - } - - v5 = a4->uTextureHeight; - if ( (signed int)uY < (signed int)this->uClipY ) - { - v10 = this->uClipY - uY; - v19 += v18 * v10; - v5 = uY - this->uClipY + a4->uTextureHeight; - //v4 = a4; - clipped_out_y = uClipY; - } - - v11 = this->uClipX; - if ( (signed int)this->uClipX < (signed int)uX ) - v11 = uX; - - if ( (signed int)(v11 + v20) > (signed int)this->uClipZ ) - { - v12 = this->uClipX; - if ( (signed int)this->uClipX < (signed int)uX ) - v12 = uX; - v20 = this->uClipZ - v12; - } - - v13 = this->uClipY; - if ( (signed int)this->uClipY < (signed int)uY ) - v13 = uY; - - if ( (signed int)(v5 + v13) > (signed int)uClipW ) - { - v15 = this->uClipY; - if ( (signed int)this->uClipY < (signed int)uY ) - v15 = uY; - v5 = uClipW - v15; - } - } - - for (int y = 0; y < v5; ++y) - { - for (int x = 0; x < v20; ++x) - { - if ( a4->pPalette16[*v19] != 0x7FF )// 2047 - WritePixel16(clipped_out_x + x, clipped_out_y + y, a4->pPalette16[*v19]); - ++v19; - } - v19 += v18 - v20; - } - /*if ( (signed int)v5 > 0 ) - { - uYa = v5; - v16 = v19; - do - { - if ( v20 > 0 ) - { - uXa = v20; - do - { - *pTarget = v4->pPalette16[*v16]; - ++pTarget; - ++v16; - --uXa; - } - while ( uXa ); - } - v16 += v18 - v20; - v17 = uYa-- == 1; - pTarget += this->uTargetSurfacePitch - v20; - } - while ( !v17 ); - }*/ - } - } - } -} - -//----- (004667E9) -------------------------------------------------------- -void Render::ChangeBetweenWinFullscreenModes() -{ - float v0; // ST14_4@17 - int v4; // edx@26 - ObjectDesc *v5; // eax@26 - RGBTexture *v6; // esi@33 - const char *v8; // [sp-4h] [bp-28h]@33 -// struct tagRECT Rect; // [sp+14h] [bp-10h]@15 - - /*if ( !pRenderer->bWindowMode && (dword_6BE364_game_settings_1 & 2) ) - { - ModalWindow(pGlobalTXT_LocalizationStrings[62], UIMSG_0);// "Might and Magic VII requires your desktop to be in 16bit (32k or 65k) Color mode in order to operate in a window." - return; - }*/ - if ( bWindowMode || pRenderD3D->pAvailableDevices->bIsDeviceCompatible ) - { - if ( pEventTimer->bPaused ) - dword_6BE364_game_settings_1 |= GAME_SETTINGS_0800; - else - pEventTimer->Pause(); - if ( pMiscTimer->bPaused ) - dword_6BE364_game_settings_1 |= GAME_SETTINGS_1000; - else - pMiscTimer->Pause(); - pMouse->bActive = 0; - if ( pRenderD3D ) - { - pBitmaps_LOD->ReleaseHardwareTextures(); - pSprites_LOD->ReleaseAll(); - } - if ( bWindowMode ) - { - //SetMenu(hWnd, 0); - //SetWindowLongA(hWnd, -20, 0); - //SetWindowLongA(hWnd, -16, 0x10000000u); - window->SetFullscreenMode(); - pRenderer->InitializeFullscreen(); - v0 = (double)(signed int)uGammaPos * 0.1 + 0.6; - pGame->pGammaController->Initialize(v0); - } - else - { - //ClipCursor(0); - window->SetWindowedMode(window->GetWidth(), window->GetHeight()); - pRenderer->SwitchToWindow(); - } - if ( pRenderD3D ) - { - pBitmaps_LOD->_410423_move_textures_to_device(); - pSprites_LOD->MoveSpritesToVideoMemory(); - } - if (!( pPaletteManager->uNumTargetBBits == uTargetBBits - && pPaletteManager->uNumTargetGBits == uTargetGBits - && pPaletteManager->uNumTargetRBits == uTargetRBits )) - { - pPaletteManager->SetColorChannelInfo(uTargetRBits, uTargetGBits, uTargetBBits); - pPaletteManager->RecalculateAll(); - pBitmaps_LOD->SetupPalettes(uTargetRBits, uTargetGBits, uTargetBBits); - pIcons_LOD->SetupPalettes(uTargetRBits, uTargetGBits, uTargetBBits); - for (uint i = 0; i < pObjectList->uNumObjects; i++) - { - BYTE3(v4) = 0; - v5 = &pObjectList->pObjects[i]; - *(short *)((char *)&v4 + 1) = v5->uParticleTrailColorR; - LOBYTE(v4) = v5->uParticleTrailColorG; - v5->uParticleTrailColor = v5->uParticleTrailColorB | (v4 << 8); - } - SetUserInterface(pParty->alignment, true); - if ( pMediaPlayer->pVideoFrame.pPixels ) - pMediaPlayer->pVideoFrame.Load(pMediaPlayer->pVideoFrameTextureFilename, 1); - if ( sCurrentMenuID != MENU_CREATEPARTY ) - { - if ( sCurrentMenuID == MENU_CREDITSPROC ) - dword_A74C88 = 1; - } - else - { - if ( sCurrentMenuID ) - { - v6 = &pTexture_PCX; - pTexture_PCX.Release(); - v8 = "makeme.pcx"; - } - else - { - v6 = &pTexture_PCX; - pTexture_PCX.Release(); - v8 = "title.pcx"; - if ( sCurrentMenuID ) - v8 = "lsave640.pcx"; - } - v6->Load(v8, 0); - } - } - viewparams->bRedrawGameUI = 1; - viewparams->InitGrayPalette(); - pMouse->SetCurrentCursorBitmap(); - /*if ( pRenderer->bWindowMode ) - { - //MoveWindow(hWnd, uWindowX, uWindowY, uWindowWidth, uWindowHeight, 0); - CenterWindowAndAdjustSize(hWnd, windowed_mode_width, windowed_mode_height); - ShowWindow(hWnd, SW_SHOWNORMAL); - }*/ - pMouse->bActive = true; - if ( pMovie_Track ) - pMediaPlayer->SelectMovieType(); - if (dword_6BE364_game_settings_1 & GAME_SETTINGS_0800) - dword_6BE364_game_settings_1 &= ~GAME_SETTINGS_0800; - else - pEventTimer->Resume(); - if (dword_6BE364_game_settings_1 & GAME_SETTINGS_1000) - dword_6BE364_game_settings_1 &= ~GAME_SETTINGS_1000; - else - pMiscTimer->Resume(); - } -} - - -//----- (004524D8) -------------------------------------------------------- -HWLTexture *RenderHWLContainer::LoadTexture(const char *pName, int bMipMaps) -{ - void *v13; // eax@13 - int v16; // esi@14 - int v17; // ecx@16 - int v18; // esi@16 - unsigned __int16 *v19; // eax@16 - int v20; // edx@16 - int v21; // ecx@16 - int v22; // eax@16 - int v23; // esi@16 - unsigned __int16 *v26; // [sp+24h] [bp-10h]@13 - int v27; // [sp+28h] [bp-Ch]@14 - int v28; // [sp+2Ch] [bp-8h]@13 - int pDestb; // [sp+3Ch] [bp+8h]@15 - - if (!uNumItems) - return nullptr; - - /////////////////////////////// - //quick search(быстрый поиск)// - /////////////////////////////// - uint idx1 = 0, - idx2 = uNumItems; - while (true) - { - uint i = idx1 + (idx2 - idx1) / 2; - - int res = _stricmp(pName, pSpriteNames[i]); - if (!res) - { - fseek(pFile, pSpriteOffsets[i], SEEK_SET); - break; - } - else if (res < 0) - idx2 = idx1 + (idx2 - idx1) / 2; - else - idx1 = i + 1; - - if ( idx1 >= idx2 ) - return false; - } - - uint uCompressedSize = 0; - fread(&uCompressedSize, 4, 1, pFile); - - HWLTexture* pTex = new HWLTexture; - fread(&pTex->uBufferWidth, 4, 1, pFile); - fread(&pTex->uBufferHeight, 4, 1, pFile); - fread(&pTex->uAreaWidth, 4, 1, pFile); - fread(&pTex->uAreaHeigth, 4, 1, pFile); - fread(&pTex->uWidth, 4, 1, pFile); - fread(&pTex->uHeight, 4, 1, pFile); - fread(&pTex->uAreaX, 4, 1, pFile); - fread(&pTex->uAreaY, 4, 1, pFile); - - pTex->pPixels = new unsigned __int16[pTex->uWidth * pTex->uHeight]; - if (uCompressedSize) - { - char* pCompressedData = new char[uCompressedSize]; - fread(pCompressedData, 1, uCompressedSize, pFile); - uint uDecompressedSize = pTex->uWidth * pTex->uHeight * sizeof(short); - zlib::MemUnzip(pTex->pPixels, &uDecompressedSize, pCompressedData, uCompressedSize); - delete [] pCompressedData; - } - else - fread(pTex->pPixels, 2, pTex->uWidth * pTex->uHeight, pFile); - - if ( scale_hwls_to_half ) - { - __debugbreak();//Ritor1 - pTex->uHeight /= 2; - pTex->uWidth /= 2; - v13 = new unsigned __int16[pTex->uWidth * pTex->uHeight]; - v28 = 0; - v26 = (unsigned __int16 *)v13; - if ( pTex->uHeight > 0 ) - { - v16 = pTex->uWidth; - v27 = 1; - do - { - pDestb = 0; - if ( v16 > 0 ) - { - do - { - v17 = v16 * v27; - v18 = v28 * v16; - v19 = pTex->pPixels; - v20 = pDestb + 2 * v18; - v21 = (int)&v19[2 * (pDestb + v17)]; - v22 = (int)&v19[2 * v20]; - LOWORD(v20) = *(unsigned short *)(v21 + 2); - LOWORD(v21) = *(unsigned short *)v21; - v23 = pDestb + v18; - pDestb++; - - v26[v23] = _452442_color_cvt(*(unsigned short *)v22, *(unsigned short *)(v22 + 2), v21, v20); - v16 = pTex->uWidth; - } - while (pDestb < pTex->uWidth); - } - ++v28; - v27 += 2; - } - while ( v28 < (signed int)pTex->uHeight ); - } - delete [] pTex->pPixels; - pTex->pPixels = v26; - } - return pTex; -} -//----- (0045271F) -------------------------------------------------------- -bool RenderHWLContainer::Release() -{ - __int32 v4; // eax@6 - FILE *v5; // ST24_4@6 - FILE *File; // [sp+4h] [bp-4h]@6 - - if ( this->bDumpDebug) - { - File = fopen("logd3d.txt", "w"); - v4 = ftell(this->pFile); - v5 = this->pFile; - this->uDataOffset = v4; - fwrite(&this->uNumItems, 4u, 1u, v5); - for (uint i = 0; i < this->uNumItems; i++) - { - fwrite(this->pSpriteNames[i], 1u, 0x14u, this->pFile); - fprintf(File, "D3D texture name: %s\t\toffset: %x\n", this->pSpriteNames[i], *(unsigned int *)(&(this->pSpriteNames[i]) + 200000/sizeof(char*))); - } - fwrite(this->pSpriteOffsets, 4u, this->uNumItems, this->pFile); - fseek(this->pFile, 4, 0); - fwrite(&this->uDataOffset, 4u, 1u, this->pFile); - fclose(this->pFile); - fclose(File); - } - else - { - fclose(this->pFile); - for (uint i = 0; i < this->uNumItems; i++) - { - delete[] this->pSpriteNames[i]; - } - } - return true; -} - -//----- (00452347) -------------------------------------------------------- -RenderHWLContainer::RenderHWLContainer(): - bDumpDebug(false) -{ - this->pFile = 0; - uSignature = 0; - this->uDataOffset = 0; - memset(&this->uNumItems, 0, 0x61A84u); - this->uNumItems = 0; - this->scale_hwls_to_half = false; -} - -//----- (0045237F) -------------------------------------------------------- -bool RenderHWLContainer::Load(const wchar_t *pFilename) -{ - pFile = _wfopen(pFilename, L"rb"); - if (!pFile) - { - Log::Warning(L"Failed to open file: %s", pFilename); - return false; - } - - fread(&uSignature, 1, 4, pFile); - if (uSignature != 'TD3D') - { - Log::Warning(L"Invalid format: %s", pFilename); - return false; - } - - fread(&uDataOffset, 4, 1, pFile); - fseek(pFile, uDataOffset, SEEK_SET); - fread(&uNumItems, 4, 1, pFile); - - memset(pSpriteNames, 0, 50000 * sizeof(char *)); - for (uint i = 0; i < uNumItems; ++i) - { - pSpriteNames[i] = new char[20]; - fread(pSpriteNames[i], 1, 20, pFile); - } - fread(pSpriteOffsets, 4, uNumItems, pFile); - - return true; -} - -//----- (004A1C1E) -------------------------------------------------------- -void Render::DoRenderBillboards_D3D() -{ - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE)); - - /*if (pRenderer->uNumBillboardsToDraw) - { - auto p = &pRenderer->pBillboardRenderListD3D[0]; - for (int i = 0; i < p->uNumVertices; ++i) - { - p->pQuads[i].pos.z -= p->pQuads[i].pos.z * 0.6; - //p->pQuads[i].rhw = + 0.8 * (1.0f - p->pQuads[i].rhw); - } - p->pQuads[0].pos.x = 10; - p->pQuads[0].pos.y = 10; - - p->pQuads[1].pos.x = 10; - p->pQuads[1].pos.y = 200; - - p->pQuads[2].pos.x = 100; - p->pQuads[2].pos.y = 200; - - p->pQuads[3].pos.x = 100; - p->pQuads[3].pos.y = 10; - - if (p->uOpacity != RenderBillboardD3D::NoBlend) - SetBillboardBlendOptions(p->uOpacity); - - pRenderer->pRenderD3D->pDevice->SetTexture(0, p->pTexture); - ErrD3D(pRenderer->pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, - D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, - p->pQuads, p->uNumVertices, - D3DDP_DONOTLIGHT | D3DDP_DONOTUPDATEEXTENTS)); - - }*/ - - for (int i = uNumBillboardsToDraw - 1; i >= 0; --i) - { - if (pBillboardRenderListD3D[i].opacity != RenderBillboardD3D::NoBlend) - SetBillboardBlendOptions(pBillboardRenderListD3D[i].opacity); - - pRenderD3D->pDevice->SetTexture(0, pBillboardRenderListD3D[i].pTexture); - ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, - D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, - pBillboardRenderListD3D[i].pQuads, pBillboardRenderListD3D[i].uNumVertices, - D3DDP_DONOTLIGHT | D3DDP_DONOTUPDATEEXTENTS)); - } - - if (bFogEnabled) - { - bFogEnabled = false; - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, GetLevelFogColor() & 0xFFFFFF)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, 0)); - } - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CW)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE)); -} - -//----- (004A1DA8) -------------------------------------------------------- -void Render::SetBillboardBlendOptions(RenderBillboardD3D::OpacityType a1) -{ - switch (a1) - { - case RenderBillboardD3D::Transparent: - { - if (bFogEnabled) - { - bFogEnabled = false; - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, GetLevelFogColor() & 0xFFFFFF)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, 0)); - } - - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE)); - } - break; - - case RenderBillboardD3D::Opaque_1: - case RenderBillboardD3D::Opaque_2: - case RenderBillboardD3D::Opaque_3: - { - if (bUsingSpecular) - { - if (!bFogEnabled) - { - bFogEnabled = true; - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE)); - } - } - - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, FALSE)); - } - break; - - default: - Log::Warning(L"SetBillboardBlendOptions: invalid opacity type (%u)", a1); - assert(false); - break; - } -} -//----- (00424CD7) -------------------------------------------------------- -int ODM_NearClip(unsigned int num_vertices) -{ - bool current_vertices_flag; // edi@1 - bool next_vertices_flag; // [sp+Ch] [bp-24h]@6 - double t; // st6@10 - bool bFound; - - bFound = false; - - if (!num_vertices) - return 0; - for (uint i = 0; i < num_vertices; ++i)// есть ли пограничные вершины - { - if ( array_50AC10[i].vWorldViewPosition.x > 8.0 ) - { - bFound = true; - break; - } - } - if ( !bFound ) - return 0; - - memcpy(&array_50AC10[num_vertices], &array_50AC10[0], sizeof(array_50AC10[0])); - current_vertices_flag = false; - next_vertices_flag = false; - if ( array_50AC10[0].vWorldViewPosition.x <= 8.0 ) - current_vertices_flag = true; - //check for near clip plane(проверка по ближней границе) - // - // v3.__________________. v0 - // | | - // | | - // | | - // ----------------------- 8.0(near_clip - 8.0) - // | | - // .__________________. - // v2 v1 - - int out_num_vertices = 0; - for (uint i = 0; i < num_vertices; ++i) - { - next_vertices_flag = array_50AC10[i + 1].vWorldViewPosition.x <= 8.0;// - if ( current_vertices_flag ^ next_vertices_flag ) - { - if ( next_vertices_flag )//следующая вершина за ближней границей - { - //t = near_clip - v0.x / v1.x - v0.x (формула получения точки пересечения отрезка с плоскостью) - t = (8.0 - array_50AC10[i].vWorldViewPosition.x) / (array_50AC10[i + 1].vWorldViewPosition.x - array_50AC10[i].vWorldViewPosition.x); - array_507D30[out_num_vertices].vWorldViewPosition.x = 8.0; - array_507D30[out_num_vertices].vWorldViewPosition.y = array_50AC10[i].vWorldViewPosition.y + (array_50AC10[i + 1].vWorldViewPosition.y - array_50AC10[i].vWorldViewPosition.y) * t; - array_507D30[out_num_vertices].vWorldViewPosition.z = array_50AC10[i].vWorldViewPosition.z + (array_50AC10[i + 1].vWorldViewPosition.z - array_50AC10[i].vWorldViewPosition.z) * t; - array_507D30[out_num_vertices].u = array_50AC10[i].u + (array_50AC10[i + 1].u - array_50AC10[i].u) * t; - array_507D30[out_num_vertices].v = array_50AC10[i].v + (array_50AC10[i + 1].v - array_50AC10[i].v) * t; - array_507D30[out_num_vertices]._rhw = 1.0 / 8.0; - } - else// текущая вершина за ближней границей - { - t = (8.0 - array_50AC10[i].vWorldViewPosition.x) / (array_50AC10[i].vWorldViewPosition.x - array_50AC10[i + 1].vWorldViewPosition.x); - array_507D30[out_num_vertices].vWorldViewPosition.x = 8.0; - array_507D30[out_num_vertices].vWorldViewPosition.y = array_50AC10[i].vWorldViewPosition.y + (array_50AC10[i].vWorldViewPosition.y - array_50AC10[i + 1].vWorldViewPosition.y) * t; - array_507D30[out_num_vertices].vWorldViewPosition.z = array_50AC10[i].vWorldViewPosition.z + (array_50AC10[i].vWorldViewPosition.z - array_50AC10[i + 1].vWorldViewPosition.z) * t; - array_507D30[out_num_vertices].u = array_50AC10[i].u + (array_50AC10[i].u - array_50AC10[i + 1].u) * t; - array_507D30[out_num_vertices].v = array_50AC10[i].v + (array_50AC10[i].v - array_50AC10[i + 1].v) * t; - array_507D30[out_num_vertices]._rhw = 1.0 / 8.0; - } - //array_507D30[out_num_vertices]._rhw = 0x3E000000u; - ++out_num_vertices; - } - if ( !next_vertices_flag ) - { - memcpy(&array_507D30[out_num_vertices], &array_50AC10[i + 1], sizeof(array_50AC10[i + 1])); - out_num_vertices++; - } - current_vertices_flag = next_vertices_flag; - } - return out_num_vertices >= 3 ? out_num_vertices : 0; -} - -//----- (00424EE0) -------------------------------------------------------- -int ODM_FarClip(unsigned int uNumVertices) -{ - bool current_vertices_flag; // [sp+Ch] [bp-28h]@6 - bool next_vertices_flag; // edi@1 - double t; // st6@10 - signed int depth_num_vertices; // [sp+18h] [bp-1Ch]@1 - bool bFound; - //Доп инфо "Программирование трёхмерных игр для windows" Ламот стр 910 - - bFound = false; - - memcpy(&array_50AC10[uNumVertices], &array_50AC10[0], sizeof(array_50AC10[uNumVertices])); - depth_num_vertices = 0; - current_vertices_flag = false; - if ( array_50AC10[0].vWorldViewPosition.x >= pODMRenderParams->shading_dist_mist ) - current_vertices_flag = true;//настоящая вершина больше границы видимости - if ( (signed int)uNumVertices <= 0 ) - return 0; - for (uint i = 0; i < uNumVertices; ++i)// есть ли пограничные вершины - { - if ( array_50AC10[i].vWorldViewPosition.x < pODMRenderParams->shading_dist_mist ) - { - bFound = true; - break; - } - } - if ( !bFound ) - return 0; - //check for far clip plane(проверка по дальней границе) - // - // v3.__________________. v0 - // | | - // | | - // | | - // ----------------------- 8192.0(far_clip - 0x2000) - // | | - // .__________________. - // v2 v1 - - for ( uint i = 0; i < uNumVertices; ++i ) - { - next_vertices_flag = array_50AC10[i + 1].vWorldViewPosition.x >= pODMRenderParams->shading_dist_mist; - if ( current_vertices_flag ^ next_vertices_flag )//одна из граней за границей видимости - { - if ( next_vertices_flag )//следующая вершина больше границы видимости(настоящая вершина меньше границы видимости) - v3 - { - //t = far_clip - v2.x / v3.x - v2.x (формула получения точки пересечения отрезка с плоскостью) - t = (pODMRenderParams->shading_dist_mist - array_50AC10[i].vWorldViewPosition.x) / (array_50AC10[i].vWorldViewPosition.x - array_50AC10[i + 1].vWorldViewPosition.x); - array_507D30[depth_num_vertices].vWorldViewPosition.x = pODMRenderParams->shading_dist_mist; - //New_y = v2.y + (v3.y - v2.y)*t - array_507D30[depth_num_vertices].vWorldViewPosition.y = array_50AC10[i].vWorldViewPosition.y + (array_50AC10[i].vWorldViewPosition.y - array_50AC10[i + 1].vWorldViewPosition.y) * t; - //New_z = v2.z + (v3.z - v2.z)*t - array_507D30[depth_num_vertices].vWorldViewPosition.z = array_50AC10[i].vWorldViewPosition.z + (array_50AC10[i].vWorldViewPosition.z - array_50AC10[i + 1].vWorldViewPosition.z) * t; - array_507D30[depth_num_vertices].u = array_50AC10[i].u + (array_50AC10[i].u - array_50AC10[i + 1].u) * t; - array_507D30[depth_num_vertices].v = array_50AC10[i].v + (array_50AC10[i].v - array_50AC10[i + 1].v) * t; - array_507D30[depth_num_vertices]._rhw = 1.0 / pODMRenderParams->shading_dist_mist; - } - else//настоящая вершина больше границы видимости(следующая вершина меньше границы видимости) - v0 - { - //t = far_clip - v1.x / v0.x - v1.x - t = (pODMRenderParams->shading_dist_mist - array_50AC10[i].vWorldViewPosition.x) / (array_50AC10[i + 1].vWorldViewPosition.x - array_50AC10[i].vWorldViewPosition.x); - array_507D30[depth_num_vertices].vWorldViewPosition.x = pODMRenderParams->shading_dist_mist; - //New_y = (v0.y - v1.y)*t + v1.y - array_507D30[depth_num_vertices].vWorldViewPosition.y = array_50AC10[i].vWorldViewPosition.y + (array_50AC10[i + 1].vWorldViewPosition.y - array_50AC10[i].vWorldViewPosition.y) * t; - //New_z = (v0.z - v1.z)*t + v1.z - array_507D30[depth_num_vertices].vWorldViewPosition.z = array_50AC10[i].vWorldViewPosition.z + (array_50AC10[i + 1].vWorldViewPosition.z - array_50AC10[i].vWorldViewPosition.z) * t; - array_507D30[depth_num_vertices].u = array_50AC10[i].u + (array_50AC10[i + 1].u - array_50AC10[i].u) * t; - array_507D30[depth_num_vertices].v = array_50AC10[i].v + (array_50AC10[i + 1].v - array_50AC10[i].v) * t; - array_507D30[depth_num_vertices]._rhw = 1.0 / pODMRenderParams->shading_dist_mist; - } - ++depth_num_vertices; - } - if ( !next_vertices_flag )//оба в границе видимости - { - memcpy(&array_507D30[depth_num_vertices], &array_50AC10[i + 1], sizeof(array_507D30[depth_num_vertices])); - depth_num_vertices++; - } - current_vertices_flag = next_vertices_flag; - } - return depth_num_vertices >= 3 ? depth_num_vertices : 0; -} - -//----- (0047840D) -------------------------------------------------------- -void Render::DrawBuildingsD3D() -{ - int v9; // ecx@8 - Texture *pFaceTexture; // eax@10 - unsigned int v16; // edi@22 - int v27; // eax@57 -// int vertex_id; // eax@58 - unsigned int v34; // eax@80 - int v40; // [sp-4h] [bp-5Ch]@2 - int v49; // [sp+2Ch] [bp-2Ch]@10 - int v50; // [sp+30h] [bp-28h]@34 - int v51; // [sp+34h] [bp-24h]@35 - int v52; // [sp+38h] [bp-20h]@36 - int v53; // [sp+3Ch] [bp-1Ch]@8 - int uNumVertices; // [sp+4Ch] [bp-Ch]@34 - int unused; // [sp+50h] [bp-8h]@3 - - if ( !pRenderD3D ) - { - MessageBoxW(nullptr, L"D3D version of RenderBuildings called in software!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Odbuild.cpp:73", 0); - } - - unused = 0; - if ( (signed int)pOutdoor->uNumBModels > 0 ) - { - for ( uint model_id = 0; model_id < (unsigned int)pOutdoor->uNumBModels; model_id++ ) - { - if ( IsBModelVisible(model_id, &unused) ) - { - pOutdoor->pBModels[model_id].field_40 |= 1; - if ( pOutdoor->pBModels[model_id].uNumFaces > 0 ) - { - for ( int face_id = 0; face_id < pOutdoor->pBModels[model_id].uNumFaces; face_id++ ) - { - if (!pOutdoor->pBModels[model_id].pFaces[face_id].Invisible()) - { - v53 = 0; - array_77EC08[pODMRenderParams->uNumPolygons].flags = 0; - array_77EC08[pODMRenderParams->uNumPolygons].field_32 = 0; - v9 = pOutdoor->pBModels[model_id].pFaces[face_id].uTextureID; - if (pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & FACE_TEXTURE_FRAME) - v9 = pTextureFrameTable->GetFrameTexture(v9, pEventTimer->uTotalGameTimeElapsed); - pFaceTexture = pBitmaps_LOD->GetTexture(v9); - array_77EC08[pODMRenderParams->uNumPolygons].pTexture = pFaceTexture; - if (pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & FACE_FLUID) - array_77EC08[pODMRenderParams->uNumPolygons].flags |= 2; - if (pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & FACE_INDOOR_SKY ) - HIBYTE(array_77EC08[pODMRenderParams->uNumPolygons].flags) |= 4; - if ( pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & FACE_FLOW_DIAGONAL ) - HIBYTE(array_77EC08[pODMRenderParams->uNumPolygons].flags) |= 4; - else - { - if ( pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & FACE_FLOW_VERTICAL ) - HIBYTE(array_77EC08[pODMRenderParams->uNumPolygons].flags) |= 8; - } - if (pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & FACE_FLOW_HORIZONTAL) - array_77EC08[pODMRenderParams->uNumPolygons].flags |= 0x2000; - else - { - if (pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & FACE_DONT_CACHE_TEXTURE) - HIBYTE(array_77EC08[pODMRenderParams->uNumPolygons].flags) |= 0x10; - } - array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaU = pOutdoor->pBModels[model_id].pFaces[face_id].sTextureDeltaU; - array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaV = pOutdoor->pBModels[model_id].pFaces[face_id].sTextureDeltaV; - v16 = GetTickCount() >> 4; - if ( pOutdoor->pBModels[model_id].pFaces[face_id].pFacePlane.vNormal.z && abs(pOutdoor->pBModels[model_id].pFaces[face_id].pFacePlane.vNormal.z) >= 59082 ) - { - if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 4 ) - array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaV += v16 & array_77EC08[pODMRenderParams->uNumPolygons].pTexture->uHeightMinus1; - if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 8 ) - array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaV -= v16 & array_77EC08[pODMRenderParams->uNumPolygons].pTexture->uHeightMinus1; - } - else - { - if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 4 ) - array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaV -= v16 & array_77EC08[pODMRenderParams->uNumPolygons].pTexture->uHeightMinus1; - if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 8 ) - array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaV += v16 & array_77EC08[pODMRenderParams->uNumPolygons].pTexture->uHeightMinus1; - } - if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 0x10 ) - array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaU -= v16 & array_77EC08[pODMRenderParams->uNumPolygons].pTexture->uWidthMinus1; - else - { - if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 0x20 ) - array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaU += v16 & array_77EC08[pODMRenderParams->uNumPolygons].pTexture->uWidthMinus1; - } - v50 = 0; - v49 = 0; - uNumVertices = pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices; - if ( pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices > 0 ) - { - for ( uint vertex_id = 1; vertex_id <= pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices; vertex_id++ ) - { - array_73D150[vertex_id - 1].vWorldPosition.x = pOutdoor->pBModels[model_id].pVertices.pVertices[pOutdoor->pBModels[model_id].pFaces[face_id].pVertexIDs[vertex_id - 1]].x; - array_73D150[vertex_id - 1].vWorldPosition.y = pOutdoor->pBModels[model_id].pVertices.pVertices[pOutdoor->pBModels[model_id].pFaces[face_id].pVertexIDs[vertex_id - 1]].y; - array_73D150[vertex_id - 1].vWorldPosition.z = pOutdoor->pBModels[model_id].pVertices.pVertices[pOutdoor->pBModels[model_id].pFaces[face_id].pVertexIDs[vertex_id - 1]].z; - array_73D150[vertex_id - 1].u = (array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaU + (signed __int16)pOutdoor->pBModels[model_id].pFaces[face_id].pTextureUIDs[vertex_id - 1]) * (1.0 / (double)pFaceTexture->uTextureWidth); - array_73D150[vertex_id - 1].v = (array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaV + (signed __int16)pOutdoor->pBModels[model_id].pFaces[face_id].pTextureVIDs[vertex_id - 1]) * (1.0 / (double)pFaceTexture->uTextureHeight); - } - for ( uint i = 1; i <= pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices; i++ ) - { - if ( pOutdoor->pBModels[model_id].pVertices.pVertices[pOutdoor->pBModels[model_id].pFaces[face_id].pVertexIDs[0]].z == array_73D150[i - 1].vWorldPosition.z ) - ++v53; - pGame->pIndoorCameraD3D->ViewTransform(&array_73D150[i - 1], 1); - if ( array_73D150[i - 1].vWorldViewPosition.x < 8.0 || array_73D150[i - 1].vWorldViewPosition.x > pODMRenderParams->shading_dist_mist ) - { - if ( array_73D150[i - 1].vWorldViewPosition.x >= 8.0 ) - v49 = 1; - else - v50 = 1; - } - else - pGame->pIndoorCameraD3D->Project(&array_73D150[i - 1], 1, 0); - } - } - if ( v53 == pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices ) - LOBYTE(array_77EC08[pODMRenderParams->uNumPolygons].field_32) |= 1; - array_77EC08[pODMRenderParams->uNumPolygons].pODMFace = &pOutdoor->pBModels[model_id].pFaces[face_id]; - array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices = pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices; - array_77EC08[pODMRenderParams->uNumPolygons].field_59 = 5; - v51 = fixpoint_mul(-pOutdoor->vSunlight.x, pOutdoor->pBModels[model_id].pFaces[face_id].pFacePlane.vNormal.x); - v53 = fixpoint_mul(-pOutdoor->vSunlight.y, pOutdoor->pBModels[model_id].pFaces[face_id].pFacePlane.vNormal.y); - v52 = fixpoint_mul(-pOutdoor->vSunlight.z, pOutdoor->pBModels[model_id].pFaces[face_id].pFacePlane.vNormal.z); - array_77EC08[pODMRenderParams->uNumPolygons].dimming_level = 20 - fixpoint_mul(20, v51 + v53 + v52); - if ( array_77EC08[pODMRenderParams->uNumPolygons].dimming_level < 0 ) - array_77EC08[pODMRenderParams->uNumPolygons].dimming_level = 0; - if ( array_77EC08[pODMRenderParams->uNumPolygons].dimming_level > 31 ) - array_77EC08[pODMRenderParams->uNumPolygons].dimming_level = 31; - if ( pODMRenderParams->uNumPolygons >= 1999 + 5000) - return; - if ( ODMFace::IsBackfaceNotCulled(array_73D150, &array_77EC08[pODMRenderParams->uNumPolygons]) ) - { - pOutdoor->pBModels[model_id].pFaces[face_id].bVisible = 1; - array_77EC08[pODMRenderParams->uNumPolygons].uBModelFaceID = face_id; - array_77EC08[pODMRenderParams->uNumPolygons].uBModelID = model_id; - v27 = 8 * (face_id | (model_id << 6)); - LOBYTE(v27) = v27 | 6; - array_77EC08[pODMRenderParams->uNumPolygons].field_50 = v27; - for ( int vertex_id = 0; vertex_id < pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices; ++vertex_id) - { - memcpy(&array_50AC10[vertex_id], &array_73D150[vertex_id], sizeof(array_50AC10[vertex_id])); - array_50AC10[vertex_id]._rhw = 1.0 / (array_73D150[vertex_id].vWorldViewPosition.x + 0.0000001); - } - static stru154 static_RenderBuildingsD3D_stru_73C834; - /*static bool __init_flag = false; - if (!__init_flag) - { - __init_flag = true; - static_RenderBuildingsD3D_byte_73C84C_init_flag |= 1u; - stru154::stru154(&static_RenderBuildingsD3D_stru_73C834); - atexit(loc_4789D4); - }*/ - - v40 = (int)&pOutdoor->pBModels[model_id].pFaces[face_id]; - pGame->pLightmapBuilder->ApplyLights_OutdoorFace(&pOutdoor->pBModels[model_id].pFaces[face_id]); - pDecalBuilder->ApplyDecals_OutdoorFace(&pOutdoor->pBModels[model_id].pFaces[face_id]); - pGame->pLightmapBuilder->std__vector_000004_size = 0; - int v31 = 0; - if ( stru_F8AD28.uNumLightsApplied > 0 || pDecalBuilder->uNumDecals > 0 ) - { - v31 = v50 ? 3 : v49 != 0 ? 5 : 0; - static_RenderBuildingsD3D_stru_73C834.GetFacePlaneAndClassify(&pOutdoor->pBModels[model_id].pFaces[face_id], &pOutdoor->pBModels[model_id].pVertices); - if ( pDecalBuilder->uNumDecals > 0 ) - { - v40 = -1; - pDecalBuilder->ApplyDecals(31 - array_77EC08[pODMRenderParams->uNumPolygons].dimming_level, 2, &static_RenderBuildingsD3D_stru_73C834, - pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices, array_50AC10, 0, (char)v31, -1); - } - } - if ( stru_F8AD28.uNumLightsApplied > 0 ) - pGame->pLightmapBuilder->ApplyLights(&stru_F8AD28, &static_RenderBuildingsD3D_stru_73C834, uNumVertices, array_50AC10, 0, (char)v31); - if ( v50 ) - { - array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices = ODM_NearClip(pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices); - uNumVertices = array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices; - ODM_Project(array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices); - } - if ( v49 ) - { - array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices = ODM_FarClip(pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices); - uNumVertices = array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices; - ODM_Project(array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices); - } - if ( uNumVertices ) - { - if ( array_77EC08[pODMRenderParams->uNumPolygons].flags & 2 ) - { - if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 0x3C ) - v34 = pRenderer->pHDWaterBitmapIDs[0]; - else - v34 = pRenderer->pHDWaterBitmapIDs[pRenderer->hd_water_current_frame]; - v40 = (int)pBitmaps_LOD->pHardwareTextures[v34]; - } - else - v40 = (int)pBitmaps_LOD->pHardwareTextures[v9]; - pRenderer->DrawPolygon(uNumVertices, &array_77EC08[pODMRenderParams->uNumPolygons], &pOutdoor->pBModels[model_id].pFaces[face_id], (IDirect3DTexture2 *)v40); - } - } - } - } - } - } - } - } - return; -} -//----- (00479543) -------------------------------------------------------- -void Render::DrawOutdoorSkyD3D() -{ - int v9; // eax@4 - int v10; // ebx@4 - int v13; // edi@6 - int v14; // ecx@6 - int v15; // eax@8 - int v16; // eax@12 - signed __int64 v17; // qtt@13 - signed int v18; // ecx@13 - struct Polygon pSkyPolygon; // [sp+14h] [bp-150h]@1 - int v30; // [sp+134h] [bp-30h]@1 - int v32; // [sp+13Ch] [bp-28h]@6 - int v33; // [sp+140h] [bp-24h]@2 - signed __int64 v34; // [sp+144h] [bp-20h]@1 - int v35; // [sp+148h] [bp-1Ch]@4 - int v36; // [sp+14Ch] [bp-18h]@2 - int v37; // [sp+154h] [bp-10h]@8 - int v38; // [sp+158h] [bp-Ch]@1 - int v39; // [sp+15Ch] [bp-8h]@4 - - v30 = (signed __int64)((double)(pODMRenderParams->int_fov_rad * pGame->pIndoorCameraD3D->vPartyPos.z) - / ((double)pODMRenderParams->int_fov_rad + 8192.0) - + (double)(pViewport->uScreenCenterY)); - v34 = cos((double)pGame->pIndoorCameraD3D->sRotationX * 0.0030664064) * 0x2000;//(double)pODMRenderParams->shading_dist_mist, 8192 - v38 = (signed __int64)((double)(pViewport->uScreenCenterY) - - (double)pODMRenderParams->int_fov_rad - / (v34 + 0.0000001) - * (sin((double)pGame->pIndoorCameraD3D->sRotationX * 0.0030664064) - * (double)-0x2000//(double)pODMRenderParams->shading_dist_mist - - (double)pGame->pIndoorCameraD3D->vPartyPos.z)); - pSkyPolygon.Create_48607B(&stru_8019C8);//заполняется ptr_38 - pSkyPolygon.ptr_38->_48694B_frustum_sky(); - pSkyPolygon.uTileBitmapID = pOutdoor->sSky_TextureID;//179(original 166) - pSkyPolygon.pTexture = (Texture *)(SLOWORD(pOutdoor->sSky_TextureID) != -1 ? (int)&pBitmaps_LOD->pTextures[SLOWORD(pOutdoor->sSky_TextureID)] : 0); - if ( pSkyPolygon.pTexture ) - { - pSkyPolygon.dimming_level = 0; - pSkyPolygon.uNumVertices = 4; - //centering(центруем)----------------------------------------------------------------- - pSkyPolygon.v_18.x = -stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationX + 16); - pSkyPolygon.v_18.y = 0; - pSkyPolygon.v_18.z = -stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationX + 16); - - //sky wiew position(положение неба на экране)------------------------------------------ - // X - // 0._____________________________.3 - // |8,8 468,8 | - // | | - // | | - // Y| | - // | | - // |8,351 468,351 | - // 1._____________________________.2 - // - array_50AC10[0].vWorldViewProjX = (double)(signed int)pViewport->uViewportTL_X;//8 - array_50AC10[0].vWorldViewProjY = (double)(signed int)pViewport->uViewportTL_Y;//8 - - array_50AC10[1].vWorldViewProjX = (double)(signed int)pViewport->uViewportTL_X;//8 - array_50AC10[1].vWorldViewProjY = (double)v38;//247 - - array_50AC10[2].vWorldViewProjX = (double)(signed int)pViewport->uViewportBR_X;//468 - array_50AC10[2].vWorldViewProjY = (double)v38;//247 - - array_50AC10[3].vWorldViewProjX = (double)(signed int)pViewport->uViewportBR_X;//468 - array_50AC10[3].vWorldViewProjY = (double)(signed int)pViewport->uViewportTL_Y;//8 - - pSkyPolygon.sTextureDeltaU = 224 * pMiscTimer->uTotalGameTimeElapsed;//7168 - pSkyPolygon.sTextureDeltaV = 224 * pMiscTimer->uTotalGameTimeElapsed;//7168 - - pSkyPolygon.field_24 = 0x2000000u;//maybe attributes - v33 = 65536 / (signed int)(signed __int64)(((double)(pViewport->uViewportBR_X - pViewport->uViewportTL_X) / 2) / tan(0.6457717418670654) + 0.5); - for ( uint i = 0; i < pSkyPolygon.uNumVertices; ++i ) - { - //rotate skydome(вращение купола неба)-------------------------------------- - // В игре принята своя система измерения углов. Полный угол (180). Значению угла 0 соответствует - // направление на север и/или юг (либо на восток и/или запад), значению 65536 еденицам(0х10000) соответствует угол 90. - // две переменные хранят данные по углу обзора. field_14 по западу и востоку. field_20 по югу и северу - // от -25080 до 25080 - v39 = fixpoint_mul(pSkyPolygon.ptr_38->viewing_angle_from_west_east, v33 * (v30 - floor(array_50AC10[i].vWorldViewProjY + 0.5))); - v35 = v39 + pSkyPolygon.ptr_38->angle_from_north; - - v39 = fixpoint_mul(pSkyPolygon.ptr_38->viewing_angle_from_north_south, v33 * (v30 - floor(array_50AC10[i].vWorldViewProjY + 0.f))); - v36 = v39 + pSkyPolygon.ptr_38->angle_from_east; - - v9 = fixpoint_mul(pSkyPolygon.v_18.z, v33 * (v30 - floor(array_50AC10[i].vWorldViewProjY + 0.5))); - v10 = pSkyPolygon.v_18.x + v9; - if ( v10 > 0 ) - v10 = 0; - v13 = v33 * (pViewport->uScreenCenterX - (signed __int64)array_50AC10[i].vWorldViewProjX); - v34 = -pSkyPolygon.field_24; - v32 = (signed __int64)array_50AC10[i].vWorldViewProjY - 1.0; - v14 = v33 * (v30 - v32); - while ( 1 ) - { - if ( v10 ) - { - v37 = abs((int)v34 >> 14); - v15 = abs(v10); - if ( v37 <= v15 || v32 <= (signed int)pViewport->uViewportTL_Y ) - { - if ( v10 <= 0 ) - break; - } - } - v16 = fixpoint_mul(pSkyPolygon.v_18.z, v14); - --v32; - v14 += v33; - v10 = pSkyPolygon.v_18.x + v16; - } - LODWORD(v17) = LODWORD(v34) << 16; - HIDWORD(v17) = v34 >> 16; - v18 = v17 / v10; - if ( v18 < 0 ) - v18 = pODMRenderParams->shading_dist_mist; - v37 = v35 + fixpoint_mul(pSkyPolygon.ptr_38->angle_from_west, v13); - v35 = 224 * pMiscTimer->uTotalGameTimeElapsed + ((signed int)fixpoint_mul(v37, v18) >> 3); - array_50AC10[i].u = (double)v35 / ((double)pSkyPolygon.pTexture->uTextureWidth * 65536.0); - - v36 = v36 + fixpoint_mul(pSkyPolygon.ptr_38->angle_from_south, v13); - v35 = 224 * pMiscTimer->uTotalGameTimeElapsed + ((signed int)fixpoint_mul(v36, v18) >> 3); - array_50AC10[i].v = (double)v35 / ((double)pSkyPolygon.pTexture->uTextureHeight * 65536.0); - - array_50AC10[i].vWorldViewPosition.x = (double)0x2000;//pODMRenderParams->shading_dist_mist 8192 - array_50AC10[i]._rhw = 1.0 / (double)(v18 >> 16); - } - pRenderer->DrawOutdoorSkyPolygon(pSkyPolygon.uNumVertices, &pSkyPolygon, pBitmaps_LOD->pHardwareTextures[(signed __int16)pSkyPolygon.uTileBitmapID]); - array_50AC10[0].vWorldViewProjY = (double)v10; - array_50AC10[1].vWorldViewProjY = array_50AC10[1].vWorldViewProjY + 30.0; - array_50AC10[2].vWorldViewProjY = array_50AC10[2].vWorldViewProjY + 30.0; - array_50AC10[3].vWorldViewProjY = (double)v10; - pRenderer->DrawOutdoorSkyPolygon(pSkyPolygon.uNumVertices, &pSkyPolygon, pBitmaps_LOD->pHardwareTextures[(signed __int16)pSkyPolygon.uTileBitmapID]); - return; - } -} -//----- (004226C2) -------------------------------------------------------- -bool PauseGameDrawing() -{ - if ( pCurrentScreen != SCREEN_GAME - && pCurrentScreen != SCREEN_NPC_DIALOGUE - && pCurrentScreen != SCREEN_CHANGE_LOCATION ) - { - if (pCurrentScreen == SCREEN_INPUT_BLV) - return pMovie_Track;//pSmackerMovie != 0; - if ( pCurrentScreen != SCREEN_BRANCHLESS_NPC_DIALOG ) - return true; - } - return false; -} - - -//----- (0045E03A) -------------------------------------------------------- -unsigned short *Render::MakeScreenshot(signed int width, signed int height) -{ - unsigned __int16 *for_pixels; // ebx@1 - DDSURFACEDESC2 Dst; // [sp+4h] [bp-A0h]@6 - unsigned __int16 *pPixels; // [sp+80h] [bp-24h]@1 - float interval_x; // [sp+84h] [bp-20h]@1 - float interval_y; // [sp+8Ch] [bp-18h]@1 - - interval_x = game_viewport_width / (double)width; - interval_y = game_viewport_height / (double)height; - - pPixels = (unsigned __int16 *)malloc(2 * height * width); - memset(pPixels, 0 , 2 * height * width); - - for_pixels = pPixels; - - BeginSceneD3D(); - - if (uCurrentlyLoadedLevelType == LEVEL_Indoor) - pIndoor->Draw(); - else if (uCurrentlyLoadedLevelType == LEVEL_Outdoor) - pOutdoor->Draw(); - DrawBillboards_And_MaybeRenderSpecialEffects_And_EndScene(); - memset(&Dst, 0, sizeof(Dst)); - Dst.dwSize = sizeof(Dst); - - if ( LockSurface_DDraw4(pBackBuffer4, &Dst, DDLOCK_WAIT) ) - { - if (uCurrentlyLoadedLevelType == LEVEL_null) - memset(&for_pixels, 0, sizeof(for_pixels)); - else - { - for (uint y = 0; y < (unsigned int)height; ++y) - { - for (uint x = 0; x < (unsigned int)width; ++x) - { - if (Dst.ddpfPixelFormat.dwRGBBitCount == 32) - { - unsigned __int32 *p = (unsigned __int32 *)Dst.lpSurface + (int)(x * interval_x + 8.0) + (int)(y * interval_y + 8.0) * (Dst.lPitch >> 2); - *for_pixels = Color16((*p >> 16) & 255, (*p >> 8) & 255, *p & 255); - } - else if (Dst.ddpfPixelFormat.dwRGBBitCount == 16) - { - unsigned __int16 * p = (unsigned __int16 *)Dst.lpSurface + (int)(x * interval_x + 8.0) + y * Dst.lPitch; - *for_pixels = *p; - } - else - assert(false); - ++for_pixels; - } - } - } - ErrD3D(pBackBuffer4->Unlock(NULL)); - } - return pPixels; -} -//----- (0045E26C) -------------------------------------------------------- -void Render::SaveScreenshot(const char *pFilename, unsigned int width, unsigned int height) -{ - auto pixels = MakeScreenshot(width, height); - SavePCXImage(pFilename, pixels, width, height); - free(pixels); -} - -void Render::PackScreenshot(unsigned int width, unsigned int height, void *data, unsigned int data_size, unsigned int *out_screenshot_size) -{ - auto pixels = MakeScreenshot(150, 112); - PackPCXpicture(pixels, 150, 112, data, 1000000, out_screenshot_size); - free(pixels); -} - - -//----- (0046A7C8) -------------------------------------------------------- -int Render::_46А6АС_GetActorsInViewport(int pDepth) -{ - unsigned int v3; // eax@2 применяется в закле Жар печи для подсчёта кол-ва монстров видимых группе и заполнения массива id видимых монстров - unsigned int v5; // eax@2 - unsigned int v6; // eax@4 - unsigned int v12; // [sp+10h] [bp-14h]@1 - int mon_num; // [sp+1Ch] [bp-8h]@1 - unsigned int a1a; // [sp+20h] [bp-4h]@1 - - mon_num = 0; - v12 = GetBillboardDrawListSize(); - if ( (signed int)GetBillboardDrawListSize() > 0 ) - { - for ( a1a = 0; (signed int)a1a < (signed int)v12; ++a1a ) - { - v3 = GetParentBillboardID(a1a); - v5 = (unsigned __int16)pBillboardRenderList[v3].object_pid; - if ( PID_TYPE(v5) == OBJECT_Actor) - { - if ( pBillboardRenderList[v3].sZValue <= (unsigned int)(pDepth << 16) ) - { - v6 = PID_ID(v5); - if ( pActors[v6].uAIState != Dead && pActors[v6].uAIState != Dying && pActors[v6].uAIState != Removed - && pActors[v6].uAIState != Disabled && pActors[v6].uAIState != Summoned ) - { - if ( pGame->pVisInstance->DoesRayIntersectBillboard((double)pDepth, a1a) ) - { - if ( mon_num < 100 ) - { - _50BF30_actors_in_viewport_ids[mon_num] = v6; - mon_num++; - } - } - } - } - } - } - } - return mon_num; -} - - - - -void Render::BeginLightmaps() -{ - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP)); - - if (bUsingSpecular) - pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE); - - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, FALSE)); - ErrD3D(pRenderD3D->pDevice->SetTexture(0, pGame->pIndoorCameraD3D->LoadTextureAndGetHardwarePtr("effpar03"))); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE)); -} - -void Render::EndLightmaps() -{ - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE)); - - if (bUsingSpecular) - { - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, uFogColor)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, 0)); - } -} - - -void Render::BeginLightmaps2() -{ - if (bUsingSpecular) - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE)); - - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, FALSE)); - - ErrD3D(pRenderD3D->pDevice->SetTexture(0, pGame->pIndoorCameraD3D->LoadTextureAndGetHardwarePtr("effpar03"))); - - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE)); -} - - -void Render::EndLightmaps2() -{ - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CW)); - - if (bUsingSpecular) - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE)); -} - - - -//----- (00437C96) -------------------------------------------------------- -void Render::do_draw_debug_line_d3d(const RenderVertexD3D3 *pLineBegin, signed int sDiffuseBegin, const RenderVertexD3D3 *pLineEnd, signed int sDiffuseEnd, float z_stuff) -{ - double v6; // st7@2 - //IDirect3DDevice3 *v7; // eax@2 -// HRESULT v8; // eax@2 - std::string v9; // [sp-18h] [bp-60h]@3 -// const char *v10; // [sp-Ch] [bp-54h]@2 -// const char *v11; // [sp-8h] [bp-50h]@2 -// int v12; // [sp-4h] [bp-4Ch]@2 - RenderVertexD3D3 v13[2]; // [sp+8h] [bp-40h]@2 - - //if ( pRenderer->pRenderD3D ) - { - v6 = 0.001 - z_stuff; - memcpy(v13, pLineBegin, 0x20u); - memcpy(&v13[1], pLineEnd, sizeof(v13[1])); - v13[0].pos.z = v6; - v13[1].pos.z = v6; - v13[0].diffuse = sDiffuseBegin; - v13[1].diffuse = sDiffuseEnd; - ErrD3D(pRenderD3D->pDevice->SetTexture(0, nullptr)); - ErrD3D(pRenderD3D->pDevice->DrawPrimitive( - D3DPT_LINELIST, - 452, - v13, - 2, - 16)); - } -} - - -void Render::DrawLines(const RenderVertexD3D3 *vertices, unsigned int num_vertices) -{ - ErrD3D(pRenderD3D->pDevice->SetTexture(0, nullptr)); - ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_LINELIST, - D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, - (void *)vertices, - num_vertices, - D3DDP_DONOTLIGHT)); -} - - -void Render::DrawFansTransparent(const RenderVertexD3D3 *vertices, unsigned int num_vertices) -{ - //ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false)); - //ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, false)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA)); - - ErrD3D(pRenderD3D->pDevice->SetTexture(0, nullptr)); - ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, - D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, - (void *)vertices, - num_vertices, - 28)); - - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE)); - //ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, TRUE)); - //ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); -} - - -void Render::BeginDecals() -{ - // code chunk from 0049C304 - if (bUsingSpecular) - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE)); - ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP)); - - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, FALSE)); - - ErrD3D(pRenderD3D->pDevice->SetTexture(0, pGame->pIndoorCameraD3D->LoadTextureAndGetHardwarePtr("hwsplat04"))); -} - - -void Render::EndDecals() -{ - // code chunk from 0049C304 - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CW)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); - - if (bUsingSpecular) - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE)); -} - - - -//----- (0049C095) -------------------------------------------------------- -void Render::DrawDecal(Decal *pDecal, float z_bias) -{ - signed int v21; // [sp+Ch] [bp-864h]@15 - RenderVertexD3D3 pVerticesD3D[64]; // [sp+20h] [bp-850h]@6 - - if (pDecal->uNumVertices < 3) - { - Log::Warning(L"Decal has < 3 vertices"); - return; - } - - float color_mult; - if ( pDecal->field_C1C & 1 ) - color_mult = 1.0; - else - color_mult = pDecal->field_C18->_43B570_get_color_mult_by_time(); - - for (uint i = 0; i < (unsigned int)pDecal->uNumVertices; ++i) - { - uint uTint = Render::GetActorTintColor(pDecal->pVertices[i].vWorldViewPosition.x, pDecal->field_C14, 0, 0, nullptr); - - uint uTintR = (uTint >> 16) & 0xFF, - uTintG = (uTint >> 8) & 0xFF, - uTintB = uTint & 0xFF; - - uint uDecalColorMultR = (pDecal->uColorMultiplier >> 16) & 0xFF, - uDecalColorMultG = (pDecal->uColorMultiplier >> 8) & 0xFF, - uDecalColorMultB = pDecal->uColorMultiplier & 0xFF; - - uint uFinalR = floorf(uTintR / 255.0 * color_mult * uDecalColorMultR + 0.0f), - uFinalG = floorf(uTintG / 255.0 * color_mult * uDecalColorMultG + 0.0f), - uFinalB = floorf(uTintB / 255.0 * color_mult * uDecalColorMultB + 0.0f); - - - float v15; - if (fabs(z_bias) < 1e-5) - v15 = 1.0 - 1.0 / ((1.0f / pGame->pIndoorCameraD3D->GetShadingDistMist()) * pDecal->pVertices[i].vWorldViewPosition.x * 1000.0); - else - { - v15 = 1.0 - 1.0 / ((1.0f / pGame->pIndoorCameraD3D->GetShadingDistMist()) * pDecal->pVertices[i].vWorldViewPosition.x * 1000.0) - z_bias; - if (v15 < 0.000099999997) - v15 = 0.000099999997; - } - - pVerticesD3D[i].pos.z = v15; - - pVerticesD3D[i].pos.x = pDecal->pVertices[i].vWorldViewProjX; - pVerticesD3D[i].pos.y = pDecal->pVertices[i].vWorldViewProjY; - pVerticesD3D[i].texcoord.x = pDecal->pVertices[i].u; - pVerticesD3D[i].texcoord.y = pDecal->pVertices[i].v; - pVerticesD3D[i].diffuse = (uFinalR << 16) | (uFinalG << 8) | uFinalB; - pVerticesD3D[i].specular = 0; - pVerticesD3D[i].rhw = 1.0 / pDecal->pVertices[i].vWorldViewPosition.x; - } - - if (uCurrentlyLoadedLevelType == LEVEL_Indoor) - v21 = D3DDP_DONOTLIGHT | D3DDP_DONOTCLIP | D3DDP_DONOTUPDATEEXTENTS; - else - v21 = D3DDP_DONOTLIGHT; - - ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, - D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, - pVerticesD3D, - pDecal->uNumVertices, - v21)); -} - - -void Render::DrawSpecialEffectsQuad(const RenderVertexD3D3 *vertices, IDirect3DTexture2 *texture) -{ - ErrD3D(pRenderD3D->pDevice->SetTexture(0, texture)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, FALSE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, D3DCMP_ALWAYS)); - ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, - D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, - (void *)vertices, 4, 28)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE)); - ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, D3DCMP_LESS)); -} - -//----- (00452442) -------------------------------------------------------- -unsigned int __fastcall _452442_color_cvt(unsigned __int16 a1, unsigned __int16 a2, int a3, int a4) -{ - int v4; // ebx@0 - __int16 v5; // ST14_2@1 - __int16 v6; // dx@1 - int v7; // ecx@1 - __int16 v8; // ST10_2@1 - int v9; // edi@1 - unsigned __int16 v10; // dh@1@1 - int v11; // ebx@1 - int v12; // ebx@1 - __int16 a3a; // [sp+1Ch] [bp+8h]@1 - - v5 = a2 >> 2; - v6 = (unsigned __int16)a4 >> 2; - v8 = a1 >> 2; - a3a = (unsigned __int16)a3 >> 2; - LOWORD(v7) = a3a; - v9 = v7; - LOWORD(v4) = ((unsigned __int16)a4 >> 2) & 0xE0; - LOWORD(v7) = a3a & 0xE0; - LOWORD(v9) = v9 & 0x1C00; - v11 = v7 + v4; - LOWORD(v7) = v5 & 0xE0; - v12 = v7 + v11; - LOWORD(v7) = v8 & 0xE0; - __debugbreak(); // warning C4700: uninitialized local variable 'v10' used - return (PID_TYPE(v8) + PID_TYPE(v5) + PID_TYPE(a3a) + PID_TYPE(v6)) | (v7 + v12) | ((v8 & 0x1C00) - + (v5 & 0x1C00) - + v9 - + (__PAIR__(v10, (unsigned __int16)a4 >> 2) & 0x1C00)); -} - -//----- (0047C4FC) -------------------------------------------------------- -int __fastcall GetActorTintColor(int max_dimm, int min_dimm, float distance, int a4, RenderBillboard *a5) -{ - //int v5; // esi@1 - signed int v6; // edx@1 - //signed int result; // eax@2 - int v8; // eax@3 - double v9; // st7@12 - //double v10; // ST0C_8@18 - int v11; // ecx@28 - //signed int v12; // edi@28 - //double v13; // ST0C_8@33 - //double v14; // ST0C_8@34 - double v15; // st7@44 - //double v16; // ST0C_8@44 - //double v17; // ST0C_8@44 - int v18; // ST14_4@44 - //double v19; // ST0C_8@44 - signed int v20; // [sp+10h] [bp-4h]@10 - // float a3a; // [sp+1Ch] [bp+8h]@33 - //float a3b; // [sp+1Ch] [bp+8h]@34 - float a3c; // [sp+1Ch] [bp+8h]@44 - //float a3d; // [sp+1Ch] [bp+8h]@44 - //float a4b; // [sp+20h] [bp+Ch]@18 - //int a4a; // [sp+20h] [bp+Ch]@33 - //float a4c; // [sp+20h] [bp+Ch]@44 - //float a4d; // [sp+20h] [bp+Ch]@44 - int a5a; // [sp+24h] [bp+10h]@44 - - //v5 = a2; - v6 = 0; - - if (uCurrentlyLoadedLevelType == LEVEL_Indoor) - return 8 * (31 - max_dimm) | ((8 * (31 - max_dimm) | ((31 - max_dimm) << 11)) << 8); - - if (pParty->armageddon_timer) - return 0xFFFF0000; - - v8 = pWeather->bNight; - if (bUnderwater) - v8 = 0; - if (v8) - { - v20 = 1; - if ((signed __int64)pParty->pPartyBuffs[PARTY_BUFF_TORCHLIGHT].uExpireTime > 0) - v20 = pParty->pPartyBuffs[PARTY_BUFF_TORCHLIGHT].uPower; - v9 = (double)v20 * 1024.0; - if (a4) - { - v6 = 216; - goto LABEL_20; - } - if (distance <= v9) - { - if (distance > 0.0) - { - //a4b = distance * 216.0 / v9; - //v10 = a4b + 6.7553994e15; - //v6 = LODWORD(v10); - v6 = floorf(0.5f + distance * 216.0 / v9); - if (v6 > 216) - { - v6 = 216; - goto LABEL_20; - } - } - } - else - { - v6 = 216; - } - if (distance != 0.0) - { - LABEL_20: - if (a5) - v6 = 8 * _43F55F_get_billboard_light_level(a5, v6 >> 3); - if (v6 > 216) - v6 = 216; - return (255 - v6) | ((255 - v6) << 16) | ((255 - v6) << 8); - } - //LABEL_19: - v6 = 216; - goto LABEL_20; - } - - - - if (fabsf(distance) < 1.0e-6f) - return 0xFFF8F8F8; - - // dim in measured in 8-steps - v11 = 8 * (max_dimm - min_dimm); - //v12 = v11; - if (v11 >= 0) - { - if (v11 > 216) - v11 = 216; - } - else - v11 = 0; - - float fog_density_mult = 216.0f; - if (a4) - fog_density_mult += distance / (double)pODMRenderParams->shading_dist_shade * 32.0; - - v6 = v11 + floorf(pOutdoor->fFogDensity * fog_density_mult + 0.5f); - /*if ( a4 ) - { - //a3b = pOutdoor->fFogDensity * 216.0; - //v14 = a3b + 6.7553994e15; - //a4a = floorf(a3b + 0.5f);//LODWORD(v14); - } - else - { - //a3a = (distance / (double)pODMRenderParams->shading_dist_shade * 32.0 + 216.0) * pOutdoor->fFogDensity; - //v13 = a3a + 6.7553994e15; - //a4a = floorf(a3a + 0.5f);//LODWORD(v13); - } - v6 = a4a + v11;*/ - if (a5) - v6 = 8 * _43F55F_get_billboard_light_level(a5, v6 >> 3); - if (v6 > 216) - v6 = 216; - if (v6 < v11) - v6 = v11; - if (v6 > 8 * pOutdoor->max_terrain_dimming_level) - v6 = 8 * pOutdoor->max_terrain_dimming_level; - if (!bUnderwater) - return (255 - v6) | ((255 - v6) << 16) | ((255 - v6) << 8); - else - { - v15 = (double)(255 - v6) * 0.0039215689; - a3c = v15; - //a4c = v15 * 16.0; - //v16 = a4c + 6.7553994e15; - a5a = floorf(v15 * 16.0 + 0.5f);//LODWORD(v16); - //a4d = a3c * 194.0; - //v17 = a4d + 6.7553994e15; - v18 = floorf(a3c * 194.0 + 0.5f);//LODWORD(v17); - //a3d = a3c * 153.0; - //v19 = a3d + 6.7553994e15; - return (int)floorf(a3c * 153.0 + 0.5f)/*LODWORD(v19)*/ | ((v18 | (a5a << 8)) << 8); - } -} -// 6BE3C4: using guessed type char bUnderwater; - -//----- (0043F55F) -------------------------------------------------------- -int __fastcall _43F55F_get_billboard_light_level(RenderBillboard *a1, int uBaseLightLevel) -{ - signed int v3; // ecx@2 - - if (uCurrentlyLoadedLevelType == LEVEL_Indoor) - v3 = pIndoor->pSectors[a1->uIndoorSectorID].uMinAmbientLightLevel; - else - { - if (uBaseLightLevel == -1) - v3 = a1->dimming_level; - else - v3 = uBaseLightLevel; - } - return _43F5C8_get_point_light_level_with_respect_to_lights(v3, a1->uIndoorSectorID, a1->world_x, a1->world_y, a1->world_z); -} - -//----- (0043F5C8) -------------------------------------------------------- -int __fastcall _43F5C8_get_point_light_level_with_respect_to_lights(unsigned int uBaseLightLevel, int uSectorID, float x, float y, float z) -{ - // int v5; // esi@1 - signed int v6; // edi@1 - int v8; // eax@6 - int v9; // ebx@6 - unsigned int v10; // ecx@6 - unsigned int v11; // edx@9 - unsigned int v12; // edx@11 - signed int v13; // ecx@12 - BLVLightMM7 *v16; // esi@20 - int v17; // ebx@21 - // int v18; // eax@24 - // int v19; // ebx@24 - // unsigned int v20; // ecx@24 - // int v21; // edx@25 - // unsigned int v22; // edx@27 - // unsigned int v23; // edx@29 - signed int v24; // ecx@30 - int v26; // ebx@35 - // int v27; // eax@38 - // int v28; // ebx@38 - // unsigned int v29; // ecx@38 - // int v30; // edx@39 - // unsigned int v31; // edx@41 - // unsigned int v32; // edx@43 - //signed int v33; // ecx@44 - int v37; // [sp+Ch] [bp-18h]@37 - // int v38; // [sp+10h] [bp-14h]@5 - int v39; // [sp+10h] [bp-14h]@23 - int v40; // [sp+10h] [bp-14h]@36 - int v42; // [sp+14h] [bp-10h]@22 - unsigned int v43; // [sp+18h] [bp-Ch]@12 - unsigned int v44; // [sp+18h] [bp-Ch]@30 - unsigned int v45; // [sp+18h] [bp-Ch]@44 - - v6 = uBaseLightLevel; - for (uint i = 0; i < pMobileLightsStack->uNumLightsActive; ++i) - { - MobileLight* p = &pMobileLightsStack->pLights[i]; - - float distX = abs(p->vPosition.x - x); - if (distX <= p->uRadius) - { - float distY = abs(p->vPosition.y - y); - if (distY <= p->uRadius) - { - float distZ = abs(p->vPosition.z - z); - if (distZ <= p->uRadius) - { - v8 = distX; - v9 = distY; - v10 = distZ; - if (distX < distY) - { - v8 = distY; - v9 = distX; - } - if (v8 < distZ) - { - v11 = v8; - v8 = distZ; - v10 = v11; - } - if (v9 < (signed int)v10) - { - v12 = v10; - v10 = v9; - v9 = v12; - } - v43 = ((unsigned int)(11 * v9) / 32) + (v10 / 4) + v8; - v13 = p->uRadius; - if ((signed int)v43 < v13) - v6 += ((unsigned __int64)(30i64 * (signed int)(v43 << 16) / v13) >> 16) - 30; - } - } - } - } - - if (uCurrentlyLoadedLevelType == LEVEL_Indoor) - { - BLVSector* pSector = &pIndoor->pSectors[uSectorID]; - - for (uint i = 0; i < pSector->uNumLights; ++i) - { - v16 = pIndoor->pLights + pSector->pLights[i]; - if (~v16->uAtributes & 8) - { - v17 = abs(v16->vPosition.x - x); - if (v17 <= v16->uRadius) - { - v42 = abs(v16->vPosition.y - y); - if (v42 <= v16->uRadius) - { - v39 = abs(v16->vPosition.z - z); - if (v39 <= v16->uRadius) - { - v44 = int_get_vector_length(v17, v42, v39); - v24 = v16->uRadius; - if ((signed int)v44 < v24) - v6 += ((unsigned __int64)(30i64 * (signed int)(v44 << 16) / v24) >> 16) - 30; - } - } - } - } - } - } - - for (uint i = 0; i < pStationaryLightsStack->uNumLightsActive; ++i) - { - //StationaryLight* p = &pStationaryLightsStack->pLights[i]; - v26 = abs(pStationaryLightsStack->pLights[i].vPosition.x - x); - if (v26 <= pStationaryLightsStack->pLights[i].uRadius) - { - v40 = abs(pStationaryLightsStack->pLights[i].vPosition.y - y); - if (v40 <= pStationaryLightsStack->pLights[i].uRadius) - { - v37 = abs(pStationaryLightsStack->pLights[i].vPosition.z - z); - if (v37 <= pStationaryLightsStack->pLights[i].uRadius) - { - v45 = int_get_vector_length(v26, v40, v37); - //v33 = pStationaryLightsStack->pLights[i].uRadius; - if ((signed int)v45 < pStationaryLightsStack->pLights[i].uRadius) - v6 += ((unsigned __int64)(30i64 * (signed int)(v45 << 16) / pStationaryLightsStack->pLights[i].uRadius) >> 16) - 30; - } - } - } - } - - if (v6 <= 31) - { - if (v6 < 0) - v6 = 0; - } - else - v6 = 31; - return v6; -} - -//----- (0049D700) -------------------------------------------------------- -unsigned int __fastcall GetMaxMipLevels(unsigned int uDim) -{ - int v2; // ecx@1 - unsigned int v3; // eax@1 - - v2 = 0; - v3 = uDim - 1; - while (v3 & 1) - { - v3 >>= 1; - ++v2; - } - return v3 == 0 ? v2 : 0; -} - -//----- (0046E44E) -------------------------------------------------------- -int _46E44E_collide_against_faces_and_portals(unsigned int b1) -{ - BLVSector *pSector; // edi@1 - signed int v2; // ebx@1 - BLVFace *pFace; // esi@2 - __int16 pNextSector; // si@10 - int pArrayNum; // ecx@12 - unsigned __int8 v6; // sf@12 - unsigned __int8 v7; // of@12 - int result; // eax@14 - //int v10; // ecx@15 - int pFloor; // eax@16 - int v15; // eax@24 - int v16; // edx@25 - int v17; // eax@29 - unsigned int v18; // eax@33 - int v21; // eax@35 - int v22; // ecx@36 - int v23; // eax@40 - unsigned int v24; // eax@44 - int a3; // [sp+10h] [bp-48h]@28 - int v26; // [sp+14h] [bp-44h]@15 - int i; // [sp+18h] [bp-40h]@1 - int a10; // [sp+1Ch] [bp-3Ch]@1 - int v29; // [sp+20h] [bp-38h]@14 - int v32; // [sp+2Ch] [bp-2Ch]@15 - int pSectorsArray[10]; // [sp+30h] [bp-28h]@1 - - pSector = &pIndoor->pSectors[stru_721530.uSectorID]; - i = 1; - a10 = b1; - pSectorsArray[0] = stru_721530.uSectorID; - for (v2 = 0; v2 < pSector->uNumPortals; ++v2) - { - pFace = &pIndoor->pFaces[pSector->pPortals[v2]]; - if (stru_721530.sMaxX <= pFace->pBounding.x2 && stru_721530.sMinX >= pFace->pBounding.x1 - && stru_721530.sMaxY <= pFace->pBounding.y2 && stru_721530.sMinY >= pFace->pBounding.y1 - && stru_721530.sMaxZ <= pFace->pBounding.z2 && stru_721530.sMinZ >= pFace->pBounding.z1 - && abs((pFace->pFacePlane_old.dist - + stru_721530.normal.x * pFace->pFacePlane_old.vNormal.x - + stru_721530.normal.y * pFace->pFacePlane_old.vNormal.y - + stru_721530.normal.z * pFace->pFacePlane_old.vNormal.z) >> 16) <= stru_721530.field_6C + 16) - { - pNextSector = pFace->uSectorID == stru_721530.uSectorID ? pFace->uBackSectorID : pFace->uSectorID;//FrontSectorID - pArrayNum = i++; - v7 = i < 10; - v6 = i - 10 < 0; - pSectorsArray[pArrayNum] = pNextSector; - if (!(v6 ^ v7)) - break; - } - } - result = 0; - for (v29 = 0; v29 < i; v29++) - { - pSector = &pIndoor->pSectors[pSectorsArray[v29]]; - v32 = pSector->uNumFloors + pSector->uNumWalls + pSector->uNumCeilings; - for (v26 = 0; v26 < v32; v26++) - { - pFloor = pSector->pFloors[v26]; - pFace = &pIndoor->pFaces[pSector->pFloors[v26]]; - if (!pFace->Portal() - && stru_721530.sMaxX <= pFace->pBounding.x2 && stru_721530.sMinX >= pFace->pBounding.x1 - && stru_721530.sMaxY <= pFace->pBounding.y2 && stru_721530.sMinY >= pFace->pBounding.y1 - && stru_721530.sMaxZ <= pFace->pBounding.z2 && stru_721530.sMinZ >= pFace->pBounding.z1 - && pFloor != stru_721530.field_84) - { - v15 = (pFace->pFacePlane_old.dist + stru_721530.normal.x * pFace->pFacePlane_old.vNormal.x - + stru_721530.normal.y * pFace->pFacePlane_old.vNormal.y - + stru_721530.normal.z * pFace->pFacePlane_old.vNormal.z) >> 16; - if (v15 > 0) - { - v16 = (pFace->pFacePlane_old.dist + stru_721530.normal2.x * pFace->pFacePlane_old.vNormal.x - + stru_721530.normal2.y * pFace->pFacePlane_old.vNormal.y - + stru_721530.normal2.z * pFace->pFacePlane_old.vNormal.z) >> 16; - if (v15 <= stru_721530.prolly_normal_d || v16 <= stru_721530.prolly_normal_d) - { - if (v16 <= v15) - { - a3 = stru_721530.field_6C; - if (sub_47531C(stru_721530.prolly_normal_d, &a3, stru_721530.normal.x, stru_721530.normal.y, stru_721530.normal.z, - stru_721530.direction.x, stru_721530.direction.y, stru_721530.direction.z, pFace, a10)) - { - v17 = a3; - } - else - { - a3 = stru_721530.field_6C + stru_721530.prolly_normal_d; - if (!sub_475D85(&stru_721530.normal, &stru_721530.direction, &a3, pFace)) - goto LABEL_34; - v17 = a3 - stru_721530.prolly_normal_d; - a3 -= stru_721530.prolly_normal_d; - } - if (v17 < stru_721530.field_7C) - { - stru_721530.field_7C = v17; - v18 = 8 * pSector->pFloors[v26]; - LOBYTE(v18) = v18 | 6; - stru_721530.uFaceID = v18; - } - } - } - } - LABEL_34: - if (!(stru_721530.field_0 & 1) - || (v21 = (pFace->pFacePlane_old.dist + stru_721530.position.x * pFace->pFacePlane_old.vNormal.x - + stru_721530.position.y * pFace->pFacePlane_old.vNormal.y - + stru_721530.position.z * pFace->pFacePlane_old.vNormal.z) >> 16, v21 <= 0) - || (v22 = (pFace->pFacePlane_old.dist + stru_721530.field_4C * pFace->pFacePlane_old.vNormal.x - + stru_721530.field_50 * pFace->pFacePlane_old.vNormal.y - + stru_721530.field_54 * pFace->pFacePlane_old.vNormal.z) >> 16, v21 > stru_721530.prolly_normal_d) - && v22 > stru_721530.prolly_normal_d || v22 > v21) - continue; - a3 = stru_721530.field_6C; - if (sub_47531C(stru_721530.field_8_radius, &a3, stru_721530.position.x, stru_721530.position.y, stru_721530.position.z, - stru_721530.direction.x, stru_721530.direction.y, stru_721530.direction.z, pFace, a10)) - { - v23 = a3; - goto LABEL_43; - } - a3 = stru_721530.field_6C + stru_721530.field_8_radius; - if (sub_475D85(&stru_721530.position, &stru_721530.direction, &a3, pFace)) - { - v23 = a3 - stru_721530.prolly_normal_d; - a3 -= stru_721530.prolly_normal_d; - LABEL_43: - if (v23 < stru_721530.field_7C) - { - stru_721530.field_7C = v23; - v24 = 8 * pSector->pFloors[v26]; - LOBYTE(v24) = v24 | 6; - stru_721530.uFaceID = v24; - } - } - } - } - result = v29 + 1; - } - return result; -} -// 46E44E: using guessed type int var_28[10]; - -//----- (0046E889) -------------------------------------------------------- -int __fastcall _46E889_collide_against_bmodels(unsigned int ecx0) -{ - int result; // eax@1 - //int v3; // ebx@9 - int v8; // eax@19 - int v9; // ecx@20 - int v10; // eax@24 - unsigned int v14; // eax@28 - int v15; // eax@30 - int v16; // ecx@31 - unsigned int v17; // eax@36 - int v21; // eax@42 - unsigned int v22; // eax@43 - //int a11; // [sp+70h] [bp-18h]@1 - //int a10; // [sp+80h] [bp-8h]@1 - int a2; // [sp+84h] [bp-4h]@23 - - //a11 = ecx0; - - BLVFace face; // [sp+Ch] [bp-7Ch]@1 - - result = 0; - for (uint i = 0; i < (signed int)pOutdoor->uNumBModels; ++i) - { - if (stru_721530.sMaxX <= pOutdoor->pBModels[i].sMaxX && stru_721530.sMinX >= pOutdoor->pBModels[i].sMinX - && stru_721530.sMaxY <= pOutdoor->pBModels[i].sMaxY && stru_721530.sMinY >= pOutdoor->pBModels[i].sMinY - && stru_721530.sMaxZ <= pOutdoor->pBModels[i].sMaxZ && stru_721530.sMinZ >= pOutdoor->pBModels[i].sMinZ) - { - for (uint j = 0; j < pOutdoor->pBModels[i].uNumFaces; ++j) - { - if (stru_721530.sMaxX <= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.x2 && stru_721530.sMinX >= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.x1 - && stru_721530.sMaxY <= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.y2 && stru_721530.sMinY >= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.y1 - && stru_721530.sMaxZ <= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.z2 && stru_721530.sMinZ >= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.z1) - { - face.pFacePlane_old.vNormal.x = pOutdoor->pBModels[i].pFaces[j].pFacePlane.vNormal.x; - face.pFacePlane_old.vNormal.y = pOutdoor->pBModels[i].pFaces[j].pFacePlane.vNormal.y; - face.pFacePlane_old.vNormal.z = pOutdoor->pBModels[i].pFaces[j].pFacePlane.vNormal.z; - - face.pFacePlane_old.dist = pOutdoor->pBModels[i].pFaces[j].pFacePlane.dist; //incorrect - - face.uAttributes = pOutdoor->pBModels[i].pFaces[j].uAttributes; - - face.pBounding.x1 = pOutdoor->pBModels[i].pFaces[j].pBoundingBox.x1; - face.pBounding.y1 = pOutdoor->pBModels[i].pFaces[j].pBoundingBox.y1; - face.pBounding.z1 = pOutdoor->pBModels[i].pFaces[j].pBoundingBox.z1; - - face.pBounding.x2 = pOutdoor->pBModels[i].pFaces[j].pBoundingBox.x2; - face.pBounding.y2 = pOutdoor->pBModels[i].pFaces[j].pBoundingBox.y2; - face.pBounding.z2 = pOutdoor->pBModels[i].pFaces[j].pBoundingBox.z2; - - face.zCalc1 = pOutdoor->pBModels[i].pFaces[j].zCalc1; - face.zCalc2 = pOutdoor->pBModels[i].pFaces[j].zCalc2; - face.zCalc3 = pOutdoor->pBModels[i].pFaces[j].zCalc3; - - face.pXInterceptDisplacements = pOutdoor->pBModels[i].pFaces[j].pXInterceptDisplacements; - face.pYInterceptDisplacements = pOutdoor->pBModels[i].pFaces[j].pYInterceptDisplacements; - face.pZInterceptDisplacements = pOutdoor->pBModels[i].pFaces[j].pZInterceptDisplacements; - - face.uPolygonType = (PolygonType)pOutdoor->pBModels[i].pFaces[j].uPolygonType; - - face.uNumVertices = pOutdoor->pBModels[i].pFaces[j].uNumVertices; - - face.uBitmapID = pOutdoor->pBModels[i].pFaces[j].uTextureID; - - face.pVertexIDs = pOutdoor->pBModels[i].pFaces[j].pVertexIDs; - - if (!face.Ethereal() && !face.Portal()) - { - v8 = (face.pFacePlane_old.dist + face.pFacePlane_old.vNormal.x * stru_721530.normal.x - + face.pFacePlane_old.vNormal.y * stru_721530.normal.y - + face.pFacePlane_old.vNormal.z * stru_721530.normal.z) >> 16; - if (v8 > 0) - { - v9 = (face.pFacePlane_old.dist + face.pFacePlane_old.vNormal.x * stru_721530.normal2.x - + face.pFacePlane_old.vNormal.y * stru_721530.normal2.y - + face.pFacePlane_old.vNormal.z * stru_721530.normal2.z) >> 16; - if (v8 <= stru_721530.prolly_normal_d || v9 <= stru_721530.prolly_normal_d) - { - if (v9 <= v8) - { - a2 = stru_721530.field_6C; - if (sub_4754BF(stru_721530.prolly_normal_d, &a2, stru_721530.normal.x, stru_721530.normal.y, stru_721530.normal.z, - stru_721530.direction.x, stru_721530.direction.y, stru_721530.direction.z, &face, i, ecx0)) - { - v10 = a2; - } - else - { - a2 = stru_721530.prolly_normal_d + stru_721530.field_6C; - if (!sub_475F30(&a2, &face, stru_721530.normal.x, stru_721530.normal.y, stru_721530.normal.z, - stru_721530.direction.x, stru_721530.direction.y, stru_721530.direction.z, i)) - goto LABEL_29; - v10 = a2 - stru_721530.prolly_normal_d; - a2 -= stru_721530.prolly_normal_d; - } - if (v10 < stru_721530.field_7C) - { - stru_721530.field_7C = v10; - v14 = 8 * (j | (i << 6)); - LOBYTE(v14) = v14 | 6; - stru_721530.uFaceID = v14; - } - } - } - } - LABEL_29: - if (stru_721530.field_0 & 1) - { - v15 = (face.pFacePlane_old.dist + face.pFacePlane_old.vNormal.x * stru_721530.position.x - + face.pFacePlane_old.vNormal.y * stru_721530.position.y - + face.pFacePlane_old.vNormal.z * stru_721530.position.z) >> 16; - if (v15 > 0) - { - v16 = (face.pFacePlane_old.dist + face.pFacePlane_old.vNormal.x * stru_721530.field_4C - + face.pFacePlane_old.vNormal.y * stru_721530.field_50 - + face.pFacePlane_old.vNormal.z * stru_721530.field_54) >> 16; - if (v15 <= stru_721530.prolly_normal_d || v16 <= stru_721530.prolly_normal_d) - { - if (v16 <= v15) - { - a2 = stru_721530.field_6C; - if (sub_4754BF(stru_721530.field_8_radius, &a2, stru_721530.position.x, stru_721530.position.y, stru_721530.position.z, - stru_721530.direction.x, stru_721530.direction.y, stru_721530.direction.z, &face, i, ecx0)) - { - if (a2 < stru_721530.field_7C) - { - stru_721530.field_7C = a2; - v17 = 8 * (j | (i << 6)); - LOBYTE(v17) = v17 | 6; - stru_721530.uFaceID = v17; - } - } - else - { - a2 = stru_721530.field_6C + stru_721530.field_8_radius; - if (sub_475F30(&a2, &face, stru_721530.position.x, stru_721530.position.y, stru_721530.position.z, - stru_721530.direction.x, stru_721530.direction.y, stru_721530.direction.z, i)) - { - v21 = a2 - stru_721530.prolly_normal_d; - a2 -= stru_721530.prolly_normal_d; - if (a2 < stru_721530.field_7C) - { - stru_721530.field_7C = v21; - v22 = 8 * (j | (i << 6)); - LOBYTE(v22) = v22 | 6; - stru_721530.uFaceID = v22; - } - } - } - } - } - } - } - } - } - } - } - result = i; - } - return result; -} - -//----- (0046ED1B) -------------------------------------------------------- -int collide_against_floor(int x, int y, int z, unsigned int *pSectorID, unsigned int *pFaceID) -{ - uint uFaceID = -1; - int floor_level = BLV_GetFloorLevel(x, y, z, *pSectorID, &uFaceID); - - if (floor_level != -30000 && floor_level <= z + 50) - { - *pFaceID = uFaceID; - return floor_level; - } - - uint uSectorID = pIndoor->GetSector(x, y, z); - *pSectorID = uSectorID; - - floor_level = BLV_GetFloorLevel(x, y, z, uSectorID, &uFaceID); - if (uSectorID && floor_level != -30000) - *pFaceID = uFaceID; - else return -30000; - return floor_level; -} - -//----- (0046ED8A) -------------------------------------------------------- -void __fastcall _46ED8A_collide_against_sprite_objects(unsigned int _this) -{ - ObjectDesc *object; // edx@4 - int v10; // ecx@12 - int v11; // esi@13 - - for (uint i = 0; i < uNumSpriteObjects; ++i) - { - if (pSpriteObjects[i].uObjectDescID) - { - object = &pObjectList->pObjects[pSpriteObjects[i].uObjectDescID]; - if (!(object->uFlags & OBJECT_DESC_NO_COLLISION)) - { - if (stru_721530.sMaxX <= pSpriteObjects[i].vPosition.x + object->uRadius && stru_721530.sMinX >= pSpriteObjects[i].vPosition.x - object->uRadius - && stru_721530.sMaxY <= pSpriteObjects[i].vPosition.y + object->uRadius && stru_721530.sMinY >= pSpriteObjects[i].vPosition.y - object->uRadius - && stru_721530.sMaxZ <= pSpriteObjects[i].vPosition.z + object->uHeight && stru_721530.sMinZ >= pSpriteObjects[i].vPosition.z) - { - if (abs(((pSpriteObjects[i].vPosition.x - stru_721530.normal.x) * stru_721530.direction.y - - (pSpriteObjects[i].vPosition.y - stru_721530.normal.y) * stru_721530.direction.x) >> 16) - <= object->uHeight + stru_721530.prolly_normal_d) - { - v10 = ((pSpriteObjects[i].vPosition.x - stru_721530.normal.x) * stru_721530.direction.x - + (pSpriteObjects[i].vPosition.y - stru_721530.normal.y) * stru_721530.direction.y) >> 16; - if (v10 > 0) - { - v11 = stru_721530.normal.z + ((unsigned __int64)(stru_721530.direction.z * (signed __int64)v10) >> 16); - if (v11 >= pSpriteObjects[i].vPosition.z - stru_721530.prolly_normal_d) - { - if (v11 <= object->uHeight + stru_721530.prolly_normal_d + pSpriteObjects[i].vPosition.z) - { - if (v10 < stru_721530.field_7C) - sub_46DEF2(_this, i); - } - } - } - } - } - } - } - } -} - -//----- (0046EF01) -------------------------------------------------------- -int _46EF01_collision_chech_player(int a1) -{ - int result; // eax@1 - int v3; // ebx@7 - int v4; // esi@7 - int v5; // edi@8 - int v6; // ecx@9 - int v7; // edi@12 - int v10; // [sp+14h] [bp-8h]@7 - int v11; // [sp+18h] [bp-4h]@7 - - result = pParty->vPosition.x; - //v9 = pParty->uPartyHeight; - if (stru_721530.sMaxX <= pParty->vPosition.x + (2 * pParty->field_14_radius) && stru_721530.sMinX >= pParty->vPosition.x - (2 * pParty->field_14_radius) - && stru_721530.sMaxY <= pParty->vPosition.y + (2 * pParty->field_14_radius) && stru_721530.sMinY >= pParty->vPosition.y - (2 * pParty->field_14_radius) - && stru_721530.sMaxZ <= pParty->vPosition.z + pParty->uPartyHeight && stru_721530.sMinZ >= pParty->vPosition.z) - { - v3 = stru_721530.prolly_normal_d + (2 * pParty->field_14_radius); - v11 = pParty->vPosition.x - stru_721530.normal.x; - v4 = ((pParty->vPosition.x - stru_721530.normal.x) * stru_721530.direction.y - - (pParty->vPosition.y - stru_721530.normal.y) * stru_721530.direction.x) >> 16; - v10 = pParty->vPosition.y - stru_721530.normal.y; - result = abs(((pParty->vPosition.x - stru_721530.normal.x) * stru_721530.direction.y - - (pParty->vPosition.y - stru_721530.normal.y) * stru_721530.direction.x) >> 16); - if (result <= stru_721530.prolly_normal_d + (2 * pParty->field_14_radius)) - { - result = v10 * stru_721530.direction.y; - v5 = (v10 * stru_721530.direction.y + v11 * stru_721530.direction.x) >> 16; - if (v5 > 0) - { - v6 = fixpoint_mul(stru_721530.direction.z, v5) + stru_721530.normal.z; - result = pParty->vPosition.z; - if (v6 >= pParty->vPosition.z) - { - result = pParty->uPartyHeight + pParty->vPosition.z; - if (v6 <= (signed int)(pParty->uPartyHeight + pParty->vPosition.z) || a1) - { - result = integer_sqrt(v3 * v3 - v4 * v4); - v7 = v5 - integer_sqrt(v3 * v3 - v4 * v4); - if (v7 < 0) - v7 = 0; - if (v7 < stru_721530.field_7C) - { - stru_721530.field_7C = v7; - stru_721530.uFaceID = 4; - } - } - } - } - } - } - return result; -} - -//----- (0046E0B2) -------------------------------------------------------- -void _46E0B2_collide_against_decorations() -{ - BLVSector *sector; // ebp@1 - LevelDecoration *decor; // edi@2 - DecorationDesc *decor_desc; // esi@3 - int v8; // ebx@10 - int v9; // esi@11 - int v11; // eax@12 - int v12; // esi@14 - unsigned int v13; // eax@17 - signed int i; // [sp+4h] [bp-14h]@1 - int v15; // [sp+8h] [bp-10h]@10 - int v16; // [sp+Ch] [bp-Ch]@10 - int v17; // [sp+10h] [bp-8h]@10 - - sector = &pIndoor->pSectors[stru_721530.uSectorID]; - for (i = 0; i < sector->uNumDecorations; ++i) - { - decor = &pLevelDecorations[sector->pDecorationIDs[i]]; - if (!(decor->uFlags & LEVEL_DECORATION_INVISIBLE)) - { - decor_desc = &pDecorationList->pDecorations[decor->uDecorationDescID]; - if (!decor_desc->CanMoveThrough()) - { - if (stru_721530.sMaxX <= decor->vPosition.x + decor_desc->uRadius && stru_721530.sMinX >= decor->vPosition.x - decor_desc->uRadius - && stru_721530.sMaxY <= decor->vPosition.y + decor_desc->uRadius && stru_721530.sMinY >= decor->vPosition.y - decor_desc->uRadius - && stru_721530.sMaxZ <= decor->vPosition.z + decor_desc->uDecorationHeight && stru_721530.sMinZ >= decor->vPosition.z) - { - v16 = decor->vPosition.x - stru_721530.normal.x; - v15 = decor->vPosition.y - stru_721530.normal.y; - v8 = stru_721530.prolly_normal_d + decor_desc->uRadius; - v17 = ((decor->vPosition.x - stru_721530.normal.x) * stru_721530.direction.y - - (decor->vPosition.y - stru_721530.normal.y) * stru_721530.direction.x) >> 16; - if (abs(v17) <= stru_721530.prolly_normal_d + decor_desc->uRadius) - { - v9 = (v16 * stru_721530.direction.x + v15 * stru_721530.direction.y) >> 16; - if (v9 > 0) - { - v11 = stru_721530.normal.z + fixpoint_mul(stru_721530.direction.z, v9); - if (v11 >= decor->vPosition.z) - { - if (v11 <= decor_desc->uDecorationHeight + decor->vPosition.z) - { - v12 = v9 - integer_sqrt(v8 * v8 - v17 * v17); - if (v12 < 0) - v12 = 0; - if (v12 < stru_721530.field_7C) - { - stru_721530.field_7C = v12; - v13 = 8 * sector->pDecorationIDs[i]; - LOBYTE(v13) = v13 | 5; - stru_721530.uFaceID = v13; - } - } - } - } - } - } - } - } - } -} - -//----- (0046F04E) -------------------------------------------------------- -int _46F04E_collide_against_portals() -{ - unsigned int v1; // eax@1 - BLVFace *face; // eax@3 - int v4; // ecx@9 - int v5; // edx@9 - signed int result; // eax@21 - unsigned int v10; // [sp+8h] [bp-Ch]@1 - int a3; // [sp+Ch] [bp-8h]@13 - int v12; // [sp+10h] [bp-4h]@15 - - v1 = 0xFFFFFFu; - v10 = 0xFFFFFFu; - for (uint i = 0; i < pIndoor->pSectors[stru_721530.uSectorID].uNumPortals; ++i) - { - if (pIndoor->pSectors[stru_721530.uSectorID].pPortals[i] != stru_721530.field_80) - { - face = &pIndoor->pFaces[pIndoor->pSectors[stru_721530.uSectorID].pPortals[i]]; - if (stru_721530.sMaxX <= face->pBounding.x2 && stru_721530.sMinX >= face->pBounding.x1 - && stru_721530.sMaxY <= face->pBounding.y2 && stru_721530.sMinY >= face->pBounding.y1 - && stru_721530.sMaxZ <= face->pBounding.z2 && stru_721530.sMinZ >= face->pBounding.z1) - { - v4 = (stru_721530.normal.x * face->pFacePlane_old.vNormal.x + face->pFacePlane_old.dist - + stru_721530.normal.y * face->pFacePlane_old.vNormal.y - + stru_721530.normal.z * face->pFacePlane_old.vNormal.z) >> 16; - v5 = (stru_721530.normal2.z * face->pFacePlane_old.vNormal.z + face->pFacePlane_old.dist - + stru_721530.normal2.x * face->pFacePlane_old.vNormal.x - + stru_721530.normal2.y * face->pFacePlane_old.vNormal.y) >> 16; - if ((v4 < stru_721530.prolly_normal_d || v5 < stru_721530.prolly_normal_d) - && (v4 > -stru_721530.prolly_normal_d || v5 > -stru_721530.prolly_normal_d) - && (a3 = stru_721530.field_6C, sub_475D85(&stru_721530.normal, &stru_721530.direction, &a3, face)) - && a3 < (signed int)v10) - { - v10 = a3; - v12 = pIndoor->pSectors[stru_721530.uSectorID].pPortals[i]; - } - } - } - } - v1 = v10; - if (stru_721530.field_7C >= (signed int)v1 && (signed int)v1 <= stru_721530.field_6C) - { - stru_721530.field_80 = v12; - if (pIndoor->pFaces[v12].uSectorID == stru_721530.uSectorID) - stru_721530.uSectorID = pIndoor->pFaces[v12].uBackSectorID; - else - stru_721530.uSectorID = pIndoor->pFaces[v12].uSectorID; - stru_721530.field_7C = 268435455; - result = 0; - } - else - result = 1; - return result; -} - -//----- (0046DEF2) -------------------------------------------------------- -unsigned int __fastcall sub_46DEF2(signed int a2, unsigned int uLayingItemID) -{ - unsigned int result; // eax@1 - - result = uLayingItemID; - if (pObjectList->pObjects[pSpriteObjects[uLayingItemID].uObjectDescID].uFlags & 0x10) - result = _46BFFA_check_object_intercept(uLayingItemID, a2); - return result; -} - -//----- (0047253E) -------------------------------------------------------- -void UpdateObjects() -{ - ObjectDesc *object; // eax@5 - int v5; // ecx@6 - signed int v7; // eax@9 - signed int v11; // eax@17 - int v12; // edi@27 - int v18; // [sp+4h] [bp-10h]@27 - int v19; // [sp+8h] [bp-Ch]@27 - - for (uint i = 0; i < uNumSpriteObjects; ++i) - { - if (pSpriteObjects[i].uAttributes & OBJECT_40) - pSpriteObjects[i].uAttributes &= ~OBJECT_40; - else - { - object = &pObjectList->pObjects[pSpriteObjects[i].uObjectDescID]; - if (pSpriteObjects[i].AttachedToActor()) - { - v5 = PID_ID(pSpriteObjects[i].spell_target_pid); - pSpriteObjects[i].vPosition.x = pActors[v5].vPosition.x; - pSpriteObjects[i].vPosition.y = pActors[v5].vPosition.y; - pSpriteObjects[i].vPosition.z = pActors[v5].vPosition.z + pActors[v5].uActorHeight; - if (!pSpriteObjects[i].uObjectDescID) - continue; - pSpriteObjects[i].uSpriteFrameID += pEventTimer->uTimeElapsed; - if (!(object->uFlags & OBJECT_DESC_TEMPORARY)) - continue; - if (pSpriteObjects[i].uSpriteFrameID >= 0) - { - v7 = object->uLifetime; - if (pSpriteObjects[i].uAttributes & ITEM_BROKEN) - v7 = pSpriteObjects[i].field_20; - if (pSpriteObjects[i].uSpriteFrameID < v7) - continue; - } - SpriteObject::OnInteraction(i); - continue; - } - if (pSpriteObjects[i].uObjectDescID) - { - pSpriteObjects[i].uSpriteFrameID += pEventTimer->uTimeElapsed; - if (object->uFlags & OBJECT_DESC_TEMPORARY) - { - if (pSpriteObjects[i].uSpriteFrameID < 0) - { - SpriteObject::OnInteraction(i); - continue; - } - v11 = object->uLifetime; - if (pSpriteObjects[i].uAttributes & ITEM_BROKEN) - v11 = pSpriteObjects[i].field_20; - } - if (!(object->uFlags & OBJECT_DESC_TEMPORARY) || pSpriteObjects[i].uSpriteFrameID < v11) - { - if (uCurrentlyLoadedLevelType == LEVEL_Indoor) - SpriteObject::UpdateObject_fn0_BLV(i); - else - SpriteObject::UpdateObject_fn0_ODM(i); - if (pParty->bTurnBasedModeOn != 1 || !(pSpriteObjects[i].uSectorID & 4)) - continue; - v12 = abs(pParty->vPosition.x - pSpriteObjects[i].vPosition.x); - v18 = abs(pParty->vPosition.y - pSpriteObjects[i].vPosition.y); - v19 = abs(pParty->vPosition.z - pSpriteObjects[i].vPosition.z); - if (int_get_vector_length(v12, v18, v19) <= 5120) - continue; - SpriteObject::OnInteraction(i); - continue; - } - if (!(object->uFlags & OBJECT_DESC_INTERACTABLE)) - { - SpriteObject::OnInteraction(i); - continue; - } - _46BFFA_check_object_intercept(i, PID(OBJECT_Item, i)); - } - } - } -} - -//----- (0047531C) -------------------------------------------------------- -bool sub_47531C(int a1, int *a2, int pos_x, int pos_y, int pos_z, int dir_x, int dir_y, int dir_z, BLVFace *face, int a10) -{ - int v11; // ST1C_4@3 - int v12; // edi@3 - int v13; // esi@3 - int v14; // edi@4 - signed __int64 v15; // qtt@6 - //__int16 v16; // si@7 - int a7a; // [sp+30h] [bp+18h]@7 - int a9b; // [sp+38h] [bp+20h]@3 - int a9a; // [sp+38h] [bp+20h]@3 - int a10b; // [sp+3Ch] [bp+24h]@3 - signed int a10a; // [sp+3Ch] [bp+24h]@4 - int a10c; // [sp+3Ch] [bp+24h]@5 - - if (a10 && face->Ethereal()) - return 0; - v11 = fixpoint_mul(dir_x, face->pFacePlane_old.vNormal.x); - a10b = fixpoint_mul(dir_y, face->pFacePlane_old.vNormal.y); - a9b = fixpoint_mul(dir_z, face->pFacePlane_old.vNormal.z); - v12 = v11 + a9b + a10b; - a9a = v11 + a9b + a10b; - v13 = (a1 << 16) - - pos_x * face->pFacePlane_old.vNormal.x - - pos_y * face->pFacePlane_old.vNormal.y - - pos_z * face->pFacePlane_old.vNormal.z - - face->pFacePlane_old.dist; - if (abs((a1 << 16) - - pos_x * face->pFacePlane_old.vNormal.x - - pos_y * face->pFacePlane_old.vNormal.y - - pos_z * face->pFacePlane_old.vNormal.z - face->pFacePlane_old.dist) >= a1 << 16) - { - a10c = abs(v13) >> 14; - if (a10c > abs(v12)) - return 0; - LODWORD(v15) = v13 << 16; - HIDWORD(v15) = v13 >> 16; - v14 = a1; - a10a = v15 / a9a; - } - else - { - a10a = 0; - v14 = abs(v13) >> 16; - } - //v16 = pos_y + ((unsigned int)fixpoint_mul(a10a, dir_y) >> 16); - LOWORD(a7a) = (short)pos_x + ((unsigned int)fixpoint_mul(a10a, dir_x) >> 16) - fixpoint_mul(v14, face->pFacePlane_old.vNormal.x); - HIWORD(a7a) = pos_y + ((unsigned int)fixpoint_mul(a10a, dir_y) >> 16) - fixpoint_mul(v14, face->pFacePlane_old.vNormal.y); - if (!sub_475665(face, a7a, (short)pos_z + ((unsigned int)fixpoint_mul(a10a, dir_z) >> 16) - fixpoint_mul(v14, face->pFacePlane_old.vNormal.z))) - return 0; - *a2 = a10a >> 16; - if (a10a >> 16 < 0) - *a2 = 0; - return 1; -} - - -//----- (004754BF) -------------------------------------------------------- -bool sub_4754BF(int a1, int *a2, int X, int Y, int Z, int dir_x, int dir_y, int dir_z, BLVFace *face, int a10, int a11) -{ - int v12; // ST1C_4@3 - int v13; // edi@3 - int v14; // esi@3 - int v15; // edi@4 - signed __int64 v16; // qtt@6 - //__int16 v17; // si@7 - int a7a; // [sp+30h] [bp+18h]@7 - int a1b; // [sp+38h] [bp+20h]@3 - int a1a; // [sp+38h] [bp+20h]@3 - int a11b; // [sp+40h] [bp+28h]@3 - signed int a11a; // [sp+40h] [bp+28h]@4 - int a11c; // [sp+40h] [bp+28h]@5 - - if (a11 && face->Ethereal()) - return false; - v12 = fixpoint_mul(dir_x, face->pFacePlane_old.vNormal.x); - a11b = fixpoint_mul(dir_y, face->pFacePlane_old.vNormal.y); - a1b = fixpoint_mul(dir_z, face->pFacePlane_old.vNormal.z); - v13 = v12 + a1b + a11b; - a1a = v12 + a1b + a11b; - v14 = (a1 << 16) - - X * face->pFacePlane_old.vNormal.x - - Y * face->pFacePlane_old.vNormal.y - - Z * face->pFacePlane_old.vNormal.z - - face->pFacePlane_old.dist; - if (abs((a1 << 16) - - X * face->pFacePlane_old.vNormal.x - - Y * face->pFacePlane_old.vNormal.y - - Z * face->pFacePlane_old.vNormal.z - face->pFacePlane_old.dist) >= a1 << 16) - { - a11c = abs(v14) >> 14; - if (a11c > abs(v13)) - return false; - LODWORD(v16) = v14 << 16; - HIDWORD(v16) = v14 >> 16; - v15 = a1; - a11a = v16 / a1a; - } - else - { - a11a = 0; - v15 = abs(v14) >> 16; - } - //v17 = Y + ((unsigned int)fixpoint_mul(a11a, dir_y) >> 16); - LOWORD(a7a) = (short)X + ((unsigned int)fixpoint_mul(a11a, dir_x) >> 16) - fixpoint_mul(v15, face->pFacePlane_old.vNormal.x); - HIWORD(a7a) = Y + ((unsigned int)fixpoint_mul(a11a, dir_y) >> 16) - fixpoint_mul(v15, face->pFacePlane_old.vNormal.y); - if (!sub_4759C9(face, a10, a7a, (short)Z + ((unsigned int)fixpoint_mul(a11a, dir_z) >> 16) - fixpoint_mul(v15, face->pFacePlane_old.vNormal.z))) - return false; - *a2 = a11a >> 16; - if (a11a >> 16 < 0) - *a2 = 0; - return true; -} - -//----- (00475665) -------------------------------------------------------- -int sub_475665(BLVFace *face, int a2, __int16 a3) -{ - bool v16; // edi@14 - signed int v20; // ebx@18 - int v21; // edi@20 - signed int v22; // ST14_4@22 - signed __int64 v23; // qtt@22 - signed int result; // eax@25 - int v25; // [sp+14h] [bp-10h]@14 - int v26; // [sp+1Ch] [bp-8h]@2 - signed int v27; // [sp+20h] [bp-4h]@2 - signed int v28; // [sp+30h] [bp+Ch]@2 - signed int v29; // [sp+30h] [bp+Ch]@7 - signed int v30; // [sp+30h] [bp+Ch]@11 - signed int v31; // [sp+30h] [bp+Ch]@14 - - if (face->uAttributes & FACE_XY_PLANE) - { - v26 = (signed __int16)a2; - v27 = SHIWORD(a2); - if (face->uNumVertices) - { - for (v28 = 0; v28 < face->uNumVertices; v28++) - { - word_720C10_intercepts_xs[2 * v28] = face->pXInterceptDisplacements[v28] + pIndoor->pVertices[face->pVertexIDs[v28]].x; - word_720B40_intercepts_zs[2 * v28] = face->pYInterceptDisplacements[v28] + pIndoor->pVertices[face->pVertexIDs[v28]].y; - word_720C10_intercepts_xs[2 * v28 + 1] = face->pXInterceptDisplacements[v28 + 1] + pIndoor->pVertices[face->pVertexIDs[v28 + 1]].x; - word_720B40_intercepts_zs[2 * v28 + 1] = face->pYInterceptDisplacements[v28 + 1] + pIndoor->pVertices[face->pVertexIDs[v28 + 1]].y; - } - } - } - else - { - if (face->uAttributes & FACE_XZ_PLANE) - { - v26 = (signed __int16)a2; - v27 = a3; - if (face->uNumVertices) - { - for (v29 = 0; v29 < face->uNumVertices; v29++) - { - word_720C10_intercepts_xs[2 * v29] = face->pXInterceptDisplacements[v29] + pIndoor->pVertices[face->pVertexIDs[v29]].x; - word_720B40_intercepts_zs[2 * v29] = face->pZInterceptDisplacements[v29] + pIndoor->pVertices[face->pVertexIDs[v29]].z; - word_720C10_intercepts_xs[2 * v29 + 1] = face->pXInterceptDisplacements[v29 + 1] + pIndoor->pVertices[face->pVertexIDs[v29 + 1]].x; - word_720B40_intercepts_zs[2 * v29 + 1] = face->pZInterceptDisplacements[v29 + 1] + pIndoor->pVertices[face->pVertexIDs[v29 + 1]].z; - } - } - } - else - { - v26 = SHIWORD(a2); - v27 = a3; - if (face->uNumVertices) - { - for (v30 = 0; v30 < face->uNumVertices; v30++) - { - word_720C10_intercepts_xs[2 * v30] = face->pYInterceptDisplacements[v30] + pIndoor->pVertices[face->pVertexIDs[v30]].y; - word_720B40_intercepts_zs[2 * v30] = face->pZInterceptDisplacements[v30] + pIndoor->pVertices[face->pVertexIDs[v30]].z; - word_720C10_intercepts_xs[2 * v30 + 1] = face->pYInterceptDisplacements[v30 + 1] + pIndoor->pVertices[face->pVertexIDs[v30 + 1]].y; - word_720B40_intercepts_zs[2 * v30 + 1] = face->pZInterceptDisplacements[v30 + 1] + pIndoor->pVertices[face->pVertexIDs[v30 + 1]].z; - } - } - } - } - v31 = 0; - word_720C10_intercepts_xs[2 * face->uNumVertices] = word_720C10_intercepts_xs[0]; - word_720B40_intercepts_zs[2 * face->uNumVertices] = word_720B40_intercepts_zs[0]; - v16 = word_720B40_intercepts_zs[0] >= v27; - if (2 * face->uNumVertices <= 0) - return 0; - for (v25 = 0; v25 < 2 * face->uNumVertices; ++v25) - { - if (v31 >= 2) - break; - if (v16 ^ (word_720B40_intercepts_zs[v25 + 1] >= v27)) - { - if (word_720C10_intercepts_xs[v25 + 1] >= v26) - v20 = 0; - else - v20 = 2; - v21 = v20 | (word_720C10_intercepts_xs[v25] < v26); - if (v21 != 3) - { - v22 = word_720C10_intercepts_xs[v25 + 1] - word_720C10_intercepts_xs[v25]; - LODWORD(v23) = v22 << 16; - HIDWORD(v23) = v22 >> 16; - if (!v21 - || (word_720C10_intercepts_xs[v25] + ((signed int)(((unsigned __int64)(v23 - / (word_720B40_intercepts_zs[v25 + 1] - word_720B40_intercepts_zs[v25]) - * ((v27 - (signed int)word_720B40_intercepts_zs[v25]) << 16)) >> 16) - + 32768) >> 16) >= v26)) - ++v31; - } - } - v16 = word_720B40_intercepts_zs[v25 + 1] >= v27; - } - result = 1; - if (v31 != 1) - result = 0; - return result; -} - -//----- (004759C9) -------------------------------------------------------- -bool __fastcall sub_4759C9(BLVFace *face, int a2, int a3, __int16 a4) -{ - bool v12; // edi@14 - signed int v16; // ebx@18 - int v17; // edi@20 - signed int v18; // ST14_4@22 - signed __int64 v19; // qtt@22 - bool result; // eax@25 - int v21; // [sp+14h] [bp-10h]@14 - signed int v22; // [sp+18h] [bp-Ch]@1 - int v23; // [sp+1Ch] [bp-8h]@2 - signed int v24; // [sp+20h] [bp-4h]@2 - signed int a4d; // [sp+30h] [bp+Ch]@14 - - if (face->uAttributes & FACE_XY_PLANE) - { - v23 = (signed __int16)a3; - v24 = SHIWORD(a3); - if (face->uNumVertices) - { - for (v22 = 0; v22 < face->uNumVertices; ++v22) - { - word_720A70_intercepts_xs_plus_xs[2 * v22] = face->pXInterceptDisplacements[v22] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22]].x); - word_7209A0_intercepts_ys_plus_ys[2 * v22] = face->pYInterceptDisplacements[v22] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22]].y); - word_720A70_intercepts_xs_plus_xs[2 * v22 + 1] = face->pXInterceptDisplacements[v22 + 1] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22 + 1]].x); - word_7209A0_intercepts_ys_plus_ys[2 * v22 + 1] = face->pYInterceptDisplacements[v22 + 1] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22 + 1]].y); - } - } - } - else - { - if (face->uAttributes & FACE_XZ_PLANE) - { - v23 = (signed __int16)a3; - v24 = a4; - if (face->uNumVertices) - { - for (v22 = 0; v22 < face->uNumVertices; ++v22) - { - word_720A70_intercepts_xs_plus_xs[2 * v22] = face->pXInterceptDisplacements[v22] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22]].x); - word_7209A0_intercepts_ys_plus_ys[2 * v22] = face->pZInterceptDisplacements[v22] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22]].z); - word_720A70_intercepts_xs_plus_xs[2 * v22 + 1] = face->pXInterceptDisplacements[v22 + 1] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22 + 1]].x); - word_7209A0_intercepts_ys_plus_ys[2 * v22 + 1] = face->pZInterceptDisplacements[v22 + 1] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22 + 1]].z); - } - } - } - else - { - v23 = SHIWORD(a3); - v24 = a4; - if (face->uNumVertices) - { - for (v22 = 0; v22 < face->uNumVertices; ++v22) - { - word_720A70_intercepts_xs_plus_xs[2 * v22] = face->pYInterceptDisplacements[v22] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22]].y); - word_7209A0_intercepts_ys_plus_ys[2 * v22] = face->pZInterceptDisplacements[v22] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22]].z); - word_720A70_intercepts_xs_plus_xs[2 * v22 + 1] = face->pYInterceptDisplacements[v22 + 1] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22 + 1]].y); - word_7209A0_intercepts_ys_plus_ys[2 * v22 + 1] = face->pZInterceptDisplacements[v22 + 1] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22 + 1]].z); - } - } - } - } - a4d = 0; - word_720A70_intercepts_xs_plus_xs[2 * face->uNumVertices] = word_720A70_intercepts_xs_plus_xs[0]; - word_7209A0_intercepts_ys_plus_ys[2 * face->uNumVertices] = word_7209A0_intercepts_ys_plus_ys[0]; - v12 = word_7209A0_intercepts_ys_plus_ys[0] >= v24; - if (2 * face->uNumVertices <= 0) - return 0; - for (v21 = 0; v21 < 2 * face->uNumVertices; ++v21) - { - if (a4d >= 2) - break; - if (v12 ^ (word_7209A0_intercepts_ys_plus_ys[v21 + 1] >= v24)) - { - if (word_720A70_intercepts_xs_plus_xs[v21 + 1] >= v23) - v16 = 0; - else - v16 = 2; - v17 = v16 | (word_720A70_intercepts_xs_plus_xs[v21] < v23); - if (v17 != 3) - { - v18 = word_720A70_intercepts_xs_plus_xs[v21 + 1] - word_720A70_intercepts_xs_plus_xs[v21]; - LODWORD(v19) = v18 << 16; - HIDWORD(v19) = v18 >> 16; - if (!v17 - || (word_720A70_intercepts_xs_plus_xs[v21] + ((signed int)(((unsigned __int64)(v19 - / (word_7209A0_intercepts_ys_plus_ys[v21 + 1] - word_7209A0_intercepts_ys_plus_ys[v21]) - * ((v24 - (signed int)word_7209A0_intercepts_ys_plus_ys[v21]) << 16)) >> 16) - + 0x8000) >> 16) >= v23)) - ++a4d; - } - } - v12 = word_7209A0_intercepts_ys_plus_ys[v21 + 1] >= v24; - } - result = 1; - if (a4d != 1) - result = 0; - return result; -} - -//----- (00475D85) -------------------------------------------------------- -bool __fastcall sub_475D85(Vec3_int_ *a1, Vec3_int_ *a2, int *a3, BLVFace *a4) -{ - BLVFace *v4; // ebx@1 - int v5; // ST24_4@2 - int v6; // ST28_4@2 - int v7; // edi@2 - int v8; // eax@5 - signed int v9; // esi@5 - signed __int64 v10; // qtt@10 - Vec3_int_ *v11; // esi@11 - int v12; // ST14_4@11 - Vec3_int_ *v14; // [sp+Ch] [bp-18h]@1 - Vec3_int_ *v15; // [sp+14h] [bp-10h]@1 - // int v16; // [sp+18h] [bp-Ch]@2 - int v17; // [sp+20h] [bp-4h]@10 - int a4b; // [sp+30h] [bp+Ch]@2 - int a4c; // [sp+30h] [bp+Ch]@9 - signed int a4a; // [sp+30h] [bp+Ch]@10 - - v4 = a4; - v15 = a2; - v14 = a1; - v5 = fixpoint_mul(a2->x, a4->pFacePlane_old.vNormal.x); - a4b = fixpoint_mul(a2->y, a4->pFacePlane_old.vNormal.y); - v6 = fixpoint_mul(a2->z, v4->pFacePlane_old.vNormal.z); - v7 = v5 + v6 + a4b; - //(v16 = v5 + v6 + a4b) == 0; - if (a4->uAttributes & FACE_ETHEREAL || !v7 || v7 > 0 && !v4->Portal()) - return 0; - v8 = v4->pFacePlane_old.vNormal.z * a1->z; - v9 = -(v4->pFacePlane_old.dist + v8 + a1->y * v4->pFacePlane_old.vNormal.y + a1->x * v4->pFacePlane_old.vNormal.x); - if (v7 <= 0) - { - if (v4->pFacePlane_old.dist + v8 + a1->y * v4->pFacePlane_old.vNormal.y + a1->x * v4->pFacePlane_old.vNormal.x < 0) - return 0; - } - else - { - if (v9 < 0) - return 0; - } - a4c = abs(-(v4->pFacePlane_old.dist + v8 + a1->y * v4->pFacePlane_old.vNormal.y + a1->x * v4->pFacePlane_old.vNormal.x)) >> 14; - v11 = v14; - LODWORD(v10) = v9 << 16; - HIDWORD(v10) = v9 >> 16; - a4a = v10 / v7; - v17 = v10 / v7; - LOWORD(v12) = LOWORD(v14->x) + (((unsigned int)fixpoint_mul(v17, v15->x) + 0x8000) >> 16); - HIWORD(v12) = LOWORD(v11->y) + (((unsigned int)fixpoint_mul(v17, v15->y) + 0x8000) >> 16); - if (a4c > abs(v7) || (v17 > *a3 << 16) || !sub_475665(v4, v12, LOWORD(v11->z) + (((unsigned int)fixpoint_mul(v17, v15->z) + 0x8000) >> 16))) - return 0; - *a3 = a4a >> 16; - return 1; -} - -//----- (00475F30) -------------------------------------------------------- -bool __fastcall sub_475F30(int *a1, BLVFace *a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9) -{ - int v10; // ST20_4@2 - int v11; // ST28_4@2 - int v12; // ST24_4@2 - int v13; // zf@2 - int v14; // edi@2 - signed int v16; // esi@5 - int v17; // ST20_4@9 - signed __int64 v18; // qtt@10 - int v19; // ST14_4@11 - int v22; // [sp+1Ch] [bp-8h]@2 - int v23; // [sp+1Ch] [bp-8h]@10 - signed int v24; // [sp+20h] [bp-4h]@10 - - v10 = fixpoint_mul(a6, a2->pFacePlane_old.vNormal.x); - v11 = fixpoint_mul(a7, a2->pFacePlane_old.vNormal.y); - v12 = fixpoint_mul(a8, a2->pFacePlane_old.vNormal.z); - v13 = v10 + v12 + v11; - v14 = v10 + v12 + v11; - v22 = v10 + v12 + v11; - if (a2->Ethereal() || !v13 || v14 > 0 && !a2->Portal()) - return 0; - v16 = -(a2->pFacePlane_old.dist + a4 * a2->pFacePlane_old.vNormal.y + a3 * a2->pFacePlane_old.vNormal.x + a5 * a2->pFacePlane_old.vNormal.z); - if (v14 <= 0) - { - if (a2->pFacePlane_old.dist + a4 * a2->pFacePlane_old.vNormal.y + a3 * a2->pFacePlane_old.vNormal.x + a5 * a2->pFacePlane_old.vNormal.z < 0) - return 0; - } - else - { - if (v16 < 0) - return 0; - } - v17 = abs(-(a2->pFacePlane_old.dist + a4 * a2->pFacePlane_old.vNormal.y + a3 * a2->pFacePlane_old.vNormal.x + a5 * a2->pFacePlane_old.vNormal.z)) >> 14; - LODWORD(v18) = v16 << 16; - HIDWORD(v18) = v16 >> 16; - v24 = v18 / v22; - v23 = v18 / v22; - LOWORD(v19) = a3 + (((unsigned int)fixpoint_mul(v23, a6) + 0x8000) >> 16); - HIWORD(v19) = a4 + (((unsigned int)fixpoint_mul(v23, a7) + 0x8000) >> 16); - if (v17 > abs(v14) || v23 > *a1 << 16 || !sub_4759C9(a2, a9, v19, a5 + (((unsigned int)fixpoint_mul(v23, a8) + 0x8000) >> 16))) - return 0; - *a1 = v24 >> 16; - return 1; -} - -//----- (00479089) -------------------------------------------------------- -bool __fastcall IsBModelVisible(unsigned int uModelID, int *reachable) -{ - int v3; // edi@1 - int v4; // ebx@1 - int v9; // eax@3 - signed int v11; // esi@6 - int v12; // esi@8 - bool result; // eax@9 - int v17; // [sp+1Ch] [bp-10h]@1 - int v19; // [sp+20h] [bp-Ch]@3 - int angle; // [sp+24h] [bp-8h]@1 - - angle = (signed int)(pODMRenderParams->uCameraFovInDegrees << 11) / 360 / 2; - v3 = pOutdoor->pBModels[uModelID].vBoundingCenter.x - pGame->pIndoorCameraD3D->vPartyPos.x; - v4 = pOutdoor->pBModels[uModelID].vBoundingCenter.y - pGame->pIndoorCameraD3D->vPartyPos.y; - stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationX); - v17 = v3 * stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationY) + v4 * stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationY); - if (pGame->pIndoorCameraD3D->sRotationX) - v17 = fixpoint_mul(v17, stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationX)); - v19 = v4 * stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationY) - v3 * stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationY); - v9 = int_get_vector_length(abs(v3), abs(v4), 0); - //v10 = v14 * 188; - //v22 = v9; - *reachable = false; - if (v9 < pOutdoor->pBModels[uModelID].sBoundingRadius + 256) - *reachable = true; - if (v19 >= 0) - v11 = fixpoint_mul(stru_5C6E00->Sin(angle), v17) - fixpoint_mul(stru_5C6E00->Cos(angle), v19); - else - v11 = fixpoint_mul(stru_5C6E00->Cos(angle), v19) + fixpoint_mul(stru_5C6E00->Sin(angle), v17); - v12 = v11 >> 16; - if (v9 <= pODMRenderParams->shading_dist_mist + 2048) - { - //if ( abs(v12) > *(int *)((char *)&pOutdoor->pBModels->sBoundingRadius + v10) + 512 ) - if (abs(v12) > pOutdoor->pBModels[uModelID].sBoundingRadius + 512) - { - result = v12 < 0; - LOBYTE(result) = v12 >= 0; - return result; - } - else - return true; - } - return false; -} - -//----- (00479295) -------------------------------------------------------- -int Polygon::_479295() -{ - int v3; // ecx@4 - int v4; // eax@4 - int v5; // edx@4 - // int v6; // ST14_4@5 - Vec3_int_ thisa; // [sp+Ch] [bp-10h]@8 - int v11; // [sp+18h] [bp-4h]@4 - - if (!this->pODMFace->pFacePlane.vNormal.z) - { - v3 = this->pODMFace->pFacePlane.vNormal.x; - v4 = -this->pODMFace->pFacePlane.vNormal.y; - v5 = 0; - v11 = 65536; - } - else if ((this->pODMFace->pFacePlane.vNormal.x || this->pODMFace->pFacePlane.vNormal.y) - && abs(this->pODMFace->pFacePlane.vNormal.z) < 59082) - { - thisa.x = -this->pODMFace->pFacePlane.vNormal.y; - thisa.y = this->pODMFace->pFacePlane.vNormal.x; - thisa.z = 0; - thisa.Normalize_float(); - v4 = thisa.x; - v3 = thisa.y; - v5 = 0; - v11 = 65536; - } - else - { - v3 = 0; - v4 = 65536; - v11 = 0; - v5 = -65536; - } - sTextureDeltaU = this->pODMFace->sTextureDeltaU; - sTextureDeltaV = this->pODMFace->sTextureDeltaV; - ptr_38->_48616B_frustum_odm(v4, v3, 0, 0, v5, v11); - return 1; -} - - -unsigned short *LoadTgaTexture(const wchar_t *filename, int *out_width = nullptr, int *out_height = nullptr) -{ -#pragma pack(push, 1) - struct TGAHeader - { - unsigned char tgaSkip; - unsigned char colourmaptype; // type of colour map 0=none, 1=has palette - unsigned char tgaType; // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed - - short colourmapstart; // first colour map entry in palette - short colourmaplength; // number of colours in palette - char colourmapbits; // number of bits per palette entry 15,16,24,32 - - //unsigned char tgaDontCare2[9]; - short xstart; // image x origin - short ystart; // image y origin - - unsigned short tgaWidth; - unsigned short tgaHeight; - unsigned char tgaBPP; - - char descriptor; // image descriptor bits: 00vhaaaa - // h horizontal flip - // v vertical flip - // a alpha bits - }; -#pragma pack(pop) - - if (out_width) - *out_width = 0; - if (out_height) - *out_height = 0; - - DWORD w; - void* file = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr); - if (file == INVALID_HANDLE_VALUE) - return nullptr; - - TGAHeader header; - ReadFile(file, &header, sizeof(header), &w, nullptr); - SetFilePointer(file, header.tgaSkip, nullptr, FILE_CURRENT); - - if (header.tgaBPP != 24 || header.tgaType != 2) - { - CloseHandle(file); - return nullptr; - } - - int imgSize = header.tgaWidth * header.tgaHeight * 3; - unsigned char* pixels = new unsigned char[imgSize]; - ReadFile(file, pixels, imgSize, &w, nullptr); - CloseHandle(file); - - if (w != imgSize) - { - delete[] pixels; - return nullptr; - } - - if (out_width) - *out_width = header.tgaWidth; - if (out_height) - *out_height = header.tgaHeight; - - unsigned short* pixels_16bit = new unsigned short[imgSize / 3]; - for (int i = 0; i < imgSize / 3; ++i) - { - pixels_16bit[i] = (pixels[i * 3] / 8 & 0x1F) | - ((pixels[i * 3 + 1] / 4 & 0x3F) << 5) | - ((pixels[i * 3 + 2] / 8 & 0x1F) << 11); - } - delete[] pixels; - return pixels_16bit; -} - -unsigned short *skybox_xn, *skybox_xp, -*skybox_yn, *skybox_yp, -*skybox_zn, *skybox_zp; -int skybox_width, skybox_height; - -IDirect3DTexture2 *skybox_texture; -IDirectDrawSurface4 *skybox_surface; - -bool Skybox_Initialize(const wchar_t *skybox_name) -{ - wchar_t xn_filename[1024], xp_filename[1024], - yn_filename[1024], yp_filename[1024], - zn_filename[1024], zp_filename[1024]; - swprintf(xn_filename, wcslen(L"%s_xn.tga"), L"%s_xn.tga", skybox_name); swprintf(xp_filename, wcslen(L"%s_xp.tga"), L"%s_xp.tga", skybox_name); - swprintf(yn_filename, wcslen(L"%s_yn.tga"), L"%s_yn.tga", skybox_name); swprintf(yp_filename, wcslen(L"%s_yp.tga"), L"%s_yp.tga", skybox_name); - swprintf(zn_filename, wcslen(L"%s_zn.tga"), L"%s_zn.tga", skybox_name); swprintf(zp_filename, wcslen(L"%s_zp.tga"), L"%s_zp.tga", skybox_name); - - int xn_width, xn_height; - skybox_xn = LoadTgaTexture(xn_filename, &xn_width, &xn_height); - if (!skybox_xn) - return false; - - int xp_width, xp_height; - skybox_xp = LoadTgaTexture(xp_filename, &xp_width, &xp_height); - if (!skybox_xp || xp_width != xn_width || xp_height != xn_height) - { - delete[] skybox_xn; - delete[] skybox_xp; - return false; - } - - int yn_width, yn_height; - skybox_yn = LoadTgaTexture(yn_filename, &yn_width, &yn_height); - if (!skybox_yn || yn_width != xn_width || yn_height != xn_height) - { - delete[] skybox_xn; - delete[] skybox_xp; - delete[] skybox_yn; - return false; - } - - int yp_width, yp_height; - skybox_yp = LoadTgaTexture(yp_filename, &yp_width, &yp_height); - if (!skybox_yp || yp_width != xn_width || yp_height != xn_height) - { - delete[] skybox_xn; - delete[] skybox_xp; - delete[] skybox_yn; - delete[] skybox_yp; - return false; - } - - int zn_width, zn_height; - skybox_zn = LoadTgaTexture(zn_filename, &zn_width, &zn_height); - if (!skybox_zn || zn_width != xn_width || zn_height != xn_height) - { - delete[] skybox_xn; - delete[] skybox_xp; - delete[] skybox_yn; - delete[] skybox_yp; - delete[] skybox_zn; - return false; - } - - int zp_width, zp_height; - skybox_zp = LoadTgaTexture(zp_filename, &zp_width, &zp_height); - if (!skybox_zp || zp_width != xn_width || zp_height != xn_height) - { - delete[] skybox_xn; - delete[] skybox_xp; - delete[] skybox_yn; - delete[] skybox_yp; - delete[] skybox_zn; - delete[] skybox_zp; - return false; - } - - skybox_width = xn_width; - skybox_height = xn_height; - - __debugbreak(); - //if (!pRenderer->pRenderD3D->CreateTexture(skybox_width, skybox_height, &skybox_surface, &skybox_texture, - //false, false, pRenderer->uMinDeviceTextureDim)) - return false; - - return true; -} - -struct vector -{ - float x, y, z; -}; - -struct matrix -{ - float m[4][4]; -}; - -void VectorNormalize(vector *v) -{ - float invmag = 1.0f / sqrtf(v->x * v->x + v->y * v->y + v->z * v->z); - v->x *= invmag; - v->y *= invmag; - v->z *= invmag; -} - -void MatrixRotationAxis(matrix *pout, CONST vector *pv, float angle) -{ - memset(pout, 0, sizeof(matrix)); - pout->m[3][0] = 0; - pout->m[3][1] = 0; - pout->m[3][2] = 0; - pout->m[3][3] = 1; - - vector v; - v.x = pv->x; v.y = pv->y; v.z = pv->z; - VectorNormalize(&v); - - pout->m[0][0] = (1.0f - cos(angle)) * v.x * v.x + cos(angle); - pout->m[1][0] = (1.0f - cos(angle)) * v.x * v.y - sin(angle) * v.z; - pout->m[2][0] = (1.0f - cos(angle)) * v.x * v.z + sin(angle) * v.y; - pout->m[0][1] = (1.0f - cos(angle)) * v.y * v.x + sin(angle) * v.z; - pout->m[1][1] = (1.0f - cos(angle)) * v.y * v.y + cos(angle); - pout->m[2][1] = (1.0f - cos(angle)) * v.y * v.z - sin(angle) * v.x; - pout->m[0][2] = (1.0f - cos(angle)) * v.z * v.x - sin(angle) * v.y; - pout->m[1][2] = (1.0f - cos(angle)) * v.z * v.y + sin(angle) * v.x; - pout->m[2][2] = (1.0f - cos(angle)) * v.z * v.z + cos(angle); -} - -void VectorTransform(const matrix *m, const vector *v, vector *out) -{ - out->x = m->m[0][0] * v->x + m->m[1][0] * v->y + m->m[2][0] * v->z + m->m[3][0]; - out->y = m->m[0][1] * v->x + m->m[1][1] * v->y + m->m[2][1] * v->z + m->m[3][1]; - out->z = m->m[0][2] * v->x + m->m[1][2] * v->y + m->m[2][2] * v->z + m->m[3][2]; -} - -bool DrawSkyD3D_Skybox() -{ - static bool initialized = false, - initialization_failed = false; - if (initialization_failed) - return false; - - static int last_camera_rot_y, - last_camera_rot_x; - if (!initialized) - { - if (!Skybox_Initialize(L"data/skybox/stars")) - { - initialization_failed = true; - return false; - } - initialized = true; - - last_camera_rot_y = pParty->sRotationY + 1; // force update for the first run - last_camera_rot_x = pParty->sRotationX + 1; - } - - /* - r(y) = - cos y 0 sin y 0 - 0 1 0 0 - -sin y 0 cos y 0 - 0 0 0 1 - - x cos y - z sin y - y - x sin y + z cos y - 1 - - - - r(x) = // should be r(right) actually - 1 0 0 0 - 0 cos x -sin x 0 - 0 sin x cos x 0 - 0 0 0 1 - - - x - y cos x + z sin x - -y sin x + z cos x - 1 - - */ - - if (last_camera_rot_y == pParty->sRotationY && - last_camera_rot_x == pParty->sRotationX) - { - draw: - struct RenderVertexD3D3 v[6]; - - v[0].pos.x = pViewport->uScreen_TL_X; - v[0].pos.y = pViewport->uScreen_TL_Y; - v[0].pos.z = 0.99989998; - v[0].rhw = 1; - v[0].diffuse = -1; - v[0].specular = 0; - v[0].texcoord.x = 0; - v[0].texcoord.y = 0; - - v[1].pos.x = pViewport->uScreen_TL_X + pViewport->uScreenWidth; - v[1].pos.y = pViewport->uScreen_TL_Y + pViewport->uScreenHeight; - v[1].pos.z = 0.99989998; - v[1].rhw = 1; - v[1].diffuse = -1; - v[1].specular = 0; - v[1].texcoord.x = (float)pViewport->uScreenWidth / skybox_width; - v[1].texcoord.y = (float)pViewport->uScreenHeight / skybox_height; - - v[2].pos.x = pViewport->uScreen_TL_X + pViewport->uScreenWidth; - v[2].pos.y = pViewport->uScreen_TL_Y; - v[2].pos.z = 0.99989998; - v[2].rhw = 1; - v[2].diffuse = -1; - v[2].specular = 0; - v[2].texcoord.x = (float)pViewport->uScreenWidth / skybox_width; - v[2].texcoord.y = 0; - - memcpy(&v[3], &v[0], sizeof(*v)); - - v[4].pos.x = pViewport->uScreen_TL_X; - v[4].pos.y = pViewport->uScreen_TL_Y + pViewport->uScreenHeight; - v[4].pos.z = 0.99989998; - v[4].rhw = 1; - v[4].diffuse = -1; - v[4].specular = 0; - v[4].texcoord.x = 0; - v[4].texcoord.y = (float)pViewport->uScreenHeight / skybox_height; - - memcpy(&v[5], &v[1], sizeof(*v)); - - __debugbreak(); - /* - pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE); - pRenderer->pRenderD3D->pDevice->SetTexture(0, skybox_texture); - pRenderer->pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, v, 6, D3DDP_DONOTUPDATEEXTENTS | D3DDP_DONOTLIGHT); - */ - return true; - } - - - DDSURFACEDESC2 desc; - desc.dwSize = sizeof(desc); - if (!pRenderer->LockSurface_DDraw4(skybox_surface, &desc, DDLOCK_WAIT | DDLOCK_WRITEONLY)) - return false; - - last_camera_rot_y = pParty->sRotationY; - last_camera_rot_x = pParty->sRotationX; - - float aspect = (float)pViewport->uScreenWidth / (float)pViewport->uScreenHeight; - float fov_x = 3.141592f * (pODMRenderParams->uCameraFovInDegrees + 0) / 360.0f; - float fov_y = fov_x / aspect; - - float ray_dx = fov_x / (float)pViewport->uScreenWidth, - ray_dy = fov_y / (float)pViewport->uScreenHeight; - float party_angle_x = 2 * 3.141592653589 * pParty->sRotationX / 2048.0, - party_angle_y = 2 * 3.141592653589 * pParty->sRotationY / 2048.0; - for (int y = 0; y < pViewport->uScreenHeight; ++y) - for (int x = 0; x < pViewport->uScreenWidth; ++x) - { - float angle_x = party_angle_x - (y - pViewport->uScreenHeight / 2) * ray_dy; - float angle_y = party_angle_y - (x - pViewport->uScreenWidth / 2) * ray_dx; - - float _dir_x_ = 1, - _dir_y_ = 0, - _dir_z_ = 0; - - float dir_x_ = _dir_x_ * cosf(angle_y);// - _dir_z_ * sinf(angle_y); // rotation around y - //float dir_y_ = _dir_y_; - float dir_z_ = _dir_x_ * sinf(angle_y);// + _dir_z_ * cosf(angle_y); - - //float dir_x = dir_x_; // rotation around x - //float dir_y = /*dir_y_ * cosf(angle_x)*/ + dir_z_ * sinf(angle_x); - //float dir_z = /*-dir_y_ * sinf(angle_x)*/ + dir_z_ * cosf(angle_x); - - vector right; // rotate around right actually to avoid space distortion - right.x = /*dir_y * 0*/ -dir_z_ * 1; - right.y = /*dir_z_ * 0 - dir_x_ * */0; - right.z = dir_x_ * 1/* - dir_y_ * 0*/; - //VectorNormalize(&right); - - matrix rightMatrix; - MatrixRotationAxis(&rightMatrix, &right, angle_x); - - vector v1, v2; - v1.x = dir_x_; v1.y = 0; v1.z = dir_z_; - VectorTransform(&rightMatrix, &v1, &v2); - - float dir_x = v2.x, - dir_y = v2.y, - dir_z = v2.z; - - float abs_dir_x = fabsf(dir_x), - abs_dir_y = fabsf(dir_y), - abs_dir_z = fabsf(dir_z); - - unsigned short color = (0x1F << 11) | (0x1F << 5) | (5); //default to orange - if (abs_dir_x >= abs_dir_y) - { - if (abs_dir_x >= abs_dir_z) - { - if (dir_x >= 0) - { - float instersect_y = dir_y / (2.0f * dir_x); // plane equation for this side is x + 0.5 = 0 - float instersect_z = dir_z / (2.0f * dir_x); - - float u = 1.0f - (instersect_z + 0.5f), - v = 1.0f - (instersect_y + 0.5f); - - int tx = u * (skybox_width - 1), - ty = v * (skybox_height - 1); - - color = skybox_xp[ty * skybox_width + tx]; - //color = ty * 0x1F / skybox_height; - } - else - { - float instersect_y = dir_y / (2.0f * dir_x); - float instersect_z = dir_z / (2.0f * dir_x); - - float u = 1.0f - (instersect_z + 0.5f), - v = instersect_y + 0.5f; - - int tx = u * (skybox_width - 1), - ty = v * (skybox_height - 1); - - color = skybox_xn[ty * skybox_width + tx]; - //color = tx * 0x1F / skybox_height; - } - } - else if (dir_z >= 0) - goto DIR_ZP; - else - goto DIR_ZN; - } - else if (abs_dir_y >= abs_dir_z) - { - if (dir_y >= 0) - { - float instersect_x = dir_x / (2.0f * dir_y); - float instersect_z = dir_z / (2.0f * dir_y); - - float u = instersect_x + 0.5f, - v = instersect_z + 0.5f; - - int tx = u * (skybox_width - 1), - ty = v * (skybox_height - 1); - - color = skybox_yp[ty * skybox_width + tx]; - //color = tx * 0x1F / skybox_height; - } - /*else should never be seen i guess - { - __debugbreak(); - // -y - //Log::Warning(L"(%03u, %03u): -y", x, y); - }*/ - } - else if (dir_z >= 0) - { - DIR_ZP: - // +z - float instersect_x = dir_x / (2.0f * dir_z); - float instersect_y = dir_y / (2.0f * dir_z); - //float intersect_z = 0.5f; - - float u = instersect_x + 0.5f, - v = -instersect_y + 0.5f; - - int tx = u * (skybox_width - 1), - ty = v * (skybox_height - 1); - - color = skybox_zp[ty * skybox_width + tx]; - } - else - { - DIR_ZN: - // -z - float instersect_x = -dir_x / (2.0f * dir_z); - float instersect_y = -dir_y / (2.0f * dir_z); - //float intersect_z = -0.5f; - - float u = 1.0f - instersect_x - 0.5f, - v = -instersect_y + 0.5f; - - int tx = u * (skybox_width - 1), - ty = v * (skybox_height - 1); - - color = skybox_zn[ty * skybox_width + tx]; - } - - //pRenderer->pTargetSurface[(pViewport->uScreenY + y) * pRenderer->uTargetSurfacePitch + pViewport->uScreenX + x] = color; - ((unsigned __int16 *)((char *)desc.lpSurface + y * desc.lPitch))[x] = color; - } - - ErrD3D((skybox_surface)->Unlock(0)); - goto draw; -} - -//----- (00485F53) -------------------------------------------------------- -void sr_485F53(Vec2_int_ *v) -{ - ++v->y; - if (v->y > 1000) - v->y = 0; -} - -//----- (0048607B) -------------------------------------------------------- -void Polygon::Create_48607B(stru149 *a2) -{ - this->pTexture = 0; - this->ptr_38 = a2; -} - -//----- (00486089) -------------------------------------------------------- -void Polygon::_normalize_v_18() -{ - //double v2; // st7@1 - //double v3; // st6@1 - //double v5; // st5@1 - - // v2 = (double)this->v_18.x; - //v3 = (double)this->v_18.y; - // v5 = (double)this->v_18.z; - float len = sqrt((double)this->v_18.z * (double)this->v_18.z + (double)this->v_18.y * (double)this->v_18.y + (double)this->v_18.x * (double)this->v_18.x); - if (fabsf(len) < 1e-6f) - { - v_18.x = 0; - v_18.y = 0; - v_18.z = 65536; - } - else - { - v_18.x = round_to_int((double)this->v_18.x / len * 65536.0); - v_18.y = round_to_int((double)this->v_18.y / len * 65536.0); - v_18.y = round_to_int((double)this->v_18.z / len * 65536.0); - } -} - -//----- (0048616B) -------------------------------------------------------- -void stru149::_48616B_frustum_odm(int a2, int a3, int a4, int a5, int a6, int a7) -{ - int v7; // ebx@1 - int v9; // edi@1 - int v11; // edx@1 - int v17; // ST0C_4@6 - int v19; // ST0C_4@9 - int v24; // [sp+14h] [bp-14h]@1 - int v25; // [sp+18h] [bp-10h]@1 - int v27; // [sp+24h] [bp-4h]@1 - - v25 = pGame->pIndoorCameraD3D->int_cosine_x; - v7 = pGame->pIndoorCameraD3D->int_sine_y; - v27 = pGame->pIndoorCameraD3D->int_sine_x; - //v8 = -pIndoorCamera->pos.y; - v9 = pGame->pIndoorCameraD3D->int_cosine_y; - //v26 = -pIndoorCamera->pos.z; - v11 = pGame->pIndoorCameraD3D->int_cosine_y * -pGame->pIndoorCameraD3D->vPartyPos.x + pGame->pIndoorCameraD3D->int_sine_y * -pGame->pIndoorCameraD3D->vPartyPos.y; - v24 = pGame->pIndoorCameraD3D->int_cosine_y * -pGame->pIndoorCameraD3D->vPartyPos.y - pGame->pIndoorCameraD3D->int_sine_y * -pGame->pIndoorCameraD3D->vPartyPos.x; - if (pGame->pIndoorCameraD3D->sRotationX) - { - this->field_0_party_dir_x = fixpoint_mul(v11, pGame->pIndoorCameraD3D->int_cosine_x) + - fixpoint_mul((-pGame->pIndoorCameraD3D->vPartyPos.z) << 16, pGame->pIndoorCameraD3D->int_sine_x); - this->field_4_party_dir_y = v24; - this->field_8_party_dir_z = fixpoint_mul((-pGame->pIndoorCameraD3D->vPartyPos.z) << 16, v25) - fixpoint_mul(v11, v27); - } - else - { - this->field_0_party_dir_x = v11; - this->field_4_party_dir_y = v24; - this->field_8_party_dir_z = (-pGame->pIndoorCameraD3D->vPartyPos.z) << 16; - } - - if (pGame->pIndoorCameraD3D->sRotationX) - { - v17 = fixpoint_mul(a2, v9) + fixpoint_mul(a3, v7); - - this->angle_from_north = fixpoint_mul(v17, v25) + fixpoint_mul(a4, v27); - this->angle_from_west = fixpoint_mul(a3, v9) - fixpoint_mul(a2, v7); - this->viewing_angle_from_west_east = fixpoint_mul(a4, v25) - fixpoint_mul(v17, v27); - } - else - { - this->angle_from_north = fixpoint_mul(a2, v9) + fixpoint_mul(a3, v7); - this->angle_from_west = fixpoint_mul(a3, v9) - fixpoint_mul(a2, v7); - this->viewing_angle_from_west_east = a4; - } - - if (pGame->pIndoorCameraD3D->sRotationX) - { - v19 = fixpoint_mul(a5, v9) + fixpoint_mul(a6, v7); - - this->angle_from_east = fixpoint_mul(v19, v25) + fixpoint_mul(a7, v27); - this->angle_from_south = fixpoint_mul(a6, v9) - fixpoint_mul(a5, v7); - this->viewing_angle_from_north_south = fixpoint_mul(a7, v25) - fixpoint_mul(v19, v27); - } - else - { - this->angle_from_east = fixpoint_mul(a5, v9) + fixpoint_mul(a6, v7); - this->angle_from_south = fixpoint_mul(a6, v9) - fixpoint_mul(a5, v7); - this->viewing_angle_from_north_south = a7; - } - - this->angle_from_east = -this->angle_from_east; - this->angle_from_south = -this->angle_from_south; - this->viewing_angle_from_north_south = -this->viewing_angle_from_north_south; - - this->field_24 = fixpoint_dot(this->angle_from_north, this->field_0_party_dir_x, - this->angle_from_west, this->field_4_party_dir_y, - this->viewing_angle_from_west_east, this->field_8_party_dir_z); - this->field_28 = fixpoint_dot(this->angle_from_east, this->field_0_party_dir_x, - this->angle_from_south, this->field_4_party_dir_y, - this->viewing_angle_from_north_south, this->field_8_party_dir_z); -} - -//----- (0048694B) -------------------------------------------------------- -void stru149::_48694B_frustum_sky() -{ - this->angle_from_east = -this->angle_from_east; - this->angle_from_south = -this->angle_from_south; - this->viewing_angle_from_north_south = -this->viewing_angle_from_north_south; - - this->field_24 = fixpoint_dot(this->angle_from_north, this->field_0_party_dir_x, - this->angle_from_west, this->field_4_party_dir_y, - this->viewing_angle_from_west_east, this->field_8_party_dir_z); - this->field_28 = fixpoint_dot(this->angle_from_east, this->field_0_party_dir_x, - this->angle_from_south, this->field_4_party_dir_y, - this->viewing_angle_from_north_south, this->field_8_party_dir_z); -} - diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Render.h --- a/Render.h Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,469 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "lib\legacy_dx\d3d.h" -#include "OSWindow.h" -#include "RenderStruct.h" - -#include "VectorTypes.h" - -#include "IRender.h" - -#pragma pack(push, 1) -struct DDM_DLV_Header -{ - //----- (00462607) -------------------------------------------------------- - inline DDM_DLV_Header() - { - this->uLastRepawnDay = 0; - this->uNumRespawns = 0; - this->uReputation = 0; - this->field_C_alert = 0; - this->uNumFacesInBModels = 0; - this->uNumDecorations = 0; - this->uNumBModels = 0; - } - - - int uNumRespawns; - int uLastRepawnDay; - int uReputation; - int field_C_alert; - unsigned int uNumFacesInBModels; - unsigned int uNumDecorations; - unsigned int uNumBModels; - int field_1C; - int field_20; - int field_24; -}; -#pragma pack(pop) - - -struct ODMFace; - - -/* 141 */ -// stru148 -#pragma pack(push, 1) -struct Polygon -{ - inline Polygon() - { - uNumVertices = 0; - } - - int _479295(); - //void _48276F_sr(); - void _normalize_v_18(); - void Create_48607B(struct stru149 *a2); - - float field_0; - float field_4; - float field_8; - float field_C; - float field_10; - unsigned int uNumVertices; - Vec3_int_ v_18; - int field_24; - int sTextureDeltaU; - int sTextureDeltaV; - __int16 flags; - __int16 field_32; - int field_34; - struct stru149 *ptr_38; - struct Texture *pTexture; - struct Span *_unused_prolly_head; - struct Span *_unused_prolly_tail; - int **ptr_48; - unsigned __int16 uTileBitmapID; - __int16 field_4E; - __int16 field_50; - __int16 field_52; - ODMFace *pODMFace; - char dimming_level; - char field_59; - char field_5A; - char field_5B; - char terrain_grid_z; - char terrain_grid_x; - unsigned __int8 uBModelID; - unsigned __int8 uBModelFaceID; - struct Edge *pEdgeList1[20]; - unsigned int uEdgeList1Size; - struct Edge *pEdgeList2[20]; - unsigned int uEdgeList2Size; - char field_108; - char field_109; - char field_10A; - char field_10B; -}; -#pragma pack(pop) -extern std::array array_77EC08; - - -/* 142 */ -#pragma pack(push, 1) -struct stru149 -{ - void _48616B_frustum_odm(int a2, int a3, int a4, int a5, int a6, int a7); - void _48653D_frustum_blv(int a2, int a3, int a4, int a5, int a6, int a7); - void _48694B_frustum_sky(); - - int field_0_party_dir_x; - int field_4_party_dir_y; - int field_8_party_dir_z; - int angle_from_north;//field_C - int angle_from_west;//field_10 - int viewing_angle_from_west_east; - int angle_from_east;//field_18 - int angle_from_south;//field_1C - int viewing_angle_from_north_south;//field_20 - int field_24; - int field_28; -}; -#pragma pack(pop) -extern stru149 stru_8019C8; - -/* 88 */ -#pragma pack(push, 1) -struct ODMRenderParams -{ - //----- (00462684) -------------------------------------------------------- - ODMRenderParams() - { - uPickDepth = 0; - this->shading_dist_shade = 2048; - shading_dist_shademist = 4096; - shading_dist_mist = 8192; - int_fov_rad = 0; - this->bNoSky = 0; - this->bDoNotRenderDecorations = 0; - this->field_5C = 0; - this->field_60 = 0; - this->outdoor_no_wavy_water = 0; - this->outdoor_no_mist = 0; - } - - void Initialize(); - - int uPickDepth; - int shading_dist_shade; - int shading_dist_shademist; - int shading_dist_mist; - unsigned int uCameraFovInDegrees; - int int_fov_rad; // 157 struct IndoorCamera::fov_rad - int int_fov_rad_inv; // 157 struct IndoorCamera::fov_rad_inv - int _unused_camera_rotation_y_int_sine; // merged with BLVRenderParams equivalents - int _unused_camera_rotation_y_int_cosine; // into IndoorCameraD3D - int _unused_camera_rotation_x_int_sine; // --//-- - int _unused_camera_rotation_x_int_cosine; // --//-- - int uNumPolygons; - unsigned int _unused_uNumEdges; - unsigned int _unused_uNumSurfs; - unsigned int _unused_uNumSpans; - unsigned int uNumBillboards; - float field_40; - int field_44; - int outdoor_grid_band_3; - int field_4C; - int field_50; - unsigned int bNoSky; - unsigned int bDoNotRenderDecorations; - int field_5C; - int field_60; - int outdoor_no_wavy_water; - int outdoor_no_mist; - int building_gamme; - int terrain_gamma; - - unsigned int uMapGridCellX; // moved from 157 struct IndoorCamera::0C - unsigned int uMapGridCellZ; // moved from 157 struct IndoorCamera::10 -}; -#pragma pack(pop) -extern ODMRenderParams *pODMRenderParams; - - - -struct Render: public IRender -{ - Render(); - virtual ~Render(); - - static Render *Create() {return new Render;} - - virtual bool Initialize(OSWindow *window); - - virtual void ClearBlack(); - virtual void PresentBlackScreen(); - - virtual void SaveWinnersCertificate(const char *a1); - virtual void ClearTarget(unsigned int uColor); - virtual void Present(); - - virtual void _49FD3A_fullscreen(); - virtual bool InitializeFullscreen(); - - virtual void CreateZBuffer(); - virtual void Release(); - - virtual bool SwitchToWindow(); - virtual void RasterLine2D(signed int uX, signed int uY, signed int uZ, signed int uW, unsigned __int16 uColor); - virtual void ClearZBuffer(int a2, int a3); - virtual void SetRasterClipRect(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW); - virtual bool LockSurface_DDraw4(IDirectDrawSurface4 *pSurface, DDSURFACEDESC2 *pDesc, unsigned int uLockFlags); - virtual void GetTargetPixelFormat(DDPIXELFORMAT *pOut); - virtual void LockRenderSurface(void **pOutSurfacePtr, unsigned int *pOutPixelsPerRow); - virtual void UnlockBackBuffer(); - virtual void LockFrontBuffer(void **pOutSurface, unsigned int *pOutPixelsPerRow); - virtual void UnlockFrontBuffer(); - virtual void RestoreFrontBuffer(); - virtual void RestoreBackBuffer(); - virtual void BltToFront(RECT *pDstRect, IDirectDrawSurface *pSrcSurface, RECT *pSrcRect, unsigned int uBltFlags); - virtual void BltBackToFontFast(int a2, int a3, RECT *pSrcRect); - virtual void BeginSceneD3D(); - - virtual unsigned int GetActorTintColor(float a2, int tint, int a4, int a5, RenderBillboard *a6); - - virtual void DrawPolygon(unsigned int uNumVertices, struct Polygon *a3, ODMFace *a4, IDirect3DTexture2 *pTexture); - virtual void DrawTerrainPolygon(unsigned int uNumVertices, struct Polygon *a4, IDirect3DTexture2 *a5, bool transparent, bool clampAtTextureBorders); - virtual void DrawIndoorPolygon(unsigned int uNumVertices, struct BLVFace *a3, IDirect3DTexture2 *pHwTex, struct Texture *pTex, int uPackedID, unsigned int uColor, int a8); - - virtual void MakeParticleBillboardAndPush_BLV(RenderBillboardTransform_local0 *a2, IDirect3DTexture2 *a3, unsigned int uDiffuse, int angle); - virtual void MakeParticleBillboardAndPush_ODM(RenderBillboardTransform_local0 *a2, IDirect3DTexture2 *a3, unsigned int uDiffuse, int angle); - - virtual void DrawBillboards_And_MaybeRenderSpecialEffects_And_EndScene(); - virtual void DrawBillboard_Indoor(RenderBillboardTransform_local0 *pSoftBillboard, Sprite *pSprite, int dimming_level); - virtual void _4A4CC9_AddSomeBillboard(struct stru6_stru1_indoor_sw_billboard *a1, int diffuse); - virtual void TransformBillboardsAndSetPalettesODM(); - virtual void DrawBillboardList_BLV(); - - virtual void DrawProjectile(float srcX, float srcY, float a3, float a4, float dstX, float dstY, float a7, float a8, IDirect3DTexture2 *a9); - virtual bool LoadTexture(const char *pName, unsigned int bMipMaps, IDirectDrawSurface4 **pOutSurface, IDirect3DTexture2 **pOutTexture); - virtual bool MoveSpriteToDevice(Sprite *pSprite); - - virtual void BeginScene(); - virtual void EndScene(); - virtual void ScreenFade(unsigned int color, float t); - - virtual void SetTextureClipRect(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW); - virtual void ResetTextureClipRect(); - virtual void DrawTextureRGB(unsigned int uOutX, unsigned int uOutY, RGBTexture *a4); - virtual void CreditsTextureScroll(unsigned int pX, unsigned int pY, int move_X, int move_Y, RGBTexture *pTexture); - virtual void DrawTextureIndexed(unsigned int uX, unsigned int uY, struct Texture *a4); - - virtual void ZBuffer_Fill_2(signed int a2, signed int a3, struct Texture *pTexture, int a5); - virtual void DrawMaskToZBuffer(signed int uOutX, unsigned int uOutY, struct Texture *pTexture, int zVal); - virtual void DrawTextureTransparent(unsigned int uX, unsigned int uY, struct Texture *pTexture); - virtual void DrawAura(unsigned int a2, unsigned int a3, struct Texture *a4, struct Texture *a5, int a6, int a7, int a8); - virtual void _4A65CC(unsigned int x, unsigned int y, struct Texture *a4, struct Texture *a5, int a6, int a7, int a8); - - virtual void DrawTransparentRedShade(unsigned int a2, unsigned int a3, struct Texture *a4); - virtual void DrawTransparentGreenShade(signed int a2, signed int a3, struct Texture *pTexture); - virtual void DrawFansTransparent(const RenderVertexD3D3 *vertices, unsigned int num_vertices); - - virtual void DrawMasked(signed int a2, signed int a3, struct Texture *pTexture, unsigned __int16 mask); - virtual void GetLeather(unsigned int a2, unsigned int a3, struct Texture *a4, __int16 height); - - virtual void DrawTextPalette(int x, int y, unsigned char* font_pixels, int a5, unsigned int uFontHeight, unsigned __int16 *pPalette, int a8); - virtual void DrawText(signed int uOutX, signed int uOutY, unsigned __int8 *pFontPixels, unsigned int uCharWidth, unsigned int uCharHeight, unsigned __int16 *pFontPalette, unsigned __int16 uFaceColor, unsigned __int16 uShadowColor); - - virtual void FillRectFast(unsigned int uX, unsigned int uY, unsigned int uWidth, unsigned int uHeight, unsigned int uColor16); - virtual void _4A6DF5(unsigned __int16 *pBitmap, unsigned int uBitmapPitch, struct Vec2_int_ *pBitmapXY, void *pTarget, unsigned int uTargetPitch, Vec4_int_ *a7); - virtual void DrawTranslucent(unsigned int a2, unsigned int a3, struct Texture *a4); - - virtual void DrawBuildingsD3D(); - //struct BSPModel *DrawBuildingsSW(); - //int OnOutdoorRedrawSW(); - - virtual void DrawIndoorSky(unsigned int uNumVertices, unsigned int uFaceID); - virtual void DrawOutdoorSkyD3D(); - //int DrawSkySW(struct Span *a1, Polygon *a2, int a3); - virtual void DrawOutdoorSkyPolygon(unsigned int uNumVertices, struct Polygon *pSkyPolygon, IDirect3DTexture2 *pTexture); - virtual void DrawIndoorSkyPolygon(signed int uNumVertices, struct Polygon *pSkyPolygon, IDirect3DTexture2 *pTexture); - - virtual void PrepareDecorationsRenderList_ODM(); - virtual void DrawSpriteObjects_ODM(); - - //float DrawBezierTerrain(); - virtual void RenderTerrainD3D(); - //void DrawTerrainSW(int a1, int a2, int a3, int a4); - - //void ExecOutdoorDrawSW(); - virtual void ChangeBetweenWinFullscreenModes(); - virtual bool AreRenderSurfacesOk(); - virtual bool IsGammaSupported(); - - virtual void SaveScreenshot(const char *pFilename, unsigned int width, unsigned int height); - virtual void PackScreenshot(unsigned int width, unsigned int height, void *out_data, unsigned int data_size, unsigned int *screenshot_size); - virtual void SavePCXScreenshot(); - - virtual int _46А6АС_GetActorsInViewport(int pDepth); - - virtual void BeginLightmaps(); - virtual void EndLightmaps(); - virtual void BeginLightmaps2(); - virtual void EndLightmaps2(); - virtual bool DrawLightmap(struct Lightmap *pLightmap, struct Vec3_float_ *pColorMult, float z_bias); - - virtual void BeginDecals(); - virtual void EndDecals(); - virtual void DrawDecal(struct Decal *pDecal, float z_bias); - - virtual void do_draw_debug_line_d3d(const RenderVertexD3D3 *pLineBegin, signed int sDiffuseBegin, const RenderVertexD3D3 *pLineEnd, signed int sDiffuseEnd, float z_stuff); - virtual void DrawLines(const RenderVertexD3D3 *vertices, unsigned int num_vertices); - - virtual void DrawSpecialEffectsQuad(const RenderVertexD3D3 *vertices, IDirect3DTexture2 *texture); - - virtual void am_Blt_Copy(RECT *pSrcRect, POINT *pTargetXY, int a3); - virtual void am_Blt_Chroma(RECT *pSrcRect, POINT *pTargetPoint, int a3, int blend_mode); - - public:/* - int *pActiveZBuffer; - IDirectDraw4 *pDirectDraw4; - IDirectDrawSurface4 *pFrontBuffer4; - IDirectDrawSurface4 *pBackBuffer4; - void *pTargetSurface; - unsigned int uTargetSurfacePitch; - unsigned int bUseColoredLights; - unsigned int bTinting; - unsigned int bUsingSpecular; - uint32_t uFogColor; - unsigned int pHDWaterBitmapIDs[7]; - int hd_water_current_frame; - int hd_water_tile_id; - void (*pBeforePresentFunction)(); - uint32_t bFogEnabled; - RenderBillboardD3D pBillboardRenderListD3D[1000]; - unsigned int uNumBillboardsToDraw;*/ - - virtual void WritePixel16(int x, int y, unsigned __int16 color) - { - if (ddpfPrimarySuface.dwRGBBitCount == 32) - { - auto p = (unsigned __int32 *)pTargetSurface + x + y * uTargetSurfacePitch; - *p = Color32(color); - } - else if (ddpfPrimarySuface.dwRGBBitCount == 16) - { - auto p = (unsigned __int16 *)pTargetSurface + x + y * uTargetSurfacePitch; - *p = color; - } - else __debugbreak(); - } - - virtual unsigned __int16 ReadPixel16(int x, int y) - { - if (ddpfPrimarySuface.dwRGBBitCount == 32) - { - auto p = (unsigned __int32 *)pTargetSurface + x + y * uTargetSurfacePitch; - return Color16((*p >> 16) & 255, (*p >> 8) & 255, *p & 255); - } - else if (ddpfPrimarySuface.dwRGBBitCount == 16) - { - auto p = (unsigned __int16 *)pTargetSurface + x + y * uTargetSurfacePitch; - return *p; - } - else __debugbreak(); - } - - virtual void ToggleTint() {bTinting = !bTinting;} - virtual void ToggleColoredLights() {bUseColoredLights = !bUseColoredLights;} - - virtual unsigned int GetRenderWidth() {return window->GetWidth();} - virtual unsigned int GetRenderHeight() {return window->GetHeight();} - - virtual void Sub01() - { - if (pRenderD3D && !bWindowMode) - _49FD3A_fullscreen(); - } - - friend void Present_NoColorKey(); - - protected: - unsigned int uDesiredDirect3DDevice; - int raster_clip_x; - int raster_clip_y; // clipping rect for raster ops - int raster_clip_z; // like RasterLine2D for (mini)map - int raster_clip_w; - int *pDefaultZBuffer; - OSWindow *window; - unsigned int bWindowMode; - RenderD3D *pRenderD3D; - DDPIXELFORMAT ddpfPrimarySuface; - unsigned int uTargetRBits; - unsigned int uTargetGBits; - unsigned int uTargetBBits; - unsigned int uTargetRMask; - unsigned int uTargetGMask; - unsigned int uTargetBMask; - unsigned int uNumSceneBegins; - unsigned __int32 *pTargetSurface_unaligned; - unsigned int uClipY; - unsigned int uClipX; - unsigned int uClipW; - unsigned int uClipZ; - unsigned int bClip; - unsigned int uNumD3DSceneBegins; - int using_software_screen_buffer; - RenderHWLContainer pD3DBitmaps; - RenderHWLContainer pD3DSprites; - unsigned int bRequiredTextureStagesAvailable; - unsigned int uLevelOfDetail; - unsigned int uMaxDeviceTextureDim; - unsigned int uMinDeviceTextureDim; - - void DoRenderBillboards_D3D(); - void SetBillboardBlendOptions(RenderBillboardD3D::OpacityType a1); - void TransformBillboard(RenderBillboardTransform_local0 *a2, Sprite *pSprite, int dimming_level, RenderBillboard *pBillboard); - unsigned int Billboard_ProbablyAddToListAndSortByZOrder(float z); - unsigned int GetParentBillboardID(unsigned int uBillboardID); - unsigned int GetBillboardDrawListSize(); - - void DrawBorderTiles(struct Polygon *poly); - - unsigned short *MakeScreenshot(signed int width, signed int height); - bool CheckTextureStages(); - void ParseTargetPixelFormat(); - - void CreateDirectDraw(); - void SetDirectDrawCooperationMode(HWND hWnd, bool bFullscreen); - void SetDirectDrawDisplayMode(unsigned int uWidth, unsigned int uHeight, unsigned int uBPP); - void CreateFrontBuffer(); - void CreateBackBuffer(); - void CreateDirectDrawPrimarySurface(); - void CreateClipper(HWND a2); - - void PackPCXpicture(unsigned short* picture_data, int wight, int heidth, void *data_buff, int max_buff_size,unsigned int* packed_size); - void SavePCXImage(const char *Filename, unsigned short* picture_data, int width, int height); - - //int windowed_mode_width; - //int windowed_mode_height; -}; - -unsigned int __fastcall _452442_color_cvt(unsigned __int16 a1, unsigned __int16 a2, int a3, int a4); - -int __fastcall GetActorTintColor(int max_dim, int min_dim, float distance, int a4, struct RenderBillboard *a5); -int __fastcall _43F55F_get_billboard_light_level(struct RenderBillboard *a1, int uBaseLightLevel); -int __fastcall _43F5C8_get_point_light_level_with_respect_to_lights(unsigned int uBaseLightLevel, int uSectorID, float x, float y, float z); -unsigned int __fastcall GetMaxMipLevels(unsigned int uDim); -int _46E44E_collide_against_faces_and_portals(unsigned int b1); // idb -int __fastcall _46E889_collide_against_bmodels(unsigned int ecx0); -int collide_against_floor(int x, int y, int z, unsigned int *pSectorID, unsigned int *pFaceID); // idb -void __fastcall _46ED8A_collide_against_sprite_objects(unsigned int _this); -int _46EF01_collision_chech_player(int a1); // idb -void _46E0B2_collide_against_decorations(); -int _46F04E_collide_against_portals(); -unsigned int __fastcall sub_46DEF2(signed int a2, unsigned int uLayingItemID); -void UpdateObjects(); -bool sub_47531C(int a1, int *a2, int pos_x, int pos_y, int pos_z, int dir_x, int dir_y, int dir_z, struct BLVFace *face, int a10); -bool sub_4754BF(int a1, int *a2, int X, int Y, int Z, int dir_x, int dir_y, int dir_z, struct BLVFace *face, int a10, int a11); -int sub_475665(struct BLVFace *face, int a2, __int16 a3); -bool __fastcall sub_4759C9(struct BLVFace *face, int a2, int a3, __int16 a4); -bool __fastcall sub_475D85(Vec3_int_ *a1, Vec3_int_ *a2, int *a3, struct BLVFace *a4); -bool __fastcall sub_475F30(int *a1, struct BLVFace *a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9); - -bool __fastcall IsBModelVisible(unsigned int uModelID, int *unused); diff -r 7b076fe64f23 -r 5abd8fc8f1c6 RenderD3D11.cpp --- a/RenderD3D11.cpp Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,325 +0,0 @@ -#include -#include // _com_error - -#include "ErrorHandling.h" -#include "RenderD3D11.h" -#include "mm7_data.h" - -#define ErrorD3D(x)\ -{\ - HRESULT hr = x;\ - if (FAILED(hr))\ - {\ - _com_error com_error(hr);\ - Error("HRESULT = %08X\n%S", hr, com_error.ErrorMessage());\ - }\ -} - - -RenderD3D11::RenderD3D11() {} -RenderD3D11::~RenderD3D11() {} - - -void RenderD3D11::ClearBlack() {__debugbreak();} -void RenderD3D11::SaveWinnersCertificate(const char *a1) {__debugbreak();} -void RenderD3D11::Present() {__debugbreak();} -void RenderD3D11::_49FD3A_fullscreen() {__debugbreak();} -bool RenderD3D11::InitializeFullscreen() {__debugbreak(); return 0;} -void RenderD3D11::CreateZBuffer() {__debugbreak();} -void RenderD3D11::Release() {__debugbreak();} -void RenderD3D11::RasterLine2D(signed int uX, signed int uY, signed int uZ, signed int uW, unsigned __int16 uColor) {__debugbreak();} -void RenderD3D11::ClearZBuffer(int a2, int a3) {__debugbreak();} -void RenderD3D11::SetRasterClipRect(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW) {__debugbreak();} -bool RenderD3D11::LockSurface_DDraw4(IDirectDrawSurface4 *pSurface, DDSURFACEDESC2 *pDesc, unsigned int uLockFlags) {__debugbreak(); return 0;} -void RenderD3D11::GetTargetPixelFormat(DDPIXELFORMAT *pOut) {__debugbreak();} -void RenderD3D11::LockRenderSurface(void **pOutSurfacePtr, unsigned int *pOutPixelsPerRow) {__debugbreak();} -void RenderD3D11::UnlockBackBuffer() {__debugbreak();} -void RenderD3D11::LockFrontBuffer(void **pOutSurface, unsigned int *pOutPixelsPerRow) {__debugbreak();} -void RenderD3D11::UnlockFrontBuffer() {__debugbreak();} -void RenderD3D11::RestoreFrontBuffer() {__debugbreak();} -void RenderD3D11::RestoreBackBuffer() {__debugbreak();} -void RenderD3D11::BltToFront(RECT *pDstRect, IDirectDrawSurface *pSrcSurface, RECT *pSrcRect, unsigned int uBltFlags) {__debugbreak();} -void RenderD3D11::BltBackToFontFast(int a2, int a3, RECT *a4) {__debugbreak();} -void RenderD3D11::BeginSceneD3D() {__debugbreak();} -unsigned int RenderD3D11::GetActorTintColor(float a2, int tint, int a4, int a5, RenderBillboard *a6) {__debugbreak(); return 0;} -void RenderD3D11::DrawPolygon(unsigned int uNumVertices, struct Polygon *a3, ODMFace *a4, IDirect3DTexture2 *pTexture) {__debugbreak();} -void RenderD3D11::DrawTerrainPolygon(unsigned int uNumVertices, struct Polygon *a4, IDirect3DTexture2 *a5, bool transparent, bool clampAtTextureBorders) {__debugbreak();} -void RenderD3D11::DrawIndoorPolygon(unsigned int uNumVertices, struct BLVFace *a3, IDirect3DTexture2 *pHwTex, struct Texture *pTex, int uPackedID, unsigned int uColor, int a8) {__debugbreak();} -void RenderD3D11::MakeParticleBillboardAndPush_BLV(RenderBillboardTransform_local0 *a2, IDirect3DTexture2 *a3, unsigned int uDiffuse, int angle) {__debugbreak();} -void RenderD3D11::MakeParticleBillboardAndPush_ODM(RenderBillboardTransform_local0 *a2, IDirect3DTexture2 *a3, unsigned int uDiffuse, int angle) {__debugbreak();} -void RenderD3D11::DrawBillboards_And_MaybeRenderSpecialEffects_And_EndScene() {__debugbreak();} -void RenderD3D11::DrawBillboard_Indoor(RenderBillboardTransform_local0 *pSoftBillboard, Sprite *pSprite, int dimming_level) {__debugbreak();} -void RenderD3D11::_4A4CC9_AddSomeBillboard(struct stru6_stru1_indoor_sw_billboard *a1, int diffuse) {__debugbreak();} -void RenderD3D11::TransformBillboardsAndSetPalettesODM() {__debugbreak();} -void RenderD3D11::DrawBillboardList_BLV() {__debugbreak();} -void RenderD3D11::DrawProjectile(float srcX, float srcY, float a3, float a4, float dstX, float dstY, float a7, float a8, IDirect3DTexture2 *a9) {__debugbreak();} -bool RenderD3D11::LoadTexture(const char *pName, unsigned int bMipMaps, IDirectDrawSurface4 **pOutSurface, IDirect3DTexture2 **pOutTexture) {__debugbreak(); return 0;} -bool RenderD3D11::MoveSpriteToDevice(Sprite *pSprite) {__debugbreak(); return 0;} -void RenderD3D11::ScreenFade(unsigned int color, float t) {__debugbreak();} -void RenderD3D11::SetTextureClipRect(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW) {__debugbreak();} -void RenderD3D11::ResetTextureClipRect() {__debugbreak();} -void RenderD3D11::CreditsTextureScroll(unsigned int pX, unsigned int pY, int move_X, int move_Y, RGBTexture *pTexture) {__debugbreak();} -void RenderD3D11::DrawTextureIndexed(unsigned int uX, unsigned int uY, struct Texture *a4) {__debugbreak();} -void RenderD3D11::ZBuffer_Fill_2(signed int a2, signed int a3, struct Texture *pTexture, int a5) {__debugbreak();} -void RenderD3D11::DrawMaskToZBuffer(signed int uOutX, unsigned int uOutY, struct Texture *pTexture, int zVal) {__debugbreak();} -void RenderD3D11::DrawTextureTransparent(unsigned int uX, unsigned int uY, struct Texture *pTexture) {__debugbreak();} -void RenderD3D11::DrawAura(unsigned int a2, unsigned int a3, struct Texture *a4, struct Texture *a5, int a6, int a7, int a8) {__debugbreak();} -void RenderD3D11::_4A65CC(unsigned int x, unsigned int y, struct Texture *a4, struct Texture *a5, int a6, int a7, int a8) {__debugbreak();} -void RenderD3D11::DrawTransparentRedShade(unsigned int a2, unsigned int a3, struct Texture *a4) {__debugbreak();} -void RenderD3D11::DrawTransparentGreenShade(signed int a2, signed int a3, struct Texture *pTexture) {__debugbreak();} -void RenderD3D11::DrawFansTransparent(const RenderVertexD3D3 *vertices, unsigned int num_vertices) {__debugbreak();} -void RenderD3D11::DrawMasked(signed int a2, signed int a3, struct Texture *pTexture, unsigned __int16 mask) {__debugbreak();} -void RenderD3D11::GetLeather(unsigned int a2, unsigned int a3, struct Texture *a4, __int16 height) {__debugbreak();} -void RenderD3D11::DrawTextPalette(int x, int y, unsigned char* font_pixels, int a5, unsigned int uFontHeight, unsigned __int16 *pPalette, int a8) {__debugbreak();} -void RenderD3D11::DrawText(signed int uOutX, signed int uOutY, unsigned __int8 *pFontPixels, unsigned int uCharWidth, unsigned int uCharHeight, unsigned __int16 *pFontPalette, unsigned __int16 uFaceColor, unsigned __int16 uShadowColor) {__debugbreak();} -void RenderD3D11::FillRectFast(unsigned int uX, unsigned int uY, unsigned int uWidth, unsigned int uHeight, unsigned int uColor16) {__debugbreak();} -void RenderD3D11::_4A6DF5(unsigned __int16 *pBitmap, unsigned int uBitmapPitch, struct Vec2_int_ *pBitmapXY, void *pTarget, unsigned int uTargetPitch, Vec4_int_ *a7) {__debugbreak();} -void RenderD3D11::DrawTranslucent(unsigned int a2, unsigned int a3, struct Texture *a4) {__debugbreak();} -void RenderD3D11::DrawBuildingsD3D() {__debugbreak();} -void RenderD3D11::DrawIndoorSky(unsigned int uNumVertices, unsigned int uFaceID) {__debugbreak();} -void RenderD3D11::DrawOutdoorSkyD3D() {__debugbreak();} -void RenderD3D11::DrawOutdoorSkyPolygon(unsigned int uNumVertices, struct Polygon *pSkyPolygon, IDirect3DTexture2 *pTexture) {__debugbreak();} -void RenderD3D11::DrawIndoorSkyPolygon(signed int uNumVertices, struct Polygon *pSkyPolygon, IDirect3DTexture2 *pTexture) {__debugbreak();} -void RenderD3D11::PrepareDecorationsRenderList_ODM() {__debugbreak();} -void RenderD3D11::DrawSpriteObjects_ODM() {__debugbreak();} -void RenderD3D11::RenderTerrainD3D() {__debugbreak();} -void RenderD3D11::ChangeBetweenWinFullscreenModes() {__debugbreak();} -bool RenderD3D11::AreRenderSurfacesOk() {__debugbreak(); return 0;} -void RenderD3D11::SaveScreenshot(const char *pFilename, unsigned int width, unsigned int height) {__debugbreak();} -void RenderD3D11::PackScreenshot(unsigned int width, unsigned int height, void *out_data, unsigned int data_size, unsigned int *screenshot_size) {__debugbreak();} -void RenderD3D11::SavePCXScreenshot() {__debugbreak();} -int RenderD3D11::_46А6АС_GetActorsInViewport(int pDepth) {__debugbreak(); return 0;} -void RenderD3D11::BeginLightmaps() {__debugbreak();} -void RenderD3D11::EndLightmaps() {__debugbreak();} -void RenderD3D11::BeginLightmaps2() {__debugbreak();} -void RenderD3D11::EndLightmaps2() {__debugbreak();} -bool RenderD3D11::DrawLightmap(struct Lightmap *pLightmap, struct Vec3_float_ *pColorMult, float z_bias) {__debugbreak(); return 0;} -void RenderD3D11::BeginDecals() {__debugbreak();} -void RenderD3D11::EndDecals() {__debugbreak();} -void RenderD3D11::DrawDecal(struct Decal *pDecal, float z_bias) {__debugbreak();} -void RenderD3D11::do_draw_debug_line_d3d(const RenderVertexD3D3 *pLineBegin, signed int sDiffuseBegin, const RenderVertexD3D3 *pLineEnd, signed int sDiffuseEnd, float z_stuff) {__debugbreak();} -void RenderD3D11::DrawLines(const RenderVertexD3D3 *vertices, unsigned int num_vertices) {__debugbreak();} -void RenderD3D11::DrawSpecialEffectsQuad(const RenderVertexD3D3 *vertices, IDirect3DTexture2 *texture) {__debugbreak();} -void RenderD3D11::am_Blt_Copy(RECT *pSrcRect, POINT *pTargetXY, int a3) {__debugbreak();} -void RenderD3D11::am_Blt_Chroma(RECT *pSrcRect, POINT *pTargetPoint, int a3, int blend_mode) {__debugbreak();} - -void RenderD3D11::Sub01() {__debugbreak();} - - - - - -void RenderD3D11::PresentBlackScreen() -{ - ClearTarget(0xFF000000); - ErrorD3D(pSwapChain->Present(0, 0)); -} - -void RenderD3D11::BeginScene() {} -void RenderD3D11::EndScene() {} - -void RenderD3D11::ClearTarget(unsigned int uColor) -{ - float clear_color[] = - { - ((uColor & 0x00FF0000) >> 16) / 255.0f, - ((uColor & 0x0000FF00) >> 8) / 255.0f, - ((uColor & 0x000000FF) >> 0) / 255.0f, - ((uColor & 0xFF000000) >> 24) / 255.0f - }; - d3dc->ClearRenderTargetView(primary_srv, clear_color); -} - - -void RenderD3D11::DrawTextureRGB(unsigned int uOutX, unsigned int uOutY, RGBTexture *a4) -{ - __debugbreak(); -} - -bool RenderD3D11::IsGammaSupported() -{ - return false; -} - -struct -{ - unsigned char restore_resolution; - unsigned char _saved_screen_bpp; - unsigned short _saved_screen_width; - unsigned short _saved_screen_height; -} on_exit; - -void ChangeResolution(int new_width, int new_height, int new_bpp) -{ - if (!on_exit.restore_resolution) - { - on_exit.restore_resolution = true; - - auto hdc = GetDC(nullptr); - { - on_exit._saved_screen_width = GetDeviceCaps(hdc, HORZRES); - on_exit._saved_screen_height = GetDeviceCaps(hdc, VERTRES); - on_exit._saved_screen_bpp = GetDeviceCaps(hdc, BITSPIXEL); - } - ReleaseDC(nullptr, hdc); - } - - DEVMODEA dm; - dm.dmSize = sizeof(dm); - dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; - dm.dmBitsPerPel = new_bpp; - dm.dmPelsWidth = new_width; - dm.dmPelsHeight = new_height; - - if (ChangeDisplaySettingsA(&dm, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) - Error("ChangeDisplaySettingsA"); -} - -__declspec(noreturn) void ExitApp() -{ - if (on_exit.restore_resolution) - ChangeResolution(on_exit._saved_screen_width, on_exit._saved_screen_height, on_exit._saved_screen_bpp); - - ExitProcess(0); -} - - - -bool RenderD3D11::SwitchToWindow() -{ - if (on_exit.restore_resolution) - { - on_exit.restore_resolution = false; - ChangeResolution(on_exit._saved_screen_width, on_exit._saved_screen_height, on_exit._saved_screen_bpp); - } - return true; -} - - - - -bool RenderD3D11::Initialize(OSWindow *window) -{ - this->window = window; - - auto d3d_lib = LoadLibraryW(L"d3d11.dll"); - if (!d3d_lib) - return Error("d3d11.dll is missing"), false; - - - DXGI_SWAP_CHAIN_DESC swapChainDesc; - memset(&swapChainDesc, 0, sizeof(swapChainDesc)); - swapChainDesc.BufferDesc.Width = window->GetWidth(); - swapChainDesc.BufferDesc.Height = window->GetHeight(); - //swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; - //swapChainDesc.BufferDesc.RefreshRate.Denominator = 0; - swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - //swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; - //swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; - swapChainDesc.SampleDesc.Count = 1; - //swapChainDesc.SampleDesc.Quality = 0; - swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swapChainDesc.BufferCount = 2; - swapChainDesc.OutputWindow = window->GetApiHandle(); - swapChainDesc.Windowed = true; - //swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; - //swapChainDesc.Flags = 0; - - - D3D_FEATURE_LEVEL requested_feature_level = D3D_FEATURE_LEVEL_11_0, - received_feature_level; - - unsigned int device_flags = 0;//D3D11_CREATE_DEVICE_DISABLE_GPU_TIMEOUT; - #ifndef NODEBUG - device_flags |= 0/*D3D11_CREATE_DEVICE_DEBUG | D3D11_CREATE_DEVICE_DEBUGGABLE*/; - #endif - - HRESULT (__stdcall *dll_D3D11CreateDeviceAndSwapChain)(IDXGIAdapter* pAdapter, D3D_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, CONST D3D_FEATURE_LEVEL* pFeatureLevels, UINT FeatureLevels, UINT SDKVersion, CONST DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, IDXGISwapChain** ppSwapChain, ID3D11Device** ppDevice, D3D_FEATURE_LEVEL* pFeatureLevel, ID3D11DeviceContext** ppImmediateContext); - dll_D3D11CreateDeviceAndSwapChain = (decltype(dll_D3D11CreateDeviceAndSwapChain))GetProcAddress(d3d_lib, "D3D11CreateDeviceAndSwapChain"); - ErrorD3D(dll_D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, device_flags, nullptr, 0, D3D11_SDK_VERSION, &swapChainDesc, &pSwapChain, &d3dd, &received_feature_level, &d3dc)); - - if (received_feature_level < D3D_FEATURE_LEVEL_10_0) - { - MessageBoxA(nullptr, "Received Direct3D 9 or lower", "", 0); - __debugbreak(); - } - /*if (fullscreen) - { - extern void ChangeResolution(int new_dith, int new_height, int new_bpp); - ChangeResolution(target_window->GetWidth(), target_window->GetHeight(), 32); - - target_window->SetPosition(0, 0); - target_window->SetTopmost(true); - } - ErrorD3D(pSwapChain->SetFullscreenState(fullscreen, nullptr));*/ - - - ID3D11Texture2D *pSwapChainSurface; - { - ErrorD3D(pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void **)&pSwapChainSurface)); - ErrorD3D(d3dd->CreateRenderTargetView(pSwapChainSurface, nullptr, &primary_srv)); - } - pSwapChainSurface->Release(); - - - D3D11_TEXTURE2D_DESC z_desc; - memset(&z_desc, 0, sizeof(z_desc)); - z_desc.Width = window->GetWidth(); - z_desc.Height = window->GetHeight(); - z_desc.MipLevels = 1; - z_desc.ArraySize = 1; - z_desc.Format = DXGI_FORMAT_D32_FLOAT; - z_desc.SampleDesc.Count = 1; - //z_desc.SampleDesc.Quality = 0; - //z_desc.Usage = D3D11_USAGE_DEFAULT; - z_desc.BindFlags = D3D11_BIND_DEPTH_STENCIL; - //z_desc.CPUAccessFlags = 0; - //z_desc.MiscFlags = 0; - - ID3D11Texture2D *depth_surface; - ErrorD3D(d3dd->CreateTexture2D(&z_desc, nullptr, &depth_surface)); - - D3D11_DEPTH_STENCIL_VIEW_DESC depth_srv_desc; - memset(&depth_srv_desc, 0, sizeof(depth_srv_desc)); - depth_srv_desc.Format = DXGI_FORMAT_D32_FLOAT; - depth_srv_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; - //depth_srv_desc.Texture2D.MipSlice = 0; - ErrorD3D(d3dd->CreateDepthStencilView(depth_surface, &depth_srv_desc, &depth_srv)); - - d3dc->OMSetRenderTargets(1, &primary_srv, depth_srv); - d3dc->ClearDepthStencilView(depth_srv, D3D11_CLEAR_DEPTH, 1.0f, 0); - - - - D3D11_RASTERIZER_DESC d3drs_desc; - memset(&d3drs_desc, 0, sizeof(d3drs_desc)); - d3drs_desc.FillMode = D3D11_FILL_SOLID; - d3drs_desc.CullMode = D3D11_CULL_NONE; - //d3drs_desc.FrontCounterClockwise = false; - //d3drs_desc.DepthBias = 0; - //d3drs_desc.DepthBiasClamp = 0.0f; - //d3drs_desc.SlopeScaledDepthBias = 0.0f; - //d3drs_desc.DepthClipEnable = true; - //d3drs_desc.ScissorEnable = false; - //d3drs_desc.MultisampleEnable = false; - //d3drs_desc.AntialiasedLineEnable = false; - - ID3D11RasterizerState *d3drs; - ErrorD3D(d3dd->CreateRasterizerState(&d3drs_desc, &d3drs)); - d3dc->RSSetState(d3drs); - d3drs->Release(); - - - - D3D11_VIEWPORT viewport; - memset(&viewport, 0, sizeof(viewport)); - viewport.TopLeftX = game_viewport_x; - viewport.TopLeftY = game_viewport_y; - viewport.Width = game_viewport_width; - viewport.Height = game_viewport_height; - //viewport.MinDepth = 0; - viewport.MaxDepth = 1; - d3dc->RSSetViewports(1, &viewport); - - return true; -} \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 RenderD3D11.h --- a/RenderD3D11.h Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,172 +0,0 @@ -#pragma once - -#include -#include - -#include "lib\legacy_dx\d3d.h" -#include - -#include "OSWindow.h" -#include "RenderStruct.h" - -#include "VectorTypes.h" - -#include "IRender.h" - -struct RenderD3D11: public IRender -{ - RenderD3D11(); - virtual ~RenderD3D11(); - - static RenderD3D11 *Create() {return new RenderD3D11;} - - virtual bool Initialize(OSWindow *window); - - virtual void ClearBlack(); - virtual void PresentBlackScreen(); - - virtual void SaveWinnersCertificate(const char *a1); - virtual void ClearTarget(unsigned int uColor); - virtual void Present(); - - virtual void _49FD3A_fullscreen(); - virtual bool InitializeFullscreen(); - - virtual void CreateZBuffer(); - virtual void Release(); - - virtual bool SwitchToWindow(); - virtual void RasterLine2D(signed int uX, signed int uY, signed int uZ, signed int uW, unsigned __int16 uColor); - virtual void ClearZBuffer(int a2, int a3); - virtual void SetRasterClipRect(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW); - virtual bool LockSurface_DDraw4(IDirectDrawSurface4 *pSurface, DDSURFACEDESC2 *pDesc, unsigned int uLockFlags); - virtual void GetTargetPixelFormat(DDPIXELFORMAT *pOut); - virtual void LockRenderSurface(void **pOutSurfacePtr, unsigned int *pOutPixelsPerRow); - virtual void UnlockBackBuffer(); - virtual void LockFrontBuffer(void **pOutSurface, unsigned int *pOutPixelsPerRow); - virtual void UnlockFrontBuffer(); - virtual void RestoreFrontBuffer(); - virtual void RestoreBackBuffer(); - virtual void BltToFront(RECT *pDstRect, IDirectDrawSurface *pSrcSurface, RECT *pSrcRect, unsigned int uBltFlags); - virtual void BltBackToFontFast(int a2, int a3, RECT *pSrcRect); - virtual void BeginSceneD3D(); - - virtual unsigned int GetActorTintColor(float a2, int tint, int a4, int a5, RenderBillboard *a6); - - virtual void DrawPolygon(unsigned int uNumVertices, struct Polygon *a3, ODMFace *a4, IDirect3DTexture2 *pTexture); - virtual void DrawTerrainPolygon(unsigned int uNumVertices, struct Polygon *a4, IDirect3DTexture2 *a5, bool transparent, bool clampAtTextureBorders); - virtual void DrawIndoorPolygon(unsigned int uNumVertices, struct BLVFace *a3, IDirect3DTexture2 *pHwTex, struct Texture *pTex, int uPackedID, unsigned int uColor, int a8); - - virtual void MakeParticleBillboardAndPush_BLV(RenderBillboardTransform_local0 *a2, IDirect3DTexture2 *a3, unsigned int uDiffuse, int angle); - virtual void MakeParticleBillboardAndPush_ODM(RenderBillboardTransform_local0 *a2, IDirect3DTexture2 *a3, unsigned int uDiffuse, int angle); - - virtual void DrawBillboards_And_MaybeRenderSpecialEffects_And_EndScene(); - virtual void DrawBillboard_Indoor(RenderBillboardTransform_local0 *pSoftBillboard, Sprite *pSprite, int dimming_level); - virtual void _4A4CC9_AddSomeBillboard(struct stru6_stru1_indoor_sw_billboard *a1, int diffuse); - virtual void TransformBillboardsAndSetPalettesODM(); - virtual void DrawBillboardList_BLV(); - - virtual void DrawProjectile(float srcX, float srcY, float a3, float a4, float dstX, float dstY, float a7, float a8, IDirect3DTexture2 *a9); - virtual bool LoadTexture(const char *pName, unsigned int bMipMaps, IDirectDrawSurface4 **pOutSurface, IDirect3DTexture2 **pOutTexture); - virtual bool MoveSpriteToDevice(Sprite *pSprite); - - virtual void BeginScene(); - virtual void EndScene(); - virtual void ScreenFade(unsigned int color, float t); - - virtual void SetTextureClipRect(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW); - virtual void ResetTextureClipRect(); - virtual void DrawTextureRGB(unsigned int uOutX, unsigned int uOutY, RGBTexture *a4); - virtual void CreditsTextureScroll(unsigned int pX, unsigned int pY, int move_X, int move_Y, RGBTexture *pTexture); - virtual void DrawTextureIndexed(unsigned int uX, unsigned int uY, struct Texture *a4); - - virtual void ZBuffer_Fill_2(signed int a2, signed int a3, struct Texture *pTexture, int a5); - virtual void DrawMaskToZBuffer(signed int uOutX, unsigned int uOutY, struct Texture *pTexture, int zVal); - virtual void DrawTextureTransparent(unsigned int uX, unsigned int uY, struct Texture *pTexture); - virtual void DrawAura(unsigned int a2, unsigned int a3, struct Texture *a4, struct Texture *a5, int a6, int a7, int a8); - virtual void _4A65CC(unsigned int x, unsigned int y, struct Texture *a4, struct Texture *a5, int a6, int a7, int a8); - - virtual void DrawTransparentRedShade(unsigned int a2, unsigned int a3, struct Texture *a4); - virtual void DrawTransparentGreenShade(signed int a2, signed int a3, struct Texture *pTexture); - virtual void DrawFansTransparent(const RenderVertexD3D3 *vertices, unsigned int num_vertices); - - virtual void DrawMasked(signed int a2, signed int a3, struct Texture *pTexture, unsigned __int16 mask); - virtual void GetLeather(unsigned int a2, unsigned int a3, struct Texture *a4, __int16 height); - - virtual void DrawTextPalette(int x, int y, unsigned char* font_pixels, int a5, unsigned int uFontHeight, unsigned __int16 *pPalette, int a8); - virtual void DrawText(signed int uOutX, signed int uOutY, unsigned __int8 *pFontPixels, unsigned int uCharWidth, unsigned int uCharHeight, unsigned __int16 *pFontPalette, unsigned __int16 uFaceColor, unsigned __int16 uShadowColor); - - virtual void FillRectFast(unsigned int uX, unsigned int uY, unsigned int uWidth, unsigned int uHeight, unsigned int uColor16); - virtual void _4A6DF5(unsigned __int16 *pBitmap, unsigned int uBitmapPitch, struct Vec2_int_ *pBitmapXY, void *pTarget, unsigned int uTargetPitch, Vec4_int_ *a7); - virtual void DrawTranslucent(unsigned int a2, unsigned int a3, struct Texture *a4); - - virtual void DrawBuildingsD3D(); - - virtual void DrawIndoorSky(unsigned int uNumVertices, unsigned int uFaceID); - virtual void DrawOutdoorSkyD3D(); - virtual void DrawOutdoorSkyPolygon(unsigned int uNumVertices, struct Polygon *pSkyPolygon, IDirect3DTexture2 *pTexture); - virtual void DrawIndoorSkyPolygon(signed int uNumVertices, struct Polygon *pSkyPolygon, IDirect3DTexture2 *pTexture); - - virtual void PrepareDecorationsRenderList_ODM(); - virtual void DrawSpriteObjects_ODM(); - - virtual void RenderTerrainD3D(); - - virtual void ChangeBetweenWinFullscreenModes(); - virtual bool AreRenderSurfacesOk(); - virtual bool IsGammaSupported(); - - virtual void SaveScreenshot(const char *pFilename, unsigned int width, unsigned int height); - virtual void PackScreenshot(unsigned int width, unsigned int height, void *out_data, unsigned int data_size, unsigned int *screenshot_size); - virtual void SavePCXScreenshot(); - - virtual int _46А6АС_GetActorsInViewport(int pDepth); - - virtual void BeginLightmaps(); - virtual void EndLightmaps(); - virtual void BeginLightmaps2(); - virtual void EndLightmaps2(); - virtual bool DrawLightmap(struct Lightmap *pLightmap, struct Vec3_float_ *pColorMult, float z_bias); - - virtual void BeginDecals(); - virtual void EndDecals(); - virtual void DrawDecal(struct Decal *pDecal, float z_bias); - - virtual void do_draw_debug_line_d3d(const RenderVertexD3D3 *pLineBegin, signed int sDiffuseBegin, const RenderVertexD3D3 *pLineEnd, signed int sDiffuseEnd, float z_stuff); - virtual void DrawLines(const RenderVertexD3D3 *vertices, unsigned int num_vertices); - - virtual void DrawSpecialEffectsQuad(const RenderVertexD3D3 *vertices, IDirect3DTexture2 *texture); - - virtual void am_Blt_Copy(RECT *pSrcRect, POINT *pTargetXY, int a3); - virtual void am_Blt_Chroma(RECT *pSrcRect, POINT *pTargetPoint, int a3, int blend_mode); - - public: - - virtual void WritePixel16(int x, int y, unsigned __int16 color) - { -__debugbreak(); - } - - virtual unsigned __int16 ReadPixel16(int x, int y) - { -__debugbreak(); return 0; - } - - virtual void ToggleTint() {} - virtual void ToggleColoredLights() {} - - virtual unsigned int GetRenderWidth() {return window->GetWidth();} - virtual unsigned int GetRenderHeight() {return window->GetHeight();} - - virtual void Sub01(); - - - protected: - OSWindow *window; - - IDXGISwapChain *pSwapChain; - ID3D11Device *d3dd; - ID3D11DeviceContext *d3dc; - ID3D11RenderTargetView *primary_srv; - ID3D11DepthStencilView *depth_srv; -}; diff -r 7b076fe64f23 -r 5abd8fc8f1c6 RenderStruct.h --- a/RenderStruct.h Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,348 +0,0 @@ -#pragma once - -#include -#include - -#include "lib\legacy_dx\d3d.h" -#include "OSWindow.h" - -#include "VectorTypes.h" - - -#define ErrD3D(hr) \ - do \ - { \ - extern void ErrHR(HRESULT, const char *, const char *, const char *, int); \ - ErrHR(hr, "Direct3D", __FUNCTION__, __FILE__, __LINE__); \ - } while(0) - -struct Polygon; -struct Texture; -struct RGBTexture; -struct RenderBillboardTransform_local0; -struct ODMFace; - - -unsigned __int16 Color16(unsigned __int32 r, unsigned __int32 g, unsigned __int32 b); -unsigned __int32 Color32(unsigned __int16 color16); - -/* 119 */ -#pragma pack(push, 1) -struct RenderVertexSoft -{ - inline RenderVertexSoft(): - flt_2C(0.0f) - {} - - Vec3_float_ vWorldPosition; - Vec3_float_ vWorldViewPosition; - float vWorldViewProjX; - float vWorldViewProjY; - float _rhw; - float u; - float v; - float flt_2C; -}; -#pragma pack(pop) - - - -/* 112 */ -#pragma pack(push, 1) -struct RenderVertexD3D3 -{ - Vec3_float_ pos; - float rhw; - signed int diffuse; - unsigned int specular; - Vec2_float_ texcoord; -}; -#pragma pack(pop) - -class Sprite; -class SpriteFrame; - -/* 161 */ -#pragma pack(push, 1) -struct RenderBillboard -{ - int _screenspace_x_scaler_packedfloat; - int _screenspace_y_scaler_packedfloat; - float fov_x; - float fov_y; - union - { - int sZValue; - struct - { - unsigned __int16 object_pid; - signed __int16 actual_z; - }; - }; - int field_14_actor_id; - signed __int16 HwSpriteID; - __int16 uPalette; - __int16 uIndoorSectorID; - __int16 field_1E; - __int16 world_x; - __int16 world_y; - __int16 world_z; - __int16 uScreenSpaceX; - __int16 uScreenSpaceY; - unsigned __int16 dimming_level; - signed int sTintColor; - SpriteFrame *pSpriteFrame; - - inline float GetFloatZ() const - { - return (float)object_pid / 65535.0f + (float)actual_z; - } -}; -#pragma pack(pop) - - -#pragma pack(push, 1) -struct RenderD3D__DevInfo -{ - unsigned int bIsDeviceCompatible; - char *pName; - char *pDescription; - GUID *pGUID; - unsigned int uCaps; - char *pDriverName; - char *pDeviceDesc; - char *pDDraw4DevDesc; - GUID *pDirectDrawGUID; - int uVideoMem; -}; -#pragma pack(pop) - - - -#pragma pack(push, 1) -struct RenderD3D_D3DDevDesc -{ - int field_0; - int field_4; - int field_8; - int field_C; - int field_10; - char *pDriverName; - char *pDeviceDesc; - char *pDDraw4DevDesc; - GUID *pGUID; - unsigned int uVideoMem; -}; -#pragma pack(pop) - - - - - - - - - -/* 280 */ -#pragma pack(push, 1) -struct HWLTexture -{ - inline HWLTexture(): - field_0(0), field_4(0), field_8(0), - field_C(0), field_10(0), field_14(0) - {} - - int field_0; - int field_4; - int field_8; - int field_C; - int field_10; - int field_14; - int uBufferWidth; - int uBufferHeight; - int uAreaWidth; - int uAreaHeigth; - unsigned int uWidth; - unsigned int uHeight; - int uAreaX; - int uAreaY; - unsigned __int16 *pPixels; -}; -#pragma pack(pop) - - -/* 185 */ -#pragma pack(push, 1) -struct RenderHWLContainer -{ - RenderHWLContainer(); - bool Load(const wchar_t *pFilename); - bool Release(); - - HWLTexture *LoadTexture(const char *pName, int bMipMaps); - - FILE *pFile; - uint32_t uSignature; - unsigned int uDataOffset; - unsigned int uNumItems; - char *pSpriteNames[50000]; - int pSpriteOffsets[50000]; - int bDumpDebug; - int scale_hwls_to_half; -}; -#pragma pack(pop) - - - -/* 242 */ -#pragma pack(push, 1) -struct RenderBillboardD3D -{ - inline RenderBillboardD3D(): - opacity(Transparent), - field_90(-1), - sParentBillboardID(-1), - uNumVertices(4) - {} - - enum OpacityType: unsigned __int32 - { - Transparent = 0, - Opaque_1 = 1, - Opaque_2 = 2, - Opaque_3 = 3, - NoBlend = 0xFFFFFFFF - }; - - IDirect3DTexture2 *pTexture; - unsigned int uNumVertices; - RenderVertexD3D3 pQuads[4]; - float z_order; - OpacityType opacity; - int field_90; - int sZValue; - signed int sParentBillboardID; -}; -#pragma pack(pop) - - - - -#pragma pack(push, 1) -struct RenderD3D_aux -{ - RenderD3D__DevInfo *pInfo; - RenderD3D_D3DDevDesc *ptr_4; -}; -#pragma pack(pop) - - - -/* 183 */ -#pragma pack(push, 1) -class RenderD3D -{ -public: - RenderD3D(); - - void GetAvailableDevices(RenderD3D__DevInfo **pOutDevices); - void Release(); - bool CreateDevice(unsigned int uDeviceID, int bWindowed, OSWindow *window); - unsigned int GetDeviceCaps(); - void ClearTarget(unsigned int bClearColor, unsigned int uClearColor, unsigned int bClearDepth, float z_clear); - void Present(bool bForceBlit); - bool CreateTexture(unsigned int uTextureWidth, unsigned int uTextureHeight, IDirectDrawSurface4 **pOutSurface, IDirect3DTexture2 **pOutTexture, bool bAlphaChannel, bool bMipmaps, unsigned int uMinDeviceTexDim); - void HandleLostResources(); - - - unsigned int bWindowed; - int field_4; - int field_8; - HWND hWindow; - int field_10; - int field_14; - int field_18; - RenderD3D__DevInfo *pAvailableDevices; - IDirectDraw4 *pHost; - IDirect3D3 *pDirect3D; - IUnknown *pUnk; - IDirectDrawSurface4 *pBackBuffer; - IDirectDrawSurface4 *pFrontBuffer; - IDirectDrawSurface4 *pZBuffer; - IDirect3DDevice3 *pDevice; - IDirect3DViewport3 *pViewport; - int field_40; - int field_44; - char pErrorMessage[48]; - char field_78[208]; -}; -#pragma pack(pop) -extern struct RenderVertexD3D3 pVertices[50]; - -/* 182 */ -#pragma pack(push, 1) - -#pragma pack(pop) - -bool PauseGameDrawing(); - -extern struct IDirectDrawClipper *pDDrawClipper; -extern struct IRender *pRenderer; // idb -extern struct pUnkTerrain *Unks; - - - -/* 248 */ -#pragma pack(push, 1) -struct RenderBillboardTransform_local0 -{ - void *pTarget; - int *pTargetZ; - int uScreenSpaceX; - int uScreenSpaceY; - int _screenspace_x_scaler_packedfloat; - int _screenspace_y_scaler_packedfloat; - char field_18[8]; - unsigned __int16 *pPalette; - unsigned __int16 *pPalette2; - union - { - int sZValue; - struct - { - unsigned short object_pid; - short zbuffer_depth; - }; - }; - unsigned int uFlags; // & 4 - mirror horizontally - unsigned int uTargetPitch; - unsigned int uViewportX; - unsigned int uViewportY; - unsigned int uViewportZ; - unsigned int uViewportW; - int field_44; - int sParentBillboardID; - int sTintColor; -}; -#pragma pack(pop) - - - - -extern int uNumDecorationsDrawnThisFrame; // weak -extern RenderBillboard pBillboardRenderList[500]; -extern unsigned int uNumBillboardsToDraw; -extern int uNumSpritesDrawnThisFrame; // weak - - - - -extern RenderVertexSoft array_507D30[50]; -extern RenderVertexSoft array_50AC10[50]; -extern RenderVertexSoft array_73D150[20]; - -extern RenderVertexD3D3 d3d_vertex_buffer[50]; - - -int ODM_NearClip(unsigned int uVertexID); // idb -int ODM_FarClip(unsigned int uNumVertices); \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 SaveLoad.cpp --- a/SaveLoad.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/SaveLoad.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -12,20 +12,20 @@ #include "SaveLoad.h" #include "Party.h" #include "LOD.h" -#include "Outdoor.h" +#include "Engine/Graphics/Outdoor.h" #include "AudioPlayer.h" #include "Actor.h" #include "Chest.h" #include "Timer.h" #include "GUIWindow.h" #include "GUIFont.h" -#include "Overlays.h" +#include "Engine/Graphics/Overlays.h" #include "SpriteObject.h" -#include "Viewport.h" +#include "Engine/Graphics/Viewport.h" #include "stru123.h" #include "texts.h" #include "Log.h" -#include "Level/Decoration.h" +#include "Engine/Graphics/Level/Decoration.h" #include "Game.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Spells.cpp --- a/Spells.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/Spells.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -7,7 +7,7 @@ #include "ErrorHandling.h" #include "Spells.h" -#include "Overlays.h" +#include "Engine/Graphics/Overlays.h" #include "LOD.h" #include "texts.h" @@ -15,7 +15,7 @@ #include "OurMath.h" #include "SpriteObject.h" #include "ObjectList.h" -#include "Indoor.h" +#include "Engine/Graphics/Indoor.h" #include "AudioPlayer.h" #include "Actor.h" #include "Game.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 SpriteObject.cpp --- a/SpriteObject.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/SpriteObject.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -3,22 +3,22 @@ #include #define _CRT_SECURE_NO_WARNINGS -#include "Sprites.h" -#include "BSPModel.h" +#include "Engine/Graphics/Sprites.h" +#include "Engine/Graphics/BSPModel.h" #include "SpriteObject.h" #include "Party.h" #include "TurnEngine.h" #include "OurMath.h" #include "ObjectList.h" -#include "Outdoor.h" -#include "ParticleEngine.h" +#include "Engine/Graphics/Outdoor.h" +#include "Engine/Graphics/ParticleEngine.h" #include "Timer.h" #include "Game.h" #include "LOD.h" #include "Actor.h" #include "Events.h" #include "AudioPlayer.h" -#include "Level/Decoration.h" +#include "Engine/Graphics/Level/Decoration.h" #include "MM7.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Sprites.cpp --- a/Sprites.cpp Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,813 +0,0 @@ -#define _CRTDBG_MAP_ALLOC -#include -#include - -#define _CRT_SECURE_NO_WARNINGS -#include -#include -#include "ErrorHandling.h" - -#include "Sprites.h" -#include "PaletteManager.h" -#include "LOD.h" -#include "FrameTableInc.h" - -#include "Outdoor.h" -#include "DecorationList.h" -#include "MM7.h" -#include "Actor.h" -#include "Level/Decoration.h" -#include "OurMath.h" - - - -struct SpriteFrameTable *pSpriteFrameTable; - - - - -//----- (0044D4D8) -------------------------------------------------------- -void SpriteFrameTable::ReleaseSFrames() -{ - free(this->pSpriteSFrames); - this->pSpriteSFrames = nullptr; - this->uNumSpriteFrames = 0; -} - -//----- (0044D4F6) -------------------------------------------------------- -void SpriteFrameTable::ResetSomeSpriteFlags() -{ - int v1; // esi@1 - signed int i; // edx@1 - char *v3; // eax@2 - - v1 = 0; - for ( i = 0; i < (signed int)this->uNumSpriteFrames; ++i ) - { - v3 = (char *)&this->pSpriteSFrames[v1].uFlags; - ++v1; - *v3 &= 0x7Fu; - } -} - -//----- (0044D513) -------------------------------------------------------- -void SpriteFrameTable::InitializeSprite( signed int uSpriteID ) -{ - //SpriteFrameTable *v2; // esi@1 - unsigned int v3; // ebx@3 - //char *v4; // edx@3 - //int v5; // eax@3 -// SpriteFrame *v6; // ecx@5 -// int v7; // eax@5 - __int16 v8; // ax@6 - //signed int v9; // edx@6 - //int v10; // ecx@6 -// signed int v11; // edi@10 - __int16 v12; // ax@16 -// int v13; // ecx@16 - size_t v14; // eax@19 -// signed int v15; // edi@19 -// __int16 v16; // ax@27 -// int v17; // ecx@27 -// signed int v18; // edi@29 -// SpriteFrame *v19; // eax@30 -// __int16 v20; // ax@45 -// int v21; // ecx@45 - - char Str[32]; // [sp+Ch] [bp-3Ch]@19 - char sprite_name[20]; // [sp+2Ch] [bp-1Ch]@15 - char Source[4]; // [sp+40h] [bp-8h]@19 - - - //v2 = this; - if ( uSpriteID <= this->uNumSpriteFrames ) - { - if ( uSpriteID >= 0 ) - { - v3 = uSpriteID; - - int uFlags = pSpriteSFrames[v3].uFlags; - if (!(uFlags & 0x0080)) //not loaded - { - pSpriteSFrames[v3].uFlags |= 0x80; //set loaded - while ( 1 ) - { - pSpriteSFrames[v3].uPaletteIndex = pPaletteManager->LoadPalette(pSpriteSFrames[v3].uPaletteID); - if ( uFlags & 0x10 ) //single frame per frame sequence - { - v8 = pSprites_LOD->LoadSprite(pSpriteSFrames[v3].pTextureName, pSpriteSFrames[v3].uPaletteID); - for (uint i = 0; i < 8; ++i) - { - - pSpriteSFrames[v3].pHwSpriteIDs[i] = v8; - } - - } - else if ( uFlags & 0x10000 ) - { - for (uint i = 0; i < 8; ++i) - { - switch ( i ) - { - case 3: - case 4: - case 5: - sprintf(sprite_name, "%s4", pSpriteSFrames[v3].pTextureName); - break; - case 2: - case 6: - sprintf(sprite_name, "%s2", pSpriteSFrames[v3].pTextureName); - break; - case 0: - case 1: - case 7: - sprintf(sprite_name, "%s0", pSpriteSFrames[v3].pTextureName); - break; - } - v12 = pSprites_LOD->LoadSprite(sprite_name, pSpriteSFrames[v3].uPaletteID); - - pSpriteSFrames[v3].pHwSpriteIDs[i]=v12; - } - - } - else if ( uFlags & 0x40 ) //part of monster fidgeting seq - { - strcpy(Source, "stA"); - strcpy(Str, pSpriteSFrames[v3].pTextureName); - v14 = strlen(Str); - strcpy(&Str[v14-3], Source); - for (uint i = 0; i < 8; ++i) - { - switch ( i ) - { - case 0: - sprintf(sprite_name, "%s0", pSpriteSFrames[v3].pTextureName); - break; - case 4: - sprintf(sprite_name, "%s4",&Str ); - break; - case 3: - case 5: - sprintf(sprite_name, "%s3",&Str ); - break; - case 2: - case 6: - sprintf(sprite_name, "%s2", pSpriteSFrames[v3].pTextureName); - break; - case 1: - case 7: - sprintf(sprite_name, "%s1", pSpriteSFrames[v3].pTextureName); - break; - } - v12 = pSprites_LOD->LoadSprite(sprite_name, pSpriteSFrames[v3].uPaletteID); - pSpriteSFrames[v3].pHwSpriteIDs[i]=v12; - } - } - - else - { - for (uint i = 0; i < 8; ++i) - - { - - if (((0x0100 << i) & pSpriteSFrames[v3].uFlags) ) //mirrors - { - switch ( i ) - { - case 1: - sprintf(sprite_name, "%s7", pSpriteSFrames[v3].pTextureName); - break; - case 2: - sprintf(sprite_name, "%s6", pSpriteSFrames[v3].pTextureName); - break; - case 3: - sprintf(sprite_name, "%s5", pSpriteSFrames[v3].pTextureName); - break; - case 4: - sprintf(sprite_name, "%s4", pSpriteSFrames[v3].pTextureName); - break; - - case 5: - sprintf(sprite_name, "%s3", pSpriteSFrames[v3].pTextureName); - break; - - case 6: - sprintf(sprite_name, "%s2", pSpriteSFrames[v3].pTextureName); - break; - case 7: - sprintf(sprite_name, "%s1", pSpriteSFrames[v3].pTextureName); - break; - } - } - else - { - sprintf(sprite_name, "%s%i", pSpriteSFrames[v3].pTextureName, i); - - } - v12 = pSprites_LOD->LoadSprite(sprite_name, pSpriteSFrames[v3].uPaletteID); - pSpriteSFrames[v3].pHwSpriteIDs[i]=v12; - - } - } - - if ( !(pSpriteSFrames[v3].uFlags & 1) ) - return; - ++v3; - } - } - } - } - } - -//----- (0044D813) -------------------------------------------------------- -signed int SpriteFrameTable::FastFindSprite( char *pSpriteName ) -{ - signed int result; // eax@2 - - int searchResult = BinarySearch(pSpriteName); - if ( searchResult < 0 ) - result = 0; - else - result = this->pSpriteEFrames[searchResult]; - return result; -} - -//----- (0044D83A) -------------------------------------------------------- -int SpriteFrameTable::BinarySearch( const char *pSpriteName ) -{ - int startPos = 0; - int endPos = uNumEFrames; - while ( 1 ) - { - int searchRange = endPos - startPos; - int middleFrameIndex = startPos + (endPos - startPos) / 2; - int comparisonResult = _stricmp(pSpriteName, this->pSpritePFrames[middleFrameIndex]->pIconName); - if ( !comparisonResult ) - { - return middleFrameIndex; - } - if ( startPos == endPos ) - { - return -1; - } - if ( comparisonResult >= 0 ) - { - startPos += max(((endPos - startPos) / 2), 1); - } - else{ - endPos = max(((endPos - startPos) / 2), 1) + startPos; - } - } -} - -//----- (0044D8D0) -------------------------------------------------------- -SpriteFrame *SpriteFrameTable::GetFrame(unsigned int uSpriteID, unsigned int uTime) -{ - //SpriteFrame *v3; // edi@1 - SpriteFrame *v4; // ecx@1 - //__int16 v5; // dx@2 - //int v6; // edx@3 - //unsigned int v7; // eax@3 - //char *i; // ecx@3 - //int v9; // esi@5 - //SpriteFrame *result; // eax@6 - - v4 = &pSpriteSFrames[uSpriteID]; - if (~v4->uFlags & 1 || !v4->uAnimLength) - return pSpriteSFrames + uSpriteID; - - for (uint t = (uTime / 8) % v4->uAnimLength; t > v4->uAnimTime; ++v4) - t -= v4->uAnimTime; - return v4; - - /*for (v4; v4->uAnimTime <= t; ++v4) - - v6 = (uTime / 8) % v4->uAnimLength; - //v7 = uSpriteID; - for ( i = (char *)&v4->uAnimTime; ; i += 60 ) - { - v9 = *(short *)i; - if ( v6 <= v9 ) - break; - v6 -= v9; - ++v7; - } - return &pSpriteSFrames[v7];*/ - -} - -//----- (0044D91F) -------------------------------------------------------- -SpriteFrame *SpriteFrameTable::GetFrameBy_x(unsigned int uSpriteID, signed int a3) -{ - SpriteFrame *v3; // edi@1 - SpriteFrame *v4; // esi@1 - __int16 v5; // ax@2 - int v6; // ecx@3 - int v7; // edx@3 - unsigned int v8; // eax@3 - int v9; // ecx@3 - char *i; // edx@3 - int v11; // esi@5 - SpriteFrame *result; // eax@6 - - v3 = this->pSpriteSFrames; - v4 = &v3[uSpriteID]; - if ( v4->uFlags & 1 && (v5 = v4->uAnimLength) != 0 ) - { - v6 = v5; - v7 = a3 % v5; - v8 = uSpriteID; - v9 = v6 - v7; - for ( i = (char *)&v4->uAnimTime; ; i += 60 ) - { - v11 = *(short *)i; - if ( v9 <= v11 ) - break; - v9 -= v11; - ++v8; - } - result = &v3[v8]; - } - else - { - result = &v3[uSpriteID]; - } - return result; -} - -//----- (0044D96D) -------------------------------------------------------- -void SpriteFrameTable::ToFile() -{ - SpriteFrameTable *v1; // esi@1 - FILE *v2; // eax@1 - FILE *v3; // edi@1 - - v1 = this; - v2 = fopen("data\\dsft.bin", "wb"); - v3 = v2; - if ( !v2 ) - Error("Unable to save dsft.bin!"); - fwrite(v1, 4u, 1u, v2); - fwrite(&v1->uNumEFrames, 4u, 1u, v3); - fwrite(v1->pSpriteSFrames, 0x3Cu, v1->uNumSpriteFrames, v3); - fwrite(v1->pSpriteEFrames, 2u, v1->uNumEFrames, v3); - fclose(v3); -} - -//----- (0044D9D7) -------------------------------------------------------- -void SpriteFrameTable::FromFile(void *data_mm6, void *data_mm7, void *data_mm8) -{ - uint num_mm6_frames = 0; - uint num_mm6_eframes = 0; - if (data_mm6) - { - num_mm6_frames = *(int *)data_mm6; - num_mm6_eframes = *((int *)data_mm6 + 1); - } - - uint num_mm7_frames = 0; - uint num_mm7_eframes = 0; - if (data_mm7) - { - num_mm7_frames = *(int *)data_mm7; - num_mm7_eframes = *((int *)data_mm7 + 1); - } - - uint num_mm8_frames = 0; - uint num_mm8_eframes = 0; - if (data_mm8) - { - num_mm8_frames = *(int *)data_mm8; - num_mm8_eframes = *((int *)data_mm8 + 1); - } - - uNumSpriteFrames = num_mm6_frames + num_mm7_frames + num_mm8_frames; - uNumEFrames = num_mm6_eframes + num_mm7_eframes + num_mm8_eframes; - - pSpriteSFrames = (SpriteFrame *)malloc(uNumSpriteFrames * sizeof(SpriteFrame)); - pSpriteEFrames = (__int16 *)malloc(uNumSpriteFrames * sizeof(short)); - - pSpritePFrames = (SpriteFrame **)malloc(4 * uNumSpriteFrames); - - uint mm7_frames_size = num_mm7_frames * sizeof(SpriteFrame); - memcpy(pSpriteSFrames, (char *)data_mm7 + 8, mm7_frames_size); - memcpy(pSpriteEFrames, (char *)data_mm7 + 8 + mm7_frames_size, 2 * num_mm7_eframes); - - uint mm6_frames_size = num_mm6_frames * sizeof(SpriteFrame_mm6); - for (uint i = 0; i < num_mm6_frames; ++i) - { - memcpy(pSpriteSFrames + num_mm7_frames + i, (char *)data_mm6 + 8 + i * sizeof(SpriteFrame_mm6), sizeof(SpriteFrame_mm6)); - pSpriteSFrames[num_mm7_frames + i].uAnimLength = 0; - } - memcpy(pSpriteEFrames + num_mm7_frames, (char *)data_mm6 + 8 + mm6_frames_size, 2 * num_mm6_eframes); - - uint mm8_frames_size = num_mm8_frames * sizeof(SpriteFrame); - memcpy(pSpriteSFrames + num_mm6_frames + num_mm7_frames, (char *)data_mm8 + 8, mm8_frames_size); - memcpy(pSpriteEFrames + num_mm6_frames + num_mm7_frames, (char *)data_mm8 + 8 + mm8_frames_size, 2 * num_mm8_eframes); - - //the original was using num_mmx_frames, but never accessed any element beyond num_mmx_eframes, but boing beyong eframes caused invalid memory accesses - for (uint i = 0; i < num_mm6_eframes + num_mm7_eframes + num_mm8_eframes; ++i) - pSpritePFrames[i] = &pSpriteSFrames[pSpriteEFrames[i]]; -} - -//----- (0044DA92) -------------------------------------------------------- -bool SpriteFrameTable::FromFileTxt(const char *Args) -{ - SpriteFrameTable *v2; // ebx@1 - FILE *v3; // eax@1 - unsigned int v4; // esi@3 - signed int result; // eax@10 - FILE *v6; // ST18_4@11 - char *i; // eax@11 - const char *v8; // ST20_4@14 - __int16 v9; // ax@14 - const char *v10; // ST0C_4@14 - double v11; // st7@14 - int v12; // eax@14 - const char *v13; // ST04_4@14 - __int16 v14; // ax@14 - const char *v15; // ST00_4@14 - int v16; // eax@14 - int v17; // eax@17 - int v18; // eax@23 - int v19; // eax@24 - int v20; // eax@25 - int v21; // eax@28 - int v22; // eax@29 - int j; // edi@30 - const char *v24; // esi@31 - int v25; // eax@32 - int v26; // edx@53 - int v27; // ecx@54 - int v28; // eax@55 - signed int k; // edx@58 - SpriteFrame *v30; // ecx@59 - int v31; // esi@59 - int l; // eax@60 - signed int v33; // eax@65 - int v34; // edi@66 - int v35; // esi@66 - SpriteFrame **v36; // eax@69 - int v37; // ecx@69 - SpriteFrame *v38; // edx@69 - __int16 *v39; // eax@69 - int v40; // ecx@69 - char Buf[500]; // [sp+Ch] [bp-2F0h]@3 - FrameTableTxtLine v42; // [sp+200h] [bp-FCh]@4 - FrameTableTxtLine v43; // [sp+27Ch] [bp-80h]@4 - FILE *File; // [sp+2F8h] [bp-4h]@1 - unsigned int Argsa; // [sp+304h] [bp+8h]@3 - int Argsb; // [sp+304h] [bp+8h]@59 - FILE *Argsc; // [sp+304h] [bp+8h]@67 - - v2 = this; - ReleaseSFrames(); - v3 = fopen(Args, "r"); - File = v3; - if ( !v3 ) - Error("CSpriteFrameTable::load - Unable to open file: %s.", Args); - - v4 = 0; - Argsa = 0; - if ( fgets(Buf, 490, v3) ) - { - do - { - *strchr(Buf, '\n') = 0; - memcpy(&v43, frame_table_txt_parser(Buf, &v42), sizeof(v43)); - if ( v43.uPropCount && *v43.pProperties[0] != '/' ) - ++Argsa; - } - while ( fgets(Buf, 490, File) ); - v4 = Argsa; - } - v2->uNumSpriteFrames = v4; - v2->pSpriteSFrames = (SpriteFrame *)malloc(60 * v4); - v2->pSpriteEFrames = (__int16 *)malloc(2 * v2->uNumSpriteFrames); - v2->pSpritePFrames = (SpriteFrame **)malloc(4 * v2->uNumSpriteFrames); - if ( v2->pSpriteSFrames ) - { - v6 = File; - v2->uNumSpriteFrames = 0; - fseek(v6, 0, 0); - for ( i = fgets(Buf, 490, File); i; i = fgets(Buf, 490, File) ) - { - *strchr(Buf, 10) = 0; - memcpy(&v43, frame_table_txt_parser(Buf, &v42), sizeof(v43)); - if ( v43.uPropCount && *v43.pProperties[0] != '/' ) - { - v8 = v43.pProperties[0]; - v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags = 0; - v2->pSpriteSFrames[v2->uNumSpriteFrames].uPaletteIndex = 0; - strcpy(v2->pSpriteSFrames[v2->uNumSpriteFrames].pIconName, v8); - strcpy(v2->pSpriteSFrames[v2->uNumSpriteFrames].pTextureName, v43.pProperties[1]); - v9 = atoi(v43.pProperties[3]); - v10 = v43.pProperties[4]; - v2->pSpriteSFrames[v2->uNumSpriteFrames].uPaletteID = v9; - v11 = atof(v10) * 65536.0; - v12 = abs((signed __int64)v11); - v13 = v43.pProperties[5]; - v2->pSpriteSFrames[v2->uNumSpriteFrames].scale = v12; - v14 = atoi(v13); - v15 = v43.pProperties[6]; - v2->pSpriteSFrames[v2->uNumSpriteFrames].uGlowRadius = v14; - v2->pSpriteSFrames[v2->uNumSpriteFrames].uAnimTime = atoi(v15); - v16 = (int)&v2->pSpriteSFrames[v2->uNumSpriteFrames]; - if ( *(short *)(v16 + 48) ) - *(int *)(v16 + 44) |= 2u; - if ( !_stricmp(v43.pProperties[2], "new") ) - { - v17 = (int)&v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags; - *(int *)v17 |= 4u; - v2->pSpritePFrames[v2->uNumEFrames] = &v2->pSpriteSFrames[v2->uNumSpriteFrames]; - v2->pSpriteEFrames[v2->uNumEFrames++] = LOWORD(v2->uNumSpriteFrames); - } - if ( !_stricmp(v43.pProperties[10], "1") ) - BYTE2(v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags) |= 4u; - if ( !_stricmp(v43.pProperties[11], "1") ) - BYTE2(v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags) |= 2u; - if ( !_stricmp(v43.pProperties[12], "1") ) - { - v18 = (int)&v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags; - *(int *)v18 |= 0x20u; - } - v19 = atoi(v43.pProperties[7]) - 1; - if ( v19 ) - { - v20 = v19 - 2; - if ( v20 ) - { - if ( v20 == 2 ) - BYTE1(v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags) |= 0xE0u; - } - else - { - v21 = (int)&v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags; - *(int *)v21 |= 0x1E000u; - } - } - else - { - v22 = (int)&v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags; - *(int *)v22 |= 0x10u; - } - for ( j = 13; j < v43.uPropCount; ++j ) - { - v24 = v43.pProperties[j]; - if ( _stricmp(v43.pProperties[j], "Luminous") ) - { - if ( _stricmp(v24, "Mirror0") ) - { - if ( _stricmp(v24, "Mirror1") ) - { - if ( _stricmp(v24, "Mirror2") ) - { - if ( _stricmp(v24, "Mirror3") ) - { - if ( _stricmp(v24, "Mirror4") ) - { - if ( _stricmp(v24, "Mirror5") ) - { - if ( _stricmp(v24, "Mirror6") ) - { - if ( !_stricmp(v24, "Mirror7") ) - BYTE1(v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags) |= 0x80u; - } - else - { - BYTE1(v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags) |= 0x40u; - } - } - else - { - BYTE1(v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags) |= 0x20u; - } - } - else - { - BYTE1(v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags) |= 0x10u; - } - } - else - { - BYTE1(v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags) |= 8u; - } - } - else - { - BYTE1(v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags) |= 4u; - } - } - else - { - BYTE1(v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags) |= 2u; - } - } - else - { - BYTE1(v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags) |= 1u; - } - } - else - { - v25 = (int)&v2->pSpriteSFrames[v2->uNumSpriteFrames].uFlags; - *(int *)v25 |= 2u; - } - } - ++v2->uNumSpriteFrames; - } - } - fclose(File); - v26 = 0; - if ( (signed int)(v2->uNumSpriteFrames - 1) > 0 ) - { - v27 = 0; - do - { - v28 = (int)&v2->pSpriteSFrames[v27]; - if ( !(*(char *)(v28 + 104) & 4) ) - *(int *)(v28 + 44) |= 1u; - ++v26; - ++v27; - } - while ( v26 < (signed int)(v2->uNumSpriteFrames - 1) ); - } - for ( k = 0; k < (signed int)v2->uNumSpriteFrames; *(short *)(Argsb + 56) = v31 ) - { - v30 = v2->pSpriteSFrames; - Argsb = (int)&v30[k]; - v31 = *(short *)(Argsb + 54); - if ( *(char *)(Argsb + 44) & 1 ) - { - ++k; - for ( l = (int)&v30[k]; *(char *)(l + 44) & 1; l += 60 ) - { - v31 += *(short *)(l + 54); - ++k; - } - LOWORD(v31) = v30[k].uAnimTime + v31; - } - ++k; - } - v33 = v2->uNumEFrames; - if ( v33 > 0 ) - { - v34 = 0; - v35 = 0; - File = (FILE *)1; - do - { - Argsc = File; - if ( (signed int)File < v33 ) - { - do - { - if ( _stricmp(v2->pSpritePFrames[(int)Argsc]->pIconName, v2->pSpritePFrames[v35]->pIconName) < 0 ) - { - v36 = v2->pSpritePFrames; - v37 = (int)&v36[(int)Argsc]; - v38 = *(SpriteFrame **)v37; - *(int *)v37 = (int)v36[v35]; - v2->pSpritePFrames[v35] = v38; - v39 = v2->pSpriteEFrames; - v40 = (int)&v39[(int)Argsc]; - LOWORD(v38) = *(short *)v40; - *(short *)v40 = v39[v34]; - v2->pSpriteEFrames[v34] = (signed __int16)v38; - } - Argsc = (FILE *)((char *)Argsc + 1); - } - while ( (signed int)Argsc < v2->uNumEFrames ); - } - File = (FILE *)((char *)File + 1); - v33 = v2->uNumEFrames; - ++v35; - ++v34; - } - while ( (signed int)((char *)File - 1) < v33 ); - } - result = 1; - } - else - { - MessageBoxW(nullptr, L"CSpriteFrameTable::load - Out of Memory!", nullptr, 0); - fclose(File); - result = 0; - } - return result; -} -//----- (0046E26D) -------------------------------------------------------- -void __fastcall _46E26D_collide_against_sprites(signed int a1, signed int a2) -{ - int v2; // edx@5 - unsigned __int16 *v3; // eax@5 - unsigned __int16 v4; // ax@6 - LevelDecoration *v5; // edi@7 - DecorationDesc *v6; // esi@8 - int v7; // edx@9 - int v8; // eax@9 - int v9; // ecx@11 - int v10; // ebx@13 - int v11; // esi@13 - int v12; // ebp@15 - int v13; // ebx@15 - int v14; // esi@16 - int v15; // edi@17 - int v16; // eax@17 - int v17; // esi@19 - char v18; // zf@23 - int v19; // [sp+0h] [bp-10h]@15 - unsigned __int16 *v20; // [sp+4h] [bp-Ch]@5 - int v21; // [sp+8h] [bp-8h]@15 - int v22; // [sp+Ch] [bp-4h]@13 - - if ( a1 >= 0 ) - { - if ( a1 <= 127 ) - { - if ( a2 >= 0 ) - { - if ( a2 <= 127 ) - { - v2 = a1 + (a2 << 7); - v3 = &pOutdoor->pFaceIDLIST[pOutdoor->pOMAP[v2]]; - v20 = &pOutdoor->pFaceIDLIST[pOutdoor->pOMAP[v2]]; - if ( v3 ) - { - do - { - v4 = *v3; - if ( PID_TYPE(v4) == OBJECT_Decoration) - { - v5 = &pLevelDecorations[(signed __int16)v4 >> 3]; - if (!(v5->uFlags & LEVEL_DECORATION_INVISIBLE)) - { - v6 = &pDecorationList->pDecorations[v5->uDecorationDescID]; - if (!v6->CanMoveThrough()) - { - v7 = v6->uRadius; - v8 = v5->vPosition.x; - if ( stru_721530.sMaxX <= v8 + v7 ) - { - if ( stru_721530.sMinX >= v8 - v7 ) - { - v9 = v5->vPosition.y; - if ( stru_721530.sMaxY <= v9 + v7 ) - { - if ( stru_721530.sMinY >= v9 - v7 ) - { - v10 = v6->uDecorationHeight; - v11 = v5->vPosition.z; - v22 = v10; - if ( stru_721530.sMaxZ <= v11 + v10 ) - { - if ( stru_721530.sMinZ >= v11 ) - { - v12 = v8 - stru_721530.normal.x; - v19 = v9 - stru_721530.normal.y; - v13 = stru_721530.prolly_normal_d + v7; - v21 = ((v8 - stru_721530.normal.x) * stru_721530.direction.y - - (v9 - stru_721530.normal.y) * stru_721530.direction.x) >> 16; - if ( abs(v21) <= stru_721530.prolly_normal_d + v7 ) - { - v14 = (v12 * stru_721530.direction.x + v19 * stru_721530.direction.y) >> 16; - if ( v14 > 0 ) - { - v15 = v5->vPosition.z; - v16 = stru_721530.normal.z + fixpoint_mul(stru_721530.direction.z, v14); - if ( v16 >= v15 ) - { - if ( v16 <= v22 + v15 ) - { - v17 = v14 - integer_sqrt(v13 * v13 - v21 * v21); - if ( v17 < 0 ) - v17 = 0; - if ( v17 < stru_721530.field_7C ) - { - stru_721530.field_7C = v17; - stru_721530.uFaceID = (signed __int16)*v20; - } - } - } - } - } - } - } - } - } - } - } - } - } - } - v3 = v20 + 1; - v18 = *v20 == 0; - ++v20; - } - while ( !v18 ); - } - } - } - } - } -} diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Sprites.h --- a/Sprites.h Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,88 +0,0 @@ -#pragma once - - -/* 18 */ -#pragma pack(push, 1) -class Sprite //28h -{ -public: - void Release(); - - const char *pName; //0 - int uPaletteID; //4 - struct IDirectDrawSurface4 *pTextureSurface; //8 - struct IDirect3DTexture2 *pTexture; //ch - int uAreaX; //10h - int uAreaY; //14h - int uBufferWidth; //18h - int uBufferHeight; //1ch - int uAreaWidth; //20h - int uAreaHeight; //24h -}; -#pragma pack(pop) - - -/* 42 */ -#pragma pack(push, 1) -struct SpriteFrame_mm6 -{ - char pIconName[12]; - char pTextureName[12]; //c - __int16 pHwSpriteIDs[8]; //18h - int scale; //28h - int uFlags; //2c - __int16 uGlowRadius; //30 - __int16 uPaletteID; //32 - __int16 uPaletteIndex; - __int16 uAnimTime; - //__int16 uAnimLength; - //__int16 _pad; -}; - -class SpriteFrame: public SpriteFrame_mm6 -{ -public: - __int16 uAnimLength; - __int16 _pad; -}; -#pragma pack(pop) - -/* 43 */ -#pragma pack(push, 1) -struct SpriteFrameTable -{ - //----- (0044D4BA) -------------------------------------------------------- - inline SpriteFrameTable() - { - uNumSpriteFrames = 0; - pSpriteSFrames = nullptr; - pSpritePFrames = nullptr; - pSpriteEFrames = nullptr; - } - void ToFile(); - void FromFile(void *data_mm6, void *data_mm7, void *data_mm8); - bool FromFileTxt(const char *Args); - void ReleaseSFrames(); - void ResetSomeSpriteFlags(); - void InitializeSprite(signed int uSpriteID); - signed int FastFindSprite(char *pSpriteName); - int BinarySearch(const char *pSpriteName); - SpriteFrame *GetFrame(unsigned int uSpriteID, unsigned int uTime); - SpriteFrame *GetFrameBy_x(unsigned int uSpriteID, signed int a3); - - signed int uNumSpriteFrames; - unsigned int uNumEFrames;//field_4; - int unused_field; //field_8 - SpriteFrame *pSpriteSFrames; //0c - SpriteFrame **pSpritePFrames; //10h - __int16 *pSpriteEFrames; //14h -}; -#pragma pack(pop) - - - - -void __fastcall _46E26D_collide_against_sprites(signed int a1, signed int a2); - - -extern struct SpriteFrameTable *pSpriteFrameTable; \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Texture.cpp --- a/Texture.cpp Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1960 +0,0 @@ -#define _CRTDBG_MAP_ALLOC -#include -#include - -#define _CRT_SECURE_NO_WARNINGS -#include - -#include "Texture.h" -#include "FrameTableInc.h" -#include "LOD.h" -#include "PaletteManager.h" -#include "ErrorHandling.h" -#include "ZlibWrapper.h" - -#include "mm7_data.h" - -#include "OurMath.h" - - - - - - - - -struct TextureFrameTable *pTextureFrameTable; - - - - - -std::array pTexture_LloydBeacons; -Texture *pTexture_50635C; -Texture *pTex_book_button8_off; -Texture *pTex_book_button8_on; -Texture *pTex_book_button7_off; -Texture *pTex_book_button7_on; -Texture *pTex_book_button6_off; -Texture *pTex_book_button6_on; -Texture *pTex_book_button5_off; -Texture *pTex_book_button5_on; -Texture *pTex_book_button4_off; -Texture *pTex_book_button4_on; -Texture *pTex_book_button3_off; -Texture *pTex_book_button3_on; -Texture *pTex_book_button2_off; -Texture *pTex_book_button1_off; -Texture *pTex_book_button2_on; -Texture *pTex_book_button1_on; -std::array pTexture_TownPortalIcons; // [0]Harmonale, [1]Pierpont, [2]Nighon, [3]Evenmorn Island, [4]Celestia, [5]The Pit -std::array SBPageCSpellsTextureList; -std::array SBPageSSpellsTextureList; -Texture *pSBQuickSpellBtnTextr; -Texture *pSpellBookClickCloseBtnTextr; -Texture *pSBClickQuickSpellBtnTextr; -Texture *pSpellBookCloseBtnTextr; -std::array, 9> pTextures_tabs; -Texture *pTexture_mapbordr; // idb -Texture *pTexture_pagemask; // idb -std::array pSpellBookPagesTextr; -Texture *pSpellBookPagesTextr_9; -Texture *pSpellBookPagesTextr_10; -Texture *pSpellBookPagesTextr_11; -Texture *pSpellBookPagesTextr_12; -Texture *pSpellBookPagesTextr_13; -Texture *pTexture_AutonotesBook; -Texture *pTexture_CurrentBook; -Texture *pTex_moon_new; -Texture *pTex_moon_4; -Texture *pTex_moon_2; -Texture *pTex_moon_2_2; -Texture *pTex_moon_ful; - - - -RGBTexture stru_506E40; // weak -RGBTexture pTexture_PCX; - - -int uTextureID_RestUI_restb4; // weak -int uTextureID_RestUI_restexit; // weak -int uTextureID_RestUI_restb3; // weak -int uTextureID_RestUI_restb1; // weak -int uTextureID_RestUI_restb2; // weak -int uTextureID_RestUI_restmain; // weak -unsigned int uTextureID_Leather; -int uTextureID_ar_dn_dn; // weak -int uTextureID_ar_dn_up; // weak -int uTextureID_ar_up_dn; // weak -int uTextureID_ar_up_up; // weak - - -int uTextureID_507698; // weak -int uTextureID_50769C; // weak -int uTextureID_5076A0; // weak -int uTextureID_5076A4; // weak -int uTextureID_5076A8; // weak -int uTextureID_5076AC; // weak -int uTextureID_5076B0; // weak -int uTextureID_5076B4; // weak -int uTextureID_Parchment; // weak -unsigned int uTextureID_mhp_yel; -unsigned int uTextureID_mhp_red; -unsigned int uTextureID_mhp_grn; -unsigned int uTextureID_mhp_capr; -unsigned int uTextureID_mhp_capl; -unsigned int uTextureID_mhp_bd; -unsigned int uTextureID_BUTTDESC2; -unsigned int uTextureID_x_x_u; -unsigned int uTextureID_BUTTMAKE2; -unsigned int uTextureID_BUTTMAKE; -unsigned int uTextureID_BUTTYES2; -unsigned int uTextureID_x_ok_u; -std::array pPlayerPortraits; -std::array pTexture_IC_KNIGHT; -Texture *pTexture_MAKESKY; -Texture *pTexture_MAKETOP; -std::array pTextures_arrowr; -std::array pTextures_arrowl; -Texture *pTexture_presleft; -Texture *pTexture_pressrigh; -Texture *pTexture_buttminu; -Texture *pTexture_buttplus; -unsigned int uTextureID_Quit1; // weak -unsigned int uTextureID_Resume1; // weak -unsigned int uTextureID_Controls1; // weak -unsigned int uTextureID_Save1; // weak -unsigned int uTextureID_Load1; // weak -unsigned int uTextureID_New1; // weak -unsigned int uTextureID_Options; // weak - - -unsigned int uTextureID_ib_td5_A; -unsigned int uTextureID_ib_td4_A; -unsigned int uTextureID_ib_td3_A; -unsigned int uTextureID_ib_td2_A; -unsigned int uTextureID_ib_td1_A; -int uTextureID_CharacterUI_InventoryBackground; // weak -int uTextureID_50795C; // weak - - -unsigned int uTextureID_Btn_GameSettings; - - -unsigned int uTextureID_Btn_Rest; -unsigned int uTextureID_Btn_CastSpell; -unsigned int uTextureID_Btn_ZoomIn; -unsigned int uTextureID_Btn_ZoomOut; -unsigned int uTextureID_FONTPAL; -unsigned int uTextureID_Btn_NPCRight; -unsigned int uTextureID_Btn_NPCLeft; -std::array pTextureIDs_pMapDirs; - - -unsigned int uTextureID_BarRed; -unsigned int uTextureID_BarYellow; -unsigned int uTextureID_BarGreen; -unsigned int uTextureID_BarBlue; - - -unsigned int uTextureID_right_panel; // weak - - -RGBTexture *pTexture_StatusBar = new RGBTexture; -RGBTexture *pTexture_LeftFrame = new RGBTexture; -RGBTexture *pTexture_TopFrame = new RGBTexture; -RGBTexture *pTexture_BottomFrame = new RGBTexture; -RGBTexture *pTexture_RightFrame = new RGBTexture; - - -unsigned int uTextureID_right_panel_loop; - - -Texture *pTexture_Leather; -Texture *pTexture_RestUI_CurrentSkyFrame; // idb -Texture *pTexture_RestUI_CurrentHourglassFrame; // idb - - -std::array uTextureID_Optkb; - -unsigned int optvid_base_texture_id; -unsigned int bloodsplats_texture_id; -unsigned int us_colored_lights_texture_id; -unsigned int tinting_texture_id; -unsigned int uTextureID_507C20; // weak -unsigned int uTextureID_507C24; // weak -std::array pTextureIDs_GammaPositions; -unsigned int not_available_bloodsplats_texture_id; -unsigned int not_available_us_colored_lights_texture_id; -unsigned int not_available_tinting_texture_id; - - -unsigned int uTextureID_detaliz_close_button; // weak -unsigned int uTextureID_MAGNIF_B; // weak -unsigned int uTextureID_BACKDOLL; // weak -unsigned int uTextureID_BACKHAND; // weak - -stru355 stru_4E82A4 = {0x20, 0x41, 0, 0x20, 0xFF0000, 0xFF00, 0xFF, 0xFF000000}; -stru355 stru_4EFCBC = {0x20, 0x41, 0, 0x10, 0x7C00, 0x3E0, 0x1F, 0x8000}; - -Texture pTex_F7CE30; - - -RGBTexture stru_5773C4; // idb - - - - - - - - - - - -/* 245 */ -#pragma pack(push, 1) -struct PCXHeader1 -{ - char magic; - char version; - char encoding; - char bpp; - __int16 left; - __int16 up; - __int16 right; - __int16 bottom; - __int16 hres; - __int16 vres; -}; -#pragma pack(pop) - -/* 246 */ -#pragma pack(push, 1) -struct PCXHeader2 -{ - char reserved; - char planes; - __int16 pitch; - __int16 palette_info; -}; -#pragma pack(pop) - - - - - - - - - -//----- (0044E054) -------------------------------------------------------- -void TextureFrameTable::ToFile() -{ - TextureFrameTable *v1; // esi@1 - FILE *v2; // eax@1 - FILE *v3; // edi@1 - - v1 = this; - v2 = fopen("data\\dtft.bin", "wb"); - v3 = v2; - if ( !v2 ) - Error("Unable to save dtft.bin!"); - fwrite(v1, 4u, 1u, v2); - fwrite(v1->pTextures, 0x14u, v1->sNumTextures, v3); - fclose(v3); -} - -//----- (0044E0A0) -------------------------------------------------------- -void TextureFrameTable::FromFile(void *data_mm6, void *data_mm7, void *data_mm8) -{ - uint num_mm6_frames = data_mm6 ? *(int *)data_mm6 : 0, - num_mm7_frames = data_mm7 ? *(int *)data_mm7 : 0, - num_mm8_frames = data_mm8 ? *(int *)data_mm8 : 0; - - sNumTextures = num_mm6_frames + num_mm7_frames + num_mm8_frames; - Assert(sNumTextures); - Assert(!num_mm8_frames); - - pTextures = (TextureFrame *)malloc(sNumTextures * sizeof(TextureFrame)); - - memcpy(pTextures, (char *)data_mm7 + 4, num_mm7_frames * sizeof(TextureFrame)); - memcpy(pTextures + num_mm7_frames, (char *)data_mm6 + 4, num_mm6_frames * sizeof(TextureFrame)); - memcpy(pTextures + num_mm6_frames + num_mm7_frames, (char *)data_mm8 + 4, num_mm8_frames * sizeof(TextureFrame)); -} - -//----- (0044E0ED) -------------------------------------------------------- -void TextureFrameTable::LoadAnimationSequenceAndPalettes( signed int uIconID ) -{ - //TextureFrameTable *v3; // ebx@1 - unsigned int i; // edi@3 - - //v3 = this; - if ( (uIconID <= this->sNumTextures) && uIconID >= 0 ) - { - for ( i = uIconID; ; ++i ) - { - this->pTextures[i].uTextureID = pBitmaps_LOD->LoadTexture(this->pTextures[i].pTextureName, TEXTURE_DEFAULT); - - if (this->pTextures[i].uTextureID != -1) - pBitmaps_LOD->pTextures[this->pTextures[i].uTextureID].palette_id2 = pPaletteManager->LoadPalette(pBitmaps_LOD->pTextures[this->pTextures[i].uTextureID].palette_id1); - //result = (unsigned int)v3->pTextures; - //if ( !(*(char *)(result + i * 20 + 18) & 1) ) - if( this->pTextures[i].uFlags & 1) - break; - } - } - return; -} - -//----- (0044E163) -------------------------------------------------------- -signed int TextureFrameTable::FindTextureByName(const char *Str2) -{ - if ( (signed int)this->sNumTextures <= 0 ) - return -1; - for ( int i = 0; (signed int)i < (signed int)this->sNumTextures; ++i ) - { - if ( !_stricmp(this->pTextures[i].pTextureName, Str2) ) - return i; - } - return -1; -} - -//----- (0044E19A) -------------------------------------------------------- -int TextureFrameTable::GetFrameTexture(int uFrameID, signed int a3) -{ - int v3; // esi@1 - TextureFrame *v4; // edi@1 - TextureFrame *v5; // ecx@1 - __int16 v6; // dx@2 - int v7; // edx@3 - char *i; // eax@3 - int v9; // ecx@5 - unsigned int result; // eax@6 - - v3 = uFrameID; - v4 = this->pTextures; - v5 = &v4[uFrameID]; - if ( v5->uFlags & 1 && (v6 = v5->uAnimLength) != 0 ) - { - v7 = (a3 >> 3) % v6; - for ( i = (char *)&v5->uAnimTime; ; i += 20 ) - { - v9 = *(short *)i; - if ( v7 <= v9 ) - break; - v7 -= v9; - ++v3; - } - result = v4[v3].uTextureID; - } - else - { - result = v5->uTextureID; - } - return result; -} - - - - - - -//----- (0040F806) -------------------------------------------------------- -void *Texture::UnzipPalette() -{ - Texture *v1; // esi@1 - - void *v2; // edi@1 - Texture *pSource; // [sp+0h] [bp-4h]@1 - - pSource = this; - v1 = this; - v2 = malloc(this->uDecompressedSize); - zlib::MemUnzip(v2, (unsigned int *)&pSource, v1->pLevelOfDetail0_prolly_alpha_mask, v1->uTextureSize); - return v2; -} - -//----- (0040F77C) -------------------------------------------------------- -void Texture::Release() -{ - if (this) - { - pName[0] = 0; - - if (pBits & 0x0400) - { - __debugbreak(); - } - - free(pLevelOfDetail0_prolly_alpha_mask); - free(pPalette16); - free(pPalette24); - - - pLevelOfDetail0_prolly_alpha_mask = nullptr; - pLevelOfDetail1 = nullptr; - pLevelOfDetail2 = nullptr; - pLevelOfDetail3 = nullptr; - - pPalette16 = nullptr; - pPalette24 = nullptr; - - uSizeOfMaxLevelOfDetail = 0; - uTextureSize = 0; - uTextureHeight = 0; - uTextureWidth = 0; - uHeightLn2 = 0; - uWidthLn2 = 0; - palette_id1 = 0; - palette_id2 = 0; - pBits &= 0xFFFF0000; - } -} - -//----- (0040F5F5) -------------------------------------------------------- -int RGBTexture::Reload(const char *pContainer) -{ - //RGBTexture *v2; // esi@1 - FILE *v3; // eax@3 - FILE *v4; // edi@3 - void *v5; // ebx@7 - signed int result; // eax@11 - unsigned int v7; // ecx@12 - unsigned __int16 *v8; // ST20_4@14 - int v9; // eax@14 - char color_map[48]; // [sp+8h] [bp-98h]@9 - Texture DstBuf; // [sp+38h] [bp-68h]@1 - PCXHeader1 header1; // [sp+80h] [bp-20h]@9 - PCXHeader2 header2; // [sp+90h] [bp-10h]@9 - FILE *File; // [sp+98h] [bp-8h]@3 - size_t Count; // [sp+9Ch] [bp-4h]@6 - void *uSourceLena; // [sp+A8h] [bp+8h]@7 - - // v2 = this; - if ( !this->pPixels ) - return 2; - v3 = pIcons_LOD->FindContainer(pContainer, 0); - v4 = v3; - File = v3; - if ( !v3 ) - Error("Unable to load %s", pContainer); - - fread(&DstBuf, 1, 0x30, v3); - Count = DstBuf.uTextureSize; - if ( DstBuf.uDecompressedSize ) - { - v5 = malloc(DstBuf.uDecompressedSize); - uSourceLena = malloc(DstBuf.uTextureSize); - fread(uSourceLena, 1, Count, File); - zlib::MemUnzip(v5, &DstBuf.uDecompressedSize, uSourceLena, DstBuf.uTextureSize); - DstBuf.uTextureSize = DstBuf.uDecompressedSize; - free(uSourceLena); - } - else - { - v5 = malloc(DstBuf.uTextureSize); - fread(v5, 1, Count, v4); - } - memcpy(&header1, v5, 0x10u); - memcpy(color_map, (char *)v5 + 16, 0x30); - memcpy(&header2, (char *)v5 + 64, 6); - if ( header1.bpp != 8 ) - return 3; - v7 = (signed __int16)(header1.right - header1.left + 1); - if ( (signed int)(v7 * (signed __int16)(header1.bottom - header1.up + 1)) <= (signed int)this->uNumPixels ) - { - this->uWidth = header1.right - header1.left + 1; - v8 = this->pPixels; - v9 = v7 * this->uHeight; - this->uNumPixels = v9; - this->uHeight = v9; - this->DecodePCX((char *)v5, v8, v7); - free(v5); - result = 0; - } - else - { - result = -1; - } - return result; -} - -//----- (0040F5BE) -------------------------------------------------------- -Texture::Texture() -{ - pName[0] = 0; - uSizeOfMaxLevelOfDetail = 0; - uTextureSize = 0; - uTextureHeight = 0; - uTextureWidth = 0; - uHeightLn2 = 0; - uWidthLn2 = 0; - palette_id1 = 0; - palette_id2 = 0; - pLevelOfDetail0_prolly_alpha_mask = nullptr; - pLevelOfDetail3 = nullptr; - pLevelOfDetail2 = nullptr; - pLevelOfDetail1 = nullptr; - pPalette16 = nullptr; - pPalette24 = nullptr; -} - -//----- (0040F414) -------------------------------------------------------- -int RGBTexture::Load(const char *pContainer, int mode) -{ - FILE *file; // eax@1 - void *v6; // ebx@5 - char color_map[48]; // [sp+Ch] [bp-98h]@7 - Texture DstBuf; // [sp+3Ch] [bp-68h]@1 - PCXHeader1 header1; // [sp+84h] [bp-20h]@7 - PCXHeader2 header2; // [sp+94h] [bp-10h]@7 - size_t Count; // [sp+A0h] [bp-4h]@4 - char *Str1a; // [sp+ACh] [bp+8h]@5 - - file = pIcons_LOD->FindContainer(pContainer, 0); - if ( !file ) - Error("Unable to load %s", pContainer); - - fread(&DstBuf, 1, 0x30u, file); - Count = DstBuf.uTextureSize; - if ( DstBuf.uDecompressedSize ) - { - Str1a = (char *)malloc(DstBuf.uDecompressedSize); - v6 = malloc(DstBuf.uTextureSize); - fread(v6, 1, Count, file); - zlib::MemUnzip(Str1a, &DstBuf.uDecompressedSize, v6, DstBuf.uTextureSize); - DstBuf.uTextureSize = DstBuf.uDecompressedSize; - free(v6); - } - else - { - Str1a = (char *)malloc(DstBuf.uTextureSize); - fread(Str1a, 1, Count, file); - } - memcpy(&header1, Str1a, 0x10u); - memcpy(color_map, Str1a + 16, 0x30u); - memcpy(&header2, Str1a + 64, 6); - if ( header1.bpp != 8 ) - return 3; - this->uWidth = header1.right - header1.left + 1; - this->uHeight = header1.bottom - header1.up + 1; - this->uNumPixels = (signed __int16)this->uWidth * (signed __int16)this->uHeight; - this->pPixels = (unsigned __int16 *)malloc(2 * this->uNumPixels + 4); - if ( this->pPixels ) - { - if ( mode ) - { - if ( mode != 2 ) - { - if ( !this->pPixels ) - return 2; - this->DecodePCX(Str1a, this->pPixels, this->uWidth); - free(Str1a); - return 0; - } - this->_allocation_flags |= 1; - this->pPixels = (unsigned __int16 *)malloc(2 * this->uNumPixels + 4); - if ( !this->pPixels ) - return 2; - this->DecodePCX(Str1a, this->pPixels, this->uWidth); - free(Str1a); - return 0; - } - free(this->pPixels); - } - if ( !mode ) - { - this->pPixels = (unsigned __int16 *)malloc(2 * this->uNumPixels + 4); - if ( !this->pPixels ) - return 2; - this->DecodePCX(Str1a, this->pPixels, this->uWidth); - free(Str1a); - return 0; - } - if ( mode != 2 ) - { - if ( !this->pPixels ) - return 2; - this->DecodePCX(Str1a, this->pPixels, this->uWidth); - free(Str1a); - return 0; - } - this->_allocation_flags |= 1; - this->pPixels = (unsigned __int16 *)malloc(2 * this->uNumPixels + 4); - if ( !this->pPixels ) - return 2; - this->DecodePCX(Str1a, this->pPixels, this->uWidth); - free(Str1a); - return 0; -} - -//----- (0040F037) -------------------------------------------------------- -signed int RGBTexture::DecodePCX(char *pPcx, unsigned __int16 *pOutPixels, unsigned int uNumPixels) -{ -// signed int result; // eax@2 - unsigned char test_byte; // edx@3 - unsigned int read_offset; // ebx@37 - unsigned int row_position; // edi@40 - unsigned char value; // cl@63 - char count; // [sp+50h] [bp-Ch]@43 - unsigned short current_line; // [sp+54h] [bp-8h]@38 - unsigned short *dec_position; - unsigned short *temp_dec_position; - PCXHeader1 psx_head1; - PCXHeader2 psx_head2; -// short int width, height; - BYTE color_map[48]; // Colormap for 16-color images - - - memcpy(&psx_head1, pPcx , 16); - memcpy(&color_map, pPcx + 16, 48); - memcpy(&psx_head2, pPcx + 64, 6); - - - if (psx_head1.bpp!=8) - return 3; - uWidth=(short int )(psx_head1.right-psx_head1.left+1); // word @ 000014 - uHeight=(short int )(psx_head1.bottom-psx_head1.up+1); // word @ 000016 - - - uNumPixels=uWidth*uHeight; // dword @ 000010 - - memset(pOutPixels, 0, uNumPixels * sizeof(__int16)); - short i=1; - while ( (1<= 15) - break; - } - field_18=i; - short i_=1; - while ( (1<= 15) - break; - } - field_1A=i_; - switch (field_18) - { - case 2: field_1C = 3; break; - case 3: field_1C = 7; break; - case 4: field_1C = 15; break; - case 5: field_1C = 31; break; - case 6: field_1C = 63; break; - case 7: field_1C = 127; break; - case 8: field_1C = 255; break; - case 9: field_1C = 511; break; - case 10: field_1C = 1023; break; - case 11: field_1C = 2047; break; - case 12: field_1C = 4095; break; - } - - switch (field_1A) - { - case 2: field_1E = 3; break; - case 3: field_1E = 7; break; - case 4: field_1E = 15; break; - case 5: field_1E = 31; break; - case 6: field_1E = 63; break; - case 7: field_1E = 127; break; - case 8: field_1E = 255; break; - case 9: field_1E = 511; break; - case 10: field_1E = 1023; break; - case 11: field_1E = 2047; break; - case 12: field_1E = 4095; break; - } - - unsigned int r_mask = 0xF800; - unsigned int num_r_bits = 5; - unsigned int g_mask = 0x07E0; - unsigned int num_g_bits = 6; - unsigned int b_mask = 0x001F; - unsigned int num_b_bits = 5; - //При сохранении изображения подряд идущие пиксели одинакового цвета объединяются и вместо указания цвета для каждого пикселя - //указывается цвет группы пикселей и их количество. - read_offset = 128; - if (psx_head2.planes != 3) - return 0; - current_line = 0; - if ( uHeight > 0 ) - { - dec_position = pOutPixels; - do - { - temp_dec_position = dec_position; - row_position = 0; - //decode red line - if (psx_head2.pitch) - { - do - { - test_byte = pPcx[read_offset]; - ++read_offset; - if ((test_byte & 0xC0) == 0xC0)//имеется ли объединение - { - value = pPcx[read_offset]; - ++read_offset; - - if ((test_byte & 0x3F) > 0) - { - count = test_byte & 0x3F;//количество одинаковых пикселей - do - { - ++row_position; - //*temp_dec_position =0xFF000000; - //*temp_dec_position|=(unsigned long)value<<16; - *temp_dec_position |= r_mask & ((unsigned __int8)value << (num_g_bits + num_r_bits + num_b_bits - 8)); - temp_dec_position++; - if (row_position == psx_head2.pitch) - break; - } - while (count-- != 1); - } - } - else - { - ++row_position; - //*temp_dec_position =0xFF000000; - //*temp_dec_position|= (unsigned long)test_byte<<16; - - *temp_dec_position |= r_mask & ((unsigned __int8)test_byte << (num_g_bits + num_r_bits + num_b_bits - 8)); - - temp_dec_position++; - } - - } - while (row_position < psx_head2.pitch); - } - - temp_dec_position = dec_position; - row_position=0; - //decode green line - while (row_position < psx_head2.pitch) - { - test_byte = *(pPcx + read_offset); - ++read_offset; - if ((test_byte & 0xC0) == 0xC0) - { - value = *(pPcx + read_offset); - ++read_offset; - if ((test_byte & 0x3F) > 0) - { - count = test_byte & 0x3F; - do - { - //*temp_dec_position|= (unsigned int)value<<8; - //temp_dec_position++; - - *temp_dec_position|= g_mask & (unsigned __int16)((unsigned __int8)value << (num_g_bits + num_b_bits - 8)); - - temp_dec_position++; - ++row_position; - if (row_position == psx_head2.pitch) - break; - - } - while (count-- != 1); - } - } - else - { - //*temp_dec_position |=(unsigned int) test_byte<<8; - //temp_dec_position++; - - *temp_dec_position|= g_mask & (unsigned __int16)((unsigned __int8)test_byte << (num_g_bits + num_b_bits - 8)); - temp_dec_position++; - ++row_position; - } - } - - temp_dec_position = dec_position; - row_position=0; - //decode blue line - while (row_position < psx_head2.pitch) - { - test_byte = *(pPcx + read_offset); - read_offset++; - if ((test_byte & 0xC0) == 0xC0) - { - value = *(pPcx + read_offset); - ++read_offset; - if ((test_byte & 0x3F) > 0) - { - count = test_byte & 0x3F; - do - { - //*temp_dec_position|= value; - //temp_dec_position++; - - *temp_dec_position |= value >> (8 - num_b_bits); - temp_dec_position++; - - ++row_position; - if (row_position == psx_head2.pitch) - break; - } - while (count-- != 1); - } - } - else - { - //*temp_dec_position|= test_byte; - //temp_dec_position++; - *temp_dec_position |= test_byte >> (8 - num_b_bits); - temp_dec_position++; - - ++row_position; - } - - } - ++current_line; - dec_position += uWidth; - } - while (current_line < uHeight); - } - return 0; -/* - RGBTexture *v4; // esi@1 - signed int result; // eax@2 - unsigned __int16 v6; // ax@3 - unsigned __int16 *v7; // ecx@3 - unsigned int v8; // edx@3 - signed int v9; // ecx@3 - signed int v10; // ecx@8 - signed int v11; // ebx@37 - unsigned __int16 *v12; // eax@40 - int v13; // edi@40 - int v14; // ebx@41 - char v15; // bl@42 - unsigned __int16 *v16; // eax@50 - int v17; // ebx@51 - char v18; // bl@52 - unsigned __int16 *v19; // eax@61 - unsigned __int8 v20; // dl@62 - unsigned __int8 v21; // dl@63 - unsigned __int8 v22; // cl@63 - char color_map[48]; // [sp+8h] [bp-54h]@1 - PCXHeader1 header1; // [sp+38h] [bp-24h]@1 - PCXHeader2 header2; // [sp+48h] [bp-14h]@1 - unsigned int v26; // [sp+50h] [bp-Ch]@43 - int v27; // [sp+54h] [bp-8h]@38 - unsigned __int16 *v28; // [sp+58h] [bp-4h]@3 - int pOutPixelsa; // [sp+68h] [bp+Ch]@41 - int pOutPixelsb; // [sp+68h] [bp+Ch]@51 - - v4 = this; - memcpy(&header1, pPcx, 0x10u); - memcpy(color_map, pPcx + 16, 0x30u); - memcpy(&header2, pPcx + 64, 6u); - if ( header1.bpp == 8 ) - { - v6 = header1.right - header1.left + 1; - LOWORD(v7) = header1.bottom - header1.up + 1; - v4->uWidth = v6; - v4->uHeight = (unsigned __int16)v7; - v7 = (unsigned __int16 *)(signed __int16)v7; - v28 = v7; - v4->uNumPixels = (signed __int16)v7 * (signed __int16)v6; - HIWORD(v8) = 0; - v9 = 1; - while ( 1 << v9 != (signed __int16)v6 ) - { - ++v9; - if ( v9 >= 15 ) - goto LABEL_8; - } - v4->field_18 = v9; -LABEL_8: - v10 = 1; - while ( (unsigned __int16 *)(1 << v10) != v28 ) - { - ++v10; - if ( v10 >= 15 ) - goto LABEL_13; - } - v4->field_1A = v10; -LABEL_13: - switch ( v4->field_18 ) - { - case 2: - v4->field_1C = 3; - break; - case 3: - v4->field_1C = 7; - break; - case 4: - v4->field_1C = 15; - break; - case 5: - v4->field_1C = 31; - break; - case 6: - v4->field_1C = 63; - break; - case 7: - v4->field_1C = 127; - break; - case 8: - v4->field_1C = 255; - break; - case 9: - v4->field_1C = 511; - break; - case 10: - v4->field_1C = 1023; - break; - case 11: - v4->field_1C = 2047; - break; - case 12: - v4->field_1C = 4095; - break; - default: - break; - } - switch ( v4->field_1A ) - { - case 2: - v4->field_1E = 3; - break; - case 3: - v4->field_1E = 7; - break; - case 4: - v4->field_1E = 15; - break; - case 5: - v4->field_1E = 31; - break; - case 6: - v4->field_1E = 63; - break; - case 7: - v4->field_1E = 127; - break; - case 8: - v4->field_1E = 255; - break; - case 9: - v4->field_1E = 511; - break; - case 10: - v4->field_1E = 1023; - break; - case 11: - v4->field_1E = 2047; - break; - case 12: - v4->field_1E = 4095; - break; - default: - break; - } - v11 = 128; - if ( header2.planes == 3 ) - { - v27 = 0; - if ( (signed int)v28 > 0 ) - { - v28 = pOutPixels; - do - { - v12 = v28; - v13 = 0; - if ( header2.pitch ) - { - do - { - LOBYTE(v8) = pPcx[v11]; - v14 = v11 + 1; - pOutPixelsa = v14; - if ( (v8 & 0xC0) == -64 ) - { - pOutPixelsa = v14 + 1; - v15 = pPcx[v14]; - if ( (signed int)(v8 & 0x3F) > 0 ) - { - v26 = v8 & 0x3F; - do - { - ++v13; - *v12 = LOWORD(pRenderer->uTargetRMask) & ((unsigned __int8)v15 << (LOBYTE(pRenderer->uTargetGBits) - + LOBYTE(pRenderer->uTargetRBits) - + LOBYTE(pRenderer->uTargetBBits) - - 8)); - ++v12; - if ( v13 == (unsigned __int16)header2.pitch ) - v12 = &v12[uNumPixels - (unsigned __int16)header2.pitch - 1]; - --v26; - } - while ( v26 ); - } - } - else - { - LOWORD(v8) = (unsigned __int8)v8; - v8 = pRenderer->uTargetRMask & (v8 << (LOBYTE(pRenderer->uTargetGBits) - + LOBYTE(pRenderer->uTargetRBits) - + LOBYTE(pRenderer->uTargetBBits) - - 8)); - ++v13; - *v12 = v8; - ++v12; - } - v11 = pOutPixelsa; - } - while ( v13 < (unsigned __int16)header2.pitch ); - } - v16 = v28; - while ( v13 < 2 * (unsigned __int16)header2.pitch ) - { - LOBYTE(v8) = pPcx[v11]; - v17 = v11 + 1; - pOutPixelsb = v17; - if ( (v8 & 0xC0) == -64 ) - { - pOutPixelsb = v17 + 1; - v18 = pPcx[v17]; - if ( (signed int)(v8 & 0x3F) > 0 ) - { - v26 = v8 & 0x3F; - do - { - *v16 |= pRenderer->uTargetGMask & (unsigned __int16)((unsigned __int8)v18 << (LOBYTE(pRenderer->uTargetGBits) - + LOBYTE(pRenderer->uTargetBBits) - - 8)); - ++v13; - ++v16; - if ( v13 == (unsigned __int16)header2.pitch ) - v16 = &v16[uNumPixels - (unsigned __int16)header2.pitch - 1]; - --v26; - } - while ( v26 ); - } - } - else - { - LOWORD(v8) = (unsigned __int8)v8; - v8 = pRenderer->uTargetGMask & (v8 << (LOBYTE(pRenderer->uTargetGBits) + LOBYTE(pRenderer->uTargetBBits) - 8)); - *v16 |= v8; - ++v13; - ++v16; - } - v11 = pOutPixelsb; - } - v19 = v28; - while ( v13 < 3 * (unsigned __int16)header2.pitch ) - { - v20 = pPcx[v11++]; - if ( (v20 & 0xC0) == -64 ) - { - v21 = v20 & 0x3F; - v22 = pPcx[v11++]; - if ( (signed int)v21 > 0 ) - { - v26 = v21; - do - { - *v19 |= v22 >> (8 - LOBYTE(pRenderer->uTargetBBits)); - ++v13; - ++v19; - if ( v13 == (unsigned __int16)header2.pitch ) - { - v8 = uNumPixels - (unsigned __int16)header2.pitch; - v19 = &v19[uNumPixels - (unsigned __int16)header2.pitch - 1]; - } - --v26; - } - while ( v26 ); - } - } - else - { - *v19 |= v20 >> (8 - LOBYTE(pRenderer->uTargetBBits)); - ++v13; - ++v19; - } - } - ++v27; - v28 += uNumPixels; - } - while ( v27 < v4->uHeight ); - } - } - result = 0; - } - else - { - result = 3; - } - return result; - */ -} - -//----- (0040EAD8) -------------------------------------------------------- -unsigned int RGBTexture::LoadFromFILE(FILE *pFile, unsigned int mode, unsigned int bCloseFile) -{ -// signed int result; // eax@2 -// unsigned char test_byte; // edx@3 - //unsigned int read_offset; // ebx@37 -// unsigned int row_position; // edi@40 -// unsigned char value; // cl@63 -// char count; // [sp+50h] [bp-Ch]@43 -// unsigned short current_line; // [sp+54h] [bp-8h]@38 -// unsigned short *dec_position; -// unsigned short *temp_dec_position; - PCXHeader1 psx_head1; - PCXHeader2 psx_head2; -// short int width, height; - BYTE color_map[48]; // Colormap for 16-color images - - unsigned int num_r_bits = 5; - unsigned int num_g_bits = 6; - unsigned int num_b_bits = 5; - - unsigned int r_mask = 0xF800; - unsigned int g_mask = 0x07E0; - unsigned int b_mask = 0x001F; - - if (!pFile) - return 1; - - - fread(&psx_head1, 1, 16, pFile); - fread(&color_map, 1, 48, pFile); - fread(&psx_head2, 1, 6, pFile); - - if (psx_head1.bpp!=8) - return 3; - uWidth=(short int )(psx_head1.right-psx_head1.left+1); // word @ 000014 - uHeight=(short int )(psx_head1.bottom-psx_head1.up+1); // word @ 000016 - - - uNumPixels=uWidth*uHeight; // dword @ 000010 - - - if ( mode == 0 ) - { - free(pPixels); - pPixels = (unsigned __int16 *)malloc(2 * uNumPixels + 4); - } - else - { - if ( mode != 1 && mode == 2 ) - { - pPixels = (unsigned __int16 *)malloc((uNumPixels + 2) * sizeof(unsigned __int16)); - _allocation_flags |= 1; - } - } - - ushort* pOutPixels = pPixels; - - memset(pOutPixels, 0, uNumPixels * sizeof(__int16)); - - short i=1; - while ( (1<= 15) - break; - } - field_18=i; - short i_=1; - while ( (1<= 15) - break; - } - field_1A=i_; - switch (field_18) - { - case 2: field_1C = 3; break; - case 3: field_1C = 7; break; - case 4: field_1C = 15; break; - case 5: field_1C = 31; break; - case 6: field_1C = 63; break; - case 7: field_1C = 127; break; - case 8: field_1C = 255; break; - case 9: field_1C = 511; break; - case 10: field_1C = 1023; break; - case 11: field_1C = 2047; break; - case 12: field_1C = 4095; break; - } - - switch (field_1A) - { - case 2: field_1E = 3; break; - case 3: field_1E = 7; break; - case 4: field_1E = 15; break; - case 5: field_1E = 31; break; - case 6: field_1E = 63; break; - case 7: field_1E = 127; break; - case 8: field_1E = 255; break; - case 9: field_1E = 511; break; - case 10: field_1E = 1023; break; - case 11: field_1E = 2047; break; - case 12: field_1E = 4095; break; - } - - fseek(pFile, 128 - 70, SEEK_CUR); - - - for (uint y = 0; y < uHeight; ++y) - { - unsigned __int16 *pDst = pPixels + y * uWidth; - - uint x = 0; - do - { - uint ctrl = 0; - fread(&ctrl, 1, 1, pFile); - if ((ctrl & 0xC0) == 0xC0) - { - uint uNumPixels = ctrl & 0x3F; - uint clr = 0; - fread(&clr, 1, 1, pFile); - for (uint i = 0; i < uNumPixels; ++i) - pDst[x++] = r_mask & (clr << (num_g_bits + num_r_bits + num_b_bits - 8)); - } - else - { - pDst[x++] = r_mask & (ctrl << (num_g_bits + num_r_bits + num_b_bits - 8)); - } - } while (x < psx_head2.pitch); - - x = 0; - do - { - uint ctrl = 0; - fread(&ctrl, 1, 1, pFile); - if ((ctrl & 0xC0) == 0xC0) - { - uint uNumPixels = ctrl & 0x3F; - uint clr = 0; - fread(&clr, 1, 1, pFile); - for (uint i = 0; i < uNumPixels; ++i) - pDst[x++] |= g_mask & (clr << (num_g_bits + num_b_bits - 8)); - } - else - { - pDst[x++] |= g_mask & (ctrl << (num_g_bits + num_b_bits - 8)); - } - } while (x < psx_head2.pitch); - - x = 0; - do - { - uint ctrl = 0; - fread(&ctrl, 1, 1, pFile); - if ((ctrl & 0xC0) == 0xC0) - { - uint uNumPixels = ctrl & 0x3F; - uint clr = 0; - fread(&clr, 1, 1, pFile); - for (uint i = 0; i < uNumPixels; ++i) - pDst[x++] |= b_mask & (clr >> (8 - num_b_bits)); - } - else - { - pDst[x++] |= b_mask & (ctrl >> (8 - num_b_bits)); - } - } while (x < psx_head2.pitch); - } - - if (bCloseFile) - fclose(pFile); - return 0; -} - -//----- (0040E51F) -------------------------------------------------------- -void RGBTexture::Release() -{ - this->pName[0] = 0; - //if ( !(this->_allocation_flags & 1) ) - //free(this->pPixels); - //else - free(this->pPixels); - this->_allocation_flags = 0; - this->pPixels = 0; - this->uNumPixels = 0; - this->uHeight = 0; - this->uWidth = 0; - this->field_1A = 0; - this->field_18 = 0; -} - -//----- (0040E55E) -------------------------------------------------------- -int RGBTexture::LoadPCXFile(const char *Filename, unsigned int a3) -{ - signed int result; // eax@2 - char *v6; // eax@3 - int v7; // edx@3 - char v8; // cl@4 - signed int v14; // ecx@19 - signed int v15; // ecx@24 -// int v16; // eax@57 -// unsigned __int16 *v17; // ecx@57 -// unsigned __int16 *v18; // edi@57 -// signed int x; // eax@59 -// unsigned __int16 *v20; // edi@64 -// signed int v21; // eax@66 -// unsigned __int16 *v22; // edi@71 -// signed int v23; // eax@73 -// int v24; // eax@78 - char v25[48]; // [sp+Ch] [bp-54h]@3 - PCXHeader1 pcx_header1; - PCXHeader2 pcx_header2; - int y; // [sp+54h] [bp-Ch]@3 - FILE *File; // [sp+5Ch] [bp-4h]@1 - - unsigned int num_r_bits = 5; - unsigned int num_g_bits = 6; - unsigned int num_b_bits = 5; - - unsigned int r_mask = 0xF800; - unsigned int g_mask = 0x07E0; - unsigned int b_mask = 0x001F; - - - File = fopen(Filename, "rb"); - if ( !File ) - return 1; - - fread(&pcx_header1, sizeof(pcx_header1), 1, File); - fread(&v25,48,1,File); - fread(&pcx_header2, 4, 1, File); - - v6 = (char *)Filename; - v7 = (char *)this - Filename; - uint i = 0; - for ( i; i < 15; ++i ) - { - v8 = *v6; - if ( !*v6 ) - break; - if ( v8 == 46 ) - break; - (v6++)[v7] = v8; - } - this->pName[i] = 0; - if ( pcx_header1.bpp != 8 ) - return 3; - this->uWidth = pcx_header1.right - pcx_header1.left + 1; - this->uHeight = pcx_header1.bottom - pcx_header1.up + 1; - this->uNumPixels = (signed __int16)this->uWidth * (signed __int16)this->uHeight; - if ( !a3 ) - { - free(this->pPixels); - this->pPixels = (unsigned __int16 *)malloc(2 * this->uNumPixels + 4); - } - if ( a3 == 2 ) - { - this->_allocation_flags |= 1; - this->pPixels = (unsigned __int16 *)malloc((uNumPixels + 2) * sizeof(unsigned __int16)); - } - if ( this->pPixels ) - { - for ( v14 = 1; v14 < 15; ++v14 ) - { - if ( 1 << v14 == this->uWidth ) - this->field_18 = v14; - } - for ( v15 = 1; v15 < 15; ++v15 ) - { - if ( 1 << v15 == this->uHeight ) - this->field_1A = v15; - } - switch ( this->field_18 ) - { - case 2: this->field_1C = 3; break; - case 3: this->field_1C = 7; break; - case 4: this->field_1C = 15; break; - case 5: this->field_1C = 31; break; - case 6: this->field_1C = 63; break; - case 7: this->field_1C = 127; break; - case 8: this->field_1C = 255; break; - case 9: this->field_1C = 511; break; - case 10: this->field_1C = 1023; break; - case 11: this->field_1C = 2047; break; - case 12: this->field_1C = 4095; break; - default: break; - } - switch ( this->field_1A ) - { - case 2: this->field_1E = 3; break; - case 3: this->field_1E = 7; break; - case 4: this->field_1E = 15; break; - case 5: this->field_1E = 31; break; - case 6: this->field_1E = 63; break; - case 7: this->field_1E = 127; break; - case 8: this->field_1E = 255; break; - case 9: this->field_1E = 511; break; - case 10: this->field_1E = 1023; break; - case 11: this->field_1E = 2047; break; - case 12: this->field_1E = 4095; break; - default: break; - } - fseek(File, 128, 0); - ftell(File); - if ( pcx_header2.planes == 1 ) - Error("24bit PCX Only!"); - - if ( pcx_header2.planes == 3 ) - { - for ( y = 0; y < this->uHeight; ++y ) - { - unsigned __int16 *pDst = pPixels + y * uWidth; - uint x = 0; - do - { - uint ctrl = 0; - fread(&ctrl, 1, 1, File); - if ( (ctrl & 0xC0) == 0xC0 ) - { - uint uNumPixels = ctrl & 0x3F; - uint clr = 0; - ctrl &= 0x3F; - fread(&clr, 1, 1, File); - for ( uint i = 0; i < uNumPixels; ++i ) - pDst[x++] = r_mask & (clr << (num_r_bits + num_g_bits + num_b_bits - 8)); - } - else - pDst[x++] = r_mask & (ctrl << (num_g_bits + num_r_bits + num_b_bits - 8)); - } - while ( x < pcx_header2.pitch ); - - x = 0; - do - { - uint ctrl = 0; - fread(&ctrl, 1, 1, File); - if ( (ctrl & 0xC0) == 0xC0 ) - { - uint uNumPixels = ctrl & 0x3F; - uint clr = 0; - ctrl &= 0x3F; - fread(&clr, 1, 1, File); - for ( uint i = 0; i < uNumPixels; ++i ) - pDst[x++] |= g_mask & (clr << (num_g_bits + num_b_bits - 8)); - } - else - pDst[x++] |= g_mask & (ctrl << (num_g_bits + num_b_bits - 8)); - } - while (x < pcx_header2.pitch); - - x = 0; - do - { - uint ctrl = 0; - fread(&ctrl, 1, 1, File); - if ( (ctrl & 0xC0) == 0xC0 ) - { - uint uNumPixels = ctrl & 0x3F; - uint clr = 0; - fread(&clr, 1, 1, File); - for ( uint i = 0; i < uNumPixels; ++i ) - pDst[x++] |= b_mask & (clr >> (8 - num_b_bits)); - } - else - pDst[x++] |= b_mask & (ctrl >> (8 - num_b_bits)); - } - while (x < pcx_header2.pitch); - } - } - fclose(File); - result = 0; - } - else - { - result = 2; - } - return result; -} - -//----- (0040D73D) -------------------------------------------------------- -RGBTexture::RGBTexture() -{ - pName[0] = 0; - pPixels = 0; - uNumPixels = 0; - uHeight = 0; - uWidth = 0; - field_1A = 0; - field_18 = 0; - _allocation_flags = 0; -} -//----- (0044E1EC) -------------------------------------------------------- -int TextureFrameTable::FromFileTxt(const char *Args) -{ - TextureFrameTable *v2; // ebx@1 - FILE *v3; // eax@1 - int v4; // esi@3 - const void *v5; // ST0C_4@10 - void *v6; // eax@10 - FILE *v7; // ST0C_4@12 - char *i; // eax@12 - signed int v9; // esi@15 - int v10; // eax@17 - int v11; // edx@22 - int v12; // ecx@23 - int v13; // eax@24 - signed int j; // eax@27 - TextureFrame *v15; // edx@28 - int v16; // esi@28 - int k; // ecx@29 - char Buf; // [sp+Ch] [bp-2F8h]@3 - FrameTableTxtLine v20; // [sp+200h] [bp-104h]@4 - int v21; // [sp+27Ch] [bp-88h]@4 - char *Str1; // [sp+280h] [bp-84h]@5 - char *Str; // [sp+284h] [bp-80h]@15 - int v24; // [sp+2F8h] [bp-Ch]@3 - int v25; // [sp+2FCh] [bp-8h]@3 - FILE *File; // [sp+300h] [bp-4h]@1 - int Argsa; // [sp+30Ch] [bp+8h]@28 - - v2 = this; - v3 = fopen(Args, "r"); - File = v3; - if ( !v3 ) - Error("CTextureFrameTable::load - Unable to open file: %s.", Args); - - v4 = 0; - v24 = 0; - v25 = 1; - if ( fgets(&Buf, 490, v3) ) - { - do - { - *strchr(&Buf, 10) = 0; - memcpy(&v21, txt_file_frametable_parser(&Buf, &v20), 0x7Cu); - __debugbreak(); // warning C4700: uninitialized local variable 'Str1' used - if ( v21 && *Str1 != 47 ) - { - if ( v21 < 2 ) - Error("CTextureFrameTable::load, too few arguments, %s line %i.", Args, v25); - ++v24; - } - ++v25; - } - while ( fgets(&Buf, 490, File) ); - v4 = v24; - } - v5 = v2->pTextures; - v2->sNumTextures = v4; - v6 = malloc(20 * v4); - v2->pTextures = (TextureFrame *)v6; - if ( !v6 ) - Error("CTextureFrameTable::load - Out of Memory!"); - v7 = File; - v2->sNumTextures = 0; - fseek(v7, 0, 0); - for ( i = fgets(&Buf, 490, File); i; i = fgets(&Buf, 490, File) ) - { - *strchr(&Buf, 10) = 0; - memcpy(&v21, txt_file_frametable_parser(&Buf, &v20), 0x7Cu); - if ( v21 && *Str1 != 47 ) - { - strcpy(v2->pTextures[v2->sNumTextures].pTextureName, Str1); - __debugbreak(); // warning C4700: uninitialized local variable 'Str' used - v2->pTextures[v2->sNumTextures].uAnimTime = atoi(Str); - v9 = 2; - for ( v2->pTextures[v2->sNumTextures].uFlags = 0; v9 < v21; ++v9 ) - { - if ( !_stricmp((&Str1)[4 * v9], "New") ) - { - //v10 = (int)&v2->pTextures[v2->sNumTextures].uFlags; - v2->pTextures[v2->sNumTextures].uFlags |= 2; - } - } - ++v2->sNumTextures; - } - } - fclose(File); - v11 = 0; - if ( (signed int)(v2->sNumTextures - 1) > 0 ) - { - v12 = 0; - do - { - v13 = (int)&v2->pTextures[v12]; - if ( !(*(char *)(v13 + 38) & 2) ) - *(char *)(v13 + 18) |= 1u; - ++v11; - ++v12; - } - while ( v11 < (signed int)(v2->sNumTextures - 1) ); - } - for ( j = 0; j < (signed int)v2->sNumTextures; *(short *)(Argsa + 16) = v16 ) - { - v15 = v2->pTextures; - Argsa = (int)&v15[j]; - v16 = *(short *)(Argsa + 14); - if ( *(char *)(Argsa + 18) & 1 ) - { - ++j; - for ( k = (int)&v15[j]; *(char *)(k + 18) & 1; k += 20 ) - { - v16 += *(short *)(k + 14); - ++j; - } - LOWORD(v16) = v15[j].uAnimTime + v16; - } - ++j; - } - return 1; -} - -//----- (00451007) -------------------------------------------------------- -int stru350::sub_451007_scale_image_bicubic(unsigned short *pSrc, int srcWidth, int srcHeight, int srcPitch, //changing this to some library function might be a good idea - unsigned short *pDst, int dstWidth, int dstHeight, int dstPitch, - int a10, int a11) -{ - int result; // eax@1 - float v17; // ST3C_4@12 - float v18; // ST38_4@12 - unsigned int v19; // esi@12 - int v21; // eax@18 - unsigned int v22; // ecx@25 - unsigned int v23; // eax@29 - unsigned int heightRatioPlusOne; // [sp+Ch] [bp-7Ch]@12 - unsigned int widthRatio; // [sp+Ch] [bp-7Ch]@218 - unsigned int heightRatio; // [sp+14h] [bp-74h]@12 - unsigned int widthRatioPlusOne; // [sp+14h] [bp-74h]@218 - // int v160; // [sp+3Ch] [bp-4Ch]@13 - unsigned __int16 *v175; // [sp+4Ch] [bp-3Ch]@13 - unsigned __int16 *v193; // [sp+5Ch] [bp-2Ch]@7 - //signed int v231; // [sp+78h] [bp-10h]@7 - __int64 v240; // [sp+7Ch] [bp-Ch]@12 - unsigned int v251; // [sp+80h] [bp-8h]@218 - unsigned int v252; // [sp+84h] [bp-4h]@218 - float a6s; // [sp+A0h] [bp+18h]@218 - float a6t; // [sp+A0h] [bp+18h]@218 - unsigned int a6b; // [sp+A0h] [bp+18h]@218 - int field_0_bits; - int field_20_bits; - - int field0value = this->field_0.field_C; - switch (field0value) - { - case 8: field_0_bits = 1; - break; - case 16: field_0_bits = 2; - break; - case 32: field_0_bits = 4; - break; - default: - return field0value; - } - int field20value = this->field_20.field_C; - switch (field20value) - { - case 8: field_20_bits = 1; - break; - case 16: field_20_bits = 2; - break; - case 32: field_20_bits = 4; - break; - default: - return field20value; - } - - result = (int)pDst; - v193 = pDst; - if (dstHeight <= 0) - return result; - - //do - for (int height = 0; height < dstHeight; height++) - { - for (int width = 0; width < dstWidth; width++) - { - a6s = (double)width / (double)dstWidth * (double)srcWidth; - widthRatio = bankersRounding(a6s); - a6t = (double)(width + 1) / (double)dstWidth * (double)srcWidth; - widthRatioPlusOne = bankersRounding(a6t); - - v17 = (double)height / (double)dstHeight * (double)srcHeight; - heightRatio = bankersRounding(v17); - v18 = (double)(height + 1) / (double)dstHeight * (double)srcHeight; - heightRatioPlusOne = bankersRounding(v18); - - v251 = 0; - v19 = (heightRatioPlusOne - heightRatio) * (widthRatioPlusOne - widthRatio); - v252 = 0; - a6b = 0; - v240 = 0i64; - - v175 = (unsigned short*)((char *)pSrc + field_0_bits * (widthRatio + srcPitch * heightRatio)); - for (int heightDiff = 0; heightDiff < heightRatioPlusOne - heightRatio; heightDiff++) - { - //int ratioDiff = widthRatioPlusOne - widthRatio; - for (int ratioDiff = 0; ratioDiff < widthRatioPlusOne - widthRatio; ratioDiff++) - { - if (field0value == 32) - v21 = _450FB1(((int*)v175)[ratioDiff]); - else if (field0value == 16) - v21 = _450FB1(((_WORD*)v175)[ratioDiff]); - else if (field0value == 8) - v21 = _450FB1(((unsigned __int8*)v175)[ratioDiff]); - v240 += ((unsigned int)v21 >> 24); - a6b += BYTE2(v21); - v252 += BYTE1(v21); - v251 += (unsigned __int8)v21; - } - if (field0value == 32) - v175 += 2 * srcPitch; - else if (field0value == 16) - v175 += srcPitch; - else if (field0value == 8) - v175 = (unsigned short*)((char *)v175 + 2 * srcPitch); - } - - v22 = (unsigned int)v240 / ((heightRatioPlusOne - heightRatio) * (widthRatioPlusOne - widthRatio)); - if (v19) - { - a6b /= v19; - v252 /= v19; - v251 /= v19; - } - if (v22 != 255) - v22 &= 0x7FFFFFFFu; - v23 = _450F55(v251 | ((v252 | ((a6b | (v22 << 8)) << 8)) << 8)); - *(_DWORD *)v193 = v23; //Invalid memory access - v193 = (unsigned __int16 *)((char *)v193 + field_20_bits); - } - v193 = (unsigned __int16 *)((char *)v193 + field_20_bits * (dstPitch - dstWidth)); - //++v231; - result = height; - } - //while(v231 < dstHeight); - return result; -} - - -//----- (00450DDE) -------------------------------------------------------- -stru350 *stru350::_450DDE() -{ - _450DF1(&stru_4E82A4, &stru_4E82A4); - return this; -} - -//----- (00450DF1) -------------------------------------------------------- -bool stru350::_450DF1(const stru355 *p1, const stru355 *p2) -{ - //stru350 *v3; // esi@1 - //void *result; // eax@1 - unsigned int v5; // ecx@2 - int v6; // edi@2 - int v7; // edx@2 - unsigned int v8; // ecx@8 - int v9; // edi@8 - int v10; // edx@8 - int v11; // ecx@12 - int v12; // edi@12 - unsigned int v13; // ecx@12 - int v14; // edx@12 - int v15; // ecx@16 - unsigned int v16; // edx@16 - int v17; // ecx@16 - int v18; // edi@16 - char v19; // zf@20 - unsigned int v20; // ecx@21 - int v21; // edi@21 - int v22; // edx@21 - unsigned int v23; // ecx@27 - int v24; // edi@27 - int v25; // edx@27 - int v26; // ecx@31 - int v27; // edi@31 - unsigned int v28; // ecx@31 - int v29; // edx@31 - int v30; // ebx@35 - int v31; // ecx@35 - int v32; // edi@35 - int v33; // edx@35 - unsigned int i; // ecx@35 - int v35; // ecx@39 - unsigned int v36; // edx@39 - int v37; // ecx@39 - int v38; // ebx@39 - - //v3 = this; - memcpy(&field_0, p1, sizeof(stru355)); - memcpy(&field_20, p2, sizeof(stru355)); - //result = memcpy(&v3->field_20, p2, 0x20u); - //LOBYTE(result) = 1; - if (field_0.field_4 & 1) - { - v5 = field_0.field_1C; - v6 = 0; - v7 = 0; - while (!(v5 & 1)) - { - ++v6; - v5 >>= 1; - } - do - { - v5 >>= 1; - ++v7; - } while (v5 & 1); - field_40 = 32 - v7 - v6; - } - else - { - field_40 = 0; - } - v8 = field_0.field_10; - v9 = 0; - v10 = 0; - while (!(v8 & 1)) - { - ++v9; - v8 >>= 1; - } - do - { - v8 >>= 1; - ++v10; - } while (v8 & 1); - v11 = 24 - v10 - v9; - v12 = 0; - field_48 = v11; - v13 = field_0.field_14; - v14 = 0; - while (!(v13 & 1)) - { - ++v12; - v13 >>= 1; - } - do - { - v13 >>= 1; - ++v14; - } while (v13 & 1); - v15 = 16 - v14; - v16 = field_0.field_18; - field_50 = v15 - v12; - v17 = 0; - v18 = 0; - while (!(v16 & 1)) - { - ++v17; - v16 >>= 1; - } - do - { - v16 >>= 1; - ++v18; - } while (v16 & 1); - v19 = (field_20.field_4 & 1) == 0; - field_58 = v17 - v18 + 8; - if (v19) - { - field_44 = 0; - } - else - { - v20 = field_20.field_1C; - v21 = 0; - v22 = 0; - while (!(v20 & 1)) - { - ++v21; - v20 >>= 1; - } - do - { - v20 >>= 1; - ++v22; - } while (v20 & 1); - field_44 = 32 - v22 - v21; - } - v23 = field_20.field_10; - v24 = 0; - v25 = 0; - while (!(v23 & 1)) - { - ++v24; - v23 >>= 1; - } - do - { - v23 >>= 1; - ++v25; - } while (v23 & 1); - v26 = 24 - v25 - v24; - v27 = 0; - field_4C = v26; - v28 = field_20.field_14; - v29 = 0; - while (!(v28 & 1)) - { - ++v27; - v28 >>= 1; - } - do - { - v28 >>= 1; - ++v29; - } while (v28 & 1); - v30 = 0; - v31 = 16 - v29 - v27; - v32 = field_20.field_18; - field_54 = v31; - v33 = 0; - for (i = v32; !(i & 1); i >>= 1) - ++v30; - do - { - i >>= 1; - ++v33; - } while (i & 1); - v35 = 32 - v33; - v36 = v32; - field_5C = v35 - v30; - v37 = 0; - v38 = 0; - while (!(v36 & 1)) - { - ++v37; - v36 >>= 1; - } - do - { - v36 >>= 1; - ++v38; - } while (v36 & 1); - field_5C = v37 - v38 + 8; - return true; -} - -//----- (00450F55) -------------------------------------------------------- -unsigned int stru350::_450F55(int a2) -{ - int v2 = a2 & stru_4E82A4.field_1C; - if (field_20.field_4 & 1) - v2 = (unsigned int)v2 >> this->field_44; - return v2 & field_20.field_1C | - field_20.field_10 & ((a2 & (unsigned int)stru_4E82A4.field_10) >> field_4C) | - field_20.field_14 & ((a2 & (unsigned int)stru_4E82A4.field_14) >> field_54) | - field_20.field_18 & ((a2 & (unsigned int)stru_4E82A4.field_18) >> field_5C); -} - -//----- (00450FB1) -------------------------------------------------------- -int stru350::_450FB1(int a2) -{ - int v2 = 0; - int v4 = field_0.field_4 & 1; - if (v4) - v2 = a2 & field_0.field_1C; - if (v4) - v2 <<= field_40; - return v2 | ((a2 & field_0.field_10) << field_48) | ((a2 & field_0.field_14) << field_50) | ((a2 & field_0.field_18) << field_58); -} - diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Texture.h --- a/Texture.h Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,369 +0,0 @@ -#pragma once -#include -#include - - - -/* 194 */ -#pragma pack(push, 1) -struct RGBTexture -{ - RGBTexture(); - void Release(); - int LoadPCXFile(const char *Filename, unsigned int a3); - unsigned int LoadFromFILE(FILE *pFile, unsigned int mode, unsigned int bCloseFile); - int DecodePCX(char *pPcx, unsigned __int16 *pOutPixels, unsigned int uNumPixels); - int Load(const char *pContainer, int mode); - int Reload(const char *pContainer); - - char pName[16]; - unsigned int uNumPixels; - unsigned __int16 uWidth; - unsigned __int16 uHeight; - __int16 field_18; - __int16 field_1A; - __int16 field_1C; - __int16 field_1E; - int _allocation_flags; // & 1 - malloc, else custom allocator - unsigned __int16 *pPixels; -}; -#pragma pack(pop) - - - -#pragma pack(push, 1) -struct Texture -{ - Texture(); - void Release(); - void *UnzipPalette(); - - char pName[16]; - unsigned int uSizeOfMaxLevelOfDetail; - unsigned int uTextureSize; - unsigned __int16 uTextureWidth; - unsigned __int16 uTextureHeight; - __int16 uWidthLn2; - __int16 uHeightLn2; - __int16 uWidthMinus1; - __int16 uHeightMinus1; - short palette_id1; - short palette_id2; - unsigned int uDecompressedSize; - int pBits; - unsigned __int8 *pLevelOfDetail0_prolly_alpha_mask; - unsigned __int8 *pLevelOfDetail1; - unsigned __int8 *pLevelOfDetail2; - unsigned __int8 *pLevelOfDetail3; - unsigned __int16 *pPalette16; - unsigned __int8 *pPalette24; -}; -#pragma pack(pop) - - - - - - - - - - - - - - - - - -/* 323 */ -enum TEXTURE_FRAME_TABLE_FLAGS -{ - TEXTURE_FRAME_TABLE_MORE_FRAMES = 0x1, - TEXTURE_FRAME_TABLE_FIRST = 0x2, -}; - - - -/* 41 */ -#pragma pack(push, 1) -struct TextureFrame -{ - char pTextureName[12]; - __int16 uTextureID; - __int16 uAnimTime; - __int16 uAnimLength; - __int16 uFlags; -}; -#pragma pack(pop) - -/* 40 */ -#pragma pack(push, 1) -struct TextureFrameTable -{ - //----- (0044D4C9) -------------------------------------------------------- - inline TextureFrameTable() - { - pTextures = 0; - sNumTextures = 0; - } - int FromFileTxt(const char *Args); - void ToFile(); - void FromFile(void *data_mm6, void *data_mm7, void *data_mm8); - void LoadAnimationSequenceAndPalettes(signed int uIconID); - int GetFrameTexture(int uFrameID, int time); - signed int FindTextureByName(const char *Str2); - - - signed int sNumTextures; - struct TextureFrame *pTextures; -}; -#pragma pack(pop) - -extern struct TextureFrameTable *pTextureFrameTable; - - - -extern std::array pSavegameThumbnails; -extern std::array pTexture_LloydBeacons; -extern struct Texture *pTexture_50635C; -extern struct Texture *pTex_book_button8_off; -extern struct Texture *pTex_book_button8_on; -extern struct Texture *pTex_book_button7_off; -extern struct Texture *pTex_book_button7_on; -extern struct Texture *pTex_book_button6_off; -extern struct Texture *pTex_book_button6_on; -extern struct Texture *pTex_book_button5_off; -extern struct Texture *pTex_book_button5_on; -extern struct Texture *pTex_book_button4_off; -extern struct Texture *pTex_book_button4_on; -extern struct Texture *pTex_book_button3_off; -extern struct Texture *pTex_book_button3_on; -extern struct Texture *pTex_book_button2_off; -extern struct Texture *pTex_book_button1_off; -extern struct Texture *pTex_book_button2_on; -extern struct Texture *pTex_book_button1_on; -extern std::array pTexture_TownPortalIcons; // [0]Harmonale, [1]Pierpont, [2]Nighon, [3]Evenmorn Island, [4]Celestia, [5]The Pit - -extern std::array SBPageCSpellsTextureList; -extern std::array SBPageSSpellsTextureList; -extern struct Texture *pSBQuickSpellBtnTextr; -extern struct Texture *pSpellBookClickCloseBtnTextr; -extern struct Texture *pSBClickQuickSpellBtnTextr; -extern struct Texture *pSpellBookCloseBtnTextr; -extern std::array, 9> pTextures_tabs; -extern struct Texture *pTexture_mapbordr; // idb -extern struct Texture *pTexture_pagemask; // idb -extern std::array pSpellBookPagesTextr; -extern struct Texture *pSpellBookPagesTextr_9; -extern struct Texture *pSpellBookPagesTextr_10; -extern struct Texture *pSpellBookPagesTextr_11; -extern struct Texture *pSpellBookPagesTextr_12; -extern struct Texture *pSpellBookPagesTextr_13; -extern struct Texture *pTexture_AutonotesBook; -extern struct Texture *pTexture_CurrentBook; -extern struct Texture *pTex_moon_new; -extern struct Texture *pTex_moon_4; -extern struct Texture *pTex_moon_2; -extern struct Texture *pTex_moon_2_2; -extern struct Texture *pTex_moon_ful; - - - -extern RGBTexture stru_506E40; // weak -extern RGBTexture pTexture_PCX; - - -extern int uTextureID_RestUI_restb4; // weak -extern int uTextureID_RestUI_restexit; // weak -extern int uTextureID_RestUI_restb3; // weak -extern int uTextureID_RestUI_restb1; // weak -extern int uTextureID_RestUI_restb2; // weak -extern int uTextureID_RestUI_restmain; // weak -extern unsigned int uTextureID_Leather; -extern int uTextureID_ar_dn_dn; // weak -extern int uTextureID_ar_dn_up; // weak -extern int uTextureID_ar_up_dn; // weak -extern int uTextureID_ar_up_up; // weak - - -extern int uTextureID_507698; // weak -extern int uTextureID_50769C; // weak -extern int uTextureID_5076A0; // weak -extern int uTextureID_5076A4; // weak -extern int uTextureID_5076A8; // weak -extern int uTextureID_5076AC; // weak -extern int uTextureID_5076B0; // weak -extern int uTextureID_5076B4; // weak -extern int uTextureID_Parchment; // weak -extern unsigned int uTextureID_mhp_yel; -extern unsigned int uTextureID_mhp_red; -extern unsigned int uTextureID_mhp_grn; -extern unsigned int uTextureID_mhp_capr; -extern unsigned int uTextureID_mhp_capl; -extern unsigned int uTextureID_mhp_bd; -extern unsigned int uTextureID_BUTTDESC2; -extern unsigned int uTextureID_x_x_u; -extern unsigned int uTextureID_BUTTMAKE2; -extern unsigned int uTextureID_BUTTMAKE; -extern unsigned int uTextureID_BUTTYES2; -extern unsigned int uTextureID_x_ok_u; -extern std::array pPlayerPortraits; -extern std::array pTexture_IC_KNIGHT; -extern struct Texture *pTexture_MAKESKY; -extern struct Texture *pTexture_MAKETOP; -extern std::array pTextures_arrowr; -extern std::array pTextures_arrowl; -extern struct Texture *pTexture_presleft; -extern struct Texture *pTexture_pressrigh; -extern struct Texture *pTexture_buttminu; -extern struct Texture *pTexture_buttplus; -extern unsigned int uTextureID_Quit1; -extern unsigned int uTextureID_Resume1; -extern unsigned int uTextureID_Controls1; -extern unsigned int uTextureID_Save1; -extern unsigned int uTextureID_Load1; -extern unsigned int uTextureID_New1; -extern unsigned int uTextureID_Options; - - -extern unsigned int uTextureID_ib_td5_A; -extern unsigned int uTextureID_ib_td4_A; -extern unsigned int uTextureID_ib_td3_A; -extern unsigned int uTextureID_ib_td2_A; -extern unsigned int uTextureID_ib_td1_A; -extern int uTextureID_CharacterUI_InventoryBackground; // weak -extern int uTextureID_50795C; // weak - - -extern unsigned int uTextureID_Btn_GameSettings; - - -extern unsigned int uTextureID_Btn_Rest; -extern unsigned int uTextureID_Btn_CastSpell; -extern unsigned int uTextureID_Btn_ZoomIn; -extern unsigned int uTextureID_Btn_ZoomOut; -extern unsigned int uTextureID_FONTPAL; -extern unsigned int uTextureID_Btn_NPCRight; -extern unsigned int uTextureID_Btn_NPCLeft; -extern std::array pTextureIDs_pMapDirs; - - -extern unsigned int uTextureID_BarRed; -extern unsigned int uTextureID_BarYellow; -extern unsigned int uTextureID_BarGreen; -extern unsigned int uTextureID_BarBlue; - - -extern unsigned int uTextureID_right_panel; // weak - - -extern RGBTexture *pTexture_StatusBar; -extern RGBTexture *pTexture_LeftFrame; -extern RGBTexture *pTexture_TopFrame; -extern RGBTexture *pTexture_BottomFrame; -extern RGBTexture *pTexture_RightFrame; - - -extern unsigned int uTextureID_right_panel_loop; // weak - - -extern struct Texture *pTexture_Leather; -extern struct Texture *pTexture_RestUI_CurrentSkyFrame; // idb -extern struct Texture *pTexture_RestUI_CurrentHourglassFrame; // idb - - -extern std::array uTextureID_Optkb; - -extern unsigned int optvid_base_texture_id; -extern unsigned int bloodsplats_texture_id; -extern unsigned int us_colored_lights_texture_id; -extern unsigned int tinting_texture_id; -extern unsigned int uTextureID_507C20; // weak -extern unsigned int uTextureID_507C24; // weak -extern std::array pTextureIDs_GammaPositions; -extern unsigned int not_available_bloodsplats_texture_id; -extern unsigned int not_available_us_colored_lights_texture_id; -extern unsigned int not_available_tinting_texture_id; - - -struct OptionsMenuSkin -{ - OptionsMenuSkin(); - void Relaease(); - - unsigned int uTextureID_Background; // 507C60 - unsigned int uTextureID_TurnSpeed[3]; // 507C64 - unsigned int uTextureID_ArrowLeft; // 507C70 - unsigned int uTextureID_ArrowRight; // 507C74 - unsigned int uTextureID_unused_0; // 507C78 - unsigned int uTextureID_unused_1; // 507C7C - unsigned int uTextureID_unused_2; // 507C80 - unsigned int uTextureID_FlipOnExit; // 507C84 - unsigned int uTextureID_SoundLevels[10]; // 507C88 - unsigned int uTextureID_AlwaysRun; // 507CB0 - unsigned int uTextureID_WalkSound; // 507CB4 - unsigned int uTextureID_ShowDamage; // 507CB8 -}; -extern OptionsMenuSkin options_menu_skin; // 507C60 - - -extern unsigned int uTextureID_detaliz_close_button; // weak -extern unsigned int uTextureID_MAGNIF_B; // weak -extern unsigned int uTextureID_BACKDOLL; // weak -extern unsigned int uTextureID_BACKHAND; // weak - - -extern struct Texture pTex_F7CE30; - - -extern RGBTexture stru_5773C4; // idb - -extern struct stru355 stru_4E82A4;// = {0x20, 0x41, 0, 0x20, 0xFF0000, 0xFF00, 0xFF, 0xFF000000}; moved to texture.h -extern struct stru355 stru_4EFCBC;// = {0x20, 0x41, 0, 0x10, 0x7C00, 0x3E0, 0x1F, 0x8000}; moved to texture.h - - - - - - - - - -struct stru355 -{ - int field_0; - int field_4; - int field_8; - int field_C; - int field_10; - int field_14; - int field_18; - int field_1C; -}; - -/* 390 */ -#pragma pack(push, 1) -struct stru350 -{ - stru350 *_450DDE(); - bool _450DF1(const struct stru355 *p1, const struct stru355 *p2); - unsigned int _450F55(int a2); - int _450FB1(int a2); - int sub_451007_scale_image_bicubic(unsigned short *pSrc, int srcWidth, int srcHeight, int srcPitch, - unsigned short *pDst, int dstWidth, int dstHeight, int dstPitch, - int a9, int a10); - - struct stru355 field_0; - struct stru355 field_20; - int field_40; - int field_44; - int field_48; - int field_4C; - int field_50; - int field_54; - int field_58; - int field_5C; -}; -#pragma pack(pop) - diff -r 7b076fe64f23 -r 5abd8fc8f1c6 TileTable.cpp --- a/TileTable.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/TileTable.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -10,7 +10,7 @@ #include "ErrorHandling.h" #include "TileFrameTable.h" #include "FrameTableInc.h" -#include "PaletteManager.h" +#include "Engine/Graphics/PaletteManager.h" #include "LOD.h" #include "mm7_data.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 TurnEngine.cpp --- a/TurnEngine.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/TurnEngine.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -14,7 +14,7 @@ #include "Timer.h" #include "stru298.h" #include "IconFrameTable.h" -#include "Viewport.h" +#include "Engine/Graphics/Viewport.h" #include "FactionTable.h" #include "TurnEngine.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 UI/Books/UIMapBook.cpp --- a/UI/Books/UIMapBook.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/UI/Books/UIMapBook.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -2,7 +2,7 @@ #include "UIMapBook.h" #include "..\..\Events.h" #include "..\..\MM7.h" -#include "..\..\Render.h" +#include "..\..\Engine/Graphics/Render.h" #include "..\..\Mouse.h" #include "..\UIBooks.h" #include "..\..\MapInfo.h" @@ -10,12 +10,12 @@ #include "..\..\GUIFont.h" #include "..\..\Party.h" #include "..\..\AudioPlayer.h" -#include "..\..\Outdoor.h" +#include "..\..\Engine/Graphics/Outdoor.h" #include "..\..\LOD.h" -#include "..\..\Viewport.h" +#include "..\..\Engine/Graphics/Viewport.h" #include "..\..\OurMath.h" #include "..\..\texts.h" -#include "..\..\Level/Decoration.h" +#include "..\..\Engine/Graphics/Level/Decoration.h" // #include "..\..\mm7_data.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 UI/Books/UINotesBooks.cpp --- a/UI/Books/UINotesBooks.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/UI/Books/UINotesBooks.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -1,6 +1,6 @@ #define _CRT_SECURE_NO_WARNINGS #include "..\..\MM7.h" -#include "..\..\Render.h" +#include "..\..\Engine/Graphics/Render.h" #include "..\..\Mouse.h" #include "..\UIBooks.h" #include "..\..\MapInfo.h" @@ -9,7 +9,7 @@ #include "..\..\Party.h" #include "..\..\AudioPlayer.h" #include "..\..\LOD.h" -#include "..\..\Viewport.h" +#include "..\..\Engine/Graphics/Viewport.h" #include "..\..\Awards.h" #include "..\..\Autonotes.h" #include "..\..\StorylineTextTable.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 UI/Books/UISpellBook.cpp --- a/UI/Books/UISpellBook.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/UI/Books/UISpellBook.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -1,6 +1,6 @@ #define _CRT_SECURE_NO_WARNINGS #include "..\..\MM7.h" -#include "..\..\Render.h" +#include "..\..\Engine/Graphics/Render.h" #include "..\..\Mouse.h" #include "..\UIBooks.h" #include "..\..\GUIWindow.h" @@ -8,7 +8,7 @@ #include "..\..\Party.h" #include "..\..\AudioPlayer.h" #include "..\..\LOD.h" -#include "..\..\Viewport.h" +#include "..\..\Engine/Graphics/Viewport.h" #include "..\..\texts.h" #include "..\..\mm7_data.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 UI/UIArena.cpp --- a/UI/UIArena.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/UI/UIArena.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -5,17 +5,17 @@ #define _CRT_SECURE_NO_WARNINGS #include "../mm7_data.h" -#include "../Sprites.h" +#include "../Engine/Graphics/Sprites.h" #include "../GUIWindow.h" #include "../GUIFont.h" #include "../Party.h" #include "../AudioPlayer.h" -#include "../Outdoor.h" +#include "../Engine/Graphics/Outdoor.h" #include "../LOD.h" #include "../Actor.h" #include "../Events.h" -#include "../Viewport.h" +#include "../Engine/Graphics/Viewport.h" #include "../texts.h" #include "../MM7.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 UI/UIBooks.cpp --- a/UI/UIBooks.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/UI/UIBooks.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -5,7 +5,7 @@ #define _CRT_SECURE_NO_WARNINGS #include "..\MM7.h" #include "UIBooks.h" -#include "..\Render.h" +#include "..\Engine/Graphics/Render.h" #include "..\GUIWindow.h" #include "..\GUIFont.h" #include "..\AudioPlayer.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 UI/UICharacter.cpp --- a/UI/UICharacter.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/UI/UICharacter.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -13,9 +13,9 @@ #include "..\GUIProgressBar.h" #include "..\Party.h" #include "..\AudioPlayer.h" -#include "..\Render.h" +#include "..\Engine/Graphics/Render.h" #include "..\LOD.h" -#include "..\Viewport.h" +#include "..\Engine/Graphics/Viewport.h" #include "..\Timer.h" #include "..\Awards.h" #include "..\CastSpellInfo.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 UI/UIGuilds.cpp --- a/UI/UIGuilds.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/UI/UIGuilds.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -9,9 +9,9 @@ #include "..\texts.h" #include "UIHouses.h" #include "..\GUIFont.h" -#include "..\Render.h" +#include "..\Engine/Graphics/Render.h" #include "..\Party.h" -#include "..\Texture.h" +#include "..\Engine/Graphics/Texture.h" #include "..\Mouse.h" #include "..\Events2D.h" #include "..\AudioPlayer.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 UI/UIHouses.cpp --- a/UI/UIHouses.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/UI/UIHouses.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -8,31 +8,31 @@ #include "UIShops.h" #include "..\GUIButton.h" #include "..\SaveLoad.h" -#include "..\Texture.h" +#include "..\Engine/Graphics/Texture.h" #include "..\mm7_data.h" #include "..\ErrorHandling.h" #include "UIHouses.h" #include "..\Party.h" #include "..\texts.h" #include "..\Events.h" -#include "..\Arcomage.h" +#include "..\Arcomage/Arcomage.h" #include "..\LOD.h" #include "..\Mouse.h" #include "..\GUIWindow.h" #include "..\GUIFont.h" -#include "..\Overlays.h" -#include "..\Outdoor.h" +#include "..\Engine/Graphics/Overlays.h" +#include "..\Engine/Graphics/Outdoor.h" #include "..\AudioPlayer.h" #include "..\MediaPlayer.h" #include "..\Monsters.h" -#include "..\Viewport.h" +#include "..\Engine/Graphics/Viewport.h" #include "..\Keyboard.h" #include "..\MapInfo.h" #include "..\Log.h" #include "..\Game.h" #include "..\CastSpellInfo.h" -#include "../Level/Decoration.h" +#include "../Engine/Graphics/Level/Decoration.h" #include "..\stru159.h" int uHouse_ExitPic; // weak diff -r 7b076fe64f23 -r 5abd8fc8f1c6 UI/UIMainMenu.cpp --- a/UI/UIMainMenu.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/UI/UIMainMenu.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -10,9 +10,9 @@ #include "..\GUIWindow.h" #include "..\GUIFont.h" #include "..\AudioPlayer.h" -#include "..\Render.h" +#include "..\Engine/Graphics/Render.h" #include "..\LOD.h" -#include "..\PaletteManager.h" +#include "..\Engine/Graphics/PaletteManager.h" #include "..\IconFrameTable.h" #include "..\texts.h" #include"MMT.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 UI/UIOptions.cpp --- a/UI/UIOptions.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/UI/UIOptions.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -6,9 +6,9 @@ #include "..\MM7.h" #include "..\Keyboard.h" -#include "..\IndoorCameraD3D.h" -#include "..\GammaControl.h" -#include "..\Render.h" +#include "..\Engine/Graphics/IndoorCameraD3D.h" +#include "..\Engine/Graphics/GammaControl.h" +#include "..\Engine/Graphics/Render.h" #include "..\Game.h" #include "..\GUIWindow.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 UI/UIPartyCreation.cpp --- a/UI/UIPartyCreation.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/UI/UIPartyCreation.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -13,7 +13,7 @@ #include "..\GUIFont.h" #include "..\Party.h" #include "..\AudioPlayer.h" -#include "..\Render.h" +#include "..\Engine/Graphics/Render.h" #include "..\LOD.h" #include "..\Timer.h" #include "..\IconFrameTable.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 UI/UIPopup.cpp --- a/UI/UIPopup.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/UI/UIPopup.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -10,8 +10,8 @@ #include "..\Mouse.h" -#include "..\Sprites.h" -#include "..\Vis.h" +#include "..\Engine/Graphics/Sprites.h" +#include "..\Engine/Graphics/Vis.h" #include "..\Game.h" #include "..\GUIWindow.h" #include "..\GUIFont.h" @@ -19,11 +19,11 @@ #include "..\AudioPlayer.h" #include "..\LOD.h" #include "..\Actor.h" -#include "..\Viewport.h" +#include "..\Engine/Graphics/Viewport.h" #include "..\SpriteObject.h" #include "..\ObjectList.h" #include "..\Chest.h" -#include "..\PaletteManager.h" +#include "..\Engine/Graphics/PaletteManager.h" #include "..\Timer.h" #include "..\texts.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 UI/UIRest.cpp --- a/UI/UIRest.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/UI/UIRest.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -7,9 +7,9 @@ #include "..\GUIFont.h" #include "..\Party.h" #include "..\AudioPlayer.h" -#include "..\Outdoor.h" +#include "..\Engine/Graphics/Outdoor.h" #include "..\LOD.h" -#include "..\Viewport.h" +#include "..\Engine/Graphics/Viewport.h" #include "..\Timer.h" #include "..\texts.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 UI/UISaveLoad.cpp --- a/UI/UISaveLoad.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/UI/UISaveLoad.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -13,7 +13,7 @@ #include "..\MapInfo.h" #include "..\GUIWindow.h" #include "..\GUIFont.h" -#include "..\Render.h" +#include "..\Engine/Graphics/Render.h" #include "..\LOD.h" #include "..\SaveLoad.h" #include "..\texts.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 UI/UIShops.cpp --- a/UI/UIShops.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/UI/UIShops.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -10,16 +10,16 @@ #include "..\texts.h" #include "UIHouses.h" #include "..\GUIFont.h" -#include "..\Render.h" +#include "..\Engine/Graphics/Render.h" #include "..\Party.h" -#include "..\Texture.h" +#include "..\Engine/Graphics/Texture.h" #include "..\Mouse.h" #include "..\Events2D.h" #include "..\AudioPlayer.h" #include "..\MapInfo.h" -#include "..\Viewport.h" -#include "..\Outdoor.h" -#include "..\Indoor.h" +#include "..\Engine/Graphics/Viewport.h" +#include "..\Engine/Graphics/Outdoor.h" +#include "..\Engine/Graphics/Indoor.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 UI/UITransition.cpp --- a/UI/UITransition.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/UI/UITransition.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -14,7 +14,7 @@ #include "..\GUIProgressBar.h" #include "..\Party.h" #include "..\AudioPlayer.h" -#include "..\Outdoor.h" +#include "..\Engine/Graphics/Outdoor.h" #include "..\LOD.h" #include "..\Timer.h" #include "..\stru159.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 UI/UiGame.cpp --- a/UI/UiGame.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/UI/UiGame.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -4,7 +4,7 @@ #define _CRT_SECURE_NO_WARNINGS #include "..\Events.h" -#include "..\Texture.h" +#include "..\Engine/Graphics/Texture.h" #include "..\MM7.h" #include "..\ErrorHandling.h" @@ -12,20 +12,20 @@ #include "..\Keyboard.h" #include "..\mm7_data.h" -#include "..\Vis.h" +#include "..\Engine/Graphics/Vis.h" #include "..\MapInfo.h" #include "..\Game.h" #include "..\GUIWindow.h" #include "..\GUIFont.h" #include "..\Party.h" #include "..\AudioPlayer.h" -#include "..\Outdoor.h" +#include "..\Engine/Graphics/Outdoor.h" #include "..\LOD.h" #include "..\Actor.h" -#include "..\Viewport.h" +#include "..\Engine/Graphics/Viewport.h" #include "..\SpriteObject.h" #include "..\ObjectList.h" -#include "..\DecorationList.h" +#include "..\Engine/Graphics/DecorationList.h" #include "..\PlayerFrameTable.h" #include "..\stru123.h" #include "..\Timer.h" @@ -33,16 +33,16 @@ #include "..\TurnEngine.h" #include "..\texts.h" #include "UIHouses.h" -#include "..\BSPModel.h" +#include "..\Engine/Graphics/BSPModel.h" #include "..\OurMath.h" -#include "..\Level/Decoration.h" +#include "..\Engine/Graphics/Level/Decoration.h" #include "..\Chest.h" #include "UIGame.h" -#include "..\Overlays.h" +#include "..\Engine/Graphics/Overlays.h" -#include "..\Sprites.h" -#include "..\PaletteManager.h" +#include "..\Engine/Graphics/Sprites.h" +#include "..\Engine/Graphics/PaletteManager.h" int uTextureID_GameUI_CharSelectionFrame; // 50C98C diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Viewport.cpp --- a/Viewport.cpp Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,714 +0,0 @@ -#define _CRTDBG_MAP_ALLOC -#include -#include - -#define _CRT_SECURE_NO_WARNINGS -#include "Viewport.h" - - -#include "Party.h" -#include "OurMath.h" -#include "Actor.h" -#include "Outdoor.h" -#include "Events.h" -#include "Mouse.h" -#include "SpriteObject.h" -#include "ObjectList.h" -#include "DecorationList.h" -#include "texts.h" -#include "Game.h" -#include "Vis.h" -#include "LOD.h" -#include "GUIWindow.h" -#include "TurnEngine.h" -#include "stru123.h" -#include "MM7.h" -#include "Level/Decoration.h" - - -//----- (004C0262) -------------------------------------------------------- -void Viewport::SetScreen( signed int sTL_X, signed int sTL_Y, signed int sBR_X, signed int sBR_Y ) - { - unsigned int tl_x; // edx@1 - unsigned int br_x; // esi@1 - unsigned int tl_y; // edi@3 - unsigned int br_y; // eax@3 - - tl_x = sTL_X; - br_x = sBR_X; - if ( sTL_X > sBR_X ) - { - br_x = sTL_X; // swap x's - tl_x = sBR_X; - } - tl_y = sTL_Y; - br_y = sBR_Y; - if ( sTL_Y > sBR_Y ) - { - br_y = sTL_Y; // swap y's - tl_y = sBR_Y; - } - this->uScreen_TL_X = tl_x; - this->uScreen_TL_Y = tl_y; - this->uScreen_BR_X = br_x; - this->uScreen_BR_Y = br_y; - this->uScreenWidth = br_x - tl_x + 1; - this->uScreenHeight = br_y - tl_y + 1; - this->uScreenCenterX = (signed int)(br_x + tl_x) /2; - //if ( pRenderer->pRenderD3D == 0 ) - // this->uScreenCenterY = this->uScreen_BR_Y - fixpoint_mul(field_30, uScreenHeight); - //else - this->uScreenCenterY = (br_y + tl_y)/2; - SetViewport(this->uScreen_TL_X, this->uScreen_TL_Y, this->uScreen_BR_X, this->uScreen_BR_Y); - } - -//----- (004C02F8) -------------------------------------------------------- -void Viewport::SetFOV(int field_of_view) -{ - this->field_of_view = field_of_view; - SetScreen(uScreen_TL_X, uScreen_TL_Y, uScreen_BR_X, uScreen_BR_Y); -} - -//----- (004C0312) -------------------------------------------------------- -void Viewport::SetViewport( signed int sTL_X, signed int sTL_Y, signed int sBR_X, signed int sBR_Y ) - { - signed int tl_x; // ebx@1 - signed int tl_y; // edi@3 - signed int br_x; // edx@5 - signed int br_y; // eax@7 - - tl_x = sTL_X; - if ( sTL_X < this->uScreen_TL_X ) - tl_x = this->uScreen_TL_X; - tl_y = sTL_Y; - if ( sTL_Y < this->uScreen_TL_Y ) - tl_y = this->uScreen_TL_Y; - br_x = sBR_X; - if ( sBR_X > this->uScreen_BR_X ) - br_x = this->uScreen_BR_X; - br_y = sBR_Y; - if ( sBR_Y > this->uScreen_BR_Y ) - br_y = this->uScreen_BR_Y; - this->uViewportTL_Y = tl_y; - this->uViewportTL_X = tl_x; - this->uViewportBR_X = br_x; - this->uViewportBR_Y = br_y; - } - -//----- (00443219) -------------------------------------------------------- - void ViewingParams::_443219() - { - this->sViewCenterY += 512; - - AdjustPosition(); - } - -//----- (00443225) -------------------------------------------------------- -void ViewingParams::_443225() -{ - this->sViewCenterX -= 512; - - AdjustPosition(); -} - -//----- (00443231) -------------------------------------------------------- -void ViewingParams::_443231() -{ - this->sViewCenterY -= 512; - - AdjustPosition(); -} - -//----- (0044323D) -------------------------------------------------------- -void ViewingParams::_44323D() -{ - this->sViewCenterX += 512; - - AdjustPosition(); -} - -//----- (00443249) -------------------------------------------------------- -void ViewingParams::CenterOnParty() -{ - this->uMapBookMapZoom = fixpoint_mul(0x8000, this->uMapBookMapZoom); - if (this->uMapBookMapZoom < 384) - this->uMapBookMapZoom = 384; - - this->sViewCenterX = pParty->vPosition.x; - this->sViewCenterY = pParty->vPosition.y; - - AdjustPosition(); -} - -//----- (00443291) -------------------------------------------------------- -void ViewingParams::CenterOnParty2() -{ - int v2; // eax@1 - - if (uCurrentlyLoadedLevelType == LEVEL_Outdoor) - v2 = 1536; - else if (uCurrentlyLoadedLevelType == LEVEL_Indoor) - v2 = 3072; - else assert(false); - - this->uMapBookMapZoom *= 2; - if (this->uMapBookMapZoom > v2 ) - this->uMapBookMapZoom = v2; - - this->sViewCenterX = pParty->vPosition.x; - this->sViewCenterY = pParty->vPosition.y; - AdjustPosition(); -} - -//----- (004432E7) -------------------------------------------------------- -void ViewingParams::AdjustPosition() -{ - ViewingParams *v1; // esi@1 - int v2; // ebx@1 - signed int v3; // edx@1 - int v4; // ecx@1 - int v5; // edi@3 - int v6; // eax@3 - int v7; // eax@5 - - - v1 = this; - v2 = this->indoor_center_y; - v3 = 88 >> (this->uMapBookMapZoom / 384); - v4 = (44 - v3) << 9; - if ( v1->sViewCenterY > v2 + v4 ) - v1->sViewCenterY = v2 + v4; - - v5 = v1->indoor_center_x; - v6 = (v3 - 44) << 9; - if ( v1->sViewCenterX < v5 + v6 ) - v1->sViewCenterX = v5 + v6; - - v7 = v2 + v6; - if ( v1->sViewCenterY < v7 ) - v1->sViewCenterY = v7; - - if ( v1->sViewCenterX > v5 + v4 ) - v1->sViewCenterX = v5 + v4; - } - -//----- (00443343) -------------------------------------------------------- -void ViewingParams::InitGrayPalette() - { - for (unsigned short i=0; i<256; ++i) - pPalette[i]=Color16(i, i, i); - } - -//----- (00443365) -------------------------------------------------------- -void ViewingParams::_443365() -{ - Vec3_short_ *v3; // eax@4 - Vec3_short_ *v6; // eax@12 - int minimum_y; // [sp+10h] [bp-10h]@2 - int maximum_y; // [sp+14h] [bp-Ch]@2 - int minimum_x; // [sp+18h] [bp-8h]@2 - int maximum_x; // [sp+1Ch] [bp-4h]@2 - - InitGrayPalette(); - if ( uCurrentlyLoadedLevelType == LEVEL_Indoor ) - { - minimum_x = 0x40000000; - minimum_y = 0x40000000; - - maximum_x = -0x40000000; - maximum_y = -0x40000000; - for (int i=0; ipMapOutlines->uNumOutlines; ++i) - { - v3 = &pIndoor->pVertices[pIndoor->pMapOutlines->pOutlines[i].uFace1ID]; - - if ( v3->x < minimum_x ) - minimum_x = v3->x; - if ( v3->x > maximum_x ) - maximum_x = v3->x; - if ( v3->y < minimum_y ) - minimum_y = v3->x; - if ( v3->y > maximum_y ) - maximum_y = v3->x; - - v6 = &pIndoor->pVertices[pIndoor->pMapOutlines->pOutlines[i].uFace2ID]; - - if ( v6->x < minimum_x ) - minimum_x = v3->x; - if ( v6->x > maximum_x ) - maximum_x = v3->x; - - if ( v6->y < minimum_y ) - minimum_y = v3->y; - if ( v6->y > maximum_y ) - maximum_y = v3->y; - } - - uMinimapZoom = 1024; - indoor_center_x = (signed int)(minimum_x + maximum_x) / 2; - field_28 = 10; - indoor_center_y = (signed int)(minimum_y + maximum_y) / 2; - } - else - { - indoor_center_x = 0; - indoor_center_y = 0; - uMinimapZoom = _576E2C_current_minimap_zoom; - field_28 = dword_576E28; - } - uMapBookMapZoom = 384; -} -//----- (0042213C) -------------------------------------------------------- -void OnGameViewportClick() -{ - signed int v0; // ebx@2 - POINT *v1; // esi@3 - signed int v6; // eax@14 - char *v7; // esi@15 - int v9; // eax@19 - unsigned int pTextureID; // eax@19 - int pEventID; // ecx@21 - int v15; // ecx@29 -// signed int v16; // edx@30 -// int v18; // ebx@47 -// signed int v21; // eax@58 - SpriteObject a1; // [sp+Ch] [bp-80h]@1 - POINT a2; // [sp+84h] [bp-8h]@3 - - int clickable_distance = 512; - - v1 = pMouse->GetCursorPos(&a2); - //if ( pRenderer->pRenderD3D ) - v0 = pGame->pVisInstance->get_picked_object_zbuf_val(); - //else - // v0 = pRenderer->pActiveZBuffer[v1->x + pSRZBufferLineOffsets[v1->y]]; - - if ( PID_TYPE(v0) == OBJECT_Item) - { - int item_id = PID_ID(v0); - //v21 = (signed int)(unsigned __int16)v0 >> 3; - if ( !(pObjectList->pObjects[pSpriteObjects[item_id].uObjectDescID].uFlags & 0x10) && item_id < 1000 && pSpriteObjects[item_id].uObjectDescID - && (unsigned int)v0 < 0x2000000 ) - { - if ( pSpriteObjects[item_id].stru_24.GetItemEquipType() == 18 ) - { - pParty->PartyFindsGold(pSpriteObjects[item_id].stru_24.uSpecEnchantmentType, 0); - viewparams->bRedrawGameUI = 1; - } - else - { - sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[471], pItemsTable->pItems[pSpriteObjects[item_id].stru_24.uItemID].pUnidentifiedName);//You found an item (%s)! - ShowStatusBarString(pTmpBuf2.data(), 2); - if ( pSpriteObjects[item_id].stru_24.uItemID == ITEM_ARTIFACT_SPLITTER ) - _449B7E_toggle_bit(pParty->_quest_bits, 184, 1); - if ( pSpriteObjects[item_id].stru_24.uItemID == 455 ) - _449B7E_toggle_bit(pParty->_quest_bits, 185, 1); - if ( !pParty->AddItemToParty(&pSpriteObjects[item_id].stru_24) ) - pParty->SetHoldingItem(&pSpriteObjects[item_id].stru_24); - } - SpriteObject::OnInteraction(item_id); - return; - } - if ( !pParty->pPickedItem.uItemID ) - return; - __debugbreak();//no checker - v6 = 0; - a1.uType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID; - if ( (signed int)pObjectList->uNumObjects <= 0 ) - LOWORD(v6) = 0; - else - { - v7 = (char *)&pObjectList->pObjects->uObjectID; - while ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID != *(short *)v7 ) - { - ++v6; - v7 += 56; - if ( v6 >= (signed int)pObjectList->uNumObjects ) - { - LOWORD(v6) = 0; - break; - } - } - } - a1.uObjectDescID = v6; - a1.vPosition.y = pParty->vPosition.y; - a1.spell_caster_pid = OBJECT_Player; - a1.vPosition.x = pParty->vPosition.x; - a1.vPosition.z = pParty->sEyelevel + pParty->vPosition.z; - a1.uSoundID = 0; - a1.uFacing = 0; - a1.uAttributes = 8; - a1.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->sEyelevel + pParty->vPosition.z); - a1.uSpriteFrameID = 0; - memcpy(&a1.stru_24, &pParty->pPickedItem, 0x24u); - - extern int UnprojectX(int); - //v9 = UnprojectX(v1->x); - a1.Create(pParty->sRotationY + UnprojectX(v1->x), 184, 200, 0); - pTextureID = pIcons_LOD->LoadTexture(pParty->pPickedItem.GetIconName(), TEXTURE_16BIT_PALETTE); - if (pTextureID != -1) - pIcons_LOD->pTextures[pTextureID].Release(); - pMouse->RemoveHoldingItem(); - pIcons_LOD->SyncLoadedFilesCount(); - return; - } - if ( PID_TYPE(v0) == OBJECT_Actor) - { - int mon_id = PID_ID(v0); - //a2.y = v16; - if ( pActors[mon_id].uAIState == Dead ) - { - if ( (unsigned int)v0 < 0x2000000 )//distance limit for loot monster - { - pActors[mon_id].LootActor(); - return; - } - if ( !pParty->pPickedItem.uItemID ) - return; - __debugbreak();//no checker - v6 = 0; - a1.uType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID; - if ( (signed int)pObjectList->uNumObjects <= 0 ) - LOWORD(v6) = 0; - else - { - v7 = (char *)&pObjectList->pObjects->uObjectID; - while ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID != *(short *)v7 ) - { - ++v6; - v7 += 56; - if ( v6 >= (signed int)pObjectList->uNumObjects ) - { - LOWORD(v6) = 0; - break; - } - } - } - a1.uObjectDescID = v6; - a1.vPosition.y = pParty->vPosition.y; - a1.spell_caster_pid = OBJECT_Player; - a1.vPosition.x = pParty->vPosition.x; - a1.vPosition.z = pParty->sEyelevel + pParty->vPosition.z; - a1.uSoundID = 0; - a1.uFacing = 0; - a1.uAttributes = 8; - a1.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->sEyelevel + pParty->vPosition.z); - a1.uSpriteFrameID = 0; - memcpy(&a1.stru_24, &pParty->pPickedItem, 0x24u); - - extern int UnprojectX(int); - //v9 = UnprojectX(v1->x); - a1.Create(pParty->sRotationY + UnprojectX(v1->x), 184, 200, 0); - pTextureID = pIcons_LOD->LoadTexture(pParty->pPickedItem.GetIconName(), TEXTURE_16BIT_PALETTE); - if (pTextureID != -1) - pIcons_LOD->pTextures[pTextureID].Release(); - pMouse->RemoveHoldingItem(); - pIcons_LOD->SyncLoadedFilesCount(); - return; - } - if ( GetAsyncKeyState(VK_SHIFT) >= 0 ) - { - if ( !pActors[mon_id].GetActorsRelation(0) && pActors[mon_id].ActorFriend() ) - { - if ( HIWORD(v0) >= clickable_distance) - { - if ( !pParty->pPickedItem.uItemID ) - return; - __debugbreak();//no checker - v6 = 0; - a1.uType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID; - if ( (signed int)pObjectList->uNumObjects <= 0 ) - LOWORD(v6) = 0; - else - { - v7 = (char *)&pObjectList->pObjects->uObjectID; - while ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID != *(short *)v7 ) - { - ++v6; - v7 += 56; - if ( v6 >= (signed int)pObjectList->uNumObjects ) - { - LOWORD(v6) = 0; - break; - } - } - } - a1.uObjectDescID = v6; - a1.vPosition.y = pParty->vPosition.y; - a1.spell_caster_pid = OBJECT_Player; - a1.vPosition.x = pParty->vPosition.x; - a1.vPosition.z = pParty->sEyelevel + pParty->vPosition.z; - a1.uSoundID = 0; - a1.uFacing = 0; - a1.uAttributes = 8; - a1.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->sEyelevel + pParty->vPosition.z); - a1.uSpriteFrameID = 0; - memcpy(&a1.stru_24, &pParty->pPickedItem, 0x24u); - - extern int UnprojectX(int); - //v9 = UnprojectX(v1->x); - a1.Create(pParty->sRotationY + UnprojectX(v1->x), 184, 200, 0); - pTextureID = pIcons_LOD->LoadTexture(pParty->pPickedItem.GetIconName(), TEXTURE_16BIT_PALETTE); - if (pTextureID != -1) - pIcons_LOD->pTextures[pTextureID].Release(); - pMouse->RemoveHoldingItem(); - pIcons_LOD->SyncLoadedFilesCount(); - return; - } - if ( !pActors[mon_id].CanAct() ) - return; - //v18 = mon_id; - Actor::AI_FaceObject(mon_id, 4, 0, 0); - if ( !pActors[mon_id].sNPC_ID ) - { - if ( pNPCStats->pGroups_copy[pActors[mon_id].uGroup] ) - { - if ( pNPCStats->pCatchPhrases[pNPCStats->pGroups_copy[pActors[mon_id].uGroup]] ) - { - pParty->uFlags |= 2; - strcpy(byte_5B0938.data(), pNPCStats->pCatchPhrases[pNPCStats->pGroups_copy[pActors[mon_id].uGroup]]); - sub_4451A8_press_any_key(0, 0, 0); - } - } - return; - } - pMessageQueue_50CBD0->AddGUIMessage(UIMSG_StartNPCDialogue, mon_id, 0); - return; - } - if ( pParty->bTurnBasedModeOn == true && pTurnEngine->turn_stage == TE_MOVEMENT ) - { - pTurnEngine->field_18 |= TE_FLAG_8; - return; - } - pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Attack, 0, 0); - } - else - { - if ( pParty->bTurnBasedModeOn == true && pTurnEngine->turn_stage == TE_MOVEMENT ) - { - pParty->uFlags |= PARTY_FLAGS_1_FALLING; - return; - } - if ( uActiveCharacter && sub_427769_isSpellQuickCastableOnShiftClick(pPlayers[uActiveCharacter]->uQuickSpell)) - pMessageQueue_50CBD0->AddGUIMessage(UIMSG_CastQuickSpell, 0, 0); - } - return; - } - if ( PID_TYPE(v0) == OBJECT_Decoration) - { - if ( (signed int)(((unsigned int)v0 >> 16) - pDecorationList->pDecorations[pLevelDecorations[(signed int)(unsigned __int16)v0 >> 3].uDecorationDescID].uRadius) >= clickable_distance ) - { - if ( !pParty->pPickedItem.uItemID ) - return; - __debugbreak();//no checker - v6 = 0; - a1.uType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID; - if ( (signed int)pObjectList->uNumObjects <= 0 ) - LOWORD(v6) = 0; - else - { - v7 = (char *)&pObjectList->pObjects->uObjectID; - while ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID != *(short *)v7 ) - { - ++v6; - v7 += 56; - if ( v6 >= (signed int)pObjectList->uNumObjects ) - { - LOWORD(v6) = 0; - break; - } - } - } - a1.uObjectDescID = v6; - a1.vPosition.y = pParty->vPosition.y; - a1.spell_caster_pid = OBJECT_Player; - a1.vPosition.x = pParty->vPosition.x; - a1.vPosition.z = pParty->sEyelevel + pParty->vPosition.z; - a1.uSoundID = 0; - a1.uFacing = 0; - a1.uAttributes = 8; - a1.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->sEyelevel + pParty->vPosition.z); - a1.uSpriteFrameID = 0; - memcpy(&a1.stru_24, &pParty->pPickedItem, 0x24u); - - extern int UnprojectX(int); - //v9 = UnprojectX(v1->x); - a1.Create(pParty->sRotationY + UnprojectX(v1->x), 184, 200, 0); - pTextureID = pIcons_LOD->LoadTexture(pParty->pPickedItem.GetIconName(), TEXTURE_16BIT_PALETTE); - if (pTextureID != -1) - pIcons_LOD->pTextures[pTextureID].Release(); - pMouse->RemoveHoldingItem(); - pIcons_LOD->SyncLoadedFilesCount(); - return; - } - if ( !pLevelDecorations[(signed int)(unsigned __int16)v0 >> 3].uEventID ) - { - if ( pLevelDecorations[(signed int)(unsigned __int16)v0 >> 3].IsInteractive() ) - { - v15 = stru_5E4C90_MapPersistVars._decor_events[pLevelDecorations[(signed int)(unsigned __int16)v0 >> 3]._idx_in_stru123 - 75] + 380; - activeLevelDecoration = &pLevelDecorations[(signed int)(unsigned __int16)v0 >> 3]; - EventProcessor(v15, 0, 1); - activeLevelDecoration = nullptr; - } - return; - } - pEventID = pLevelDecorations[(signed int)(unsigned __int16)v0 >> 3].uEventID; - EventProcessor(pEventID, (unsigned __int16)v0, 1); - return; - } - if ( PID_TYPE(v0) == OBJECT_BModel && HIWORD(v0) < clickable_distance) - { - if ( uCurrentlyLoadedLevelType == LEVEL_Indoor) - { - if ( !pIndoor->pFaces[PID_ID(v0)].Clickable() ) - { - if ( !pParty->pPickedItem.uItemID ) - { - ShowNothingHereStatus(); - if ( !pParty->pPickedItem.uItemID ) - return; - } - __debugbreak();//no checker - v6 = 0; - a1.uType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID; - if ( (signed int)pObjectList->uNumObjects <= 0 ) - LOWORD(v6) = 0; - else - { - v7 = (char *)&pObjectList->pObjects->uObjectID; - while ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID != *(short *)v7 ) - { - ++v6; - v7 += 56; - if ( v6 >= (signed int)pObjectList->uNumObjects ) - { - LOWORD(v6) = 0; - break; - } - } - } - a1.uObjectDescID = v6; - a1.vPosition.y = pParty->vPosition.y; - a1.spell_caster_pid = OBJECT_Player; - a1.vPosition.x = pParty->vPosition.x; - a1.vPosition.z = pParty->sEyelevel + pParty->vPosition.z; - a1.uSoundID = 0; - a1.uFacing = 0; - a1.uAttributes = 8; - a1.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->sEyelevel + pParty->vPosition.z); - a1.uSpriteFrameID = 0; - memcpy(&a1.stru_24, &pParty->pPickedItem, 0x24u); - - extern int UnprojectX(int); - v9 = UnprojectX(v1->x); - a1.Create(pParty->sRotationY + v9, 184, 200, 0); - pTextureID = pIcons_LOD->LoadTexture(pParty->pPickedItem.GetIconName(), TEXTURE_16BIT_PALETTE); - if (pTextureID != -1) - pIcons_LOD->pTextures[pTextureID].Release(); - pMouse->RemoveHoldingItem(); - pIcons_LOD->SyncLoadedFilesCount(); - return; - } - pEventID = pIndoor->pFaceExtras[pIndoor->pFaces[PID_ID(v0)].uFaceExtraID].uEventID; - } - if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor) - { - if ( !pOutdoor->pBModels[(signed int)(v0 & 0xFFFF) >> 9].pFaces[PID_ID(v0) & 0x3F].Clickable()) - { - if ( !pParty->pPickedItem.uItemID ) - { - ShowNothingHereStatus(); - if ( !pParty->pPickedItem.uItemID ) - return; - } - __debugbreak();//no checker - v6 = 0; - a1.uType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID; - if ( (signed int)pObjectList->uNumObjects <= 0 ) - LOWORD(v6) = 0; - else - { - v7 = (char *)&pObjectList->pObjects->uObjectID; - while ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID != *(short *)v7 ) - { - ++v6; - v7 += 56; - if ( v6 >= (signed int)pObjectList->uNumObjects ) - { - LOWORD(v6) = 0; - break; - } - } - } - a1.uObjectDescID = v6; - a1.vPosition.y = pParty->vPosition.y; - a1.spell_caster_pid = OBJECT_Player; - a1.vPosition.x = pParty->vPosition.x; - a1.vPosition.z = pParty->sEyelevel + pParty->vPosition.z; - a1.uSoundID = 0; - a1.uFacing = 0; - a1.uAttributes = 8; - a1.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->sEyelevel + pParty->vPosition.z); - a1.uSpriteFrameID = 0; - memcpy(&a1.stru_24, &pParty->pPickedItem, 0x24u); - - extern int UnprojectX(int); - v9 = UnprojectX(v1->x); - a1.Create(pParty->sRotationY + v9, 184, 200, 0); - pTextureID = pIcons_LOD->LoadTexture(pParty->pPickedItem.GetIconName(), TEXTURE_16BIT_PALETTE); - if (pTextureID != -1) - pIcons_LOD->pTextures[pTextureID].Release(); - pMouse->RemoveHoldingItem(); - pIcons_LOD->SyncLoadedFilesCount(); - return; - } - pEventID = pOutdoor->pBModels[(signed int)(v0 & 0xFFFF) >> 9].pFaces[PID_ID(v0) & 0x3F].sCogTriggeredID; - } - EventProcessor(pEventID, (unsigned __int16)v0, 1); - return; - } - if ( PID_TYPE(v0) != OBJECT_BModel || HIWORD(v0) >= clickable_distance ) - { - if ( !pParty->pPickedItem.uItemID ) - return; - //__debugbreak();//no checker - v6 = 0; - a1.uType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID; - if ( (signed int)pObjectList->uNumObjects <= 0 ) - LOWORD(v6) = 0; - else - { - v7 = (char *)&pObjectList->pObjects->uObjectID; - while ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID != *(short *)v7 ) - { - ++v6; - v7 += 56; - if ( v6 >= (signed int)pObjectList->uNumObjects ) - { - LOWORD(v6) = 0; - break; - } - } - } - a1.uObjectDescID = v6; - a1.vPosition.y = pParty->vPosition.y; - a1.spell_caster_pid = OBJECT_Player; - a1.vPosition.x = pParty->vPosition.x; - a1.vPosition.z = pParty->sEyelevel + pParty->vPosition.z; - a1.uSoundID = 0; - a1.uFacing = 0; - a1.uAttributes = 8; - a1.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->sEyelevel + pParty->vPosition.z); - a1.uSpriteFrameID = 0; - memcpy(&a1.stru_24, &pParty->pPickedItem, 0x24u); - - extern int UnprojectX(int); - //v9 = UnprojectX(v1->x); - a1.Create(pParty->sRotationY + UnprojectX(v1->x), 184, 200, 0); - pTextureID = pIcons_LOD->LoadTexture(pParty->pPickedItem.GetIconName(), TEXTURE_16BIT_PALETTE); - if (pTextureID != -1) - pIcons_LOD->pTextures[pTextureID].Release(); - pMouse->RemoveHoldingItem(); - pIcons_LOD->SyncLoadedFilesCount(); - return; - } -} diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Viewport.h --- a/Viewport.h Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,98 +0,0 @@ -#pragma once - -/* 149 */ -#pragma pack(push, 1) -struct Viewport -{ - inline Viewport() - { - field_of_view = 65536 / 2; - SetScreen(0, 0, 639, 479); - } - - void SetScreen(signed int uX, signed int uY, signed int uZ, signed int uW); - void SetFOV(int a2); - void SetViewport(signed int uX, signed int uY, signed int uZ, signed int uW); - - - signed int uScreen_TL_X; - signed int uScreen_TL_Y; - signed int uScreen_BR_X; - signed int uScreen_BR_Y; - signed int uViewportTL_X; - signed int uViewportTL_Y; - signed int uViewportBR_X; - signed int uViewportBR_Y; - int uScreenWidth; - int uScreenHeight; - int uScreenCenterX; - int uScreenCenterY; - int field_of_view; -}; -#pragma pack(pop) - -void OnGameViewportClick(); - - -extern struct Viewport *pViewport; - - - -/* 201 */ -#pragma pack(push, 1) -struct ViewingParams -{ - inline ViewingParams() - { - draw_sw_outlines = false; - draw_d3d_outlines = false; - field_4C = 0; - } - - void CenterOnParty2(); - void InitGrayPalette(); - void _443219(); - void _443225(); - void _443231(); - void _44323D(); - void CenterOnParty(); - void AdjustPosition(); - void _443365(); - - - - int uSomeX; - int uSomeY; - int uSomeZ; - int uSomeW; - unsigned int uScreen_topL_X; - unsigned int uScreen_topL_Y; - unsigned int uScreen_BttmR_X; - unsigned int uScreen_BttmR_Y; - int field_20; - unsigned int uMinimapZoom; - int field_28; - unsigned int uMapBookMapZoom; - int sViewCenterX; - int sViewCenterY; - __int16 indoor_center_x; - __int16 indoor_center_y; - int field_3C; - unsigned int uTextureID_LocationMap; - int bRedrawGameUI; - int field_48; - int field_4C; - int draw_sw_outlines; - int draw_d3d_outlines; - int field_58; - int field_5C; - int field_60; - int field_64; - int field_68; - unsigned __int16 pPalette[256]; -}; -#pragma pack(pop) - - - -extern struct ViewingParams *viewparams; \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Vis.cpp --- a/Vis.cpp Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1556 +0,0 @@ -#define _CRTDBG_MAP_ALLOC -#include -#include - -#define _CRT_SECURE_NO_WARNINGS -#include "Vis.h" -#include "Sprites.h" -#include "Lod.h" -#include "Outdoor.h" -#include "Game.h" -#include "Actor.h" -#include "Viewport.h" -#include "OurMath.h" -#include "Log.h" -#include "ErrorHandling.h" - -#include "MM7.h" -#include "Level/Decoration.h" - - -static Vis_SelectionList Vis_static_sub_4C1944_stru_F8BDE8; - -Vis_SelectionFilter vis_sprite_filter_1 = {VisObjectType_Sprite, OBJECT_Decoration, 0, 0, 2}; // 00F93E1C -Vis_SelectionFilter vis_sprite_filter_2 = {VisObjectType_Sprite, OBJECT_Decoration, 0, 0, 2}; // 00F93E30 -Vis_SelectionFilter vis_face_filter = {VisObjectType_Face, OBJECT_Any, -1, 0, 0}; // 00F93E44 -Vis_SelectionFilter vis_door_filter = {VisObjectType_Face, OBJECT_BLVDoor, -1, 0x100000, 0}; // 00F93E58 -Vis_SelectionFilter vis_sprite_filter_3 = {VisObjectType_Sprite, OBJECT_Decoration, -1, 0, 4}; // 00F93E6C -Vis_SelectionFilter vis_sprite_filter_4 = {VisObjectType_Any, OBJECT_Item, -1, 0, 0}; // static to sub_44EEA7 - - - -//----- (004C1026) -------------------------------------------------------- -Vis_ObjectInfo *Vis::DetermineFacetIntersection(BLVFace *face, unsigned int pid, float pick_depth) -{ -// char *v4; // eax@4 -// signed int v5; // ecx@4 - RenderVertexSoft pRay[2]; // [sp+20h] [bp-70h]@17 -// int v20; // [sp+84h] [bp-Ch]@10 - - static Vis_SelectionList SelectedPointersList;//stru_F8FE00 - SelectedPointersList.uNumPointers = 0; - - static bool _init_flag = false; - static RenderVertexSoft static_DetermineFacetIntersection_array_F8F200[64]; - if (!_init_flag) - { - _init_flag = true; - for (uint i = 0; i < 64; ++i) - static_DetermineFacetIntersection_array_F8F200[i].flt_2C = 0.0f; - } - - if (uCurrentlyLoadedLevelType == LEVEL_Indoor) - { - if ( (signed int)face->uNumVertices > 0 ) - { - for ( int i = 0; i < face->uNumVertices; i++) - { - static_DetermineFacetIntersection_array_F8F200[i].vWorldPosition.x = (double)pIndoor->pVertices[face->pVertexIDs[i]].x; - static_DetermineFacetIntersection_array_F8F200[i].vWorldPosition.y = (double)pIndoor->pVertices[face->pVertexIDs[i]].y; - static_DetermineFacetIntersection_array_F8F200[i].vWorldPosition.z = (double)pIndoor->pVertices[face->pVertexIDs[i]].z; - } - } - } - else if (uCurrentlyLoadedLevelType == LEVEL_Outdoor) - { - uint bmodel_id = pid >> 9; - Vec3_int_* v = (Vec3_int_ *)pOutdoor->pBModels[bmodel_id].pVertices.pVertices; - for (uint i = 0; i < face->uNumVertices; ++i) - { - static_DetermineFacetIntersection_array_F8F200[i].vWorldPosition.x = v[face->pVertexIDs[i]].x; - static_DetermineFacetIntersection_array_F8F200[i].vWorldPosition.y = v[face->pVertexIDs[i]].y; - static_DetermineFacetIntersection_array_F8F200[i].vWorldPosition.z = v[face->pVertexIDs[i]].z; - } - } - else assert(false); - - pGame->pIndoorCameraD3D->ViewTransform(static_DetermineFacetIntersection_array_F8F200, face->uNumVertices); - pGame->pIndoorCameraD3D->Project(static_DetermineFacetIntersection_array_F8F200, face->uNumVertices, 1); - - SortVectors_x(static_DetermineFacetIntersection_array_F8F200, 0, face->uNumVertices - 1); - if (static_DetermineFacetIntersection_array_F8F200[0].vWorldViewPosition.x > pick_depth) - return nullptr; - - float screenspace_center_x, - screenspace_center_y; - GetPolygonScreenSpaceCenter(static_DetermineFacetIntersection_array_F8F200, face->uNumVertices, &screenspace_center_x, &screenspace_center_y); - if (IsPolygonOccludedByBillboard(static_DetermineFacetIntersection_array_F8F200, face->uNumVertices, screenspace_center_x, screenspace_center_y)) - return nullptr; - - CastPickRay(pRay, screenspace_center_x, screenspace_center_y, pick_depth); - - if (uCurrentlyLoadedLevelType == LEVEL_Outdoor) - PickOutdoorFaces_Mouse(pick_depth, pRay, &SelectedPointersList, &vis_face_filter, true); - else if (uCurrentlyLoadedLevelType == LEVEL_Indoor) - PickIndoorFaces_Mouse(pick_depth, pRay, &SelectedPointersList, &vis_face_filter); - else assert(false); - - SelectedPointersList.create_object_pointers(); - sort_object_pointers(SelectedPointersList.object_pointers, 0, SelectedPointersList.uNumPointers - 1); - if (!SelectedPointersList.uNumPointers) - return nullptr; - - if (!SelectedPointersList.SelectionPointers(VisObjectType_Face, pid)) - return nullptr; - - if (SelectedPointersList.uNumPointers) - return SelectedPointersList.object_pointers[0]; - else return nullptr; -} -// F91E08: using guessed type char static_DetermineFacetIntersection_byte_F91E08__init_flags; - -//----- (004C12C3) -------------------------------------------------------- -bool Vis::IsPolygonOccludedByBillboard(RenderVertexSoft *vertices, int num_vertices, float x, float y) -{ - int v13 = -1; - //v5 = 0; - - //v6 = pRenderer->pBillboardRenderListD3D; - for (uint i = 0; i < pRenderer->uNumBillboardsToDraw; ++i) - { - RenderBillboardD3D* billboard = &pRenderer->pBillboardRenderListD3D[i]; - if (IsPointInsideD3DBillboard(billboard, x, y)) - { - if (v13 == -1) - v13 = i; - else if (pBillboardRenderList[billboard->sParentBillboardID].sZValue < - pBillboardRenderList[pRenderer->pBillboardRenderListD3D[v13].sParentBillboardID].sZValue) - v13 = i; - } - } - - if ( v13 == -1 ) - return false; - - // //Bounding rectangle(Ограничивающий прямоугольник)------------------------- - //v7 = 3.4028235e38; - float min_x = FLT_MAX; - //a4a = 3.4028235e38; - float min_y = FLT_MAX; - //a3a = -3.4028235e38; - float max_x = -FLT_MAX; - //thisb = -3.4028235e38; - float max_y = -FLT_MAX; - for (int i = 0; i < num_vertices; ++i) - { - RenderVertexSoft* v = &vertices[i]; - - if (v->vWorldViewProjX < min_x) - min_x = v->vWorldViewProjX; - if (v->vWorldViewProjX > max_x) - max_x = v->vWorldViewProjX; - - if (v->vWorldViewProjY < min_y) - min_y = v->vWorldViewProjY; - if (v->vWorldViewProjY > max_y) - max_y = v->vWorldViewProjY; - } - // //-------------------------------- - - if (min_x < pRenderer->pBillboardRenderListD3D[v13].pQuads[0].pos.x || pRenderer->pBillboardRenderListD3D[v13].pQuads[0].pos.y > min_y || - pRenderer->pBillboardRenderListD3D[v13].pQuads[3].pos.x < max_x || pRenderer->pBillboardRenderListD3D[v13].pQuads[1].pos.y < max_y) - return false; - - return true; -} - -//----- (004C1417) -------------------------------------------------------- -void Vis::GetPolygonCenter(RenderVertexD3D3 *pVertices, unsigned int uNumVertices, float *pCenterX, float *pCenterY) -{ - static RenderVertexD3D3 unk_F8EA00[64]; - - memcpy(unk_F8EA00, pVertices, 32 * uNumVertices); - - SortVerticesByX(unk_F8EA00, 0, uNumVertices - 1); - *pCenterX = (unk_F8EA00[uNumVertices - 1].pos.x - unk_F8EA00[0].pos.x) * 0.5 + unk_F8EA00[0].pos.x; - - SortVerticesByY(unk_F8EA00, 0, uNumVertices - 1); - *pCenterY = (unk_F8EA00[uNumVertices - 1].pos.y - unk_F8EA00[0].pos.y) * 0.5 + unk_F8EA00[0].pos.y; -} - -//----- (004C1495) -------------------------------------------------------- -void Vis::GetPolygonScreenSpaceCenter(RenderVertexSoft *vertices, int num_vertices, float *out_center_x, float *out_center_y) -{ -// char *v5; // eax@2 -// signed int v6; // ecx@2 -// float *result; // eax@5 - - static RenderVertexSoft static_sub_4C1495_array_F8DDF8[64]; - - memcpy(static_sub_4C1495_array_F8DDF8, vertices, 48 * num_vertices); - - SortByScreenSpaceX(static_sub_4C1495_array_F8DDF8, 0, num_vertices - 1); - *out_center_x = (static_sub_4C1495_array_F8DDF8[num_vertices - 1].vWorldViewProjX - static_sub_4C1495_array_F8DDF8[0].vWorldViewProjX) * 0.5 + static_sub_4C1495_array_F8DDF8[0].vWorldViewProjX; - - SortByScreenSpaceY(static_sub_4C1495_array_F8DDF8, 0, num_vertices - 1); - *out_center_y = (static_sub_4C1495_array_F8DDF8[num_vertices - 1].vWorldViewProjY - static_sub_4C1495_array_F8DDF8[0].vWorldViewProjY) * 0.5 + static_sub_4C1495_array_F8DDF8[0].vWorldViewProjY; -} - -//----- (004C1542) -------------------------------------------------------- -void Vis::PickBillboards_Mouse(float fPickDepth, float fX, float fY, Vis_SelectionList *list, Vis_SelectionFilter *filter) -{ - for (uint i = 0; i < pRenderer->uNumBillboardsToDraw; ++i) - { - RenderBillboardD3D* d3d_billboard = &pRenderer->pBillboardRenderListD3D[i]; - if (is_part_of_selection((void *)i, filter) && IsPointInsideD3DBillboard(d3d_billboard, fX, fY)) - { - if (DoesRayIntersectBillboard(fPickDepth, i)) - { - RenderBillboard* billboard = &pBillboardRenderList[d3d_billboard->sParentBillboardID]; - - list->AddObject((void *)d3d_billboard->sParentBillboardID, VisObjectType_Sprite, billboard->sZValue); - } - } - } -} - - -//----- (004C1607) -------------------------------------------------------- -bool Vis::IsPointInsideD3DBillboard(RenderBillboardD3D *a1, float x, float y) -{ - /*Not the original implementation. - This function is redone to use Grayface's mouse pick implementation to take only the visible - parts of billboards into account - I don't really have too much of an idea how it actually works*/ - float drX; // st7@2 - float drY; // ecx@2 - float drH; // [sp+4h] [bp-8h]@2 - float drW; // [sp+14h] [bp+8h]@2 - - if ( a1->sParentBillboardID == -1 ) - return false; - - drX = a1->pQuads[0].pos.x; - drW = a1->pQuads[3].pos.x - drX; - drY = a1->pQuads[0].pos.y; - drH = a1->pQuads[1].pos.y - drY; - - Sprite* ownerSprite = nullptr; - for (int i = 0; i < pSprites_LOD->uNumLoadedSprites; ++i) - { - if (pSprites_LOD->pHardwareSprites[i].pTexture == a1->pTexture) - { - ownerSprite = &pSprites_LOD->pHardwareSprites[i]; - break; - } - } - - if (ownerSprite == nullptr) - return false; - - int i = ownerSprite->uAreaX + int(ownerSprite->uAreaWidth * (x - drX) / drW); - int j = ownerSprite->uAreaY + int(ownerSprite->uAreaHeight * (y - drY) / drH); - - - LODSprite* spriteHeader = nullptr; - - for (int i = 0; i < MAX_LOD_SPRITES; ++i) - { - if (strcmp(pSprites_LOD->pSpriteHeaders[i].pName, ownerSprite->pName) == 0) - { - spriteHeader = &pSprites_LOD->pSpriteHeaders[i]; - break; - } - } - - if (j < 0 || j >= spriteHeader->uHeight) - return false; - - if (spriteHeader->pSpriteLines[j].a1 < 0 || i > spriteHeader->pSpriteLines[j].a2 || i < spriteHeader->pSpriteLines[j].a1) - { - return false; - } - return *(spriteHeader->pSpriteLines[j].pos + i - spriteHeader->pSpriteLines[j].a1) != 0; -} - -//----- (004C16B4) -------------------------------------------------------- -void Vis::PickIndoorFaces_Mouse(float fDepth, RenderVertexSoft *pRay, Vis_SelectionList *list, Vis_SelectionFilter *filter) -{ - int v5; // eax@1 - signed int pFaceID; // edi@2 - int v9; // eax@7 - unsigned int *pNumPointers; // eax@7 - Vis_ObjectInfo *v12; // edi@7 - RenderVertexSoft a1; // [sp+Ch] [bp-44h]@1 - void *v15; // [sp+40h] [bp-10h]@7 - int v17; // [sp+48h] [bp-8h]@1 - - v5 = 0; - v17 = 0; - for ( a1.flt_2C = 0.0; v17 < (signed int)pBspRenderer->num_faces; ++v17 ) - { - pFaceID = pBspRenderer->faces[v5].uFaceID; - if ( pFaceID >= 0 ) - { - if ( pFaceID < (signed int)pIndoor->uNumFaces ) - { - BLVFace* face = &pIndoor->pFaces[pFaceID]; - if ( is_part_of_selection(face, filter) ) - { - if ( !pGame->pIndoorCameraD3D->IsCulled(face) ) - { - if ( Intersect_Ray_Face(pRay, pRay + 1, &fDepth, &a1, face, 0xFFFFFFFFu) ) - { - pGame->pIndoorCameraD3D->ViewTransform(&a1, 1); - v9 = fixpoint_from_float(/*v8, */a1.vWorldViewPosition.x); - LOWORD(v9) = 0; - v15 = (void *)((PID(OBJECT_BModel,pFaceID)) + v9); - pNumPointers = &list->uNumPointers; - v12 = &list->object_pool[list->uNumPointers]; - v12->object = &pIndoor->pFaces[pFaceID]; - v12 = (Vis_ObjectInfo *) &v12->sZValue; - v12->object = v15; - v12->sZValue = 2; - ++*pNumPointers; - } - } - } - - if (face->uAttributes & FACE_PICKED) - face->uAttributes |= FACE_OUTLINED; - else - face->uAttributes &= ~FACE_OUTLINED; - face->uAttributes &= ~FACE_PICKED; - } - } - v5 = v17 + 1; - } -} - -//----- (004C17CF) -------------------------------------------------------- -void Vis::PickOutdoorFaces_Mouse(float fDepth, RenderVertexSoft *pRay, Vis_SelectionList *list, Vis_SelectionFilter *filter, bool only_reachable) -{ - if (!pOutdoor) - return; - - for (int i = 0; i < pOutdoor->uNumBModels; ++i) - { - int reachable; - if (!IsBModelVisible(i, &reachable)) - continue; - if (!reachable && only_reachable) - continue; - - BSPModel* bmodel = &pOutdoor->pBModels[i]; - for (int j = 0; j < bmodel->uNumFaces; ++j) - { - ODMFace* face = &bmodel->pFaces[j]; - if (is_part_of_selection(face, filter)) - { - BLVFace blv_face; - blv_face.FromODM(face); - - RenderVertexSoft intersection; - if (Intersect_Ray_Face(pRay, pRay + 1, &fDepth, &intersection, &blv_face, i)) - { - pGame->pIndoorCameraD3D->ViewTransform(&intersection, 1); - int v13 = fixpoint_from_float(/*v12, */intersection.vWorldViewPosition.x); - v13 &= 0xFFFF0000; - v13 += PID(OBJECT_BModel, j | (i << 6)); - - list->AddObject(face, VisObjectType_Face, v13); - } - - if (blv_face.uAttributes & FACE_PICKED) - face->uAttributes |= FACE_OUTLINED; - else - face->uAttributes &= ~FACE_OUTLINED; - blv_face.uAttributes &= ~FACE_PICKED; - } - } - } -} - -//----- (004C1930) -------------------------------------------------------- -//bool Vis::j_DoesRayIntersectBillboard(float fDepth, unsigned int uD3DBillboardIdx) -//{return DoesRayIntersectBillboard(fDepth, uD3DBillboardIdx);} - -//----- (004C1944) -------------------------------------------------------- -int Vis::PickClosestActor(int object_id, unsigned int pick_depth, int a4, int a5, int a6) -{ - Vis_SelectionFilter v8; // [sp+18h] [bp-20h]@3 - - static Vis_SelectionList Vis_static_sub_4C1944_stru_F8BDE8; - - v8.object_type = VisObjectType_Sprite; - v8.object_id = object_id; - v8.at_ai_state = a6; - v8.no_at_ai_state = a5; - v8.select_flags = a4; - Vis_static_sub_4C1944_stru_F8BDE8.uNumPointers = 0; - PickBillboards_Keyboard(pick_depth, &Vis_static_sub_4C1944_stru_F8BDE8, &v8); - Vis_static_sub_4C1944_stru_F8BDE8.create_object_pointers(Vis_SelectionList::Unique); - sort_object_pointers(Vis_static_sub_4C1944_stru_F8BDE8.object_pointers, 0, Vis_static_sub_4C1944_stru_F8BDE8.uNumPointers - 1); - - if (!Vis_static_sub_4C1944_stru_F8BDE8.uNumPointers) - return -1; - return Vis_static_sub_4C1944_stru_F8BDE8.object_pointers[0]->sZValue; -} - -//----- (004C1A02) -------------------------------------------------------- -void Vis::_4C1A02() -{ - RenderVertexSoft v1; // [sp+8h] [bp-C0h]@1 - RenderVertexSoft v2; // [sp+38h] [bp-90h]@1 - RenderVertexSoft v3; // [sp+68h] [bp-60h]@1 - RenderVertexSoft v4; // [sp+98h] [bp-30h]@1 - - v4.flt_2C = 0.0; - v4.vWorldPosition.x = 0.0; - v4.vWorldPosition.y = 65536.0; - v4.vWorldPosition.z = 0.0; - v3.flt_2C = 0.0; - v3.vWorldPosition.x = 65536.0; - v3.vWorldPosition.y = 0.0; - v3.vWorldPosition.z = 0.0; - memcpy(&v1, &v3, sizeof(v1)); - v3.flt_2C = 0.0; - v3.vWorldPosition.x = 0.0; - v3.vWorldPosition.y = 65536.0; - v3.vWorldPosition.z = 0.0; - memcpy(&v2, &v4, sizeof(v2)); - v4.flt_2C = 0.0; - v4.vWorldPosition.x = 65536.0; - v4.vWorldPosition.y = 0.0; - v4.vWorldPosition.z = 0.0; - memcpy(&this->stru_200C, &v1, 0x60u); - memcpy(&v1, &v4, sizeof(v1)); - memcpy(&v2, &v3, sizeof(v2)); - memcpy(&this->stru_206C, &v1, 0x60u); -} - -//----- (004C1ABA) -------------------------------------------------------- -void Vis::SortVectors_x(RenderVertexSoft *pArray, int start, int end) -{ - int left_sort_index; // ebx@2 - int right_sort_index; // ecx@2 - RenderVertexSoft temp_array; // [sp+4h] [bp-6Ch]@8 - RenderVertexSoft max_array; // [sp+34h] [bp-3Ch]@2 - - if ( end > start ) - { - left_sort_index = start - 1; - right_sort_index = end; - memcpy(&max_array, &pArray[end], sizeof(max_array)); - while ( 1 ) - { - do - { - ++left_sort_index; - } - while ( pArray[left_sort_index].vWorldViewPosition.x < (double)max_array.vWorldViewPosition.x ); - do - { - --right_sort_index; - } - while ( pArray[right_sort_index].vWorldViewPosition.x > (double)max_array.vWorldViewPosition.x ); - if ( left_sort_index >= right_sort_index ) - break; - memcpy(&temp_array, &pArray[left_sort_index], sizeof(temp_array)); - memcpy(&pArray[left_sort_index], &pArray[right_sort_index], sizeof(pArray[left_sort_index])); - memcpy(&pArray[right_sort_index], &temp_array, sizeof(pArray[right_sort_index])); - } - memcpy(&temp_array, &pArray[left_sort_index], sizeof(temp_array)); - memcpy(&pArray[left_sort_index], &pArray[end], sizeof(pArray[left_sort_index])); - memcpy(&pArray[end], &temp_array, sizeof(pArray[end])); - SortVectors_x(pArray, start, left_sort_index - 1); - SortVectors_x(pArray, left_sort_index + 1, end); - } -} - -//----- (004C1BAA) -------------------------------------------------------- -int Vis::get_object_zbuf_val(Vis_ObjectInfo *info) -{ - switch (info->object_type) - { - case VisObjectType_Sprite: - case VisObjectType_Face: - return info->sZValue; - - default: - MessageBoxW(nullptr, L"Undefined type requested for: CVis::get_object_zbuf_val()", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Vis.cpp:1037", 0); - return -1; - } -} - -//----- (004C1BF1) -------------------------------------------------------- -int Vis::get_picked_object_zbuf_val() -{ - if (!default_list.uNumPointers) - return -1; - - return get_object_zbuf_val(default_list.object_pointers[0]); -} - -//----- (004C1C0C) -------------------------------------------------------- -bool Vis::Intersect_Ray_Face(RenderVertexSoft *pRayStart, RenderVertexSoft *pRayEnd, float *pDepth, RenderVertexSoft *Intersection, BLVFace *pFace, signed int pBModelID) -{ - float c1; // st5@6 - float c2; // st7@11 - Vec3_short_ IntersectPoint; // ST04_6@11 - - - if (pFace->Portal() || pFace->Invisible()) - return false; - - int ray_dir_x = pRayEnd->vWorldPosition.x - pRayStart->vWorldPosition.x,//calculate the direction vector of the line(вычислим вектор направления линий) - ray_dir_y = pRayEnd->vWorldPosition.y - pRayStart->vWorldPosition.y, - ray_dir_z = pRayEnd->vWorldPosition.z - pRayStart->vWorldPosition.z; - -//c1 = -d-(n*p0) - c1 = -pFace->pFacePlane.dist -(pFace->pFacePlane.vNormal.x * pRayStart->vWorldPosition.x - + pFace->pFacePlane.vNormal.y * pRayStart->vWorldPosition.y - + pFace->pFacePlane.vNormal.z * pRayStart->vWorldPosition.z); - if (c1 > 0) - return false; -#define EPSILON 1e-6 -//c2 = n*u - c2 = pFace->pFacePlane.vNormal.x * ray_dir_y// get length of the line(Это дает нам длину линии) - + pFace->pFacePlane.vNormal.y * ray_dir_x - + pFace->pFacePlane.vNormal.z * ray_dir_z; - if (c2 > -EPSILON && c2 < EPSILON) // ray faces face's normal ( > 0) or parallel ( == 0) - return false; - -//t = -d-(n*p0)/n*u - float t = c1 / c2;//How far is crossing the line in percent for 0 to 1(Как далеко пересечение линии в процентах от 0 до 1 ) - - if (t < 0 || t > 1) - return false; - -// p(t) = p0 + tu; - Intersection->vWorldPosition.x = pRayStart->vWorldPosition.x + t * ray_dir_y;// add the interest to the start line(прибавляем процент линии к линии старта) - Intersection->vWorldPosition.y = pRayStart->vWorldPosition.y + t * ray_dir_x; - Intersection->vWorldPosition.z = pRayStart->vWorldPosition.z + t * ray_dir_z; - - IntersectPoint.x = Intersection->vWorldPosition.x; - IntersectPoint.y = Intersection->vWorldPosition.y; - IntersectPoint.z = Intersection->vWorldPosition.z; - - if ( !CheckIntersectBModel(pFace, IntersectPoint, pBModelID) ) - return false; - - *pDepth = t;//Record the distance from the origin of the ray (Записываем дистанцию от начала луча) - return true; -} - -//----- (004C1D2B) -------------------------------------------------------- -bool Vis::CheckIntersectBModel(BLVFace *pFace, Vec3_short_ IntersectPoint, signed int sModelID) -{ - int v5; // esi@10 - bool v6; // edi@10 - signed int v10; // ebx@14 -// int v15; // [sp+10h] [bp-Ch]@10 - signed int v16; // [sp+18h] [bp-4h]@10 - - int a = 0, b = 0; - - if (IntersectPoint.x < pFace->pBounding.x1 || IntersectPoint.x > pFace->pBounding.x2 || - IntersectPoint.y < pFace->pBounding.y1 || IntersectPoint.y > pFace->pBounding.y2 || - IntersectPoint.z < pFace->pBounding.z1 || IntersectPoint.z > pFace->pBounding.z2 ) - return false; - - if (sModelID != -1) - ODM_CreateIntersectFacesVertexCoordList(&a, &b, intersect_face_vertex_coords_list_a.data(), intersect_face_vertex_coords_list_b.data(), - &IntersectPoint, pFace, sModelID); - else - BLV_CreateIntersectFacesVertexCoordList(&a, &b, intersect_face_vertex_coords_list_a.data(), intersect_face_vertex_coords_list_b.data(), - &IntersectPoint, pFace); - v5 = 2 * pFace->uNumVertices; - v16 = 0; - intersect_face_vertex_coords_list_a[v5] = intersect_face_vertex_coords_list_a[0]; - intersect_face_vertex_coords_list_b[v5] = intersect_face_vertex_coords_list_b[0]; - v6 = intersect_face_vertex_coords_list_b[0] >= b; - if (v5 <= 0) - return false; - for ( int i = 0; i < v5; ++i ) - { - if ( v16 >= 2 ) - break; - if ( v6 ^ (intersect_face_vertex_coords_list_b[i + 1] >= b) ) - { - if ( intersect_face_vertex_coords_list_a[i + 1] >= a ) - v10 = 0; - else - v10 = 2; - v10 |= intersect_face_vertex_coords_list_a[i] < a ? 1 : 0; - if ( v10 != 3 ) - { - if ( !v10) - ++v16; - else - { - int _v1 = fixpoint_div(intersect_face_vertex_coords_list_a[i + 1] - intersect_face_vertex_coords_list_a[i], - intersect_face_vertex_coords_list_b[i + 1] - intersect_face_vertex_coords_list_b[i]); - int _v2 = fixpoint_mul(b - intersect_face_vertex_coords_list_b[i], _v1) + 32768; - - if (intersect_face_vertex_coords_list_a[i] + (_v2 >> 16) >= a) - ++v16; - } - } - } - v6 = intersect_face_vertex_coords_list_b[i + 1] >= b; - } - - if ( v16 != 1 ) - return false; - - if ( show_picked_face ) - pFace->uAttributes |= FACE_PICKED; - return true; -/* - int v5; // esi@10 - bool v6; // edi@10 - signed int v10; // ebx@14 - int v11; // edi@16 - signed int v12; // ST28_4@18 - signed __int64 v13; // qtt@18 - signed int result; // eax@21 - int v15; // [sp+10h] [bp-Ch]@10 - signed int v16; // [sp+18h] [bp-4h]@10 - - int a = 0, b = 0; - - if (IntersectPoint.x < pFace->pBounding.x1 || IntersectPoint.x > pFace->pBounding.x2 || - IntersectPoint.y < pFace->pBounding.y1 || IntersectPoint.y > pFace->pBounding.y2 || - IntersectPoint.z < pFace->pBounding.z1 || IntersectPoint.z > pFace->pBounding.z2 ) - return false; - - pFace->uAttributes |= 0x80000000; - - if (uModelID != -1) - ODM_CreateIntersectFacesVertexCoordList(&a, &b, intersect_face_vertex_coords_list_a, intersect_face_vertex_coords_list_b, - &IntersectPoint, pFace, uModelID); - else - BLV_CreateIntersectFacesVertexCoordList(&a, &b, intersect_face_vertex_coords_list_a, intersect_face_vertex_coords_list_b, - &IntersectPoint, pFace); - v5 = 2 * pFace->uNumVertices; - v16 = 0; - intersect_face_vertex_coords_list_a[v5] = intersect_face_vertex_coords_list_a[0]; - intersect_face_vertex_coords_list_b[v5] = intersect_face_vertex_coords_list_b[0]; - v6 = intersect_face_vertex_coords_list_b[0] >= b; - if (v5 <= 0) - return false; - for ( uint i = 0; i < v5; ++i ) - { - if ( v16 >= 2 ) - break; - if ( v6 ^ intersect_face_vertex_coords_list_b[i + 1] >= b ) - { - if ( intersect_face_vertex_coords_list_a[i + 1] >= a ) - v10 = 0; - else - v10 = 2; - v11 = v10 | intersect_face_vertex_coords_list_a[i] < a; - if ( v11 != 3 ) - { - if ( !v11 - || (v12 = intersect_face_vertex_coords_list_a[i + 1] - intersect_face_vertex_coords_list_a[i], - LODWORD(v13) = v12 << 16, - HIDWORD(v13) = v12 >> 16, - intersect_face_vertex_coords_list_a[i] - + ((signed int)(((unsigned __int64)(v13 / (intersect_face_vertex_coords_list_b[i + 1] - intersect_face_vertex_coords_list_b[i]) - * (signed int)((b - intersect_face_vertex_coords_list_b[i]) << 16)) >> 16) + 32768) >> 16) >= a) ) - ++v16; - } - } - v6 = intersect_face_vertex_coords_list_b[i + 1] >= b; - } - result = true; - if ( v16 != 1 ) - result = false; - return result; -}*/ -} - -//----- (004C1EE5) -------------------------------------------------------- -void Vis::BLV_CreateIntersectFacesVertexCoordList(int *a, int *b, __int16 *intersect_face_vertex_coords_list_a, - __int16 *intersect_face_vertex_coords_list_b, - Vec3_short_ *IntersectPoint, BLVFace *pFace) -{ - if (pFace->uAttributes & FACE_XY_PLANE) - { - *a = IntersectPoint->x; - *b = IntersectPoint->y; - - for (uint i = 0; i < pFace->uNumVertices; ++i) - { - intersect_face_vertex_coords_list_a[2 * i] = pFace->pXInterceptDisplacements[i] + pIndoor->pVertices[pFace->pVertexIDs[i]].x; - intersect_face_vertex_coords_list_a[2 * i + 1] = pFace->pXInterceptDisplacements[i + 1] + pIndoor->pVertices[pFace->pVertexIDs[i + 1]].x; - - intersect_face_vertex_coords_list_b[2 * i] = pFace->pYInterceptDisplacements[i] + pIndoor->pVertices[pFace->pVertexIDs[i]].y; - intersect_face_vertex_coords_list_b[2 * i + 1] = pFace->pYInterceptDisplacements[i + 1] + pIndoor->pVertices[pFace->pVertexIDs[i + 1]].y; - } - } - else if (pFace->uAttributes & FACE_XZ_PLANE) - { - *a = IntersectPoint->x; - *b = IntersectPoint->z; - - for (uint i = 0; i < pFace->uNumVertices; ++i) - { - intersect_face_vertex_coords_list_a[2 * i] = pFace->pXInterceptDisplacements[i] + pIndoor->pVertices[pFace->pVertexIDs[i]].x; - intersect_face_vertex_coords_list_a[2 * i + 1] = pFace->pXInterceptDisplacements[i + 1] + pIndoor->pVertices[pFace->pVertexIDs[i + 1]].x; - - intersect_face_vertex_coords_list_b[2 * i] = pFace->pZInterceptDisplacements[i] + pIndoor->pVertices[pFace->pVertexIDs[i]].z; - intersect_face_vertex_coords_list_b[2 * i + 1] = pFace->pZInterceptDisplacements[i + 1] + pIndoor->pVertices[pFace->pVertexIDs[i + 1]].z; - } - } - else if (pFace->uAttributes & FACE_YZ_PLANE) - { - *a = IntersectPoint->y; - *b = IntersectPoint->z; - - for (uint i = 0; i < pFace->uNumVertices; ++i) - { - intersect_face_vertex_coords_list_a[2 * i] = pFace->pYInterceptDisplacements[i] + pIndoor->pVertices[pFace->pVertexIDs[i]].y; - intersect_face_vertex_coords_list_a[2 * i + 1] = pFace->pYInterceptDisplacements[i + 1] + pIndoor->pVertices[pFace->pVertexIDs[i + 1]].y; - - intersect_face_vertex_coords_list_b[2 * i] = pFace->pZInterceptDisplacements[i] + pIndoor->pVertices[pFace->pVertexIDs[i]].z; - intersect_face_vertex_coords_list_b[2 * i + 1] = pFace->pZInterceptDisplacements[i + 1] + pIndoor->pVertices[pFace->pVertexIDs[i + 1]].z; - } - } - else assert(false); -} - -//----- (004C2186) -------------------------------------------------------- -void Vis::ODM_CreateIntersectFacesVertexCoordList(int *a, int *b, __int16 *intersect_face_vertex_coords_list_a, - __int16 *intersect_face_vertex_coords_list_b, - Vec3_short_ *IntersectPoint, BLVFace *pFace, unsigned int uModelID) -{ - if (pFace->uAttributes & FACE_XY_PLANE) - { - *a = IntersectPoint->x; - *b = IntersectPoint->y; - - for (int i = 0; i < pFace->uNumVertices; ++i) - { - intersect_face_vertex_coords_list_a[2 * i] = pFace->pXInterceptDisplacements[i] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i]].x; - intersect_face_vertex_coords_list_a[i * 2 + 1] = pFace->pXInterceptDisplacements[i + 1] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i + 1]].x; - - intersect_face_vertex_coords_list_b[2 * i] = pFace->pYInterceptDisplacements[i] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i]].y; - intersect_face_vertex_coords_list_b[i * 2 + 1] = pFace->pYInterceptDisplacements[i + 1] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i + 1]].y; - } - } - else if (pFace->uAttributes & FACE_XZ_PLANE) - { - *a = IntersectPoint->x; - *b = IntersectPoint->z; - - for (int i = 0; i < pFace->uNumVertices; ++i) - { - intersect_face_vertex_coords_list_a[2 * i] = pFace->pXInterceptDisplacements[i] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i]].x; - intersect_face_vertex_coords_list_a[i * 2 + 1] = pFace->pXInterceptDisplacements[i + 1] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i + 1]].x; - - intersect_face_vertex_coords_list_b[2 * i] = pFace->pZInterceptDisplacements[i] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i]].z; - intersect_face_vertex_coords_list_b[i * 2 + 1] = pFace->pZInterceptDisplacements[i + 1] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i + 1]].z; - } - } - else if (pFace->uAttributes & FACE_YZ_PLANE) - { - *a = IntersectPoint->y; - *b = IntersectPoint->z; - - for (int i = 0; i < pFace->uNumVertices; ++i) - { - intersect_face_vertex_coords_list_a[2 * i] = pFace->pYInterceptDisplacements[i] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i]].y; - intersect_face_vertex_coords_list_a[i * 2 + 1] = pFace->pYInterceptDisplacements[i + 1] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i + 1]].y; - - intersect_face_vertex_coords_list_b[2 * i] = pFace->pZInterceptDisplacements[i] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i]].z; - intersect_face_vertex_coords_list_b[i * 2 + 1] = pFace->pZInterceptDisplacements[i + 1] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i + 1]].z; - } - } - else assert(false); -} - -//----- (0046A0A1) -------------------------------------------------------- -int UnprojectX(int x) -{ - int v3; // [sp-4h] [bp-8h]@5 - - if ( uCurrentlyLoadedLevelType == LEVEL_Indoor ) - { - //if ( pRenderer->pRenderD3D ) - v3 = pGame->pIndoorCameraD3D->fov; - //else - // v3 = pIndoorCamera->fov_rad; - } - else - { - v3 = pODMRenderParams->int_fov_rad; - } - return stru_5C6E00->Atan2(x - pViewport->uScreenCenterX, v3) - stru_5C6E00->uIntegerHalfPi; -} - -//----- (0046A0F6) -------------------------------------------------------- -int UnprojectY(int y) -{ - int v3; // [sp-4h] [bp-8h]@5 - - if ( uCurrentlyLoadedLevelType == LEVEL_Indoor ) - { - //if ( pRenderer->pRenderD3D ) - v3 = pGame->pIndoorCameraD3D->fov; - //else - // v3 = pIndoorCamera->fov_rad; - } - else - { - v3 = pODMRenderParams->int_fov_rad; - } - return stru_5C6E00->Atan2(y - pViewport->uScreenCenterY, v3) - stru_5C6E00->uIntegerHalfPi; -} - -//----- (004C248E) -------------------------------------------------------- -void Vis::CastPickRay(RenderVertexSoft *pRay, float fMouseX, float fMouseY, float fPickDepth) -{ - int pRotY; // esi@1 - Vec3_int_ pStartR; // ST08_12@1 - int pRotX; // ST04_4@1 - int pDepth; // eax@1 - RenderVertexSoft v11[2]; // [sp+2Ch] [bp-74h]@1 - int outx; - int outz; // [sp+94h] [bp-Ch]@1 - int outy; // [sp+98h] [bp-8h]@1 - - pRotY = pGame->pIndoorCameraD3D->sRotationY + UnprojectX(fMouseX); - pRotX = pGame->pIndoorCameraD3D->sRotationX + UnprojectY(fMouseY); - - pStartR.z = pGame->pIndoorCameraD3D->vPartyPos.z; - pStartR.x = pGame->pIndoorCameraD3D->vPartyPos.x; - pStartR.y = pGame->pIndoorCameraD3D->vPartyPos.y; - - v11[1].vWorldPosition.x = (double)pGame->pIndoorCameraD3D->vPartyPos.x; - v11[1].vWorldPosition.y = (double)pGame->pIndoorCameraD3D->vPartyPos.y; - v11[1].vWorldPosition.z = (double)pGame->pIndoorCameraD3D->vPartyPos.z; - - pDepth = fixpoint_from_float(fPickDepth); - Vec3_int_::Rotate(pDepth, pRotY, pRotX, pStartR, &outx, &outy, &outz); - - v11[0].vWorldPosition.x = (double)outx; - v11[0].vWorldPosition.y = (double)outy; - v11[0].vWorldPosition.z = (double)outz; - - memcpy(pRay + 0, &v11[1], sizeof(RenderVertexSoft)); - memcpy(pRay + 1, &v11[0], sizeof(RenderVertexSoft)); -} - -//----- (004C2551) -------------------------------------------------------- -Vis_ObjectInfo *Vis_SelectionList::SelectionPointers(int pVisObjectType, int pid) -{ - //unsigned int v3; // esi@1 - //signed int v4; // edx@1 - //char *v5; // eax@2 - //Vis_ObjectInfo *result; // eax@6 - - //v3 = this->uNumPointers; - if ( this->uNumPointers > 0 ) - { - for ( uint i = 0; i < this->uNumPointers; ++i ) - { - if ( this->object_pool[i].object_type == pVisObjectType && (this->object_pool[i].sZValue & 0xFFFF) == pid ) - return &this->object_pool[i]; - } - } - return nullptr; - /*v4 = 0; - if ( this->uNumPointers <= 0 ) - return false; - else - { - //v5 = (char *)&this->object_pool[0].sZValue; - while ( this->object_pool[v4].object_type != a2 || (this->object_pool[v4].sZValue & 0xFFFF) != a3 ) - { - ++v4; - //v5 += 12; - if ( v4 >= this->uNumPointers ) - return false; - } - result = &this->object_pool[v4]; - } - return result;*/ -} - -//----- (004C2591) -------------------------------------------------------- -void Vis_SelectionList::create_object_pointers(PointerCreationType type) -{ - switch (type) - { - case All: - { - for (uint i = 0; i < uNumPointers; ++i) - object_pointers[i] = &object_pool[i]; - } - break; - - case Unique: // seems quite retarted; the inner if condition will never trigger, since we compare pointers, not values. pointers will always be unique - { // but it may be decompilation error thou - bool create = true; - - for (uint i = 0; i < uNumPointers; ++i) - { - for (uint j = 0; j < i; ++j) - { - if (object_pointers[j] == &object_pool[i]) - { - create = false; - break; - } - } - - if (create) - object_pointers[i] = &object_pool[i]; - } - } - break; - - default: - MessageBoxW(nullptr, L"Unknown pointer creation flag passed to ::create_object_pointers()", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Vis.cpp:1358", 0); - } -} - -//----- (004C264A) -------------------------------------------------------- -void Vis::sort_object_pointers( Vis_ObjectInfo **pPointers, int start, int end )//сортировка -{ - int sort_start; // edx@1 - int forward_sort_index; // esi@2 - signed int backward_sort_index; // ecx@2 - unsigned int last_z_val; // eax@3 - unsigned int more_lz_val; // ebx@4 - unsigned int less_lz_val; // ebx@6 - Vis_ObjectInfo *temp_pointer; // eax@7 -// Vis_ObjectInfo *a3a; // [sp+14h] [bp+Ch]@2 - - sort_start = start; - - if ( end > start ) - { - do - { - forward_sort_index = sort_start - 1; - backward_sort_index = end; - do - { - last_z_val = pPointers[end]->sZValue & 0xFFFF0000; - do - { - ++forward_sort_index; - more_lz_val = pPointers[forward_sort_index]->sZValue & 0xFFFF0000; - } - while ( more_lz_val < last_z_val ); - - do - { - if ( backward_sort_index < 1 ) - break; - --backward_sort_index; - less_lz_val = pPointers[backward_sort_index]->sZValue & 0xFFFF0000; - } - while ( less_lz_val > last_z_val ); - - temp_pointer = pPointers[forward_sort_index]; - if ( forward_sort_index >= backward_sort_index ) - { - pPointers[forward_sort_index] = pPointers[end]; - pPointers[end] = temp_pointer; - } - else - { - pPointers[forward_sort_index] = pPointers[backward_sort_index]; - pPointers[backward_sort_index] = temp_pointer; - } - - } while ( forward_sort_index < backward_sort_index ); - - sort_object_pointers(pPointers, sort_start, forward_sort_index - 1); - sort_start = forward_sort_index + 1; - } - while ( end > forward_sort_index + 1 ); - } -} - -//----- (004C26D0) -------------------------------------------------------- -void Vis::SortVerticesByX(RenderVertexD3D3 *pArray, unsigned int uStart, unsigned int uEnd) -{ - unsigned int left_sort_index; // ebx@2 - RenderVertexD3D3 temp_array; // [sp+4h] [bp-4Ch]@8 - RenderVertexD3D3 max_array; // [sp+24h] [bp-2Ch]@2 - unsigned int right_sort_index; // [sp+4Ch] [bp-4h]@2 - - if ( (signed int)uEnd > (signed int)uStart ) - { - left_sort_index = uStart - 1; - right_sort_index = uEnd; - while ( 1 ) - { - memcpy(&max_array, &pArray[uEnd], sizeof(max_array)); - do - { - ++left_sort_index; - } - while ( pArray[left_sort_index].pos.x < (double)max_array.pos.x ); - do - { - --right_sort_index; - } - while ( pArray[right_sort_index].pos.x > (double)max_array.pos.x ); - if ( (signed int)left_sort_index >= (signed int)right_sort_index ) - break; - memcpy(&temp_array, &pArray[left_sort_index], sizeof(temp_array)); - memcpy(&pArray[left_sort_index], &pArray[right_sort_index], sizeof(pArray[left_sort_index])); - memcpy(&pArray[right_sort_index], &temp_array, sizeof(pArray[right_sort_index])); - } - memcpy(&temp_array, &pArray[left_sort_index], sizeof(temp_array)); - memcpy(&pArray[left_sort_index], &pArray[uEnd], sizeof(pArray[left_sort_index])); - memcpy(&pArray[uEnd], &temp_array, sizeof(pArray[uEnd])); - SortVerticesByX(pArray, uStart, left_sort_index - 1); - SortVerticesByX(pArray, left_sort_index + 1, uEnd); - } -} - -//----- (004C27AD) -------------------------------------------------------- -void Vis::SortVerticesByY(RenderVertexD3D3 *pArray, unsigned int uStart, unsigned int uEnd) -{ - unsigned int left_sort_index; // ebx@2 - RenderVertexD3D3 temp_array; // [sp+4h] [bp-4Ch]@8 - RenderVertexD3D3 max_array; // [sp+24h] [bp-2Ch]@2 - unsigned int right_sort_index; // [sp+4Ch] [bp-4h]@2 - - if ( (signed int)uEnd > (signed int)uStart ) - { - left_sort_index = uStart - 1; - right_sort_index = uEnd; - while ( 1 ) - { - memcpy(&max_array, &pArray[uEnd], sizeof(max_array)); - do - { - ++left_sort_index; - } - while ( pArray[left_sort_index].pos.y < (double)max_array.pos.y ); - do - { - --right_sort_index; - } - while ( pArray[right_sort_index].pos.y > (double)max_array.pos.y ); - if ( (signed int)left_sort_index >= (signed int)right_sort_index ) - break; - memcpy(&temp_array, &pArray[left_sort_index], sizeof(temp_array)); - memcpy(&pArray[left_sort_index], &pArray[right_sort_index], sizeof(pArray[left_sort_index])); - memcpy(&pArray[right_sort_index], &temp_array, sizeof(pArray[right_sort_index])); - } - memcpy(&temp_array, &pArray[left_sort_index], sizeof(temp_array)); - memcpy(&pArray[left_sort_index], &pArray[uEnd], sizeof(pArray[left_sort_index])); - memcpy(&pArray[uEnd], &temp_array, sizeof(pArray[uEnd])); - SortVerticesByY(pArray, uStart, left_sort_index - 1); - SortVerticesByY(pArray, left_sort_index + 1, uEnd); - } -} - -//----- (004C288E) -------------------------------------------------------- -void Vis::SortByScreenSpaceX(RenderVertexSoft *pArray, int start, int end)//сортировка по возрастанию экранных координат х -{ - int left_sort_index; // ebx@2 - int right_sort_index; // ecx@2 - RenderVertexSoft temp_array; // [sp+4h] [bp-6Ch]@8 - RenderVertexSoft max_array; // [sp+34h] [bp-3Ch]@2 - - if ( end > start ) - { - left_sort_index = start - 1; - right_sort_index = end; - memcpy(&max_array, &pArray[end], sizeof(max_array)); - while ( 1 ) - { - do - { - ++left_sort_index; - } - while ( pArray[left_sort_index].vWorldViewProjX < (double)max_array.vWorldViewProjX ); - do - { - --right_sort_index; - } - while ( pArray[right_sort_index].vWorldViewProjX > (double)max_array.vWorldViewProjX ); - if ( left_sort_index >= right_sort_index ) - break; - memcpy(&temp_array, &pArray[left_sort_index], sizeof(temp_array)); - memcpy(&pArray[left_sort_index], &pArray[right_sort_index], sizeof(pArray[left_sort_index])); - memcpy(&pArray[right_sort_index], &temp_array, sizeof(pArray[right_sort_index])); - } - memcpy(&temp_array, &pArray[left_sort_index], sizeof(temp_array)); - memcpy(&pArray[left_sort_index], &pArray[end], sizeof(pArray[left_sort_index])); - memcpy(&pArray[end], &temp_array, sizeof(pArray[end])); - Vis::SortByScreenSpaceX(pArray, start, left_sort_index - 1); - Vis::SortByScreenSpaceX(pArray, left_sort_index + 1, end); - } -} - -//----- (004C297E) -------------------------------------------------------- -void Vis::SortByScreenSpaceY(RenderVertexSoft *pArray, int start, int end) -{ - int left_sort_index; // ebx@2 - int right_sort_index; // ecx@2 - RenderVertexSoft temp_array; // [sp+4h] [bp-6Ch]@8 - RenderVertexSoft max_array; // [sp+34h] [bp-3Ch]@2 - - if ( end > start ) - { - left_sort_index = start - 1; - right_sort_index = end; - memcpy(&max_array, &pArray[end], sizeof(max_array)); - while ( 1 ) - { - do - { - ++left_sort_index; - } - while ( pArray[left_sort_index].vWorldViewProjY < (double)max_array.vWorldViewProjY ); - do - { - --right_sort_index; - } - while ( pArray[right_sort_index].vWorldViewProjY > (double)max_array.vWorldViewProjY ); - if ( left_sort_index >= right_sort_index ) - break; - memcpy(&temp_array, &pArray[left_sort_index], sizeof(temp_array)); - memcpy(&pArray[left_sort_index], &pArray[right_sort_index], sizeof(pArray[left_sort_index])); - memcpy(&pArray[right_sort_index], &temp_array, sizeof(pArray[right_sort_index])); - } - memcpy(&temp_array, &pArray[left_sort_index], sizeof(temp_array)); - memcpy(&pArray[left_sort_index], &pArray[end], sizeof(pArray[left_sort_index])); - memcpy(&pArray[end], &temp_array, sizeof(pArray[end])); - Vis::SortByScreenSpaceY(pArray, start, left_sort_index - 1); - Vis::SortByScreenSpaceY(pArray, left_sort_index + 1, end); - } -} - -//----- (004C04AF) -------------------------------------------------------- -Vis::Vis() -{ - RenderVertexSoft v3; // [sp+Ch] [bp-60h]@1 - RenderVertexSoft v4; // [sp+3Ch] [bp-30h]@1 - - v3.flt_2C = 0.0; - v3.vWorldPosition.x = 0.0; - v3.vWorldPosition.y = 65536.0; - v3.vWorldPosition.z = 0.0; - v4.flt_2C = 0.0; - v4.vWorldPosition.x = 65536.0; - v4.vWorldPosition.y = 0.0; - v4.vWorldPosition.z = 0.0; - memcpy(&stru_200C, &v4, sizeof(stru_200C)); - - v4.flt_2C = 0.0; - v4.vWorldPosition.x = 0.0; - v4.vWorldPosition.y = 65536.0; - v4.vWorldPosition.z = 0.0; - memcpy(&stru_203C, &v3, sizeof(stru_203C)); - - v3.flt_2C = 0.0; - v3.vWorldPosition.x = 65536.0; - v3.vWorldPosition.y = 0.0; - v3.vWorldPosition.z = 0.0; - memcpy(&stru_206C, &v3, sizeof(stru_206C)); - memcpy(&stru_209C, &v4, sizeof(stru_209C)); - - keyboard_pick_depth = 512; -} - -//----- (004C055C) -------------------------------------------------------- -Vis_SelectionList::Vis_SelectionList() -{ - for (uint i = 0; i < 512; ++i) - { - object_pool[i].object = nullptr; - object_pool[i].sZValue = -1; - object_pool[i].object_type = VisObjectType_Any; - } - uNumPointers = 0; -} - -//----- (004C05CC) -------------------------------------------------------- -bool Vis::PickKeyboard(Vis_SelectionList *list, Vis_SelectionFilter *sprite_filter, Vis_SelectionFilter *face_filter) -{ - if (!list) - list = &default_list; - list->uNumPointers = 0; - - PickBillboards_Keyboard(keyboard_pick_depth, list, sprite_filter); - if (uCurrentlyLoadedLevelType == LEVEL_Indoor) - PickIndoorFaces_Keyboard(keyboard_pick_depth, list, face_filter); - else if (uCurrentlyLoadedLevelType == LEVEL_Outdoor) - PickOutdoorFaces_Keyboard(keyboard_pick_depth, list, face_filter); - else - assert(false); - - list->create_object_pointers(Vis_SelectionList::Unique); - sort_object_pointers(list->object_pointers, 0, list->uNumPointers - 1); - - return true; -} - -//----- (004C0646) -------------------------------------------------------- -bool Vis::PickMouse(float fDepth, float fMouseX, float fMouseY, Vis_SelectionFilter *sprite_filter, Vis_SelectionFilter *face_filter) -{ - RenderVertexSoft pMouseRay[2]; // [sp+1Ch] [bp-60h]@1 - - default_list.uNumPointers = 0; - CastPickRay(pMouseRay, fMouseX, fMouseY, fDepth); - PickBillboards_Mouse(fDepth, fMouseX, fMouseY, &default_list, sprite_filter); - if (uCurrentlyLoadedLevelType == LEVEL_Indoor) - PickIndoorFaces_Mouse(fDepth, pMouseRay, &default_list, face_filter); - else if (uCurrentlyLoadedLevelType == LEVEL_Outdoor) - PickOutdoorFaces_Mouse(fDepth, pMouseRay, &default_list, face_filter, false); - else - { - Log::Warning(L"Picking mouse in undefined level"); // picking in main menu is default (buggy) game behaviour. should've returned false in Game::PickMouse - return false; - } - default_list.create_object_pointers(Vis_SelectionList::All); - sort_object_pointers(default_list.object_pointers, 0, default_list.uNumPointers - 1); - - return true; -} - -//----- (004C06F8) -------------------------------------------------------- -void Vis::PickBillboards_Keyboard(float pick_depth, Vis_SelectionList *list, Vis_SelectionFilter *filter) -{ - for (uint i = 0; i < pRenderer->uNumBillboardsToDraw; ++i) - { - RenderBillboardD3D* d3d_billboard = &pRenderer->pBillboardRenderListD3D[i]; - - if (is_part_of_selection((void *)i, filter)) - { - if (DoesRayIntersectBillboard(pick_depth, i)) - { - RenderBillboard* billboard = &pBillboardRenderList[d3d_billboard->sParentBillboardID]; - - list->AddObject((void *)d3d_billboard->sParentBillboardID, VisObjectType_Sprite, billboard->sZValue); - } - } - } -} - - -// tests the object against selection filter to determine whether it can be picked or not -//----- (004C0791) -------------------------------------------------------- -bool Vis::is_part_of_selection(void *uD3DBillboardIdx_or_pBLVFace_or_pODMFace, Vis_SelectionFilter *filter) -{ - //stru157 *v3; // esi@1 - //int result; // eax@1 - //int v5; // edx@2 - //int v6; // ecx@2 - //char v7; // zf@3 - //int v8; // esi@5 -// std::string *v9; // ecx@7 - //Actor *v10; // edi@18 - //const char *v12; // [sp-20h] [bp-2Ch]@7 -// int v13; // [sp-1Ch] [bp-28h]@7 - //std::string v14; // [sp-18h] [bp-24h]@7 - //const char *v15; // [sp-8h] [bp-14h]@7 -// int v16; // [sp-4h] [bp-10h]@7 - - switch (filter->object_type) - { - case VisObjectType_Any: - return true; - - case VisObjectType_Sprite: - { - //v5 = filter->select_flags; - int object_idx = PID_ID(pBillboardRenderList[pRenderer->pBillboardRenderListD3D[(int)uD3DBillboardIdx_or_pBLVFace_or_pODMFace].sParentBillboardID].object_pid); - int object_type = PID_TYPE(pBillboardRenderList[pRenderer->pBillboardRenderListD3D[(int)uD3DBillboardIdx_or_pBLVFace_or_pODMFace].sParentBillboardID].object_pid); - if ( filter->select_flags & 2 ) - { - if (object_type == filter->object_id) - return false; - return true; - } - if ( filter->select_flags & 4 ) - { - //v8 = filter->object_id; - if ( object_type != filter->object_id) - return true; - if (filter->object_id != OBJECT_Decoration) - { - MessageBoxA(nullptr, "Unsupported \"exclusion if no event\" type in CVis::is_part_of_selection", "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Vis.cpp:207", 0); - return true; - } - if (pLevelDecorations[object_idx].uCog || pLevelDecorations[object_idx].uEventID) - return true; - return pLevelDecorations[object_idx].IsInteractive(); - } - if (object_type == filter->object_id) - { - if (object_type != OBJECT_Actor) - { - MessageBoxA(nullptr, "Default case reached in VIS", "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Vis.cpp:245", 0); - return true; - } - - //v10 = &pActors[object_idx]; - int result = 1 << LOBYTE(pActors[object_idx].uAIState); - if ( result & filter->no_at_ai_state - || !(result & filter->at_ai_state) - || filter->select_flags & 8 && (result = MonsterStats::BelongsToSupertype(pActors[object_idx].pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD)) == 0 ) - return false; - if ( !(filter->select_flags & 1) ) - return true; - - result = pActors[object_idx].GetActorsRelation(nullptr); - if (result == 0) - return false; - return true; - } - return false; - } - - case VisObjectType_Face: - { - uint face_attrib = 0; - bool no_event = true; - if (uCurrentlyLoadedLevelType == LEVEL_Outdoor) - { - ODMFace* face = (ODMFace *)uD3DBillboardIdx_or_pBLVFace_or_pODMFace; - no_event = face->sCogTriggeredID == 0; - face_attrib = face->uAttributes; - } - else if (uCurrentlyLoadedLevelType == LEVEL_Indoor) - { - BLVFace* face = (BLVFace *)uD3DBillboardIdx_or_pBLVFace_or_pODMFace; - no_event = pIndoor->pFaceExtras[face->uFaceExtraID].uEventID == 0; - face_attrib = face->uAttributes; - } - else - assert(false); - - if (filter->object_id != OBJECT_BLVDoor) - return true; - if (no_event || face_attrib & filter->no_at_ai_state)//face_attrib = 0x2009408 incorrect - return false; - return (face_attrib & filter->at_ai_state) != 0; - } - - default: - assert(false); - } -} - -//----- (004C091D) -------------------------------------------------------- -bool Vis::DoesRayIntersectBillboard(float fDepth, unsigned int uD3DBillboardIdx) -{ - int v3; // eax@3 - //signed int v5; // ecx@4 - //float v6; // ST04_4@6 - //float v7; // ST00_4@7 - //int v8; // eax@10 - //unsigned int v9; // eax@12 -// int v10; // eax@17 -// double v11; // st6@18 -// double v12; // st7@18 -// double v13; // st4@18 -// float v14; // ST0C_4@22 -// float v15; // ST08_4@22 - //float v16; // ST04_4@23 - //float v17; // ST00_4@24 - //signed int v18; // eax@27 - //unsigned int v19; // eax@29 -// double v20; // st6@32 -// double v21; // st7@32 -// int v22; // eax@32 -// double v23; // st7@36 - //void *v24; // esi@40 -// float v25; // ST08_4@40 - //float v26; // ST04_4@41 - //float v27; // ST00_4@42 -// int v28; // eax@45 -// unsigned int v29; // eax@47 -// char result; // al@48 - struct RenderVertexSoft pPickingRay[2]; - //int v31; // [sp+20h] [bp-DCh]@5 - struct RenderVertexSoft local_80[2]; - - float test_x; - float test_y; - - float t1_x; - float t1_y; - float t2_x; - float t2_y; - float swap_temp; -// int v37; // [sp+F0h] [bp-Ch]@5 - - signed int v40; // [sp+108h] [bp+Ch]@17 - - - static Vis_SelectionList Vis_static_stru_F91E10; - Vis_static_stru_F91E10.uNumPointers = 0; - v3 = pRenderer->pBillboardRenderListD3D[uD3DBillboardIdx].sParentBillboardID; - if (v3 == -1) - return false; - - if (pBillboardRenderList[v3].GetFloatZ() > fDepth) - return false; - - - GetPolygonCenter(pRenderer->pBillboardRenderListD3D[v3].pQuads, 4, &test_x, &test_y); - CastPickRay(pPickingRay, test_x, test_y, fDepth); - if (uCurrentlyLoadedLevelType == LEVEL_Indoor) - PickIndoorFaces_Mouse(fDepth, pPickingRay, &Vis_static_stru_F91E10, &vis_face_filter); - else - PickOutdoorFaces_Mouse(fDepth, pPickingRay, &Vis_static_stru_F91E10, &vis_face_filter, false); - Vis_static_stru_F91E10.create_object_pointers(); - sort_object_pointers(Vis_static_stru_F91E10.object_pointers, 0, Vis_static_stru_F91E10.uNumPointers - 1); - if (Vis_static_stru_F91E10.uNumPointers) - { - if (Vis_static_stru_F91E10.object_pointers[0]->actual_z > pBillboardRenderList[v3].actual_z) - return true; - } - else if ((double)(pViewport->uScreen_TL_X) <= test_x && - (double)pViewport->uScreen_BR_X >= test_x && - (double)pViewport->uScreen_TL_Y <= test_y && - (double)pViewport->uScreen_BR_Y >= test_y) - return true; - - for (v40 = 0; v40 < 4; ++v40) - { - test_x=pRenderer->pBillboardRenderListD3D[uD3DBillboardIdx].pQuads[v40].pos.x; - test_y= pRenderer->pBillboardRenderListD3D[uD3DBillboardIdx].pQuads[v40].pos.y; - if ((double)(pViewport->uScreen_TL_X) <= test_x && - (double)pViewport->uScreen_BR_X >= test_x && - (double)pViewport->uScreen_TL_Y <= test_y && - (double)pViewport->uScreen_BR_Y >= test_y) - { - CastPickRay(local_80, test_x, test_y, fDepth); - if ( uCurrentlyLoadedLevelType == LEVEL_Indoor ) - PickIndoorFaces_Mouse(fDepth, local_80, &Vis_static_stru_F91E10, &vis_face_filter); - else - PickOutdoorFaces_Mouse(fDepth, local_80, &Vis_static_stru_F91E10, &vis_face_filter, false); - Vis_static_stru_F91E10.create_object_pointers(); - sort_object_pointers(Vis_static_stru_F91E10.object_pointers, 0, Vis_static_stru_F91E10.uNumPointers - 1); - if ( !Vis_static_stru_F91E10.uNumPointers ) - return true; - if (Vis_static_stru_F91E10.object_pointers[0]->actual_z > pBillboardRenderList[v3].actual_z) - return true; - } - - } - - if ( v40 >= 4 ) - { - if ( uCurrentlyLoadedLevelType != LEVEL_Outdoor ) - return false; - t1_x = pRenderer->pBillboardRenderListD3D[uD3DBillboardIdx].pQuads[0].pos.x; - t2_x = pRenderer->pBillboardRenderListD3D[uD3DBillboardIdx].pQuads[3].pos.x; - - t1_y = pRenderer->pBillboardRenderListD3D[uD3DBillboardIdx].pQuads[0].pos.y; - t2_y = pRenderer->pBillboardRenderListD3D[uD3DBillboardIdx].pQuads[1].pos.y; - if ( t1_x > t2_x ) - { - swap_temp = t1_x; - t1_x = t2_x; - t2_x = swap_temp; - } - if ( t1_y > t2_y ) - test_y = t1_y; - else - test_y = t2_y; - - Vis_static_stru_F91E10.uNumPointers = 0; - - test_x = (t2_x - t1_x) * 0.5; - if ((double)(pViewport->uScreen_TL_X) <= test_x && - (double)pViewport->uScreen_BR_X >= test_x && - (double)pViewport->uScreen_TL_Y <= test_y && - (double)pViewport->uScreen_BR_Y >= test_y) - { - CastPickRay(local_80, test_x, test_y, fDepth); - if ( uCurrentlyLoadedLevelType == LEVEL_Indoor ) - PickIndoorFaces_Mouse(fDepth, local_80, &Vis_static_stru_F91E10, &vis_face_filter); - else - PickOutdoorFaces_Mouse(fDepth, local_80, &Vis_static_stru_F91E10, &vis_face_filter, false); - Vis_static_stru_F91E10.create_object_pointers(); - sort_object_pointers(Vis_static_stru_F91E10.object_pointers, 0, Vis_static_stru_F91E10.uNumPointers - 1); - if ( !Vis_static_stru_F91E10.uNumPointers ) - return true; - if (Vis_static_stru_F91E10.object_pointers[0]->actual_z > pBillboardRenderList[v3].actual_z) - return true; - - } - - } - return false; -} -// F93E18: using guessed type char static_byte_F93E18_init; - -//----- (004C0D32) -------------------------------------------------------- -void Vis::PickIndoorFaces_Keyboard(float pick_depth, Vis_SelectionList *list, Vis_SelectionFilter *filter) -{ - int result; // eax@1 - signed int pFaceID; // esi@2 - BLVFace *pFace; // edi@4 - //unsigned int v7; // eax@6 - Vis_ObjectInfo *v8; // eax@6 - signed int i; // [sp+18h] [bp-8h]@1 - - result = 0; - for ( i = 0; i < (signed int)pBspRenderer->num_faces; ++i ) - { - pFaceID = pBspRenderer->faces[result].uFaceID; - if ( pFaceID >= 0 ) - { - if ( pFaceID < (signed int)pIndoor->uNumFaces ) - { - pFace = &pIndoor->pFaces[pFaceID]; - if ( !pGame->pIndoorCameraD3D->IsCulled(&pIndoor->pFaces[pFaceID]) ) - { - if ( is_part_of_selection(pFace, filter) ) - { - v8 = DetermineFacetIntersection(pFace, PID(OBJECT_BModel, pFaceID), pick_depth); - if ( v8 ) - list->AddObject(v8->object, v8->object_type, v8->sZValue); - } - } - } - } - result = i + 1; - } -} - -//----- (004C0DEA) -------------------------------------------------------- -void Vis::PickOutdoorFaces_Keyboard(float pick_depth, Vis_SelectionList *list, Vis_SelectionFilter *filter) -{ - for (int i = 0; i < pOutdoor->uNumBModels; ++i) - { - int v17; - if (!IsBModelVisible(i, &v17)) - continue; - if (!v17) - continue; - - BSPModel* bmodel = &pOutdoor->pBModels[i]; - for (int j = 0; j < bmodel->uNumFaces; ++j) - { - //ODMFace* face = &bmodel->pFaces[j]; - - if (is_part_of_selection(&bmodel->pFaces[j], filter) ) - { - BLVFace blv_face; - blv_face.FromODM(&bmodel->pFaces[j]); - - int pid = PID(OBJECT_BModel, j | (i << 6)); - if (Vis_ObjectInfo* object_info = DetermineFacetIntersection(&blv_face, pid, pick_depth)) - list->AddObject(object_info->object, object_info->object_type, object_info->sZValue); - } - } - } -} \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Vis.h --- a/Vis.h Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,133 +0,0 @@ -#pragma once -#include "Render.h" - - - -enum VisObjectType: unsigned __int32 -{ - VisObjectType_Any = 0, - VisObjectType_Sprite = 1, - VisObjectType_Face = 2 -}; - -/* 150 */ -#pragma pack(push, 1) -struct Vis_SelectionFilter //stru157 -{ - VisObjectType object_type; - int object_id; // OBJECT_Actor, OBJECT_Player etc - int at_ai_state; - int no_at_ai_state; - int select_flags; -}; -#pragma pack(pop) -extern Vis_SelectionFilter vis_sprite_filter_1; // 00F93E1C -extern Vis_SelectionFilter vis_sprite_filter_2; // 00F93E30 -extern Vis_SelectionFilter vis_face_filter; // 00F93E44 -extern Vis_SelectionFilter vis_door_filter; // 00F93E58 -extern Vis_SelectionFilter vis_sprite_filter_3; // 00F93E6C -extern Vis_SelectionFilter vis_sprite_filter_4; // static to sub_44EEA7 - - - -#pragma pack(push, 1) -struct Vis_ObjectInfo -{ - void *object; - union - { - int sZValue; - struct - { - unsigned __int16 object_pid; - signed __int16 actual_z; - }; - }; - VisObjectType object_type; -}; -#pragma pack(pop) - - -#pragma pack(push, 1) -struct Vis_SelectionList -{ - enum PointerCreationType - { - All = 0, - Unique = 1 - }; - - Vis_SelectionList(); - //----- (004C0585) -------------------------------------------------------- - ~Vis_SelectionList() {} - Vis_ObjectInfo *SelectionPointers(int a2, int a3); - void create_object_pointers(PointerCreationType type = All); - - inline void AddObject(void *object, VisObjectType type, int packed_zval) - { - object_pool[uNumPointers].object = object; - object_pool[uNumPointers].object_type = type; - object_pool[uNumPointers++].sZValue = packed_zval; - } - - void ( ***vdestructor_ptr)(Vis_SelectionList *, bool); - Vis_ObjectInfo object_pool[512]; - Vis_ObjectInfo *object_pointers[512]; - unsigned int uNumPointers; -}; -#pragma pack(pop) - - - -/* 116 */ -#pragma pack(push, 1) -class Vis -{ -public: - Vis(); - //----- (004C05A2) -------------------------------------------------------- - //virtual ~Vis() {} - //----- (004C05BE) -------------------------------------------------------- - virtual ~Vis() {} - bool PickKeyboard(Vis_SelectionList *list, Vis_SelectionFilter *sprite_filter, Vis_SelectionFilter *face_filter); - void PickBillboards_Keyboard(float pick_depth, Vis_SelectionList *list, Vis_SelectionFilter *filter); - void PickIndoorFaces_Keyboard(float pick_depth, Vis_SelectionList *list, Vis_SelectionFilter *filter); - void PickOutdoorFaces_Keyboard(float pick_depth, Vis_SelectionList *list, Vis_SelectionFilter *filter); - - bool PickMouse(float fDepth, float fMouseX, float fMouseY, Vis_SelectionFilter *sprite_filter, Vis_SelectionFilter *face_filter); - void PickBillboards_Mouse(float fPickDepth, float fX, float fY, Vis_SelectionList *list, Vis_SelectionFilter *filter); - void PickIndoorFaces_Mouse(float fDepth, struct RenderVertexSoft *pRay, Vis_SelectionList *list, Vis_SelectionFilter *filter); - void PickOutdoorFaces_Mouse(float fDepth, struct RenderVertexSoft *pRay, Vis_SelectionList *list, Vis_SelectionFilter *filter, bool only_reachable); - - bool is_part_of_selection(void *uD3DBillboardIdx_or_pBLVFace_or_pODMFace, Vis_SelectionFilter *filter); - bool DoesRayIntersectBillboard(float fDepth, unsigned int uD3DBillboardIdx); - Vis_ObjectInfo *DetermineFacetIntersection(struct BLVFace *face, unsigned int a3, float pick_depth); - bool IsPolygonOccludedByBillboard(struct RenderVertexSoft *vertices, int num_vertices, float x, float y); - void GetPolygonCenter(struct RenderVertexD3D3 *pVertices, unsigned int uNumVertices, float *pCenterX, float *pCenterY); - void GetPolygonScreenSpaceCenter(struct RenderVertexSoft *vertices, int num_vertices, float *out_center_x, float *out_center_y); - bool IsPointInsideD3DBillboard(struct RenderBillboardD3D *a1, float x, float y); - int PickClosestActor(int object_id, unsigned int pick_depth, int a4, int a5, int a6); - void _4C1A02(); - void SortVectors_x(RenderVertexSoft *pArray, int start, int end); - int get_object_zbuf_val(Vis_ObjectInfo *info); - int get_picked_object_zbuf_val(); - bool Intersect_Ray_Face(struct RenderVertexSoft *pRayStart, struct RenderVertexSoft *pRayEnd, float *pDepth, RenderVertexSoft *Intersection, BLVFace *pFace, signed int pBModelID); - bool CheckIntersectBModel(BLVFace *pFace, Vec3_short_ IntersectPoint, signed int sModelID); - void BLV_CreateIntersectFacesVertexCoordList(int *a, int *b, __int16 *intersect_face_vertex_coords_list_a, __int16 *intersect_face_vertex_coords_list_b, Vec3_short_ *IntersectPoint, BLVFace *pFace); - void ODM_CreateIntersectFacesVertexCoordList(int *a, int *b, __int16 *intersect_face_vertex_coords_list_a, __int16 *intersect_face_vertex_coords_list_b, Vec3_short_ *IntersectPoint, BLVFace *pFace, unsigned int uModelID); - void CastPickRay(RenderVertexSoft *pRay, float fMouseX, float fMouseY, float fPickDepth); - void sort_object_pointers(Vis_ObjectInfo **pPointers, int start, int end); - void SortVerticesByX(struct RenderVertexD3D3 *pArray, unsigned int uStart, unsigned int uEnd); - void SortVerticesByY(struct RenderVertexD3D3 *pArray, unsigned int uStart, unsigned int uEnd); - void SortByScreenSpaceX(struct RenderVertexSoft *pArray, int start, int end); - void SortByScreenSpaceY(struct RenderVertexSoft *pArray, int start, int end); - - //void ( ***vdestructor_ptr)(Vis *, bool); - Vis_SelectionList default_list; - RenderVertexSoft stru_200C; - RenderVertexSoft stru_203C; - RenderVertexSoft stru_206C; - RenderVertexSoft stru_209C; - int keyboard_pick_depth; -}; -#pragma pack(pop) diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Weather.cpp --- a/Weather.cpp Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,179 +0,0 @@ -#define _CRTDBG_MAP_ALLOC -#include -#include - -#define _CRT_SECURE_NO_WARNINGS -#include - -#include "Weather.h" -#include "Viewport.h" -#include "Render.h" - -#include "mm7_data.h" ////TODO: remove this once LOWORD/HIWRD stuff is refactored - - - - -struct Weather *pWeather = new Weather; - - - -//----- (004C2AA6) -------------------------------------------------------- -int Weather::DrawSnow() -{ - -// if (!FORCE_16_BITS) - // __debugbreak(); // function expects 16bit target buffer, will fail otherwise - for ( uint i = 0; i < 700; ++i ) - { - int x = 2 * i; - int y = 2 * i + 1; - this->Screen_Coord[x] += rand() % 3 + 1; - this->Screen_Coord[y] += rand() % 2 + 1; - if ( this->Screen_Coord[x] < (signed int)(viewparams->uScreen_BttmR_X - 1) )//467 - { - if ( this->Screen_Coord[x] < (signed int)viewparams->uScreen_topL_X )//8 - this->Screen_Coord[x] = viewparams->uScreen_BttmR_X - rand() % 8; - } - else - this->Screen_Coord[x] = viewparams->uScreen_topL_X + rand() % 8; - if ( this->Screen_Coord[y] < (signed int)viewparams->uScreen_topL_Y//8 - || this->Screen_Coord[y] >= (signed int)viewparams->uScreen_BttmR_Y )//351 - { - this->Screen_Coord[y] = viewparams->uScreen_topL_Y; - this->Screen_Coord[x] = viewparams->uScreen_topL_X + (rand() % (signed int)((viewparams->uScreen_BttmR_X - viewparams->uScreen_topL_X) - 2)); - } - //v1[this->Screen_Coord[2 * i] + 640 * this->Screen_Coord[2 * i + 1]] = 0xFFFFu; - pRenderer->WritePixel16(this->Screen_Coord[x], this->Screen_Coord[y], 0xFFFF);//snowflake - point(снежинка - точка) - } - - for ( uint i = 700; i < 950; ++i ) - { - int x = 2 * i; - int y = 2 * i + 1; - this->Screen_Coord[x] += rand() % 5 - 3;//x - this->Screen_Coord[y] += 4;//y - if ( this->Screen_Coord[x] < (signed int)viewparams->uScreen_topL_X ) - this->Screen_Coord[x] = viewparams->uScreen_BttmR_X - rand() % 4 - 2; - if ( this->Screen_Coord[x] >= (signed int)(viewparams->uScreen_BttmR_X - 2) ) - this->Screen_Coord[x] = rand() % 4 + viewparams->uScreen_topL_X + 2; - if ( this->Screen_Coord[y] < (signed int)viewparams->uScreen_topL_Y || this->Screen_Coord[y] >= (signed int)(viewparams->uScreen_BttmR_Y - 1) ) - { - this->Screen_Coord[y] = viewparams->uScreen_topL_Y; - this->Screen_Coord[x] = viewparams->uScreen_topL_X + (rand() % (signed int)((viewparams->uScreen_BttmR_X - viewparams->uScreen_topL_X) - 2)); - } - pRenderer->WritePixel16(this->Screen_Coord[x], this->Screen_Coord[y], 0xFFFF);//x, y квадратная снежинка) - pRenderer->WritePixel16(this->Screen_Coord[x] + 1, this->Screen_Coord[y], 0xFFFF);//x + 1, y - pRenderer->WritePixel16(this->Screen_Coord[x], this->Screen_Coord[y] + 1, 0xFFFF);//x , y + 1 - pRenderer->WritePixel16(this->Screen_Coord[x] + 1, this->Screen_Coord[y] + 1, 0xFFFF);//x + 1, y + 1 - - //v1[this->Screen_Coord[2 * i] + 640 * this->Screen_Coord[2 * i + 1]] = 0xFFFFu; - //v1[this->Screen_Coord[2 * i] + 640 * this->Screen_Coord[2 * i + 1] + 1] = 0xFFFFu; - //v1[this->Screen_Coord[2 * i] + 640 * (this->Screen_Coord[2 * i + 1] + 1)] = 0xFFFFu; - //v1[this->Screen_Coord[2 * i] + 640 * this->Screen_Coord[2 * i + 1] + 641] = 0xFFFFu; - } - - for ( uint i = 0; i < 50; i++) - { - this->Screen_Coord[1901 + (i * 2)] += 8; - this->Screen_Coord[1901 + ((i * 2) -1)] += rand() % 11 - 5; - if ( this->Screen_Coord[1901 + ((i * 2) -1)] < (signed int)viewparams->uScreen_topL_X || this->Screen_Coord[1901 + ((i * 2) -1)] >= (signed int)(viewparams->uScreen_BttmR_X - 5) ) - { - this->Screen_Coord[1901 + (i * 2)] = viewparams->uScreen_topL_Y; - this->Screen_Coord[1901 + ((i * 2) -1)] = viewparams->uScreen_topL_X + (rand() % (signed int)((viewparams->uScreen_BttmR_X - viewparams->uScreen_topL_X) - 5)); - } - if ( this->Screen_Coord[1901 + (i * 2)] < (signed int)viewparams->uScreen_topL_Y || this->Screen_Coord[1901 + (i * 2)] >= (signed int)(viewparams->uScreen_BttmR_Y - 5) ) - { - this->Screen_Coord[1901 + (i * 2)] = viewparams->uScreen_topL_Y; - this->Screen_Coord[1901 + ((i * 2) -1)] = viewparams->uScreen_topL_X + (rand() % (signed int)((viewparams->uScreen_BttmR_X - viewparams->uScreen_topL_X) - 5)); - } - pRenderer->WritePixel16(this->Screen_Coord[1901 + ((i * 2) -1)], this->Screen_Coord[1901 + (i * 2)], 0xFFFF);//x, y - pRenderer->WritePixel16(this->Screen_Coord[1901 + ((i * 2) -1)], this->Screen_Coord[1901 + (i * 2)] + 1, 0xFFFF);//x, y + 1 - pRenderer->WritePixel16(this->Screen_Coord[1901 + ((i * 2) -1)], this->Screen_Coord[1901 + (i * 2)] + 2, 0xFFFF);//x, y + 2 - pRenderer->WritePixel16(this->Screen_Coord[1901 + ((i * 2) -1)], this->Screen_Coord[1901 + (i * 2)] + 3, 0xFFFF);//x, y + 3 - - pRenderer->WritePixel16(this->Screen_Coord[1901 + ((i * 2) -1)] + 1, this->Screen_Coord[1901 + (i * 2)], 0xFFFF);//x + 1, y - pRenderer->WritePixel16(this->Screen_Coord[1901 + ((i * 2) -1)] + 1, this->Screen_Coord[1901 + (i * 2)] + 1, 0xFFFF);//x + 1, y + 1 - pRenderer->WritePixel16(this->Screen_Coord[1901 + ((i * 2) -1)] + 1, this->Screen_Coord[1901 + (i * 2)] + 2, 0xFFFF);//x + 1, y + 2 - pRenderer->WritePixel16(this->Screen_Coord[1901 + ((i * 2) -1)] + 1, this->Screen_Coord[1901 + (i * 2)] + 3, 0xFFFF);//x + 1, y + 3 - - pRenderer->WritePixel16(this->Screen_Coord[1901 + ((i * 2) -1)] + 2, this->Screen_Coord[1901 + (i * 2)], 0xFFFF);//x + 2, y - pRenderer->WritePixel16(this->Screen_Coord[1901 + ((i * 2) -1)] + 2, this->Screen_Coord[1901 + (i * 2)] + 1, 0xFFFF);//x + 2, y + 1 - pRenderer->WritePixel16(this->Screen_Coord[1901 + ((i * 2) -1)] + 2, this->Screen_Coord[1901 + (i * 2)] + 2, 0xFFFF);//x + 2, y + 2 - pRenderer->WritePixel16(this->Screen_Coord[1901 + ((i * 2) -1)] + 2, this->Screen_Coord[1901 + (i * 2)] + 3, 0xFFFF);//x + 2, y + 3 - - pRenderer->WritePixel16(this->Screen_Coord[1901 + ((i * 2) -1)] + 3, this->Screen_Coord[1901 + (i * 2)], 0xFFFF);//x + 3, y - pRenderer->WritePixel16(this->Screen_Coord[1901 + ((i * 2) -1)] + 3, this->Screen_Coord[1901 + (i * 2)] + 1, 0xFFFF);//x + 3, y + 1 - pRenderer->WritePixel16(this->Screen_Coord[1901 + ((i * 2) -1)] + 3, this->Screen_Coord[1901 + (i * 2)] + 2, 0xFFFF);//x + 3, y + 2 - pRenderer->WritePixel16(this->Screen_Coord[1901 + ((i * 2) -1)] + 3, this->Screen_Coord[1901 + (i * 2)] + 3, 0xFFFF);//x + 3, y + 3 - - //v1[this->Screen_Coord[1901 + ((i * 2) -1)] + 640 * this->Screen_Coord[1901 + (i * 2)]] = 0xFFFFu;//x, y - //v1[this->Screen_Coord[1901 + ((i * 2) -1)] + 640 * (this->Screen_Coord[1901 + (i * 2)] + 1)] = 0xFFFFu;//x, y + 1 - //v1[this->Screen_Coord[1901 + ((i * 2) -1)] + 640 * (this->Screen_Coord[1901 + (i * 2)] + 2)] = 0xFFFFu;//x, y + 2 - //v1[this->Screen_Coord[1901 + ((i * 2) -1)] + 640 * (this->Screen_Coord[1901 + (i * 2)] + 3)] = 0xFFFFu;//x, y + 3 - - //*(&v1[640 * this->Screen_Coord[1901 + (i * 2)] + 1] + this->Screen_Coord[1901 + ((i * 2) -1)]) = 0xFFFFu;//y, x + 1 - //*(&v1[640 * this->Screen_Coord[1901 + (i * 2)] + 641] + this->Screen_Coord[1901 + ((i * 2) -1)]) = 0xFFFFu;//y + 1, x + 1 - //*(&v1[640 * this->Screen_Coord[1901 + (i * 2)] + 1281] + this->Screen_Coord[1901 + ((i * 2) -1)]) = 0xFFFFu;//y + 2, x + 1 - //*(&v1[640 * this->Screen_Coord[1901 + (i * 2)] + 1921] + this->Screen_Coord[1901 + ((i * 2) -1)]) = 0xFFFFu;//y + 3, x + 1 - - //*(&v1[640 * this->Screen_Coord[1901 + (i * 2)] + 2] + this->Screen_Coord[1901 + ((i * 2) -1)]) = 0xFFFFu;//y, x + 2 - //*(&v1[640 * this->Screen_Coord[1901 + (i * 2)] + 642] + this->Screen_Coord[1901 + ((i * 2) -1)]) = 0xFFFFu;//y + 1, x + 2 - //*(&v1[128 * (5 * this->Screen_Coord[1901 + (i * 2)]) + 1282] + this->Screen_Coord[1901 + ((i * 2) -1)]) = 0xFFFFu;//y + 2, x + 2 - //*(&v1[640 * this->Screen_Coord[1901 + (i * 2)] + 1922] + this->Screen_Coord[1901 + ((i * 2) -1)]) = 0xFFFFu;//y + 3, x + 2 - - //*(&v1[640 * this->Screen_Coord[1901 + (i * 2)] + 3] + this->Screen_Coord[1901 + ((i * 2) -1)]) = 0xFFFFu;//y, x + 3 - //*(&v1[640 * this->Screen_Coord[1901 + (i * 2)] + 643] + this->Screen_Coord[1901 + ((i * 2) -1)]) = 0xFFFFu;//y + 1, x + 3 - //*(&v1[640 * this->Screen_Coord[1901 + (i * 2)] + 1283] + this->Screen_Coord[1901 + ((i * 2) -1)]) = 0xFFFFu;//y + 2, x + 3 - //*(&v1[640 * this->Screen_Coord[1901 + (i * 2)] + 1923] + this->Screen_Coord[1901 + ((i * 2) -1)]) = 0xFFFFu;//y + 3, x + 3 - } - return 0; -} - -//----- (004C2EA0) -------------------------------------------------------- -int Weather::Initialize() -{ - signed int v3; // ebx@1 - signed int v4; // ebp@1 - - v3 = pViewport->uScreen_BR_X - pViewport->uScreen_TL_X - 4; - v4 = pViewport->uScreen_BR_Y - pViewport->uScreen_TL_Y - 4; - for ( uint i = 0; i < 1000; i++ ) - { - this->Screen_Coord[2 * i] = LOWORD(pViewport->uViewportTL_X) + rand() % v3; - this->Screen_Coord[(2 * (i + 1)) - 1] = LOWORD(pViewport->uViewportTL_Y) + rand() % v4; - } - return 0; -} - -//----- (004C2EFA) -------------------------------------------------------- -int Weather::Draw() -{ - if ( bRenderSnow || bSnow ) - DrawSnow(); - return 0; -} - -//----- (004C2F0B) -------------------------------------------------------- -bool Weather::OnPlayerTurn(__int16 a2) -{ - unsigned int screen_width; // esi@3 - - if ( this->bRenderSnow != true ) - return 0; - screen_width = viewparams->uScreen_BttmR_X - viewparams->uScreen_topL_X; - - for ( uint i = 0; i < 1000; ++i ) - { - this->Screen_Coord[2 * i] += a2; - if ( this->Screen_Coord[2 * i] < (signed int)viewparams->uScreen_BttmR_X - 4 ) - { - if ( this->Screen_Coord[2 * i] >= (signed int)viewparams->uScreen_topL_X ) - continue; - this->Screen_Coord[2 * i] += screen_width; - } - else - this->Screen_Coord[2 * i] = this->Screen_Coord[2 * i] - screen_width + 4; - } - return 1; -} \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 Weather.h --- a/Weather.h Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -#pragma once - - -#pragma pack(push, 1) - - - -/* 255 */ -struct Weather -{ - inline Weather(): - bNight(false), bRenderSnow(false) - {} - - int DrawSnow(); - int Initialize(); - int Draw(); - bool OnPlayerTurn(__int16 dangle); - - - - __int16 Screen_Coord[2000]; - int bNight; - int bRenderSnow; -}; -#pragma pack(pop) - - - -extern struct Weather *pWeather; \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 mm7_data.cpp --- a/mm7_data.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/mm7_data.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -33,7 +33,7 @@ #include "MapInfo.h" struct MapStats *pMapStats; -#include "Viewport.h" +#include "Engine/Graphics/Viewport.h" struct Viewport *pViewport = new Viewport; struct ViewingParams *viewparams = new ViewingParams; @@ -364,9 +364,9 @@ const char *format_4E2D80 = "\f%05d%s\f00000\n"; //const char *format_4E2DC8 = "\f%05d"; const char *format_4E2DE8 = "\f%05d%s\f00000 - "; -const char *Stat_string_format_2_column_text = "%s\f%05u\t100%s\n"; +const char *Stat_string_format_2_column_text = "%s\f%05u\r180%s\n"; const char *Stat_string_format_2_column_less_100 = "%s\f%05u\t110%d\f00000 / %d\n"; -const char *Stat_string_format_2_column_over_100 = "%s\f%05u\t100%d\f00000 / %d\n"; +const char *Stat_string_format_2_column_over_100 = "%s\f%05u\r180%d\f00000 / %d\n"; int dword_4E455C; // weak std::array dword_4E4560; std::array dword_4E4578; diff -r 7b076fe64f23 -r 5abd8fc8f1c6 stru10.cpp --- a/stru10.cpp Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,860 +0,0 @@ -#define _CRTDBG_MAP_ALLOC -#include -#include - -#define _CRT_SECURE_NO_WARNINGS -#include "stru10.h" -#include "Indoor.h" -#include "Game.h" -#include "Party.h" -#include "ErrorHandling.h" - - - -int _49CE9E_sub0_x(RenderVertexSoft *pVertices, unsigned int uNumVertices, float test_val) -{ - float max_val = FLT_MAX; - int idx = -1; - - float temp_val; - for (uint i = 0; i < uNumVertices; ++i) - { - if (pVertices[i].vWorldPosition.x <= test_val) - temp_val = test_val - pVertices[i].vWorldPosition.x; - else - temp_val = pVertices[i].vWorldPosition.x - test_val; - - if (temp_val < max_val) - { - max_val = temp_val; - idx = i; - } - } - return idx; -} - - -int _49CE9E_sub0_y(RenderVertexSoft *pVertices, unsigned int uNumVertices, float test_val) -{ - float max_val = FLT_MAX; - int idx = -1; - - float temp_val; - for (uint i = 0; i < uNumVertices; ++i) - { - if (pVertices[i].vWorldPosition.y <= test_val) - temp_val = test_val - pVertices[i].vWorldPosition.y; - else - temp_val = pVertices[i].vWorldPosition.y - test_val; - - if (temp_val < max_val) - { - max_val = temp_val; - idx = i; - } - } - return idx; -} - - -int _49CE9E_sub0_z(RenderVertexSoft *pVertices, unsigned int uNumVertices, float test_val) -{ - float max_val = FLT_MAX; - int idx = -1; - - float temp_val; - for (uint i = 0; i < uNumVertices; ++i) - { - if (pVertices[i].vWorldPosition.z <= test_val) - temp_val = test_val - pVertices[i].vWorldPosition.z; - else - temp_val = pVertices[i].vWorldPosition.z - test_val; - - if (temp_val < max_val) - { - max_val = temp_val; - idx = i; - } - } - return idx; -} - -//----- (0049CE9E) -------------------------------------------------------- -void stru10::_49CE9E(BLVFace *pFace, RenderVertexSoft *pVertices, unsigned int uNumVertices, RenderVertexSoft *pOutLimits) -{ - Assert(sizeof(RenderVertexSoft) == 0x30); - - RenderVertexSoft pLimits[64]; - stru10::CalcPolygonLimits(pFace, pLimits); - - if (pFace->uAttributes & FACE_XY_PLANE) - { - memcpy(&pOutLimits[0], &pVertices[_49CE9E_sub0_x(pVertices, uNumVertices, pLimits[0].vWorldPosition.x)], 0x30); - memcpy(&pOutLimits[2], &pVertices[_49CE9E_sub0_x(pVertices, uNumVertices, pLimits[2].vWorldPosition.x)], 0x30); - memcpy(&pOutLimits[1], &pVertices[_49CE9E_sub0_y(pVertices, uNumVertices, pLimits[1].vWorldPosition.y)], 0x30); - memcpy(&pOutLimits[3], &pVertices[_49CE9E_sub0_y(pVertices, uNumVertices, pLimits[3].vWorldPosition.y)], 0x30); - } - else if (pFace->uAttributes & FACE_XZ_PLANE) - { - memcpy(&pOutLimits[0], &pVertices[_49CE9E_sub0_x(pVertices, uNumVertices, pLimits[0].vWorldPosition.x)], 0x30); - memcpy(&pOutLimits[2], &pVertices[_49CE9E_sub0_x(pVertices, uNumVertices, pLimits[2].vWorldPosition.x)], 0x30); - memcpy(&pOutLimits[1], &pVertices[_49CE9E_sub0_z(pVertices, uNumVertices, pLimits[1].vWorldPosition.z)], 0x30); - memcpy(&pOutLimits[3], &pVertices[_49CE9E_sub0_z(pVertices, uNumVertices, pLimits[3].vWorldPosition.z)], 0x30); - } - else if (pFace->uAttributes & FACE_YZ_PLANE) - { - memcpy(&pOutLimits[0], &pVertices[_49CE9E_sub0_y(pVertices, uNumVertices, pLimits[0].vWorldPosition.y)], 0x30); - memcpy(&pOutLimits[2], &pVertices[_49CE9E_sub0_y(pVertices, uNumVertices, pLimits[2].vWorldPosition.y)], 0x30); - memcpy(&pOutLimits[1], &pVertices[_49CE9E_sub0_z(pVertices, uNumVertices, pLimits[1].vWorldPosition.z)], 0x30); - memcpy(&pOutLimits[3], &pVertices[_49CE9E_sub0_z(pVertices, uNumVertices, pLimits[3].vWorldPosition.z)], 0x30); - } -} - -//----- (0049D379) -------------------------------------------------------- -void stru10::CalcPolygonLimits(BLVFace *pFace, RenderVertexSoft *pOutVertices) -{ - struct - { - float x; - float y; - int c; - } v46[40]; //[sp+0C]; - - if (pFace->uAttributes & FACE_XY_PLANE) - { - for (uint i = 0; i < pFace->uNumVertices; ++i) - { - v46[i].x = pIndoor->pVertices[pFace->pVertexIDs[i]].x + pFace->pXInterceptDisplacements[i]; - v46[i].y = pIndoor->pVertices[pFace->pVertexIDs[i]].y + pFace->pYInterceptDisplacements[i]; - v46[i].c = i; - } - } - if (pFace->uAttributes & FACE_XZ_PLANE) - { - for (uint i = 0; i < pFace->uNumVertices; ++i) - { - v46[i].x = pIndoor->pVertices[pFace->pVertexIDs[i]].x + pFace->pXInterceptDisplacements[i]; - v46[i].y = pIndoor->pVertices[pFace->pVertexIDs[i]].z + pFace->pZInterceptDisplacements[i]; - v46[i].c = i; - } - } - if (pFace->uAttributes & FACE_YZ_PLANE) - { - for (uint i = 0; i < pFace->uNumVertices; ++i) - { - v46[i].x = pIndoor->pVertices[pFace->pVertexIDs[i]].y + pFace->pYInterceptDisplacements[i]; - v46[i].y = pIndoor->pVertices[pFace->pVertexIDs[i]].z + pFace->pZInterceptDisplacements[i]; - v46[i].c = i; - } - } - - float x_min = v46[0].x; - uint x_min_idx = 0; - - float x_max = v46[0].x; - uint x_max_idx = 0; - - float y_min = v46[0].y; - uint y_min_idx = 0; - - float y_max = v46[0].y; - uint y_max_idx = 0; - - for (uint i = 0; i < pFace->uNumVertices; ++i) - { - if (v46[i].x < x_min) - { - x_min = v46[i].x; - x_min_idx = v46[i].c; - } - if (v46[i].x > x_max) - { - x_max = v46[i].x; - x_max_idx = v46[i].c; - } - - if (v46[i].y < y_min) - { - y_min = v46[i].y; - y_min_idx = v46[i].c; - } - if (v46[i].y > y_max) - { - y_max = v46[i].y; - y_max_idx = v46[i].c; - } - } - - RenderVertexSoft v1; // [sp+30Ch] [bp-54h]@24 - v1.vWorldPosition.x = (float)pIndoor->pVertices[pFace->pVertexIDs[x_min_idx]].x; - v1.vWorldPosition.y = (float)pIndoor->pVertices[pFace->pVertexIDs[x_min_idx]].y; - v1.vWorldPosition.z = (float)pIndoor->pVertices[pFace->pVertexIDs[x_min_idx]].z; - memcpy(&pOutVertices[0], &v1, sizeof(RenderVertexSoft)); - - RenderVertexSoft v2; // [sp+30Ch] [bp-54h]@24 - v2.vWorldPosition.x = (float)pIndoor->pVertices[pFace->pVertexIDs[y_min_idx]].x; - v2.vWorldPosition.y = (float)pIndoor->pVertices[pFace->pVertexIDs[y_min_idx]].y; - v2.vWorldPosition.z = (float)pIndoor->pVertices[pFace->pVertexIDs[y_min_idx]].z; - memcpy(&pOutVertices[1], &v2, sizeof(RenderVertexSoft)); - - RenderVertexSoft v3; // [sp+30Ch] [bp-54h]@24 - v3.vWorldPosition.x = (float)pIndoor->pVertices[pFace->pVertexIDs[x_max_idx]].x; - v3.vWorldPosition.y = (float)pIndoor->pVertices[pFace->pVertexIDs[x_max_idx]].y; - v3.vWorldPosition.z = (float)pIndoor->pVertices[pFace->pVertexIDs[x_max_idx]].z; - memcpy(&pOutVertices[2], &v3, sizeof(RenderVertexSoft)); - - RenderVertexSoft v4; // [sp+30Ch] [bp-54h]@24 - v4.vWorldPosition.x = (double)pIndoor->pVertices[pFace->pVertexIDs[y_max_idx]].x; - v4.vWorldPosition.y = (double)pIndoor->pVertices[pFace->pVertexIDs[y_max_idx]].y; - v4.vWorldPosition.z = (double)pIndoor->pVertices[pFace->pVertexIDs[y_max_idx]].z; - memcpy(&pOutVertices[3], &v4, sizeof(RenderVertexSoft)); -} - - -//----- (0049C9E3) -------------------------------------------------------- -bool stru10::CalcFaceBounding(BLVFace *pFace, RenderVertexSoft *pFaceLimits, unsigned int uNumVertices, RenderVertexSoft *pOutBounding) -{ - //IndoorCameraD3D *v6; // edi@1 - //PolygonType v7; // al@1 - //unsigned int v8; // edx@7 - //char v10; // zf@10 - //float v13; // ST14_4@20 - //stru10 *v15; // ecx@21 - //RenderVertexSoft *v16; // ST0C_4@21 - //bool result; // eax@21 - //float v18; // ST14_4@24 - //stru10 *v19; // edi@29 - //float v20; // ST14_4@30 - //float v21; // ST14_4@30 - //float v22; // ST14_4@30 - //float v23; // ST14_4@30 - //float v24; // ST14_4@31 - //RenderVertexSoft v25; // [sp+10h] [bp-90h]@24 - //RenderVertexSoft v26; // [sp+40h] [bp-60h]@20 - //IndoorCameraD3D *thisa; // [sp+70h] [bp-30h]@1 - //stru10 *v31; // [sp+84h] [bp-1Ch]@1 - //float v32; // [sp+88h] [bp-18h]@8 - Vec3_float_ a1; // [sp+8Ch] [bp-14h]@1 - //float v35; // [sp+9Ch] [bp-4h]@8 - - //auto a3 = pFace; - //auto arg4 = pFaceBounding; - - //_ESI = a3; - //v31 = this; - //v6 = pGame->pIndoorCameraD3D; - //v7 = a3->uPolygonType; - - a1.x = 0.0f; - a1.y = 0.0f; - a1.z = 0.0f; - - float var_28; - float var_24; - switch (pFace->uPolygonType) - { - case POLYGON_VerticalWall: - a1.x = -pFace->pFacePlane.vNormal.y;// направление полигона - a1.y = pFace->pFacePlane.vNormal.x; - a1.z = 0.0f; - a1.Normalize(); - - var_28 = 0; - var_24 = 1; - break; - - case POLYGON_Floor: - case POLYGON_Ceiling: - a1.x = 1; - a1.y = 0; - a1.z = 0.0f; - - var_28 = 1; - var_24 = 0; - break; - - default: - Error("Invalid polygon type (%u)", pFace->uPolygonType); - } - - - float face_center_x; - float face_center_y; - float face_center_z; - float a3; - float var_8; - - if (pFace->uAttributes & FACE_XY_PLANE) - { - face_center_x = (pFaceLimits[0].vWorldPosition.x + pFaceLimits[2].vWorldPosition.x) / 2; - face_center_y = (pFaceLimits[3].vWorldPosition.y + pFaceLimits[1].vWorldPosition.y) / 2; - face_center_z = (pFaceLimits[0].vWorldPosition.z + pFaceLimits[2].vWorldPosition.z) / 2; - - a3 = face_center_x - pFaceLimits[0].vWorldPosition.x; - var_8 = face_center_y - pFaceLimits[1].vWorldPosition.y; - } - if (pFace->uAttributes & FACE_XZ_PLANE) - { - face_center_x = (pFaceLimits[0].vWorldPosition.x + pFaceLimits[2].vWorldPosition.x) / 2;// центр полигона - face_center_y = (pFaceLimits[0].vWorldPosition.y + pFaceLimits[2].vWorldPosition.y) / 2; - face_center_z = (pFaceLimits[1].vWorldPosition.z + pFaceLimits[3].vWorldPosition.z) / 2; - - a3 = face_center_x - pFaceLimits[0].vWorldPosition.x;//от центра до верхнего края - var_8 = face_center_z - pFaceLimits[1].vWorldPosition.z;// высота от центра - - if (pFace->uPolygonType == POLYGON_VerticalWall) - a3 /= a1.x; - } - if (pFace->uAttributes & FACE_YZ_PLANE) - { - face_center_x = (pFaceLimits[0].vWorldPosition.x + pFaceLimits[2].vWorldPosition.x) / 2; - face_center_y = (pFaceLimits[0].vWorldPosition.y + pFaceLimits[2].vWorldPosition.y) / 2; - face_center_z = (pFaceLimits[1].vWorldPosition.z + pFaceLimits[3].vWorldPosition.z) / 2; - - a3 = face_center_y - pFaceLimits[0].vWorldPosition.y; - var_8 = face_center_z - pFaceLimits[1].vWorldPosition.z; - // [0.5] - if (pFace->uPolygonType == POLYGON_VerticalWall) - { - if (a1.x != 1.0f) - a3 /= a1.y; - } - } - - - - - //_EBX = arg0; - //v15 = v31; - //v16 = arg0; - //float var_20 = var_8 * var_24; - //var_8 = a3 * a1.z; - //float arg_0 = var_8 + var_4; - -/* - - - -.text:0049CBB3 fld [ebp+var_8] 0 var8 -.text:0049CBB6 1 fmul ds:flt_4D84E8 0 var8 * flt_4D84E8 - -.text:0049CBBC 1 fld [ebp+var_8] 0 var8 - 1 var8 * flt_4D84E8 - -.text:0049CBBF 2 fmul [ebp+var_28] 0 var8 * var28 - 1 var8 * flt_4D84E8 - -.text:0049CBC2 2 fld [ebp+var_8] 0 var8 - 1 var8 * var28 - 2 var8 * flt_4D84E8 - -.text:0049CBC5 3 fmul [ebp+var_24] 0 var8 * var24 768 - 1 var8 * var28 0 - 2 var8 * flt_4D84E8 0 - -.text:0049CBD5 3 fst [ebp+var_20] 0 var8 * var24 768 - 1 var8 * var28 0 - 2 var8 * flt_4D84E8 0 - [var20] var8 * var24 768 - -.text:0049CBD8 3 fld [ebp+a3] 0 a3 -1984 - 1 var8 * var24 768 - 2 var8 * var28 0 - 3 var8 * flt_4D84E8 0 - -.text:0049CBDB 4 fmul [ebp+a1.x] 0 a3 * a1.x 1984 - 1 var8 * var24 768 - 2 var8 * var28 0 - 3 var8 * flt_4D84E8 0 - -.text:0049CBDE 4 fld [ebp+a3] 0 a3 - 1 a3 * a1.x 1984 - 2 var8 * var24 768 - 3 var8 * var28 0 - 4 var8 * flt_4D84E8 0 - -.text:0049CBE1 5 fmul [ebp+a1.y] 0 a3 * a1.y 0 - 1 a3 * a1.x 1984 - 2 var8 * var24 768 - 3 var8 * var28 0 - 4 var8 * flt_4D84E8 0 -.text:0049CBE4 5 fld [ebp+a3] -.text:0049CBE7 6 fmul [ebp+a1.z] 0 a3 * a1.z 0 - 1 a3 * a1.y 0 - 2 a3 * a1.x 1984 - 3 var8 * var24 768 - 4 var8 * var28 0 - 5 var8 * flt_4D84E8 0 - -.text:0049CBEC 6 fstp [ebp+var_8] - var8 <- a3 * a1.z 0 - -.text:0049CBEF 5 fld [ebp+arg4] 0 arg4 -1700 - 1 a3 * a1.y 0 - 2 a3 * a1.x 1984 - 3 var8 * var24 768 - 4 var8 * var28 0 - 5 var8 * flt_4D84E8 0 - -.text:0049CBF2 6 fsub st, st(2) 0 arg4 - a3 * a1.x -3684 - 1 a3 * a1.y 0 - 2 a3 * a1.x 1984 - 3 var8 * var24 768 - 4 var8 * var28 0 - 5 var8 * flt_4D84E8 0 - -.text:0049CBF4 6 fld st 0 arg4 - a3 * a1.x -3684 - 1 arg4 - a3 * a1.x -3684 - 2 a3 * a1.y 0 - 3 a3 * a1.x 1984 - 4 var8 * var24 768 - 5 var8 * var28 0 - 6 var8 * flt_4D84E8 0 - -.text:0049CBF6 7 fadd st, st(6) 0 arg4 - a3 * a1.x + var8 * flt_4D84E8 -3684 - 1 arg4 - a3 * a1.x -3684 - 2 a3 * a1.y 0 - 3 a3 * a1.x 1984 - 4 var8 * var24 768 - 5 var8 * var28 0 - 6 var8 * flt_4D84E8 0 -.text:0049CBF8 7 fstp dword ptr [ebx] - [0].x <- arg4 - a3 * a1.x + var8 * flt_4D84E8 -3684 - -.text:0049CBFA 6 fld [ebp+var_18] 0 var18 1480 - 1 arg4 - a3 * a1.x -3684 - 2 a3 * a1.y 0 - 3 a3 * a1.x 1984 - 4 var8 * var24 768 - 5 var8 * var28 0 - 6 var8 * flt_4D84E8 0 - -.text:0049CBFD 7 fsub st, st(2) 0 var18 - a3 * a1.y 1480 - 1 arg4 - a3 * a1.x -3684 - 2 a3 * a1.y 0 - 3 a3 * a1.x 1984 - 4 var8 * var24 768 - 5 var8 * var28 0 - 6 var8 * flt_4D84E8 0 - -.text:0049CBFF 7 fld st 0 var18 - a3 * a1.y 1480 - 1 var18 - a3 * a1.y 1480 - 2 arg4 - a3 * a1.x -3684 - 3 a3 * a1.y 0 - 4 a3 * a1.x 1984 - 5 var8 * var24 768 - 6 var8 * var28 0 - 7 var8 * flt_4D84E8 0 - -.text:0049CC01 8 fadd st, st(6) 0 var18 - a3 * a1.y + var8 * var28 1480 - 1 var18 - a3 * a1.y 1480 - 2 arg4 - a3 * a1.x -3684 - 3 a3 * a1.y 0 - 4 a3 * a1.x 1984 - 5 var8 * var24 768 - 6 var8 * var28 0 - 7 var8 * flt_4D84E8 0 - -.text:0049CC03 8 fstp dword ptr [ebx+4] - [0].y <- var18 - a3 * a1.y + var8 * var28 1480 - -.text:0049CC06 7 fld [ebp+var_4] -.text:0049CC09 8 fsub [ebp+var_8] 0 var4 - a3 * a1.z 768 - 1 var18 - a3 * a1.y 1480 - 2 arg4 - a3 * a1.x -3684 - 3 a3 * a1.y 0 - 4 a3 * a1.x 1984 - 5 var8 * var24 768 - 6 var8 * var28 0 - 7 var8 * flt_4D84E8 0 -.text:0049CC0C 8 fst [ebp+a3] - a3 <- var4 - a3 * a1.z 768 - -.text:0049CC0F 8 fadd st, st(5) -.text:0049CC11 8 fstp dword ptr [ebx+8] - [0].z <- var4 - a3 * a1.z + var8 * var24 1536 - - 0 var18 - a3 * a1.y 1480 - 1 arg4 - a3 * a1.x -3684 - 2 a3 * a1.y 0 - 3 a3 * a1.x 1984 - 4 var8 * var24 768 - 5 var8 * var28 0 - 6 var8 * flt_4D84E8 0 - - - - - [var20] var8 * var24 768 - [var8] a3 * a1.z - [a3] var4 - a3 * a1.z 768 - - -.text:0049CC14 7 fld st(1) -.text:0049CC16 8 fsub st, st(7) 0 arg4 - a3 * a1.x - var8 * flt_4D84E8 -3684 - 1 var18 - a3 * a1.y 1480 - 2 arg4 - a3 * a1.x -3684 - 3 a3 * a1.y 0 - 4 a3 * a1.x 1984 - 5 var8 * var24 768 - 6 var8 * var28 0 - 7 var8 * flt_4D84E8 0 -.text:0049CC18 8 fstp dword ptr [ebx+30h] - [1].x <- arg4 - a3 * a1.x - var8 * flt_4D84E8 -3684 - - 0 var18 - a3 * a1.y 1480 - 1 arg4 - a3 * a1.x -3684 - 2 a3 * a1.y 0 - 3 a3 * a1.x 1984 - 4 var8 * var24 768 - 5 var8 * var28 0 - 6 var8 * flt_4D84E8 0 -.text:0049CC1B 7 fsub st, st(5) -.text:0049CC1D 7 fstp dword ptr [ebx+34h] - [1].y <- var18 - a3 * a1.y - var8 * var28 1480 -.text:0049CC20 6 fstp st - 0 a3 * a1.y 0 - 1 a3 * a1.x 1984 - 2 var8 * var24 768 - 3 var8 * var28 0 - 4 var8 * flt_4D84E8 0 - - - [var20] var8 * var24 768 - [var8] a3 * a1.z - [a3] var4 - a3 * a1.z 768 - -.text:0049CC22 5 fld [ebp+a3] 0 var4 - a3 * a1.z 768 - 1 a3 * a1.y 0 - 2 a3 * a1.x 1984 - 3 var8 * var24 768 - 4 var8 * var28 0 - 5 var8 * flt_4D84E8 0 -.text:0049CC25 6 fsub st, st(3) -.text:0049CC27 6 fstp dword ptr [ebx+38h] - [1].z <- var4 - a3 * a1.z - var8 * var24 768 - 768 = 0 - - 0 a3 * a1.y 0 - 1 a3 * a1.x 1984 - 2 var8 * var24 768 - 3 var8 * var28 0 - 4 var8 * flt_4D84E8 0 - - -.text:0049CC2A fld st(1) -.text:0049CC2C 6 fadd [ebp+arg4] 0 arg4 + a3 * a1.x 284 - 1 a3 * a1.y 0 - 2 a3 * a1.x 1984 - 3 var8 * var24 768 - 4 var8 * var28 0 - 5 var8 * flt_4D84E8 0 -.text:0049CC2F 6 fst [ebp+a3] - - [var20] var8 * var24 768 - [var8] a3 * a1.z - [a3] arg4 + a3 * a1.x 284 -.text:0049CC32 6 fsub st, st(5) -.text:0049CC34 6 fstp dword ptr [ebx+60h] - [2].x <- arg4 + a3 * a1.x - var8 * flt_4D84E8 284 - - 0 a3 * a1.y 0 - 1 a3 * a1.x 1984 - 2 var8 * var24 768 - 3 var8 * var28 0 - 4 var8 * flt_4D84E8 0 - -.text:0049CC37 5 fadd [ebp+var_18] 0 var18 + a3 * a1.y 1480 - 1 a3 * a1.x 1984 - 2 var8 * var24 768 - 3 var8 * var28 0 - 4 var8 * flt_4D84E8 0 - -.text:0049CC3A 5 fstp st(2) 0 a3 * a1.x 1984 - 1 var18 + a3 * a1.y 1480 - 2 var8 * var28 0 - 3 var8 * flt_4D84E8 0 - -.text:0049CC3C 4 fstp st 0 var18 + a3 * a1.y 1480 - 1 var8 * var28 0 - 2 var8 * flt_4D84E8 0 - -.text:0049CC3E 3 fld st 0 var18 + a3 * a1.y 1480 - 1 var18 + a3 * a1.y 1480 - 2 var8 * var28 0 - 3 var8 * flt_4D84E8 0 -.text:0049CC40 4 fsub st, st(2) -.text:0049CC42 4 fstp dword ptr [ebx+64h] - [2].y <- var18 + a3 * a1.y - var8 * var28 1480 - - 0 var18 + a3 * a1.y 1480 - 1 var8 * var28 0 - 2 var8 * flt_4D84E8 0 - - [var20] var8 * var24 768 - [var8] a3 * a1.z - [a3] arg4 + a3 * a1.x 284 -.text:0049CC45 3 fld [ebp+var_8] -.text:0049CC48 4 fadd [ebp+var_4] 0 var4 + a3 * a1.z 768 - 1 var18 + a3 * a1.y 1480 - 2 var8 * var28 0 - 3 var8 * flt_4D84E8 0 - -.text:0049CC4B 4 fst [ebp+arg0] - [var20] var8 * var24 768 - [arg0] var4 + a3 * a1.z 768 - [var8] a3 * a1.z 0 - [a3] arg4 + a3 * a1.x 284 - -.text:0049CC4E 4 fsub [ebp+var_20] -.text:0049CC51 4 fstp dword ptr [ebx+68h] - [2].z <- var4 + a3 * a1.z - var8 * var24 0 - - - - [var20] var8 * var24 768 - [arg0] var4 + a3 * a1.z 768 - [var8] a3 * a1.z 0 - [a3] arg4 + a3 * a1.x 284 - - - 0 var18 + a3 * a1.y 1480 - 1 var8 * var28 0 - 2 var8 * flt_4D84E8 0 - -.text:0049CC54 3 fld [ebp+a3] -.text:0049CC57 4 fadd st, st(3) -.text:0049CC59 4 fstp dword ptr [ebx+90h] - [3].x <- arg4 + a3 * a1.x + var8 * flt_4D84E8 284 - -.text:0049CC5F 3 fadd st, st(1) -.text:0049CC61 3 fstp dword ptr [ebx+94h] - [3].y <- var18 + a3 * a1.y + var8 * var28 1480 - -.text:0049CC67 2 fstp st -.text:0049CC69 1 fstp st - 0 empty -.text:0049CC6B 0 fld [ebp+arg0] -.text:0049CC6E 1 fadd [ebp+var_20] -.text:0049CC71 1 fstp dword ptr [ebx+98h] - [3].z <- var4 + a3 * a1.z + var8 * var24 1536 - - 0 empty -*/ - - pOutBounding[0].vWorldPosition.x = face_center_x - a3 * a1.x + var_8 * flt_4D84E8; - pOutBounding[0].vWorldPosition.y = face_center_y - a3 * a1.y + var_8 * var_28; - pOutBounding[0].vWorldPosition.z = face_center_z - a3 * a1.z + var_8 * var_24; - - pOutBounding[1].vWorldPosition.x = face_center_x - a3 * a1.x - var_8 * flt_4D84E8; - pOutBounding[1].vWorldPosition.y = face_center_y - a3 * a1.y - var_8 * var_28; - pOutBounding[1].vWorldPosition.z = face_center_z - a3 * a1.z - var_8 * var_24; - - pOutBounding[2].vWorldPosition.x = face_center_x + a3 * a1.x - var_8 * flt_4D84E8; - pOutBounding[2].vWorldPosition.y = face_center_y + a3 * a1.y - var_8 * var_28; - pOutBounding[2].vWorldPosition.z = face_center_z + a3 * a1.z - var_8 * var_24; - - pOutBounding[3].vWorldPosition.x = face_center_x + a3 * a1.x + var_8 * flt_4D84E8; - pOutBounding[3].vWorldPosition.y = face_center_y + a3 * a1.y + var_8 * var_28; - pOutBounding[3].vWorldPosition.z = face_center_z + a3 * a1.z + var_8 * var_24; - - a1.x = 0.0f; - a1.y = 0.0f; - a1.z = 0.0f; - a3 = face_center_x + a3 * a1.x; - - if (!FindFacePlane(pOutBounding, &a1, &a3)) - return false; - - - - RenderVertexSoft v25; // [sp+10h] [bp-90h]@20 - memcpy(&v25, pOutBounding, sizeof(RenderVertexSoft)); - - float _dp = (v25.vWorldPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x) * a1.x + - (v25.vWorldPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y) * a1.y + - (v25.vWorldPosition.z - pGame->pIndoorCameraD3D->vPartyPos.z) * a1.z; - if (fabs(_dp) < 1e-6f) - { - memcpy(&v25, &pOutBounding[1], sizeof(RenderVertexSoft)); - memcpy(&pOutBounding[1], &pOutBounding[3], sizeof(RenderVertexSoft)); - memcpy(&pOutBounding[3], &v25, sizeof(RenderVertexSoft)); - } - - //if ( byte_4D864C && pGame->uFlags & GAME_FLAGS_1_DRAW_BLV_DEBUGS) - //{ - RenderVertexSoft v26; // [sp+40h] [bp-60h]@20 - if ( draw_portals_loops ) - { - if (!bDoNotDrawPortalFrustum) - { - v26.vWorldPosition.x = pParty->vPosition.x; - v26.vWorldPosition.y = pParty->vPosition.y; - v26.vWorldPosition.z = pParty->vPosition.z + pParty->sEyelevel; // frustum - - pGame->pIndoorCameraD3D->do_draw_debug_line_sw(&v26, 0xFF0000u, &pOutBounding[0], 0xFF0000u, 0, 0); - pGame->pIndoorCameraD3D->do_draw_debug_line_sw(&v26, 0xFF00u, &pOutBounding[1], 0xFF00u, 0, 0); - pGame->pIndoorCameraD3D->do_draw_debug_line_sw(&v26, 0xFFu, &pOutBounding[2], 0xFFu, 0, 0); - pGame->pIndoorCameraD3D->do_draw_debug_line_sw(&v26, 0xFFFFFFu, &pOutBounding[3], 0xFFFFFFu, 0, 0); - bDoNotDrawPortalFrustum = true; - } - pGame->pIndoorCameraD3D->debug_outline_sw(pOutBounding, uNumVertices, 0x1EFF1Eu, 0.00019999999); // bounding - } - //} - - //pGame->pIndoorCameraD3D->debug_outline_sw(pFaceLimits, 4, 0xFFF14040, 0.000099999997); // limits - - /*if ( byte_4D864C && pGame->uFlags & GAME_FLAGS_1_DRAW_BLV_DEBUGS) - { - RenderVertexSoft v26; // [sp+40h] [bp-60h]@20 - v26.vWorldPosition.x = face_center_x; // corner to center - v26.vWorldPosition.y = face_center_y; - v26.vWorldPosition.z = face_center_z; - - pGame->pIndoorCameraD3D->do_draw_debug_line_sw(pFaceLimits, 0xFF00u, &v26, 0xFF0000u, 0, 0); - }*/ - - - /*if ( byte_4D864C ) - { - if ( pGame->uFlags & GAME_FLAGS_1_DRAW_BLV_DEBUGS)*/ - { - RenderVertexSoft v25; // [sp+10h] [bp-90h]@20 - RenderVertexSoft v26; // [sp+40h] [bp-60h]@20 - - v25.vWorldPosition.x = face_center_x; // portal normal - v25.vWorldPosition.y = face_center_y; - v25.vWorldPosition.z = face_center_z; - - v26.vWorldPosition.x = face_center_x + a1.x * 400.0f; - v26.vWorldPosition.y = face_center_y + a1.y * 400.0f; - v26.vWorldPosition.z = face_center_z + a1.z * 400.0f; - - if ( draw_portals_loops ) - pGame->pIndoorCameraD3D->do_draw_debug_line_sw(&v25, -1, &v26, 0xFFFF00u, 0, 0); - } - //} - - return true; -} - - - -//----- (0049C5B0) -------------------------------------------------------- -stru10::stru10() -{ - this->bDoNotDrawPortalFrustum = false; -} - -//----- (0049C5BD) -------------------------------------------------------- -stru10::~stru10() -{ -} - -//----- (0049C5DA) -------------------------------------------------------- -char stru10::_49C5DA(BLVFace *pFace, RenderVertexSoft *pVertices, unsigned int *pNumVertices, IndoorCameraD3D_Vec4 *a5, RenderVertexSoft *pOutBounding) -{ - RenderVertexSoft pLimits[4]; // [sp+Ch] [bp-C0h]@1 - - _49CE9E(pFace, pVertices, *pNumVertices, pLimits); - - //if ( byte_4D864C && pGame->uFlags & GAME_FLAGS_1_DRAW_BLV_DEBUGS) - // pGame->pIndoorCameraD3D->debug_outline_sw(a4a, 4u, 0xFF1E1Eu, 0.000099999997); - if (CalcFaceBounding(pFace, pLimits, 4, pOutBounding)) - return _49C720(pOutBounding, a5); - return false; -} -// 4D864C: using guessed type char byte_4D864C; - -//----- (0049C681) -------------------------------------------------------- -bool stru10::CalcPortalShape(BLVFace *pFace, IndoorCameraD3D_Vec4 *pPortalDataFrustum, RenderVertexSoft *pOutBounding) -{ - RenderVertexSoft pLimits[4]; // [sp+Ch] [bp-C0h]@1 - - CalcPolygonLimits(pFace, pLimits);//определение границ портала - //if ( byte_4D864C && pGame->uFlags & GAME_FLAGS_1_DRAW_BLV_DEBUGS) - // pGame->pIndoorCameraD3D->debug_outline_sw(pLimits, 4, 0xFF1E1E, 0.000099999997); - if (CalcFaceBounding(pFace, pLimits, 4, pOutBounding)) - return _49C720(pOutBounding, pPortalDataFrustum) != 0; - return false; -} - -// 4D864C: using guessed type char byte_4D864C; - -//----- (0049C720) -------------------------------------------------------- -char stru10::_49C720(RenderVertexSoft *pFaceBounding, IndoorCameraD3D_Vec4 *pPortalDataFrustum) -{ - Vec3_float_ pRayStart; // [sp+4h] [bp-34h]@1 - pRayStart.x = (double)pGame->pIndoorCameraD3D->vPartyPos.x; - pRayStart.y = (double)pGame->pIndoorCameraD3D->vPartyPos.y; - pRayStart.z = (double)pGame->pIndoorCameraD3D->vPartyPos.z; - - if (FindFaceNormal(&pFaceBounding[0], &pFaceBounding[1], &pRayStart, &pPortalDataFrustum[0]) && - FindFaceNormal(&pFaceBounding[1], &pFaceBounding[2], &pRayStart, &pPortalDataFrustum[1]) && - FindFaceNormal(&pFaceBounding[2], &pFaceBounding[3], &pRayStart, &pPortalDataFrustum[2]) && - FindFaceNormal(&pFaceBounding[3], &pFaceBounding[0], &pRayStart, &pPortalDataFrustum[3])) - return true; - return false; -} - -//----- (0049C7C5) -------------------------------------------------------- -bool stru10::FindFaceNormal(RenderVertexSoft *pFaceBounding1, RenderVertexSoft *pFaceBounding2, Vec3_float_ *pRayStart, IndoorCameraD3D_Vec4 *pPortalDataFrustum) -{ - Vec3_float_ ray_dir; // [sp+4h] [bp-48h]@1 - Vec3_float_ pRay2; // [sp+10h] [bp-3Ch]@1 - - ray_dir.x = pFaceBounding1->vWorldPosition.x - pRayStart->x;//get ray for cmera to bounding1 - ray_dir.y = pFaceBounding1->vWorldPosition.y - pRayStart->y; - ray_dir.z = pFaceBounding1->vWorldPosition.z - pRayStart->z; - Vec3_float_::Cross(&ray_dir, &pRay2, pFaceBounding2->vWorldPosition.x - pFaceBounding1->vWorldPosition.x, - pFaceBounding2->vWorldPosition.y - pFaceBounding1->vWorldPosition.y, - pFaceBounding2->vWorldPosition.z - pFaceBounding1->vWorldPosition.z); - - float sqr_mag = pRay2.x * pRay2.x + pRay2.y * pRay2.y + pRay2.z * pRay2.z; - if (fabsf(sqr_mag) > 1e-6f) - { - float inv_mag = 1.0f / sqrtf(sqr_mag); - pRay2.x *= inv_mag; - pRay2.y *= inv_mag; - pRay2.z *= inv_mag; - pRay2.Normalize(); - - pPortalDataFrustum->x = pRay2.x; - pPortalDataFrustum->y = pRay2.y; - pPortalDataFrustum->z = pRay2.z; - pPortalDataFrustum->dot = pRayStart->z * pRay2.z + pRayStart->y * pRay2.y + pRayStart->x * pRay2.x; - return true; - } - return false; -} - -//----- (0049C8DC) -------------------------------------------------------- -bool stru10::FindFacePlane(RenderVertexSoft *arg0, Vec3_float_ *a2, float *a3) -{ - Vec3_float_ v1; // [sp+8h] [bp-3Ch]@1 - Vec3_float_ v2; // [sp+14h] [bp-30h]@1 - - v1.x = arg0[1].vWorldPosition.x - arg0[0].vWorldPosition.x; - v1.y = arg0[1].vWorldPosition.y - arg0[0].vWorldPosition.y; - v1.z = arg0[1].vWorldPosition.z - arg0[0].vWorldPosition.z; - - Vec3_float_::Cross(&v1, &v2, arg0[2].vWorldPosition.x - arg0[1].vWorldPosition.x, - arg0[2].vWorldPosition.y - arg0[1].vWorldPosition.y, - arg0[2].vWorldPosition.z - arg0[1].vWorldPosition.z); - - float sqr_mag = v2.x * v2.x + v2.y * v2.y + v2.z * v2.z; - if (fabsf(sqr_mag) > 1e-6f) - { - //v2.Normalize(); - float inv_mag = 1.0f / sqrtf(sqr_mag); - v2.x *= inv_mag; - v2.y *= inv_mag; - v2.z *= inv_mag; - - a2->x = v2.x; - a2->y = v2.y; - a2->z = v2.z; - *a3 = -(arg0[0].vWorldPosition.z * v2.z + arg0[0].vWorldPosition.y * v2.y + arg0[0].vWorldPosition.x * v2.x); - return true; - } - return false; -} diff -r 7b076fe64f23 -r 5abd8fc8f1c6 stru10.h --- a/stru10.h Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,23 +0,0 @@ -#pragma once - - -/* 127 */ -#pragma pack(push, 1) -struct stru10 -{ - stru10(); - virtual ~stru10(); - char _49C5DA(struct BLVFace *pFace, struct RenderVertexSoft *pVertices, unsigned int *pNumVertices, struct IndoorCameraD3D_Vec4 *a5, struct RenderVertexSoft *pOutBounding); - bool CalcPortalShape(struct BLVFace *pFace, struct IndoorCameraD3D_Vec4 *pPortalDataFrustum, struct RenderVertexSoft *pOutBounding); - char _49C720(struct RenderVertexSoft *pFaceBounding, struct IndoorCameraD3D_Vec4 *pPortalDataFrustum); - bool FindFaceNormal(struct RenderVertexSoft *pFaceBounding1, struct RenderVertexSoft *pFaceBounding2, struct Vec3_float_ *pRayStart, struct IndoorCameraD3D_Vec4 *pPortalDataFrustum); - bool FindFacePlane(struct RenderVertexSoft *face, struct Vec3_float_ *out_normal, float *out_distance); - bool CalcFaceBounding(struct BLVFace *pFace, struct RenderVertexSoft *pFaceLimits, unsigned int uNumVertices, struct RenderVertexSoft *pOutBounding); - void CalcPolygonLimits(struct BLVFace *pFace, struct RenderVertexSoft pOutVertices[4]); - void _49CE9E(struct BLVFace *pFace, struct RenderVertexSoft *pVertices, unsigned int uNumVertices, RenderVertexSoft *pOutLimits); - - - void ( ***vdestructor_ptr)(stru10 *, bool); - int bDoNotDrawPortalFrustum; -}; -#pragma pack(pop) diff -r 7b076fe64f23 -r 5abd8fc8f1c6 stru6.cpp --- a/stru6.cpp Wed Sep 17 17:35:13 2014 +0600 +++ b/stru6.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -5,26 +5,26 @@ #define _CRT_SECURE_NO_WARNINGS #include "stru6.h" -#include "LightmapBuilder.h" +#include "Engine/Graphics/LightmapBuilder.h" #include "SpriteObject.h" -#include "ParticleEngine.h" +#include "Engine/Graphics/ParticleEngine.h" #include "Game.h" #include "LOD.h" -#include "Sprites.h" +#include "Engine/Graphics/Sprites.h" #include "ObjectList.h" #include "Actor.h" #include "Random.h" #include "IconFrameTable.h" #include "Timer.h" -#include "Viewport.h" -#include "Overlays.h" +#include "Engine/Graphics/Viewport.h" +#include "Engine/Graphics/Overlays.h" #include "stru160.h" #include "OurMath.h" -#include "Lights.h" +#include "Engine/Graphics/Lights.h" #include "MM7.h" -#include "Indoor.h" +#include "Engine/Graphics/Indoor.h" diff -r 7b076fe64f23 -r 5abd8fc8f1c6 stru9.cpp --- a/stru9.cpp Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,457 +0,0 @@ -#define _CRTDBG_MAP_ALLOC -#include -#include - -#define _CRT_SECURE_NO_WARNINGS -#include "stru9.h" -#include "IndoorCameraD3D.h" - -#include "mm7_data.h" - - - -//----- (00498377) -------------------------------------------------------- -bool stru9::_498377(struct RenderVertexSoft *pPortalBounding, unsigned int uNumVertices, struct IndoorCameraD3D_Vec4 *pVertices, struct RenderVertexSoft *pVertices2, unsigned int *pOutNumVertices) -{ - int result; // eax@7 - //unsigned int *v7; // ebx@7 - //char *v8; // esi@8 - RenderVertexSoft *v9; // ecx@9 - //double v10; // st7@12 - //double v11; // st6@12 - //RenderVertexSoft *v12; // esi@13 - //int v13; // ecx@25 - //VertexBuffer *v14; // edx@26 - //char *v15; // eax@26 - //unsigned int i; // ecx@26 - //int v17; // [sp+0h] [bp-28h]@9 - //char *v18; // [sp+10h] [bp-18h]@8 - RenderVertexSoft *v19; // [sp+14h] [bp-14h]@0 - //RenderVertexSoft *v20; // [sp+18h] [bp-10h]@0 - signed int v21; // [sp+1Ch] [bp-Ch]@7 - //RenderVertexSoft *a2; // [sp+20h] [bp-8h]@8 - //stru9 *thisa; // [sp+24h] [bp-4h]@1 -// signed int a3a; // [sp+38h] [bp+10h]@12 - //int a3b; // [sp+38h] [bp+10h]@25 - - //__debugbreak(); - //thisa = this; - return true; - - static RenderVertexSoft static_AE3FB4; - /*static bool __init_flag1 = false; - if (!__init_flag1) - { - __init_flag1 = true; - - static_AE3FB4.flt_2C = 0.0; - }*/ - - static stru312 static_AE3FA4; // idb - /*static bool __init_flag2 = false; - if (!__init_flag2) - { - __init_flag2 = true; - - //stru312::stru312(&static_AE3FA4); - }*/ - - static VertexBuffer static_AE33A0; // idb - /*static bool __init_flag3 = false; - if (!__init_flag3) - { - __init_flag3 = true; - - //VertexBuffer::VertexBuffer(&static_AE33A0); - }*/ - - result = false; - //v7 = pOutNumVertices; - v21 = 0; - if ( (signed int)uNumVertices <= 0 ) - { - *pOutNumVertices = 0; - return true; - } - //a2 = a1; - //v8 = (char *)&a3->y; - //v18 = (char *)&a3->y; - //do - for (uint j = 0; j < uNumVertices; j++ ) - { - //v17 = result + 1; - result = j; - v9 = &pPortalBounding[(j + 1) % (signed int)uNumVertices]; - if ( pPortalBounding->vWorldPosition.x != v9->vWorldPosition.x - || pPortalBounding->vWorldPosition.y != v9->vWorldPosition.y - || pPortalBounding->vWorldPosition.z != v9->vWorldPosition.z ) - { - //v10 = a3->z; - //v11 = a3->y; - ++v21; - //result = 0; - static_AE33A0.uNumVertices = 0; - //a3a = 0; - static_AE3FA4.x = pVertices->x; - static_AE3FA4.y = pVertices->y; - static_AE3FA4.z = pVertices->z; - if ( (signed int)*pOutNumVertices <= 0 ) - { - *pOutNumVertices = 0; - return true; - } - //do - for ( int i = 0; i < (signed int)*pOutNumVertices; i++ ) - { - //v12 = &pVertices[result]; - if ( result ) - { - if ( _4989E1(&pVertices2[i], &pVertices2[i], pPortalBounding, &static_AE3FA4) - && _498774(&pVertices2[i], &pVertices2[i], pPortalBounding, &static_AE3FA4, &static_AE3FB4) ) - AddVertex(&static_AE33A0, &static_AE3FB4); - } - else - { - v19 = &pVertices2[i]; - } - //v20 = v12; - if ( AreVectorsCollinear(&pVertices2[i], pPortalBounding, &static_AE3FA4) ) - AddVertex(&static_AE33A0, &pVertices2[i]); - //pOutNumVertices = pOutNumVertices; - //a3a++; - } - //while ( a3a < (signed int)*pOutNumVertices ); - if ( !static_AE33A0.uNumVertices ) - { - *pOutNumVertices = 0; - return true; - } - if ( _4989E1(&pVertices2[result], v19, pPortalBounding, &static_AE3FA4) - && _498774(&pVertices2[result], v19, pPortalBounding, &static_AE3FA4, &static_AE3FB4) ) - AddVertex(&static_AE33A0, &static_AE3FB4); - - for (uint i = 0; i < static_AE33A0.uNumVertices; ++i) - { - pVertices2[i].vWorldPosition.x = static_AE33A0.pVertices[i].vWorldPosition.x; - pVertices2[i].vWorldPosition.y = static_AE33A0.pVertices[i].vWorldPosition.y; - pVertices2[i].vWorldPosition.z = static_AE33A0.pVertices[i].vWorldPosition.z; - pVertices2[i].u = static_AE33A0.pVertices[i].u; - pVertices2[i].v = static_AE33A0.pVertices[i].v; - } - - //v13 = static_AE33A0.uNumVertices; - /*a3b = 0; - if ( static_AE33A0.uNumVertices > 0 ) - { - v14 = &static_AE33A0; - v15 = (char *)&pVertices->vWorldPosition.y; - for ( i = (char *)&static_AE33A0.pVertices[0].vWorldPosition.y - (char *)pVertices; - ; - i = (char *)&static_AE33A0.pVertices[0].vWorldPosition.y - (char *)pVertices ) - { - ++a3b; - pVertices->vWorldPosition.x = v14->pVertices[0].vWorldPosition.x; - v14 = (VertexBuffer *)((char *)v14 + 48); - pVertices->vWorldPosition.y = *(float *)&v15[(char *)&static_AE33A0 - (char *)pVertices]; - pVertices->vWorldPosition.z = *(float *)&v15[i]; - pVertices->u = *(float *)&v15[(char *)&static_AE33A0.pVertices[0]._rhw - (char *)pVertices]; - pVertices->v = *(float *)&v15[(char *)&static_AE33A0.pVertices[0].u - (char *)pVertices]; - //static_AE33A0.uNumVertices = static_AE33A0.uNumVertices; - v15 += 48; - if ( a3b >= static_AE33A0.uNumVertices ) - break; - } - }*/ - - //v7 = pOutNumVertices; - //a3->y = a3->y; - *pOutNumVertices = static_AE33A0.uNumVertices; - } - //result = v17; - ++pPortalBounding; - pVertices++; - //v18 = (char *)&a3->y; - } - //while ( v17 < (signed int)uNumVertices ); - if ( v21 < 3 ) - *pOutNumVertices = 0; - return true; -} - - -//----- (004985FB) -------------------------------------------------------- -bool stru9::CalcPortalShape(struct RenderVertexSoft *a1, signed int a2, struct RenderVertexSoft *pVertices, unsigned int *pOutNumVertices, struct Vec3_float_ *a5, float a6, char *a7, int unused) -{ - //RenderVertexSoft *v9; // ecx@1 - //Vec3_float_ *v10; // esi@1 - //char *v11; // ebx@1 - //RenderVertexSoft *pVertices; // edi@1 - double pLinelength1; // st7@1 - //bool result; // eax@4 - signed int v15; // edx@9 - RenderVertexSoft *pLineEnd; // ecx@9 - double pLinelength2; // st7@9 - double t; // st6@12 - signed int v19; // [sp+Ch] [bp-Ch]@7 - //float v20; // [sp+10h] [bp-8h]@1 - bool v21; // [sp+14h] [bp-4h]@2 - - //v9 = a1; - //v10 = a5; - //v11 = (char *)&a1->vWorldPosition.z; - RenderVertexSoft* pLineStart = &a1[0]; - //pVertices = a3; - pLinelength1 = a5->x * a1[0].vWorldPosition.x + a1[0].vWorldPosition.y * a5->y + a1[0].vWorldPosition.z * a5->z; - //v20 = v13; - v21 = pLinelength1 >= a6; - - *pOutNumVertices = 0; - if ( a2 <= 0 ) - return false; - v19 = 1; - - while ( 1 ) - { - if ( v21 ) - { - //++pVertices; - memcpy(pVertices, pLineStart, sizeof(RenderVertexSoft)); - ++*pOutNumVertices; - //v10 = a5; - pVertices++; - //v9 = a1; - } - v15 = 0; - pLineEnd = &a1[v19 % a2]; - pLinelength2 = a5->x * pLineEnd->vWorldPosition.x + pLineEnd->vWorldPosition.y * a5->y + pLineEnd->vWorldPosition.z * a5->z; - if ( pLinelength2 >= a6 ) - v15 = 1; - - if ( v21 != v15 ) - { - t = (a6 - pLinelength1) / (pLinelength2 - pLinelength1); - pVertices->vWorldPosition.x = pLineStart->vWorldPosition.x + (pLineEnd->vWorldPosition.x - pLineStart->vWorldPosition.x) * t; - pVertices->vWorldPosition.y = pLineStart->vWorldPosition.y + (pLineEnd->vWorldPosition.y - pLineStart->vWorldPosition.y) * t; - pVertices->vWorldPosition.z = pLineStart->vWorldPosition.z + (pLineEnd->vWorldPosition.z - pLineStart->vWorldPosition.z) * t; - pVertices->u = pLineStart->u + (pLineEnd->u - pLineStart->u) * t; - pVertices->v = pLineStart->v + (pLineEnd->v - pLineStart->v) * t; - ++pVertices; - //a3 = pVertices; - ++*pOutNumVertices; - *a7 = 1; - } - - pLineStart++; - v21 = v15; - pLinelength1 = pLinelength2; - if ( v19 >= a2 ) - break; - //v9 = a1; - v19++; - } - - return *pOutNumVertices >= 3; -} - -//----- (00498737) -------------------------------------------------------- -void stru9::AddVertex(struct VertexBuffer *pVertexBuffer, struct RenderVertexSoft *pVertex) -{ -// __debugbreak(); - RenderVertexSoft *v3; // eax@1 - - v3 = &pVertexBuffer->pVertices[pVertexBuffer->uNumVertices]; - v3->vWorldPosition.x = pVertex->vWorldPosition.x; - v3->vWorldPosition.y = pVertex->vWorldPosition.y; - v3->vWorldPosition.z = pVertex->vWorldPosition.z; - v3->u = pVertex->u; - v3->v = pVertex->v; - ++pVertexBuffer->uNumVertices; -} - -//----- (00498774) -------------------------------------------------------- -bool stru9::_498774(struct RenderVertexSoft *a1, struct RenderVertexSoft *a2, struct RenderVertexSoft *a3, struct stru312 *a4, struct RenderVertexSoft *a5) -{ - RenderVertexSoft *v6; // ecx@5 - int result; // eax@5 - double v8; // st7@5 - __int16 v9; // fps@5 - double v10; // st7@6 - double v11; // st6@8 - double v12; // st6@18 - char v13; // c0@24 - char v14; // c2@24 - char v15; // c3@24 - float a1a; // [sp+10h] [bp+8h]@5 - - __debugbreak(); - - static stru312 static_AE3388; - static stru312 static_AE3378; - - v6 = a1; - static_AE3378.x = a1->vWorldPosition.x - a3->vWorldPosition.x; - static_AE3378.y = a1->vWorldPosition.y - a3->vWorldPosition.y; - HIWORD(result) = HIWORD(a4); - static_AE3378.z = a1->vWorldPosition.z - a3->vWorldPosition.z; - static_AE3388.x = a2->vWorldPosition.x - a1->vWorldPosition.x; - static_AE3388.y = a2->vWorldPosition.y - a1->vWorldPosition.y; - static_AE3388.z = a2->vWorldPosition.z - a1->vWorldPosition.z; - a1a = static_AE3388.x * a4->x + static_AE3388.z * a4->z + static_AE3388.y * a4->y; - v8 = static_AE3378.x * a4->x + static_AE3378.z * a4->z + static_AE3378.y * a4->y; - //UNDEF(v9); - if ( a1a != 0.0 ) - { - v10 = -(v8 / a1a); - if ( a1a <= 0.0 ) - { - if ( v10 <= 0.0 ) - v12 = 0.0; - else - v12 = v10; - if ( v12 <= 1.0 ) - { - if ( v10 <= 0.0 ) - v10 = (float)0.0; - } - else - v10 = 1.0; - } - else - { - if ( v10 >= 1.0 ) - v11 = 1.0; - else - v11 = v10; - if ( v11 >= 0.0 ) - { - if ( v10 >= 1.0 ) - v10 = (float)1.0; - } - else - v10 = 0.0; - } - result = (bool)a5; - a5->vWorldPosition.x = (a2->vWorldPosition.x - v6->vWorldPosition.x) * v10 + v6->vWorldPosition.x; - a5->vWorldPosition.y = (a2->vWorldPosition.y - v6->vWorldPosition.y) * v10 + v6->vWorldPosition.y; - a5->vWorldPosition.z = (a2->vWorldPosition.z - v6->vWorldPosition.z) * v10 + v6->vWorldPosition.z; - a5->u = (a2->u - v6->u) * v10 + v6->u; - a5->v = (a2->v - v6->v) * v10 + v6->v; - return 1; - } - v13 = v8 < 0.0; - v14 = 0; - v15 = v8 == 0.0; - // BYTE1(result) = HIBYTE(v9); - if ( v8 < 0.0 ) - return 1; - return 0; -} -// AE3398: using guessed type char static_init_flag__AE3388_bit1__AE3378_bit2; - -//----- (0049895A) -------------------------------------------------------- -bool stru9::AreVectorsCollinear(struct RenderVertexSoft *a1, struct RenderVertexSoft *a2, struct stru312 *a3) -{ - static stru312 static_F942A0; - - static_F942A0.x = a1->vWorldPosition.x - a2->vWorldPosition.x; - static_F942A0.y = a1->vWorldPosition.y - a2->vWorldPosition.y; - static_F942A0.z = a1->vWorldPosition.z - a2->vWorldPosition.z; - - static float flt_F942B4 = static_F942A0.z * a3->z + static_F942A0.y * a3->y + static_F942A0.x * a3->x; - if (flt_F942B4 >= 0) - return true; - return false; -} - - -//----- (004989E1) -------------------------------------------------------- -bool stru9::_4989E1(struct RenderVertexSoft *a1, struct RenderVertexSoft *a2, struct RenderVertexSoft *a3, struct stru312 *a4) -{ - bool r1; - bool r2; - - r1 = AreVectorsCollinear(a1, a3, a4); - r2 = AreVectorsCollinear(a2, a3, a4); - return !r1 && r2 == 1 || - r1 == 1 && !r2; -} - -//----- (004980B9) -------------------------------------------------------- -bool stru9::_4980B9(RenderVertexSoft *a1, unsigned int uNumVertices, float a3, float a4, float a5, RenderVertexSoft *pOutVertices, unsigned int *pOutNumVertices) -{ - RenderVertexSoft *v12; // ecx@9 - double v13; // st7@12 - double v14; // st6@12 - double v15; // st5@12 - signed int v25; // [sp+18h] [bp-Ch]@7 - - static RenderVertexSoft stru_AE4BFC; - static stru312 static_sub_4980B9_stru_AE4BEC; // idb - static VertexBuffer static_sub_4980B9_stru_AE3FE8; // idb - - v25 = 0; - if (uNumVertices <= 0) - { - *pOutNumVertices = 0; - return true; - } - - for (uint i = 0; i < uNumVertices; ++i) - { - v12 = &a1[(i + 1) % uNumVertices]; - if (a1[i].vWorldPosition.x != v12->vWorldPosition.x || - a1[i].vWorldPosition.y != v12->vWorldPosition.y || - a1[i].vWorldPosition.z!= v12->vWorldPosition.z) - { - v13 = v12->vWorldPosition.x - a1[i].vWorldPosition.x; - v14 = v12->vWorldPosition.y - a1[i].vWorldPosition.y; - v15 = v12->vWorldPosition.z - a1[i].vWorldPosition.z; - ++v25; - - static_sub_4980B9_stru_AE3FE8.uNumVertices = 0; - static_sub_4980B9_stru_AE4BEC.x = a4 * v15 - v14 * a5; - static_sub_4980B9_stru_AE4BEC.y = v13 * a5 - v15 * a3; - static_sub_4980B9_stru_AE4BEC.z = v14 * a3 - v13 * a4; - if (*pOutNumVertices == 0) - return true; - - for (uint j = 0; j < *pOutNumVertices; ++j) - { - if (j) - { - if (_4989E1(&pOutVertices[j - 1], &pOutVertices[j], &a1[i], &static_sub_4980B9_stru_AE4BEC) && - _498774(&pOutVertices[j - 1], &pOutVertices[j], &a1[i], &static_sub_4980B9_stru_AE4BEC, &stru_AE4BFC)) - AddVertex(&static_sub_4980B9_stru_AE3FE8, &stru_AE4BFC); - } - - if (AreVectorsCollinear(&pOutVertices[j], &a1[i], &static_sub_4980B9_stru_AE4BEC)) - AddVertex(&static_sub_4980B9_stru_AE3FE8, &pOutVertices[j]); - } - - if (!static_sub_4980B9_stru_AE3FE8.uNumVertices) - { - *pOutNumVertices = 0; - return true; - } - if (_4989E1(&pOutVertices[*pOutNumVertices - 1], &pOutVertices[0], &a1[i], &static_sub_4980B9_stru_AE4BEC) && - _498774(&pOutVertices[*pOutNumVertices - 1], &pOutVertices[0], &a1[i], &static_sub_4980B9_stru_AE4BEC, &stru_AE4BFC) ) - AddVertex(&static_sub_4980B9_stru_AE3FE8, &stru_AE4BFC); - - for (uint j = 0; j < static_sub_4980B9_stru_AE3FE8.uNumVertices; ++j) - { - pOutVertices[j].vWorldPosition.y = static_sub_4980B9_stru_AE3FE8.pVertices[j].vWorldPosition.x; - pOutVertices[j].vWorldPosition.y = static_sub_4980B9_stru_AE3FE8.pVertices[j].vWorldPosition.y; - pOutVertices[j].vWorldPosition.z = static_sub_4980B9_stru_AE3FE8.pVertices[j].vWorldPosition.z; - pOutVertices[j].u = static_sub_4980B9_stru_AE3FE8.pVertices[j].u; - pOutVertices[j].v = static_sub_4980B9_stru_AE3FE8.pVertices[j].v; - } - *pOutNumVertices = static_sub_4980B9_stru_AE3FE8.uNumVertices; - } - } - - if (v25 < 3) - *pOutNumVertices = 0; - - return true; -} -// AE4C2C: using guessed type char static_sub_4980B9_byte_AE4C2C_init_flag; \ No newline at end of file diff -r 7b076fe64f23 -r 5abd8fc8f1c6 stru9.h --- a/stru9.h Wed Sep 17 17:35:13 2014 +0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ -#pragma once -#include "Render.h" - -/* 341 */ -#pragma pack(push, 1) -struct VertexBuffer -{ - //----- (0049835A) -------------------------------------------------------- - inline VertexBuffer() - { - for (unsigned int i = 0; i < 64; ++i) - pVertices[i].flt_2C = 0.0f; - - uNumVertices = 0; - } - - - RenderVertexSoft pVertices[64]; - int uNumVertices; -}; -#pragma pack(pop) - - - - -/* 342 */ -#pragma pack(push, 1) -struct stru312 -{ - //----- (004BE6D1) -------------------------------------------------------- - inline stru312() - { - } - - float x; - float y; - float z; - char field_C; - char pad[3]; -}; -#pragma pack(pop) - - - -/* 126 */ -#pragma pack(push, 1) -struct stru9 -{ - //----- (00498093) -------------------------------------------------------- - inline stru9() - {} - - bool _4980B9(struct RenderVertexSoft *a1, unsigned int uNumVertices, float a3, float a4, float a5, struct RenderVertexSoft *pOutVertices, unsigned int *pOutNumVertices); - bool _498377(struct RenderVertexSoft *pPortalBounding, unsigned int uNumVertices, struct IndoorCameraD3D_Vec4 *pVertices, struct RenderVertexSoft *pVertices2, unsigned int *pOutNumVertices); - bool CalcPortalShape(struct RenderVertexSoft *a1, signed int a2, struct RenderVertexSoft *pVertices, unsigned int *pOutNumVertices, struct Vec3_float_ *a5, float a6, char *a7, int unused); - void AddVertex(struct VertexBuffer *pVertexBuffer, struct RenderVertexSoft *pVertex); - bool _498774(struct RenderVertexSoft *a1, struct RenderVertexSoft *a2, struct RenderVertexSoft *a3, struct stru312 *a4, struct RenderVertexSoft *a5); - bool AreVectorsCollinear(struct RenderVertexSoft *a1, struct RenderVertexSoft *a2, struct stru312 *a3); - bool _4989E1(struct RenderVertexSoft *a1, struct RenderVertexSoft *a2, struct RenderVertexSoft *a3, struct stru312 *a4); - - void ( ***vdestructor_ptr)(stru9 *, bool); -}; -#pragma pack(pop) \ No newline at end of file