Mercurial > mm7
diff Render.cpp @ 0:9c0607679772
init
author | Ritor1 |
---|---|
date | Sat, 12 Jan 2013 09:45:18 +0600 |
parents | |
children | 8e33efd39355 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Render.cpp Sat Jan 12 09:45:18 2013 +0600 @@ -0,0 +1,11160 @@ +#include "Render.h" +#include "OutdoorCamera.h" +#include "IndoorCamera.h" +#include "Outdoor.h" +#include "Party.h" +#include "LOD.h" +#include "Viewport.h" +#include "Math.h" +#include "PaletteManager.h" +#include "Time.h" +#include "Game.h" +#include "LightmapBuilder.h" +#include "stru220.h" +#include "ObjectList.h" +#include "LayingItem.h" +#include "DecorationList.h" +#include "Allocator.h" +#include "OSInfo.h" +#include "Log.h" + +#include "mm7_data.h" + + +#pragma comment(lib, "lib\\legacy_dx\\lib\\ddraw.lib") +#pragma comment(lib, "lib\\legacy_dx\\lib\\dxguid.lib") + + + + + + + +struct IDirectDrawClipper *pDDrawClipper; +struct Render *pRenderer; // idb + + +int uNumDecorationsDrawnThisFrame; // weak +RenderBillboard pBillboardRenderList[500]; +unsigned int uNumBillboardsToDraw; +int uNumSpritesDrawnThisFrame; // weak + + +RenderVertexSoft array_507D30[50]; +RenderVertexSoft array_508690[50]; +RenderVertexSoft array_508FF0[50]; +RenderVertexSoft array_509950[50]; +RenderVertexSoft array_50A2B0[50]; +RenderVertexSoft array_50AC10[50]; + +RenderVertexSoft array_73D150[20]; + +RenderVertexD3D3 arary_77E5C8[50]; + +RenderVertexSoft *ptr_801A04; +RenderVertexSoft *ptr_801A08; + +RenderVertexSoft pVerticesSR_801A10[384]; +RenderVertexSoft pVerticesSR_806210[384]; + + + + + + + +void SetBillboardBlendOptions(RenderBillboardD3D::OpacityType a1); + + +/* 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 __cdecl 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; + pRenderer->pRenderD3D->CreateTexture(64u, 64u, &pSurface1, &pTexture1, true, false, 32u); + pRenderer->pRenderD3D->CreateTexture(64u, 64u, &pSurface2, &pTexture2, true, false, 32u); + + ErrD3D(pRenderer->pRenderD3D->pDevice->SetTexture(0, pTexture1)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, 1u)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLOROP, 2u)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, 2u)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, 2u)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MINFILTER, 2u)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, 1u)); + + ErrD3D(pRenderer->pRenderD3D->pDevice->SetTexture(0, pTexture2)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_ADDRESS, 3u)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1u)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_COLOROP, 7u)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_COLORARG1, 2u)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_COLORARG2, 1u)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_MAGFILTER, 2u)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_MINFILTER, 2u)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_MIPFILTER, 1u)); + + if ( !pRenderer->pRenderD3D->pDevice->ValidateDevice(&v4) && v4 == 1 ) + v0 = true; + ErrD3D(pRenderer->pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_COLOROP, 1u)); + pTexture1->Release(); + pTexture2->Release(); + pSurface1->Release(); + pSurface2->Release(); + return v0; +} + + + + + + + + + + + + + +//----- (00440CB8) -------------------------------------------------------- +void Render::DrawBillboardList_BLV() +{ + __int16 v2; // ax@3 + int v5; // eax@11 + RenderBillboardTransform_local0 soft_billboard; // [sp+4h] [bp-50h]@1 + + soft_billboard.uParentBillboardID = -1; + soft_billboard.pTarget = pBLVRenderParams->pRenderTarget; + soft_billboard.pTargetZ = pBLVRenderParams->pTargetZBuffer; + soft_billboard.uTargetPitch = pRenderer->uTargetSurfacePitch; + soft_billboard.uViewportX = pBLVRenderParams->uViewportX; + soft_billboard.uViewportY = pBLVRenderParams->uViewportY; + soft_billboard.uViewportZ = pBLVRenderParams->uViewportZ - 1; + soft_billboard.uViewportW = pBLVRenderParams->uViewportW; + + pOutdoorCamera->uNumBillboards = uNumBillboardsToDraw; + + for (uint i = 0; i < uNumBillboardsToDraw; ++i) + { + auto p = pBillboardRenderList + i; + + soft_billboard.uScreenSpaceX = p->uScreenSpaceX; + soft_billboard.uParentBillboardID = i; + soft_billboard.uScreenSpaceY = p->uScreenSpaceY; + soft_billboard.field_10 = p->field_0; + soft_billboard.field_14 = p->field_4; + soft_billboard.sZValue = p->sZValue; + soft_billboard.uFlags = p->field_1E; + soft_billboard.uTintColor = p->uTintColor; + v2 = p->uHwSpriteID; + if ( v2 != -1 ) + { + if ( pRenderer->pRenderD3D ) + pRenderer->DrawBillboard_Indoor(&soft_billboard, &pSprites_LOD->pHardwareSprites[v2], p->uPaletteSubindex); + else + { + soft_billboard.pPalette = PaletteManager::Get_Dark_or_Red_LUT(p->uPalette, p->uPaletteSubindex, 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); + v5 = p->uHwSpriteID; + if ( v5 >= 0 ) + pSprites_LOD->pSpriteHeaders[v5]._4ACC38(&soft_billboard, 1); + } + } + } +} + + + + + +//----- (004A16A5) -------------------------------------------------------- +bool __cdecl AreRenderSurfacesOk() +{ + char v0; // zf@4 + bool result; // eax@8 + + if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 ) + { + if ( !pRenderer->pBackBuffer4 ) + goto LABEL_9; + v0 = pRenderer->pFrontBuffer4 == 0; + } + else + { + if ( !pRenderer->pBackBuffer2 ) + goto LABEL_9; + v0 = pRenderer->pFrontBuffer2 == 0; + } + if ( !v0 ) + { + LOBYTE(result) = 1; + return result; + } +LABEL_9: + LOBYTE(result) = 0; + return result; +} + + + +//----- (00487389) -------------------------------------------------------- +__int16 Render::ExecOutdoorDrawSW() +{ + unsigned __int16 *v0; // ebx@1 + unsigned int v1; // esi@1 + stru148 *v2; // eax@1 + Span *v3; // edi@6 + stru148 *v4; // esi@9 + Texture *v5; // ebp@10 + int v6; // esi@16 + unsigned int v7; // edx@16 + char *v8; // ecx@17 + unsigned int v9; // edi@22 + int v10; // eax@26 + int v11; // eax@27 + unsigned int v12; // ebp@32 + Span *v13; // esi@33 + int v14; // ecx@37 + int v15; // eax@40 + Texture *v16; // ebp@51 + unsigned int v17; // eax@51 + int v18; // eax@54 + char v19; // al@56 + unsigned int v20; // eax@57 + int v21; // ecx@57 + unsigned int v22; // eax@57 + stru149 *v23; // eax@65 + int v24; // eax@67 + ODMFace *v25; // eax@78 + signed int v26; // edx@79 + signed int v27; // ecx@79 + unsigned int v28; // eax@106 + unsigned int v29; // ebp@117 + Span *v30; // esi@118 + unsigned int v31; // ST04_4@124 + int v33; // [sp+18h] [bp-44h]@80 + signed int v34; // [sp+1Ch] [bp-40h]@3 + signed int v35; // [sp+20h] [bp-3Ch]@79 + Span **v36; // [sp+24h] [bp-38h]@4 + unsigned int v37; // [sp+28h] [bp-34h]@1 + unsigned __int16 *a1; // [sp+2Ch] [bp-30h]@1 + int a1a; // [sp+2Ch] [bp-30h]@26 + unsigned int a1b; // [sp+2Ch] [bp-30h]@116 + char v41; // [sp+30h] [bp-2Ch]@57 + + v0 = pRenderer->pTargetSurface; + v1 = pOutdoorCamera->numStru148s; + a1 = pRenderer->pTargetSurface; + v2 = array_77EC08; + v37 = pOutdoorCamera->numStru148s; + if ( !(pParty->uFlags & 2) ) + { + v1 = uNumElementsIn80AA28; + v2 = ptr_80AA28[0]; + v37 = uNumElementsIn80AA28; + } + v34 = 0; + if ( (signed int)v1 > 0 ) + { + v36 = &v2->prolly_head; + do + { + if ( pParty->uFlags & 2 ) + v3 = *v36; + else + v3 = ptr_80AA28[v34]->prolly_head; + if ( v3 ) + { + v4 = v3->pParent; + if ( v4 ) + { + v5 = v4->pTexture; + if ( v5 ) + { + if ( v3->field_8 >= (signed int)pViewport->uViewportX || v3->field_C != pViewport->uViewportX ) + { + LOBYTE(v4->field_32) |= 2u; + v14 = *(int *)&v4->flags; + if ( v14 & 0x10 && v4->field_59 != 5 ) + { + dword_80AA20 = (v4->field_5C - 64) << 25; + dword_80AA1C = dword_80AA20 + 0x1FF0000; + dword_80AA14 = (v4->field_5D << 25) + 0x7FFF0000; + dword_80AA18 = dword_80AA14 - 0x1FF0000; + byte_80AA10 = ((unsigned int)pOutdoor->ActuallyGetSomeOtherTileInfo( + v4->field_5C, + v4->field_5D - 1) >> 9) & 1; + if ( *(int *)&v4->flags & 2 || (v15 = *(int *)&v4->flags, BYTE1(v15) & 1) ) + { + if ( *(int *)&v4->flags & 2 ) + { + while ( 1 ) + { + if ( pOutdoorCamera->outdoor_no_wavy_water ) + sr_sub_48408A_prolly_odm_water_no_waves(v3); + else + sr_sub_485407_prolly_odm_water_wavy(v3); + v3->field_E = LOWORD(unnamed_6BE060[1]); + if ( v4->prolly_tail == v3 ) + break; + v3 = v3->pNext; + } + } + else + { + while ( 1 ) + { + v16 = v4->pTexture; + v17 = pBitmaps_LOD->LoadTexture("wtrtyl"); + v4->pTexture = (Texture *)(v17 != -1 ? (int)&pBitmaps_LOD->pTextures[v17] : 0); + if ( pOutdoorCamera->outdoor_no_wavy_water ) + sr_sub_48408A_prolly_odm_water_no_waves(v3); + else + sr_sub_485407_prolly_odm_water_wavy(v3); + v18 = v4->field_5C - 64; + v4->pTexture = v16; + dword_80AA20 = v18 << 25; + dword_80AA1C = (v18 << 25) + 0x1FF0000; + dword_80AA14 = (v4->field_5D << 25) + 0x7FFF0000; + dword_80AA18 = dword_80AA14 - 0x1FF0000; + byte_80AA10 = ((unsigned int)pOutdoor->ActuallyGetSomeOtherTileInfo( + v4->field_5C, + v4->field_5D - 1) >> 9) & 1; + sr_sub_484442(v3); + v3->field_E = LOWORD(unnamed_6BE060[1]); + if ( v4->prolly_tail == v3 ) + break; + v3 = v3->pNext; + } + } + } + else + { + while ( sr_sub_48408A_prolly_odm_water_no_waves(v3) ) + { + v3->field_E = LOWORD(unnamed_6BE060[1]); + if ( v4->prolly_tail == v3 ) + break; + v3 = v3->pNext; + } + } + } + else + { + v19 = v4->field_59; + if ( v19 != 5 ) + { + if ( v14 & 2 ) + { + while ( 1 ) + { + v28 = pBitmaps_LOD->LoadTexture("wtrtyla"); + v4->pTexture = (Texture *)(v28 != -1 ? &pBitmaps_LOD->pTextures[v28] : 0); + if ( !sr_sub_4847EB(v3) ) + break; + v4->pTexture = v5; + if ( !sr_sub_484442(v3) ) + break; + v3->field_E = LOWORD(unnamed_6BE060[1]); + if ( v4->prolly_tail == v3 ) + break; + v3 = v3->pNext; + v5 = v4->pTexture; + } + } + else + { + if ( v19 == 1 ) + { + dword_80AA20 = (v4->field_5C - 64) << 25; + dword_80AA1C = dword_80AA20 + 33488896; + dword_80AA14 = (v4->field_5D << 25) + 0x7FFF0000; + dword_80AA18 = dword_80AA14 - 33488896; + byte_80AA10 = ((unsigned int)pOutdoor->ActuallyGetSomeOtherTileInfo( + v4->field_5C, + v4->field_5D - 1) >> 9) & 1; + while ( 1 ) + { + if ( !sr_sub_4847EB(v3) ) + sr_sub_48585C_mb_DrawSpan(v3, &pRenderer->pTargetSurface[v3->field_8 + 640 * v3->field_A], 0); + v3->field_E = LOWORD(unnamed_6BE060[1]); + if ( v4->prolly_tail == v3 ) + break; + v3 = v3->pNext; + } + } + } + goto LABEL_14; + } + v4->ptr_38 = (stru149 *)&v41; + v4->_479295(); + v20 = GetTickCount(); + v21 = *(int *)&v4->flags; + v22 = v20 >> 3; + if ( BYTE1(v21) & 4 ) + { + v4->sTextureDeltaV -= v22 & v4->pTexture->uHeightMinus1; + } + else + { + if ( BYTE1(v21) & 8 ) + v4->sTextureDeltaV += v22 & v4->pTexture->uHeightMinus1; + } + if ( BYTE1(v21) & 0x10 ) + { + v4->sTextureDeltaU -= v22 & v4->pTexture->uWidthMinus1; + } + else + { + if ( BYTE1(v21) & 0x20 ) + v4->sTextureDeltaU += v22 & v4->pTexture->uWidthMinus1; + } + v23 = v4->ptr_38; + v4->field_52 = 32; + v4->field_5A = 5; + if ( (double)abs(v23->field_C) > 52428.8 ) + { + v4->field_52 = 8; + v4->field_5A = 3; + } + v24 = *(int *)&v4->flags; + if ( !(v24 & 0x10000) ) + { + if ( !(v24 & 2) ) + { + v25 = v4->pODMFace; + if ( v25->uPolygonType == 1 ) + { + v26 = v25->pTextureUIDs[0]; + dword_80AA1C = v26; + dword_80AA20 = v26; + v27 = v25->pTextureVIDs[0]; + dword_80AA14 = v27; + dword_80AA18 = v27; + v35 = 1; + if ( v25->uNumVertices > 1u ) + { + v33 = (int)&v25->pTextureVIDs[1]; + do + { + if ( dword_80AA20 > *(short *)(v33 - 40) ) + dword_80AA20 = *(short *)(v33 - 40); + if ( v26 < *(short *)(v33 - 40) ) + { + v26 = *(short *)(v33 - 40); + dword_80AA1C = *(short *)(v33 - 40); + } + if ( dword_80AA18 > *(short *)v33 ) + dword_80AA18 = *(short *)v33; + if ( v27 < *(short *)v33 ) + { + v27 = *(short *)v33; + dword_80AA14 = *(short *)v33; + } + ++v35; + v33 += 2; + } + while ( v35 < v25->uNumVertices ); + v0 = a1; + } + dword_80AA20 = (dword_80AA20 + v4->sTextureDeltaU) << 16; + dword_80AA1C = ((v26 + v4->sTextureDeltaU) << 16) - 65536; + dword_80AA18 = (dword_80AA18 + v4->sTextureDeltaV) << 16; + dword_80AA14 = ((v27 + v4->sTextureDeltaV) << 16) - 65536; + } + while ( 1 ) + { + if ( !sr_sub_482E07(v3, v0) ) + sr_sub_48585C_mb_DrawSpan(v3, &v0[v3->field_8 + 640 * v3->field_A], 0); + v3->field_E = LOWORD(unnamed_6BE060[1]); + if ( v4->prolly_tail == v3 ) + break; + v3 = v3->pNext; + } + goto LABEL_14; + } + while ( 1 ) + { +LABEL_74: + if ( !sr_sub_4839BD(v3, v0) ) + sr_sub_48585C_mb_DrawSpan(v3, &v0[v3->field_8 + 640 * v3->field_A], 0); + v3->field_E = LOWORD(unnamed_6BE060[1]); + if ( v4->prolly_tail == v3 ) + break; + v3 = v3->pNext; + } + goto LABEL_14; + } + if ( v24 & 2 ) + goto LABEL_74; + while ( 1 ) + { + if ( !sr_sub_482A94(v3) ) + sr_sub_48585C_mb_DrawSpan(v3, &v0[v3->field_8 + 640 * v3->field_A], 0); + v3->field_E = LOWORD(unnamed_6BE060[1]); + if ( v4->prolly_tail == v3 ) + break; + v3 = v3->pNext; + } + } + } + else + { + v3->field_E = LOWORD(unnamed_6BE060[1]); + } + } + } + } +LABEL_14: + ++v34; + LOWORD(v2) = v34; + v36 += 67; + } + while ( v34 < (signed int)v37 ); + } + if ( pParty->uFlags & 2 ) + { + v6 = pOutdoorCamera->numStru148s; + v7 = 0; + uNumElementsIn80AA28 = 0; + if ( pOutdoorCamera->numStru148s > 0 ) + { + v8 = (char *)&array_77EC08[0].flags; + do + { + v2 = *(stru148 **)v8; + if ( (unsigned int)v2 & 0x20000 ) + { + ++v7; + *(int *)v8 = (unsigned int)v2 & 0xFFFDFFFF; + LOWORD(v2) = (short)v8 - 48; + *(&uNumElementsIn80AA28 + v7) = (unsigned int)(v8 - 48); + } + v8 += 268; + --v6; + } + while ( v6 ); + uNumElementsIn80AA28 = v7; + } + } + v9 = pOutdoorCamera->uNumSpans; + unnamed_6BE060[0] = pOutdoorCamera->uNumSpans; + if ( pOutdoorCamera->numStru148s >= 1999 + || (array_77EC08[1999]._48607B(&stru_8019C8), + array_77EC08[1999].ptr_38->_48694B(), + v2 = (stru148 *)&pBitmaps_LOD->pTextures[pOutdoor->uMainTile_BitmapID], + (array_77EC08[1999].pTexture = (Texture *)(pOutdoor->uMainTile_BitmapID != -1 ? (int)v2 : 0)) == 0) ) + return (signed __int16)v2; + array_77EC08[1999].field_58 = 23 - (-20 * pOutdoor->vSunlight.z >> 16); + if ( array_77EC08[1999].field_58 > 20 ) + array_77EC08[1999].field_58 = 20; + v10 = stru_5C6E00->SinCos(pIndoorCamera->sRotationX - stru_5C6E00->uIntegerHalfPi); + array_77EC08[1999].v_18.y = 0; + array_77EC08[1999].v_18.x = v10; + array_77EC08[1999].v_18.z = stru_5C6E00->SinCos(pIndoorCamera->sRotationX); + array_77EC08[1999].field_24 = 2048 - (pIndoorCamera->pos.z << 16); + a1a = (signed __int64)((double)(pIndoorCamera->pos.z * pOutdoorCamera->int_fov_rad) + / ((double)pOutdoorCamera->int_fov_rad + 8192.0) + + (double)pViewport->uScreenCenterY); + cos((double)pIndoorCamera->sRotationX * 0.0030664064); + sin((double)pIndoorCamera->sRotationX * 0.0030664064); + array_77EC08[1999]._48607B(&stru_8019C8); + array_77EC08[1999].ptr_38->_48694B(); + v2 = (stru148 *)&pBitmaps_LOD->pTextures[pOutdoor->uSky_TextureID]; + array_77EC08[1999].pTexture = (Texture *)(pOutdoor->uSky_TextureID != -1 ? (int)v2 : 0); + if ( !(pOutdoor->uSky_TextureID != -1 ? (int)v2 : 0) ) + return (signed __int16)v2; + array_77EC08[1999].field_58 = 0; + v11 = stru_5C6E00->SinCos(pIndoorCamera->sRotationX + 16 - stru_5C6E00->uIntegerHalfPi); + array_77EC08[1999].v_18.y = 0; + array_77EC08[1999].v_18.x = -v11; + array_77EC08[1999].v_18.z = -stru_5C6E00->SinCos(pIndoorCamera->sRotationX + 16); + LOWORD(v2) = 224 * LOWORD(pMiscTimer->uTotalGameTimeElapsed); + array_77EC08[1999].field_24 = 0x2000000u; + array_77EC08[1999].sTextureDeltaU = 224 * pMiscTimer->uTotalGameTimeElapsed; + array_77EC08[1999].sTextureDeltaV = 224 * pMiscTimer->uTotalGameTimeElapsed; + if ( day_attrib & 1 + && (LOWORD(v2) = LOWORD(pParty->uCurrentHour), pParty->uCurrentHour >= 5) + && pParty->uCurrentHour < 0x15 + || bUnderwater ) + { + v2 = (stru148 *)*(short *)PaletteManager::Get_Mist_or_Red_LUT(array_77EC08[1999].pTexture->palette_id2, 31, 1); + a1b = (unsigned int)v2; + if ( (signed int)v9 <= 0 ) + return (signed __int16)v2; + v29 = v9; + while ( 1 ) + { + v30 = &pSpans[v29 - 1]; + v2 = (stru148 *)v30->field_E; + if ( v2 != (stru148 *)unnamed_6BE060[1] ) + { + LOWORD(v2) = LOWORD(pViewport->uViewportX); + if ( v30->field_8 >= (signed int)pViewport->uViewportX ) + goto LABEL_124; + if ( v30->field_C == pViewport->uViewportX ) + { + v30->field_E = LOWORD(unnamed_6BE060[1]); + } + else + { + v30->field_8 = LOWORD(pViewport->uViewportX); + v30->field_C -= LOWORD(pViewport->uViewportX); + if ( v30->field_C >= 0 ) + { +LABEL_124: + v31 = v30->field_C; + v30->pParent = &array_77EC08[1999]; + fill_pixels_fast( + a1b, + &pRenderer->pTargetSurface[v30->field_8 + pRenderer->uTargetSurfacePitch * v30->field_A], + v31); + j_memset32(-65536, &pRenderer->pActiveZBuffer[v30->field_8 + 640 * v30->field_A], v30->field_C); + goto LABEL_125; + } + LOWORD(v2) = LOWORD(unnamed_6BE060[1]); + v30->field_E = LOWORD(unnamed_6BE060[1]); + } + } +LABEL_125: + --v29; + --v9; + if ( !v9 ) + return (signed __int16)v2; + } + } + if ( (signed int)v9 > 0 ) + { + v12 = v9; + do + { + v13 = &pSpans[v12 - 1]; + v2 = (stru148 *)v13->field_E; + if ( v2 != (stru148 *)unnamed_6BE060[1] ) + { + LOWORD(v2) = LOWORD(pViewport->uViewportX); + if ( v13->field_8 >= (signed int)pViewport->uViewportX ) + goto LABEL_109; + if ( v13->field_C != pViewport->uViewportX ) + { + v13->field_8 = LOWORD(pViewport->uViewportX); + v13->field_C -= LOWORD(pViewport->uViewportX); + if ( v13->field_C >= 0 ) + { +LABEL_109: + if ( pOutdoorCamera->bNoSky ) + { + const_1_0(); + } + else + { + v13->pParent = &array_77EC08[1999]; + if ( !Render::DrawSkySW(v13, &array_77EC08[1999], a1a) ) + j_memset32(-65536, &pRenderer->pActiveZBuffer[v13->field_8 + 640 * v13->field_A], v13->field_C); + } + } + LOWORD(v2) = LOWORD(unnamed_6BE060[1]); + v13->field_E = LOWORD(unnamed_6BE060[1]); + goto LABEL_114; + } + v13->field_E = LOWORD(unnamed_6BE060[1]); + } +LABEL_114: + --v12; + --v9; + } + while ( v9 ); + } + return (signed __int16)v2; +} +// 6BE030: using guessed type int day_attrib; +// 6BE3C4: using guessed type char bUnderwater; +// 80AA10: using guessed type char byte_80AA10; +// 80AA14: using guessed type int dword_80AA14; +// 80AA18: using guessed type int dword_80AA18; +// 80AA1C: using guessed type int dword_80AA1C; +// 80AA20: using guessed type int dword_80AA20; + +//----- (00485044) -------------------------------------------------------- +int Render::DrawSkySW(Span *a1, stru148 *a2, int a3) +{ + stru148 *v3; // esi@1 + Span *v4; // edi@1 + float v5; // ST2C_4@1 + signed int result; // eax@2 + int v7; // ST40_4@3 + stru149 *v8; // eax@3 + int v9; // ebx@3 + int v10; // ecx@3 + int v11; // edx@3 + int v12; // eax@3 + int v13; // ST28_4@5 + int v14; // eax@5 + signed __int64 v15; // qtt@11 + int v16; // ST28_4@11 + int v17; // eax@11 + signed int v18; // ecx@11 + int v19; // ST40_4@11 + int v20; // ST3C_4@11 + int v21; // ST30_4@11 + void *v22; // eax@11 + Texture *v23; // esi@11 + int v24; // ecx@11 + unsigned int v25; // esi@11 + int v26; // edi@11 + unsigned __int16 *v27; // eax@11 + int *v28; // ebx@12 + int v29; // edx@13 + unsigned __int16 v30; // cx@13 + int v31; // edx@14 + unsigned __int16 v32; // cx@14 + unsigned __int8 v33; // sf@15 + unsigned __int8 v34; // of@15 + double v35; // [sp+14h] [bp-38h]@1 + int v36; // [sp+18h] [bp-34h]@3 + signed int v37; // [sp+18h] [bp-34h]@11 + int v38; // [sp+1Ch] [bp-30h]@3 + signed int v39; // [sp+1Ch] [bp-30h]@11 + int v40; // [sp+20h] [bp-2Ch]@3 + void *v41; // [sp+20h] [bp-2Ch]@11 + int v42; // [sp+24h] [bp-28h]@3 + unsigned __int8 *v43; // [sp+24h] [bp-28h]@11 + int v44; // [sp+28h] [bp-24h]@11 + int v45; // [sp+2Ch] [bp-20h]@3 + signed int v46; // [sp+30h] [bp-1Ch]@3 + __int16 v47; // [sp+30h] [bp-1Ch]@11 + signed int v48; // [sp+34h] [bp-18h]@3 + int v49; // [sp+34h] [bp-18h]@11 + int v50; // [sp+38h] [bp-14h]@3 + unsigned __int16 *v51; // [sp+38h] [bp-14h]@11 + int v52; // [sp+3Ch] [bp-10h]@4 + int a1a; // [sp+40h] [bp-Ch]@3 + int v54; // [sp+44h] [bp-8h]@3 + int v55; // [sp+48h] [bp-4h]@3 + int v56; // [sp+54h] [bp+8h]@11 + int *v57; // [sp+54h] [bp+8h]@11 + + v3 = a2; + v4 = a1; + v5 = (double)(pViewport->uViewportZ - pViewport->uViewportX) * 0.5 / tan(0.6457717418670654) + 0.5; + v35 = v5 + 6.7553994e15; + if ( LODWORD(v35) ) + { + v55 = 65536 / SLODWORD(v35); + v7 = 65536 / SLODWORD(v35) * (a3 - v4->field_A); + v8 = v3->ptr_38; + v42 = ((unsigned __int64)(v3->ptr_38->field_14 * (signed __int64)v7) >> 16) + v8->field_C; + v40 = ((unsigned __int64)(v8->field_20 * (signed __int64)v7) >> 16) + v3->ptr_38->field_18; + v38 = pOutdoorCamera->camera_rotation_y_int_sine; + HIDWORD(v35) = pOutdoorCamera->camera_rotation_y_int_cosine; + v45 = v4->field_C; + v9 = ((unsigned __int64)(v3->v_18.z * (signed __int64)v7) >> 16) + v3->v_18.x; + v10 = 65536 / SLODWORD(v35) * (pViewport->uScreenCenterX - v4->field_8); + v48 = 0; + v50 = 65536 / SLODWORD(v35) * (pViewport->uScreenCenterX - v4->field_8); + v46 = -v3->field_24; + v11 = v4->field_A - 1; + v54 = v11; + v12 = 65536 / SLODWORD(v35) * (a3 - v11); + a1a = 65536 / SLODWORD(v35) * (a3 - v11); + while ( 1 ) + { + v52 = v9; + if ( v9 ) + { + v13 = abs(v46 >> 14); + v14 = abs(v9); + v11 = v54; + v10 = v50; + if ( v13 <= v14 ) + break; + v12 = a1a; + } + if ( v11 <= (signed int)pViewport->uViewportY ) + break; + v9 = ((unsigned __int64)(v3->v_18.z * (signed __int64)v12) >> 16) + v3->v_18.x; + --v54; + a1a += v55; + v12 = a1a; + v11 = v54; + v48 = 1; + } + if ( v48 ) + v52 = ((unsigned __int64)(v3->v_18.z * (signed __int64)(v55 * (a3 + (signed int)v4->field_A - 2 * v11))) >> 16) + + v3->v_18.x; + LODWORD(v15) = v46 << 16; + HIDWORD(v15) = v46 >> 16; + v16 = v42 + ((unsigned __int64)(v3->ptr_38->field_10 * (signed __int64)v10) >> 16); + v17 = v40 + ((unsigned __int64)(v3->ptr_38->field_1C * (signed __int64)v10) >> 16); + v18 = v15 / v52; + v43 = v3->pTexture->pLevelOfDetail0; + v19 = v3->sTextureDeltaU + ((signed int)((unsigned __int64)(v16 * v15 / v52) >> 16) >> 3); + v56 = v15 / v52; + v20 = v3->sTextureDeltaV + ((signed int)((unsigned __int64)(v17 * v15 / v52) >> 16) >> 3); + v21 = (unsigned __int64)(v55 * (signed __int64)v56) >> 16; + v39 = (signed int)((unsigned __int64)(v21 * (signed __int64)v38) >> 16) >> 3; + v37 = (signed int)((unsigned __int64)(v21 * (signed __int64)v36) >> 16) >> 3; + v22 = sr_sub_47C178(v18, v3, 0, 1); + v23 = v3->pTexture; + v41 = v22; + v47 = 16 - v23->uWidthLn2; + v44 = v23->uTextureWidth - 1; + v49 = (v23->uTextureHeight << 16) - 65536; + v24 = v4->field_8; + v51 = &pRenderer->pTargetSurface[v24 + pRenderer->uTargetSurfacePitch * v4->field_A]; + v57 = &pRenderer->pActiveZBuffer[v24 + 640 * v4->field_A]; + v25 = v19; + v26 = v20; + v27 = v51; + if ( !(v45 & 1) ) + goto LABEL_15; + --v45; + v27 = v51 - 1; + v28 = v57; + ++v57; + while ( 1 ) + { + *v28 = -65536; + v31 = v44 & (v25 >> 16); + v27 += 2; + v25 += v39; + v32 = *((short *)v41 + *(&v43[v31] + ((v49 & (unsigned int)v26) >> v47))); + v26 += v37; + *(v27 - 1) = v32; +LABEL_15: + v34 = __OFSUB__(v45, 2); + v33 = v45 - 2 < 0; + v45 -= 2; + if ( v33 ^ v34 ) + break; + v29 = v44 & (v25 >> 16); + v25 += v39; + v30 = *((short *)v41 + *(&v43[v29] + ((v49 & (unsigned int)v26) >> v47))); + v26 += v37; + v28 = v57; + *v27 = v30; + v57 += 2; + v28[1] = -65536; + } + result = 1; + } + else + { + result = 0; + } + return result; +} + +//----- (0047F5C6) -------------------------------------------------------- +float Render::DrawBezierTerrain() +{ + //__debugbreak();Ritor1: it's temporarily + //return 0; + + unsigned int v0; // ebx@1 + unsigned int v1; // edi@1 + unsigned int v2; // eax@1 + int v3; // eax@3 + int v4; // edi@3 + int v5; // ebx@3 + int v6; // esi@3 + unsigned int v7; // eax@3 + int v8; // eax@4 + unsigned int v9; // eax@6 + int v10; // eax@7 + int v11; // ebx@9 + int v12; // edi@9 + int v13; // eax@21 + int v14; // eax@31 + int v15; // edi@33 + float v16; // eax@34 + int v17; // edx@34 + int v18; // ebx@34 + int v19; // eax@36 + int v20; // eax@39 + int v21; // ecx@43 + char v22; // zf@44 + int v23; // ecx@47 + int v24; // edi@52 + float v25; // eax@54 + int v26; // ecx@54 + int v27; // eax@56 + int v28; // edx@60 + int v29; // ecx@61 + int v30; // ecx@64 + int v31; // ecx@68 + int v32; // eax@70 + int v33; // ecx@71 + int v34; // eax@73 + int v35; // ecx@77 + int v36; // ecx@81 + int v37; // ecx@86 + float v38; // eax@88 + IndoorCameraD3D *v39; // ecx@88 + int v40; // eax@90 + int v41; // edx@94 + int v42; // ecx@95 + int v43; // ecx@98 + int v44; // ecx@102 + int v45; // eax@104 + int v46; // eax@107 + int v47; // ecx@111 + int v48; // ecx@115 + int v49; // edi@120 + float v50; // eax@122 + int v51; // ecx@122 + int v52; // eax@124 + int v53; // edx@128 + int v54; // ecx@129 + int v55; // ecx@132 + int v56; // eax@139 + int v57; // ecx@140 + int v58; // eax@142 + int v59; // ecx@146 + int v60; // ecx@147 + int v61; // ecx@150 + int v62; // ecx@155 + float v63; // eax@157 + IndoorCameraD3D *v64; // ecx@157 + int v65; // eax@159 + int v66; // edx@163 + int v67; // ecx@164 + int v68; // ecx@167 + int v69; // eax@173 + int v70; // edi@178 + int v71; // eax@178 + int v72; // ecx@178 + int v73; // ebx@180 + int v74; // eax@182 + int v75; // eax@184 + IndoorCameraD3D *v76; // ecx@184 + int v77; // ecx@184 + int v79; // ebx@185 + int v127; // esi@185 + int v86; // edi@196 + int v87; // eax@196 + int v88; // ecx@196 + int v89; // eax@198 + int v90; // ecx@200 + int v92; // ebx@203 + int v93; // ST08_4@204 + int v97; // ST08_4@204 + float result; // eax@212 + char v102; // [sp+Ch] [bp-68h]@191 + __int16 v103; // [sp+10h] [bp-64h]@190 + __int16 v104; // [sp+12h] [bp-62h]@190 + int v105; // [sp+1Ch] [bp-58h]@1 + int v106; // [sp+20h] [bp-54h]@3 + int v107; // [sp+24h] [bp-50h]@3 + int v108; // [sp+28h] [bp-4Ch]@9 + int v109; // [sp+2Ch] [bp-48h]@9 + int v110; // [sp+30h] [bp-44h]@9 + int v111; // [sp+34h] [bp-40h]@3 + int v112; // [sp+38h] [bp-3Ch]@6 + IndoorCameraD3D *a1; // [sp+3Ch] [bp-38h]@9 + int v114; // [sp+40h] [bp-34h]@9 + int v115; // [sp+44h] [bp-30h]@9 + int v116; // [sp+48h] [bp-2Ch]@9 + int v117; // [sp+4Ch] [bp-28h]@9 + int v118; // [sp+50h] [bp-24h]@9 + int v119; // [sp+54h] [bp-20h]@1 + int v120; // [sp+58h] [bp-1Ch]@1 + int i; // [sp+5Ch] [bp-18h]@1 + int v122; // [sp+60h] [bp-14h]@1 + int v123; // [sp+64h] [bp-10h]@1 + float v124; // [sp+68h] [bp-Ch]@1 + int v125; // [sp+6Ch] [bp-8h]@9 + float v126; // [sp+70h] [bp-4h]@9 + + memset(&v102, 0, sizeof(v102)); + v105 = pIndoorCamera->sRotationY / ((signed int)stru_5C6E00->uIntegerHalfPi / 2); + v0 = stru_5C6E00->uDoublePiMask & (stru_5C6E00->uIntegerDoublePi - pIndoorCamera->sRotationY); + v1 = stru_5C6E00->uDoublePiMask & (stru_5C6E00->uIntegerPi + v0); + LODWORD(v124) = (signed int)((pIndoorCamera->uMapGridCellX << 16) + + 3 + * stru_5C6E00->SinCos( + stru_5C6E00->uDoublePiMask & (stru_5C6E00->uIntegerPi + v0))) >> 16; + v123 = (signed int)((pIndoorCamera->uMapGridCellZ << 16) + + 3 * stru_5C6E00->SinCos(v1 - stru_5C6E00->uIntegerHalfPi)) >> 16; + v120 = pOutdoorCamera->outdoor_grid_band_3 + LODWORD(v124); + v119 = pOutdoorCamera->outdoor_grid_band_3 + v123; + v2 = pOutdoorCamera->uCameraFovInDegrees + 15; + i = LODWORD(v124) - pOutdoorCamera->outdoor_grid_band_3; + v122 = v123 - pOutdoorCamera->outdoor_grid_band_3; + if ( (signed int)(pOutdoorCamera->uCameraFovInDegrees + 15) > 90 ) + v2 = 90; + v3 = (signed int)(v2 << 11) / 720; + v4 = stru_5C6E00->uDoublePiMask & (v0 - v3); + v5 = stru_5C6E00->uDoublePiMask & (v3 + v0); + v106 = stru_5C6E00->SinCos(v4); + v107 = stru_5C6E00->SinCos(v4 - stru_5C6E00->uIntegerHalfPi); + v111 = stru_5C6E00->SinCos(v5); + v6 = stru_5C6E00->SinCos(v5 - stru_5C6E00->uIntegerHalfPi); + v7 = v4 & stru_5C6E00->uPiMask; + if ( (signed int)(v4 & stru_5C6E00->uPiMask) >= (signed int)stru_5C6E00->uIntegerHalfPi ) + v8 = -stru_5C6E00->pTanTable[stru_5C6E00->uIntegerPi - v7]; + else + v8 = stru_5C6E00->pTanTable[v7]; + v112 = abs(v8); + v9 = v5 & stru_5C6E00->uPiMask; + if ( (signed int)(v5 & stru_5C6E00->uPiMask) >= (signed int)stru_5C6E00->uIntegerHalfPi ) + v10 = -stru_5C6E00->pTanTable[stru_5C6E00->uIntegerPi - v9]; + else + v10 = stru_5C6E00->pTanTable[v9]; + v108 = abs(v10); + v11 = LODWORD(v124); + v12 = v123; + v114 = 0; + v115 = 0; + a1 = 0; + v125 = 0; + v110 = 2 * (v106 >= 0) - 1; + v126 = v124; + v118 = v123; + v109 = 2 * (v107 >= 0) - 1; + v107 = 2 * (v111 >= 0) - 1; + terrain_76E1C8[0] = 65535; + v116 = 1; + v106 = 2 * (v6 >= 0) - 1; + v117 = 1; + terrain_76E3C8[0] = 65535; + terrain_76DDC8[0] = 65535; + terrain_76DFC8[0] = 65535; + while ( 1 ) + { + if ( v112 >= 65536 ) + { + v111 = 4294967296i64 / v112; + v114 += v111; + if ( v114 >= 65536 ) + { + v11 += v110; + v114 = (unsigned __int16)v114; + } + v12 += v109; + } + else + { + v11 += v110; + v115 += v112; + if ( v115 >= 65536 ) + { + v12 += v109; + v115 = (unsigned __int16)v115; + } + } + if ( v116 > 128 || v11 < i || v11 > v120 || v12 < v122 || v12 > v119 ) + break; + v13 = v116++; + terrain_76E3C8[v13] = v11; + terrain_76E1C8[v13] = v12; + } + while ( 1 ) + { + if ( v108 >= 65536 ) + { + v111 = 4294967296i64 / v108; + a1 = (IndoorCameraD3D *)((char *)a1 + v111); + if ( (signed int)a1 >= 65536 ) + { + LODWORD(v126) += v107; + a1 = (IndoorCameraD3D *)(unsigned __int16)a1; + } + v118 += v106; + } + else + { + v125 += v108; + LODWORD(v126) += v107; + if ( v125 >= 65536 ) + { + v118 += v106; + v125 = (unsigned __int16)v125; + } + } + if ( v117 >= 128 ) + break; + if ( SLODWORD(v126) < i ) + break; + if ( SLODWORD(v126) > v120 ) + break; + v14 = v118; + if ( v118 < v122 ) + break; + if ( v118 > v119 ) + break; + v15 = v117++; + terrain_76DFC8[v15] = LODWORD(v126); + terrain_76DDC8[v15] = v14; + } + LODWORD(v16) = 0; + LODWORD(v126) = 0; + v17 = v117 - 1; + v18 = v116 - 1; + switch ( v105 ) + { + case 0: + case 7: + v116 = terrain_76DFC8[v17]; + if ( v120 > v116 ) + { + v125 = v120; + memset32(terrain_76D9C8, v119 + 1, v120 - v116 + 1); + v19 = v120; + do + terrain_76DBC8[LODWORD(v126)++] = v19--; + while ( v19 >= v116 ); + if ( terrain_76DFC8[v17] == terrain_76DDC8[v17 + 127] ) + { + do + v20 = terrain_76DDC8[v17-- + 127]; + while ( v20 == terrain_76DDC8[v17 + 127] ); + } + v16 = v126; + --v17; + } + if ( v17 < 0 ) + v17 = 0; + v21 = terrain_76DFC8[v17]; + while ( 1 ) + { + v125 = v21; + if ( v21 < SLODWORD(v124) ) + break; + terrain_76DBC8[LODWORD(v16)] = v21; + v22 = terrain_76DDC8[v17] == 65535; + terrain_76D9C8[LODWORD(v16)] = terrain_76DDC8[v17] + 1; + if ( v22 ) + { + terrain_76D9C8[LODWORD(v16)] = v123 + 1; + break; + } + if ( !v17 ) + break; + if ( terrain_76DFC8[v17] == terrain_76DDC8[v17 + 127] ) + { + do + v23 = terrain_76DDC8[v17-- + 127]; + while ( v23 == terrain_76DDC8[v17 + 127] ); + } + --v17; + v21 = v125 - 1; + ++LODWORD(v16); + } + LODWORD(v16) = 0; + v24 = terrain_76E3C8[v18]; + LODWORD(v126) = 0; + if ( v120 > v24 ) + { + v125 = v120; + memset32(terrain_76D5C8, v122, v120 - v24 + 1); + do + { + v25 = v126; + v26 = v125--; + ++LODWORD(v126); + terrain_76D7C8[LODWORD(v25)] = v26; + } + while ( v125 >= terrain_76E3C8[v18] ); + if ( terrain_76E3C8[v18] == terrain_76E1C8[v18 + 127] ) + { + do + v27 = terrain_76E1C8[v18-- + 127]; + while ( v27 == terrain_76E1C8[v18 + 127] ); + } + v16 = v126; + --v18; + } + if ( v18 < 0 ) + v18 = 0; + v28 = terrain_76E3C8[v18]; + while ( v28 >= SLODWORD(v124) ) + { + v29 = terrain_76E1C8[v18]; + terrain_76D7C8[LODWORD(v16)] = v28; + terrain_76D5C8[LODWORD(v16)] = v29; + if ( v29 == 65535 ) + { + v31 = v123; + goto LABEL_172; + } + if ( !v18 ) + break; + if ( terrain_76E3C8[v18] == terrain_76E1C8[v18 + 127] ) + { + do + v30 = terrain_76E1C8[v18-- + 127]; + while ( v30 == terrain_76E1C8[v18 + 127] ); + } + --v18; + --v28; + ++LODWORD(v16); + } + break; + case 1: + case 2: + v116 = terrain_76DDC8[v17]; + if ( v122 < v116 ) + { + v106 = v122; + memset32(terrain_76DBC8, v120 + 1, v116 - v122 + 1); + v32 = v122; + do + { + v33 = LODWORD(v126)++; + terrain_76D9C8[v33] = v32++; + } + while ( v32 <= v116 ); + if ( terrain_76DDC8[v17] == terrain_76DBC8[v17 + 127] ) + { + do + v34 = terrain_76DBC8[v17-- + 127]; + while ( v34 == terrain_76DBC8[v17 + 127] ); + } + v16 = v126; + --v17; + } + if ( v17 < 0 ) + v17 = 0; + v35 = terrain_76DDC8[v17]; + v125 = terrain_76DDC8[v17]; + while ( v35 <= v123 ) + { + v22 = terrain_76DFC8[v17] == 65535; + terrain_76DBC8[LODWORD(v16)] = terrain_76DFC8[v17] + 1; + terrain_76D9C8[LODWORD(v16)] = v125; + if ( v22 ) + { + terrain_76DBC8[LODWORD(v16)] = LODWORD(v124) + 1; + break; + } + if ( !v17 ) + break; + if ( terrain_76DDC8[v17] == terrain_76DBC8[v17 + 127] ) + { + do + v36 = terrain_76DBC8[v17-- + 127]; + while ( v36 == terrain_76DBC8[v17 + 127] ); + } + --v17; + ++v125; + v35 = v125; + ++LODWORD(v16); + } + LODWORD(v16) = 0; + LODWORD(v126) = 0; + v37 = terrain_76E1C8[v18]; + if ( v122 < v37 ) + { + a1 = (IndoorCameraD3D *)v122; + memset32(terrain_76D7C8, i, v37 - v122 + 1); + do + { + v38 = v126; + v39 = a1; + ++LODWORD(v126); + a1 = (IndoorCameraD3D *)((char *)a1 + 1); + terrain_76D5C8[LODWORD(v38)] = (int)v39; + } + while ( (signed int)a1 <= terrain_76E1C8[v18] ); + if ( terrain_76E1C8[v18] == terrain_76DFC8[v18 + 127] ) + { + do + v40 = terrain_76DFC8[v18-- + 127]; + while ( v40 == terrain_76DFC8[v18 + 127] ); + } + v16 = v126; + --v18; + } + if ( v18 < 0 ) + v18 = 0; + v41 = terrain_76E1C8[v18]; + while ( v41 <= v123 ) + { + v42 = terrain_76E3C8[v18]; + terrain_76D5C8[LODWORD(v16)] = v41; + terrain_76D7C8[LODWORD(v16)] = v42; + if ( v42 == 65535 ) + { + v44 = LODWORD(v124); + goto LABEL_137; + } + if ( !v18 ) + break; + if ( terrain_76E1C8[v18] == terrain_76DFC8[v18 + 127] ) + { + do + v43 = terrain_76DFC8[v18-- + 127]; + while ( v43 == terrain_76DFC8[v18 + 127] ); + } + --v18; + ++v41; + ++LODWORD(v16); + } + break; + case 5: + case 6: + v116 = terrain_76DDC8[v17]; + if ( v119 > v116 ) + { + v106 = v119; + memset32(terrain_76DBC8, i, v119 - v116 + 1); + v45 = v119; + do + terrain_76D9C8[LODWORD(v126)++] = v45--; + while ( v45 >= v116 ); + if ( terrain_76DDC8[v17] == terrain_76DBC8[v17 + 127] ) + { + do + v46 = terrain_76DBC8[v17-- + 127]; + while ( v46 == terrain_76DBC8[v17 + 127] ); + } + v16 = v126; + --v17; + } + if ( v17 < 0 ) + v17 = 0; + v47 = terrain_76DDC8[v17]; + v125 = terrain_76DDC8[v17]; + while ( v47 >= v123 ) + { + v22 = terrain_76DFC8[v17] == 65535; + terrain_76DBC8[LODWORD(v16)] = terrain_76DFC8[v17]; + terrain_76D9C8[LODWORD(v16)] = v125; + if ( v22 ) + { + terrain_76DBC8[LODWORD(v16)] = LODWORD(v124); + break; + } + if ( !v17 ) + break; + if ( terrain_76DDC8[v17] == terrain_76DBC8[v17 + 127] ) + { + do + v48 = terrain_76DBC8[v17-- + 127]; + while ( v48 == terrain_76DBC8[v17 + 127] ); + } + --v17; + --v125; + v47 = v125; + ++LODWORD(v16); + } + LODWORD(v16) = 0; + v49 = terrain_76E1C8[v18]; + LODWORD(v126) = 0; + if ( v119 > v49 ) + { + v125 = v119; + memset32(terrain_76D7C8, v120 + 1, v119 - v49 + 1); + do + { + v50 = v126; + v51 = v125--; + ++LODWORD(v126); + terrain_76D5C8[LODWORD(v50)] = v51; + } + while ( v125 >= terrain_76E1C8[v18] ); + if ( terrain_76E1C8[v18] == terrain_76DFC8[v18 + 127] ) + { + do + v52 = terrain_76DFC8[v18-- + 127]; + while ( v52 == terrain_76DFC8[v18 + 127] ); + } + v16 = v126; + --v18; + } + if ( v18 < 0 ) + v18 = 0; + v53 = terrain_76E1C8[v18]; + while ( v53 >= v123 ) + { + v54 = terrain_76E3C8[v18]; + terrain_76D5C8[LODWORD(v16)] = v53; + terrain_76D7C8[LODWORD(v16)] = v54 + 1; + if ( v54 == 65535 ) + { + v44 = LODWORD(v124) + 1; +LABEL_137: + terrain_76D7C8[LODWORD(v16)] = v44; + goto LABEL_173; + } + if ( !v18 ) + goto LABEL_173; + if ( terrain_76E1C8[v18] == terrain_76DFC8[v18 + 127] ) + { + do + v55 = terrain_76DFC8[v18-- + 127]; + while ( v55 == terrain_76DFC8[v18 + 127] ); + } + --v18; + --v53; + ++LODWORD(v16); + } + break; + case 3: + case 4: + v116 = terrain_76DFC8[v17]; + if ( i < v116 ) + { + v106 = i; + memset32(terrain_76D9C8, v122, v116 - i + 1); + v56 = i; + do + { + v57 = LODWORD(v126)++; + terrain_76DBC8[v57] = v56++; + } + while ( v56 <= v116 ); + if ( terrain_76DFC8[v17] == terrain_76DDC8[v17 + 127] ) + { + do + v58 = terrain_76DDC8[v17-- + 127]; + while ( v58 == terrain_76DDC8[v17 + 127] ); + } + v16 = v126; + --v17; + } + if ( v17 < 0 ) + v17 = 0; + v59 = terrain_76DFC8[v17]; + while ( 1 ) + { + v125 = v59; + if ( v59 > SLODWORD(v124) ) + break; + terrain_76DBC8[LODWORD(v16)] = v59; + v60 = terrain_76DDC8[v17]; + terrain_76D9C8[LODWORD(v16)] = v60; + if ( v60 == 65535 ) + { + terrain_76D9C8[LODWORD(v16)] = v123; + break; + } + if ( !v17 ) + break; + if ( terrain_76DFC8[v17] == terrain_76DDC8[v17 + 127] ) + { + do + v61 = terrain_76DDC8[v17-- + 127]; + while ( v61 == terrain_76DDC8[v17 + 127] ); + } + --v17; + v59 = v125 + 1; + ++LODWORD(v16); + } + LODWORD(v16) = 0; + LODWORD(v126) = 0; + v62 = terrain_76E3C8[v18]; + if ( i < v62 ) + { + a1 = (IndoorCameraD3D *)i; + memset32(terrain_76D5C8, v119 + 1, v62 - i + 1); + do + { + v63 = v126; + v64 = a1; + ++LODWORD(v126); + a1 = (IndoorCameraD3D *)((char *)a1 + 1); + terrain_76D7C8[LODWORD(v63)] = (int)v64; + } + while ( (signed int)a1 <= terrain_76E3C8[v18] ); + if ( terrain_76E3C8[v18] == terrain_76E1C8[v18 + 127] ) + { + do + v65 = terrain_76E1C8[v18-- + 127]; + while ( v65 == terrain_76E1C8[v18 + 127] ); + } + v16 = v126; + --v18; + } + if ( v18 < 0 ) + v18 = 0; + v66 = terrain_76E3C8[v18]; + while ( v66 <= SLODWORD(v124) ) + { + v67 = terrain_76E1C8[v18]; + terrain_76D7C8[LODWORD(v16)] = v66; + terrain_76D5C8[LODWORD(v16)] = v67 + 1; + if ( v67 == 65535 ) + { + v31 = v123 + 1; +LABEL_172: + terrain_76D5C8[LODWORD(v16)] = v31; + goto LABEL_173; + } + if ( !v18 ) + goto LABEL_173; + if ( terrain_76E3C8[v18] == terrain_76E1C8[v18 + 127] ) + { + do + v68 = terrain_76E1C8[v18-- + 127]; + while ( v68 == terrain_76E1C8[v18 + 127] ); + } + --v18; + ++v66; + ++LODWORD(v16); + } + break; + default: + break; + } +LABEL_173: + v69 = LODWORD(v16) - 1; + ptr_801A08 = pVerticesSR_806210; + ptr_801A04 = pVerticesSR_801A10; + LODWORD(v126) = v69; + if ( v105 && v105 != 7 && v105 != 3 && v105 != 4 ) + { + for ( i = v69; i >= 1; --i ) + { + v70 = i; + v71 = terrain_76D7C8[i]; + v72 = terrain_76DBC8[i]; + if ( v71 < v72 ) + { + terrain_76DBC8[v70] = v71; + terrain_76D7C8[v70] = v72; + } + v73 = terrain_76DBC8[v70]; + v111 = 0; + if ( v73 <= 0 ) + v73 = -v73; + v74 = terrain_76D7C8[v70]; + if ( v74 <= 0 ) + v74 = -v74; + v75 = v74 + 2; + v76 = pGame->pIndoorCameraD3D; + v107 = v75; + a1 = v76; + v77 = v73 - 2; + if ( v73 - 2 < v75 ) + { + v127 = 0; + v79 = (v73 - 66) << 9; + v116 = v77; + v105 = v79; + v111 = v75 - v77; + do + { + *(float *)&v106 = (double)v105; + *(float *)((char *)&ptr_801A08->vWorldPosition.x + v127) = *(float *)&v106; + v105 = (64 - *(int *)((char *)terrain_76D9C8 + v70)) << 9; + *(float *)((char *)&ptr_801A08->vWorldPosition.y + v127) = (double)v105; + v105 = pOutdoor->GetHeightOnTerrain(v112, *(int *)((char *)terrain_76D9C8 + v70)); + *(float *)((char *)&ptr_801A08->vWorldPosition.z + v127) = (double)v105; + *(float *)((char *)&ptr_801A04->vWorldPosition.x + v127) = *(float *)&v106; + v105 = (63 - *(int *)((char *)terrain_76D9C8 + v70)) << 9; + *(float *)((char *)&ptr_801A04->vWorldPosition.y + v127) = (double)v105; + v105 = pOutdoor->GetHeightOnTerrain(v112, *(int *)((char *)terrain_76D9C8 + v70) + 1); + *(float *)((char *)&ptr_801A04->vWorldPosition.z + v127) = (double)v105; + if ( !byte_4D864C || !(pGame->uFlags & 0x80) ) + { + a1->ViewTransform((RenderVertexSoft *)(char *)ptr_801A08 + v127, 1); + a1->ViewTransform((RenderVertexSoft *)(char *)ptr_801A04 + v127, 1); + a1->Project((RenderVertexSoft *)(char *)ptr_801A08 + v127, 1, 0); + a1->Project((RenderVertexSoft *)(char *)ptr_801A04 + v127, 1, 0); + } + v79 += 512; + v127 += 48; + ++v116; + v105 = v79; + } + while ( v116 < v107 ); + } + v103 = abs((int)pIndoorCamera->uMapGridCellZ - terrain_76D9C8[v70]); + v104 = abs((int)pIndoorCamera->uMapGridCellX - terrain_76DBC8[v70]); + if ( pRenderer->pRenderD3D ) + Render::DrawTerrainD3D(v111, 0, (int)&v102); + else + Render::DrawTerrainSW(v111, 0, (int)&v102); + } + } + else + { + for ( i = v69; i >= 1; --i ) + { + v86 = i; + v87 = terrain_76D5C8[i]; + v88 = terrain_76D9C8[i]; + if ( v87 < v88 ) + { + terrain_76D9C8[v86] = v87; + terrain_76D5C8[v86] = v88; + } + v89 = terrain_76D9C8[v86]; + v111 = 0; + if ( v89 <= 0 ) + v89 = -v89; + v90 = terrain_76D5C8[v86]; + if ( v90 <= 0 ) + v90 = -v90; + a1 = pGame->pIndoorCameraD3D; + v107 = v90 + 2; + if ( v89 - 2 < v90 + 2 ) + { + v86 = 0; + v116 = v89 - 2; + v92 = (66 - v89) << 9; + v105 = (66 - v89) << 9; + v111 = v90 + 2 - (v89 - 2); + do + { + v93 = v116; + v106 = (*(int *)((char *)terrain_76DBC8 + v86) - 64) << 9; + *(float *)((char *)&ptr_801A08->vWorldPosition.x + v86) = (double)v106; + *(float *)&v105 = (double)v105; + *(float *)((char *)&ptr_801A08->vWorldPosition.y + v86) = *(float *)&v105; + v106 = pOutdoor->GetHeightOnTerrain(*(int *)((char *)terrain_76DBC8 + v86), v93); + v97 = v116; + *(float *)((char *)&ptr_801A08->vWorldPosition.z + v86) = (double)v106; + v106 = (*(int *)((char *)terrain_76DBC8 + v86) - 63) << 9; + *(float *)((char *)&ptr_801A04->vWorldPosition.x + v86) = (double)v106; + *(float *)((char *)&ptr_801A04->vWorldPosition.y + v86) = *(float *)&v105; + v105 = pOutdoor->GetHeightOnTerrain(*(int *)((char *)terrain_76DBC8 + v86) + 1, v97); + *(float *)((char *)&ptr_801A04->vWorldPosition.z + v86) = (double)v105; + if ( !byte_4D864C || !(pGame->uFlags & 0x80) ) + { + a1->ViewTransform((RenderVertexSoft *)(char *)ptr_801A08 + v86, 1); + a1->ViewTransform((RenderVertexSoft *)(char *)ptr_801A04 + v86, 1); + a1->Project((RenderVertexSoft *)(char *)ptr_801A08 + v86, 1, 0); + a1->Project((RenderVertexSoft *)(char *)ptr_801A04 + v86, 1, 0); + } + v92 -= 512; + v86 += 48; + ++v116; + v105 = v92; + } + while ( v116 < v107 ); + } + v103 = abs((int)pIndoorCamera->uMapGridCellX - terrain_76DBC8[v86]); + v104 = abs((int)pIndoorCamera->uMapGridCellZ - terrain_76D9C8[v86]); + if ( pRenderer->pRenderD3D ) + Render::DrawTerrainD3D(v111, 1, (int)&v102); + else + Render::DrawTerrainSW(v111, 1, (int)&v102); + } + } + result = v126; + pOutdoorCamera->field_40 = v126; + return result; +} +// 47FFC4: inconsistent fpu stack +// 4D864C: using guessed type char byte_4D864C; + + + +//----- (0048034E) -------------------------------------------------------- +void Render::DrawTerrainD3D(int a1, int edx0, int a3) +{ + int v3; // esi@1 + int v4; // edi@1 + int v5; // ebx@2 + int v6; // eax@2 + int v7; // eax@3 + RenderVertexSoft *v8; // edi@3 + RenderVertexSoft *v9; // ebx@4 + RenderVertexSoft *v10; // ecx@4 + float v11; // eax@6 + double v12; // ST5C_8@6 + double v13; // ST2C_8@6 + int v14; // eax@6 + double v15; // st7@6 + stru148 *v16; // ebx@12 + unsigned __int16 v17; // ax@12 + int v18; // eax@13 + LightmapBuilder *v19; // ecx@13 + stru220 *v20; // eax@13 + int v21; // eax@13 + signed int v22; // eax@13 + Vec3_float_ *v23; // eax@15 + double v24; // st6@17 + double v25; // ST54_8@17 + unsigned __int8 v26; // sf@17 + unsigned __int8 v27; // of@17 + double v28; // st5@19 + double v29; // st5@19 + double v30; // st5@19 + double v31; // st5@19 + double v32; // st7@32 + int v33; // edi@38 + unsigned int v34; // ecx@47 + char v35; // zf@47 + unsigned int v36; // eax@50 + int v37; // eax@54 + stru148 *v38; // ecx@55 + unsigned int v39; // eax@59 + stru148 *v40; // ebx@62 + unsigned __int16 v41; // ax@62 + int v42; // eax@63 + LightmapBuilder *v43; // ecx@63 + stru220 *v44; // eax@63 + int v45; // eax@63 + int v46; // eax@63 + signed int v47; // eax@63 + Vec3_float_ *v48; // eax@65 + double v49; // st6@67 + double v50; // ST4C_8@67 + double v51; // st5@71 + double v52; // st5@71 + double v53; // st5@71 + double v54; // st7@84 + unsigned int v55; // ecx@98 + unsigned int v56; // eax@101 + int v57; // eax@105 + unsigned int v58; // eax@109 + stru148 *v59; // esi@112 + unsigned __int16 v60; // ax@112 + stru220 *v61; // eax@113 + signed int v62; // eax@113 + Vec3_float_ *v63; // eax@114 + double v64; // st6@116 + double v65; // ST3C_8@116 + double v66; // st5@120 + double v67; // st5@120 + double v68; // st5@120 + double v69; // st7@133 + int v70; // edi@138 + RenderVertexSoft *v71; // esi@147 + unsigned int v72; // ecx@147 + unsigned int v73; // eax@150 + float v74; // eax@154 + unsigned int v75; // eax@158 + unsigned int v76; // [sp-10h] [bp-E0h]@61 + stru148 *v77; // [sp-Ch] [bp-DCh]@61 + IDirect3DTexture2 *v78; // [sp-8h] [bp-D8h]@61 + int v79; // [sp-4h] [bp-D4h]@61 + int v80; // [sp+0h] [bp-D0h]@59 + int v81; // [sp+0h] [bp-D0h]@109 + int v82; // [sp+54h] [bp-7Ch]@1 + int v83; // [sp+60h] [bp-70h]@1 + int v84; // [sp+6Ch] [bp-64h]@1 + int v85; // [sp+70h] [bp-60h]@63 + int a4; // [sp+74h] [bp-5Ch]@73 + float v87; // [sp+78h] [bp-58h]@122 + int v88; // [sp+7Ch] [bp-54h]@1 + int v89; // [sp+80h] [bp-50h]@6 + float v90; // [sp+84h] [bp-4Ch]@1 + float v91; // [sp+88h] [bp-48h]@1 + float v92; // [sp+8Ch] [bp-44h]@1 + stru220 *v93; // [sp+90h] [bp-40h]@2 + int X; // [sp+94h] [bp-3Ch]@1 + float v95; // [sp+98h] [bp-38h]@21 + LightmapBuilder *v96; // [sp+9Ch] [bp-34h]@73 + LightmapBuilder *_this; // [sp+A0h] [bp-30h]@6 + int sX; // [sp+A4h] [bp-2Ch]@6 + unsigned int uNumVertices; // [sp+A8h] [bp-28h]@73 + int v100; // [sp+ACh] [bp-24h]@122 + int sY; // [sp+B0h] [bp-20h]@6 + RenderVertexSoft *a2; // [sp+B4h] [bp-1Ch]@3 + unsigned int a5; // [sp+B8h] [bp-18h]@21 + RenderVertexSoft *v101; // [sp+BCh] [bp-14h]@6 + Vec3_float_ *v99; // [sp+C0h] [bp-10h]@17 + RenderVertexSoft *pVertices; // [sp+C4h] [bp-Ch]@6 + RenderVertexSoft *a8; // [sp+C8h] [bp-8h]@6 + char v108; // [sp+CFh] [bp-1h]@36 + float thisd; // [sp+D8h] [bp+8h]@6 + float thise; // [sp+D8h] [bp+8h]@6 + float thisf; // [sp+D8h] [bp+8h]@17 + IndoorCameraD3D *thisa; // [sp+D8h] [bp+8h]@23 + float thisg; // [sp+D8h] [bp+8h]@67 + IndoorCameraD3D *thisb; // [sp+D8h] [bp+8h]@75 + float thish; // [sp+D8h] [bp+8h]@116 + IndoorCameraD3D *thisc; // [sp+D8h] [bp+8h]@124 + char this_3; // [sp+DBh] [bp+Bh]@30 + char this_3a; // [sp+DBh] [bp+Bh]@82 + char this_3b; // [sp+DBh] [bp+Bh]@131 + + v3 = a1; + v82 = edx0; + v83 = *(/*short **/_WORD *)(a3 + 4); + X = abs(*(/*short **/_WORD *)(a3 + 6)); + v4 = 0; + v88 = 0; + v84 = v3 - 1; + v90 = (double)pOutdoor->vSunlight.x * 0.000015258789; + v91 = (double)pOutdoor->vSunlight.y * 0.000015258789; + v92 = (double)pOutdoor->vSunlight.z * 0.000015258789; + if ( v3 - 1 > 0 ) + { + while ( 1 ) + { + v5 = abs(X);//v5 = 13108 + v6 = abs(v83);//v6 = 13108 + --X; + v93 = &stru_76E5C8[(v5 << 7) + v6]; + if ( !v93->field_0 || ((v7 = 48 * v4, v8 = &pVerticesSR_806210[v4], a2 = v8, !v82) ? (v9 = (RenderVertexSoft *)((char *)&pVerticesSR_801A10 + v7), + v10 = &pVerticesSR_806210[1] + v7) : (v9 = &pVerticesSR_806210[1] + v7, v10 = (RenderVertexSoft *)((char *)&pVerticesSR_801A10 + v7)), + ((a8 = v9, + pVertices = &pVerticesSR_801A10[1] + v7, + v11 = v8->vWorldPosition.x, + v101 = v10, + v12 = v11 + 6.755399441055744e15, + sX = LODWORD(v12), + v13 = v8->vWorldPosition.y + 6.755399441055744e15, + sY = LODWORD(v13), + thisd = (v10->vWorldPosition.x + v8->vWorldPosition.x) * 0.5, + v14 = WorldPosToGridCellX(floorf(thisd + 0.5f)), + v15 = v9->vWorldPosition.y + v8->vWorldPosition.y, + v89 = v14, + thise = v15 * 0.5, + _this = (LightmapBuilder *)WorldPosToGridCellZ(floorf(thisd + 0.5f)), + WorldPosToGridCellX(sX), + WorldPosToGridCellZ(sY), + !byte_4D864C) + || !(pGame->uFlags & 0x80)) + && !sub_481EFA(v8, v9, v101, pVertices, 1)) ) + goto LABEL_162; + if ( v8->vWorldPosition.z != v9->vWorldPosition.z || v9->vWorldPosition.z != pVertices->vWorldPosition.z || pVertices->vWorldPosition.z != v101->vWorldPosition.z ) + break; + v16 = &array_77EC08[pOutdoorCamera->numStru148s]; + v17 = pOutdoor->GetTileTexture(sX, sY); + v16->uTileBitmapID = v17; + if ( v17 != -1 ) + { + v18 = pOutdoor->GetSomeOtherTileInfo(sX, sY); + LOWORD(v18) = v18 | 0x8010; + v19 = _this; + *(int *)&v16->flags = v18; + v20 = v93; + v16->field_59 = 1; + v16->field_5D = (char)v19; + v16->field_34 = v20->distance; + v21 = v89; + v16->field_5C = v89; + v22 = pTerrainNormalIndices[2 * (signed int)((char *)v19 + 128 * v21) + 1]; + if ( v22 < 0 || v22 > (signed int)(uNumTerrainNormals - 1) ) + v23 = 0; + else + v23 = &pTerrainNormals[v22]; + v24 = v92 * v23->z; + v99 = v23; + thisf = 20.0 - (-v24 - v91 * v23->y - v90 * v23->x) * 20.0; + v25 = thisf + 6.7553994e15; + v27 = pOutdoorCamera->numStru148s > 1999; + v26 = pOutdoorCamera->numStru148s - 1999 < 0; + v16->field_58 = LOBYTE(v25); + if ( !(v26 ^ v27) ) + return; + ++pOutdoorCamera->numStru148s; + if ( !sub_481FC9(v8, a8, v101, v16) ) + goto LABEL_126; + v28 = 1.0 / (a2->vWorldViewPosition.x + 0.0000001); + memcpy(array_50AC10, a2, 0x30u); + array_50AC10[0].flt_20 = v28; + array_50AC10[0].u = 0.0; + array_50AC10[0].v = 0.0; + v29 = a8->vWorldViewPosition.x + 0.0000001; + memcpy(&array_50AC10[1], a8, sizeof(array_50AC10[1])); + array_50AC10[1].flt_20 = 1.0 / v29; + array_50AC10[1].u = 0.0; + array_50AC10[1].v = 1.0; + v30 = pVertices->vWorldViewPosition.x + 0.0000001; + memcpy(&array_50AC10[2], pVertices, sizeof(array_50AC10[2])); + array_50AC10[2].flt_20 = 1.0 / v30; + array_50AC10[2].u = 1.0; + array_50AC10[2].v = 1.0; + v31 = v101->vWorldViewPosition.x + 0.0000001; + memcpy(&array_50AC10[3], v101, sizeof(array_50AC10[3])); + array_50AC10[3].flt_20 = 1.0 / v31; + array_50AC10[3].u = 1.0; + array_50AC10[3].v = 0.0; + + static stru154 static_sub_0048034E_stru_154; + /*static bool __init_flag3 = false; + if (!__init_flag3) + { + __init_flag3 = true; + + stru154::stru154(&static_sub_0048034E_stru_154); + }*/ + + _this = pGame->pLightmapBuilder; + pGame->pLightmapBuilder->StackLights_TerrainFace(v99, &v95, array_50AC10, 4u, 1); + pDecalBuilder->_49BE8A(v16, *(float *)&v99, (int)&v95, array_50AC10, 4u, 1); + a5 = 4; + if ( byte_4D864C && pGame->uFlags & 0x80 ) + { + thisa = pGame->pIndoorCameraD3D; + if ( pGame->pIndoorCameraD3D->_4371C3(array_50AC10, &a5, 0) == 1 && !a5 ) + goto LABEL_162; + thisa->ViewTransform(array_50AC10, a5); + thisa->Project(array_50AC10, a5, 0); + } + this_3 = a2->vWorldViewPosition.x < 8.0 + || a8->vWorldViewPosition.x < 8.0 + || v101->vWorldViewPosition.x < 8.0 + || pVertices->vWorldViewPosition.x < 8.0; + v32 = (double)pOutdoorCamera->shading_dist_mist; + v108 = v32 < a2->vWorldViewPosition.x + || v32 < a8->vWorldViewPosition.x + || v32 < v101->vWorldViewPosition.x + || v32 < pVertices->vWorldViewPosition.x; + LOBYTE(v33) = 0; + pGame->pLightmapBuilder->std__vector_000004_size = 0; + if ( stru_F8AD28.uNumLightsApplied > 0 || pDecalBuilder->uNumDecals > 0 ) + { + if ( this_3 ) + LOBYTE(v33) = 3; + else + v33 = v108 != 0 ? 5 : 0; + static_sub_0048034E_stru_154._49B0C9(v99, v95); + if ( pDecalBuilder->uNumDecals > 0 ) + pDecalBuilder->ApplyDecals( + 31 - v16->field_58, + 4, + &static_sub_0048034E_stru_154, + a5, + array_50AC10, + 0, + v33, + -1); + } + if ( stru_F8AD28.uNumLightsApplied > 0 ) + pGame->pLightmapBuilder->ApplyLights(&stru_F8AD28, &static_sub_0048034E_stru_154, a5, array_50AC10, 0, v33); + v34 = a5; + v35 = byte_4D864C == 0; + v16->uNumVertices = a5; + if ( v35 || !(pGame->uFlags & 0x80) ) + { + if ( this_3 ) + { + v36 = sr_424CD7(v34); + goto LABEL_53; + } + if ( v108 ) + { + v36 = sr_424EE0_MakeFanFromTriangle(v34); +LABEL_53: + v16->uNumVertices = v36; + OutdoorCamera::Project(v36); + } + } + v37 = *(int *)&v16->flags; + if ( !(BYTE1(v37) & 1) ) + { + if ( v37 & 2 && v16->uTileBitmapID == pRenderer->field_1036AC_bitmapid ) + { + v80 = 0; + v39 = pRenderer->pHDWaterBitmapIDs[pRenderer->field_1036A8_bitmapid]; + } + else + { + v39 = v16->uTileBitmapID; + v80 = 1; + } + v79 = 0; + v78 = pBitmaps_LOD->pHardwareTextures[v39]; + v77 = v16; + v76 = v16->uNumVertices; +LABEL_161: + pRenderer->DrawTerrainPolygon(v76, v77, v78, v79, v80); + goto LABEL_162; + } + v38 = v16; +LABEL_56: + v38->_4811A3(); + } +LABEL_162: + v4 = v88++ + 1; + if ( v88 >= v84 ) + return; + } + v40 = &array_77EC08[pOutdoorCamera->numStru148s]; + v41 = pOutdoor->GetTileTexture(sX, sY); + v40->uTileBitmapID = v41; + if ( v41 == -1 ) + goto LABEL_162; + v42 = pOutdoor->GetSomeOtherTileInfo(sX, sY); + BYTE1(v42) |= 0x80u; + v43 = pGame->pLightmapBuilder; + *(int *)&v40->flags = v42; + v44 = v93; + v40->field_59 = 1; + v40->field_5D = (char)v43; + v40->field_34 = v44->distance; + v45 = v89; + v40->field_5C = v89; + v46 = 2 * (int)((char *)v43 + 128 * v45); + v85 = v46 * 2; + v47 = pTerrainNormalIndices[v46 + 1]; + if ( v47 < 0 || v47 > (signed int)(uNumTerrainNormals - 1) ) + v48 = 0; + else + v48 = &pTerrainNormals[v47]; + v49 = v92 * v48->z; + v99 = v48; + thisg = 20.0 - (-v49 - v91 * v48->y - v90 * v48->x) * 20.0; + v50 = thisg + 6.7553994e15; + v40->field_58 = LOBYTE(v50); + if ( SLOBYTE(v50) < 0 ) + v40->field_58 = 0; + if ( pOutdoorCamera->numStru148s >= 1999 ) + return; + ++pOutdoorCamera->numStru148s; + if ( !sub_481FC9(a8, pVertices, v8, v40) ) + goto LABEL_77; + v51 = 1.0 / (a2->vWorldViewPosition.x + 0.0000001); + memcpy(array_50AC10, a2, 0x30u); + array_50AC10[0].flt_20 = v51; + array_50AC10[0].u = 0.0; + array_50AC10[0].v = 0.0; + v52 = a8->vWorldViewPosition.x + 0.0000001; + memcpy(&array_50AC10[1], a8, sizeof(array_50AC10[1])); + array_50AC10[1].flt_20 = 1.0 / v52; + array_50AC10[1].u = 0.0; + array_50AC10[1].v = 1.0; + v53 = pVertices->vWorldViewPosition.x + 0.0000001; + memcpy(&array_50AC10[2], pVertices, sizeof(array_50AC10[2])); + array_50AC10[2].flt_20 = 1.0 / v53; + array_50AC10[2].u = 1.0; + array_50AC10[2].v = 1.0; + + static stru154 static_sub_0048034E_stru_76D590; + /*static bool __init_flag2 = false; + if (!__init_flag2) + { + __init_flag2 = true; + + stru154::stru154(&static_sub_0048034E_stru_76D590); + }*/ + + v96 = pGame->pLightmapBuilder; + pGame->pLightmapBuilder->StackLights_TerrainFace(v99, (float *)&a4, array_50AC10, 3u, 0); + pDecalBuilder->_49BE8A(v40, *(float *)&v99, (int)&a4, array_50AC10, 3u, 0); + uNumVertices = 3; + if ( byte_4D864C && pGame->uFlags & 0x80 ) + { + thisb = pGame->pIndoorCameraD3D; + if ( pGame->pIndoorCameraD3D->_4371C3(array_50AC10, &uNumVertices, 0) == 1 && !uNumVertices ) + { +LABEL_77: + --pOutdoorCamera->numStru148s; + goto LABEL_112; + } + thisb->ViewTransform(array_50AC10, uNumVertices); + thisb->Project(array_50AC10, uNumVertices, 0); + } + this_3a = a2->vWorldViewPosition.x < 8.0 || a8->vWorldViewPosition.x < 8.0 || pVertices->vWorldViewPosition.x < 8.0; + v54 = (double)pOutdoorCamera->shading_dist_mist; + v108 = v54 < a2->vWorldViewPosition.x || v54 < a8->vWorldViewPosition.x || v54 < pVertices->vWorldViewPosition.x; + a8 = 0; + v96->std__vector_000004_size = 0; + if ( stru_F8AD28.uNumLightsApplied > 0 || pDecalBuilder->uNumDecals > 0 ) + { + a8 = (RenderVertexSoft *)(this_3a ? 3 : v108 != 0 ? 5 : 0); + static_sub_0048034E_stru_76D590._49B0C9(v99, *(float *)&a4); + if ( pDecalBuilder->uNumDecals > 0 ) + pDecalBuilder->ApplyDecals( + 31 - v40->field_58, + 4, + &static_sub_0048034E_stru_76D590, + uNumVertices, + array_50AC10, + 0, + (char)a8, + -1); + } + if ( stru_F8AD28.uNumLightsApplied > 0 ) + v96->ApplyLights( + &stru_F8AD28, + &static_sub_0048034E_stru_76D590, + uNumVertices, + array_50AC10, + 0, + (char)a8); + v55 = uNumVertices; + v35 = byte_4D864C == 0; + v40->uNumVertices = uNumVertices; + if ( v35 || !(pGame->uFlags & 0x80) ) + { + if ( this_3a ) + { + v56 = sr_424CD7(v55); + } + else + { + if ( !v108 ) + goto LABEL_105; + v56 = sr_424EE0_MakeFanFromTriangle(v55); + } + v40->uNumVertices = v56; + OutdoorCamera::Project(v56); + } +LABEL_105: + v57 = *(int *)&v40->flags; + if ( BYTE1(v57) & 1 ) + { + v40->_4811A3(); + } + else + { + if ( v57 & 2 && v40->uTileBitmapID == pRenderer->field_1036AC_bitmapid ) + { + v81 = 0; + v58 = pRenderer->pHDWaterBitmapIDs[pRenderer->field_1036A8_bitmapid]; + } + else + { + v58 = v40->uTileBitmapID; + v81 = 1; + } + pRenderer->DrawTerrainPolygon(v40->uNumVertices, v40, pBitmaps_LOD->pHardwareTextures[v58], 0, v81); + } +LABEL_112: + v59 = &array_77EC08[pOutdoorCamera->numStru148s]; + a8 = (RenderVertexSoft *)&array_77EC08[pOutdoorCamera->numStru148s]; + v60 = pOutdoor->GetTileTexture(sX, sY); + v59->uTileBitmapID = v60; + if ( v60 == -1 ) + goto LABEL_162; + *(int *)&v59->flags = pOutdoor->GetSomeOtherTileInfo(sX, sY); + v61 = v93; + v59->field_59 = 1; + v59->field_34 = v61->distance; + v59->field_5C = v89; + v59->field_5D = (char)_this; + v62 = *(unsigned __int16 *)((char *)pTerrainNormalIndices + v85); + if ( v62 > (signed int)(uNumTerrainNormals - 1) ) + v63 = 0; + else + v63 = &pTerrainNormals[v62]; + v64 = v92 * v63->z; + v99 = v63; + thish = 20.0 - (-v64 - v91 * v63->y - v90 * v63->x) * 20.0; + v65 = thish + 6.7553994e15; + v59->field_58 = LOBYTE(v65); + if ( SLOBYTE(v65) < 0 ) + v59->field_58 = 0; + if ( pOutdoorCamera->numStru148s >= 1999 ) + return; + ++pOutdoorCamera->numStru148s; + if ( !sub_481FC9(v101, a2, pVertices, v59) ) + { +LABEL_126: + --pOutdoorCamera->numStru148s; + goto LABEL_162; + } + v66 = 1.0 / (a2->vWorldViewPosition.x + 0.0000001); + memcpy(array_50AC10, a2, 0x30u); + array_50AC10[0].flt_20 = v66; + array_50AC10[0].u = 0.0; + array_50AC10[0].v = 0.0; + v67 = pVertices->vWorldViewPosition.x + 0.0000001; + memcpy(&array_50AC10[1], pVertices, sizeof(array_50AC10[1])); + array_50AC10[1].flt_20 = 1.0 / v67; + array_50AC10[1].u = 1.0; + array_50AC10[1].v = 1.0; + v68 = v101->vWorldViewPosition.x + 0.0000001; + memcpy(&array_50AC10[2], v101, sizeof(array_50AC10[2])); + array_50AC10[2].flt_20 = 1.0 / v68; + array_50AC10[2].u = 1.0; + array_50AC10[2].v = 0.0; + + static stru154 static_sub_0048034E_stru_76D578; + /*static bool __init_flag1 = false; + if (!__init_flag1) + { + __init_flag1 = true; + + stru154::stru154(&static_sub_0048034E_stru_76D578); + }*/ + + v96 = pGame->pLightmapBuilder; + pGame->pLightmapBuilder->StackLights_TerrainFace(v99, &v87, array_50AC10, 3u, 1); + pDecalBuilder->_49BE8A(v40, *(float *)&v99, (int)&v87, array_50AC10, 3u, 1); + v100 = 3; + if ( byte_4D864C && pGame->uFlags & 0x80 ) + { + thisc = pGame->pIndoorCameraD3D; + if ( pGame->pIndoorCameraD3D->_4371C3(array_50AC10, (unsigned int *)&v100, 0) == 1 && !v100 ) + goto LABEL_126; + thisc->ViewTransform(array_50AC10, v100); + thisc->Project(array_50AC10, v100, 0); + } + this_3b = a2->vWorldViewPosition.x < 8.0 + || pVertices->vWorldViewPosition.x < 8.0 + || v101->vWorldViewPosition.x < 8.0; + v69 = (double)pOutdoorCamera->shading_dist_mist; + v108 = v69 < a2->vWorldViewPosition.x || v69 < pVertices->vWorldViewPosition.x || v69 < v101->vWorldViewPosition.x; + LOBYTE(v70) = 0; + v96->std__vector_000004_size = 0; + if ( stru_F8AD28.uNumLightsApplied > 0 || pDecalBuilder->uNumDecals > 0 ) + { + if ( this_3b ) + LOBYTE(v70) = 3; + else + v70 = v108 != 0 ? 5 : 0; + static_sub_0048034E_stru_76D578._49B0C9(v99, v87); + if ( pDecalBuilder->uNumDecals > 0 ) + pDecalBuilder->ApplyDecals( + 31 - v40->field_58, + 4, + &static_sub_0048034E_stru_76D578, + v100, + array_50AC10, + 0, + v70, + -1); + } + if ( stru_F8AD28.uNumLightsApplied > 0 ) + v96->ApplyLights(&stru_F8AD28, &static_sub_0048034E_stru_76D578, v100, array_50AC10, 0, v70); + v71 = a8; + v72 = v100; + v35 = byte_4D864C == 0; + LODWORD(a8->vWorldViewPosition.z) = v100; + if ( !v35 && pGame->uFlags & 0x80 ) + goto LABEL_154; + if ( this_3b ) + { + v73 = sr_424CD7(v72); + } + else + { + if ( !v108 ) + { +LABEL_154: + v74 = v71[1].vWorldPosition.x; + if ( !(BYTE1(v74) & 1) ) + { + if ( LOBYTE(v74) & 2 && LOWORD(v71[1].vWorldViewProjY) == pRenderer->field_1036AC_bitmapid ) + { + v80 = 0; + v75 = pRenderer->pHDWaterBitmapIDs[pRenderer->field_1036A8_bitmapid]; + } + else + { + v75 = LOWORD(v71[1].vWorldViewProjY); + v80 = 1; + } + v79 = 0; + v78 = pBitmaps_LOD->pHardwareTextures[v75]; + v77 = (stru148 *)v71; + v76 = LODWORD(v71->vWorldViewPosition.z); + goto LABEL_161; + } + v38 = (stru148 *)v71; + goto LABEL_56; + } + v73 = sr_424EE0_MakeFanFromTriangle(v72); + } + LODWORD(v71->vWorldViewPosition.z) = v73; + OutdoorCamera::Project(v73); + goto LABEL_154; + } +} +// 47F44B: using guessed type int __stdcall WorldPosToGridCellX(int); +// 47F458: using guessed type int __stdcall WorldPosToGridCellZ(int); +// 4D864C: using guessed type char byte_4D864C; +// 76D5C0: using guessed type char static_sub_0048034E_byte_76D5C0__init_flag; + + + +//----- (00481212) -------------------------------------------------------- +void Render::DrawTerrainSW(int a1, int a2, int a3) +{ + int v3; // esi@1 + int v4; // ecx@1 + int v5; // ST10_4@1 + int v6; // edi@1 + int v7; // ebx@2 + int v8; // eax@2 + int v9; // eax@3 + RenderVertexSoft *v10; // edi@3 + RenderVertexSoft *v11; // ebx@4 + RenderVertexSoft *v12; // ecx@4 + float v13; // eax@6 + int v14; // eax@6 + double v15; // st7@6 + double v16; // st7@6 + stru148 *v17; // ebx@12 + unsigned __int16 v18; // ax@12 + int v19; // eax@13 + float v20; // ecx@13 + stru220 *v21; // eax@13 + int v22; // eax@13 + signed int v23; // eax@13 + Vec3_float_ *v24; // eax@15 + double v25; // st7@18 + double v26; // st5@24 + double v27; // st5@24 + double v28; // st5@24 + double v29; // st5@24 + Game *v30; // eax@25 + RenderVertexSoft *v31; // edi@29 + double v32; // st7@31 + int v33; // esi@35 + RenderVertexSoft *v34; // edx@36 + RenderVertexSoft *v35; // ecx@36 + signed int v36; // eax@39 + signed int v37; // esi@40 + stru148 *v38; // ebx@43 + unsigned __int16 v39; // ax@43 + int v40; // eax@44 + float v41; // ecx@44 + stru220 *v42; // eax@44 + int v43; // eax@44 + int v44; // eax@44 + signed int v45; // eax@44 + Vec3_float_ *v46; // eax@46 + double v47; // st7@49 + double v48; // st5@57 + double v49; // st5@57 + double v50; // st5@57 + Game *v51; // eax@58 + RenderVertexSoft *v52; // edi@62 + double v53; // st7@63 + int v54; // esi@66 + signed int v55; // eax@69 + signed int v56; // esi@71 + unsigned __int16 v57; // ax@75 + stru220 *v58; // eax@76 + signed int v59; // eax@76 + Vec3_float_ *v60; // eax@77 + double v61; // st7@80 + double v62; // st5@88 + double v63; // st5@88 + double v64; // st5@88 + Game *v65; // eax@89 + double v66; // st7@94 + RenderVertexSoft *v67; // [sp-Ch] [bp-C4h]@36 + stru148 *v68; // [sp-8h] [bp-C0h]@36 + int v69; // [sp-4h] [bp-BCh]@36 + float v70; // [sp+Ch] [bp-ACh]@88 + double v71; // [sp+10h] [bp-A8h]@6 + double v72; // [sp+18h] [bp-A0h]@82 + double v73; // [sp+20h] [bp-98h]@6 + double v74; // [sp+28h] [bp-90h]@51 + double v75; // [sp+30h] [bp-88h]@6 + double v76; // [sp+38h] [bp-80h]@20 + double v77; // [sp+40h] [bp-78h]@6 + float v78; // [sp+48h] [bp-70h]@57 + float v79; // [sp+4Ch] [bp-6Ch]@6 + float v80; // [sp+50h] [bp-68h]@6 + int v81; // [sp+54h] [bp-64h]@1 + int v82; // [sp+58h] [bp-60h]@6 + int v83; // [sp+5Ch] [bp-5Ch]@82 + int v84; // [sp+60h] [bp-58h]@20 + int v85; // [sp+64h] [bp-54h]@1 + int v86; // [sp+68h] [bp-50h]@1 + int v87; // [sp+6Ch] [bp-4Ch]@51 + float v88; // [sp+70h] [bp-48h]@51 + int v89; // [sp+74h] [bp-44h]@6 + int v90; // [sp+78h] [bp-40h]@1 + float a3a; // [sp+7Ch] [bp-3Ch]@24 + stru220 *v92; // [sp+80h] [bp-38h]@2 + float v93; // [sp+84h] [bp-34h]@44 + int v94; // [sp+88h] [bp-30h]@6 + float v95; // [sp+8Ch] [bp-2Ch]@1 + float v96; // [sp+90h] [bp-28h]@1 + float v97; // [sp+94h] [bp-24h]@1 + int X; // [sp+98h] [bp-20h]@1 + float v99; // [sp+9Ch] [bp-1Ch]@6 + int v100; // [sp+A0h] [bp-18h]@6 + unsigned __int64 v101; // [sp+A4h] [bp-14h]@6 + RenderVertexSoft *v102; // [sp+ACh] [bp-Ch]@6 + RenderVertexSoft *v103; // [sp+B0h] [bp-8h]@6 + RenderVertexSoft *v104; // [sp+B4h] [bp-4h]@3 + float pNormalc; // [sp+C0h] [bp+8h]@6 + float pNormald; // [sp+C0h] [bp+8h]@6 + Vec3_float_ *pNormal; // [sp+C0h] [bp+8h]@17 + Vec3_float_ *pNormala; // [sp+C0h] [bp+8h]@48 + Vec3_float_ *pNormalb; // [sp+C0h] [bp+8h]@77 + + v3 = a1; + //v4 = *(short *)(a3 + 4); + //v5 = *(short *)(a3 + 6); + v85 = a2; + v86 = *(_WORD *)(a3 + 4); //v4; + X = abs(*(_WORD *)(a3 + 6)); //v5 + v6 = 0; + v90 = 0; + v81 = v3 - 1; + v95 = (double)pOutdoor->vSunlight.x * 0.000015258789; + v96 = (double)pOutdoor->vSunlight.y * 0.000015258789; + v97 = (double)pOutdoor->vSunlight.z * 0.000015258789; + if ( v3 - 1 > 0 ) + { + while ( 1 ) + { + v7 = abs(X); + v8 = abs(v86); + --X; + v92 = &stru_76E5C8[(v7 << 7) + v8]; + if ( !v92->field_0 + || ((v9 = v6, v10 = &pVerticesSR_806210[v6], v104 = v10, !v85) ? (v11 = &pVerticesSR_801A10[v9], + v12 = &pVerticesSR_806210[v9 + 1]) : (v11 = &pVerticesSR_806210[v9 + 1], v12 = &pVerticesSR_801A10[v9]), + ((v103 = &pVerticesSR_801A10[v9 + 1], + v13 = v10->vWorldPosition.x, + v102 = v12, + v80 = v13, + v73 = v13 + 6.7553994e15, + v101 = __PAIR__((unsigned int)v11, LODWORD(v73)), + v79 = v10->vWorldPosition.y, + v75 = v79 + 6.7553994e15, + v100 = LODWORD(v75), + pNormalc = (v12->vWorldPosition.x + v10->vWorldPosition.x) * 0.5, + v71 = pNormalc + 6.7553994e15, + v89 = LODWORD(v71), + v14 = WorldPosToGridCellX(COERCE_UNSIGNED_INT64(pNormalc + 6.7553994e15)), + v15 = v11->vWorldPosition.y + v10->vWorldPosition.y, + v94 = v14, + pNormald = v15 * 0.5, + v16 = pNormald + 6.7553994e15, + v77 = v16, + v82 = LODWORD(v77), + LODWORD(v99) = WorldPosToGridCellZ(LODWORD(v16)), + WorldPosToGridCellX(v101), + WorldPosToGridCellZ(v100), + !byte_4D864C) + || !(pGame->uFlags & 0x80)) + && !sub_481EFA(v10, v11, v102, v103, 1)) ) + goto LABEL_105; + if ( v10->vWorldPosition.z != v11->vWorldPosition.z + || v11->vWorldPosition.z != v103->vWorldPosition.z + || v103->vWorldPosition.z != v102->vWorldPosition.z ) + break; + v17 = &array_77EC08[pOutdoorCamera->numStru148s]; + v18 = pOutdoor->GetTileTexture(v101, v100); + v17->uTileBitmapID = v18; + if ( v18 != -1 ) + { + v19 = pOutdoor->GetSomeOtherTileInfo(v101, v100); + LOWORD(v19) = v19 | 0x8010; + v20 = v99; + *(int *)&v17->flags = v19; + v21 = v92; + v17->field_59 = 1; + v17->field_5D = LOBYTE(v20); + v17->field_34 = v21->distance; + v22 = v94; + v17->field_5C = v94; + v23 = pTerrainNormalIndices[2 * (LODWORD(v20) + (v22 << 7)) + 1]; + if ( v23 < 0 || v23 > (signed int)(uNumTerrainNormals - 1) ) + v24 = 0; + else + v24 = &pTerrainNormals[v23]; + pNormal = v24; + if ( v24 ) + { + v25 = -(v97 * v24->z + v96 * v24->y + v95 * v24->x); + if ( v25 < 0.0 ) + v25 = 0.0; + v99 = v25 * 31.0; + v76 = v99 + 6.7553994e15; + v84 = LODWORD(v76); + v17->field_58 = 31 - LOBYTE(v76); + } + else + { + v17->field_58 = 0; + } + if ( pOutdoorCamera->numStru148s >= 1999 ) + return; + ++pOutdoorCamera->numStru148s; + if ( !sub_481FC9(v10, (RenderVertexSoft *)HIDWORD(v101), v102, v17) ) + goto LABEL_104; + v26 = 1.0 / (v104->vWorldViewPosition.x + 0.0000001); + memcpy(array_50AC10, v104, 0x30u); + array_50AC10[0].flt_20 = v26; + array_50AC10[0].u = 0.0; + array_50AC10[0].v = 0.0; + v27 = *(float *)(HIDWORD(v101) + 12) + 0.0000001; + memcpy(&array_50AC10[1], (void *)HIDWORD(v101), sizeof(array_50AC10[1])); + array_50AC10[1].flt_20 = 1.0 / v27; + array_50AC10[1].u = 0.0; + array_50AC10[1].v = 1.0; + v28 = v103->vWorldViewPosition.x + 0.0000001; + memcpy(&array_50AC10[2], v103, sizeof(array_50AC10[2])); + array_50AC10[2].flt_20 = 1.0 / v28; + array_50AC10[2].u = 1.0; + array_50AC10[2].v = 1.0; + v29 = v102->vWorldViewPosition.x + 0.0000001; + memcpy(&array_50AC10[3], v102, sizeof(array_50AC10[3])); + array_50AC10[3].flt_20 = 1.0 / v29; + array_50AC10[3].u = 1.0; + array_50AC10[3].v = 0.0; + pGame->pLightmapBuilder->StackLights_TerrainFace(pNormal, &a3a, array_50AC10, 4u, 1); + if ( stru_F8AD28.uNumLightsApplied <= 0 ) + { + v17->field_108 = 0; + } + else + { + v30 = pGame; + v17->field_108 = 1; + pGame->pLightmapBuilder->_45CA88(&stru_F8AD28, array_50AC10, 4, pNormal); + } + if ( v104->vWorldViewPosition.x < 8.0 + || *(float *)(HIDWORD(v101) + 12) < 8.0 + || (v31 = v102, v102->vWorldViewPosition.x < 8.0) + || v103->vWorldViewPosition.x < 8.0 ) + { + v36 = sr_4250FE(4u); + } + else + { + v32 = (double)pOutdoorCamera->shading_dist_mist; + if ( v32 >= v104->vWorldViewPosition.x + && v32 >= *(float *)(HIDWORD(v101) + 12) + && v32 >= v102->vWorldViewPosition.x + && v32 >= v103->vWorldViewPosition.x ) + { + v33 = sr_4254D2(4); + v17->uNumVertices = v33; + if ( !v33 ) + goto LABEL_104; + v34 = (RenderVertexSoft *)HIDWORD(v101); + v35 = v104; + v69 = 0; + v68 = v17; + v67 = v31; + goto LABEL_37; + } + v36 = sr_4252E8(4u); + } + v37 = v36; + if ( !v36 ) + goto LABEL_104; +LABEL_41: + OutdoorCamera::Project(v37); +LABEL_102: + v33 = sr_4254D2(v37); + v17->uNumVertices = v33; + if ( !v33 ) + goto LABEL_104; + v17->_48276F_sr(); + goto LABEL_38; + } +LABEL_105: + v6 = v90++ + 1; + if ( v90 >= v81 ) + return; + } + v38 = &array_77EC08[pOutdoorCamera->numStru148s]; + v39 = pOutdoor->GetTileTexture(v101, v100); + v38->uTileBitmapID = v39; + if ( v39 == -1 ) + goto LABEL_105; + v40 = pOutdoor->GetSomeOtherTileInfo(v101, v100); + BYTE1(v40) |= 0x80u; + v41 = v99; + *(int *)&v38->flags = v40; + v42 = v92; + v38->field_59 = 1; + v38->field_5D = LOBYTE(v41); + v38->field_34 = v42->distance; + v43 = v94; + v38->field_5C = v94; + v44 = 2 * (LODWORD(v41) + (v43 << 7)); + LODWORD(v93) = v44 * 2; + v45 = pTerrainNormalIndices[v44 + 1]; + if ( v45 < 0 || v45 > (signed int)(uNumTerrainNormals - 1) ) + v46 = 0; + else + v46 = &pTerrainNormals[v45]; + pNormala = v46; + if ( v46 ) + { + v47 = -(v97 * v46->z + v96 * v46->y + v95 * v46->x); + if ( v47 < 0.0 ) + v47 = 0.0; + v88 = v47 * 31.0; + v74 = v88 + 6.7553994e15; + v87 = LODWORD(v74); + v38->field_58 = 31 - LOBYTE(v74); + } + else + { + v38->field_58 = 0; + } + if ( v38->field_58 < 0 ) + v38->field_58 = 0; + if ( pOutdoorCamera->numStru148s >= 1999 ) + return; + ++pOutdoorCamera->numStru148s; + if ( !sub_481FC9((RenderVertexSoft *)HIDWORD(v101), v103, v104, v38) ) + goto LABEL_74; + v48 = 1.0 / (v104->vWorldViewPosition.x + 0.0000001); + memcpy(array_50AC10, v104, 0x30u); + array_50AC10[0].flt_20 = v48; + array_50AC10[0].u = 0.0; + array_50AC10[0].v = 0.0; + v49 = *(float *)(HIDWORD(v101) + 12) + 0.0000001; + memcpy(&array_50AC10[1], (void *)HIDWORD(v101), sizeof(array_50AC10[1])); + array_50AC10[1].flt_20 = 1.0 / v49; + array_50AC10[1].u = 0.0; + array_50AC10[1].v = 1.0; + v50 = v103->vWorldViewPosition.x + 0.0000001; + memcpy(&array_50AC10[2], v103, sizeof(array_50AC10[2])); + array_50AC10[2].flt_20 = 1.0 / v50; + array_50AC10[2].u = 1.0; + array_50AC10[2].v = 1.0; + pGame->pLightmapBuilder->StackLights_TerrainFace(pNormala, &v78, array_50AC10, 3u, 0); + if ( stru_F8AD28.uNumLightsApplied <= 0 ) + { + v38->field_108 = 0; + } + else + { + v51 = pGame; + v38->field_108 = 1; + pGame->pLightmapBuilder->_45CA88(&stru_F8AD28, array_50AC10, 3, pNormala); + } + if ( v104->vWorldViewPosition.x < 8.0 + || *(float *)(HIDWORD(v101) + 12) < 8.0 + || (v52 = v103, v103->vWorldViewPosition.x < 8.0) ) + { + v55 = sr_4250FE(3u); + } + else + { + v53 = (double)pOutdoorCamera->shading_dist_mist; + if ( v53 >= v104->vWorldViewPosition.x + && v53 >= *(float *)(HIDWORD(v101) + 12) + && v53 >= v103->vWorldViewPosition.x ) + { + v54 = sr_4254D2(3); + v38->uNumVertices = v54; + if ( v54 ) + { + sr_sub_4829B9((RenderVertexSoft *)HIDWORD(v101), v52, v104, v38, 0); +LABEL_68: + sr_sub_481DB2(array_508690, v54, v38); +LABEL_75: + v17 = &array_77EC08[pOutdoorCamera->numStru148s]; + v57 = pOutdoor->GetTileTexture(v101, v100); + v17->uTileBitmapID = v57; + if ( v57 == -1 ) + goto LABEL_105; + *(int *)&v17->flags = pOutdoor->GetSomeOtherTileInfo(v101, v100); + v58 = v92; + v17->field_59 = 1; + v17->field_34 = v58->distance; + v17->field_5C = v94; + v17->field_5D = LOBYTE(v99); + v59 = *(unsigned __int16 *)((char *)pTerrainNormalIndices + LODWORD(v93)); + if ( v59 > (signed int)(uNumTerrainNormals - 1) ) + { + pNormalb = 0; + v60 = 0; + } + else + { + v60 = &pTerrainNormals[v59]; + pNormalb = v60; + } + if ( v60 ) + { + v61 = -(v97 * v60->z + v96 * v60->y + v95 * v60->x); + if ( v61 < 0.0 ) + v61 = 0.0; + v93 = v61 * 31.0; + v72 = v93 + 6.7553994e15; + v83 = LODWORD(v72); + v17->field_58 = 31 - LOBYTE(v72); + } + else + { + v17->field_58 = 0; + } + if ( v17->field_58 < 0 ) + v17->field_58 = 0; + if ( pOutdoorCamera->numStru148s >= 1999 ) + return; + ++pOutdoorCamera->numStru148s; + if ( !sub_481FC9(v102, v104, v103, v17) ) + { +LABEL_104: + --pOutdoorCamera->numStru148s; + goto LABEL_105; + } + v62 = 1.0 / (v104->vWorldViewPosition.x + 0.0000001); + memcpy(array_50AC10, v104, 0x30u); + array_50AC10[0].flt_20 = v62; + array_50AC10[0].u = 0.0; + array_50AC10[0].v = 0.0; + v63 = v103->vWorldViewPosition.x + 0.0000001; + memcpy(&array_50AC10[1], v103, sizeof(array_50AC10[1])); + array_50AC10[1].flt_20 = 1.0 / v63; + array_50AC10[1].u = 1.0; + array_50AC10[1].v = 1.0; + v64 = v102->vWorldViewPosition.x + 0.0000001; + memcpy(&array_50AC10[2], v102, sizeof(array_50AC10[2])); + array_50AC10[2].flt_20 = 1.0 / v64; + array_50AC10[2].u = 1.0; + array_50AC10[2].v = 0.0; + pGame->pLightmapBuilder->StackLights_TerrainFace(pNormalb, &v70, array_50AC10, 3u, 1); + if ( stru_F8AD28.uNumLightsApplied <= 0 ) + { + v17->field_108 = 0; + } + else + { + v65 = pGame; + v17->field_108 = 1; + pGame->pLightmapBuilder->_45CA88(&stru_F8AD28, array_50AC10, 3, pNormalb); + } + if ( v104->vWorldViewPosition.x < 8.0 || v103->vWorldViewPosition.x < 8.0 || v102->vWorldViewPosition.x < 8.0 ) + { + v37 = sr_4250FE(3u); + OutdoorCamera::Project(v37); + if ( !v37 ) + goto LABEL_104; + goto LABEL_102; + } + v66 = (double)pOutdoorCamera->shading_dist_mist; + if ( v66 < v104->vWorldViewPosition.x || v66 < v103->vWorldViewPosition.x || v66 < v102->vWorldViewPosition.x ) + { + v37 = sr_4252E8(3u); + if ( !v37 ) + goto LABEL_105; + goto LABEL_41; + } + v33 = sr_4254D2(3); + v17->uNumVertices = v33; + if ( !v33 ) + goto LABEL_104; + v34 = v104; + v35 = v102; + v69 = 0; + v68 = v17; + v67 = v103; +LABEL_37: + sr_sub_4829B9(v35, v34, v67, v68, v69); +LABEL_38: + sr_sub_481DB2(array_508690, v33, v17); + goto LABEL_105; + } + goto LABEL_74; + } + v55 = sr_4252E8(3u); + } + v56 = v55; + if ( v55 ) + { + OutdoorCamera::Project(v55); + v54 = sr_4254D2(v56); + v38->uNumVertices = v54; + if ( v54 ) + { + v38->_48276F_sr(); + goto LABEL_68; + } + } +LABEL_74: + --pOutdoorCamera->numStru148s; + goto LABEL_75; + } +} +// 47F44B: using guessed type int __stdcall WorldPosToGridCellX(int); +// 47F458: using guessed type int __stdcall WorldPosToGridCellZ(int); +// 4D864C: using guessed type char byte_4D864C; + + +//----- (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.uParentBillboardID = -1; + billboard.pTarget = pRenderer->pTargetSurface; + billboard.pTargetZ = pRenderer->pActiveZBuffer; + billboard.uTargetPitch = pRenderer->uTargetSurfacePitch; + billboard.uViewportX = pViewport->uViewportX; + billboard.uViewportY = pViewport->uViewportY; + billboard.uViewportZ = pViewport->uViewportZ - 1; + billboard.uViewportW = pViewport->uViewportW; + v0 = 0; + pOutdoorCamera->uNumBillboards = uNumBillboardsToDraw; + v16 = 0; + if ( (signed int)uNumBillboardsToDraw > 0 ) + { + v17 = 0; + v1 = (char *)&pBillboardRenderList[0].uScreenSpaceY; + do + { + billboard.uScreenSpaceX = *((short *)v1 - 1); + v2 = *((short *)v1 - 5); + billboard.uScreenSpaceY = *(short *)v1; + v3 = *((int *)v1 - 10); + billboard.uParentBillboardID = v0; + v4 = *((int *)v1 + 1); + billboard.field_10 = v3; + v5 = *((int *)v1 - 9); + billboard.uTintColor = v4; + v6 = *((short *)v1 - 8); + billboard.field_14 = v5; + v7 = *((int *)v1 - 6); + billboard.sZValue = *((int *)v1 - 6); + billboard.uFlags = v2; + if ( v6 != -1 ) + { + v8 = *((short *)v1 + 1); + if ( pRenderer->pRenderD3D ) + { + billboard.sZValue = v7; + billboard.uFlags = v2; + pRenderer->TransformBillboard( + &billboard, + &pSprites_LOD->pHardwareSprites[v6], + v8, + (RenderBillboard *)(v1 - 40)); + } + else + { + if ( *(v1 - 10) & 2 ) + v9 = PaletteManager::Get_Dark_or_Red_LUT(*((short *)v1 - 7), 0, 1); + else + v9 = GetBillboardPalette((RenderBillboard *)(v1 - 40), *((short *)v1 - 7), v7, *((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 ) + { + v11 = GetTickCount(); + v12 = stru_5C6E00->SinCos(v17 + v11); + 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]._4ACC38(&billboard, 1); + } + } + v17 += 5; + v0 = v16 + 1; + v1 += 52; + ++v16; + } + while ( v16 < (signed int)uNumBillboardsToDraw ); + } +} + + +//----- (0047AF11) -------------------------------------------------------- +void Render::DrawLayingItems_Shooting_Magic_ODM() +{ + char *v0; // edi@2 + ObjectDesc *v1; // ebx@4 + __int16 v2; // cx@5 + RenderBillboard *v3; // esi@10 + SpriteFrame *v4; // eax@10 + SpriteFrame *v5; // ebx@10 + unsigned int v6; // eax@10 + int v7; // ecx@10 + int v8; // edx@10 + int v9; // ecx@10 + unsigned __int16 v10; // ax@10 + int *v11; // eax@14 + int v12; // eax@22 + int v13; // ST3C_4@23 + int v14; // eax@23 + int v15; // ecx@23 + int v16; // ebx@23 + int v17; // ecx@25 + int v18; // eax@25 + int v19; // ST40_4@26 + int v20; // ecx@26 + int v21; // ST44_4@28 + int v22; // ST3C_4@29 + signed __int64 v23; // qtt@30 + int v24; // ebx@30 + int v25; // ST3C_4@30 + int v26; // eax@31 + char v27; // zf@31 + SpriteFrame *v28; // [sp+Ch] [bp-34h]@10 + __int16 a5; // [sp+10h] [bp-30h]@10 + int v30; // [sp+14h] [bp-2Ch]@23 + int v31; // [sp+14h] [bp-2Ch]@29 + __int16 v32; // [sp+14h] [bp-2Ch]@30 + int v33; // [sp+18h] [bp-28h]@23 + int v34; // [sp+18h] [bp-28h]@26 + int v35; // [sp+18h] [bp-28h]@30 + int v36; // [sp+1Ch] [bp-24h]@10 + int v37; // [sp+1Ch] [bp-24h]@23 + int a6; // [sp+20h] [bp-20h]@10 + int a6a; // [sp+20h] [bp-20h]@23 + int v40; // [sp+24h] [bp-1Ch]@25 + signed int v41; // [sp+28h] [bp-18h]@1 + 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; + if ( (signed int)uNumLayingItems > 0 ) + { + v0 = (char *)&pLayingItems[0].uSectorID; + do + { + if ( *((short *)v0 - 13) ) + { + v1 = &pObjectList->pObjects[*((short *)v0 - 13)]; + if ( !(v1->uFlags & 1) ) + { + if ( ((v2 = *((short *)v0 - 14), v2 < 1000) || v2 >= 10000) && (v2 < 500 || v2 >= 600) + || pGame->pStru6Instance->_4A81CA((LayingItem *)(v0 - 28)) ) + { + a5 = *(short *)v0; + x = *((int *)v0 - 6); + y = *((int *)v0 - 5); + z = *((int *)v0 - 4); + v3 = &pBillboardRenderList[uNumBillboardsToDraw]; + v4 = pSpriteFrameTable->GetFrame(v1->uSpriteID, *((short *)v0 + 1)); + v5 = v4; + v28 = v4; + v36 = v4->uFlags; + a6 = v4->uGlowRadius * *((short *)v0 + 3); + v6 = stru_5C6E00->Atan2( + *((int *)v0 - 6) - pIndoorCamera->pos.x, + *((int *)v0 - 5) - pIndoorCamera->pos.y); + LOWORD(v7) = *((short *)v0 - 3); + v8 = v36; + v9 = ((signed int)(stru_5C6E00->uIntegerPi + ((signed int)stru_5C6E00->uIntegerPi >> 3) + v7 - v6) >> 8) & 7; + v10 = v5->pHwSpriteIDs[v9]; + v3->uHwSpriteID = v10; + if ( v36 & 0x20 ) + { + v8 = v36; + z -= (signed int)((unsigned __int64)(v5->scale + * (signed __int64)pSprites_LOD->pSpriteHeaders[(signed __int16)v10].uHeight) >> 16) >> 1; + } + v46 = 0; + if ( v8 & 2 ) + v46 = 2; + v11 = (int *)(256 << v9); + if ( (256 << v9) & v8 ) + v46 |= 4u; + if ( v8 & 0x40000 ) + v46 |= 0x40u; + if ( v8 & 0x20000 ) + LOBYTE(v46) = v46 | 0x80; + if ( a6 ) + { + LOBYTE(v11) = byte_4E94D3; + pMobileLightsStack->AddLight(x, y, z, a5, a6, 0xFFu, 0xFFu, 0xFFu, byte_4E94D3); + } + v12 = (x - pIndoorCamera->pos.x) << 16; + if ( pIndoorCamera->sRotationX ) + { + v13 = (y - pIndoorCamera->pos.y) << 16; + v30 = ((unsigned __int64)(v12 * (signed __int64)pOutdoorCamera->camera_rotation_y_int_cosine) >> 16) + + ((unsigned __int64)(v13 * (signed __int64)pOutdoorCamera->camera_rotation_y_int_sine) >> 16); + v37 = (unsigned __int64)(v12 * (signed __int64)pOutdoorCamera->camera_rotation_y_int_sine) >> 16; + a6a = (unsigned __int64)(v13 * (signed __int64)pOutdoorCamera->camera_rotation_y_int_cosine) >> 16; + v33 = (z - pIndoorCamera->pos.z) << 16; + v14 = (unsigned __int64)(v30 * (signed __int64)pOutdoorCamera->camera_rotation_x_int_cosine) >> 16; + v15 = (unsigned __int64)(v33 * (signed __int64)pOutdoorCamera->camera_rotation_x_int_sine) >> 16; + v16 = v15 + v14; + v42 = v15 + v14; + if ( v15 + v14 >= 262144 && v16 <= pOutdoorCamera->shading_dist_mist << 16 ) + { + v17 = a6a - v37; + v40 = a6a - v37; + v18 = ((unsigned __int64)(v33 * (signed __int64)pOutdoorCamera->camera_rotation_x_int_cosine) >> 16) + - ((unsigned __int64)(v30 * (signed __int64)pOutdoorCamera->camera_rotation_x_int_sine) >> 16); + goto LABEL_29; + } + } + else + { + v34 = (y - pIndoorCamera->pos.y) << 16; + v19 = (unsigned __int64)(v12 * (signed __int64)pOutdoorCamera->camera_rotation_y_int_cosine) >> 16; + v20 = (unsigned __int64)(v34 * (signed __int64)pOutdoorCamera->camera_rotation_y_int_sine) >> 16; + v16 = v20 + v19; + v42 = v20 + v19; + if ( v20 + v19 >= 262144 && v16 <= pOutdoorCamera->shading_dist_mist << 16 ) + { + v21 = (unsigned __int64)(((x - pIndoorCamera->pos.x) << 16) + * (signed __int64)pOutdoorCamera->camera_rotation_y_int_sine) >> 16; + v17 = ((unsigned __int64)(v34 * (signed __int64)pOutdoorCamera->camera_rotation_y_int_cosine) >> 16) + - v21; + v40 = ((unsigned __int64)(v34 * (signed __int64)pOutdoorCamera->camera_rotation_y_int_cosine) >> 16) + - v21; + v18 = (z - pIndoorCamera->pos.z) << 16; +LABEL_29: + v31 = v18; + v22 = abs(v17); + if ( abs(v16) >= v22 ) + { + LODWORD(v23) = 0; + HIDWORD(v23) = SLOWORD(pOutdoorCamera->int_fov_rad); + v24 = v23 / v42; + v25 = v23 / v42; + LODWORD(v23) = 0; + HIDWORD(v23) = SLOWORD(pOutdoorCamera->int_fov_rad); + v35 = pViewport->uScreenCenterX + - ((signed int)(((unsigned __int64)(v25 * (signed __int64)v40) >> 16) + 32768) >> 16); + v32 = LOWORD(pViewport->uScreenCenterY) + - (((unsigned int)((unsigned __int64)(v23 / v42 * v31) >> 16) + 32768) >> 16); + if ( (signed int)uNumBillboardsToDraw >= 500 ) + return; + ++uNumBillboardsToDraw; + ++uNumSpritesDrawnThisFrame; + *(v0 - 2) |= 1u; + v3->uPalette = v28->uPaletteIndex; + v3->uIndoorSectorID = a5; + v3->field_0 = (unsigned __int64)(v28->scale * (signed __int64)v24) >> 16; + v26 = (unsigned __int64)(v28->scale * (signed __int64)v24) >> 16; + v3->pSpriteFrame = v28; + v3->field_4 = v26; + v3->field_1E = v46; + v3->some_x = x; + v3->some_y = y; + v3->some_z = z; + v3->uScreenSpaceX = v35; + v3->uScreenSpaceY = v32; + HIWORD(v26) = HIWORD(v42); + LOWORD(v26) = 0; + v27 = (*(v0 - 2) & 0x20) == 0; + v3->sZValue = v26 + (8 * v41 | 2); + v3->uPaletteSubindex = 0; + v3->uTintColor = 0; + if ( !v27 ) + { + if ( !pRenderer->pRenderD3D ) + v3->sZValue = 0; + } + } + goto LABEL_34; + } + } + } + } + } +LABEL_34: + ++v41; + v0 += 112; + } + while ( v41 < (signed int)uNumLayingItems ); + } +} +// 4E94D3: using guessed type char byte_4E94D3; +// 5187E4: using guessed type int 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 + IUnknown *v6; // eax@10 + size_t v7; // eax@13 + DDDEVICEIDENTIFIER ddDevId; // [sp+4h] [bp-4F8h]@11 + DDSURFACEDESC2 v10;/*int v10; // [sp+42Ch] [bp-D0h]@16 + int v11; // [sp+430h] [bp-CCh]@16 + int v12; // [sp+434h] [bp-C8h]@16 + int v13; // [sp+438h] [bp-C4h]@16 + int v14; // [sp+474h] [bp-88h]@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 v19; // [sp+4C8h] [bp-34h]@16 + RenderD3D_D3DDevDesc v20; // [sp+4CCh] [bp-30h]@1 + LPDIRECTDRAW pDirectDraw; // [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, 0x10u); + } + else + { + v20.pGUID = 0; + } + + if (FAILED(DirectDrawCreate(v20.pGUID, &pDirectDraw, 0))) + { + delete [] v20.pDriverName; + delete [] v20.pDeviceDesc; + if ( v20.pGUID ) + delete v20.pGUID; + } + else + { + if (FAILED(pDirectDraw->QueryInterface(IID_IDirectDraw4, (LPVOID *)&pDirectDraw4))) + { + delete [] v20.pDriverName; + delete [] v20.pDeviceDesc; + if ( v20.pGUID ) + delete v20.pGUID; + v6 = (IUnknown *)pDirectDraw; + } + else + { + pDirectDraw->Release(); + if (FAILED( pDirectDraw4->GetDeviceIdentifier(&ddDevId, 1u))) + { + v20.pDDraw4DevDesc = 0; + } + else + { + v7 = strlen(ddDevId.szDescription); + v20.pDDraw4DevDesc = new char[v7 + 1]; + strcpy(v20.pDDraw4DevDesc, ddDevId.szDescription); + } + memset(&ddsCaps, 0, 0x10u); + if (FAILED(pDirectDraw4->GetAvailableVidMem( + &ddsCaps, + (LPDWORD)&v20.uVideoMem, + (LPDWORD)&uFreeVideoMem))) + v20.uVideoMem = 0; + memset(&v10, 0, 0x7Cu); + v10.dwSize = 124; + v10.dwFlags = 6; + v10.dwHeight = 640; + v10.dwWidth = 480; + v10.ddpfPixelFormat.dwSize = 32; + + v19 = 0; + if ( FAILED(pDirectDraw4->EnumDisplayModes( + 0, + 0, + &v19, + (LPDDENUMMODESCALLBACK2)DDrawDisplayModesEnumerator)) + || !v19 + || FAILED(pDirectDraw4->QueryInterface(IID_IDirect3D3, (LPVOID *)&pDirect3D3))) + { + delete [] v20.pDriverName; + delete [] v20.pDeviceDesc; + if ( v20.pDDraw4DevDesc ) + free(v20.pDDraw4DevDesc); + if ( v20.pGUID ) + delete v20.pGUID; + v6 = (IUnknown *)pDirectDraw4; + } + else + { + aux.pInfo = pOut; + aux.ptr_4 = &v20; + pDirect3D3->EnumDevices((LPD3DENUMDEVICESCALLBACK)D3DDeviceEnumerator, &aux); + delete [] v20.pDriverName; + delete [] v20.pDeviceDesc; + if ( v20.pDDraw4DevDesc ) + free(v20.pDDraw4DevDesc); + if ( v20.pGUID ) + delete v20.pGUID; + pDirectDraw4->Release(); + v6 = (IUnknown *)pDirect3D3; + pDirectDraw4 = 0; + } + } + v6->Release(); + } + return 1; +} + + +//----- (0049D784) -------------------------------------------------------- +HRESULT __stdcall D3DDeviceEnumerator(const GUID *lpGUID, const char *lpDeviceDesc, const char *lpDeviceName, D3DDEVICEDESC *pHWDesc, D3DDEVICEDESC *pSWDesc, RenderD3D_aux *a6) +{ + int v6; // eax@1 + signed int v7; // edi@1 + signed int v8; // edi@14 + size_t v9; // eax@30 + size_t v10; // eax@30 + size_t v11; // eax@30 + size_t v12; // eax@30 + size_t v13; // eax@30 + + v6 = pHWDesc->dwFlags; + v7 = -1; + if ( v6 ) + { + if ( !a6->ptr_4->pGUID ) + v7 = 0; + if ( v6 && 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 ) + { + v8 = v7; + a6->pInfo[v8].bIsDeviceCompatible = 1; + a6->pInfo[v8].uCaps = 0; + if ( !(pHWDesc->dpcTriCaps.dwSrcBlendCaps & 0x10) ) + a6->pInfo[v8].uCaps |= 2u; + if ( !(pHWDesc->dpcTriCaps.dwSrcBlendCaps & 2) ) + a6->pInfo[v8].uCaps |= 4u; + if ( !(pHWDesc->dpcTriCaps.dwSrcBlendCaps & 1) ) + a6->pInfo[v8].uCaps |= 8u; + if ( !(pHWDesc->dpcTriCaps.dwDestBlendCaps & 0x20) ) + a6->pInfo[v8].uCaps |= 0x10u; + if ( !(pHWDesc->dpcTriCaps.dwDestBlendCaps & 2) ) + a6->pInfo[v8].uCaps |= 0x20u; + if ( !(pHWDesc->dpcTriCaps.dwDestBlendCaps & 4) ) + a6->pInfo[v8].uCaps |= 0x40u; + if ( !(BYTE1(pHWDesc->dwDevCaps) & 0x10) ) + BYTE1(a6->pInfo[v8].uCaps) |= 1u; + if ( pHWDesc->dpcTriCaps.dwTextureCaps & 0x20 ) + LOBYTE(a6->pInfo[v8].uCaps) |= 0x80u; + v9 = strlen(lpDeviceName); + a6->pInfo[v8].pName = new char[v9 + 1]; + strcpy(a6->pInfo[v8].pName, lpDeviceName); + v10 = strlen(lpDeviceDesc); + a6->pInfo[v8].pDescription = new char[v10 + 1]; + strcpy(a6->pInfo[v8].pDescription, lpDeviceDesc); + a6->pInfo[v8].pGUID = (GUID *)operator new(0x10u); + memcpy(a6->pInfo[v8].pGUID, lpGUID, 0x10u); + v11 = strlen(a6->ptr_4->pDriverName); + a6->pInfo[v8].pDriverName = new char[v11 + 1]; + strcpy(a6->pInfo[v8].pDriverName, a6->ptr_4->pDriverName); + v12 = strlen(a6->ptr_4->pDeviceDesc); + a6->pInfo[v8].pDeviceDesc = new char[v12 + 1]; + strcpy(a6->pInfo[v8].pDeviceDesc, a6->ptr_4->pDeviceDesc); + v13 = strlen(a6->ptr_4->pDDraw4DevDesc); + a6->pInfo[v8].pDDraw4DevDesc = new char[v13 + 1]; + strcpy(a6->pInfo[v8].pDDraw4DevDesc, a6->ptr_4->pDDraw4DevDesc); + if ( a6->ptr_4->pGUID ) + { + a6->pInfo[v8].pDirectDrawGUID = new GUID; + memcpy(a6->pInfo[v8].pDirectDrawGUID, a6->ptr_4->pGUID, 0x10u); + } + else + { + a6->pInfo[v8].pDirectDrawGUID = 0; + } + a6->pInfo[v8].uVideoMem = a6->ptr_4->uVideoMem; + } + return 1; +} + + +//----- (0049D75C) -------------------------------------------------------- +HRESULT __stdcall DDrawDisplayModesEnumerator(DDSURFACEDESC2 *pSurfaceDesc, __int16 *a2) +{ + HRESULT result; // eax@3 + + if ( pSurfaceDesc->ddsCaps.dwCaps | 0x2000 && pSurfaceDesc->ddpfPixelFormat.dwRGBBitCount == 16 ) + { + *a2 = 1; + result = 0; + } + else + { + result = 1; + } + return result; +} + + + +//----- (0047A95E) -------------------------------------------------------- +void Render::DrawDecorations() +{ + char *v0; // esi@2 + DecorationDesc *v1; // ebx@6 + __int16 v2; // ax@6 + double v3; // st7@7 + int v4; // eax@9 + int v5; // edx@9 + unsigned int v6; // edi@9 + int v7; // eax@9 + SpriteFrame *v8; // eax@9 + SpriteFrame *v9; // edi@9 + unsigned __int16 *v10; // eax@9 + int v11; // ecx@9 + int v12; // 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 + int v23; // eax@30 + signed __int64 v24; // qtt@31 + int v25; // ebx@31 + int v26; // ecx@32 + RenderBillboard *v27; // eax@37 + __int16 v28; // dx@37 + __int16 v29; // cx@37 + int v30; // ecx@37 + int v31; // ebx@37 + Particle_ local_0; // [sp+Ch] [bp-98h]@7 + int x; // [sp+74h] [bp-30h]@9 + int y; // [sp+78h] [bp-2Ch]@9 + int v35; // [sp+7Ch] [bp-28h]@1 + int v36; // [sp+80h] [bp-24h]@9 + unsigned __int16 *v37; // [sp+84h] [bp-20h]@9 + int v38; // [sp+88h] [bp-1Ch]@9 + int v39; // [sp+8Ch] [bp-18h]@24 + int v40; // [sp+90h] [bp-14h]@24 + int v41; // [sp+94h] [bp-10h]@24 + int v42; // [sp+98h] [bp-Ch]@9 + int a5; // [sp+9Ch] [bp-8h]@9 + int b; // [sp+A0h] [bp-4h]@22 + + v35 = 0; + if ( (signed int)uNumLevelDecorations > 0 ) + { + v0 = (char *)&pLevelDecorations[0].vPosition.y; + do + { + if ( (!(*(v0 - 6) & 0x40) || ((LevelDecoration *)(v0 - 8))->_47A825()) && !(*(v0 - 6) & 0x20) ) + { + v1 = &pDecorationList->pDecorations[*((short *)v0 - 4)]; + v2 = v1->uFlags; + if ( (char)v2 >= 0 ) + { + if ( !(v2 & 0x22) ) + { + v4 = *((int *)v0 - 1); + v5 = *((int *)v0 + 1); + v6 = pMiscTimer->uTotalGameTimeElapsed; + y = *(int *)v0; + x = v4; + v36 = v5; + v7 = abs(v4 + y); + v8 = pSpriteFrameTable->GetFrame(v1->uSpriteID, v6 + v7); + v9 = v8; + v42 = v8->uFlags; + a5 = v8->uGlowRadius; + v10 = (unsigned __int16 *)stru_5C6E00->Atan2( + *((int *)v0 - 1) - pIndoorCamera->pos.x, + *(int *)v0 - pIndoorCamera->pos.y); + v11 = *((int *)v0 + 2); + v37 = v10; + v12 = v42; + v38 = 0; + v13 = ((signed int)(stru_5C6E00->uIntegerPi + + ((signed int)stru_5C6E00->uIntegerPi >> 3) + + v11 + - (signed int)v37) >> 8) & 7; + v37 = (unsigned __int16 *)v13; + if ( v42 & 2 ) + v38 = 2; + if ( (256 << v13) & v42 ) + v38 |= 4u; + if ( v12 & 0x40000 ) + v38 |= 0x40u; + if ( v12 & 0x20000 ) + LOBYTE(v38) = v38 | 0x80; + if ( a5 ) + { + if ( pRenderer->pRenderD3D && pRenderer->bUseColoredLights ) + { + v14 = v1->uColoredLightRed; + v15 = v1->uColoredLightGreen; + v16 = v1->uColoredLightBlue; + } + else + { + v16 = 255; + v14 = 255; + v15 = 255; + } + b = v16; + pStationaryLightsStack->AddLight( + x, + y, + v36 + v1->uDecorationHeight / 2, + a5, + v14, + v15, + v16, + byte_4E94D0); + } + v17 = (x - pIndoorCamera->pos.x) << 16; + if ( pIndoorCamera->sRotationX ) + { + v40 = (y - pIndoorCamera->pos.y) << 16; + v18 = ((unsigned __int64)(v17 * (signed __int64)pOutdoorCamera->camera_rotation_y_int_cosine) >> 16) + + ((unsigned __int64)(v40 * (signed __int64)pOutdoorCamera->camera_rotation_y_int_sine) >> 16); + v42 = v18; + b = (unsigned __int64)(v17 * (signed __int64)pOutdoorCamera->camera_rotation_y_int_sine) >> 16; + a5 = (unsigned __int64)(v40 * (signed __int64)pOutdoorCamera->camera_rotation_y_int_cosine) >> 16; + v40 = (v36 - pIndoorCamera->pos.z) << 16; + v41 = (unsigned __int64)(v40 * (signed __int64)pOutdoorCamera->camera_rotation_x_int_sine) >> 16; + v19 = (unsigned __int64)(v18 * (signed __int64)pOutdoorCamera->camera_rotation_x_int_cosine) >> 16; + v20 = v19 + ((unsigned __int64)(v40 * (signed __int64)pOutdoorCamera->camera_rotation_x_int_sine) >> 16); + v39 = v19 + ((unsigned __int64)(v40 * (signed __int64)pOutdoorCamera->camera_rotation_x_int_sine) >> 16); + if ( v20 >= 262144 && v20 <= pOutdoorCamera->shading_dist_mist << 16 ) + { + v21 = a5 - b; + v41 = a5 - b; + a5 = (unsigned __int64)(v42 * (signed __int64)pOutdoorCamera->camera_rotation_x_int_sine) >> 16; + b = (unsigned __int64)(v40 * (signed __int64)pOutdoorCamera->camera_rotation_x_int_cosine) >> 16; + v22 = ((unsigned __int64)(v40 * (signed __int64)pOutdoorCamera->camera_rotation_x_int_cosine) >> 16) - a5; +LABEL_30: + v42 = v22; + v40 = 2 * abs(v20); + v23 = abs(v21); + if ( v40 >= v23 ) + { + LODWORD(v24) = 0; + HIDWORD(v24) = SLOWORD(pOutdoorCamera->int_fov_rad); + a5 = v24 / v39; + v25 = pViewport->uScreenCenterX + - ((signed int)(((unsigned __int64)(v24 / v39 * v41) >> 16) + 32768) >> 16); + b = (unsigned __int64)(a5 * (signed __int64)v42) >> 16; + v41 = v24 / v39; + v40 = pViewport->uScreenCenterY + - ((signed int)(((unsigned __int64)(a5 * (signed __int64)v42) >> 16) + 32768) >> 16); + v42 = v9->scale; + v41 = (unsigned __int64)(v42 * v24 / v39) >> 16; + v37 = (unsigned __int16 *)&v9->pHwSpriteIDs[(int)v37]; + if ( pRenderer->pRenderD3D ) + { + v26 = v41; + v42 = pSprites_LOD->pHardwareSprites[(signed __int16)*v37].uBufferWidth >> 1; + b = (unsigned __int64)(v42 * (signed __int64)v41) >> 16; + } + else + { + v26 = v41; + v42 = pSprites_LOD->pSpriteHeaders[(signed __int16)*v37].uWidth >> 1; + b = (unsigned __int64)(v42 * (signed __int64)v41) >> 16; + } + if ( b + v25 >= (signed int)pViewport->uViewportX && v25 - b <= (signed int)pViewport->uViewportZ ) + { + if ( (signed int)uNumBillboardsToDraw >= 500 ) + return; + v27 = &pBillboardRenderList[uNumBillboardsToDraw++]; + ++uNumDecorationsDrawnThisFrame; + v27->uHwSpriteID = *v37; + v28 = v9->uPaletteIndex; + v27->field_0 = v26; + v27->field_4 = v26; + v29 = v38; + v27->uScreenSpaceX = v25; + HIBYTE(v29) |= 2u; + v27->uPalette = v28; + v27->field_1E = v29; + v27->some_x = x; + v27->some_y = y; + v27->some_z = v36; + v27->uScreenSpaceY = v40; + HIWORD(v30) = HIWORD(v39); + v31 = 8 * v35 | 5; + LOWORD(v30) = 0; + v27->uIndoorSectorID = 0; + v27->sZValue = v30 + v31; + v27->uPaletteSubindex = 0; + v27->pSpriteFrame = v9; + v27->uTintColor = 0; + } + } + goto LABEL_38; + } + } + else + { + v42 = (x - pIndoorCamera->pos.x) << 16; + v40 = (y - pIndoorCamera->pos.y) << 16; + b = (unsigned __int64)(v17 * (signed __int64)pOutdoorCamera->camera_rotation_y_int_cosine) >> 16; + a5 = (unsigned __int64)(v40 * (signed __int64)pOutdoorCamera->camera_rotation_y_int_sine) >> 16; + v20 = b + ((unsigned __int64)(v40 * (signed __int64)pOutdoorCamera->camera_rotation_y_int_sine) >> 16); + v39 = b + ((unsigned __int64)(v40 * (signed __int64)pOutdoorCamera->camera_rotation_y_int_sine) >> 16); + if ( v20 >= 262144 && v20 <= pOutdoorCamera->shading_dist_mist << 16 ) + { + a5 = (unsigned __int64)(v42 * (signed __int64)pOutdoorCamera->camera_rotation_y_int_sine) >> 16; + b = (unsigned __int64)(v40 * (signed __int64)pOutdoorCamera->camera_rotation_y_int_cosine) >> 16; + v21 = ((unsigned __int64)(v40 * (signed __int64)pOutdoorCamera->camera_rotation_y_int_cosine) >> 16) - a5; + v41 = ((unsigned __int64)(v40 * (signed __int64)pOutdoorCamera->camera_rotation_y_int_cosine) >> 16) - a5; + v22 = (v36 - pIndoorCamera->pos.z) << 16; + goto LABEL_30; + } + } + } + } + else + { + memset(&local_0, 0, 0x68u); + v3 = (double)*((signed int *)v0 - 1); + local_0.bFree = 1036; + local_0.uDiffuse = 0xFF3C1Eu; + local_0.x = v3; + local_0.y = (double)*(signed int *)v0; + local_0.z = (double)*((signed int *)v0 + 1); + local_0.flt_10 = 0.0; + local_0.flt_14 = 0.0; + local_0.flt_18 = 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); + } + } +LABEL_38: + ++v35; + v0 += 32; + } + while ( v35 < (signed int)uNumLevelDecorations ); + } +} +// 4E94D0: using guessed type char byte_4E94D0; +// 5187EC: using guessed type int uNumDecorationsDrawnThisFrame; + + +//----- (0049D717) -------------------------------------------------------- +HRESULT __stdcall D3DZBufferFormatEnumerator(DDPIXELFORMAT *Src, DDPIXELFORMAT *Dst) +{ + HRESULT v2; // esi@2 + + if ( Src->dwFlags & 0x400 | 0x2000 ) + { + v2 = 0; + if ( Src->dwRGBBitCount == 16 && !Src->dwRBitMask ) + goto LABEL_6; + if ( !Dst->dwSize ) + { + v2 = 1; +LABEL_6: + memcpy(Dst, Src, 0x20u); + return v2; + } + } + 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, 0xA0u); + DirectDrawEnumerateA((LPDDENUMCALLBACKA)RenderD3D__DeviceEnumerator, *pOutDevices); +} + + +//----- (0049DC58) -------------------------------------------------------- +RenderD3D::RenderD3D() +{ + RenderD3D *v1; // esi@1 + + v1 = this; + this->pHost = 0; + this->pDirect3D = 0; + this->pUnk = 0; + this->pBackBuffer = 0; + this->pFrontBuffer = 0; + this->pZBuffer = 0; + this->pDevice = 0; + this->pViewport = 0; + this->field_40 = 1; + this->field_44 = 10; + GetAvailableDevices(&this->pAvailableDevices); +} + +//----- (0049DC90) -------------------------------------------------------- +void RenderD3D::Release() +{ + RenderD3D *v1; // esi@1 + IDirectDraw4 *v2; // eax@2 + signed int v3; // edi@4 + IDirect3DViewport3 *v4; // eax@22 + IUnknown *v5; // eax@24 + IDirectDrawSurface4 *v6; // eax@26 + IDirect3DDevice3 *v7; // eax@28 + IDirect3D3 *v8; // eax@30 + IDirectDrawSurface4 *v9; // eax@32 + IDirectDrawSurface4 *v10; // eax@34 + IDirectDraw4 *v11; // eax@36 + + v1 = this; + if ( !this->bWindowed ) + { + v2 = this->pHost; + if ( v2 ) + { + v2->RestoreDisplayMode(); + v1->pHost->SetCooperativeLevel(v1->hWindow, 8u); + v1->pHost->FlipToGDISurface(); + } + } + v3 = 0; + do + { + if ( v1->pAvailableDevices[v3].pDriverName ) + { + free(v1->pAvailableDevices[v3].pDriverName); + v1->pAvailableDevices[v3].pDriverName = 0; + } + if ( v1->pAvailableDevices[v3].pDeviceDesc ) + { + free(v1->pAvailableDevices[v3].pDeviceDesc); + v1->pAvailableDevices[v3].pDeviceDesc = 0; + } + if ( v1->pAvailableDevices[v3].pDDraw4DevDesc ) + { + free(v1->pAvailableDevices[v3].pDDraw4DevDesc); + v1->pAvailableDevices[v3].pDDraw4DevDesc = 0; + } + if ( v1->pAvailableDevices[v3].pDirectDrawGUID ) + { + free(v1->pAvailableDevices[v3].pDirectDrawGUID); + v1->pAvailableDevices[v3].pDirectDrawGUID = 0; + } + if ( v1->pAvailableDevices[v3].pName ) + { + free(v1->pAvailableDevices[v3].pName); + v1->pAvailableDevices[v3].pName = 0; + } + if ( v1->pAvailableDevices[v3].pDescription ) + { + free(v1->pAvailableDevices[v3].pDescription); + v1->pAvailableDevices[v3].pDescription = 0; + } + if ( v1->pAvailableDevices[v3].pGUID ) + { + free(v1->pAvailableDevices[v3].pGUID); + v1->pAvailableDevices[v3].pGUID = 0; + } + ++v3; + } + while ( v3 < 4 ); + if ( v1->pAvailableDevices ) + { + free(v1->pAvailableDevices); + v1->pAvailableDevices = 0; + } + v4 = v1->pViewport; + if ( v4 ) + { + v4->Release(); + v1->pViewport = 0; + } + v5 = v1->pUnk; + if ( v5 ) + { + v5->Release(); + v1->pUnk = 0; + } + v6 = v1->pZBuffer; + if ( v6 ) + { + v6->Release(); + v1->pZBuffer = 0; + } + v7 = v1->pDevice; + if ( v7 ) + { + v7->Release(); + v1->pDevice = 0; + } + v8 = v1->pDirect3D; + if ( v8 ) + { + v8->Release(); + v1->pDirect3D = 0; + } + v9 = v1->pBackBuffer; + if ( v9 ) + { + v9->Release(); + v1->pBackBuffer = 0; + } + v10 = v1->pFrontBuffer; + if ( v10 ) + { + v10->Release(); + v1->pFrontBuffer = 0; + } + v11 = v1->pHost; + if ( v11 ) + { + v11->Release(); + v1->pHost = 0; + } +} + + +//----- (0049DE14) -------------------------------------------------------- +bool RenderD3D::CreateDevice(unsigned int uDeviceID, int bWindowed, HWND hWnd) +{ + //IDirectDraw4 *v8; // eax@12 + //IDirectDraw4 *v9; // eax@16 + //IDirectDraw4 *v10; // eax@20 + //IDirectDraw4 *v13; // eax@35 + const char *v23; // [sp-4h] [bp-DCh]@9 + const char *v24; // [sp-4h] [bp-DCh]@13 + const char *v25; // [sp-4h] [bp-DCh]@19 + 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 *v30; // [sp+C4h] [bp-14h]@18 + LPDIRECTDRAW lpDD; // [sp+C8h] [bp-10h]@1 + + this->bWindowed = bWindowed; + this->hWindow = hWnd; + + if (FAILED(DirectDrawCreate(pAvailableDevices[uDeviceID].pDirectDrawGUID, &lpDD, 0))) + { + sprintf(pErrorMessage, "Init - Failed to create DirectDraw interface.\n"); + return 0; + } + + 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 = 0; + + if (bWindowed && !pAvailableDevices[uDeviceID].pDirectDrawGUID) + { + if (FAILED(pHost->SetCooperativeLevel(hWnd, DDSCL_MULTITHREADED | DDSCL_NORMAL))) + { + v23 = "Init - Failed to set cooperative level.\n"; + sprintf(pErrorMessage, v23); +LABEL_65: + if (pHost) + { + pHost->Release(); + pHost = 0; + } + return 0; + } + memset(&ddsd2, 0, sizeof(DDSURFACEDESC2)); + ddsd2.dwSize = sizeof(DDSURFACEDESC2); + ddsd2.dwFlags = DDSD_CAPS; + ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + if ( !pHost->CreateSurface(&ddsd2, &pFrontBuffer, 0) ) + { + ddsd2.dwSize = sizeof(DDSURFACEDESC2); + pHost->GetDisplayMode(&ddsd2); + if ( ddsd2.ddpfPixelFormat.dwRGBBitCount != 16 ) + { + v24 = "Init - Desktop isn't in 16 bit mode.\n"; + goto LABEL_14; + } + + ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + ddsd2.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE; + ddsd2.dwWidth = 640; + ddsd2.dwHeight = 480; + if (pHost->CreateSurface(&ddsd2, &pBackBuffer, 0) ) + { + v24 = "Init - Failed to create back buffer.\n"; +LABEL_14: + sprintf(pErrorMessage, v24); + if (pFrontBuffer) + { + pFrontBuffer->Release(); + pFrontBuffer = 0; + } + goto LABEL_65; + } + if ( pHost->CreateClipper(0, &v30, 0) ) + { + v25 = "Init - Failed to create clipper.\n"; + goto LABEL_45; + } + v30->SetHWnd(0, hWnd); + pFrontBuffer->SetClipper(v30); + + v30->Release(); + v30 = 0; + + pHost->QueryInterface(IID_IDirect3D3, (LPVOID *)&pDirect3D); + + 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) ) + goto LABEL_21; + if ( uDeviceID == 2 || uDeviceID == 3 ) + ddsd2.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; + + if ( !pHost->CreateSurface(&ddsd2, &pZBuffer, 0) ) + { + 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; + } +LABEL_51: + sprintf(pErrorMessage, "Init - Failed to create D3D device.\n"); + if (pDirect3D) + { + pDirect3D->Release(); + pDirect3D = 0; + } + goto LABEL_59; + } +LABEL_48: + sprintf(pErrorMessage, "Init - Failed to attach z-buffer to back buffer.\n"); + if (pZBuffer) + { + pZBuffer->Release(); + pZBuffer = 0; + } + goto LABEL_61; + } + goto LABEL_44; + } +LABEL_36: + v23 = "Init - Failed to create front buffer.\n"; + sprintf(pErrorMessage, v23); + goto LABEL_65; + } + if ( uDeviceID == 1 ) + v26 = 1045; + else + v26 = 1041; + if (pHost->SetCooperativeLevel(hWnd, v26) ) + { + v23 = "Init - Failed to set cooperative level.\n"; + sprintf(pErrorMessage, v23); + goto LABEL_65; + } + if (pHost->SetDisplayMode(640u, 480u, 16u, 0, 0) ) + { + v23 = "Init - Failed to set display mode.\n"; + sprintf(pErrorMessage, v23); + goto LABEL_65; + } + + 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; + ddsd2.dwBackBufferCount = 1; + if ( pHost->CreateSurface(&ddsd2, &pFrontBuffer, 0) ) + goto LABEL_36; + //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))) + { + v25 = "Init - Failed to get D3D interface.\n"; + goto LABEL_45; + } + + 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) ) + { +LABEL_21: + v25 = "Init - Failed to enumerate Z buffer formats.\n"; + goto LABEL_45; + } + if ( uDeviceID == 2 || uDeviceID == 3 ) + BYTE1(ddsd2.ddsCaps.dwCaps) |= 8u; + //uDeviceIDa = &pZBuffer; + if (pHost->CreateSurface(&ddsd2, &pZBuffer, 0) ) + { +LABEL_44: + v25 = "Init - Failed to create z-buffer.\n"; +LABEL_45: + sprintf(pErrorMessage, v25); + if (pBackBuffer) + { + pBackBuffer->Release(); + pBackBuffer = 0; + } +LABEL_63: + //v19 = &pFrontBuffer; + if (pFrontBuffer) + { + pFrontBuffer->Release(); + pFrontBuffer= 0; + } + goto LABEL_65; + } + if (pBackBuffer->AddAttachedSurface(pZBuffer)) + goto LABEL_48; + //v33 = &pDevice; + if (pDirect3D->CreateDevice(*pAvailableDevices[uDeviceID].pGUID, + pBackBuffer, + &pDevice, + 0) ) + goto LABEL_51; + 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 = 640; + d3dvp2.dwHeight = 480; + 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; + } +LABEL_59: + if (pZBuffer) + { + pZBuffer->Release(); + pZBuffer = 0; + } +LABEL_61: + if (pBackBuffer) + { + pBackBuffer->Release(); + pBackBuffer = 0; + } + goto LABEL_63; + } + + pDevice->AddViewport(pViewport); + pViewport->SetViewport2(&d3dvp2); + pDevice->SetCurrentViewport(pViewport); + return 1; +} + + +//----- (0049E444) -------------------------------------------------------- +unsigned int RenderD3D::GetDeviceCaps() +{ + unsigned int v1; // ebx@1 + RenderD3D *v2; // edi@1 + IDirect3DDevice3 *v3; // eax@1 + unsigned int result; // eax@2 + D3DDEVICEDESC refCaps; // [sp+Ch] [bp-1F8h]@1 + D3DDEVICEDESC halCaps; // [sp+108h] [bp-FCh]@1 + + v1 = 0; + v2 = this; + memset(&halCaps, 0, 0xFCu); + halCaps.dwSize = 252; + memset(&refCaps, 0, 0xFCu); + v3 = v2->pDevice; + refCaps.dwSize = 252; + if ( v3->GetCaps(&halCaps, &refCaps) ) + { + result = 1; + } + else + { + if ( !(halCaps.dpcTriCaps.dwSrcBlendCaps & 0x10) ) + v1 = 2; + if ( !(halCaps.dpcTriCaps.dwSrcBlendCaps & 2) ) + v1 |= 4u; + if ( !(halCaps.dpcTriCaps.dwSrcBlendCaps & 1) ) + v1 |= 8u; + if ( !(halCaps.dpcTriCaps.dwDestBlendCaps & 0x20) ) + v1 |= 0x10u; + if ( !(halCaps.dpcTriCaps.dwDestBlendCaps & 2) ) + v1 |= 0x20u; + if ( !(halCaps.dpcTriCaps.dwDestBlendCaps & 4) ) + v1 |= 0x40u; + if ( halCaps.dpcTriCaps.dwTextureCaps & 0x20 ) + LOBYTE(v1) = v1 | 0x80; + 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, 640, 480}}; + if (uClearFlags) + pViewport->Clear2(1, rects, uClearFlags, uClearColor, z_clear, 0); +} + + +//----- (0049E54D) -------------------------------------------------------- +void RenderD3D::Present(bool bForceBlit) +{ + RECT v5; // [sp+18h] [bp-18h]@1 + struct tagPOINT Point; // [sp+28h] [bp-8h]@4 + + v5.left = 0; + v5.top = 0; + v5.bottom = 480; + v5.right = 640; + + if (bWindowed || bForceBlit) + { + RECT rc; + GetClientRect(hWindow, &rc); + Point.y = 0; + Point.x = 0; + ClientToScreen(hWindow, &Point); + OffsetRect(&rc, Point.x, Point.y); + pFrontBuffer->Blt(&rc, pBackBuffer, &v5, DDBLT_WAIT, 0); + } + else + pFrontBuffer->Flip(0, 1); +} + + +//----- (0049E5D4) -------------------------------------------------------- +bool RenderD3D::CreateTexture(unsigned int uTextureWidth, unsigned int uTextureHeight, IDirectDrawSurface4 **pOutSurface, IDirect3DTexture2 **pOutTexture, bool bAlphaChannel, bool bMipmaps, unsigned int uMinDeviceTexDim) +{ + unsigned int v8; // edx@4 + unsigned int v9; // ebx@5 + unsigned int v10; // eax@5 + DWORD v11; // edx@5 + //int v12; // edx@7 + DDSURFACEDESC2 ddsd2; // [sp+Ch] [bp-80h]@1 + //RenderD3D *v15; // [sp+88h] [bp-4h]@1 + + //v15 = this; + memset(&ddsd2, 0, 0x7Cu); + ddsd2.dwSize = 0x7Cu; + 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 ) + { + v8 = GetMaxMipLevels(uTextureHeight) - GetMaxMipLevels(uMinDeviceTexDim); +LABEL_8: + ddsd2.dwMipMapCount = v8; + if ( !v8 ) + goto LABEL_12; + goto LABEL_11; + } + if ( (signed int)uTextureWidth < (signed int)uMinDeviceTexDim ) + { + v8 = GetMaxMipLevels(uMinDeviceTexDim); + goto LABEL_8; + } + v9 = GetMaxMipLevels(uTextureWidth); + v10 = GetMaxMipLevels(uMinDeviceTexDim); + ddsd2.dwMipMapCount = v9 - v10; + if ( v9 == v10 ) + { + ddsd2.dwFlags = 0x1007u; + ddsd2.ddsCaps.dwCaps = v11; + goto LABEL_12; + } + } + else + { + ddsd2.dwMipMapCount = 1; + } +LABEL_11: + 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 = 0x8000u; + } + 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, 0))) + 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, stru148 *a3, ODMFace *a4, IDirect3DTexture2 *pTexture) +{ + Render *v5; // edi@1 + unsigned int v6; // ebx@1 + LightmapBuilder *v7; // esi@3 + int v8; // eax@7 + ODMFace *v9; // eax@12 + char *v10; // esi@12 + double v11; // st7@14 + double v12; // st7@14 + int v13; // eax@14 + ODMFace *v14; // ecx@14 + double v15; // st7@14 + float v16; // ST48_4@15 + int v17; // eax@15 + char v18; // zf@17 + HRESULT v19; // eax@18 + HRESULT v20; // eax@18 + HRESULT v21; // eax@20 + HRESULT v22; // eax@20 + unsigned int v23; // ecx@20 + char *v24; // eax@21 + HRESULT v25; // eax@23 + HRESULT v26; // eax@23 + HRESULT v27; // eax@24 + HRESULT v28; // eax@25 + HRESULT v29; // eax@25 + HRESULT v30; // eax@25 + HRESULT v31; // eax@25 + HRESULT v32; // eax@26 + unsigned int v33; // ecx@26 + char *v34; // eax@27 + int v35; // edx@28 + HRESULT v36; // eax@29 + HRESULT v37; // eax@29 + HRESULT v38; // eax@29 + HRESULT v39; // eax@29 + //IDirect3DDevice3Vtbl *v40; // ebx@29 + unsigned int v41; // eax@29 + HRESULT v42; // eax@30 + HRESULT v43; // eax@30 + HRESULT v44; // eax@30 + char *v45; // esi@34 + int v46; // ecx@35 + double v47; // st6@35 + int v48; // eax@36 + const char *v49; // [sp+4Ch] [bp-1Ch]@0 + const char *v50; // [sp+4Ch] [bp-1Ch]@20 + int v51; // [sp+50h] [bp-18h]@0 + unsigned int v52; // [sp+54h] [bp-14h]@0 + LightmapBuilder *v53; // [sp+58h] [bp-10h]@3 + unsigned int v54; // [sp+5Ch] [bp-Ch]@3 + unsigned int v55; // [sp+5Ch] [bp-Ch]@34 + unsigned int v56; // [sp+60h] [bp-8h]@12 + int v57; // [sp+60h] [bp-8h]@34 + HRESULT a2; // [sp+64h] [bp-4h]@4 + + v5 = this; + v6 = 0; + if ( this->uNumD3DSceneBegins && (signed int)uNumVertices >= 3 ) + { + v7 = pGame->pLightmapBuilder; + v53 = v7; + v54 = v7->std__vector_000004_size; + if ( v7->std__vector_000004_size) + a2 = -1; + pGame->_44EE30(a4, (int)&a2); + if ( byte_4D864C && pGame->uFlags & 1 ) + { + v8 = GetActorTintColor(a3->field_58, 0, array_50AC10[0].vWorldViewPosition.x, 0, 0); + v7->_45D74F_MessWithLight(v8, 0); + } + else + { + if ( !v54 || byte_4D864C && pGame->uFlags & 2 ) + { + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, 1u)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CW)); + if (bUsingSpecular) + { + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, true)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, 2)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 1)); + } + if ( (signed int)uNumVertices > 0 ) + { + v45 = (char *)&array_50AC10[0].vWorldViewPosition; + v57 = (int)&arary_77E5C8[0].pos.y; + v55 = uNumVertices; + do + { + a2 = GetActorTintColor(a3->field_58, 0, *(float *)v45, 0, 0); + pGame->_44EE30(a4, (int)&a2); + v46 = v57; + v47 = *(float *)v45 * 1000.0 / (double)pOutdoorCamera->shading_dist_mist; + *(int *)(v57 - 4) = *((int *)v45 + 3); + *(int *)v57 = *((int *)v45 + 4); + *(int *)(v57 + 12) = a2; + *(float *)(v57 + 4) = 1.0 - 1.0 / v47; + *(float *)(v57 + 8) = 1.0 / (*(float *)v45 + 0.0000001); + if ( v5->bUsingSpecular ) + { + v48 = sub_47C3D7_get_fog_related_stuff(0, 0, *(float *)v45); + v46 = v57; + } + else + { + v48 = 0; + } + *(int *)(v46 + 16) = v48; + *(int *)(v46 + 20) = *((int *)v45 + 6); + *(int *)(v46 + 24) = *((int *)v45 + 7); + v45 += 48; + v18 = v55-- == 1; + v57 = v46 + 32; + } + while ( !v18 ); + } + pRenderD3D->pDevice->SetTexture(0, pTexture); + pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + arary_77E5C8, + uNumVertices, + D3DDP_DONOTLIGHT); + } + else + { + if ( (signed int)uNumVertices > 0 ) + { + v9 = (ODMFace *)&arary_77E5C8[0].pos.y; + v10 = (char *)&array_50AC10[0].vWorldViewPosition; + a4 = (ODMFace *)&arary_77E5C8[0].pos.y; + v56 = uNumVertices; + while ( 1 ) + { + v11 = *(float *)v10 * 1000.0; + *((int *)v9 - 1) = *((int *)v10 + 3); + v12 = v11 / (double)pOutdoorCamera->shading_dist_mist; + v9->pFacePlane.vNormal.x = *((int *)v10 + 4); + *(float *)&v9->pFacePlane.vNormal.y = 1.0 - 1.0 / v12; + *(float *)&v9->pFacePlane.vNormal.z = 1.0 / (*(float *)v10 + 0.0000001); + v13 = GetActorTintColor(a3->field_58, 0, *(float *)v10, 0, 0); + v14 = a4; + v15 = *(float *)v10; + a4->pFacePlane.dist = v13; + if ( v5->bUsingSpecular ) + { + v16 = v15; + v17 = sub_47C3D7_get_fog_related_stuff(0, 0, v16); + v14 = a4; + } + else + { + v17 = 0; + } + v14->zCalc1 = v17; + v14->zCalc2 = *((int *)v10 + 6); + v14->zCalc3 = *((int *)v10 + 7); + v10 += 48; + v18 = v56-- == 1; + a4 = (ODMFace *)((char *)v14 + 32); + if ( v18 ) + break; + v9 = a4; + } + } + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, 1u)); + if (bUsingSpecular) + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 0)); + + ErrD3D(pRenderD3D->pDevice->SetTexture(0, nullptr)); + ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_TEX1 | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, + arary_77E5C8, + uNumVertices, + D3DDP_DONOTLIGHT)); + //v50 = (const char *)v5->pRenderD3D->pDevice; + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE)); + //(*(void (**)(void))(*(int *)v50 + 88))(); + v53->_45D74F_MessWithLight(-1, 0); + v23 = uNumVertices; + if ( (signed int)uNumVertices > 0 ) + { + v24 = (char *)&arary_77E5C8[0].diffuse; + do + { + *(int *)v24 = a2; + v24 += 32; + --v23; + } + while ( v23 ); + } + ErrD3D(pRenderD3D->pDevice->SetTexture(0, pTexture)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, 1u)); + if ( !pRenderer->bUsingSpecular ) + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, true)); + + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, true)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, 1)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 3)); + ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_TEX1 | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, + arary_77E5C8, + uNumVertices, + D3DDP_DONOTLIGHT)); + if (bUsingSpecular) + { + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, true)); + + v33 = uNumVertices; + if ( (signed int)uNumVertices > 0 ) + { + v34 = (char *)&arary_77E5C8[0].specular; + do + { + v35 = *(int *)v34; + *(int *)v34 = 0; + v34 += 32; + --v33; + *((int *)v34 - 9) = pRenderer->uFogColor | v35 & 0xFF000000; + } + while ( v33 ); + } + ErrD3D(pRenderD3D->pDevice->SetTexture(0, nullptr)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, 6)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 5)); + ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_TEX1 | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, + arary_77E5C8, + 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, 2)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 1)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, v6)); + } + } + } +} +// 4D864C: using guessed type char byte_4D864C; + + +//----- (0049EB79) -------------------------------------------------------- +Render::~Render() +{ + Render *v1; // esi@1 + + v1 = this; + pAllocator->FreeChunk(this->pDefaultZBuffer); + v1->pD3DBitmaps.Release(); + v1->pD3DSprites.Release(); + Release(); + v1->bWindowMode = 1; + //nullsub_1(); + //nullsub_1(); +} + + + +//----- (0049E756) -------------------------------------------------------- +bool Render::IsColorKeySupported(IDirectDraw4 *this_) +{ + DDCAPS refCaps; // [sp+0h] [bp-2F8h]@1 + DDCAPS halCaps; // [sp+17Ch] [bp-17Ch]@1 + + halCaps.dwSize = 380; + refCaps.dwSize = 380; + this_->GetCaps(&halCaps, &refCaps); + return halCaps.dwSVBCaps & 0x40 && BYTE1(halCaps.dwSVBCKeyCaps) & 2; +} + +//----- (0049E992) -------------------------------------------------------- +Render::Render() +{ + Render *v1; // esi@1 + int v2; // eax@1 + char v3; // zf@1 + + v1 = this; + this->pDirectDraw4 = 0; + this->pFrontBuffer4 = 0; + this->pBackBuffer4 = 0; + this->pColorKeySurface4 = 0; + this->pDirectDraw2 = 0; + this->pFrontBuffer2 = 0; + this->pBackBuffer2 = 0; + this->pSomeSurface2 = 0; + //RenderHWLContainer::RenderHWLContainer(&this->pD3DBitmaps); + //RenderHWLContainer::RenderHWLContainer(&v1->pD3DSprites); + v1->bWindowMode = 1; + v1->field_40054 = 0; + v1->field_10 = 640; + v1->field_14 = 480; + v1->field_40030 = 0; + v1->field_4002C = 0; + v1->pActiveZBuffer = 0; + v1->pDefaultZBuffer = 0; + v1->field_20_clipy = 0; + v1->field_1C_clipx = 0; + v1->field_24_clipz = 639; + v1->field_28_clipw = 479; + v1->field_4003C = (int)&unk_4EED80; + v1->field_40040 = dword_4EED78; + v1->uClipZ = 640; + v1->field_40044 = 2; + v1->field_40048 = 6; + v1->pFrontBuffer4 = 0; + v1->pBackBuffer4 = 0; + v1->pColorKeySurface4 = 0; + v1->pDirectDraw4 = 0; + v1->pRenderD3D = 0; + v1->uNumSceneBegins = 0; + v1->uNumD3DSceneBegins = 0; + v1->field_40110 = 0; + v1->pTargetSurface = 0; + v1->uTargetSurfacePitch = 0; + v1->uClipY = 0; + v1->uClipX = 0; + v1->uClipW = 480; + v1->bClip = 1; + v1->bColorKeySupported = 0; + v1->bRequiredTextureStagesAvailable = 0; + v1->bTinting = 1; + LOBYTE(v1->field_103668) = 0; + v1->field_1036B8 = 0; + v1->_gpu_memory_used = 0; + uNumBillboardsToDraw = 0; + bFogEnabled = false; +} + +bool Render::Initialize(bool bWindowed, uint uDefaultDevice, + bool bColoredLights, uint uDetailLevel, uint bTinting) +{ + bUserDirect3D = true;//ReadWindowsRegistryInt("Use D3D", 0); + bStartInWindow = bWindowed; + + uDesiredDirect3DDevice = uDefaultDevice;//ReadWindowsRegistryInt("D3D Device", 1); + + bUseColoredLights = bColoredLights;//ReadWindowsRegistryInt("Colored Lights", 0); + uLevelOfDetail = uDetailLevel;//ReadWindowsRegistryInt("Detail Level", 1); + + this->bTinting = bTinting; + + auto r1 = pD3DBitmaps.Load(L"data\\d3dbitmap.hwl"); + auto r2 = pD3DSprites.Load(L"data\\d3dsprite.hwl"); + + return r1 && r2; +} + + + +//----- (0049EBF1) -------------------------------------------------------- +void Render::_49EBF1() +{ + signed int uNumRedBits; // edx@1 + signed int uNuGreenBits; // edi@1 + signed int uNumBlueBits; // esi@1 + unsigned int v4; // edx@4 + unsigned int v5; // edi@4 + int v6; // ebx@4 + int v7; // edx@4 + signed int v8; // [sp+8h] [bp-24h]@1 + signed int v9; // [sp+Ch] [bp-20h]@1 + signed int v10; // [sp+20h] [bp-Ch]@1 + signed int i; // [sp+24h] [bp-8h]@2 + signed int v12; // [sp+28h] [bp-4h]@3 + + v10 = 0; + uNumRedBits = 1 << this->uTargetRBits; + uNuGreenBits = 1 << this->uTargetGBits; + uNumBlueBits = 1 << this->uTargetBBits; + v9 = 1 << this->uTargetRBits; + v8 = 1 << this->uTargetGBits; + if ( uNumRedBits > 0 ) + { + do + { + for ( i = 0; i < uNuGreenBits; ++i ) + { + v12 = 0; + if ( uNumBlueBits > 0 ) + { + do + { + v4 = this->uTargetBBits; + v5 = v4 + this->uTargetGBits; + v6 = (v12 >> 1) + (v10 >> 1 << v5) + (i >> 1 << this->uTargetBBits); + v7 = (v10 << v5) + v12++ + (i << v4); + this->field_2C[v7] = v6; + } + while ( v12 < uNumBlueBits ); + uNumRedBits = v9; + uNuGreenBits = v8; + } + } + ++v10; + } + while ( v10 < uNumRedBits ); + } +} + + +//----- (0049ECC4) -------------------------------------------------------- +void Render::ClearBlack() +{ + if (pRenderD3D) + { + if (field_40110) + pRenderD3D->ClearTarget(true, 0, false, 0.0); + } + else + memset(pRenderer->pTargetSurface, 0, 4 * (field_10 * field_14 / 2)); +} + + +//----- (0049ED18) -------------------------------------------------------- +void Render::PresentBlackScreen() +{ + LONG w; // edx@3 + IDirectDrawSurface *v2; // eax@3 + DDBLTFX v3; // [sp+4h] [bp-74h]@5 + RECT x; // [sp+68h] [bp-10h]@3 + + memset(&v3, 0, sizeof(DDBLTFX)); + if (pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || + pVersion->pVersionInfo.dwMajorVersion >= 5) + { + x.left = uWindowX; + x.right = uWindowX + uWindowHeight; + x.top = uWindowY; + w = uWindowY + uWindowWidth; + v2 = (IDirectDrawSurface *)this->pBackBuffer4; + } + else + { + x.left = uWindowX; + x.right = uWindowX + uWindowHeight; + x.top = uWindowY; + w = uWindowY + uWindowWidth; + v2 = (IDirectDrawSurface *)this->pBackBuffer2; + } + x.bottom = w; + v3.dwFillColor = 0; + v3.dwSize = 100; + v2->Blt(&x, 0, 0, DDBLT_COLORFILL, &v3); + pRenderer->Present(); +} + + +//----- (0049EDB6) -------------------------------------------------------- +void Render::SavePCXScreenshot() +{ + Render *v1; // esi@1 + __int16 v2; // di@1 + int v3; // eax@4 + int v4; // ecx@4 + int v5; // eax@8 + FILE *v6; // edi@10 + int v7; // ecx@11 + int v8; // eax@11 + int v9; // eax@13 + int v10; // ecx@15 + unsigned __int8 v11; // dl@15 + signed int v12; // eax@18 + char v13; // zf@27 + HRESULT v14; // eax@29 + char v15[56]; // [sp+Ch] [bp-158h]@10 + __int16 v16; // [sp+44h] [bp-120h]@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 *v20; // [sp+11Ch] [bp-48h]@14 + char *v21; // [sp+120h] [bp-44h]@14 + int v24; // [sp+124h] [bp-40h]@11 + FILE *File; // [sp+128h] [bp-3Ch]@3 + int var38; // [sp+12Ch] [bp-38h]@4 + PCXHeader_1 header1; // [sp+130h] [bp-34h]@10 + PCXHeader_2 header2; // [sp+140h] [bp-24h]@10 + void *ptr; // [sp+148h] [bp-1Ch]@10 + void *v28; // [sp+14Ch] [bp-18h]@8 + int v29; // [sp+150h] [bp-14h]@4 + int v30; // [sp+154h] [bp-10h]@4 + char v31; // [sp+15Ah] [bp-Ah]@25 + unsigned __int8 v32; // [sp+15Bh] [bp-9h]@17 + int i; // [sp+15Ch] [bp-8h]@10 + unsigned __int8 v34; // [sp+163h] [bp-1h]@17 + + v1 = this; + v2 = 0; + if ( !this->pRenderD3D || this->field_40110 ) + { + sprintf(Filename, "screen%0.2i.pcx", dword_4EFA80++ % 100); + File = fopen(Filename, "wb"); + if ( File ) + { + v3 = v1->field_10; + v4 = v1->field_14; + var38 = v3; + v29 = v4; + v30 = v3; + if ( v3 & 1 ) + v30 = v3 + 1; + if ( v1->pRenderD3D ) + { + memset(&Dst, 0, 0x7Cu); + Dst.dwSize = 124; + if ( !pRenderer->LockSurface_DDraw4(pRenderer->pBackBuffer4, &Dst, 1u) ) + return; + v28 = Dst.lpSurface; + v5 = Dst.lPitch >> 1; + v2 = 0; + } + else + { + pRenderer->BeginScene(); + v28 = pRenderer->pTargetSurface; + v5 = pRenderer->uTargetSurfacePitch; + } + i = v5; + header1.right = var38 - 1; + header1.left = v2; + header1.bottom = v29 - 1; + header1.up = v2; + header2.pitch = v30; + memset(color_map, 0, sizeof(color_map)); + memset(v15, 0, sizeof(v15)); + header2.reserved = 0; + header1.manufacturer = 10; + v16 = 0; + v6 = 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, 1u, 1u, File); + fwrite(&header1.version, 1u, 1u, v6); + fwrite(&header1.encoding, 1u, 1u, v6); + fwrite(&header1.bpp, 1u, 1u, v6); + fwrite(&header1.left, 2u, 1u, v6); + fwrite(&header1.up, 2u, 1u, v6); + fwrite(&header1.right, 2u, 1u, v6); + fwrite(&header1.bottom, 2u, 1u, v6); + fwrite(&header1.hdpi, 2u, 1u, v6); + fwrite(&header1.vdpi, 2u, 1u, v6); + fwrite(color_map, 0x30u, 1u, v6); + fwrite(&header2, 1u, 1u, v6); + fwrite(&header2.planes, 1u, 1u, v6); + fwrite(&header2.pitch, 2u, 1u, v6); + fwrite(&header2.palette_info, 2u, 1u, v6); + fwrite(v15, 0x3Au, 1u, v6); + ptr = pAllocator->AllocNamedChunk(0, 3 * var38 + 6, 0); + if ( v29 > 0 ) + { + v7 = v30; + File = (FILE *)v29; + v29 = 3 * v30; + v24 = 2 * i; + v8 = (int)v28; + while ( 1 ) + { + i = v8; + v9 = 0; + if ( var38 > 0 ) + { + v21 = (char *)ptr + v7; + v20 = (char *)ptr + 2 * v30; + do + { + *((char *)ptr + v9) = (signed int)(v1->uTargetRMask & *(short *)i) >> (LOBYTE(v1->uTargetGBits) + + LOBYTE(v1->uTargetBBits) + + v1->uTargetRBits + - 8); + v21[v9] = (signed int)(v1->uTargetGMask & *(short *)i) >> (LOBYTE(v1->uTargetBBits) + + LOBYTE(v1->uTargetGBits) + - 8); + v10 = i; + v11 = LOBYTE(v1->uTargetBMask); + i += 2; + v20[v9++] = (*(char *)v10 & v11) << (8 - LOBYTE(v1->uTargetBBits)); + } + while ( v9 < var38 ); + } + for ( i = 0; i < v29; i += v34 ) + { + v34 = 1; + v32 = *((char *)ptr + i); + do + { + v12 = i + v34; + if ( *((char *)ptr + v12) != v32 ) + break; + if ( !(v12 % v30) ) + break; + ++v34; + } + while ( v34 < 0x3Fu ); + if ( i + v34 > v29 ) + v34 = 3 * v30 - i; + if ( v34 > 1u || v32 >= 0xC0u ) + { + v31 = v34 | 0xC0; + fwrite(&v31, 1u, 1u, v6); + } + fwrite(&v32, 1u, 1u, v6); + } + v8 = (int)((char *)v28 + v24); + v13 = File == (FILE *)1; + File = (FILE *)((char *)File - 1); + v28 = (char *)v28 + v24; + if ( v13 ) + break; + v7 = v30; + } + } + if ( v1->pRenderD3D ) + { + ErrD3D(pRenderer->pBackBuffer4->Unlock(0)); + } + else + { + pRenderer->EndScene(); + } + + pAllocator->FreeChunk(ptr); + fclose(v6); + } + } +} +// 4EFA80: using guessed type int dword_4EFA80; + + +//----- (0049F1BC) -------------------------------------------------------- +void Render::_49F1BC(const char *a1) +{ + Render *v2; // esi@1 + __int16 v3; // di@1 + int v4; // eax@4 + char *v5; // ecx@4 + unsigned int v6; // eax@8 + FILE *v7; // edi@10 + int v8; // ecx@11 + int v9; // eax@11 + int v10; // eax@13 + const char *v11; // ecx@15 + unsigned __int8 v12; // dl@15 + signed int v13; // eax@18 + char v14; // zf@27 + HRESULT v15; // eax@29 + char v16; // [sp+Ch] [bp-12Ch]@10 + __int16 v17; // [sp+44h] [bp-F4h]@10 + int Dst; // [sp+48h] [bp-F0h]@7 + int v19; // [sp+58h] [bp-E0h]@8 + unsigned __int16 *v20; // [sp+6Ch] [bp-CCh]@8 + char v21; // [sp+C4h] [bp-74h]@10 + unsigned int v22; // [sp+F4h] [bp-44h]@11 + char *v23; // [sp+F8h] [bp-40h]@14 + int v24; // [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 + void *ptr; // [sp+120h] [bp-18h]@10 + unsigned __int16 *v42; // [sp+124h] [bp-14h]@8 + int v43; // [sp+128h] [bp-10h]@4 + char v44; // [sp+12Fh] [bp-9h]@25 + char *i; // [sp+130h] [bp-8h]@10 + unsigned __int8 v46; // [sp+137h] [bp-1h]@17 + + v2 = this; + v3 = 0; + if ( !this->pRenderD3D || this->field_40110 ) + { + ++dword_4EFA84; + File = fopen(a1, "wb"); + if ( File ) + { + v4 = v2->field_10; + v5 = (char *)v2->field_14; + v25 = v4; + a1 = v5; + v43 = v4; + if ( v4 & 1 ) + v43 = v4 + 1; + if ( v2->pRenderD3D ) + { + memset(&Dst, 0, 0x7Cu); + Dst = 124; + if ( !pRenderer->LockSurface_DDraw4(pRenderer->pBackBuffer4, (DDSURFACEDESC2 *)&Dst, 1u) ) + return; + v42 = v20; + v6 = v19 >> 1; + v3 = 0; + } + else + { + pRenderer->BeginScene(); + v42 = pRenderer->pTargetSurface; + v6 = pRenderer->uTargetSurfacePitch; + } + i = (char *)v6; + v33 = v25 - 1; + v31 = v3; + v34 = (short)a1 - 1; + v32 = v3; + v39 = v43; + memset(&v21, 0, 0x30u); + memset(&v16, 0, 0x38u); + v37 = 0; + Str = 10; + v17 = 0; + v7 = File; + v28 = 5; + v29 = 1; + v30 = 8; + v35 = 75; + v36 = 75; + v38 = 3; + v40 = 1; + fwrite(&Str, 1u, 1u, File); + fwrite(&v28, 1u, 1u, v7); + fwrite(&v29, 1u, 1u, v7); + fwrite(&v30, 1u, 1u, v7); + fwrite(&v31, 2u, 1u, v7); + fwrite(&v32, 2u, 1u, v7); + fwrite(&v33, 2u, 1u, v7); + fwrite(&v34, 2u, 1u, v7); + fwrite(&v35, 2u, 1u, v7); + fwrite(&v36, 2u, 1u, v7); + fwrite(&v21, 0x30u, 1u, v7); + fwrite(&v37, 1u, 1u, v7); + fwrite(&v38, 1u, 1u, v7); + fwrite(&v39, 2u, 1u, v7); + fwrite(&v40, 2u, 1u, v7); + fwrite(&v16, 0x3Au, 1u, v7); + ptr = pAllocator->AllocNamedChunk(0, 3 * v25 + 6, 0); + if ( (signed int)a1 > 0 ) + { + v8 = v43; + File = (FILE *)a1; + v24 = 3 * v43; + v22 = 2 * (int)i; + v9 = (int)v42; + while ( 1 ) + { + a1 = (const char *)v9; + v10 = 0; + if ( v25 > 0 ) + { + i = (char *)ptr + v8; + v23 = (char *)ptr + 2 * v43; + do + { + *((char *)ptr + v10) = (signed int)(v2->uTargetRMask & *(short *)a1) >> (LOBYTE(v2->uTargetGBits) + + LOBYTE(v2->uTargetBBits) + + v2->uTargetRBits + - 8); + i[v10] = (signed int)(v2->uTargetGMask & *(short *)a1) >> (LOBYTE(v2->uTargetBBits) + + LOBYTE(v2->uTargetGBits) + - 8); + v11 = a1; + v12 = LOBYTE(v2->uTargetBMask); + a1 += 2; + v23[v10++] = ((unsigned __int8)*v11 & v12) << (8 - LOBYTE(v2->uTargetBBits)); + } + while ( v10 < v25 ); + } + for ( i = 0; (signed int)i < v24; i += BYTE3(a1) ) + { + BYTE3(a1) = 1; + v46 = *((char *)ptr + (int)i); + do + { + v13 = (signed int)&i[BYTE3(a1)]; + if ( *((char *)ptr + v13) != v46 ) + break; + if ( !(v13 % v43) ) + break; + ++BYTE3(a1); + } + while ( BYTE3(a1) < 0x3Fu ); + if ( (signed int)&i[BYTE3(a1)] > v24 ) + BYTE3(a1) = 3 * v43 - (char)i; + if ( BYTE3(a1) > 1u || v46 >= 0xC0u ) + { + v44 = BYTE3(a1) | 0xC0; + fwrite(&v44, 1u, 1u, v7); + } + fwrite(&v46, 1u, 1u, v7); + } + v9 = (int)&v42[v22 / 2]; + v14 = File == (FILE *)1; + File = (FILE *)((char *)File - 1); + v42 = (unsigned __int16 *)((char *)v42 + v22); + if ( v14 ) + break; + v8 = v43; + } + } + if ( v2->pRenderD3D ) + { + ErrD3D(pRenderer->pBackBuffer4->Unlock(0)); + } + else + { + pRenderer->EndScene(); + } + pAllocator->FreeChunk(ptr); + fclose(v7); + } + } +} +// 4EFA84: using guessed type int dword_4EFA84; + + + +//----- (0049F5A2) -------------------------------------------------------- +int Render::_49F5A2(int a2, int a3, int a4, void *Dst, int a6, int a7) +{ + Render *v7; // ebx@1 + void *v8; // esi@3 + void *v9; // esi@3 + int v10; // ecx@4 + int v11; // eax@4 + int v12; // eax@6 + 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 + // __int16 v19; // [sp+44h] [bp-74h]@3 + char v20[48]; // [sp+48h] [bp-70h]@3 + char *v21; // [sp+78h] [bp-40h]@7 + char *v22; // [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 + char Src; // [sp+90h] [bp-28h]@3 + char v28; // [sp+91h] [bp-27h]@3 + char v29; // [sp+92h] [bp-26h]@3 + char v30; // [sp+93h] [bp-25h]@3 + __int16 v31; // [sp+94h] [bp-24h]@3 + __int16 v32; // [sp+96h] [bp-22h]@3 + __int16 v33; // [sp+98h] [bp-20h]@3 + __int16 v34; // [sp+9Ah] [bp-1Eh]@3 + __int16 v35; // [sp+9Ch] [bp-1Ch]@3 + __int16 v36; // [sp+9Eh] [bp-1Ah]@3 + char v37; // [sp+A0h] [bp-18h]@3 + char v38; // [sp+A1h] [bp-17h]@3 + __int16 v39; // [sp+A2h] [bp-16h]@3 + __int16 v40; // [sp+A4h] [bp-14h]@3 + void *ptr; // [sp+A8h] [bp-10h]@3 + int v42; // [sp+ACh] [bp-Ch]@1 + char v43; // [sp+B3h] [bp-5h]@18 + int i; // [sp+B4h] [bp-4h]@6 + + v7 = this; + v42 = a3; + if ( a3 & 1 ) + v42 = a3 + 1; + v31 = 0; + v32 = 0; + v33 = a3 - 1; + v34 = a4 - 1; + v39 = v42; + memset(&v20, 0, 0x30u); + memset(&v18, 0, 0x38u); + v8 = Dst; + v37 = 0; + *(_WORD *)&v18[56] = 0; + Src = 10; + v28 = 5; + v29 = 1; + v30 = 8; + v35 = 75; + v36 = 75; + v38 = 3; + v40 = 1; + memcpy(Dst, &Src, 1u); + v8 = (char *)v8 + 1; + memcpy(v8, &v28, 1u); + v8 = (char *)v8 + 1; + memcpy(v8, &v29, 1u); + v8 = (char *)v8 + 1; + memcpy(v8, &v30, 1u); + v8 = (char *)v8 + 1; + memcpy(v8, &v31, 2u); + v8 = (char *)v8 + 2; + memcpy(v8, &v32, 2u); + v8 = (char *)v8 + 2; + memcpy(v8, &v33, 2u); + v8 = (char *)v8 + 2; + memcpy(v8, &v34, 2u); + v8 = (char *)v8 + 2; + memcpy(v8, &v35, 2u); + v8 = (char *)v8 + 2; + memcpy(v8, &v36, 2u); + v8 = (char *)v8 + 2; + memcpy(v8, &v20, 0x30u); + v8 = (char *)v8 + 48; + memcpy(v8, &v37, 1u); + v8 = (char *)v8 + 1; + memcpy(v8, &v38, 1u); + v8 = (char *)v8 + 1; + memcpy(v8, &v39, 2u); + v8 = (char *)v8 + 2; + memcpy(v8, &v40, 2u); + v8 = (char *)v8 + 2; + memcpy(v8, &v18, 0x3Au); + v9 = (char *)v8 + 58; + ptr = pAllocator->AllocNamedChunk(0, 3 * a3 + 6, 0); + if ( a4 > 0 ) + { + v10 = v42; + v25 = a4; + v26 = 3 * v42; + v23 = 2 * a3; + v11 = a2; + v24 = a2; + while ( 1 ) + { + a4 = v11; + v12 = 0; + i = 0; + if ( a3 > 0 ) + { + v21 = (char *)ptr + v10; + v22 = (char *)ptr + 2 * v42; + do + { + *((char *)ptr + v12) = (signed int)(v7->uTargetRMask & *(short *)a4) >> (LOBYTE(v7->uTargetGBits) + + LOBYTE(v7->uTargetBBits) + + v7->uTargetRBits + - 8); + v13 = i; + v21[i] = (signed int)(v7->uTargetGMask & *(short *)a4) >> (LOBYTE(v7->uTargetBBits) + + LOBYTE(v7->uTargetGBits) + - 8); + v14 = a4; + a4 += 2; + v22[v13] = (v7->uTargetBMask & *(char *)v14) << (8 - LOBYTE(v7->uTargetBBits)); + v12 = v13 + 1; + i = v12; + } + while ( v12 < a3 ); + } + for ( i = 0; i < v26; v9 = (char *)v9 + 1 ) + { + BYTE3(a4) = 1; + BYTE3(a2) = *((char *)ptr + i); + do + { + v15 = i + BYTE3(a4); + if ( *((char *)ptr + v15) != BYTE3(a2) ) + break; + if ( !(v15 % v42) ) + break; + ++BYTE3(a4); + } + while ( BYTE3(a4) < 0x3Fu ); + if ( i + BYTE3(a4) > v26 ) + BYTE3(a4) = 3 * v42 - i; + if ( BYTE3(a4) > 1u || BYTE3(a2) >= 0xC0u ) + { + v43 = BYTE3(a4) | 0xC0; + memcpy(v9, &v43, 1u); + v9 = (char *)v9 + 1; + } + memcpy(v9, (char *)&a2 + 3, 1u); + i += BYTE3(a4); + } + v11 = v23 + v24; + v16 = v25-- == 1; + v24 += v23; + if ( v16 ) + break; + v10 = v42; + } + } + pAllocator->FreeChunk(ptr); + result = a7; + *(int *)a7 = (char *)v9 - Dst; + return result; +} + + +//----- (0049F8B5) -------------------------------------------------------- +FILE *Render::SavePCXImage(const char *Filename, char *a3, int a4, int a5) +{ + Render *v5; // esi@1 + FILE *result; // eax@1 + FILE *v7; // edi@4 + int v8; // ecx@5 + int v9; // eax@5 + int v10; // eax@7 + int v11; // ecx@9 + 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 v17; // [sp+70h] [bp-34h]@5 + int v18; // [sp+74h] [bp-30h]@5 + char *v19; // [sp+78h] [bp-2Ch]@5 + int v20; // [sp+7Ch] [bp-28h]@5 + PCXHeader_1 header1; // [sp+80h] [bp-24h]@4 + PCXHeader_2 header2; // [sp+90h] [bp-14h]@4 + void *ptr; // [sp+98h] [bp-Ch]@4 + int v24; // [sp+9Ch] [bp-8h]@2 + char *i; // [sp+A0h] [bp-4h]@8 + + v5 = this; + result = fopen(Filename, "wb"); + Filename = (const char *)result; + if ( result ) + { + v24 = a4; + if ( a4 & 1 ) + v24 = a4 + 1; + header1.left = 0; + header1.up = 0; + header1.right = a4 - 1; + header1.bottom = a5 - 1; + header2.pitch = v24; + 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, 1u, 1u, (FILE *)Filename); + v7 = (FILE *)Filename; + fwrite(&header1.version, 1u, 1u, (FILE *)Filename); + fwrite(&header1.encoding, 1u, 1u, v7); + fwrite(&header1.bpp, 1u, 1u, v7); + fwrite(&header1.left, 2u, 1u, v7); + fwrite(&header1.up, 2u, 1u, v7); + fwrite(&header1.right, 2u, 1u, v7); + fwrite(&header1.bottom, 2u, 1u, v7); + fwrite(&header1.hdpi, 2u, 1u, v7); + fwrite(&header1.vdpi, 2u, 1u, v7); + fwrite(color_map, 0x30u, 1u, v7); + fwrite(&header2, 1u, 1u, v7); + fwrite(&header2.planes, 1u, 1u, v7); + fwrite(&header2.pitch, 2u, 1u, v7); + fwrite(&header2.palette_info, 2u, 1u, v7); + fwrite(v14, 0x3Au, 1u, v7); + ptr = pAllocator->AllocNamedChunk(0, 3 * a4 + 6, 0); + if ( a5 > 0 ) + { + v8 = v24; + v18 = a5; + v20 = 3 * v24; + v17 = 2 * a4; + v9 = (int)a3; + v19 = a3; + while ( 1 ) + { + a5 = v9; + v10 = 0; + if ( a4 > 0 ) + { + a3 = (char *)ptr + v8; + i = (char *)ptr + 2 * v24; + do + { + *((char *)ptr + v10) = (signed int)(v5->uTargetRMask & *(short *)a5) >> (LOBYTE(v5->uTargetGBits) + + LOBYTE(v5->uTargetBBits) + + v5->uTargetRBits + - 8); + a3[v10] = (signed int)(v5->uTargetGMask & *(short *)a5) >> (LOBYTE(v5->uTargetBBits) + + LOBYTE(v5->uTargetGBits) + - 8); + v11 = a5; + a5 += 2; + i[v10++] = (v5->uTargetBMask & *(char *)v11) << (8 - LOBYTE(v5->uTargetBBits)); + } + while ( v10 < a4 ); + } + for ( i = 0; (signed int)i < v20; i += BYTE3(a5) ) + { + BYTE3(a5) = 1; + BYTE3(Filename) = *((char *)ptr + (int)i); + do + { + v12 = (signed int)&i[BYTE3(a5)]; + if ( *((char *)ptr + v12) != BYTE3(Filename) ) + break; + if ( !(v12 % v24) ) + break; + ++BYTE3(a5); + } + while ( BYTE3(a5) < 0x3Fu ); + if ( (signed int)&i[BYTE3(a5)] > v20 ) + BYTE3(a5) = 3 * v24 - (char)i; + if ( BYTE3(a5) > 1u || BYTE3(Filename) >= 0xC0u ) + { + BYTE3(a3) = BYTE3(a5) | 0xC0; + fwrite((char *)&a3 + 3, 1u, 1u, v7); + } + fwrite((char *)&Filename + 3, 1u, 1u, v7); + } + v9 = (int)&v19[v17]; + v13 = v18-- == 1; + v19 += v17; + if ( v13 ) + break; + v8 = v24; + } + } + pAllocator->FreeChunk(ptr); + result = (FILE *)fclose(v7); + } + return result; +} + + +//----- (0049FBCD) -------------------------------------------------------- +void Render::ClearTarget(unsigned int uColor) +{ + if (pRenderD3D) + { + if (field_40110) + pRenderD3D->ClearTarget(true, uColor, false, 0.0); + } + else + memset32(pTargetSurface, uColor, field_10 * field_14 / 2); +} + + + +//----- (0049FC23) -------------------------------------------------------- +void Render::Release2() +{ + Release(); + bWindowMode = 1; +} + + +//----- (0049FC37) -------------------------------------------------------- +void Render::Present() +{ + Render *v1; // esi@1 + struct tagRECT Rect; // [sp+8h] [bp-28h]@11 + RECT a4; // [sp+18h] [bp-18h]@11 + struct tagPOINT Point; // [sp+28h] [bp-8h]@11 + + v1 = this; + if ( !pRenderer->pRenderD3D || this->field_40110 ) + { + this->pBeforePresentFunction(); + if ( v1->pRenderD3D ) + { + if ( v1->field_40110 ) + { + if (pAsyncMouse) + pAsyncMouse->_46BAEC(); + pRenderD3D->Present(false); + if (pAsyncMouse) + pAsyncMouse->_46BB0A(); + } + } + else + { + if ( v1->bWindowMode ) + { + RestoreFrontBuffer(); + GetClientRect(v1->hWnd, &Rect); + Point.y = 0; + Point.x = 0; + ClientToScreen(v1->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() +{ + Render *v2; // esi@1 + IDirectDrawSurface4 *v3; // eax@6 + IDirectDrawSurface4 *v4; // ST0C_4@6 + RECT v5; // [sp+8h] [bp-10h]@6 + + auto a1 = this; + v2 = a1; + if ( a1->pRenderD3D ) + { + if (pFrontBuffer4->IsLost() == DDERR_SURFACELOST) + pFrontBuffer4->Restore(); + if (pBackBuffer4->IsLost() == DDERR_SURFACELOST) + pBackBuffer4->Restore(); + v3 = v2->pBackBuffer4; + v4 = v2->pFrontBuffer4; + v5.top = 0; + v5.bottom = 480; + v5.left = 0; + v5.right = 640; + v3->BltFast(0, 0, v4, &v5, 16u); + } +} + + +//----- (0049FDBF) -------------------------------------------------------- +void Render::CreateZBuffer() +{ + if (!pDefaultZBuffer) + { + pDefaultZBuffer = pActiveZBuffer = nullptr; + pDefaultZBuffer = pActiveZBuffer = (int *)pAllocator->AllocNamedChunk(0, 0x12C000, "Z Buf."); + memset32(pActiveZBuffer, 0xFFFF0000u, 0x4B000u); + } +} + + +//----- (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; + v2 = this->pRenderD3D; + if ( v2 ) + { + if ( v1->field_40110 ) + { + pRenderD3D->ClearTarget(1u, 0, 0, 1.0); + pRenderD3D->Present(0); + pRenderD3D->ClearTarget(1u, 0, 0, 1.0); + } + v1->pColorKeySurface4 = 0; + v1->pBackBuffer4 = 0; + v3 = v1->pTargetSurface == 0; + v1->pFrontBuffer4 = 0; + v1->pDirectDraw4 = 0; + if ( !v3 ) + { + free(v1->ptr_400E8); + v1->pTargetSurface = 0; + v1->ptr_400E8 = 0; + } + v4 = v1->pRenderD3D; + if ( v4 ) + { + pRenderD3D->Release(); + free(v4); + } + v1->pRenderD3D = 0; + } + else + { + if ( bWinNT4_0 == 1 ) + { + v5 = (IDirectDraw *)v1->pDirectDraw2; + if ( !v5 ) + return; + v5->SetCooperativeLevel(v1->hWnd, 8u); + v1->pDirectDraw2->FlipToGDISurface(); + v6 = v1->pSomeSurface2; + if ( v6 ) + { + v6->Release(); + v1->pSomeSurface2 = 0; + } + v7 = v1->pBackBuffer2; + if ( v7 ) + { + v7->Release(); + v1->pBackBuffer2 = 0; + } + v8 = v1->pFrontBuffer2; + if ( v8 ) + { + v8->Release(); + v1->pFrontBuffer2 = 0; + } + v9 = v1->pDirectDraw2; + if ( v9 ) + { + v9->Release(); + v1->pDirectDraw2 = 0; + } + } + else + { + v10 = v1->pDirectDraw4; + if ( !v10 ) + return; + v10->SetCooperativeLevel(v1->hWnd, 1032u); + v1->pDirectDraw4->FlipToGDISurface(); + v11 = v1->pColorKeySurface4; + if ( v11 ) + { + v11->Release(); + v1->pColorKeySurface4 = 0; + } + v12 = v1->pBackBuffer4; + if ( v12 ) + { + v12->Release(); + v1->pBackBuffer4 = 0; + } + v13 = v1->pFrontBuffer4; + if ( v13 ) + { + v13->Release(); + v1->pFrontBuffer4 = 0; + } + v14 = v1->pDirectDraw4; + if ( v14 ) + { + v14->Release(); + v1->pDirectDraw4 = 0; + } + } + v15 = &v1->pTargetSurface; + if ( v1->pTargetSurface ) + { + v16 = (void **)&v1->ptr_400E8; + free(*v16); + *v15 = 0; + *v16 = 0; + } + } +} + +//----- (0049FFD7) -------------------------------------------------------- +void Render::CreateSomeTexture() +{ + pRenderD3D->CreateTexture(64, 64, &pSurface, &pTexture, true, false, 32); +} + +//----- (0049FFFB) -------------------------------------------------------- +bool Render::InitializeFullscreen(HWND hWnd) +{ + //Render *v2; // esi@1 + //HWND v3; // ebx@1 + //void *v4; // eax@2 + //RenderD3D *v5; // eax@3 + unsigned int v6; // edx@5 + RenderD3D__DevInfo *v7; // ecx@5 + bool v8; // eax@6 + RenderD3D *v9; // ecx@13 + unsigned int v10; // eax@13 + RenderD3D *v11; // eax@25 + HRESULT v12; // eax@25 + int v13; // ecx@25 + int v14; // eax@27 + signed int v15; // ebx@31 + bool v16; // eax@35 + char v17; // zf@35 + IDirectDraw4 *v18; // eax@38 + HRESULT v19; // eax@38 + int *v20; // eax@39 + 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 + DDSURFACEDESC2 ddsd2; // [sp+280h] [bp-8Ch]@38 + void *v28; // [sp+2FCh] [bp-10h]@2 + int v29; // [sp+308h] [bp-4h]@2 + + //v2 = this; + this->field_40110 = 0; + this->pColorKeySurface4 = 0; + this->pBackBuffer4 = 0; + this->pFrontBuffer4 = 0; + this->pDirectDraw4 = 0; + this->bColorKeySupported = 0; + Release(); + //v3 = hWnd; + this->hWnd = hWnd; + CreateZBuffer(); + if ( bUserDirect3D ) + { + pRenderD3D = new RenderD3D; + v28 = pRenderD3D; + v6 = uDesiredDirect3DDevice; + v29 = -1; + v7 = pRenderD3D->pAvailableDevices; + if ( v7[v6].bIsDeviceCompatible ) + { + v8 = pRenderD3D->CreateDevice(v6, 0, hWnd); + uAcquiredDirect3DDevice = uDesiredDirect3DDevice; + } + else + { + if ( v7[1].bIsDeviceCompatible ) + { + v8 = pRenderD3D->CreateDevice(1u, 0, hWnd); + uAcquiredDirect3DDevice = 1; + } + else + { + if ( !v7->bIsDeviceCompatible ) + Abortf("There aren't any D3D devices to create."); + v8 = pRenderD3D->CreateDevice(0, 0, hWnd); + uAcquiredDirect3DDevice = 0; + } + } + if ( !v8 ) + Abortf("D3Drend->Init failed."); + v9 = pRenderD3D; + pBackBuffer4 = v9->pBackBuffer; + pFrontBuffer4 = v9->pFrontBuffer; + pDirectDraw4 = v9->pHost; + v10 = pRenderD3D->GetDeviceCaps(); + if ( v10 & 1 ) + { + if ( pRenderD3D ) + { + pRenderD3D->Release(); + delete pRenderD3D; + } + pRenderD3D = 0; + pBackBuffer4 = 0; + pFrontBuffer4 = 0; + pDirectDraw4 = 0; + Abortf("Direct3D renderer: The device failed to return capabilities."); + } + if ( v10 & 0x3E ) + { + if ( pRenderD3D ) + { + pRenderD3D->Release(); + delete pRenderD3D; + } + pColorKeySurface4 = 0; + pRenderD3D = 0; + pBackBuffer4 = 0; + pFrontBuffer4 = 0; + pDirectDraw4 = 0; + Abortf("Direct3D renderer: The device doesn't support the necessary alpha blending modes."); + } + if ( (v10 & 0x80u) != 0 ) + { + if ( pRenderD3D ) + { + pRenderD3D->Release(); + delete pRenderD3D; + } + pRenderD3D = 0; + pBackBuffer4 = 0; + pFrontBuffer4 = 0; + pDirectDraw4 = 0; + Abortf("Direct3D renderer: The device doesn't support non-square textures."); + } + LOBYTE(field_10365C) = ~(unsigned __int8)(v10 >> 6) & 1; + bRequiredTextureStagesAvailable = CheckTextureStages(); + memset(&halCaps, 0, 0xFCu); + halCaps.dwSize = 252; + memset(&refCaps, 0, 0xFCu); + v11 = pRenderD3D; + refCaps.dwSize = 252; + ErrD3D(v11->pDevice->GetCaps(&halCaps, &refCaps)); + v13 = halCaps.dwMinTextureWidth; + if ( (unsigned int)halCaps.dwMinTextureWidth >= halCaps.dwMinTextureHeight ) + v13 = halCaps.dwMinTextureHeight; + v14 = halCaps.dwMaxTextureWidth; + uMinDeviceTextureDim = v13; + if ( (unsigned int)v14 < halCaps.dwMaxTextureHeight ) + v14 = halCaps.dwMaxTextureHeight; + uMaxDeviceTextureDim = v14; + if ( (unsigned int)v13 < 4 ) + uMinDeviceTextureDim = 4; + CreateSomeTexture(); + v15 = 1; + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, true)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, true)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, 2u)); + 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, 1u)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, 2u)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MINFILTER, 2u)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, 3u)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, 2u)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, 0)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, 2u)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, 2u)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, 0)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLOROP, 4u)); + } + else + { + CreateDirectDraw(); + SetDirectDrawCooperationMode(hWnd, 1); + SetDirectDrawDisplayMode(640u, 480u, 16u); + CreateDirectDrawPrimarySurface(); + v15 = 1; + } + ddpfPrimareSuface.dwSize = 32; + GetTargetPixelFormat(&ddpfPrimareSuface); + ParseTargetPixelFormat(); + _49EBF1(); + if ( pRenderD3D ) + { + v16 = IsColorKeySupported(pDirectDraw4); + v17 = uAcquiredDirect3DDevice == v15; + bColorKeySupported = v16; + if ( !v17 ) + bColorKeySupported = 0; + if ( bColorKeySupported ) + { + memset(&ddsd2, 0, 0x7Cu); + ddsd2.ddckCKSrcBlt.dwColorSpaceLowValue = uTargetGMask | uTargetBMask; + ddsd2.ddckCKSrcBlt.dwColorSpaceHighValue = ddsd2.ddckCKSrcBlt.dwColorSpaceLowValue; + v18 = pDirectDraw4; + ddsd2.dwSize = 124; + ddsd2.dwFlags = 65543; + ddsd2.ddsCaps.dwCaps = 2112; + ddsd2.dwWidth = 640; + ddsd2.dwHeight = 480; + ErrD3D(v18->CreateSurface(&ddsd2, &pColorKeySurface4, 0)); + pBeforePresentFunction = Present_ColorKey; + } + else + { + pTargetSurface = 0; + ptr_400E8 = 0; + v20 = (int *)operator new(0x96020u); + ptr_400E8 = v20; + if ( !v20 + || (memset(&pDesc, 0, 0x7Cu), + pDesc.dwSize = 124, + !pRenderer->LockSurface_DDraw4(pRenderer->pBackBuffer4, &pDesc, v15)) ) + return 0; + pBackBuffer4->Unlock(0); + v22 = ptr_400E8 + 4; + v23 = (unsigned int)pDesc.lpSurface & 7; + LOBYTE(v22) = (unsigned __int8)v22 & 0xF8; + uTargetSurfacePitch = 640; + pBeforePresentFunction = Present_NoColorKey; + v15 = 1; + pTargetSurface = (unsigned __int16 *)((char *)v22 + 2 * v23); + } + field_40110 = v15; + } + else + { + pBeforePresentFunction = 0;//nullsub_1; + } + bWindowMode = 0; + pParty->uFlags |= 2u; + LODWORD(flt_6BE3A0) = 0x3F0CCCCDu; + pViewport->_4C02F8(36044); + return v15; +} +// 6BE3A0: using guessed type float flt_6BE3A0; + + +//----- (004A05F3) -------------------------------------------------------- +bool Render::SwitchToWindow(HWND hWnd) +{ + //Render *v2; // esi@1 + //void *v3; // eax@2 + //RenderD3D *v4; // eax@3 + //unsigned int v5; // edx@5 + //RenderD3D__DevInfo *v6; // ecx@5 + bool v7; // eax@7 + //RenderD3D *v8; // ecx@12 + unsigned int v9; // eax@12 + RenderD3D *v10; // eax@24 + HRESULT v11; // eax@24 + int v12; // eax@24 + int v13; // eax@26 + bool v14; // eax@32 + char v15; // zf@32 + IDirectDraw4 *v16; // eax@35 + HRESULT v17; // eax@35 + int *v18; // eax@36 + int *v19; // edx@38 + int v20; // eax@38 + unsigned int v21; // ecx@38 + int v22; // eax@41 + D3DDEVICEDESC refCaps; // [sp+Ch] [bp-300h]@24 + DDSURFACEDESC2 pDesc; // [sp+108h] [bp-204h]@37 + D3DDEVICEDESC halCaps; // [sp+184h] [bp-188h]@24 + DDSURFACEDESC2 ddsd2; // [sp+280h] [bp-8Ch]@35 + //RenderD3D *thisa; // [sp+2FCh] [bp-10h]@2 + int v29; // [sp+308h] [bp-4h]@2 + + pParty->uFlags |= 2u; + //v2 = this; + flt_6BE3A0 = 0.55000001f; + pViewport->_4C02F8(36044); + field_40110 = 0; + Release(); + pColorKeySurface4 = 0; + pBackBuffer4 = 0; + pFrontBuffer4 = 0; + pDirectDraw4 = 0; + bColorKeySupported = 0; + CreateZBuffer(); + if ( bUserDirect3D ) + { + /*v3 = operator new(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, 1, hWnd); + uAcquiredDirect3DDevice = uDesiredDirect3DDevice; + } + else + { + if ( !pRenderD3D->pAvailableDevices[0].bIsDeviceCompatible ) + Abortf("There aren't any D3D devices to init."); + v7 = pRenderD3D->CreateDevice(0, 1, hWnd); + uAcquiredDirect3DDevice = 0; + } + if ( !v7 ) + Abortf("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 = 0; + pBackBuffer4 = 0; + pFrontBuffer4 = 0; + pDirectDraw4 = 0; + Abortf("Direct3D renderer: The device failed to return capabilities."); + } + if ( v9 & 0x3E ) + { + if (pRenderD3D) + { + pRenderD3D->Release(); + delete pRenderD3D; + } + pColorKeySurface4 = 0; + pRenderD3D = 0; + pBackBuffer4 = 0; + pFrontBuffer4 = 0; + pDirectDraw4 = 0; + Abortf("Direct3D renderer: The device doesn't support the necessary alpha blending modes."); + } + if ( (v9 & 0x80u) != 0 ) + { + if (pRenderD3D) + { + pRenderD3D->Release(); + delete pRenderD3D; + } + pRenderD3D = 0; + pBackBuffer4 = 0; + pFrontBuffer4 = 0; + pDirectDraw4 = 0; + Abortf("Direct3D renderer: The device doesn't support non-square textures."); + } + LOBYTE(field_10365C) = ~(unsigned __int8)(v9 >> 6) & 1; + bRequiredTextureStagesAvailable = CheckTextureStages(); + memset(&halCaps, 0, 0xFCu); + halCaps.dwSize = 252; + memset(&refCaps, 0, 0xFCu); + //v10 = v2->pRenderD3D; + refCaps.dwSize = 252; + 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; + CreateSomeTexture(); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, 1u)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, 1u)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, 2u)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SPECULARENABLE, 0)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_COLORKEYENABLE, 0)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, 1u)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, 2u)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MINFILTER, 2u)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, 3u)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, 2u)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, 0)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, 2u)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, 2u)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, 0)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLOROP, 4u)); + } + else + { + CreateDirectDraw(); + SetDirectDrawCooperationMode(hWnd, 0); + field_4004C = 1; + CreateFrontBuffer(); + CreateClipper(hWnd); + CreateBackBuffer(); + field_40030 = 0; + field_18_locked_pitch = 0; + } + ddpfPrimareSuface.dwSize = 32; + GetTargetPixelFormat(&ddpfPrimareSuface); + ParseTargetPixelFormat(); + _49EBF1(); + if ( !pRenderD3D ) + { + pBeforePresentFunction = 0;//nullsub_1; + goto LABEL_47; + } + v14 = IsColorKeySupported(pDirectDraw4); + v15 = uAcquiredDirect3DDevice == 1; + bColorKeySupported = v14; + if ( !v15 ) + bColorKeySupported = 0; + if ( bColorKeySupported ) + { + 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, 0)); + pBeforePresentFunction = Present_ColorKey; +LABEL_45: + field_40110 = 1; +LABEL_47: + bWindowMode = 1; + hWnd = hWnd; + return 0; + } + pTargetSurface = 0; + ptr_400E8 = 0; + v18 = (int *)new char[0x96020]; + memset(v18, -1, 0x96020); + ptr_400E8 = v18; + if ( v18 ) + { + memset(&pDesc, 0, 0x7Cu); + pDesc.dwSize = 124; + if ( pRenderer->LockSurface_DDraw4(pRenderer->pBackBuffer4, &pDesc, 1u) ) + { + pRenderer->pBackBuffer4->Unlock(0); + v19 = ptr_400E8; + 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; + } + uTargetSurfacePitch = 640; + pBeforePresentFunction = Present_NoColorKey; + goto LABEL_45; + } + } + return 0; +} + + +//----- (004A0BEE) -------------------------------------------------------- +char Render::Line2D(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW, unsigned __int16 uColor) +{ + int v6; // edi@1 + int v7; // edx@5 + unsigned int v8; // ebx@5 + int v9; // eax@7 + unsigned int v10; // ecx@9 + unsigned int v11; // esi@13 + int v12; // eax@17 + int v13; // eax@21 + Render *v14; // edi@21 + int v15; // eax@25 + int v16; // eax@27 + signed int v17; // eax@28 + signed int v18; // edi@30 + signed __int64 v19; // qax@41 + int v20; // edi@41 + 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 + int v34; // [sp+Ch] [bp-10h]@3 + Render *v35; // [sp+10h] [bp-Ch]@1 + __int64 v36; // [sp+14h] [bp-8h]@1 + signed int v37; // [sp+18h] [bp-4h]@28 + unsigned int uXa; // [sp+24h] [bp+8h]@49 + unsigned int uYa; // [sp+28h] [bp+Ch]@28 + int uYb; // [sp+28h] [bp+Ch]@47 + int uZa; // [sp+2Ch] [bp+10h]@38 + + v36 = 0i64; + v6 = this->field_1C_clipx; + v35 = this; + if ( (signed int)uX < v6 ) + HIDWORD(v36) = 8; + v34 = this->field_24_clipz; + if ( (signed int)uX > this->field_24_clipz ) + HIDWORD(v36) |= 4u; + v7 = this->field_20_clipy; + v8 = uY; + if ( (signed int)uY < v7 ) + HIDWORD(v36) |= 2u; + v9 = this->field_28_clipw; + if ( (signed int)uY > v9 ) + HIDWORD(v36) |= 1u; + v10 = uZ; + if ( (signed int)uZ < v6 ) + LODWORD(v36) = 8; + if ( (signed int)uZ > v34 ) + LODWORD(v36) = v36 | 4; + v11 = uW; + if ( (signed int)uW < v7 ) + LODWORD(v36) = v36 | 2; + if ( (signed int)uW > v9 ) + LODWORD(v36) = v36 | 1; + LOBYTE(v12) = v36; + if ( (unsigned int)v36 & HIDWORD(v36) ) + return v12; + if ( !v36 ) + { +LABEL_46: + v21 = pRenderer->uTargetSurfacePitch; + if ( pRenderer->uTargetSurfacePitch ) + { + v12 = uX + v8 * pRenderer->uTargetSurfacePitch; + v22 = v11 - v8; + v23 = v22; + uYb = v22; + if ( v22 < 0 ) + { + v23 = -v22; + uYb = -v22; + v21 = -pRenderer->uTargetSurfacePitch; + } + uXa = v10 - uX; + if ( (uXa & 0x80000000u) == 0 ) + { + v24 = 1; + } + else + { + uXa = -uXa; + v24 = -1; + } + v25 = 0; + v26 = v35->pTargetSurface; + if ( v26 ) + { + if ( (signed int)uXa <= v23 ) + { + v30 = v23 + 1; + if ( v30 > 0 ) + { + v31 = 2 * v24; + v32 = 2 * v21; + v12 = (int)&v26[v12]; + do + { + v25 += uXa; + *(short *)v12 = uColor; + v12 += v32; + if ( v25 > 0 ) + { + v25 -= uYb; + v12 += v31; + } + --v30; + } + while ( v30 ); + } + } + else + { + v27 = uXa + 1; + if ( (signed int)(uXa + 1) > 0 ) + { + v28 = 2 * v21; + v29 = 2 * v24; + v12 = (int)&v26[v12]; + do + { + v25 += uYb; + *(short *)v12 = uColor; + v12 += v29; + if ( v25 > (signed int)uXa ) + { + v25 -= uXa; + v12 += v28; + } + --v27; + } + while ( v27 ); + } + } + } + } + return v12; + } + if ( (BYTE4(v36) ^ (unsigned __int8)v36) & 8 ) + { + if ( BYTE4(v36) & 8 ) + { + v13 = (signed int)((uW - uY) * (v6 - uX)) / (signed int)(uZ - uX); + v14 = v35; + v8 = v13 + uY; + uX = v35->field_1C_clipx; + goto LABEL_24; + } + v10 = v6; + v11 = (signed int)((uY - uW) * (v6 - uZ)) / (signed int)(uX - uZ) + uW; + } + v14 = v35; +LABEL_24: + if ( (BYTE4(v36) ^ (unsigned __int8)v36) & 4 ) + { + v15 = v14->field_24_clipz; + if ( BYTE4(v36) & 4 ) + { + v14 = v35; + v8 += (signed int)((v11 - v8) * (v15 - uX)) / (signed int)(v10 - uX); + uX = v35->field_24_clipz; + } + else + { + v16 = (signed int)((v8 - v11) * (v15 - v10)) / (signed int)(uX - v10); + v10 = v14->field_24_clipz; + v11 += v16; + } + } + v17 = v14->field_20_clipy; + v37 = 0; + uYa = v14->field_20_clipy; + if ( (signed int)v8 < v17 ) + v37 = 2; + v18 = v14->field_28_clipw; + if ( (signed int)v8 > v18 ) + v37 |= 1u; + if ( (signed int)v11 >= v17 ) + v12 = 0; + else + v12 = 2; + if ( (signed int)v11 > v18 ) + LOBYTE(v12) = v12 | 1; + if ( !(v12 & v37) ) + { + v12 ^= v37; + uZa = v12; + if ( v12 & 2 ) + { + if ( v37 & 2 ) + { + uX += (signed int)((v10 - uX) * (uYa - v8)) / (signed int)(v11 - v8); + LOBYTE(v12) = (char)v35; + v8 = v35->field_20_clipy; + } + else + { + v19 = (signed int)((uX - v10) * (uYa - v11)); + v20 = v8 - v11; + v11 = uYa; + v12 = v19 / v20; + v10 += v12; + } + } + if ( uZa & 1 ) + { + if ( v37 & 1 ) + { + uX += (signed int)((v10 - uX) * (v35->field_28_clipw - v8)) / (signed int)(v11 - v8); + LOBYTE(v12) = (char)v35; + v8 = v35->field_28_clipw; + } + else + { + v12 = (signed int)((uX - v10) * (v35->field_28_clipw - v11)) / (signed int)(v8 - v11); + v11 = v35->field_28_clipw; + v10 += v12; + } + } + goto LABEL_46; + } + return v12; +} + + + +//----- (004A0E80) -------------------------------------------------------- +void Render::ClearZBuffer(int a2, int a3) +{ + memset32(this->pActiveZBuffer, -65536, 0x4B000u); +} + + + +//----- (004A0E97) -------------------------------------------------------- +void Render::Clip_v2(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW) +{ + this->field_1C_clipx = uX; + this->field_20_clipy = uY; + this->field_24_clipz = uZ; + this->field_28_clipw = uW; +} + + +//----- (004A0EB6) -------------------------------------------------------- +void Render::ParseTargetPixelFormat() +{ + Render *v1; // eax@1 + 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 + + v1 = this; + v2 = 0; + uRedMask = v1->ddpfPrimareSuface.dwRBitMask; + v1->uTargetBBits = 0; + v1->uTargetGBits = 0; + v1->uTargetRBits = 0; + do + { + if ( (1 << v2) & uRedMask ) + ++v1->uTargetRBits; + ++v2; + } + while ( v2 < 16 ); + uGreenMask = v1->ddpfPrimareSuface.dwGBitMask; + v5 = 0; + do + { + if ( (1 << v5) & uGreenMask ) + ++v1->uTargetGBits; + ++v5; + } + while ( v5 < 16 ); + uBlueMask = v1->ddpfPrimareSuface.dwBBitMask; + v7 = 0; + do + { + if ( (1 << v7) & uBlueMask ) + ++v1->uTargetBBits; + ++v7; + } + while ( v7 < 16 ); + v8 = v1->ddpfPrimareSuface.dwRBitMask; + v1->uTargetGMask = uGreenMask; + v1->uTargetRMask = v8; + v1->uTargetBMask = uBlueMask; +} + +//----- (004A0F40) -------------------------------------------------------- +bool Render::LockSurface_DDraw4(IDirectDrawSurface4 *pSurface, DDSURFACEDESC2 *pDesc, unsigned int uLockFlags) +{ + IDirectDrawSurface4 *v4; // esi@1 + bool result; // eax@1 + HRESULT v6; // eax@4 + int v7; // [sp-8h] [bp-14h]@10 + unsigned int v8; // [sp-4h] [bp-10h]@10 + char v9; // [sp+Bh] [bp-1h]@1 + + v4 = pSurface; + v9 = 1; + result = pSurface->Lock(0, pDesc, uLockFlags, 0); + if ( result == DDERR_SURFACELOST ) + { + if (pAsyncMouse) + pAsyncMouse->Suspend(); + v6 = v4->Restore(); + if ( v6 ) + { + if ( v6 != DDERR_IMPLICITLYCREATED ) + { +LABEL_20: + v9 = 0; + result = (bool)memset(pDesc, 0, 4u); + goto LABEL_21; + } + pRenderer->pFrontBuffer4->Restore(); + v4->Restore(); + } + result = v4->Lock(0, pDesc, DDLOCK_WAIT, 0); + if ( result == DDERR_INVALIDRECT || result == DDERR_SURFACEBUSY ) + goto LABEL_20; + 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); + goto LABEL_20; + } + if ( pRenderer->pRenderD3D ) + pRenderD3D->HandleLostResources(); + result = pRenderer->pDirectDraw4->RestoreAllSurfaces(); + if (pAsyncMouse) + pAsyncMouse->Resume(); + } + else + { + if ( result ) + { + if ( result == DDERR_INVALIDRECT || result == DDERR_SURFACEBUSY ) + goto LABEL_20; + ErrD3D(result); + //v8 = 0; + //v7 = 2199; + //goto LABEL_19; + } + } +LABEL_21: + LOBYTE(result) = v9; + return result; +} + + +//----- (004A1032) -------------------------------------------------------- +bool Render::LockSurface_DDraw2(IDirectDrawSurface2 *pSurface, DDSURFACEDESC *pDesc, unsigned int uLockFlags) +{ + IDirectDrawSurface2 *v4; // esi@1 + bool v5; // eax@1 + HRESULT v6; // eax@2 + int v7; // [sp-8h] [bp-10h]@8 + unsigned int v8; // [sp-4h] [bp-Ch]@8 + + v4 = pSurface; + v5 = pSurface->Lock( + 0, + pDesc, + uLockFlags, + 0); + BYTE3(pSurface) = 1; + if ( v5 == DDERR_SURFACELOST ) + { + v6 = v4->Restore(); + if ( !v6 ) + goto LABEL_5; + if ( v6 == DDERR_IMPLICITLYCREATED ) + { + pRenderer->pFrontBuffer2->Restore(); + v4->Restore(); +LABEL_5: + v5 = v4->Lock(0, pDesc, 1u, 0) != 0; + if ( v5 == DDERR_INVALIDRECT || v5 == DDERR_SURFACEBUSY ) + goto LABEL_14; + if ( !v5 ) + return true; + ErrD3D(v5); + //v8 = 0; + //v7 = 2247; + goto LABEL_13; + } + else + { + pDesc->dwSize = 0; + return false; + } + } + else + { + if ( !v5 ) + return true; + if ( v5 != DDERR_INVALIDRECT && v5 != DDERR_SURFACEBUSY ) + { + //v8 = 0; + //v7 = 2269; + ErrD3D(v5); + pDesc->dwSize = 0; + return false; +LABEL_13: + //CheckHRESULT((CheckHRESULT_stru0 *)&pSurface, v5, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Screen16.cpp", v7, v8); + goto LABEL_14; + } + } +LABEL_14: + 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)); + + pDirectDraw2 = nullptr; + pDirectDraw4 = nullptr; + + if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 ) + ErrD3D(lpDD->QueryInterface(IID_IDirectDraw4, (void **)&pDirectDraw4)); + else + ErrD3D(lpDD->QueryInterface(IID_IDirectDraw2, (void **)&pDirectDraw2)); + + lpDD->Release(); + lpDD = nullptr; +} + +//----- (004A1169) -------------------------------------------------------- +void Render::SetDirectDrawCooperationMode(HWND hWnd, bool bFullscreen) +{ + DWORD flags; // eax@1 + IDirectDraw *v4; // ecx@3 + HRESULT v5; // eax@5 + int v6; // [sp-8h] [bp-8h]@3 + unsigned int v7; // [sp-4h] [bp-4h]@3 + + flags = bFullscreen ? DDSCL_NORMAL | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN : + DDSCL_NORMAL; + + if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 ) + ErrD3D(pDirectDraw4->SetCooperativeLevel(hWnd, flags | DDSCL_MULTITHREADED)); + else + ErrD3D(pDirectDraw2->SetCooperativeLevel(hWnd, flags)); +} + +//----- (004A11C6) -------------------------------------------------------- +void Render::SetDirectDrawDisplayMode(unsigned int uWidth, unsigned int uHeight, unsigned int uBPP) +{ + if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 ) + ErrD3D(pDirectDraw4->SetDisplayMode(uWidth, uHeight, uBPP, 0, 0)); + else + ErrD3D(pDirectDraw2->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 + 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, 0x7Cu); + pDD = (IDirectDraw *)v1->pDirectDraw4; + a2.dwSize = 124; + a2.dwFlags = 1; + v7 = 0; + a2.ddsCaps.dwCaps = 512; + v6 = 2357; + pOutSurf = (IDirectDrawSurface **)&v1->pFrontBuffer4; + v4 = (struct _DDSURFACEDESC *)&a2; + } + else + { + memset(&a2.lPitch, 0, 0x6Cu); // DDSURFACEDESC here + pDD = (IDirectDraw *)v1->pDirectDraw2; + a2.lPitch = 108; + a2.dwBackBufferCount = 1; + v7 = 0; + a2.dwTextureStage = 512; + v6 = 2346; + pOutSurf = (IDirectDrawSurface **)&v1->pFrontBuffer2; + v4 = (struct _DDSURFACEDESC *)&a2.lPitch; + } + ErrD3D(pDD->CreateSurface(v4, pOutSurf, 0)); +} + +//----- (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, 0x7Cu); + v2 = (IDirectDraw *)v1->pDirectDraw4; + a2.dwSize = 124; + a2.dwFlags = 7; + v7 = 0; + a2.ddsCaps.dwCaps = 2112; + a2.dwWidth = 640; + a2.dwHeight = 480; + v6 = 2387; + ppBackBuffer = (IDirectDrawSurface **)&v1->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, 0)); +} + +//----- (004A139A) -------------------------------------------------------- +void Render::CreateDirectDrawPrimarySurface() +{ + Render *v1; // esi@1 + int v2; // ebx@3 + IDirectDraw2 *v3; // eax@3 + HRESULT v4; // eax@3 + IDirectDrawSurface *pFrontBuffer; // eax@3 + DDSCAPS2 *v6; // edx@3 + IDirectDraw4 *v7; // eax@4 + HRESULT v8; // eax@4 + int v9; // ST14_4@5 + IDirectDrawSurface *v10; // ST10_4@5 + HRESULT v11; // eax@5 + IDirectDrawSurface **ppBackBuffer; // [sp-4h] [bp-A4h]@3 + const char *v13; // [sp+0h] [bp-A0h]@0 + int v14; // [sp+4h] [bp-9Ch]@0 + unsigned int v15; // [sp+8h] [bp-98h]@0 + DDSURFACEDESC2 ddsd2; // [sp+Ch] [bp-94h]@3 + DDSCAPS2 v17; // [sp+88h] [bp-18h]@4 + int a4; // [sp+98h] [bp-8h]@3 + + v1 = this; + if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 ) + { + v2 = 0; + this->field_4004C = 1; + memset(&ddsd2, 0, 0x7Cu); + v7 = v1->pDirectDraw4; + ddsd2.dwBackBufferCount = 1; + ddsd2.dwSize = 0x7Cu; + ddsd2.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; + ddsd2.ddsCaps.dwCaps = DDSCAPS_COMPLEX | DDSCAPS_FLIP | DDSCAPS_3DDEVICE | DDSCAPS_PRIMARYSURFACE; + ErrD3D(v7->CreateSurface( + &ddsd2, + &pFrontBuffer4, + 0)); + pFrontBuffer = (IDirectDrawSurface *)v1->pFrontBuffer4; + ppBackBuffer = (IDirectDrawSurface **)&v1->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, + 0)); + + pFrontBuffer = (IDirectDrawSurface *)v1->pFrontBuffer2; + ppBackBuffer = (IDirectDrawSurface **)&v1->pBackBuffer2; + } + 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) +{ + if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 ) + { + ErrD3D(pDirectDraw4->CreateClipper(0, &pDDrawClipper, 0)); + ErrD3D(pDDrawClipper->SetHWnd(0, a2)); + ErrD3D(pFrontBuffer4->SetClipper(pDDrawClipper)); + } + else + { + ErrD3D(pDirectDraw2->CreateClipper(0, &pDDrawClipper, 0)); + ErrD3D(pDDrawClipper->SetHWnd(0, a2)); + } +} + +//----- (004A15D8) -------------------------------------------------------- +void Render::GetTargetPixelFormat(DDPIXELFORMAT *pOut) +{ + IDirectDrawSurface *v2; // eax@3 + + if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 ) + v2 = (IDirectDrawSurface *)this->pFrontBuffer4; + else + v2 = (IDirectDrawSurface *)this->pFrontBuffer2; + v2->GetPixelFormat(pOut); +} + +//----- (004A1605) -------------------------------------------------------- +void Render::LockRenderSurface(void **pOutSurfacePtr, unsigned int *pOutPixelsPerRow) +{ + Render *v3; // esi@1 + signed int v4; // eax@3 + + v3 = this; + if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 ) + { + DDSURFACEDESC2 pDesc; // [sp+4h] [bp-7Ch]@3 + memset(&pDesc, 0, 0x7Cu); + pDesc.dwSize = 124; + LockSurface_DDraw4(v3->pBackBuffer4, &pDesc, 1u); + *pOutSurfacePtr = pDesc.lpSurface; + v4 = pDesc.lPitch; + } + else + { + DDSURFACEDESC pDesc; // [sp+4h] [bp-7Ch]@3 + memset(&pDesc.lPitch, 0, 0x6Cu); + pDesc.lPitch = 108; + LockSurface_DDraw2(v3->pBackBuffer2, &pDesc, 1u); + *pOutSurfacePtr = (void *)pDesc.lpSurface; + v4 = pDesc.dwReserved; + } + *pOutPixelsPerRow = v4 >> 1; +} + +//----- (004A169E) -------------------------------------------------------- +bool Render::UsingDirect3D() +{ + return bUserDirect3D == 0; +} + + +//----- (004A16E1) -------------------------------------------------------- +void Render::UnlockBackBuffer() +{ + if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 ) + ErrD3D(pBackBuffer4->Unlock(0)); + else + ErrD3D(pBackBuffer2->Unlock(0)); +} + + +//----- (004A172E) -------------------------------------------------------- +void Render::LockFrontBuffer(void **pOutSurface, unsigned int *pOutPixelsPerRow) +{ + Render *v3; // esi@1 + signed int v4; // eax@3 + + v3 = this; + if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 ) + { + DDSURFACEDESC2 pDesc; // [sp+4h] [bp-7Ch]@3 + memset(&pDesc, 0, 0x7Cu); + pDesc.dwSize = 124; + LockSurface_DDraw4(v3->pFrontBuffer4, &pDesc, 1u); + *pOutSurface = pDesc.lpSurface; + v4 = pDesc.lPitch; + } + else + { + DDSURFACEDESC pDesc; // [sp+4h] [bp-7Ch]@3 + memset(&pDesc.lPitch, 0, 0x6Cu); + pDesc.lPitch = 108; + LockSurface_DDraw2(v3->pFrontBuffer2, &pDesc, 1u); + *pOutSurface = (void *)pDesc.lpSurface; + v4 = pDesc.dwReserved; + } + *pOutPixelsPerRow = v4 >> 1; +} + +//----- (004A17C7) -------------------------------------------------------- +void Render::UnlockFrontBuffer() +{ + IDirectDrawSurface *pFront; // eax@3 + HRESULT v2; // eax@5 + signed int v3; // [sp-8h] [bp-Ch]@3 + int v4; // [sp-4h] [bp-8h]@3 + + auto a5 = this; + if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 ) + { + pFront = (IDirectDrawSurface *)a5->pFrontBuffer4; + v4 = 0; + v3 = 2615; + } + else + { + pFront = (IDirectDrawSurface *)a5->pFrontBuffer2; + v4 = 0; + v3 = 2611; + } + ErrD3D(pFront->Unlock(0)); +} + + +//----- (004A1814) -------------------------------------------------------- +void Render::RestoreFrontBuffer() +{ + IDirectDrawSurface **v1; // esi@2 + + if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT + || (v1 = (IDirectDrawSurface **)&this->pFrontBuffer2, pVersion->pVersionInfo.dwMajorVersion >= 5u) ) + v1 = (IDirectDrawSurface **)&this->pFrontBuffer4; + if ( (*v1)->IsLost() == DDERR_SURFACELOST ) + (*v1)->Restore(); +} + + +//----- (004A184C) -------------------------------------------------------- +HRESULT Render::_4A184C() +{ + IDirectDrawSurface **pBack; // esi@2 + HRESULT result; // eax@4 + + if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT + || (pBack = (IDirectDrawSurface **)&this->pBackBuffer2, pVersion->pVersionInfo.dwMajorVersion != 4) ) + pBack = (IDirectDrawSurface **)&this->pBackBuffer4; + result = (*pBack)->IsLost(); + if ( result == DDERR_SURFACELOST ) + result = (*pBack)->Restore(); + return result; +} + +//----- (004A1884) -------------------------------------------------------- +void Render::PresentRect(RECT *a2, RECT *a3) +{ + IDirectDrawSurface *pFront; // eax@3 + HRESULT v4; // eax@5 + IDirectDrawSurface *pBack; // [sp-1Ch] [bp-1Ch]@3 + struct tagRECT *v6; // [sp-18h] [bp-18h]@3 + DWORD v7; // [sp-14h] [bp-14h]@3 + DDBLTFX *v8; // [sp-10h] [bp-10h]@3 + const char *v9; // [sp-Ch] [bp-Ch]@3 + int v10; // [sp-8h] [bp-8h]@3 + unsigned int v11; // [sp-4h] [bp-4h]@3 + + if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 ) + { + v11 = 0; + pFront = (IDirectDrawSurface *)this->pFrontBuffer4; + v10 = 2657; + v9 = "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Screen16.cpp"; + v8 = 0; + v7 = DDBLT_WAIT; + v6 = a3; + pBack = (IDirectDrawSurface *)this->pBackBuffer4; + } + else + { + v11 = 0; + pFront = (IDirectDrawSurface *)this->pFrontBuffer2; + v10 = 2653; + v9 = "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Screen16.cpp"; + v8 = 0; + v7 = DDBLT_WAIT; + v6 = a3; + pBack = (IDirectDrawSurface *)this->pBackBuffer2; + } + ErrD3D(pFront->Blt(a2, pBack, v6, v7, v8)); +} + + +//----- (004A18F5) -------------------------------------------------------- +void Render::BltToFront(RECT *pDstRect, IDirectDrawSurface *pSrcSurface, RECT *pSrcRect, unsigned int uBltFlags) +{ + IDirectDrawSurface *pFront; // eax@3 + HRESULT v6; // eax@5 + int v7; // [sp-8h] [bp-8h]@3 + unsigned int v8; // [sp-4h] [bp-4h]@3 + + if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion >= 5u ) + ErrD3D(pFrontBuffer4->Blt(pDstRect, (IDirectDrawSurface4 *)pSrcSurface, pSrcRect, uBltFlags, nullptr)); + else + ErrD3D(pFrontBuffer2->Blt(pDstRect, (IDirectDrawSurface2 *)pSrcSurface, pSrcRect, uBltFlags, nullptr)); +} + +//----- (004A194A) -------------------------------------------------------- +void Render::BltBackToFontFast(int a2, int a3, RECT *a4) +{ + IDirectDrawSurface *pFront; // eax@3 + IDirectDrawSurface *pBack; // [sp-Ch] [bp-Ch]@3 + RECT *v6; // [sp-8h] [bp-8h]@3 + DWORD v7; // [sp-4h] [bp-4h]@3 + + if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 ) + { + pFront = (IDirectDrawSurface *)this->pFrontBuffer4; + v7 = DDBLTFAST_WAIT; + v6 = a4; + pBack = (IDirectDrawSurface *)this->pBackBuffer4; + } + else + { + pFront = (IDirectDrawSurface *)this->pFrontBuffer2; + v7 = DDBLTFAST_WAIT; + v6 = a4; + pBack = (IDirectDrawSurface *)this->pBackBuffer2; + } + pFront->BltFast(0, 0, pBack, v6, v7); +} + +//----- (004A1B22) -------------------------------------------------------- +unsigned int Render::Billboard_ProbablyAddToListAndSortByZOrder(unsigned int a1) +{ + unsigned int v2; // ebx@1 + double v4; // st7@5 + unsigned int v5; // esi@5 + int v6; // ecx@5 + unsigned int v7; // edx@6 + char *v8; // ecx@12 + void *v9; // edi@16 + unsigned int v10; // eax@16 + void *v11; // edi@21 + unsigned int v12; // eax@21 + + v2 = pRenderer->uNumBillboardsToDraw; + if ( (signed int)pRenderer->uNumBillboardsToDraw >= 999 ) + return 0; + if ( !pRenderer->uNumBillboardsToDraw ) + { + pRenderer->uNumBillboardsToDraw = 1; + return 0; + } + v4 = *(float *)&a1; + v5 = pRenderer->uNumBillboardsToDraw; + v6 = 0; + if ( (signed int)pRenderer->uNumBillboardsToDraw <= 0 ) + { + v7 = a1; + } + else + { + do + { + v7 = v6 + (signed int)(v5 - v6) / 2; + if ( v4 <= pRenderer->pBillboardRenderListD3D[v6 + (signed int)(v5 - v6) / 2].flt_88 ) + v5 = v6 + (signed int)(v5 - v6) / 2; + else + v6 = v7 + 1; + } + while ( v6 < (signed int)v5 ); + } + v8 = (char *)&pRenderer->pBillboardRenderListD3D[v7].flt_88; + if ( v4 > *(float *)v8 ) + { + if ( v7 == pRenderer->uNumBillboardsToDraw - 1 ) + { + v7 = pRenderer->uNumBillboardsToDraw; + } + else + { + if ( (signed int)pRenderer->uNumBillboardsToDraw > (signed int)v7 ) + { + v9 = &pRenderer->pBillboardRenderListD3D[pRenderer->uNumBillboardsToDraw]; + v10 = pRenderer->uNumBillboardsToDraw - v7; + do + { + memcpy(v9, (char *)v9 - 156, 0x9Cu); + v9 = (char *)v9 - 156; + --v10; + } + while ( v10 ); + } + ++v7; + } +LABEL_23: + pRenderer->uNumBillboardsToDraw = v2 + 1; + return v7; + } + if ( v4 <= *(float *)v8 ) + { + if ( (signed int)pRenderer->uNumBillboardsToDraw > (signed int)v7 ) + { + v11 = &pRenderer->pBillboardRenderListD3D[pRenderer->uNumBillboardsToDraw]; + v12 = pRenderer->uNumBillboardsToDraw - v7; + do + { + memcpy(v11, (char *)v11 - 156, 0x9Cu); + v11 = (char *)v11 - 156; + --v12; + } + while ( v12 ); + } + goto LABEL_23; + } + return v7; +} + + +//----- (004A1E9D) -------------------------------------------------------- +unsigned int Render::GetBillboardDrawListSize() +{ + return pRenderer->uNumBillboardsToDraw; +} + +//----- (004A1EA3) -------------------------------------------------------- +unsigned int Render::GetParentBillboardID(unsigned int uBillboardID) +{ + return pRenderer->pBillboardRenderListD3D[uBillboardID].uParentBillboardID; +} + +//----- (004A1EB6) -------------------------------------------------------- +void Render::BeginSceneD3D() +{ + if (!uNumD3DSceneBegins++) + { + if (pRenderD3D) + { + pRenderD3D->ClearTarget(true, 0x00F08020, true, 1.0); + pRenderer->uNumBillboardsToDraw = 0; + pRenderD3D->pDevice->BeginScene(); + if (!pRenderD3D->DoesRaiseExceptions()) + { + MessageBoxW(nullptr, L"Error executing scratch 3D operations", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\screen16_3d.cpp:360", 0); + } + 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(); Ritor1: it's temporarily + pGame->pStru6Instance->RenderSpecialEffects(); + pRenderD3D->pDevice->EndScene(); + } + else + pGame->pStru6Instance->RenderSpecialEffects(); +} + + + +//----- (004A2031) -------------------------------------------------------- +unsigned int Render::GetActorTintColor(float a2, int a3, int a4, int a5, RenderBillboard *a6) +{ + return ::GetActorTintColor(a3, a4, a2, a5, a6); +} + + +//----- (004A26BC) -------------------------------------------------------- +void Render::DrawTerrainPolygon(unsigned int uNumVertices, stru148 *a4, IDirect3DTexture2 *a5, int a6, int a7) +{ + RenderVertexSoft *pVertices; // esi@0 + Render *v7; // edi@1 + unsigned int v8; // ebx@1 + LightmapBuilder *v9; // esi@3 + unsigned int v10; // edx@3 + int v11; // eax@5 + int v12; // eax@11 + char *v13; // esi@11 + double v14; // st7@13 + double v15; // st7@13 + signed int v16; // eax@13 + int v17; // ecx@13 + double v18; // st7@13 + float v19; // ST78_4@14 + int v20; // eax@14 + char v21; // zf@16 + HRESULT v22; // eax@17 + HRESULT v23; // eax@17 + HRESULT v24; // eax@19 + HRESULT v25; // eax@19 + unsigned int v26; // ecx@19 + char *v27; // eax@20 + HRESULT v28; // eax@22 + HRESULT v29; // eax@22 + HRESULT v30; // eax@23 + HRESULT v31; // eax@24 + HRESULT v32; // eax@24 + HRESULT v33; // eax@24 + HRESULT v34; // eax@24 + HRESULT v35; // eax@25 + HRESULT v36; // eax@25 + unsigned int v37; // ecx@25 + char *v38; // eax@26 + int v39; // edx@27 + HRESULT v40; // eax@28 + HRESULT v41; // eax@28 + HRESULT v42; // eax@28 + HRESULT v43; // eax@28 + //IDirect3DDevice3Vtbl *v44; // ebx@28 + unsigned int v45; // eax@28 + HRESULT v46; // eax@29 + HRESULT v47; // eax@29 + HRESULT v48; // eax@29 + IDirect3DDevice3 *v49; // eax@35 + //IDirect3DDevice3Vtbl *v50; // ecx@35 + int v51; // eax@40 + char *v52; // esi@40 + double v53; // st7@42 + double v54; // st7@42 + signed int v55; // eax@42 + int v56; // ecx@42 + double v57; // st7@42 + float v58; // ST7C_4@43 + int v59; // eax@43 + signed int v60; // [sp+78h] [bp-14h]@31 + RenderVertexSoft *v61; // [sp+7Ch] [bp-10h]@3 + const char *v62; // [sp+80h] [bp-Ch]@0 + const char *v63; // [sp+80h] [bp-Ch]@19 + int v64; // [sp+84h] [bp-8h]@0 + LightmapBuilder *v65; // [sp+88h] [bp-4h]@3 + unsigned int v66; // [sp+88h] [bp-4h]@40 + unsigned int a6a; // [sp+A0h] [bp+14h]@11 + + v7 = this; + v8 = 0; + if ( this->uNumD3DSceneBegins && (signed int)uNumVertices >= 3 ) + { + v61 = pVertices; + v9 = pGame->pLightmapBuilder; + v65 = v9; + v10 = v9->std__vector_000004_size; + if ( byte_4D864C && pGame->uFlags & 1 ) + { + v11 = GetActorTintColor(a4->field_58, 0, array_50AC10[0].vWorldViewPosition.x, 0, 0); + v9->_45D74F_MessWithLight(v11, 0); + } + else + { + if ( a6 || !v10 || byte_4D864C && pGame->uFlags & 2 ) + { + if ( (char)a7 ) + v60 = 3; + else + v60 = 1; + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, v60)); + if ( a6 || v7->bUsingSpecular ) + { + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, 1u)); + //v49 = v7->pRenderD3D->pDevice; + //v50 = v49->lpVtbl; + if ( a6 ) + { + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, 5)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 6)); + } + else + { + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, 2)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 1)); + } + + } + if ( (signed int)uNumVertices > 0 ) + { + v51 = (int)&arary_77E5C8[0].pos.y; + v52 = (char *)&array_50AC10[0].vWorldViewPosition; + a7 = (int)&arary_77E5C8[0].pos.y; + v66 = uNumVertices; + while ( 1 ) + { + v53 = *(float *)v52 * 1000.0; + *(int *)(v51 - 4) = *((int *)v52 + 3); + v54 = v53 / (double)pOutdoorCamera->shading_dist_mist; + *(int *)v51 = *((int *)v52 + 4); + *(float *)(v51 + 4) = 1.0 - 1.0 / v54; + *(float *)(v51 + 8) = 1.0 / (*(float *)v52 + 0.0000001); + v55 = GetActorTintColor(a4->field_58, 0, *(float *)v52, 0, 0); + v56 = a7; + v57 = *(float *)v52; + *(int *)(a7 + 12) = v55; + if ( v7->bUsingSpecular ) + { + v58 = v57; + v59 = sub_47C3D7_get_fog_related_stuff(0, 0, v58); + v56 = a7; + } + else + { + v59 = 0; + } + *(int *)(v56 + 16) = v59; + *(int *)(v56 + 20) = *((int *)v52 + 6); + *(int *)(v56 + 24) = *((int *)v52 + 7); + v52 += 48; + v21 = v66-- == 1; + a7 = v56 + 32; + if ( v21 ) + break; + v51 = a7; + } + } + ErrD3D(pRenderD3D->pDevice->SetTexture(0, a5)); + ErrD3D(pRenderD3D->pDevice->DrawPrimitive( + D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + arary_77E5C8, + uNumVertices, + 16)); + if ( a6 ) + { + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, 0)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, 2u)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 1u)); + } + } + else + { + if ( (signed int)uNumVertices > 0 ) + { + v12 = (int)&arary_77E5C8[0].pos.y; + v13 = (char *)&array_50AC10[0].vWorldViewPosition; + a7 = (int)&arary_77E5C8[0].pos.y; + a6a = uNumVertices; + while ( 1 ) + { + v14 = *(float *)v13 * 1000.0; + *(int *)(v12 - 4) = *((int *)v13 + 3); + v15 = v14 / (double)pOutdoorCamera->shading_dist_mist; + *(int *)v12 = *((int *)v13 + 4); + *(float *)(v12 + 4) = 1.0 - 1.0 / v15; + *(float *)(v12 + 8) = 1.0 / (*(float *)v13 + 0.0000001); + v16 = GetActorTintColor(a4->field_58, 0, *(float *)v13, 0, 0); + v17 = a7; + v18 = *(float *)v13; + *(int *)(a7 + 12) = v16; + if ( v7->bUsingSpecular ) + { + v19 = v18; + v20 = sub_47C3D7_get_fog_related_stuff(0, 0, v19); + v17 = a7; + } + else + { + v20 = 0; + } + *(int *)(v17 + 16) = v20; + *(int *)(v17 + 20) = *((int *)v13 + 6); + *(int *)(v17 + 24) = *((int *)v13 + 7); + v13 += 48; + v21 = a6a-- == 1; + a7 = v17 + 32; + if ( v21 ) + break; + v12 = a7; + } + } + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, 1u)); + if ( pRenderer->bUsingSpecular ) + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 0)); + + ErrD3D(pRenderD3D->pDevice->SetTexture(0, 0)); + ErrD3D(pRenderD3D->pDevice->DrawPrimitive( + D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + arary_77E5C8, + uNumVertices, + 16)); + //v63 = (const char *)v7->pRenderD3D->pDevice; + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, 1)); + //(*(void (**)(void))(*(int *)v63 + 88))(); + pGame->pLightmapBuilder->_45D74F_MessWithLight(-1, 0); + v26 = uNumVertices; + if ( (signed int)uNumVertices > 0 ) + { + v27 = (char *)&arary_77E5C8[0].diffuse; + do + { + *(int *)v27 = -1; + v27 += 32; + --v26; + } + while ( v26 ); + } + ErrD3D(pRenderD3D->pDevice->SetTexture(0, a5)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, 1u)); + if ( !pRenderer->bUsingSpecular ) + { + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, 1u)); + } + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, 1u)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, 1u)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 3u)); + ErrD3D(pRenderD3D->pDevice->DrawPrimitive( + D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + arary_77E5C8, + uNumVertices, + 16)); + if ( pRenderer->bUsingSpecular ) + { + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, 1u)); + ErrD3D(pRenderD3D->pDevice->SetTexture(0, 0)); + v37 = uNumVertices; + if ( (signed int)uNumVertices > 0 ) + { + v38 = (char *)&arary_77E5C8[0].specular; + do + { + v39 = *(int *)v38; + *(int *)v38 = 0; + v38 += 32; + --v37; + *((int *)v38 - 9) = pRenderer->uFogColor | v39 & 0xFF000000; + } + while ( v37 ); + } + ErrD3D(pRenderD3D->pDevice->SetTexture(0, 0)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, 6u)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 5u)); + ErrD3D(pRenderD3D->pDevice->DrawPrimitive( + D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + arary_77E5C8, + uNumVertices, + 16)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 1)); + //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, 2)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 1u)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, v8)); + } + } + if ( pIndoorCamera->field_4C & 2 || pBLVRenderParams->uFlags & 2 ) + pGame->pIndoorCameraD3D->debug_outline_d3d(arary_77E5C8, uNumVertices, 0xFFFFFFu, 0.0); + } +} +// 4A26BC: could not find valid save-restore pair for esi +// 4D864C: using guessed type char byte_4D864C; + + +//----- (004A2DA3) -------------------------------------------------------- +void Render::DrawFan(unsigned int uNumVertices, stru148 *a3, IDirect3DTexture2 *a4) +{ + Render *v4; // ebx@1 + char *v5; // esi@6 + char *v6; // edi@6 + double v7; // st7@7 + float v8; // ST34_4@7 + int v9; // eax@7 + signed int v10; // eax@7 + double v11; // st7@7 + int v12; // eax@7 + float v13; // ST3C_4@8 + unsigned int v14; // [sp+4Ch] [bp-4h]@6 + + v4 = this; + if ( this->uNumD3DSceneBegins && (signed int)uNumVertices >= 3 ) + { + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, 1u)); + if ( v4->bUsingSpecular ) + { + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, 1u)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, 2u)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 1u)); + } + if ( (signed int)uNumVertices > 0 ) + { + v5 = (char *)&arary_77E5C8[0].pos.y; + v6 = (char *)&array_50AC10[0].vWorldViewProjY; + v14 = uNumVertices; + do + { + v7 = *((float *)v6 - 4); + *((int *)v5 - 1) = *((int *)v6 - 1); + v8 = v7; + *(int *)v5 = *(int *)v6; + v9 = *((int *)v6 + 1); + *((int *)v5 + 1) = 0x3F7FF972u; + *((int *)v5 + 2) = v9; + v10 = GetActorTintColor(31, 0, v8, 1, 0); + v11 = *((float *)v6 - 4); + *((int *)v5 + 3) = v10; + v12 = 0; + if ( v4->bUsingSpecular ) + { + v13 = v11; + v12 = sub_47C3D7_get_fog_related_stuff(0, 1, v13); + } + *((int *)v5 + 4) = v12; + *((int *)v5 + 5) = *((int *)v6 + 2); + *((int *)v5 + 6) = *((int *)v6 + 3); + v6 += 48; + v5 += 32; + --v14; + } + while ( v14 ); + } + ErrD3D(pRenderD3D->pDevice->SetTexture(0, a4)); + ErrD3D(pRenderD3D->pDevice->DrawPrimitive( + D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + arary_77E5C8, + uNumVertices, + 24)); + } +} + + +//----- (004A2ED5) -------------------------------------------------------- +void Render::_4A2ED5(signed int a2, stru148 *a3, IDirect3DTexture2 *pHwTex) +{ + signed int v4; // edi@2 + int v5; // eax@3 + int v6; // edx@5 + char *v7; // eax@6 + char *v8; // ecx@6 + double v9; // st6@7 + int v10; // ebx@7 + int v11; // ebx@7 + + if ( this->uNumD3DSceneBegins ) + { + v4 = a2; + if ( a2 >= 3 ) + { + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, 1u)); + v5 = 31 - (a3->field_58 & 0x1F); + if ( v5 < pOutdoor->field_CBC_terrain_triangles_shade_type ) + v5 = pOutdoor->field_CBC_terrain_triangles_shade_type; + v6 = 8 * v5 | ((8 * v5 | (v5 << 11)) << 8); + if ( a2 > 0 ) + { + v7 = (char *)&arary_77E5C8[0].pos.y; + v8 = (char *)&array_507D30[0].vWorldViewProjY; + do + { + v9 = *((float *)v8 - 4) * 0.061758894; + v10 = *((int *)v8 - 1); + *((int *)v7 + 4) = 0; + *((int *)v7 - 1) = v10; + *(int *)v7 = *(int *)v8; + *((int *)v7 + 2) = *((int *)v8 + 1); + *((int *)v7 + 5) = *((int *)v8 + 2); + v11 = *((int *)v8 + 3); + *((int *)v7 + 3) = v6; + *((int *)v7 + 6) = v11; + v8 += 48; + v7 += 32; + --v4; + *((float *)v7 - 7) = 1.0 - 1.0 / v9; + } + while ( v4 ); + } + ErrD3D(pRenderD3D->pDevice->SetTexture(0, pHwTex)); + ErrD3D(pRenderD3D->pDevice->DrawPrimitive( + D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + arary_77E5C8, + a2, + 28)); + } + } +} + + + +//----- (004A2FC0) -------------------------------------------------------- +void Render::DrawIndoorPolygon(unsigned int uNumVertices, BLVFace *pFace, IDirect3DTexture2 *pHwTex, Texture *pTex, int uPackedID, unsigned int uColor, int a8) +{ + //Render *v8; // edi@1 + //unsigned int v9; // esi@3 + char *v12; // ecx@9 + char *v13; // eax@9 + double v14; // st6@10 + int v15; // edx@10 + Texture *v16; // edx@10 + double v17; // st6@10 + //char v18; // zf@10 + Texture *v19; // edx@10 + Texture *v23; // edx@16 + char *v24; // ecx@16 + char *v25; // eax@16 + double v26; // st6@17 + int v27; // esi@17 + double v28; // st6@17 + unsigned int v33; // ecx@18 + char *v34; // eax@19 + //Texture *v45; // edx@23 + //char *v46; // ecx@23 + //char *v47; // eax@23 + //double v48; // st6@24 + //int v49; // esi@24 + //double v50; // st6@24 + const char *v53; // [sp-Ch] [bp-20h]@21 + //int v54; // [sp-8h] [bp-1Ch]@21 + //unsigned int v55; // [sp-4h] [bp-18h]@21 + const char *v56; // [sp+0h] [bp-14h]@0 + int v57; // [sp+4h] [bp-10h]@0 + unsigned int v58; // [sp+8h] [bp-Ch]@0 + //LightmapBuilder *v59; // [sp+Ch] [bp-8h]@3 + //int a3a; // [sp+10h] [bp-4h]@4 + + //v8 = this; + if (!uNumD3DSceneBegins || uNumVertices < 3) + return; + + //auto a3 = pFace; + //auto a6 = uPackedID; + //v59 = pGame->pLightmapBuilder; + //v9 = v59->std__vector_000004_size; + + auto uCorrectedColor = uColor; + if (pGame->pLightmapBuilder->std__vector_000004_size) + uCorrectedColor = 0xFFFFFFFF; + pGame->AlterGamma(pFace, &uCorrectedColor); + + if (byte_4D864C && pGame->uFlags & 1) + { + __debugbreak(); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, 1)); + if ( (signed int)uNumVertices > 0 ) + { + v12 = (char *)&array_507D30[0].vWorldViewPosition; + v13 = (char *)&arary_77E5C8[0].pos.y; + auto a7 = uNumVertices; + uint v18; + do + { + v14 = *(float *)v12 * 0.061758894; + v15 = *((int *)v12 + 3); + *((int *)v13 + 4) = 0; + *((int *)v13 - 1) = v15; + *(int *)v13 = *((int *)v12 + 4); + *((int *)v13 + 3) = uCorrectedColor; + v16 = pTex; + v13 += 32; + *((float *)v13 - 7) = 1.0 - 1.0 / v14; + v17 = 1.0 / *(float *)v12; + v12 += 48; + v18 = a7-- == 1; + *((float *)v13 - 6) = v17; + pHwTex = (IDirect3DTexture2 *)v16->uTextureWidth; + v19 = pTex; + *((float *)v13 - 3) = *((float *)v12 - 6) / (double)(signed int)pHwTex; + pHwTex = (IDirect3DTexture2 *)v19->uTextureHeight; + *((float *)v13 - 2) = *((float *)v12 - 5) / (double)(signed int)pHwTex; + } + while ( !v18 ); + } + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, 1)); + ErrD3D(pRenderD3D->pDevice->SetTexture(0, nullptr)); + ErrD3D(pRenderD3D->pDevice->DrawPrimitive( + D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + arary_77E5C8, + uNumVertices, + 28)); + pGame->pLightmapBuilder->_45D74F_MessWithLight(-1, 0); + } + else + { + if (!pGame->pLightmapBuilder->std__vector_000004_size || + byte_4D864C && pGame->uFlags & 2) + { + for (uint i = 0; i < uNumVertices; ++i) + { + arary_77E5C8[i].pos.x = array_507D30[i].vWorldViewProjX; + arary_77E5C8[i].pos.y = array_507D30[i].vWorldViewProjY; + arary_77E5C8[i].pos.z = 1.0 - 1.0 / (array_507D30[i].vWorldViewPosition.x * 0.061758894); + arary_77E5C8[i].rhw = 1.0 / array_507D30[i].vWorldViewPosition.x; + arary_77E5C8[i].diffuse = uCorrectedColor; + arary_77E5C8[i].specular = 0; + arary_77E5C8[i].texcoord.x = array_507D30[i].u / (double)pTex->uTextureWidth; + arary_77E5C8[i].texcoord.y = array_507D30[i].v / (double)pTex->uTextureHeight; + } + + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, 1)); + ErrD3D(pRenderD3D->pDevice->SetTexture(0, pHwTex)); + ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + arary_77E5C8, + uNumVertices, + 28)); + } + else + { + __debugbreak(); + if ( (signed int)uNumVertices > 0 ) + { + v23 = pTex; + v24 = (char *)&array_507D30[0].vWorldViewPosition; + v25 = (char *)&arary_77E5C8[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, 1)); + ErrD3D(pRenderD3D->pDevice->SetTexture(0, nullptr)); + ErrD3D(pRenderD3D->pDevice->DrawPrimitive( + D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + arary_77E5C8, + uNumVertices, + 28)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, 1)); + pGame->pLightmapBuilder->_45D74F_MessWithLight(-1, 0); + v33 = uNumVertices; + if ( (signed int)uNumVertices > 0 ) + { + v34 = (char *)&arary_77E5C8[0].diffuse; + do + { + *(int *)v34 = uCorrectedColor; + v34 += 32; + --v33; + } + while ( v33 ); + } + ErrD3D(pRenderD3D->pDevice->SetTexture(0, pHwTex)); + ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, 1)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, 1u)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, true)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, 1)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 3)); + ErrD3D(pRenderD3D->pDevice->DrawPrimitive( + D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + arary_77E5C8, + uNumVertices, + 28)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, 2)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 1)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, false)); + } + } +} +// 4D864C: using guessed type char byte_4D864C; + + +//----- (004A43B1) -------------------------------------------------------- +void Render::DrawBillboard_Indoor(RenderBillboardTransform_local0 *pSoftBillboard, Sprite *a3, int uPaletteSubindex) +{ + RenderBillboardTransform_local0 *v4; // ebx@2 + double v5; // st7@2 + float v6; // ST08_4@2 + unsigned int v7; // eax@2 + int v8; // ecx@2 + unsigned int v9; // esi@2 + Sprite *v10; // edi@5 + signed int v11; // eax@9 + signed int v12; // eax@9 + double v13; // st7@12 + double v14; // st6@12 + 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 + IDirect3DTexture2 *v23; // eax@18 + signed int v24; // [sp+18h] [bp-18h]@5 + signed int v25; // [sp+1Ch] [bp-14h]@5 + Render *v26; // [sp+20h] [bp-10h]@1 + float v27; // [sp+24h] [bp-Ch]@5 + int v28; // [sp+28h] [bp-8h]@2 + float v29; // [sp+2Ch] [bp-4h]@5 + float pSoftBillboarda; // [sp+38h] [bp+8h]@2 + float v31; // [sp+3Ch] [bp+Ch]@5 + float v32; // [sp+3Ch] [bp+Ch]@12 + float a1; // [sp+40h] [bp+10h]@5 + + v26 = this; + if ( this->uNumD3DSceneBegins ) + { + v4 = pSoftBillboard; + v5 = (double)HIWORD(pSoftBillboard->sZValue); + pSoftBillboarda = v5; + v6 = v5; + v7 = Billboard_ProbablyAddToListAndSortByZOrder(LODWORD(v6)); + v8 = uPaletteSubindex; + v9 = v7; + v28 = uPaletteSubindex & 0xFF000000; + if ( uPaletteSubindex & 0xFF000000 ) + pBillboardRenderListD3D[v9].uOpacity = RenderBillboardD3D::Opaque_3; + else + pBillboardRenderListD3D[v9].uOpacity = RenderBillboardD3D::Transparent; + v10 = a3; + pBillboardRenderListD3D[v9].field_90 = v4->field_44; + pBillboardRenderListD3D[v9].sZValue = v4->sZValue; + pBillboardRenderListD3D[v9].uParentBillboardID = v4->uParentBillboardID; + v25 = v4->uScreenSpaceX; + v24 = v4->uScreenSpaceY; + a1 = (double)(v4->field_10 & 0xFFFF) * 0.000015260186 + (double)HIWORD(v4->field_10); + v29 = (double)(v4->field_14 & 0xFFFF) * 0.000015260186 + (double)HIWORD(v4->field_14); + v31 = (double)((v10->uBufferWidth >> 1) - v10->uAreaX); + v27 = (double)(v10->uBufferHeight - v10->uAreaY); + if ( v4->uFlags & 4 ) + v31 = v31 * -1.0; + if ( v4->uTintColor && v26->bTinting ) + { + v11 = GetActorTintColor(v8, 0, pSoftBillboarda, 0, 0); + v12 = sub_4A19D8(v4->uTintColor, v11); + if ( v28 ) + v12 = (unsigned int)((char *)&array_77EC08[1852].pEdgeList1[17] + 3) & ((unsigned int)v12 >> 1); + } + else + { + v12 = GetActorTintColor(v8, 0, pSoftBillboarda, 0, 0); + } + v13 = (double)v25; + pBillboardRenderListD3D[v9].pQuards[0].specular = 0; + pBillboardRenderListD3D[v9].pQuards[0].diffuse = v12; + pBillboardRenderListD3D[v9].pQuards[0].pos.x = v13 - v31 * a1; + v14 = (double)v24; + v32 = v14; + pBillboardRenderListD3D[v9].pQuards[0].pos.y = v14 - v27 * v29; + v15 = 1.0 - 1.0 / (pSoftBillboarda * 0.061758894); + pBillboardRenderListD3D[v9].pQuards[0].pos.z = v15; + v16 = 1.0 / pSoftBillboarda; + pBillboardRenderListD3D[v9].pQuards[0].rhw = 1.0 / pSoftBillboarda; + pBillboardRenderListD3D[v9].pQuards[0].texcoord.x = 0.0; + pBillboardRenderListD3D[v9].pQuards[0].texcoord.y = 0.0; + v17 = (double)((v10->uBufferWidth >> 1) - v10->uAreaX); + v18 = (double)(v10->uBufferHeight - v10->uAreaY - v10->uAreaHeight); + if ( v4->uFlags & 4 ) + v17 = v17 * -1.0; + pBillboardRenderListD3D[v9].pQuards[1].specular = 0; + pBillboardRenderListD3D[v9].pQuards[1].diffuse = v12; + pBillboardRenderListD3D[v9].pQuards[1].pos.x = v13 - v17 * a1; + pBillboardRenderListD3D[v9].pQuards[1].pos.y = v32 - v18 * v29; + pBillboardRenderListD3D[v9].pQuards[1].pos.z = v15; + pBillboardRenderListD3D[v9].pQuards[1].rhw = v16; + pBillboardRenderListD3D[v9].pQuards[1].texcoord.x = 0.0; + pBillboardRenderListD3D[v9].pQuards[1].texcoord.y = 1.0; + v19 = v10->uBufferHeight - v10->uAreaY - v10->uAreaHeight; + v20 = (double)(v10->uAreaX + v10->uAreaWidth + (v10->uBufferWidth >> 1) - v10->uBufferWidth); + if ( v4->uFlags & 4 ) + v20 = v20 * -1.0; + pBillboardRenderListD3D[v9].pQuards[2].specular = 0; + pBillboardRenderListD3D[v9].pQuards[2].diffuse = v12; + pBillboardRenderListD3D[v9].pQuards[2].pos.x = v20 * a1 + v13; + pBillboardRenderListD3D[v9].pQuards[2].pos.y = v32 - (double)v19 * v29; + pBillboardRenderListD3D[v9].pQuards[2].pos.z = v15; + pBillboardRenderListD3D[v9].pQuards[2].rhw = v16; + pBillboardRenderListD3D[v9].pQuards[2].texcoord.x = 1.0; + pBillboardRenderListD3D[v9].pQuards[2].texcoord.y = 1.0; + v21 = v10->uBufferHeight - v10->uAreaY; + v22 = (double)(v10->uAreaX + v10->uAreaWidth + (v10->uBufferWidth >> 1) - v10->uBufferWidth); + if ( v4->uFlags & 4 ) + v22 = v22 * -1.0; + pBillboardRenderListD3D[v9].pQuards[3].specular = 0; + pBillboardRenderListD3D[v9].pQuards[3].diffuse = v12; + pBillboardRenderListD3D[v9].pQuards[3].pos.x = v22 * a1 + v13; + pBillboardRenderListD3D[v9].pQuards[3].pos.y = v32 - (double)v21 * v29; + pBillboardRenderListD3D[v9].pQuards[3].pos.z = v15; + pBillboardRenderListD3D[v9].pQuards[3].rhw = v16; + pBillboardRenderListD3D[v9].pQuards[3].texcoord.x = 1.0; + pBillboardRenderListD3D[v9].pQuards[3].texcoord.y = 0.0; + v23 = v10->pTexture; + pBillboardRenderListD3D[v9].uNumVertices = 4; + pBillboardRenderListD3D[v9].flt_88 = pSoftBillboarda; + pBillboardRenderListD3D[v9].pTexture = v23; + } +} + + + +//----- (004A354F) -------------------------------------------------------- +void Render::MakeParticleBillboardAndPush_BLV(RenderBillboardTransform_local0 *a2, IDirect3DTexture2 *a3, unsigned int uDiffuse, int angle) +{ + double v5; // st7@3 + float v6; // ST20_4@3 + float v7; // ST00_4@3 + unsigned int v8; // esi@3 + int v9; // eax@3 + int v10; // ebx@3 + float v11; // ST28_4@3 + double v12; // st7@3 + float v13; // ST24_4@3 + double v14; // st6@3 + float v15; // ST1C_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 ( HIWORD(a2->sZValue) ) + { + v5 = (double)HIWORD(a2->sZValue); + v6 = v5; + v7 = v5; + v8 = Billboard_ProbablyAddToListAndSortByZOrder(LODWORD(v7)); + pBillboardRenderListD3D[v8].uOpacity = RenderBillboardD3D::Opaque_1; + pBillboardRenderListD3D[v8].field_90 = a2->field_44; + pBillboardRenderListD3D[v8].sZValue = a2->sZValue; + pBillboardRenderListD3D[v8].uParentBillboardID = a2->uParentBillboardID; + v9 = a2->uScreenSpaceX; + v10 = a2->uScreenSpaceY; + v11 = (double)(a2->field_10 & 0xFFFF) * 0.000015260186 + (double)HIWORD(a2->field_10); + v12 = (double)v9; + v13 = v12; + v14 = (double)(v10 - 12); + v15 = v14; + v16 = (double)(v9 - 12) - v12; + v17 = (double)(v10 - 25) - v14; + v18 = stru_5C6E00->SinCos(angle); + v19 = stru_5C6E00->SinCos(angle - stru_5C6E00->uIntegerHalfPi); + v20 = stru_5C6E00->SinCos(angle - stru_5C6E00->uIntegerHalfPi); + v21 = stru_5C6E00->SinCos(angle); + pBillboardRenderListD3D[v8].pQuards[0].pos.x = (((double)(unsigned __int16)v18 * 0.000015259022 + + (double)(v18 >> 16)) + * v16 + - ((double)(unsigned __int16)v19 * 0.000015259022 + + (double)(v19 >> 16)) + * v17) + * v11 + v13; + 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].pQuards[0].specular = 0; + pBillboardRenderListD3D[v8].pQuards[0].diffuse = uDiffuse; + pBillboardRenderListD3D[v8].pQuards[0].pos.y = v22; + pBillboardRenderListD3D[v8].pQuards[0].pos.z = 1.0 - 1.0 / (v6 * 0.061758894); + pBillboardRenderListD3D[v8].pQuards[0].rhw = 1.0 / v6; + pBillboardRenderListD3D[v8].pQuards[0].texcoord.x = 0.0; + pBillboardRenderListD3D[v8].pQuards[0].texcoord.y = 0.0; + v31 = (double)(a2->uScreenSpaceX + 12) - v13; + v32 = (double)a2->uScreenSpaceY - v15; + v25 = stru_5C6E00->SinCos(angle); + v26 = stru_5C6E00->SinCos(angle - stru_5C6E00->uIntegerHalfPi); + v27 = stru_5C6E00->SinCos(angle - stru_5C6E00->uIntegerHalfPi); + v28 = stru_5C6E00->SinCos(angle); + pBillboardRenderListD3D[v8].pQuards[1].pos.x = (((double)(unsigned __int16)v25 * 0.000015259022 + + (double)(v25 >> 16)) + * v23 + - ((double)(unsigned __int16)v26 * 0.000015259022 + + (double)(v26 >> 16)) + * v24) + * v11 + v13; + v29 = (((double)(unsigned __int16)v28 * 0.000015259022 + (double)(v28 >> 16)) * v24 + + ((double)(unsigned __int16)v27 * 0.000015259022 + (double)(v27 >> 16)) * v23 + - 12.0) + * v11 + + (double)a2->uScreenSpaceY; + pBillboardRenderListD3D[v8].pQuards[1].pos.z = pRenderer->pBillboardRenderListD3D[v8].pQuards[0].pos.z; + v30 = pBillboardRenderListD3D[v8].pQuards[0].rhw; + pBillboardRenderListD3D[v8].pQuards[1].pos.y = v29; + pBillboardRenderListD3D[v8].pQuards[1].specular = 0; + pBillboardRenderListD3D[v8].pQuards[1].rhw = v30; + pBillboardRenderListD3D[v8].pQuards[1].diffuse = uDiffuse; + pBillboardRenderListD3D[v8].pQuards[1].texcoord.x = 0.0; + pBillboardRenderListD3D[v8].pQuards[1].texcoord.y = 1.0; + v23 = (double)(a2->uScreenSpaceX - 12) - v13; + v24 = (double)a2->uScreenSpaceY - v15; + v33 = stru_5C6E00->SinCos(angle); + v34 = stru_5C6E00->SinCos(angle - stru_5C6E00->uIntegerHalfPi); + v35 = stru_5C6E00->SinCos(angle - stru_5C6E00->uIntegerHalfPi); + v36 = stru_5C6E00->SinCos(angle); + pBillboardRenderListD3D[v8].pQuards[2].pos.x = (((double)(unsigned __int16)v33 * 0.000015259022 + + (double)(v33 >> 16)) + * v31 + - ((double)(unsigned __int16)v34 * 0.000015259022 + + (double)(v34 >> 16)) + * v32) + * v11 + v13; + v37 = pBillboardRenderListD3D[v8].pQuards[0].pos.z; + v38 = (((double)(unsigned __int16)v36 * 0.000015259022 + (double)(v36 >> 16)) * v32 + + ((double)(unsigned __int16)v35 * 0.000015259022 + (double)(v35 >> 16)) * v31 + - 12.0) + * v11 + + (double)a2->uScreenSpaceY; + pBillboardRenderListD3D[v8].pQuards[2].specular = 0; + pBillboardRenderListD3D[v8].pQuards[2].pos.z = v37; + pBillboardRenderListD3D[v8].pQuards[2].rhw = pBillboardRenderListD3D[v8].pQuards[0].rhw; + pBillboardRenderListD3D[v8].pQuards[2].diffuse = uDiffuse; + pBillboardRenderListD3D[v8].pQuards[2].pos.y = v38; + pBillboardRenderListD3D[v8].pQuards[2].texcoord.x = 1.0; + pBillboardRenderListD3D[v8].pQuards[2].texcoord.y = 1.0; + v39 = (double)(a2->uScreenSpaceX + 12) - v13; + v40 = (double)(a2->uScreenSpaceY - 25) - v15; + v41 = stru_5C6E00->SinCos(angle); + v42 = stru_5C6E00->SinCos(angle - stru_5C6E00->uIntegerHalfPi); + v43 = stru_5C6E00->SinCos(angle - stru_5C6E00->uIntegerHalfPi); + v44 = stru_5C6E00->SinCos(angle); + pBillboardRenderListD3D[v8].pQuards[3].pos.x = (((double)(unsigned __int16)v41 * 0.000015259022 + + (double)(v41 >> 16)) + * v39 + - ((double)(unsigned __int16)v42 * 0.000015259022 + + (double)(v42 >> 16)) + * v40) + * v11 + v13; + 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].pQuards[0].pos.z; + pBillboardRenderListD3D[v8].pQuards[3].specular = 0; + pBillboardRenderListD3D[v8].pQuards[3].pos.z = v46; + pBillboardRenderListD3D[v8].pQuards[3].rhw = pBillboardRenderListD3D[v8].pQuards[0].rhw; + pBillboardRenderListD3D[v8].pQuards[3].diffuse = uDiffuse; + pBillboardRenderListD3D[v8].pTexture = a3; + pBillboardRenderListD3D[v8].flt_88 = v6; + pBillboardRenderListD3D[v8].uNumVertices = 4; + pBillboardRenderListD3D[v8].pQuards[3].pos.y = v45; + pBillboardRenderListD3D[v8].pQuards[3].texcoord.x = 1.0; + pBillboardRenderListD3D[v8].pQuards[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)HIWORD(a2->sZValue); + v6 = v5; + v7 = v5; + v8 = Billboard_ProbablyAddToListAndSortByZOrder(LODWORD(v7)); + pBillboardRenderListD3D[v8].uOpacity = RenderBillboardD3D::Opaque_1; + pBillboardRenderListD3D[v8].field_90 = a2->field_44; + pBillboardRenderListD3D[v8].sZValue = a2->sZValue; + pBillboardRenderListD3D[v8].uParentBillboardID = a2->uParentBillboardID; + v9 = a2->uScreenSpaceX; + v10 = a2->uScreenSpaceY; + v11 = (double)(a2->field_10 & 0xFFFF) * 0.000015260186 + (double)HIWORD(a2->field_10); + v12 = (double)v9; + v13 = v12; + v14 = (double)(v10 - 12); + v15 = v14; + v16 = (double)(v9 - 12) - v12; + v17 = (double)(v10 - 25) - v14; + v18 = stru_5C6E00->SinCos(angle); + v19 = angle - stru_5C6E00->uIntegerHalfPi; + v20 = stru_5C6E00->SinCos(angle - stru_5C6E00->uIntegerHalfPi); + v21 = stru_5C6E00->SinCos(v19); + v22 = stru_5C6E00->SinCos(angle); + pBillboardRenderListD3D[v8].pQuards[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].pQuards[0].specular = 0; + pBillboardRenderListD3D[v8].pQuards[0].diffuse = uDiffuse; + pBillboardRenderListD3D[v8].pQuards[0].pos.y = v23; + v24 = 1.0 - 1.0 / (v6 * 1000.0 / (double)pOutdoorCamera->shading_dist_mist); + pBillboardRenderListD3D[v8].pQuards[0].pos.z = v24; + v25 = 1.0 / v6; + pBillboardRenderListD3D[v8].pQuards[0].rhw = v25; + pBillboardRenderListD3D[v8].pQuards[0].texcoord.x = 0.0; + pBillboardRenderListD3D[v8].pQuards[0].texcoord.y = 0.0; + v26 = (double)(a2->uScreenSpaceX - 12) - v13; + v27 = (double)a2->uScreenSpaceY - v15; + v28 = stru_5C6E00->SinCos(angle); + v29 = stru_5C6E00->SinCos(v19); + v30 = stru_5C6E00->SinCos(v19); + v31 = stru_5C6E00->SinCos(angle); + pBillboardRenderListD3D[v8].pQuards[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].pQuards[1].pos.z = v24; + pBillboardRenderListD3D[v8].pQuards[1].pos.y = v32; + pBillboardRenderListD3D[v8].pQuards[1].specular = 0; + pBillboardRenderListD3D[v8].pQuards[1].rhw = v25; + pBillboardRenderListD3D[v8].pQuards[1].diffuse = uDiffuse; + pBillboardRenderListD3D[v8].pQuards[1].texcoord.x = 0.0; + pBillboardRenderListD3D[v8].pQuards[1].texcoord.y = 1.0; + v33 = (double)(a2->uScreenSpaceX + 12) - v13; + v34 = (double)a2->uScreenSpaceY - v15; + v35 = stru_5C6E00->SinCos(angle); + v36 = stru_5C6E00->SinCos(v19); + v37 = stru_5C6E00->SinCos(v19); + v38 = stru_5C6E00->SinCos(angle); + pBillboardRenderListD3D[v8].pQuards[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].pQuards[2].specular = 0; + pBillboardRenderListD3D[v8].pQuards[2].pos.z = v24; + pBillboardRenderListD3D[v8].pQuards[2].rhw = v25; + pBillboardRenderListD3D[v8].pQuards[2].diffuse = uDiffuse; + pBillboardRenderListD3D[v8].pQuards[2].pos.y = v39; + pBillboardRenderListD3D[v8].pQuards[2].texcoord.x = 1.0; + pBillboardRenderListD3D[v8].pQuards[2].texcoord.y = 1.0; + v40 = (double)(a2->uScreenSpaceX + 12) - v13; + v41 = (double)(a2->uScreenSpaceY - 25) - v15; + v42 = stru_5C6E00->SinCos(angle); + v43 = stru_5C6E00->SinCos(v19); + v44 = stru_5C6E00->SinCos(v19); + v45 = stru_5C6E00->SinCos(angle); + pBillboardRenderListD3D[v8].pQuards[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].pQuards[3].specular = 0; + pBillboardRenderListD3D[v8].pQuards[3].pos.z = v24; + pBillboardRenderListD3D[v8].pQuards[3].rhw = v25; + pBillboardRenderListD3D[v8].pQuards[3].diffuse = uDiffuse; + pBillboardRenderListD3D[v8].pTexture = a3; + pBillboardRenderListD3D[v8].flt_88 = v6; + pBillboardRenderListD3D[v8].uNumVertices = 4; + pBillboardRenderListD3D[v8].pQuards[3].pos.y = v46; + pBillboardRenderListD3D[v8].pQuards[3].texcoord.x = 1.0; + pBillboardRenderListD3D[v8].pQuards[3].texcoord.y = 0.0; + } +} + + +//----- (004A4023) -------------------------------------------------------- +void Render::TransformBillboard(RenderBillboardTransform_local0 *a2, Sprite *pSprite, int a1a, RenderBillboard *pBillboard) +{ + RenderBillboardTransform_local0 *v5; // ebx@2 + double v6; // st7@2 + float v7; // ST08_4@2 + unsigned int v8; // esi@2 + Sprite *v9; // edi@5 + signed int v10; // eax@9 + signed int v11; // eax@9 + int v12; // eax@12 + double v13; // st7@12 + double v14; // st6@14 + double v15; // st5@14 + unsigned int v16; // ecx@16 + double v17; // st7@16 + double v18; // st5@16 + double v19; // st4@16 + double v20; // st5@18 + double v21; // st4@18 + IDirect3DTexture2 *v22; // eax@20 + signed int v23; // [sp+18h] [bp-18h]@5 + signed int v24; // [sp+1Ch] [bp-14h]@5 + float v25; // [sp+1Ch] [bp-14h]@12 + float v26; // [sp+20h] [bp-10h]@5 + float v27; // [sp+20h] [bp-10h]@12 + Render *a3; // [sp+24h] [bp-Ch]@1 + float v29; // [sp+28h] [bp-8h]@5 + float v30; // [sp+2Ch] [bp-4h]@5 + float v31; // [sp+38h] [bp+8h]@2 + float pSpritea; // [sp+3Ch] [bp+Ch]@5 + float a1b; // [sp+40h] [bp+10h]@12 + float pBillboarda; // [sp+44h] [bp+14h]@12 + + auto a1 = this; + a3 = a1; + if ( a1->uNumD3DSceneBegins ) + { + v5 = a2; + v6 = (double)HIWORD(a2->sZValue); + v31 = v6; + v7 = v6; + v8 = Billboard_ProbablyAddToListAndSortByZOrder(LODWORD(v7)); + if ( BYTE3(v5->uTintColor) ) + pBillboardRenderListD3D[v8].uOpacity = RenderBillboardD3D::Opaque_3; + else + pBillboardRenderListD3D[v8].uOpacity = RenderBillboardD3D::Transparent; + v9 = pSprite; + pBillboardRenderListD3D[v8].field_90 = v5->field_44; + pBillboardRenderListD3D[v8].sZValue = v5->sZValue; + pBillboardRenderListD3D[v8].uParentBillboardID = v5->uParentBillboardID; + v24 = v5->uScreenSpaceX; + v23 = v5->uScreenSpaceY; + v30 = (double)(v5->field_10 & 0xFFFF) * 0.000015260186 + (double)HIWORD(v5->field_10); + v29 = (double)(v5->field_14 & 0xFFFF) * 0.000015260186 + (double)HIWORD(v5->field_14); + pSpritea = (double)((v9->uBufferWidth >> 1) - v9->uAreaX); + v26 = (double)(v9->uBufferHeight - v9->uAreaY); + if ( v5->uFlags & 4 ) + pSpritea = pSpritea * -1.0; + if ( v5->uTintColor & 0xFFFFFF && a3->bTinting ) + { + v10 = GetActorTintColor(a1a, 0, v31, 0, pBillboard); + v11 = sub_4A19D8(v5->uTintColor, v10); + if ( BYTE3(v5->uTintColor) ) + v11 = (unsigned int)((char *)&array_77EC08[1852].pEdgeList1[17] + 3) & ((unsigned int)v11 >> 1); + } + else + { + v11 = GetActorTintColor(a1a, 0, v31, 0, pBillboard); + } + pBillboardRenderListD3D[v8].pQuards[0].diffuse = v11; + v12 = 0; + pBillboarda = (double)v24; + pBillboardRenderListD3D[v8].pQuards[0].pos.x = pBillboarda - pSpritea * v30; + a1b = (double)v23; + pBillboardRenderListD3D[v8].pQuards[0].pos.y = a1b - v26 * v29; + v27 = v31 * 1000.0; + v13 = 1.0; + pBillboardRenderListD3D[v8].pQuards[0].pos.z = 1.0 + - 1.0 / (v27 / (double)pOutdoorCamera->shading_dist_mist); + v25 = 1.0 / v31; + pBillboardRenderListD3D[v8].pQuards[0].rhw = v25; + if ( a3->bUsingSpecular ) + { + v12 = sub_47C3D7_get_fog_related_stuff(0, 0, v31); + v13 = 1.0; + } + pBillboardRenderListD3D[v8].pQuards[0].specular = v12; + pBillboardRenderListD3D[v8].pQuards[0].texcoord.x = 0.0; + pBillboardRenderListD3D[v8].pQuards[0].texcoord.y = 0.0; + v14 = (double)((v9->uBufferWidth >> 1) - v9->uAreaX); + v15 = (double)(v9->uBufferHeight - v9->uAreaHeight - v9->uAreaY); + if ( v5->uFlags & 4 ) + v14 = v14 * -1.0; + v16 = pBillboardRenderListD3D[v8].pQuards[0].diffuse; + pBillboardRenderListD3D[v8].pQuards[1].specular = v12; + pBillboardRenderListD3D[v8].pQuards[1].diffuse = v16; + pBillboardRenderListD3D[v8].pQuards[1].pos.x = pBillboarda - v14 * v30; + pBillboardRenderListD3D[v8].pQuards[1].pos.y = a1b - v15 * v29; + v17 = v13 - v13 / (v27 / (double)pOutdoorCamera->shading_dist_mist); + pBillboardRenderListD3D[v8].pQuards[1].pos.z = v17; + pBillboardRenderListD3D[v8].pQuards[1].rhw = v25; + pBillboardRenderListD3D[v8].pQuards[1].texcoord.x = 0.0; + pBillboardRenderListD3D[v8].pQuards[1].texcoord.y = 1.0; + v18 = (double)(v9->uAreaWidth + v9->uAreaX + (v9->uBufferWidth >> 1) - v9->uBufferWidth); + v19 = (double)(v9->uBufferHeight - v9->uAreaHeight - v9->uAreaY); + if ( v5->uFlags & 4 ) + v18 = v18 * -1.0; + pBillboardRenderListD3D[v8].pQuards[2].diffuse = v16; + pBillboardRenderListD3D[v8].pQuards[2].specular = v12; + pBillboardRenderListD3D[v8].pQuards[2].pos.x = v18 * v30 + pBillboarda; + pBillboardRenderListD3D[v8].pQuards[2].pos.y = a1b - v19 * v29; + pBillboardRenderListD3D[v8].pQuards[2].pos.z = v17; + pBillboardRenderListD3D[v8].pQuards[2].rhw = v25; + pBillboardRenderListD3D[v8].pQuards[2].texcoord.x = 1.0; + pBillboardRenderListD3D[v8].pQuards[2].texcoord.y = 1.0; + v20 = (double)(v9->uAreaWidth + v9->uAreaX + (v9->uBufferWidth >> 1) - v9->uBufferWidth); + v21 = (double)(v9->uBufferHeight - v9->uAreaY); + if ( v5->uFlags & 4 ) + v20 = v20 * -1.0; + pBillboardRenderListD3D[v8].pQuards[3].diffuse = v16; + pBillboardRenderListD3D[v8].pQuards[3].specular = v12; + pBillboardRenderListD3D[v8].pQuards[3].pos.x = v20 * v30 + pBillboarda; + pBillboardRenderListD3D[v8].pQuards[3].pos.y = a1b - v21 * v29; + pBillboardRenderListD3D[v8].pQuards[3].pos.z = v17; + pBillboardRenderListD3D[v8].pQuards[3].rhw = v25; + pBillboardRenderListD3D[v8].pQuards[3].texcoord.x = 1.0; + pBillboardRenderListD3D[v8].pQuards[3].texcoord.y = 0.0; + v22 = v9->pTexture; + pBillboardRenderListD3D[v8].uNumVertices = 4; + pBillboardRenderListD3D[v8].pTexture = v22; + pBillboardRenderListD3D[v8].flt_88 = v31; + } +} + + +//----- (004A48E4) -------------------------------------------------------- +int Render::MakeParticleBillboardAndPush_BLV_Software(int screenSpaceX, int screenSpaceY, int z, int lightColor, int a6) +{ + int v6; // ecx@1 + int v7; // ebx@1 + int v8; // ecx@1 + int v9; // edx@1 + int v10; // edi@1 + unsigned int x; // esi@1 + int result; // eax@8 + int v13; // [sp+Ch] [bp-10h]@1 + int v14; // [sp+10h] [bp-Ch]@1 + int v15; // [sp+14h] [bp-8h]@1 + int v16; // [sp+18h] [bp-4h]@1 + int v17; // [sp+24h] [bp+8h]@1 + unsigned int v18; // [sp+28h] [bp+Ch]@1 + int v19; // [sp+34h] [bp+18h]@1 + + v6 = screenSpaceX; + v7 = (a6 >> 1) + screenSpaceY; + v17 = 0; + v15 = 0; + v8 = (a6 >> 1) + v6; + v14 = (a6 >> 1) * (a6 >> 1); + v9 = 2 * (a6 >> 1); + v10 = (a6 >> 1) * ((a6 >> 1) - 1); + x = v8 - (a6 >> 1); + v16 = (a6 >> 1) + screenSpaceY - v8; + v19 = a6 >> 1; + v13 = v9; + v18 = v8; + do + { + sr_4A46E6_draw_particle_segment(x, v16 + v18, z, 2 * v19, lightColor); + if ( v15 ) + sr_4A46E6_draw_particle_segment(x, v17 + v7, z, 2 * v19, lightColor); + v14 -= v15; + if ( v14 <= v10 ) + { + if ( v19 != v17 ) + { + sr_4A46E6_draw_particle_segment(v18, v16 + x, z, 2 * v17, lightColor); + sr_4A46E6_draw_particle_segment(v18, v19 + v7, z, 2 * v17, lightColor); + } + --v19; + v13 -= 2; + ++x; + v10 -= v13; + } + result = v17++; + v15 += 2; + --v18; + } + while ( result < v19 ); + return result; +} + +//----- (004A49D0) -------------------------------------------------------- +void Render::DrawProjectile(float srcX, float srcY, float a3, float a4, float dstX, float dstY, float a7, float a8, IDirect3DTexture2 *a9) +{ + int v10; // eax@1 + unsigned int v11; // ebx@1 + unsigned int v12; // ecx@1 + int v13; // edx@2 + int v14; // edx@4 + unsigned int v15; // edx@6 + double v16; // st7@7 + double v17; // st7@7 + double v18; // st6@7 + double v19; // st4@7 + double v20; // st4@8 + double v21; // st4@10 + double v22; // st4@10 + double v23; // st4@10 + double v24; // st4@10 + double v25; // st4@11 + double v26; // st4@13 + double v27; // st5@13 + double v28; // st4@13 + RenderVertexD3D3 v29[4]; // [sp+0h] [bp-94h]@7 + double v30; // [sp+80h] [bp-14h]@1 + int v31; // [sp+88h] [bp-Ch]@1 + signed int v32; // [sp+8Ch] [bp-8h]@1 + int X; // [sp+90h] [bp-4h]@1 + float a3a; // [sp+A4h] [bp+10h]@10 + float a4a; // [sp+A8h] [bp+14h]@10 + + *(float *)&X = dstX - srcX; + v30 = *(float *)&X + 6.7553994e15; + v31 = LODWORD(v30); + *(float *)&v32 = dstY - srcY; + v30 = *(float *)&v32 + 6.7553994e15; + X = LODWORD(v30); + HIDWORD(v30) = abs(COERCE_UNSIGNED_INT64(*(float *)&v32 + 6.7553994e15)); + v10 = abs(v31); + v32 = v10; + v11 = HIDWORD(v30); + v12 = 0; + if ( v10 < SHIDWORD(v30) ) + { + v13 = v10; + v10 = HIDWORD(v30); + v11 = v13; + } + if ( v10 < 0 ) + { + v14 = v10; + v10 = 0; + v12 = v14; + } + if ( (signed int)v11 < (signed int)v12 ) + { + v15 = v12; + v12 = v11; + v11 = v15; + } + v32 = (11 * v11 >> 5) + (v12 >> 2) + v10; + v16 = 1.0 / (double)v32; + *(float *)&v31 = (double)v31 * v16; + *(float *)&X = (double)X * v16; + v17 = *(float *)&X * a4; + v29[0].pos.x = srcX + v17; + v18 = *(float *)&v31 * a4; + v29[0].pos.y = srcY - v18; + v19 = a3; + if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor ) + v20 = v19 * 1000.0 / (double)pOutdoorCamera->shading_dist_mist; + else + v20 = v19 * 0.061758894; + v29[0].diffuse = -1; + v29[0].specular = 0; + v29[0].pos.z = 1.0 - 1.0 / v20; + v21 = 1.0 / a3; + *((float *)&v30 + 1) = v21; + v29[0].rhw = v21; + v29[0].texcoord.x = 1.0; + v29[0].texcoord.y = 0.0; + v22 = *(float *)&X * a8; + a3a = v22; + v29[1].pos.x = v22 + dstX; + v23 = *(float *)&v31 * a8; + a4a = v23; + v29[1].pos.y = dstY - v23; + v24 = a7; + if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor ) + v25 = v24 * 1000.0 / (double)pOutdoorCamera->shading_dist_mist; + else + v25 = v24 * 0.061758894; + v29[2].diffuse = -1; + v29[3].diffuse = -1; + *(_QWORD *)&v29[3].pos.z = __PAIR__(HIDWORD(v30), LODWORD(v29[0].pos.z)); + v29[1].diffuse = -16711936; + v29[1].specular = 0; + v29[2].specular = 0; + v29[3].specular = 0; + v26 = 1.0 - 1.0 / v25; + v29[1].pos.z = v26; + v27 = v26; + v28 = 1.0 / a7; + v29[1].rhw = v28; + v29[1].texcoord.x = 1.0; + v29[1].texcoord.y = 1.0; + v29[2].pos.x = dstX - a3a; + v29[2].pos.y = a4a + dstY; + v29[2].pos.z = v27; + v29[2].rhw = v28; + 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].texcoord.x = 0.0; + v29[3].texcoord.y = 0.0; + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, 1u)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, 2u)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 2u)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, 0)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, 0)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, 1u)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetTexture(0, a9)); + ErrD3D(pRenderer->pRenderD3D->pDevice->DrawPrimitive( + D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + v29, + 4, + 24)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, 0)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, 2u)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 1u)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, 1u)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, 1u)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, 2u)); +} + + +//----- (004A4CC9) -------------------------------------------------------- +void Render::_4A4CC9(stru6_stru1_indoor_sw_billboard *a1, int a2) +{ + int v3; // eax@1 + int v4; // edx@3 + unsigned int v5; // eax@7 + int v6; // edi@7 + char *v7; // edx@8 + char *v8; // ecx@8 + char v9; // zf@9 + double v10; // st6@9 + double v11; // st6@10 + int v12; // ebx@13 + int v13; // ecx@16 + unsigned int v14; // [sp+Ch] [bp-4h]@1 + + auto _this = this; + + *(float *)&v14 = 1000000.0; + v3 = a1->field_10; + if ( v3 >= 3 ) + { + if ( v3 > 0 ) + { + _this = (Render *)&a1->field_14[62]; + v4 = a1->field_10; + do + { + if ( *(float *)&this->bUserDirect3D < (double)*(float *)&v14 ) + v14 = this->bUserDirect3D; + _this = (Render *)((char *)_this + 16); + --v4; + } + while ( v4 ); + } + v5 = Billboard_ProbablyAddToListAndSortByZOrder(v14); + v6 = 0; + pBillboardRenderListD3D[v5].field_90 = 0; + pBillboardRenderListD3D[v5].uParentBillboardID = -1; + pBillboardRenderListD3D[v5].uOpacity = RenderBillboardD3D::Opaque_2; + if ( a1->field_10 > 0 ) + { + v7 = (char *)&a1->field_14[62]; + v8 = (char *)&pBillboardRenderListD3D[v5].pQuards[0].pos.z; + do + { + v9 = uCurrentlyLoadedLevelType == LEVEL_Indoor; + *((int *)v8 - 2) = *((int *)v7 - 2); + *((int *)v8 - 1) = *((int *)v7 - 1); + v10 = *(float *)v7; + if ( v9 ) + v11 = v10 * 0.061758894; + else + v11 = v10 * 1000.0 / (double)pOutdoorCamera->shading_dist_mist; + *(float *)v8 = 1.0 - 1.0 / v11; + *((float *)v8 + 1) = 1.0 / *(float *)v7; + if ( a2 & 0xFF000000 ) + v12 = *((int *)v7 + 1); + else + v12 = a2; + *((int *)v8 + 3) = 0; + *((int *)v8 + 2) = v12; + ++v6; + v7 += 16; + *((float *)v8 + 4) = 0.0; + *((float *)v8 + 5) = 0.0; + v8 += 32; + } + while ( v6 < a1->field_10 ); + } + v13 = a1->field_10; + pBillboardRenderListD3D[v5].pTexture = 0; + pBillboardRenderListD3D[v5].uNumVertices = v13; + LODWORD(pBillboardRenderListD3D[v5].flt_88) = v14; + } +} + + +//----- (004A4DE1) -------------------------------------------------------- +bool Render::LoadTexture(const char *pName, unsigned int bMipMaps, IDirectDrawSurface4 **pOutSurface, IDirect3DTexture2 **pOutTexture) +{ + HRESULT v12; // eax@14 + unsigned __int16 *v13; // ecx@19 + unsigned __int16 *v14; // eax@19 + DWORD v15; // edx@20 + HRESULT v16; // eax@23 + stru350 Dst; // [sp+Ch] [bp-F8h]@12 + + auto pHWLTexture = pD3DBitmaps.LoadTexture(pName, bMipMaps); + if ( pHWLTexture ) + { + bMipMaps = !strncmp(pName, "HDWTR", 5); + if ( !pRenderD3D->CreateTexture( + pHWLTexture->uWidth, + pHWLTexture->uHeight, + pOutSurface, + pOutTexture, + true, + bMipMaps, + uMinDeviceTextureDim) ) + Abortf("HiScreen16::LoadTexture - D3Drend->CreateTexture() failed: %x", 0); + //v10 = *pOutSurface; + //v11 = 0; + if ( bMipMaps ) + { + Dst._450DDE(); + //v20 = 0; + 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, 0x21u) ) + { + 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(0)); + //bMipMaps = 0x4D86ACu; + } + if (FAILED(pNextSurf->GetAttachedSurface(&v19, &pNextSurf))) + break; + //v10 = (IDirectDrawSurface4 *)pName; + //v11 = 0; + } + //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, 0x21u) ) + { + bMipMaps = 0; + v13 = pHWLTexture->pPixels; + v14 = (unsigned __int16 *)desc.lpSurface; + if ( desc.dwHeight ) + { + do + { + v15 = 0; + if ( desc.dwWidth ) + { + do + { + ++v15; + *v14 = *v13; + ++v14; + ++v13; + } + while ( v15 < desc.dwWidth ); + } + ++bMipMaps; + v14 += (desc.lPitch >> 1) - desc.dwWidth; + } + while ( bMipMaps < desc.dwHeight ); + } + ErrD3D((*pOutSurface)->Unlock(0)); + } + } + delete [] pHWLTexture->pPixels; + delete pHWLTexture; + return true; + } + return false; +} + +//----- (004A5048) -------------------------------------------------------- +HWLTexture *Render::MoveSpriteToDevice(Sprite *pSprite) +{ + Sprite *v2; // edi@1 + Render *v3; // ebx@1 + HWLTexture *result; // eax@1 + HWLTexture *v5; // esi@1 + unsigned int v6; // ST18_4@2 + RenderD3D *v7; // ecx@2 + Sprite *v8; // ebx@4 + unsigned __int16 *v9; // edx@5 + LPVOID v10; // eax@5 + signed int v11; // ebx@5 + signed int v12; // ecx@6 + signed int v13; // edi@7 + HRESULT v14; // eax@10 + DDSURFACEDESC2 Dst; // [sp+Ch] [bp-7Ch]@4 + + v2 = pSprite; + v3 = this; + result = pD3DSprites.LoadTexture(pSprite->pName, pSprite->uPaletteID); + v5 = result; + if ( result ) + { + v3->_gpu_memory_used += 2 * result->uWidth * result->uHeight; + v2->uAreaX = result->field_30; + v2->uAreaY = result->field_34; + v2->uBufferWidth = result->field_18; + v2->uBufferHeight = result->field_1C; + v2->uAreaWidth = result->field_20; + v2->uAreaHeight = result->field_24; + v6 = v3->uMinDeviceTextureDim; + v7 = v3->pRenderD3D; + if ( !v7->CreateTexture(result->uWidth, result->uHeight, &v2->pTextureSurface, &v2->pTexture, 1u, 0, v6) ) + Abortf("HiScreen16::LoadTexture - D3Drend->CreateTexture() failed: %x", 0); + //pSprite = v2->pTextureSurface; + //pSprite = (Sprite *)pSprite->pName; + //v8 = pSprite; + memset(&Dst, 0, 0x7Cu); + Dst.dwSize = 124; + if ( LockSurface_DDraw4((IDirectDrawSurface4 *)v2->pTextureSurface, &Dst, 0x21u) ) + { + v9 = v5->pPixels; + v10 = Dst.lpSurface; + v11 = 0; + if ( (signed int)v5->uHeight > 0 ) + { + v12 = (signed int)v5->uWidth >> 1; + do + { + v13 = 0; + if ( v12 > 0 ) + { + do + { + ++v13; + *(int *)v10 = *(int *)v9; + v9 += 2; + v10 = (char *)v10 + 4; + } + while ( v13 < (signed int)v5->uWidth >> 1 ); + } + v12 = (signed int)v5->uWidth >> 1; + ++v11; + v10 = (char *)v10 + 4 * ((Dst.lPitch >> 2) - v12); + } + while ( v11 < (signed int)v5->uHeight ); + } + ErrD3D(v2->pTextureSurface->Unlock(0)); + } + free(v5->pPixels); + free(v5); + result = (HWLTexture *)1; + } + return result; +} + +//----- (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(v1->pColorKeySurface4, &Dst, 0x801u) ) + { + v1->pTargetSurface = (unsigned __int16 *)Dst.lpSurface; + v3 = Dst.lPitch >> 1; + v1->uTargetSurfacePitch = Dst.lPitch >> 1; +LABEL_10: + v1->field_18_locked_pitch = v3; + goto LABEL_11; + } + goto LABEL_8; + } + } + else + { + v4 = &this->pTargetSurface; + if ( !this->pTargetSurface ) + { + v5 = (char *)&this->uTargetSurfacePitch; + LockRenderSurface((void **)&this->pTargetSurface, &this->uTargetSurfacePitch); + if ( *v4 ) + { + v3 = *(int *)v5; + goto LABEL_10; + } +LABEL_8: + --v1->uNumSceneBegins; + return; + } + } +LABEL_11: + RestoreFrontBuffer(); + } +} + +//----- (004A527D) -------------------------------------------------------- +void Render::EndScene() +{ + unsigned int v1; // edx@1 + unsigned int v2; // edx@2 + HRESULT v3; // eax@5 + + v1 = this->uNumSceneBegins; + if ( v1 ) + { + v2 = v1 - 1; + this->uNumSceneBegins = v2; + if ( !v2 ) + { + if ( this->pRenderD3D ) + { + if ( this->bColorKeySupported ) + { + this->pTargetSurface = 0; + this->uTargetSurfacePitch = 0; + this->field_18_locked_pitch = 0; + ErrD3D(this->pColorKeySurface4->Unlock(0)); + } + } + else + { + this->pTargetSurface = 0; + this->uTargetSurfacePitch = 0; + this->field_18_locked_pitch = 0; + UnlockBackBuffer(); + } + } + } +} + + +//----- ( ) -------------------------------------------------------- +unsigned int Render::_4A52F1(unsigned int this_, float a3) +{ + unsigned int v3; // esi@1 + double v4; // st7@2 + double v5; // st7@6 + double v6; // st6@6 + unsigned int v7; // eax@6 + double v8; // st5@6 + double v9; // st4@6 + HRESULT v10; // eax@6 + HRESULT v11; // eax@6 + unsigned int result; // eax@6 + unsigned int v13; // eax@7 + unsigned __int16 *v14; // ecx@7 + int *v15; // eax@7 + unsigned int v16; // ecx@8 + __int16 v17; // ax@10 + int v18; // esi@10 + float v19; // edi@10 + void *v20; // esi@10 + int v21; // edx@10 + int v22; // ecx@11 + int v23; // edx@12 + __int16 v24; // ax@15 + int v25; // esi@15 + float v26; // edi@15 + char *v27; // esi@15 + int v28; // edx@15 + int v29; // ecx@16 + int v30; // edx@17 + int v31; // [sp-Ch] [bp-ACh]@11 + int v32; // [sp-Ch] [bp-ACh]@16 + const char *v33; // [sp+0h] [bp-A0h]@0 + int v34; // [sp+4h] [bp-9Ch]@0 + unsigned int v35; // [sp+8h] [bp-98h]@0 + RenderVertexD3D3 v36[4]; // [sp+Ch] [bp-94h]@6 + unsigned int v37; // [sp+8Ch] [bp-14h]@7 + int v38; // [sp+90h] [bp-10h]@7 + double v39; // [sp+94h] [bp-Ch]@6 + float v40; // [sp+9Ch] [bp-4h]@6 + + auto ecx0 = this; + v3 = 0; + if ( ecx0->pRenderD3D ) + { + v4 = a3; + if ( a3 <= 1.0 ) + { + if ( v4 < 0.0 ) + v4 = 0.0; + } + else + { + v4 = 1.0; + } + a3 = v4 * 255.0; + v39 = a3 + 6.7553994e15; + LODWORD(v40) = LODWORD(v39); + v5 = (double)(signed int)pViewport->uViewportX; + v36[0].pos.x = v5; + v6 = (double)(signed int)pViewport->uViewportY; + v7 = this_ | (LODWORD(v39) << 24); + this_ = pViewport->uViewportW + 1; + v36[0].specular = 0; + v36[0].pos.y = v6; + v36[0].diffuse = v7; + v36[1].diffuse = v7; + v36[0].pos.z = 0.0; + v36[2].diffuse = v7; + v36[3].diffuse = v7; + v36[0].rhw = 1.0; + v36[1].specular = 0; + v36[0].texcoord.x = 0.0; + v36[2].specular = 0; + v36[3].specular = 0; + v36[0].texcoord.y = 0.0; + v36[1].pos.x = v5; + v8 = (double)(pViewport->uViewportW + 1); + v36[1].pos.y = v8; + v36[1].pos.z = 0.0; + v36[1].rhw = 1.0; + v36[1].texcoord.x = 0.0; + v36[1].texcoord.y = 0.0; + v9 = (double)(signed int)pViewport->uViewportZ; + v36[2].pos.x = v9; + v36[2].pos.y = v8; + v36[2].pos.z = 0.0; + v36[2].rhw = 1.0; + v36[2].texcoord.x = 0.0; + v36[2].texcoord.y = 0.0; + v36[3].pos.x = v9; + v36[3].pos.y = v6; + v36[3].pos.z = 0.0; + 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, 0)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, 1u)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, 0)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, 5u)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 6u)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, 0)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, 8u)); + ErrD3D(pRenderD3D->pDevice->DrawPrimitive( + D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + v36, + 4, + 28)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, 2)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 1u)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, 0)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, 1u)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, 1u)); + ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, 2u)); + } + else + { + v40 = (1.0 - a3) * 65536.0; + v39 = v40 + 6.7553994e15; + LODWORD(a3) = LODWORD(v39); + v38 = (signed int)(pViewport->uViewportZ - pViewport->uViewportX) >> 1; + HIDWORD(v39) = pViewport->uViewportW - pViewport->uViewportY + 1; + v13 = pViewport->uViewportX + ecx0->uTargetSurfacePitch - pViewport->uViewportZ; + v14 = &ecx0->pTargetSurface[pViewport->uViewportX + pViewport->uViewportY * ecx0->uTargetSurfacePitch]; + v37 = 2 * v13; + LODWORD(v40) = (int)v14; + + int __i = 0; + v15 = dword_F1B430; + 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 = _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 = _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 ); + } + } + return result; +} + + + +//----- (004A5B81) -------------------------------------------------------- +void Render::Clip(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW) +{ + this->bClip = 1; + this->uClipY = uY; + this->uClipX = uX; + this->uClipW = uW; + this->uClipZ = uZ; +} + + +//----- (004A5BB6) -------------------------------------------------------- +void Render::ResetClip() +{ + this->uClipY = 0; + this->uClipX = 0; + this->bClip = 1; + this->uClipW = 480; + this->uClipZ = 640; +} + + +//----- (004A5BE3) -------------------------------------------------------- +void Render::DrawTextureRGB(unsigned int uOutX, unsigned int uOutY, RGBTexture *a4) +{ + int v4; // edi@3 + unsigned __int16 *v5; // edx@3 + unsigned __int16 *v6; // esi@3 + unsigned int v7; // ebx@4 + unsigned int v8; // eax@5 + unsigned int v9; // ebx@5 + unsigned int v10; // eax@6 + unsigned int v11; // eax@7 + unsigned int v12; // ebx@8 + unsigned int v13; // eax@10 + unsigned int v14; // edi@11 + unsigned int v15; // eax@14 + unsigned int v16; // ebx@17 + int v17; // eax@23 + char v18; // zf@25 + int v19; // [sp+10h] [bp-8h]@3 + int v20; // [sp+14h] [bp-4h]@3 + unsigned int uOutXa; // [sp+20h] [bp+8h]@16 + int uOutXb; // [sp+20h] [bp+8h]@21 + int v23; // [sp+28h] [bp+10h]@3 + + if ( this->uNumSceneBegins && a4 ) + { + v4 = a4->uWidth; + v5 = &this->pTargetSurface[uOutX + uOutY * this->uTargetSurfacePitch]; + v6 = a4->pPixels; + v20 = v4; + v23 = a4->uHeight; + v19 = v4; + if ( this->bClip ) + { + v7 = this->uClipX; + if ( (signed int)uOutX < (signed int)v7 ) + { + v8 = v7 - uOutX; + v9 = uOutX - v7; + v8 *= 2; + v4 += v9; + v6 = (unsigned __int16 *)((char *)v6 + v8); + v20 += v9; + v5 = (unsigned __int16 *)((char *)v5 + v8); + } + v10 = this->uClipY; + if ( (signed int)uOutY < (signed int)v10 ) + { + v11 = v10 - uOutY; + v6 += v19 * v11; + v23 += uOutY - this->uClipY; + v4 = v20; + v5 += this->uTargetSurfacePitch * v11; + } + v12 = this->uClipX; + if ( (signed int)v12 < (signed int)uOutX ) + v12 = uOutX; + v13 = this->uClipZ; + if ( (signed int)(v4 + v12) > (signed int)v13 ) + { + v14 = this->uClipX; + if ( (signed int)v14 < (signed int)uOutX ) + v14 = uOutX; + v4 = v13 - v14; + } + v15 = this->uClipY; + if ( (signed int)v15 < (signed int)uOutY ) + v15 = uOutY; + uOutXa = this->uClipW; + if ( (signed int)(v15 + v23) > (signed int)uOutXa ) + { + v16 = this->uClipY; + if ( (signed int)v16 < (signed int)uOutY ) + v16 = uOutY; + v23 = uOutXa - v16; + } + } + if ( v23 > 0 ) + { + uOutXb = v23; + do + { + if ( v4 > 0 ) + { + v17 = v4; + do + { + *v5 = *v6; + ++v5; + ++v6; + --v17; + } + while ( v17 ); + } + v6 += v19 - v4; + v18 = uOutXb-- == 1; + v5 += this->uTargetSurfacePitch - v4; + } + while ( !v18 ); + } + } +} + + +//----- (004A5D33) -------------------------------------------------------- +void Render::_4A5D33(unsigned int pX, unsigned int pY, int a4, int a5, RGBTexture *pTexture) +{ + Render *v6; // esi@1 + unsigned __int16 *v7; // ebx@3 + int v8; // ecx@3 + int v9; // edx@3 + int v10; // ecx@3 + int v11; // edi@3 + signed int v12; // eax@4 + unsigned int v13; // eax@5 + signed int v14; // eax@6 + unsigned int v15; // eax@7 + unsigned int v16; // edx@8 + int v17; // eax@10 + unsigned int v18; // ecx@11 + unsigned int v19; // ecx@14 + int v20; // eax@16 + unsigned int v21; // ecx@17 + int v22; // eax@21 + int v23; // edi@23 + int v24; // [sp+Ch] [bp-4h]@3 + int a2a; // [sp+18h] [bp+8h]@21 + unsigned int teal; // [sp+1Ch] [bp+Ch]@20 + int a4a; // [sp+20h] [bp+10h]@3 + int a4b; // [sp+20h] [bp+10h]@21 + unsigned __int16 *pTexturea; // [sp+28h] [bp+18h]@3 + + v6 = this; + if ( this->uNumSceneBegins && pTexture ) + { + v7 = &this->pTargetSurface[pX + pY * this->uTargetSurfacePitch]; + v8 = pTexture->uWidth; + v24 = pTexture->uWidth; + v9 = a4 + a5 * v8; + v10 = v8 - a4; + a4a = v10; + v11 = pTexture->uHeight - a5; + pTexturea = &pTexture->pPixels[v9]; + if ( v6->bClip ) + { + v12 = v6->uClipX; + if ( (signed int)pX < v12 ) + { + v13 = 2 * (v12 - pX); + pTexturea = (unsigned __int16 *)((char *)pTexturea + v13); + v10 += pX - v6->uClipX; + v7 = (unsigned __int16 *)((char *)v7 + v13); + a4a = v10; + } + v14 = v6->uClipY; + if ( (signed int)pY < v14 ) + { + v15 = v14 - pY; + pTexturea += v24 * v15; + v11 += pY - v6->uClipY; + v10 = a4a; + v7 += v6->uTargetSurfacePitch * v15; + } + v16 = v6->uClipX; + if ( (signed int)v16 < (signed int)pX ) + v16 = pX; + v17 = v6->uClipZ; + if ( (signed int)(v10 + v16) > v17 ) + { + v18 = v6->uClipX; + if ( (signed int)v18 < (signed int)pX ) + v18 = pX; + a4a = v17 - v18; + } + v19 = v6->uClipY; + if ( (signed int)v19 < (signed int)pY ) + v19 = pY; + v20 = v6->uClipW; + if ( (signed int)(v11 + v19) > v20 ) + { + v21 = v6->uClipY; + if ( (signed int)v21 < (signed int)pY ) + v21 = pY; + v11 = v20 - v21; + } + } + teal = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0, 0xFFu, 0xFFu); + if ( v11 > 0 ) + { + v22 = a4a; + a2a = v11; + a4b = 2 * (v24 - a4a); + do + { + if ( v22 > 0 ) + { + v23 = v22; + do + { + if ( *pTexturea != teal ) + *v7 = *pTexturea; + ++pTexturea; + ++v7; + --v23; + } + while ( v23 ); + } + v7 += v6->uTargetSurfacePitch - v22; + pTexturea = (unsigned __int16 *)((char *)pTexturea + a4b); + --a2a; + } + while ( a2a ); + } + } +} + + + +//----- (004A6E7E) -------------------------------------------------------- +void Render::_4A6E7E(unsigned int a2, unsigned int a3, Texture *a4) +{ + unsigned __int16 *v4; // eax@4 + 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 + char v17; // zf@29 + int v18; // [sp+14h] [bp-Ch]@4 + int v19; // [sp+18h] [bp-8h]@4 + unsigned __int8 *v20; // [sp+1Ch] [bp-4h]@4 + int v21; // [sp+28h] [bp+8h]@25 + int v22; // [sp+28h] [bp+8h]@34 + unsigned int v23; // [sp+2Ch] [bp+Ch]@23 + unsigned int v24; // [sp+2Ch] [bp+Ch]@32 + + if ( this->uNumSceneBegins && a4 && a4->pPalette16 ) + { + v4 = &this->pTargetSurface[a2 + a3 * this->uTargetSurfacePitch]; + v20 = a4->pLevelOfDetail0; + v5 = a4->uTextureWidth; + v6 = a4->uTextureHeight; + v19 = a4->uTextureWidth; + v18 = a4->uTextureWidth; + if ( this->bClip ) + { + v7 = this->uClipX; + if ( (signed int)a2 < (signed int)v7 ) + { + v8 = v7 - a2; + v20 += v8; + v19 += a2 - this->uClipX; + v4 += v8; + } + 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; + } + 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; + } + } + 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) -------------------------------------------------------- +int Render::_4A6DF5(unsigned __int16 *pBitmap, unsigned int uBitmapPitch, Vec2_int_ *pBitmapXY, unsigned __int16 *pTarget, unsigned int uTargetPitch, Vec4_int_ *a7) +{ + int result; // eax@0 + int v8; // ecx@3 + unsigned __int16 *v9; // edi@4 + unsigned __int16 *v10; // ebx@4 + int v11; // esi@4 + unsigned __int16 *pBitmapa; // [sp+14h] [bp+8h]@3 + unsigned __int16 *pTargeta; // [sp+20h] [bp+14h]@3 + + if ( pBitmap ) + { + if ( pTarget ) + { + pBitmapa = &pBitmap[pBitmapXY->x + uBitmapPitch * pBitmapXY->y]; + pTargeta = &pTarget[a7->x + uTargetPitch * a7->y]; + v8 = a7->z - a7->x; + result = a7->w - a7->y; + if ( result > 0 ) + { + v9 = pBitmapa; + v10 = pTargeta; + v11 = a7->w - a7->y; + do + { + if ( v8 > 0 ) + { + result = v8; + do + { + *v9 = *v10; + ++v9; + ++v10; + --result; + } + while ( result ); + } + v9 += uBitmapPitch - v8; + v10 += uTargetPitch - v8; + --v11; + } + while ( v11 ); + } + } + } + return result; +} + + +//----- (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) + { + auto pDst = &pTargetSurface[uX + (y + uY) * uTargetSurfacePitch]; + + memset32(pDst, twoColors, uWidth / 2); + if (uWidth & 1) + pDst[uWidth - 1] = 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 __int16 *v11; // eax@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 int v21; // esi@22 + unsigned __int16 v22; // dx@24 + char v23; // zf@28 + unsigned __int8 *v24; // [sp+Ch] [bp-4h]@2 + unsigned int uOutXa; // [sp+18h] [bp+8h]@20 + + if ( this->uNumSceneBegins ) + { + v9 = uCharWidth; + v10 = uCharHeight; + v11 = &this->pTargetSurface[uOutX + uOutY * this->uTargetSurfacePitch]; + v24 = pFontPixels; + if ( this->bClip ) + { + v12 = this->uClipX; + if ( uOutX < (signed int)v12 ) + { + v24 = &pFontPixels[v12 - uOutX]; + v11 += v12 - uOutX; + v9 = uCharWidth + uOutX - v12; + } + v13 = this->uClipY; + if ( uOutY < v13 ) + { + v14 = v13 - uOutY; + v24 += uCharWidth * v14; + v10 = uCharHeight + uOutY - this->uClipY; + v11 += this->uTargetSurfacePitch * v14; + } + v15 = this->uClipX; + if ( v15 < uOutX ) + v15 = uOutX; + v16 = this->uClipZ; + if ( (signed int)(v9 + v15) > (signed int)v16 ) + { + v17 = this->uClipX; + if ( v17 < uOutX ) + v17 = uOutX; + v9 = v16 - v17; + } + v18 = this->uClipY; + if ( v18 < uOutY ) + v18 = uOutY; + v19 = this->uClipW; + if ( (signed int)(v10 + v18) > (signed int)v19 ) + { + v20 = this->uClipY; + if ( v20 < uOutY ) + v20 = uOutY; + v10 = v19 - v20; + } + } + if ( (signed int)v10 > 0 ) + { + uOutXa = v10; + do + { + if ( (signed int)v9 > 0 ) + { + v21 = v9; + do + { + if ( *v24 ) + { + v22 = uShadowColor; + if ( *v24 != 1 ) + v22 = uFaceColor; + *v11 = v22; + } + ++v11; + ++v24; + --v21; + } + while ( v21 ); + } + v24 += uCharWidth - v9; + v23 = uOutXa-- == 1; + v11 += this->uTargetSurfacePitch - v9; + } + while ( !v23 ); + } + } +} + + + +//----- (004A6A68) -------------------------------------------------------- +void Render::_4A6A68(unsigned int a2, unsigned int a3, Texture *a4, __int16 height) +{ + Render *v5; // ebx@1 + unsigned __int16 v6; // ax@1 + + v5 = this; + + Texture tex; // [sp+Ch] [bp-48h]@1 + //Texture::Texture(&tex); + + v6 = a4->uTextureHeight - height; + memcpy(&tex, a4, sizeof(tex)); + tex.uTextureHeight = v6; + if ( (signed __int16)v6 > 0 ) + DrawTextureIndexed(a2, a3, &tex); +} + + + +//----- (004A6AB1) -------------------------------------------------------- +void Render::DrawTextPalette(int x, int y, int a4, int a5, unsigned int uFontHeight, unsigned __int16 *pPalette, int a8) +{ + int v8; // edi@2 + unsigned int v9; // esi@2 + unsigned __int16 *v10; // eax@2 + unsigned char *v11; // edx@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 + int v21; // ebx@22 + char v22; // zf@28 + int v23; // ebx@31 + unsigned __int16 v24; // si@35 + int v25; // [sp+Ch] [bp-4h]@2 + int v26; // [sp+1Ch] [bp+Ch]@24 + int v27; // [sp+1Ch] [bp+Ch]@33 + unsigned int v28; // [sp+20h] [bp+10h]@30 + unsigned int v29; // [sp+24h] [bp+14h]@22 + unsigned int v30; // [sp+24h] [bp+14h]@31 + + auto a2 = x; + auto a3 = y; + auto a6 = uFontHeight; + if ( this->uNumSceneBegins ) + { + v8 = a5; + v9 = a6; + v10 = &pTargetSurface[x + y * uTargetSurfacePitch]; + v11 = (unsigned char *)a4; + v25 = a4; + if ( this->bClip ) + { + v12 = this->uClipX; + if ( a2 < (signed int)v12 ) + { + v25 = v12 - a2 + a4; + v10 += v12 - a2; + v8 = a5 + a2 - v12; + } + v13 = this->uClipY; + if ( a3 < v13 ) + { + v14 = v13 - a3; + v25 += a5 * v14; + v9 = a6 + a3 - this->uClipY; + v10 += this->uTargetSurfacePitch * v14; + } + v15 = this->uClipX; + if ( v15 < a2 ) + v15 = a2; + v16 = this->uClipZ; + if ( v8 + v15 > (signed int)v16 ) + { + v17 = this->uClipX; + if ( v17 < a2 ) + v17 = a2; + v8 = v16 - v17; + } + v18 = this->uClipY; + if ( v18 < a3 ) + v18 = a3; + v19 = this->uClipW; + if ( (signed int)(v9 + v18) > (signed int)v19 ) + { + v20 = this->uClipY; + if ( v20 < a3 ) + v20 = a3; + v9 = v19 - v20; + } + v11 = (unsigned char *)v25; + } + if ( a8 ) + { + v28 = pRenderer->uTargetGMask | pRenderer->uTargetBMask; + 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 + { + 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) +{ + Texture *v4; // edi@2 + unsigned int v5; // ebx@4 + unsigned __int16 *v6; // eax@4 + signed int v7; // edx@5 + int v8; // edx@6 + signed int v9; // edx@7 + int v10; // edx@8 + signed int v11; // edx@9 + signed int v12; // esi@12 + signed int v13; // esi@15 + unsigned int v14; // edx@17 + signed 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 v21; // [sp+28h] [bp+8h]@24 + unsigned int v22; // [sp+2Ch] [bp+Ch]@22 + unsigned int pTexturea; // [sp+30h] [bp+10h]@11 + + if ( this->uNumSceneBegins ) + { + v4 = pTexture; + if ( pTexture ) + { + if ( pTexture->pPalette16 ) + { + v5 = pTexture->uTextureHeight; + v6 = &this->pTargetSurface[a2 + a3 * this->uTargetSurfacePitch]; + v19 = pTexture->pLevelOfDetail0; + v20 = pTexture->uTextureWidth; + v18 = pTexture->uTextureWidth; + if ( this->bClip ) + { + v7 = this->uClipX; + if ( a2 < v7 ) + { + v8 = v7 - a2; + v19 += v8; + v20 += a2 - this->uClipX; + v6 += v8; + } + v9 = this->uClipY; + v5 = pTexture->uTextureHeight; + if ( a3 < v9 ) + { + v10 = v9 - a3; + v19 += v18 * v10; + v5 = a3 - this->uClipY + pTexture->uTextureHeight; + v4 = pTexture; + v6 += this->uTargetSurfacePitch * v10; + } + v11 = this->uClipX; + if ( v11 < a2 ) + v11 = a2; + pTexturea = this->uClipZ; + if ( v11 + v20 > (signed int)pTexturea ) + { + v12 = this->uClipX; + if ( v12 < a2 ) + v12 = a2; + v20 = pTexturea - v12; + } + v13 = this->uClipY; + if ( v13 < a3 ) + v13 = a3; + v14 = this->uClipW; + if ( (signed int)(v5 + v13) > (signed int)v14 ) + { + v15 = this->uClipY; + if ( v15 < a3 ) + v15 = a3; + v5 = v14 - v15; + } + } + 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 ); + } + } + } + } +} + + +//----- (004A6776) -------------------------------------------------------- +void Render::_4A6776(unsigned int a2, unsigned int a3, Texture *a4) +{ + 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; + 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 ); + } + } + } + } +} + +//----- (004A65CC) -------------------------------------------------------- +void Render::_4A65CC(unsigned int x, unsigned int y, Texture *a4, Texture *a5, int a6, int a7, int a8) +{ + unsigned __int16 *v8; // esi@6 + unsigned int v9; // edi@6 + unsigned int v10; // eax@7 + unsigned int v11; // eax@8 + unsigned int v12; // eax@9 + unsigned int v13; // eax@10 + unsigned int v14; // edx@11 + unsigned int v15; // eax@13 + unsigned int v16; // edx@14 + unsigned int v17; // edx@17 + unsigned int v18; // eax@19 + unsigned int v19; // edx@20 + int v20; // eax@27 + int v21; // edx@29 + int v22; // [sp+Ch] [bp-Ch]@6 + int v23; // [sp+Ch] [bp-Ch]@24 + unsigned __int8 *v24; // [sp+14h] [bp-4h]@6 + int xa; // [sp+20h] [bp+8h]@26 + unsigned int ya; // [sp+24h] [bp+Ch]@24 + int v27; // [sp+2Ch] [bp+14h]@6 + + if ( this->uNumSceneBegins && a4 && a4->pPalette16 && a5 && a5->pPalette16 ) + { + v8 = &this->pTargetSurface[x + y * this->uTargetSurfacePitch]; + v24 = a4->pLevelOfDetail0; + v27 = a4->uTextureWidth; + v9 = a4->uTextureHeight; + v22 = a4->uTextureWidth; + if ( this->bClip ) + { + v10 = this->uClipX; + if ( (signed int)x < (signed int)v10 ) + { + v11 = v10 - x; + v24 += v11; + v27 += x - this->uClipX; + v8 += v11; + } + v12 = this->uClipY; + if ( (signed int)y < (signed int)v12 ) + { + v13 = v12 - y; + v24 += v22 * v13; + v9 = y - this->uClipY + a4->uTextureHeight; + v8 += this->uTargetSurfacePitch * v13; + } + v14 = this->uClipX; + if ( (signed int)v14 < (signed int)x ) + v14 = x; + v15 = this->uClipZ; + if ( (signed int)(v27 + v14) > (signed int)v15 ) + { + v16 = this->uClipX; + if ( (signed int)v16 < (signed int)x ) + v16 = x; + v27 = v15 - v16; + } + v17 = this->uClipY; + if ( (signed int)v17 < (signed int)y ) + v17 = y; + v18 = this->uClipW; + if ( (signed int)(v9 + v17) > (signed int)v18 ) + { + v19 = this->uClipY; + if ( (signed int)v19 < (signed int)y ) + v19 = y; + v9 = v18 - v19; + } + } + 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::_4A63E6(unsigned int a2, unsigned int a3, Texture *a4, Texture *a5, int a6, int a7, int a8) +{ + Texture *v8; // eax@2 + Texture *v9; // ebx@4 + unsigned __int16 *v10; // esi@6 + unsigned int v11; // edi@7 + unsigned int v12; // eax@9 + unsigned int v13; // eax@10 + unsigned int v14; // edx@11 + unsigned int v15; // eax@13 + unsigned int v16; // edx@14 + unsigned int v17; // edx@17 + unsigned int v18; // eax@19 + unsigned int v19; // edx@20 + int v20; // eax@27 + int v21; // edx@29 + int v22; // [sp+Ch] [bp-Ch]@6 + int v23; // [sp+Ch] [bp-Ch]@24 + int v24; // [sp+10h] [bp-8h]@6 + int v25; // [sp+14h] [bp-4h]@6 + int i; // [sp+20h] [bp+8h]@25 + int v27; // [sp+24h] [bp+Ch]@23 + unsigned __int8 *v28; // [sp+28h] [bp+10h]@6 + + if ( this->uNumSceneBegins ) + { + v8 = a4; + if ( a4 ) + { + if ( a4->pPalette16 ) + { + v9 = a5; + if ( a5 ) + { + if ( a5->pPalette16 ) + { + v10 = &this->pTargetSurface[a2 + a3 * this->uTargetSurfacePitch]; + v28 = a4->pLevelOfDetail0; + v25 = v8->uTextureWidth; + v24 = v8->uTextureHeight; + v22 = v8->uTextureWidth; + if ( this->bClip ) + { + v11 = this->uClipX; + if ( (signed int)a2 < (signed int)v11 ) + { + v28 += v11 - a2; + v25 += a2 - v11; + v9 = a5; + v10 += v11 - a2; + } + v12 = this->uClipY; + if ( (signed int)a3 < (signed int)v12 ) + { + v13 = v12 - a3; + v9 = a5; + v28 += v22 * v13; + v24 += a3 - this->uClipY; + v10 += this->uTargetSurfacePitch * v13; + } + v14 = this->uClipX; + if ( (signed int)v14 < (signed int)a2 ) + v14 = a2; + v15 = this->uClipZ; + if ( (signed int)(v25 + v14) > (signed int)v15 ) + { + v16 = this->uClipX; + if ( (signed int)v16 < (signed int)a2 ) + v16 = a2; + v25 = v15 - v16; + } + v17 = this->uClipY; + if ( (signed int)v17 < (signed int)a3 ) + v17 = a3; + v18 = this->uClipW; + if ( (signed int)(v24 + v17) > (signed int)v18 ) + { + v19 = this->uClipY; + if ( (signed int)v19 < (signed int)a3 ) + v19 = a3; + v24 = v18 - v19; + } + } + v27 = 0; + if ( v24 > 0 ) + { + v23 = v22 - v25; + do + { + for ( i = 0; i < v25; ++v28 ) + { + if ( *v28 ) + { + v20 = *(&v9->pLevelOfDetail0[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) +{ + Texture *pCurrentTexture; // edi@2 + int uHeight; // 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 uFlag; // zf@28 + int v18; // [sp+10h] [bp-10h]@4 + unsigned __int8 *v19; // [sp+18h] [bp-8h]@4 + int uWidth; // [sp+1Ch] [bp-4h]@4 + int uXa; // [sp+28h] [bp+8h]@24 + unsigned int uYa; // [sp+2Ch] [bp+Ch]@22 + unsigned int pTexturea; // [sp+30h] [bp+10h]@11 + + if ( this->uNumSceneBegins ) + { + pCurrentTexture = pTexture; + if ( pTexture ) + { + if ( pTexture->pPalette16 ) + { + uHeight = pTexture->uTextureHeight; + v6 = &this->pTargetSurface[uX + uY * this->uTargetSurfacePitch]; + v19 = pTexture->pLevelOfDetail0; + uWidth = pTexture->uTextureWidth; + v18 = pTexture->uTextureWidth; + if ( this->bClip ) + { + v7 = this->uClipX; + if ( (signed int)uX < (signed int)v7 ) + { + v8 = v7 - uX; + v19 += v8; + uWidth += uX - this->uClipX; + v6 += v8; + } + v9 = this->uClipY; + uHeight = pTexture->uTextureHeight; + if ( (signed int)uY < (signed int)v9 ) + { + v10 = v9 - uY; + v19 += v18 * v10; + uHeight = uY - this->uClipY + pTexture->uTextureHeight; + pCurrentTexture = pTexture; + v6 += this->uTargetSurfacePitch * v10; + } + v11 = this->uClipX; + if ( (signed int)v11 < (signed int)uX ) + v11 = uX; + pTexturea = this->uClipZ; + if ( (signed int)(v11 + uWidth) > (signed int)pTexturea ) + { + v12 = this->uClipX; + if ( (signed int)v12 < (signed int)uX ) + v12 = uX; + uWidth = pTexturea - v12; + } + v13 = this->uClipY; + if ( (signed int)v13 < (signed int)uY ) + v13 = uY; + v14 = this->uClipW; + if ( (signed int)(uHeight + v13) > (signed int)v14 ) + { + v15 = this->uClipY; + if ( (signed int)v15 < (signed int)uY ) + v15 = uY; + uHeight = v14 - v15; + } + } + 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::_4A612A(signed int uOutX, unsigned int uOutY, Texture *pTexture, int zVal) +{ + Texture *v5; // eax@2 + unsigned int v6; // edx@3 + int v7; // ebx@3 + int v8; // edi@3 + signed int v9; // eax@4 + int v10; // eax@5 + unsigned int v11; // esi@6 + signed int v12; // esi@8 + unsigned int v13; // eax@10 + signed int v14; // esi@11 + unsigned int v15; // esi@14 + unsigned int v16; // eax@16 + 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 ) + { + v5 = pTexture; + if ( pTexture ) + { + v6 = uOutY; + v7 = pTexture->uTextureHeight; + pZBuffer = &this->pActiveZBuffer[uOutX + 640 * uOutY]; + uOutYa = v5->pLevelOfDetail0; + v8 = v5->uTextureWidth; + v20 = v5->uTextureWidth; + v19 = v5->uTextureWidth; + if ( this->bClip ) + { + v9 = this->uClipX; + if ( uOutX < v9 ) + { + v10 = v9 - uOutX; + uOutYa += v10; + v8 += uOutX - this->uClipX; + v20 = v8; + pZBuffer += v10; + } + v11 = this->uClipY; + if ( (signed int)v6 < (signed int)v11 ) + { + uOutYa += v19 * (v11 - v6); + v7 += v6 - v11; + pZBuffer += 640 * (v11 - v6); + v8 = v20; + } + v12 = this->uClipX; + if ( v12 < uOutX ) + v12 = uOutX; + v13 = this->uClipZ; + if ( v8 + v12 > (signed int)v13 ) + { + v14 = this->uClipX; + if ( v14 < uOutX ) + v14 = uOutX; + v8 = v13 - v14; + } + v15 = this->uClipY; + if ( (signed int)v15 < (signed int)v6 ) + v15 = v6; + v16 = this->uClipW; + if ( (signed int)(v7 + v15) > (signed int)v16 ) + { + v17 = this->uClipY; + if ( (signed int)v17 >= (signed int)v6 ) + v6 = v17; + v7 = v16 - v6; + } + } + if ( v7 > 0 ) + { + uOutXa = v7; + do + { + if ( v8 > 0 ) + { + v18 = v8; + do + { + if ( *uOutYa ) + *pZBuffer = zVal; + ++pZBuffer; + ++uOutYa; + --v18; + } + while ( v18 ); + } + pZBuffer += 640 - v8; + uOutYa += v19 - v8; + --uOutXa; + } + while ( uOutXa ); + } + } + } +} + + +//----- (004A601E) -------------------------------------------------------- +void Render::_4A601E(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 + unsigned int v9; // eax@4 + unsigned int v10; // eax@6 + signed int v11; // edi@8 + unsigned int v12; // eax@10 + signed int v13; // edi@11 + unsigned int v14; // edi@14 + unsigned int v15; // eax@16 + 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 ) + { + v9 = this->uClipX; + if ( a2 < (signed int)v9 ) + { + pTexturea += a2 - v9; + v8 = (char *)v8 + 4 * (v9 - a2); + } + v10 = this->uClipY; + if ( v5 < (signed int)v10 ) + { + v17 += v5 - v10; + v8 = (char *)v8 + 2560 * (v10 - v5); + } + v11 = this->uClipX; + if ( v11 < a2 ) + v11 = a2; + v12 = this->uClipZ; + if ( (signed int)(pTexturea + v11) > (signed int)v12 ) + { + v13 = this->uClipX; + if ( v13 < a2 ) + v13 = a2; + pTexturea = v12 - v13; + } + v14 = this->uClipY; + if ( (signed int)v14 < v5 ) + v14 = v5; + v6 = v17; + v15 = this->uClipW; + if ( (signed int)(v17 + v14) > (signed int)v15 ) + { + v16 = this->uClipY; + if ( (signed int)v16 < v5 ) + v16 = v5; + v6 = v15 - v16; + } + } + if ( v6 > 0 ) + { + do + { + if ( (signed int)pTexturea > 0 ) + { + memset32(v8, a5, pTexturea); + v8 = (char *)v8 + 4 * pTexturea; + } + v8 = (char *)v8 + 4 * (640 - pTexturea); + --v6; + } + while ( v6 ); + } + } +} + +//----- (004A5EB2) -------------------------------------------------------- +void Render::DrawTextureIndexed(unsigned int uX, unsigned int uY, Texture *a4) +{ + Texture *v4; // edi@2 + unsigned int v5; // ebx@4 + unsigned __int16 *pTarget; // 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; // edx@22 + char v17; // zf@26 + int v18; // [sp+10h] [bp-10h]@4 + unsigned __int8 *v19; // [sp+18h] [bp-8h]@4 + int v20; // [sp+1Ch] [bp-4h]@4 + int uXa; // [sp+28h] [bp+8h]@24 + unsigned int uYa; // [sp+2Ch] [bp+Ch]@22 + unsigned int v23; // [sp+30h] [bp+10h]@11 + + if ( this->uNumSceneBegins ) + { + v4 = a4; + if ( a4 ) + { + if ( a4->pPalette16 ) + { + v5 = a4->uTextureHeight; + pTarget = &this->pTargetSurface[uX + uY * this->uTargetSurfacePitch]; + v19 = a4->pLevelOfDetail0; + v20 = a4->uTextureWidth; + v18 = a4->uTextureWidth; + if ( this->bClip ) + { + v7 = this->uClipX; + if ( (signed int)uX < (signed int)v7 ) + { + v8 = v7 - uX; + v19 += v8; + v20 += uX - this->uClipX; + pTarget += v8; + } + v9 = this->uClipY; + v5 = a4->uTextureHeight; + if ( (signed int)uY < (signed int)v9 ) + { + v10 = v9 - uY; + v19 += v18 * v10; + v5 = uY - this->uClipY + a4->uTextureHeight; + v4 = a4; + pTarget += this->uTargetSurfacePitch * v10; + } + v11 = this->uClipX; + if ( (signed int)v11 < (signed int)uX ) + v11 = uX; + v23 = this->uClipZ; + if ( (signed int)(v11 + v20) > (signed int)v23 ) + { + v12 = this->uClipX; + if ( (signed int)v12 < (signed int)uX ) + v12 = uX; + v20 = v23 - v12; + } + v13 = this->uClipY; + if ( (signed int)v13 < (signed int)uY ) + v13 = uY; + v14 = this->uClipW; + if ( (signed int)(v5 + v13) > (signed int)v14 ) + { + v15 = this->uClipY; + if ( (signed int)v15 < (signed int)uY ) + v15 = uY; + v5 = v14 - v15; + } + } + 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 v1; // edx@24 + signed int v2; // ecx@24 + int v3; // esi@25 + int v4; // edx@26 + ObjectDesc *v5; // eax@26 + RGBTexture *v6; // esi@33 + const char *v7; // eax@34 + const char *v8; // [sp-4h] [bp-28h]@33 + int v9; // [sp+0h] [bp-24h]@33 + struct tagRECT Rect; // [sp+14h] [bp-10h]@15 + + if ( pRenderer->bWindowMode ) + goto LABEL_52; + if ( dword_6BE364_game_settings_1 & 2 ) + { + ModalWindow(pGlobalTXT_LocalizationStrings[62], 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 ( !pRenderer->pRenderD3D || pRenderer->pRenderD3D->pAvailableDevices->bIsDeviceCompatible ) + { +LABEL_52: + if ( pEventTimer->bPaused ) + BYTE1(dword_6BE364_game_settings_1) |= 8u; + else + pEventTimer->Pause(); + if ( pMiscTimer->bPaused ) + BYTE1(dword_6BE364_game_settings_1) |= 0x10u; + else + pMiscTimer->Pause(); + pMouse->bActive = 0; + if ( pRenderer->pRenderD3D ) + { + pBitmaps_LOD->ReleaseHardwareTextures(); + pSprites_LOD->ReleaseAll(); + } + if ( pRenderer->bWindowMode ) + { + if ( GetWindowRect(hWnd, &Rect) ) + { + WriteWindowsRegistryInt("window X", Rect.left); + WriteWindowsRegistryInt("window Y", Rect.top); + uWindowX = Rect.left; + uWindowY = Rect.top; + } + SetMenu(hWnd, 0); + SetWindowLongA(hWnd, -20, 0); + SetWindowLongA(hWnd, -16, 0x10000000u); + pRenderer->InitializeFullscreen(hWnd); + v0 = (double)(signed int)uGammaPos * 0.1 + 0.6; + pGame->pGammaController->Initialize(v0); + } + else + { + ClipCursor(0); + pRenderer->SwitchToWindow(hWnd); + SetWindowLongA(hWnd, -16, uWindowStyle); + SetMenu(hWnd, hOSMenu); + } + if ( pRenderer->pRenderD3D ) + { + pBitmaps_LOD->_410423_move_textures_to_device(); + pSprites_LOD->MoveSpritesToVideoMemory(); + } + if ( pPaletteManager->uNumTargetBBits == pRenderer->uTargetBBits + && pPaletteManager->uNumTargetGBits == pRenderer->uTargetGBits + && pPaletteManager->uNumTargetRBits == pRenderer->uTargetRBits ) + goto LABEL_38; + pPaletteManager->SetColorChannelInfo(pRenderer->uTargetRBits, pRenderer->uTargetGBits, pRenderer->uTargetBBits); + pPaletteManager->RecalculateAll(); + pBitmaps_LOD->SetupPalettes(pRenderer->uTargetRBits, pRenderer->uTargetGBits, pRenderer->uTargetBBits); + pIcons_LOD->SetupPalettes(pRenderer->uTargetRBits, pRenderer->uTargetGBits, pRenderer->uTargetBBits); + v2 = 0; + if ( (signed int)pObjectList->uNumObjects > 0 ) + { + v3 = 0; + do + { + BYTE3(v4) = 0; + v5 = &pObjectList->pObjects[v3]; + ++v3; + *(short *)((char *)&v4 + 1) = v5->uParticleTrailColorR; + LOBYTE(v4) = v5->uParticleTrailColorG; + v1 = v5->uParticleTrailColorB | (v4 << 8); + ++v2; + v5->uParticleTrailColor = v1; + } + while ( v2 < (signed int)pObjectList->uNumObjects ); + } + LOBYTE(v1) = 1; + SetUserInterface(pParty->uAlignment, v1); + if ( pVideoPlayer->pVideoFrame.pPixels ) + pVideoPlayer->pVideoFrame.Load(pVideoPlayer->pVideoFrameTextureFilename, 1); + if ( uCurrentMenuID ) + { + if ( uCurrentMenuID != 6 ) + { + if ( uCurrentMenuID == 8 ) + dword_A74C88 = 1; + goto LABEL_38; + } + v6 = &pTexture_PCX; + pTexture_PCX.Release(); + v9 = 0; + v8 = "makeme.pcx"; + } + else + { + v6 = &pTexture_PCX; + pTexture_PCX.Release(); + v7 = "title.pcx"; + if ( uCurrentMenuID ) + v7 = "lsave640.pcx"; + v9 = 0; + v8 = v7; + } + v6->Load(v8, v9); +LABEL_38: + viewparams->bRedrawGameUI = 1; + viewparams->_443343(); + pMouse->SetCurrentCursorBitmap(); + if ( pRenderer->bWindowMode ) + { + InvalidateRect(0, 0, 0); + MoveWindow(hWnd, uWindowX, uWindowY, uWindowWidth, uWindowHeight, 0); + ShowWindow(hWnd, 1); + } + pMouse->bActive = 1; + if ( pVideoPlayer->AnyMovieLoaded() ) + pVideoPlayer->_4BF73A(); + if ( BYTE1(dword_6BE364_game_settings_1) & 8 ) + BYTE1(dword_6BE364_game_settings_1) &= 0xF7u; + else + pEventTimer->Resume(); + if ( BYTE1(dword_6BE364_game_settings_1) & 0x10 ) + BYTE1(dword_6BE364_game_settings_1) &= 0xEFu; + else + pMiscTimer->Resume(); + pAsyncMouse->Release(); + CreateAsyncMouse(); + if (pAsyncMouse) + pAsyncMouse->Clip(); + } +} +// 6BE364: using guessed type int dword_6BE364_game_settings_1; +// A74C88: using guessed type int dword_A74C88; + + +//----- (0044EC20) -------------------------------------------------------- +bool RenderD3D::DoesRaiseExceptions() +{ + return true; +} + + +//----- (0040DBD3) -------------------------------------------------------- +void __fastcall Render::SetPixel(Vec2_int_ *pTargetXY, unsigned __int16 uColor) +{ + Vec2_int_ *pTargetXY_; // esi@1 + unsigned __int16 v3; // di@1 + signed int v4; // ecx@2 + signed int v5; // eax@4 + + pTargetXY_ = pTargetXY; + v3 = uColor; + pRenderer->BeginScene(); + if ( pRenderer->uNumSceneBegins ) + { + v4 = pTargetXY_->x; + if ( pTargetXY_->x >= 0 ) + { + if ( v4 <= 639 ) + { + v5 = pTargetXY_->y; + if ( v5 >= 0 ) + { + if ( v5 <= 479 ) + pRenderer->pTargetSurface[v4 + pRenderer->uTargetSurfacePitch * v5] = v3; + } + } + } + pRenderer->EndScene(); + } +} + + +//----- (004524D8) -------------------------------------------------------- +HWLTexture *RenderHWLContainer::LoadTexture(const char *pName, int bMipMaps) +{ + int v11; // eax@13 + int v12; // ecx@13 + void *v13; // eax@13 + unsigned __int8 v14; // zf@13 + unsigned __int8 v15; // sf@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 + + //v3 = this; + //sprintf(Str1, "%s", pName); + //v4 = uNumItems; + if (!uNumItems) + return nullptr; + + //{ + //v5 = 0, pDesta = uNumItems; + uint idx1 = 0, + idx2 = uNumItems; + while (true) + { + auto i = idx1 + (idx2 - idx1) / 2; + + auto res = strcmpi(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); + + auto pTex = new HWLTexture; + fread(&pTex->field_18, 4, 1, pFile); + fread(&pTex->field_1C, 4, 1, pFile); + fread(&pTex->field_20, 4, 1, pFile); + fread(&pTex->field_24, 4, 1, pFile); + fread(&pTex->uWidth, 4, 1, pFile); + fread(&pTex->uHeight, 4, 1, pFile); + fread(&pTex->field_30, 4, 1, pFile); + fread(&pTex->field_34, 4, 1, pFile); + + pTex->pPixels = new unsigned __int16[pTex->uWidth * pTex->uHeight]; + if (uCompressedSize) + { + auto pCompressedData = new char[uCompressedSize]; + { + fread(pCompressedData, 1, uCompressedSize, pFile); + auto 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 ( field_61A94_scale_hwls_to_half ) + { + v11 = pTex->uHeight / 2; + v12 = pTex->uWidth / 2; + pTex->uHeight = v11; + pTex->uWidth = v12; + v13 = new unsigned __int16[v12 * v11]; + v28 = 0; + v14 = pTex->uHeight == 0; + v15 = (pTex->uHeight & 0x80000000u) != 0; + v26 = (unsigned __int16 *)v13; + if ( !(v15 | v14) ) + { + 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; + v26[v23] = sub_452442(*(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; + //result = pTex; +// } +// else +// { +//LABEL_8: +// return nullptr; +// } +} + +//----- (0045271F) -------------------------------------------------------- +bool RenderHWLContainer::Release() +{ + RenderHWLContainer *v1; // esi@1 + int v2; // ebx@1 + void **v3; // edi@3 + __int32 v4; // eax@6 + FILE *v5; // ST24_4@6 + size_t *v6; // edi@6 + int v7; // ebx@7 + signed int v9; // [sp+0h] [bp-8h]@6 + FILE *File; // [sp+4h] [bp-4h]@6 + + v1 = this; + v2 = 0; + if ( this->bDumpDebug ) + { + File = fopen("logd3d.txt", "w"); + v4 = ftell(v1->pFile); + v5 = v1->pFile; + v6 = &v1->uNumItems; + v1->uDataOffset = v4; + fwrite(&v1->uNumItems, 4u, 1u, v5); + v9 = 0; + if ( (signed int)v1->uNumItems > 0 ) + { + v7 = (int)v1->pSpriteNames; + do + { + fwrite(*(const void **)v7, 1u, 0x14u, v1->pFile); + fprintf(File, "D3D texture name: %s\t\toffset: %x\n", *(unsigned int *)v7, *(unsigned int *)(v7 + 200000)); + ++v9; + v7 += 4; + } + while ( v9 < (signed int)*v6 ); + v2 = 0; + } + fwrite(v1->pSpriteOffsets, 4u, *v6, v1->pFile); + fseek(v1->pFile, 4, v2); + fwrite(&v1->uDataOffset, 4u, 1u, v1->pFile); + fclose(v1->pFile); + fclose(File); + } + else + { + fclose(this->pFile); + if ( (signed int)v1->uNumItems > 0 ) + { + v3 = (void **)v1->pSpriteNames; + do + { + free(*v3); + ++v2; + ++v3; + } + while ( v2 < (signed int)v1->uNumItems ); + } + } + return 1; +} + +//----- (00452347) -------------------------------------------------------- +RenderHWLContainer::RenderHWLContainer(): + bDumpDebug(false) +{ + RenderHWLContainer *v1; // esi@1 + + v1 = this; + this->pFile = 0; + uSignature = 0; + v1->uDataOffset = 0; + memset(&v1->uNumItems, 0, 0x61A84u); + v1->uNumItems = 0; + v1->field_61A94_scale_hwls_to_half = 0; +} + +//----- (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 DoRenderBillboards_D3D() +{ + ErrD3D(pRenderer->pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, 3u)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, 1u)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, 0)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, 1u)); + + for (uint i = pRenderer->uNumBillboardsToDraw - 1; i != (uint)-1; --i) + { + auto p = pRenderer->pBillboardRenderListD3D + i; + + if (p->uOpacity != RenderBillboardD3D::InvalidOpacity) + SetBillboardBlendOptions(p->uOpacity); + + ErrD3D(pRenderer->pRenderD3D->pDevice->SetTexture(0, p->pTexture)); + ErrD3D(pRenderer->pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + p->pQuards, p->uNumVertices, D3DDP_DONOTLIGHT | D3DDP_DONOTUPDATEEXTENTS)); + } + + if (pRenderer->bFogEnabled) + { + pRenderer->bFogEnabled = false; + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 1)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, GetLevelFogColor() & 0xFFFFFF)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, 0)); + } + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, 2)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, 1)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, 0)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, 2u)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 1u)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, 1u)); +} + + + + + +//----- (004A1DA8) -------------------------------------------------------- +void SetBillboardBlendOptions(RenderBillboardD3D::OpacityType a1) +{ + switch (a1) + { + case RenderBillboardD3D::Transparent: + { + if (pRenderer->bFogEnabled) + { + pRenderer->bFogEnabled = false; + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 1u)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, GetLevelFogColor() & 0xFFFFFF)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, 0)); + } + + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, 5)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 6u)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, 1)); + } + break; + + case RenderBillboardD3D::Opaque_1: + case RenderBillboardD3D::Opaque_2: + case RenderBillboardD3D::Opaque_3: + { + if (pRenderer->bUsingSpecular) + { + if (!pRenderer->bFogEnabled) + { + pRenderer->bFogEnabled = true; + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 0)); + } + } + + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, 2)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 2u)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, 0)); + } + break; + + default: + Log::Warning(L"SetBillboardBlendOptions: invalid opacity type (%u)", a1); + break; + } +} +